puzzle: Add mouse support
authorMatthias Clasen <mclasen@redhat.com>
Thu, 7 Jun 2018 21:38:24 +0000 (17:38 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 8 Jun 2018 01:47:30 +0000 (21:47 -0400)
Make it so that clicking on a puzzle piece moves enough
pieces to move the empty space there, if it is possible.

demos/gtk-demo/sliding_puzzle.c

index f21a84b8f18257385bdcf50db34de1db99d6334a..a49e034c0c231ba3ab561fb8ac9dbefdb2bb46aa 100644 (file)
@@ -219,6 +219,68 @@ puzzle_key_pressed (GtkEventControllerKey *controller,
   return TRUE;
 }
 
+static void
+puzzle_button_pressed (GtkGestureMultiPress *gesture,
+                       int                   n_press,
+                       double                x,
+                       double                y,
+                       GtkWidget            *grid)
+{
+  GtkWidget *child;
+  int l, t, i;
+  int pos;
+
+  child = gtk_widget_pick (grid, x, y);
+
+  if (!child)
+    {
+      gtk_widget_error_bell (grid);
+      return;
+    }
+
+  gtk_container_child_get (GTK_CONTAINER (grid), child,
+                           "left-attach", &l,
+                           "top-attach", &t,
+                           NULL);
+
+  if (l == pos_x && t == pos_y)
+    {
+      gtk_widget_error_bell (grid);
+    }
+  else if (l == pos_x)
+    {
+      pos = pos_y;
+      for (i = t; i < pos; i++)
+        {
+          if (!move_puzzle (grid, 0, -1))
+            gtk_widget_error_bell (grid);
+        }
+      for (i = pos; i < t; i++)
+        {
+          if (!move_puzzle (grid, 0, 1))
+            gtk_widget_error_bell (grid);
+        }
+    }
+  else if (t == pos_y)
+    {
+      pos = pos_x;
+      for (i = l; i < pos; i++)
+        {
+          if (!move_puzzle (grid, -1, 0))
+            gtk_widget_error_bell (grid);
+        }
+      for (i = pos; i < l; i++)
+        {
+          if (!move_puzzle (grid, 1, 0))
+            gtk_widget_error_bell (grid);
+        }
+    }
+  else
+    {
+      gtk_widget_error_bell (grid);
+    }
+}
+
 static void
 start_puzzle (GdkPaintable *puzzle)
 {
@@ -244,6 +306,12 @@ start_puzzle (GdkPaintable *puzzle)
                     grid);
   gtk_widget_add_controller (GTK_WIDGET (grid), controller);
 
+  controller = gtk_gesture_multi_press_new ();
+  g_signal_connect (controller, "pressed",
+                    G_CALLBACK (puzzle_button_pressed),
+                    grid);
+  gtk_widget_add_controller (GTK_WIDGET (grid), controller);
+
   /* Make sure the cells have equal size */
   gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
   gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);