Code

f95c9e064b285296a3303b3d5f25a3bf5e8cb68e
[inkscape.git] / selector.cpp
1 /** @file
2  * Selector component (click and rubberband)
3  */
4 /* Authors:
5  *   Krzysztof KosiƄski <tweenk.pl@gmail.com>
6  *
7  * Copyright (C) 2009 Authors
8  * Released under GNU GPL, read the file 'COPYING' for more information
9  */
11 #include "desktop.h"
12 #include "desktop-handles.h"
13 #include "display/sodipodi-ctrlrect.h"
14 #include "event-context.h"
15 #include "preferences.h"
16 #include "ui/tool/control-point.h"
17 #include "ui/tool/event-utils.h"
18 #include "ui/tool/selector.h"
20 namespace Inkscape {
21 namespace UI {
23 /** A hidden control point used for rubberbanding and selection.
24  * It uses a clever hack: the canvas item is hidden and only receives events when fed */
25 class SelectorPoint : public ControlPoint {
26 public:
27     SelectorPoint(SPDesktop *d, SPCanvasGroup *group, Selector *s)
28         : ControlPoint(d, Geom::Point(0,0), Gtk::ANCHOR_CENTER, SP_CTRL_SHAPE_SQUARE,
29             1, &invisible_cset, group)
30         , _selector(s)
31         , _cancel(false)
32     {
33         setVisible(false);
34         _rubber = static_cast<CtrlRect*>(sp_canvas_item_new(sp_desktop_controls(_desktop),
35         SP_TYPE_CTRLRECT, NULL));
36         sp_canvas_item_hide(_rubber);
38         signal_clicked.connect(sigc::mem_fun(*this, &SelectorPoint::_clicked));
39         signal_grabbed.connect(
40             sigc::bind_return(
41                 sigc::hide(
42                     sigc::mem_fun(*this, &SelectorPoint::_grabbed)),
43                 false));
44         signal_dragged.connect(
45                 sigc::hide<0>( sigc::hide(
46                     sigc::mem_fun(*this, &SelectorPoint::_dragged))));
47         signal_ungrabbed.connect(sigc::mem_fun(*this, &SelectorPoint::_ungrabbed));
48     }
49     ~SelectorPoint() {
50         gtk_object_destroy(_rubber);
51     }
52     SPDesktop *desktop() { return _desktop; }
53     bool event(GdkEvent *e) {
54         return _eventHandler(e);
55     }
57 protected:
58     virtual bool _eventHandler(GdkEvent *event) {
59         if (event->type == GDK_KEY_PRESS && shortcut_key(event->key) == GDK_Escape &&
60             sp_canvas_item_is_visible(_rubber))
61         {
62             _cancel = true;
63             sp_canvas_item_hide(_rubber);
64             return true;
65         }
66         return ControlPoint::_eventHandler(event);
67     }
69 private:
70     bool _clicked(GdkEventButton *event) {
71         if (event->button != 1) return false;
72         _selector->signal_point.emit(position(), event);
73         return true;
74     }
75     void _grabbed() {
76         _cancel = false;
77         _start = position();
78         sp_canvas_item_show(_rubber);
79     }
80     void _dragged(Geom::Point &new_pos) {
81         if (_cancel) return;
82         Geom::Rect sel(_start, new_pos);
83         _rubber->setRectangle(sel);
84     }
85     void _ungrabbed(GdkEventButton *event) {
86         if (_cancel) return;
87         sp_canvas_item_hide(_rubber);
88         Geom::Rect sel(_start, position());
89         _selector->signal_area.emit(sel, event);
90     }
91     CtrlRect *_rubber;
92     Selector *_selector;
93     Geom::Point _start;
94     bool _cancel;
95 };
98 Selector::Selector(SPDesktop *d)
99     : Manipulator(d)
100     , _dragger(new SelectorPoint(d, sp_desktop_controls(d), this))
102     _dragger->setVisible(false);
105 Selector::~Selector()
107     delete _dragger;
110 bool Selector::event(GdkEvent *event)
112     switch (event->type) {
113     case GDK_BUTTON_PRESS:
114         _dragger->setPosition(_desktop->w2d(event_point(event->motion)));
115         break;
116     default: break;
117     }
118     return _dragger->event(event);
121 } // namespace UI
122 } // namespace Inkscape
124 /*
125   Local Variables:
126   mode:c++
127   c-file-style:"stroustrup"
128   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
129   indent-tabs-mode:nil
130   fill-column:99
131   End:
132 */
133 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :