[iagno] Introduce GameView.



commit 1ab832843d7514745a8a2cde7554436f85a2c7d3
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Sat Mar 2 15:38:43 2019 +0100

    Introduce GameView.
    
    That is needed for subclassing BaseWindow.

 data/iagno.css          |  30 +++++++++++++-
 data/ui/iagno.ui        |  30 ++------------
 src/game-headerbar.vala |  26 +++++++++---
 src/game-view.vala      | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/game-window.vala    |  81 ++++++++++--------------------------
 src/meson.build         |   1 +
 6 files changed, 181 insertions(+), 94 deletions(-)
---
diff --git a/data/iagno.css b/data/iagno.css
index c5209da..e60f627 100644
--- a/data/iagno.css
+++ b/data/iagno.css
@@ -25,7 +25,35 @@ button.unfullscreen-button {
   padding:1.5rem;
 }
 
-/* Labels' tweaks */
+/*\
+* * new-game screen generics
+\*/
+
+                               button.start-game-button { margin-top:1.5rem; margin-bottom:0.5rem;
+                                               transition:margin-top 0 ease, margin-bottom 0 ease; }
+                  .flat-window button.start-game-button { margin-top:0.5rem;                       }
+.extra-flat-window.flat-window button.start-game-button { margin-top:  0rem; margin-bottom:0.4rem; }
+
+.extra-thin-window             button.start-game-button { margin-top:1.0rem; }
+
+/*\
+* * options buttons
+\*/
+
+.extra-flat-window button.start-game-button {
+  min-height:2rem;
+}
+                   button.start-game-button {
+  min-height:3rem;
+  min-width:11rem;
+
+  transition:min-height          0.3s ease 0.01s;
+}
+
+/*\
+* * labels' tweaks
+\*/
+
 label.bold-label {
   font-weight: bold;
 }
diff --git a/data/ui/iagno.ui b/data/ui/iagno.ui
index 1c79eb6..71c0896 100644
--- a/data/ui/iagno.ui
+++ b/data/ui/iagno.ui
@@ -22,35 +22,11 @@
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="GameWindow" parent="GtkApplicationWindow">
+    <property name="width-request">600</property>
+    <property name="height-request">600</property>
     <child>
-      <object class="GtkOverlay">
+      <object class="GtkOverlay" id="main_overlay">
         <property name="visible">True</property>
-        <child>
-          <object class="GtkStack" id="stack">
-            <property name="visible">True</property>
-            <property name="homogeneous">True</property>
-            <child>
-              <object class="GtkBox" id="new_game_box">
-                <property name="orientation">vertical</property>
-                <property name="visible">True</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-                <property name="margin">25</property>
-                <property name="width-request">350</property>
-                <property name="height-request">350</property>
-                <property name="spacing">6</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkBox" id="view_box">
-                <property name="visible">True</property>
-                <style>
-                  <class name="main-box"/>
-                </style>
-              </object>
-            </child>
-          </object>
-        </child>
         <child type="overlay">
           <object class="GtkButton" id="unfullscreen_button">
             <property name="visible">False</property>
diff --git a/src/game-headerbar.vala b/src/game-headerbar.vala
index 87a37eb..f31094a 100644
--- a/src/game-headerbar.vala
+++ b/src/game-headerbar.vala
@@ -83,27 +83,41 @@ private class GameHeaderBar : HeaderBar
     * * showing the stack
     \*/
 
-    internal bool show_new_game_screen (bool game_finished)
+ // private bool current_view_is_new_game_screen = false;
+
+    internal /* grabs focus */ bool show_new_game_screen (bool game_finished)
     {
+     // current_view_is_new_game_screen = true;
+
         set_subtitle (null);      // TODO save / restore?
 
         new_game_button.hide ();
         history_button.hide ();
 
-        bool grab_focus = !game_finished && back_button.visible;
-        if (grab_focus)
+        if (!game_finished && back_button.visible)
+        {
             back_button.grab_focus ();
-        return grab_focus;
+            return true;
+        }
+        else
+            return false;
     }
 
-    internal void show_view (bool game_finished)
+    internal /* grabs focus */ bool show_view (bool game_finished)
     {
+     // current_view_is_new_game_screen = false;
+
         back_button.hide ();        // TODO transition?
-        new_game_button.show ();
+        new_game_button.show ();    // TODO transition?
         history_button.show ();
 
         if (game_finished)
+        {
             new_game_button.grab_focus ();
+            return true;
+        }
+        else
+            return false;
     }
 
     /*\
diff --git a/src/game-view.vala b/src/game-view.vala
new file mode 100644
index 0000000..ef8f021
--- /dev/null
+++ b/src/game-view.vala
@@ -0,0 +1,107 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+   This file is part of a GNOME game.
+
+   Copyright 2019 Arnaud Bonatti
+
+   This game is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This game is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this game.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+using Gtk;
+
+private class GameView : Grid
+{
+    private Stack           game_stack;
+    private Widget          game_content;
+    private ScrolledWindow  scrolled;
+    private Box             new_game_box;
+    private Button?         start_game_button = null;
+
+    construct
+    {
+        game_stack = new Stack ();
+        game_stack.hexpand = true;
+        game_stack.vexpand = true;
+        game_stack.show ();
+        this.add (game_stack);
+
+        scrolled = new ScrolledWindow (null, null);
+        scrolled.visible = true;
+        game_stack.add (scrolled);
+
+        new_game_box = new Box (Orientation.VERTICAL, /* spacing */ 0);
+        new_game_box.halign = Align.CENTER;
+        new_game_box.valign = Align.CENTER;
+        new_game_box.show ();
+        scrolled.add (new_game_box);
+    }
+
+    internal GameView (GameWindowFlags flags, Box new_game_screen, Widget content)
+    {
+        new_game_box.pack_start (new_game_screen, true, true, 0);
+
+        if (GameWindowFlags.SHOW_START_BUTTON in flags)
+        {
+            /* Translators: when configuring a new game, label of the blue Start button (with a mnemonic 
that appears pressing Alt) */
+            Button _start_game_button = new Button.with_mnemonic (_("_Start Game"));
+            _start_game_button.halign = Align.CENTER;
+            _start_game_button.set_action_name ("ui.start-game");
+
+            StyleContext context = _start_game_button.get_style_context ();
+            context.add_class ("start-game-button");
+            context.add_class ("suggested-action");
+            /* Translators: when configuring a new game, tooltip text of the blue Start button */
+            // _start_game_button.set_tooltip_text (_("Start a new game as configured"));
+            _start_game_button.show ();
+            new_game_box.pack_end (_start_game_button, false, false, 0);
+            start_game_button = _start_game_button;
+        }
+
+        game_content = content;
+        game_content.margin = 20;   // FIXME
+        game_stack.add (content);
+        content.can_focus = true;
+        content.show ();
+    }
+
+    internal void show_new_game_box (bool grab_focus)
+    {
+        game_stack.set_visible_child (scrolled);
+        if (grab_focus && start_game_button != null)
+            ((!) start_game_button).grab_focus ();
+        // TODO else if (grab_focus && start_game_button == null)
+    }
+
+    internal void show_game_content (bool grab_focus)
+    {
+        game_stack.set_visible_child (game_content);
+        if (grab_focus)
+            game_content.grab_focus ();
+    }
+
+    internal bool game_content_visible_if_true ()
+    {
+        Widget? visible_child = game_stack.get_visible_child ();
+        if (visible_child == null)
+            assert_not_reached ();
+        return (!) visible_child == game_content;
+    }
+
+    internal void configure_transition (StackTransitionType transition_type,
+                                        uint                transition_duration)
+    {
+        game_stack.set_transition_type (transition_type);
+        game_stack.set_transition_duration (transition_duration);
+    }
+}
diff --git a/src/game-window.vala b/src/game-window.vala
index 99a4f8b..bdca97b 100644
--- a/src/game-window.vala
+++ b/src/game-window.vala
@@ -43,13 +43,11 @@ private class GameWindow : ApplicationWindow
     private bool game_finished = false;
 
     /* private widgets */
-    [GtkChild] private Stack stack;
-    [GtkChild] private Box new_game_box;
-    [GtkChild] private Box view_box;
+    [GtkChild] private Overlay main_overlay;
     [GtkChild] private Button unfullscreen_button;
 
-    private GameHeaderBar headerbar;
-    private Button? start_game_button = null;
+    private GameHeaderBar   headerbar;
+    private GameView        game_view;
     private Widget view;
 
     /* signals */
@@ -82,7 +80,11 @@ private class GameWindow : ApplicationWindow
         headerbar.show ();
         set_titlebar (headerbar);
 
-        ((ReversiView) view).notify_final_animation.connect ((undoing) => { headerbar.update_history_button 
(!undoing); });
+        ((ReversiView) _view).notify_final_animation.connect ((undoing) => { headerbar.update_history_button 
(!undoing); });
+
+        game_view = new GameView (flags, new_game_screen, _view);
+        game_view.show ();
+        main_overlay.add (game_view);
 
         set_default_size (width, height);
         if (maximized)
@@ -91,30 +93,6 @@ private class GameWindow : ApplicationWindow
         size_allocate.connect (size_allocate_cb);
         window_state_event.connect (window_state_event_cb);
 
-        /* add widgets */
-        new_game_box.pack_start (new_game_screen, true, true, 0);
-        if (GameWindowFlags.SHOW_START_BUTTON in flags)
-        {
-            /* Translators: when configuring a new game, label of the blue Start button (with a mnemonic 
that appears pressing Alt) */
-            Button _start_game_button = new Button.with_mnemonic (_("_Start Game"));
-            _start_game_button.width_request = 222;
-            _start_game_button.height_request = 60;
-            _start_game_button.halign = Align.CENTER;
-            _start_game_button.set_action_name ("ui.start-game");
-            /* Translators: when configuring a new game, tooltip text of the blue Start button */
-            // _start_game_button.set_tooltip_text (_("Start a new game as configured"));
-            ((StyleContext) _start_game_button.get_style_context ()).add_class ("suggested-action");
-            _start_game_button.show ();
-            new_game_box.pack_end (_start_game_button, false, false, 0);
-            start_game_button = _start_game_button;
-        }
-
-        view_box.add (view);
-        stack.set_visible_child (view_box);
-        view.halign = Align.FILL;
-        view.can_focus = true;
-        view.show ();
-
         /* start or not */
         if (start_now)
             show_view ();
@@ -254,20 +232,14 @@ private class GameWindow : ApplicationWindow
 
     private void show_new_game_screen ()
     {
-        stack.set_visible_child (new_game_box);
-
-        bool headerbar_grabbed_focus = headerbar.show_new_game_screen (game_finished);
-        if (!headerbar_grabbed_focus && start_game_button != null)
-            ((!) start_game_button).grab_focus ();
+        bool grabs_focus = headerbar.show_new_game_screen (game_finished);
+        game_view.show_new_game_box (/* grab focus */ !grabs_focus);
     }
 
     private void show_view ()
     {
-        stack.set_visible_child (view_box);
-
-        headerbar.show_view (game_finished);
-        if (!game_finished)
-            view.grab_focus ();
+        bool grabs_focus = headerbar.show_view (game_finished);
+        game_view.show_game_content (/* grab focus */ !grabs_focus);
     }
 
     /*\
@@ -276,14 +248,12 @@ private class GameWindow : ApplicationWindow
 
     private void new_game_cb ()
     {
-        Widget? stack_child = stack.get_visible_child ();
-        if (stack_child == null || (!) stack_child != view_box)
+        if (!game_view.game_content_visible_if_true ())
             return;
 
         wait ();
 
-        stack.set_transition_type (StackTransitionType.SLIDE_LEFT);
-        stack.set_transition_duration (800);
+        game_view.configure_transition (StackTransitionType.SLIDE_LEFT, 800);
 
         headerbar.new_game ();
         back_action.set_enabled (true);
@@ -293,8 +263,7 @@ private class GameWindow : ApplicationWindow
 
     private void start_game_cb ()
     {
-        Widget? stack_child = stack.get_visible_child ();
-        if (stack_child == null || (!) stack_child != new_game_box)
+        if (game_view.game_content_visible_if_true ())
             return;
 
         game_finished = false;
@@ -306,19 +275,16 @@ private class GameWindow : ApplicationWindow
 
         play ();        // FIXME lag (see in Taquin…)
 
-        stack.set_transition_type (StackTransitionType.SLIDE_DOWN);
-        stack.set_transition_duration (1000);
+        game_view.configure_transition (StackTransitionType.SLIDE_DOWN, 1000);
         show_view ();
     }
 
     private void back_cb ()
     {
-        Widget? stack_child = stack.get_visible_child ();
-        if (stack_child == null || (!) stack_child != new_game_box)
+        if (game_view.game_content_visible_if_true ())
             return;
         // TODO change back headerbar subtitle?
-        stack.set_transition_type (StackTransitionType.SLIDE_RIGHT);
-        stack.set_transition_duration (800);
+        game_view.configure_transition (StackTransitionType.SLIDE_RIGHT, 800);
         show_view ();
 
         back ();
@@ -330,10 +296,7 @@ private class GameWindow : ApplicationWindow
 
     private void undo_cb ()
     {
-        Widget? stack_child = stack.get_visible_child ();
-        if (stack_child == null)
-            return;
-        if ((!) stack_child != view_box)
+        if (!game_view.game_content_visible_if_true ())
         {
             if (back_action.get_enabled ())
                 back_cb ();
@@ -350,8 +313,7 @@ private class GameWindow : ApplicationWindow
 
 /*    private void redo_cb ()
     {
-        Widget? stack_child = stack.get_visible_child ();
-        if (stack_child == null || (!) stack_child != view_box)
+        if (!game_view.game_content_visible_if_true ())
             return;
 
         if (!headerbar.back_button_is_focus ())
@@ -362,8 +324,7 @@ private class GameWindow : ApplicationWindow
 
 /*    private void hint_cb ()
     {
-        Widget? stack_child = stack.get_visible_child ();
-        if (stack_child == null || (!) stack_child != view_box)
+        if (!game_view.game_content_visible_if_true ())
             return;
         hint ();
     } */
diff --git a/src/meson.build b/src/meson.build
index 8ff7333..b79ce82 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -22,6 +22,7 @@ executable(meson.project_name(),
         'computer-player.vala',
         'computer-reversi.vala',
         'game-headerbar.vala',
+        'game-view.vala',
         'game-window.vala',
         'game.vala',
         'iagno.vala',


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