summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Makefile_insert1
-rw-r--r--src/attributes-test.h1
-rw-r--r--src/conn-avoid-ref.cpp243
-rw-r--r--src/conn-avoid-ref.h16
-rw-r--r--src/connection-points.cpp37
-rw-r--r--src/connection-points.h70
-rw-r--r--src/connector-context.cpp595
-rw-r--r--src/connector-context.h20
-rw-r--r--src/knot.cpp1
-rw-r--r--src/knot.h2
-rw-r--r--src/sp-conn-end-pair.cpp17
-rw-r--r--src/sp-conn-end.cpp106
-rw-r--r--src/sp-conn-end.h13
-rw-r--r--src/sp-item.cpp3
-rw-r--r--src/widgets/connector-toolbar.cpp67
-rw-r--r--src/widgets/toolbox.cpp3
16 files changed, 88 insertions, 1107 deletions
diff --git a/src/Makefile_insert b/src/Makefile_insert
index 36e05270a..a70f3caf8 100644
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
@@ -25,7 +25,6 @@ ink_common_sources += \
composite-undo-stack-observer.cpp \
composite-undo-stack-observer.h \
conditions.cpp conditions.h \
- connection-points.cpp connection-points.h \
conn-avoid-ref.cpp conn-avoid-ref.h \
connection-pool.h \
connector-context.cpp connector-context.h \
diff --git a/src/attributes-test.h b/src/attributes-test.h
index 5a036fd41..78e0ea48f 100644
--- a/src/attributes-test.h
+++ b/src/attributes-test.h
@@ -383,7 +383,6 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"inkscape:connector-type", true},
{"inkscape:connection-start", true},
{"inkscape:connection-end", true},
- {"inkscape:connection-points", true},
{"inkscape:connector-curvature", true},
{"inkscape:connector-avoid", true},
{"inkscape:connector-spacing", true},
diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp
index c0882c526..15a8392c4 100644
--- a/src/conn-avoid-ref.cpp
+++ b/src/conn-avoid-ref.cpp
@@ -23,7 +23,6 @@
#include "helper/geom-curves.h"
#include "svg/stringstream.h"
#include "conn-avoid-ref.h"
-#include "connection-points.h"
#include "sp-conn-end.h"
#include "sp-path.h"
#include "libavoid/router.h"
@@ -86,206 +85,6 @@ void SPAvoidRef::setAvoid(char const *value)
}
}
-static void print_connection_points(std::map<int, ConnectionPoint>& cp)
-{
- std::map<int, ConnectionPoint>::iterator i;
- for (i=cp.begin(); i!=cp.end(); ++i)
- {
- const ConnectionPoint& p = i->second;
- std::cout<<p.id<<" "<<p.type<<" "<<p.pos[Geom::X]<<" "<<p.pos[Geom::Y]<<std::endl;
- }
-}
-
-void SPAvoidRef::setConnectionPoints(gchar const *value)
-{
- std::set<int> updates;
- std::set<int> deletes;
- std::set<int> seen;
-
- if (value)
- {
- /* Rebuild the connection points list.
- Update the connectors for which
- the endpoint has changed.
- */
-
- gchar ** strarray = g_strsplit(value, "|", 0);
- gchar ** iter = strarray;
-
- while (*iter != NULL) {
- ConnectionPoint cp;
- Inkscape::SVGIStringStream is(*iter);
- is>>cp;
- cp.type = ConnPointUserDefined;
-
- /* Mark this connection point as seen, so we can delete
- the other ones.
- */
- seen.insert(cp.id);
- if ( connection_points.find(cp.id) != connection_points.end() )
- {
- /* An already existing connection point.
- Check to see if changed, and, if it is
- the case, trigger connector update for
- the connector attached to this connection
- point. This is done by adding the
- connection point to a list of connection
- points to be updated.
- */
- if ( connection_points[cp.id] != cp )
- // The connection point got updated.
- // Put it in the update list.
- updates.insert(cp.id);
- }
- connection_points[cp.id] = cp;
- ++iter;
- }
- /* Delete the connection points that didn't appear
- in the new connection point list.
- */
- std::map<int, ConnectionPoint>::iterator it;
-
- for (it=connection_points.begin(); it!=connection_points.end(); ++it)
- if ( seen.find(it->first) == seen.end())
- deletes.insert(it->first);
- g_strfreev(strarray);
- }
- else
- {
- /* Delete all the user-defined connection points
- Actually we do this by adding them to the list
- of connection points to be deleted.
- */
- std::map<int, ConnectionPoint>::iterator it;
-
- for (it=connection_points.begin(); it!=connection_points.end(); ++it)
- deletes.insert(it->first);
- }
- /* Act upon updates and deletes.
- */
- if (deletes.empty() && updates.empty())
- // Nothing to do, just return.
- return;
- // Get a list of attached connectors.
- GSList* conns = getAttachedConnectors(Avoid::runningToAndFrom);
- for (GSList *i = conns; i != NULL; i = i->next)
- {
- SPPath* path = SP_PATH(i->data);
- SPConnEnd** connEnds = path->connEndPair.getConnEnds();
- for (int ix=0; ix<2; ++ix) {
- if (connEnds[ix]->type == ConnPointUserDefined) {
- if (updates.find(connEnds[ix]->id) != updates.end()) {
- if (path->connEndPair.isAutoRoutingConn()) {
- path->connEndPair.tellLibavoidNewEndpoints();
- } else {
- }
- }
- else if (deletes.find(connEnds[ix]->id) != deletes.end()) {
- sp_conn_end_detach(path, ix);
- }
- }
- }
- }
- g_slist_free(conns);
- // Remove all deleted connection points
- if (deletes.size())
- for (std::set<int>::iterator it = deletes.begin(); it != deletes.end(); ++it)
- connection_points.erase(*it);
-}
-
-void SPAvoidRef::setConnectionPointsAttrUndoable(const gchar* value, const gchar* action)
-{
- SPDocument* doc = item->document;
-
- item->setAttribute( "inkscape:connection-points", value, 0 );
- item->updateRepr();
- doc->ensureUpToDate();
- DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, action);
-}
-
-void SPAvoidRef::addConnectionPoint(ConnectionPoint &cp)
-{
- Inkscape::SVGOStringStream ostr;
- bool first = true;
- int newId = 1;
- if ( connection_points.size() )
- {
- for (IdConnectionPointMap::iterator it = connection_points.begin(); ; )
- {
- if ( first )
- {
- first = false;
- ostr<<it->second;
- }
- else
- ostr<<'|'<<it->second;
- IdConnectionPointMap::iterator prev_it = it;
- ++it;
- if ( it == connection_points.end() || prev_it->first + 1 != it->first )
- {
- newId = prev_it->first + 1;
- break;
- }
- }
- }
- cp.id = newId;
- if ( first )
- {
- first = false;
- ostr<<cp;
- }
- else
- ostr<<'|'<<cp;
-
- this->setConnectionPointsAttrUndoable( ostr.str().c_str(), _("Add a new connection point") );
-}
-
-void SPAvoidRef::updateConnectionPoint(ConnectionPoint &cp)
-{
- Inkscape::SVGOStringStream ostr;
- IdConnectionPointMap::iterator cp_pos = connection_points.find( cp.id );
- if ( cp_pos != connection_points.end() )
- {
- bool first = true;
- for (IdConnectionPointMap::iterator it = connection_points.begin(); it != connection_points.end(); ++it)
- {
- ConnectionPoint* to_write;
- if ( it != cp_pos )
- to_write = &it->second;
- else
- to_write = &cp;
- if ( first )
- {
- first = false;
- ostr<<*to_write;
- }
- else
- ostr<<'|'<<*to_write;
- }
- this->setConnectionPointsAttrUndoable( ostr.str().c_str(), _("Move a connection point") );
- }
-}
-
-void SPAvoidRef::deleteConnectionPoint(ConnectionPoint &cp)
-{
- Inkscape::SVGOStringStream ostr;
- IdConnectionPointMap::iterator cp_pos = connection_points.find( cp.id );
- if ( cp_pos != connection_points.end() ) {
- bool first = true;
- for (IdConnectionPointMap::iterator it = connection_points.begin(); it != connection_points.end(); ++it) {
- if ( it != cp_pos ) {
- if ( first ) {
- first = false;
- ostr<<it->second;
- } else {
- ostr<<'|'<<it->second;
- }
- }
- }
- this->setConnectionPointsAttrUndoable( ostr.str().c_str(), _("Remove a connection point") );
- }
-}
-
void SPAvoidRef::handleSettingChange(void)
{
SPDesktop *desktop = inkscape_active_desktop();
@@ -387,45 +186,13 @@ GSList *SPAvoidRef::getAttachedConnectors(const unsigned int type)
return list;
}
-Geom::Point SPAvoidRef::getConnectionPointPos(const int type, const int id)
+Geom::Point SPAvoidRef::getConnectionPointPos()
{
g_assert(item);
- Geom::Point pos;
- const Geom::Affine& transform = item->i2doc_affine();
-
- if ( type == ConnPointDefault )
- {
- // For now, just default to the centre of the item
- Geom::OptRect bbox = item->documentVisualBounds();
- pos = (bbox) ? bbox->midpoint() : Geom::Point(0, 0);
- }
- else
- {
- // Get coordinates from the list of connection points
- // that are attached to the item
- pos = connection_points[id].pos * transform;
- }
-
- return pos;
-}
-
-bool SPAvoidRef::isValidConnPointId( const int type, const int id )
-{
- if ( type < 0 || type > 1 )
- return false;
- else
- {
- if ( type == ConnPointDefault )
- if ( id < 0 || id > 8 )
- return false;
- else
- {
- }
- else
- return connection_points.find( id ) != connection_points.end();
- }
-
- return true;
+ // the center is all we are interested in now; we used to care
+ // about non-center points, but that's moot.
+ Geom::OptRect bbox = item->documentVisualBounds();
+ return (bbox) ? bbox->midpoint() : Geom::Point(0, 0);
}
static std::vector<Geom::Point> approxCurveWithPoints(SPCurve *curve)
diff --git a/src/conn-avoid-ref.h b/src/conn-avoid-ref.h
index 4d38f2845..30b380eb7 100644
--- a/src/conn-avoid-ref.h
+++ b/src/conn-avoid-ref.h
@@ -13,14 +13,13 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include <2geom/point.h>
#include <glib.h>
#include <stddef.h>
#include <sigc++/connection.h>
class SPDesktop;
class SPItem;
-struct ConnectionPoint;
-typedef std::map<int, ConnectionPoint> IdConnectionPointMap;
namespace Avoid { class ShapeRef; }
class SPAvoidRef {
@@ -31,16 +30,11 @@ public:
// libavoid's internal representation of the item.
Avoid::ShapeRef *shapeRef;
- // Used for holding connection points for item
- IdConnectionPointMap connection_points;
-
void setAvoid(char const *value);
- void setConnectionPoints(gchar const *value);
- void addConnectionPoint(ConnectionPoint &cp);
- void updateConnectionPoint(ConnectionPoint &cp);
- void deleteConnectionPoint(ConnectionPoint &cp);
void handleSettingChange(void);
+ Geom::Point getConnectionPointPos(void);
+
// Returns a list of SPItems of all connectors/shapes attached to
// this object. Pass one of the following for 'type':
// Avoid::runningTo
@@ -48,9 +42,6 @@ public:
// Avoid::runningToAndFrom
GSList *getAttachedShapes(const unsigned int type);
GSList *getAttachedConnectors(const unsigned int type);
- Geom::Point getConnectionPointPos(const int type, const int id);
-
- bool isValidConnPointId( const int type, const int id );
private:
SPItem *item;
@@ -61,7 +52,6 @@ private:
// A sigc connection for transformed signal.
sigc::connection _transformed_connection;
- void setConnectionPointsAttrUndoable(const gchar* value, const gchar* action);
};
extern GSList *get_avoided_items(GSList *list, SPObject *from,
diff --git a/src/connection-points.cpp b/src/connection-points.cpp
deleted file mode 100644
index 9ed98d211..000000000
--- a/src/connection-points.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "connection-points.h"
-
-
-bool ConnectionPoint::operator!=(ConnectionPoint& cp)
-{
- return (id!=cp.id || type!=cp.type || dir!=cp.dir || pos!=cp.pos);
-}
-
-bool ConnectionPoint::operator==(ConnectionPoint& cp)
-{
- return (id==cp.id && type==cp.type && dir==cp.dir && pos==cp.pos);
-}
-
-
-namespace Inkscape{
-
-SVGIStringStream&
-operator>>(SVGIStringStream& istr, ConnectionPoint& cp)
-{
- istr>>cp.id>>cp.dir>>cp.pos[Geom::X]>>cp.pos[Geom::Y];
-
- return istr;
-}
-
-SVGOStringStream&
-operator<<(SVGOStringStream& ostr, const ConnectionPoint& cp)
-{
- ostr<<cp.id<<' '<<cp.dir<<' ';
- ::operator<<( ostr, cp.pos[Geom::X] );
- ostr<<' ';
- ::operator<<( ostr, cp.pos[Geom::Y] );
-
- return ostr;
-}
-
-
-}
diff --git a/src/connection-points.h b/src/connection-points.h
deleted file mode 100644
index c1ddeb481..000000000
--- a/src/connection-points.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef INKSCAPE_CONNECTION_POINT_H
-#define INKSCAPE_CONNECTION_POINT_H
-
-#include <2geom/point.h>
-//#include <libavoid/vertices.h>
-#include <libavoid/connector.h>
-
-#include "svg/stringstream.h"
-
-
-enum ConnPointType {
- ConnPointDefault = 0,
- ConnPointUserDefined = 1
-};
-enum ConnPointDefaultPos{
- ConnPointPosTL, // Top Left
- ConnPointPosTC, // Top Centre
- ConnPointPosTR, // Top Right
- ConnPointPosCL, // Centre Left
- ConnPointPosCC, // Centre Centre
- ConnPointPosCR, // Centre Right
- ConnPointPosBL, // Bottom Left
- ConnPointPosBC, // Bottom Centre
- ConnPointPosBR, // Bottom Right
-};
-
-
-struct ConnectionPoint
-{
- ConnectionPoint():
- type(ConnPointDefault), // default to a default connection point
- id(ConnPointPosCC), // default to the centre point
- pos(),
- dir(Avoid::ConnDirAll) // allow any direction
- {
- }
- // type of the connection point
- // default or user-defined
- int type;
-
- /* id of the connection point
- in the case of default
- connection points it specifies
- which of the 9 types the
- connection point is.
- */
- int id;
-
- /* position related to parent item
- in the case of default connection
- points, these positions should be
- computed by the item's avoidRef
- */
- Geom::Point pos;
-
- // directions from which connections can occur
- Avoid::ConnDirFlags dir;
-
- bool operator!=(ConnectionPoint&);
- bool operator==(ConnectionPoint&);
-};
-
-namespace Inkscape{
-
-SVGIStringStream& operator>>(SVGIStringStream& istr, ConnectionPoint& cp);
-SVGOStringStream& operator<<(SVGOStringStream& ostr, const ConnectionPoint& cp);
-
-}
-
-#endif \ No newline at end of file
diff --git a/src/connector-context.cpp b/src/connector-context.cpp
index 5f87ab712..1848652e3 100644
--- a/src/connector-context.cpp
+++ b/src/connector-context.cpp
@@ -5,10 +5,11 @@
* Michael Wybrow <mjwybrow@users.sourceforge.net>
* Abhishek Sharma
* Jon A. Cruz <jon@joncruz.org>
+ * Martin Owens <doctormo@ubuntu.com>
*
* Copyright (C) 2005-2008 Michael Wybrow
* Copyright (C) 2009 Monash University
- * Copyright (C) 2010 authors
+ * Copyright (C) 2012 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*
@@ -22,7 +23,6 @@
* in the connector tool. Perhaps have a way to convert between.
* o Only call libavoid's updateEndPoint as required. Currently we do it
* for both endpoints, even if only one is moving.
- * o Allow user-placeable connection points.
* o Deal sanely with connectors with both endpoints attached to the
* same connection point, and drawing of connectors attaching
* overlapping shapes (currently tries to adjust connector to be
@@ -41,30 +41,17 @@
* o Fix up libavoid's representation after undo actions. It doesn't see
* any transform signals and hence doesn't know shapes have moved back to
* there earlier positions.
- * o Decide whether drawing/editing mode should be an Inkscape preference
- * or the connector tool should always start in drawing mode.
- * o Correct the problem with switching to the select tool when pressing
- * space bar (there are moments when it refuses to do so).
*
* ----------------------------------------------------------------------------
*
- * mjwybrow's observations on acracan's Summer of Code connector work:
+ * Notes:
*
- * - GUI comments:
- *
- * - Buttons for adding and removing user-specified connection
- * points should probably have "+" and "-" symbols on them so they
- * are consistent with the similar buttons for the node tool.
- * - Controls on the connector tool be should be reordered logically,
- * possibly as follows:
- *
- * *Connector*: [Polyline-radio-button] [Orthgonal-radio-button]
- * [Curvature-control] | *Shape*: [Avoid-button] [Dont-avoid-button]
- * [Spacing-control] | *Connection pts*: [Edit-mode] [Add-pt] [Rm-pt]
- *
- * I think that the network layout controls be moved to the
- * Align and Distribute dialog (there is already the layout button
- * there, but no options are exposed).
+ * Much of the way connectors work for user-defined points has been
+ * changed so that it no longer defines special attributes to record
+ * the points. Instead it uses single node paths to define points
+ * who are then seperate objects that can be fixed on the canvas,
+ * grouped into objects and take full advantage of all tranform, snap
+ * and align functionality of all other objects.
*
* I think that the style change between polyline and orthogonal
* would be much clearer with two buttons (radio behaviour -- just
@@ -74,80 +61,9 @@
* depending on whether an object is selected. We could consider
* this but there may not be space.
*
- * The Add-pt and Rm-pt buttons should be greyed out (inactive) if
- * we are not in connection point editing mode. And probably also
- * if there is no shape selected, i.e. at the times they have no
- * effect when clicked.
- *
* Likewise for the avoid/ignore shapes buttons. These should be
* inactive when a shape is not selected in the connector context.
*
- * - When creating/editing connection points:
- *
- * - Strange things can happen if you have connectors selected, or
- * try rerouting connectors by dragging their endpoints when in
- * connection point editing mode.
- *
- * - Possibly the selected shape's connection points should always
- * be shown (i.e., have knots) when in editing mode.
- *
- * - It is a little strange to be able to place connection points
- * competely outside shapes. Especially when you later can't draw
- * connectors to them since the knots are only visible when you
- * are over the shape. I think that you should only be able to
- * place connection points inside or on the boundary of the shape
- * itself.
- *
- * - The intended ability to place a new point at the current cursor
- * position by pressing RETURN does not seem to work.
- *
- * - The Status bar tooltip should change to reflect editing mode
- * and tell the user about RETURN and how to use the tool.
- *
- * - Connection points general:
- *
- * - Connection points that were inside the shape can end up outside
- * after a rotation is applied to the shape in the select tool.
- * It doesn't seem like the correct transform is being applied to
- * these, or it is being applied at the wrong time. I'd expect
- * connection points to rotate with the shape, and stay at the
- * same position "on the shape"
- *
- * - I was able to make the connectors attached to a shape fall off
- * the shape after scaling it. Not sure the exact cause, but may
- * require more investigation/debugging.
- *
- * - The user-defined connection points should be either absolute
- * (as the current ones are) or defined as a percentage of the
- * shape. These would be based on a toggle setting on the
- * toolbar, and they would be placed in exactly the same way by
- * the user. The only difference would be that they would be
- * store as percentage positions in the SVG connection-points
- * property and that they would update/move automatically if the
- * object was resized or scaled.
- *
- * - Thinking more, I think you always want to store and think about
- * the positions of connection points to be pre-transform, but
- * obviously the shape transform is applied to them. That way,
- * they will rotate and scale automatically with the shape, when
- * the shape transform is altered. The Percentage version would
- * compute their position from the pre-transform dimensions and
- * then have the transform applied to them, for example.
- *
- * - The connection points in the test_connection_points.svg file
- * seem to follow the shape when it is moved, but connection
- * points I add to new shapes, do not follow the shape, either
- * when the shape is just moved or transformed. There is
- * something wrong here. What exactly should the behaviour be
- * currently?
- *
- * - I see that connection points are specified at absolute canvas
- * positions. I really think that they should be specified in
- * shape coordinated relative to the shapes. There may be
- * transforms applied to layers and the canvas which would make
- * specifying them quite difficult. I'd expect a position of 0, 0
- * to be on the shape in question or very close to it, for example.
- *
*/
@@ -158,7 +74,6 @@
#include "connector-context.h"
#include "pixmaps/cursor-connector.xpm"
-#include "pixmaps/cursor-node.xpm"
#include "xml/node-event-vector.h"
#include "xml/repr.h"
#include "svg/svg.h"
@@ -219,12 +134,13 @@ static gint connector_handle_motion_notify(SPConnectorContext *const cc, GdkEven
static gint connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent);
static gint connector_handle_key_press(SPConnectorContext *const cc, guint const keyval);
-static void cc_active_shape_add_knot(SPDesktop* desktop, SPItem* item, ConnectionPointMap &cphandles, ConnectionPoint& cp);
+static void cc_active_shape_add_knot(SPConnectorContext *cc, SPItem* item);
static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item);
+static void cc_clear_active_knots(SPKnotList k);
static void cc_clear_active_shape(SPConnectorContext *cc);
static void cc_set_active_conn(SPConnectorContext *cc, SPItem *item);
static void cc_clear_active_conn(SPConnectorContext *cc);
-static bool conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid);
+static bool conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href);
static void cc_select_handle(SPKnot* knot);
static void cc_deselect_handle(SPKnot* knot);
static bool cc_item_is_shape(SPItem *item);
@@ -238,10 +154,6 @@ static void shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *nam
gchar const *old_value, gchar const *new_value, bool is_interactive,
gpointer data);
-
-static char* cc_knot_tips[] = { _("<b>Connection point</b>: click or drag to create a new connector"),
- _("<b>Connection point</b>: click to select, drag to move") };
-
/*static Geom::Point connector_drag_origin_w(0, 0);
static bool connector_within_tolerance = false;*/
static SPEventContextClass *parent_class;
@@ -316,9 +228,6 @@ sp_connector_context_init(SPConnectorContext *cc)
ec->xp = 0;
ec->yp = 0;
- cc->mode = SP_CONNECTOR_CONTEXT_DRAWING_MODE;
- cc->knot_tip = 0;
-
cc->red_color = 0xff00007f;
cc->newconn = NULL;
@@ -341,16 +250,14 @@ sp_connector_context_init(SPConnectorContext *cc)
cc->clickeditem = NULL;
cc->clickedhandle = NULL;
- new (&cc->connpthandles) ConnectionPointMap();
+ new (&cc->knots) SPKnotList();
for (int i = 0; i < 2; ++i) {
cc->endpt_handle[i] = NULL;
cc->endpt_handler_id[i] = 0;
}
cc->shref = NULL;
- cc->scpid = NULL;
cc->ehref = NULL;
- cc->ecpid = NULL;
cc->npoints = 0;
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
}
@@ -363,14 +270,6 @@ sp_connector_context_dispose(GObject *object)
cc->sel_changed_connection.disconnect();
- if (!cc->connpthandles.empty()) {
- for (ConnectionPointMap::iterator it = cc->connpthandles.begin();
- it != cc->connpthandles.end(); ++it) {
- g_object_unref(it->first);
- }
- cc->connpthandles.clear();
- }
- cc->connpthandles.~ConnectionPointMap();
for (int i = 0; i < 2; ++i) {
if (cc->endpt_handle[1]) {
g_object_unref(cc->endpt_handle[i]);
@@ -381,18 +280,10 @@ sp_connector_context_dispose(GObject *object)
g_free(cc->shref);
cc->shref = NULL;
}
- if (cc->scpid) {
- g_free(cc->scpid);
- cc->scpid = NULL;
- }
if (cc->ehref) {
g_free(cc->shref);
cc->shref = NULL;
}
- if (cc->ecpid) {
- g_free(cc->scpid);
- cc->scpid = NULL;
- }
g_assert( cc->newConnRef == NULL );
G_OBJECT_CLASS(parent_class)->dispose(object);
@@ -435,8 +326,6 @@ sp_connector_context_setup(SPEventContext *ec)
sp_event_context_read(ec, "curvature");
sp_event_context_read(ec, "orthogonal");
- sp_event_context_read(ec, "mode");
- cc->knot_tip = cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE ? cc_knot_tips[0] : cc_knot_tips[1];
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/tools/connector/selcue", 0)) {
ec->enableSelectionCue();
@@ -462,50 +351,8 @@ sp_connector_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val)
else if ( name == "orthogonal" ) {
cc->isOrthogonal = val->getBool();
}
- else if ( name == "mode")
- {
- sp_connector_context_switch_mode(ec, val->getBool() ? SP_CONNECTOR_CONTEXT_EDITING_MODE : SP_CONNECTOR_CONTEXT_DRAWING_MODE);
- }
}
-void sp_connector_context_switch_mode(SPEventContext* ec, unsigned int newMode)
-{
- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec);
-
- cc->mode = newMode;
- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
- {
- ec->cursor_shape = cursor_connector_xpm;
- cc->knot_tip = cc_knot_tips[0];
- if (cc->selected_handle)
- cc_deselect_handle( cc->selected_handle );
- cc->selected_handle = NULL;
- // Show all default connection points
-
- }
- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
- {
- ec->cursor_shape = cursor_node_xpm;
- cc->knot_tip = cc_knot_tips[1];
-/* if (cc->active_shape)
- {
- cc->selection->set( cc->active_shape );
- }
- else
- {
- SPItem* item = cc->selection->singleItem();
- if ( item )
- {
- cc_set_active_shape(cc, item);
- cc->selection->set( item );
- }
- }*/
- }
- sp_event_context_update_cursor(ec);
-
-}
-
-
static void
sp_connector_context_finish(SPEventContext *ec)
{
@@ -554,16 +401,20 @@ cc_clear_active_shape(SPConnectorContext *cc)
cc->active_shape_layer_repr = NULL;
}
+ cc_clear_active_knots(cc->knots);
+}
+
+static void
+cc_clear_active_knots(SPKnotList k)
+{
// Hide the connection points if they exist.
- if (cc->connpthandles.size()) {
- for (ConnectionPointMap::iterator it = cc->connpthandles.begin();
- it != cc->connpthandles.end(); ++it) {
+ if (k.size()) {
+ for (SPKnotList::iterator it = k.begin(); it != k.end(); ++it) {
sp_knot_hide(it->first);
}
}
}
-
static void
cc_clear_active_conn(SPConnectorContext *cc)
{
@@ -590,21 +441,15 @@ cc_clear_active_conn(SPConnectorContext *cc)
static bool
-conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid)
+conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href)
{
- // TODO: this will need to change when there are more connection
- // points available for each shape.
-
- if (cc->active_handle && (cc->connpthandles.find(cc->active_handle) != cc->connpthandles.end()))
+ if (cc->active_handle && (cc->knots.find(cc->active_handle) != cc->knots.end()))
{
p = cc->active_handle->pos;
- const ConnectionPoint& cp = cc->connpthandles[cc->active_handle];
- *href = g_strdup_printf("#%s", cc->active_shape->getId());
- *cpid = g_strdup_printf("%c%d", cp.type == ConnPointDefault ? 'd' : 'u' , cp.id);
+ *href = g_strdup_printf("#%s", cc->active_handle->owner->getId());
return true;
}
*href = NULL;
- *cpid = NULL;
return false;
}
@@ -660,14 +505,8 @@ sp_connector_context_item_handler(SPEventContext *event_context, SPItem *item, G
cc->selection->toggle(item);
} else {
cc->selection->set(item);
- if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE && cc->selected_handle )
- {
- cc_deselect_handle( cc->selected_handle );
- cc->selected_handle = NULL;
- }
- /* When selecting a new item,
- do not allow showing connection points
- on connectors. (yet?)
+ /* When selecting a new item, do not allow showing
+ connection points on connectors. (yet?)
*/
if ( item != cc->active_shape && !cc_item_is_connector( item ) )
cc_set_active_shape( cc, item );
@@ -678,20 +517,9 @@ sp_connector_context_item_handler(SPEventContext *event_context, SPItem *item, G
break;
case GDK_ENTER_NOTIFY:
{
- if (cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE || (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE && !cc->selected_handle))
+ if (!cc->selected_handle)
{
if (cc_item_is_shape(item)) {
-
- // I don't really understand what the above does,
- // so I commented it.
- // This is a shape, so show connection point(s).
- /* if (!(cc->active_shape)
- // Don't show handle for another handle.
- // || (cc->connpthandles.find((SPKnot*) item) != cc->connpthandles.end())
- )
- {
- cc_set_active_shape(cc, item);
- }*/
cc_set_active_shape(cc, item);
}
ret = TRUE;
@@ -754,8 +582,7 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
SPEventContext *event_context = SP_EVENT_CONTEXT(cc);
gint ret = FALSE;
- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
- {
+
if ( bevent.button == 1 && !event_context->space_panning ) {
SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
@@ -766,7 +593,7 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
Geom::Point const event_w(bevent.x,
bevent.y);
-// connector_drag_origin_w = event_w;
+
cc->xp = bevent.x;
cc->yp = bevent.y;
cc->within_tolerance = true;
@@ -790,7 +617,7 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
Geom::Point p = event_dt;
// Test whether we clicked on a connection point
- bool found = conn_pt_handle_test(cc, p, &cc->shref, &cc->scpid);
+ bool found = conn_pt_handle_test(cc, p, &cc->shref);
if (!found) {
// This is the first point, so just snap it to the grid
@@ -815,8 +642,8 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
spcc_connector_set_subsequent_point(cc, p);
spcc_connector_finish_segment(cc, p);
- // Test whether we clicked on a connection point
- /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
+
+ conn_pt_handle_test(cc, p, &cc->ehref);
if (cc->npoints != 0) {
spcc_connector_finish(cc);
}
@@ -850,73 +677,9 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
ret = TRUE;
}
}
- }
- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
- {
- if ( bevent.button == 1 && !event_context->space_panning )
- {
- // Initialize variables in case of dragging
-
- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
-
- if (Inkscape::have_viable_layer(desktop, cc->_message_context) == false) {
- return TRUE;
- }
-
- cc->xp = bevent.x;
- cc->yp = bevent.y;
- cc->within_tolerance = true;
-
- ConnectionPointMap::iterator const& active_knot_it = cc->connpthandles.find( cc->active_handle );
-
- switch (cc->state)
- {
- case SP_CONNECTOR_CONTEXT_IDLE:
- if ( active_knot_it != cc->connpthandles.end() )
- {
- // We do not allow selecting and, thereby, moving default knots
- if ( active_knot_it->second.type != ConnPointDefault)
- {
- if (cc->selected_handle != cc->active_handle)
- {
- if ( cc->selected_handle )
- cc_deselect_handle( cc->selected_handle );
- cc->selected_handle = cc->active_handle;
- cc_select_handle( cc->selected_handle );
- }
- }
- else
- // Just ignore the default connection point
- return FALSE;
- }
- else
- if ( cc->selected_handle )
- {
- cc_deselect_handle( cc->selected_handle );
- cc->selected_handle = NULL;
- }
-
- if ( cc->selected_handle )
- {
- cc->state = SP_CONNECTOR_CONTEXT_DRAGGING;
- cc->selection->set( cc->active_shape );
- }
-
- ret = TRUE;
- break;
- // Dragging valid because of the way we create
- // new connection points.
- case SP_CONNECTOR_CONTEXT_DRAGGING:
- // Do nothing.
- ret = TRUE;
- break;
- }
- }
- }
return ret;
}
-
static gint
connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion const &mevent)
{
@@ -948,8 +711,6 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons
/* Find desktop coordinates */
Geom::Point p = dt->w2d(event_w);
- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
- {
SnapManager &m = dt->namedview->snap_manager;
switch (cc->state) {
@@ -1010,26 +771,9 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons
}
break;
}
- }
- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
- {
- switch ( cc->state )
- {
- case SP_CONNECTOR_CONTEXT_DRAGGING:
- sp_knot_set_position(cc->selected_handle, p, 0);
- ret = TRUE;
- break;
- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
- sp_knot_set_position(cc->selected_handle, p, 0);
- ret = TRUE;
- break;
- }
- }
-
return ret;
}
-
static gint
connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent)
{
@@ -1046,8 +790,7 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
/* Find desktop coordinates */
Geom::Point p = cc->desktop->w2d(event_w);
- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
- {
+
switch (cc->state) {
//case SP_CONNECTOR_CONTEXT_POINT:
case SP_CONNECTOR_CONTEXT_DRAGGING:
@@ -1065,7 +808,7 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
spcc_connector_set_subsequent_point(cc, p);
spcc_connector_finish_segment(cc, p);
// Test whether we clicked on a connection point
- /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
+ conn_pt_handle_test(cc, p, &cc->ehref);
if (cc->npoints != 0) {
spcc_connector_finish(cc);
}
@@ -1093,68 +836,14 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
}
ret = TRUE;
}
- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
- {
- switch ( cc->state )
- {
- case SP_CONNECTOR_CONTEXT_DRAGGING:
-
- if (!cc->within_tolerance)
- {
- m.setup(desktop);
- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- m.unSetup();
- sp_knot_set_position(cc->selected_handle, p, 0);
- ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
- cp.pos = p * (cc->active_shape)->dt2i_affine();
- cc->active_shape->avoidRef->updateConnectionPoint(cp);
- }
-
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
- break;
-
-
- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
- m.setup(desktop);
- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- m.unSetup();
-
- sp_knot_set_position(cc->selected_handle, p, 0);
-
- ConnectionPoint cp;
- cp.type = ConnPointUserDefined;
- cp.pos = p * (cc->active_shape)->dt2i_affine();
- cp.dir = Avoid::ConnDirAll;
- g_object_unref(cc->selected_handle);
- cc->active_shape->avoidRef->addConnectionPoint(cp);
- doc->ensureUpToDate();
- for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it)
- if (it->second.type == ConnPointUserDefined && it->second.id == cp.id)
- {
- cc->selected_handle = it->first;
- break;
- }
- cc_select_handle( cc->selected_handle );
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
- break;
- }
- }
- }
-
-
return ret;
}
-
static gint
connector_handle_key_press(SPConnectorContext *const cc, guint const keyval)
{
gint ret = FALSE;
- /* fixme: */
- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
- {
+
switch (keyval) {
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
@@ -1189,100 +878,6 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval)
default:
break;
}
- }
- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
- {
- switch ( cc->state )
- {
- case SP_CONNECTOR_CONTEXT_DRAGGING:
- if ( keyval == GDK_KEY_Escape )
- {
- // Cancel connection point dragging
-
- // Obtain original position
- ConnectionPoint const& cp = cc->connpthandles[cc->selected_handle];
- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
- const Geom::Affine& i2doc = (cc->active_shape)->i2doc_affine();
- sp_knot_set_position(cc->selected_handle, cp.pos * i2doc * desktop->doc2dt(), 0);
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE,
- _("Connection point drag cancelled."));
- ret = TRUE;
- }
- else if ( keyval == GDK_KEY_Return || keyval == GDK_KEY_KP_Enter )
- {
- // Put connection point at current position
-
- Geom::Point p = cc->selected_handle->pos;
-
- if (!cc->within_tolerance)
- {
- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- m.unSetup();
- sp_knot_set_position(cc->selected_handle, p, 0);
- ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
- cp.pos = p * (cc->active_shape)->dt2i_affine();
- cc->active_shape->avoidRef->updateConnectionPoint(cp);
- }
-
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
- }
- break;
- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
- if ( keyval == GDK_KEY_Escape )
- {
- // Just destroy the knot
- g_object_unref( cc->selected_handle );
- cc->selected_handle = NULL;
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
- }
- else if ( keyval == GDK_KEY_Return || keyval == GDK_KEY_KP_Enter )
- {
- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
- SPDocument *doc = sp_desktop_document(desktop);
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
- Geom::Point p = cc->selected_handle->pos;
- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- m.unSetup();
- sp_knot_set_position(cc->selected_handle, p, 0);
-
- ConnectionPoint cp;
- cp.type = ConnPointUserDefined;
- cp.pos = p * (cc->active_shape)->dt2i_affine();
- cp.dir = Avoid::ConnDirAll;
- g_object_unref(cc->selected_handle);
- cc->active_shape->avoidRef->addConnectionPoint(cp);
- doc->ensureUpToDate();
- for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it)
- if (it->second.type == ConnPointUserDefined && it->second.id == cp.id)
- {
- cc->selected_handle = it->first;
- break;
- }
- cc_select_handle( cc->selected_handle );
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
- }
-
- break;
- case SP_CONNECTOR_CONTEXT_IDLE:
- if ( keyval == GDK_KEY_Delete && cc->selected_handle )
- {
- cc->active_shape->avoidRef->deleteConnectionPoint(cc->connpthandles[cc->selected_handle]);
- cc->selected_handle = NULL;
- ret = TRUE;
- }
-
- break;
- }
- }
-
return ret;
}
@@ -1300,17 +895,15 @@ cc_connector_rerouting_finish(SPConnectorContext *const cc, Geom::Point *const p
if (p != NULL)
{
// Test whether we clicked on a connection point
- gchar *shape_label, *cpid;
- bool found = conn_pt_handle_test(cc, *p, &shape_label, &cpid);
+ gchar *shape_label;
+ bool found = conn_pt_handle_test(cc, *p, &shape_label);
if (found) {
if (cc->clickedhandle == cc->endpt_handle[0]) {
cc->clickeditem->setAttribute("inkscape:connection-start", shape_label, NULL);
- cc->clickeditem->setAttribute("inkscape:connection-start-point", cpid, NULL);
}
else {
cc->clickeditem->setAttribute("inkscape:connection-end", shape_label, NULL);
- cc->clickeditem->setAttribute("inkscape:connection-end-point", cpid, NULL);
}
g_free(shape_label);
}
@@ -1456,18 +1049,12 @@ spcc_flush_white(SPConnectorContext *cc, SPCurve *gc)
if (cc->shref)
{
cc->newconn->setAttribute( "inkscape:connection-start", cc->shref, NULL);
- if (cc->scpid) {
- cc->newconn->setAttribute( "inkscape:connection-start-point", cc->scpid, NULL);
- }
connection = true;
}
if (cc->ehref)
{
cc->newconn->setAttribute( "inkscape:connection-end", cc->ehref, NULL);
- if (cc->ecpid) {
- cc->newconn->setAttribute( "inkscape:connection-end-point", cc->ecpid, NULL);
- }
connection = true;
}
// Process pending updates.
@@ -1540,7 +1127,7 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot)
gboolean consumed = FALSE;
- gchar* knot_tip = knot->tip ? knot->tip : cc->knot_tip;
+ gchar* knot_tip = "Click to join at this point";
switch (event->type) {
case GDK_ENTER_NOTIFY:
sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE);
@@ -1624,10 +1211,12 @@ endpt_handler(SPKnot */*knot*/, GdkEvent *event, SPConnectorContext *cc)
return consumed;
}
-static void cc_active_shape_add_knot(SPDesktop* desktop, SPItem* item, ConnectionPointMap &cphandles, ConnectionPoint& cp)
+static void cc_active_shape_add_knot(SPConnectorContext *cc, SPItem* item)
{
+ SPDesktop *desktop = cc->desktop;
SPKnot *knot = sp_knot_new(desktop, 0);
+ knot->owner = item;
knot->setShape(SP_KNOT_SHAPE_SQUARE);
knot->setSize(8);
knot->setAnchor(SP_ANCHOR_CENTER);
@@ -1641,17 +1230,15 @@ static void cc_active_shape_add_knot(SPDesktop* desktop, SPItem* item, Connectio
g_signal_connect(G_OBJECT(knot->item), "event",
G_CALLBACK(cc_generic_knot_handler), knot);
- sp_knot_set_position(knot, item->avoidRef->getConnectionPointPos(cp.type, cp.id) * desktop->doc2dt(), 0);
+ sp_knot_set_position(knot, item->avoidRef->getConnectionPointPos() * desktop->doc2dt(), 0);
sp_knot_show(knot);
- cphandles[knot] = cp;
+ cc->knots[knot] = 1;
}
static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item)
{
g_assert(item != NULL );
- std::map<int, ConnectionPoint>* connpts = &item->avoidRef->connection_points;
-
if (cc->active_shape != item)
{
// The active shape has changed
@@ -1677,84 +1264,23 @@ static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item)
sp_repr_add_listener(cc->active_shape_layer_repr, &layer_repr_events, cc);
}
+ cc_clear_active_knots(cc->knots);
+
+ // The idea here is to try and add a group's children to solidify
+ // connection handling. We react to path objects with only one node.
+ for (SPObject *child = item->firstChild() ; child ; child = child->getNext() ) {
+ if (SP_IS_PATH(child) && SP_PATH(child)->nodesInPath() == 1) {
+ cc_active_shape_add_knot(cc, (SPItem *) child);
+ }
+ }
+ cc_active_shape_add_knot(cc, item);
- // Set the connection points.
- if ( cc->connpthandles.size() )
- // destroy the old list
- while (! cc->connpthandles.empty() )
- {
- g_object_unref(cc->connpthandles.begin()->first);
- cc->connpthandles.erase(cc->connpthandles.begin());
- }
- // build the new one
- if ( connpts->size() )
- for (std::map<int, ConnectionPoint>::iterator it = connpts->begin(); it != connpts->end(); ++it)
- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, it->second);
-
- // Also add default connection points
- // For now, only centre default connection point will
- // be available
- ConnectionPoint centre;
- centre.type = ConnPointDefault;
- centre.id = ConnPointPosCC;
- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, centre);
}
else
{
- // The active shape didn't change
- // Update only the connection point knots
-
// Ensure the item's connection_points map
// has been updated
item->document->ensureUpToDate();
-
- std::set<int> seen;
- for ( ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end() ;)
- {
- bool removed = false;
- if ( it->second.type == ConnPointUserDefined )
- {
- std::map<int, ConnectionPoint>::iterator p = connpts->find(it->second.id);
- if (p != connpts->end())
- {
- if ( it->second != p->second )
- // Connection point position has changed
- // Update knot position
- sp_knot_set_position(it->first,
- item->avoidRef->getConnectionPointPos(it->second.type, it->second.id) * cc->desktop->doc2dt(), 0);
- seen.insert(it->second.id);
- sp_knot_show(it->first);
- }
- else
- {
- // This connection point does no longer exist,
- // remove the knot
- ConnectionPointMap::iterator curr = it;
- ++it;
- g_object_unref( curr->first );
- cc->connpthandles.erase(curr);
- removed = true;
- }
- }
- else
- {
- // It's a default connection point
- // Just make sure it's position is correct
- sp_knot_set_position(it->first,
- item->avoidRef->getConnectionPointPos(it->second.type, it->second.id) * cc->desktop->doc2dt(), 0);
- sp_knot_show(it->first);
-
- }
- if ( !removed )
- ++it;
- }
- // Add knots for new connection points.
- if (connpts->size())
- for ( std::map<int, ConnectionPoint>::iterator it = connpts->begin(); it != connpts->end(); ++it )
- if ( seen.find(it->first) == seen.end() )
- // A new connection point has been added
- // to the shape. Add a knot for it.
- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, it->second);
}
}
@@ -1885,15 +1411,6 @@ void cc_create_connection_point(SPConnectorContext* cc)
}
}
-void cc_remove_connection_point(SPConnectorContext* cc)
-{
- if (cc->selected_handle && cc->state == SP_CONNECTOR_CONTEXT_IDLE )
- {
- cc->active_shape->avoidRef->deleteConnectionPoint(cc->connpthandles[cc->selected_handle]);
- cc->selected_handle = NULL;
- }
-}
-
static bool cc_item_is_shape(SPItem *item)
{
if (SP_IS_PATH(item)) {
@@ -2032,12 +1549,6 @@ shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
cc_set_active_conn(cc, cc->active_conn);
}
}
- else
- if ( !strcmp(name, "inkscape:connection-points") )
- if (repr == cc->active_shape_repr)
- // The connection points of the active shape
- // have changed. Update them.
- cc_set_active_shape(cc, cc->active_shape);
}
diff --git a/src/connector-context.h b/src/connector-context.h
index 128f2bbeb..e157bbf50 100644
--- a/src/connector-context.h
+++ b/src/connector-context.h
@@ -18,7 +18,6 @@
#include "event-context.h"
#include <2geom/point.h>
#include "libavoid/connector.h"
-#include "connection-points.h"
#include <glibmm/i18n.h>
#define SP_TYPE_CONNECTOR_CONTEXT (sp_connector_context_get_type())
@@ -44,12 +43,7 @@ enum {
SP_CONNECTOR_CONTEXT_NEWCONNPOINT
};
-enum {
- SP_CONNECTOR_CONTEXT_DRAWING_MODE,
- SP_CONNECTOR_CONTEXT_EDITING_MODE
-};
-
-typedef std::map<SPKnot *, ConnectionPoint> ConnectionPointMap;
+typedef std::map<SPKnot *, int> SPKnotList;
struct SPConnectorContext : public SPEventContext {
Inkscape::Selection *selection;
@@ -57,14 +51,8 @@ struct SPConnectorContext : public SPEventContext {
/** \invar npoints in {0, 2}. */
gint npoints;
- /* The tool mode can be connector drawing or
- connection points editing.
- */
- unsigned int mode : 1;
unsigned int state : 4;
- gchar* knot_tip;
-
// Red curve
SPCanvasItem *red_bpath;
SPCurve *red_curve;
@@ -89,7 +77,6 @@ struct SPConnectorContext : public SPEventContext {
Inkscape::XML::Node *active_conn_repr;
sigc::connection sel_changed_connection;
-
// The activehandle
SPKnot *active_handle;
@@ -99,13 +86,11 @@ struct SPConnectorContext : public SPEventContext {
SPItem *clickeditem;
SPKnot *clickedhandle;
- ConnectionPointMap connpthandles;
+ SPKnotList knots;
SPKnot *endpt_handle[2];
guint endpt_handler_id[2];
gchar *shref;
- gchar *scpid;
gchar *ehref;
- gchar *ecpid;
SPCanvasItem *c0, *c1, *cl0, *cl1;
};
@@ -113,7 +98,6 @@ struct SPConnectorContextClass : public SPEventContextClass { };
GType sp_connector_context_get_type();
-void sp_connector_context_switch_mode(SPEventContext* ec, unsigned int newMode);
void cc_selection_set_avoid(bool const set_ignore);
void cc_create_connection_point(SPConnectorContext* cc);
void cc_remove_connection_point(SPConnectorContext* cc);
diff --git a/src/knot.cpp b/src/knot.cpp
index afcd70eb5..890abd0a1 100644
--- a/src/knot.cpp
+++ b/src/knot.cpp
@@ -184,6 +184,7 @@ static void sp_knot_init(SPKnot *knot)
{
knot->desktop = NULL;
knot->item = NULL;
+ knot->owner = NULL;
knot->flags = 0;
knot->size = 8;
diff --git a/src/knot.h b/src/knot.h
index c0d2f68e4..ec640df3a 100644
--- a/src/knot.h
+++ b/src/knot.h
@@ -21,6 +21,7 @@
#include <sigc++/sigc++.h>
#include "enums.h"
#include <gtk/gtk.h>
+#include "sp-item.h"
class SPDesktop;
class SPKnot;
@@ -43,6 +44,7 @@ struct SPCanvasItem;
struct SPKnot : GObject {
SPDesktop *desktop; /**< Desktop we are on. */
SPCanvasItem *item; /**< Our CanvasItem. */
+ SPItem *owner; /**< Optional Owner Item */
guint flags;
guint size; /**< Always square. */
diff --git a/src/sp-conn-end-pair.cpp b/src/sp-conn-end-pair.cpp
index 17e9e7397..8e89b28fb 100644
--- a/src/sp-conn-end-pair.cpp
+++ b/src/sp-conn-end-pair.cpp
@@ -82,9 +82,7 @@ sp_conn_end_pair_build(SPObject *object)
{
object->readAttr( "inkscape:connector-type" );
object->readAttr( "inkscape:connection-start" );
- object->readAttr( "inkscape:connection-start-point" );
object->readAttr( "inkscape:connection-end" );
- object->readAttr( "inkscape:connection-end-point" );
object->readAttr( "inkscape:connector-curvature" );
}
@@ -164,10 +162,6 @@ SPConnEndPair::setAttr(unsigned const key, gchar const *const value)
case SP_ATTR_CONNECTION_END:
this->_connEnd[(key == SP_ATTR_CONNECTION_START ? 0 : 1)]->setAttacherHref(value, _path);
break;
- case SP_ATTR_CONNECTION_START_POINT:
- case SP_ATTR_CONNECTION_END_POINT:
- this->_connEnd[(key == SP_ATTR_CONNECTION_START_POINT ? 0 : 1)]->setAttacherEndpoint(value, _path);
- break;
}
}
@@ -175,15 +169,10 @@ SPConnEndPair::setAttr(unsigned const key, gchar const *const value)
void
SPConnEndPair::writeRepr(Inkscape::XML::Node *const repr) const
{
- char const * const attr_strs[] = {"inkscape:connection-start", "inkscape:connection-start-point",
- "inkscape:connection-end", "inkscape:connection-end-point"};
+ char const * const attr_strs[] = {"inkscape:connection-start", "inkscape:connection-end"};
for (unsigned handle_ix = 0; handle_ix < 2; ++handle_ix) {
if (this->_connEnd[handle_ix]->ref.getURI()) {
- repr->setAttribute(attr_strs[2*handle_ix], this->_connEnd[handle_ix]->ref.getURI()->toString());
- std::ostringstream ostr;
- ostr<<(this->_connEnd[handle_ix]->type == ConnPointDefault ? "d":"u") <<
- this->_connEnd[handle_ix]->id;
- repr->setAttribute(attr_strs[2*handle_ix+1], ostr.str().c_str());
+ repr->setAttribute(attr_strs[handle_ix], this->_connEnd[handle_ix]->ref.getURI()->toString());
}
}
repr->setAttribute("inkscape:connector-curvature", Glib::Ascii::dtostr(_connCurvature).c_str());
@@ -222,7 +211,7 @@ void SPConnEndPair::getEndpoints(Geom::Point endPts[]) const
for (unsigned h = 0; h < 2; ++h) {
if ( h2attItem[h] ) {
g_assert(h2attItem[h]->avoidRef);
- endPts[h] = h2attItem[h]->avoidRef->getConnectionPointPos(_connEnd[h]->type, _connEnd[h]->id);
+ endPts[h] = h2attItem[h]->avoidRef->getConnectionPointPos();
}
else if (!curve->is_empty())
{
diff --git a/src/sp-conn-end.cpp b/src/sp-conn-end.cpp
index cabda82d3..c136cea66 100644
--- a/src/sp-conn-end.cpp
+++ b/src/sp-conn-end.cpp
@@ -21,11 +21,10 @@ SPConnEnd::SPConnEnd(SPObject *const owner) :
ref(owner),
href(NULL),
// Default to center connection endpoint
- type(ConnPointDefault),
- id(4),
_changed_connection(),
_delete_connection(),
- _transformed_connection()
+ _transformed_connection(),
+ _group_connection()
{
}
@@ -154,9 +153,9 @@ sp_conn_get_route_and_redraw(SPPath *const path,
Geom::PathVector conn_pv = path->_curve->get_pathvector();
double endPos[2] = { 0.0, static_cast<double>(conn_pv[0].size()) };
- SPConnEnd** _connEnd = path->connEndPair.getConnEnds();
for (unsigned h = 0; h < 2; ++h) {
- if (h2attItem[h] && _connEnd[h]->type == ConnPointDefault && _connEnd[h]->id == ConnPointPosCC) {
+ // Assume center point for all
+ if (h2attItem[h]) {
Geom::Affine h2i2anc = i2anc_affine(h2attItem[h], ancestor);
try_get_intersect_point_with_item(path, h2attItem[h], h2i2anc, path2anc,
(h == 0), endPos[h]);
@@ -228,13 +227,9 @@ change_endpts(SPCurve *const curve, double const endPos[2])
static void
sp_conn_end_deleted(SPObject *, SPObject *const owner, unsigned const handle_ix)
{
- // todo: The first argument is the deleted object, or just NULL if
- // called by sp_conn_end_detach.
- g_return_if_fail(handle_ix < 2);
- char const * const attr_strs[] = {"inkscape:connection-start", "inkscape:connection-start-point",
- "inkscape:connection-end", "inkscape:connection-end-point"};
- owner->getRepr()->setAttribute(attr_strs[2*handle_ix], NULL);
- owner->getRepr()->setAttribute(attr_strs[2*handle_ix+1], NULL);
+ char const * const attrs[] = {
+ "inkscape:connection-start", "inkscape:connection-end"};
+ owner->getRepr()->setAttribute(attrs[handle_ix], NULL);
/* I believe this will trigger sp_conn_end_href_changed. */
}
@@ -283,84 +278,6 @@ SPConnEnd::setAttacherHref(gchar const *value, SPPath* /*path*/)
}
}
-void
-SPConnEnd::setAttacherEndpoint(gchar const *value, SPPath* /*path*/)
-{
-
- /* References to the connection points have the following format
- <t><id>, where t is the type of the point, which
- can be either "d" for default or "u" for user-defined, and
- id is the local (inside the item) id of the connection point.
- In the case of default points id represents the position on the
- item (i.e. Top-Left, Center-Center, etc.).
- */
-
- bool changed = false;
- ConnPointType newtype = type;
-
- if (!value)
- {
- // Default to center endpoint
- type = ConnPointDefault;
- id = 4;
- }
- else
- {
- switch (value[0])
- {
- case 'd':
- if ( newtype != ConnPointDefault )
- {
- newtype = ConnPointDefault;
- changed = true;
- }
- break;
- case 'u':
- if ( newtype != ConnPointUserDefined)
- {
- newtype = ConnPointUserDefined;
- changed = true;
- }
- break;
- default:
- g_warning("Bad reference to a connection point.");
- }
-
- int newid = (int) g_ascii_strtod( value+1, 0 );
- if ( id != newid )
- {
- id = newid;
- changed = true;
- }
-
- // We have to verify that the reference to the
- // connection point is a valid one.
-
- if ( changed )
- {
-
- // Get the item the connector is attached to
- SPItem* item = ref.getObject();
- if ( item )
- {
- if (!item->avoidRef->isValidConnPointId( newtype, newid ) )
- {
- g_warning("Bad reference to a connection point.");
- }
- else
- {
- type = newtype;
- id = newid;
- }
- /* // Update the connector
- if (path->connEndPair.isAutoRoutingConn()) {
- path->connEndPair.tellLibavoidNewEndpoints();
- }
- */
- }
- }
- }
-}
void
sp_conn_end_href_changed(SPObject */*old_ref*/, SPObject */*ref*/,
@@ -370,6 +287,7 @@ sp_conn_end_href_changed(SPObject */*old_ref*/, SPObject */*ref*/,
SPConnEnd &connEnd = *connEndPtr;
connEnd._delete_connection.disconnect();
connEnd._transformed_connection.disconnect();
+ connEnd._group_connection.disconnect();
if (connEnd.href) {
SPObject *refobj = connEnd.ref.getObject();
@@ -377,6 +295,14 @@ sp_conn_end_href_changed(SPObject */*old_ref*/, SPObject */*ref*/,
connEnd._delete_connection
= refobj->connectDelete(sigc::bind(sigc::ptr_fun(&sp_conn_end_deleted),
path, handle_ix));
+ // This allows the connector tool to dive into a group's children
+ // And connect to their children's centers.
+ SPObject *parent = refobj->parent;
+ if (SP_IS_GROUP(parent) and ! SP_IS_LAYER(parent)) {
+ connEnd._group_connection
+ = SP_ITEM(parent)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_conn_end_shape_move),
+ path));
+ }
connEnd._transformed_connection
= SP_ITEM(refobj)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_conn_end_shape_move),
path));
diff --git a/src/sp-conn-end.h b/src/sp-conn-end.h
index de0d2c0b7..a0b1ba5df 100644
--- a/src/sp-conn-end.h
+++ b/src/sp-conn-end.h
@@ -6,7 +6,6 @@
#include <sigc++/connection.h>
#include "sp-use-reference.h"
-#include "connection-points.h"
#include "conn-avoid-ref.h"
class SPPath;
@@ -18,15 +17,6 @@ public:
SPUseReference ref;
gchar *href;
- /* In the following, type refers to connection point type,
- i.e. default (one of the 9 combinations of right, centre,
- left, top, bottom) or user-defined. The id serves to identify
- the connection point in a list of connection points.
- */
-
- ConnPointType type;
- int id;
-
/** Change of href string (not a modification of the attributes of the referrent). */
sigc::connection _changed_connection;
@@ -36,6 +26,9 @@ public:
/** A sigc connection for transformed signal, used to do move compensation. */
sigc::connection _transformed_connection;
+ /** A sigc connection for owning group transformed, used to do move compensation. */
+ sigc::connection _group_connection;
+
void setAttacherHref(gchar const *, SPPath *);
void setAttacherEndpoint(gchar const *, SPPath *);
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 3ca7d5d16..8d6b07058 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -511,9 +511,6 @@ void SPItem::sp_item_set(SPObject *object, unsigned key, gchar const *value)
case SP_ATTR_CONNECTOR_AVOID:
item->avoidRef->setAvoid(value);
break;
- case SP_ATTR_CONNECTION_POINTS:
- item->avoidRef->setConnectionPoints(value);
- break;
case SP_ATTR_TRANSFORM_CENTER_X:
if (value) {
item->transform_center_x = g_strtod(value, NULL);
diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp
index 87deffc71..7c72f8e0c 100644
--- a/src/widgets/connector-toolbar.cpp
+++ b/src/widgets/connector-toolbar.cpp
@@ -78,13 +78,6 @@ using Inkscape::UI::PrefPusher;
//## Connector ##
//#########################
-static void sp_connector_mode_toggled( GtkToggleAction* act, GObject * /*tbl*/ )
-{
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setBool("/tools/connector/mode",
- gtk_toggle_action_get_active( act ));
-}
-
static void sp_connector_path_set_avoid(void)
{
cc_selection_set_avoid(true);
@@ -303,26 +296,6 @@ static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr,
}
}
-static void sp_connector_new_connection_point(GtkWidget *, GObject *tbl)
-{
- SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));
- SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context);
-
- if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) {
- cc_create_connection_point(cc);
- }
-}
-
-static void sp_connector_remove_connection_point(GtkWidget *, GObject *tbl)
-{
- SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));
- SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context);
-
- if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) {
- cc_remove_connection_point(cc);
- }
-}
-
static Inkscape::XML::NodeEventVector connector_tb_repr_events = {
NULL, /* child_added */
NULL, /* child_removed */
@@ -351,22 +324,6 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions,
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
- // Editing mode toggle button
- {
- InkToggleAction* act = ink_toggle_action_new( "ConnectorEditModeAction",
- _("EditMode"),
- _("Switch between connection point editing and connector drawing mode"),
- INKSCAPE_ICON("connector-edit"),
- Inkscape::ICON_SIZE_DECORATION );
- gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
-
- bool tbuttonstate = prefs->getBool("/tools/connector/mode");
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE ));
- g_object_set_data( holder, "mode", act );
- g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_mode_toggled), holder );
- }
-
-
{
InkAction* inky = ink_action_new( "ConnectorAvoidAction",
_("Avoid"),
@@ -480,30 +437,6 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions,
}
- // New connection point button
- {
- InkAction* inky = ink_action_new( "ConnectorNewConnPointAction",
- _("New connection point"),
- _("Add a new connection point to the currently selected item"),
- INKSCAPE_ICON("connector-new-connpoint"),
- secondarySize );
- g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_new_connection_point), holder );
- gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
- }
-
- // Remove selected connection point button
-
- {
- InkAction* inky = ink_action_new( "ConnectorRemoveConnPointAction",
- _("Remove connection point"),
- _("Remove the currently selected connection point"),
- INKSCAPE_ICON("connector-remove-connpoint"),
- secondarySize );
- g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_remove_connection_point), holder );
- gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
- }
-
-
// Code to watch for changes to the connector-spacing attribute in
// the XML.
Inkscape::XML::Node *repr = desktop->namedview->getRepr();
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index b758e4f0f..59e866881 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -526,7 +526,6 @@ static gchar const * ui_descr =
" </toolbar>"
" <toolbar name='ConnectorToolbar'>"
-// " <toolitem action='ConnectorEditModeAction' />"
" <toolitem action='ConnectorAvoidAction' />"
" <toolitem action='ConnectorIgnoreAction' />"
" <toolitem action='ConnectorOrthogonalAction' />"
@@ -536,8 +535,6 @@ static gchar const * ui_descr =
" <toolitem action='ConnectorLengthAction' />"
" <toolitem action='ConnectorDirectedAction' />"
" <toolitem action='ConnectorOverlapAction' />"
-// " <toolitem action='ConnectorNewConnPointAction' />"
-// " <toolitem action='ConnectorRemoveConnPointAction' />"
" </toolbar>"
"</ui>"