summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-02-03 22:29:15 +0000
committerDavid Robillard <d@drobilla.net>2013-02-03 22:29:15 +0000
commit6ddaa0260c4749aa6c0395000381d7df0bd3feb1 (patch)
tree00024d5d970317292355b663383b43d151c6757b
parent39b748a4836d6220922867eae0dd5339792033ab (diff)
downloadganv-6ddaa0260c4749aa6c0395000381d7df0bd3feb1.tar.gz
ganv-6ddaa0260c4749aa6c0395000381d7df0bd3feb1.tar.bz2
ganv-6ddaa0260c4749aa6c0395000381d7df0bd3feb1.zip
Port control performance improvements (further improvement for #879).
Only request a redraw, not a full update, where appropriate. Use a raw double instead of GVariant for port control-changed signal. git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@5045 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--ganv/Port.hpp2
-rw-r--r--src/Canvas.cpp6
-rw-r--r--src/Port.cpp2
-rw-r--r--src/box.c12
-rw-r--r--src/edge.c6
-rw-r--r--src/ganv-private.h13
-rw-r--r--src/ganv_test.c6
-rw-r--r--src/port.c90
8 files changed, 76 insertions, 61 deletions
diff --git a/ganv/Port.hpp b/ganv/Port.hpp
index ac1a5f9..431742b 100644
--- a/ganv/Port.hpp
+++ b/ganv/Port.hpp
@@ -62,7 +62,7 @@ public:
METHOD1(ganv_port, set_control_max, float, max)
METHOD1(ganv_port, set_value_label, const char*, str);
- sigc::signal<void, GVariant*> signal_value_changed;
+ sigc::signal<void, double> signal_value_changed;
Module* get_module() const;
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
index 37a99f9..f55d1d8 100644
--- a/src/Canvas.cpp
+++ b/src/Canvas.cpp
@@ -1163,9 +1163,9 @@ GanvCanvasImpl::port_event(GdkEvent* event, GanvPort* port)
if (module && port->impl->is_input && port->impl->control) {
if (port->impl->control->is_toggle) {
if (port->impl->control->value >= 0.5) {
- ganv_port_set_control_value(port, 0.0);
+ ganv_port_set_control_value_internal(port, 0.0);
} else {
- ganv_port_set_control_value(port, 1.0);
+ ganv_port_set_control_value_internal(port, 1.0);
}
} else {
control_dragging = port_pressed = true;
@@ -1231,7 +1231,7 @@ GanvCanvasImpl::port_event(GdkEvent* event, GanvPort* port)
} else if (value > port->impl->control->max) {
value = port->impl->control->max;
}
- ganv_port_set_control_value(port, value);
+ ganv_port_set_control_value_internal(port, value);
return true;
}
break;
diff --git a/src/Port.cpp b/src/Port.cpp
index 0791f3c..e94f16d 100644
--- a/src/Port.cpp
+++ b/src/Port.cpp
@@ -26,7 +26,7 @@
namespace Ganv {
static void
-on_value_changed(GanvPort* port, GVariant* value, void* portmm)
+on_value_changed(GanvPort* port, double value, void* portmm)
{
((Port*)portmm)->signal_value_changed.emit(value);
}
diff --git a/src/box.c b/src/box.c
index c41f5ed..9ad67b5 100644
--- a/src/box.c
+++ b/src/box.c
@@ -145,10 +145,10 @@ ganv_box_bounds_item(const GanvBoxCoords* coords,
}
}
-static void
-request_redraw(GanvItem* item,
- const GanvBoxCoords* coords,
- gboolean world)
+void
+ganv_box_request_redraw(GanvItem* item,
+ const GanvBoxCoords* coords,
+ gboolean world)
{
double x1, y1, x2, y2;
ganv_box_bounds_item(coords, &x1, &y1, &x2, &y2);
@@ -189,7 +189,7 @@ ganv_box_update(GanvItem* item, int flags)
impl->coords.border_width = box->node.impl->border_width;
// Request redraw of old location
- request_redraw(item, &impl->old_coords, TRUE);
+ ganv_box_request_redraw(item, &impl->old_coords, TRUE);
GanvItemClass* item_class = GANV_ITEM_CLASS(parent_class);
item_class->update(item, flags);
@@ -208,7 +208,7 @@ ganv_box_update(GanvItem* item, int flags)
ganv_canvas_base_w2c_d(GANV_CANVAS_BASE(item->canvas), x2, y2, &item->x2, &item->y2);
// Request redraw of new location
- request_redraw(item, &impl->coords, FALSE);
+ ganv_box_request_redraw(item, &impl->coords, FALSE);
}
static void
diff --git a/src/edge.c b/src/edge.c
index 326931d..7838564 100644
--- a/src/edge.c
+++ b/src/edge.c
@@ -647,16 +647,14 @@ void
ganv_edge_highlight(GanvEdge* edge)
{
edge->impl->highlighted = TRUE;
- ganv_item_raise(GANV_ITEM(edge));
- ganv_item_request_update(GANV_ITEM(edge));
+ ganv_edge_request_redraw(GANV_ITEM(edge)->canvas, &edge->impl->coords);
}
void
ganv_edge_unhighlight(GanvEdge* edge)
{
edge->impl->highlighted = FALSE;
- ganv_item_lower(GANV_ITEM(edge));
- ganv_item_request_update(GANV_ITEM(edge));
+ ganv_edge_request_redraw(GANV_ITEM(edge)->canvas, &edge->impl->coords);
}
void
diff --git a/src/ganv-private.h b/src/ganv-private.h
index 85ed1ab..d9d81df 100644
--- a/src/ganv-private.h
+++ b/src/ganv-private.h
@@ -199,6 +199,19 @@ void
ganv_edge_request_redraw(GanvCanvasBase* canvas,
const GanvEdgeCoords* coords);
+/* Box */
+
+void
+ganv_box_request_redraw(GanvItem* item,
+ const GanvBoxCoords* coords,
+ gboolean world);
+
+/* Port */
+
+void
+ganv_port_set_control_value_internal(GanvPort* port,
+ float value);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/src/ganv_test.c b/src/ganv_test.c
index 31359e2..bb50e0c 100644
--- a/src/ganv_test.c
+++ b/src/ganv_test.c
@@ -36,11 +36,9 @@ on_disconnect(GanvCanvas* canvas, GanvNode* tail, GanvNode* head, void* data)
}
static void
-on_value_changed(GanvPort* port, GVariant* value, void* data)
+on_value_changed(GanvPort* port, double value, void* data)
{
- char* str = g_variant_print(value, TRUE);
- fprintf(stderr, "Value changed: port %p = %s\n", (void*)port, str);
- g_free(str);
+ fprintf(stderr, "Value changed: port %p = %lf\n", (void*)port, value);
}
int
diff --git a/src/port.c b/src/port.c
index 5780571..3bc300e 100644
--- a/src/port.c
+++ b/src/port.c
@@ -354,7 +354,7 @@ ganv_port_class_init(GanvPortClass* klass)
NULL, NULL,
NULL,
G_TYPE_NONE, 1,
- G_TYPE_VARIANT);
+ G_TYPE_DOUBLE);
object_class->destroy = ganv_port_destroy;
@@ -497,26 +497,6 @@ ganv_port_set_value_label(GanvPort* port,
}
}
-void
-ganv_port_set_control_is_toggle(GanvPort* port,
- gboolean is_toggle)
-{
- if (port->impl->control) {
- port->impl->control->is_toggle = is_toggle;
- ganv_port_set_control_value(port, port->impl->control->value);
- }
-}
-
-void
-ganv_port_set_control_is_integer(GanvPort* port,
- gboolean is_integer)
-{
- if (port->impl->control) {
- port->impl->control->is_integer = is_integer;
- ganv_port_set_control_value(port, lrintf(port->impl->control->value));
- }
-}
-
static void
ganv_port_update_control_slider(GanvPort* port,
float value)
@@ -526,6 +506,7 @@ ganv_port_update_control_slider(GanvPort* port,
return;
}
+ // Clamp to toggle or integer value if applicable
if (impl->control->is_toggle) {
if (value != 0.0f) {
value = impl->control->max;
@@ -536,43 +517,51 @@ ganv_port_update_control_slider(GanvPort* port,
value = lrintf(value);
}
+ // Clamp to range
if (value < impl->control->min) {
- impl->control->min = value;
+ value = impl->control->min;
}
if (value > impl->control->max) {
- impl->control->max = value;
- }
-
- if (impl->control->max == impl->control->min) {
- impl->control->max = impl->control->min + 1.0f;
- }
-
- const int inf = isinf(value);
- if (inf == -1) {
- value = impl->control->min;
- } else if (inf == 1) {
value = impl->control->max;
}
+
+ if (value == impl->control->value) {
+ return; // No change, do nothing
+ }
const double w = (value - impl->control->min)
/ (impl->control->max - impl->control->min)
* ganv_box_get_width(&port->box);
if (isnan(w)) {
- return;
+ return; // Shouldn't happen, but ignore crazy values
}
+ // Redraw port
+ impl->control->value = value;
ganv_box_set_width(impl->control->rect, MAX(0.0, w - 1.0));
+ ganv_box_request_redraw(
+ GANV_ITEM(port), &GANV_BOX(port)->impl->coords, FALSE);
+}
- if (impl->control->value != value) {
- GVariant* gvar = g_variant_ref_sink(g_variant_new_double(value));
- g_signal_emit(port, port_signals[PORT_VALUE_CHANGED], 0, gvar, NULL);
- g_variant_unref(gvar);
+void
+ganv_port_set_control_is_toggle(GanvPort* port,
+ gboolean is_toggle)
+{
+ if (port->impl->control) {
+ port->impl->control->is_toggle = is_toggle;
+ ganv_port_update_control_slider(port, port->impl->control->value);
}
+}
- impl->control->value = value;
-
- ganv_item_request_update(GANV_ITEM(port));
+void
+ganv_port_set_control_is_integer(GanvPort* port,
+ gboolean is_integer)
+{
+ if (port->impl->control) {
+ port->impl->control->is_integer = is_integer;
+ ganv_port_update_control_slider(port, lrintf(port->impl->control->value));
+ }
}
void
@@ -585,16 +574,30 @@ ganv_port_set_control_value(GanvPort* port,
ganv_port_set_value_label(
port, (const char*)((value == 0.0f) ? check_off : check_on));
}
-
ganv_port_update_control_slider(port, value);
}
void
+ganv_port_set_control_value_internal(GanvPort* port,
+ float value)
+{
+ // Update slider
+ ganv_port_set_control_value(port, value);
+
+ // Fire signal to notify user value has changed
+ const double dvalue = value;
+ g_signal_emit(port, port_signals[PORT_VALUE_CHANGED], 0, dvalue, NULL);
+}
+
+void
ganv_port_set_control_min(GanvPort* port,
float min)
{
if (port->impl->control) {
port->impl->control->min = min;
+ if (port->impl->control->max < min) {
+ port->impl->control->max = min;
+ }
ganv_port_update_control_slider(port, port->impl->control->value);
}
}
@@ -605,6 +608,9 @@ ganv_port_set_control_max(GanvPort* port,
{
if (port->impl->control) {
port->impl->control->max = max;
+ if (port->impl->control->min > max) {
+ port->impl->control->min = max;
+ }
ganv_port_update_control_slider(port, port->impl->control->value);
}
}