summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 606e46e)
raw | patch | inline | side by side (parent: 606e46e)
author | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Mon, 22 Feb 2010 22:18:29 +0000 (23:18 +0100) | ||
committer | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Mon, 22 Feb 2010 22:18:29 +0000 (23:18 +0100) |
2) Always apply the constraint when asking for a constrained snap
3) Show snap indicator when applying a constraint
3) Show snap indicator when applying a constraint
src/display/snap-indicator.cpp | patch | blob | history | |
src/pen-context.cpp | patch | blob | history | |
src/snap-enums.h | patch | blob | history | |
src/snap.cpp | patch | blob | history |
index c0ed322e417fdde6ee3c1e6f66cb4edfe3cb9c0b..25b5090c1f8c75adb670daaab105798cd0d97e6e 100644 (file)
@@ -143,6 +143,9 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap
case SNAPTARGET_CONSTRAINED_ANGLE:
target_name = _("constrained angle");
break;
+ case SNAPTARGET_CONSTRAINT:
+ target_name = _("constraint");
+ break;
default:
g_warning("Snap target has not yet been defined!");
break;
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index 74c402c425284d823c2e83b8ac1b7784311dec04..bb52b1950cd2e3661bbe7b9642271173b6be1cee 100644 (file)
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
static SPDrawContextClass *pen_parent_class;
static int pen_next_paraxial_direction(const SPPenContext *const pc, Geom::Point const &pt, Geom::Point const &origin, guint state);
-static void pen_set_to_nearest_horiz_vert(const SPPenContext *const pc, Geom::Point &pt, guint const state);
+static void pen_set_to_nearest_horiz_vert(const SPPenContext *const pc, Geom::Point &pt, guint const state, bool snap);
static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical
static void
spdc_endpoint_snap(SPPenContext const *const pc, Geom::Point &p, guint const state)
{
- if ((state & GDK_CONTROL_MASK)) { //CTRL enables angular snapping
+ if ((state & GDK_CONTROL_MASK) && !pc->polylines_paraxial) { //CTRL enables angular snapping
if (pc->npoints > 0) {
spdc_endpoint_snap_rotation(pc, p, pc->p[0], state);
}
} else {
- if (!(state & GDK_SHIFT_MASK)) { //SHIFT disables all snapping, except the angular snapping above
- //After all, the user explicitely asked for angular snapping by
- //pressing CTRL
+ // We cannot use shift here to disable snapping because the shift-key is already used
+ // to toggle the paraxial direction; if the user wants to disable snapping (s)he will
+ // have to use the %-key, the menu, or the snap toolbar
+ if ((pc->npoints > 0) && pc->polylines_paraxial) {
+ // snap constrained
+ pen_set_to_nearest_horiz_vert(pc, p, state, true);
+ } else {
+ // snap freely
spdc_endpoint_snap_free(pc, p, state);
}
}
- if (pc->polylines_paraxial) {
- // TODO: must we avoid one of the snaps in the previous case distinction in some situations?
- pen_set_to_nearest_horiz_vert(pc, p, state);
- }
}
/**
@@ -507,11 +508,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
/* Create green anchor */
p = event_dt;
- if (!pc->polylines_paraxial) {
- // only snap the starting point if we're not in horizontal/vertical mode
- // because otherwise it gets shifted; TODO: why do we snap here at all??
- spdc_endpoint_snap(pc, p, bevent.state);
- }
+ spdc_endpoint_snap(pc, p, bevent.state);
pc->green_anchor = sp_draw_anchor_new(pc, pc->green_curve, TRUE, p);
}
spdc_pen_set_initial_point(pc, p);
@@ -1259,7 +1256,7 @@ spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point const p, bool
if (pc->polylines_paraxial && !statusbar) {
// we are drawing horizontal/vertical lines and hit an anchor; draw an L-shaped path
Geom::Point intermed = p;
- pen_set_to_nearest_horiz_vert(pc, intermed, status);
+ pen_set_to_nearest_horiz_vert(pc, intermed, status, false);
pc->red_curve->lineto(intermed);
pc->red_curve->lineto(p);
is_curve = false;
}
}
-void pen_set_to_nearest_horiz_vert(const SPPenContext *const pc, Geom::Point &pt, guint const state)
+void pen_set_to_nearest_horiz_vert(const SPPenContext *const pc, Geom::Point &pt, guint const state, bool snap)
{
Geom::Point const &origin = pc->p[0];
int next_dir = pen_next_paraxial_direction(pc, pt, origin, state);
- if (next_dir == 0) {
- // line is forced to be horizontal
- pt[Geom::Y] = origin[Geom::Y];
+ if (!snap) {
+ if (next_dir == 0) {
+ // line is forced to be horizontal
+ pt[Geom::Y] = origin[Geom::Y];
+ } else {
+ // line is forced to be vertical
+ pt[Geom::X] = origin[Geom::X];
+ }
} else {
- // line is forced to be vertical
- pt[Geom::X] = origin[Geom::X];
+ // Create a horizontal or vertical constraint line
+ Inkscape::Snapper::ConstraintLine cl(origin, next_dir ? Geom::Point(0, 1) : Geom::Point(1, 0));
+
+ // Snap along the constraint line; if we didn't snap then still the constraint will be applied
+ SnapManager &m = pc->desktop->namedview->snap_manager;
+
+ Inkscape::Selection *selection = sp_desktop_selection (pc->desktop);
+ // selection->singleItem() is the item that is currently being drawn. This item will not be snapped to (to avoid self-snapping)
+ // TODO: Allow snapping to the stationary parts of the item, and only ignore the last segment
+
+ m.setup(pc->desktop, true, selection->singleItem());
+ m.constrainedSnapReturnByRef(pt, Inkscape::SNAPSOURCE_NODE_HANDLE, cl);
}
}
diff --git a/src/snap-enums.h b/src/snap-enums.h
index 60893de6afa1b9fdae60e1c6a222479bc6d9e61f..3d03711e3361054206b205b79af7c13e85a70cab 100644 (file)
--- a/src/snap-enums.h
+++ b/src/snap-enums.h
SNAPTARGET_CENTER, // of ellipse
SNAPTARGET_CORNER, // of image or of rectangle
SNAPTARGET_TEXT_BASELINE,
- SNAPTARGET_CONSTRAINED_ANGLE
+ SNAPTARGET_CONSTRAINED_ANGLE,
+ SNAPTARGET_CONSTRAINT
};
enum SnapSourceType {
diff --git a/src/snap.cpp b/src/snap.cpp
index 1033b0a2c39f7e4f87d2ce608114d3decb2473de..53832994f386c2a616bdaee75dd86478b61bb3ad 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
@@ -357,9 +357,14 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapCandidatePoint
// First project the mouse pointer onto the constraint
Geom::Point pp = constraint.projection(p.getPoint());
+ Inkscape::SnappedPoint no_snap = Inkscape::SnappedPoint(pp, p.getSourceType(), p.getSourceNum(), Inkscape::SNAPTARGET_CONSTRAINT, Geom::L2(pp - p.getPoint()), 0, false, false);
+
if (!someSnapperMightSnap()) {
- // The constraint should always be enforce, so we return pp here instead of p
- return Inkscape::SnappedPoint(pp, p.getSourceType(), p.getSourceNum(), Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+ // The constraint should always be enforced, so we return pp here instead of p
+ if (_snapindicator) {
+ _desktop->snapindicator->set_new_snaptarget(no_snap);
+ }
+ return no_snap;
}
// Then try to snap the projected point
@@ -371,7 +376,17 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapCandidatePoint
(*i)->constrainedSnap(sc, candidate, bbox_to_snap, constraint, &_items_to_ignore);
}
- return findBestSnap(candidate, sc, true);
+ Inkscape::SnappedPoint result = findBestSnap(candidate, sc, true);
+
+ if (result.getSnapped()) {
+ return result;
+ }
+
+ // The constraint should always be enforced, so we return pp here instead of p
+ if (_snapindicator) {
+ _desktop->snapindicator->set_new_snaptarget(no_snap);
+ }
+ return no_snap;
}
/**