diff options
author | David Robillard <d@drobilla.net> | 2013-12-18 22:10:22 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2013-12-18 22:10:22 +0000 |
commit | 730f7d88ff1c86872cdcf289dd2b72a845fb8449 (patch) | |
tree | dc897c0e5c009ed7c26fa76bf625306654d71f38 /src | |
parent | 0b6320b122e546f873cc8d8f3a90f8c5b97a423e (diff) | |
download | ganv-730f7d88ff1c86872cdcf289dd2b72a845fb8449.tar.gz ganv-730f7d88ff1c86872cdcf289dd2b72a845fb8449.tar.bz2 ganv-730f7d88ff1c86872cdcf289dd2b72a845fb8449.zip |
FDGL: Only install layout handler as needed.
git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@5184 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r-- | src/Canvas.cpp | 52 | ||||
-rw-r--r-- | src/fdgl.hpp | 6 | ||||
-rw-r--r-- | src/node.c | 1 |
3 files changed, 43 insertions, 16 deletions
diff --git a/src/Canvas.cpp b/src/Canvas.cpp index 56c4f21..21b6255 100644 --- a/src/Canvas.cpp +++ b/src/Canvas.cpp @@ -141,20 +141,13 @@ struct GanvCanvasImpl { , _zoom(1.0) , _font_size(0.0) , _drag_state(NOT_DRAGGING) + , _layout_idle_id(0) { _wrapper_key = g_quark_from_string("ganvmm"); _move_cursor = gdk_cursor_new(GDK_FLEUR); g_signal_connect(G_OBJECT(ganv_canvas_base_root(GANV_CANVAS_BASE(_gcanvas))), "event", G_CALLBACK(on_canvas_event), this); - -#ifdef GANV_FDGL - g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, - 40, - on_timeout, - this, - NULL); -#endif } ~GanvCanvasImpl() @@ -171,11 +164,13 @@ struct GanvCanvasImpl { } #ifdef GANV_FDGL - static gboolean - on_timeout(gpointer impl) - { + static gboolean on_layout_timeout(gpointer impl) { return ((GanvCanvasImpl*)impl)->layout_iteration(); - } + } + + static void on_layout_done(gpointer impl) { + ((GanvCanvasImpl*)impl)->_layout_idle_id = 0; + } gboolean layout_iteration(); #endif @@ -185,6 +180,7 @@ struct GanvCanvasImpl { } void resize(double width, double height); + void contents_changed(); void set_zoom_and_font_size(double zoom, double points); @@ -279,6 +275,7 @@ struct GanvCanvasImpl { GQuark _wrapper_key; GdkCursor* _move_cursor; + guint _layout_idle_id; }; typedef struct { @@ -785,12 +782,13 @@ GanvCanvasImpl::layout_iteration() const Vector tpos = { edge->impl->coords.x1, edge->impl->coords.y1 }; const Vector hpos = { edge->impl->coords.x2, edge->impl->coords.y2 }; - const Vector f = vec_add(dir, spring_force(hpos, tpos, 1.0)); + const Vector f = vec_add(dir, spring_force(hpos, tpos, 0.5)); apply_force(tail, head, f); } // Update positions based on calculated forces + size_t n_moved = 0; FOREACH_ITEM(_items, i) { if (!GANV_IS_MODULE(*i) && !GANV_IS_CIRCLE(*i)) { continue; @@ -813,6 +811,7 @@ GanvCanvasImpl::layout_iteration() const Vector dpos = vec_mult(node->impl->vel, dur); if (fabs(dpos.x) >= 1.0 || fabs(dpos.y) >= 1.0) { ganv_item_move(GANV_ITEM(node), dpos.x, dpos.y); + ++n_moved; } } @@ -821,6 +820,10 @@ GanvCanvasImpl::layout_iteration() node->impl->force.y = 0.0; } + if (n_moved == 0) { + return FALSE; // Stabilized, we're done + } + // Now update edge positions to reflect new node positions FOREACH_EDGE(_edges, i) { GanvEdge* const edge = *i; @@ -841,6 +844,7 @@ GanvCanvasImpl::remove_edge(GanvEdge* edge) _dst_edges.erase(edge); ganv_edge_request_redraw(GANV_ITEM(edge)->canvas, &edge->impl->coords); gtk_object_destroy(GTK_OBJECT(edge)); + contents_changed(); } } @@ -1609,6 +1613,21 @@ GanvCanvasImpl::resize(double width, double height) } void +GanvCanvasImpl::contents_changed() +{ +#ifdef GANV_FDGL + if (!_layout_idle_id) { + _layout_idle_id = g_timeout_add_full( + G_PRIORITY_DEFAULT_IDLE, + 40, + on_layout_timeout, + this, + on_layout_done); + } +#endif +} + +void GanvCanvasImpl::set_zoom_and_font_size(double zoom, double points) { points = std::max(points, 1.0); @@ -1956,6 +1975,12 @@ ganv_canvas_resize(GanvCanvas* canvas, double width, double height) canvas->impl->resize(width, height); } +void +ganv_canvas_contents_changed(GanvCanvas* canvas) +{ + canvas->impl->contents_changed(); +} + GanvItem* ganv_canvas_get_root(const GanvCanvas* canvas) { @@ -2142,6 +2167,7 @@ ganv_canvas_add_edge(GanvCanvas* canvas, { canvas->impl->_edges.insert(edge); canvas->impl->_dst_edges.insert(edge); + canvas->impl->contents_changed(); } void diff --git a/src/fdgl.hpp b/src/fdgl.hpp index c2dac10..b28df82 100644 --- a/src/fdgl.hpp +++ b/src/fdgl.hpp @@ -16,9 +16,9 @@ #include <float.h> #include <math.h> -static const double SPRING_K = 12.0; -static const double CHARGE_KE = 80000.0; -static const double AREA_WEIGHT = 0.4; +static const double SPRING_K = 14.0; +static const double CHARGE_KE = 60000.0; +static const double AREA_WEIGHT = 0.5; struct Region { Vector pos; @@ -461,6 +461,7 @@ ganv_node_default_event(GanvItem* item, g_object_get(G_OBJECT(node), "selected", &selected, NULL); ganv_item_ungrab(GANV_ITEM(node), event->button.time); node->impl->grabbed = FALSE; + ganv_canvas_contents_changed(canvas); dragging = FALSE; if (event->button.x != drag_start_x || event->button.y != drag_start_y) { if (selected) { |