summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 05be941)
raw | patch | inline | side by side (parent: 05be941)
author | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Tue, 28 Aug 2007 20:07:38 +0000 (20:07 +0000) | ||
committer | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Tue, 28 Aug 2007 20:07:38 +0000 (20:07 +0000) |
13 files changed:
diff --git a/src/arc-context.cpp b/src/arc-context.cpp
index d5a25b61bfc4e48a20b2944999eea89a8bc99f82..ab6b3a01ddf26e0a46c0b909c419d12ac11c8c14 100644 (file)
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
SnapManager const &m = desktop->namedview->snap_manager;
motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, ac->item).getPoint();
-
+
sp_arc_drag(ac, motion_dt, event->motion.state);
gobble_motion_events(GDK_BUTTON1_MASK);
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 8ac3c8c74baaf40a6f69056b6e3613291aeb709a..977ab3483630a944bb4a22e894c4cd959e946ef0 100644 (file)
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
{SP_ATTR_INKSCAPE_WINDOW_Y, "inkscape:window-y"},
{SP_ATTR_INKSCAPE_SNAP_BBOX, "inkscape:snap-bbox"},
{SP_ATTR_INKSCAPE_SNAP_NODES, "inkscape:snap-nodes"},
+ {SP_ATTR_INKSCAPE_SNAP_GUIDE, "inkscape:snap-guide"},
{SP_ATTR_INKSCAPE_SNAP_CENTER, "inkscape:snap-center"},
{SP_ATTR_INKSCAPE_OBJECT_PATHS, "inkscape:object-paths"},
{SP_ATTR_INKSCAPE_OBJECT_NODES, "inkscape:object-nodes"},
diff --git a/src/attributes.h b/src/attributes.h
index 73ecf0252568cd4bab3b77fd813beb95040e63d2..4a2970830d414dbe5e250030a2415d5c3c0f008c 100644 (file)
--- a/src/attributes.h
+++ b/src/attributes.h
SP_ATTR_INKSCAPE_WINDOW_Y,
SP_ATTR_INKSCAPE_SNAP_BBOX,
SP_ATTR_INKSCAPE_SNAP_NODES,
+ SP_ATTR_INKSCAPE_SNAP_GUIDE,
SP_ATTR_INKSCAPE_SNAP_CENTER,
SP_ATTR_INKSCAPE_OBJECT_PATHS,
SP_ATTR_INKSCAPE_OBJECT_NODES,
diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp
index a1026481199609c52e32905a33a19b5f95684e8b..7f9ce0b04158d08d3e5b96c86a93179de54dcf9e 100644 (file)
--- a/src/desktop-events.cpp
+++ b/src/desktop-events.cpp
#include "message-context.h"
#include "xml/repr.h"
#include "dialogs/guidelinedialog.h"
+#include "snap.h"
/* Root item handler */
if (dragging) {
NR::Point const motion_w(event->motion.x,
event->motion.y);
- NR::Point const motion_dt(desktop->w2d(motion_w));
+ NR::Point motion_dt(desktop->w2d(motion_w));
+
+ SnapManager const &m = desktop->namedview->snap_manager;
+ motion_dt = m.guideSnap(motion_dt, *guide).getPoint();
+
sp_guide_moveto(*guide, sp_guide_position_from_pt(guide, motion_dt), false);
moved = true;
desktop->set_coordinate_status(motion_dt);
if (moved) {
NR::Point const event_w(event->button.x,
event->button.y);
- NR::Point const event_dt(desktop->w2d(event_w));
+ NR::Point event_dt(desktop->w2d(event_w));
+
+ //If we don't snap here again, it will end up at the current mouse position
+ //whereas it might have been at a snapped position a millisecond before.
+ //See GDK_MOTION_NOTIFY above. Why's that????
+ SnapManager const &m = desktop->namedview->snap_manager;
+ event_dt = m.guideSnap(event_dt, *guide).getPoint();
+
if (sp_canvas_world_pt_inside_window(item->canvas, event_w)) {
sp_guide_moveto(*guide, sp_guide_position_from_pt(guide, event_dt), true);
sp_document_done(sp_desktop_document(desktop), SP_VERB_NONE,
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 427b7c50790d0459f351855deecc9a87e44b9df2..57937145a6e75a2b8bee753b474abfde71c16595 100644 (file)
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
Inkscape::ObjectSnapper::ObjectSnapper(SPNamedView const *nv, NR::Coord const d)
: Snapper(nv, d), _snap_to_itemnode(true), _snap_to_itempath(true),
- _snap_to_bboxnode(true), _snap_to_bboxpath(true), _strict_snapping(true)
+ _snap_to_bboxnode(true), _snap_to_bboxpath(true), _strict_snapping(true),
+ _include_item_center(false)
{
}
void Inkscape::ObjectSnapper::_findCandidates(std::list<SPItem*>& c,
SPObject* r,
std::list<SPItem const *> const &it,
- NR::Point const &p) const
+ NR::Point const &p,
+ DimensionToSnap const snap_dim) const
{
if (ThisSnapperMightSnap()) {
SPDesktop const *desktop = SP_ACTIVE_DESKTOP;
if (i == it.end()) {
/* See if the item is within range */
if (SP_IS_GROUP(o)) {
- _findCandidates(c, o, it, p);
+ _findCandidates(c, o, it, p, snap_dim);
} else {
NR::Maybe<NR::Rect> b = sp_item_bbox_desktop(SP_ITEM(o));
- if ( b && NR::expand(*b, -getDistance()).contains(p) ) {
+ NR::Point b_min = b->min();
+ NR::Point b_max = b->max();
+ double d = getDistance();
+ bool withinX = (p[NR::X] >= b_min[NR::X] - d) && (p[NR::X] <= b_max[NR::X] + d);
+ bool withinY = (p[NR::Y] >= b_min[NR::Y] - d) && (p[NR::Y] <= b_max[NR::Y] + d);
+ if (snap_dim == SNAP_X && withinX || snap_dim == SNAP_Y && withinY || snap_dim == SNAP_XY && withinX && withinY) {
c.push_back(SP_ITEM(o));
}
}
void Inkscape::ObjectSnapper::_snapNodes(Inkscape::Snapper::PointType const &t,
Inkscape::SnappedPoint &s,
NR::Point const &p,
+ DimensionToSnap const snap_dim,
std::list<SPItem*> const &cand) const
{
/* FIXME: this seems like a hack. Perhaps Snappers should be
}
bool p_is_a_node = t & Inkscape::Snapper::SNAPPOINT_NODE;
+ bool p_is_a_bbox = t & Inkscape::Snapper::SNAPPOINT_BBOX;
+ bool p_is_a_guide = t & Inkscape::Snapper::SNAPPOINT_GUIDE;
+
+ // A point considered for snapping should be either a node, a bbox corner or a guide. Pick only ONE!
+ g_assert(!(p_is_a_node && p_is_a_bbox || p_is_a_bbox && p_is_a_guide || p_is_a_node && p_is_a_guide));
for (std::list<SPItem*>::const_iterator i = cand.begin(); i != cand.end(); i++) {
//Collect all nodes so we can snap to them
if (_snap_to_itemnode) {
- if (!(_strict_snapping && !p_is_a_node)) {
+ if (!(_strict_snapping && !p_is_a_node) || p_is_a_guide) {
if (curve) {
int j = 0;
while (SP_CURVE_BPATH(curve)[j].code != NR_END) {
@@ -126,13 +139,16 @@ void Inkscape::ObjectSnapper::_snapNodes(Inkscape::Snapper::PointType const &t,
points_to_snap_to.push_back(desktop->doc2dt(bp.c(3) * i2doc));
j++;
}
+ if (_include_item_center) {
+ points_to_snap_to.push_back(root_item->getCenter());
+ }
}
}
}
//Collect the bounding box's corners so we can snap to them
if (_snap_to_bboxnode) {
- if (!(_strict_snapping && p_is_a_node)) {
+ if (!(_strict_snapping && !p_is_a_bbox) || p_is_a_guide) {
NR::Maybe<NR::Rect> b = sp_item_bbox_desktop(root_item, bbox_type);
if (b) {
for ( unsigned k = 0 ; k < 4 ; k++ ) {
@@ -145,9 +161,24 @@ void Inkscape::ObjectSnapper::_snapNodes(Inkscape::Snapper::PointType const &t,
//Do the snapping, using all the nodes and corners collected above
for (std::list<NR::Point>::const_iterator k = points_to_snap_to.begin(); k != points_to_snap_to.end(); k++) {
/* Try to snap to this node of the path */
- NR::Coord const dist = NR::L2(*k - p);
+ NR::Coord dist = NR_HUGE;
+ NR::Point snapped_point;
+ switch (snap_dim) {
+ case SNAP_X:
+ dist = fabs((*k)[NR::X] - p[NR::X]);
+ snapped_point = NR::Point((*k)[NR::X], p[NR::Y]);
+ break;
+ case SNAP_Y:
+ dist = fabs((*k)[NR::Y] - p[NR::Y]);
+ snapped_point = NR::Point(p[NR::X], (*k)[NR::Y]);
+ break;
+ case SNAP_XY:
+ dist = NR::L2(*k - p);
+ snapped_point = *k;
+ break;
+ }
if (dist < getDistance() && dist < s.getDistance()) {
- s = SnappedPoint(*k, dist);
+ s = SnappedPoint(snapped_point, dist);
}
}
}
@@ -251,12 +282,12 @@ Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doFreeSnap(Inkscape::Snapper::P
/* Get a list of all the SPItems that we will try to snap to */
std::list<SPItem*> cand;
- _findCandidates(cand, sp_document_root(_named_view->document), it, p);
+ _findCandidates(cand, sp_document_root(_named_view->document), it, p, SNAP_XY);
SnappedPoint s(p, NR_HUGE);
if (_snap_to_itemnode || _snap_to_bboxnode) {
- _snapNodes(t, s, p, cand);
+ _snapNodes(t, s, p, SNAP_XY, cand);
}
if (_snap_to_itempath || _snap_to_bboxpath) {
_snapPaths(t, s, p, cand);
@@ -278,6 +309,26 @@ Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doConstrainedSnap(Inkscape::Sna
return _doFreeSnap(t, p, it);
}
+
+
+Inkscape::SnappedPoint Inkscape::ObjectSnapper::guideSnap(NR::Point const &p,
+ DimensionToSnap const snap_dim) const
+{
+ if ( NULL == _named_view ) {
+ return SnappedPoint(p, NR_HUGE);
+ }
+
+ /* Get a list of all the SPItems that we will try to snap to */
+ std::list<SPItem*> cand;
+ std::list<SPItem const *> const it; //just an empty list
+ _findCandidates(cand, sp_document_root(_named_view->document), it, p, snap_dim);
+
+ SnappedPoint s(p, NR_HUGE);
+ _snapNodes(Inkscape::Snapper::SNAPPOINT_GUIDE, s, p, snap_dim, cand);
+
+ return s;
+}
+
/**
* \return true if this Snapper will snap at least one kind of point.
*/
diff --git a/src/object-snapper.h b/src/object-snapper.h
index a0d5f0b65d8cc7b0b801d7e00b1e91e59daeae64..ad4cfc6492e0bc055931fbdd2362f7deec94e85c 100644 (file)
--- a/src/object-snapper.h
+++ b/src/object-snapper.h
class ObjectSnapper : public Snapper
{
+
public:
ObjectSnapper(SPNamedView const *nv, NR::Coord const d);
+ enum DimensionToSnap {SNAP_X, SNAP_Y, SNAP_XY};
+
void setSnapToItemNode(bool s) {
_snap_to_itemnode = s;
}
return _snap_to_bboxpath;
}
+ void setIncludeItemCenter(bool s) {
+ _include_item_center = s;
+ }
+
+ bool getIncludeItemCenter() const {
+ return _include_item_center;
+ }
+
void setStrictSnapping(bool enabled) {
_strict_snapping = enabled;
}
+ SnappedPoint guideSnap(NR::Point const &p,
+ DimensionToSnap const snap_dim) const;
+
bool ThisSnapperMightSnap() const;
private:
void _findCandidates(std::list<SPItem*>& c,
SPObject* r,
std::list<SPItem const *> const &it,
- NR::Point const &p) const;
+ NR::Point const &p,
+ DimensionToSnap const snap_dim) const;
void _snapNodes(Inkscape::Snapper::PointType const &t,
Inkscape::SnappedPoint &s,
NR::Point const &p,
+ DimensionToSnap const snap_dim,
std::list<SPItem*> const &cand) const;
void _snapPaths(Inkscape::Snapper::PointType const &t,
//snap bbox corners to nodes, or nodes to bboxes.
//(snapping to grids and guides is not affected by this)
bool _strict_snapping;
+ bool _include_item_center;
};
}
diff --git a/src/snap.cpp b/src/snap.cpp
index c585a979089dcda595251ad942d21d661e10c06d..07e76362d8c1919f5665808f335c40e1a72f69b1 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
#include "inkscape.h"
#include "desktop.h"
+#include "sp-guide.h"
+using std::vector;
/**
* Construct a SnapManager for a SPNamedView.
return guide.getSnapFrom(Inkscape::Snapper::SNAPPOINT_NODE);
}
+void SnapManager::setSnapModeGuide(bool enabled)
+{
+ object.setSnapFrom(Inkscape::Snapper::SNAPPOINT_GUIDE, enabled);
+}
+
+bool SnapManager::getSnapModeGuide() const
+{
+ return object.getSnapFrom(Inkscape::Snapper::SNAPPOINT_GUIDE);
+}
+
/**
* Try to snap a point to any interested snappers.
*
@@ -317,6 +329,21 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType
return r;
}
+Inkscape::SnappedPoint SnapManager::guideSnap(NR::Point const &p,
+ SPGuide const &guide) const
+{
+ Inkscape::ObjectSnapper::DimensionToSnap snap_dim;
+ if (guide.normal == component_vectors[NR::Y]) {
+ snap_dim = Inkscape::ObjectSnapper::SNAP_Y;
+ } else if (guide.normal == component_vectors[NR::X]) {
+ snap_dim = Inkscape::ObjectSnapper::SNAP_X;
+ } else {
+ g_warning("WARNING: snapping of angled guides is not supported yet!");
+ snap_dim = Inkscape::ObjectSnapper::SNAP_XY;
+ }
+
+ return object.guideSnap(p, snap_dim);
+}
/**
diff --git a/src/snap.h b/src/snap.h
index c60d866ad34d0bce75a65f667c961f605b82e9c6..276069fe672b145c9b42ccc720693aa866f7021a 100644 (file)
--- a/src/snap.h
+++ b/src/snap.h
NR::Point const &p,
Inkscape::Snapper::ConstraintLine const &c,
std::list<SPItem const *> const &it) const;
+
+ Inkscape::SnappedPoint guideSnap(NR::Point const &p,
+ SPGuide const &guide) const;
std::pair<NR::Point, bool> freeSnapTranslation(Inkscape::Snapper::PointType t,
std::vector<NR::Point> const &p,
void setSnapModeBBox(bool enabled);
void setSnapModeNode(bool enabled);
+ void setSnapModeGuide(bool enabled);
bool getSnapModeBBox() const;
bool getSnapModeNode() const;
+ bool getSnapModeGuide() const;
void setIncludeItemCenter(bool enabled) {
_include_item_center = enabled;
+ object.setIncludeItemCenter(enabled); //store a local copy in the object-snapper
+ //instead of passing it through many functions
}
bool getIncludeItemCenter() const {
diff --git a/src/snapper.cpp b/src/snapper.cpp
index 7a82fe1d462f384e3be8c9ff85146c1d3f768fff..5d39c6b02aeecd984b635b1bf6b677a2a44e09fd 100644 (file)
--- a/src/snapper.cpp
+++ b/src/snapper.cpp
Inkscape::Snapper::PointType const Inkscape::Snapper::SNAPPOINT_BBOX = 0x1;
Inkscape::Snapper::PointType const Inkscape::Snapper::SNAPPOINT_NODE = 0x2;
+Inkscape::Snapper::PointType const Inkscape::Snapper::SNAPPOINT_GUIDE = 0x4;
/**
* Construct new Snapper for named view.
diff --git a/src/snapper.h b/src/snapper.h
index 1440f64c7b44d53748c1d608834ae540d8ffe25e..085eb156e89fba925653b690d972b9bd6a967806 100644 (file)
--- a/src/snapper.h
+++ b/src/snapper.h
typedef int PointType;
static const PointType SNAPPOINT_NODE;
static const PointType SNAPPOINT_BBOX;
+ static const PointType SNAPPOINT_GUIDE;
void setSnapFrom(PointType t, bool s);
void setDistance(::NR::Coord d);
diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp
index 319e0ba39b4f330521942139b2d675d8460fd7cc..fa41060c2cd26267f2616936a38a20415ccef00d 100644 (file)
--- a/src/sp-namedview.cpp
+++ b/src/sp-namedview.cpp
@@ -155,6 +155,7 @@ static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape:
sp_object_read_attr(object, "inkscape:window-y");
sp_object_read_attr(object, "inkscape:snap-bbox");
sp_object_read_attr(object, "inkscape:snap-nodes");
+ sp_object_read_attr(object, "inkscape:snap-guide");
sp_object_read_attr(object, "inkscape:snap-center");
sp_object_read_attr(object, "inkscape:object-paths");
sp_object_read_attr(object, "inkscape:object-nodes");
@@ -355,6 +356,10 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
nv->snap_manager.setIncludeItemCenter(value ? sp_str_to_bool(value) : FALSE);
object->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+ case SP_ATTR_INKSCAPE_SNAP_GUIDE:
+ nv->snap_manager.setSnapModeGuide(value ? sp_str_to_bool(value) : FALSE);
+ object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
case SP_ATTR_INKSCAPE_OBJECT_PATHS:
nv->snap_manager.object.setSnapToItemPath(value ? sp_str_to_bool(value) : FALSE);
object->requestModified(SP_OBJECT_MODIFIED_FLAG);
index f301629e488041da6b7889852f2e237d8695b9e4..b62248cc3bbb1a17ddc5870fe64a5f5f71e206f0 100644 (file)
_rcbsnn.init (_("_Nodes"),
_("Snap nodes to grid lines, to guides, to paths, and to other nodes"),
"inkscape:snap-nodes", _wr);
- _rcbic.init (_("Include the object's center"),
- _("Also snap the rotation center of an object when snapping nodes"),
- "inkscape:snap-center", _wr);
+ _rcbsng.init (_("_Guides"),
+ _("While dragging a guide, snap to object nodes. (In 'Snapping to objects', 'Snap to nodes' must also be enabled)"),
+ "inkscape:snap-guide", _wr);
//Options for snapping to objects
- _rcbsnop.init (_("Snap to _paths"),
+ _rcbsnop.init (_("Snap to p_aths"),
_("Snap nodes to object paths"),
"inkscape:object-paths", _wr);
_rcbsnon.init (_("Snap to n_odes"),
- _("Snap nodes to object nodes"),
+ _("Snap nodes or guides to object nodes"),
"inkscape:object-nodes", _wr);
_rsu_sno.init (_("Snap _distance"), _("Snap at any dist_ance"),
_("Snapping distance, in screen pixels, for snapping to objects"),
_("If set, objects snap to the nearest guide, regardless of distance"),
"guidetolerance", _wr);
- std::list<Gtk::ToggleButton*> list;
- list.push_back(_rcbic._button);
- list.push_back(_rcbsnop._button);
- list.push_back(_rcbsnon._button);
- _rcbsnn.setSlaveButton(list);
-
+ //Some other options
+ _rcbic.init (_("_Include the object's center"),
+ _("Also snap the rotation center of an object when snapping nodes or guides"),
+ "inkscape:snap-center", _wr);
+ //Applies to both nodes and guides, but not to bboxes, that's why its located here
+ //Other options to locate here: e.g. visual snapping indicators on/off
Gtk::Label *label_g = manage (new Gtk::Label);
- label_g->set_markup (_("<b>Snapping from</b>"));
+ label_g->set_markup (_("<b>Snapping of</b>"));
Gtk::Label *label_o = manage (new Gtk::Label);
label_o->set_markup (_("<b>Snapping to objects</b>"));
Gtk::Label *label_gr = manage (new Gtk::Label);
label_gr->set_markup (_("<b>Snapping to grids</b>"));
Gtk::Label *label_gu = manage (new Gtk::Label);
label_gu->set_markup (_("<b>Snapping to guides</b>"));
+ Gtk::Label *label_m = manage (new Gtk::Label);
+ label_m->set_markup (_("<b>Miscellaneous</b>"));
Gtk::Widget *const array[] =
{
label_g, 0,
0, _rcbsnn._button,
- 0, 0, //_rcbic._button will be inserted here
+ //0, 0, //_rcbic._button will be inserted here
0, _rcbsnbb._button,
+ 0, _rcbsng._button,
0, 0,
0, 0,
0, 0,
0, 0,
label_gu, 0,
0, _rsu_gusn._vbox,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ label_m, 0,
+ 0, _rcbic._button
};
attach_all(_page_snap.table(), array, G_N_ELEMENTS(array));
-
- // add _rcbic manually to get some additional indenting
- _page_snap.table().attach(*_rcbic._button, 1, 3, 2, 3, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 18, 0);
}
/**
_rcbsnbb.setActive (nv->snap_manager.getSnapModeBBox());
_rcbsnn.setActive (nv->snap_manager.getSnapModeNode());
+ _rcbsng.setActive (nv->snap_manager.getSnapModeGuide());
_rcbic.setActive (nv->snap_manager.getIncludeItemCenter());
_rcbsnop.setActive(nv->snap_manager.object.getSnapToItemPath());
_rcbsnon.setActive(nv->snap_manager.object.getSnapToItemNode());
index 5db1c734fb83dff29c32ce1c34c68d902f3b25bf..846d9534179af581d04dfdfc0a39181955ce4a1b 100644 (file)
RegisteredUnitMenu _rum_gusn;
RegisteredColorPicker _rcp_gui, _rcp_hgui;
//---------------------------------------------------------------
- RegisteredCheckButton _rcbsnbb, _rcbsnn, _rcbic, _rcbsnop, _rcbsnon;
+ RegisteredCheckButton _rcbsnbb, _rcbsng, _rcbsnn, _rcbic, _rcbsnop, _rcbsnon;
RegisteredUnitMenu _rumso;
ToleranceSlider _rsu_sno, _rsu_sn, _rsu_gusn;
RegisteredRadioButtonPair _rrb_pix;