diff --git a/src/object-edit.cpp b/src/object-edit.cpp
index 0719a59d319e2f2fc30cb7bd877356f5d66a19e5..6b83413e481c184a2a0745f7d8381e2a1a4fadcf 100644 (file)
--- a/src/object-edit.cpp
+++ b/src/object-edit.cpp
RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &origin, guint state)
{
SPRect *rect = SP_RECT(item);
- Geom::Point const s = snap_knot_position(p);
+
+ Geom::Point s = p;
if (state & GDK_CONTROL_MASK) {
// original width/height when drag started
@@ -267,41 +268,56 @@ RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &or
gdouble const h_orig = (origin[Geom::Y] - rect->y.computed);
//original ratio
- gdouble const ratio = (w_orig / h_orig);
+ gdouble ratio = (w_orig / h_orig);
// mouse displacement since drag started
- gdouble const minx = s[Geom::X] - origin[Geom::X];
- gdouble const miny = s[Geom::Y] - origin[Geom::Y];
+ gdouble minx = p[Geom::X] - origin[Geom::X];
+ gdouble miny = p[Geom::Y] - origin[Geom::Y];
- if (fabs(minx) > fabs(miny)) {
+ Geom::Point p_handle(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed);
- // snap to horizontal or diagonal
- rect->width.computed = MAX(w_orig + minx, 0);
+ if (fabs(minx) > fabs(miny)) {
+ // snap to horizontal or diagonal
if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) {
// closer to the diagonal and in same-sign quarters, change both using ratio
- rect->height.computed = MAX(h_orig + minx / ratio, 0);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(-ratio, -1)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->height.computed = MAX(h_orig + minx / ratio, 0);
} else {
// closer to the horizontal, change only width, height is h_orig
- rect->height.computed = MAX(h_orig, 0);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(-1, 0)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->height.computed = MAX(h_orig, 0);
}
+ rect->width.computed = MAX(w_orig + minx, 0);
} else {
// snap to vertical or diagonal
- rect->height.computed = MAX(h_orig + miny, 0);
if (miny != 0 && fabs(minx/miny) > 0.5 * ratio && (SGN(minx) == SGN(miny))) {
// closer to the diagonal and in same-sign quarters, change both using ratio
- rect->width.computed = MAX(w_orig + miny * ratio, 0);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(-ratio, -1)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->width.computed = MAX(w_orig + miny * ratio, 0);
} else {
// closer to the vertical, change only height, width is w_orig
- rect->width.computed = MAX(w_orig, 0);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(0, -1)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->width.computed = MAX(w_orig, 0);
}
+ rect->height.computed = MAX(h_orig + miny, 0);
+
}
rect->width._set = rect->height._set = true;
} else {
// move freely
- rect->width.computed = MAX(s[Geom::X] - rect->x.computed, 0);
+ s = snap_knot_position(p);
+ rect->width.computed = MAX(s[Geom::X] - rect->x.computed, 0);
rect->height.computed = MAX(s[Geom::Y] - rect->y.computed, 0);
rect->width._set = rect->height._set = true;
}
@@ -339,53 +355,66 @@ RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin
gdouble w_orig = opposite_x - origin[Geom::X];
gdouble h_orig = opposite_y - origin[Geom::Y];
- Geom::Point const s = snap_knot_position(p);
+ Geom::Point s = p;
+ Geom::Point p_handle(rect->x.computed, rect->y.computed);
// mouse displacement since drag started
- gdouble minx = s[Geom::X] - origin[Geom::X];
- gdouble miny = s[Geom::Y] - origin[Geom::Y];
+ gdouble minx = p[Geom::X] - origin[Geom::X];
+ gdouble miny = p[Geom::Y] - origin[Geom::Y];
if (state & GDK_CONTROL_MASK) {
//original ratio
gdouble ratio = (w_orig / h_orig);
if (fabs(minx) > fabs(miny)) {
-
- // snap to horizontal or diagonal
- rect->x.computed = MIN(s[Geom::X], opposite_x);
- rect->width.computed = MAX(w_orig - minx, 0);
+ // snap to horizontal or diagonal
if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) {
// closer to the diagonal and in same-sign quarters, change both using ratio
- rect->y.computed = MIN(origin[Geom::Y] + minx / ratio, opposite_y);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(-ratio, -1)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->y.computed = MIN(origin[Geom::Y] + minx / ratio, opposite_y);
rect->height.computed = MAX(h_orig - minx / ratio, 0);
} else {
// closer to the horizontal, change only width, height is h_orig
- rect->y.computed = MIN(origin[Geom::Y], opposite_y);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(-1, 0)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->y.computed = MIN(origin[Geom::Y], opposite_y);
rect->height.computed = MAX(h_orig, 0);
}
-
+ rect->x.computed = MIN(s[Geom::X], opposite_x);
+ rect->width.computed = MAX(w_orig - minx, 0);
} else {
-
// snap to vertical or diagonal
- rect->y.computed = MIN(s[Geom::Y], opposite_y);
- rect->height.computed = MAX(h_orig - miny, 0);
- if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) {
+ if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) {
// closer to the diagonal and in same-sign quarters, change both using ratio
- rect->x.computed = MIN(origin[Geom::X] + miny * ratio, opposite_x);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(-ratio, -1)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->x.computed = MIN(origin[Geom::X] + miny * ratio, opposite_x);
rect->width.computed = MAX(w_orig - miny * ratio, 0);
} else {
// closer to the vertical, change only height, width is w_orig
- rect->x.computed = MIN(origin[Geom::X], opposite_x);
+ s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(p_handle, Geom::Point(0, -1)));
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+ rect->x.computed = MIN(origin[Geom::X], opposite_x);
rect->width.computed = MAX(w_orig, 0);
}
-
+ rect->y.computed = MIN(s[Geom::Y], opposite_y);
+ rect->height.computed = MAX(h_orig - miny, 0);
}
rect->width._set = rect->height._set = rect->x._set = rect->y._set = true;
} else {
// move freely
- rect->x.computed = MIN(s[Geom::X], opposite_x);
+ s = snap_knot_position(p);
+ minx = s[Geom::X] - origin[Geom::X];
+ miny = s[Geom::Y] - origin[Geom::Y];
+
+ rect->x.computed = MIN(s[Geom::X], opposite_x);
rect->width.computed = MAX(w_orig - minx, 0);
rect->y.computed = MIN(s[Geom::Y], opposite_y);
rect->height.computed = MAX(h_orig - miny, 0);
@@ -901,7 +930,7 @@ ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderRelea
_("Adjust ellipse <b>height</b>, with <b>Ctrl</b> to make circle"),
SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR);
entity_start->create(desktop, item, this,
- _("Position the <b>start point</b> of the arc or segment; with <b>Ctrl</b>"
+ _("Position the <b>start point</b> of the arc or segment; with <b>Ctrl</b> "
"to snap angle; drag <b>inside</b> the ellipse for arc, <b>outside</b> for segment"),
SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR);
entity_end->create(desktop, item, this,
* [control] constrain inner arg to round per PI/4
*/
void
-SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
+SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12);
@@ -1092,10 +1121,16 @@ SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &/
gdouble dx = p[Geom::X] - spiral->cx;
gdouble dy = p[Geom::Y] - spiral->cy;
+ gdouble moved_y = p[Geom::Y] - origin[Geom::Y];
+
if (state & GDK_MOD1_MASK) {
// adjust divergence by vertical drag, relative to rad
- double new_exp = (spiral->rad + dy)/(spiral->rad);
- spiral->exp = new_exp > 0? new_exp : 0;
+ if (spiral->rad > 0) {
+ double exp_delta = 0.1*moved_y/(spiral->rad); // arbitrary multiplier to slow it down
+ spiral->exp += exp_delta;
+ if (spiral->exp < 1e-3)
+ spiral->exp = 1e-3;
+ }
} else {
// roll/unroll from inside
gdouble arg_t0;