summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8416943)
raw | patch | inline | side by side (parent: 8416943)
author | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Thu, 4 Feb 2010 02:14:09 +0000 (03:14 +0100) | ||
committer | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Thu, 4 Feb 2010 02:14:09 +0000 (03:14 +0100) |
in the new node tool.
15 files changed:
index 615968fef2a68a205863bd95b37787f177ba1b9b..de19fef8d0268d47b37aa05f4603f8f3c6f1f260 100644 (file)
return std::pair<iterator, bool>(found, false);
}
- boost::shared_ptr<connlist_type> clist(new connlist_type());
-
- // hide event param and always return false
- clist->push_back(
- x->signal_grabbed.connect(
- sigc::bind_return(
- sigc::hide(
- sigc::mem_fun(*this, &ControlPointSelection::_pointGrabbed)),
- false)));
- clist->push_back(
- x->signal_dragged.connect(
- sigc::mem_fun(*this, &ControlPointSelection::_pointDragged)));
- clist->push_back(
- x->signal_ungrabbed.connect(
- sigc::hide(
- sigc::mem_fun(*this, &ControlPointSelection::_pointUngrabbed))));
- clist->push_back(
- x->signal_clicked.connect(
- sigc::bind<0>(
- sigc::mem_fun(*this, &ControlPointSelection::_pointClicked),
- x)));
-
- found = _points.insert(std::make_pair(x, clist)).first;
+ found = _points.insert(x).first;
x->updateState();
_rot_radius.reset();
@@ -112,11 +90,7 @@ std::pair<ControlPointSelection::iterator, bool> ControlPointSelection::insert(c
/** Remove a point from the selection. */
void ControlPointSelection::erase(iterator pos)
{
- SelectableControlPoint *erased = pos->first;
- boost::shared_ptr<connlist_type> clist = pos->second;
- for (connlist_type::iterator i = clist->begin(); i != clist->end(); ++i) {
- i->disconnect();
- }
+ SelectableControlPoint *erased = *pos;
_points.erase(pos);
erased->updateState();
_rot_radius.reset();
@@ -198,7 +172,7 @@ void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir)
void ControlPointSelection::transform(Geom::Matrix const &m)
{
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
+ SelectableControlPoint *cur = *i;
cur->transform(m);
}
// TODO preserving the rotation radius needs some rethinking...
Geom::OptInterval bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- bound.unionWith(Geom::OptInterval(i->first->position()[d]));
+ bound.unionWith(Geom::OptInterval((*i)->position()[d]));
}
double new_coord = bound->middle();
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- Geom::Point pos = i->first->position();
+ Geom::Point pos = (*i)->position();
pos[d] = new_coord;
- i->first->move(pos);
+ (*i)->move(pos);
}
}
// first we insert all points into a multimap keyed by the aligned coord to sort them
// simultaneously we compute the extent of selection
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- Geom::Point pos = i->first->position();
- sm.insert(std::make_pair(pos[d], i->first));
+ Geom::Point pos = (*i)->position();
+ sm.insert(std::make_pair(pos[d], (*i)));
bound.unionWith(Geom::OptInterval(pos[d]));
}
{
Geom::OptRect bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
+ SelectableControlPoint *cur = (*i);
Geom::Point p = cur->position();
if (!bound) {
bound = Geom::Rect(p, p);
{
Geom::OptRect bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
+ SelectableControlPoint *cur = (*i);
Geom::OptRect r = cur->bounds();
bound.unionWith(r);
}
@@ -320,7 +294,7 @@ void ControlPointSelection::_pointDragged(Geom::Point const &old_pos, Geom::Poin
{
Geom::Point delta = new_pos - old_pos;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
+ SelectableControlPoint *cur = (*i);
cur->move(cur->position() + delta);
}
_handles->rotationCenter().move(_handles->rotationCenter().position() + delta);
_handles->setBounds(*b, preserve_center);
_handles->setVisible(true);
} else if (_one_node_handles && size() == 1) { // only one control point in selection
- SelectableControlPoint *p = begin()->first;
+ SelectableControlPoint *p = *begin();
_handles->setBounds(p->bounds());
_handles->rotationCenter().move(p->position());
_handles->rotationCenter().setVisible(false);
index 54d724f00062a74ff727f32c64457103a6ff090c..025f9bb618be83927473a0e942c4f1396969ec9d 100644 (file)
ControlPointSelection(SPDesktop *d, SPCanvasGroup *th_group);
~ControlPointSelection();
typedef std::list<sigc::connection> connlist_type;
- typedef std::tr1::unordered_map< SelectableControlPoint *,
- boost::shared_ptr<connlist_type> > map_type;
typedef std::tr1::unordered_set< SelectableControlPoint * > set_type;
typedef set_type Set; // convenience alias
- typedef map_type::iterator iterator;
- typedef map_type::const_iterator const_iterator;
- typedef map_type::size_type size_type;
+ 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;
bool _keyboardFlip(Geom::Dim2);
void _keyboardTransform(Geom::Matrix const &);
void _commitTransform(CommitEvent ce);
- map_type _points;
+ set_type _points;
set_type _all_points;
boost::optional<double> _rot_radius;
TransformHandleSet *_handles;
index 941924e0a73041324021e5712df03d1170d397c7..2eaddc6b4f57a4afcc671df372c8f1c7dc9b3c2f 100644 (file)
* point in the drawing. The drawing can be changed by dragging the point and the things that are
* attached to it with the mouse. Example things that could be edited with draggable points
* are gradient stops, the place where text is attached to a path, text kerns, nodes and handles
- * in a path, and many more. Control points use signals heavily - <b>read the libsigc++
- * tutorial on the wiki</b> before using this class.</b>
+ * in a path, and many more.
*
- * @par Control point signals
+ * @par Control point event handlers
* @par
- * The control point has several signals which allow you to react to things that happen to it.
- * The most important singals are the grabbed, dragged, ungrabbed and moved signals.
- * When a drag happens, the order of emission is as follows:
- * - <tt>signal_grabbed</tt>
- * - <tt>signal_dragged</tt>
- * - <tt>signal_dragged</tt>
- * - <tt>signal_dragged</tt>
+ * The control point has several virtual methods which allow you to react to things that
+ * happen to it. The most important ones are the grabbed, dragged, ungrabbed and moved functions.
+ * When a drag happens, the order of calls is as follows:
+ * - <tt>grabbed()</tt>
+ * - <tt>dragged()</tt>
+ * - <tt>dragged()</tt>
+ * - <tt>dragged()</tt>
* - ...
- * - <tt>signal_dragged</tt>
- * - <tt>signal_ungrabbed</tt>
+ * - <tt>dragged()</tt>
+ * - <tt>ungrabbed()</tt>
*
* The control point can also respond to clicks and double clicks. On a double click,
- * <tt>signal_clicked</tt> is emitted, followed by <tt>signal_doubleclicked</tt>.
- *
- * A few signal usage hints if you can't be bothered to read the tutorial:
- * - If you want some other object or a global function to react to signals of a control point
- * from some other object, and you want to access the control point that emitted the signal
- * in the handler, use <tt>sigc::bind</tt> like this:
- * @code
- * void handle_clicked_signal(ControlPoint *point, int button);
- * point->signal_clicked.connect(
- * sigc::bind<0>( sigc::ptr_fun(handle_clicked_signal),
- * point ));
- * @endcode
- * - You can ignore unneeded parameters using sigc::hide.
- * - If you want to get rid of the handlers added by constructors in superclasses,
- * use the <tt>clear()</tt> method: @code signal_clicked.clear(); @endcode
- * - To connect at the front of the slot list instead of at the end, use:
- * @code
- * signal_clicked.slots().push_front(
- * sigc::mem_fun(*this, &FunkyPoint::_clickedHandler));
- * @endcode
- * - Note that calling <tt>slots()</tt> does not copy anything. You can disconnect
- * and reorder slots by manipulating the elements of the slot list. The returned object is
- * of type @verbatim (signal type)::slot_list @endverbatim.
+ * clicked() is called, followed by doubleclicked(). When deriving from SelectableControlPoint,
+ * you need to manually call the superclass version at the appropriate point in your handler.
*
* @par Which method to override?
* @par
* the setPosition() method.
*/
-/**
- * @var ControlPoint::signal_dragged
- * Emitted while dragging, but before moving the knot to new position.
- * Old position will always be the same as position() - there are two parameters
- * only for convenience.
- * - First parameter: old position, always equal to position()
- * - Second parameter: new position (after drag). This is passed as a non-const reference,
- * so you can change it from the handler - that's how constrained dragging is implemented.
- * - Third parameter: motion event
- */
-
-/**
- * @var ControlPoint::signal_clicked
- * Emitted when the control point is clicked, at mouse button release. The parameter contains
- * the event that caused the signal to be emitted. Your signal handler should return true
- * if the click had some effect. If it did nothing, return false. Improperly handling this signal
- * can cause the context menu not to appear when a control point is right-clicked.
- */
-
-/**
- * @var ControlPoint::signal_doubleclicked
- * Emitted when the control point is doubleclicked, at mouse button release. The parameter
- * contains the event that caused the signal to be emitted. Your signal handler should return true
- * if the double click had some effect. If it did nothing, return false.
- */
-
-/**
- * @var ControlPoint::signal_grabbed
- * Emitted when the control point is grabbed and a drag starts. The parameter contains
- * the causing event. Return true to prevent further processing. Because all control points
- * handle drag tolerance, <tt>signal_dragged</tt> will be emitted immediately after this signal
- * to move the point to its new position.
- */
-
-/**
- * @var ControlPoint::signal_ungrabbed
- * Emitted when the control point finishes a drag. The parameter contains the event which
- * caused the signal, but it can be NULL if the grab was broken.
- */
-
/**
* @enum ControlPoint::State
* Enumeration representing the possible states of the control point, used to determine
void ControlPoint::_commonInit()
{
+ SP_CTRL(_canvas_item)->moveto(_position);
_event_handler_connection = g_signal_connect(G_OBJECT(_canvas_item), "event",
G_CALLBACK(_event_handler), this);
- SP_CTRL(_canvas_item)->moveto(_position);
}
/** Relocate the control point without side effects.
// if we are here, it means the tolerance was just exceeded.
next_release_doubleclick = 0;
_drag_origin = _position;
- transferred = signal_grabbed.emit(&event->motion);
- // _drag_initiated might change during the above signal emission
+ transferred = grabbed(&event->motion);
+ // _drag_initiated might change during the above virtual call
if (!_drag_initiated) {
// this guarantees smooth redraws while dragging
sp_canvas_force_full_redraw_after_interruptions(_desktop->canvas, 5);
Geom::Point new_pos = _desktop->w2d(event_point(event->motion)) + pointer_offset;
// the new position is passed by reference and can be changed in the handlers.
- signal_dragged.emit(_position, new_pos, &event->motion);
+ dragged(new_pos, &event->motion);
move(new_pos);
_updateDragTip(&event->motion); // update dragging tip after moving to new position
if (event->button.button == next_release_doubleclick) {
_drag_initiated = false;
- return signal_doubleclicked.emit(&event->button);
+ return doubleclicked(&event->button);
}
if (event->button.button == 1) {
if (_drag_initiated) {
// it is the end of a drag
- signal_ungrabbed.emit(&event->button);
+ ungrabbed(&event->button);
_drag_initiated = false;
return true;
} else {
// it is the end of a click
- return signal_clicked.emit(&event->button);
+ return clicked(&event->button);
}
}
_drag_initiated = false;
case GDK_GRAB_BROKEN:
if (!event->grab_broken.keyboard && _event_grab) {
{
- signal_ungrabbed.emit(0);
+ ungrabbed(NULL);
if (_drag_initiated)
sp_canvas_end_forced_full_redraws(_desktop->canvas);
}
@@ -578,7 +516,7 @@ void ControlPoint::transferGrab(ControlPoint *prev_point, GdkEventMotion *event)
{
if (!_event_grab) return;
- signal_grabbed.emit(event);
+ grabbed(event);
sp_canvas_item_ungrab(prev_point->_canvas_item, event->time);
sp_canvas_item_grab(_canvas_item, _grab_event_mask, NULL, event->time);
g_object_set(_canvas_item, "fill_color", colors.fill, "stroke_color", colors.stroke, NULL);
}
+// dummy implementations for handlers
+// they are here to avoid unused param warnings
+bool ControlPoint::grabbed(GdkEventMotion *) { return false; }
+void ControlPoint::dragged(Geom::Point &, GdkEventMotion *) {}
+void ControlPoint::ungrabbed(GdkEventButton *) {}
+bool ControlPoint::clicked(GdkEventButton *) { return false; }
+bool ControlPoint::doubleclicked(GdkEventButton *) { return false; }
+
} // namespace UI
} // namespace Inkscape
index e59d6d5cfff64f9e09d9c21880a7b27c406973d1..48c70748b0f465f997089381f8e22feab7d1719d 100644 (file)
/// @name Receive notifications about control point events
/// @{
- sigc::signal<void, Geom::Point const &, Geom::Point &, GdkEventMotion*> signal_dragged;
+ /*sigc::signal<void, Geom::Point const &, Geom::Point &, GdkEventMotion*> signal_dragged;
sigc::signal<bool, GdkEventButton*>::accumulated<RInt> signal_clicked;
sigc::signal<bool, GdkEventButton*>::accumulated<RInt> signal_doubleclicked;
sigc::signal<bool, GdkEventMotion*>::accumulated<Int> signal_grabbed;
- sigc::signal<void, GdkEventButton*> signal_ungrabbed;
+ sigc::signal<void, GdkEventButton*> signal_ungrabbed;*/
/// @}
/// @name Inspect the state of the control point
static sigc::signal<void, ControlPoint*> signal_mouseover_change;
static Glib::ustring format_tip(char const *format, ...) G_GNUC_PRINTF(1,2);
- // temporarily public, until snapping is refactored a little
+ // temporarily public, until snap delay is refactored a little
virtual bool _eventHandler(GdkEvent *event);
protected:
ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, Gtk::AnchorType anchor,
Glib::RefPtr<Gdk::Pixbuf> pixbuf, ColorSet *cset = 0, SPCanvasGroup *group = 0);
+ /// @name Handle control point events in subclasses
+ /// @{
+ /**
+ * Called when the user moves the point beyond the drag tolerance with the first button held
+ * down. Return true if you called transferGrab() during this method.
+ * @param event Motion event when drag tolerance was exceeded */
+ virtual bool grabbed(GdkEventMotion *event);
+ /**
+ * Called while dragging, but before moving the knot to new position.
+ * @param pos Old position, always equal to position()
+ * @param new_pos New position (after drag). This is passed as a non-const reference,
+ * so you can change it from the handler - that's how constrained dragging is implemented.
+ * @param event Motion event */
+ virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event);
+ /**
+ * @var ControlPoint::signal_ungrabbed
+ * Emitted when the control point finishes a drag.
+ * @param event Button release event
+ */
+ virtual void ungrabbed(GdkEventButton *event);
+ /**
+ * Called when the control point is clicked, at mouse button release. Your override should
+ * return true if the click had some effect. If it did nothing, return false. Improperly
+ * implementing this method can cause the default context menu not to appear when a control
+ * point is right-clicked.
+ * @param event Button release event */
+ virtual bool clicked(GdkEventButton *event);
+ /**
+ * Called when the control point is doubleclicked, at mouse button release.
+ * @param event Button release event */
+ virtual bool doubleclicked(GdkEventButton *);
+ /// @}
+
/// @name Manipulate the control point's appearance in subclasses
/// @{
virtual void _setState(State state);
index 0e02761736cff695d269f13afbc9e78d5b1bd308..88cb72ed5698d8a952e0b1fac165ce71cea0054c 100644 (file)
, _pm(pm)
{
setVisible(false);
- signal_grabbed.connect(
- sigc::bind_return(
- sigc::mem_fun(*this, &CurveDragPoint::_grabbedHandler),
- false));
- signal_dragged.connect(
- sigc::hide(
- sigc::mem_fun(*this, &CurveDragPoint::_draggedHandler)));
- signal_ungrabbed.connect(
- sigc::hide(
- sigc::mem_fun(*this, &CurveDragPoint::_ungrabbedHandler)));
- signal_clicked.connect(
- sigc::mem_fun(*this, &CurveDragPoint::_clickedHandler));
- signal_doubleclicked.connect(
- sigc::mem_fun(*this, &CurveDragPoint::_doubleclickedHandler));
}
-void CurveDragPoint::_grabbedHandler(GdkEventMotion */*event*/)
+bool CurveDragPoint::grabbed(GdkEventMotion */*event*/)
{
_pm._selection.hideTransformHandles();
NodeList::iterator second = first.next();
first->front()->move(first->front()->position() + delta);
second->back()->move(second->back()->position() - delta);
- signal_update.emit();
+ _pm.update();
}
+ return false;
}
-void CurveDragPoint::_draggedHandler(Geom::Point const &old_pos, Geom::Point const &new_pos)
+void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *)
{
- if (_drags_stroke) {
- // TODO
- } else {
- NodeList::iterator second = first.next();
- // Magic Bezier Drag Equations follow!
- // "weight" describes how the influence of the drag should be distributed
- // among the handles; 0 = front handle only, 1 = back handle only.
- double weight, t = _t;
- if (t <= 1.0 / 6.0) weight = 0;
- else if (t <= 0.5) weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
- else if (t <= 5.0 / 6.0) weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
- else weight = 1;
-
- Geom::Point delta = new_pos - old_pos;
- Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
- Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta;
-
- first->front()->move(first->front()->position() + offset0);
- second->back()->move(second->back()->position() + offset1);
- }
-
- signal_update.emit();
+ NodeList::iterator second = first.next();
+ // Magic Bezier Drag Equations follow!
+ // "weight" describes how the influence of the drag should be distributed
+ // among the handles; 0 = front handle only, 1 = back handle only.
+ double weight, t = _t;
+ if (t <= 1.0 / 6.0) weight = 0;
+ else if (t <= 0.5) weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
+ else if (t <= 5.0 / 6.0) weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
+ else weight = 1;
+
+ Geom::Point delta = new_pos - position();
+ Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
+ Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta;
+
+ first->front()->move(first->front()->position() + offset0);
+ second->back()->move(second->back()->position() + offset1);
+
+ _pm.update();
}
-void CurveDragPoint::_ungrabbedHandler()
+void CurveDragPoint::ungrabbed(GdkEventButton *)
{
_pm._updateDragPoint(_desktop->d2w(position()));
_pm._commit(_("Drag curve"));
_pm._selection.restoreTransformHandles();
}
-bool CurveDragPoint::_clickedHandler(GdkEventButton *event)
+bool CurveDragPoint::clicked(GdkEventButton *event)
{
// This check is probably redundant
if (!first || event->button != 1) return false;
return true;
}
-bool CurveDragPoint::_doubleclickedHandler(GdkEventButton *event)
+bool CurveDragPoint::doubleclicked(GdkEventButton *event)
{
if (event->button != 1 || !first || !first.next()) return false;
_insertNode(true);
}
_pm._selection.insert(inserted.ptr());
- signal_update.emit();
+ _pm.update();
_pm._commit(_("Add node"));
}
index 51382615e74848291edcbd0bd206dc3cecc6ff17..147a918371c480dfe8f2153fdbc8c41bb38c5153 100644 (file)
void setSize(double sz) { _setSize(sz); }
void setTimeValue(double t) { _t = t; }
void setIterator(NodeList::iterator i) { first = i; }
- sigc::signal<void> signal_update;
protected:
virtual Glib::ustring _getTip(unsigned state);
private:
- void _grabbedHandler(GdkEventMotion *);
- void _draggedHandler(Geom::Point const &, Geom::Point const &);
- bool _clickedHandler(GdkEventButton *);
- bool _doubleclickedHandler(GdkEventButton *);
- void _ungrabbedHandler();
+ virtual void dragged(Geom::Point &, GdkEventMotion *);
+ virtual bool grabbed(GdkEventMotion *);
+ virtual void ungrabbed(GdkEventButton *);
+ virtual bool clicked(GdkEventButton *);
+ virtual bool doubleclicked(GdkEventButton *);
+
void _insertNode(bool take_selection);
double _t;
PathManipulator &_pm;
index d133fcf25fa05dc792cc77342ab1bb662402dfee..c34ef066e48d448a88ce52b642e1830e9315715e 100644 (file)
// find all endnodes in selection
for (ControlPointSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
- Node *node = dynamic_cast<Node*>(i->first);
+ Node *node = dynamic_cast<Node*>(*i);
if (!node) continue;
NodeList::iterator iter = NodeList::get_iterator(node);
if (!iter.next() || !iter.prev()) join_iters.insert(iter);
{
if (_selection.empty()) return;
for (ControlPointSelection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
- Node *node = dynamic_cast<Node*>(i->first);
+ Node *node = dynamic_cast<Node*>(*i);
if (node) node->setType(type);
}
_done(_("Change node type"));
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index 2675b4045f796a82c2d38429fafbc88c9a207cec..6419acf6d32e12bc842a43a9a14584035e7f7c1b 100644 (file)
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
_cset = &handle_colors;
_handle_line = sp_canvas_item_new(data.handle_line_group, SP_TYPE_CTRLLINE, NULL);
setVisible(false);
- signal_grabbed.connect(
- sigc::bind_return(
- sigc::hide(
- sigc::mem_fun(*this, &Handle::_grabbedHandler)),
- false));
- signal_dragged.connect(
- sigc::hide<0>(
- sigc::mem_fun(*this, &Handle::_draggedHandler)));
- signal_ungrabbed.connect(
- sigc::hide(sigc::mem_fun(*this, &Handle::_ungrabbedHandler)));
}
Handle::~Handle()
{
- sp_canvas_item_hide(_handle_line);
+ //sp_canvas_item_hide(_handle_line);
gtk_object_destroy(GTK_OBJECT(_handle_line));
}
}
}
-void Handle::_grabbedHandler()
+bool Handle::grabbed(GdkEventMotion *)
{
_saved_length = _drag_out ? 0 : length();
+ _pm()._handleGrabbed();
+ return false;
}
-void Handle::_draggedHandler(Geom::Point &new_pos, GdkEventMotion *event)
+void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
Geom::Point parent_pos = _parent->position();
// with Alt, preserve length
new_pos = parent_pos + Geom::constrain_angle(Geom::Point(0,0), new_pos - parent_pos, snaps,
_drag_out ? Geom::Point(1,0) : Geom::unit_vector(rel_origin));
}
- signal_update.emit();
+ _pm().update();
}
-void Handle::_ungrabbedHandler()
+void Handle::ungrabbed(GdkEventButton *)
{
// hide the handle if it's less than dragtolerance away from the node
+ // TODO is this actually desired?
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int drag_tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
move(_parent->position());
}
_drag_out = false;
+
+ _pm()._handleUngrabbed();
+}
+
+bool Handle::clicked(GdkEventButton *event)
+{
+ _pm()._handleClicked(this, event);
+ return true;
}
static double snap_increment_degrees() {
, _handles_shown(false)
{
// NOTE we do not set type here, because the handles are still degenerate
- // connect to own grabbed signal - dragging out handles
- signal_grabbed.connect(
- sigc::mem_fun(*this, &Node::_grabbedHandler));
- signal_dragged.connect( sigc::hide<0>(
- sigc::mem_fun(*this, &Node::_draggedHandler)));
}
// NOTE: not using iterators won't make this much quicker because iterators can be 100% inlined.
SelectableControlPoint::_setState(state);
}
-bool Node::_grabbedHandler(GdkEventMotion *event)
+bool Node::grabbed(GdkEventMotion *event)
{
+ if (SelectableControlPoint::grabbed(event))
+ return true;
+
// Dragging out handles with Shift + drag on a node.
if (!held_shift(*event)) return false;
return true;
}
-void Node::_draggedHandler(Geom::Point &new_pos, GdkEventMotion *event)
+void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
// For a note on how snapping is implemented in Inkscape, see snap.h.
SnapManager &sm = _desktop->namedview->snap_manager;
} else if (snap) {
sm.freeSnapReturnByRef(new_pos, _snapSourceType());
}
+
+ SelectableControlPoint::dragged(new_pos, event);
+}
+
+bool Node::clicked(GdkEventButton *event)
+{
+ if(_pm()._nodeClicked(this, event))
+ return true;
+ return SelectableControlPoint::clicked(event);
}
Inkscape::SnapSourceType Node::_snapSourceType()
ins->prev->next = x;
ins->prev = x;
x->ListNode::list = this;
- _list.signal_insert_node.emit(x);
return iterator(x);
}
@@ -1100,9 +1107,7 @@ void NodeList::splice(iterator pos, NodeList &list, iterator first, iterator las
{
ListNode *ins_beg = first._node, *ins_end = last._node, *at = pos._node;
for (ListNode *ln = ins_beg; ln != ins_end; ln = ln->next) {
- list._list.signal_remove_node.emit(static_cast<Node*>(ln));
ln->list = this;
- _list.signal_insert_node.emit(static_cast<Node*>(ln));
}
ins_beg->prev->next = ins_end;
ins_end->prev->next = at;
Node *rm = static_cast<Node*>(i._node);
ListNode *rmnext = rm->next, *rmprev = rm->prev;
++i;
- _list.signal_remove_node.emit(rm);
delete rm;
rmprev->next = rmnext;
rmnext->prev = rmprev;
diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h
index d822d854f100971a1eda0d697e527bf54a9d7e17..581cc9b6fe9e41dab25fcd61d3aa2f5da6ea8b98 100644 (file)
--- a/src/ui/tool/node.h
+++ b/src/ui/tool/node.h
#ifndef SEEN_UI_TOOL_NODE_H
#define SEEN_UI_TOOL_NODE_H
+#include <glib.h>
#include <iterator>
#include <iosfwd>
#include <stdexcept>
Node *parent() { return _parent; }
static char const *handle_type_to_localized_string(NodeType type);
- sigc::signal<void> signal_update;
protected:
Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent);
+
+ virtual void dragged(Geom::Point &, GdkEventMotion *);
+ virtual bool grabbed(GdkEventMotion *);
+ virtual void ungrabbed(GdkEventButton *);
+ virtual bool clicked(GdkEventButton *);
+
virtual Glib::ustring _getTip(unsigned state);
virtual Glib::ustring _getDragTip(GdkEventMotion *event);
virtual bool _hasDragTips() { return true; }
private:
- void _grabbedHandler();
- void _draggedHandler(Geom::Point &, GdkEventMotion *);
- void _ungrabbedHandler();
+ inline PathManipulator &_pm();
Node *_parent; // the handle's lifetime does not extend beyond that of the parent node,
// so a naked pointer is OK and allows setting it during Node's construction
SPCanvasItem *_handle_line;
// temporarily public
virtual bool _eventHandler(GdkEvent *event);
protected:
+ virtual void dragged(Geom::Point &, GdkEventMotion *);
+ virtual bool grabbed(GdkEventMotion *);
+ virtual bool clicked(GdkEventButton *);
+
virtual void _setState(State state);
virtual Glib::ustring _getTip(unsigned state);
virtual Glib::ustring _getDragTip(GdkEventMotion *event);
virtual bool _hasDragTips() { return true; }
private:
Node(Node const &);
- bool _grabbedHandler(GdkEventMotion *);
- void _draggedHandler(Geom::Point &, GdkEventMotion *);
void _fixNeighbors(Geom::Point const &old_pos, Geom::Point const &new_pos);
void _updateAutoHandles();
void _linearGrow(int dir);
Node *_prev();
Inkscape::SnapSourceType _snapSourceType();
Inkscape::SnapTargetType _snapTargetType();
+ inline PathManipulator &_pm();
static SPCtrlShapeType _node_type_to_shape(NodeType type);
static bool _is_line_segment(Node *first, Node *second);
SubpathList(PathManipulator &pm) : _path_manipulator(pm) {}
- sigc::signal<void, Node *> signal_insert_node;
- sigc::signal<void, Node *> signal_remove_node;
private:
list_type _nodelists;
PathManipulator &_path_manipulator;
inline double Handle::length() {
return relativePos().length();
}
+inline PathManipulator &Handle::_pm() {
+ return _parent->_pm();
+}
+inline PathManipulator &Node::_pm() {
+ return list()->_list._path_manipulator;
+}
// definitions for node iterator
template <typename N>
NodeIterator<N> NodeIterator<N>::next() const {
NodeIterator<N> ret(*this);
++ret;
- if (!ret && _node->list->closed()) ++ret;
+ if (G_UNLIKELY(!ret) && _node->list->closed()) ++ret;
return ret;
}
template <typename N>
NodeIterator<N> NodeIterator<N>::prev() const {
NodeIterator<N> ret(*this);
--ret;
- if (!ret && _node->list->closed()) --ret;
+ if (G_UNLIKELY(!ret) && _node->list->closed()) --ret;
return ret;
}
index 0ce02aa95e504ca048af83b52f15393693d39a95..43955edbfa9303fd15180d78d9e7d75a918b1f80 100644 (file)
SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(_outline), 0, SP_WIND_RULE_NONZERO);
- _subpaths.signal_insert_node.connect(
- sigc::mem_fun(*this, &PathManipulator::_attachNodeHandlers));
- // NOTE: signal_remove_node is called just before destruction. Nodes are trackable,
- // so removing the signals manually is not necessary.
- /*_subpaths.signal_remove_node.connect(
- sigc::mem_fun(*this, &PathManipulator::_removeNodeHandlers));*/
-
_selection.signal_update.connect(
sigc::mem_fun(*this, &PathManipulator::update));
_selection.signal_point_changed.connect(
sigc::mem_fun(*this, &PathManipulator::_selectionChanged));
- _dragpoint->signal_update.connect(
- sigc::mem_fun(*this, &PathManipulator::update));
_desktop->signal_zoom_changed.connect(
sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange)));
return LIVEPATHEFFECT(_path)->repr;
}
-void PathManipulator::_attachNodeHandlers(Node *node)
-{
- Handle *handles[2] = { node->front(), node->back() };
- for (int i = 0; i < 2; ++i) {
- handles[i]->signal_update.connect(
- sigc::mem_fun(*this, &PathManipulator::update));
- handles[i]->signal_ungrabbed.connect(
- sigc::hide(
- sigc::mem_fun(*this, &PathManipulator::_handleUngrabbed)));
- handles[i]->signal_grabbed.connect(
- sigc::bind_return(
- sigc::hide(
- sigc::mem_fun(*this, &PathManipulator::_handleGrabbed)),
- false));
- handles[i]->signal_clicked.connect(
- sigc::bind<0>(
- sigc::mem_fun(*this, &PathManipulator::_handleClicked),
- handles[i]));
- }
- node->signal_clicked.connect(
- sigc::bind<0>(
- sigc::mem_fun(*this, &PathManipulator::_nodeClicked),
- node));
-}
-
bool PathManipulator::_nodeClicked(Node *n, GdkEventButton *event)
{
- // cycle between node types on ctrl+click
if (event->button != 1) return false;
if (held_alt(*event) && held_control(*event)) {
// Ctrl+Alt+click: delete nodes
index 6b69e226a7665effc6a0e4d5548f8e8a2351af07..1e9e5057547952cfd0a56b4dbc385aa23a20d5d6 100644 (file)
Glib::ustring _nodetypesKey();
Inkscape::XML::Node *_getXMLNode();
- void _attachNodeHandlers(Node *n);
void _selectionChanged(SelectableControlPoint *p, bool selected);
bool _nodeClicked(Node *, GdkEventButton *);
void _handleGrabbed();
friend class PathManipulatorObserver;
friend class CurveDragPoint;
friend class Node;
+ friend class Handle;
};
} // namespace UI
index 9039bd53320f81c4a699673ac0c9533d94ba085e..1835f0008594cb9e4615ea662c8d9d10f68e14a0 100644 (file)
: reinterpret_cast<ControlPoint::ColorSet*>(&default_scp_color_set), group)
, _selection (sel)
{
- _connectHandlers();
+ _selection.allPoints().insert(this);
}
SelectableControlPoint::SelectableControlPoint(SPDesktop *d, Geom::Point const &initial_pos,
Gtk::AnchorType anchor, Glib::RefPtr<Gdk::Pixbuf> pixbuf,
: reinterpret_cast<ControlPoint::ColorSet*>(&default_scp_color_set), group)
, _selection (sel)
{
- _connectHandlers();
+ _selection.allPoints().insert(this);
}
SelectableControlPoint::~SelectableControlPoint()
_selection.allPoints().erase(this);
}
-void SelectableControlPoint::_connectHandlers()
-{
- _selection.allPoints().insert(this);
- signal_grabbed.connect(
- sigc::bind_return(
- sigc::hide(
- sigc::mem_fun(*this, &SelectableControlPoint::_grabbedHandler)),
- false));
- signal_clicked.connect(
- sigc::mem_fun(*this, &SelectableControlPoint::_clickedHandler));
-}
-
-void SelectableControlPoint::_grabbedHandler()
+bool SelectableControlPoint::grabbed(GdkEventMotion *)
{
// if a point is dragged while not selected, it should select itself
if (!selected()) {
_takeSelection();
}
+ _selection._pointGrabbed();
+ return false;
}
-bool SelectableControlPoint::_clickedHandler(GdkEventButton *event)
+void SelectableControlPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
+ _selection._pointDragged(position(), new_pos, event);
+}
+
+void SelectableControlPoint::ungrabbed(GdkEventButton *)
+{
+ _selection._pointUngrabbed();
+}
+
+bool SelectableControlPoint::clicked(GdkEventButton *event)
+{
+ if (_selection._pointClicked(this, event))
+ return true;
+
if (event->button != 1) return false;
if (held_shift(*event)) {
if (selected()) {
index f5e9541c30661f580f1789c28231d716eaf90b88..2fde16ea94dfd596e58a74e53c2f6859c73961d5 100644 (file)
virtual void _setState(State state);
+ virtual void dragged(Geom::Point &, GdkEventMotion *);
+ virtual bool grabbed(GdkEventMotion *);
+ virtual void ungrabbed(GdkEventButton *);
+ virtual bool clicked(GdkEventButton *);
+
ControlPointSelection &_selection;
private:
- void _connectHandlers();
void _takeSelection();
-
- void _grabbedHandler();
- bool _clickedHandler(GdkEventButton *);
};
} // namespace UI
index bf3ea67144016c221237b0329e9e2361b2140261..8d3cf565059b21a0c746d0cfd46a72d29a06def3 100644 (file)
--- a/src/ui/tool/selector.cpp
+++ b/src/ui/tool/selector.cpp
_rubber = static_cast<CtrlRect*>(sp_canvas_item_new(sp_desktop_controls(_desktop),
SP_TYPE_CTRLRECT, NULL));
sp_canvas_item_hide(_rubber);
-
- signal_clicked.connect(sigc::mem_fun(*this, &SelectorPoint::_clicked));
- signal_grabbed.connect(
- sigc::bind_return(
- sigc::hide(
- sigc::mem_fun(*this, &SelectorPoint::_grabbed)),
- false));
- signal_dragged.connect(
- sigc::hide<0>( sigc::hide(
- sigc::mem_fun(*this, &SelectorPoint::_dragged))));
- signal_ungrabbed.connect(sigc::mem_fun(*this, &SelectorPoint::_ungrabbed));
}
~SelectorPoint() {
gtk_object_destroy(_rubber);
}
private:
- bool _clicked(GdkEventButton *event) {
- if (event->button != 1) return false;
- _selector->signal_point.emit(position(), event);
- return true;
- }
- void _grabbed() {
+ virtual bool grabbed(GdkEventMotion *) {
_cancel = false;
_start = position();
sp_canvas_item_show(_rubber);
+ return false;
}
- void _dragged(Geom::Point &new_pos) {
+ virtual void dragged(Geom::Point &new_pos, GdkEventMotion *) {
if (_cancel) return;
Geom::Rect sel(_start, new_pos);
_rubber->setRectangle(sel);
}
- void _ungrabbed(GdkEventButton *event) {
+ virtual void ungrabbed(GdkEventButton *event) {
if (_cancel) return;
sp_canvas_item_hide(_rubber);
Geom::Rect sel(_start, position());
_selector->signal_area.emit(sel, event);
}
+ virtual bool clicked(GdkEventButton *event) {
+ if (event->button != 1) return false;
+ _selector->signal_point.emit(position(), event);
+ return true;
+ }
CtrlRect *_rubber;
Selector *_selector;
Geom::Point _start;
index f9086950dc3011c06ae3494a8df2684cd75dd729..1af848b964d0a0930d6088df5365ef150dfcc55b 100644 (file)
, _th(th)
{
setVisible(false);
- signal_grabbed.connect(
- sigc::bind_return(
- sigc::hide(
- sigc::mem_fun(*this, &TransformHandle::_grabbedHandler)),
- false));
- signal_dragged.connect(
- sigc::hide<0>(
- sigc::mem_fun(*this, &TransformHandle::_draggedHandler)));
- signal_ungrabbed.connect(
- sigc::hide(
- sigc::mem_fun(*this, &TransformHandle::_ungrabbedHandler)));
}
protected:
virtual void startTransform() {}
Geom::Point _origin;
TransformHandleSet &_th;
private:
- void _grabbedHandler() {
+ virtual bool grabbed(GdkEventMotion *) {
_origin = position();
_last_transform.setIdentity();
startTransform();
_th._setActiveHandle(this);
_cset = &invisible_cset;
_setState(_state);
+ return false;
}
- void _draggedHandler(Geom::Point &new_pos, GdkEventMotion *event)
+ virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
Geom::Matrix t = computeTransform(new_pos, event);
// protect against degeneracies
_th.signal_transform.emit(incr);
_last_transform = t;
}
- void _ungrabbedHandler() {
+ virtual void ungrabbed(GdkEventButton *) {
_th._clearActiveHandle();
_cset = &thandle_cset;
_setState(_state);