summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2017-03-30 09:41:29 +0000
committertavmjong-free <tavmjong@free.fr>2017-03-30 09:41:29 +0000
commit3de63445fe736ca7c67cdce96426f6e5e3b8ebf4 (patch)
tree2d40dafb380e3879ed5d9d8d4a6cfabd00761fb6 /src
parentWhite space. (diff)
downloadinkscape-3de63445fe736ca7c67cdce96426f6e5e3b8ebf4.tar.gz
inkscape-3de63445fe736ca7c67cdce96426f6e5e3b8ebf4.zip
Add canvas-rotate for rapid previewing canvas rotation.
Add canvas-debug for study of canvas tiling. (bzr r15612)
Diffstat (limited to 'src')
-rw-r--r--src/desktop.cpp16
-rw-r--r--src/desktop.h2
-rw-r--r--src/display/CMakeLists.txt4
-rw-r--r--src/display/canvas-debug.cpp100
-rw-r--r--src/display/canvas-debug.h41
-rw-r--r--src/display/canvas-rotate.cpp288
-rw-r--r--src/display/canvas-rotate.h50
-rw-r--r--src/display/gnome-canvas-acetate.cpp8
-rw-r--r--src/display/sp-canvas.cpp9
-rw-r--r--src/display/sp-canvas.h6
-rw-r--r--src/ui/CMakeLists.txt1
-rw-r--r--src/ui/tools/tool-base.cpp81
12 files changed, 544 insertions, 62 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp
index ccc3d3da4..c56c42267 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -40,7 +40,9 @@
#include "desktop-style.h"
#include "device-manager.h"
#include "display/canvas-arena.h"
+#include "display/canvas-debug.h"
#include "display/canvas-grid.h"
+#include "display/canvas-rotate.h"
#include "display/canvas-temporary-item-list.h"
#include "display/drawing-group.h"
#include "display/gnome-canvas-acetate.h"
@@ -129,7 +131,6 @@ SPDesktop::SPDesktop() :
layers->_layer_deactivated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_deactivated), this));
layers->_layer_changed_signal.connect(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this));
selection = Inkscape::GC::release( new Inkscape::Selection(layers, this) );
- // _current_affine.setRotate(M_PI/4); // To test zooming with rotation
}
void
@@ -221,10 +222,10 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
// being selected? or does it intercept some of the events that should have gone to the
// node handler? see bug https://bugs.launchpad.net/inkscape/+bug/414142)
gridgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
- guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
- sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
tempgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
- controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
// Set the select tool as the active tool.
set_event_context2("/tools/select");
@@ -252,7 +253,8 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
_doc2dt[5] = document->getHeight().value("px");
sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt);
- _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
+ _modified_connection =
+ namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
Inkscape::DrawingItem *ai = document->getRoot()->invoke_show(
SP_CANVAS_ARENA (drawing)->drawing,
@@ -314,6 +316,10 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
temporary_item_list = new Inkscape::Display::TemporaryItemList( this );
snapindicator = new Inkscape::Display::SnapIndicator ( this );
+
+ canvas_rotate = sp_canvas_item_new (root, SP_TYPE_CANVAS_ROTATE, NULL);
+ sp_canvas_item_hide( canvas_rotate );
+ // canvas_debug = sp_canvas_item_new (main, SP_TYPE_CANVAS_DEBUG, NULL);
}
diff --git a/src/desktop.h b/src/desktop.h
index 757ca8cb0..330d95607 100644
--- a/src/desktop.h
+++ b/src/desktop.h
@@ -177,6 +177,8 @@ public:
SPCanvasGroup *tempgroup; ///< contains temporary canvas items
SPCanvasItem *page; ///< page background
SPCanvasItem *page_border; ///< page border
+ SPCanvasItem *canvas_rotate; ///< quickly show canvas rotation
+ SPCanvasItem *canvas_debug; ///< shows tiling
SPCSSAttr *current; ///< current style
bool _focusMode; ///< Whether we're focused working or general working
diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt
index 0bf1d6e45..8eaaee99a 100644
--- a/src/display/CMakeLists.txt
+++ b/src/display/CMakeLists.txt
@@ -4,7 +4,9 @@ set(display_SRC
canvas-arena.cpp
canvas-axonomgrid.cpp
canvas-bpath.cpp
+ canvas-debug.cpp
canvas-grid.cpp
+ canvas-rotate.cpp
canvas-temporary-item-list.cpp
canvas-temporary-item.cpp
canvas-text.cpp
@@ -64,7 +66,9 @@ set(display_SRC
canvas-arena.h
canvas-axonomgrid.h
canvas-bpath.h
+ canvas-debug.h
canvas-grid.h
+ canvas-rotate.h
canvas-temporary-item-list.h
canvas-temporary-item.h
canvas-text.h
diff --git a/src/display/canvas-debug.cpp b/src/display/canvas-debug.cpp
new file mode 100644
index 000000000..1748029e9
--- /dev/null
+++ b/src/display/canvas-debug.cpp
@@ -0,0 +1,100 @@
+/*
+ * A simple surface for debugging the canvas. Shows how tiles are drawn.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "inkscape.h"
+#include "desktop.h"
+
+#include "canvas-debug.h"
+#include "sp-canvas.h"
+#include "cairo-utils.h"
+#include "ui/event-debug.h"
+
+namespace {
+
+static void sp_canvas_debug_destroy(SPCanvasItem *item);
+static void sp_canvas_debug_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags);
+static void sp_canvas_debug_render (SPCanvasItem *item, SPCanvasBuf *buf);
+static int sp_canvas_debug_event (SPCanvasItem *item, GdkEvent *event);
+
+} // namespace
+
+G_DEFINE_TYPE(SPCanvasDebug, sp_canvas_debug, SP_TYPE_CANVAS_ITEM);
+
+static void sp_canvas_debug_class_init (SPCanvasDebugClass *klass)
+{
+ klass->destroy = sp_canvas_debug_destroy;
+ klass->update = sp_canvas_debug_update;
+ klass->render = sp_canvas_debug_render;
+ klass->event = sp_canvas_debug_event;
+}
+
+static void sp_canvas_debug_init (SPCanvasDebug *debug)
+{
+ debug->pickable = true; // So we can receive events.
+}
+
+namespace {
+static void sp_canvas_debug_destroy (SPCanvasItem *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (SP_IS_CANVAS_DEBUG (object));
+
+ if (SP_CANVAS_ITEM_CLASS(sp_canvas_debug_parent_class)->destroy) {
+ SP_CANVAS_ITEM_CLASS(sp_canvas_debug_parent_class)->destroy(object);
+ }
+}
+
+static void sp_canvas_debug_update( SPCanvasItem *item, Geom::Affine const &/*affine*/, unsigned int /*flags*/ )
+{
+ // We cover the entire canvas
+ item->x1 = -G_MAXINT;
+ item->y1 = -G_MAXINT;
+ item->x2 = G_MAXINT;
+ item->y2 = G_MAXINT;
+}
+
+static void sp_canvas_debug_render( SPCanvasItem *item, SPCanvasBuf *buf)
+{
+ if (!buf->ct) {
+ return;
+ }
+
+ cairo_set_line_width (buf->ct, 2);
+
+ // Draw box around buffer (for debugging)
+ cairo_new_path (buf->ct);
+ cairo_move_to (buf->ct, 0, 0);
+ cairo_line_to (buf->ct, buf->rect.width(), 0);
+ cairo_line_to (buf->ct, buf->rect.width(), buf->rect.height());
+ cairo_line_to (buf->ct, 0, buf->rect.height());
+ cairo_close_path (buf->ct);
+ ink_cairo_set_source_rgba32 (buf->ct, 0xff7f7f7f);
+ cairo_stroke (buf->ct);
+}
+
+static int sp_canvas_debug_event (SPCanvasItem *item, GdkEvent *event)
+{
+ ui_dump_event (event, Glib::ustring("sp_canvas_debug_event"));
+ return false; // We don't use any events...
+}
+
+} // namespace
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/display/canvas-debug.h b/src/display/canvas-debug.h
new file mode 100644
index 000000000..d5a166da9
--- /dev/null
+++ b/src/display/canvas-debug.h
@@ -0,0 +1,41 @@
+#ifndef SEEN_SP_CANVAS_DEBUG_H
+#define SEEN_SP_CANVAS_DEBUG_H
+
+/*
+ * A simple surface for debugging the canvas. Shows how tiles are drawn.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-canvas-item.h"
+
+class SPItem;
+
+#define SP_TYPE_CANVAS_DEBUG (sp_canvas_debug_get_type ())
+#define SP_CANVAS_DEBUG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CANVAS_DEBUG, SPCanvasDebug))
+#define SP_IS_CANVAS_DEBUG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CANVAS_DEBUG))
+
+struct SPCanvasDebug : public SPCanvasItem {
+};
+
+GType sp_canvas_debug_get_type (void);
+
+struct SPCanvasDebugClass : public SPCanvasItemClass{};
+
+#endif // SEEN_SP_CANVAS_DEBUG_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/display/canvas-rotate.cpp b/src/display/canvas-rotate.cpp
new file mode 100644
index 000000000..aaf6b962c
--- /dev/null
+++ b/src/display/canvas-rotate.cpp
@@ -0,0 +1,288 @@
+/*
+ * Temporary surface for previewing rotated canvas.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "inkscape.h"
+#include "desktop.h"
+
+#include "canvas-rotate.h"
+#include "sp-canvas.h"
+#include "cairo-utils.h"
+#include "ui/event-debug.h"
+
+#include "2geom/point.h"
+#include "2geom/rect.h"
+
+#include <gtk/gtk.h>
+
+namespace {
+
+static void sp_canvas_rotate_destroy(SPCanvasItem *item);
+static void sp_canvas_rotate_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags);
+static void sp_canvas_rotate_render (SPCanvasItem *item, SPCanvasBuf *buf);
+static int sp_canvas_rotate_event (SPCanvasItem *item, GdkEvent *event);
+
+} // namespace
+
+void sp_canvas_rotate_paint (SPCanvasRotate *canvas_rotate, cairo_surface_t *background);
+
+G_DEFINE_TYPE(SPCanvasRotate, sp_canvas_rotate, SP_TYPE_CANVAS_ITEM);
+
+static void sp_canvas_rotate_class_init (SPCanvasRotateClass *klass)
+{
+ klass->destroy = sp_canvas_rotate_destroy;
+ //klass->update = sp_canvas_rotate_update;
+ //klass->render = sp_canvas_rotate_render;
+ klass->event = sp_canvas_rotate_event;
+}
+
+static void sp_canvas_rotate_init (SPCanvasRotate *rotate)
+{
+ rotate->pickable = true; // So we can receive events.
+ rotate->angle = 0.0;
+ rotate->start_angle = -1000;
+ rotate->surface_copy = NULL;
+ rotate->surface_rotated = NULL;
+}
+
+namespace {
+static void sp_canvas_rotate_destroy (SPCanvasItem *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (SP_IS_CANVAS_ROTATE (object));
+
+ if (SP_CANVAS_ITEM_CLASS(sp_canvas_rotate_parent_class)->destroy) {
+ SP_CANVAS_ITEM_CLASS(sp_canvas_rotate_parent_class)->destroy(object);
+ }
+}
+
+// NOT USED... TOO SLOW
+static void sp_canvas_rotate_update( SPCanvasItem *item, Geom::Affine const &/*affine*/, unsigned int /*flags*/ )
+{
+ SPCanvasRotate *cr = SP_CANVAS_ROTATE(item);
+
+ if (cr->surface_copy == NULL) {
+ // std::cout << "sp_canvas_rotate_update: surface_copy is NULL" << std::endl;
+ return;
+ }
+
+ // Destroy surface_rotated if it already exists.
+ if (cr->surface_rotated != NULL) {
+ cairo_surface_destroy (cr->surface_rotated);
+ cr->surface_rotated = NULL;
+ }
+
+ // Create rotated surface
+ cr->surface_rotated = ink_cairo_surface_create_identical(cr->surface_copy);
+ double width = cairo_image_surface_get_width (cr->surface_rotated);
+ double height = cairo_image_surface_get_height (cr->surface_rotated);
+ cairo_t *context = cairo_create( cr->surface_rotated );
+ cairo_set_operator( context, CAIRO_OPERATOR_SOURCE );
+ cairo_translate( context, width/2.0, height/2.0 );
+ cairo_rotate( context, Geom::rad_from_deg(-cr->angle) );
+ cairo_translate( context, -width/2.0, -height/2.0 );
+ cairo_set_source_surface( context, cr->surface_copy, 0, 0 );
+ cairo_paint( context );
+ cairo_destroy( context);
+
+ // We cover the entire canvas
+ item->x1 = -G_MAXINT;
+ item->y1 = -G_MAXINT;
+ item->x2 = G_MAXINT;
+ item->y2 = G_MAXINT;
+
+ item->canvas->requestRedraw(item->x1, item->y1, item->x2, item->y2);
+}
+
+// NOT USED... TOO SLOW
+static void sp_canvas_rotate_render( SPCanvasItem *item, SPCanvasBuf *buf)
+{
+ // std::cout << "sp_canvas_rotate_render:" << std::endl;
+ // std::cout << " buf->rect: " << buf->rect << std::endl;
+ // std::cout << " buf->canvas_rect: " << buf->canvas_rect << std::endl;
+ SPCanvasRotate *cr = SP_CANVAS_ROTATE(item);
+
+ if (!buf->ct) {
+ return;
+ }
+
+ if (cr->surface_rotated == NULL ) {
+ // std::cout << " surface_rotated is NULL" << std::endl;
+ return;
+ }
+
+ // Draw rotated canvas
+ cairo_save (buf->ct);
+ cairo_translate (buf->ct,
+ buf->canvas_rect.left() - buf->rect.left(),
+ buf->canvas_rect.top() - buf->rect.top() );
+ cairo_set_operator (buf->ct, CAIRO_OPERATOR_SOURCE );
+ cairo_set_source_surface (buf->ct, cr->surface_rotated, 0, 0 );
+ cairo_paint (buf->ct);
+ cairo_restore (buf->ct);
+
+
+ // Draw line from center to cursor
+ cairo_save (buf->ct);
+ cairo_translate (buf->ct, -buf->rect.left(), -buf->rect.top());
+ cairo_new_path (buf->ct);
+ cairo_move_to (buf->ct, cr->center[Geom::X], cr->center[Geom::Y]);
+ cairo_rel_line_to (buf->ct, cr->cursor[Geom::X], cr->cursor[Geom::Y]);
+ cairo_set_line_width (buf->ct, 2);
+ ink_cairo_set_source_rgba32 (buf->ct, 0xff00007f);
+ cairo_stroke (buf->ct);
+ cairo_restore (buf->ct);
+
+}
+
+static int sp_canvas_rotate_event (SPCanvasItem *item, GdkEvent *event)
+{
+ SPCanvasRotate *cr = SP_CANVAS_ROTATE(item);
+
+// ui_dump_event (event, Glib::ustring("sp_canvas_rotate_event"));
+
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ Geom::Rect viewbox = desktop->canvas->getViewbox(); // Not SVG viewbox!
+ cr->center = viewbox.midpoint();
+
+ switch (event->type) {
+ case GDK_MOTION_NOTIFY:
+ {
+ Geom::Point cursor( event->motion.x, event->motion.y );
+
+ // Both cursor and center are in window coordinates
+ Geom::Point rcursor( cursor - cr->center );
+ double angle = Geom::deg_from_rad( Geom::atan2(rcursor) );
+
+ // Set start angle
+ if (cr->start_angle < -360) {
+ cr->start_angle = angle;
+ }
+
+ double rotation_snap = 15;
+
+ double delta_angle = cr->start_angle - angle;
+
+ if (event->motion.state & GDK_SHIFT_MASK &&
+ event->motion.state & GDK_CONTROL_MASK) {
+ delta_angle = 0;
+ } else if (event->motion.state & GDK_SHIFT_MASK) {
+ delta_angle = round(delta_angle/rotation_snap) * rotation_snap;
+ } else if (event->motion.state & GDK_CONTROL_MASK) {
+ // ?
+ } else if (event->motion.state & GDK_MOD1_MASK) {
+ // Decimal raw angle
+ } else {
+ delta_angle = floor(delta_angle);
+ }
+
+ cr->angle = delta_angle;
+
+ // Correct line for snapping of angle
+ double distance = rcursor.length();
+ cr->cursor = Geom::Point::polar( Geom::rad_from_deg(angle), distance );
+
+ // Update screen
+ // sp_canvas_item_request_update( item );
+ sp_canvas_rotate_paint (cr, cr->canvas->_backing_store);
+ break;
+ }
+ case GDK_BUTTON_RELEASE:
+
+ // Rotate the actual canvas
+ desktop->rotate_relative_center_point (desktop->w2d(cr->center),
+ Geom::rad_from_deg(cr->angle) );
+
+ // We're done
+ sp_canvas_item_ungrab (item, event->button.time);
+ sp_canvas_item_hide (item);
+
+ cr->start_angle = -1000;
+ if (cr->surface_copy != NULL) {
+ cairo_surface_destroy( cr->surface_copy );
+ cr->surface_copy = NULL;
+ }
+ if (cr->surface_rotated != NULL) {
+ cairo_surface_destroy( cr->surface_rotated );
+ cr->surface_rotated = NULL;
+ }
+ // sp_canvas_item_show (desktop->drawing);
+
+ break;
+ case GDK_KEY_PRESS:
+ // std::cout << " Key press: " << std::endl;
+ break;
+ case GDK_KEY_RELEASE:
+ // std::cout << " Key release: " << std::endl;
+ break;
+ default:
+ // ui_dump_event (event, "sp_canvas_rotate_event: unwanted event: ");
+ break;
+ }
+
+ if (event->type == GDK_KEY_PRESS) return false;
+
+ return true;
+}
+
+} // namespace
+
+void sp_canvas_rotate_start (SPCanvasRotate *canvas_rotate, cairo_surface_t *background)
+{
+ if (background == NULL) {
+ std::cerr << "sp_canvas_rotate_start: background is NULL!" << std::endl;
+ return;
+ }
+
+ canvas_rotate->angle = 0.0;
+
+ // Copy current background
+ canvas_rotate->surface_copy = ink_cairo_surface_copy( background );
+
+ // Paint canvas with background... since we are hiding drawing.
+ sp_canvas_item_request_update( canvas_rotate );
+}
+
+// Paint the canvas ourselves for speed....
+void sp_canvas_rotate_paint (SPCanvasRotate *canvas_rotate, cairo_surface_t *background)
+{
+ if (background == NULL) {
+ std::cerr << "sp_canvas_rotate_paint: background is NULL!" << std::endl;
+ return;
+ }
+
+ double width = cairo_image_surface_get_width (background);
+ double height = cairo_image_surface_get_height (background);
+
+ // Draw rotated canvas
+ cairo_t *context = cairo_create( background );
+
+ cairo_save (context);
+ cairo_set_operator( context, CAIRO_OPERATOR_SOURCE );
+ cairo_translate( context, width/2.0, height/2.0 );
+ cairo_rotate( context, Geom::rad_from_deg(-canvas_rotate->angle) );
+ cairo_translate( context, -width/2.0, -height/2.0 );
+ cairo_set_source_surface( context, canvas_rotate->surface_copy, 0, 0 );
+ cairo_paint( context );
+ cairo_restore( context );
+ cairo_destroy( context );
+
+ gtk_widget_queue_draw (GTK_WIDGET (canvas_rotate->canvas));
+}
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/display/canvas-rotate.h b/src/display/canvas-rotate.h
new file mode 100644
index 000000000..8620dcced
--- /dev/null
+++ b/src/display/canvas-rotate.h
@@ -0,0 +1,50 @@
+#ifndef SEEN_SP_CANVAS_ROTATE_H
+#define SEEN_SP_CANVAS_ROTATE_H
+
+/*
+ * Temporary surface for previewing rotated canvas.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-canvas-item.h"
+#include "2geom/line.h"
+
+class SPItem;
+
+#define SP_TYPE_CANVAS_ROTATE (sp_canvas_rotate_get_type ())
+#define SP_CANVAS_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CANVAS_ROTATE, SPCanvasRotate))
+#define SP_IS_CANVAS_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CANVAS_ROTATE))
+
+struct SPCanvasRotate : public SPCanvasItem {
+ Geom::Point center; // Center of screen
+ Geom::Point cursor; // Position of cursor relative to center (after angle snapping)
+ double angle; // Rotation angle in degrees
+ double start_angle; // Starting angle of cursor
+ cairo_surface_t *surface_copy; // Copy of original surface
+ cairo_surface_t *surface_rotated; // Copy of original surface, rotated
+};
+
+void sp_canvas_rotate_start( SPCanvasRotate *canvas_rotate, cairo_surface_t *background );
+
+GType sp_canvas_rotate_get_type (void);
+
+struct SPCanvasRotateClass : public SPCanvasItemClass{};
+
+#endif // SEEN_SP_CANVAS_ROTATE_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/display/gnome-canvas-acetate.cpp b/src/display/gnome-canvas-acetate.cpp
index 9147a1bbf..297d69068 100644
--- a/src/display/gnome-canvas-acetate.cpp
+++ b/src/display/gnome-canvas-acetate.cpp
@@ -14,11 +14,13 @@
*/
#include "gnome-canvas-acetate.h"
+#include "ui/event-debug.h"
static void sp_canvas_acetate_destroy(SPCanvasItem *object);
static void sp_canvas_acetate_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags);
static double sp_canvas_acetate_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item);
+static int sp_canvas_acetate_event( SPCanvasItem *item, GdkEvent *event);
G_DEFINE_TYPE(SPCanvasAcetate, sp_canvas_acetate, SP_TYPE_CANVAS_ITEM);
@@ -29,6 +31,7 @@ static void sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass)
item_class->destroy = sp_canvas_acetate_destroy;
item_class->update = sp_canvas_acetate_update;
item_class->point = sp_canvas_acetate_point;
+ // item_class->event = sp_canvas_acetate_event;
}
static void sp_canvas_acetate_init (SPCanvasAcetate */*acetate*/)
@@ -60,3 +63,8 @@ static double sp_canvas_acetate_point( SPCanvasItem *item, Geom::Point /*p*/, SP
return 0.0;
}
+// static int sp_canvas_acetate_event( SPCanvasItem *item, GdkEvent *event)
+// {
+// ui_dump_event (event, "sp_canvas_acetate_event");
+// return 0; // ?
+// }
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp
index f27038593..74aa4807a 100644
--- a/src/display/sp-canvas.cpp
+++ b/src/display/sp-canvas.cpp
@@ -1507,7 +1507,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect
buf.buf = NULL;
buf.buf_rowstride = 0;
buf.rect = paint_rect;
- buf.visible_rect = canvas_rect;
+ buf.canvas_rect = canvas_rect;
buf.is_empty = true;
// create temporary surface
@@ -1571,7 +1571,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect
}
struct PaintRectSetup {
- Geom::IntRect big_rect;
+ Geom::IntRect canvas_rect;
GTimeVal start_time;
int max_pixels;
Geom::Point mouse_loc;
@@ -1630,7 +1630,7 @@ int SPCanvas::paintRectInternal(PaintRectSetup const *setup, Geom::IntRect const
gdk_window_begin_paint_rect(window, &r);
*/
- paintSingleBuffer(this_rect, setup->big_rect, bw);
+ paintSingleBuffer(this_rect, setup->canvas_rect, bw);
//gdk_window_end_paint(window);
return 1;
}
@@ -1695,6 +1695,7 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1)
gtk_widget_get_allocation(GTK_WIDGET(this), &allocation);
+ // Find window rectangle in 'world coordinates'.
Geom::IntRect canvas_rect = Geom::IntRect::from_xywh(_x0, _y0,
allocation.width, allocation.height);
Geom::IntRect paint_rect(xx0, yy0, xx1, yy1);
@@ -1705,7 +1706,7 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1)
paint_rect = *area;
PaintRectSetup setup;
- setup.big_rect = paint_rect;
+ setup.canvas_rect = canvas_rect;
// Save the mouse location
gint x, y;
diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h
index b13477283..a2cbe0b27 100644
--- a/src/display/sp-canvas.h
+++ b/src/display/sp-canvas.h
@@ -51,7 +51,7 @@ enum {
struct SPCanvasBuf {
cairo_t *ct;
Geom::IntRect rect;
- Geom::IntRect visible_rect;
+ Geom::IntRect canvas_rect; // visible window in world coordinates (i.e. offset by _x0, _y0)
unsigned char *buf;
int buf_rowstride;
@@ -174,8 +174,8 @@ public:
bool _is_dragging;
double _dx0;
double _dy0;
- int _x0; ///< World coordinate of the leftmost pixels
- int _y0; ///< World coordinate of the topmost pixels
+ int _x0; ///< World coordinate of the leftmost pixels of window
+ int _y0; ///< World coordinate of the topmost pixels of window
/// Image surface storing the contents of the widget
cairo_surface_t *_backing_store;
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 259a06013..389e8902a 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -177,6 +177,7 @@ set(ui_SRC
control-types.h
dialog-events.h
draw-anchor.h
+ event-debug.h
icon-names.h
interface.h
object-edit.h
diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp
index cd5defcc6..3d755eadc 100644
--- a/src/ui/tools/tool-base.cpp
+++ b/src/ui/tools/tool-base.cpp
@@ -22,12 +22,21 @@
#include "shortcuts.h"
#include "file.h"
+
+#include "ui/interface.h"
+#include "ui/event-debug.h"
+#include "ui/tool/control-point.h"
+#include "ui/shape-editor.h"
#include "ui/tools/tool-base.h"
+#include "ui/tools-switch.h"
+#include "ui/tools/lpe-tool.h"
#include <gdk/gdkkeysyms.h>
#include <glibmm/i18n.h>
#include "display/sp-canvas.h"
+#include "display/sp-canvas-group.h"
+#include "display/canvas-rotate.h"
#include "xml/node-event-vector.h"
#include "sp-cursor.h"
#include "desktop.h"
@@ -36,16 +45,11 @@
#include "desktop-style.h"
#include "sp-namedview.h"
#include "selection.h"
-#include "ui/interface.h"
#include "macros.h"
-#include "ui/tools-switch.h"
#include "message-context.h"
#include "gradient-drag.h"
#include "rubberband.h"
#include "selcue.h"
-#include "ui/tools/lpe-tool.h"
-#include "ui/tool/control-point.h"
-#include "ui/shape-editor.h"
#include "sp-guide.h"
#include "knot-ptr.h"
@@ -323,6 +327,8 @@ static gdouble accelerate_scroll(GdkEvent *event, gdouble acceleration,
}
bool ToolBase::root_handler(GdkEvent* event) {
+
+ // ui_dump_event (event, "ToolBase::root_handler");
static Geom::Point button_w;
static unsigned int panning = 0;
static unsigned int panning_cursor = 0;
@@ -374,7 +380,22 @@ bool ToolBase::root_handler(GdkEvent* event) {
break;
case 2:
- if (event->button.state & GDK_SHIFT_MASK) {
+ if (event->button.state & GDK_CONTROL_MASK) {
+ // On screen canvas rotation preview
+
+ // Grab background before doing anything else
+ sp_canvas_rotate_start (SP_CANVAS_ROTATE(desktop->canvas_rotate),
+ desktop->canvas->_backing_store);
+ sp_canvas_item_ungrab (desktop->acetate, event->button.time);
+ sp_canvas_item_show (desktop->canvas_rotate);
+ sp_canvas_item_grab (desktop->canvas_rotate,
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ NULL, event->button.time );
+ // sp_canvas_item_hide (desktop->drawing);
+
+ } else if (event->button.state & GDK_SHIFT_MASK) {
zoom_rb = 2;
} else {
// When starting panning, make sure there are no snap events pending because these might disable the panning again
@@ -384,9 +405,9 @@ bool ToolBase::root_handler(GdkEvent* event) {
panning = 2;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK, NULL,
- event->button.time - 1);
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK,
+ NULL, event->button.time - 1);
}
@@ -496,6 +517,7 @@ bool ToolBase::root_handler(GdkEvent* event) {
break;
case GDK_BUTTON_RELEASE:
+
xp = yp = 0;
if (panning_cursor == 1) {
@@ -1187,47 +1209,6 @@ sp_event_context_get_shape_editor(ToolBase *ec) {
return ec->shape_editor;
}
-void event_context_print_event_info(GdkEvent *event, bool print_return) {
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- g_print("GDK_BUTTON_PRESS");
- break;
- case GDK_2BUTTON_PRESS:
- g_print("GDK_2BUTTON_PRESS");
- break;
- case GDK_3BUTTON_PRESS:
- g_print("GDK_3BUTTON_PRESS");
- break;
-
- case GDK_MOTION_NOTIFY:
- g_print("GDK_MOTION_NOTIFY");
- break;
- case GDK_ENTER_NOTIFY:
- g_print("GDK_ENTER_NOTIFY");
- break;
-
- case GDK_LEAVE_NOTIFY:
- g_print("GDK_LEAVE_NOTIFY");
- break;
- case GDK_BUTTON_RELEASE:
- g_print("GDK_BUTTON_RELEASE");
- break;
-
- case GDK_KEY_PRESS:
- g_print("GDK_KEY_PRESS: %d", get_group0_keyval(&event->key));
- break;
- case GDK_KEY_RELEASE:
- g_print("GDK_KEY_RELEASE: %d", get_group0_keyval(&event->key));
- break;
- default:
- //g_print ("even type not recognized");
- break;
- }
-
- if (print_return) {
- g_print("\n");
- }
-}
/**
* Analyses the current event, calculates the mouse speed, turns snapping off (temporarily) if the