summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2010-03-26 04:34:25 +0000
committerTed Gould <ted@gould.cx>2010-03-26 04:34:25 +0000
commit9e023a3aa964a0d3fa1e31e46d33657367ba68aa (patch)
tree33f1392a340737e4eeefca6fd031f96c29befd2b /src/display
parentInstalling the pkgconfig file (diff)
parentAdding in shape-record.h (diff)
downloadinkscape-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.cpp4
-rw-r--r--src/display/curve.cpp10
-rw-r--r--src/display/snap-indicator.cpp71
-rw-r--r--src/display/snap-indicator.h10
-rw-r--r--src/display/sp-canvas-util.cpp7
-rw-r--r--src/display/sp-canvas.cpp59
-rw-r--r--src/display/sp-canvas.h1
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);