summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: de35f71)
raw | patch | inline | side by side (parent: de35f71)
author | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Wed, 26 Nov 2008 19:55:59 +0000 (19:55 +0000) | ||
committer | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Wed, 26 Nov 2008 19:55:59 +0000 (19:55 +0000) |
diff --git a/src/context-fns.cpp b/src/context-fns.cpp
index c394e38ca7b62f826b64f7d7107bed5e52d166d2..399e8515451788708dc824bc8798b02f4168d4b2 100644 (file)
--- a/src/context-fns.cpp
+++ b/src/context-fns.cpp
@@ -204,7 +204,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
}
if (snappoint.getSnapped()) {
- desktop->snapindicator->set_new_snappoint(snappoint);
+ desktop->snapindicator->set_new_snaptarget(snappoint);
}
p[0] = sp_desktop_dt2root_xy_point(desktop, p[0]);
index 441b64c02fa74679ba4d36523e39a13c684a9181..e48f48cedb77823530a3cc241295ba0509a76f63 100644 (file)
namespace Display {
SnapIndicator::SnapIndicator(SPDesktop * desktop)
- : _tempitem(NULL),
+ : _snaptarget(NULL),
+ _snapsource(NULL),
_desktop(desktop)
{
}
SnapIndicator::~SnapIndicator()
{
// remove item that might be present
- remove_snappoint();
+ remove_snaptarget();
+ remove_snapsource();
}
void
-SnapIndicator::set_new_snappoint(Inkscape::SnappedPoint const p)
+SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p)
{
- remove_snappoint();
+ remove_snaptarget();
g_assert(_desktop != NULL);
NULL );
SP_CTRL(canvasitem)->moveto(p.getPoint());
- _tempitem = _desktop->add_temporary_canvasitem(canvasitem, 1000); // TODO add preference for snap indicator timeout
+ remove_snapsource(); // Don't set both the source and target indicators, as these will overlap
+ _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, 1000); // TODO add preference for snap indicator timeout
}
}
void
-SnapIndicator::remove_snappoint()
+SnapIndicator::remove_snaptarget()
{
- if (_tempitem) {
- _desktop->remove_temporary_canvasitem(_tempitem);
- _tempitem = NULL;
+ if (_snaptarget) {
+ _desktop->remove_temporary_canvasitem(_snaptarget);
+ _snaptarget = NULL;
}
}
+void
+SnapIndicator::set_new_snapsource(Geom::Point const p)
+{
+ remove_snapsource();
+
+ g_assert(_desktop != NULL);
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool value = prefs->getBool("/options/snapindicator/value", true);
+
+ if (value) {
+ SPCanvasItem * canvasitem = sp_canvas_item_new( sp_desktop_tempgroup (_desktop),
+ SP_TYPE_CTRL,
+ "anchor", GTK_ANCHOR_CENTER,
+ "size", 10.0,
+ "stroked", TRUE,
+ "stroke_color", 0xf000f0ff,
+ "mode", SP_KNOT_MODE_XOR,
+ "shape", SP_KNOT_SHAPE_DIAMOND,
+ NULL );
+
+ SP_CTRL(canvasitem)->moveto(p);
+ _snapsource = _desktop->add_temporary_canvasitem(canvasitem, 1000);
+ }
+}
+
+void
+SnapIndicator::remove_snapsource()
+{
+ if (_snapsource) {
+ _desktop->remove_temporary_canvasitem(_snapsource);
+ _snapsource = NULL;
+ }
+}
+
+
} //namespace Display
} /* namespace Inkscape */
index 1d291bcdf62265877049489a70c7fe7da8f1926f..d2c6dba8e74c0a15114a180e7a6c07bc9e0e64d8 100644 (file)
SnapIndicator(SPDesktop *desktop);
virtual ~SnapIndicator();
- void set_new_snappoint(Inkscape::SnappedPoint const p);
- void remove_snappoint();
+ void set_new_snaptarget(Inkscape::SnappedPoint const p);
+ void remove_snaptarget();
+
+ void set_new_snapsource(Geom::Point const p);
+ void remove_snapsource();
protected:
- TemporaryItem *_tempitem;
+ TemporaryItem *_snaptarget;
+ TemporaryItem *_snapsource;
SPDesktop *_desktop;
private:
diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp
index 1394cd7581d8e602a44a17db2ba1b6230e1be7c2..08be1a849266d9b91670792394454dbb55671cec 100644 (file)
--- a/src/gradient-drag.cpp
+++ b/src/gradient-drag.cpp
@@ -625,7 +625,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
}
}
if (was_snapped) {
- desktop->snapindicator->set_new_snappoint(s);
+ desktop->snapindicator->set_new_snaptarget(s);
}
}
}
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index 7165dab98e57a0cc04158a532629ab3024f15645..5a13588ab20235132cc95e4c380ee68b843e33e8 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
@@ -1404,9 +1404,9 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
}
if (best.getSnapped()) {
- nodepath->desktop->snapindicator->set_new_snappoint(best);
+ nodepath->desktop->snapindicator->set_new_snaptarget(best);
} else {
- nodepath->desktop->snapindicator->remove_snappoint();
+ nodepath->desktop->snapindicator->remove_snaptarget();
}
}
@@ -3649,7 +3649,7 @@ node_request(SPKnot */*knot*/, Geom::Point const &p, guint state, gpointer data)
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data;
- n->subpath->nodepath->desktop->snapindicator->remove_snappoint();
+ n->subpath->nodepath->desktop->snapindicator->remove_snaptarget();
// If either (Shift and some handle retracted), or (we're already dragging out a handle)
if ( (!n->subpath->nodepath->straight_path) &&
@@ -3936,7 +3936,7 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point const &p, guint st
if ((state & GDK_SHIFT_MASK) != 0) {
// We will not try to snap when the shift-key is pressed
// so remove the old snap indicator and don't wait for it to time-out
- desktop->snapindicator->remove_snappoint();
+ desktop->snapindicator->remove_snaptarget();
}
Inkscape::NodePath::Node *othernode = opposite->other;
diff --git a/src/seltrans.cpp b/src/seltrans.cpp
index 4bb1b3d2bc1fdfd64febfe2aa55413f9580ebfff..32a46f775b2c1683362d382767186971e4aeb0b7 100644 (file)
--- a/src/seltrans.cpp
+++ b/src/seltrans.cpp
@@ -332,8 +332,19 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
// points immediately.
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/options/snapclosestonly/value", false)) {
- _keepClosestPointOnly(_snap_points, p);
- _keepClosestPointOnly(_bbox_points, p);
+ if (m.snapprefs.getSnapModeNode()) {
+ _keepClosestPointOnly(_snap_points, p);
+ } else {
+ _snap_points.clear(); // don't keep any point
+ }
+
+ if (m.snapprefs.getSnapModeBBox()) {
+ _keepClosestPointOnly(_bbox_points, p);
+ } else {
+ _bbox_points.clear(); // don't keep any point
+ }
+
+ g_assert(_bbox_points.size() < 2 && _snap_points.size() < 2);
if (_snap_points.size() == 1 && _bbox_points.size() == 1) { //both vectors can only have either one or zero elements
// So we have exactly one bbox corner and one node left; now find out which is closest and delete the other one
if (Geom::L2(_snap_points.at(0) - p) < Geom::L2(_bbox_points.at(0) - p)) {
@@ -342,9 +353,17 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
_snap_points.clear();
}
}
+
+ // Now either _bbox_points or _snap_points has a single element, the other one has zero..... or both have zero elements
+ g_assert((_bbox_points.size() + _snap_points.size()) < 2);
+ if (_bbox_points.size() == 1) {
+ _desktop->snapindicator->set_new_snapsource(_bbox_points.at(0));
+ } else if (_snap_points.size() == 1){
+ _desktop->snapindicator->set_new_snapsource(_snap_points.at(0));
+ }
}
- // The lines below are usefull for debugging any snapping issues, as they'll spit out all points that are considered for snapping
+ // The lines below are useful for debugging any snapping issues, as they'll spit out all points that are considered for snapping
/*std::cout << "Number of snap points: " << _snap_points.size() << std::endl;
for (std::vector<Geom::Point>::const_iterator i = _snap_points.begin(); i != _snap_points.end(); i++)
if (!(bb.getSnapped() || sn.getSnapped())) {
// We didn't snap at all! Don't update the handle position, just calculate the new transformation
_calcAbsAffineDefault(default_scale);
- _desktop->snapindicator->remove_snappoint();
+ _desktop->snapindicator->remove_snaptarget();
} else if (bd < sd) {
// We snapped the bbox (which is either visual or geometric)
- _desktop->snapindicator->set_new_snappoint(bb);
+ _desktop->snapindicator->set_new_snaptarget(bb);
default_scale = Geom::Scale(bb.getTransformation());
// Calculate the new transformation and update the handle position
pt = _calcAbsAffineDefault(default_scale);
} else {
- _desktop->snapindicator->set_new_snappoint(sn);
+ _desktop->snapindicator->set_new_snaptarget(sn);
// We snapped the special points (e.g. nodes), which are not at the visual bbox
// The handle location however (pt) might however be at the visual bbox, so we
// will have to calculate pt taking the stroke width into account
@@ -1072,13 +1091,13 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, Geom
if (!(bb.getSnapped() || sn.getSnapped())) {
// We didn't snap at all! Don't update the handle position, just calculate the new transformation
_calcAbsAffineDefault(default_scale);
- _desktop->snapindicator->remove_snappoint();
+ _desktop->snapindicator->remove_snaptarget();
} else if (bd < sd) {
- _desktop->snapindicator->set_new_snappoint(bb);
+ _desktop->snapindicator->set_new_snaptarget(bb);
// Calculate the new transformation and update the handle position
pt = _calcAbsAffineDefault(default_scale);
} else {
- _desktop->snapindicator->set_new_snappoint(sn);
+ _desktop->snapindicator->set_new_snaptarget(sn);
// We snapped the special points (e.g. nodes), which are not at the visual bbox
// The handle location however (pt) might however be at the visual bbox, so we
// will have to calculate pt taking the stroke width into account
@@ -1171,10 +1190,10 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, Geom::P
if (sn.getSnapped()) {
// We snapped something, so change the skew to reflect it
Geom::Coord const sd = sn.getSnapped() ? sn.getTransformation()[0] : NR_HUGE;
- _desktop->snapindicator->set_new_snappoint(sn);
+ _desktop->snapindicator->set_new_snaptarget(sn);
skew[dim_a] = sd;
} else {
- _desktop->snapindicator->remove_snappoint();
+ _desktop->snapindicator->remove_snaptarget();
}
}
}
}
if (best_snapped_point.getSnapped()) {
- _desktop->snapindicator->set_new_snappoint(best_snapped_point);
+ _desktop->snapindicator->set_new_snaptarget(best_snapped_point);
} else {
// We didn't snap, so remove any previous snap indicator
- _desktop->snapindicator->remove_snappoint();
+ _desktop->snapindicator->remove_snaptarget();
if (control) {
// If we didn't snap, then we should still constrain horizontally or vertically
// (When we did snap, then this constraint has already been enforced by
diff --git a/src/seltrans.h b/src/seltrans.h
index a472f3366ebd4f6dad7f6cd826de9f7bfe0bd15a..42effff7c03dfb4e2eff255362ba5bb44884fe5a 100644 (file)
--- a/src/seltrans.h
+++ b/src/seltrans.h
Geom::Point _calcAbsAffineDefault(Geom::Scale const default_scale);
Geom::Point _calcAbsAffineGeom(Geom::Scale const geom_scale);
void _keepClosestPointOnly(std::vector<Geom::Point> &points, const Geom::Point &reference);
+ void _display_snapsource();
enum State {
STATE_SCALE, //scale or stretch
diff --git a/src/snap.cpp b/src/snap.cpp
index e89063b432b3dfae359c9f72f45182a722057bad..e13809256660fe942c33e9484dbc49c91c12a46e 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
#include "inkscape.h"
#include "desktop.h"
#include "sp-guide.h"
+#include "preferences.h"
using std::vector;
/**
for (std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
/* Work out the transformed version of this point */
- Geom::Point transformed;
- switch (transformation_type) {
- case TRANSLATION:
- transformed = *i + transformation;
- break;
- case SCALE:
- transformed = (*i - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
- break;
- case STRETCH:
- {
- Geom::Scale s(1, 1);
- if (uniform)
- s[Geom::X] = s[Geom::Y] = transformation[dim];
- else {
- s[dim] = transformation[dim];
- s[1 - dim] = 1;
- }
- transformed = ((*i - origin) * s) + origin;
- break;
- }
- case SKEW:
- // Apply the skew factor
- transformed[dim] = (*i)[dim] + transformation[0] * ((*i)[1 - dim] - origin[1 - dim]);
- // While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed.
- // Apply that scale factor here
- transformed[1-dim] = (*i - origin)[1 - dim] * transformation[1] + origin[1 - dim];
- break;
- default:
- g_assert_not_reached();
- }
+ Geom::Point transformed = _transformPoint(*i, transformation_type, transformation, origin, dim, uniform);
// add the current transformed point to the box hulling all transformed points
if (i == points.begin()) {
@@ -600,7 +572,11 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreference
Geom::Point const &pointer,
Geom::Point const &tr) const
{
- return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+ }
+
+ return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
}
@@ -622,7 +598,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPre
Inkscape::Snapper::ConstraintLine const &constraint,
Geom::Point const &tr) const
{
- return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+ }
+
+ return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
}
@@ -643,7 +623,11 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::Poi
Geom::Scale const &s,
Geom::Point const &o) const
{
- return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false));
+ }
+
+ return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
}
@@ -666,7 +650,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferenc
Geom::Point const &o) const
{
// When constrained scaling, only uniform scaling is supported.
- return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true));
+ }
+
+ return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
}
@@ -691,7 +679,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
Geom::Dim2 d,
bool u) const
{
- return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u));
+ }
+
+ return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u);
}
@@ -723,6 +715,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreference
// so it's corners have a different transformation. The snappers cannot handle this, therefore snapping
// of bounding boxes is not allowed here.
g_assert(!(point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX));
+
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), SKEW, s, o, d, false));
+ }
+
return _snapTransformed(point_type, p, pointer, true, constraint, SKEW, s, o, d, false);
}
@@ -825,9 +822,9 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
// Update the snap indicator, if requested
if (_snapindicator) {
if (bestSnappedPoint.getSnapped()) {
- _desktop->snapindicator->set_new_snappoint(bestSnappedPoint);
+ _desktop->snapindicator->set_new_snaptarget(bestSnappedPoint);
} else {
- _desktop->snapindicator->remove_snappoint();
+ _desktop->snapindicator->remove_snaptarget();
}
}
return _named_view->document;
}
+Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
+ Transformation const transformation_type,
+ Geom::Point const &transformation,
+ Geom::Point const &origin,
+ Geom::Dim2 const dim,
+ bool const uniform) const
+{
+ /* Work out the transformed version of this point */
+ Geom::Point transformed;
+ switch (transformation_type) {
+ case TRANSLATION:
+ transformed = p + transformation;
+ break;
+ case SCALE:
+ transformed = (p - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
+ break;
+ case STRETCH:
+ {
+ Geom::Scale s(1, 1);
+ if (uniform)
+ s[Geom::X] = s[Geom::Y] = transformation[dim];
+ else {
+ s[dim] = transformation[dim];
+ s[1 - dim] = 1;
+ }
+ transformed = ((p - origin) * s) + origin;
+ break;
+ }
+ case SKEW:
+ // Apply the skew factor
+ transformed[dim] = p[dim] + transformation[0] * (p[1 - dim] - origin[1 - dim]);
+ // While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed.
+ // Apply that scale factor here
+ transformed[1-dim] = (p - origin)[1 - dim] * transformation[1] + origin[1 - dim];
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ return transformed;
+}
+
+void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p) const {
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (prefs->getBool("/options/snapclosestonly/value")) {
+ bool p_is_a_node = point_type & Inkscape::SnapPreferences::SNAPPOINT_NODE;
+ bool p_is_a_bbox = point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX;
+ if ((p_is_a_node && snapprefs.getSnapModeNode()) || (p_is_a_bbox && snapprefs.getSnapModeBBox())) {
+ _desktop->snapindicator->set_new_snapsource(p);
+ } else {
+ _desktop->snapindicator->remove_snapsource();
+ }
+ }
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/snap.h b/src/snap.h
index 05af0d20281fcbc043f9c4c4435b90987b0b083c..b8d9fdd25604680c25bba39e4d318624c2d14a72 100644 (file)
--- a/src/snap.h
+++ b/src/snap.h
class SnapManager
{
public:
- SnapManager(SPNamedView const *v);
+ enum Transformation {
+ TRANSLATION,
+ SCALE,
+ STRETCH,
+ SKEW
+ };
+
+ SnapManager(SPNamedView const *v);
typedef std::list<const Inkscape::Snapper*> SnapperList;
Geom::Point const &s, // s[0] = skew factor, s[1] = scale factor
Geom::Point const &o,
Geom::Dim2 d) const;
-
+
Inkscape::GuideSnapper guide; ///< guide snapper
Inkscape::ObjectSnapper object; ///< snapper to other objects
Inkscape::SnapPreferences snapprefs;
SPNamedView const *_named_view;
private:
- enum Transformation {
- TRANSLATION,
- SCALE,
- STRETCH,
- SKEW
- };
-
- std::vector<SPItem const *> *_items_to_ignore;
+ std::vector<SPItem const *> *_items_to_ignore;
SPItem const *_item_to_ignore;
SPDesktop const *_desktop;
bool _snapindicator;
Geom::Point const &origin,
Geom::Dim2 dim,
bool uniform) const;
-
+
+ Geom::Point _transformPoint(Geom::Point const &p,
+ Transformation const transformation_type,
+ Geom::Point const &transformation,
+ Geom::Point const &origin,
+ Geom::Dim2 const dim,
+ bool const uniform) const;
+
+ void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p) const;
+
Inkscape::SnappedPoint findBestSnap(Geom::Point const &p, SnappedConstraints &sc, bool constrained) const;
};