X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fconnector-context.cpp;h=adc54a1ae228b68e08b129030f19b17415caec16;hb=a401603e1e2635fadeec3b7a3a48de442da93472;hp=307d59d1f5f2efad35e2068b78e710424d0b71f3;hpb=2910ec6c2c2e59f4472f1e019ac6bdcc0c3790f2;p=inkscape.git diff --git a/src/connector-context.cpp b/src/connector-context.cpp index 307d59d1f..adc54a1ae 100644 --- a/src/connector-context.cpp +++ b/src/connector-context.cpp @@ -156,8 +156,8 @@ #include "connector-context.h" #include "pixmaps/cursor-connector.xpm" #include "pixmaps/cursor-node.xpm" -#include "pixmaps/cursor-node-m.xpm" -#include "pixmaps/cursor-node-d.xpm" +//#include "pixmaps/cursor-node-m.xpm" +//#include "pixmaps/cursor-node-d.xpm" #include "xml/node-event-vector.h" #include "xml/repr.h" #include "svg/svg.h" @@ -218,7 +218,7 @@ static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item); 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 gchar *conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& w); +static bool conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid); static void cc_select_handle(SPKnot* knot); static void cc_deselect_handle(SPKnot* knot); static bool cc_item_is_shape(SPItem *item); @@ -233,6 +233,9 @@ static void shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *nam gpointer data); +static char* cc_knot_tips[] = { _("Connection point: click or drag to create a new connector"), + _("Connection point: 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; @@ -338,8 +341,10 @@ sp_connector_context_init(SPConnectorContext *cc) cc->endpt_handle[i] = NULL; cc->endpt_handler_id[i] = 0; } - cc->sid = NULL; - cc->eid = NULL; + cc->shref = NULL; + cc->scpid = NULL; + cc->ehref = NULL; + cc->ecpid = NULL; cc->npoints = 0; cc->state = SP_CONNECTOR_CONTEXT_IDLE; } @@ -366,13 +371,21 @@ sp_connector_context_dispose(GObject *object) cc->endpt_handle[i] = NULL; } } - if (cc->sid) { - g_free(cc->sid); - cc->sid = NULL; + if (cc->shref) { + g_free(cc->shref); + cc->shref = NULL; + } + if (cc->scpid) { + g_free(cc->scpid); + cc->scpid = NULL; } - if (cc->eid) { - g_free(cc->eid); - cc->eid = 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 ); @@ -570,8 +583,8 @@ cc_clear_active_conn(SPConnectorContext *cc) } -static gchar * -conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p) +static bool +conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid) { // TODO: this will need to change when there are more connection // points available for each shape. @@ -580,10 +593,13 @@ conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p) { p = cc->active_handle->pos; const ConnectionPoint& cp = cc->connpthandles[cc->active_handle]; - return g_strdup_printf("#%s_%c_%d", SP_OBJECT_ID(cc->active_shape), - cp.type == ConnPointDefault ? 'd' : 'u' , cp.id); + *href = g_strdup_printf("#%s", cc->active_shape->getId()); + *cpid = g_strdup_printf("%c%d", cp.type == ConnPointDefault ? 'd' : 'u' , cp.id); + return true; } - return NULL; + *href = NULL; + *cpid = NULL; + return false; } static void @@ -625,7 +641,6 @@ sp_connector_context_item_handler(SPEventContext *event_context, SPItem *item, G { spcc_reset_colors(cc); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(event_context); } if (cc->state != SP_CONNECTOR_CONTEXT_IDLE) { // Doing something else like rerouting. @@ -753,11 +768,10 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const Geom::Point const event_dt = cc->desktop->w2d(event_w); SnapManager &m = cc->desktop->namedview->snap_manager; - m.setup(cc->desktop); switch (cc->state) { case SP_CONNECTOR_CONTEXT_STOP: - /* This is allowed, if we just cancelled curve */ + /* This is allowed, if we just canceled curve */ case SP_CONNECTOR_CONTEXT_IDLE: { if ( cc->npoints == 0 ) { @@ -770,14 +784,14 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const Geom::Point p = event_dt; // Test whether we clicked on a connection point - cc->sid = conn_pt_handle_test(cc, p); - -// sp_event_context_snap_window_open(event_context); + bool found = conn_pt_handle_test(cc, p, &cc->shref, &cc->scpid); - if (!cc->sid) { + if (!found) { // This is the first point, so just snap it to the grid // as there's no other points to go off. - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); + m.setup(cc->desktop); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); } spcc_connector_set_initial_point(cc, p); @@ -789,18 +803,19 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const case SP_CONNECTOR_CONTEXT_DRAGGING: { // This is the second click of a connector creation. - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); + m.setup(cc->desktop); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); spcc_connector_set_subsequent_point(cc, p); spcc_connector_finish_segment(cc, p); // Test whether we clicked on a connection point - cc->eid = conn_pt_handle_test(cc, p); + /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid); if (cc->npoints != 0) { spcc_connector_finish(cc); } cc_set_active_conn(cc, cc->newconn); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(event_context); ret = TRUE; break; } @@ -819,7 +834,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const cc_connector_rerouting_finish(cc, &p); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(event_context); // Don't set ret to TRUE, so we drop through to the // parent handler which will open the context menu. @@ -827,7 +841,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const else if (cc->npoints != 0) { spcc_connector_finish(cc); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(event_context); ret = TRUE; } } @@ -879,7 +892,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const if ( cc->selected_handle ) { -// sp_event_context_snap_window_open(event_context); cc->state = SP_CONNECTOR_CONTEXT_DRAGGING; cc->selection->set( SP_OBJECT( cc->active_shape ) ); } @@ -933,7 +945,6 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE ) { SnapManager &m = dt->namedview->snap_manager; - m.setup(dt); switch (cc->state) { case SP_CONNECTOR_CONTEXT_DRAGGING: @@ -941,8 +952,9 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons gobble_motion_events(mevent.state); // This is movement during a connector creation. if ( cc->npoints > 0 ) { - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, - Inkscape::SNAPSOURCE_HANDLE); + m.setup(dt); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); cc->selection->clear(); spcc_connector_set_subsequent_point(cc, p); ret = TRUE; @@ -954,8 +966,9 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons gobble_motion_events(GDK_BUTTON1_MASK); g_assert( SP_IS_PATH(cc->clickeditem)); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, - Inkscape::SNAPSOURCE_HANDLE); + m.setup(dt); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); // Update the hidden path Geom::Matrix i2d = sp_item_i2d_affine(cc->clickeditem); @@ -985,6 +998,11 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons /* This is perfectly valid */ break; default: + if (!sp_event_context_knot_mouseover(cc)) { + m.setup(dt); + m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE)); + m.unSetup(); + } break; } } @@ -1018,7 +1036,6 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con SPDocument *doc = sp_desktop_document(desktop); SnapManager &m = desktop->namedview->snap_manager; - m.setup(desktop); Geom::Point const event_w(revent.x, revent.y); @@ -1030,7 +1047,9 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con //case SP_CONNECTOR_CONTEXT_POINT: case SP_CONNECTOR_CONTEXT_DRAGGING: { - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); + m.setup(desktop); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); if (cc->within_tolerance) { @@ -1041,23 +1060,23 @@ 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 - cc->eid = conn_pt_handle_test(cc, p); + /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid); if (cc->npoints != 0) { spcc_connector_finish(cc); } cc_set_active_conn(cc, cc->newconn); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(event_context); break; } case SP_CONNECTOR_CONTEXT_REROUTING: { - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); + m.setup(desktop); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); cc_connector_rerouting_finish(cc, &p); sp_document_ensure_up_to_date(doc); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(event_context); return TRUE; break; } @@ -1077,10 +1096,10 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con if (!cc->within_tolerance) { -// sp_event_context_snap_window_open(event_context); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); + m.setup(desktop); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); sp_knot_set_position(cc->selected_handle, p, 0); -// sp_event_context_snap_window_closed(event_context); ConnectionPoint& cp = cc->connpthandles[cc->selected_handle]; cp.pos = p * sp_item_dt2i_affine(cc->active_shape); cc->active_shape->avoidRef->updateConnectionPoint(cp); @@ -1092,11 +1111,11 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con case SP_CONNECTOR_CONTEXT_NEWCONNPOINT: -// sp_event_context_snap_window_open( event_context ); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); + m.setup(desktop); + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); sp_knot_set_position(cc->selected_handle, p, 0); -// sp_event_context_snap_window_closed(event_context); ConnectionPoint cp; cp.type = ConnPointUserDefined; @@ -1137,7 +1156,6 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) if (cc->npoints != 0) { spcc_connector_finish(cc); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(SP_EVENT_CONTEXT(cc)); ret = TRUE; } break; @@ -1152,7 +1170,6 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) sp_document_undo(doc); cc->state = SP_CONNECTOR_CONTEXT_IDLE; -// sp_event_context_snap_window_closed(SP_EVENT_CONTEXT(cc)); desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE, _("Connector endpoint drag cancelled.")); ret = TRUE; @@ -1160,7 +1177,6 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) else if (cc->npoints != 0) { // if drawing, cancel, otherwise pass it up for deselecting cc->state = SP_CONNECTOR_CONTEXT_STOP; -// sp_event_context_snap_window_closed(SP_EVENT_CONTEXT(cc)); spcc_reset_colors(cc); ret = TRUE; } @@ -1192,18 +1208,16 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) { // Put connection point at current position - SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc); - SnapManager &m = desktop->namedview->snap_manager; - m.setup(desktop); Geom::Point p = cc->selected_handle->pos; -// SPEventContext* event_context = SP_EVENT_CONTEXT( cc ); if (!cc->within_tolerance) { -// sp_event_context_snap_window_open(event_context); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); + 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); -// sp_event_context_snap_window_closed(event_context); ConnectionPoint& cp = cc->connpthandles[cc->selected_handle]; cp.pos = p * sp_item_dt2i_affine(cc->active_shape); cc->active_shape->avoidRef->updateConnectionPoint(cp); @@ -1229,13 +1243,9 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); Geom::Point p = cc->selected_handle->pos; -// SPEventContext* event_context = SP_EVENT_CONTEXT( cc ); - -// sp_event_context_snap_window_open( event_context ); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE); - + m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); sp_knot_set_position(cc->selected_handle, p, 0); -// sp_event_context_snap_window_closed(event_context); ConnectionPoint cp; cp.type = ConnPointUserDefined; @@ -1285,16 +1295,21 @@ 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 = conn_pt_handle_test(cc, *p); + gchar *shape_label, *cpid; + bool found = conn_pt_handle_test(cc, *p, &shape_label, &cpid); - if (shape_label) { + if (found) { if (cc->clickedhandle == cc->endpt_handle[0]) { sp_object_setAttribute(cc->clickeditem, - "inkscape:connection-start",shape_label, false); + "inkscape:connection-start", shape_label, false); + sp_object_setAttribute(cc->clickeditem, + "inkscape:connection-start-point", cpid, false); } else { sp_object_setAttribute(cc->clickeditem, - "inkscape:connection-end",shape_label, false); + "inkscape:connection-end", shape_label, false); + sp_object_setAttribute(cc->clickeditem, + "inkscape:connection-end-point", cpid, false); } g_free(shape_label); } @@ -1437,17 +1452,23 @@ spcc_flush_white(SPConnectorContext *cc, SPCurve *gc) cc->isOrthogonal ? "orthogonal" : "polyline", false); sp_object_setAttribute(cc->newconn, "inkscape:connector-curvature", Glib::Ascii::dtostr(cc->curvature).c_str(), false); - if (cc->sid) + if (cc->shref) { sp_object_setAttribute(cc->newconn, "inkscape:connection-start", - cc->sid, false); + cc->shref, false); + if (cc->scpid) + sp_object_setAttribute(cc->newconn, "inkscape:connection-start-point", + cc->scpid, false); connection = true; } - if (cc->eid) + if (cc->ehref) { sp_object_setAttribute(cc->newconn, "inkscape:connection-end", - cc->eid, false); + cc->ehref, false); + if (cc->ecpid) + sp_object_setAttribute(cc->newconn, "inkscape:connection-end-point", + cc->ecpid, false); connection = true; } // Process pending updates. @@ -1571,7 +1592,6 @@ endpt_handler(SPKnot */*knot*/, GdkEvent *event, SPConnectorContext *cc) cc->clickedhandle = cc->active_handle; cc_clear_active_conn(cc); cc->state = SP_CONNECTOR_CONTEXT_REROUTING; -// sp_event_context_snap_window_open(SP_EVENT_CONTEXT(cc)); // Disconnect from attached shape unsigned ind = (cc->active_handle == cc->endpt_handle[0]) ? 0 : 1; @@ -1750,12 +1770,22 @@ cc_set_active_conn(SPConnectorContext *cc, SPItem *item) if (cc->active_conn == item) { - // Just adjust handle positions. - Geom::Point startpt = *(curve->first_point()) * i2d; - sp_knot_set_position(cc->endpt_handle[0], startpt, 0); + if (curve->is_empty()) + { + // Connector is invisible because it is clipped to the boundary of + // two overlpapping shapes. + sp_knot_hide(cc->endpt_handle[0]); + sp_knot_hide(cc->endpt_handle[1]); + } + else + { + // Just adjust handle positions. + Geom::Point startpt = *(curve->first_point()) * i2d; + sp_knot_set_position(cc->endpt_handle[0], startpt, 0); - Geom::Point endpt = *(curve->last_point()) * i2d; - sp_knot_set_position(cc->endpt_handle[1], endpt, 0); + Geom::Point endpt = *(curve->last_point()) * i2d; + sp_knot_set_position(cc->endpt_handle[1], endpt, 0); + } return; } @@ -1818,6 +1848,13 @@ cc_set_active_conn(SPConnectorContext *cc, SPItem *item) G_CALLBACK(endpt_handler), cc); } + if (curve->is_empty()) + { + // Connector is invisible because it is clipped to the boundary + // of two overlpapping shapes. So, it doesn't need endpoints. + return; + } + Geom::Point startpt = *(curve->first_point()) * i2d; sp_knot_set_position(cc->endpt_handle[0], startpt, 0); @@ -1881,8 +1918,10 @@ static bool cc_item_is_shape(SPItem *item) bool cc_item_is_connector(SPItem *item) { if (SP_IS_PATH(item)) { - if (SP_PATH(item)->connEndPair.isAutoRoutingConn()) { - g_assert( SP_PATH(item)->original_curve ? !(SP_PATH(item)->original_curve->is_closed()) : !(SP_PATH(item)->curve->is_closed()) ); + bool closed = SP_PATH(item)->original_curve ? SP_PATH(item)->original_curve->is_closed() : SP_PATH(item)->curve->is_closed(); + if (SP_PATH(item)->connEndPair.isAutoRoutingConn() && !closed) { + // To be considered a connector, an object must be a non-closed + // path that is marked with a "inkscape:connector-type" attribute. return true; } } @@ -2013,4 +2052,4 @@ shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :