summaryrefslogtreecommitdiffstats
path: root/src/event-context.cpp
diff options
context:
space:
mode:
authorMarkus Engel <markus.engel@tum.de>2013-03-29 23:52:42 +0000
committerMarkus Engel <markus.engel@tum.de>2013-03-29 23:52:42 +0000
commita168040d5a452544328a1e6ad35aaac351f94d44 (patch)
treefae1ba829f543a473da281bd5fa6e4deabbf6912 /src/event-context.cpp
parentRemoved function pointers from SPObject and subclasses. (diff)
parentDutch translation update (diff)
downloadinkscape-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.cpp201
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;