summaryrefslogtreecommitdiffstats
path: root/src/edge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/edge.c')
-rw-r--r--src/edge.c786
1 files changed, 0 insertions, 786 deletions
diff --git a/src/edge.c b/src/edge.c
deleted file mode 100644
index a22bc73..0000000
--- a/src/edge.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <string.h>
-
-#include <cairo.h>
-
-#include "ganv/canvas.h"
-#include "ganv/edge.h"
-#include "ganv/node.h"
-
-#include "./boilerplate.h"
-#include "./color.h"
-#include "./gettext.h"
-
-#include "color.h"
-#include "ganv-private.h"
-
-#define ARROW_DEPTH 32
-#define ARROW_BREADTH 32
-
-// Uncomment to see control point path as straight lines
-//#define GANV_DEBUG_CURVES 1
-
-// Uncomment along with GANV_DEBUG_CURVES to see bounding box (buggy)
-//#define GANV_DEBUG_BOUNDS 1
-
-enum {
- PROP_0,
- PROP_TAIL,
- PROP_HEAD,
- PROP_WIDTH,
- PROP_HANDLE_RADIUS,
- PROP_DASH_LENGTH,
- PROP_DASH_OFFSET,
- PROP_COLOR,
- PROP_CONSTRAINING,
- PROP_CURVED,
- PROP_ARROWHEAD,
- PROP_SELECTED,
- PROP_HIGHLIGHTED,
- PROP_GHOST
-};
-
-G_DEFINE_TYPE_WITH_CODE(GanvEdge, ganv_edge, GANV_TYPE_ITEM,
- G_ADD_PRIVATE(GanvEdge))
-
-static GanvItemClass* parent_class;
-
-static void
-ganv_edge_init(GanvEdge* edge)
-{
- GanvEdgePrivate* impl = ganv_edge_get_instance_private(edge);
-
- edge->impl = impl;
-
- impl->tail = NULL;
- impl->head = NULL;
-
- memset(&impl->coords, '\0', sizeof(GanvEdgeCoords));
- impl->coords.width = 2.0;
- impl->coords.handle_radius = 4.0;
- impl->coords.constraining = TRUE;
- impl->coords.curved = FALSE;
- impl->coords.arrowhead = FALSE;
-
- impl->old_coords = impl->coords;
- impl->dash_length = 0.0;
- impl->dash_offset = 0.0;
- impl->color = 0;
-}
-
-static void
-ganv_edge_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_EDGE(object));
-
- GanvEdge* edge = GANV_EDGE(object);
- GanvCanvas* canvas = GANV_CANVAS(edge->item.impl->canvas);
- if (canvas && !edge->impl->ghost) {
- edge->item.impl->canvas = NULL;
- }
- edge->item.impl->parent = NULL;
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-static void
-ganv_edge_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_EDGE(object));
-
- GanvItem* item = GANV_ITEM(object);
- GanvEdge* edge = GANV_EDGE(object);
- GanvEdgePrivate* impl = edge->impl;
- GanvEdgeCoords* coords = &impl->coords;
-
- switch (prop_id) {
- SET_CASE(WIDTH, double, coords->width);
- SET_CASE(HANDLE_RADIUS, double, coords->handle_radius);
- SET_CASE(DASH_LENGTH, double, impl->dash_length);
- SET_CASE(DASH_OFFSET, double, impl->dash_offset);
- SET_CASE(COLOR, uint, impl->color);
- SET_CASE(CONSTRAINING, boolean, impl->coords.constraining);
- SET_CASE(CURVED, boolean, impl->coords.curved);
- SET_CASE(ARROWHEAD, boolean, impl->coords.arrowhead);
- SET_CASE(SELECTED, boolean, impl->selected);
- SET_CASE(HIGHLIGHTED, boolean, impl->highlighted);
- SET_CASE(GHOST, boolean, impl->ghost);
- case PROP_TAIL: {
- const gobject tmp = g_value_get_object(value);
- if (impl->tail != tmp) {
- impl->tail = GANV_NODE(tmp);
- ganv_item_request_update(item);
- }
- break;
- }
- case PROP_HEAD: {
- const gobject tmp = g_value_get_object(value);
- if (impl->head != tmp) {
- impl->head = GANV_NODE(tmp);
- ganv_item_request_update(item);
- }
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_edge_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_EDGE(object));
-
- GanvEdge* edge = GANV_EDGE(object);
- GanvEdgePrivate* impl = edge->impl;
-
- switch (prop_id) {
- GET_CASE(TAIL, object, impl->tail);
- GET_CASE(HEAD, object, impl->head);
- GET_CASE(WIDTH, double, impl->coords.width);
- SET_CASE(HANDLE_RADIUS, double, impl->coords.handle_radius);
- GET_CASE(DASH_LENGTH, double, impl->dash_length);
- GET_CASE(DASH_OFFSET, double, impl->dash_offset);
- GET_CASE(COLOR, uint, impl->color);
- GET_CASE(CONSTRAINING, boolean, impl->coords.constraining);
- GET_CASE(CURVED, boolean, impl->coords.curved);
- GET_CASE(ARROWHEAD, boolean, impl->coords.arrowhead);
- GET_CASE(SELECTED, boolean, impl->selected);
- GET_CASE(HIGHLIGHTED, boolean, impl->highlighted);
- SET_CASE(GHOST, boolean, impl->ghost);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-void
-ganv_edge_request_redraw(GanvItem* item,
- const GanvEdgeCoords* coords)
-{
- GanvCanvas* canvas = item->impl->canvas;
- const double w = coords->width;
- if (coords->curved) {
- const double src_x = coords->x1;
- const double src_y = coords->y1;
- const double dst_x = coords->x2;
- const double dst_y = coords->y2;
- const double join_x = (src_x + dst_x) / 2.0;
- const double join_y = (src_y + dst_y) / 2.0;
- const double src_x1 = coords->cx1;
- const double src_y1 = coords->cy1;
- const double dst_x1 = coords->cx2;
- const double dst_y1 = coords->cy2;
-
- const double r1x1 = MIN(MIN(src_x, join_x), src_x1);
- const double r1y1 = MIN(MIN(src_y, join_y), src_y1);
- const double r1x2 = MAX(MAX(src_x, join_x), src_x1);
- const double r1y2 = MAX(MAX(src_y, join_y), src_y1);
- ganv_canvas_request_redraw_w(canvas,
- r1x1 - w, r1y1 - w,
- r1x2 + w, r1y2 + w);
-
- const double r2x1 = MIN(MIN(dst_x, join_x), dst_x1);
- const double r2y1 = MIN(MIN(dst_y, join_y), dst_y1);
- const double r2x2 = MAX(MAX(dst_x, join_x), dst_x1);
- const double r2y2 = MAX(MAX(dst_y, join_y), dst_y1);
- ganv_canvas_request_redraw_w(canvas,
- r2x1 - w, r2y1 - w,
- r2x2 + w, r2y2 + w);
-
- } else {
- const double x1 = MIN(coords->x1, coords->x2);
- const double y1 = MIN(coords->y1, coords->y2);
- const double x2 = MAX(coords->x1, coords->x2);
- const double y2 = MAX(coords->y1, coords->y2);
-
- ganv_canvas_request_redraw_w(canvas,
- x1 - w, y1 - w,
- x2 + w, y2 + w);
- }
-
- if (coords->handle_radius > 0.0) {
- ganv_canvas_request_redraw_w(
- canvas,
- coords->handle_x - coords->handle_radius - w,
- coords->handle_y - coords->handle_radius - w,
- coords->handle_x + coords->handle_radius + w,
- coords->handle_y + coords->handle_radius + w);
- }
-
- if (coords->arrowhead) {
- ganv_canvas_request_redraw_w(
- canvas,
- coords->x2 - ARROW_DEPTH,
- coords->y2 - ARROW_BREADTH,
- coords->x2 + ARROW_DEPTH,
- coords->y2 + ARROW_BREADTH);
- }
-}
-
-static void
-ganv_edge_bounds(GanvItem* item,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- GanvEdge* edge = GANV_EDGE(item);
- GanvEdgePrivate* impl = edge->impl;
- GanvEdgeCoords* coords = &impl->coords;
- const double w = coords->width;
-
- if (coords->curved) {
- *x1 = MIN(coords->x1, MIN(coords->cx1, MIN(coords->x2, coords->cx2))) - w;
- *y1 = MIN(coords->y1, MIN(coords->cy1, MIN(coords->y2, coords->cy2))) - w;
- *x2 = MAX(coords->x1, MAX(coords->cx1, MAX(coords->x2, coords->cx2))) + w;
- *y2 = MAX(coords->y1, MAX(coords->cy1, MAX(coords->y2, coords->cy2))) + w;
- } else {
- *x1 = MIN(impl->coords.x1, impl->coords.x2) - w;
- *y1 = MIN(impl->coords.y1, impl->coords.y2) - w;
- *x2 = MAX(impl->coords.x1, impl->coords.x2) + w;
- *y2 = MAX(impl->coords.y1, impl->coords.y2) + w;
- }
-}
-
-void
-ganv_edge_get_coords(const GanvEdge* edge, GanvEdgeCoords* coords)
-{
- GanvEdgePrivate* impl = edge->impl;
-
- GANV_NODE_GET_CLASS(impl->tail)->tail_vector(
- impl->tail, impl->head,
- &coords->x1, &coords->y1, &coords->cx1, &coords->cy1);
- GANV_NODE_GET_CLASS(impl->head)->head_vector(
- impl->head, impl->tail,
- &coords->x2, &coords->y2, &coords->cx2, &coords->cy2);
-
- const double dx = coords->x2 - coords->x1;
- const double dy = coords->y2 - coords->y1;
-
- coords->handle_x = coords->x1 + (dx / 2.0);
- coords->handle_y = coords->y1 + (dy / 2.0);
-
- const double abs_dx = fabs(dx);
- const double abs_dy = fabs(dy);
-
- coords->cx1 = coords->x1 + (coords->cx1 * (abs_dx / 4.0));
- coords->cy1 = coords->y1 + (coords->cy1 * (abs_dy / 4.0));
- coords->cx2 = coords->x2 + (coords->cx2 * (abs_dx / 4.0));
- coords->cy2 = coords->y2 + (coords->cy2 * (abs_dy / 4.0));
-}
-
-static void
-ganv_edge_update(GanvItem* item, int flags)
-{
- GanvEdge* edge = GANV_EDGE(item);
- GanvEdgePrivate* impl = edge->impl;
-
- // Request redraw of old location
- ganv_edge_request_redraw(item, &impl->old_coords);
-
- // Calculate new coordinates from tail and head
- ganv_edge_get_coords(edge, &impl->coords);
-
- // Update old coordinates
- impl->old_coords = impl->coords;
-
- // Get bounding box
- double x1, x2, y1, y2;
- ganv_edge_bounds(item, &x1, &y1, &x2, &y2);
-
- // Ensure bounding box has non-zero area
- if (x1 == x2) {
- x2 += 1.0;
- }
- if (y1 == y2) {
- y2 += 1.0;
- }
-
- // Update world-relative bounding box
- item->impl->x1 = x1;
- item->impl->y1 = y1;
- item->impl->x2 = x2;
- item->impl->y2 = y2;
- ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
-
- // Request redraw of new location
- ganv_edge_request_redraw(item, &impl->coords);
-
- parent_class->update(item, flags);
-}
-
-static void
-ganv_edge_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvEdge* edge = GANV_EDGE(item);
- GanvEdgePrivate* impl = edge->impl;
-
- double src_x = impl->coords.x1;
- double src_y = impl->coords.y1;
- double dst_x = impl->coords.x2;
- double dst_y = impl->coords.y2;
- double dx = src_x - dst_x;
- double dy = src_y - dst_y;
-
- double r, g, b, a;
- if (impl->highlighted) {
- color_to_rgba(highlight_color(impl->color, 0x40), &r, &g, &b, &a);
- } else {
- color_to_rgba(impl->color, &r, &g, &b, &a);
- }
- cairo_set_source_rgba(cr, r, g, b, a);
-
- cairo_set_line_width(cr, impl->coords.width);
- cairo_move_to(cr, src_x, src_y);
-
- const double dash_length = (impl->selected ? 4.0 : impl->dash_length);
- if (dash_length > 0.0) {
- double dashed[2] = { dash_length, dash_length };
- cairo_set_dash(cr, dashed, 2, impl->dash_offset);
- } else {
- cairo_set_dash(cr, &dash_length, 0, 0);
- }
-
- const double join_x = (src_x + dst_x) / 2.0;
- const double join_y = (src_y + dst_y) / 2.0;
-
- if (impl->coords.curved) {
- // Curved line as 2 paths which join at the middle point
-
- // Path 1 (src_x, src_y) -> (join_x, join_y)
- // Control point 1
- const double src_x1 = impl->coords.cx1;
- const double src_y1 = impl->coords.cy1;
- // Control point 2
- const double src_x2 = (join_x + src_x1) / 2.0;
- const double src_y2 = (join_y + src_y1) / 2.0;
-
- // Path 2, (join_x, join_y) -> (dst_x, dst_y)
- // Control point 1
- const double dst_x1 = impl->coords.cx2;
- const double dst_y1 = impl->coords.cy2;
- // Control point 2
- const double dst_x2 = (join_x + dst_x1) / 2.0;
- const double dst_y2 = (join_y + dst_y1) / 2.0;
-
- cairo_move_to(cr, src_x, src_y);
- cairo_curve_to(cr, src_x1, src_y1, src_x2, src_y2, join_x, join_y);
- cairo_curve_to(cr, dst_x2, dst_y2, dst_x1, dst_y1, dst_x, dst_y);
-
-#ifdef GANV_DEBUG_CURVES
- cairo_stroke(cr);
- cairo_save(cr);
- cairo_set_source_rgba(cr, 1.0, 0, 0, 0.5);
-
- cairo_move_to(cr, src_x, src_y);
- cairo_line_to(cr, src_x1, src_y1);
- cairo_stroke(cr);
-
- cairo_move_to(cr, join_x, join_y);
- cairo_line_to(cr, src_x2, src_y2);
- cairo_stroke(cr);
-
- cairo_move_to(cr, join_x, join_y);
- cairo_line_to(cr, dst_x2, dst_y2);
- cairo_stroke(cr);
-
- cairo_move_to(cr, dst_x, dst_y);
- cairo_line_to(cr, dst_x1, dst_y1);
- cairo_stroke(cr);
-
-#ifdef GANV_DEBUG_BOUNDS
- double bounds_x1, bounds_y1, bounds_x2, bounds_y2;
- ganv_edge_bounds(item, &bounds_x1, &bounds_y1, &bounds_x2, &bounds_y2);
- cairo_rectangle(cr,
- bounds_x1, bounds_y1,
- bounds_x2 - bounds_x1, bounds_y2 - bounds_y1);
-#endif
-
- cairo_restore(cr);
-#endif
-
- cairo_stroke(cr);
- if (impl->coords.arrowhead) {
- cairo_move_to(cr, dst_x - 12, dst_y - 4);
- cairo_line_to(cr, dst_x, dst_y);
- cairo_line_to(cr, dst_x - 12, dst_y + 4);
- cairo_close_path(cr);
- cairo_stroke_preserve(cr);
- cairo_fill(cr);
- }
-
- } else {
- // Straight line from (x1, y1) to (x2, y2)
- cairo_move_to(cr, src_x, src_y);
- cairo_line_to(cr, dst_x, dst_y);
- cairo_stroke(cr);
-
- if (impl->coords.arrowhead) {
- const double ah = sqrt(dx * dx + dy * dy);
- const double adx = dx / ah * 8.0;
- const double ady = dy / ah * 8.0;
-
- cairo_move_to(cr,
- dst_x + adx - ady/1.5,
- dst_y + ady + adx/1.5);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
- cairo_line_to(cr, dst_x, dst_y);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
- cairo_line_to(cr,
- dst_x + adx + ady/1.5,
- dst_y + ady - adx/1.5);
- cairo_close_path(cr);
- cairo_stroke_preserve(cr);
- cairo_fill(cr);
- }
- }
-
- if (!ganv_canvas_exporting(item->impl->canvas) &&
- impl->coords.handle_radius > 0.0) {
- cairo_move_to(cr, join_x, join_y);
- cairo_arc(cr, join_x, join_y, impl->coords.handle_radius, 0, 2 * G_PI);
- cairo_fill(cr);
- }
-}
-
-static double
-ganv_edge_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- const GanvEdge* edge = GANV_EDGE(item);
- const GanvEdgeCoords* coords = &edge->impl->coords;
-
- const double dx = fabs(x - coords->handle_x);
- const double dy = fabs(y - coords->handle_y);
- const double d = sqrt((dx * dx) + (dy * dy));
-
- *actual_item = item;
-
- if (d <= coords->handle_radius) {
- // Point is inside the handle
- return 0.0;
- } else {
- // Distance from the edge of the handle
- return d - (coords->handle_radius + coords->width);
- }
-}
-
-gboolean
-ganv_edge_is_within(const GanvEdge* edge,
- double x1,
- double y1,
- double x2,
- double y2)
-{
- const double handle_x = edge->impl->coords.handle_x;
- const double handle_y = edge->impl->coords.handle_y;
-
- return handle_x >= x1
- && handle_x <= x2
- && handle_y >= y1
- && handle_y <= y2;
-}
-
-static void
-ganv_edge_class_init(GanvEdgeClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
-
- parent_class = GANV_ITEM_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_edge_set_property;
- gobject_class->get_property = ganv_edge_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_TAIL, g_param_spec_object(
- "tail",
- _("Tail"),
- _("Node this edge starts from."),
- GANV_TYPE_NODE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HEAD, g_param_spec_object(
- "head",
- _("Head"),
- _("Node this edge ends at."),
- GANV_TYPE_NODE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_WIDTH, g_param_spec_double(
- "width",
- _("Line width"),
- _("Width of edge line."),
- 0.0, G_MAXDOUBLE,
- 2.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HANDLE_RADIUS, g_param_spec_double(
- "handle-radius",
- _("Gandle radius"),
- _("Radius of handle in canvas units."),
- 0.0, G_MAXDOUBLE,
- 4.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_DASH_LENGTH, g_param_spec_double(
- "dash-length",
- _("Line dash length"),
- _("Length of line dashes, or zero for no dashing."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_DASH_OFFSET, g_param_spec_double(
- "dash-offset",
- _("Line dash offset"),
- _("Start offset for line dashes, used for selected animation."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_COLOR, g_param_spec_uint(
- "color",
- _("Color"),
- _("Line color as an RGBA integer."),
- 0, G_MAXUINT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_CONSTRAINING, g_param_spec_boolean(
- "constraining",
- _("Constraining"),
- _("Whether edge should constrain the layout."),
- 1,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_CURVED, g_param_spec_boolean(
- "curved",
- _("Curved"),
- _("Whether line should be curved rather than straight."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_ARROWHEAD, g_param_spec_boolean(
- "arrowhead",
- _("Arrowhead"),
- _("Whether to show an arrowhead at the head of this edge."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_SELECTED, g_param_spec_boolean(
- "selected",
- _("Selected"),
- _("Whether this edge is selected."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HIGHLIGHTED, g_param_spec_boolean(
- "highlighted",
- _("Highlighted"),
- _("Whether to highlight the edge."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_GHOST, g_param_spec_boolean(
- "ghost",
- _("Ghost"),
- _("Whether this edge is a `ghost', which is an edge that is not "
- "added to the canvas data structures. Ghost edges are used for "
- "temporary edges that are not considered `real', e.g. the edge "
- "made while dragging to make a connection."),
- 0,
- G_PARAM_READWRITE));
-
- object_class->destroy = ganv_edge_destroy;
-
- item_class->update = ganv_edge_update;
- item_class->bounds = ganv_edge_bounds;
- item_class->point = ganv_edge_point;
- item_class->draw = ganv_edge_draw;
-}
-
-GanvEdge*
-ganv_edge_new(GanvCanvas* canvas,
- GanvNode* tail,
- GanvNode* head,
- const char* first_prop_name, ...)
-{
- GanvEdge* edge = GANV_EDGE(
- g_object_new(ganv_edge_get_type(), NULL));
-
- va_list args;
- va_start(args, first_prop_name);
- ganv_item_construct(&edge->item,
- GANV_ITEM(ganv_canvas_root(canvas)),
- first_prop_name, args);
- va_end(args);
-
- edge->impl->tail = tail;
- edge->impl->head = head;
-
- if (!edge->impl->color) {
- const guint tail_color = GANV_NODE(tail)->impl->fill_color;
- g_object_set(G_OBJECT(edge),
- "color", EDGE_COLOR(tail_color),
- NULL);
- }
-
- if (!edge->impl->ghost) {
- ganv_canvas_add_edge(canvas, edge);
- }
- return edge;
-}
-
-void
-ganv_edge_update_location(GanvEdge* edge)
-{
- ganv_item_request_update(GANV_ITEM(edge));
-}
-
-gboolean
-ganv_edge_get_constraining(const GanvEdge* edge)
-{
- return edge->impl->coords.constraining;
-}
-
-void
-ganv_edge_set_constraining(GanvEdge* edge, gboolean constraining)
-{
- edge->impl->coords.constraining = constraining;
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
-}
-
-gboolean
-ganv_edge_get_curved(const GanvEdge* edge)
-{
- return edge->impl->coords.curved;
-}
-
-void
-ganv_edge_set_curved(GanvEdge* edge, gboolean curved)
-{
- edge->impl->coords.curved = curved;
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
-}
-
-void
-ganv_edge_set_selected(GanvEdge* edge, gboolean selected)
-{
- GanvCanvas* canvas = GANV_CANVAS(edge->item.impl->canvas);
- if (selected) {
- ganv_canvas_select_edge(canvas, edge);
- } else {
- ganv_canvas_unselect_edge(canvas, edge);
- }
-}
-
-void
-ganv_edge_select(GanvEdge* edge)
-{
- ganv_edge_set_selected(edge, TRUE);
-}
-
-void
-ganv_edge_unselect(GanvEdge* edge)
-{
- ganv_edge_set_selected(edge, FALSE);
-}
-
-void
-ganv_edge_highlight(GanvEdge* edge)
-{
- ganv_edge_set_highlighted(edge, TRUE);
-}
-
-void
-ganv_edge_unhighlight(GanvEdge* edge)
-{
- ganv_edge_set_highlighted(edge, FALSE);
-}
-
-void
-ganv_edge_set_highlighted(GanvEdge* edge, gboolean highlighted)
-{
- edge->impl->highlighted = highlighted;
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
-}
-
-void
-ganv_edge_tick(GanvEdge* edge, double seconds)
-{
- ganv_item_set(GANV_ITEM(edge),
- "dash-offset", seconds * 8.0,
- NULL);
-}
-
-void
-ganv_edge_disconnect(GanvEdge* edge)
-{
- if (!edge->impl->ghost) {
- ganv_canvas_disconnect_edge(
- GANV_CANVAS(edge->item.impl->canvas),
- edge);
- }
-}
-
-void
-ganv_edge_remove(GanvEdge* edge)
-{
- if (!edge->impl->ghost) {
- ganv_canvas_remove_edge(
- GANV_CANVAS(edge->item.impl->canvas),
- edge);
- }
-}
-
-GanvNode*
-ganv_edge_get_tail(const GanvEdge* edge)
-{
- return edge->impl->tail;
-}
-
-GanvNode*
-ganv_edge_get_head(const GanvEdge* edge)
-{
- return edge->impl->head;
-}