[gnome-tetravex] Allow finishing puzzle on right.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-tetravex] Allow finishing puzzle on right.
- Date: Fri, 20 Sep 2019 17:11:25 +0000 (UTC)
commit 096865c44e70a24f0b4caa1a7032c136aa9ffe29
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Fri Sep 20 19:09:07 2019 +0200
Allow finishing puzzle on right.
Or to be exact, allow to work
a puzzle on the right side of
the board, then move it left.
Fixes #15.
src/gnome-tetravex.vala | 65 +++++++++++++++++++++++++++++++++++++++++++++----
src/puzzle-view.vala | 20 ++++++++++-----
src/puzzle.vala | 14 ++++++++++-
3 files changed, 87 insertions(+), 12 deletions(-)
---
diff --git a/src/gnome-tetravex.vala b/src/gnome-tetravex.vala
index f004122..06ffa40 100644
--- a/src/gnome-tetravex.vala
+++ b/src/gnome-tetravex.vala
@@ -41,6 +41,7 @@ private class Tetravex : Gtk.Application
private SimpleAction pause_action;
private SimpleAction solve_action;
+ private SimpleAction finish_action;
private const OptionEntry [] option_entries =
{
@@ -60,6 +61,7 @@ private class Tetravex : Gtk.Application
{ "new-game", new_game_cb },
{ "pause", pause_cb },
{ "solve", solve_cb },
+ { "finish", finish_cb },
{ "scores", scores_cb },
{ "quit", quit },
{ "move-up", move_up },
@@ -186,9 +188,17 @@ private class Tetravex : Gtk.Application
/* align end */ true,
sizegroup);
+ Button finish_button = new BottomButton ("go-previous-symbolic",
+ "app.finish",
+ /* Translators: tooltip text of bottom bar button that appears is the puzzle is solved on the right
part of the board */
+ _("Move all tiles left"),
+ /* align end */ true,
+ sizegroup);
+
new_game_solve_stack = new Stack ();
new_game_solve_stack.add_named (solve_button, "solve");
new_game_solve_stack.add_named (new_game_button, "new-game");
+ new_game_solve_stack.add_named (finish_button, "finish");
grid.attach (new_game_solve_stack, 2, 1, 1, 1);
Box box = new Box (Orientation.HORIZONTAL, 8);
@@ -202,14 +212,20 @@ private class Tetravex : Gtk.Application
box.set_margin_bottom (20);
grid.attach (box, 1, 1, 1, 1);
- pause_action = (SimpleAction) lookup_action ("pause");
- solve_action = (SimpleAction) lookup_action ("solve");
- view.tile_selected.connect ((/* bool */ selected) => {
+ pause_action = (SimpleAction) lookup_action ("pause");
+ solve_action = (SimpleAction) lookup_action ("solve");
+ finish_action = (SimpleAction) lookup_action ("finish");
+ finish_action.set_enabled (false);
+ view.notify ["tile-selected"].connect (() => {
if (!puzzle_init_done)
return;
if (puzzle.is_solved)
return;
- solve_action.set_enabled (!selected);
+ if (puzzle.is_solved_right)
+ solve_action.set_enabled (false);
+ else
+ solve_action.set_enabled (!view.tile_selected && /* should never happen */
!puzzle.paused);
+ finish_action.set_enabled (!view.tile_selected);
});
window.show_all ();
@@ -301,8 +317,10 @@ private class Tetravex : Gtk.Application
private void new_game ()
{
+ has_been_finished = false;
pause_action.set_enabled (true);
solve_action.set_enabled (true);
+ finish_action.set_enabled (false);
new_game_solve_stack.set_visible_child_name ("solve");
if (puzzle_init_done)
@@ -313,6 +331,7 @@ private class Tetravex : Gtk.Application
puzzle_init_done = true;
puzzle.tick.connect (tick_cb);
puzzle.solved.connect (solved_cb);
+ puzzle.solved_right.connect (solved_right_cb);
puzzle.show_end_game.connect (show_end_game_cb);
view.puzzle = puzzle;
tick_cb ();
@@ -343,6 +362,24 @@ private class Tetravex : Gtk.Application
{
pause_action.set_enabled (false);
solve_action.set_enabled (false);
+ finish_action.set_enabled (false);
+ }
+
+ private void solved_right_cb (Puzzle puzzle, bool is_solved)
+ {
+ if (is_solved)
+ {
+ solve_action.set_enabled (false);
+ finish_action.set_enabled (/* should never happen */ !puzzle.paused);
+ new_game_solve_stack.set_visible_child_name ("finish");
+ }
+ else
+ {
+ solve_action.set_enabled (/* should never happen */ !puzzle.paused);
+ finish_action.set_enabled (false);
+ if (!has_been_finished) // keep the "finish" button if it has been clicked
+ new_game_solve_stack.set_visible_child_name ("solve");
+ }
}
private void show_end_game_cb (Puzzle puzzle)
@@ -429,9 +466,18 @@ private class Tetravex : Gtk.Application
new_game_solve_stack.set_visible_child_name ("new-game");
pause_action.set_enabled (false);
solve_action.set_enabled (false);
+ finish_action.set_enabled (false);
}
}
+ private bool has_been_finished = false;
+ private void finish_cb ()
+ {
+ finish_action.set_enabled (false);
+ has_been_finished = true;
+ view.finish ();
+ }
+
private void size_changed (SimpleAction action, Variant variant)
{
int size = ((string) variant)[0] - '0'; // FIXME that... is... horrible
@@ -479,7 +525,16 @@ private class Tetravex : Gtk.Application
private void update_button_states ()
{
- solve_action.set_enabled (!puzzle.paused);
+ if (puzzle.is_solved_right)
+ {
+ solve_action.set_enabled (false);
+ finish_action.set_enabled (!puzzle.paused && !view.tile_selected);
+ }
+ else
+ {
+ solve_action.set_enabled (!puzzle.paused && !view.tile_selected);
+ finish_action.set_enabled (false);
+ }
play_pause_stack.set_visible_child_name (puzzle.paused ? "play" : "pause");
}
diff --git a/src/puzzle-view.vala b/src/puzzle-view.vala
index 6838b6b..dc01d2d 100644
--- a/src/puzzle-view.vala
+++ b/src/puzzle-view.vala
@@ -48,6 +48,7 @@ private class PuzzleView : Gtk.DrawingArea
/* Animations duration */
private const double animation_duration = 0.25;
+ private const uint final_animation_duration = 250;
private const double half_animation_duration = 0.15;
/* Puzzle being rendered */
@@ -92,7 +93,7 @@ private class PuzzleView : Gtk.DrawingArea
/* Tile being controlled by the mouse */
private TileImage? selected_tile = null;
private TileImage? last_selected_tile = null;
- internal signal void tile_selected (bool selected);
+ [CCode (notify = true)] internal bool tile_selected { internal get; private set; default = false; }
/* Timeout to detect if a click is a selection or a drag */
private uint selection_timeout = 0;
@@ -321,7 +322,7 @@ private class PuzzleView : Gtk.DrawingArea
if (selected_tile != null)
((!) selected_tile).snap_to_cursor = true;
selected_tile = null;
- tile_selected (false);
+ tile_selected = false;
return false;
}
@@ -429,7 +430,7 @@ private class PuzzleView : Gtk.DrawingArea
{
selected_tile = image;
last_selected_tile = image;
- tile_selected (true);
+ tile_selected = true;
selected_x_offset = x - image.x;
selected_y_offset = y - image.y;
@@ -485,7 +486,7 @@ private class PuzzleView : Gtk.DrawingArea
move_tile_to_location ((!) selected_tile, selected_x, selected_y, animation_duration);
((!) selected_tile).snap_to_cursor = true;
selected_tile = null;
- tile_selected (false);
+ tile_selected = false;
}
private void move_tile_to_right_half (Tile tile)
@@ -536,14 +537,14 @@ private class PuzzleView : Gtk.DrawingArea
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));
+ puzzle.switch_tiles (selected_x, selected_y, x, y, final_animation_duration);
}
}
else
move_tile_to_right_half (((!) selected_tile).tile);
((!) selected_tile).snap_to_cursor = true;
selected_tile = null;
- tile_selected (false);
+ tile_selected = false;
}
}
@@ -622,4 +623,11 @@ private class PuzzleView : Gtk.DrawingArea
return false;
}
+
+ internal void finish ()
+ {
+ for (uint8 x = 0; x < puzzle.size; x++)
+ for (uint8 y = 0; y < puzzle.size; y++)
+ puzzle.switch_tiles (x + puzzle.size, y, x, y, final_animation_duration);
+ }
}
diff --git a/src/puzzle.vala b/src/puzzle.vala
index e3cc2c5..b0feb0f 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 solved_right (bool is_solved);
internal signal void show_end_game ();
internal signal void tick ();
@@ -157,7 +158,7 @@ private class Puzzle : Object
}
}
}
- private inline bool solved_on_right ()
+ private bool solved_on_right ()
{
for (uint8 x = size; x < 2 * size; x++)
{
@@ -234,6 +235,7 @@ private class Puzzle : Object
}
private uint timeout_id = 0;
+ internal bool is_solved_right { internal get; private set; default = false; }
internal void switch_tiles (uint8 x0, uint8 y0, uint8 x1, uint8 y1, uint delay_if_finished = 0)
{
if (x0 == x1 && y0 == y1)
@@ -262,6 +264,16 @@ private class Puzzle : Object
return Source.REMOVE;
});
}
+ else if (solved_on_right ())
+ {
+ is_solved_right = true;
+ solved_right (true);
+ }
+ else if (is_solved_right)
+ {
+ is_solved_right = false;
+ solved_right (false);
+ }
}
/*\
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]