[gnome-tetravex] Allow finishing by a double-click.



commit 4e4b1822cfbda69c4977f80ddda092da0b0969d8
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Wed Sep 18 17:10:51 2019 +0200

    Allow finishing by a double-click.

 src/gnome-tetravex.vala | 10 +++++++---
 src/puzzle-view.vala    | 36 +++++++++++++++++++++++++++++++++++-
 src/puzzle.vala         | 12 +++++++++++-
 3 files changed, 53 insertions(+), 5 deletions(-)
---
diff --git a/src/gnome-tetravex.vala b/src/gnome-tetravex.vala
index 7dcaa5b..eb35595 100644
--- a/src/gnome-tetravex.vala
+++ b/src/gnome-tetravex.vala
@@ -312,6 +312,7 @@ private class Tetravex : Gtk.Application
         puzzle_init_done = true;
         puzzle.tick.connect (tick_cb);
         puzzle.solved.connect (solved_cb);
+        puzzle.show_end_game.connect (show_end_game_cb);
         view.puzzle = puzzle;
         tick_cb ();
 
@@ -338,6 +339,12 @@ private class Tetravex : Gtk.Application
     }
 
     private void solved_cb (Puzzle puzzle)
+    {
+        pause_action.set_enabled (false);
+        solve_action.set_enabled (false);
+    }
+
+    private void show_end_game_cb (Puzzle puzzle)
     {
         DateTime date = new DateTime.now_local ();
         uint duration = (uint) (puzzle.elapsed + 0.5);
@@ -345,9 +352,6 @@ private class Tetravex : Gtk.Application
         history.add (entry);
         history.save ();
 
-        pause_action.set_enabled (false);
-        solve_action.set_enabled (false);
-
         int score_dialog_action = show_scores (entry, true);
         if (score_dialog_action == ResponseType.CLOSE)
             window.destroy ();
diff --git a/src/puzzle-view.vala b/src/puzzle-view.vala
index ac02dbc..7ce9bfb 100644
--- a/src/puzzle-view.vala
+++ b/src/puzzle-view.vala
@@ -497,7 +497,21 @@ private class PuzzleView : Gtk.DrawingArea
             {
                 /* Move tile from left to right on double click */
                 pick_tile (event.x, event.y);
-                if (selected_tile != null && !on_right_half (((!) selected_tile).x))
+                if (selected_tile == null)
+                    return false;
+                if (on_right_half (((!) selected_tile).x))
+                {
+                    uint8 x;
+                    uint8 y;
+                    if (selected_tile_is_last_tile (out x, out y))
+                    {
+                        uint8 selected_x, selected_y;
+                        puzzle.get_tile_location (((!) selected_tile).tile, out selected_x, out selected_y);
+                        if (puzzle.can_switch (selected_x, selected_y, x, y))
+                            puzzle.switch_tiles (selected_x, selected_y, x, y, (uint) (animation_duration * 
1000.0));
+                    }
+                }
+                else
                     move_tile_to_right_half (((!) selected_tile).tile);
                 selected_tile = null;
                 tile_selected (false);
@@ -506,6 +520,26 @@ private class PuzzleView : Gtk.DrawingArea
 
         return false;
     }
+    private inline bool selected_tile_is_last_tile (out uint8 empty_x, out uint8 empty_y)
+    {
+        bool empty_found = false;
+        empty_x = uint8.MAX;    // garbage
+        empty_y = uint8.MAX;    // garbage
+        for (uint8 x = 0; x < puzzle.size; x++)
+            for (uint8 y = 0; y < puzzle.size; y++)
+                if (puzzle.get_tile (x, y) == null)
+                {
+                    if (empty_found)
+                        return false;
+                    empty_found = true;
+                    empty_x = x;
+                    empty_y = y;
+                }
+
+        if (!empty_found)
+            assert_not_reached ();
+        return true;
+    }
 
     protected override bool button_release_event (Gdk.EventButton event)
     {
diff --git a/src/puzzle.vala b/src/puzzle.vala
index 9ebee1e..e3cc2c5 100644
--- a/src/puzzle.vala
+++ b/src/puzzle.vala
@@ -66,6 +66,7 @@ private class Puzzle : Object
 
     internal signal void tile_moved (Tile tile, uint8 x, uint8 y);
     internal signal void solved ();
+    internal signal void show_end_game ();
     internal signal void tick ();
 
     [CCode (notify = false)] internal bool is_solved
@@ -232,7 +233,8 @@ private class Puzzle : Object
         return true;
     }
 
-    internal void switch_tiles (uint8 x0, uint8 y0, uint8 x1, uint8 y1)
+    private uint timeout_id = 0;
+    internal void switch_tiles (uint8 x0, uint8 y0, uint8 x1, uint8 y1, uint delay_if_finished = 0)
     {
         if (x0 == x1 && y0 == y1)
             return;
@@ -251,6 +253,14 @@ private class Puzzle : Object
         {
             stop_clock ();
             solved ();
+            if (delay_if_finished == 0)
+                show_end_game ();
+            else if (timeout_id == 0)
+                timeout_id = Timeout.add (delay_if_finished, () => {
+                        show_end_game ();
+                        timeout_id = 0;
+                        return Source.REMOVE;
+                    });
         }
     }
 


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