summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a778639)
raw | patch | inline | side by side (parent: a778639)
author | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Tue, 2 Jun 2009 04:36:17 +0000 (04:36 +0000) | ||
committer | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Tue, 2 Jun 2009 04:36:17 +0000 (04:36 +0000) |
diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp
index 3d8e88fba7ea1c3422bfac0d51c7808732fb4d6a..17b0778909e2ed34679a6f819a014a61619696d6 100644 (file)
--- a/src/desktop-events.cpp
+++ b/src/desktop-events.cpp
@@ -161,7 +161,7 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge
m.setup(desktop);
// We only have a temporary guide which is not stored in our document yet. Because the guide snapper only looks
// in the document for guides to snap to, we don't have to worry about a guide snapping to itself here
- m.guideSnap(event_dt, normal);
+ m.guideFreeSnap(event_dt, normal);
sp_guideline_set_position(SP_GUIDELINE(guide), from_2geom(event_dt));
desktop->set_coordinate_status(to_2geom(event_dt));
@@ -178,7 +178,7 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge
m.setup(desktop);
// We only have a temporary guide which is not stored in our document yet. Because the guide snapper only looks
// in the document for guides to snap to, we don't have to worry about a guide snapping to itself here
- m.guideSnap(event_dt, normal);
+ m.guideFreeSnap(event_dt, normal);
dragging = false;
@@ -226,17 +226,15 @@ int sp_dt_vruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw)
}
/* Guides */
-
-static Geom::Point drag_origin;
-
enum SPGuideDragType {
SP_DRAG_TRANSLATE,
- SP_DRAG_TRANSLATE_CONSTRAINED,
+ SP_DRAG_TRANSLATE_CONSTRAINED, // Is not being used currently!
SP_DRAG_ROTATE,
SP_DRAG_MOVE_ORIGIN,
SP_DRAG_NONE
};
+static Geom::Point drag_origin;
static SPGuideDragType drag_type = SP_DRAG_NONE;
gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data)
// which are dragged off the ruler, are being snapped in sp_dt_ruler_event
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, NULL, NULL, guide);
- m.guideSnap(motion_dt, to_2geom(guide->normal_to_line));
+ if (drag_type == SP_DRAG_MOVE_ORIGIN) {
+ // If we snap in guideConstrainedSnap() below, then motion_dt will be forced to be on the guide
+ // If we don't snap however, then it the origin should still be constrained to the guide
+ // So let's do that explicitly first:
+ Geom::Line line(guide->point_on_line, guide->angle());
+ Geom::Coord t = line.nearestPoint(motion_dt);
+ motion_dt = line.pointAt(t);
+ m.guideConstrainedSnap(motion_dt, *guide);
+ } else {
+ m.guideFreeSnap(motion_dt, guide->normal_to_line);
+ }
switch (drag_type) {
case SP_DRAG_TRANSLATE:
sp_guide_moveto(*guide, guide->point_on_line + motion_dt - drag_origin, false);
break;
}
- case SP_DRAG_TRANSLATE_CONSTRAINED:
+ case SP_DRAG_TRANSLATE_CONSTRAINED: // Is not being used currently!
{
Geom::Point pt_constr = Geom::constrain_angle(guide->point_on_line, motion_dt);
sp_guide_moveto(*guide, pt_constr, false);
}
case SP_DRAG_MOVE_ORIGIN:
{
- Geom::Line line(guide->point_on_line, guide->angle());
- Geom::Coord t = line.nearestPoint(motion_dt);
- sp_guide_moveto(*guide, line.pointAt(t), false);
- break;
+ sp_guide_moveto(*guide, motion_dt, false);
+ break;
}
case SP_DRAG_NONE:
g_assert_not_reached();
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, NULL, NULL, guide);
- m.guideSnap(event_dt, guide->normal_to_line);
+ if (drag_type == SP_DRAG_MOVE_ORIGIN) {
+ // If we snap in guideConstrainedSnap() below, then motion_dt will be forced to be on the guide
+ // If we don't snap however, then it the origin should still be constrained to the guide
+ // So let's do that explicitly first:
+ Geom::Line line(guide->point_on_line, guide->angle());
+ Geom::Coord t = line.nearestPoint(event_dt);
+ event_dt = line.pointAt(t);
+ m.guideConstrainedSnap(event_dt, *guide);
+ } else {
+ m.guideFreeSnap(event_dt, guide->normal_to_line);
+ }
if (sp_canvas_world_pt_inside_window(item->canvas, event_w)) {
switch (drag_type) {
sp_guide_moveto(*guide, guide->point_on_line + event_dt - drag_origin, true);
break;
}
- case SP_DRAG_TRANSLATE_CONSTRAINED:
+ case SP_DRAG_TRANSLATE_CONSTRAINED: // Is not being used currently!
{
Geom::Point pt_constr = Geom::constrain_angle(guide->point_on_line, event_dt);
sp_guide_moveto(*guide, pt_constr, true);
}
case SP_DRAG_MOVE_ORIGIN:
{
- Geom::Line line(guide->point_on_line, guide->angle());
- Geom::Coord t = line.nearestPoint(event_dt);
- sp_guide_moveto(*guide, line.pointAt(t), true);
- break;
+ sp_guide_moveto(*guide, event_dt, true);
+ break;
}
case SP_DRAG_NONE:
g_assert_not_reached();
index e73eef79675c607ec5caf8b1b614115078aacdec..081496fd0943bb2f03d7eba737ebc24fbabb79aa 100644 (file)
bool value = prefs->getBool("/options/snapindicator/value", true);
if (value) {
- // TRANSLATORS: undefined target for snapping
+ // TRANSLATORS: undefined target for snapping
gchar *target_name = _("UNDEFINED");
switch (p.getTarget()) {
case SNAPTARGET_UNDEFINED:
case SNAPSOURCE_GUIDE:
source_name = _("Guide");
break;
+ case SNAPSOURCE_GUIDE_ORIGIN:
+ source_name = _("Guide origin");
+ break;
case SNAPSOURCE_CONVEX_HULL_CORNER:
source_name = _("Convex hull corner");
break;
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 70377cb661fe77f22dafc401387a90b72e359216..5dd9350dcf11b3d8cc110ea13c6cae0f5a12744d 100644 (file)
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -330,6 +330,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
SPItem::BBoxType bbox_type = SPItem::GEOMETRIC_BBOX;
bool p_is_a_node = t & Inkscape::SnapPreferences::SNAPPOINT_NODE;
+ bool p_is_a_guide = t & Inkscape::SnapPreferences::SNAPPOINT_GUIDE;
if (_snapmanager->snapprefs.getSnapToBBoxPath()) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -365,7 +366,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
//Add the item's path to snap to
if (_snapmanager->snapprefs.getSnapToItemPath()) {
- if (!(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_node)) {
+ if (p_is_a_guide || !(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_node)) {
// Snapping to the path of characters is very cool, but for a large
// chunk of text this will take ages! So limit snapping to text paths
// containing max. 240 characters. Snapping the bbox will not be affected
@@ -399,7 +400,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
//Add the item's bounding box to snap to
if (_snapmanager->snapprefs.getSnapToBBoxPath()) {
- if (!(_snapmanager->snapprefs.getStrictSnapping() && p_is_a_node)) {
+ if (p_is_a_guide || !(_snapmanager->snapprefs.getStrictSnapping() && p_is_a_node)) {
// Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox
// of the item AND the bbox of the clipping path at the same time
if (!(*i).clip_or_mask) {
// This method is used to snap a guide to nodes, while dragging the guide around
-void Inkscape::ObjectSnapper::guideSnap(SnappedConstraints &sc,
+void Inkscape::ObjectSnapper::guideFreeSnap(SnappedConstraints &sc,
Geom::Point const &p,
Geom::Point const &guide_normal) const
{
snap_dim = ANGLED_GUIDE_TRANSL_SNAP;
}
- // We don't support ANGLED_GUIDE_ROT_SNAP yet.
+ _findCandidates(sp_document_root(_snapmanager->getDocument()), &it, true, Geom::Rect(p, p), snap_dim, false, Geom::identity());
+ _snapTranslatingGuideToNodes(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, guide_normal);
+ // _snapRotatingGuideToNodes has not been implemented yet.
+}
- // It would be cool to allow the user to rotate a guide by dragging it, instead of
- // only translating it. (For example when CTRL is pressed). We will need an UI part
- // for that first; and some important usability choices need to be made:
- // E.g. which point should be used for pivoting? A previously snapped point,
- // or a transformation center (which can be moved after clicking for the
- // second time on an object; but should this point then be constrained to the
- // line, or can it be located anywhere?)
+// This method is used to snap the origin of a guide to nodes/paths, while dragging the origin along the guide
+void Inkscape::ObjectSnapper::guideConstrainedSnap(SnappedConstraints &sc,
+ Geom::Point const &p,
+ Geom::Point const &guide_normal,
+ ConstraintLine const &c) const
+{
+ /* Get a list of all the SPItems that we will try to snap to */
+ std::vector<SPItem*> cand;
+ std::vector<SPItem const *> const it; //just an empty list
+
+ DimensionToSnap snap_dim;
+ if (guide_normal == to_2geom(component_vectors[Geom::Y])) {
+ snap_dim = GUIDE_TRANSL_SNAP_Y;
+ } else if (guide_normal == to_2geom(component_vectors[Geom::X])) {
+ snap_dim = GUIDE_TRANSL_SNAP_X;
+ } else {
+ snap_dim = ANGLED_GUIDE_TRANSL_SNAP;
+ }
_findCandidates(sp_document_root(_snapmanager->getDocument()), &it, true, Geom::Rect(p, p), snap_dim, false, Geom::identity());
_snapTranslatingGuideToNodes(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, guide_normal);
diff --git a/src/object-snapper.h b/src/object-snapper.h
index f220106e389a73fc97a409322db5aaf6c834e908..baa60a096fdc392049dfb48664aad4bb3563c8cb 100644 (file)
--- a/src/object-snapper.h
+++ b/src/object-snapper.h
GUIDE_TRANSL_SNAP_X, // For snapping a vertical guide (normal in the X-direction) to objects,
GUIDE_TRANSL_SNAP_Y, // For snapping a horizontal guide (normal in the Y-direction) to objects
ANGLED_GUIDE_TRANSL_SNAP, // For snapping an angled guide, while translating it accross the desktop
- ANGLED_GUIDE_ROT_SNAP, // For snapping an angled guide, while rotating it around some pivot point
TRANSL_SNAP_XY}; // All other cases; for snapping to objects, other than guides
- void guideSnap(SnappedConstraints &sc,
+ void guideFreeSnap(SnappedConstraints &sc,
Geom::Point const &p,
Geom::Point const &guide_normal) const;
+ void guideConstrainedSnap(SnappedConstraints &sc,
+ Geom::Point const &p,
+ Geom::Point const &guide_normal,
+ ConstraintLine const &c) const;
+
bool ThisSnapperMightSnap() const;
bool GuidesMightSnap() const;
diff --git a/src/snap.cpp b/src/snap.cpp
index 9ca9b78382ec5b68d8fc9bcdc325c3a2c16d11e1..aa0e4af5c511fa90c9fb2d735ceb651ff5ff6440 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
@@ -330,7 +330,8 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
return findBestSnap(p, source_type, sc, true);
}
-void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const
+// guideFreeSnap is used when dragging or rotating the guide
+void SnapManager::guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal) const
{
// This method is used to snap a guide to nodes or to other guides, while dragging the guide around. Will not snap to grids!
@@ -350,7 +351,7 @@ void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) con
// Snap to nodes
SnappedConstraints sc;
if (object.GuidesMightSnap()) {
- object.guideSnap(sc, p, guide_normal);
+ object.guideFreeSnap(sc, p, guide_normal);
}
// Snap to guides
@@ -364,6 +365,41 @@ void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) con
s.getPoint(p);
}
+// guideConstrainedSnap is used when dragging the origin of the guide along the guide itself
+void SnapManager::guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) const
+{
+ // This method is used to snap a guide to paths or to other guides, while dragging the origin of the guide around. Will not snap to grids!
+
+ if (_desktop->event_context && _desktop->event_context->_snap_window_open == false) {
+ g_warning("The current tool tries to snap, but it hasn't yet opened the snap window. Please report this!");
+ // When the context goes into dragging-mode, then Inkscape should call this: sp_event_context_snap_window_open(event_context);
+ }
+
+ if (!snapprefs.getSnapEnabledGlobally() || snapprefs.getSnapPostponedGlobally()) {
+ return;
+ }
+
+ if (!(object.ThisSnapperMightSnap() || snapprefs.getSnapToGuides())) {
+ return;
+ }
+
+ // Snap to nodes or paths
+ SnappedConstraints sc;
+ Inkscape::Snapper::ConstraintLine cl(guideline.point_on_line, Geom::rot90(guideline.normal_to_line));
+ if (object.ThisSnapperMightSnap()) {
+ object.constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, Inkscape::SNAPSOURCE_GUIDE_ORIGIN, true, Geom::OptRect(), cl, NULL);
+ }
+
+ // Snap to guides
+ if (snapprefs.getSnapToGuides()) {
+ guide.constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, Inkscape::SNAPSOURCE_GUIDE_ORIGIN, true, Geom::OptRect(), cl, NULL);
+ }
+
+ // We won't snap to grids, what's the use?
+
+ Inkscape::SnappedPoint const s = findBestSnap(p, Inkscape::SNAPSOURCE_GUIDE, sc, false);
+ s.getPoint(p);
+}
/**
* Main internal snapping method, which is called by the other, friendlier, public
diff --git a/src/snap.h b/src/snap.h
index 5290ef081ed3f90a98012439900b2981911cf573..ba920510f1b61d669ac880c3ecd4791f468d14d0 100644 (file)
--- a/src/snap.h
+++ b/src/snap.h
#include "guide-snapper.h"
#include "object-snapper.h"
#include "snap-preferences.h"
+//#include "sp-guide.h"
class SPNamedView;
bool first_point = true,
Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
- void guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const;
+ void guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal) const;
+ void guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) const;
Inkscape::SnappedPoint freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
std::vector<std::pair<Geom::Point, int> > const &p,
diff --git a/src/snapped-point.h b/src/snapped-point.h
index ee7c12aa7e9687d785401a7fad2a51de18ca5f0b..d071afddc7c9f29120fbe869940380a5b2436892 100644 (file)
--- a/src/snapped-point.h
+++ b/src/snapped-point.h
SNAPSOURCE_HANDLE,
SNAPSOURCE_PATH_INTERSECTION,
SNAPSOURCE_GUIDE,
+ SNAPSOURCE_GUIDE_ORIGIN,
SNAPSOURCE_CONVEX_HULL_CORNER,
SNAPSOURCE_ELLIPSE_QUADRANT_POINT,
SNAPSOURCE_CENTER, // of ellipse