greatly reduce number of comparisions required to apply parameters to GUI

This commit is contained in:
Tomasz Moń
2009-05-15 20:59:28 +02:00
parent cc85da9c71
commit 7a6e3b159c

115
gui.c
View File

@@ -24,18 +24,16 @@
typedef struct { typedef struct {
GtkObject *widget; GtkObject *widget;
gint id;
gint position;
/* used for combo boxes, if widget isn't combo box, then both value and x are -1 */ /* used for combo boxes, if widget isn't combo box, then both value and x are -1 */
gint value; /**< effect type value */ gint value; /**< effect type value */
gint x; /**< combo box item number */ gint x; /**< combo box item number */
} WidgetListElem; } WidgetTreeElem;
#ifndef DOXYGEN_SHOULD_SKIP_THIS #ifndef DOXYGEN_SHOULD_SKIP_THIS
static GtkKnobAnim *knob_anim = NULL; /* animation used by knobs */ static GtkKnobAnim *knob_anim = NULL; /* animation used by knobs */
#endif /* DOXYGEN_SHOULD_SKIP_THIS */ #endif /* DOXYGEN_SHOULD_SKIP_THIS */
static GList *widget_list = NULL; /**< this list contains WidgetListElem data elements */ static GTree *widget_tree = NULL; /**< this tree contains lists containing WidgetTreeElem data elements */
static gboolean allow_send = FALSE; /**< if FALSE GUI parameter changes won't be sent to device */ static gboolean allow_send = FALSE; /**< if FALSE GUI parameter changes won't be sent to device */
/** /**
@@ -106,46 +104,59 @@ void toggled_cb(GtkToggleButton *button, Effect *effect)
} }
/** /**
* \param widget GtkObject to add to widget list * \param widget GtkObject to add to widget tree
* \param id object controlled ID * \param id object controlled ID
* \param position object controlled position * \param position object controlled position
* \param value effect value type (if widget is GtkComboBox, otherwise -1) * \param value effect value type (if widget is GtkComboBox, otherwise -1)
* \param x combo box item number (if widget is GtkComboBox, otherwise -1) * \param x combo box item number (if widget is GtkComboBox, otherwise -1)
* *
* Adds widget to widget list. * Adds widget to widget tree.
**/ **/
static void widget_list_add(GtkObject *widget, gint id, gint position, gint value, gint x) static WidgetTreeElem *widget_tree_add(GtkObject *widget, gint id, gint position, gint value, gint x)
{ {
WidgetListElem *el; GList *list;
WidgetTreeElem *el;
gpointer key;
el = g_slice_new(WidgetListElem); el = g_slice_new(WidgetTreeElem);
el->widget = widget; el->widget = widget;
el->id = id;
el->position = position;
el->value = value; el->value = value;
el->x = x; el->x = x;
widget_list = g_list_prepend(widget_list, el); key = GINT_TO_POINTER((position << 16) | id);
list = g_tree_lookup(widget_tree, key);
if (list == NULL) {
list = g_list_append(list, el);
g_tree_insert(widget_tree, key, list);
} else {
list = g_list_append(list, el);
/* replace the list pointer */
g_tree_steal(widget_tree, key);
g_tree_insert(widget_tree, key, list);
}
return el;
} }
/** /**
* \param el widget list element * \param el widget tree element
* \param param parameter to set * \param param parameter to set
* *
* Sets widget list element value to param value. * Sets widget tree element value to param value.
**/ **/
static void apply_widget_setting(WidgetListElem *el, SettingParam *param) static void apply_widget_setting(WidgetTreeElem *el, SettingParam *param)
{ {
if ((el->id == param->id) && (el->position == param->position)) { if (el->value == -1) {
if (el->value == -1) { if (GTK_IS_TOGGLE_BUTTON(el->widget))
if (GTK_IS_TOGGLE_BUTTON(el->widget)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(el->widget), (param->value == 0) ? FALSE : TRUE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(el->widget), (param->value == 0) ? FALSE : TRUE); else if (GTK_IS_ADJUSTMENT(el->widget))
else if (GTK_IS_ADJUSTMENT(el->widget)) gtk_adjustment_set_value(GTK_ADJUSTMENT(el->widget), (gdouble)param->value);
gtk_adjustment_set_value(GTK_ADJUSTMENT(el->widget), (gdouble)param->value); } else { /* combo box */
} else { /* combo box */ if (el->value == param->value)
if (el->value == param->value) gtk_combo_box_set_active(GTK_COMBO_BOX(el->widget), el->x);
gtk_combo_box_set_active(GTK_COMBO_BOX(el->widget), el->x);
}
} }
} }
@@ -156,10 +167,13 @@ static void apply_widget_setting(WidgetListElem *el, SettingParam *param)
**/ **/
void apply_setting_param_to_gui(SettingParam *param) void apply_setting_param_to_gui(SettingParam *param)
{ {
gpointer key;
g_return_if_fail(param != NULL); g_return_if_fail(param != NULL);
allow_send = FALSE; allow_send = FALSE;
g_list_foreach(widget_list, (GFunc)apply_widget_setting, param); key = GINT_TO_POINTER((param->position << 16) | param->id);
GList *list = g_tree_lookup(widget_tree, key);
g_list_foreach(list, (GFunc)apply_widget_setting, param);
allow_send = TRUE; allow_send = TRUE;
} }
@@ -171,17 +185,22 @@ void apply_setting_param_to_gui(SettingParam *param)
static void apply_preset_to_gui(Preset *preset) static void apply_preset_to_gui(Preset *preset)
{ {
g_return_if_fail(preset != NULL); g_return_if_fail(preset != NULL);
g_return_if_fail(widget_list != NULL); g_return_if_fail(widget_tree != NULL);
allow_send = FALSE; allow_send = FALSE;
GList *iter = preset->params; GList *iter = preset->params;
while (iter) { while (iter) {
gpointer key;
SettingParam *param = iter->data; SettingParam *param = iter->data;
iter = iter->next; iter = iter->next;
if (param != NULL) if (param != NULL) {
g_list_foreach(widget_list, (GFunc)apply_widget_setting, param); key = GINT_TO_POINTER((param->position << 16) | param->id);
GList *list = g_tree_lookup(widget_tree, key);
g_list_foreach(list, (GFunc)apply_widget_setting, param);
}
} }
allow_send = TRUE; allow_send = TRUE;
@@ -245,7 +264,7 @@ GtkWidget *create_table(EffectSettings *settings, gint amt, GHashTable *widget_t
g_object_set_data(G_OBJECT(adj), "label", widget); g_object_set_data(G_OBJECT(adj), "label", widget);
} }
widget_list_add(adj, settings[x].id, settings[x].position, -1, -1); widget_tree_add(adj, settings[x].id, settings[x].position, -1, -1);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2); gtk_table_attach(GTK_TABLE(table), label, 0, 1, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
gtk_table_attach(GTK_TABLE(table), knob, 1, 2, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2); gtk_table_attach(GTK_TABLE(table), knob, 1, 2, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
gtk_table_attach(GTK_TABLE(table), widget, 2, 3, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2); gtk_table_attach(GTK_TABLE(table), widget, 2, 3, x, x+1, GTK_SHRINK, GTK_SHRINK, 2, 2);
@@ -276,7 +295,7 @@ GtkWidget *create_on_off_button(Effect *effect)
button = gtk_check_button_new_with_label(effect->label); button = gtk_check_button_new_with_label(effect->label);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(toggled_cb), effect); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(toggled_cb), effect);
widget_list_add(GTK_OBJECT(button), effect->id, effect->position, -1, -1); widget_tree_add(GTK_OBJECT(button), effect->id, effect->position, -1, -1);
return button; return button;
} }
@@ -395,7 +414,7 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p
settings->position = position; settings->position = position;
settings->child = widget; settings->child = widget;
widget_list_add(GTK_OBJECT(combo_box), id, position, group[x].type, x); widget_tree_add(GTK_OBJECT(combo_box), id, position, group[x].type, x);
name = g_strdup_printf("SettingsGroup%d", cmbox_no); name = g_strdup_printf("SettingsGroup%d", cmbox_no);
g_object_set_data_full(G_OBJECT(combo_box), name, settings, ((GDestroyNotify)effect_settings_group_free)); g_object_set_data_full(G_OBJECT(combo_box), name, settings, ((GDestroyNotify)effect_settings_group_free));
@@ -785,15 +804,15 @@ static void action_open_preset_cb(GtkAction *action)
} }
/** /**
* \param list widget list to be freed * \param list widget tree list to be freed
* *
* Frees all memory used by widget list. * Frees all memory used by widget tree list.
*/ */
static void widget_list_free(GList *list) static void widget_tree_elem_free(GList *list)
{ {
GList *iter; GList *iter;
for (iter = list; iter; iter = iter->next) { for (iter = list; iter; iter = iter->next) {
g_slice_free(WidgetListElem, iter->data); g_slice_free(WidgetTreeElem, iter->data);
} }
g_list_free(list); g_list_free(list);
} }
@@ -897,6 +916,21 @@ static void add_menubar(GtkWidget *window, GtkWidget *vbox)
g_object_unref(ui); g_object_unref(ui);
} }
static gint widget_tree_key_compare_func(gconstpointer a, gconstpointer b, gpointer data)
{
gint position_a = GPOINTER_TO_INT(a) & 0xFF0000;
gint position_b = GPOINTER_TO_INT(b) & 0xFF0000;
if (position_a > position_b) {
return 1;
} else if (position_a == position_b) {
gint val_a = GPOINTER_TO_INT(a) & 0xFFFF;
gint val_b = GPOINTER_TO_INT(b) & 0xFFFF;
return val_a - val_b;
} else
return -1;
}
/** /**
* Creates main window. * Creates main window.
**/ **/
@@ -932,6 +966,11 @@ void gui_create(Device *device)
knob_anim = gtk_knob_animation_new_from_inline(knob_pixbuf); knob_anim = gtk_knob_animation_new_from_inline(knob_pixbuf);
widget_tree = g_tree_new_full(widget_tree_key_compare_func,
NULL, /* key compare data */
NULL, /* key destroy func */
(GDestroyNotify) widget_tree_elem_free);
for (x = 0; x<device->n_effects; x++) { for (x = 0; x<device->n_effects; x++) {
if ((x % ((device->n_effects+1)/2)) == 0) { if ((x % ((device->n_effects+1)/2)) == 0) {
hbox = gtk_hbox_new(FALSE, 0); hbox = gtk_hbox_new(FALSE, 0);
@@ -952,8 +991,8 @@ void gui_create(Device *device)
**/ **/
void gui_free() void gui_free()
{ {
widget_list_free(widget_list); g_tree_destroy(widget_tree);
widget_list = NULL; widget_tree = NULL;
gtk_knob_animation_free(knob_anim); gtk_knob_animation_free(knob_anim);
knob_anim = NULL; knob_anim = NULL;