4de5e58475b667e365d55f5630c8c46b28595992
1 /** @file
2 * Desktop-bound visual control object
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 #ifndef SEEN_UI_TOOL_CONTROL_POINT_H
12 #define SEEN_UI_TOOL_CONTROL_POINT_H
14 #include <boost/utility.hpp>
15 #include <sigc++/sigc++.h>
16 #include <gdkmm.h>
17 #include <gtkmm.h>
18 #include <2geom/point.h>
20 #include "display/display-forward.h"
21 #include "forward.h"
22 #include "util/accumulators.h"
23 #include "display/sodipodi-ctrl.h"
25 namespace Inkscape {
26 namespace UI {
28 // most of the documentation is in the .cpp file
30 class ControlPoint : boost::noncopyable, public sigc::trackable {
31 public:
32 typedef Inkscape::Util::ReverseInterruptible RInt;
33 typedef Inkscape::Util::Interruptible Int;
34 // these have to be public, because GCC doesn't allow protected types in constructors,
35 // even if the constructors are protected themselves.
36 struct ColorEntry {
37 guint32 fill;
38 guint32 stroke;
39 };
40 struct ColorSet {
41 ColorEntry normal;
42 ColorEntry mouseover;
43 ColorEntry clicked;
44 };
45 enum State {
46 STATE_NORMAL,
47 STATE_MOUSEOVER,
48 STATE_CLICKED
49 };
51 virtual ~ControlPoint();
53 /// @name Adjust the position of the control point
54 /// @{
55 /** Current position of the control point. */
56 Geom::Point const &position() const { return _position; }
57 operator Geom::Point const &() { return _position; }
58 virtual void move(Geom::Point const &pos);
59 virtual void setPosition(Geom::Point const &pos);
60 virtual void transform(Geom::Matrix const &m);
61 /// @}
63 /// @name Toggle the point's visibility
64 /// @{
65 bool visible() const;
66 virtual void setVisible(bool v);
67 /// @}
69 /// @name Transfer grab from another event handler
70 /// @{
71 void transferGrab(ControlPoint *from, GdkEventMotion *event);
72 /// @}
74 /// @name Receive notifications about control point events
75 /// @{
76 /*sigc::signal<void, Geom::Point const &, Geom::Point &, GdkEventMotion*> signal_dragged;
77 sigc::signal<bool, GdkEventButton*>::accumulated<RInt> signal_clicked;
78 sigc::signal<bool, GdkEventButton*>::accumulated<RInt> signal_doubleclicked;
79 sigc::signal<bool, GdkEventMotion*>::accumulated<Int> signal_grabbed;
80 sigc::signal<void, GdkEventButton*> signal_ungrabbed;*/
81 /// @}
83 /// @name Inspect the state of the control point
84 /// @{
85 State state() { return _state; }
86 bool mouseovered() { return this == mouseovered_point; }
87 /// @}
89 static ControlPoint *mouseovered_point;
90 static sigc::signal<void, ControlPoint*> signal_mouseover_change;
91 static Glib::ustring format_tip(char const *format, ...) G_GNUC_PRINTF(1,2);
93 // temporarily public, until snap delay is refactored a little
94 virtual bool _eventHandler(GdkEvent *event);
96 protected:
97 ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, Gtk::AnchorType anchor,
98 SPCtrlShapeType shape, unsigned int size, ColorSet *cset = 0, SPCanvasGroup *group = 0);
99 ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, Gtk::AnchorType anchor,
100 Glib::RefPtr<Gdk::Pixbuf> pixbuf, ColorSet *cset = 0, SPCanvasGroup *group = 0);
102 /// @name Handle control point events in subclasses
103 /// @{
104 /**
105 * Called when the user moves the point beyond the drag tolerance with the first button held
106 * down. Return true if you called transferGrab() during this method.
107 * @param event Motion event when drag tolerance was exceeded */
108 virtual bool grabbed(GdkEventMotion *event);
109 /**
110 * Called while dragging, but before moving the knot to new position.
111 * @param pos Old position, always equal to position()
112 * @param new_pos New position (after drag). This is passed as a non-const reference,
113 * so you can change it from the handler - that's how constrained dragging is implemented.
114 * @param event Motion event */
115 virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event);
116 /**
117 * @var ControlPoint::signal_ungrabbed
118 * Emitted when the control point finishes a drag.
119 * @param event Button release event
120 */
121 virtual void ungrabbed(GdkEventButton *event);
122 /**
123 * Called when the control point is clicked, at mouse button release. Your override should
124 * return true if the click had some effect. If it did nothing, return false. Improperly
125 * implementing this method can cause the default context menu not to appear when a control
126 * point is right-clicked.
127 * @param event Button release event */
128 virtual bool clicked(GdkEventButton *event);
129 /**
130 * Called when the control point is doubleclicked, at mouse button release.
131 * @param event Button release event */
132 virtual bool doubleclicked(GdkEventButton *);
133 /// @}
135 /// @name Manipulate the control point's appearance in subclasses
136 /// @{
137 virtual void _setState(State state);
138 void _setColors(ColorEntry c);
140 unsigned int _size() const;
141 SPCtrlShapeType _shape() const;
142 GtkAnchorType _anchor() const;
143 Glib::RefPtr<Gdk::Pixbuf> _pixbuf();
145 void _setSize(unsigned int size);
146 void _setShape(SPCtrlShapeType shape);
147 void _setAnchor(GtkAnchorType anchor);
148 void _setPixbuf(Glib::RefPtr<Gdk::Pixbuf>);
149 /// @}
151 virtual Glib::ustring _getTip(unsigned /*state*/) { return ""; }
152 virtual Glib::ustring _getDragTip(GdkEventMotion */*event*/) { return ""; }
153 virtual bool _hasDragTips() { return false; }
155 SPDesktop *const _desktop; ///< The desktop this control point resides on.
156 SPCanvasItem * _canvas_item; ///< Visual representation of the control point.
157 ColorSet *_cset; ///< Colors used to represent the point
158 State _state;
160 static int const _grab_event_mask;
161 static Geom::Point const &_last_click_event_point() { return _drag_event_origin; }
162 static Geom::Point const &_last_drag_origin() { return _drag_origin; }
164 private:
165 ControlPoint(ControlPoint const &other);
166 void operator=(ControlPoint const &other);
168 static int _event_handler(SPCanvasItem *item, GdkEvent *event, ControlPoint *point);
169 static void _setMouseover(ControlPoint *, unsigned state);
170 static void _clearMouseover();
171 bool _updateTip(unsigned state);
172 bool _updateDragTip(GdkEventMotion *event);
173 void _setDefaultColors();
174 void _commonInit();
176 Geom::Point _position; ///< Current position in desktop coordinates
177 gulong _event_handler_connection;
179 static Geom::Point _drag_event_origin;
180 static Geom::Point _drag_origin;
181 static bool _event_grab;
182 static bool _drag_initiated;
183 };
185 extern ControlPoint::ColorSet invisible_cset;
188 } // namespace UI
189 } // namespace Inkscape
191 #endif
193 /*
194 Local Variables:
195 mode:c++
196 c-file-style:"stroustrup"
197 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
198 indent-tabs-mode:nil
199 fill-column:99
200 End:
201 */
202 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :