Code

6a5b05e853592dbcde34c3f94f6a337c43c552bd
[inkscape.git] / src / ui / tool / control-point-selection.h
1 /** @file
2  * Control point selection - stores a set of control points and applies transformations
3  * to them
4  */
5 /* Authors:
6  *   Krzysztof KosiƄski <tweenk.pl@gmail.com>
7  *
8  * Copyright (C) 2009 Authors
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #ifndef SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H
13 #define SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H
15 #include <memory>
16 #include <boost/optional.hpp>
17 #include <sigc++/sigc++.h>
18 #include <2geom/forward.h>
19 #include <2geom/point.h>
20 #include <2geom/rect.h>
21 #include "util/accumulators.h"
22 #include "util/unordered-containers.h"
23 #include "ui/tool/commit-events.h"
24 #include "ui/tool/manipulator.h"
26 class SPDesktop;
27 struct SPCanvasGroup;
29 namespace Inkscape {
30 namespace UI {
31 class TransformHandleSet;
32 class SelectableControlPoint;
33 }
34 }
36 namespace Inkscape {
37 namespace UI {
39 class ControlPointSelection : public Manipulator, public sigc::trackable {
40 public:
41     ControlPointSelection(SPDesktop *d, SPCanvasGroup *th_group);
42     ~ControlPointSelection();
43     typedef INK_UNORDERED_SET<SelectableControlPoint *> set_type;
44     typedef set_type Set; // convenience alias
46     typedef set_type::iterator iterator;
47     typedef set_type::const_iterator const_iterator;
48     typedef set_type::size_type size_type;
49     typedef SelectableControlPoint *value_type;
50     typedef SelectableControlPoint *key_type;
52     // size
53     bool empty() { return _points.empty(); }
54     size_type size() { return _points.size(); }
56     // iterators
57     iterator begin() { return _points.begin(); }
58     const_iterator begin() const { return _points.begin(); }
59     iterator end() { return _points.end(); }
60     const_iterator end() const { return _points.end(); }
62     // insert
63     std::pair<iterator, bool> insert(const value_type& x);
64     template <class InputIterator>
65     void insert(InputIterator first, InputIterator last) {
66         for (; first != last; ++first) {
67             insert(*first);
68         }
69     }
71     // erase
72     void clear();
73     void erase(iterator pos);
74     size_type erase(const key_type& k);
75     void erase(iterator first, iterator last);
77     // find
78     iterator find(const key_type &k) {
79         return _points.find(k);
80     }
82     // Sometimes it is very useful to keep a list of all selectable points.
83     set_type const &allPoints() const { return _all_points; }
84     set_type &allPoints() { return _all_points; }
85     // ...for example in these methods. Another useful case is snapping.
86     void selectAll();
87     void selectArea(Geom::Rect const &);
88     void invertSelection();
89     void spatialGrow(SelectableControlPoint *origin, int dir);
91     virtual bool event(GdkEvent *);
93     void transform(Geom::Matrix const &m);
94     void align(Geom::Dim2 d);
95     void distribute(Geom::Dim2 d);
97     Geom::OptRect pointwiseBounds();
98     Geom::OptRect bounds();
100     bool transformHandlesEnabled() { return _handles_visible; }
101     void showTransformHandles(bool v, bool one_node);
102     // the two methods below do not modify the state; they are for use in manipulators
103     // that need to temporarily hide the handles, for example when moving a node
104     void hideTransformHandles();
105     void restoreTransformHandles();
106     void toggleTransformHandlesMode();
108     sigc::signal<void> signal_update;
109     sigc::signal<void, SelectableControlPoint *, bool> signal_point_changed;
110     sigc::signal<void, CommitEvent> signal_commit;
111 private:
112     // The functions below are invoked from SelectableControlPoint.
113     // Previously they were connected to handlers when selecting, but this
114     // creates problems when dragging a point that was not selected.
115     void _pointGrabbed(SelectableControlPoint *);
116     void _pointDragged(Geom::Point &, GdkEventMotion *);
117     void _pointUngrabbed();
118     bool _pointClicked(SelectableControlPoint *, GdkEventButton *);
119     void _pointChanged(SelectableControlPoint *, bool);
120     void _mouseoverChanged();
122     void _updateTransformHandles(bool preserve_center);
123     void _updateBounds();
124     bool _keyboardMove(GdkEventKey const &, Geom::Point const &);
125     bool _keyboardRotate(GdkEventKey const &, int);
126     bool _keyboardScale(GdkEventKey const &, int);
127     bool _keyboardFlip(Geom::Dim2);
128     void _keyboardTransform(Geom::Matrix const &);
129     void _commitHandlesTransform(CommitEvent ce);
130     double _rotationRadius(Geom::Point const &);
132     set_type _points;
133     set_type _all_points;
134     INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Point> _original_positions;
135     INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Matrix> _last_trans;
136     boost::optional<double> _rot_radius;
137     boost::optional<double> _mouseover_rot_radius;
138     Geom::OptRect _bounds;
139     TransformHandleSet *_handles;
140     SelectableControlPoint *_grabbed_point, *_farthest_point;
141     unsigned _dragging         : 1;
142     unsigned _handles_visible  : 1;
143     unsigned _one_node_handles : 1;
145     friend class SelectableControlPoint;
146 };
148 } // namespace UI
149 } // namespace Inkscape
151 #endif
153 /*
154   Local Variables:
155   mode:c++
156   c-file-style:"stroustrup"
157   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
158   indent-tabs-mode:nil
159   fill-column:99
160   End:
161 */
162 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :