From 9a602080e545965b97c22926b010963ebb6a4350 Mon Sep 17 00:00:00 2001 From: Philip Schaten Date: Wed, 24 Jan 2024 17:56:57 +0100 Subject: [PATCH] Remove implicit callback chains from gtk_ui Some program logic in view relies on callbacks triggering other callbacks in the UI framework. To allow swapping the UI framework, this commit splits up one such chain. --- src/gtk_ui.c | 79 ++++++++++++++++++++++++---------------------------- src/gtk_ui.h | 3 +- src/view.c | 37 ++++++++++++++++-------- src/view.h | 10 ++++--- 4 files changed, 70 insertions(+), 59 deletions(-) diff --git a/src/gtk_ui.c b/src/gtk_ui.c index 04cbf77..cb35c46 100644 --- a/src/gtk_ui.c +++ b/src/gtk_ui.c @@ -66,18 +66,10 @@ extern gboolean fit_callback(GtkWidget* /*widget*/, gpointer data) if (!flag) return FALSE; - double aniso = gtk_adjustment_get_value(v->ui->gtk_aniso); - GtkAllocation alloc; gtk_widget_get_allocation(v->ui->gtk_viewport, &alloc); - double xz = (double)(alloc.width - 5) / (double)view_get_dims(v)[v->settings.xdim]; - double yz = (double)(alloc.height - 5) / (double)view_get_dims(v)[v->settings.ydim]; - - - if (yz > xz / aniso) - yz = xz / aniso; // aniso - gtk_adjustment_set_value(v->ui->gtk_zoom, yz); + view_fit(v, alloc.width, alloc.height); return FALSE; } @@ -91,27 +83,20 @@ extern gboolean geom_callback(GtkWidget* /*widget*/, gpointer data) { struct view_s* v = data; - struct view_ui_geom_params_s gp; - - gp.N = DIMS; - gp.selected = malloc(sizeof(bool[DIMS])); - for (int j = 0; j < DIMS; j++) { v->settings.pos[j] = gtk_adjustment_get_value(v->ui->gtk_posall[j]); - gp.selected[j] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(v->ui->gtk_checkall[j])); + v->ui_params.selected[j] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(v->ui->gtk_checkall[j])); } - gp.zoom = gtk_adjustment_get_value(v->ui->gtk_zoom); - gp.aniso = gtk_adjustment_get_value(v->ui->gtk_aniso); + v->ui_params.zoom = gtk_adjustment_get_value(v->ui->gtk_zoom); + v->ui_params.aniso = gtk_adjustment_get_value(v->ui->gtk_aniso); v->settings.flip = gtk_combo_box_get_active(v->ui->gtk_flip); v->settings.interpolation = gtk_combo_box_get_active(v->ui->gtk_interp); - gp.transpose = gtk_toggle_tool_button_get_active(v->ui->gtk_transpose); - - view_set_geom(v, gp); + v->ui_params.transpose = gtk_toggle_tool_button_get_active(v->ui->gtk_transpose); - free(gp.selected); + view_set_geom(v); return FALSE; } @@ -252,6 +237,7 @@ extern gboolean window_close(GtkWidget* /*widget*/, GdkEvent* /*event*/, gpointe { struct view_s* v = data; + free(v->ui_params.selected); view_window_close(v); return FALSE; @@ -342,27 +328,6 @@ void ui_rgbbuffer_connect(struct view_s* v, int rgbw, int rgbh, int rgbstr, unsi v->ui->source = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_RGB24, rgbw, rgbh, rgbstr); } -void ui_set_selected_dims(struct view_s* v, const bool* selected) -{ - // Avoid calling this function from itself. - // Toggling the GTK_TOOGLE_BUTTONs below would normally lead to another call of this function. - static bool in_callback = false; - if (in_callback) - return; - - in_callback = true; - - for (int i = 0; i < DIMS; i++) { - - if (selected[i]) - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v->ui->gtk_checkall[i]), TRUE); - else - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v->ui->gtk_checkall[i]), FALSE); - } - - in_callback = false; -} - void ui_pull_geom(struct view_s* v) { geom_callback(NULL, v); @@ -398,6 +363,11 @@ void ui_set_msg(struct view_s* v, const char* msg) void ui_window_new(struct view_s* v, int N, const long dims[N]) { v->ui = xmalloc(sizeof(struct view_gtk_ui_s)); + v->ui_params.selected = xmalloc(sizeof(bool[DIMS])); + + for (int i = 0; i < DIMS; i++) + v->ui_params.selected[i] = (i == v->settings.xdim || i == v->settings.ydim) ? true : false; + v->ui->source = NULL; GtkBuilder* builder = gtk_builder_new(); @@ -515,3 +485,28 @@ void ui_set_position(struct view_s* v, unsigned int dim, unsigned int p) if (v->sync && v2->sync) gtk_adjustment_set_value(v2->ui->gtk_posall[dim], p); } + +void ui_set_params(struct view_s* v) +{ + // Avoid calling this function from itself. + // Toggling the GTK_TOOGLE_BUTTONs below would normally lead to another call of this function. + static bool in_callback = false; + if (in_callback) + return; + + in_callback = true; + + double zoom = gtk_adjustment_get_value(v->ui->gtk_zoom); + if (zoom != v->ui_params.zoom) + gtk_adjustment_set_value(v->ui->gtk_zoom, v->ui_params.zoom); + + for (int j = 0; j < DIMS; j++) { + + bool selected = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(v->ui->gtk_checkall[j])); + + if (selected != v->ui_params.selected[j]) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v->ui->gtk_checkall[j]), v->ui_params.selected[j] ? TRUE : FALSE); + } + + in_callback = false; +} diff --git a/src/gtk_ui.h b/src/gtk_ui.h index c19a1ad..5606a98 100644 --- a/src/gtk_ui.h +++ b/src/gtk_ui.h @@ -7,8 +7,6 @@ struct view_s; extern void ui_rgbbuffer_disconnect(struct view_s* v); extern void ui_rgbbuffer_connect(struct view_s* v, int rgbw, int rgbh, int rgbstr, unsigned char* buf); -extern void ui_set_selected_dims(struct view_s* v, const bool* selected); - extern void ui_set_position(struct view_s* v, unsigned int dim, unsigned int p); extern void ui_set_limits(struct view_s* v); @@ -19,6 +17,7 @@ extern void ui_set_mode(struct view_s* v); extern void ui_set_msg(struct view_s* v, const char* msg); +void ui_set_params(struct view_s* v); extern void ui_window_new(struct view_s* v, int N, const long dims[N]); diff --git a/src/view.c b/src/view.c index 6f3592f..3e19f30 100644 --- a/src/view.c +++ b/src/view.c @@ -198,29 +198,29 @@ void view_add_geometry(struct view_s* v, unsigned long flags, const float (*geom } -void view_set_geom(struct view_s* v, struct view_ui_geom_params_s gp) +void view_set_geom(struct view_s* v) { for (int j = 0; j < DIMS; j++) { - if (!gp.selected[j]) + if (!v->ui_params.selected[j]) continue; if (1 == v->control->dims[j]) { - gp.selected[j] = false; + v->ui_params.selected[j] = false; } else if ((j != v->settings.xdim) && (j != v->settings.ydim)) { for (int i = 0; i < DIMS; i++) { if (v->settings.xdim == (DIMS + j - i) % DIMS) { - gp.selected[v->settings.xdim] = false; + v->ui_params.selected[v->settings.xdim] = false; v->settings.xdim = j; break; } if (v->settings.ydim == (DIMS + j - i) % DIMS) { - gp.selected[v->settings.ydim] = false; + v->ui_params.selected[v->settings.ydim] = false; v->settings.ydim = j; break; } @@ -229,15 +229,15 @@ void view_set_geom(struct view_s* v, struct view_ui_geom_params_s gp) } } - gp.selected[v->settings.xdim] = true; - gp.selected[v->settings.ydim] = true; + v->ui_params.selected[v->settings.xdim] = true; + v->ui_params.selected[v->settings.ydim] = true; - ui_set_selected_dims(v, gp.selected); + ui_set_params(v); - v->settings.xzoom = gp.zoom * gp.aniso; - v->settings.yzoom = gp.zoom; + v->settings.xzoom = v->ui_params.zoom * v->ui_params.aniso; + v->settings.yzoom = v->ui_params.zoom; - if (gp.transpose) { + if (v->ui_params.transpose) { if (v->settings.xdim < v->settings.ydim) { @@ -484,6 +484,8 @@ struct view_s* create_view(const char* name, const long pos[DIMS], const long di struct view_s* v = xmalloc(sizeof(struct view_s)); v->control = xmalloc(sizeof(struct view_control_s)); v->ui = NULL; + v->ui_params.selected = NULL; + v->settings.pos = NULL; v->next = v->prev = v; v->sync = true; @@ -698,3 +700,16 @@ const long *view_get_dims(struct view_s* v) { return v->control->dims; } + +void view_fit(struct view_s* v, int width, int height) +{ + double xz = (double)(width - 5) / (double)v->control->dims[v->settings.xdim]; + double yz = (double)(height - 5) / (double)v->control->dims[v->settings.ydim]; + + if (yz > xz / v->ui_params.aniso) + yz = xz / v->ui_params.aniso; // aniso + + v->ui_params.zoom = yz; + + view_set_geom(v); +} diff --git a/src/view.h b/src/view.h index a27541d..b8c7ef5 100644 --- a/src/view.h +++ b/src/view.h @@ -37,20 +37,20 @@ struct view_settings_s { enum interp_t interpolation; }; -struct view_ui_geom_params_s { - int N; +struct view_ui_params_s { bool* selected; double zoom; double aniso; bool transpose; - }; + struct view_s { const char* name; struct view_settings_s settings; + struct view_ui_params_s ui_params; struct view_control_s* control; struct view_gtk_ui_s* ui; @@ -93,8 +93,10 @@ extern void view_toggle_absolute_windowing(struct view_s* v); extern void view_window_close(struct view_s* v); +extern void view_fit(struct view_s* v, int width, int height); + // -extern void view_set_geom(struct view_s* v, struct view_ui_geom_params_s gp); +extern void view_set_geom(struct view_s* v); extern void view_refresh(struct view_s* v); extern void view_redraw(struct view_s* v);