summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-12-18 22:10:22 +0000
committerDavid Robillard <d@drobilla.net>2013-12-18 22:10:22 +0000
commit730f7d88ff1c86872cdcf289dd2b72a845fb8449 (patch)
treedc897c0e5c009ed7c26fa76bf625306654d71f38 /src
parent0b6320b122e546f873cc8d8f3a90f8c5b97a423e (diff)
downloadganv-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.cpp52
-rw-r--r--src/fdgl.hpp6
-rw-r--r--src/node.c1
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;
diff --git a/src/node.c b/src/node.c
index 77791ba..af487c2 100644
--- a/src/node.c
+++ b/src/node.c
@@ -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) {