From 34141b09492f461b1d3d78aaf662a91ced94c39b Mon Sep 17 00:00:00 2001 From: Philip Schaten Date: Thu, 25 Jan 2024 17:04:39 +0100 Subject: [PATCH] Remove program logic from gtk_ui.c To be able to easily switch UI backends, the UI implementation should contain as few "application logic" as possible. --- src/gtk_ui.c | 104 ++++++++++++++++++--------------------------------- src/gtk_ui.h | 10 +---- src/view.c | 52 +++++++++++++++----------- src/view.h | 21 +++++------ 4 files changed, 78 insertions(+), 109 deletions(-) diff --git a/src/gtk_ui.c b/src/gtk_ui.c index 5d1b1d6..7d59c61 100644 --- a/src/gtk_ui.c +++ b/src/gtk_ui.c @@ -10,6 +10,8 @@ #include #include +#include + #include "gtk_ui.h" #include "view.h" @@ -54,6 +56,8 @@ struct view_gtk_ui_s { GtkWidget *dialog; // Save dialog GtkFileChooser *chooser; // Save dialog GtkWindow *window; + + atomic_flag in_callback; }; @@ -221,6 +225,19 @@ extern gboolean motion_callback(GtkWidget* /*widget*/, GdkEventMotion *event, gp return FALSE; } +extern gboolean click_callback(GtkWidget* /*widget*/, GdkEventButton *event, gpointer data) +{ + struct view_s* v = data; + + if (event->button == GDK_BUTTON_PRIMARY) + view_click(v, event->x, event->y, 1); + + if (event->button == GDK_BUTTON_SECONDARY) + view_click(v, event->x, event->y, 2); + + return FALSE; +} + extern gboolean show_hide_callback(GtkWidget *widget, GtkCheckButton* button) { gboolean flag = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(button)); @@ -269,8 +286,6 @@ extern gboolean toggle_sync_callback(GtkToggleButton* /*button*/, gpointer data) extern gboolean toggle_plot_callback(GtkToggleButton* /*button*/, gpointer data) { struct view_s* v = data; - v->settings.plot = !v->settings.plot; - view_toggle_plot(v); return FALSE; @@ -288,19 +303,6 @@ extern gboolean toogle_absolute_windowing_callback(GtkToggleToolButton* button, return FALSE; } -extern gboolean click_callback(GtkWidget* /*widget*/, GdkEventButton *event, gpointer data) -{ - struct view_s* v = data; - - if (event->button == GDK_BUTTON_PRIMARY) - view_click(v, event->x, event->y, 1); - - if (event->button == GDK_BUTTON_SECONDARY) - view_click(v, event->x, event->y, 2); - - return FALSE; -} - void ui_trigger_redraw(struct view_s* v) @@ -330,23 +332,6 @@ void ui_pull_window(struct view_s* v) window_callback(NULL, v); } -void ui_set_limits(struct view_s* v) -{ - gtk_adjustment_set_upper(v->ui->gtk_winhigh, v->win_high_max); - gtk_adjustment_set_upper(v->ui->gtk_winlow, v->win_low_max); -} - -void ui_set_values(struct view_s* v) -{ - gtk_adjustment_set_value(v->ui->gtk_winlow, v->settings.winlow); - gtk_adjustment_set_value(v->ui->gtk_winhigh, v->settings.winhigh); -} - -void ui_set_mode(struct view_s* v) -{ - gtk_combo_box_set_active(v->ui->gtk_mode, v->settings.mode); -} - void ui_set_msg(struct view_s* v, const char* msg) { gtk_entry_set_text(v->ui->gtk_entry, msg); @@ -360,6 +345,8 @@ void ui_window_new(struct view_s* v, int N, const long dims[N]) for (int i = 0; i < DIMS; i++) v->ui_params.selected[i] = (i == v->settings.xdim || i == v->settings.ydim) ? true : false; + atomic_flag_clear(&v->ui->in_callback); + v->ui->source = NULL; GtkBuilder* builder = gtk_builder_new(); @@ -454,43 +441,12 @@ bool gtk_ui_save_png(struct view_s* v, const char* filename) return false; } -void ui_set_windowing(struct view_s* v, double max, double inc, int digits) -{ - gtk_adjustment_configure(v->ui->gtk_winhigh, v->settings.winhigh, 0, max, inc, gtk_adjustment_get_page_increment(v->ui->gtk_winhigh), gtk_adjustment_get_page_size(v->ui->gtk_winhigh)); - gtk_adjustment_configure(v->ui->gtk_winlow, v->settings.winlow, 0, max, inc, gtk_adjustment_get_page_increment(v->ui->gtk_winlow), gtk_adjustment_get_page_size(v->ui->gtk_winlow)); - gtk_spin_button_set_digits(v->ui->gtk_button_winhigh, digits); - gtk_spin_button_set_digits(v->ui->gtk_button_winlow, digits); - - gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_scale1), v->settings.absolute_windowing ? FALSE : TRUE); - gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_scale2), v->settings.absolute_windowing ? FALSE : TRUE); - gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_button1), v->settings.absolute_windowing ? TRUE : FALSE); - gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_button2), v->settings.absolute_windowing ? TRUE : FALSE); -} - -void ui_set_position(struct view_s* v, unsigned int dim, unsigned int p) -{ - v->settings.pos[dim] = p; - - gtk_adjustment_set_value(v->ui->gtk_posall[dim], p); - - for (struct view_s* v2 = v->next; v2 != v; v2 = v2->next) - 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) + if (!atomic_flag_test_and_set(&v->ui->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); + gtk_adjustment_set_value(v->ui->gtk_zoom, v->ui_params.zoom); for (int j = 0; j < DIMS; j++) { @@ -498,10 +454,24 @@ void ui_set_params(struct view_s* v) 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; + gtk_adjustment_set_value(v->ui->gtk_posall[j], v->settings.pos[j]); + } gtk_widget_set_sensitive(GTK_WIDGET(v->ui->gtk_mode), v->settings.plot ? FALSE : TRUE); + + gtk_combo_box_set_active(v->ui->gtk_mode, v->settings.mode); + + gtk_adjustment_configure(v->ui->gtk_winhigh, v->settings.winhigh, 0, v->ui_params.windowing_max, v->ui_params.windowing_inc, gtk_adjustment_get_page_increment(v->ui->gtk_winhigh), gtk_adjustment_get_page_size(v->ui->gtk_winhigh)); + gtk_adjustment_configure(v->ui->gtk_winlow, v->settings.winlow, 0, v->ui_params.windowing_max, v->ui_params.windowing_inc, gtk_adjustment_get_page_increment(v->ui->gtk_winlow), gtk_adjustment_get_page_size(v->ui->gtk_winlow)); + gtk_spin_button_set_digits(v->ui->gtk_button_winhigh, v->ui_params.windowing_digits); + gtk_spin_button_set_digits(v->ui->gtk_button_winlow, v->ui_params.windowing_digits); + + gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_scale1), v->settings.absolute_windowing ? FALSE : TRUE); + gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_scale2), v->settings.absolute_windowing ? FALSE : TRUE); + gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_button1), v->settings.absolute_windowing ? TRUE : FALSE); + gtk_widget_set_visible(GTK_WIDGET(v->ui->toolbar_button2), v->settings.absolute_windowing ? TRUE : FALSE); + + atomic_flag_clear(&v->ui->in_callback); } diff --git a/src/gtk_ui.h b/src/gtk_ui.h index 5606a98..ea84f57 100644 --- a/src/gtk_ui.h +++ b/src/gtk_ui.h @@ -7,18 +7,10 @@ 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_position(struct view_s* v, unsigned int dim, unsigned int p); - -extern void ui_set_limits(struct view_s* v); -extern void ui_set_values(struct view_s* v); -extern void ui_set_windowing(struct view_s* v, double max, double inc, int digits); - -extern void ui_set_mode(struct view_s* v); +void ui_set_params(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]); extern void ui_main(); diff --git a/src/view.c b/src/view.c index b63e05e..01a774f 100644 --- a/src/view.c +++ b/src/view.c @@ -105,7 +105,7 @@ void update_geom(struct view_s* v) (*v->control->geom_current)[2][0], (*v->control->geom_current)[2][1], (*v->control->geom_current)[2][2]); } -void view_sync_windowing(struct view_s* v) +void view_sync(struct view_s* v) { for (struct view_s* v2 = v->next; v2 != v; v2 = v2->next) { @@ -115,8 +115,7 @@ void view_sync_windowing(struct view_s* v) v2->settings.mode = v->settings.mode; v2->settings.winlow = v->settings.winlow; v2->settings.winhigh= v->settings.winhigh; - ui_set_values(v2); - ui_set_mode(v2); + ui_set_params(v2); } } } @@ -150,23 +149,16 @@ void view_refresh(struct view_s* v) if (0 == v->control->max) { - v->win_high_max = max; - v->win_low_max = max; v->settings.winhigh = max; v->control->max = max; - - ui_set_limits(v); - ui_set_values(v); } - if (v->control->max < max) { - - v->win_high_max = max; - v->win_low_max = max; + if (v->control->max < max) v->control->max = max; - ui_set_limits(v); - } + v->ui_params.windowing_max = v->control->max; + ui_set_params(v); + } else { long size = md_calc_size(DIMS, v->control->dims); @@ -266,7 +258,7 @@ void view_geom(struct view_s* v) void view_window(struct view_s* v) { - view_sync_windowing(v); + view_sync(v); v->rgb_invalid = true; ui_trigger_redraw(v); @@ -485,7 +477,9 @@ struct view_s* create_view(const char* name, const long pos[DIMS], const long di v->control = xmalloc(sizeof(struct view_control_s)); v->ui = NULL; v->ui_params.selected = NULL; + v->ui_params.windowing_max = v->control->max; v->settings.pos = NULL; + v->settings.mode = 0; v->next = v->prev = v; v->sync = true; @@ -552,9 +546,11 @@ static void view_set_windowing(struct view_s* v) { double max = v->settings.absolute_windowing ? v->control->max : 1; max = MIN(1.e10, max); - double inc = exp(log(10) * round(log(max) / log(10.))) * 0.001; - int digits = MAX(3, 3 - (int)round(log(max) / log(10.))); - ui_set_windowing(v, max, inc, digits); + v->ui_params.windowing_max = max; + v->ui_params.windowing_inc = exp(log(10) * round(log(max) / log(10.))) * 0.001; + v->ui_params.windowing_digits = MAX(3, 3 - (int)round(log(max) / log(10.))); + + ui_set_params(v); } void view_toggle_absolute_windowing(struct view_s* v) @@ -588,6 +584,17 @@ void view_toggle_absolute_windowing(struct view_s* v) view_set_windowing(v); } +static void view_set_position(struct view_s* v, float pos[DIMS]) +{ + v->settings.pos[v->settings.xdim] = pos[v->settings.xdim]; + v->settings.pos[v->settings.ydim] = pos[v->settings.ydim]; + for (int i = 0; i < DIMS; i++) + printf("%ld ", v->settings.pos[i]); + printf("\n"); + ui_set_params(v); + view_sync(v); +} + void view_click(struct view_s* v, int x, int y, int button) { struct xy_s xy = { x, y }; @@ -610,8 +617,7 @@ void view_click(struct view_s* v, int x, int y, int button) v->settings.cross_hair = true; v->control->status_bar = true; - ui_set_position(v, v->settings.xdim, pos[v->settings.xdim]); - ui_set_position(v, v->settings.ydim, pos[v->settings.ydim]); + view_set_position(v, pos); } } @@ -638,8 +644,8 @@ void view_motion(struct view_s* v, int x, int y, double inc_low, double inc_high v->settings.winlow = low; v->settings.winhigh = high; - ui_set_values(v); - view_sync_windowing(v); + ui_set_params(v); + view_sync(v); } } @@ -714,6 +720,8 @@ void view_fit(struct view_s* v, int width, int height) void view_toggle_plot(struct view_s* v) { + v->settings.plot = !v->settings.plot; + v->invalid = true; ui_set_params(v); ui_trigger_redraw(v); diff --git a/src/view.h b/src/view.h index 5b56b87..e093798 100644 --- a/src/view.h +++ b/src/view.h @@ -44,6 +44,11 @@ struct view_ui_params_s { double aniso; bool transpose; + + int windowing_digits; + double windowing_max; + double windowing_inc; + }; @@ -62,10 +67,6 @@ struct view_s { struct view_s* next; struct view_s* prev; bool sync; - - // shared state (owned by controller) - double win_high_max; - double win_low_max; }; @@ -82,23 +83,21 @@ extern void view_geom(struct view_s* v); extern void view_refresh(struct view_s* v); extern void view_window(struct view_s* v); +extern void view_draw(struct view_s* v); + extern bool view_save_png(struct view_s* v, const char *filename); extern bool view_save_pngmovie(struct view_s* v, const char *folder); extern void view_motion(struct view_s* v, int x, int y, double inc_low, double inc_high, int button); -extern struct view_s* view_window_clone(struct view_s* v, const long pos[DIMS]); - -extern void view_draw(struct view_s* v); +extern void view_click(struct view_s* v, int x, int y, int button); extern void view_toggle_plot(struct view_s* v); +extern void view_toggle_absolute_windowing(struct view_s* v); extern void view_add_geometry(struct view_s* v, unsigned long flags, const float (*geom)[3][3]); -extern void view_click(struct view_s* v, int x, int y, int button); - - -extern void view_toggle_absolute_windowing(struct view_s* v); +extern struct view_s* view_window_clone(struct view_s* v, const long pos[DIMS]); extern void view_window_close(struct view_s* v);