[lightsoff/arnaudb/rework-ui: 26/29] Add a restart action.




commit 0e8f5852f83fd323ce50770e9e47ede491467f74
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Sat Nov 21 12:10:33 2020 +0100

    Add a restart action.

 data/game-button.ui         | 19 +++++++++++++++++++
 data/lightsoff.css          |  6 ------
 data/lightsoff.ui           |  9 ++-------
 src/game-view-gtk.vala      |  9 +++++++--
 src/game-view.vala          | 23 ++++++++++++++++-------
 src/lightsoff-window.vala   | 46 ++++++++++++++++++++++++++++++++++++---------
 src/lightsoff.gresource.xml |  1 +
 src/lightsoff.vala          | 15 ++++++++++-----
 8 files changed, 92 insertions(+), 36 deletions(-)
---
diff --git a/data/game-button.ui b/data/game-button.ui
new file mode 100644
index 0000000..02d56a7
--- /dev/null
+++ b/data/game-button.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <menu id="restart-menu">
+    <section>
+      <item>
+        <!-- Translators: entry of the window menu (with a mnemonic that appears when pressing Alt); 
restarts current level  -->
+        <attribute name="label" translatable="yes">_Restart</attribute>
+        <attribute name="action">win.restart</attribute>
+      </item>
+    </section>
+  </menu>
+
+  <requires lib="gtk+" version="3.12"/>
+  <template class="GameButton" parent="GtkMenuButton">
+    <property name="valign">center</property>
+    <property name="label" translatable="no">0</property>
+    <property name="menu-model">restart-menu</property>
+  </template>
+</interface>
diff --git a/data/lightsoff.css b/data/lightsoff.css
index d948e58..07b4257 100644
--- a/data/lightsoff.css
+++ b/data/lightsoff.css
@@ -58,12 +58,6 @@ label.level-label:dir(ltr) {
 label.level-label:dir(rtl) {
   margin-right: 12px;
 }
-label.score-label:dir(rtl) {
-  margin-left : 6px;
-}
-label.score-label:dir(ltr) {
-  margin-right: 6px;
-}
 
 /*\
 * * app notification
diff --git a/data/lightsoff.ui b/data/lightsoff.ui
index 5a22f71..c96aed3 100644
--- a/data/lightsoff.ui
+++ b/data/lightsoff.ui
@@ -48,9 +48,8 @@
           </object>
         </child>
         <child>
-          <object class="GtkLabel" id="score_label_1">
+          <object class="GameButton" id="game_button_1">
             <property name="visible">True</property>
-            <property name="label" translatable="no">0</property>
           </object>
           <packing>
             <property name="pack_type">end</property>
@@ -112,12 +111,8 @@
                       </object>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="score_label_2">
+                      <object class="GameButton" id="game_button_2">
                         <property name="visible">True</property>
-                        <property name="label" translatable="no">0</property>
-                        <style>
-                          <class name="score-label"/>
-                        </style>
                       </object>
                       <packing>
                         <property name="pack_type">end</property>
diff --git a/src/game-view-gtk.vala b/src/game-view-gtk.vala
index f9e7766..bf8ec8d 100644
--- a/src/game-view-gtk.vala
+++ b/src/game-view-gtk.vala
@@ -19,9 +19,12 @@ private class GtkGameView : Stack, GameView
         transition_duration = fast ? 500 : 1000;
         switch (style)
         {
-            case REFRESH:
+            case RESTART:
                 transition_type = StackTransitionType.SLIDE_DOWN;
                 break;
+            case REFRESH:
+                transition_type = StackTransitionType.CROSSFADE;
+                break;
             case SLIDE_NEXT:
             case SLIDE_FORWARD:
                 transition_type = StackTransitionType.SLIDE_LEFT;
@@ -29,6 +32,8 @@ private class GtkGameView : Stack, GameView
             case SLIDE_BACKWARD:
                 transition_type = StackTransitionType.SLIDE_RIGHT;
                 break;
+            default:
+                assert_not_reached ();
         }
 
         add ((Widget)new_board);
@@ -69,7 +74,7 @@ private class GtkGameView : Stack, GameView
         if (is_transitioning())
             return;
 
-        replace_board (get_board_view (), create_board_view (1), GameView.ReplaceStyle.REFRESH);
+        replace_board (get_board_view (), create_board_view (1), GameView.ReplaceStyle.RESTART);
     }
 
     internal GtkGameView (int level)
diff --git a/src/game-view.vala b/src/game-view.vala
index 87e9ec4..cfcc31e 100644
--- a/src/game-view.vala
+++ b/src/game-view.vala
@@ -11,10 +11,11 @@
 private interface GameView : GLib.Object {
 
     internal enum ReplaceStyle {
-        REFRESH, // crossfade
-        SLIDE_FORWARD, // slide out-in
-        SLIDE_BACKWARD, // slide in-out
-        SLIDE_NEXT // slide over
+        REFRESH,        // crossfade
+        RESTART,        // slide down
+        SLIDE_FORWARD,  // slide left
+        SLIDE_BACKWARD, // slide right
+        SLIDE_NEXT      // slide left
     }
 
     internal abstract void replace_board (BoardView board_biew, BoardView new_board_view, ReplaceStyle 
style, bool fast = true);
@@ -37,9 +38,17 @@ private interface GameView : GLib.Object {
         if (is_transitioning ())
             return;
 
-        replace_board (get_board_view (), create_board_view (next_level (direction)),
-                       direction == 1 ? GameView.ReplaceStyle.SLIDE_FORWARD
-                                      : GameView.ReplaceStyle.SLIDE_BACKWARD);
+        ReplaceStyle style;
+        if (direction == 1)
+            style = GameView.ReplaceStyle.SLIDE_FORWARD;
+        else if (direction == 0)
+            style = GameView.ReplaceStyle.REFRESH;
+        else if (direction == -1)
+            style = GameView.ReplaceStyle.SLIDE_BACKWARD;
+        else
+            assert_not_reached ();
+
+        replace_board (get_board_view (), create_board_view (next_level (direction)), style);
     }
 
     // The player won the game; create a new board, update the level count,
diff --git a/src/lightsoff-window.vala b/src/lightsoff-window.vala
index ffa8b92..06dea3b 100644
--- a/src/lightsoff-window.vala
+++ b/src/lightsoff-window.vala
@@ -18,8 +18,8 @@ private class LightsoffWindow : ManagedWindow
     [GtkChild] private HeaderBar                headerbar;
     [GtkChild] private MenuButton               menu_button;
     [GtkChild] private Label                    level_label;
-    [GtkChild] private Label                    score_label_1;
-    [GtkChild] private Label                    score_label_2;
+    [GtkChild] private GameButton               game_button_1;
+    [GtkChild] private GameButton               game_button_2;
     [GtkChild] private AspectFrame              aspect_frame;
     [GtkChild] private Revealer                 revealer;
     [GtkChild] private NotificationsRevealer    notifications_revealer;
@@ -27,15 +27,20 @@ private class LightsoffWindow : ManagedWindow
     private GLib.Settings settings;
     private GameView game_view;
     private SimpleAction previous_level;
+    private SimpleAction restart_action;
     private EventControllerKey key_controller;
 
     private string custom_title = "";
 
     private const GLib.ActionEntry[] window_actions =
     {
-        { "new-game",       new_game_cb },
-        { "previous-level", previous_level_cb },
-        { "next-level",     next_level_cb }
+        // "Change Puzzle" menu
+        { "new-game",       new_game_cb         },
+        { "previous-level", previous_level_cb   },
+        { "next-level",     next_level_cb       },
+
+        // game menu
+        { "restart",        restart_cb          },
     };
 
     private inline void init_keyboard ()
@@ -72,6 +77,8 @@ private class LightsoffWindow : ManagedWindow
 
         add_action_entries (window_actions, this);
         previous_level = (SimpleAction) this.lookup_action ("previous-level");
+        restart_action = (SimpleAction) this.lookup_action ("restart");
+        enable_restart_action (false);
 
         init_keyboard ();
         int level = settings.get_int ("level");
@@ -89,8 +96,9 @@ private class LightsoffWindow : ManagedWindow
     private void update_subtitle (int moves)
     {
         string moves_string = moves.to_string ();
-        score_label_1.set_label (moves_string);
-        score_label_2.set_label (moves_string);
+        game_button_1.set_label (moves_string);
+        game_button_2.set_label (moves_string);
+        enable_restart_action (moves > 0);
     }
 
     private void update_title ()
@@ -102,6 +110,13 @@ private class LightsoffWindow : ManagedWindow
         notifications_revealer.hide_notification ();
     }
 
+    private void enable_restart_action (bool new_state)
+    {
+        restart_action.set_enabled (new_state);
+        game_button_1.set_sensitive (new_state);
+        game_button_2.set_sensitive (new_state);
+    }
+
     private void previous_level_cb ()
     {
         game_view.swap_board (-1);
@@ -112,9 +127,16 @@ private class LightsoffWindow : ManagedWindow
         game_view.swap_board (1);
     }
 
+    private void restart_cb ()
+    {
+        game_view.swap_board (0);
+        enable_restart_action (false);
+    }
+
     private void level_changed_cb (int level)
     {
         previous_level.set_enabled (level > 1);
+        enable_restart_action (false);
         /* Translators: the title of the window, %d is the level number */
         custom_title = _("Puzzle %d").printf (level);
         update_title ();
@@ -150,6 +172,7 @@ private class LightsoffWindow : ManagedWindow
     private void new_game_cb ()
     {
         game_view.reset_game ();
+        enable_restart_action (false);
     }
 
     bool large_window_size = true;
@@ -158,17 +181,22 @@ private class LightsoffWindow : ManagedWindow
         large_window_size = large;
         if (large)
         {
-            score_label_1.show ();
+            game_button_1.show ();
             headerbar.set_title (custom_title);
             revealer.set_reveal_child (false);
             notifications_revealer.set_window_size (/* thin */ false);
         }
         else
         {
-            score_label_1.hide ();
+            game_button_1.hide ();
             headerbar.set_title (null);
             revealer.set_reveal_child (true);
             notifications_revealer.set_window_size (/* thin */ true);
         }
     }
 }
+
+[GtkTemplate (ui = "/org/gnome/LightsOff/ui/game-button.ui")]
+private class GameButton : MenuButton
+{
+}
diff --git a/src/lightsoff.gresource.xml b/src/lightsoff.gresource.xml
index b57d791..561b044 100644
--- a/src/lightsoff.gresource.xml
+++ b/src/lightsoff.gresource.xml
@@ -5,6 +5,7 @@
     <file alias="lightsoff.css">../data/lightsoff.css</file>
     <file preprocess="xml-stripblanks" alias="menus.ui">../data/lightsoff-menus.ui</file>
     <file preprocess="xml-stripblanks" 
alias="notifications-revealer.ui">../data/notifications-revealer.ui</file>
+    <file preprocess="xml-stripblanks" alias="game-button.ui">../data/game-button.ui</file>
   </gresource>
 </gresources>
 
diff --git a/src/lightsoff.vala b/src/lightsoff.vala
index 577d86d..eab0ff0 100644
--- a/src/lightsoff.vala
+++ b/src/lightsoff.vala
@@ -88,12 +88,17 @@ private class LightsOff : Gtk.Application
 
         add_action_entries (action_entries, this);
 
-        set_accels_for_action ("app.quit", {"<control>Q"});
-        set_accels_for_action ("app.help", {"F1"});
+        // generic
+        set_accels_for_action ("app.quit",              { "<Primary>q"          });
+        set_accels_for_action ("app.help",              {          "F1"         });
 
-        set_accels_for_action ("win.new-game", {"<control>N"});
-        set_accels_for_action ("win.previous-level", {"<control>Page_Up"});
-        set_accels_for_action ("win.next-level", {"<control>Page_Down"});
+        // "Change Puzzle" menu
+        set_accels_for_action ("win.new-game",          { "<Primary>n"          });
+        set_accels_for_action ("win.previous-level",    { "<Primary>Page_Up"    });
+        set_accels_for_action ("win.next-level",        { "<Primary>Page_Down"  });
+
+        // game menu
+        set_accels_for_action ("win.restart",           { "<Primary>r"          });
 
         window = new LightsoffWindow ();
         add_window (window);


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