summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbulia byak <buliabyak@gmail.com>2007-04-17 20:57:57 +0000
committerbuliabyak <buliabyak@users.sourceforge.net>2007-04-17 20:57:57 +0000
commit01f61dcd0fb06269539c9cbe8ef885d3a4b3b5c5 (patch)
tree0d87b6d9132a9c46a56c7835662e0e818ddc04fd /src
parentGrid: added dotted rendering of rectangular grid. Fixed bug in emphasized lin... (diff)
downloadinkscape-01f61dcd0fb06269539c9cbe8ef885d3a4b3b5c5.tar.gz
inkscape-01f61dcd0fb06269539c9cbe8ef885d3a4b3b5c5.zip
flipping patch by maximilian albert
(bzr r2916)
Diffstat (limited to 'src')
-rw-r--r--src/nodepath.cpp43
-rw-r--r--src/nodepath.h7
-rw-r--r--src/seltrans.h6
-rw-r--r--src/shape-editor.cpp4
-rw-r--r--src/shape-editor.h3
-rw-r--r--src/verbs.cpp35
6 files changed, 75 insertions, 23 deletions
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index 32e302e33..0ad4c66a0 100644
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
@@ -136,7 +136,7 @@ static Inkscape::NodePath::NodeSide *sp_node_opposite_side(Inkscape::NodePath::N
static NRPathcode sp_node_path_code_from_side(Inkscape::NodePath::Node *node,Inkscape::NodePath::NodeSide *me);
// active_node indicates mouseover node
-static Inkscape::NodePath::Node *active_node = NULL;
+Inkscape::NodePath::Node * Inkscape::NodePath::Path::active_node = NULL;
/**
* \brief Creates new nodepath from item
@@ -2897,10 +2897,10 @@ static gboolean node_event(SPKnot *knot, GdkEvent *event, Inkscape::NodePath::No
gboolean ret = FALSE;
switch (event->type) {
case GDK_ENTER_NOTIFY:
- active_node = n;
+ Inkscape::NodePath::Path::active_node = n;
break;
case GDK_LEAVE_NOTIFY:
- active_node = NULL;
+ Inkscape::NodePath::Path::active_node = NULL;
break;
case GDK_SCROLL:
if ((event->scroll.state & GDK_CONTROL_MASK) && !(event->scroll.state & GDK_SHIFT_MASK)) { // linearly
@@ -2971,33 +2971,33 @@ gboolean node_key(GdkEvent *event)
Inkscape::NodePath::Path *np;
// there is no way to verify nodes so set active_node to nil when deleting!!
- if (active_node == NULL) return FALSE;
+ if (Inkscape::NodePath::Path::active_node == NULL) return FALSE;
if ((event->type == GDK_KEY_PRESS) && !(event->key.state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))) {
gint ret = FALSE;
switch (get_group0_keyval (&event->key)) {
/// \todo FIXME: this does not seem to work, the keys are stolen by tool contexts!
case GDK_BackSpace:
- np = active_node->subpath->nodepath;
- sp_nodepath_node_destroy(active_node);
+ np = Inkscape::NodePath::Path::active_node->subpath->nodepath;
+ sp_nodepath_node_destroy(Inkscape::NodePath::Path::active_node);
sp_nodepath_update_repr(np, _("Delete node"));
- active_node = NULL;
+ Inkscape::NodePath::Path::active_node = NULL;
ret = TRUE;
break;
case GDK_c:
- sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_CUSP);
+ sp_nodepath_set_node_type(Inkscape::NodePath::Path::active_node,Inkscape::NodePath::NODE_CUSP);
ret = TRUE;
break;
case GDK_s:
- sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_SMOOTH);
+ sp_nodepath_set_node_type(Inkscape::NodePath::Path::active_node,Inkscape::NodePath::NODE_SMOOTH);
ret = TRUE;
break;
case GDK_y:
- sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_SYMM);
+ sp_nodepath_set_node_type(Inkscape::NodePath::Path::active_node,Inkscape::NodePath::NODE_SYMM);
ret = TRUE;
break;
case GDK_b:
- sp_nodepath_node_break(active_node);
+ sp_nodepath_node_break(Inkscape::NodePath::Path::active_node);
ret = TRUE;
break;
}
@@ -3513,6 +3513,16 @@ static gboolean node_handle_event(SPKnot *knot, GdkEvent *event,Inkscape::NodePa
break;
}
break;
+ case GDK_ENTER_NOTIFY:
+ // we use an experimentally determined threshold that seems to work fine
+ if (NR::L2(n->pos - knot->pos) < 0.75)
+ Inkscape::NodePath::Path::active_node = n;
+ break;
+ case GDK_LEAVE_NOTIFY:
+ // we use an experimentally determined threshold that seems to work fine
+ if (NR::L2(n->pos - knot->pos) < 0.75)
+ Inkscape::NodePath::Path::active_node = NULL;
+ break;
default:
break;
}
@@ -3803,11 +3813,11 @@ void sp_nodepath_selected_nodes_scale_screen(Inkscape::NodePath::Path *nodepath,
/**
* Flip selected nodes horizontally/vertically.
*/
-void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis)
+void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis, NR::Maybe<NR::Point> center)
{
if (!nodepath || !nodepath->selected) return;
- if (g_list_length(nodepath->selected) == 1) {
+ if (g_list_length(nodepath->selected) == 1 && !center) {
// flip handles of the single selected node
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) nodepath->selected->data;
double temp = n->p.pos[axis];
@@ -3824,10 +3834,13 @@ void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis)
box.expandTo (n->pos); // contain all selected nodes
}
+ if (!center) {
+ center = box.midpoint();
+ }
NR::Matrix t =
- NR::Matrix (NR::translate(-box.midpoint())) *
+ NR::Matrix (NR::translate(- *center)) *
NR::Matrix ((axis == NR::X)? NR::scale(-1, 1) : NR::scale(1, -1)) *
- NR::Matrix (NR::translate(box.midpoint()));
+ NR::Matrix (NR::translate(*center));
for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
diff --git a/src/nodepath.h b/src/nodepath.h
index 46d768b63..967650818 100644
--- a/src/nodepath.h
+++ b/src/nodepath.h
@@ -134,6 +134,11 @@ class Path {
/// true if we're showing selected nodes' handles
bool show_handles;
+
+ /// active_node points to the node that is currently mouseovered (= NULL if
+ /// there isn't any); we also consider the node mouseovered if it is covered
+ /// by one of its handles and the latter is mouseovered
+ static Node *active_node;
};
@@ -285,6 +290,6 @@ void sp_nodepath_selected_nodes_rotate (Inkscape::NodePath::Path * nodepath, gdo
void sp_nodepath_selected_nodes_scale (Inkscape::NodePath::Path * nodepath, gdouble grow, int which);
void sp_nodepath_selected_nodes_scale_screen (Inkscape::NodePath::Path * nodepath, gdouble grow, int which);
-void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis);
+void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis, NR::Maybe<NR::Point> center);
#endif
diff --git a/src/seltrans.h b/src/seltrans.h
index 74734cdd8..d3cbcbd57 100644
--- a/src/seltrans.h
+++ b/src/seltrans.h
@@ -18,6 +18,7 @@
#include <libnr/nr-point.h>
#include <libnr/nr-matrix.h>
#include <libnr/nr-rect.h>
+#include "knot.h"
#include "forward.h"
#include "selcue.h"
#include "message-context.h"
@@ -84,7 +85,10 @@ public:
bool isGrabbed() {
return _grabbed;
}
-
+ bool centerIsVisible() {
+ return ( _chandle && SP_KNOT_IS_VISIBLE (_chandle) );
+ }
+
private:
void _updateHandles();
void _updateVolatileState();
diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp
index d9eaf11bc..1a0f319da 100644
--- a/src/shape-editor.cpp
+++ b/src/shape-editor.cpp
@@ -412,9 +412,9 @@ void ShapeEditor::select_prev () {
sp_nodepath_select_prev (this->nodepath);
}
-void ShapeEditor::flip (NR::Dim2 axis) {
+void ShapeEditor::flip (NR::Dim2 axis, NR::Maybe<NR::Point> center) {
if (this->nodepath)
- sp_nodepath_flip (this->nodepath, axis);
+ sp_nodepath_flip (this->nodepath, axis, center);
}
void ShapeEditor::distribute (NR::Dim2 axis) {
diff --git a/src/shape-editor.h b/src/shape-editor.h
index 37117331b..85837d105 100644
--- a/src/shape-editor.h
+++ b/src/shape-editor.h
@@ -22,6 +22,7 @@ class Path;
#include "libnr/nr-path-code.h"
#include "libnr/nr-point.h"
+#include "libnr/nr-maybe.h"
class SPKnotHolder;
class SPDesktop;
@@ -101,7 +102,7 @@ public:
void select_next ();
void select_prev ();
- void flip (NR::Dim2 axis);
+ void flip (NR::Dim2 axis, NR::Maybe<NR::Point> center = NR::Nothing());
void distribute (NR::Dim2 axis);
void align (NR::Dim2 axis);
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 977c22cf8..a7e39e38f 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -76,6 +76,8 @@
#include "sp-flowtext.h"
#include "layer-fns.h"
#include "node-context.h"
+#include "select-context.h"
+#include "seltrans.h"
#include "gradient-context.h"
#include "shape-editor.h"
@@ -1262,7 +1264,13 @@ ObjectVerb::perform( SPAction *action, void *data, void *pdata )
if (!bbox) {
return;
}
- NR::Point const center(bbox->midpoint());
+ // If the rotation center of the selection is visible, choose it as reference point
+ // for horizontal and vertical flips. Otherwise, take the center of the bounding box.
+ NR::Point center;
+ if (tools_isactive(dt, TOOLS_SELECT) && sel->center() && SP_SELECT_CONTEXT(ec)->_seltrans->centerIsVisible())
+ center = *sel->center();
+ else
+ center = bbox->midpoint();
switch (reinterpret_cast<std::size_t>(data)) {
case SP_VERB_OBJECT_ROTATE_90_CW:
@@ -1287,8 +1295,23 @@ ObjectVerb::perform( SPAction *action, void *data, void *pdata )
flowtext_to_text();
break;
case SP_VERB_OBJECT_FLIP_HORIZONTAL:
+ // When working with the node tool ...
if (tools_isactive(dt, TOOLS_NODES)) {
- SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::X);
+ Inkscape::NodePath::Node *active_node = Inkscape::NodePath::Path::active_node;
+
+ // ... and one of the nodes is currently mouseovered ...
+ if (active_node) {
+
+ // ... flip the selected nodes about that node
+ SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::X, active_node->pos);
+ } else {
+
+ // ... or else about the center of their bounding box.
+ SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::X);
+ }
+
+ // When working with the selector tool, flip the selection about its rotation center
+ // (if it is visible) or about the center of the bounding box.
} else {
sp_selection_scale_relative(sel, center, NR::scale(-1.0, 1.0));
}
@@ -1296,8 +1319,14 @@ ObjectVerb::perform( SPAction *action, void *data, void *pdata )
_("Flip horizontally"));
break;
case SP_VERB_OBJECT_FLIP_VERTICAL:
+ // The behaviour is analogous to flipping horizontally
if (tools_isactive(dt, TOOLS_NODES)) {
- SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::Y);
+ Inkscape::NodePath::Node *active_node = Inkscape::NodePath::Path::active_node;
+ if (active_node) {
+ SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::Y, active_node->pos);
+ } else {
+ SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::Y);
+ }
} else {
sp_selection_scale_relative(sel, center, NR::scale(1.0, -1.0));
}