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"
25 #include "snap-candidate.h"
27 class SPDesktop;
28 struct SPCanvasGroup;
30 namespace Inkscape {
31 namespace UI {
32 class TransformHandleSet;
33 class SelectableControlPoint;
34 }
35 }
37 namespace Inkscape {
38 namespace UI {
40 class ControlPointSelection : public Manipulator, public sigc::trackable {
41 public:
42 ControlPointSelection(SPDesktop *d, SPCanvasGroup *th_group);
43 ~ControlPointSelection();
44 typedef INK_UNORDERED_SET<SelectableControlPoint *> set_type;
45 typedef set_type Set; // convenience alias
47 typedef set_type::iterator iterator;
48 typedef set_type::const_iterator const_iterator;
49 typedef set_type::size_type size_type;
50 typedef SelectableControlPoint *value_type;
51 typedef SelectableControlPoint *key_type;
53 // size
54 bool empty() { return _points.empty(); }
55 size_type size() { return _points.size(); }
57 // iterators
58 iterator begin() { return _points.begin(); }
59 const_iterator begin() const { return _points.begin(); }
60 iterator end() { return _points.end(); }
61 const_iterator end() const { return _points.end(); }
63 // insert
64 std::pair<iterator, bool> insert(const value_type& x);
65 template <class InputIterator>
66 void insert(InputIterator first, InputIterator last) {
67 for (; first != last; ++first) {
68 insert(*first);
69 }
70 }
72 // erase
73 void clear();
74 void erase(iterator pos);
75 size_type erase(const key_type& k);
76 void erase(iterator first, iterator last);
78 // find
79 iterator find(const key_type &k) {
80 return _points.find(k);
81 }
83 // Sometimes it is very useful to keep a list of all selectable points.
84 set_type const &allPoints() const { return _all_points; }
85 set_type &allPoints() { return _all_points; }
86 // ...for example in these methods. Another useful case is snapping.
87 void selectAll();
88 void selectArea(Geom::Rect const &);
89 void invertSelection();
90 void spatialGrow(SelectableControlPoint *origin, int dir);
92 virtual bool event(GdkEvent *);
94 void transform(Geom::Matrix const &m);
95 void align(Geom::Dim2 d);
96 void distribute(Geom::Dim2 d);
98 Geom::OptRect pointwiseBounds();
99 Geom::OptRect bounds();
101 bool transformHandlesEnabled() { return _handles_visible; }
102 void showTransformHandles(bool v, bool one_node);
103 // the two methods below do not modify the state; they are for use in manipulators
104 // that need to temporarily hide the handles, for example when moving a node
105 void hideTransformHandles();
106 void restoreTransformHandles();
107 void toggleTransformHandlesMode();
109 sigc::signal<void> signal_update;
110 sigc::signal<void, SelectableControlPoint *, bool> signal_point_changed;
111 sigc::signal<void, CommitEvent> signal_commit;
113 std::vector<Inkscape::SnapCandidatePoint> getOriginalPoints();
114 void setOriginalPoints();
116 private:
117 // The functions below are invoked from SelectableControlPoint.
118 // Previously they were connected to handlers when selecting, but this
119 // creates problems when dragging a point that was not selected.
120 void _pointGrabbed(SelectableControlPoint *);
121 void _pointDragged(Geom::Point &, GdkEventMotion *);
122 void _pointUngrabbed();
123 bool _pointClicked(SelectableControlPoint *, GdkEventButton *);
124 void _pointChanged(SelectableControlPoint *, bool);
125 void _mouseoverChanged();
127 void _updateTransformHandles(bool preserve_center);
128 void _updateBounds();
129 bool _keyboardMove(GdkEventKey const &, Geom::Point const &);
130 bool _keyboardRotate(GdkEventKey const &, int);
131 bool _keyboardScale(GdkEventKey const &, int);
132 bool _keyboardFlip(Geom::Dim2);
133 void _keyboardTransform(Geom::Matrix const &);
134 void _commitHandlesTransform(CommitEvent ce);
135 double _rotationRadius(Geom::Point const &);
137 set_type _points;
138 set_type _all_points;
139 INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Point> _original_positions;
140 INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Matrix> _last_trans;
141 boost::optional<double> _rot_radius;
142 boost::optional<double> _mouseover_rot_radius;
143 Geom::OptRect _bounds;
144 TransformHandleSet *_handles;
145 SelectableControlPoint *_grabbed_point, *_farthest_point;
146 unsigned _dragging : 1;
147 unsigned _handles_visible : 1;
148 unsigned _one_node_handles : 1;
150 friend class SelectableControlPoint;
151 };
153 } // namespace UI
154 } // namespace Inkscape
156 #endif
158 /*
159 Local Variables:
160 mode:c++
161 c-file-style:"stroustrup"
162 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
163 indent-tabs-mode:nil
164 fill-column:99
165 End:
166 */
167 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :