[five-or-more] Use GtkHeaderBar



commit e84ffa87a16bbac12ba0df9c0984cd14719594b4
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Sun Nov 24 20:55:34 2013 -0600

    Use GtkHeaderBar

 data/five-or-more.ui |   88 +++++++++++++++---------------------------
 src/glines.c         |  106 +++++++++++++++++++++-----------------------------
 2 files changed, 75 insertions(+), 119 deletions(-)
---
diff --git a/data/five-or-more.ui b/data/five-or-more.ui
index b6209cc..1d58e38 100644
--- a/data/five-or-more.ui
+++ b/data/five-or-more.ui
@@ -4,99 +4,73 @@
   <object class="GtkAccelGroup" id="accelgroup"/>
   <object class="GtkApplicationWindow" id="glines_window">
     <property name="can_focus">False</property>
-    <property name="title" translatable="yes">Five or More</property>
     <property name="default_width">320</property>
     <property name="default_height">400</property>
     <property name="icon_name">glines</property>
     <accel-groups>
       <group name="accelgroup"/>
     </accel-groups>
-    <child>
-      <object class="GtkBox" id="vbox">
+    <child type="titlebar">
+      <object class="GtkHeaderBar" id="headerbar">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <placeholder/>
-        </child>
+        <property name="show_close_button">True</property>
+        <property name="show_fallback_app_menu">True</property>
+        <property name="spacing">6</property>
+        <property name="title" translatable="yes">Five or More</property>
         <child>
-          <object class="GtkBox" id="top_box">
+          <object class="GtkBox" id="preview_hbox">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="orientation">horizontal</property>
             <child>
               <object class="GtkLabel" id="labelNext">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="xpad">6</property>
+                <property name="xpad">2</property>
                 <property name="label" translatable="yes">Next:</property>
                 <attributes>
                   <attribute name="weight" value="bold"/>
                 </attributes>
               </object>
               <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <object class="GtkLabel" id="scorelabel">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xpad">6</property>
-                <property name="label" translatable="yes">0</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="pack_type">end</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="labelScore">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Score:</property>
-                <attributes>
-                  <attribute name="weight" value="bold"/>
-                </attributes>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="pack_type">end</property>
-                <property name="position">3</property>
+                <property name="pack_type">start</property>
               </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">1</property>
-          </packing>
         </child>
         <child>
-          <placeholder/>
+          <object class="GtkLabel" id="labelScore">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Score:</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
         </child>
         <child>
-          <object class="GtkStatusbar" id="statusbar">
+          <object class="GtkLabel" id="scorelabel">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">2</property>
+            <property name="xpad">6</property>
+            <property name="label" translatable="yes">0</property>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
             <property name="pack_type">end</property>
-            <property name="position">4</property>
           </packing>
         </child>
       </object>
     </child>
+    <child>
+      <object class="GtkBox" id="vbox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+      </object>
+    </child>
   </object>
 </interface>
diff --git a/src/glines.c b/src/glines.c
index e10dcec..0407ab1 100644
--- a/src/glines.c
+++ b/src/glines.c
@@ -58,6 +58,9 @@
 #define DEFAULT_GAME_SIZE MEDIUM
 #define DEFAULT_BALL_THEME "balls.svg"
 
+#define PREVIEW_IMAGE_WIDTH 20
+#define PREVIEW_IMAGE_HEIGHT 20
+
 enum {
   UNSET = 0,
   SMALL = 1,
@@ -95,7 +98,7 @@ static gboolean pref_dialog_done = FALSE;
 static GRand *rgen;
 
 static GtkWidget *draw_area;
-static GtkWidget *app, *statusbar, *pref_dialog, *gridframe;
+static GtkWidget *app, *headerbar, *pref_dialog, *gridframe;
 static GtkWidget *preview_widgets[MAXNPIECES];
 
 static gint window_width = 0, window_height = 0;
@@ -110,6 +113,9 @@ static cairo_surface_t *ball_surface = NULL;
 /* The balls rendered to a size appropriate for the preview. */
 static cairo_surface_t *preview_surfaces[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
+static GtkImage* preview_images[MAXNPIECES];
+static GdkPixbuf* preview_pixbufs[MAXNPIECES];
+
 /* A cairo_surface_t of a blank tile. */
 static cairo_surface_t *blank_surface = NULL;
 static cairo_surface_t *blank_preview_surface = NULL;
@@ -126,9 +132,6 @@ static gboolean show_cursor = FALSE;
 
 static int boxsize;
 
-static int preview_height = 0;
-static int preview_width = 0;
-
 static int move_timeout = 100;
 static int animate_id = 0;
 static int preview[MAXNPIECES];
@@ -148,13 +151,9 @@ static struct {
 static gchar *warning_message = NULL;
 
 static void
-set_statusbar_message (gchar * message)
+set_status_message (gchar * message)
 {
-  guint context_id;
-  context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar),
-                                             "message");
-  gtk_statusbar_pop (GTK_STATUSBAR (statusbar), context_id);
-  gtk_statusbar_push (GTK_STATUSBAR (statusbar), context_id, message);
+  gtk_header_bar_set_subtitle (GTK_HEADER_BAR (headerbar), message);
 }
 
 static void
@@ -292,13 +291,13 @@ refresh_preview_surfaces (void)
 
   /* Like the refresh_pixmaps() function, we may be called before
    * the window is ready. */
-  if (preview_height == 0)
+  if (PREVIEW_IMAGE_HEIGHT == 0)
     return;
 
   preview_rect.x = 0;
   preview_rect.y = 0;
-  preview_rect.width = preview_width;
-  preview_rect.height = preview_height;
+  preview_rect.width = PREVIEW_IMAGE_WIDTH;
+  preview_rect.height = PREVIEW_IMAGE_HEIGHT;
 
   /* We create pixmaps for each of the ball colours and then
    * set them as the background for each widget in the preview array.
@@ -309,27 +308,33 @@ refresh_preview_surfaces (void)
       cairo_surface_destroy (preview_surfaces[i]);
 
   if (ball_preimage)
-    scaled = games_preimage_render (ball_preimage, 4 * preview_width,
-                                    7 * preview_height);
+    scaled = games_preimage_render (ball_preimage, 4 * PREVIEW_IMAGE_WIDTH,
+                                    7 * PREVIEW_IMAGE_HEIGHT);
 
   if (!scaled) {
     scaled = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
-                             4 * preview_width, 7 * preview_height);
+                             4 * PREVIEW_IMAGE_WIDTH, 7 * PREVIEW_IMAGE_HEIGHT);
     gdk_pixbuf_fill (scaled, 0x00000000);
   }
 
   for (i = 0; i < 7; i++) {
     preview_surfaces[i] = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
                                                              CAIRO_CONTENT_COLOR_ALPHA,
-                                                             preview_width, preview_height);
+                                                             PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT);
     cr = cairo_create (preview_surfaces[i]);
     gdk_cairo_set_source_rgba (cr, &bg);
     gdk_cairo_rectangle (cr, &preview_rect);
     cairo_fill (cr);
 
-    gdk_cairo_set_source_pixbuf (cr, scaled, 0, -1.0 * preview_height * i);
+    gdk_cairo_set_source_pixbuf (cr, scaled, 0, -1.0 * PREVIEW_IMAGE_HEIGHT * i);
     cairo_mask (cr, cairo_get_source (cr));
 
+    if (preview_pixbufs[i])
+      g_object_unref (preview_pixbufs[i]);
+
+    preview_pixbufs[i] = gdk_pixbuf_get_from_surface (preview_surfaces[i], 0, 0,
+                                                      PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT);
+
     cairo_destroy (cr);
   }
 
@@ -338,7 +343,7 @@ refresh_preview_surfaces (void)
 
   blank_preview_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
                                                              CAIRO_CONTENT_COLOR_ALPHA,
-                                                             preview_width, preview_height);
+                                                             PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT);
   cr = cairo_create (blank_preview_surface);
   gdk_cairo_set_source_rgba (cr, &bg);
   gdk_cairo_rectangle (cr, &preview_rect);
@@ -404,7 +409,7 @@ start_game (void)
 {
   char string[20];
 
-  set_statusbar_message (_
+  set_status_message (_
                          ("Match five objects of the same type in a row to score!"));
   refresh_screen ();
   active = -1;
@@ -438,19 +443,16 @@ void
 draw_preview (void)
 {
   guint i;
-  cairo_pattern_t *pattern;
 
-  for (i = 0; i < MAXNPIECES; i++) {
+  /* This function can be called before the images are initialized */
+  if (!GTK_IS_IMAGE (preview_images[0]))
+    return;
 
+  for (i = 0; i < MAXNPIECES; i++) {
     if (i < npieces)
-      pattern = cairo_pattern_create_for_surface (preview_surfaces[preview[i] - 1]);
+      gtk_image_set_from_pixbuf (preview_images[i], preview_pixbufs[preview[i] - 1]);
     else
-      pattern = cairo_pattern_create_for_surface (blank_preview_surface);
-
-    gdk_window_set_background_pattern (gtk_widget_get_window (preview_widgets[i]),
-                                       pattern);
-    cairo_pattern_destroy (pattern);
-    gtk_widget_queue_draw (preview_widgets[i]);
+      gtk_image_clear (preview_images[i]);
   }
 }
 
@@ -488,7 +490,7 @@ game_over (void)
 {
   int pos;
 
-  set_statusbar_message (_("Game Over!"));
+  set_status_message (_("Game Over!"));
   pos = games_scores_add_plain_score (highscores, score);
   show_scores (pos);
   return;
@@ -629,7 +631,7 @@ cell_clicked (GtkWidget * widget, int fx, int fy)
 {
   int x, y;
 
-  set_statusbar_message ("");
+  set_status_message (NULL);
   if (field[fx + fy * hfieldsize].color == 0) {
     /* Clicked on an empty field */
 
@@ -645,7 +647,7 @@ cell_clicked (GtkWidget * widget, int fx, int fy)
         set_inmove (1);
       } else {
         /* Can't move there! */
-        set_statusbar_message (_("You can't move there!"));
+        set_status_message (_("You can't move there!"));
         reset_pathsearch ();
         target = -1;
       }
@@ -1437,19 +1439,6 @@ game_help_callback (GSimpleAction *action,
 }
 
 static int
-preview_configure_cb (GtkWidget * widget, GdkEventConfigure * event)
-{
-  preview_width = event->width;
-  preview_height = event->height;
-
-  refresh_preview_surfaces ();
-
-  draw_preview ();
-
-  return TRUE;
-}
-
-static int
 configure_event_callback (GtkWidget * widget, GdkEventConfigure * event)
 {
   if (ball_surface)
@@ -1530,7 +1519,7 @@ static void
 startup_cb (GApplication *application)
 {
   gchar *ui_path;
-  GtkWidget *vbox, *hbox;
+  GtkWidget *vbox;
   GtkWidget *preview_hbox;
   guint i;
   GError *error = NULL;
@@ -1585,6 +1574,7 @@ startup_cb (GApplication *application)
   }
 
   app = GTK_WIDGET (gtk_builder_get_object (builder, "glines_window"));
+  gtk_window_set_icon_name (GTK_WINDOW (app), "five-or-more");
   g_signal_connect (GTK_WINDOW (app), "configure-event", G_CALLBACK (window_configure_event_cb), NULL);
   g_signal_connect (GTK_WINDOW (app), "window-state-event", G_CALLBACK (window_state_event_cb), NULL);
   gtk_window_set_default_size (GTK_WINDOW (app), g_settings_get_int (settings, "window-width"), 
g_settings_get_int (settings, "window-height"));
@@ -1594,26 +1584,20 @@ startup_cb (GApplication *application)
     gtk_window_maximize (GTK_WINDOW (app));
   gtk_application_add_window (GTK_APPLICATION (application), GTK_WINDOW (app));
 
-  hbox = GTK_WIDGET (gtk_builder_get_object (builder, "top_box"));
-
-  gridframe = games_grid_frame_new (MAXNPIECES, 1);
-  games_grid_frame_set_alignment (GAMES_GRID_FRAME (gridframe), 0, 0.5);
-  gtk_box_pack_start (GTK_BOX (hbox), gridframe, TRUE, TRUE, 0);
+  headerbar = GTK_WIDGET (gtk_builder_get_object (builder, "headerbar"));
 
-  preview_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-  gtk_container_add (GTK_CONTAINER (gridframe), preview_hbox);
+  preview_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "preview_hbox"));
 
   for (i = 0; i < MAXNPIECES; i++) {
+    // FIXME This array of drawing areas is used just so we can get the style
+    // context from the first one in refresh_preview_surfaces() -- remove it
     preview_widgets[i] = gtk_drawing_area_new ();
-    gtk_box_pack_start (GTK_BOX (preview_hbox),
-                        preview_widgets[i], TRUE, TRUE, 0);
-    /* So we have all the windows at configure time since
-     * we only hook into one of the configure events. */
-    /* Yes, this is an evil hack. */
+    gtk_box_pack_start (GTK_BOX (preview_hbox), preview_widgets[i], TRUE, TRUE, 0);
     gtk_widget_realize (preview_widgets[i]);
+
+    preview_images[i] = GTK_IMAGE (gtk_image_new ());
+    gtk_box_pack_start (GTK_BOX (preview_hbox), GTK_WIDGET (preview_images[i]), FALSE, FALSE, 0);
   }
-  g_signal_connect (preview_widgets[0], "configure-event",
-                    G_CALLBACK (preview_configure_cb), NULL);
 
   scorelabel = GTK_WIDGET (gtk_builder_get_object (builder, "scorelabel"));
 
@@ -1632,8 +1616,6 @@ startup_cb (GApplication *application)
   gtk_container_add (GTK_CONTAINER (gridframe), draw_area);
   gtk_box_pack_start (GTK_BOX (vbox), gridframe, TRUE, TRUE, 0);
 
-  statusbar = GTK_WIDGET (gtk_builder_get_object (builder, "statusbar"));
-
   gtk_widget_set_events (draw_area,
                          gtk_widget_get_events (draw_area) |
                          GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]