From dedfdbe5d68088cf3db4be3b0eb52d4b2a2b20fa Mon Sep 17 00:00:00 2001 From: =?utf8?q?Krzysztof=20Kosi=C5=84ski?= Date: Thu, 14 Jan 2010 18:45:20 +0100 Subject: [PATCH] * Add "show transform handles" toggle button. * Transform handle mode switching similar to selector tool, when node transform handles are visible. --- share/icons/icons.svg | 135 +++++++---------------- src/ui/tool/control-point-selection.cpp | 82 +++++++------- src/ui/tool/control-point-selection.h | 21 ++-- src/ui/tool/node-tool.cpp | 1 + src/ui/tool/selectable-control-point.cpp | 27 +++-- src/ui/tool/selectable-control-point.h | 4 +- src/widgets/toolbox.cpp | 36 ++++-- 7 files changed, 137 insertions(+), 169 deletions(-) diff --git a/share/icons/icons.svg b/share/icons/icons.svg index e8f690ecb..32ebcec7f 100644 --- a/share/icons/icons.svg +++ b/share/icons/icons.svg @@ -18,13 +18,6 @@ version="1.0"> - @@ -3853,42 +3846,6 @@ x1="109.28288" id="linearGradient6625-4" inkscape:collect="always" /> - - - - - - - - - - - - - - - - - - - - - id="rect6096" style="fill:#ff7777;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.99999952;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:0.94117647;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" /> + + + + + + diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index 5a84592b6..245feae1d 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -49,8 +49,6 @@ ControlPointSelection::ControlPointSelection(SPDesktop *d, SPCanvasGroup *th_gro , _dragging(false) , _handles_visible(true) , _one_node_handles(false) - , _sculpt_enabled(false) - , _sculpting(false) { signal_update.connect( sigc::bind( sigc::mem_fun(*this, &ControlPointSelection::_updateTransformHandles), @@ -83,7 +81,7 @@ std::pair ControlPointSelection::insert(c boost::shared_ptr clist(new connlist_type()); // hide event param and always return false - clist->push_back( + /*clist->push_back( x->signal_grabbed.connect( sigc::bind_return( sigc::bind<0>( @@ -93,11 +91,16 @@ std::pair ControlPointSelection::insert(c clist->push_back( x->signal_dragged.connect( sigc::mem_fun(*this, &ControlPointSelection::_selectionDragged))); - // hide event parameter clist->push_back( x->signal_ungrabbed.connect( sigc::hide( sigc::mem_fun(*this, &ControlPointSelection::_selectionUngrabbed)))); + clist->push_back( + x->signal_clicked.connect( + sigc::hide( + sigc::bind<0>( + sigc::mem_fun(*this, &ControlPointSelection::_selectionClicked), + x))));*/ found = _points.insert(std::make_pair(x, clist)).first; @@ -298,52 +301,35 @@ void ControlPointSelection::restoreTransformHandles() _updateTransformHandles(true); } -void ControlPointSelection::_selectionGrabbed(SelectableControlPoint *p, GdkEventMotion *event) +void ControlPointSelection::toggleTransformHandlesMode() { - hideTransformHandles(); - _dragging = true; - if (held_alt(*event) && _sculpt_enabled) { - _sculpting = true; - _grabbed_point = p; + if (_handles->mode() == TransformHandleSet::MODE_SCALE) { + _handles->setMode(TransformHandleSet::MODE_ROTATE_SKEW); + if (size() == 1) _handles->rotationCenter().setVisible(false); } else { - _sculpting = false; + _handles->setMode(TransformHandleSet::MODE_SCALE); } } -void ControlPointSelection::_selectionDragged(Geom::Point const &old_pos, Geom::Point &new_pos, +void ControlPointSelection::_pointGrabbed() +{ + hideTransformHandles(); + _dragging = true; +} + +void ControlPointSelection::_pointDragged(Geom::Point const &old_pos, Geom::Point &new_pos, GdkEventMotion *event) { Geom::Point delta = new_pos - old_pos; - /*if (_sculpting) { - // for now we only support the default sculpting profile (bell) - // others will be added when preferences will be able to store enumerated values - double pressure, alpha; - if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &pressure)) { - pressure = CLAMP(pressure, 0.2, 0.8); - } else { - pressure = 0.5; - } - - alpha = 1 - 2 * fabs(pressure - 0.5); - if (pressure > 0.5) alpha = 1/alpha; - - for (iterator i = _points.begin(); i != _points.end(); ++i) { - SelectableControlPoint *cur = i->first; - double dist = Geom::distance(cur->position(), _grabbed_point->position()); - - cur->move(cur->position() + delta); - } - } else*/ { - for (iterator i = _points.begin(); i != _points.end(); ++i) { - SelectableControlPoint *cur = i->first; - cur->move(cur->position() + delta); - } - _handles->rotationCenter().move(_handles->rotationCenter().position() + delta); + for (iterator i = _points.begin(); i != _points.end(); ++i) { + SelectableControlPoint *cur = i->first; + cur->move(cur->position() + delta); } + _handles->rotationCenter().move(_handles->rotationCenter().position() + delta); signal_update.emit(); } -void ControlPointSelection::_selectionUngrabbed() +void ControlPointSelection::_pointUngrabbed() { _dragging = false; _grabbed_point = NULL; @@ -351,6 +337,18 @@ void ControlPointSelection::_selectionUngrabbed() signal_commit.emit(COMMIT_MOUSE_MOVE); } +bool ControlPointSelection::_pointClicked(SelectableControlPoint *p, GdkEventButton *event) +{ + // clicking a selected node should toggle the transform handles between rotate and scale mode, + // if they are visible + if (held_shift(*event)) return false; + if (_handles_visible && p->selected()) { + toggleTransformHandlesMode(); + return true; + } + return false; +} + void ControlPointSelection::_updateTransformHandles(bool preserve_center) { if (_dragging) return; @@ -544,13 +542,7 @@ bool ControlPointSelection::event(GdkEvent *event) case GDK_h: case GDK_H: if (held_shift(event->key)) { - // TODO make a method for mode switching - if (_handles->mode() == TransformHandleSet::MODE_SCALE) { - _handles->setMode(TransformHandleSet::MODE_ROTATE_SKEW); - if (size() == 1) _handles->rotationCenter().setVisible(false); - } else { - _handles->setMode(TransformHandleSet::MODE_SCALE); - } + toggleTransformHandlesMode(); return true; } // any modifiers except shift should cause no action diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index 38df5c7e5..7a83b5290 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -101,20 +101,23 @@ public: 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 signal_update; sigc::signal signal_point_changed; sigc::signal 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(); + void _pointDragged(Geom::Point const &, Geom::Point &, GdkEventMotion *); + void _pointUngrabbed(); + bool _pointClicked(SelectableControlPoint *, GdkEventButton *); + void _updateTransformHandles(bool preserve_center); bool _keyboardMove(GdkEventKey const &, Geom::Point const &); bool _keyboardRotate(GdkEventKey const &, int); @@ -130,8 +133,8 @@ private: unsigned _dragging : 1; unsigned _handles_visible : 1; unsigned _one_node_handles : 1; - unsigned _sculpt_enabled : 1; - unsigned _sculpting : 1; + + friend class SelectableControlPoint; }; } // namespace UI diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp index c1ba3394e..1e98f0859 100644 --- a/src/ui/tool/node-tool.cpp +++ b/src/ui/tool/node-tool.cpp @@ -554,6 +554,7 @@ void ink_node_tool_select_area(InkNodeTool *nt, Geom::Rect const &sel, GdkEventB selection->setList(items); g_slist_free(items); } else { + if (!held_shift(*event)) nt->_selected_nodes->clear(); nt->_selected_nodes->selectArea(sel); } } diff --git a/src/ui/tool/selectable-control-point.cpp b/src/ui/tool/selectable-control-point.cpp index 5b9aa4fc8..df2410dc2 100644 --- a/src/ui/tool/selectable-control-point.cpp +++ b/src/ui/tool/selectable-control-point.cpp @@ -56,26 +56,39 @@ SelectableControlPoint::~SelectableControlPoint() void SelectableControlPoint::_connectHandlers() { _selection.allPoints().insert(this); - signal_clicked.connect( - sigc::mem_fun(*this, &SelectableControlPoint::_clickedHandler)); signal_grabbed.connect( sigc::bind_return( - sigc::mem_fun(*this, &SelectableControlPoint::_grabbedHandler), + sigc::hide( + sigc::mem_fun(*this, &SelectableControlPoint::_grabbedHandler)), false)); + signal_dragged.connect( + sigc::mem_fun(*this, &SelectableControlPoint::_draggedHandler)); + signal_ungrabbed.connect( + sigc::hide( + sigc::mem_fun(*this, &SelectableControlPoint::_ungrabbedHandler))); + signal_clicked.connect( + sigc::mem_fun(*this, &SelectableControlPoint::_clickedHandler)); } -void SelectableControlPoint::_grabbedHandler(GdkEventMotion *event) +void SelectableControlPoint::_grabbedHandler() { // if a point is dragged while not selected, it should select itself if (!selected()) { _takeSelection(); - // HACK!!! invoke the last slot for signal_grabbed (it will be the callback registered - // by ControlPointSelection when adding to selection). - signal_grabbed.slots().back()(event); + _selection._pointGrabbed(); } } +void SelectableControlPoint::_draggedHandler(Geom::Point const &old_pos, Geom::Point &new_pos, GdkEventMotion *event) +{ + _selection._pointDragged(old_pos, new_pos, event); +} +void SelectableControlPoint::_ungrabbedHandler() +{ + _selection._pointUngrabbed(); +} bool SelectableControlPoint::_clickedHandler(GdkEventButton *event) { + if (selected() && _selection._pointClicked(this, event)) return true; if (event->button != 1) return false; if (held_shift(*event)) { if (selected()) { diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h index 87e415258..208593e3f 100644 --- a/src/ui/tool/selectable-control-point.h +++ b/src/ui/tool/selectable-control-point.h @@ -50,8 +50,10 @@ private: void _connectHandlers(); void _takeSelection(); + void _grabbedHandler(); + void _draggedHandler(Geom::Point const &, Geom::Point &, GdkEventMotion *); + void _ungrabbedHandler(); bool _clickedHandler(GdkEventButton *); - void _grabbedHandler(GdkEventMotion *); }; } // namespace UI diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 00f83cdbd..e4a585fb3 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -282,6 +282,8 @@ static gchar const * ui_descr = " " " " + " " + " " " " " " " " @@ -299,9 +301,9 @@ static gchar const * ui_descr = " " " " " " - " " - " " - " " + //" " + //" " + //" " " " " " " " @@ -1027,7 +1029,6 @@ static InkNodeTool *get_node_tool() return static_cast(ec); } - void sp_node_path_edit_add(void) { @@ -1112,6 +1113,12 @@ sp_node_path_edit_auto(void) if (nt) nt->_multipath->setNodeType(Inkscape::UI::NODE_AUTO); } +static void toggle_show_transform_handles (GtkToggleAction *act, gpointer /*data*/) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool show = gtk_toggle_action_get_active( act ); + prefs->setBool("/tools/nodes/show_transform_handles", show); +} + static void toggle_show_handles (GtkToggleAction *act, gpointer /*data*/) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool show = gtk_toggle_action_get_active( act ); @@ -1390,12 +1397,23 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); } + { + InkToggleAction* act = ink_toggle_action_new( "NodesShowTransformHandlesAction", + _("Show Transform Handles"), + _("Show node transformation handles"), + "node-transform", + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_transform_handles), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/nodes/show_transform_handles", false) ); + } + { InkToggleAction* act = ink_toggle_action_new( "NodesShowHandlesAction", _("Show Handles"), _("Show the Bezier handles of selected nodes"), INKSCAPE_ICON_SHOW_NODE_HANDLES, - Inkscape::ICON_SIZE_DECORATION ); + secondarySize ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_handles), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/nodes/show_handles", true) ); @@ -1406,7 +1424,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions _("Show Outline"), _("Show the outline of the path"), INKSCAPE_ICON_SHOW_PATH_OUTLINE, - Inkscape::ICON_SIZE_DECORATION ); + secondarySize ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_helperpath), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/nodes/show_outline", false) ); @@ -1417,7 +1435,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions _("Next path effect parameter"), _("Show next path effect parameter for editing"), INKSCAPE_ICON_PATH_EFFECT_PARAMETER_NEXT, - Inkscape::ICON_SIZE_DECORATION ); + secondarySize ); g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_nextLPEparam), desktop ); gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); g_object_set_data( holder, "nodes_lpeedit", inky); @@ -1428,7 +1446,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions _("Edit clipping paths"), _("Show editing controls for clipping paths of selected objects"), INKSCAPE_ICON_PATH_CLIP_EDIT, - Inkscape::ICON_SIZE_DECORATION ); + secondarySize ); gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); g_signal_connect_after( G_OBJECT(inky), "toggled", G_CALLBACK(toggle_edit_clip), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(inky), prefs->getBool("/tools/nodes/edit_clipping_paths") ); @@ -1439,7 +1457,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions _("Edit masks"), _("Show editing controls for masks of selected objects"), INKSCAPE_ICON_PATH_MASK_EDIT, - Inkscape::ICON_SIZE_DECORATION ); + secondarySize ); gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); g_signal_connect_after( G_OBJECT(inky), "toggled", G_CALLBACK(toggle_edit_mask), desktop ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(inky), prefs->getBool("/tools/nodes/edit_masks") ); -- 2.30.2