[gnome-tetravex] Add an hidden function.



commit edc4bf7577cbbd58a051d2c1772c0c9e7979ee47
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Fri Oct 18 03:40:09 2019 +0200

    Add an hidden function.
    
    Part of #14 resolution.

 src/puzzle-view.vala | 61 +++++++++++++++++++++++++++++++++++++++-------------
 src/puzzle.vala      | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 15 deletions(-)
---
diff --git a/src/puzzle-view.vala b/src/puzzle-view.vala
index 6df97d3..45306f3 100644
--- a/src/puzzle-view.vala
+++ b/src/puzzle-view.vala
@@ -360,8 +360,8 @@ private class PuzzleView : Gtk.DrawingArea
             right_margin = allocated_width - x_offset_right - boardsize;
 
             /* Precalculate sockets positions */
-            for (uint y = 0; y < puzzle.size; y++)
-                for (uint x = 0; x < puzzle.size * 2; x++)
+            for (uint8 y = 0; y < puzzle.size; y++)
+                for (uint8 x = 0; x < puzzle.size * 2; x++)
                 {
                     if (x >= puzzle.size)
                         sockets_xs [x, y] = x_offset + x * tilesize + gap;
@@ -430,28 +430,23 @@ private class PuzzleView : Gtk.DrawingArea
 
         /* Draw arrow */
         context.save ();
-        Cairo.Matrix matrix = Cairo.Matrix.identity ();
-        matrix.translate (- arrow_x, - (int) y_offset);
-        ((!) arrow_pattern).set_matrix (matrix);
-
+        context.translate (arrow_x, y_offset);
         context.set_source ((!) arrow_pattern);
-        context.rectangle (arrow_x, y_offset, /* width and height */ gap, boardsize);
+        context.rectangle (0.0, 0.0, /* width and height */ gap, boardsize);
         context.fill ();
         context.restore ();
 
         /* Draw sockets */
-        for (uint y = 0; y < puzzle.size; y++)
-            for (uint x = 0; x < puzzle.size * 2; x++)
+        for (uint8 y = 0; y < puzzle.size; y++)
+            for (uint8 x = 0; x < puzzle.size * 2; x++)
             {
                 context.save ();
-                matrix = Cairo.Matrix.identity ();
-                matrix.translate (- sockets_xs [x, y],
-                                  - sockets_ys [x, y]);
-                ((!) socket_pattern).set_matrix (matrix);
+                context.translate (sockets_xs [x, y], sockets_ys [x, y]);
 
                 context.set_source ((!) socket_pattern);
-                context.rectangle (sockets_xs [x, y], sockets_ys [x, y], /* width and height */ tilesize, 
tilesize);
+                context.rectangle (0.0, 0.0, /* width and height */ tilesize, tilesize);
                 context.fill ();
+
                 context.restore ();
             }
 
@@ -572,6 +567,39 @@ private class PuzzleView : Gtk.DrawingArea
                 selection_timeout = Timeout.add (200, selection_timeout_cb);
             }
         }
+
+        if (!tile_selected && !on_right_half (x))
+        {
+            uint8 tile_x;
+            uint8 tile_y;
+            if (get_left_tile_coords (x, y, out tile_x, out tile_y))
+                puzzle.try_move (tile_x, tile_y);
+        }
+    }
+    private inline bool get_left_tile_coords (double event_x, double event_y, out uint8 tile_x, out uint8 
tile_y)
+    {
+        if (!get_left_tile_coord_x (event_x, out tile_x))
+        {
+            tile_y = 0; // garbage
+            return false;
+        }
+        if (!get_tile_coord_y (event_y, out tile_y))
+            return false;
+        return true;
+    }
+    private inline bool get_left_tile_coord_x (double event_x, out uint8 tile_x)
+    {
+        for (tile_x = 0; tile_x < puzzle.size; tile_x++)
+            if (event_x > sockets_xs [tile_x, 0] && event_x < sockets_xs [tile_x, 0] + tilesize)
+                return true;
+        return false;
+    }
+    private inline bool get_tile_coord_y (double event_y, out uint8 tile_y)
+    {
+        for (tile_y = 0; tile_y < puzzle.size; tile_y++)
+            if (event_y > sockets_ys [0, tile_y] && event_y < sockets_ys [0, tile_y] + tilesize)
+                return true;
+        return false;
     }
 
     private bool selection_timeout_cb ()
@@ -744,7 +772,7 @@ private class PuzzleView : Gtk.DrawingArea
             return false;
         clear_keyboard_highlight (/* only selection */ false);
 
-        if (event.button == 1 && selected_tile != null && selection_timeout == 0)
+        if ((event.button == 1 || event.button == 3) && selected_tile != null && selection_timeout == 0)
             drop_tile (event.x, event.y);
 
         if (selection_timeout != 0)
@@ -928,7 +956,10 @@ private class PuzzleView : Gtk.DrawingArea
             {
                 Tile? tile = puzzle.get_tile (highlight_x, highlight_y);
                 if (tile == null)
+                {
+                    puzzle.try_move (highlight_x, highlight_y);
                     return true;
+                }
 
                 if (highlight_x >= puzzle.size)
                 {
diff --git a/src/puzzle.vala b/src/puzzle.vala
index cd5bb6c..706ba67 100644
--- a/src/puzzle.vala
+++ b/src/puzzle.vala
@@ -398,6 +398,62 @@ private class Puzzle : Object
         return true;
     }
 
+    internal void try_move (uint8 x, uint8 y)
+        requires (x >= 0 && x < size)
+        requires (y >= 0 && y < size)
+    {
+        switch (can_move (x, y))
+        {
+            case Direction.UP:      move_up ();     return;
+            case Direction.DOWN:    move_down ();   return;
+            case Direction.LEFT:    move_left ();   return;
+            case Direction.RIGHT:   move_right ();  return;
+            case Direction.NONE:
+            default:                                return;
+        }
+    }
+
+    private inline Direction can_move (uint8 x, uint8 y)
+    {
+        if (left_half_board_is_empty ())
+            return Direction.NONE;
+
+        if (y == 0 && can_move_up ()
+         && !(x == 0 && can_move_left ())
+         && !(x == size - 1 && can_move_right ()))
+            return Direction.UP;
+        if (y == size - 1 && can_move_down ()
+         && !(x == 0 && can_move_left ())
+         && !(x == size - 1 && can_move_right ()))
+            return Direction.DOWN;
+        if (x == 0 && can_move_left ()
+         && !(y == 0 && can_move_up ())
+         && !(y == size - 1 && can_move_down ()))
+            return Direction.LEFT;
+        if (x == size - 1 && can_move_right ()
+         && !(y == 0 && can_move_up ())
+         && !(y == size - 1 && can_move_down ()))
+            return Direction.RIGHT;
+        return Direction.NONE;
+    }
+    private inline bool left_half_board_is_empty ()
+    {
+        for (uint8 x = 0; x < size; x++)
+            for (uint8 y = 0; y < size; y++)
+                if (board [x, y] != null)
+                    return false;
+        return true;
+    }
+
+    private enum Direction
+    {
+        NONE,
+        UP,
+        DOWN,
+        LEFT,
+        RIGHT;
+    }
+
     /*\
     * * actions
     \*/


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