diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-03-29 23:52:42 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-03-29 23:52:42 +0000 |
| commit | a168040d5a452544328a1e6ad35aaac351f94d44 (patch) | |
| tree | fae1ba829f543a473da281bd5fa6e4deabbf6912 /src/event-context.cpp | |
| parent | Removed function pointers from SPObject and subclasses. (diff) | |
| parent | Dutch translation update (diff) | |
| download | inkscape-a168040d5a452544328a1e6ad35aaac351f94d44.tar.gz inkscape-a168040d5a452544328a1e6ad35aaac351f94d44.zip | |
merged from trunk
(bzr r11608.1.56)
Diffstat (limited to 'src/event-context.cpp')
| -rw-r--r-- | src/event-context.cpp | 201 |
1 files changed, 131 insertions, 70 deletions
diff --git a/src/event-context.cpp b/src/event-context.cpp index bb3619877..6e5f0caad 100644 --- a/src/event-context.cpp +++ b/src/event-context.cpp @@ -18,6 +18,7 @@ # include "config.h" #endif +#include "shortcuts.h" #include "file.h" #include "event-context.h" @@ -31,7 +32,6 @@ #include "display/sp-canvas.h" #include "xml/node-event-vector.h" #include "sp-cursor.h" -#include "shortcuts.h" #include "desktop.h" #include "desktop-handles.h" #include "desktop-events.h" @@ -54,8 +54,6 @@ #include "sp-guide.h" #include "color.h" -static void sp_event_context_class_init(SPEventContextClass *klass); -static void sp_event_context_init(SPEventContext *event_context); static void sp_event_context_dispose(GObject *object); static void sp_event_context_private_setup(SPEventContext *ec); @@ -66,8 +64,6 @@ static gint sp_event_context_private_item_handler( static void set_event_location(SPDesktop * desktop, GdkEvent * event); -static GObjectClass *parent_class; - // globals for temporary switching to selector by space static bool selector_toggled = FALSE; static int switch_selector_to = 0; @@ -85,32 +81,13 @@ static guint32 scroll_event_time = 0; static gdouble scroll_multiply = 1; static guint scroll_keyval = 0; -/** - * Registers the SPEventContext class with Glib and returns its type number. - */ -GType sp_event_context_get_type(void) { - static GType type = 0; - if (!type) { - GTypeInfo info = { sizeof(SPEventContextClass), NULL, NULL, - (GClassInitFunc) sp_event_context_class_init, NULL, NULL, - sizeof(SPEventContext), 4, - (GInstanceInitFunc) sp_event_context_init, NULL, /* value_table */ - }; - type = g_type_register_static(G_TYPE_OBJECT, "SPEventContext", &info, - (GTypeFlags) 0); - } - return type; -} +G_DEFINE_TYPE(SPEventContext, sp_event_context, G_TYPE_OBJECT); /** * Callback to set up the SPEventContext vtable. */ static void sp_event_context_class_init(SPEventContextClass *klass) { - GObjectClass *object_class; - - object_class = (GObjectClass *) klass; - - parent_class = (GObjectClass*) g_type_class_peek_parent(klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->dispose = sp_event_context_dispose; @@ -168,7 +145,28 @@ static void sp_event_context_dispose(GObject *object) { delete ec->_delayed_snap_event; } - G_OBJECT_CLASS(parent_class)->dispose(object); + G_OBJECT_CLASS(sp_event_context_parent_class)->dispose(object); +} + +/** + * Set the cursor to a standard GDK cursor + */ +static void sp_event_context_set_cursor(SPEventContext *event_context, GdkCursorType cursor_type) { + + GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(event_context->desktop)); + GdkDisplay *display = gdk_display_get_default(); + GdkCursor *cursor = gdk_cursor_new_for_display(display, cursor_type); + +#if WITH_GTKMM_3_0 + if (cursor) { + gdk_window_set_cursor (gtk_widget_get_window (w), cursor); + g_object_unref (cursor); + } +#else + gdk_window_set_cursor (gtk_widget_get_window (w), cursor); + gdk_cursor_unref (cursor); +#endif + } /** @@ -314,7 +312,7 @@ static void sp_toggle_selector(SPDesktop *dt) { * Toggles current tool between active tool and dropper tool. * Subroutine of sp_event_context_private_root_handler(). */ -static void sp_toggle_dropper(SPDesktop *dt) { +void sp_toggle_dropper(SPDesktop *dt) { if (!dt->event_context) return; @@ -360,6 +358,7 @@ static gint sp_event_context_private_root_handler( SPEventContext *event_context, GdkEvent *event) { static Geom::Point button_w; static unsigned int panning = 0; + static unsigned int panning_cursor = 0; static unsigned int zoom_rb = 0; SPDesktop *desktop = event_context->desktop; @@ -393,6 +392,7 @@ static gint sp_event_context_private_root_handler( switch (event->button.button) { case 1: if (event_context->space_panning) { + // When starting panning, make sure there are no snap events pending because these might disable the panning again sp_event_context_discard_delayed_snap_event(event_context); panning = 1; @@ -408,6 +408,7 @@ static gint sp_event_context_private_root_handler( 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 sp_event_context_discard_delayed_snap_event(event_context); panning = 2; @@ -415,6 +416,7 @@ static gint sp_event_context_private_root_handler( GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK, NULL, event->button.time - 1); + } ret = TRUE; break; @@ -439,10 +441,23 @@ static gint sp_event_context_private_root_handler( break; case GDK_MOTION_NOTIFY: if (panning) { + if (panning == 4 && !xp && !yp ) { + // <Space> + mouse panning started, save location and grab canvas + xp = event->motion.x; + yp = event->motion.y; + button_w = Geom::Point(event->motion.x, event->motion.y); + + sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), + GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK, NULL, + event->motion.time - 1); + + + } if ((panning == 2 && !(event->motion.state & GDK_BUTTON2_MASK)) - || (panning == 1 && !(event->motion.state - & GDK_BUTTON1_MASK)) || (panning == 3 - && !(event->motion.state & GDK_BUTTON3_MASK))) { + || (panning == 1 && !(event->motion.state & GDK_BUTTON1_MASK)) + || (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))) { /* Gdk seems to lose button release for us sometimes :-( */ panning = 0; sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), @@ -466,6 +481,11 @@ static gint sp_event_context_private_root_handler( gobble_motion_events(panning == 2 ? GDK_BUTTON2_MASK : (panning == 1 ? GDK_BUTTON1_MASK : GDK_BUTTON3_MASK)); + if (panning_cursor == 0) { + panning_cursor = 1; + sp_event_context_set_cursor(event_context, GDK_FLEUR); + } + Geom::Point const motion_w(event->motion.x, event->motion.y); Geom::Point const moved_w(motion_w - button_w); event_context->desktop->scroll_world(moved_w, true); // we're still scrolling, do not redraw @@ -496,6 +516,11 @@ static gint sp_event_context_private_root_handler( break; case GDK_BUTTON_RELEASE: xp = yp = 0; + if (panning_cursor == 1) { + panning_cursor = 0; + GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(event_context->desktop)); + gdk_window_set_cursor(gtk_widget_get_window (w), event_context->cursor); + } if (within_tolerance && (panning || zoom_rb)) { zoom_rb = 0; if (panning) { @@ -535,6 +560,7 @@ static gint sp_event_context_private_root_handler( } ret = TRUE; } + break; case GDK_KEY_PRESS: { double const acceleration = prefs->getDoubleLimited( @@ -637,15 +663,13 @@ static gint sp_event_context_private_root_handler( } break; case GDK_KEY_space: - if (prefs->getBool("/options/spacepans/value")) { - event_context->space_panning = true; - event_context->_message_context->set(Inkscape::INFORMATION_MESSAGE, - _("<b>Space+mouse drag</b> to pan canvas")); - ret = TRUE; - } else { - sp_toggle_selector(desktop); - ret = TRUE; - } + xp = yp = 0; + within_tolerance = true; + panning = 4; + event_context->space_panning = true; + event_context->_message_context->set(Inkscape::INFORMATION_MESSAGE, + _("<b>Space+mouse move</b> to pan canvas")); + ret = TRUE; break; case GDK_KEY_z: case GDK_KEY_Z: @@ -660,19 +684,35 @@ static gint sp_event_context_private_root_handler( } break; case GDK_KEY_RELEASE: + + // Stop panning on any key release + if (event_context->space_panning) { + event_context->space_panning = false; + event_context->_message_context->clear(); + } + + if (panning) { + panning = 0; + xp = yp = 0; + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), + event->key.time); + desktop->updateNow(); + } + + if (panning_cursor == 1) { + panning_cursor = 0; + GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(event_context->desktop)); + gdk_window_set_cursor(gtk_widget_get_window (w), event_context->cursor); + } + switch (get_group0_keyval(&event->key)) { case GDK_KEY_space: - if (event_context->space_panning) { - event_context->space_panning = false; - event_context->_message_context->clear(); - if (panning == 1) { - panning = 0; - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), - event->key.time); - desktop->updateNow(); - } + if (within_tolerance == true) { + // Space was pressed, but not panned + sp_toggle_selector(desktop); ret = TRUE; } + within_tolerance = false; break; case GDK_KEY_Q: case GDK_KEY_q: @@ -691,9 +731,11 @@ static gint sp_event_context_private_root_handler( int const wheel_scroll = prefs->getIntLimited( "/options/wheelscroll/value", 40, 0, 1000); +#if GTK_CHECK_VERSION(3,0,0) // Size of smooth-scrolls (only used in GTK+ 3) gdouble delta_x = 0; gdouble delta_y = 0; +#endif /* shift + wheel, pan left--right */ if (event->scroll.state & GDK_SHIFT_MASK) { @@ -807,8 +849,8 @@ public: Inkscape::Preferences::Observer(path), _ec(ec) { } virtual void notify(Inkscape::Preferences::Entry const &val) { - if (((SPEventContextClass *) G_OBJECT_GET_CLASS(_ec))->set) { - ((SPEventContextClass *) G_OBJECT_GET_CLASS(_ec))->set(_ec, + if ((SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(_ec)))->set) { + (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(_ec)))->set(_ec, const_cast<Inkscape::Preferences::Entry*> (&val)); } } @@ -841,8 +883,8 @@ sp_event_context_new(GType type, SPDesktop *desktop, gchar const *pref_path, prefs->addObserver(*(ec->pref_observer)); } - if (((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->setup) - ((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->setup(ec); + if ((SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->setup) + (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->setup(ec); return ec; } @@ -860,8 +902,8 @@ void sp_event_context_finish(SPEventContext *ec) { g_warning("Finishing event context with active link\n"); } - if (((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->finish) - ((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->finish(ec); + if ((SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->finish) + (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->finish(ec); } //-------------------------------member functions @@ -897,6 +939,19 @@ void SPEventContext::enableGrDrag(bool enable) { } /** + * Delete a selected GrDrag point + */ +bool SPEventContext::deleteSelectedDrag(bool just_one) { + + if (_grdrag && _grdrag->selected) { + _grdrag->deleteSelected(just_one); + return TRUE; + } + + return FALSE; +} + +/** * Calls virtual set() function of SPEventContext. */ void sp_event_context_read(SPEventContext *ec, gchar const *key) { @@ -904,11 +959,11 @@ void sp_event_context_read(SPEventContext *ec, gchar const *key) { g_return_if_fail(SP_IS_EVENT_CONTEXT(ec)); g_return_if_fail(key != NULL); - if (((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->set) { + if ((SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->set) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Inkscape::Preferences::Entry val = prefs->getEntry( ec->pref_observer->observed_path + '/' + key); - ((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->set(ec, &val); + (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->set(ec, &val); } } @@ -924,8 +979,8 @@ void sp_event_context_activate(SPEventContext *ec) { // context should take care of this by itself. sp_event_context_discard_delayed_snap_event(ec); - if (((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->activate) - ((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->activate(ec); + if ((SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->activate) + (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->activate(ec); } /** @@ -935,8 +990,8 @@ void sp_event_context_deactivate(SPEventContext *ec) { g_return_if_fail(ec != NULL); g_return_if_fail(SP_IS_EVENT_CONTEXT(ec)); - if (((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->deactivate) - ((SPEventContextClass *) G_OBJECT_GET_CLASS(ec))->deactivate(ec); + if ((SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->deactivate) + (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(ec)))->deactivate(ec); } /** @@ -977,7 +1032,7 @@ gint sp_event_context_virtual_root_handler(SPEventContext * event_context, GdkEv gint ret = false; if (event_context) { // If no event-context is available then do nothing, otherwise Inkscape would crash // (see the comment in SPDesktop::set_event_context, and bug LP #622350) - ret = ((SPEventContextClass *) G_OBJECT_GET_CLASS(event_context))->root_handler(event_context, event); + ret = (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(event_context)))->root_handler(event_context, event); set_event_location(event_context->desktop, event); } return ret; @@ -1016,7 +1071,7 @@ gint sp_event_context_virtual_item_handler(SPEventContext * event_context, SPIte gint ret = false; if (event_context) { // If no event-context is available then do nothing, otherwise Inkscape would crash // (see the comment in SPDesktop::set_event_context, and bug LP #622350) - ret = ((SPEventContextClass *) G_OBJECT_GET_CLASS(event_context))->item_handler(event_context, item, event); + ret = (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(event_context)))->item_handler(event_context, item, event); if (!ret) { ret = sp_event_context_virtual_root_handler(event_context, event); } else { @@ -1028,7 +1083,7 @@ gint sp_event_context_virtual_item_handler(SPEventContext * event_context, SPIte } /** - * Emits 'position_set' signal on desktop and shows coordinates on status bar. + * Shows coordinates on status bar. */ static void set_event_location(SPDesktop *desktop, GdkEvent *event) { if (event->type != GDK_MOTION_NOTIFY) { @@ -1037,7 +1092,6 @@ static void set_event_location(SPDesktop *desktop, GdkEvent *event) { Geom::Point const button_w(event->button.x, event->button.y); Geom::Point const button_dt(desktop->w2d(button_w)); - desktop->setPosition(button_dt); desktop->set_coordinate_status(button_dt); } @@ -1046,10 +1100,18 @@ static void set_event_location(SPDesktop *desktop, GdkEvent *event) { * Create popup menu and tell Gtk to show it. */ void sp_event_root_menu_popup(SPDesktop *desktop, SPItem *item, GdkEvent *event) { + + // It seems the param item is the SPItem at the bottom of the z-order + // Using the same function call used on left click in sp_select_context_item_handler() to get top of z-order + // fixme: sp_canvas_arena should set the top z-order object as arena->active + item = sp_event_context_find_item (desktop, + Geom::Point(event->button.x, event->button.y), FALSE, FALSE); + /* fixme: This is not what I want but works for now (Lauris) */ if (event->type == GDK_KEY_PRESS) { item = sp_desktop_selection(desktop)->singleItem(); } + ContextMenu* CM = new ContextMenu(desktop, item); CM->show(); @@ -1318,17 +1380,16 @@ gboolean sp_event_context_snap_watchdog_callback(gpointer data) { sp_event_context_virtual_root_handler(ec, dse->getEvent()); break; case DelayedSnapEvent::EVENTCONTEXT_ITEM_HANDLER: { - SPItem* item = NULL; - item = SP_ITEM(dse->getItem()); + gpointer item = dse->getItem(); if (item && SP_IS_ITEM(item)) { - sp_event_context_virtual_item_handler(ec, item, dse->getEvent()); + sp_event_context_virtual_item_handler(ec, SP_ITEM(item), dse->getEvent()); } } break; case DelayedSnapEvent::KNOT_HANDLER: { - SPKnot* knot = SP_KNOT(dse->getItem2()); + gpointer knot = dse->getItem2(); if (knot && SP_IS_KNOT(knot)) { - sp_knot_handler_request_position(dse->getEvent(), knot); + sp_knot_handler_request_position(dse->getEvent(), SP_KNOT(knot)); } } break; |
