index 0f0daffaa4cdb0143d8e546d03c80a9c86cd7209..8023c3e2884825f8eb28942ce110b0fe89c22f31 100644 (file)
/** @file
- * Node selection - stores a set of nodes and applies transformations
+ * Control point selection - stores a set of control points and applies transformations
* to them
*/
/* Authors:
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#ifndef SEEN_UI_TOOL_NODE_SELECTION_H
-#define SEEN_UI_TOOL_NODE_SELECTION_H
+#ifndef SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H
+#define SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H
#include <memory>
-#include <tr1/unordered_map>
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
#include <boost/optional.hpp>
#include <sigc++/sigc++.h>
#include <2geom/forward.h>
#include <2geom/point.h>
+#include <2geom/rect.h>
#include "display/display-forward.h"
#include "util/accumulators.h"
-#include "util/hash.h"
+#include "util/unordered-containers.h"
#include "ui/tool/commit-events.h"
#include "ui/tool/manipulator.h"
-namespace std { using namespace tr1; }
-
class SPDesktop;
namespace Inkscape {
namespace UI {
-
class TransformHandleSet;
class SelectableControlPoint;
+}
+}
+
+namespace Inkscape {
+namespace UI {
-class ControlPointSelection : public Manipulator {
+class ControlPointSelection : public Manipulator, public sigc::trackable {
public:
ControlPointSelection(SPDesktop *d, SPCanvasGroup *th_group);
~ControlPointSelection();
- typedef std::list<sigc::connection> connlist_type;
- typedef std::unordered_map< SelectableControlPoint *,
- boost::shared_ptr<connlist_type> > map_type;
-
- // boilerplate typedefs
- typedef map_type::iterator iterator;
- typedef map_type::const_iterator const_iterator;
- typedef map_type::size_type size_type;
+ typedef INK_UNORDERED_SET<SelectableControlPoint *> set_type;
+ typedef set_type Set; // convenience alias
+ typedef set_type::iterator iterator;
+ typedef set_type::const_iterator const_iterator;
+ typedef set_type::size_type size_type;
typedef SelectableControlPoint *value_type;
typedef SelectableControlPoint *key_type;
void erase(iterator first, iterator last);
// find
- iterator find(const key_type &k) { return _points.find(k); }
+ iterator find(const key_type &k) {
+ return _points.find(k);
+ }
+
+ // Sometimes it is very useful to keep a list of all selectable points.
+ set_type const &allPoints() const { return _all_points; }
+ set_type &allPoints() { return _all_points; }
+ // ...for example in these methods. Another useful case is snapping.
+ void selectAll();
+ void selectArea(Geom::Rect const &);
+ void invertSelection();
+ void spatialGrow(SelectableControlPoint *origin, int dir);
virtual bool event(GdkEvent *);
Geom::OptRect pointwiseBounds();
Geom::OptRect bounds();
+ bool transformHandlesEnabled() { return _handles_visible; }
void showTransformHandles(bool v, bool one_node);
// the two methods below do not modify the state; they are for use in manipulators
- // that need to temporarily hide the handles
+ // that need to temporarily hide the handles, for example when moving a node
void hideTransformHandles();
void restoreTransformHandles();
-
- // TODO this is really only applicable to nodes... maybe derive a NodeSelection?
- void setSculpting(bool v) { _sculpt_enabled = v; }
+ void toggleTransformHandlesMode();
sigc::signal<void> signal_update;
sigc::signal<void, SelectableControlPoint *, bool> signal_point_changed;
sigc::signal<void, CommitEvent> signal_commit;
private:
- void _selectionGrabbed(SelectableControlPoint *, GdkEventMotion *);
- void _selectionDragged(Geom::Point const &, Geom::Point &, GdkEventMotion *);
- void _selectionUngrabbed();
+ // The functions below are invoked from SelectableControlPoint.
+ // Previously they were connected to handlers when selecting, but this
+ // creates problems when dragging a point that was not selected.
+ void _pointGrabbed(SelectableControlPoint *);
+ void _pointDragged(Geom::Point &, GdkEventMotion *);
+ void _pointUngrabbed();
+ bool _pointClicked(SelectableControlPoint *, GdkEventButton *);
+ void _pointChanged(SelectableControlPoint *, bool);
+ void _mouseoverChanged();
+
void _updateTransformHandles(bool preserve_center);
+ void _updateBounds();
bool _keyboardMove(GdkEventKey const &, Geom::Point const &);
bool _keyboardRotate(GdkEventKey const &, int);
bool _keyboardScale(GdkEventKey const &, int);
bool _keyboardFlip(Geom::Dim2);
void _keyboardTransform(Geom::Matrix const &);
- void _commitTransform(CommitEvent ce);
- map_type _points;
+ void _commitHandlesTransform(CommitEvent ce);
+ double _rotationRadius(Geom::Point const &);
+
+ set_type _points;
+ set_type _all_points;
+ INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Point> _original_positions;
+ INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Matrix> _last_trans;
boost::optional<double> _rot_radius;
+ boost::optional<double> _mouseover_rot_radius;
+ Geom::OptRect _bounds;
TransformHandleSet *_handles;
- SelectableControlPoint *_grabbed_point;
+ SelectableControlPoint *_grabbed_point, *_farthest_point;
unsigned _dragging : 1;
unsigned _handles_visible : 1;
unsigned _one_node_handles : 1;
- unsigned _sculpt_enabled : 1;
- unsigned _sculpting : 1;
+
+ friend class SelectableControlPoint;
};
} // namespace UI