X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fconnector-context.cpp;h=f4b202451156cc5e83133d55d3fe5dfda76075b1;hb=0dc33d4ce43e0bb49c63aa53b826ec4a1ff68e28;hp=ba6c067c0eb7513c8f708813a106c6d688af5667;hpb=839598cdda20adbc1a3b5d0982c13558440d1fcb;p=inkscape.git diff --git a/src/connector-context.cpp b/src/connector-context.cpp index ba6c067c0..f4b202451 100644 --- a/src/connector-context.cpp +++ b/src/connector-context.cpp @@ -1,11 +1,14 @@ -/* +/** * Connector creation tool * * Authors: * Michael Wybrow + * Abhishek Sharma + * Jon A. Cruz * * Copyright (C) 2005-2008 Michael Wybrow * Copyright (C) 2009 Monash University + * Copyright (C) 2010 authors * * Released under GNU GPL, read the file 'COPYING' for more information * @@ -171,6 +174,7 @@ #include "inkscape.h" #include "preferences.h" #include "sp-path.h" +#include "display/sp-canvas.h" #include "display/canvas-bpath.h" #include "display/sodipodi-ctrl.h" #include @@ -188,6 +192,8 @@ #include "sp-flowtext.h" #include "display/curve.h" +using Inkscape::DocumentUndo; + static void sp_connector_context_class_init(SPConnectorContextClass *klass); static void sp_connector_context_init(SPConnectorContext *conn_context); static void sp_connector_context_dispose(GObject *object); @@ -233,6 +239,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; @@ -765,7 +774,6 @@ 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: @@ -787,7 +795,9 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const if (!found) { // This is the first point, so just snap it to the grid // as there's no other points to go off. + m.setup(cc->desktop); m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); } spcc_connector_set_initial_point(cc, p); @@ -799,7 +809,9 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const case SP_CONNECTOR_CONTEXT_DRAGGING: { // This is the second click of a connector creation. + 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); @@ -939,7 +951,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: @@ -947,7 +958,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.setup(dt); m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); cc->selection->clear(); spcc_connector_set_subsequent_point(cc, p); ret = TRUE; @@ -959,10 +972,12 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons gobble_motion_events(GDK_BUTTON1_MASK); g_assert( SP_IS_PATH(cc->clickeditem)); + 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); + Geom::Matrix i2d = (cc->clickeditem)->i2d_affine(); Geom::Matrix d2i = i2d.inverse(); SPPath *path = SP_PATH(cc->clickeditem); SPCurve *curve = path->original_curve ? path->original_curve : path->curve; @@ -990,7 +1005,9 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons break; default: if (!sp_event_context_knot_mouseover(cc)) { + m.setup(dt); m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE)); + m.unSetup(); } break; } @@ -1025,7 +1042,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); @@ -1037,7 +1053,9 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con //case SP_CONNECTOR_CONTEXT_POINT: case SP_CONNECTOR_CONTEXT_DRAGGING: { + m.setup(desktop); m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); + m.unSetup(); if (cc->within_tolerance) { @@ -1058,10 +1076,12 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con } case SP_CONNECTOR_CONTEXT_REROUTING: { + 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); + doc->ensureUpToDate(); cc->state = SP_CONNECTOR_CONTEXT_IDLE; return TRUE; break; @@ -1082,10 +1102,12 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con 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 * sp_item_dt2i_affine(cc->active_shape); + cp.pos = p * (cc->active_shape)->dt2i_affine(); cc->active_shape->avoidRef->updateConnectionPoint(cp); } @@ -1095,17 +1117,19 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con 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 * sp_item_dt2i_affine(cc->active_shape); + cp.pos = p * (cc->active_shape)->dt2i_affine(); cp.dir = Avoid::ConnDirAll; g_object_unref(cc->selected_handle); cc->active_shape->avoidRef->addConnectionPoint(cp); - sp_document_ensure_up_to_date(doc); + doc->ensureUpToDate(); for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it) if (it->second.type == ConnPointUserDefined && it->second.id == cp.id) { @@ -1149,7 +1173,7 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) cc_connector_rerouting_finish(cc, NULL); - sp_document_undo(doc); + DocumentUndo::undo(doc); cc->state = SP_CONNECTOR_CONTEXT_IDLE; desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE, @@ -1179,7 +1203,7 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) // Obtain original position ConnectionPoint const& cp = cc->connpthandles[cc->selected_handle]; SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc); - const Geom::Matrix& i2doc = sp_item_i2doc_affine(cc->active_shape); + const Geom::Matrix& 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, @@ -1190,18 +1214,18 @@ 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) { + 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 * sp_item_dt2i_affine(cc->active_shape); + cp.pos = p * (cc->active_shape)->dt2i_affine(); cc->active_shape->avoidRef->updateConnectionPoint(cp); } @@ -1225,18 +1249,17 @@ 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; - 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 * sp_item_dt2i_affine(cc->active_shape); + cp.pos = p * (cc->active_shape)->dt2i_affine(); cp.dir = Avoid::ConnDirAll; g_object_unref(cc->selected_handle); cc->active_shape->avoidRef->addConnectionPoint(cp); - sp_document_ensure_up_to_date(doc); + doc->ensureUpToDate(); for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it) if (it->second.type == ConnPointUserDefined && it->second.id == cp.id) { @@ -1283,16 +1306,12 @@ cc_connector_rerouting_finish(SPConnectorContext *const cc, Geom::Point *const p if (found) { if (cc->clickedhandle == cc->endpt_handle[0]) { - sp_object_setAttribute(cc->clickeditem, - "inkscape:connection-start", shape_label, false); - sp_object_setAttribute(cc->clickeditem, - "inkscape:connection-start-point", cpid, false); + cc->clickeditem->setAttribute("inkscape:connection-start", shape_label, false); + cc->clickeditem->setAttribute("inkscape:connection-start-point", cpid, false); } else { - sp_object_setAttribute(cc->clickeditem, - "inkscape:connection-end", shape_label, false); - sp_object_setAttribute(cc->clickeditem, - "inkscape:connection-end-point", cpid, false); + cc->clickeditem->setAttribute("inkscape:connection-end", shape_label, false); + cc->clickeditem->setAttribute("inkscape:connection-end-point", cpid, false); } g_free(shape_label); } @@ -1300,7 +1319,7 @@ cc_connector_rerouting_finish(SPConnectorContext *const cc, Geom::Point *const p cc->clickeditem->setHidden(false); sp_conn_reroute_path_immediate(SP_PATH(cc->clickeditem)); cc->clickeditem->updateRepr(); - sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR, + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, _("Reroute connector")); cc_set_active_conn(cc, cc->clickeditem); } @@ -1412,7 +1431,7 @@ spcc_flush_white(SPConnectorContext *cc, SPCurve *gc) SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc); SPDocument *doc = sp_desktop_document(desktop); - Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); if ( c && !c->is_empty() ) { /* We actually have something to write */ @@ -1428,35 +1447,33 @@ spcc_flush_white(SPConnectorContext *cc, SPCurve *gc) /* Attach repr */ cc->newconn = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); - cc->newconn->transform = sp_item_i2doc_affine(SP_ITEM(desktop->currentLayer())).inverse(); + cc->newconn->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); bool connection = false; - sp_object_setAttribute(cc->newconn, "inkscape:connector-type", - cc->isOrthogonal ? "orthogonal" : "polyline", false); - sp_object_setAttribute(cc->newconn, "inkscape:connector-curvature", - Glib::Ascii::dtostr(cc->curvature).c_str(), false); + cc->newconn->setAttribute( "inkscape:connector-type", + cc->isOrthogonal ? "orthogonal" : "polyline", false ); + cc->newconn->setAttribute( "inkscape:connector-curvature", + Glib::Ascii::dtostr(cc->curvature).c_str(), false ); if (cc->shref) { - sp_object_setAttribute(cc->newconn, "inkscape:connection-start", - cc->shref, false); - if (cc->scpid) - sp_object_setAttribute(cc->newconn, "inkscape:connection-start-point", - cc->scpid, false); + cc->newconn->setAttribute( "inkscape:connection-start", cc->shref, false); + if (cc->scpid) { + cc->newconn->setAttribute( "inkscape:connection-start-point", cc->scpid, false); + } connection = true; } if (cc->ehref) { - sp_object_setAttribute(cc->newconn, "inkscape:connection-end", - cc->ehref, false); - if (cc->ecpid) - sp_object_setAttribute(cc->newconn, "inkscape:connection-end-point", - cc->ecpid, false); + cc->newconn->setAttribute( "inkscape:connection-end", cc->ehref, false); + if (cc->ecpid) { + cc->newconn->setAttribute( "inkscape:connection-end-point", cc->ecpid, false); + } connection = true; } // Process pending updates. cc->newconn->updateRepr(); - sp_document_ensure_up_to_date(doc); + doc->ensureUpToDate(); if (connection) { // Adjust endpoints to shape edge. @@ -1474,7 +1491,7 @@ spcc_flush_white(SPConnectorContext *cc, SPCurve *gc) c->unref(); - sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR, _("Create connector")); + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, _("Create connector")); } @@ -1590,7 +1607,7 @@ endpt_handler(SPKnot */*knot*/, GdkEvent *event, SPConnectorContext *cc) // Show the red path for dragging. cc->red_curve = SP_PATH(cc->clickeditem)->original_curve ? SP_PATH(cc->clickeditem)->original_curve->copy() : SP_PATH(cc->clickeditem)->curve->copy(); - Geom::Matrix i2d = sp_item_i2d_affine(cc->clickeditem); + Geom::Matrix i2d = (cc->clickeditem)->i2d_affine(); cc->red_curve->transform(i2d); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve); @@ -1690,7 +1707,7 @@ static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item) // Ensure the item's connection_points map // has been updated - sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); + item->document->ensureUpToDate(); std::set seen; for ( ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end() ;) @@ -1749,16 +1766,26 @@ cc_set_active_conn(SPConnectorContext *cc, SPItem *item) g_assert( SP_IS_PATH(item) ); SPCurve *curve = SP_PATH(item)->original_curve ? SP_PATH(item)->original_curve : SP_PATH(item)->curve; - Geom::Matrix i2d = sp_item_i2d_affine(item); + Geom::Matrix i2d = item->i2d_affine(); 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; } @@ -1821,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); @@ -1884,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; } } @@ -1914,8 +1950,7 @@ void cc_selection_set_avoid(bool const set_avoid) char const *value = (set_avoid) ? "true" : NULL; if (cc_item_is_shape(item)) { - sp_object_setAttribute(item, "inkscape:connector-avoid", - value, false); + item->setAttribute("inkscape:connector-avoid", value, false); item->avoidRef->handleSettingChange(); changes++; } @@ -1932,7 +1967,7 @@ void cc_selection_set_avoid(bool const set_avoid) char *event_desc = (set_avoid) ? _("Make connectors avoid selected objects") : _("Make connectors ignore selected objects"); - sp_document_done(document, SP_VERB_CONTEXT_CONNECTOR, event_desc); + DocumentUndo::done(document, SP_VERB_CONTEXT_CONNECTOR, event_desc); } @@ -2016,4 +2051,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 :