From 31bb8269c26a781036448ed8f8cd93cc84fb2118 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 29 Nov 2009 16:33:18 +0100 Subject: First GSoC node tool commit to Bazaar (bzr r8846.1.1) --- src/ui/tool/selector.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/ui/tool/selector.cpp (limited to 'src/ui/tool/selector.cpp') diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp new file mode 100644 index 000000000..f95c9e064 --- /dev/null +++ b/src/ui/tool/selector.cpp @@ -0,0 +1,133 @@ +/** @file + * Selector component (click and rubberband) + */ +/* Authors: + * Krzysztof KosiƄski + * + * Copyright (C) 2009 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "desktop.h" +#include "desktop-handles.h" +#include "display/sodipodi-ctrlrect.h" +#include "event-context.h" +#include "preferences.h" +#include "ui/tool/control-point.h" +#include "ui/tool/event-utils.h" +#include "ui/tool/selector.h" + +namespace Inkscape { +namespace UI { + +/** A hidden control point used for rubberbanding and selection. + * It uses a clever hack: the canvas item is hidden and only receives events when fed */ +class SelectorPoint : public ControlPoint { +public: + SelectorPoint(SPDesktop *d, SPCanvasGroup *group, Selector *s) + : ControlPoint(d, Geom::Point(0,0), Gtk::ANCHOR_CENTER, SP_CTRL_SHAPE_SQUARE, + 1, &invisible_cset, group) + , _selector(s) + , _cancel(false) + { + setVisible(false); + _rubber = static_cast(sp_canvas_item_new(sp_desktop_controls(_desktop), + SP_TYPE_CTRLRECT, NULL)); + sp_canvas_item_hide(_rubber); + + signal_clicked.connect(sigc::mem_fun(*this, &SelectorPoint::_clicked)); + signal_grabbed.connect( + sigc::bind_return( + sigc::hide( + sigc::mem_fun(*this, &SelectorPoint::_grabbed)), + false)); + signal_dragged.connect( + sigc::hide<0>( sigc::hide( + sigc::mem_fun(*this, &SelectorPoint::_dragged)))); + signal_ungrabbed.connect(sigc::mem_fun(*this, &SelectorPoint::_ungrabbed)); + } + ~SelectorPoint() { + gtk_object_destroy(_rubber); + } + SPDesktop *desktop() { return _desktop; } + bool event(GdkEvent *e) { + return _eventHandler(e); + } + +protected: + virtual bool _eventHandler(GdkEvent *event) { + if (event->type == GDK_KEY_PRESS && shortcut_key(event->key) == GDK_Escape && + sp_canvas_item_is_visible(_rubber)) + { + _cancel = true; + sp_canvas_item_hide(_rubber); + return true; + } + return ControlPoint::_eventHandler(event); + } + +private: + bool _clicked(GdkEventButton *event) { + if (event->button != 1) return false; + _selector->signal_point.emit(position(), event); + return true; + } + void _grabbed() { + _cancel = false; + _start = position(); + sp_canvas_item_show(_rubber); + } + void _dragged(Geom::Point &new_pos) { + if (_cancel) return; + Geom::Rect sel(_start, new_pos); + _rubber->setRectangle(sel); + } + void _ungrabbed(GdkEventButton *event) { + if (_cancel) return; + sp_canvas_item_hide(_rubber); + Geom::Rect sel(_start, position()); + _selector->signal_area.emit(sel, event); + } + CtrlRect *_rubber; + Selector *_selector; + Geom::Point _start; + bool _cancel; +}; + + +Selector::Selector(SPDesktop *d) + : Manipulator(d) + , _dragger(new SelectorPoint(d, sp_desktop_controls(d), this)) +{ + _dragger->setVisible(false); +} + +Selector::~Selector() +{ + delete _dragger; +} + +bool Selector::event(GdkEvent *event) +{ + switch (event->type) { + case GDK_BUTTON_PRESS: + _dragger->setPosition(_desktop->w2d(event_point(event->motion))); + break; + default: break; + } + return _dragger->event(event); +} + +} // namespace UI +} // namespace Inkscape + +/* + 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:encoding=utf-8:textwidth=99 : -- cgit v1.2.3 From d85c1f7df8f884e92a362e6f1dec34c2479cbfd4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 20 Jan 2010 17:37:55 +0100 Subject: Fix middle click zoom in the node tool. (bzr r9004) --- src/ui/tool/selector.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/ui/tool/selector.cpp') diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp index f95c9e064..bf3ea6714 100644 --- a/src/ui/tool/selector.cpp +++ b/src/ui/tool/selector.cpp @@ -21,7 +21,9 @@ namespace Inkscape { namespace UI { /** A hidden control point used for rubberbanding and selection. - * It uses a clever hack: the canvas item is hidden and only receives events when fed */ + * It uses a clever hack: the canvas item is hidden and only receives events when they + * are passed to it using Selector's event() function. When left mouse button + * is pressed, it grabs events and handles drags and clicks in the usual way. */ class SelectorPoint : public ControlPoint { public: SelectorPoint(SPDesktop *d, SPCanvasGroup *group, Selector *s) @@ -109,8 +111,14 @@ Selector::~Selector() bool Selector::event(GdkEvent *event) { + // The hidden control point will capture all events after it obtains the grab, + // but it relies on this function to initiate it. Here we can filter what events + // it will receive. switch (event->type) { case GDK_BUTTON_PRESS: + // Do not pass button presses other than left button to the control point. + // This way middle click and right click can be handled in SPEventContext. + if (event->button.button != 1) return false; _dragger->setPosition(_desktop->w2d(event_point(event->motion))); break; default: break; -- cgit v1.2.3 From 7ce8847f2410a24a6bce4ca8a43ad7ebdb4839eb Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 4 Feb 2010 03:14:09 +0100 Subject: Reduce libsigc++ usage to partially fix performance regressions in the new node tool. (bzr r9044) --- src/ui/tool/selector.cpp | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'src/ui/tool/selector.cpp') diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp index bf3ea6714..8d3cf5650 100644 --- a/src/ui/tool/selector.cpp +++ b/src/ui/tool/selector.cpp @@ -36,17 +36,6 @@ public: _rubber = static_cast(sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRLRECT, NULL)); sp_canvas_item_hide(_rubber); - - signal_clicked.connect(sigc::mem_fun(*this, &SelectorPoint::_clicked)); - signal_grabbed.connect( - sigc::bind_return( - sigc::hide( - sigc::mem_fun(*this, &SelectorPoint::_grabbed)), - false)); - signal_dragged.connect( - sigc::hide<0>( sigc::hide( - sigc::mem_fun(*this, &SelectorPoint::_dragged)))); - signal_ungrabbed.connect(sigc::mem_fun(*this, &SelectorPoint::_ungrabbed)); } ~SelectorPoint() { gtk_object_destroy(_rubber); @@ -69,27 +58,28 @@ protected: } private: - bool _clicked(GdkEventButton *event) { - if (event->button != 1) return false; - _selector->signal_point.emit(position(), event); - return true; - } - void _grabbed() { + virtual bool grabbed(GdkEventMotion *) { _cancel = false; _start = position(); sp_canvas_item_show(_rubber); + return false; } - void _dragged(Geom::Point &new_pos) { + virtual void dragged(Geom::Point &new_pos, GdkEventMotion *) { if (_cancel) return; Geom::Rect sel(_start, new_pos); _rubber->setRectangle(sel); } - void _ungrabbed(GdkEventButton *event) { + virtual void ungrabbed(GdkEventButton *event) { if (_cancel) return; sp_canvas_item_hide(_rubber); Geom::Rect sel(_start, position()); _selector->signal_area.emit(sel, event); } + virtual bool clicked(GdkEventButton *event) { + if (event->button != 1) return false; + _selector->signal_point.emit(position(), event); + return true; + } CtrlRect *_rubber; Selector *_selector; Geom::Point _start; -- cgit v1.2.3 From aef0b601b6f7aa1cac25272afca788fa35805070 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Mon, 8 Feb 2010 17:07:50 +0100 Subject: Really fix middle click zoom in the node tool. (bzr r9067) --- src/ui/tool/selector.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/ui/tool/selector.cpp') diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp index 8d3cf5650..a30f96025 100644 --- a/src/ui/tool/selector.cpp +++ b/src/ui/tool/selector.cpp @@ -108,12 +108,14 @@ bool Selector::event(GdkEvent *event) case GDK_BUTTON_PRESS: // Do not pass button presses other than left button to the control point. // This way middle click and right click can be handled in SPEventContext. - if (event->button.button != 1) return false; - _dragger->setPosition(_desktop->w2d(event_point(event->motion))); + if (event->button.button == 1) { + _dragger->setPosition(_desktop->w2d(event_point(event->motion))); + return _dragger->event(event); + } break; default: break; } - return _dragger->event(event); + return false; } } // namespace UI -- cgit v1.2.3 From 81f88ca0856da56bdf426cd065ff0acd3414567f Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 9 Feb 2010 03:20:18 +0100 Subject: Fix multiple minor problems in the node tool (bzr r9070) --- src/ui/tool/selector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/tool/selector.cpp') diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp index a30f96025..d766d5be3 100644 --- a/src/ui/tool/selector.cpp +++ b/src/ui/tool/selector.cpp @@ -102,8 +102,8 @@ Selector::~Selector() bool Selector::event(GdkEvent *event) { // The hidden control point will capture all events after it obtains the grab, - // but it relies on this function to initiate it. Here we can filter what events - // it will receive. + // but it relies on this function to initiate it. If we pass only first button + // press events here, it won't interfere with any other event handling. switch (event->type) { case GDK_BUTTON_PRESS: // Do not pass button presses other than left button to the control point. -- cgit v1.2.3