From 65b14544b89afc3a7d3a7de57e6ef15ca8165bd0 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 26 Apr 2014 16:49:15 +0000 Subject: Clean up Ganv API. git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@5367 a436a847-0d15-0410-975c-d299462d15a1 --- src/Canvas.cpp | 169 +++++++++++++++++++++++---------------------------- src/boilerplate.h | 2 +- src/box.c | 6 +- src/circle.c | 71 +++++++++++++++------- src/edge.c | 62 +++++++++++-------- src/ganv-private.h | 91 ++++++++++++++++++++++++++-- src/group.c | 93 ++++++++++++++-------------- src/item.c | 130 ++++++++++++++++++++++------------------ src/module.c | 14 ++--- src/node.c | 108 ++++++++++++++++++++++++--------- src/port.c | 30 +++++----- src/text.c | 12 ++-- src/widget.c | 173 +++++++++++++++++++++++++++-------------------------- 13 files changed, 572 insertions(+), 389 deletions(-) (limited to 'src') 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, ®.pos.x, ®.pos.y, ®.area.x, ®.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 @@ -60,15 +60,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, @@ -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 { @@ -198,10 +275,6 @@ void 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); @@ -270,6 +343,9 @@ 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); @@ -277,6 +353,9 @@ 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; -- cgit v1.2.1