summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authormjwybrow <mjwybrow@users.sourceforge.net>2006-01-20 04:12:21 +0000
committermjwybrow <mjwybrow@users.sourceforge.net>2006-01-20 04:12:21 +0000
commitb01791161926320dbb8b9a5435ea2fb470c32795 (patch)
treec61cf814c6f1a3a840cf5a9efdc3f6f961b9c9e6 /src
parentUpdate to gtk28 (diff)
downloadinkscape-b01791161926320dbb8b9a5435ea2fb470c32795.tar.gz
inkscape-b01791161926320dbb8b9a5435ea2fb470c32795.zip
* src/widgets/toolbox.cpp, src/widgets/desktop-widget.cpp,
src/conn-avoid-ref.cpp, src/conn-avoid-ref.h, src/sp-namedview.cpp, src/sp-namedview.h, src/attributes.cpp, src/attributes.h, src/attributes-test.cpp: Added a "Spacing" control to the connector toolbar which allows the user to adjust the amount of space left around avoided shapes for the purpose of determining auto-routing connector paths. (bzr r18)
Diffstat (limited to 'src')
-rw-r--r--src/attributes-test.cpp1
-rw-r--r--src/attributes.cpp1
-rw-r--r--src/attributes.h1
-rw-r--r--src/conn-avoid-ref.cpp75
-rw-r--r--src/conn-avoid-ref.h6
-rw-r--r--src/sp-namedview.cpp11
-rw-r--r--src/sp-namedview.h2
-rw-r--r--src/widgets/desktop-widget.cpp5
-rw-r--r--src/widgets/toolbox.cpp135
9 files changed, 223 insertions, 14 deletions
diff --git a/src/attributes-test.cpp b/src/attributes-test.cpp
index 50d2e81bd..f40200c1f 100644
--- a/src/attributes-test.cpp
+++ b/src/attributes-test.cpp
@@ -323,6 +323,7 @@ static struct {char const *attr; bool supported;} const all_attrs[] = {
{"inkscape:connection-start", true},
{"inkscape:connection-end", true},
{"inkscape:connector-avoid", true},
+ {"inkscape:connector-spacing", true},
{"sodipodi:cx", true},
{"sodipodi:cy", true},
{"sodipodi:rx", true},
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 4d182179c..ce9c0e105 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -100,6 +100,7 @@ static SPStyleProp const props[] = {
{SP_ATTR_INKSCAPE_OBJECT_NODES, "inkscape:object-nodes"},
{SP_ATTR_INKSCAPE_CURRENT_LAYER, "inkscape:current-layer"},
{SP_ATTR_INKSCAPE_DOCUMENT_UNITS, "inkscape:document-units"},
+ {SP_ATTR_INKSCAPE_CONNECTOR_SPACING, "inkscape:connector-spacing"},
/* SPGuide */
{SP_ATTR_ORIENTATION, "orientation"},
{SP_ATTR_POSITION, "position"},
diff --git a/src/attributes.h b/src/attributes.h
index 24b87fc1c..2b4a68f34 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -101,6 +101,7 @@ enum SPAttributeEnum {
SP_ATTR_INKSCAPE_OBJECT_NODES,
SP_ATTR_INKSCAPE_CURRENT_LAYER,
SP_ATTR_INKSCAPE_DOCUMENT_UNITS,
+ SP_ATTR_INKSCAPE_CONNECTOR_SPACING,
/* SPGuide */
SP_ATTR_ORIENTATION,
SP_ATTR_POSITION,
diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp
index 0dbd8c730..657560902 100644
--- a/src/conn-avoid-ref.cpp
+++ b/src/conn-avoid-ref.cpp
@@ -18,10 +18,15 @@
#include "libavoid/incremental.h"
#include "xml/simple-node.cpp"
#include "document.h"
+#include "prefs-utils.h"
+
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "sp-namedview.h"
+#include "inkscape.h"
static Avoid::Polygn avoid_item_poly(SPItem const *item);
-static void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item);
SPAvoidRef::SPAvoidRef(SPItem *spitem)
@@ -61,6 +66,11 @@ void SPAvoidRef::setAvoid(char const *value)
void SPAvoidRef::handleSettingChange(void)
{
+ SPDesktop *desktop = inkscape_active_desktop();
+ if (desktop == NULL) {
+ return;
+ }
+
if (new_setting == setting) {
// Don't need to make any changes
return;
@@ -100,6 +110,9 @@ void SPAvoidRef::handleSettingChange(void)
static Avoid::Polygn avoid_item_poly(SPItem const *item)
{
+ SPDesktop *desktop = inkscape_active_desktop();
+ g_assert(desktop != NULL);
+
Avoid::Polygn poly;
// TODO: The right way to do this is to return the convex hull of
@@ -116,9 +129,12 @@ static Avoid::Polygn avoid_item_poly(SPItem const *item)
sp_document_ensure_up_to_date(item->document);
NR::Rect rHull = item->invokeBbox(sp_item_i2doc_affine(item));
-
+
+
+ double spacing = desktop->namedview->connector_spacing;
+
// Add a little buffer around the edge of each object.
- NR::Rect rExpandedHull = NR::expand(rHull, -10.0);
+ NR::Rect rExpandedHull = NR::expand(rHull, -spacing);
poly = Avoid::newPoly(4);
for (unsigned n = 0; n < 4; ++n) {
@@ -151,7 +167,31 @@ static Avoid::Polygn avoid_item_poly(SPItem const *item)
}
-static void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item)
+GSList *get_avoided_items(GSList *list, SPObject *from, SPDesktop *desktop,
+ bool initialised)
+{
+ for (SPObject *child = sp_object_first_child(SP_OBJECT(from)) ;
+ child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ if (SP_IS_ITEM(child) &&
+ !desktop->isLayer(SP_ITEM(child)) &&
+ !SP_ITEM(child)->isLocked() &&
+ !desktop->itemIsHidden(SP_ITEM(child)) &&
+ (!initialised || SP_ITEM(child)->avoidRef->shapeRef)
+ )
+ {
+ list = g_slist_prepend (list, SP_ITEM(child));
+ }
+
+ if (SP_IS_ITEM(child) && desktop->isLayer(SP_ITEM(child))) {
+ list = get_avoided_items(list, child, desktop, initialised);
+ }
+ }
+
+ return list;
+}
+
+
+void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item)
{
Avoid::ShapeRef *shapeRef = moved_item->avoidRef->shapeRef;
g_assert(shapeRef);
@@ -163,7 +203,32 @@ static void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item)
Avoid::freePoly(poly);
}
}
-
+
+
+void init_avoided_shape_geometry(SPDesktop *desktop)
+{
+ // Don't count this as changes to the document,
+ // it is basically just llate initialisation.
+ SPDocument *document = SP_DT_DOCUMENT(desktop);
+ gboolean saved = sp_document_get_undo_sensitive(document);
+ sp_document_set_undo_sensitive(document, FALSE);
+
+ bool initialised = false;
+ GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop,
+ initialised);
+
+ for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) {
+ SPItem *item = reinterpret_cast<SPItem *>(iter->data);
+ item->avoidRef->handleSettingChange();
+ }
+
+ if (items) {
+ g_slist_free(items);
+ }
+ sp_document_set_undo_sensitive(document, saved);
+}
+
+
/*
Local Variables:
mode:c++
diff --git a/src/conn-avoid-ref.h b/src/conn-avoid-ref.h
index 3b5e6d3b5..ac9295cf9 100644
--- a/src/conn-avoid-ref.h
+++ b/src/conn-avoid-ref.h
@@ -42,6 +42,12 @@ private:
sigc::connection _transformed_connection;
};
+extern GSList *get_avoided_items(GSList *list, SPObject *from,
+ SPDesktop *desktop, bool initialised = true);
+extern void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item);
+extern void init_avoided_shape_geometry(SPDesktop *desktop);
+
+static const double defaultConnSpacing = 10.0;
#endif /* !SEEN_CONN_AVOID_REF */
diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp
index c6e6b872b..32e713792 100644
--- a/src/sp-namedview.cpp
+++ b/src/sp-namedview.cpp
@@ -31,8 +31,9 @@
#include "sp-namedview.h"
#include "prefs-utils.h"
#include "desktop.h"
+#include "conn-avoid-ref.h" // for defaultConnSpacing.
-#include "isnan.h" //temp fox for isnan(). include last
+#include "isnan.h" //temp fix for isnan(). include last
#define DEFAULTTOLERANCE 0.4
#define DEFAULTGRIDCOLOR 0x3f3fff25
@@ -117,6 +118,8 @@ static void sp_namedview_init(SPNamedView *nv)
nv->default_layer_id = 0;
+ nv->connector_spacing = defaultConnSpacing;
+
new (&nv->grid_snapper) Inkscape::GridSnapper(nv, 0);
new (&nv->guide_snapper) Inkscape::GuideSnapper(nv, 0);
new (&nv->object_snapper) Inkscape::ObjectSnapper(nv, 0);
@@ -176,6 +179,7 @@ static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape:
sp_object_read_attr(object, "inkscape:object-paths");
sp_object_read_attr(object, "inkscape:object-nodes");
sp_object_read_attr(object, "inkscape:current-layer");
+ sp_object_read_attr(object, "inkscape:connector-spacing");
/* Construct guideline list */
@@ -492,6 +496,11 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
nv->default_layer_id = value ? g_quark_from_string(value) : 0;
object->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
+ case SP_ATTR_INKSCAPE_CONNECTOR_SPACING:
+ nv->connector_spacing = value ? g_ascii_strtod(value, NULL) :
+ defaultConnSpacing;
+ object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
case SP_ATTR_INKSCAPE_DOCUMENT_UNITS: {
/* The default unit if the document doesn't override this: e.g. for files saved as
* `plain SVG', or non-inkscape files, or files created by an inkscape 0.40 &
diff --git a/src/sp-namedview.h b/src/sp-namedview.h
index f96207794..2265dd863 100644
--- a/src/sp-namedview.h
+++ b/src/sp-namedview.h
@@ -81,6 +81,8 @@ struct SPNamedView : public SPObjectGroup {
bool has_abs_tolerance;
GQuark default_layer_id;
+
+ double connector_spacing;
guint32 gridcolor;
guint32 gridempcolor;
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp
index f9a8b8f62..b7832658f 100644
--- a/src/widgets/desktop-widget.cpp
+++ b/src/widgets/desktop-widget.cpp
@@ -46,6 +46,7 @@
#include "ui/widget/selected-style.h"
#include "sp-item.h"
#include "dialogs/swatches.h"
+#include "conn-avoid-ref.h"
#ifdef WITH_INKBOARD
#endif
@@ -912,6 +913,10 @@ sp_desktop_widget_new (SPNamedView *namedview)
dtw->desktop->init (namedview, dtw->canvas);
inkscape_add_desktop (dtw->desktop);
+ // Add the shape geometry to libavoid for autorouting connectors.
+ // This needs desktop set for its spacing preferences.
+ init_avoided_shape_geometry(dtw->desktop);
+
dtw->selected_style->setDesktop(dtw->desktop);
/* Once desktop is set, we can update rulers */
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 7ebbf7a85..0e3bf206a 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -47,6 +47,8 @@
#include "helper/unit-menu.h"
#include "helper/units.h"
+#include "inkscape.h"
+#include "conn-avoid-ref.h"
#include "select-toolbar.h"
@@ -789,7 +791,7 @@ sp_stb_magnitude_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
// in turn, prevent listener from responding
g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
- bool modmade = FALSE;
+ bool modmade = false;
Inkscape::Selection *selection = SP_DT_SELECTION(desktop);
GSList const *items = selection->itemList();
@@ -828,7 +830,7 @@ sp_stb_proportion_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
// in turn, prevent listener from responding
g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
- bool modmade = FALSE;
+ bool modmade = false;
Inkscape::Selection *selection = SP_DT_SELECTION(desktop);
GSList const *items = selection->itemList();
for (; items != NULL; items = items->next) {
@@ -879,7 +881,7 @@ sp_stb_sides_flat_state_changed(GtkWidget *widget, GtkObject *tbl)
Inkscape::Selection *selection = SP_DT_SELECTION(desktop);
GSList const *items = selection->itemList();
GtkWidget *prop_widget = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "prop_widget");
- bool modmade = FALSE;
+ bool modmade = false;
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
gtk_widget_set_sensitive(GTK_WIDGET(prop_widget), FALSE);
for (; items != NULL; items = items->next) {
@@ -925,7 +927,7 @@ sp_stb_rounded_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
// in turn, prevent listener from responding
g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
- bool modmade = FALSE;
+ bool modmade = false;
Inkscape::Selection *selection = SP_DT_SELECTION(desktop);
GSList const *items = selection->itemList();
@@ -962,7 +964,7 @@ sp_stb_randomized_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
// in turn, prevent listener from responding
g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
- bool modmade = FALSE;
+ bool modmade = false;
Inkscape::Selection *selection = SP_DT_SELECTION(desktop);
GSList const *items = selection->itemList();
@@ -1603,7 +1605,7 @@ sp_spl_tb_value_changed(GtkAdjustment *adj, GtkWidget *tbl, gchar const *value_n
gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL);
- bool modmade = FALSE;
+ bool modmade = false;
for (GSList const *items = SP_DT_SELECTION(desktop)->itemList();
items != NULL;
items = items->next)
@@ -2098,7 +2100,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GtkWidget *tbl, gchar const
gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL);
- bool modmade = FALSE;
+ bool modmade = false;
for (GSList const *items = SP_DT_SELECTION(desktop)->itemList();
items != NULL;
items = items->next)
@@ -2173,7 +2175,7 @@ sp_arctb_open_state_changed(GtkWidget *widget, GtkObject *tbl)
// in turn, prevent listener from responding
g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
- bool modmade = FALSE;
+ bool modmade = false;
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
for (GSList const *items = SP_DT_SELECTION(desktop)->itemList();
@@ -2991,11 +2993,89 @@ static void sp_connector_path_set_ignore(void)
}
+static void connector_spacing_changed(GtkAdjustment *adj, GtkWidget *tbl)
+{
+ // quit if run by the _changed callbacks
+ if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
+ return;
+ }
+
+ SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl),
+ "desktop");
+ SPDocument *doc = SP_DT_DOCUMENT(desktop);
+
+ if (!sp_document_get_undo_sensitive(doc))
+ {
+ return;
+ }
+
+ // in turn, prevent callbacks from responding
+ g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
+
+ double old_spacing = desktop->namedview->connector_spacing;
+
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview);
+
+ sp_repr_set_css_double(repr, "inkscape:connector-spacing", adj->value);
+ SP_OBJECT(desktop->namedview)->updateRepr();
+
+ GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop);
+ for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) {
+ SPItem *item = reinterpret_cast<SPItem *>(iter->data);
+ avoid_item_move(&NR::identity(), item);
+ }
+
+ if (items) {
+ g_slist_free(items);
+ }
+
+ sp_document_done(doc);
+
+ g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
+
+ spinbutton_defocus(GTK_OBJECT(tbl));
+}
+
+
+static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr,
+ gchar const *name, gchar const *old_value, gchar const *new_value,
+ bool is_interactive, gpointer data)
+{
+ GtkWidget *tbl = GTK_WIDGET(data);
+
+ if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
+ return;
+ }
+ if (strcmp(name, "inkscape:connector-spacing") != 0) {
+ return;
+ }
+
+ GtkAdjustment *adj = (GtkAdjustment*)
+ gtk_object_get_data(GTK_OBJECT(tbl), "spacing");
+ gdouble spacing = defaultConnSpacing;
+ sp_repr_get_double(repr, "inkscape:connector-spacing", &spacing);
+
+ gtk_adjustment_set_value(adj, spacing);
+}
+
+
+static Inkscape::XML::NodeEventVector connector_tb_repr_events = {
+ NULL, /* child_added */
+ NULL, /* child_removed */
+ connector_tb_event_attr_changed,
+ NULL, /* content_changed */
+ NULL /* order_changed */
+};
+
+
static GtkWidget *
sp_connector_toolbox_new(SPDesktop *desktop)
{
GtkTooltips *tt = gtk_tooltips_new();
GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
+
+ gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
+ gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE,
AUX_BETWEEN_BUTTON_GROUPS);
@@ -3008,8 +3088,47 @@ sp_connector_toolbox_new(SPDesktop *desktop)
"connector_ignore", GTK_SIGNAL_FUNC(sp_connector_path_set_ignore),
tt, _("Make connectors ignore selected objects"));
+ // interval
+ gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE,
+ AUX_BETWEEN_BUTTON_GROUPS);
+
+ // Spacing spinbox
+ {
+ GtkWidget *object_spacing = sp_tb_spinbutton(_("Spacing:"),
+ _("The amount of space left around objects by auto-routing connectors"),
+ "tools.connector", "spacing", 10, NULL, tbl, TRUE,
+ "inkscape:connector-spacing", 0, 100, 1.0, 10.0,
+ connector_spacing_changed, 1, 0);
+
+ gtk_box_pack_start(GTK_BOX(tbl), object_spacing, FALSE, FALSE,
+ AUX_SPACING);
+ }
+
gtk_widget_show_all(tbl);
+ sp_set_font_size_smaller (tbl);
+
+ // Code to watch for changes to the connector-spacing attribute in
+ // the XML.
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview);
+ g_assert(repr != NULL);
+
+ Inkscape::XML::Node *oldrepr = (Inkscape::XML::Node *)
+ gtk_object_get_data(GTK_OBJECT(tbl), "repr");
+
+ if (oldrepr) { // remove old listener
+ sp_repr_remove_listener_by_data(oldrepr, tbl);
+ Inkscape::GC::release(oldrepr);
+ oldrepr = NULL;
+ g_object_set_data(G_OBJECT(tbl), "repr", NULL);
+ }
+ if (repr) {
+ g_object_set_data(G_OBJECT(tbl), "repr", repr);
+ Inkscape::GC::anchor(repr);
+ sp_repr_add_listener(repr, &connector_tb_repr_events, tbl);
+ sp_repr_synthesize_events(repr, &connector_tb_repr_events, tbl);
+ }
+
return tbl;
} // end of sp_connector_toolbox_new()