summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7563df3)
raw | patch | inline | side by side (parent: 7563df3)
author | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Thu, 14 Jan 2010 17:45:20 +0000 (18:45 +0100) | ||
committer | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Thu, 14 Jan 2010 17:45:20 +0000 (18:45 +0100) |
* Transform handle mode switching similar to selector tool, when
node transform handles are visible.
node transform handles are visible.
diff --git a/share/icons/icons.svg b/share/icons/icons.svg
index e8f690ecb7a0cfe15ce2d6d93969d1c5770fb4f8..32ebcec7f9f28ffec13578250ff8bc8e656bf074 100644 (file)
--- a/share/icons/icons.svg
+++ b/share/icons/icons.svg
version="1.0">
<defs
id="defs3">
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 270 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="1250 : 270 : 1"
- inkscape:persp3d-origin="625 : 180 : 1"
- id="perspective2930" />
<linearGradient
inkscape:collect="always"
id="linearGradient7836">
x1="109.28288"
id="linearGradient6625-4"
inkscape:collect="always" />
- <linearGradient
- xlink:href="#linearGradient10585"
- y2="214.77893"
- x2="13.522233"
- y1="209.98189"
- x1="5.6449146"
- gradientUnits="userSpaceOnUse"
- id="linearGradient8276"
- inkscape:collect="always" />
- <linearGradient
- xlink:href="#linearGradient10585"
- y2="214.77893"
- x2="13.522233"
- y1="209.98189"
- x1="5.6449146"
- gradientUnits="userSpaceOnUse"
- id="linearGradient8278"
- inkscape:collect="always" />
- <linearGradient
- xlink:href="#linearGradient10585"
- y2="214.77893"
- x2="13.522233"
- y1="209.98189"
- x1="5.6449146"
- gradientUnits="userSpaceOnUse"
- id="linearGradient8288"
- inkscape:collect="always" />
- <linearGradient
- xlink:href="#linearGradient10585"
- y2="214.77893"
- x2="13.522233"
- y1="209.98189"
- x1="5.6449146"
- gradientUnits="userSpaceOnUse"
- id="linearGradient8290"
- inkscape:collect="always" />
<radialGradient
xlink:href="#linearGradient5602"
r="0.75"
style="stop-color:#000000;stop-opacity:1"
offset="1" />
</linearGradient>
- <inkscape:perspective
- id="perspective5649"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10585-7"
gradientUnits="userSpaceOnUse"
id="linearGradient8278-4"
inkscape:collect="always" />
- <linearGradient
- id="linearGradient5658-5">
- <stop
- style="stop-color:#d7d7d7;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop5660" />
- <stop
- style="stop-color:#000000;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop5662" />
- </linearGradient>
<linearGradient
xlink:href="#linearGradient10585-7"
y2="214.77893"
gradientUnits="userSpaceOnUse"
id="linearGradient8276-2"
inkscape:collect="always" />
- <linearGradient
- id="linearGradient5665">
- <stop
- style="stop-color:#d7d7d7;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop5667-5" />
- <stop
- style="stop-color:#000000;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop5669" />
- </linearGradient>
<linearGradient
xlink:href="#linearGradient10585-7"
y2="214.77893"
gradientUnits="userSpaceOnUse"
id="linearGradient8290-1"
inkscape:collect="always" />
- <linearGradient
- id="linearGradient5672">
- <stop
- style="stop-color:#d7d7d7;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop5674" />
- <stop
- style="stop-color:#000000;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop5676" />
- </linearGradient>
<linearGradient
xlink:href="#linearGradient10585-7"
y2="214.77893"
gradientUnits="userSpaceOnUse"
id="linearGradient8288-3"
inkscape:collect="always" />
- <linearGradient
- id="linearGradient5679-3">
- <stop
- style="stop-color:#d7d7d7;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop5681" />
- <stop
- style="stop-color:#000000;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop5683" />
- </linearGradient>
</defs>
<sodipodi:namedview
inkscape:guide-bbox="true"
inkscape:window-x="0"
inkscape:window-height="737"
inkscape:window-width="1024"
- inkscape:cy="142.58814"
- inkscape:cx="464.32174"
- inkscape:zoom="1.3732371"
+ inkscape:cy="476.8061"
+ inkscape:cx="492.06334"
+ inkscape:zoom="21.971794"
gridtolerance="6"
snaptogrid="false"
showgrid="true"
inkscape:object-nodes="true"
objecttolerance="11"
inkscape:snap-bbox="true"
- inkscape:snap-nodes="false"
+ inkscape:snap-nodes="true"
inkscape:bbox-nodes="false"
inkscape:bbox-paths="false"
inkscape:snap-global="true"
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" />
</g>
+ <g
+ id="node-transform"
+ inkscape:label="#g5821">
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path5786"
+ d="m 480,55 0,5 1.5,-1.5 2,2 -1.5,1.5 5,0 0,-5 -1.5,1.5 -2,-2 1.5,-1.5 -5,0 z"
+ style="fill:#000000;stroke:none;stroke-width:0.15833369999999999;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <use
+ height="540"
+ width="1250"
+ transform="matrix(-1,0,0,1,976,0)"
+ id="use5795"
+ xlink:href="#path5786"
+ y="0"
+ x="0" />
+ <use
+ height="540"
+ width="1250"
+ transform="matrix(1,0,0,-1,0,126)"
+ id="use5805"
+ xlink:href="#path5786"
+ y="0"
+ x="0" />
+ <use
+ height="540"
+ width="1250"
+ transform="matrix(-1,0,0,-1,976,126)"
+ id="use5819"
+ xlink:href="#path5786"
+ y="0"
+ x="0" />
+ </g>
</svg>
index 5a84592b69113dbf0a47ea055fa206de877996dc..245feae1d2bed10e132a6c0090936822b74ec8e2 100644 (file)
, _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),
boost::shared_ptr<connlist_type> 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::iterator, bool> 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;
_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;
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;
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
index 38df5c7e5f76802cdda10fe75173c7a34f74c1a2..7a83b529064bb5860440536c6e284d059efe5c03 100644 (file)
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();
+ 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);
unsigned _dragging : 1;
unsigned _handles_visible : 1;
unsigned _one_node_handles : 1;
- unsigned _sculpt_enabled : 1;
- unsigned _sculpting : 1;
+
+ friend class SelectableControlPoint;
};
} // namespace UI
index c1ba3394e53cdd0b1fc335cdd95dca8fcd0bcbe6..1e98f0859b744cf8203093e4e63c8a4b1263545b 100644 (file)
@@ -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);
}
}
index 5b9aa4fc838207a1b42753503b4f5c3abdeae4d4..df2410dc29c5831cb719de33bb88342d3b0907c9 100644 (file)
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()) {
index 87e4152581f39aa67bf986fdc65082ae0db17737..208593e3fc2cb36eb160e2e1592864d88760fad6 100644 (file)
void _connectHandlers();
void _takeSelection();
+ void _grabbedHandler();
+ void _draggedHandler(Geom::Point const &, Geom::Point &, GdkEventMotion *);
+ void _ungrabbedHandler();
bool _clickedHandler(GdkEventButton *);
- void _grabbedHandler(GdkEventMotion *);
};
} // namespace UI
index 00f83cdbd85cf78f44c645ef637878dc20b52a3f..e4a585fb3bfa98bb450ec58fe5e71014a16f849e 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
" </toolbar>"
" <toolbar name='NodeToolbar'>"
+ " <toolitem action='NodesShowTransformHandlesAction' />"
+ " <separator />"
" <toolitem action='NodeInsertAction' />"
" <toolitem action='NodeDeleteAction' />"
" <separator />"
" <toolitem action='NodeLineAction' />"
" <toolitem action='NodeCurveAction' />"
" <separator />"
- " <toolitem action='ObjectToPath' />"
- " <toolitem action='StrokeToPath' />"
- " <separator />"
+ //" <toolitem action='ObjectToPath' />"
+ //" <toolitem action='StrokeToPath' />"
+ //" <separator />"
" <toolitem action='NodeXAction' />"
" <toolitem action='NodeYAction' />"
" <toolitem action='NodeUnitsAction' />"
return static_cast<InkNodeTool*>(ec);
}
-
void
sp_node_path_edit_add(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") );