aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devel.but10
-rw-r--r--gtk.c80
-rw-r--r--midend.c29
-rw-r--r--puzzles.h1
4 files changed, 115 insertions, 5 deletions
diff --git a/devel.but b/devel.but
index 1df57cf..e481ec6 100644
--- a/devel.but
+++ b/devel.but
@@ -2728,6 +2728,16 @@ are owned by the mid-end structure: the front end should not ever
free them directly, because they will be freed automatically during
\cw{midend_free()}.
+\H{midend-which-preset} \cw{midend_which_preset()}
+
+\c int midend_which_preset(midend *me);
+
+Returns the numeric index of the preset game parameter structure
+which matches the current game parameters, or a negative number if
+no preset matches. Front ends could use this to maintain a tick
+beside one of the items in the menu (or tick the \q{Custom} option
+if the return value is less than zero).
+
\H{midend-wants-statusbar} \cw{midend_wants_statusbar()}
\c int midend_wants_statusbar(midend *me);
diff --git a/gtk.c b/gtk.c
index c7713a1..1f991d6 100644
--- a/gtk.c
+++ b/gtk.c
@@ -79,6 +79,8 @@ void fatal(char *fmt, ...)
* GTK front end to puzzles.
*/
+static void update_preset_tick(frontend *fe);
+
struct font {
#ifdef USE_PANGO
PangoFontDescription *desc;
@@ -122,6 +124,9 @@ struct frontend {
int pw, ph; /* pixmap size (w, h are area size) */
int ox, oy; /* offset of pixmap in drawing area */
char *filesel_name;
+ int npresets;
+ GtkWidget **preset_bullets;
+ GtkWidget *preset_custom_bullet;
};
void get_random_seed(void **randseed, int *randseedsize)
@@ -844,6 +849,7 @@ static void config_ok_button_clicked(GtkButton *button, gpointer data)
else {
fe->cfgret = TRUE;
gtk_widget_destroy(fe->cfgbox);
+ update_preset_tick(fe);
}
}
@@ -1100,6 +1106,29 @@ static void get_size(frontend *fe, int *px, int *py)
gdk_window_resize(GTK_WIDGET(win)->window, x, y)
#endif
+static void update_menuitem_bullet(GtkWidget *label, int visible)
+{
+ if (visible) {
+ gtk_label_set_text(GTK_LABEL(label), "\xE2\x80\xA2");
+ } else {
+ gtk_label_set_text(GTK_LABEL(label), "");
+ }
+}
+
+static void update_preset_tick(frontend *fe)
+{
+ int n = midend_which_preset(fe->me);
+ int i;
+
+ if (fe->preset_bullets) {
+ for (i = 0; i < fe->npresets; i++)
+ update_menuitem_bullet(fe->preset_bullets[i], n == i);
+ }
+ if (fe->preset_custom_bullet) {
+ update_menuitem_bullet(fe->preset_custom_bullet, n < 0);
+ }
+}
+
static void resize_fe(frontend *fe)
{
int x, y;
@@ -1129,6 +1158,7 @@ static void menu_preset_event(GtkMenuItem *menuitem, gpointer data)
midend_set_params(fe->me, params);
midend_new_game(fe->me);
+ update_preset_tick(fe);
resize_fe(fe);
}
@@ -1358,6 +1388,7 @@ static void menu_load_event(GtkMenuItem *menuitem, gpointer data)
return;
}
+ update_preset_tick(fe);
resize_fe(fe);
}
}
@@ -1448,6 +1479,34 @@ static void add_menu_separator(GtkContainer *cont)
enum { ARG_EITHER, ARG_SAVE, ARG_ID }; /* for argtype */
+static GtkWidget *make_preset_menuitem(GtkWidget **bulletlabel,
+ const char *name)
+{
+ GtkWidget *hbox, *lab1, *lab2, *menuitem;
+ GtkRequisition req;
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(hbox);
+ lab1 = gtk_label_new("\xE2\x80\xA2 ");
+ gtk_widget_show(lab1);
+ gtk_box_pack_start(GTK_BOX(hbox), lab1, FALSE, FALSE, 0);
+ gtk_misc_set_alignment(GTK_MISC(lab1), 0.0, 0.0);
+ lab2 = gtk_label_new(name);
+ gtk_widget_show(lab2);
+ gtk_box_pack_start(GTK_BOX(hbox), lab2, TRUE, TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(lab2), 0.0, 0.0);
+
+ gtk_widget_size_request(lab1, &req);
+ gtk_widget_set_usize(lab1, req.width, -1);
+ gtk_label_set_text(GTK_LABEL(lab1), "");
+
+ menuitem = gtk_menu_item_new();
+ gtk_container_add(GTK_CONTAINER(menuitem), hbox);
+
+ *bulletlabel = lab1;
+ return menuitem;
+}
+
static frontend *new_window(char *arg, int argtype, char **error)
{
frontend *fe;
@@ -1583,13 +1642,17 @@ static frontend *new_window(char *arg, int argtype, char **error)
submenu = gtk_menu_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
+ fe->npresets = n;
+ fe->preset_bullets = snewn(n, GtkWidget *);
+
for (i = 0; i < n; i++) {
char *name;
game_params *params;
midend_fetch_preset(fe->me, i, &name, &params);
- menuitem = gtk_menu_item_new_with_label(name);
+ menuitem = make_preset_menuitem(&fe->preset_bullets[i], name);
+
gtk_container_add(GTK_CONTAINER(submenu), menuitem);
gtk_object_set_data(GTK_OBJECT(menuitem), "user-data", params);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
@@ -1598,14 +1661,23 @@ static frontend *new_window(char *arg, int argtype, char **error)
}
if (thegame.can_configure) {
- menuitem = gtk_menu_item_new_with_label("Custom...");
+ menuitem = make_preset_menuitem(&fe->preset_custom_bullet,
+ "Custom...");
+
+ gtk_container_add(GTK_CONTAINER(submenu), menuitem);
gtk_object_set_data(GTK_OBJECT(menuitem), "user-data",
GPOINTER_TO_INT(CFG_SETTINGS));
- gtk_container_add(GTK_CONTAINER(submenu), menuitem);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
GTK_SIGNAL_FUNC(menu_config_event), fe);
gtk_widget_show(menuitem);
- }
+ } else
+ fe->preset_custom_bullet = NULL;
+
+ update_preset_tick(fe);
+ } else {
+ fe->npresets = 0;
+ fe->preset_bullets = NULL;
+ fe->preset_custom_bullet = NULL;
}
add_menu_separator(GTK_CONTAINER(menu));
diff --git a/midend.c b/midend.c
index 250a479..87df28a 100644
--- a/midend.c
+++ b/midend.c
@@ -31,7 +31,7 @@ struct midend {
const game *ourgame;
game_params **presets;
- char **preset_names;
+ char **preset_names, **preset_encodings;
int npresets, presetsize;
/*
@@ -115,6 +115,7 @@ midend *midend_new(frontend *fe, const game *ourgame,
me->oldstate = NULL;
me->presets = NULL;
me->preset_names = NULL;
+ me->preset_encodings = NULL;
me->npresets = me->presetsize = 0;
me->anim_time = me->anim_pos = 0.0F;
me->flash_time = me->flash_pos = 0.0F;
@@ -186,9 +187,11 @@ void midend_free(midend *me)
for (i = 0; i < me->npresets; i++) {
sfree(me->presets[i]);
sfree(me->preset_names[i]);
+ sfree(me->preset_encodings[i]);
}
sfree(me->presets);
sfree(me->preset_names);
+ sfree(me->preset_encodings);
}
if (me->ui)
me->ourgame->free_ui(me->ui);
@@ -836,10 +839,14 @@ int midend_num_presets(midend *me)
game_params *);
me->preset_names = sresize(me->preset_names, me->presetsize,
char *);
+ me->preset_encodings = sresize(me->preset_encodings,
+ me->presetsize, char *);
}
me->presets[me->npresets] = preset;
me->preset_names[me->npresets] = name;
+ me->preset_encodings[me->npresets] =
+ me->ourgame->encode_params(preset, TRUE);;
me->npresets++;
}
}
@@ -890,10 +897,14 @@ int midend_num_presets(midend *me)
game_params *);
me->preset_names = sresize(me->preset_names,
me->presetsize, char *);
+ me->preset_encodings = sresize(me->preset_encodings,
+ me->presetsize, char *);
}
me->presets[me->npresets] = preset;
me->preset_names[me->npresets] = dupstr(name);
+ me->preset_encodings[me->npresets] =
+ me->ourgame->encode_params(preset, TRUE);
me->npresets++;
}
}
@@ -910,6 +921,22 @@ void midend_fetch_preset(midend *me, int n,
*params = me->presets[n];
}
+int midend_which_preset(midend *me)
+{
+ char *encoding = me->ourgame->encode_params(me->params, TRUE);
+ int i, ret;
+
+ ret = -1;
+ for (i = 0; i < me->npresets; i++)
+ if (!strcmp(encoding, me->preset_encodings[i])) {
+ ret = i;
+ break;
+ }
+
+ sfree(encoding);
+ return ret;
+}
+
int midend_wants_statusbar(midend *me)
{
return me->ourgame->wants_statusbar;
diff --git a/puzzles.h b/puzzles.h
index 2a9f517..1c5342d 100644
--- a/puzzles.h
+++ b/puzzles.h
@@ -235,6 +235,7 @@ void midend_timer(midend *me, float tplus);
int midend_num_presets(midend *me);
void midend_fetch_preset(midend *me, int n,
char **name, game_params **params);
+int midend_which_preset(midend *me);
int midend_wants_statusbar(midend *me);
enum { CFG_SETTINGS, CFG_SEED, CFG_DESC, CFG_FRONTEND_SPECIFIC };
config_item *midend_get_config(midend *me, int which, char **wintitle);