Code

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