summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 672b20e)
raw | patch | inline | side by side (parent: 672b20e)
author | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Sat, 30 Jan 2010 22:04:33 +0000 (23:04 +0100) | ||
committer | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Sat, 30 Jan 2010 22:04:33 +0000 (23:04 +0100) |
22 files changed:
diff --git a/src/arc-context.cpp b/src/arc-context.cpp
index 9cb6e822285101a46d81eb2e12b1996ff5e5f297..ccaaedd14e6d6f5be8e24d37a462400c882673a2 100644 (file)
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
static void sp_arc_context_finish(SPEventContext *ec)
{
SPArcContext *ac = SP_ARC_CONTEXT(ec);
- SPDesktop *desktop = ec->desktop;
+ SPDesktop *desktop = ec->desktop;
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME);
- sp_arc_finish(ac);
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME);
+ sp_arc_finish(ac);
ac->sel_changed_connection.disconnect();
if (((SPEventContextClass *) parent_class)->finish) {
- ((SPEventContextClass *) parent_class)->finish(ec);
- }
+ ((SPEventContextClass *) parent_class)->finish(ec);
+ }
}
static void sp_arc_context_dispose(GObject *object)
@@ -274,6 +274,13 @@ static gint sp_arc_context_root_handler(SPEventContext *event_context, GdkEvent
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
+ } else if (sp_event_context_knot_mouseover(ac)){
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point motion_dt(desktop->w2d(motion_w));
+ m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE));
}
break;
case GDK_BUTTON_RELEASE:
sp_event_context_discard_delayed_snap_event(event_context);
if (!event_context->within_tolerance) {
// we've been dragging, finish the arc
- sp_arc_finish(ac);
+ sp_arc_finish(ac);
} else if (event_context->item_to_select) {
// no dragging, select clicked item if any
if (event->button.state & GDK_SHIFT_MASK) {
@@ -335,14 +342,14 @@ static gint sp_arc_context_root_handler(SPEventContext *event_context, GdkEvent
}
break;
case GDK_Escape:
- if (dragging) {
- dragging = false;
- sp_event_context_discard_delayed_snap_event(event_context);
- // if drawing, cancel, otherwise pass it up for deselecting
- sp_arc_cancel(ac);
- ret = TRUE;
- }
- break;
+ if (dragging) {
+ dragging = false;
+ sp_event_context_discard_delayed_snap_event(event_context);
+ // if drawing, cancel, otherwise pass it up for deselecting
+ sp_arc_cancel(ac);
+ ret = TRUE;
+ }
+ break;
case GDK_space:
if (dragging) {
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
if (ac->item != NULL) {
- SPGenericEllipse *ge = SP_GENERICELLIPSE(SP_ARC(ac->item));
- if (ge->rx.computed == 0 || ge->ry.computed == 0) {
- sp_arc_cancel(ac); // Don't allow the creating of zero sized arc, for example when the start and and point snap to the snap grid point
- return;
- }
+ SPGenericEllipse *ge = SP_GENERICELLIPSE(SP_ARC(ac->item));
+ if (ge->rx.computed == 0 || ge->ry.computed == 0) {
+ sp_arc_cancel(ac); // Don't allow the creating of zero sized arc, for example when the start and and point snap to the snap grid point
+ return;
+ }
- SPDesktop *desktop = SP_EVENT_CONTEXT(ac)->desktop;
+ SPDesktop *desktop = SP_EVENT_CONTEXT(ac)->desktop;
SP_OBJECT(ac->item)->updateRepr();
static void sp_arc_cancel(SPArcContext *ac)
{
- SPDesktop *desktop = SP_EVENT_CONTEXT(ac)->desktop;
+ SPDesktop *desktop = SP_EVENT_CONTEXT(ac)->desktop;
- sp_desktop_selection(desktop)->clear();
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0);
+ sp_desktop_selection(desktop)->clear();
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0);
if (ac->item != NULL) {
- SP_OBJECT(ac->item)->deleteObject();
- ac->item = NULL;
+ SP_OBJECT(ac->item)->deleteObject();
+ ac->item = NULL;
}
ac->within_tolerance = false;
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index ad9c51f0fda674e20c289a984beb2294b4f098dd..bf9bd7b6faa49bf97c017d08b161de8f12a2a62b 100644 (file)
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
@@ -358,8 +358,8 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
}
if (!bc->extruded) {
- bc->drag_ptB = from_2geom(motion_dt);
- bc->drag_ptC = from_2geom(motion_dt);
+ bc->drag_ptB = from_2geom(motion_dt);
+ bc->drag_ptC = from_2geom(motion_dt);
bc->drag_ptB_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(motion_dt), 0, Proj::Z);
bc->drag_ptC_proj = bc->drag_ptB_proj;
@@ -387,6 +387,13 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
sp_box3d_drag(*bc, event->motion.state);
ret = TRUE;
+ } else if (sp_event_context_knot_mouseover(bc)) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point motion_dt(desktop->w2d(motion_w));
+ m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE));
}
break;
case GDK_BUTTON_RELEASE:
index bfdef103213dfb7f8775cd97592c6ef12dbbd3ba..294e129b3f4e40bdda229aeedd30fd44d9bbb9f8 100644 (file)
@@ -976,6 +976,9 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons
/* This is perfectly valid */
break;
default:
+ if (sp_event_context_knot_mouseover(cc)) {
+ m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE));
+ }
break;
}
}
index dd80524f1614eafe20f1ab43e2e42723f87dc758..b135dd9fe7640c1cf051df06411562ae0076afbd 100644 (file)
}
void
-SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p)
+SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap)
{
remove_snaptarget(); //only display one snaptarget at a time
"anchor", GTK_ANCHOR_CENTER,
"size", 10.0,
"stroked", TRUE,
- "stroke_color", 0xff0000ff,
+ "stroke_color", pre_snap ? 0x7f7f7fff : 0xff0000ff,
"mode", SP_KNOT_MODE_XOR,
"shape", SP_KNOT_SHAPE_DIAMOND,
NULL );
"anchor", GTK_ANCHOR_CENTER,
"size", 10.0,
"stroked", TRUE,
- "stroke_color", 0xff0000ff,
+ "stroke_color", pre_snap ? 0x7f7f7fff : 0xff0000ff,
"mode", SP_KNOT_MODE_XOR,
"shape", SP_KNOT_SHAPE_CROSS,
NULL );
SP_CTRL(canvasitem)->moveto(p.getPoint());
_snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val);
+ // Display the tooltip, which reveals the type of snap source and the type of snap target
gchar *tooltip_str = g_strconcat(source_name, _(" to "), target_name, NULL);
Geom::Point tooltip_pos = p.getPoint() + _desktop->w2d(Geom::Point(15, -15));
SPCanvasItem *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(_desktop), _desktop, tooltip_pos, tooltip_str);
+ if (pre_snap) {
+ SP_CANVASTEXT(canvas_tooltip)->rgba = 0x7f7f7fff;
+ }
g_free(tooltip_str);
sp_canvastext_set_anchor((SPCanvasText* )canvas_tooltip, -1, 1);
_snaptarget_tooltip = _desktop->add_temporary_canvasitem(canvas_tooltip, timeout_val);
+ // Display the bounding box, if we snapped to one
Geom::OptRect const bbox = p.getTargetBBox();
if (bbox) {
SPCanvasItem* box = sp_canvas_item_new(sp_desktop_tempgroup (_desktop),
NULL);
SP_CTRLRECT(box)->setRectangle(*bbox);
- SP_CTRLRECT(box)->setColor(0xff0000ff, 0, 0);
+ SP_CTRLRECT(box)->setColor(pre_snap ? 0x7f7f7fff : 0xff0000ff, 0, 0);
SP_CTRLRECT(box)->setDashed(true);
sp_canvas_item_move_to_z(box, 0);
_snaptarget_bbox = _desktop->add_temporary_canvasitem(box, timeout_val);
index feb118baabdf2bc9bea0855cbba69c984a903308..259af8ae6d9c73547d3d4f94214c373245700c57 100644 (file)
SnapIndicator(SPDesktop *desktop);
virtual ~SnapIndicator();
- void set_new_snaptarget(Inkscape::SnappedPoint const &p);
+ void set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap = false);
void remove_snaptarget();
void set_new_snapsource(Inkscape::SnapCandidatePoint const &p);
diff --git a/src/event-context.cpp b/src/event-context.cpp
index 5592741d9a525cd48d0258c76c0c4e523a660040..1e47b9d9da4be0790ec4094543c7138eca6f8a2a 100644 (file)
--- a/src/event-context.cpp
+++ b/src/event-context.cpp
#include "selcue.h"
#include "lpe-tool-context.h"
#include "ui/tool/control-point.h"
+#include "shape-editor.h"
static void sp_event_context_class_init(SPEventContextClass *klass);
static void sp_event_context_init(SPEventContext *event_context);
return ret;
}
+bool sp_event_context_knot_mouseover(SPEventContext *ec)
+{
+ if (ec->shape_editor) {
+ return !(ec->shape_editor->knot_mouseover());
+ }
+
+ return false;
+}
+
/**
* @brief An observer that relays pref changes to the derived classes
*/
diff --git a/src/event-context.h b/src/event-context.h
index 97abee0d5a24a1d4298aed411e87543b7799c5ba..be06f0a3411eb490b57113849fe2d974fdf7986e 100644 (file)
--- a/src/event-context.h
+++ b/src/event-context.h
@@ -171,6 +171,7 @@ SPItem *sp_event_context_find_item (SPDesktop *desktop, Geom::Point const &p, bo
SPItem *sp_event_context_over_item (SPDesktop *desktop, SPItem *item, Geom::Point const &p);
ShapeEditor *sp_event_context_get_shape_editor (SPEventContext *ec);
+bool sp_event_context_knot_mouseover(SPEventContext *ec);
void ec_shape_event_attr_changed(Inkscape::XML::Node *shape_repr,
gchar const *name, gchar const *old_value, gchar const *new_value,
index a1fcf582b8c3f46ab6b814c3cbc760c8f20eb086..b73d258fdddfb31d1216cdd3a8b6eae2aa45891c 100644 (file)
--- a/src/gradient-context.cpp
+++ b/src/gradient-context.cpp
@@ -593,6 +593,15 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
ret = TRUE;
} else {
+ if (sp_event_context_knot_mouseover(event_context)) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt = event_context->desktop->w2d(motion_w);
+ m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE));
+ }
+
bool over_line = false;
if (drag->lines) {
for (GSList *l = drag->lines; l != NULL; l = l->next) {
diff --git a/src/knot.cpp b/src/knot.cpp
index b17e41b243bf9b640365be12de1f755cd5f9b7f4..cc26653e5f7d996af169d7556412be1a80090c11 100644 (file)
--- a/src/knot.cpp
+++ b/src/knot.cpp
*/
static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot)
{
- g_assert(knot != NULL);
+ g_assert(knot != NULL);
g_assert(SP_IS_KNOT(knot));
/* Run client universal event handler, if present */
@@ -302,7 +302,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
switch (event->type) {
- case GDK_2BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
if (event->button.button == 1) {
g_signal_emit(knot, knot_signals[DOUBLECLICKED], 0, event->button.state);
@@ -311,23 +311,23 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
consumed = TRUE;
}
break;
- case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_PRESS:
if (event->button.button == 1 && !knot->desktop->event_context->space_panning) {
Geom::Point const p = knot->desktop->w2d(Geom::Point(event->button.x, event->button.y));
sp_knot_start_dragging(knot, p, (gint) event->button.x, (gint) event->button.y, event->button.time);
- consumed = TRUE;
+ consumed = TRUE;
}
break;
- case GDK_BUTTON_RELEASE:
- if (event->button.button == 1 && !knot->desktop->event_context->space_panning) {
- // If we have any pending snap event, then invoke it now
- if (knot->desktop->event_context->_delayed_snap_event) {
- sp_event_context_snap_watchdog_callback(knot->desktop->event_context->_delayed_snap_event);
- }
+ case GDK_BUTTON_RELEASE:
+ if (event->button.button == 1 && !knot->desktop->event_context->space_panning) {
+ // If we have any pending snap event, then invoke it now
+ if (knot->desktop->event_context->_delayed_snap_event) {
+ sp_event_context_snap_watchdog_callback(knot->desktop->event_context->_delayed_snap_event);
+ }
- sp_event_context_discard_delayed_snap_event(knot->desktop->event_context);
+ sp_event_context_discard_delayed_snap_event(knot->desktop->event_context);
- knot->pressure = 0;
+ knot->pressure = 0;
if (transform_escaped) {
transform_escaped = false;
consumed = TRUE;
@@ -356,7 +356,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
}
}
break;
- case GDK_MOTION_NOTIFY:
+ case GDK_MOTION_NOTIFY:
if (grabbed && !knot->desktop->event_context->space_panning) {
consumed = TRUE;
@@ -389,7 +389,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
moved = TRUE;
}
break;
- case GDK_ENTER_NOTIFY:
+ case GDK_ENTER_NOTIFY:
sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE);
sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);
@@ -401,7 +401,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
moved = FALSE;
consumed = TRUE;
break;
- case GDK_LEAVE_NOTIFY:
+ case GDK_LEAVE_NOTIFY:
sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE);
sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);
@@ -413,35 +413,35 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
moved = FALSE;
consumed = TRUE;
break;
- case GDK_KEY_PRESS: // keybindings for knot
+ case GDK_KEY_PRESS: // keybindings for knot
switch (get_group0_keyval(&event->key)) {
- case GDK_Escape:
- sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);
- if (!nograb) {
- sp_canvas_item_ungrab(knot->item, event->button.time);
- }
- if (moved) {
- sp_knot_set_flag(knot,
- SP_KNOT_DRAGGING,
- FALSE);
- g_signal_emit(knot,
- knot_signals[UNGRABBED], 0,
- event->button.state);
- sp_document_undo(sp_desktop_document(knot->desktop));
- knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled."));
- transform_escaped = true;
- consumed = TRUE;
- }
- grabbed = FALSE;
- moved = FALSE;
- sp_event_context_discard_delayed_snap_event(knot->desktop->event_context);
- break;
- default:
- consumed = FALSE;
- break;
- }
- break;
- default:
+ case GDK_Escape:
+ sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);
+ if (!nograb) {
+ sp_canvas_item_ungrab(knot->item, event->button.time);
+ }
+ if (moved) {
+ sp_knot_set_flag(knot,
+ SP_KNOT_DRAGGING,
+ FALSE);
+ g_signal_emit(knot,
+ knot_signals[UNGRABBED], 0,
+ event->button.state);
+ sp_document_undo(sp_desktop_document(knot->desktop));
+ knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled."));
+ transform_escaped = true;
+ consumed = TRUE;
+ }
+ grabbed = FALSE;
+ moved = FALSE;
+ sp_event_context_discard_delayed_snap_event(knot->desktop->event_context);
+ break;
+ default:
+ consumed = FALSE;
+ break;
+ }
+ break;
+ default:
break;
}
@@ -452,14 +452,14 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot
void sp_knot_handler_request_position(GdkEvent *event, SPKnot *knot)
{
- Geom::Point const motion_w(event->motion.x, event->motion.y);
- Geom::Point const motion_dt = knot->desktop->w2d(motion_w);
- Geom::Point p = motion_dt - knot->grabbed_rel_pos;
- sp_knot_request_position (knot, p, event->motion.state);
- knot->desktop->scroll_to_point (motion_dt);
- knot->desktop->set_coordinate_status(knot->pos); // display the coordinate of knot, not cursor - they may be different!
- if (event->motion.state & GDK_BUTTON1_MASK)
- gobble_motion_events(GDK_BUTTON1_MASK);
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt = knot->desktop->w2d(motion_w);
+ Geom::Point p = motion_dt - knot->grabbed_rel_pos;
+ sp_knot_request_position (knot, p, event->motion.state);
+ knot->desktop->scroll_to_point (motion_dt);
+ knot->desktop->set_coordinate_status(knot->pos); // display the coordinate of knot, not cursor - they may be different!
+ if (event->motion.state & GDK_BUTTON1_MASK)
+ gobble_motion_events(GDK_BUTTON1_MASK);
}
/**
}
switch (flag) {
- case SP_KNOT_VISIBLE:
+ case SP_KNOT_VISIBLE:
if (set) {
sp_canvas_item_show(knot->item);
} else {
sp_canvas_item_hide(knot->item);
}
break;
- case SP_KNOT_MOUSEOVER:
- case SP_KNOT_DRAGGING:
+ case SP_KNOT_MOUSEOVER:
+ case SP_KNOT_DRAGGING:
sp_knot_set_ctrl_state(knot);
break;
- case SP_KNOT_GRABBED:
+ case SP_KNOT_GRABBED:
break;
- default:
+ default:
g_assert_not_reached();
break;
}
diff --git a/src/knotholder.cpp b/src/knotholder.cpp
index 45cb140c019883787c478e928668a85c73511fd7..314ad807c5a1de383472327124a322bff06cfd6a 100644 (file)
--- a/src/knotholder.cpp
+++ b/src/knotholder.cpp
}
}
+/**
+ * \brief Returns true if at least one of the KnotHolderEntities has the mouse hovering above it
+ */
+bool KnotHolder::knot_mouseover()
+{
+ for(std::list<KnotHolderEntity *>::iterator i = entity.begin(); i != entity.end(); ++i) {
+ SPKnot *knot = (*i)->knot;
+ if (knot && (knot->flags & SP_KNOT_MOUSEOVER)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void
KnotHolder::knot_clicked_handler(SPKnot *knot, guint state)
{
diff --git a/src/knotholder.h b/src/knotholder.h
index fa1abd071efd4e226efdfcc5fb470f803b8c3184..0b37d211c52079b2358621fd9a964f02b8cc5b30 100644 (file)
--- a/src/knotholder.h
+++ b/src/knotholder.h
const SPItem *getItem() { return item; }
+ bool knot_mouseover();
+
friend class ShapeEditor;
protected:
diff --git a/src/object-edit.cpp b/src/object-edit.cpp
index 6b83413e481c184a2a0745f7d8381e2a1a4fadcf..1d81aa7f5a86ef2854d5b9771d52c117de8969a0 100644 (file)
--- a/src/object-edit.cpp
+++ b/src/object-edit.cpp
@@ -194,7 +194,7 @@ RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*orig
Geom::Point const s = snap_knot_position_constrained(p, Inkscape::Snapper::ConstraintLine(Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed), Geom::Point(0, 1)));
if (state & GDK_CONTROL_MASK) { // When holding control then rx will be kept equal to ry,
- // resulting in a perfect circle (and not an ellipse)
+ // resulting in a perfect circle (and not an ellipse)
gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0;
rect->rx.computed = rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, 0.0, temp);
rect->ry._set = rect->rx._set = true;
@@ -277,19 +277,19 @@ RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &or
Geom::Point p_handle(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed);
if (fabs(minx) > fabs(miny)) {
- // snap to horizontal or diagonal
+ // 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
- 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);
+ 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
- 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);
+ 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);
@@ -297,16 +297,16 @@ RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &or
// snap to vertical or diagonal
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
- 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);
+ 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
- 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);
+ 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);
@@ -316,8 +316,8 @@ RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &or
} else {
// move freely
- s = snap_knot_position(p);
- 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;
}
@@ -367,54 +367,54 @@ RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin
gdouble ratio = (w_orig / h_orig);
if (fabs(minx) > fabs(miny)) {
- // snap to horizontal or diagonal
+ // 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
- 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);
+ 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
- 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);
+ 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
- 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
- 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);
+ 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
- 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);
+ 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->height.computed = MAX(h_orig - miny, 0);
}
rect->width._set = rect->height._set = rect->x._set = rect->y._set = true;
} else {
// move freely
- s = snap_knot_position(p);
- minx = s[Geom::X] - origin[Geom::X];
- miny = s[Geom::Y] - origin[Geom::Y];
+ 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->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);
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index b71bc2e54eecc5e1313beef76085050d7e8d5366..9cf4d5420ef10ad905cce0210c6206beb3183224 100644 (file)
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
@@ -469,7 +469,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
if (pc->npoints == 0) {
Geom::Point p;
- if ((bevent.state & GDK_CONTROL_MASK) && (pc->polylines_only || pc->polylines_paraxial)) {
+ if ((bevent.state & GDK_CONTROL_MASK) && (pc->polylines_only || pc->polylines_paraxial)) {
p = event_dt;
if (!(bevent.state & GDK_SHIFT_MASK)) {
SnapManager &m = desktop->namedview->snap_manager;
@@ -479,7 +479,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
spdc_create_single_dot(event_context, p, "/tools/freehand/pen", bevent.state);
ret = TRUE;
break;
- }
+ }
// TODO: Perhaps it would be nicer to rearrange the following case
// distinction so that the case of a waiting LPE is treated separately
spdc_endpoint_snap(pc, p, mevent.state);
spdc_pen_set_subsequent_point(pc, p, true);
ret = TRUE;
+ } else if (sp_event_context_knot_mouseover(pc)) {
+ SnapManager &m = dt->namedview->snap_manager;
+ m.setup(dt);
+ m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
}
break;
case SP_PEN_CONTEXT_CONTROL:
pc->_message_context->clear();
pc->anchor_statusbar = false;
}
+ if (sp_event_context_knot_mouseover(pc)) {
+ SnapManager &m = dt->namedview->snap_manager;
+ m.setup(dt);
+ m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
+ }
}
break;
case SP_PEN_CONTEXT_CONTROL:
/* This is perfectly valid */
break;
default:
+ if (sp_event_context_knot_mouseover(pc)) {
+ SnapManager &m = dt->namedview->snap_manager;
+ m.setup(dt);
+ m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
+ }
break;
}
break;
diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp
index acdd4d6e5d14759fc1321028e12a055b2c8ab3c5..5aa9efbd91f7add0250a9bc6c6bf9e95d86201a0 100644 (file)
--- a/src/pencil-context.cpp
+++ b/src/pencil-context.cpp
@@ -295,7 +295,7 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
static gint
pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mevent)
{
- SPDesktop *const dt = pc->desktop;
+ SPDesktop *const dt = pc->desktop;
if ((mevent.state & GDK_CONTROL_MASK) && (mevent.state & GDK_BUTTON1_MASK)) {
// mouse was accidentally moved during Ctrl+click;
@@ -395,6 +395,11 @@ pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mev
pc->_message_context->clear();
pc->anchor_statusbar = false;
}
+ if (sp_event_context_knot_mouseover(pc)) {
+ SnapManager &m = dt->namedview->snap_manager;
+ m.setup(dt);
+ m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
+ }
}
break;
}
diff --git a/src/rect-context.cpp b/src/rect-context.cpp
index dcc1f0aa1309a4049da77e3cbfc1f078d6b7a9c3..9eab188ddea51a9a1ee0f87327be2bdb4ab8d600 100644 (file)
--- a/src/rect-context.cpp
+++ b/src/rect-context.cpp
@@ -317,6 +317,13 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
sp_rect_drag(*rc, motion_dt, event->motion.state); // this will also handle the snapping
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
+ } else if (sp_event_context_knot_mouseover(rc)) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point motion_dt(desktop->w2d(motion_w));
+ m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE));
}
break;
case GDK_BUTTON_RELEASE:
diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp
index 7002c972356accbcd98339de0555e4fd78a99f13..e3b6d65c284e66b8a5b300743eb863cf868297fc 100644 (file)
--- a/src/shape-editor.cpp
+++ b/src/shape-editor.cpp
return false; // so far, knotholder cannot have selection
}
+/**
+ * \brief Returns true if this ShapeEditor has a knot above which the mouse currently hovers
+ */
+bool ShapeEditor::knot_mouseover()
+{
+ if (this->knotholder) {
+ return knotholder->knot_mouseover();
+ }
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/shape-editor.h b/src/shape-editor.h
index 2374d6ac645bd5d28a3c08f78d014b594130d012..f400244b326ac40b8ad73512af8181007c7caa27 100644 (file)
--- a/src/shape-editor.h
+++ b/src/shape-editor.h
// this one is only public because it's called from non-C++ repr changed callback
void shapeeditor_event_attr_changed(gchar const *name);
+ bool knot_mouseover();
+
private:
bool has_knotholder ();
void reset_item (SubType type, bool keep_knotholder = true);
diff --git a/src/snap.cpp b/src/snap.cpp
index 4727c7b3e2f78cbfad54bf5caa5faba671c2a63d..9ee575e22e789731df282b06058af3884179e8ad 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
@@ -214,6 +214,22 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapCandidatePoint const
return findBestSnap(p, sc, false);
}
+void SnapManager::preSnap(Inkscape::SnapCandidatePoint const &p)
+{
+ // setup() must have been called before calling this method!
+
+ if (_snapindicator) {
+ _snapindicator = false; // prevent other methods from drawing a snap indicator; we want to control this here
+ Inkscape::SnappedPoint s = freeSnap(p);
+ if (s.getSnapped()) {
+ _desktop->snapindicator->set_new_snaptarget(s, true);
+ } else {
+ _desktop->snapindicator->remove_snaptarget();
+ }
+ _snapindicator = true; // restore the original value
+ }
+}
+
/**
* \brief Snap to the closest multiple of a grid pitch
*
diff --git a/src/snap.h b/src/snap.h
index 24a60eaf0ce152c6b85dfcbd87cc083d7171de26..613550376aca3d485f3f33536631358494aa2d51 100644 (file)
--- a/src/snap.h
+++ b/src/snap.h
Inkscape::SnappedPoint freeSnap(Inkscape::SnapCandidatePoint const &p,
Geom::OptRect const &bbox_to_snap = Geom::OptRect() ) const;
+ void preSnap(Inkscape::SnapCandidatePoint const &p);
+
Geom::Point multipleOfGridPitch(Geom::Point const &t) const;
// constrainedSnapReturnByRef() is preferred over constrainedSnap(), because it only returns a
diff --git a/src/spiral-context.cpp b/src/spiral-context.cpp
index d751fae6dbc75781f3e0917b820300916e3a1533..f8a4bddfb8c4f0b81f2ab322e363f6a95b15482a 100644 (file)
--- a/src/spiral-context.cpp
+++ b/src/spiral-context.cpp
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
+ } else if (sp_event_context_knot_mouseover(sc)) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point motion_dt(desktop->w2d(motion_w));
+ m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE));
}
break;
case GDK_BUTTON_RELEASE:
diff --git a/src/star-context.cpp b/src/star-context.cpp
index f67ca434d26c60311ebcd0b59e24f9d299831c43..693d5188860d9c07eaeb10619dcbf41a80dbbd93 100644 (file)
--- a/src/star-context.cpp
+++ b/src/star-context.cpp
@@ -291,6 +291,13 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
+ } else if (sp_event_context_knot_mouseover(event_context)) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point motion_dt(desktop->w2d(motion_w));
+ m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE));
}
break;
case GDK_BUTTON_RELEASE:
sc->_message_context->clear();
if (sc->item != NULL) {
- SPStar *star = SP_STAR(sc->item);
- if (star->r[1] == 0) {
- sp_star_cancel(sc); // Don't allow the creating of zero sized arc, for example when the start and and point snap to the snap grid point
- return;
- }
+ SPStar *star = SP_STAR(sc->item);
+ if (star->r[1] == 0) {
+ sp_star_cancel(sc); // Don't allow the creating of zero sized arc, for example when the start and and point snap to the snap grid point
+ return;
+ }
- SPDesktop *desktop = SP_EVENT_CONTEXT(sc)->desktop;
+ SPDesktop *desktop = SP_EVENT_CONTEXT(sc)->desktop;
SPObject *object = SP_OBJECT(sc->item);
sp_shape_set_shape(SP_SHAPE(sc->item));
static void sp_star_cancel(SPStarContext *sc)
{
- SPDesktop *desktop = SP_EVENT_CONTEXT(sc)->desktop;
+ SPDesktop *desktop = SP_EVENT_CONTEXT(sc)->desktop;
- sp_desktop_selection(desktop)->clear();
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0);
+ sp_desktop_selection(desktop)->clear();
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0);
if (sc->item != NULL) {
- SP_OBJECT(sc->item)->deleteObject();
- sc->item = NULL;
+ SP_OBJECT(sc->item)->deleteObject();
+ sc->item = NULL;
}
sc->within_tolerance = false;
diff --git a/src/star-context.h b/src/star-context.h
index 6db29ec4212abd32558644fd3b9524fcc4fca0e8..024bf8d74940499d69b478a3cdb14fab48504b1e 100644 (file)
--- a/src/star-context.h
+++ b/src/star-context.h
class SPStarContextClass;
struct SPStarContext : public SPEventContext {
- SPItem *item;
- Geom::Point center;
-
- /* Number of corners */
- gint magnitude;
- /* Outer/inner radius ratio */
- gdouble proportion;
- /* flat sides or not? */
- bool isflatsided;
- /* rounded corners ratio */
- gdouble rounded;
- // randomization
- gdouble randomized;
+ SPItem *item;
+ Geom::Point center;
+
+ /* Number of corners */
+ gint magnitude;
+ /* Outer/inner radius ratio */
+ gdouble proportion;
+ /* flat sides or not? */
+ bool isflatsided;
+ /* rounded corners ratio */
+ gdouble rounded;
+ // randomization
+ gdouble randomized;
sigc::connection sel_changed_connection;
- Inkscape::MessageContext *_message_context;
+ Inkscape::MessageContext *_message_context;
};
struct SPStarContextClass {
- SPEventContextClass parent_class;
+ SPEventContextClass parent_class;
};
GtkType sp_star_context_get_type (void);