char *filesel_name;
#endif
GSList *preset_radio;
- int n_preset_menu_items;
int preset_threaded;
GtkWidget *preset_custom;
GtkWidget *copy_menu_item;
fe->image = NULL;
}
-static void wipe_and_destroy_cairo(frontend *fe, cairo_t *cr)
+static void wipe_and_maybe_destroy_cairo(frontend *fe, cairo_t *cr,
+ int destroy)
{
cairo_set_source_rgb(cr, fe->colours[0], fe->colours[1], fe->colours[2]);
cairo_paint(cr);
- cairo_destroy(cr);
+ if (destroy)
+ cairo_destroy(cr);
}
static void setup_backing_store(frontend *fe)
fe->image = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
fe->pw, fe->ph);
- wipe_and_destroy_cairo(fe, cairo_create(fe->image));
+ wipe_and_maybe_destroy_cairo(fe, cairo_create(fe->image), TRUE);
#ifndef USE_CAIRO_WITHOUT_PIXMAP
- wipe_and_destroy_cairo(fe, gdk_cairo_create(fe->pixmap));
+ wipe_and_maybe_destroy_cairo(fe, gdk_cairo_create(fe->pixmap), TRUE);
+#endif
+#if GTK_CHECK_VERSION(3,22,0)
+ {
+ GdkWindow *gdkwin;
+ cairo_region_t *region;
+ GdkDrawingContext *drawctx;
+ cairo_t *cr;
+
+ gdkwin = gtk_widget_get_window(fe->area);
+ region = gdk_window_get_clip_region(gdkwin);
+ drawctx = gdk_window_begin_draw_frame(gdkwin, region);
+ cr = gdk_drawing_context_get_cairo_context(drawctx);
+ wipe_and_maybe_destroy_cairo(fe, cr, FALSE);
+ gdk_window_end_draw_frame(gdkwin, drawctx);
+ cairo_region_destroy(region);
+ }
+#else
+ wipe_and_maybe_destroy_cairo(
+ fe, gdk_cairo_create(gtk_widget_get_window(fe->area)), TRUE);
#endif
- wipe_and_destroy_cairo(fe, gdk_cairo_create
- (gtk_widget_get_window(fe->area)));
}
static int backing_store_ok(frontend *fe)
TRUE);
} else {
GSList *gs = fe->preset_radio;
- int i = fe->n_preset_menu_items - 1 - n;
- if (fe->preset_custom)
- gs = gs->next;
- while (i && gs) {
- i--;
- gs = gs->next;
- }
- if (gs) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gs->data),
- TRUE);
- } else for (gs = fe->preset_radio; gs; gs = gs->next) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gs->data),
- FALSE);
- }
+ GSList *found = NULL;
+
+ for (gs = fe->preset_radio; gs; gs = gs->next) {
+ struct preset_menu_entry *entry =
+ (struct preset_menu_entry *)g_object_get_data(
+ G_OBJECT(gs->data), "user-data");
+
+ if (entry && entry->id != n)
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(gs->data), FALSE);
+ else
+ found = gs;
+ }
+ if (found)
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(found->data), FALSE);
}
fe->preset_threaded = FALSE;
static void menu_preset_event(GtkMenuItem *menuitem, gpointer data)
{
frontend *fe = (frontend *)data;
- game_params *params =
- (game_params *)g_object_get_data(G_OBJECT(menuitem), "user-data");
+ struct preset_menu_entry *entry =
+ (struct preset_menu_entry *)g_object_get_data(
+ G_OBJECT(menuitem), "user-data");
if (fe->preset_threaded ||
(GTK_IS_CHECK_MENU_ITEM(menuitem) &&
!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))))
return;
- midend_set_params(fe->me, params);
+ midend_set_params(fe->me, entry->params);
midend_new_game(fe->me);
changed_preset(fe);
resize_fe(fe);
gtk_widget_show(menuitem);
}
+static void populate_gtk_preset_menu(frontend *fe, struct preset_menu *menu,
+ GtkWidget *gtkmenu)
+{
+ int i;
+
+ for (i = 0; i < menu->n_entries; i++) {
+ struct preset_menu_entry *entry = &menu->entries[i];
+ GtkWidget *menuitem;
+
+ if (entry->params) {
+ menuitem = gtk_radio_menu_item_new_with_label(
+ fe->preset_radio, entry->title);
+ fe->preset_radio = gtk_radio_menu_item_get_group(
+ GTK_RADIO_MENU_ITEM(menuitem));
+ g_object_set_data(G_OBJECT(menuitem), "user-data", entry);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(menu_preset_event), fe);
+ } else {
+ GtkWidget *submenu;
+ menuitem = gtk_menu_item_new_with_label(entry->title);
+ submenu = gtk_menu_new();
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
+ populate_gtk_preset_menu(fe, entry->submenu, submenu);
+ }
+
+ gtk_container_add(GTK_CONTAINER(gtkmenu), menuitem);
+ gtk_widget_show(menuitem);
+ }
+}
+
enum { ARG_EITHER, ARG_SAVE, ARG_ID }; /* for argtype */
static frontend *new_window(char *arg, int argtype, char **error)
char errbuf[1024];
extern char *const *const xpm_icons[];
extern const int n_xpm_icons;
+ struct preset_menu *preset_menu;
fe = snew(frontend);
#if GTK_CHECK_VERSION(3,20,0)
fe->preset_radio = NULL;
fe->preset_custom = NULL;
- fe->n_preset_menu_items = 0;
fe->preset_threaded = FALSE;
- if ((n = midend_num_presets(fe->me)) > 0 || thegame.can_configure) {
+
+ preset_menu = midend_get_presets(fe->me, NULL);
+ if (preset_menu->n_entries > 0 || thegame.can_configure) {
GtkWidget *submenu;
- int i;
menuitem = gtk_menu_item_new_with_mnemonic("_Type");
gtk_container_add(GTK_CONTAINER(fe->menubar), menuitem);
submenu = gtk_menu_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
- for (i = 0; i < n; i++) {
- char *name;
- game_params *params;
-
- midend_fetch_preset(fe->me, i, &name, ¶ms);
-
- menuitem =
- gtk_radio_menu_item_new_with_label(fe->preset_radio, name);
- fe->preset_radio =
- gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
- fe->n_preset_menu_items++;
- gtk_container_add(GTK_CONTAINER(submenu), menuitem);
- g_object_set_data(G_OBJECT(menuitem), "user-data", params);
- g_signal_connect(G_OBJECT(menuitem), "activate",
- G_CALLBACK(menu_preset_event), fe);
- gtk_widget_show(menuitem);
- }
+ populate_gtk_preset_menu(fe, preset_menu, submenu);
if (thegame.can_configure) {
menuitem = fe->preset_custom =
return ret;
}
+static void list_presets_from_menu(struct preset_menu *menu)
+{
+ int i;
+
+ for (i = 0; i < menu->n_entries; i++) {
+ if (menu->entries[i].params) {
+ char *paramstr = thegame.encode_params(
+ menu->entries[i].params, TRUE);
+ printf("%s %s\n", paramstr, menu->entries[i].title);
+ sfree(paramstr);
+ } else {
+ list_presets_from_menu(menu->entries[i].submenu);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
char *pname = argv[0];
* Another specialist mode which causes the puzzle to list the
* game_params strings for all its preset configurations.
*/
- int i, npresets;
midend *me;
+ struct preset_menu *menu;
me = midend_new(NULL, &thegame, NULL, NULL);
- npresets = midend_num_presets(me);
-
- for (i = 0; i < npresets; i++) {
- game_params *params;
- char *name, *paramstr;
-
- midend_fetch_preset(me, i, &name, ¶ms);
- paramstr = thegame.encode_params(params, TRUE);
-
- printf("%s %s\n", paramstr, name);
- sfree(paramstr);
- }
-
+ menu = midend_get_presets(me, NULL);
+ list_presets_from_menu(menu);
midend_free(me);
return 0;
} else {