From 5d76af2d7ca46e58e0802dcb12d6acff2475561c Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 28 May 2012 12:15:15 -0300 Subject: [PATCH] make variable type changes also commit the value (name) being edited This streamlines the workflow. --- gui_frame.c | 3 +- gui_frame.h | 2 - gui_status.c | 156 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 94 insertions(+), 67 deletions(-) diff --git a/gui_frame.c b/gui_frame.c index e16a264..fe892e2 100644 --- a/gui_frame.c +++ b/gui_frame.c @@ -572,7 +572,7 @@ static void add_sep(GtkWidget *box, int size) /* ----- variable name editor ---------------------------------------------- */ -int find_var_in_frame(const struct frame *frame, const char *name, +static int find_var_in_frame(const struct frame *frame, const char *name, const struct var *self) { const struct table *table; @@ -668,7 +668,6 @@ static void set_col_values(void *user, const struct value *values, void reselect_var(struct var *var) { - edit_var(var, set_col_values, var, -1); } diff --git a/gui_frame.h b/gui_frame.h index 7d0f3a7..0b54f43 100644 --- a/gui_frame.h +++ b/gui_frame.h @@ -22,8 +22,6 @@ extern int show_vars; -int find_var_in_frame(const struct frame *frame, const char *name, - const struct var *self); void reselect_var(struct var *var); void make_popups(void); diff --git a/gui_status.c b/gui_status.c index 28feb41..05d92e0 100644 --- a/gui_status.c +++ b/gui_status.c @@ -174,7 +174,6 @@ void status_set_angle_xy(const char *tooltip, struct coord v) status_set_angle(tooltip, "a = 0 deg"); else status_set_angle(tooltip, "a = %3.1f deg", theta_vec(v)); - } @@ -187,59 +186,6 @@ static void entry_color(GtkWidget *widget, const char *color) } -/* ----- variable type display and change ---------------------------------- */ - - -static struct var *curr_var; -static GtkWidget *var_type; - - -static void show_var_type(void) -{ - gtk_label_set_text(GTK_LABEL(var_type), - curr_var->key ? "key" : "assign"); -} - - -static gboolean var_type_button_press_event(GtkWidget *widget, - GdkEventButton *event, gpointer data) -{ - switch (event->button) { - case 1: - if (curr_var->key && - find_var_in_frame(curr_var->frame, curr_var->name, - curr_var)) - return TRUE; - curr_var->key = !curr_var->key; - show_var_type(); - break; - } - /* - * We can't just redraw() here, because changing the variable type may - * also affect lots of other things. So we change the world and hope - * we end up selecting the same variable afterwards. - */ - change_world(); - reselect_var(curr_var); - return TRUE; -} - - -void edit_var_type(struct var *var) -{ - vacate_widget(status_box_x); - curr_var = var; - var_type = label_in_box_new(NULL, "Variable type. Click to cycle."); - gtk_container_add(GTK_CONTAINER(status_box_x), box_of_label(var_type)); - label_in_box_bg(var_type, COLOR_SELECTOR); - g_signal_connect(G_OBJECT(box_of_label(var_type)), - "button_press_event", G_CALLBACK(var_type_button_press_event), - NULL); - show_var_type(); - gtk_widget_show_all(status_box_x); -} - - /* ----- pad type display and change --------------------------------------- */ @@ -503,22 +449,30 @@ struct edit_unique_with_values_ctx { }; -static enum edit_status unique_with_values_status(const char *s, void *ctx) +static int unique_with_values_check(const char *s, + const struct edit_unique_with_values_ctx *unique_ctx) { - const struct edit_unique_with_values_ctx *unique_ctx = ctx; const char *id; struct value *values; int n; - if (!strcmp(s, *unique_ctx->s)) - return es_unchanged; status_begin_reporting(); n = parse_var(s, &id, &values, unique_ctx->max_values); if (n < 0) - return es_bad; + return 0; free_values(values, 0); - return !unique_ctx->validate || - unique_ctx->validate(id, unique_ctx->ctx) ? es_good : es_bad; + return unique_ctx->validate ? + unique_ctx->validate(id, unique_ctx->ctx) : 0; +} + + +static enum edit_status unique_with_values_status(const char *s, void *ctx) +{ + const struct edit_unique_with_values_ctx *unique_ctx = ctx; + + if (!strcmp(s, *unique_ctx->s)) + return es_unchanged; + return unique_with_values_check(s, unique_ctx) ? es_good : es_bad; } @@ -565,6 +519,76 @@ void edit_unique_with_values(const char **s, } +/* ----- variable type display and change ---------------------------------- */ + + +static struct var *curr_var; +static GtkWidget *var_type; + + +static void show_var_type(void) +{ + gtk_label_set_text(GTK_LABEL(var_type), + curr_var->key ? "key" : "assign"); +} + + +/* + * This is a bit of a layering violation. Note that we can't just try to + * activate the edit and see what happens, because unique_with_values_status + * would unconditionally accept the previous value, even if it is no longer + * acceptable after the type change. + */ + +static int attempt_var_type_change(struct var *var) +{ + const struct edit_unique_with_values_ctx *ctx; + const char *s; + + ctx = gtk_object_get_data(GTK_OBJECT(status_entry), "edit-ctx"); + s = gtk_entry_get_text(GTK_ENTRY(status_entry)); + var->key = !var->key; + if (unique_with_values_check(s, ctx)) + return 1; + var->key = !var->key; + return 0; +} + + +static gboolean do_activate(void); + + +static gboolean var_type_button_press_event(GtkWidget *widget, + GdkEventButton *event, gpointer data) +{ + switch (event->button) { + case 1: + if (!attempt_var_type_change(curr_var)) + return TRUE; + /* commit edit and change_world() */ + do_activate(); + reselect_var(curr_var); + return TRUE; + } + return TRUE; +} + + +void edit_var_type(struct var *var) +{ + vacate_widget(status_box_x); + curr_var = var; + var_type = label_in_box_new(NULL, "Variable type. Click to cycle."); + gtk_container_add(GTK_CONTAINER(status_box_x), box_of_label(var_type)); + label_in_box_bg(var_type, COLOR_SELECTOR); + g_signal_connect(G_OBJECT(box_of_label(var_type)), + "button_press_event", G_CALLBACK(var_type_button_press_event), + NULL); + show_var_type(); + gtk_widget_show_all(status_box_x); +} + + /* ----- string fields ----------------------------------------------------- */ @@ -849,8 +873,7 @@ static gboolean changed(GtkWidget *widget, GdkEventMotion *event, } -static gboolean activate(GtkWidget *widget, GdkEventMotion *event, - gpointer data) +static gboolean do_activate(void) { GtkWidget *edit; enum edit_status status; @@ -880,6 +903,13 @@ static gboolean activate(GtkWidget *widget, GdkEventMotion *event, } +static gboolean activate(GtkWidget *widget, GdkEventMotion *event, + gpointer data) +{ + return do_activate(); +} + + void edit_nothing(void) { gtk_widget_hide(status_entry);