summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-04-26 16:49:15 +0000
committerDavid Robillard <d@drobilla.net>2014-04-26 16:49:15 +0000
commit65b14544b89afc3a7d3a7de57e6ef15ca8165bd0 (patch)
treeaff9e8f19197c83df67ff723ea154b7573880cdb /src
parentfb3498abb00ed3cf5c5938fcb1bffef163674274 (diff)
downloadganv-65b14544b89afc3a7d3a7de57e6ef15ca8165bd0.tar.gz
ganv-65b14544b89afc3a7d3a7de57e6ef15ca8165bd0.tar.bz2
ganv-65b14544b89afc3a7d3a7de57e6ef15ca8165bd0.zip
Clean up Ganv API.
git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@5367 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/Canvas.cpp169
-rw-r--r--src/boilerplate.h2
-rw-r--r--src/box.c6
-rw-r--r--src/circle.c71
-rw-r--r--src/edge.c62
-rw-r--r--src/ganv-private.h91
-rw-r--r--src/group.c93
-rw-r--r--src/item.c130
-rw-r--r--src/module.c14
-rw-r--r--src/node.c108
-rw-r--r--src/port.c30
-rw-r--r--src/text.c12
-rw-r--r--src/widget.c173
13 files changed, 572 insertions, 389 deletions
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
index 7e4fec3..5e0605b 100644
--- a/src/Canvas.cpp
+++ b/src/Canvas.cpp
@@ -195,8 +195,8 @@ struct GanvCanvasImpl {
, _select_start_y(0.0)
, _drag_state(NOT_DRAGGING)
{
- this->root = GANV_ITEM(g_object_new(ganv_group_get_type(), NULL));
- this->root->canvas = canvas;
+ this->root = GANV_ITEM(g_object_new(ganv_group_get_type(), NULL));
+ this->root->impl->canvas = canvas;
g_object_ref_sink(this->root);
this->direction = GANV_DIRECTION_RIGHT;
@@ -514,7 +514,7 @@ select_if_head_is_selected(GanvEdge* edge, void* data)
}
if (selected) {
- ganv_edge_select(edge);
+ ganv_edge_set_selected(edge, TRUE);
}
}
@@ -774,8 +774,8 @@ get_region(GanvNode* node)
ganv_item_get_bounds(item, &reg.pos.x, &reg.pos.y, &reg.area.x, &reg.area.y);
reg.area.x = x2 - x1;
reg.area.y = y2 - y1;
- reg.pos.x = item->x + (reg.area.x / 2.0);
- reg.pos.y = item->y + (reg.area.y / 2.0);
+ reg.pos.x = item->impl->x + (reg.area.x / 2.0);
+ reg.pos.y = item->impl->y + (reg.area.y / 2.0);
// No need for i2w here since we only care about top-level items
return reg;
@@ -923,19 +923,19 @@ GanvCanvasImpl::layout_calculate(double dur, bool update)
// Update position
GanvItem* item = &node->item;
- const double x0 = item->x;
- const double y0 = item->y;
+ const double x0 = item->impl->x;
+ const double y0 = item->impl->y;
const Vector dpos = vec_mult(node->impl->vel, dur);
- item->x = std::max(MIN_COORD, item->x + dpos.x);
- item->y = std::max(MIN_COORD, item->y + dpos.y);
+ item->impl->x = std::max(MIN_COORD, item->impl->x + dpos.x);
+ item->impl->y = std::max(MIN_COORD, item->impl->y + dpos.y);
if (update) {
ganv_item_request_update(item);
- item->canvas->impl->need_repick = TRUE;
+ item->impl->canvas->impl->need_repick = TRUE;
}
- if (lrint(x0) != lrint(item->x) || lrint(y0) != lrint(item->y)) {
+ if (lrint(x0) != lrint(item->impl->x) || lrint(y0) != lrint(item->impl->y)) {
++n_moved;
}
}
@@ -1073,7 +1073,7 @@ GanvCanvasImpl::get_node_at(double x, double y)
if (GANV_IS_NODE(item)) {
return GANV_NODE(item);
} else {
- item = item->parent;
+ item = item->impl->parent;
}
}
@@ -1698,7 +1698,7 @@ Canvas::~Canvas()
}
void
-Canvas::remove_edge(Node* item1, Node* item2)
+Canvas::remove_edge_between(Node* item1, Node* item2)
{
GanvEdge* edge = ganv_canvas_get_edge(_gobj, item1->gobj(), item2->gobj());
if (edge) {
@@ -1712,15 +1712,24 @@ Canvas::remove_edge(Edge* edge)
ganv_canvas_remove_edge(_gobj, edge->gobj());
}
+Item*
+Canvas::get_item_at(double x, double y) const
+{
+ GanvItem* item = ganv_canvas_get_item_at(_gobj, x, y);
+ if (item) {
+ return Glib::wrap(item);
+ }
+ return NULL;
+}
+
Edge*
Canvas::get_edge(Node* tail, Node* head) const
{
GanvEdge* e = ganv_canvas_get_edge(_gobj, tail->gobj(), head->gobj());
if (e) {
return Glib::wrap(e);
- } else {
- return NULL;
}
+ return NULL;
}
GQuark
@@ -1766,7 +1775,7 @@ ganv_canvas_init(GanvCanvas* canvas)
canvas->impl = new GanvCanvasImpl(canvas);
- g_signal_connect(G_OBJECT(ganv_canvas_root(GANV_CANVAS(canvas))),
+ g_signal_connect(G_OBJECT(ganv_canvas_root(canvas)),
"event", G_CALLBACK(on_canvas_event), canvas->impl);
}
@@ -1839,6 +1848,8 @@ ganv_canvas_class_init(GanvCanvasClass* klass)
canvas_parent_class = GTK_LAYOUT_CLASS(g_type_class_peek_parent(klass));
+ g_type_class_add_private(klass, sizeof(GanvCanvasImpl));
+
gobject_class->set_property = ganv_canvas_set_property;
gobject_class->get_property = ganv_canvas_get_property;
@@ -1951,8 +1962,7 @@ ganv_canvas_resize(GanvCanvas* canvas, double width, double height)
if (width != canvas->impl->width || height != canvas->impl->height) {
canvas->impl->width = width;
canvas->impl->height = height;
- ganv_canvas_set_scroll_region(
- GANV_CANVAS(canvas), 0.0, 0.0, width, height);
+ ganv_canvas_set_scroll_region(canvas, 0.0, 0.0, width, height);
}
}
@@ -2049,7 +2059,7 @@ ganv_canvas_zoom_full(GanvCanvas* canvas)
int win_width, win_height;
GdkWindow* win = gtk_widget_get_window(
- GTK_WIDGET(GANV_CANVAS(canvas->impl->_gcanvas)));
+ GTK_WIDGET(canvas->impl->_gcanvas));
gdk_window_get_size(win, &win_width, &win_height);
// Box containing all canvas items
@@ -2060,8 +2070,8 @@ ganv_canvas_zoom_full(GanvCanvas* canvas)
FOREACH_ITEM(canvas->impl->_items, i) {
GanvItem* const item = GANV_ITEM(*i);
- const double x = item->x;
- const double y = item->y;
+ const double x = item->impl->x;
+ const double y = item->impl->y;
if (GANV_IS_CIRCLE(*i)) {
const double r = GANV_CIRCLE(*i)->impl->coords.radius;
left = MIN(left, x - r);
@@ -2085,11 +2095,11 @@ ganv_canvas_zoom_full(GanvCanvas* canvas)
ganv_canvas_set_zoom(canvas, new_zoom);
int scroll_x, scroll_y;
- ganv_canvas_w2c(GANV_CANVAS(canvas->impl->_gcanvas),
+ ganv_canvas_w2c(canvas->impl->_gcanvas,
lrintf(left - pad), lrintf(bottom - pad),
&scroll_x, &scroll_y);
- ganv_canvas_scroll_to(GANV_CANVAS(canvas->impl->_gcanvas),
+ ganv_canvas_scroll_to(canvas->impl->_gcanvas,
scroll_x, scroll_y);
}
@@ -2140,7 +2150,7 @@ ganv_canvas_move_selected_items(GanvCanvas* canvas,
double dy)
{
FOREACH_ITEM(canvas->impl->_selected_items, i) {
- if ((*i)->item.parent == canvas->impl->root) {
+ if ((*i)->item.impl->parent == canvas->impl->root) {
ganv_node_move(*i, dx, dy);
}
}
@@ -2150,8 +2160,8 @@ void
ganv_canvas_selection_move_finished(GanvCanvas* canvas)
{
FOREACH_ITEM(canvas->impl->_selected_items, i) {
- const double x = GANV_ITEM(*i)->x;
- const double y = GANV_ITEM(*i)->y;
+ const double x = GANV_ITEM(*i)->impl->x;
+ const double y = GANV_ITEM(*i)->impl->y;
g_signal_emit(*i, signal_moved, 0, x, y, NULL);
}
}
@@ -2161,7 +2171,7 @@ select_if_ends_are_selected(GanvEdge* edge, void* data)
{
if (ganv_node_is_selected(ganv_edge_get_tail(edge)) &&
ganv_node_is_selected(ganv_edge_get_head(edge))) {
- ganv_edge_select(edge);
+ ganv_edge_set_selected(edge, TRUE);
}
}
@@ -2221,7 +2231,7 @@ ganv_canvas_add_node(GanvCanvas* canvas,
GanvNode* node)
{
GanvItem* item = GANV_ITEM(node);
- if (item->parent == ganv_canvas_root(canvas)) {
+ if (item->impl->parent == ganv_canvas_root(canvas)) {
canvas->impl->_items.insert(node);
}
}
@@ -2468,8 +2478,8 @@ ganv_canvas_move_contents_to(GanvCanvas* canvas, double x, double y)
{
double min_x=HUGE_VAL, min_y=HUGE_VAL;
FOREACH_ITEM(canvas->impl->_items, i) {
- const double x = GANV_ITEM(*i)->x;
- const double y = GANV_ITEM(*i)->y;
+ const double x = GANV_ITEM(*i)->impl->x;
+ const double y = GANV_ITEM(*i)->impl->y;
min_x = std::min(min_x, x);
min_y = std::min(min_y, y);
}
@@ -2493,7 +2503,7 @@ ganv_canvas_arrange(GanvCanvas* canvas)
// Arrange to graphviz coordinates
for (GVNodes::iterator i = nodes.begin(); i != nodes.end(); ++i) {
- if (GANV_ITEM(i->first)->parent != GANV_ITEM(ganv_canvas_root(canvas))) {
+ if (GANV_ITEM(i->first)->impl->parent != GANV_ITEM(ganv_canvas_root(canvas))) {
continue;
}
const std::string pos = agget(i->second, (char*)"pos");
@@ -2549,11 +2559,11 @@ ganv_canvas_arrange(GanvCanvas* canvas)
static const double border_width = GANV_CANVAS_PAD;
canvas->impl->move_contents_to_internal(border_width, border_width, least_x, least_y);
- ganv_canvas_scroll_to(GANV_CANVAS(canvas->impl->_gcanvas), 0, 0);
+ ganv_canvas_scroll_to(canvas->impl->_gcanvas, 0, 0);
FOREACH_ITEM(canvas->impl->_items, i) {
- const double x = GANV_ITEM(*i)->x;
- const double y = GANV_ITEM(*i)->y;
+ const double x = GANV_ITEM(*i)->impl->x;
+ const double y = GANV_ITEM(*i)->impl->y;
g_signal_emit(*i, signal_moved, 0, x, y, NULL);
}
#endif
@@ -2569,7 +2579,7 @@ ganv_canvas_export_dot(GanvCanvas* canvas, const char* filename)
}
gboolean
-ganv_canvas_supports_sprung_layout(GanvCanvas* canvas)
+ganv_canvas_supports_sprung_layout(const GanvCanvas* canvas)
{
#ifdef GANV_FDGL
return TRUE;
@@ -2591,7 +2601,7 @@ ganv_canvas_set_sprung_layout(GanvCanvas* canvas, gboolean sprung_layout)
}
gboolean
-ganv_canvas_get_locked(GanvCanvas* canvas)
+ganv_canvas_get_locked(const GanvCanvas* canvas)
{
return canvas->impl->locked;
}
@@ -2672,8 +2682,7 @@ ganv_canvas_new(double width, double height)
"height", height,
NULL));
- ganv_canvas_set_scroll_region(GANV_CANVAS(canvas),
- 0.0, 0.0, width, height);
+ ganv_canvas_set_scroll_region(canvas, 0.0, 0.0, width, height);
return canvas;
}
@@ -2682,8 +2691,6 @@ ganv_canvas_new(double width, double height)
static void
ganv_canvas_map(GtkWidget* widget)
{
- GanvCanvas* canvas;
-
g_return_if_fail(GANV_IS_CANVAS(widget));
/* Normal widget mapping stuff */
@@ -2692,7 +2699,7 @@ ganv_canvas_map(GtkWidget* widget)
(*GTK_WIDGET_CLASS(canvas_parent_class)->map)(widget);
}
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
if (canvas->impl->need_update) {
add_idle(canvas);
@@ -2709,11 +2716,9 @@ ganv_canvas_map(GtkWidget* widget)
static void
ganv_canvas_unmap(GtkWidget* widget)
{
- GanvCanvas* canvas;
-
g_return_if_fail(GANV_IS_CANVAS(widget));
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
shutdown_transients(canvas);
@@ -2734,8 +2739,6 @@ ganv_canvas_unmap(GtkWidget* widget)
static void
ganv_canvas_realize(GtkWidget* widget)
{
- GanvCanvas* canvas;
-
g_return_if_fail(GANV_IS_CANVAS(widget));
/* Normal widget realization stuff */
@@ -2744,7 +2747,7 @@ ganv_canvas_realize(GtkWidget* widget)
(*GTK_WIDGET_CLASS(canvas_parent_class)->realize)(widget);
}
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
gdk_window_set_events(
canvas->layout.bin_window,
@@ -2770,11 +2773,9 @@ ganv_canvas_realize(GtkWidget* widget)
static void
ganv_canvas_unrealize(GtkWidget* widget)
{
- GanvCanvas* canvas;
-
g_return_if_fail(GANV_IS_CANVAS(widget));
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
shutdown_transients(canvas);
@@ -2889,8 +2890,6 @@ scroll_to(GanvCanvas* canvas, int cx, int cy)
static void
ganv_canvas_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
{
- GanvCanvas* canvas;
-
g_return_if_fail(GANV_IS_CANVAS(widget));
g_return_if_fail(allocation != NULL);
@@ -2898,7 +2897,7 @@ ganv_canvas_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
(*GTK_WIDGET_CLASS(canvas_parent_class)->size_allocate)(widget, allocation);
}
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
/* Recenter the view, if appropriate */
@@ -2920,7 +2919,7 @@ ganv_canvas_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
static gboolean
is_descendant(GanvItem* item, GanvItem* parent)
{
- for (; item; item = item->parent) {
+ for (; item; item = item->impl->parent) {
if (item == parent) {
return TRUE;
}
@@ -3050,7 +3049,7 @@ ganv_canvas_emit_event(GanvCanvas* canvas, GdkEvent* event)
ganv_item_emit_event(item, ev, &finished);
- parent = item->parent;
+ parent = item->impl->parent;
g_object_unref(G_OBJECT(item));
item = parent;
@@ -3143,9 +3142,9 @@ int
ganv_canvas_grab_item(GanvItem* item, guint event_mask, GdkCursor* cursor, guint32 etime)
{
g_return_val_if_fail(GANV_IS_ITEM(item), GDK_GRAB_NOT_VIEWABLE);
- g_return_val_if_fail(GTK_WIDGET_MAPPED(item->canvas), GDK_GRAB_NOT_VIEWABLE);
+ g_return_val_if_fail(GTK_WIDGET_MAPPED(item->impl->canvas), GDK_GRAB_NOT_VIEWABLE);
- if (item->canvas->impl->grabbed_item) {
+ if (item->impl->canvas->impl->grabbed_item) {
return GDK_GRAB_ALREADY_GRABBED;
}
@@ -3153,7 +3152,7 @@ ganv_canvas_grab_item(GanvItem* item, guint event_mask, GdkCursor* cursor, guint
return GDK_GRAB_NOT_VIEWABLE;
}
- int retval = gdk_pointer_grab(item->canvas->layout.bin_window,
+ int retval = gdk_pointer_grab(item->impl->canvas->layout.bin_window,
FALSE,
(GdkEventMask)event_mask,
NULL,
@@ -3164,9 +3163,9 @@ ganv_canvas_grab_item(GanvItem* item, guint event_mask, GdkCursor* cursor, guint
return retval;
}
- item->canvas->impl->grabbed_item = item;
- item->canvas->impl->grabbed_event_mask = event_mask;
- item->canvas->impl->current_item = item; /* So that events go to the grabbed item */
+ item->impl->canvas->impl->grabbed_item = item;
+ item->impl->canvas->impl->grabbed_event_mask = event_mask;
+ item->impl->canvas->impl->current_item = item; /* So that events go to the grabbed item */
return retval;
}
@@ -3184,11 +3183,11 @@ ganv_canvas_ungrab_item(GanvItem* item, guint32 etime)
{
g_return_if_fail(GANV_IS_ITEM(item));
- if (item->canvas->impl->grabbed_item != item) {
+ if (item->impl->canvas->impl->grabbed_item != item) {
return;
}
- item->canvas->impl->grabbed_item = NULL;
+ item->impl->canvas->impl->grabbed_item = NULL;
gdk_pointer_ungrab(etime);
}
@@ -3285,7 +3284,7 @@ pick_current_item(GanvCanvas* canvas, GdkEvent* event)
if (canvas->impl->root->object.flags & GANV_ITEM_VISIBLE) {
GANV_ITEM_GET_CLASS(canvas->impl->root)->point(
canvas->impl->root,
- x - canvas->impl->root->x, y - canvas->impl->root->y,
+ x - canvas->impl->root->impl->x, y - canvas->impl->root->impl->y,
&canvas->impl->new_current_item);
} else {
canvas->impl->new_current_item = NULL;
@@ -3344,16 +3343,15 @@ pick_current_item(GanvCanvas* canvas, GdkEvent* event)
static gint
ganv_canvas_button(GtkWidget* widget, GdkEventButton* event)
{
- GanvCanvas* canvas;
- int mask;
- int retval;
+ int mask;
+ int retval;
g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
retval = FALSE;
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
/*
* dispatch normally regardless of the event's window if an item has
@@ -3419,12 +3417,10 @@ ganv_canvas_button(GtkWidget* widget, GdkEventButton* event)
static gint
ganv_canvas_motion(GtkWidget* widget, GdkEventMotion* event)
{
- GanvCanvas* canvas;
-
g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
if (event->window != canvas->layout.bin_window) {
return FALSE;
@@ -3438,12 +3434,10 @@ ganv_canvas_motion(GtkWidget* widget, GdkEventMotion* event)
static gboolean
ganv_canvas_scroll(GtkWidget* widget, GdkEventScroll* event)
{
- GanvCanvas* canvas;
-
g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
if (event->window != canvas->layout.bin_window) {
return FALSE;
@@ -3458,12 +3452,10 @@ ganv_canvas_scroll(GtkWidget* widget, GdkEventScroll* event)
static gboolean
ganv_canvas_key(GtkWidget* widget, GdkEventKey* event)
{
- GanvCanvas* canvas;
-
g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
if (!ganv_canvas_emit_event(canvas, (GdkEvent*)event)) {
GtkWidgetClass* widget_class;
@@ -3492,12 +3484,10 @@ ganv_canvas_key(GtkWidget* widget, GdkEventKey* event)
static gint
ganv_canvas_crossing(GtkWidget* widget, GdkEventCrossing* event)
{
- GanvCanvas* canvas;
-
g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
g_return_val_if_fail(event != NULL, FALSE);
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
if (event->window != canvas->layout.bin_window) {
return FALSE;
@@ -3511,11 +3501,9 @@ ganv_canvas_crossing(GtkWidget* widget, GdkEventCrossing* event)
static gint
ganv_canvas_focus_in(GtkWidget* widget, GdkEventFocus* event)
{
- GanvCanvas* canvas;
-
GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
if (canvas->impl->focused_item) {
return ganv_canvas_emit_event(canvas, (GdkEvent*)event);
@@ -3528,11 +3516,9 @@ ganv_canvas_focus_in(GtkWidget* widget, GdkEventFocus* event)
static gint
ganv_canvas_focus_out(GtkWidget* widget, GdkEventFocus* event)
{
- GanvCanvas* canvas;
-
GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
- canvas = GANV_CANVAS(widget);
+ GanvCanvas* canvas = GANV_CANVAS(widget);
if (canvas->impl->focused_item) {
return ganv_canvas_emit_event(canvas, (GdkEvent*)event);
@@ -3695,11 +3681,9 @@ update_again:
static gboolean
idle_handler(gpointer data)
{
- GanvCanvas* canvas;
-
GDK_THREADS_ENTER();
- canvas = GANV_CANVAS(data);
+ GanvCanvas* canvas = GANV_CANVAS(data);
do_update(canvas);
@@ -3809,7 +3793,7 @@ ganv_canvas_set_center_scroll_region(GanvCanvas* canvas, gboolean center_scroll_
}
gboolean
-ganv_canvas_get_center_scroll_region(GanvCanvas* canvas)
+ganv_canvas_get_center_scroll_region(const GanvCanvas* canvas)
{
g_return_val_if_fail(GANV_IS_CANVAS(canvas), FALSE);
@@ -3841,14 +3825,13 @@ ganv_canvas_get_scroll_offsets(const GanvCanvas* canvas, int* cx, int* cy)
GanvItem*
ganv_canvas_get_item_at(GanvCanvas* canvas, double x, double y)
{
-
g_return_val_if_fail(GANV_IS_CANVAS(canvas), NULL);
GanvItem* item = NULL;
double dist = GANV_ITEM_GET_CLASS(canvas->impl->root)->point(
canvas->impl->root,
- x - canvas->impl->root->x,
- y - canvas->impl->root->y,
+ x - canvas->impl->root->impl->x,
+ y - canvas->impl->root->impl->y,
&item);
if ((int)(dist * canvas->impl->pixels_per_unit + 0.5) <= GANV_CLOSE_ENOUGH) {
return item;
diff --git a/src/boilerplate.h b/src/boilerplate.h
index 33c09df..a6be001 100644
--- a/src/boilerplate.h
+++ b/src/boilerplate.h
@@ -27,7 +27,7 @@ typedef gpointer gobject;
if (field != tmp) { \
field = tmp; \
GanvItem* item = GANV_ITEM(object); \
- if (item->canvas) { \
+ if (item->impl->canvas) { \
ganv_item_request_update(item); \
} \
} \
diff --git a/src/box.c b/src/box.c
index 08ab8da..dbff13f 100644
--- a/src/box.c
+++ b/src/box.c
@@ -153,7 +153,7 @@ ganv_box_request_redraw(GanvItem* item,
ganv_item_i2w_pair(item, &x1, &y1, &x2, &y2);
}
- ganv_canvas_request_redraw_w(item->canvas, x1, y1, x2, y2);
+ ganv_canvas_request_redraw_w(item->impl->canvas, x1, y1, x2, y2);
}
static void
@@ -193,8 +193,8 @@ ganv_box_update(GanvItem* item, int flags)
ganv_box_normalize(box);
// Update world-relative bounding box
- ganv_box_bounds(item, &item->x1, &item->y1, &item->x2, &item->y2);
- ganv_item_i2w_pair(item, &item->x1, &item->y1, &item->x2, &item->y2);
+ ganv_box_bounds(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
+ ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
// Request redraw of new location
ganv_box_request_redraw(item, &impl->coords, FALSE);
diff --git a/src/circle.c b/src/circle.c
index 789ebb0..b16accd 100644
--- a/src/circle.c
+++ b/src/circle.c
@@ -61,15 +61,6 @@ ganv_circle_destroy(GtkObject* object)
}
static void
-set_radius_ems(GanvCircle* circle,
- double ems)
-{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(circle)->canvas);
- const double points = ganv_canvas_get_font_size(canvas);
- circle->impl->coords.radius = points * ems;
-}
-
-static void
ganv_circle_set_property(GObject* object,
guint prop_id,
const GValue* value,
@@ -90,7 +81,7 @@ ganv_circle_set_property(GObject* object,
}
if (prop_id == PROP_RADIUS_EMS) {
- set_radius_ems(circle, circle->impl->coords.radius_ems);
+ ganv_circle_set_radius_ems(circle, circle->impl->coords.radius_ems);
}
}
@@ -120,7 +111,7 @@ ganv_circle_resize(GanvNode* self)
{
GanvNode* node = GANV_NODE(self);
GanvCircle* circle = GANV_CIRCLE(self);
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->canvas);
+ GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->impl->canvas);
if (node->impl->label) {
if (node->impl->label->impl->needs_layout) {
@@ -159,7 +150,7 @@ ganv_circle_redraw_text(GanvNode* self)
{
GanvCircle* circle = GANV_CIRCLE(self);
if (circle->impl->coords.radius_ems) {
- set_radius_ems(circle, circle->impl->coords.radius_ems);
+ ganv_circle_set_radius_ems(circle, circle->impl->coords.radius_ems);
}
if (parent_class->redraw_text) {
@@ -174,8 +165,8 @@ ganv_circle_is_within(const GanvNode* self,
double x2,
double y2)
{
- const double x = GANV_ITEM(self)->x;
- const double y = GANV_ITEM(self)->y;
+ const double x = GANV_ITEM(self)->impl->x;
+ const double y = GANV_ITEM(self)->impl->y;
return x >= x1
&& x <= x2
@@ -193,10 +184,10 @@ ganv_circle_vector(const GanvNode* self,
{
GanvCircle* circle = GANV_CIRCLE(self);
- const double cx = GANV_ITEM(self)->x;
- const double cy = GANV_ITEM(self)->y;
- const double other_x = GANV_ITEM(other)->x;
- const double other_y = GANV_ITEM(other)->y;
+ const double cx = GANV_ITEM(self)->impl->x;
+ const double cy = GANV_ITEM(self)->impl->y;
+ const double other_x = GANV_ITEM(other)->impl->x;
+ const double other_y = GANV_ITEM(other)->impl->y;
const double xdist = other_x - cx;
const double ydist = other_y - cy;
@@ -212,7 +203,7 @@ ganv_circle_vector(const GanvNode* self,
*dx = 0.0;
*dy = 0.0;
- ganv_item_i2w(GANV_ITEM(circle)->parent, x, y);
+ ganv_item_i2w(GANV_ITEM(circle)->impl->parent, x, y);
}
static void
@@ -232,7 +223,7 @@ request_redraw(GanvItem* item,
ganv_item_i2w_pair(item, &x1, &y1, &x2, &y2);
}
- ganv_canvas_request_redraw_w(item->canvas, x1, y1, x2, y2);
+ ganv_canvas_request_redraw_w(item->impl->canvas, x1, y1, x2, y2);
}
static void
@@ -283,8 +274,8 @@ ganv_circle_update(GanvItem* item, int flags)
coords_i2w(item, &impl->old_coords);
// Update world-relative bounding box
- ganv_circle_bounds(item, &item->x1, &item->y1, &item->x2, &item->y2);
- ganv_item_i2w_pair(item, &item->x1, &item->y1, &item->x2, &item->y2);
+ ganv_circle_bounds(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
+ ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
// Request redraw of new location
request_redraw(item, &impl->coords, FALSE);
@@ -437,3 +428,39 @@ ganv_circle_get_radius(const GanvCircle* circle)
{
return circle->impl->coords.radius;
}
+
+void
+ganv_circle_set_radius(GanvCircle* circle, double radius)
+{
+ circle->impl->coords.radius = radius;
+ ganv_item_request_update(GANV_ITEM(circle));
+}
+
+double
+ganv_circle_get_radius_ems(const GanvCircle* circle)
+{
+ return circle->impl->coords.radius_ems;
+}
+
+void
+ganv_circle_set_radius_ems(GanvCircle* circle, double ems)
+{
+ GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(circle)->impl->canvas);
+ const double points = ganv_canvas_get_font_size(canvas);
+ circle->impl->coords.radius_ems = ems;
+ circle->impl->coords.radius = points * ems;
+ ganv_item_request_update(GANV_ITEM(circle));
+}
+
+gboolean
+ganv_circle_get_fit_label(const GanvCircle* circle)
+{
+ return circle->impl->fit_label;
+}
+
+void
+ganv_circle_set_fit_label(GanvCircle* circle, gboolean fit_label)
+{
+ circle->impl->fit_label = fit_label;
+ ganv_item_request_update(GANV_ITEM(circle));
+}
diff --git a/src/edge.c b/src/edge.c
index 79d82c5..444de82 100644
--- a/src/edge.c
+++ b/src/edge.c
@@ -88,11 +88,11 @@ ganv_edge_destroy(GtkObject* object)
g_return_if_fail(GANV_IS_EDGE(object));
GanvEdge* edge = GANV_EDGE(object);
- GanvCanvas* canvas = GANV_CANVAS(edge->item.canvas);
+ GanvCanvas* canvas = GANV_CANVAS(edge->item.impl->canvas);
if (canvas && !edge->impl->ghost) {
- edge->item.canvas = NULL;
+ edge->item.impl->canvas = NULL;
}
- edge->item.parent = NULL;
+ edge->item.impl->parent = NULL;
if (GTK_OBJECT_CLASS(parent_class)->destroy) {
(*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
@@ -166,7 +166,7 @@ void
ganv_edge_request_redraw(GanvItem* item,
const GanvEdgeCoords* coords)
{
- GanvCanvas* canvas = item->canvas;
+ GanvCanvas* canvas = item->impl->canvas;
const double w = coords->width;
if (coords->curved) {
const double src_x = coords->x1;
@@ -308,11 +308,11 @@ ganv_edge_update(GanvItem* item, int flags)
}
// Update world-relative bounding box
- item->x1 = x1;
- item->y1 = y1;
- item->x2 = x2;
- item->y2 = y2;
- ganv_item_i2w_pair(item, &item->x1, &item->y1, &item->x2, &item->y2);
+ 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);
@@ -638,37 +638,51 @@ ganv_edge_update_location(GanvEdge* edge)
ganv_item_request_update(GANV_ITEM(edge));
}
+gboolean
+ganv_edge_get_curved(const GanvEdge* edge)
+{
+ return edge->impl->coords.curved;
+}
+
void
-ganv_edge_select(GanvEdge* edge)
+ganv_edge_set_curved(GanvEdge* edge, gboolean curved)
{
- GanvCanvas* canvas = GANV_CANVAS(edge->item.canvas);
- ganv_canvas_select_edge(canvas, edge);
+ edge->impl->coords.curved = curved;
+ ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
}
void
-ganv_edge_unselect(GanvEdge* edge)
+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)
{
- GanvCanvas* canvas = GANV_CANVAS(edge->item.canvas);
- ganv_canvas_unselect_edge(canvas, edge);
+ ganv_edge_set_selected(edge, TRUE);
}
void
-ganv_edge_highlight(GanvEdge* edge)
+ganv_edge_unselect(GanvEdge* edge)
{
- edge->impl->highlighted = TRUE;
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
+ ganv_edge_set_selected(edge, FALSE);
}
void
-ganv_edge_unhighlight(GanvEdge* edge)
+ganv_edge_set_highlighted(GanvEdge* edge, gboolean highlighted)
{
- edge->impl->highlighted = FALSE;
+ edge->impl->highlighted = highlighted;
ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
}
void
-ganv_edge_tick(GanvEdge* edge,
- double seconds)
+ganv_edge_tick(GanvEdge* edge, double seconds)
{
ganv_item_set(GANV_ITEM(edge),
"dash-offset", seconds * 8.0,
@@ -680,7 +694,7 @@ ganv_edge_disconnect(GanvEdge* edge)
{
if (!edge->impl->ghost) {
ganv_canvas_disconnect_edge(
- GANV_CANVAS(edge->item.canvas),
+ GANV_CANVAS(edge->item.impl->canvas),
edge);
}
}
@@ -690,7 +704,7 @@ ganv_edge_remove(GanvEdge* edge)
{
if (!edge->impl->ghost) {
ganv_canvas_remove_edge(
- GANV_CANVAS(edge->item.canvas),
+ GANV_CANVAS(edge->item.impl->canvas),
edge);
}
}
diff --git a/src/ganv-private.h b/src/ganv-private.h
index 870dcec..8f32480 100644
--- a/src/ganv-private.h
+++ b/src/ganv-private.h
@@ -130,6 +130,83 @@ struct _GanvNodeImpl {
#endif
};
+/* Widget */
+
+struct _GanvWidgetImpl {
+ GtkWidget* widget; /* The child widget */
+
+ double x, y; /* Position at anchor */
+ double width, height; /* Dimensions of widget */
+ GtkAnchorType anchor; /* Anchor side for widget */
+
+ int cx, cy; /* Top-left canvas coordinates for widget */
+ int cwidth, cheight; /* Size of widget in pixels */
+
+ guint destroy_id; /* Signal connection id for destruction of child widget */
+
+ guint size_pixels : 1; /* Is size specified in (unchanging) pixels or units (get scaled)? */
+ guint in_destroy : 1; /* Is child widget being destroyed? */
+};
+
+/* Group */
+struct _GanvGroupImpl {
+ GList* item_list;
+ GList* item_list_end;
+};
+
+/* Item */
+struct _GanvItemImpl {
+ /* Parent canvas for this item */
+ struct _GanvCanvas* canvas;
+
+ /* Parent for this item */
+ GanvItem* parent;
+
+ /* Layer (z order), higher values are on top */
+ guint layer;
+
+ /* Position in parent-relative coordinates. */
+ double x, y;
+
+ /* Bounding box for this item (in world coordinates) */
+ double x1, y1, x2, y2;
+
+ /* True if parent manages this item (don't call add/remove) */
+ gboolean managed;
+};
+
+void
+ganv_node_tick(GanvNode* self, double seconds);
+
+void
+ganv_node_tail_vector(const GanvNode* self,
+ const GanvNode* head,
+ double* x1,
+ double* y1,
+ double* x2,
+ double* y2);
+
+void
+ganv_node_head_vector(const GanvNode* self,
+ const GanvNode* tail,
+ double* x1,
+ double* y1,
+ double* x2,
+ double* y2);
+
+/**
+ * ganv_node_get_draw_properties:
+ *
+ * Get the colours that should currently be used for drawing this node. Note
+ * these may not be identical to the property values because of highlighting
+ * and selection.
+ */
+void
+ganv_node_get_draw_properties(const GanvNode* node,
+ double* dash_length,
+ double* border_color,
+ double* fill_color);
+
/* Port */
typedef struct {
@@ -199,10 +276,6 @@ ganv_canvas_add_edge(GanvCanvas* canvas,
GanvEdge* edge);
void
-ganv_canvas_remove_edge(GanvCanvas* canvas,
- GanvEdge* edge);
-
-void
ganv_canvas_select_edge(GanvCanvas* canvas,
GanvEdge* edge);
@@ -271,12 +344,18 @@ ganv_canvas_request_redraw_w(GanvCanvas* canvas,
/* Edge */
void
+ganv_edge_update_location(GanvEdge* edge);
+
+void
ganv_edge_get_coords(const GanvEdge* edge, GanvEdgeCoords* coords);
void
ganv_edge_request_redraw(GanvItem* item,
const GanvEdgeCoords* coords);
+void
+ganv_edge_tick(GanvEdge* edge, double seconds);
+
/* Box */
void
@@ -290,6 +369,10 @@ void
ganv_port_set_control_value_internal(GanvPort* port,
float value);
+void
+ganv_port_set_direction(GanvPort* port,
+ GanvDirection direction);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/src/group.c b/src/group.c
index fdcb1f6..4e7731a 100644
--- a/src/group.c
+++ b/src/group.c
@@ -37,6 +37,12 @@ static GanvItemClass* group_parent_class;
static void
ganv_group_init(GanvGroup* group)
{
+ GanvGroupImpl* impl = G_TYPE_INSTANCE_GET_PRIVATE(
+ group, GANV_TYPE_GROUP, GanvGroupImpl);
+
+ group->impl = impl;
+ group->impl->item_list = NULL;
+ group->impl->item_list_end = NULL;
}
static void
@@ -74,9 +80,9 @@ ganv_group_destroy(GtkObject* object)
group = GANV_GROUP(object);
- while (group->item_list) {
+ while (group->impl->item_list) {
// child is unref'ed by the child's group_remove().
- gtk_object_destroy(GTK_OBJECT(group->item_list->data));
+ gtk_object_destroy(GTK_OBJECT(group->impl->item_list->data));
}
if (GTK_OBJECT_CLASS(group_parent_class)->destroy) {
(*GTK_OBJECT_CLASS(group_parent_class)->destroy)(object);
@@ -86,11 +92,7 @@ ganv_group_destroy(GtkObject* object)
static void
ganv_group_update(GanvItem* item, int flags)
{
- GanvGroup* group;
- GList* list;
- GanvItem* i;
-
- group = GANV_GROUP(item);
+ GanvGroup* group = GANV_GROUP(item);
(*group_parent_class->update)(item, flags);
@@ -99,20 +101,20 @@ ganv_group_update(GanvItem* item, int flags)
double max_x = 0.0;
double max_y = 0.0;
- for (list = group->item_list; list; list = list->next) {
- i = (GanvItem*)list->data;
+ for (GList* list = group->impl->item_list; list; list = list->next) {
+ GanvItem* i = (GanvItem*)list->data;
ganv_item_invoke_update(i, flags);
- min_x = fmin(min_x, fmin(i->x1, i->x2));
- min_y = fmin(min_y, fmin(i->y1, i->y2));
- max_x = fmax(max_x, fmax(i->x1, i->x2));
- max_y = fmax(max_y, fmax(i->y2, i->y2));
+ min_x = fmin(min_x, fmin(i->impl->x1, i->impl->x2));
+ min_y = fmin(min_y, fmin(i->impl->y1, i->impl->y2));
+ max_x = fmax(max_x, fmax(i->impl->x1, i->impl->x2));
+ max_y = fmax(max_y, fmax(i->impl->y2, i->impl->y2));
}
- item->x1 = min_x;
- item->y1 = min_y;
- item->x2 = max_x;
- item->y2 = max_y;
+ item->impl->x1 = min_x;
+ item->impl->y1 = min_y;
+ item->impl->x2 = max_x;
+ item->impl->y2 = max_y;
}
static void
@@ -124,7 +126,7 @@ ganv_group_realize(GanvItem* item)
group = GANV_GROUP(item);
- for (list = group->item_list; list; list = list->next) {
+ for (list = group->impl->item_list; list; list = list->next) {
i = (GanvItem*)list->data;
if (!(i->object.flags & GANV_ITEM_REALIZED)) {
@@ -144,7 +146,7 @@ ganv_group_unrealize(GanvItem* item)
group = GANV_GROUP(item);
- for (list = group->item_list; list; list = list->next) {
+ for (list = group->impl->item_list; list; list = list->next) {
i = (GanvItem*)list->data;
if (i->object.flags & GANV_ITEM_REALIZED) {
@@ -164,7 +166,7 @@ ganv_group_map(GanvItem* item)
group = GANV_GROUP(item);
- for (list = group->item_list; list; list = list->next) {
+ for (list = group->impl->item_list; list; list = list->next) {
i = (GanvItem*)list->data;
if (!(i->object.flags & GANV_ITEM_MAPPED)) {
@@ -184,7 +186,7 @@ ganv_group_unmap(GanvItem* item)
group = GANV_GROUP(item);
- for (list = group->item_list; list; list = list->next) {
+ for (list = group->impl->item_list; list; list = list->next) {
i = (GanvItem*)list->data;
if (i->object.flags & GANV_ITEM_MAPPED) {
@@ -200,7 +202,6 @@ ganv_group_draw(GanvItem* item,
cairo_t* cr, double cx, double cy, double cw, double ch)
{
GanvGroup* group = GANV_GROUP(item);
- GanvItem* child = NULL;
// Draw background
cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
@@ -209,14 +210,14 @@ ganv_group_draw(GanvItem* item,
// TODO: Layered drawing
- for (GList* list = group->item_list; list; list = list->next) {
- child = (GanvItem*)list->data;
+ for (GList* list = group->impl->item_list; list; list = list->next) {
+ GanvItem* child = (GanvItem*)list->data;
if (((child->object.flags & GANV_ITEM_VISIBLE)
- && ((child->x1 < (cx + cw))
- && (child->y1 < (cy + ch))
- && (child->x2 > cx)
- && (child->y2 > cy)))) {
+ && ((child->impl->x1 < (cx + cw))
+ && (child->impl->y1 < (cy + ch))
+ && (child->impl->x2 > cx)
+ && (child->impl->y2 > cy)))) {
if (GANV_ITEM_GET_CLASS(child)->draw) {
(*GANV_ITEM_GET_CLASS(child)->draw)(
child, cr, cx, cy, cw, ch);
@@ -240,9 +241,9 @@ ganv_group_point(GanvItem* item, double x, double y, GanvItem** actual_item)
*actual_item = NULL;
- for (GList* list = group->item_list; list; list = list->next) {
+ for (GList* list = group->impl->item_list; list; list = list->next) {
GanvItem* child = (GanvItem*)list->data;
- if ((child->x1 > x2) || (child->y1 > y2) || (child->x2 < x1) || (child->y2 < y1)) {
+ if ((child->impl->x1 > x2) || (child->impl->y1 > y2) || (child->impl->x2 < x1) || (child->impl->y2 < y1)) {
continue;
}
@@ -253,7 +254,7 @@ ganv_group_point(GanvItem* item, double x, double y, GanvItem** actual_item)
&& GANV_ITEM_GET_CLASS(child)->point) {
dist = GANV_ITEM_GET_CLASS(child)->point(
child,
- x - child->x, y - child->y,
+ x - child->impl->x, y - child->impl->y,
&point_item);
has_point = TRUE;
}
@@ -281,10 +282,10 @@ get_child_bounds(GanvItem* child, double* x1, double* y1, double* x2, double* y2
ganv_item_get_bounds(child, x1, y1, x2, y2);
// Make bounds relative to the item's parent coordinate system
- *x1 -= child->x;
- *y1 -= child->y;
- *x2 -= child->x;
- *y2 -= child->y;
+ *x1 -= child->impl->x;
+ *y1 -= child->impl->y;
+ *x2 -= child->impl->x;
+ *y2 -= child->impl->y;
}
static void
@@ -305,7 +306,7 @@ ganv_group_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y2
set = FALSE;
- for (list = group->item_list; list; list = list->next) {
+ for (list = group->impl->item_list; list; list = list->next) {
child = (GanvItem*)list->data;
if (child->object.flags & GANV_ITEM_VISIBLE) {
@@ -364,11 +365,11 @@ ganv_group_add(GanvItem* parent, GanvItem* item)
GanvGroup* group = GANV_GROUP(parent);
g_object_ref_sink(G_OBJECT(item));
- if (!group->item_list) {
- group->item_list = g_list_append(group->item_list, item);
- group->item_list_end = group->item_list;
+ if (!group->impl->item_list) {
+ group->impl->item_list = g_list_append(group->impl->item_list, item);
+ group->impl->item_list_end = group->impl->item_list;
} else {
- group->item_list_end = g_list_append(group->item_list_end, item)->next;
+ group->impl->item_list_end = g_list_append(group->impl->item_list_end, item)->next;
}
if (group->item.object.flags & GANV_ITEM_REALIZED) {
@@ -391,7 +392,7 @@ ganv_group_remove(GanvItem* parent, GanvItem* item)
g_return_if_fail(GANV_IS_GROUP(group));
g_return_if_fail(GANV_IS_ITEM(item));
- for (children = group->item_list; children; children = children->next) {
+ for (children = group->impl->item_list; children; children = children->next) {
if (children->data == item) {
if (item->object.flags & GANV_ITEM_MAPPED) {
(*GANV_ITEM_GET_CLASS(item)->unmap)(item);
@@ -403,16 +404,16 @@ ganv_group_remove(GanvItem* parent, GanvItem* item)
/* Unparent the child */
- item->parent = NULL;
+ item->impl->parent = NULL;
g_object_unref(G_OBJECT(item));
/* Remove it from the list */
- if (children == group->item_list_end) {
- group->item_list_end = children->prev;
+ if (children == group->impl->item_list_end) {
+ group->impl->item_list_end = children->prev;
}
- group->item_list = g_list_remove_link(group->item_list, children);
+ group->impl->item_list = g_list_remove_link(group->impl->item_list, children);
g_list_free(children);
break;
}
@@ -432,6 +433,8 @@ ganv_group_class_init(GanvGroupClass* klass)
group_parent_class = (GanvItemClass*)g_type_class_peek_parent(klass);
+ g_type_class_add_private(klass, sizeof(GanvGroupImpl));
+
gobject_class->set_property = ganv_group_set_property;
gobject_class->get_property = ganv_group_get_property;
diff --git a/src/item.c b/src/item.c
index 1bc6de0..c022ac8 100644
--- a/src/item.c
+++ b/src/item.c
@@ -72,8 +72,12 @@ static GtkObjectClass* item_parent_class;
static void
ganv_item_init(GanvItem* item)
{
+ GanvItemImpl* impl = G_TYPE_INSTANCE_GET_PRIVATE(
+ item, GANV_TYPE_ITEM, GanvItemImpl);
+
item->object.flags |= GANV_ITEM_VISIBLE;
- item->managed = FALSE;
+ item->impl = impl;
+ item->impl->managed = FALSE;
}
/**
@@ -98,13 +102,11 @@ ganv_item_init(GanvItem* item)
GanvItem*
ganv_item_new(GanvItem* parent, GType type, const gchar* first_arg_name, ...)
{
- GanvItem* item;
- va_list args;
-
g_return_val_if_fail(g_type_is_a(type, ganv_item_get_type()), NULL);
- item = GANV_ITEM(g_object_new(type, NULL));
+ GanvItem* item = GANV_ITEM(g_object_new(type, NULL));
+ va_list args;
va_start(args, first_arg_name);
ganv_item_construct(item, parent, first_arg_name, args);
va_end(args);
@@ -118,18 +120,18 @@ ganv_item_new(GanvItem* parent, GType type, const gchar* first_arg_name, ...)
static void
item_post_create_setup(GanvItem* item)
{
- GanvItemClass* parent_class = GANV_ITEM_GET_CLASS(item->parent);
- if (!item->managed) {
+ GanvItemClass* parent_class = GANV_ITEM_GET_CLASS(item->impl->parent);
+ if (!item->impl->managed) {
if (parent_class->add) {
- parent_class->add(item->parent, item);
+ parent_class->add(item->impl->parent, item);
} else {
g_warning("item added to non-parent item\n");
}
}
- ganv_canvas_request_redraw_w(item->canvas,
- item->x1, item->y1,
- item->x2 + 1, item->y2 + 1);
- ganv_canvas_set_need_repick(item->canvas);
+ ganv_canvas_request_redraw_w(item->impl->canvas,
+ item->impl->x1, item->impl->y1,
+ item->impl->x2 + 1, item->impl->y2 + 1);
+ ganv_canvas_set_need_repick(item->impl->canvas);
}
static void
@@ -145,25 +147,25 @@ ganv_item_set_property(GObject* object,
switch (prop_id) {
case ITEM_PROP_PARENT:
- if (item->parent != NULL) {
+ if (item->impl->parent != NULL) {
g_warning("Cannot set `parent' argument after item has "
"already been constructed.");
} else if (g_value_get_object(value)) {
- item->parent = GANV_ITEM(g_value_get_object(value));
- item->canvas = item->parent->canvas;
+ item->impl->parent = GANV_ITEM(g_value_get_object(value));
+ item->impl->canvas = item->impl->parent->impl->canvas;
item_post_create_setup(item);
}
break;
case ITEM_PROP_X:
- item->x = g_value_get_double(value);
+ item->impl->x = g_value_get_double(value);
ganv_item_request_update(item);
break;
case ITEM_PROP_Y:
- item->y = g_value_get_double(value);
+ item->impl->y = g_value_get_double(value);
ganv_item_request_update(item);
break;
case ITEM_PROP_MANAGED:
- item->managed = g_value_get_boolean(value);
+ item->impl->managed = g_value_get_boolean(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -184,16 +186,16 @@ ganv_item_get_property(GObject* object,
switch (prop_id) {
case ITEM_PROP_PARENT:
- g_value_set_object(value, item->parent);
+ g_value_set_object(value, item->impl->parent);
break;
case ITEM_PROP_X:
- g_value_set_double(value, item->x);
+ g_value_set_double(value, item->impl->x);
break;
case ITEM_PROP_Y:
- g_value_set_double(value, item->y);
+ g_value_set_double(value, item->impl->y);
break;
case ITEM_PROP_MANAGED:
- g_value_set_boolean(value, item->managed);
+ g_value_set_boolean(value, item->impl->managed);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -216,9 +218,9 @@ ganv_item_construct(GanvItem* item, GanvItem* parent,
{
g_return_if_fail(GANV_IS_ITEM(item));
- item->parent = parent;
- item->canvas = item->parent->canvas;
- item->layer = 0;
+ item->impl->parent = parent;
+ item->impl->canvas = item->impl->parent->impl->canvas;
+ item->impl->layer = 0;
g_object_set_valist(G_OBJECT(item), first_arg_name, args);
@@ -230,9 +232,9 @@ static void
redraw_if_visible(GanvItem* item)
{
if (item->object.flags & GANV_ITEM_VISIBLE) {
- ganv_canvas_request_redraw_w(item->canvas,
- item->x1, item->y1,
- item->x2 + 1, item->y2 + 1);
+ ganv_canvas_request_redraw_w(item->impl->canvas,
+ item->impl->x1, item->impl->y1,
+ item->impl->x2 + 1, item->impl->y2 + 1);
}
}
@@ -246,9 +248,9 @@ ganv_item_dispose(GObject* object)
item = GANV_ITEM(object);
- if (item->canvas) {
+ if (item->impl->canvas) {
redraw_if_visible(item);
- ganv_canvas_forget_item(item->canvas, item);
+ ganv_canvas_forget_item(item->impl->canvas, item);
}
/* Normal destroy stuff */
@@ -261,18 +263,18 @@ ganv_item_dispose(GObject* object)
(*GANV_ITEM_GET_CLASS(item)->unrealize)(item);
}
- if (!item->managed && item->parent) {
- if (GANV_ITEM_GET_CLASS(item->parent)->remove) {
- GANV_ITEM_GET_CLASS(item->parent)->remove(item->parent, item);
+ if (!item->impl->managed && item->impl->parent) {
+ if (GANV_ITEM_GET_CLASS(item->impl->parent)->remove) {
+ GANV_ITEM_GET_CLASS(item->impl->parent)->remove(item->impl->parent, item);
} else {
fprintf(stderr, "warning: Item parent has no remove method\n");
}
}
G_OBJECT_CLASS(item_parent_class)->dispose(object);
- /* items should remove any reference to item->canvas after the
+ /* items should remove any reference to item->impl->canvas after the
first ::destroy */
- item->canvas = NULL;
+ item->impl->canvas = NULL;
}
/* Realize handler for canvas items */
@@ -380,19 +382,31 @@ ganv_item_set_valist(GanvItem* item, const gchar* first_arg_name, va_list args)
g_object_set_valist(G_OBJECT(item), first_arg_name, args);
- ganv_canvas_set_need_repick(item->canvas);
+ ganv_canvas_set_need_repick(item->impl->canvas);
+}
+
+GanvCanvas*
+ganv_item_get_canvas(GanvItem* item)
+{
+ return item->impl->canvas;
+}
+
+GanvItem*
+ganv_item_get_parent(GanvItem* item)
+{
+ return item->impl->parent;
}
void
ganv_item_raise(GanvItem* item)
{
- ++item->layer;
+ ++item->impl->layer;
}
void
ganv_item_lower(GanvItem* item)
{
- --item->layer;
+ --item->impl->layer;
}
/**
@@ -408,11 +422,11 @@ ganv_item_move(GanvItem* item, double dx, double dy)
return;
}
- item->x += dx;
- item->y += dy;
+ item->impl->x += dx;
+ item->impl->y += dy;
ganv_item_request_update(item);
- ganv_canvas_set_need_repick(item->canvas);
+ ganv_canvas_set_need_repick(item->impl->canvas);
}
/**
@@ -428,10 +442,10 @@ ganv_item_show(GanvItem* item)
if (!(item->object.flags & GANV_ITEM_VISIBLE)) {
item->object.flags |= GANV_ITEM_VISIBLE;
- ganv_canvas_request_redraw_w(item->canvas,
- item->x1, item->y1,
- item->x2 + 1, item->y2 + 1);
- ganv_canvas_set_need_repick(item->canvas);
+ ganv_canvas_request_redraw_w(item->impl->canvas,
+ item->impl->x1, item->impl->y1,
+ item->impl->x2 + 1, item->impl->y2 + 1);
+ ganv_canvas_set_need_repick(item->impl->canvas);
}
}
@@ -449,10 +463,10 @@ ganv_item_hide(GanvItem* item)
if (item->object.flags & GANV_ITEM_VISIBLE) {
item->object.flags &= ~GANV_ITEM_VISIBLE;
- ganv_canvas_request_redraw_w(item->canvas,
- item->x1, item->y1,
- item->x2 + 1, item->y2 + 1);
- ganv_canvas_set_need_repick(item->canvas);
+ ganv_canvas_request_redraw_w(item->impl->canvas,
+ item->impl->x1, item->impl->y1,
+ item->impl->x2 + 1, item->impl->y2 + 1);
+ ganv_canvas_set_need_repick(item->impl->canvas);
}
}
@@ -462,9 +476,9 @@ ganv_item_i2w_offset(GanvItem* item, double* px, double* py)
double x = 0.0;
double y = 0.0;
while (item) {
- x += item->x;
- y += item->y;
- item = item->parent;
+ x += item->impl->x;
+ y += item->impl->y;
+ item = item->impl->parent;
}
*px = x;
*py = y;
@@ -538,7 +552,7 @@ ganv_item_w2i(GanvItem* item, double* x, double* y)
void
ganv_item_grab_focus(GanvItem* item)
{
- ganv_canvas_grab_focus(item->canvas, item);
+ ganv_canvas_grab_focus(item->impl->canvas, item);
}
void
@@ -587,19 +601,19 @@ ganv_item_request_update(GanvItem* item)
return;
}
- if (!item->canvas) {
+ if (!item->impl->canvas) {
/* Item is being / has been destroyed, ignore */
return;
}
item->object.flags |= GANV_ITEM_NEED_UPDATE;
- if (item->parent != NULL) {
+ if (item->impl->parent != NULL) {
/* Recurse up the tree */
- ganv_item_request_update(item->parent);
+ ganv_item_request_update(item->impl->parent);
} else {
/* Have reached the top of the tree, make sure the update call gets scheduled. */
- ganv_canvas_request_update(item->canvas);
+ ganv_canvas_request_update(item->impl->canvas);
}
}
@@ -629,6 +643,8 @@ ganv_item_class_init(GanvItemClass* klass)
item_parent_class = (GtkObjectClass*)g_type_class_peek_parent(klass);
+ g_type_class_add_private(klass, sizeof(GanvItemImpl));
+
gobject_class->set_property = ganv_item_set_property;
gobject_class->get_property = ganv_item_get_property;
diff --git a/src/module.c b/src/module.c
index c8da4d2..d630ec8 100644
--- a/src/module.c
+++ b/src/module.c
@@ -148,7 +148,7 @@ measure(GanvModule* module, Metrics* m)
double title_w, title_h;
title_size(module, &title_w, &title_h);
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
GanvText* canvas_title = GANV_NODE(module)->impl->label;
GanvModuleImpl* impl = module->impl;
@@ -253,7 +253,7 @@ place_title(GanvModule* module, GanvDirection dir)
static void
resize_right(GanvModule* module)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
GanvModuleImpl* impl = module->impl;
Metrics m;
@@ -331,7 +331,7 @@ resize_right(GanvModule* module)
static void
resize_down(GanvModule* module)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
GanvModuleImpl* impl = module->impl;
Metrics m;
@@ -414,7 +414,7 @@ layout(GanvNode* self)
GanvModule* module = GANV_MODULE(self);
GanvModuleImpl* impl = module->impl;
GanvNode* node = GANV_NODE(self);
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
double label_w = 0.0;
double label_h = 0.0;
@@ -468,7 +468,7 @@ static void
ganv_module_add_port(GanvModule* module,
GanvPort* port)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
GanvModuleImpl* impl = module->impl;
const double width = ganv_port_get_natural_width(port);
@@ -640,7 +640,7 @@ ganv_module_point(GanvItem* item, double x, double y, GanvItem** actual_item)
*actual_item = NULL;
d = GANV_ITEM_GET_CLASS(port)->point(
- port, x - port->x, y - port->y, actual_item);
+ port, x - port->impl->x, y - port->impl->y, actual_item);
if (*actual_item) {
// Point is inside a port
@@ -719,7 +719,7 @@ ganv_module_get_empty_port_breadth(const GanvModule* module)
double
ganv_module_get_empty_port_depth(const GanvModule* module)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
return ganv_canvas_get_font_size(canvas) * 1.1;
}
diff --git a/src/node.c b/src/node.c
index acfa9df..0037217 100644
--- a/src/node.c
+++ b/src/node.c
@@ -84,8 +84,7 @@ static void
ganv_node_realize(GanvItem* item)
{
GANV_ITEM_CLASS(parent_class)->realize(item);
- ganv_canvas_add_node(GANV_CANVAS(item->canvas),
- GANV_NODE(item));
+ ganv_canvas_add_node(ganv_item_get_canvas(item), GANV_NODE(item));
}
static void
@@ -103,16 +102,16 @@ ganv_node_destroy(GtkObject* object)
GanvItem* item = GANV_ITEM(object);
ganv_node_disconnect(node);
- if (item->canvas) {
- ganv_canvas_remove_node(GANV_CANVAS(item->canvas), node);
+ if (item->impl->canvas) {
+ ganv_canvas_remove_node(item->impl->canvas, node);
}
if (GTK_OBJECT_CLASS(parent_class)->destroy) {
(*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
}
- impl->partner = NULL;
- item->canvas = NULL;
+ impl->partner = NULL;
+ item->impl->canvas = NULL;
}
static void
@@ -154,21 +153,21 @@ ganv_node_set_property(GObject* object,
if (impl->selected != g_value_get_boolean(value)) {
GanvItem* item = GANV_ITEM(object);
impl->selected = g_value_get_boolean(value);
- if (item->canvas) {
+ if (item->impl->canvas) {
if (impl->selected) {
- ganv_canvas_select_node(GANV_CANVAS(item->canvas), node);
+ ganv_canvas_select_node(ganv_item_get_canvas(item), node);
} else {
- ganv_canvas_unselect_node(GANV_CANVAS(item->canvas), node);
+ ganv_canvas_unselect_node(ganv_item_get_canvas(item), node);
}
ganv_item_request_update(item);
}
}
break;
case PROP_CANVAS:
- if (!GANV_ITEM(object)->parent) {
+ if (!GANV_ITEM(object)->impl->parent) {
GanvCanvas* canvas = GANV_CANVAS(g_value_get_object(value));
g_object_set(object, "parent", ganv_canvas_root(canvas), NULL);
- ganv_canvas_add_node(GANV_CANVAS(canvas), node);
+ ganv_canvas_add_node(canvas, node);
} else {
g_warning("Cannot change `canvas' property after construction");
}
@@ -213,7 +212,7 @@ ganv_node_get_property(GObject* object,
GET_CASE(DRAGGABLE, boolean, impl->draggable);
GET_CASE(GRABBED, boolean, impl->grabbed);
case PROP_CANVAS:
- g_value_set_object(value, GANV_ITEM(object)->canvas);
+ g_value_set_object(value, ganv_item_get_canvas(GANV_ITEM(object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -229,10 +228,10 @@ ganv_node_default_tail_vector(const GanvNode* self,
double* dx,
double* dy)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(self)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(self));
- *x = GANV_ITEM(self)->x;
- *y = GANV_ITEM(self)->y;
+ *x = GANV_ITEM(self)->impl->x;
+ *y = GANV_ITEM(self)->impl->y;
switch (ganv_canvas_get_direction(canvas)) {
case GANV_DIRECTION_RIGHT:
@@ -245,7 +244,7 @@ ganv_node_default_tail_vector(const GanvNode* self,
break;
}
- ganv_item_i2w(GANV_ITEM(self)->parent, x, y);
+ ganv_item_i2w(GANV_ITEM(self)->impl->parent, x, y);
}
static void
@@ -256,10 +255,10 @@ ganv_node_default_head_vector(const GanvNode* self,
double* dx,
double* dy)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(self)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(self));
- *x = GANV_ITEM(self)->x;
- *y = GANV_ITEM(self)->y;
+ *x = GANV_ITEM(self)->impl->x;
+ *y = GANV_ITEM(self)->impl->y;
switch (ganv_canvas_get_direction(canvas)) {
case GANV_DIRECTION_RIGHT:
@@ -272,7 +271,7 @@ ganv_node_default_head_vector(const GanvNode* self,
break;
}
- ganv_item_i2w(GANV_ITEM(self)->parent, x, y);
+ ganv_item_i2w(GANV_ITEM(self)->impl->parent, x, y);
}
void
@@ -355,7 +354,7 @@ ganv_node_default_tick(GanvNode* self,
static void
ganv_node_default_disconnect(GanvNode* node)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(node));
if (canvas) {
ganv_canvas_for_each_edge_on(
canvas, node, (GanvEdgeFunc)ganv_edge_disconnect, NULL);
@@ -367,7 +366,7 @@ ganv_node_default_move(GanvNode* node,
double dx,
double dy)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(node));
ganv_item_move(GANV_ITEM(node), dx, dy);
ganv_canvas_for_each_edge_on(
canvas, node, (GanvEdgeFunc)ganv_edge_update_location, NULL);
@@ -378,7 +377,7 @@ ganv_node_default_move_to(GanvNode* node,
double x,
double y)
{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(node));
ganv_item_set(GANV_ITEM(node),
"x", x,
"y", y,
@@ -396,8 +395,8 @@ static void
ganv_node_default_resize(GanvNode* node)
{
GanvItem* item = GANV_ITEM(node);
- if (GANV_IS_NODE(item->parent)) {
- ganv_node_resize(GANV_NODE(item->parent));
+ if (GANV_IS_NODE(item->impl->parent)) {
+ ganv_node_resize(GANV_NODE(item->impl->parent));
}
}
@@ -415,7 +414,7 @@ ganv_node_default_event(GanvItem* item,
GdkEvent* event)
{
GanvNode* node = GANV_NODE(item);
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(node));
// FIXME: put these somewhere better
static double last_x, last_y;
@@ -462,8 +461,8 @@ ganv_node_default_event(GanvItem* item,
if (selected) {
ganv_canvas_selection_move_finished(canvas);
} else {
- const double x = GANV_ITEM(node)->x;
- const double y = GANV_ITEM(node)->y;
+ const double x = GANV_ITEM(node)->impl->x;
+ const double y = GANV_ITEM(node)->impl->y;
g_signal_emit(node, signal_moved, 0, x, y, NULL);
}
} else {
@@ -771,12 +770,65 @@ ganv_node_get_border_width(const GanvNode* node)
return node->impl->border_width;
}
+void
+ganv_node_set_border_width(const GanvNode* node, double border_width)
+{
+ node->impl->border_width = border_width;
+ ganv_item_request_update(GANV_ITEM(node));
+}
+
double
ganv_node_get_dash_length(const GanvNode* node)
{
return node->impl->dash_length;
}
+void
+ganv_node_set_dash_length(const GanvNode* node, double dash_length)
+{
+ node->impl->dash_length = dash_length;
+ ganv_item_request_update(GANV_ITEM(node));
+}
+
+double
+ganv_node_get_dash_offset(const GanvNode* node)
+{
+ return node->impl->dash_offset;
+}
+
+void
+ganv_node_set_dash_offset(const GanvNode* node, double dash_offset)
+{
+ node->impl->dash_offset = dash_offset;
+ ganv_item_request_update(GANV_ITEM(node));
+}
+
+guint
+ganv_node_get_fill_color(const GanvNode* node)
+{
+ return node->impl->fill_color;
+}
+
+void
+ganv_node_set_fill_color(const GanvNode* node, guint fill_color)
+{
+ node->impl->fill_color = fill_color;
+ ganv_item_request_update(GANV_ITEM(node));
+}
+
+guint
+ganv_node_get_border_color(const GanvNode* node)
+{
+ return node->impl->border_color;
+}
+
+void
+ganv_node_set_border_color(const GanvNode* node, guint border_color)
+{
+ node->impl->border_color = border_color;
+ ganv_item_request_update(GANV_ITEM(node));
+}
+
GanvNode*
ganv_node_get_partner(const GanvNode* node)
{
diff --git a/src/port.c b/src/port.c
index 2f7b2b5..f632a7a 100644
--- a/src/port.c
+++ b/src/port.c
@@ -69,7 +69,7 @@ ganv_port_destroy(GtkObject* object)
GanvItem* item = GANV_ITEM(object);
GanvPort* port = GANV_PORT(object);
- GanvCanvas* canvas = GANV_CANVAS(item->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(item);
if (canvas) {
if (port->impl->is_input) {
ganv_canvas_for_each_edge_to(
@@ -130,7 +130,7 @@ ganv_port_draw(GanvItem* item,
cairo_t* cr, double cx, double cy, double cw, double ch)
{
GanvPort* port = GANV_PORT(item);
- GanvCanvas* canvas = GANV_CANVAS(item->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(item);
// Draw Box
GanvItemClass* item_class = GANV_ITEM_CLASS(parent_class);
@@ -168,10 +168,10 @@ ganv_port_tail_vector(const GanvNode* self,
{
GanvPort* port = GANV_PORT(self);
GanvItem* item = &port->box.node.item;
- GanvCanvas* canvas = GANV_CANVAS(item->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(item);
- const double px = item->x;
- const double py = item->y;
+ const double px = item->impl->x;
+ const double py = item->impl->y;
switch (ganv_canvas_get_direction(canvas)) {
case GANV_DIRECTION_RIGHT:
@@ -188,7 +188,7 @@ ganv_port_tail_vector(const GanvNode* self,
break;
}
- ganv_item_i2w(item->parent, x, y);
+ ganv_item_i2w(item->impl->parent, x, y);
}
static void
@@ -201,10 +201,10 @@ ganv_port_head_vector(const GanvNode* self,
{
GanvPort* port = GANV_PORT(self);
GanvItem* item = &port->box.node.item;
- GanvCanvas* canvas = GANV_CANVAS(item->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(item);
- const double px = item->x;
- const double py = item->y;
+ const double px = item->impl->x;
+ const double py = item->impl->y;
switch (ganv_canvas_get_direction(canvas)) {
case GANV_DIRECTION_RIGHT:
@@ -221,7 +221,7 @@ ganv_port_head_vector(const GanvNode* self,
break;
}
- ganv_item_i2w(item->parent, x, y);
+ ganv_item_i2w(item->impl->parent, x, y);
}
static void
@@ -229,7 +229,7 @@ ganv_port_place_value_label(GanvPort* port)
{
GanvPortControl* control = port->impl->control;
if (control && control->label) {
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(port)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(port));
const double port_w = ganv_box_get_width(&port->box);
const double label_w = control->label->impl->coords.width;
if (ganv_canvas_get_direction(canvas) == GANV_DIRECTION_RIGHT) {
@@ -327,7 +327,7 @@ ganv_port_set_height(GanvBox* box,
static gboolean
ganv_port_event(GanvItem* item, GdkEvent* event)
{
- GanvCanvas* canvas = GANV_CANVAS(item->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(item);
return ganv_canvas_port_event(canvas, GANV_PORT(item), event);
}
@@ -414,7 +414,7 @@ ganv_port_new(GanvModule* module,
node->impl->draggable = FALSE;
node->impl->border_width = 1.0;
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(port)->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(port));
ganv_port_set_direction(port, ganv_canvas_get_direction(canvas));
return port;
@@ -633,7 +633,7 @@ ganv_port_set_control_max(GanvPort* port,
double
ganv_port_get_natural_width(const GanvPort* port)
{
- GanvCanvas* const canvas = GANV_CANVAS(GANV_ITEM(port)->canvas);
+ GanvCanvas* const canvas = ganv_item_get_canvas(GANV_ITEM(port));
GanvText* const label = port->box.node.impl->label;
double w = 0.0;
if (ganv_canvas_get_direction(canvas) == GANV_DIRECTION_DOWN) {
@@ -658,7 +658,7 @@ ganv_port_get_natural_width(const GanvPort* port)
GanvModule*
ganv_port_get_module(const GanvPort* port)
{
- return GANV_MODULE(GANV_ITEM(port)->parent);
+ return GANV_MODULE(GANV_ITEM(port)->impl->parent);
}
float
diff --git a/src/text.c b/src/text.c
index c36aefa..39df696 100644
--- a/src/text.c
+++ b/src/text.c
@@ -90,7 +90,7 @@ ganv_text_layout(GanvText* text)
{
GanvTextImpl* impl = text->impl;
GanvItem* item = GANV_ITEM(text);
- GanvCanvas* canvas = GANV_CANVAS(item->canvas);
+ GanvCanvas* canvas = ganv_item_get_canvas(item);
GtkWidget* widget = GTK_WIDGET(canvas);
double font_size = ganv_canvas_get_font_size(canvas);
guint color = 0xFFFFFFFF;
@@ -164,8 +164,8 @@ ganv_text_set_property(GObject* object,
free(impl->text);
impl->text = g_value_dup_string(value);
impl->needs_layout = TRUE;
- if (GANV_IS_NODE(GANV_ITEM(text)->parent)) {
- ganv_node_resize(GANV_NODE(GANV_ITEM(text)->parent));
+ if (GANV_IS_NODE(GANV_ITEM(text)->impl->parent)) {
+ ganv_node_resize(GANV_NODE(GANV_ITEM(text)->impl->parent));
}
break;
default:
@@ -236,11 +236,11 @@ ganv_text_update(GanvItem* item, int flags)
parent_class->update(item, flags);
// Update world-relative bounding box
- ganv_text_bounds(item, &item->x1, &item->y1, &item->x2, &item->y2);
- ganv_item_i2w_pair(item, &item->x1, &item->y1, &item->x2, &item->y2);
+ ganv_text_bounds(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
+ ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
ganv_canvas_request_redraw_w(
- item->canvas, item->x1, item->y1, item->x2, item->y2);
+ item->impl->canvas, item->impl->x1, item->impl->y1, item->impl->x2, item->impl->y2);
}
static double
diff --git a/src/widget.c b/src/widget.c
index ca391d6..0702ca5 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -45,27 +45,30 @@ enum {
static void
ganv_widget_init(GanvWidget* witem)
{
- witem->x = 0.0;
- witem->y = 0.0;
- witem->width = 0.0;
- witem->height = 0.0;
- witem->anchor = GTK_ANCHOR_NW;
- witem->size_pixels = FALSE;
+ GanvWidgetImpl* impl = G_TYPE_INSTANCE_GET_PRIVATE(
+ witem, GANV_TYPE_WIDGET, GanvWidgetImpl);
+
+ witem->impl = impl;
+ witem->impl->x = 0.0;
+ witem->impl->y = 0.0;
+ witem->impl->width = 0.0;
+ witem->impl->height = 0.0;
+ witem->impl->anchor = GTK_ANCHOR_NW;
+ witem->impl->size_pixels = FALSE;
}
static void
ganv_widget_destroy(GtkObject* object)
{
-
g_return_if_fail(object != NULL);
g_return_if_fail(GANV_IS_WIDGET(object));
GanvWidget* witem = GANV_WIDGET(object);
- if (witem->widget && !witem->in_destroy) {
- g_signal_handler_disconnect(witem->widget, witem->destroy_id);
- gtk_widget_destroy(witem->widget);
- witem->widget = NULL;
+ if (witem->impl->widget && !witem->impl->in_destroy) {
+ g_signal_handler_disconnect(witem->impl->widget, witem->impl->destroy_id);
+ gtk_widget_destroy(witem->impl->widget);
+ witem->impl->widget = NULL;
}
if (GTK_OBJECT_CLASS(parent_class)->destroy) {
@@ -80,44 +83,44 @@ recalc_bounds(GanvWidget* witem)
/* Get world coordinates */
- double wx = witem->x;
- double wy = witem->y;
+ double wx = witem->impl->x;
+ double wy = witem->impl->y;
ganv_item_i2w(item, &wx, &wy);
/* Get canvas pixel coordinates */
- ganv_canvas_w2c(item->canvas, wx, wy, &witem->cx, &witem->cy);
+ ganv_canvas_w2c(item->impl->canvas, wx, wy, &witem->impl->cx, &witem->impl->cy);
/* Anchor widget item */
- switch (witem->anchor) {
+ switch (witem->impl->anchor) {
case GTK_ANCHOR_N:
case GTK_ANCHOR_CENTER:
case GTK_ANCHOR_S:
- witem->cx -= witem->cwidth / 2;
+ witem->impl->cx -= witem->impl->cwidth / 2;
break;
case GTK_ANCHOR_NE:
case GTK_ANCHOR_E:
case GTK_ANCHOR_SE:
- witem->cx -= witem->cwidth;
+ witem->impl->cx -= witem->impl->cwidth;
break;
default:
break;
}
- switch (witem->anchor) {
+ switch (witem->impl->anchor) {
case GTK_ANCHOR_W:
case GTK_ANCHOR_CENTER:
case GTK_ANCHOR_E:
- witem->cy -= witem->cheight / 2;
+ witem->impl->cy -= witem->impl->cheight / 2;
break;
case GTK_ANCHOR_SW:
case GTK_ANCHOR_S:
case GTK_ANCHOR_SE:
- witem->cy -= witem->cheight;
+ witem->impl->cy -= witem->impl->cheight;
break;
default:
@@ -126,17 +129,17 @@ recalc_bounds(GanvWidget* witem)
/* Bounds */
- item->x1 = witem->cx;
- item->y1 = witem->cy;
- item->x2 = witem->cx + witem->cwidth;
- item->y2 = witem->cy + witem->cheight;
+ item->impl->x1 = witem->impl->cx;
+ item->impl->y1 = witem->impl->cy;
+ item->impl->x2 = witem->impl->cx + witem->impl->cwidth;
+ item->impl->y2 = witem->impl->cy + witem->impl->cheight;
int zoom_xofs, zoom_yofs;
- ganv_canvas_get_zoom_offsets(item->canvas, &zoom_xofs, &zoom_yofs);
- if (witem->widget) {
- gtk_layout_move(GTK_LAYOUT(item->canvas), witem->widget,
- witem->cx + zoom_xofs,
- witem->cy + zoom_yofs);
+ ganv_canvas_get_zoom_offsets(item->impl->canvas, &zoom_xofs, &zoom_yofs);
+ if (witem->impl->widget) {
+ gtk_layout_move(GTK_LAYOUT(item->impl->canvas), witem->impl->widget,
+ witem->impl->cx + zoom_xofs,
+ witem->impl->cy + zoom_yofs);
}
}
@@ -145,7 +148,7 @@ do_destroy(GtkObject* object, gpointer data)
{
GanvWidget* witem = GANV_WIDGET(data);
- witem->in_destroy = TRUE;
+ witem->impl->in_destroy = TRUE;
gtk_object_destroy(GTK_OBJECT(data));
}
@@ -163,66 +166,66 @@ ganv_widget_set_property(GObject* object,
switch (param_id) {
case PROP_WIDGET:
- if (witem->widget) {
- g_signal_handler_disconnect(witem->widget, witem->destroy_id);
- gtk_container_remove(GTK_CONTAINER(item->canvas), witem->widget);
+ if (witem->impl->widget) {
+ g_signal_handler_disconnect(witem->impl->widget, witem->impl->destroy_id);
+ gtk_container_remove(GTK_CONTAINER(item->impl->canvas), witem->impl->widget);
}
obj = (GObject*)g_value_get_object(value);
if (obj) {
- witem->widget = GTK_WIDGET(obj);
- witem->destroy_id = g_signal_connect(obj, "destroy",
+ witem->impl->widget = GTK_WIDGET(obj);
+ witem->impl->destroy_id = g_signal_connect(obj, "destroy",
G_CALLBACK(do_destroy),
witem);
int zoom_xofs, zoom_yofs;
- ganv_canvas_get_zoom_offsets(item->canvas, &zoom_xofs, &zoom_yofs);
+ ganv_canvas_get_zoom_offsets(item->impl->canvas, &zoom_xofs, &zoom_yofs);
- gtk_layout_put(GTK_LAYOUT(item->canvas), witem->widget,
- witem->cx + zoom_xofs,
- witem->cy + zoom_yofs);
+ gtk_layout_put(GTK_LAYOUT(item->impl->canvas), witem->impl->widget,
+ witem->impl->cx + zoom_xofs,
+ witem->impl->cy + zoom_yofs);
}
update = TRUE;
break;
case PROP_X:
- if (witem->x != g_value_get_double(value)) {
- witem->x = g_value_get_double(value);
+ if (witem->impl->x != g_value_get_double(value)) {
+ witem->impl->x = g_value_get_double(value);
calc_bounds = TRUE;
}
break;
case PROP_Y:
- if (witem->y != g_value_get_double(value)) {
- witem->y = g_value_get_double(value);
+ if (witem->impl->y != g_value_get_double(value)) {
+ witem->impl->y = g_value_get_double(value);
calc_bounds = TRUE;
}
break;
case PROP_WIDTH:
- if (witem->width != fabs(g_value_get_double(value))) {
- witem->width = fabs(g_value_get_double(value));
+ if (witem->impl->width != fabs(g_value_get_double(value))) {
+ witem->impl->width = fabs(g_value_get_double(value));
update = TRUE;
}
break;
case PROP_HEIGHT:
- if (witem->height != fabs(g_value_get_double(value))) {
- witem->height = fabs(g_value_get_double(value));
+ if (witem->impl->height != fabs(g_value_get_double(value))) {
+ witem->impl->height = fabs(g_value_get_double(value));
update = TRUE;
}
break;
case PROP_ANCHOR:
- if (witem->anchor != (GtkAnchorType)g_value_get_enum(value)) {
- witem->anchor = g_value_get_enum(value);
+ if (witem->impl->anchor != (GtkAnchorType)g_value_get_enum(value)) {
+ witem->impl->anchor = g_value_get_enum(value);
update = TRUE;
}
break;
case PROP_SIZE_PIXELS:
- if (witem->size_pixels != g_value_get_boolean(value)) {
- witem->size_pixels = g_value_get_boolean(value);
+ if (witem->impl->size_pixels != g_value_get_boolean(value)) {
+ witem->impl->size_pixels = g_value_get_boolean(value);
update = TRUE;
}
break;
@@ -254,31 +257,31 @@ ganv_widget_get_property(GObject* object,
switch (param_id) {
case PROP_WIDGET:
- g_value_set_object(value, (GObject*)witem->widget);
+ g_value_set_object(value, (GObject*)witem->impl->widget);
break;
case PROP_X:
- g_value_set_double(value, witem->x);
+ g_value_set_double(value, witem->impl->x);
break;
case PROP_Y:
- g_value_set_double(value, witem->y);
+ g_value_set_double(value, witem->impl->y);
break;
case PROP_WIDTH:
- g_value_set_double(value, witem->width);
+ g_value_set_double(value, witem->impl->width);
break;
case PROP_HEIGHT:
- g_value_set_double(value, witem->height);
+ g_value_set_double(value, witem->impl->height);
break;
case PROP_ANCHOR:
- g_value_set_enum(value, witem->anchor);
+ g_value_set_enum(value, witem->impl->anchor);
break;
case PROP_SIZE_PIXELS:
- g_value_set_boolean(value, witem->size_pixels);
+ g_value_set_boolean(value, witem->impl->size_pixels);
break;
default:
@@ -296,20 +299,20 @@ ganv_widget_update(GanvItem* item, int flags)
(*parent_class->update)(item, flags);
}
- if (witem->widget) {
- const double pixels_per_unit = ganv_canvas_get_zoom(item->canvas);
- if (witem->size_pixels) {
- witem->cwidth = (int)(witem->width + 0.5);
- witem->cheight = (int)(witem->height + 0.5);
+ if (witem->impl->widget) {
+ const double pixels_per_unit = ganv_canvas_get_zoom(item->impl->canvas);
+ if (witem->impl->size_pixels) {
+ witem->impl->cwidth = (int)(witem->impl->width + 0.5);
+ witem->impl->cheight = (int)(witem->impl->height + 0.5);
} else {
- witem->cwidth = (int)(witem->width * pixels_per_unit + 0.5);
- witem->cheight = (int)(witem->height * pixels_per_unit + 0.5);
+ witem->impl->cwidth = (int)(witem->impl->width * pixels_per_unit + 0.5);
+ witem->impl->cheight = (int)(witem->impl->height * pixels_per_unit + 0.5);
}
- gtk_widget_set_size_request(witem->widget, witem->cwidth, witem->cheight);
+ gtk_widget_set_size_request(witem->impl->widget, witem->impl->cwidth, witem->impl->cheight);
} else {
- witem->cwidth = 0.0;
- witem->cheight = 0.0;
+ witem->impl->cwidth = 0.0;
+ witem->impl->cheight = 0.0;
}
recalc_bounds(witem);
@@ -321,8 +324,8 @@ ganv_widget_draw(GanvItem* item,
{
GanvWidget* witem = GANV_WIDGET(item);
- if (witem->widget) {
- gtk_widget_queue_draw(witem->widget);
+ if (witem->impl->widget) {
+ gtk_widget_queue_draw(witem->impl->widget);
}
}
@@ -334,12 +337,12 @@ ganv_widget_point(GanvItem* item, double x, double y, GanvItem** actual_item)
*actual_item = item;
double x1, y1;
- ganv_canvas_c2w(item->canvas, witem->cx, witem->cy, &x1, &y1);
+ ganv_canvas_c2w(item->impl->canvas, witem->impl->cx, witem->impl->cy, &x1, &y1);
- const double pixels_per_unit = ganv_canvas_get_zoom(item->canvas);
+ const double pixels_per_unit = ganv_canvas_get_zoom(item->impl->canvas);
- double x2 = x1 + (witem->cwidth - 1) / pixels_per_unit;
- double y2 = y1 + (witem->cheight - 1) / pixels_per_unit;
+ double x2 = x1 + (witem->impl->cwidth - 1) / pixels_per_unit;
+ double y2 = y1 + (witem->impl->cheight - 1) / pixels_per_unit;
/* Is point inside widget bounds? */
@@ -375,10 +378,10 @@ ganv_widget_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y
{
GanvWidget* witem = GANV_WIDGET(item);
- *x1 = witem->x;
- *y1 = witem->y;
+ *x1 = witem->impl->x;
+ *y1 = witem->impl->y;
- switch (witem->anchor) {
+ switch (witem->impl->anchor) {
case GTK_ANCHOR_NW:
case GTK_ANCHOR_W:
case GTK_ANCHOR_SW:
@@ -387,20 +390,20 @@ ganv_widget_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y
case GTK_ANCHOR_N:
case GTK_ANCHOR_CENTER:
case GTK_ANCHOR_S:
- *x1 -= witem->width / 2.0;
+ *x1 -= witem->impl->width / 2.0;
break;
case GTK_ANCHOR_NE:
case GTK_ANCHOR_E:
case GTK_ANCHOR_SE:
- *x1 -= witem->width;
+ *x1 -= witem->impl->width;
break;
default:
break;
}
- switch (witem->anchor) {
+ switch (witem->impl->anchor) {
case GTK_ANCHOR_NW:
case GTK_ANCHOR_N:
case GTK_ANCHOR_NE:
@@ -409,21 +412,21 @@ ganv_widget_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y
case GTK_ANCHOR_W:
case GTK_ANCHOR_CENTER:
case GTK_ANCHOR_E:
- *y1 -= witem->height / 2.0;
+ *y1 -= witem->impl->height / 2.0;
break;
case GTK_ANCHOR_SW:
case GTK_ANCHOR_S:
case GTK_ANCHOR_SE:
- *y1 -= witem->height;
+ *y1 -= witem->impl->height;
break;
default:
break;
}
- *x2 = *x1 + witem->width;
- *y2 = *y1 + witem->height;
+ *x2 = *x1 + witem->impl->width;
+ *y2 = *y1 + witem->impl->height;
}
static void
@@ -435,6 +438,8 @@ ganv_widget_class_init(GanvWidgetClass* klass)
parent_class = g_type_class_peek_parent(klass);
+ g_type_class_add_private(klass, sizeof(GanvWidgetImpl));
+
gobject_class->set_property = ganv_widget_set_property;
gobject_class->get_property = ganv_widget_get_property;