diff --git a/src/event-context.cpp b/src/event-context.cpp
index 2ab045e7e2d19d9fd742de27ebd7a3911e72d335..7e14d5a492f4106dcdc7f2c97dd37a8487883b23 100644 (file)
--- a/src/event-context.cpp
+++ b/src/event-context.cpp
#include <gdk/gdkkeysyms.h>
#include <gtk/gtkmain.h>
#include <gtk/gtkmenu.h>
+#include <glibmm/i18n.h>
#include "display/sp-canvas.h"
#include "xml/node-event-vector.h"
event_context->_message_context = NULL;
event_context->_selcue = NULL;
event_context->_grdrag = NULL;
+ event_context->space_panning = false;
}
/**
}
gdk_window_set_cursor(w->window, ec->cursor);
}
+ ec->desktop->waiting_cursor = false;
}
/**
* Calculates and keeps track of scroll acceleration.
* Subroutine of sp_event_context_private_root_handler().
*/
-static gdouble accelerate_scroll(GdkEvent *event, gdouble acceleration)
+static gdouble accelerate_scroll(GdkEvent *event, gdouble acceleration, SPCanvas *canvas)
{
guint32 time_diff = ((GdkEventKey *) event)->time - scroll_event_time;
/* key pressed within 500ms ? (1/2 second) */
if (time_diff > 500 || event->key.keyval != scroll_keyval) {
- scroll_multiply = 1;
+ scroll_multiply = 1; // abort acceleration
} else {
- scroll_multiply += acceleration;
+ scroll_multiply += acceleration; // continue acceleration
}
scroll_event_time = ((GdkEventKey *) event)->time;
@@ -335,10 +338,19 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
yp = (gint) event->button.y;
within_tolerance = true;
+ button_w = NR::Point(event->button.x, event->button.y);
+
switch (event->button.button) {
+ case 1:
+ if (event_context->space_panning) {
+ panning = 1;
+ sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
+ GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
+ NULL, event->button.time-1);
+ ret = TRUE;
+ }
+ break;
case 2:
- button_w = NR::Point(event->button.x,
- event->button.y);
if (event->button.state == GDK_SHIFT_MASK) {
zoom_rb = 2;
} else {
@@ -352,8 +364,6 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
case 3:
if (event->button.state & GDK_SHIFT_MASK
|| event->button.state & GDK_CONTROL_MASK) {
- button_w = NR::Point(event->button.x,
- event->button.y);
panning = 3;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
@@ -370,7 +380,9 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
case GDK_MOTION_NOTIFY:
if (panning) {
if ((panning == 2 && !(event->motion.state & GDK_BUTTON2_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),
@@ -393,12 +405,12 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
// gobble subsequent motion events to prevent "sticking"
// when scrolling is slow
gobble_motion_events(panning == 2 ?
- GDK_BUTTON2_MASK : GDK_BUTTON3_MASK);
+ GDK_BUTTON2_MASK :
+ (panning == 1 ? GDK_BUTTON1_MASK : GDK_BUTTON3_MASK));
- NR::Point const motion_w(event->motion.x,
- event->motion.y);
+ NR::Point const motion_w(event->motion.x, event->motion.y);
NR::Point const moved_w( motion_w - button_w );
- event_context->desktop->scroll_world(moved_w);
+ event_context->desktop->scroll_world(moved_w, true); // we're still scrolling, do not redraw
ret = TRUE;
}
} else if (zoom_rb) {
@@ -410,42 +422,57 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
&& ( abs( (gint) event->motion.y - yp ) < tolerance ) ) {
break; // do not drag if we're within tolerance from origin
}
-
- if (within_tolerance) {
- Inkscape::Rubberband::get()->start(desktop, motion_dt);
- } else {
- Inkscape::Rubberband::get()->move(motion_dt);
- }
-
// Once the user has moved farther than tolerance from the original location
// (indicating they intend to move the object, not click), then always process the
// motion notify coordinates as given (no snapping back to origin)
within_tolerance = false;
+
+ if (Inkscape::Rubberband::get()->is_started()) {
+ Inkscape::Rubberband::get()->move(motion_dt);
+ } else {
+ Inkscape::Rubberband::get()->start(desktop, motion_dt);
+ }
+ if (zoom_rb == 2)
+ gobble_motion_events(GDK_BUTTON2_MASK);
}
break;
case GDK_BUTTON_RELEASE:
xp = yp = 0;
if (within_tolerance && (panning || zoom_rb)) {
zoom_rb = 0;
+ if (panning) {
+ panning = 0;
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
+ event->button.time);
+ }
NR::Point const event_w(event->button.x, event->button.y);
NR::Point const event_dt(desktop->w2d(event_w));
desktop->zoom_relative_keep_point(event_dt,
(event->button.state & GDK_SHIFT_MASK) ? 1/zoom_inc : zoom_inc);
desktop->updateNow();
- }
- if (panning == event->button.button) {
- panning = 0;
ret = TRUE;
+ } else if (panning == event->button.button) {
+ panning = 0;
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
event->button.time);
+
+ // in slow complex drawings, some of the motion events are lost;
+ // to make up for this, we scroll it once again to the button-up event coordinates
+ // (i.e. canvas will always get scrolled all the way to the mouse release point,
+ // even if few intermediate steps were visible)
+ NR::Point const motion_w(event->button.x, event->button.y);
+ NR::Point const moved_w( motion_w - button_w );
+ event_context->desktop->scroll_world(moved_w);
desktop->updateNow();
+ ret = TRUE;
} else if (zoom_rb == event->button.button) {
zoom_rb = 0;
NR::Maybe<NR::Rect> const b = Inkscape::Rubberband::get()->getRectangle();
Inkscape::Rubberband::get()->stop();
- if (b != NR::Nothing() && !within_tolerance) {
- desktop->set_display_area(b.assume(), 10);
+ if (b && !within_tolerance) {
+ desktop->set_display_area(*b, 10);
}
+ ret = TRUE;
}
break;
case GDK_KEY_PRESS:
@@ -480,7 +507,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
case GDK_KP_Left:
case GDK_KP_4:
if (MOD__CTRL_ONLY) {
- int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration));
+ int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop)));
gobble_key_events(get_group0_keyval(&event->key),
GDK_CONTROL_MASK);
event_context->desktop->scroll_world(i, 0);
@@ -491,7 +518,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
case GDK_KP_Up:
case GDK_KP_8:
if (MOD__CTRL_ONLY) {
- int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration));
+ int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop)));
gobble_key_events(get_group0_keyval(&event->key),
GDK_CONTROL_MASK);
event_context->desktop->scroll_world(0, i);
@@ -502,7 +529,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
case GDK_KP_Right:
case GDK_KP_6:
if (MOD__CTRL_ONLY) {
- int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration));
+ int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop)));
gobble_key_events(get_group0_keyval(&event->key),
GDK_CONTROL_MASK);
event_context->desktop->scroll_world(-i, 0);
@@ -513,7 +540,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
case GDK_KP_Down:
case GDK_KP_2:
if (MOD__CTRL_ONLY) {
- int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration));
+ int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop)));
gobble_key_events(get_group0_keyval(&event->key),
GDK_CONTROL_MASK);
event_context->desktop->scroll_world(0, -i);
@@ -527,8 +554,14 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
}
break;
case GDK_space:
- sp_toggle_selector(desktop);
- ret= TRUE;
+ if (prefs_get_int_attribute("options.spacepans","value", 0) == 1) {
+ 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;
+ }
break;
case GDK_z:
case GDK_Z:
@@ -541,7 +574,29 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
break;
}
break;
+ case GDK_KEY_RELEASE:
+ switch (get_group0_keyval(&event->key)) {
+ case GDK_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();
+ }
+ ret= TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
case GDK_SCROLL:
+ {
+ bool ctrl = (event->scroll.state & GDK_CONTROL_MASK);
+ bool wheelzooms = (prefs_get_int_attribute("options.wheelzooms","value", 0) == 1);
/* shift + wheel, pan left--right */
if (event->scroll.state & GDK_SHIFT_MASK) {
switch (event->scroll.direction) {
@@ -556,7 +611,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
}
/* ctrl + wheel, zoom in--out */
- } else if (event->scroll.state & GDK_CONTROL_MASK) {
+ } else if ((ctrl && !wheelzooms) || (!ctrl && wheelzooms)) {
double rel_zoom;
switch (event->scroll.direction) {
case GDK_SCROLL_UP:
@@ -592,6 +647,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
}
}
break;
+ }
default:
break;
}