summaryrefslogtreecommitdiffstats
path: root/src/sp-conn-end.cpp
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2018-01-30 08:33:01 +0000
committerTavmjong Bah <tavmjong@free.fr>2018-01-30 08:33:01 +0000
commit267299811df952d08324a39008f52c19641de9e0 (patch)
tree28fef736a52cb7a72119d119be8eb663ad20a77f /src/sp-conn-end.cpp
parentTranslations: update inkscape.pot (diff)
downloadinkscape-267299811df952d08324a39008f52c19641de9e0.tar.gz
inkscape-267299811df952d08324a39008f52c19641de9e0.zip
Move classes derived from SPObject to own directory.
A lot of header clean-up.
Diffstat (limited to 'src/sp-conn-end.cpp')
-rw-r--r--src/sp-conn-end.cpp304
1 files changed, 0 insertions, 304 deletions
diff --git a/src/sp-conn-end.cpp b/src/sp-conn-end.cpp
deleted file mode 100644
index 996d8499a..000000000
--- a/src/sp-conn-end.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-#include "sp-conn-end.h"
-
-#include <cstring>
-#include <string>
-#include <limits>
-
-#include "bad-uri-exception.h"
-#include "display/curve.h"
-#include "xml/repr.h"
-#include "sp-path.h"
-#include "uri.h"
-#include "document.h"
-#include "sp-item-group.h"
-#include "2geom/path-intersection.h"
-
-
-static void change_endpts(SPCurve *const curve, double const endPos[2]);
-
-SPConnEnd::SPConnEnd(SPObject *const owner)
- : ref(owner)
- , href(NULL)
- // Default to center connection endpoint
- , _changed_connection()
- , _delete_connection()
- , _transformed_connection()
- , _group_connection()
-{
-}
-
-static SPObject const *get_nearest_common_ancestor(SPObject const *const obj, SPItem const *const objs[2])
-{
- SPObject const *anc_sofar = obj;
- for (unsigned i = 0; i < 2; ++i) {
- if ( objs[i] != NULL ) {
- anc_sofar = anc_sofar->nearestCommonAncestor(objs[i]);
- }
- }
- return anc_sofar;
-}
-
-
-static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_pv, SPItem* item,
- const Geom::Affine& item_transform, double& intersect_pos)
-{
- double initial_pos = intersect_pos;
- // if this is a group...
- if (SP_IS_GROUP(item)) {
- SPGroup* group = SP_GROUP(item);
-
- // consider all first-order children
- double child_pos = 0.0;
- std::vector<SPItem*> g = sp_item_group_item_list(group);
- for (std::vector<SPItem*>::const_iterator i = g.begin();i!=g.end();++i) {
- SPItem* child_item = *i;
- try_get_intersect_point_with_item_recursive(conn_pv, child_item,
- item_transform * child_item->transform, child_pos);
- if (intersect_pos < child_pos)
- intersect_pos = child_pos;
- }
- return intersect_pos != initial_pos;
- }
-
- // if this is not a shape, nothing to be done
- if (!SP_IS_SHAPE(item)) return false;
-
- // make sure it has an associated curve
- SPCurve* item_curve = SP_SHAPE(item)->getCurve();
- if (!item_curve) return false;
-
- // apply transformations (up to common ancestor)
- item_curve->transform(item_transform);
-
- const Geom::PathVector& curve_pv = item_curve->get_pathvector();
- Geom::CrossingSet cross = crossings(conn_pv, curve_pv);
- // iterate over all Crossings
- //TODO: check correctness of the following code: inner loop uses loop variable
- // with a name identical to the loop variable of the outer loop. Then rename.
- for (Geom::CrossingSet::const_iterator i = cross.begin(); i != cross.end(); ++i) {
- const Geom::Crossings& cr = *i;
-
- for (Geom::Crossings::const_iterator i = cr.begin(); i != cr.end(); ++i) {
- const Geom::Crossing& cr_pt = *i;
- if ( intersect_pos < cr_pt.ta)
- intersect_pos = cr_pt.ta;
- }
- }
-
- item_curve->unref();
-
- return intersect_pos != initial_pos;
-}
-
-
-// This function returns the outermost intersection point between the path (a connector)
-// and the item given. If the item is a group, then the component items are considered.
-// The transforms given should be to a common ancestor of both the path and item.
-//
-static bool try_get_intersect_point_with_item(SPPath* conn, SPItem* item,
- const Geom::Affine& item_transform, const Geom::Affine& conn_transform,
- const bool at_start, double& intersect_pos)
-{
- // Copy the curve and apply transformations up to common ancestor.
- SPCurve* conn_curve = conn->_curve->copy();
- conn_curve->transform(conn_transform);
-
- Geom::PathVector conn_pv = conn_curve->get_pathvector();
-
- // If this is not the starting point, use Geom::Path::reverse() to reverse the path
- if (!at_start) {
- // connectors are actually a single path, so consider the first element from a Geom::PathVector
- conn_pv[0] = conn_pv[0].reversed();
- }
-
- // We start with the intersection point at the beginning of the path
- intersect_pos = 0.0;
-
- // Find the intersection.
- bool result = try_get_intersect_point_with_item_recursive(conn_pv, item, item_transform, intersect_pos);
-
- if (!result) {
- // No intersection point has been found (why?)
- // just default to connector end
- intersect_pos = 0;
- }
- // If not at the starting point, recompute position with respect to original path
- if (!at_start) {
- intersect_pos = conn_pv[0].size() - intersect_pos;
- }
- // Free the curve copy.
- conn_curve->unref();
-
- return result;
-}
-
-
-static void sp_conn_get_route_and_redraw(SPPath *const path, const bool updatePathRepr = true)
-{
- // Get the new route around obstacles.
- bool rerouted = path->connEndPair.reroutePathFromLibavoid();
- if (!rerouted) {
- return;
- }
-
- SPItem *h2attItem[2] = {0};
- path->connEndPair.getAttachedItems(h2attItem);
-
- SPObject const *const ancestor = get_nearest_common_ancestor(path, h2attItem);
- Geom::Affine const path2anc(i2anc_affine(path, ancestor));
-
- // Set sensible values in case there the connector ends are not
- // attached to any shapes.
- Geom::PathVector conn_pv = path->_curve->get_pathvector();
- double endPos[2] = { 0.0, static_cast<double>(conn_pv[0].size()) };
-
- for (unsigned h = 0; h < 2; ++h) {
- // 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]);
- }
- }
- change_endpts(path->_curve, endPos);
- if (updatePathRepr) {
- path->updateRepr();
- path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- }
-}
-
-
-static void sp_conn_end_shape_move(Geom::Affine const */*mp*/, SPItem */*moved_item*/, SPPath *const path)
-{
- if (path->connEndPair.isAutoRoutingConn()) {
- path->connEndPair.tellLibavoidNewEndpoints();
- }
-}
-
-
-void sp_conn_reroute_path(SPPath *const path)
-{
- if (path->connEndPair.isAutoRoutingConn()) {
- path->connEndPair.tellLibavoidNewEndpoints();
- }
-}
-
-
-void sp_conn_reroute_path_immediate(SPPath *const path)
-{
- if (path->connEndPair.isAutoRoutingConn()) {
- bool processTransaction = true;
- path->connEndPair.tellLibavoidNewEndpoints(processTransaction);
- }
- // Don't update the path repr or else connector dragging is slowed by
- // constant update of values to the xml editor, and each step is also
- // needlessly remembered by undo/redo.
- bool const updatePathRepr = false;
- sp_conn_get_route_and_redraw(path, updatePathRepr);
-}
-
-void sp_conn_redraw_path(SPPath *const path)
-{
- sp_conn_get_route_and_redraw(path);
-}
-
-
-static void change_endpts(SPCurve *const curve, double const endPos[2])
-{
- // Use Geom::Path::portion to cut the curve at the end positions
- if (endPos[0] > endPos[1]) {
- // Path is "negative", reset the curve and return
- curve->reset();
- return;
- }
- const Geom::Path& old_path = curve->get_pathvector()[0];
- Geom::PathVector new_path_vector;
- new_path_vector.push_back(old_path.portion(endPos[0], endPos[1]));
- curve->set_pathvector(new_path_vector);
-}
-
-static void sp_conn_end_deleted(SPObject *, SPObject *const owner, unsigned const handle_ix)
-{
- 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. */
-}
-
-void sp_conn_end_detach(SPObject *const owner, unsigned const handle_ix)
-{
- sp_conn_end_deleted(NULL, owner, handle_ix);
-}
-
-void SPConnEnd::setAttacherHref(gchar const *value, SPPath* /*path*/)
-{
- bool validRef = true;
-
- if (value && href && strcmp(value, href) == 0) {
- /* No change, do nothing. */
- } else if (!value) {
- validRef = false;
- } else {
- href = g_strdup(value);
- // Now do the attaching, which emits the changed signal.
- try {
- ref.attach(Inkscape::URI(value));
- } catch (Inkscape::BadURIException &e) {
- /* TODO: Proper error handling as per
- * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. (Also needed for
- * sp-use.) */
- g_warning("%s", e.what());
- validRef = false;
- }
- }
-
- if (!validRef) {
- ref.detach();
- g_free(href);
- href = NULL;
- }
-}
-
-
-void sp_conn_end_href_changed(SPObject */*old_ref*/, SPObject */*ref*/,
- SPConnEnd *connEndPtr, SPPath *const path, unsigned const handle_ix)
-{
- g_return_if_fail(connEndPtr != NULL);
- SPConnEnd &connEnd = *connEndPtr;
- connEnd._delete_connection.disconnect();
- connEnd._transformed_connection.disconnect();
- connEnd._group_connection.disconnect();
-
- if (connEnd.href) {
- SPObject *refobj = connEnd.ref.getObject();
- if (refobj) {
- 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) && ! 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));
- }
- }
-}
-
-
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :