diff options
| author | Ted Gould <ted@gould.cx> | 2010-03-26 04:34:25 +0000 |
|---|---|---|
| committer | Ted Gould <ted@gould.cx> | 2010-03-26 04:34:25 +0000 |
| commit | 9e023a3aa964a0d3fa1e31e46d33657367ba68aa (patch) | |
| tree | 33f1392a340737e4eeefca6fd031f96c29befd2b /src/display | |
| parent | Installing the pkgconfig file (diff) | |
| parent | Adding in shape-record.h (diff) | |
| download | inkscape-9e023a3aa964a0d3fa1e31e46d33657367ba68aa.tar.gz inkscape-9e023a3aa964a0d3fa1e31e46d33657367ba68aa.zip | |
Merge from trunk
(bzr r8254.1.53)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/canvas-text.cpp | 4 | ||||
| -rw-r--r-- | src/display/curve.cpp | 10 | ||||
| -rw-r--r-- | src/display/snap-indicator.cpp | 71 | ||||
| -rw-r--r-- | src/display/snap-indicator.h | 10 | ||||
| -rw-r--r-- | src/display/sp-canvas-util.cpp | 7 | ||||
| -rw-r--r-- | src/display/sp-canvas.cpp | 59 | ||||
| -rw-r--r-- | src/display/sp-canvas.h | 1 |
7 files changed, 123 insertions, 39 deletions
diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index 1c715291f..d32bc20c3 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -91,7 +91,9 @@ sp_canvastext_destroy (GtkObject *object) SPCanvasText *canvastext = SP_CANVASTEXT (object); - canvastext->item=NULL; + g_free(canvastext->text); + canvastext->text = NULL; + canvastext->item = NULL; if (GTK_OBJECT_CLASS (parent_class_ct)->destroy) (* GTK_OBJECT_CLASS (parent_class_ct)->destroy) (object); diff --git a/src/display/curve.cpp b/src/display/curve.cpp index 7d7dbc987..1b54c981c 100644 --- a/src/display/curve.cpp +++ b/src/display/curve.cpp @@ -51,10 +51,10 @@ SPCurve::new_from_rect(Geom::Rect const &rect) Geom::Point p = rect.corner(0); c->moveto(p); - for (int i=3; i>=0; i--) { + for (int i=3; i>=1; i--) { c->lineto(rect.corner(i)); } - c->closepath_current(); + c->closepath(); return c; } @@ -285,7 +285,11 @@ SPCurve::closepath() void SPCurve::closepath_current() { - _pathv.back().setFinal(_pathv.back().initialPoint()); + if (_pathv.back().size() > 0 && dynamic_cast<Geom::LineSegment const *>(&_pathv.back().back_open())) { + _pathv.back().erase_last(); + } else { + _pathv.back().setFinal(_pathv.back().initialPoint()); + } _pathv.back().close(true); } diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index fdea9cbbf..1e4ca12a8 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -6,7 +6,7 @@ * Diederik van Lierop * * Copyright (C) Johan Engelen 2009 <j.b.c.engelen@utwente.nl> - * Copyright (C) Diederik van Lierop 2009 <mail@diedenrezi.nl> + * Copyright (C) Diederik van Lierop 2010 <mail@diedenrezi.nl> * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -16,7 +16,9 @@ #include "desktop.h" #include "desktop-handles.h" #include "display/sodipodi-ctrl.h" +#include "display/sodipodi-ctrlrect.h" #include "display/canvas-text.h" +#include "display/sp-canvas-util.h" #include "knot.h" #include "preferences.h" #include <glibmm/i18n.h> @@ -27,7 +29,9 @@ namespace Display { SnapIndicator::SnapIndicator(SPDesktop * desktop) : _snaptarget(NULL), _snaptarget_tooltip(NULL), + _snaptarget_bbox(NULL), _snapsource(NULL), + _snaptarget_is_presnap(false), _desktop(desktop) { } @@ -40,7 +44,7 @@ SnapIndicator::~SnapIndicator() } 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 @@ -97,9 +101,6 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) case SNAPTARGET_BBOX_EDGE: target_name = _("bounding box side"); break; - case SNAPTARGET_GRADIENTS_PARENT_BBOX: - target_name = _("bounding box"); - break; case SNAPTARGET_PAGE_BORDER: target_name = _("page border"); break; @@ -139,6 +140,12 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) case SNAPTARGET_TEXT_BASELINE: target_name = _("text baseline"); break; + 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; @@ -173,7 +180,8 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) case SNAPSOURCE_ROTATION_CENTER: source_name = _("Object rotation center"); break; - case SNAPSOURCE_HANDLE: + case SNAPSOURCE_NODE_HANDLE: + case SNAPSOURCE_OTHER_HANDLE: source_name = _("Handle"); break; case SNAPSOURCE_PATH_INTERSECTION: @@ -200,6 +208,9 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) case SNAPSOURCE_TEXT_BASELINE: source_name = _("Text baseline"); break; + case SNAPSOURCE_GRID_PITCH: + source_name = _("Multiple of grid spacing"); + break; default: g_warning("Snap source has not yet been defined!"); break; @@ -216,7 +227,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) "anchor", GTK_ANCHOR_CENTER, "size", 10.0, "stroked", TRUE, - "stroke_color", 0xf000f0ff, + "stroke_color", pre_snap ? 0x7f7f7fff : 0xff0000ff, "mode", SP_KNOT_MODE_XOR, "shape", SP_KNOT_SHAPE_DIAMOND, NULL ); @@ -226,7 +237,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) "anchor", GTK_ANCHOR_CENTER, "size", 10.0, "stroked", TRUE, - "stroke_color", 0xf000f0ff, + "stroke_color", pre_snap ? 0x7f7f7fff : 0xff0000ff, "mode", SP_KNOT_MODE_XOR, "shape", SP_KNOT_SHAPE_CROSS, NULL ); @@ -236,24 +247,53 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) SP_CTRL(canvasitem)->moveto(p.getPoint()); _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val); + _snaptarget_is_presnap = pre_snap; - gchar *tooltip_str = g_strconcat(source_name, _(" to "), target_name, NULL); + // Display the tooltip, which reveals the type of snap source and the type of snap target + gchar *tooltip_str = NULL; + if (p.getSource() != SNAPSOURCE_GRID_PITCH) { + tooltip_str = g_strconcat(source_name, _(" to "), target_name, NULL); + } else { + tooltip_str = g_strdup(source_name); + } 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), + SP_TYPE_CTRLRECT, + NULL); + + SP_CTRLRECT(box)->setRectangle(*bbox); + 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); + } } } void -SnapIndicator::remove_snaptarget() +SnapIndicator::remove_snaptarget(bool only_if_presnap) { + if (only_if_presnap && !_snaptarget_is_presnap) { + return; + } + if (_snaptarget) { _desktop->remove_temporary_canvasitem(_snaptarget); _snaptarget = NULL; + _snaptarget_is_presnap = false; } if (_snaptarget_tooltip) { @@ -261,10 +301,15 @@ SnapIndicator::remove_snaptarget() _snaptarget_tooltip = NULL; } + if (_snaptarget_bbox) { + _desktop->remove_temporary_canvasitem(_snaptarget_bbox); + _snaptarget_bbox = NULL; + } + } void -SnapIndicator::set_new_snapsource(std::pair<Geom::Point, int> const p) +SnapIndicator::set_new_snapsource(Inkscape::SnapCandidatePoint const &p) { remove_snapsource(); @@ -279,12 +324,12 @@ SnapIndicator::set_new_snapsource(std::pair<Geom::Point, int> const p) "anchor", GTK_ANCHOR_CENTER, "size", 6.0, "stroked", TRUE, - "stroke_color", 0xf000f0ff, + "stroke_color", 0xff0000ff, "mode", SP_KNOT_MODE_XOR, "shape", SP_KNOT_SHAPE_CIRCLE, NULL ); - SP_CTRL(canvasitem)->moveto(p.first); + SP_CTRL(canvasitem)->moveto(p.getPoint()); _snapsource = _desktop->add_temporary_canvasitem(canvasitem, 1000); } } diff --git a/src/display/snap-indicator.h b/src/display/snap-indicator.h index 4391ca6d6..5475f9f60 100644 --- a/src/display/snap-indicator.h +++ b/src/display/snap-indicator.h @@ -9,7 +9,7 @@ * Diederik van Lierop * * Copyright (C) Johan Engelen 2008 <j.b.c.engelen@utwente.nl> - * Copyright (C) Diederik van Lierop 2008 <mail@diedenrezi.nl> + * Copyright (C) Diederik van Lierop 2010 <mail@diedenrezi.nl> * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -26,16 +26,18 @@ public: SnapIndicator(SPDesktop *desktop); virtual ~SnapIndicator(); - void set_new_snaptarget(Inkscape::SnappedPoint const p); - void remove_snaptarget(); + void set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap = false); + void remove_snaptarget(bool only_if_presnap = false); - void set_new_snapsource(std::pair<Geom::Point, int> const p); + void set_new_snapsource(Inkscape::SnapCandidatePoint const &p); void remove_snapsource(); protected: TemporaryItem *_snaptarget; TemporaryItem *_snaptarget_tooltip; + TemporaryItem *_snaptarget_bbox; TemporaryItem *_snapsource; + bool _snaptarget_is_presnap; SPDesktop *_desktop; private: diff --git a/src/display/sp-canvas-util.cpp b/src/display/sp-canvas-util.cpp index 30cd0dfa0..a23b157df 100644 --- a/src/display/sp-canvas-util.cpp +++ b/src/display/sp-canvas-util.cpp @@ -112,10 +112,11 @@ void sp_canvas_item_move_to_z (SPCanvasItem * item, gint z) if (z == current_z) return; - if (z > current_z) + if (z > current_z) { sp_canvas_item_raise (item, z - current_z); - - sp_canvas_item_lower (item, current_z - z); + } else { + sp_canvas_item_lower (item, current_z - z); + } } gint diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index e640911d6..e39fef45b 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -103,6 +103,7 @@ static void group_remove (SPCanvasGroup *group, SPCanvasItem *item); /* SPCanvasItem */ enum {ITEM_EVENT, ITEM_LAST_SIGNAL}; +enum {PROP_0, PROP_VISIBLE}; static void sp_canvas_request_update (SPCanvas *canvas); @@ -114,11 +115,10 @@ static void sp_canvas_item_dispose (GObject *object); static void sp_canvas_item_construct (SPCanvasItem *item, SPCanvasGroup *parent, gchar const *first_arg_name, va_list args); static int emit_event (SPCanvas *canvas, GdkEvent *event); +static int pick_current_item (SPCanvas *canvas, GdkEvent *event); static guint item_signals[ITEM_LAST_SIGNAL] = { 0 }; -static GtkObjectClass *item_parent_class; - /** * Registers the SPCanvasItem class with Glib and returns its type number. */ @@ -151,9 +151,6 @@ sp_canvas_item_class_init (SPCanvasItemClass *klass) { GObjectClass *object_class = (GObjectClass *) klass; - /* fixme: Derive from GObject */ - item_parent_class = (GtkObjectClass*)gtk_type_class (GTK_TYPE_OBJECT); - item_signals[ITEM_EVENT] = g_signal_new ("event", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, @@ -172,6 +169,9 @@ sp_canvas_item_class_init (SPCanvasItemClass *klass) static void sp_canvas_item_init (SPCanvasItem *item) { + // TODO items should not be visible on creation - this causes kludges with items + // that should be initially invisible; examples of such items: node handles, the CtrlRect + // used for rubberbanding, path outline, etc. item->flags |= SP_CANVAS_ITEM_VISIBLE; item->xform = Geom::Matrix(Geom::identity()); } @@ -277,7 +277,7 @@ sp_canvas_item_dispose (GObject *object) group_remove (SP_CANVAS_GROUP (item->parent), item); } - G_OBJECT_CLASS (item_parent_class)->dispose (object); + G_OBJECT_CLASS (g_type_class_peek(g_type_parent(sp_canvas_item_get_type())))->dispose (object); } /** @@ -477,6 +477,13 @@ sp_canvas_item_lower (SPCanvasItem *item, int positions) item->canvas->need_repick = TRUE; } +bool +sp_canvas_item_is_visible (SPCanvasItem *item) +{ + return item->flags & SP_CANVAS_ITEM_VISIBLE; +} + + /** * Sets visible flag on item and requests a redraw. */ @@ -542,8 +549,13 @@ sp_canvas_item_grab (SPCanvasItem *item, guint event_mask, GdkCursor *cursor, gu if (item->canvas->grabbed_item) return -1; - if (!(item->flags & SP_CANVAS_ITEM_VISIBLE)) - return -1; + // This test disallows grabbing events by an invisible item, which may be useful + // sometimes. An example is the hidden control point used for the selector component, + // where it is used for object selection and rubberbanding. There seems to be nothing + // preventing this except this test, so I removed it. + // -- Krzysztof KosiĆski, 2009.08.12 + //if (!(item->flags & SP_CANVAS_ITEM_VISIBLE)) + // return -1; if (HAS_BROKEN_MOTION_HINTS) { event_mask &= ~GDK_POINTER_MOTION_HINT_MASK; @@ -1316,6 +1328,20 @@ emit_event (SPCanvas *canvas, GdkEvent *event) if (canvas->grabbed_item && !is_descendant (canvas->current_item, canvas->grabbed_item)) { item = canvas->grabbed_item; } else { + // Make sure that current_item is up-to-date. If a snap indicator was just deleted, then + // sp_canvas_item_dispose has been called and there is no current_item specified. We need + // that though because otherwise we don't know where to send this event to, leading to a + // lost event. We can't wait for idle events to have current_item updated, we need it now! + // Otherwise, scrolling when hovering above a pre-snap indicator won't work (for example) + // See this bug report: https://bugs.launchpad.net/inkscape/+bug/522335/comments/8 + if (canvas->need_repick && !canvas->in_repick && event->type == GDK_SCROLL) { + // To avoid side effects, we'll only do this for scroll events, because this is the + // only thing we want to fix here. An example of a reported side effect is that + // otherwise selection of nodes in the node editor by dragging a rectangle using a + // tablet will break + canvas->need_repick = FALSE; + pick_current_item (canvas, (GdkEvent *) event); + } item = canvas->current_item; } @@ -1481,6 +1507,8 @@ pick_current_item (SPCanvas *canvas, GdkEvent *event) retval = emit_event (canvas, &new_event); } + + return retval; } @@ -1578,7 +1606,7 @@ static inline void request_motions(GdkWindow *w, GdkEventMotion *event) { static int sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) { - int status; + int status; SPCanvas *canvas = SP_CANVAS (widget); track_latency((GdkEvent *)event); @@ -1590,11 +1618,11 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) return FALSE; canvas->state = event->state; - pick_current_item (canvas, (GdkEvent *) event); - status = emit_event (canvas, (GdkEvent *) event); - if (event->is_hint) { - request_motions(widget->window, event); - } + pick_current_item (canvas, (GdkEvent *) event); + status = emit_event (canvas, (GdkEvent *) event); + if (event->is_hint) { + request_motions(widget->window, event); + } return status; } @@ -2085,7 +2113,7 @@ paint (SPCanvas *canvas) static int do_update (SPCanvas *canvas) { - if (!canvas->root || !canvas->pixmap_gc) // canvas may have already be destroyed by closing desktop durring interrupted display! + if (!canvas->root || !canvas->pixmap_gc) // canvas may have already be destroyed by closing desktop during interrupted display! return TRUE; if (canvas->drawing_disabled) @@ -2189,6 +2217,7 @@ sp_canvas_scroll_to (SPCanvas *canvas, double cx, double cy, unsigned int clear, } else { // scrolling as part of zoom; do nothing here - the next do_update will perform full redraw } + } /** diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index a17e2e086..5cd201618 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -101,6 +101,7 @@ void sp_canvas_item_affine_absolute(SPCanvasItem *item, Geom::Matrix const &aff) void sp_canvas_item_raise(SPCanvasItem *item, int positions); void sp_canvas_item_lower(SPCanvasItem *item, int positions); +bool sp_canvas_item_is_visible(SPCanvasItem *item); void sp_canvas_item_show(SPCanvasItem *item); void sp_canvas_item_hide(SPCanvasItem *item); int sp_canvas_item_grab(SPCanvasItem *item, unsigned int event_mask, GdkCursor *cursor, guint32 etime); |
