chiark / gitweb /
GTK 3 cleanup: use GtkAboutDialog for the About box.
[sgt-puzzles.git] / gtk.c
diff --git a/gtk.c b/gtk.c
index 4309f6dc509b407682bfdd932ca8d2d4b77b7220..78d8eaa5c4bba3e45a03c70bd0c0cff807a353f3 100644 (file)
--- a/gtk.c
+++ b/gtk.c
 # endif
 #endif
 
+#if GTK_CHECK_VERSION(3,0,0)
+/* The old names are still more concise! */
+#define gtk_hbox_new(x,y) gtk_box_new(GTK_ORIENTATION_HORIZONTAL,y)
+#define gtk_vbox_new(x,y) gtk_box_new(GTK_ORIENTATION_VERTICAL,y)
+/* GTK 3 has retired stock button labels */
+#define LABEL_OK "_OK"
+#define LABEL_CANCEL "_Cancel"
+#define LABEL_NO "_No"
+#define LABEL_YES "_Yes"
+#define LABEL_SAVE "_Save"
+#define LABEL_OPEN "_Open"
+#define gtk_button_new_with_our_label gtk_button_new_with_mnemonic
+#else
+#define LABEL_OK GTK_STOCK_OK
+#define LABEL_CANCEL GTK_STOCK_CANCEL
+#define LABEL_NO GTK_STOCK_NO
+#define LABEL_YES GTK_STOCK_YES
+#define LABEL_SAVE GTK_STOCK_SAVE
+#define LABEL_OPEN GTK_STOCK_OPEN
+#define gtk_button_new_with_our_label gtk_button_new_from_stock
+#endif
+
 /* #undef USE_CAIRO */
 /* #define NO_THICK_LINE */
 #ifdef DEBUGGING
@@ -268,6 +290,15 @@ static void set_colour(frontend *fe, int colour)
 
 static void set_window_background(frontend *fe, int colour)
 {
+#if GTK_CHECK_VERSION(3,0,0)
+    GdkRGBA rgba;
+    rgba.red = fe->colours[3*colour + 0];
+    rgba.green = fe->colours[3*colour + 1];
+    rgba.blue = fe->colours[3*colour + 2];
+    rgba.alpha = 1.0;
+    gdk_window_set_background_rgba(gtk_widget_get_window(fe->area), &rgba);
+    gdk_window_set_background_rgba(gtk_widget_get_window(fe->window), &rgba);
+#else
     GdkColormap *colmap;
 
     colmap = gdk_colormap_get_system();
@@ -283,6 +314,7 @@ static void set_window_background(frontend *fe, int colour)
                               &fe->background);
     gdk_window_set_background(gtk_widget_get_window(fe->window),
                               &fe->background);
+#endif
 }
 
 static PangoLayout *make_pango_layout(frontend *fe)
@@ -1340,18 +1372,6 @@ static void window_destroy(GtkWidget *widget, gpointer data)
     gtk_main_quit();
 }
 
-static void msgbox_button_clicked(GtkButton *button, gpointer data)
-{
-    GtkWidget *window = GTK_WIDGET(data);
-    int v, *ip;
-
-    ip = (int *)g_object_get_data(G_OBJECT(window), "user-data");
-    v = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "user-data"));
-    *ip = v;
-
-    gtk_widget_destroy(GTK_WIDGET(data));
-}
-
 static int win_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
     GObject *cancelbutton = G_OBJECT(data);
@@ -1369,6 +1389,47 @@ static int win_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
 
 enum { MB_OK, MB_YESNO };
 
+static void align_label(GtkLabel *label, double x, double y)
+{
+#if GTK_CHECK_VERSION(3,16,0)
+    gtk_label_set_xalign(label, x);
+    gtk_label_set_yalign(label, y);
+#else
+    gtk_misc_set_alignment(GTK_MISC(label), x, y);
+#endif
+}
+
+#if GTK_CHECK_VERSION(3,0,0)
+int message_box(GtkWidget *parent, char *title, char *msg, int centre,
+               int type)
+{
+    GtkWidget *window;
+    gint ret;
+
+    window = gtk_message_dialog_new
+        (GTK_WINDOW(parent),
+         (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
+         (type == MB_OK ? GTK_MESSAGE_INFO : GTK_MESSAGE_QUESTION),
+         (type == MB_OK ? GTK_BUTTONS_OK   : GTK_BUTTONS_YES_NO),
+         "%s", msg);
+    gtk_window_set_title(GTK_WINDOW(window), title);
+    ret = gtk_dialog_run(GTK_DIALOG(window));
+    gtk_widget_destroy(window);
+    return (type == MB_OK ? TRUE : (ret == GTK_RESPONSE_YES));
+}
+#else /* GTK_CHECK_VERSION(3,0,0) */
+static void msgbox_button_clicked(GtkButton *button, gpointer data)
+{
+    GtkWidget *window = GTK_WIDGET(data);
+    int v, *ip;
+
+    ip = (int *)g_object_get_data(G_OBJECT(window), "user-data");
+    v = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "user-data"));
+    *ip = v;
+
+    gtk_widget_destroy(GTK_WIDGET(data));
+}
+
 int message_box(GtkWidget *parent, char *title, char *msg, int centre,
                int type)
 {
@@ -1378,7 +1439,7 @@ int message_box(GtkWidget *parent, char *title, char *msg, int centre,
 
     window = gtk_dialog_new();
     text = gtk_label_new(msg);
-    gtk_misc_set_alignment(GTK_MISC(text), 0.0, 0.0);
+    align_label(GTK_LABEL(text), 0.0, 0.0);
     hbox = gtk_hbox_new(FALSE, 0);
     gtk_box_pack_start(GTK_BOX(hbox), text, FALSE, FALSE, 20);
     gtk_box_pack_start
@@ -1390,18 +1451,18 @@ int message_box(GtkWidget *parent, char *title, char *msg, int centre,
     gtk_label_set_line_wrap(GTK_LABEL(text), TRUE);
 
     if (type == MB_OK) {
-       titles = GTK_STOCK_OK "\0";
+       titles = LABEL_OK "\0";
        def = cancel = 0;
     } else {
        assert(type == MB_YESNO);
-       titles = GTK_STOCK_NO "\0" GTK_STOCK_YES "\0";
+       titles = LABEL_NO "\0" LABEL_YES "\0";
        def = 1;
        cancel = 0;
     }
     i = 0;
     
     while (*titles) {
-       button = gtk_button_new_from_stock(titles);
+       button = gtk_button_new_with_our_label(titles);
        gtk_box_pack_end
             (GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(window))),
              button, FALSE, FALSE, 0);
@@ -1432,6 +1493,7 @@ int message_box(GtkWidget *parent, char *title, char *msg, int centre,
     gtk_main();
     return (type == MB_YESNO ? i == 1 : TRUE);
 }
+#endif /* GTK_CHECK_VERSION(3,0,0) */
 
 void error_box(GtkWidget *parent, char *msg)
 {
@@ -1520,7 +1582,7 @@ static int get_config(frontend *fe, int which)
     gtk_window_set_title(GTK_WINDOW(fe->cfgbox), title);
     sfree(title);
 
-    w = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+    w = gtk_button_new_with_our_label(LABEL_CANCEL);
     gtk_box_pack_end
         (GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(fe->cfgbox))),
          w, FALSE, FALSE, 0);
@@ -1529,7 +1591,7 @@ static int get_config(frontend *fe, int which)
                      G_CALLBACK(config_cancel_button_clicked), fe);
     cancel = w;
 
-    w = gtk_button_new_from_stock(GTK_STOCK_OK);
+    w = gtk_button_new_with_our_label(LABEL_OK);
     gtk_box_pack_end
         (GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(fe->cfgbox))),
          w, FALSE, FALSE, 0);
@@ -1562,7 +1624,7 @@ static int get_config(frontend *fe, int which)
             */
 
            w = gtk_label_new(i->name);
-           gtk_misc_set_alignment(GTK_MISC(w), 0.0, 0.5);
+           align_label(GTK_LABEL(w), 0.0, 0.5);
 #if GTK_CHECK_VERSION(3,0,0)
             gtk_grid_attach(GTK_GRID(table), w, 0, y, 1, 1);
 #else
@@ -1618,7 +1680,7 @@ static int get_config(frontend *fe, int which)
             */
 
            w = gtk_label_new(i->name);
-           gtk_misc_set_alignment(GTK_MISC(w), 0.0, 0.5);
+           align_label(GTK_LABEL(w), 0.0, 0.5);
 #if GTK_CHECK_VERSION(3,0,0)
             gtk_grid_attach(GTK_GRID(table), w, 0, y, 1, 1);
 #else
@@ -1857,8 +1919,6 @@ static void resize_fe(frontend *fe)
 #if GTK_CHECK_VERSION(3,0,0)
     gtk_window_resize_to_geometry(GTK_WINDOW(fe->window), x, y);
 #else
-    fe->w = x;
-    fe->h = y;
     fe->drawing_area_shrink_pending = FALSE;
     gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
     {
@@ -2014,8 +2074,8 @@ static char *file_selector(frontend *fe, char *title, int save)
                                    GTK_WINDOW(fe->window),
                                    save ? GTK_FILE_CHOOSER_ACTION_SAVE :
                                    GTK_FILE_CHOOSER_ACTION_OPEN,
-                                   GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                   save ? GTK_STOCK_SAVE : GTK_STOCK_OPEN,
+                                   LABEL_CANCEL, GTK_RESPONSE_CANCEL,
+                                   save ? LABEL_SAVE : LABEL_OPEN,
                                    GTK_RESPONSE_ACCEPT,
                                    NULL);
 
@@ -2169,6 +2229,21 @@ static void menu_config_event(GtkMenuItem *menuitem, gpointer data)
 static void menu_about_event(GtkMenuItem *menuitem, gpointer data)
 {
     frontend *fe = (frontend *)data;
+
+#if GTK_CHECK_VERSION(3,0,0)
+    extern char *const *const xpm_icons[];
+    extern const int n_xpm_icons;
+    GdkPixbuf *icon = gdk_pixbuf_new_from_xpm_data
+        ((const gchar **)xpm_icons[n_xpm_icons-1]);
+    gtk_show_about_dialog
+        (GTK_WINDOW(fe->window),
+         "program-name", thegame.name,
+         "version", ver,
+         "comments", "Part of Simon Tatham's Portable Puzzle Collection",
+         "logo", icon,
+         (const gchar *)NULL);
+    g_object_unref(G_OBJECT(icon));
+#else
     char titlebuf[256];
     char textbuf[1024];
 
@@ -2179,6 +2254,7 @@ static void menu_about_event(GtkMenuItem *menuitem, gpointer data)
            "%.500s", thegame.name, ver);
 
     message_box(fe->window, titlebuf, textbuf, TRUE, MB_OK);
+#endif
 }
 
 static GtkWidget *add_menu_item_with_key(frontend *fe, GtkContainer *cont,
@@ -2530,17 +2606,18 @@ static frontend *new_window(char *arg, int argtype, char **error)
        fe->statusctx = gtk_statusbar_get_context_id
            (GTK_STATUSBAR(fe->statusbar), "game");
        gtk_statusbar_push(GTK_STATUSBAR(fe->statusbar), fe->statusctx,
-                          "test");
+                          DEFAULT_STATUSBAR_TEXT);
+#if GTK_CHECK_VERSION(3,0,0)
+       gtk_widget_get_preferred_size(fe->statusbar, &req, NULL);
+#else
        gtk_widget_size_request(fe->statusbar, &req);
-#if 0
-       /* For GTK 2.0, should we be using gtk_widget_set_size_request? */
 #endif
-       gtk_widget_set_usize(viewport, -1, req.height);
+       gtk_widget_set_size_request(viewport, -1, req.height);
     } else
        fe->statusbar = NULL;
 
     fe->area = gtk_drawing_area_new();
-#if GTK_CHECK_VERSION(2,0,0)
+#if GTK_CHECK_VERSION(2,0,0) && !GTK_CHECK_VERSION(3,0,0)
     gtk_widget_set_double_buffered(fe->area, FALSE);
 #endif
     {
@@ -2549,6 +2626,8 @@ static frontend *new_window(char *arg, int argtype, char **error)
         gtk_window_set_geometry_hints(GTK_WINDOW(fe->window), fe->area,
                                       &geom, GDK_HINT_BASE_SIZE);
     }
+    fe->w = -1;
+    fe->h = -1;
     get_size(fe, &x, &y);
 #if GTK_CHECK_VERSION(3,0,0)
     gtk_window_set_default_geometry(GTK_WINDOW(fe->window), x, y);
@@ -2556,8 +2635,6 @@ static frontend *new_window(char *arg, int argtype, char **error)
     fe->drawing_area_shrink_pending = FALSE;
     gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
 #endif
-    fe->w = x;
-    fe->h = y;
 
     gtk_box_pack_end(vbox, fe->area, TRUE, TRUE, 0);