[gtk/matthiasc/for-master] gtk-demo: Finish peg solitaire demo
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/for-master] gtk-demo: Finish peg solitaire demo
- Date: Sun, 9 Aug 2020 22:28:24 +0000 (UTC)
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]