summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0e24433)
raw | patch | inline | side by side (parent: 0e24433)
author | buliabyak <buliabyak@users.sourceforge.net> | |
Tue, 17 Apr 2007 20:57:57 +0000 (20:57 +0000) | ||
committer | buliabyak <buliabyak@users.sourceforge.net> | |
Tue, 17 Apr 2007 20:57:57 +0000 (20:57 +0000) |
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index 32e302e330ad1fd7b3b7321f84f49c9f6f4ca5ca..0ad4c66a030c190776b9c53cc158dd6c1ea7ae5e 100644 (file)
--- 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
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];
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 46d768b6315db85975cbd49899c6b176ea852369..967650818764710eb0d6089b5b616a0c18206db4 100644 (file)
--- a/src/nodepath.h
+++ b/src/nodepath.h
/// 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 74734cdd876e6189e20efddc8a1a22973380b3b8..d3cbcbd5750861cfb3210631a3aeeaf43443cf0e 100644 (file)
--- a/src/seltrans.h
+++ b/src/seltrans.h
#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"
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 d9eaf11bc83bebf347bdf20ff6e9d1b789c1e4c4..1a0f319da0b362ea1bc027051e70d63e6bcf27a8 100644 (file)
--- a/src/shape-editor.cpp
+++ b/src/shape-editor.cpp
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 37117331bf8d8e572879af0b17bf7aaabfb13068..85837d10558cdf2cf3d489a60cc9735364fad04d 100644 (file)
--- a/src/shape-editor.h
+++ b/src/shape-editor.h
#include "libnr/nr-path-code.h"
#include "libnr/nr-point.h"
+#include "libnr/nr-maybe.h"
class SPKnotHolder;
class SPDesktop;
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 977c22cf8a1de84bd5b987f6ec152e7226c34172..a7e39e38fda5859f40366990e49081a688a7e716 100644 (file)
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
#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"
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:
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));
}
_("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));
}