[gtk/matthiasc/for-master] gtk-demo: Finish peg solitaire demo



commit e5247b7cbb03e73dfbea4942fefbeef5ccda37e0
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Aug 9 18:27:18 2020 -0400

    gtk-demo: Finish peg solitaire demo
    
    The restart button was simply not implemented.
    While we are at it, make the pegs a bit bigger,
    so clicking them is easier.

 demos/gtk-demo/peg_solitaire.c | 162 ++++++++++++++++++++++++-----------------
 1 file changed, 96 insertions(+), 66 deletions(-)
---
diff --git a/demos/gtk-demo/peg_solitaire.c b/demos/gtk-demo/peg_solitaire.c
index 6532cce254..81f9a5c4c5 100644
--- a/demos/gtk-demo/peg_solitaire.c
+++ b/demos/gtk-demo/peg_solitaire.c
@@ -6,8 +6,6 @@
 
 #include <gtk/gtk.h>
 
-static GtkWidget *window = NULL;
-
 /* Create an object for the pegs that get moved around in the game.
  *
  * We implement the GdkPaintable interface for them, so we can use GtkPicture
@@ -56,11 +54,25 @@ solitaire_peg_get_flags (GdkPaintable *paintable)
   return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
 }
 
+static int
+solitaire_peg_get_intrinsic_width (GdkPaintable *paintable)
+{
+  return 32;
+}
+
+static int
+solitaire_peg_get_intrinsic_height (GdkPaintable *paintable)
+{
+  return 32;
+}
+
 static void
 solitaire_peg_paintable_init (GdkPaintableInterface *iface)
 {
   iface->snapshot = solitaire_peg_snapshot;
   iface->get_flags = solitaire_peg_get_flags;
+  iface->get_intrinsic_width = solitaire_peg_get_intrinsic_width;
+  iface->get_intrinsic_height = solitaire_peg_get_intrinsic_height;
 }
 
 /* When defining the GType, we need to implement the GdkPaintable interface */
@@ -259,25 +271,99 @@ drop_drop (GtkDropTarget *target,
   return TRUE;
 }
 
+static void
+create_board (GtkWidget *window)
+{
+  GtkWidget *grid;
+  GtkWidget *image;
+  int x, y;
+  GtkDragSource *source;
+  GtkDropTarget *target;
+
+  grid = gtk_grid_new ();
+  gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
+  gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
+  gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+  gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
+  gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
+  gtk_window_set_child (GTK_WINDOW (window), grid);
+
+  for (x = 0; x < 7; x++)
+    {
+      for (y = 0; y < 7; y++)
+        {
+          if ((x < 2 || x >= 5) && (y < 2 || y >= 5))
+            continue;
+
+          image = gtk_image_new ();
+          gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
+          if (x != 3 || y != 3)
+            {
+              SolitairePeg *peg = solitaire_peg_new ();
+              solitaire_peg_set_position (peg, x, y);
+              gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (peg));
+            }
+
+          gtk_grid_attach (GTK_GRID (grid), image, x, y, 1, 1);
+
+          /* Set up the drag source.
+           * This is rather straightforward: Set the supported actions
+           * (in our case, pegs can only be moved) and connect all the
+           * relevant signals.
+           * And because all drag'n'drop handling is done via event controllers,
+           * we need to add the controller to the widget.
+           */
+          source = gtk_drag_source_new ();
+          gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
+          g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare), image);
+          g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
+          g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), image);
+          gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
+
+          /* Set up the drop target.
+           * This is more involved, because the game logic goes here.
+           */
+
+          /* First we specify the data we accept: pegs.
+           * And we only want moves.
+           */
+          target = gtk_drop_target_new (SOLITAIRE_TYPE_PEG, GDK_ACTION_MOVE);
+          /* Then we connect our signals.
+           */
+          g_signal_connect (target, "accept", G_CALLBACK (drop_accept), image);
+          g_signal_connect (target, "drop", G_CALLBACK (drop_drop), image);
+          /* Finally, like above, we add it to the widget.
+           */
+          gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (target));
+        }
+    }
+}
+
+static void
+restart_game (GtkButton *button,
+              GtkWidget *window)
+{
+  create_board (window);
+}
+
 GtkWidget *
 do_peg_solitaire (GtkWidget *do_widget)
 {
+  static GtkWidget *window = NULL;
+
   if (!window)
     {
       GtkWidget *header;
       GtkWidget *restart;
-      GtkWidget *grid;
-      GtkWidget *image;
-      int x, y;
-      GtkDragSource *source;
-      GtkDropTarget *target;
+
+      window = gtk_window_new ();
 
       restart = gtk_button_new_from_icon_name ("view-refresh-symbolic");
-      g_signal_connect (restart, "clicked", G_CALLBACK (restart), NULL);
+      g_signal_connect (restart, "clicked", G_CALLBACK (restart_game), window);
 
       header = gtk_header_bar_new ();
       gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
-      window = gtk_window_new ();
       gtk_window_set_display (GTK_WINDOW (window),
                               gtk_widget_get_display (do_widget));
       gtk_window_set_title (GTK_WINDOW (window), "Peg Solitaire");
@@ -285,63 +371,7 @@ do_peg_solitaire (GtkWidget *do_widget)
       gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
       g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
 
-      grid = gtk_grid_new ();
-      gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
-      gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
-      gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
-      gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
-      gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
-      gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
-      gtk_window_set_child (GTK_WINDOW (window), grid);
-
-      for (x = 0; x < 7; x++)
-        {
-          for (y = 0; y < 7; y++)
-            {
-              if ((x < 2 || x >= 5) && (y < 2 || y >= 5))
-                continue;
-
-              image = gtk_image_new ();
-              if (x != 3 || y != 3)
-                {
-                  SolitairePeg *peg = solitaire_peg_new ();
-                  solitaire_peg_set_position (peg, x, y);
-                  gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (peg));
-                }
-
-              gtk_grid_attach (GTK_GRID (grid), image, x, y, 1, 1);
-
-              /* Set up the drag source.
-               * This is rather straightforward: Set the supported actions
-               * (in our case, pegs can only be moved) and connect all the
-               * relevant signals.
-               * And because all drag'n'drop handling is done via event controllers,
-               * we need to add the controller to the widget.
-               */
-              source = gtk_drag_source_new ();
-              gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
-              g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare), image);
-              g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
-              g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), image);
-              gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
-
-              /* Set up the drop target.
-               * This is more involved, because the game logic goes here.
-               */
-
-              /* First we specify the data we accept: pegs.
-               * And we only want moves.
-               */
-              target = gtk_drop_target_new (SOLITAIRE_TYPE_PEG, GDK_ACTION_MOVE);
-              /* Then we connect our signals.
-               */
-              g_signal_connect (target, "accept", G_CALLBACK (drop_accept), image);
-              g_signal_connect (target, "drop", G_CALLBACK (drop_drop), image);
-              /* Finally, like above, we add it to the widget.
-               */
-              gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (target));
-            }
-        }
+      create_board (window);
     }
 
   if (!gtk_widget_get_visible (window))


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