[gnome-taquin] Prepare for libgames-support.
- From: Arnaud Bonatti <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-taquin] Prepare for libgames-support.
- Date: Sun, 1 Mar 2015 04:45:13 +0000 (UTC)
commit 2a7e48b797e3e7ece0b299ba9ad46b3463e15bf3
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Sun Mar 1 05:40:32 2015 +0100
Prepare for libgames-support.
data/Makefile.am | 1 +
data/org.gnome.taquin.desktop.in | 1 -
data/taquin-menus.ui | 2 +
data/taquin-screens.ui | 123 ++++++++++++++
data/taquin.css | 2 +-
data/taquin.ui | 159 ++----------------
gnome-taquin.doap | 2 +
help/C/shortcuts.page | 13 ++
po/POTFILES.in | 2 +
src/Makefile.am | 2 +
src/game-window.vala | 338 ++++++++++++++++++++++++++++++++++++++
src/taquin-game.vala | 13 ++
src/taquin-main.vala | 225 ++++++++------------------
src/taquin.gresource.xml | 3 +-
14 files changed, 580 insertions(+), 306 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 39152f7..8137df1 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -4,6 +4,7 @@ SUBDIRS = \
dist_noinst_DATA = \
taquin-menus.ui \
+ taquin-screens.ui \
taquin.ui \
taquin.css \
schema-15.png \
diff --git a/data/org.gnome.taquin.desktop.in b/data/org.gnome.taquin.desktop.in
index 1b9db74..19cafa7 100644
--- a/data/org.gnome.taquin.desktop.in
+++ b/data/org.gnome.taquin.desktop.in
@@ -8,7 +8,6 @@ Terminal=false
Type=Application
Categories=GNOME;GTK;Game;LogicGame;
StartupNotify=true
-DBusActivatable=true
Actions=Fifteen;Sixteen;
[Desktop Action Fifteen]
diff --git a/data/taquin-menus.ui b/data/taquin-menus.ui
index 2bba404..68f3bbe 100644
--- a/data/taquin-menus.ui
+++ b/data/taquin-menus.ui
@@ -12,6 +12,7 @@
<item>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="action">app.help</attribute>
+ <attribute name="accel">F1</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About</attribute>
@@ -20,6 +21,7 @@
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
+ <attribute name="accel"><Primary>q</attribute>
</item>
</section>
</menu>
diff --git a/data/taquin-screens.ui b/data/taquin-screens.ui
new file mode 100644
index 0000000..b194c29
--- /dev/null
+++ b/data/taquin-screens.ui
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <menu id="size-menu"><!-- TODO 3/4/5 accels? -->
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">3 × 3</attribute>
+ <attribute name="action">app.change-size</attribute>
+ <attribute name="target">3</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">4 × 4</attribute>
+ <attribute name="action">app.change-size</attribute>
+ <attribute name="target">4</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">5 × 5</attribute>
+ <attribute name="action">app.change-size</attribute>
+ <attribute name="target">5</attribute>
+ </item>
+ </section>
+ </menu>
+ <menu id="theme-menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Cats</attribute>
+ <attribute name="action">app.change-theme</attribute>
+ <attribute name="target">cats</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Numbers</attribute>
+ <attribute name="action">app.change-theme</attribute>
+ <attribute name="target">numbers</attribute>
+ </item>
+ </section>
+ </menu>
+ <object class="GtkBox" id="new-game-screen">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="radio-fifteen">
+ <property name="visible">True</property>
+ <property name="name">radio-fifteen</property>
+ <style><class name="radio-like-toggle"/></style>
+ <property name="focus-on-click">False</property>
+ <property name="relief">none</property> <!-- could probably be replaced by a use of the "flat"
style-class -->
+ <property name="action-name">app.change-type</property>
+ <property name="action-target">'fifteen'</property>
+ <property name="draw-indicator">False</property>
+ <property name="label" translatable="yes">15-Puzzle</property>
+ <property name="width-request">197</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radio-sixteen">
+ <property name="visible">True</property>
+ <property name="name">radio-sixteen</property>
+ <style><class name="radio-like-toggle"/></style>
+ <property name="focus-on-click">False</property>
+ <property name="relief">none</property>
+ <property name="action-name">app.change-type</property>
+ <property name="action-target">'sixteen'</property>
+ <property name="group">radio-fifteen</property>
+ <property name="draw-indicator">False</property>
+ <property name="label" translatable="yes">16-Puzzle</property>
+ <property name="width-request">197</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkMenuButton" id="size-button">
+ <property name="visible">True</property>
+ <property name="use-underline">True</property>
+ <property name="menu-model">size-menu</property>
+ <property name="height-request">60</property>
+ <style><class name="menubutton-like-combo"/></style>
+ <property name="relief">none</property> <!-- could probably be replaced by a use of the "flat"
style-class -->
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="theme-button">
+ <property name="visible">True</property>
+ <property name="use-underline">True</property>
+ <property name="menu-model">theme-menu</property>
+ <property name="height-request">60</property>
+ <style><class name="menubutton-like-combo"/></style>
+ <property name="relief">none</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/data/taquin.css b/data/taquin.css
index 714e053..d3f5232 100644
--- a/data/taquin.css
+++ b/data/taquin.css
@@ -7,7 +7,7 @@ GtkRadioButton.radio-like-toggle#radio-sixteen {
GtkRadioButton.radio-like-toggle {
background-repeat: no-repeat;
- /* width is requested by the widget: 200 */
+ /* width is requested by the widget: 197 */
padding-top: 15px;
padding-bottom: 185px;
background-position: center 25px;
diff --git a/data/taquin.ui b/data/taquin.ui
index 77dcff7..3e5d383 100644
--- a/data/taquin.ui
+++ b/data/taquin.ui
@@ -1,68 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
- <menu id="size-menu">
- <section>
- <item>
- <attribute name="label" translatable="yes">3 × 3</attribute>
- <attribute name="action">win.change-size</attribute>
- <attribute name="target">3</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">4 × 4</attribute>
- <attribute name="action">win.change-size</attribute>
- <attribute name="target">4</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">5 × 5</attribute>
- <attribute name="action">win.change-size</attribute>
- <attribute name="target">5</attribute>
- </item>
- </section>
- </menu>
- <menu id="theme-menu">
- <section>
- <item>
- <attribute name="label" translatable="yes">Cats</attribute>
- <attribute name="action">win.change-theme</attribute>
- <attribute name="target">cats</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">Numbers</attribute>
- <attribute name="action">win.change-theme</attribute>
- <attribute name="target">numbers</attribute>
- </item>
- </section>
- </menu>
- <object class="GtkApplicationWindow" id="taquin-window">
+ <template class="GameWindow" parent="GtkApplicationWindow">
<!-- <initial-focus name="view"/> -->
- <property name="title" translatable="yes">Taquin</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">True</property>
<property name="show-close-button">True</property>
- <property name="title" translatable="yes">Taquin</property>
<child>
- <object class="GtkButton" id="undo-button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="valign">center</property>
- <property name="tooltip-text" translatable="yes">Undo your most recent move</property>
- <property name="can-focus">True</property>
- <property name="focus-on-click">False</property>
- <property name="action-name">win.undo</property>
- <style><class name="image-button"/></style>
- <child>
- <object class="GtkImage">
- <property name="icon-name">edit-undo-symbolic</property>
- <property name="visible">True</property>
- <property name="icon-size">1</property>
- </object>
- </child>
+ <object class="GtkBox" id="controls_box">
+ <property name="visible">False</property>
+ <property name="orientation">horizontal</property>
</object>
</child>
<child>
- <object class="GtkButton" id="back-button">
+ <object class="GtkButton" id="back_button">
<property name="visible">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
@@ -82,11 +34,11 @@
</object>
</child>
<child>
- <object class="GtkStack" id="main-stack">
+ <object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<child>
- <object class="GtkBox">
+ <object class="GtkBox" id="new_game_box">
<property name="orientation">vertical</property>
<property name="visible">True</property>
<property name="halign">center</property>
@@ -96,91 +48,11 @@
<property name="height-request">350</property>
<property name="spacing">6</property>
<child>
- <object class="GtkBox">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkRadioButton" id="radio-fifteen">
- <property name="visible">True</property>
- <property name="name">radio-fifteen</property>
- <style><class name="radio-like-toggle"/></style>
- <property name="focus-on-click">False</property>
- <property name="relief">none</property> <!-- could probably be replaced by a use of the
"flat" style-class -->
- <property name="action-name">win.change-type</property>
- <property name="action-target">'fifteen'</property>
- <property name="draw-indicator">False</property>
- <property name="label" translatable="yes">15-Puzzle</property>
- <property name="width-request">200</property>
- </object>
- </child>
- <child>
- <object class="GtkRadioButton" id="radio-sixteen">
- <property name="visible">True</property>
- <property name="name">radio-sixteen</property>
- <style><class name="radio-like-toggle"/></style>
- <property name="focus-on-click">False</property>
- <property name="relief">none</property>
- <property name="action-name">win.change-type</property>
- <property name="action-target">'sixteen'</property>
- <property name="group">radio-fifteen</property>
- <property name="draw-indicator">False</property>
- <property name="label" translatable="yes">16-Puzzle</property>
- <property name="width-request">200</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkMenuButton" id="size-button">
- <property name="visible">True</property>
- <property name="use-underline">True</property>
- <property name="menu-model">size-menu</property>
- <property name="height-request">60</property>
- <style><class name="menubutton-like-combo"/></style>
- <property name="relief">none</property> <!-- could probably be replaced by a use of the
"flat" style-class -->
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkMenuButton" id="theme-button">
- <property name="visible">True</property>
- <property name="use-underline">True</property>
- <property name="menu-model">theme-menu</property>
- <property name="height-request">60</property>
- <style><class name="menubutton-like-combo"/></style>
- <property name="relief">none</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="start-game-button">
+ <object class="GtkButton" id="start_game_button">
<property name="visible">True</property>
<property name="use-underline">True</property>
<property name="label" translatable="yes">_Start Game</property>
+ <property name="tooltip-text" translatable="yes">Start a new game as configured</property>
<property name="action-name">win.start-game</property>
<property name="width-request">222</property>
<property name="height-request">60</property>
@@ -188,6 +60,7 @@
<style><class name="suggested-action"/></style>
</object>
<packing>
+ <property name="pack-type">end</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
@@ -205,23 +78,21 @@
<property name="ratio">1.4</property>
<property name="margin">25</property>
<child>
- <object class="GtkBox" id="game-box">
+ <object class="GtkBox" id="game_box">
<property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">25</property>
<child>
- <placeholder/>
- </child>
- <child>
- <object class="GtkBox">
+ <object class="GtkBox" id="side_box">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
- <object class="GtkButton" id="start-over-button">
+ <object class="GtkButton" id="new_game_button">
<property name="visible">True</property>
<property name="use-underline">True</property>
<property name="label" translatable="yes">_Start Over</property>
+ <property name="tooltip-text" translatable="yes">Configure a new game</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="action-name">win.new-game</property>
@@ -254,5 +125,5 @@
</child>
</object>
</child>
- </object>
+ </template>
</interface>
diff --git a/gnome-taquin.doap b/gnome-taquin.doap
index c1c1ff0..397f184 100644
--- a/gnome-taquin.doap
+++ b/gnome-taquin.doap
@@ -1,3 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
diff --git a/help/C/shortcuts.page b/help/C/shortcuts.page
index 3f88539..19d825d 100644
--- a/help/C/shortcuts.page
+++ b/help/C/shortcuts.page
@@ -62,6 +62,19 @@
</tr>
</table>
</section>
+ <section id="start-screen">
+ <title>Start Screen shortcuts</title>
+ <table frame="all" rules="cols" shade="rows">
+ <tr>
+ <td><p>New Game</p></td>
+ <td><p><keyseq><key>Ctrl</key><key>Shift</key><key>N</key></keyseq></p></td>
+ </tr>
+ <tr>
+ <td><p>Back to previous game (if any)</p></td>
+ <td><p><key>Escape</key></p></td>
+ </tr>
+ </table>
+ </section>
<section id="general">
<title>General shortcuts</title>
<table frame="all" rules="cols" shade="rows">
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 80dd365..1f2a24b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,10 +2,12 @@
# Please keep this file in alphabetical order.
[encoding: UTF-8]
[type: gettext/glade]data/taquin-menus.ui
+[type: gettext/glade]data/taquin-screens.ui
[type: gettext/glade]data/taquin.ui
data/org.gnome.taquin.appdata.xml.in
data/org.gnome.taquin.desktop.in
data/org.gnome.taquin.gschema.xml
+src/game-window.vala
src/taquin-main.vala
src/taquin-game.vala
src/taquin-view.vala
diff --git a/src/Makefile.am b/src/Makefile.am
index 7aa35a5..e6192d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,6 +3,7 @@ bin_PROGRAMS = gnome-taquin
BUILT_SOURCES = taquin-resources.c
gnome_taquin_SOURCES = \
+ game-window.vala \
taquin-main.vala \
taquin-view.vala \
taquin-game.vala \
@@ -24,6 +25,7 @@ gnome_taquin_VALAFLAGS = \
--pkg librsvg-2.0 \
--pkg libcanberra \
--pkg libcanberra-gtk \
+ --gresources taquin.gresource.xml \
--target-glib $(GLIB_REQUIRED)
gnome_taquin_LDADD = $(GNOME_TAQUIN_LIBS)
diff --git a/src/game-window.vala b/src/game-window.vala
new file mode 100644
index 0000000..c75ffce
--- /dev/null
+++ b/src/game-window.vala
@@ -0,0 +1,338 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright (C) 2015 Arnaud Bonatti <arnaud bonatti gmail com>
+ *
+ * This file is part of a GNOME game.
+ *
+ * This application 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 application 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 application. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Gtk;
+
+[Flags]
+public enum GameWindowFlags {
+ SHOW_UNDO,
+ SHOW_REDO,
+ SHOW_HINT;
+}
+
+[GtkTemplate (ui = "/org/gnome/taquin/ui/game-window.ui")]
+public class GameWindow : ApplicationWindow
+{
+ /* settings */
+ private bool tiled_state;
+ private bool maximized_state;
+ private int window_width;
+ private int window_height;
+
+ private bool game_finished = false;
+
+ /* private widgets */
+ [GtkChild]
+ private HeaderBar headerbar;
+ [GtkChild]
+ private Stack stack;
+
+ [GtkChild]
+ private Button new_game_button;
+ [GtkChild]
+ private Button start_game_button;
+ [GtkChild]
+ private Button back_button;
+
+ [GtkChild]
+ private Box controls_box;
+ [GtkChild]
+ private Box game_box;
+ [GtkChild]
+ private Box new_game_box;
+ [GtkChild]
+ private Box side_box;
+
+ private Widget view;
+
+ /* signals */
+ public signal void play ();
+ public signal void wait ();
+ public signal void back ();
+
+ public signal void undo ();
+ public signal void redo ();
+ public signal void hint ();
+
+ /* actions */
+ private const GLib.ActionEntry win_actions[] =
+ {
+ { "new-game", new_game_cb },
+ { "start-game", start_game_cb },
+ { "back", back_cb },
+
+ { "undo", undo_cb },
+ { "redo", redo_cb },
+ { "hint", hint_cb }
+ };
+
+ private SimpleAction back_action;
+
+ public SimpleAction undo_action;
+ public SimpleAction redo_action;
+
+ public GameWindow (string name, int width, int height, bool maximized, bool start_now, GameWindowFlags
flags, Box new_game_screen, Widget _view)
+ {
+ view = _view;
+
+ /* window actions */
+ add_action_entries (win_actions, this);
+
+ back_action = (SimpleAction) lookup_action ("back");
+ undo_action = (SimpleAction) lookup_action ("undo");
+ redo_action = (SimpleAction) lookup_action ("redo");
+
+ back_action.set_enabled (false);
+ undo_action.set_enabled (false);
+ redo_action.set_enabled (false);
+
+ /* window config */
+ set_title (name);
+ headerbar.set_title (name);
+
+ set_default_size (width, height);
+ if (maximized)
+ maximize ();
+
+ 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);
+
+ game_box.pack_start (view, true, true, 0);
+ game_box.set_focus_child (view); // TODO test if necessary; note: view could grab focus
from application
+ view.halign = Align.FILL;
+ view.can_focus = true;
+ view.show ();
+
+ /* add controls */
+ if (GameWindowFlags.SHOW_UNDO in flags)
+ {
+ Box history_box = new Box (Orientation.HORIZONTAL, 0);
+ history_box.get_style_context ().add_class ("linked");
+
+ Button undo_button = new Button.from_icon_name ("edit-undo-symbolic", Gtk.IconSize.BUTTON);
+ undo_button.action_name = "win.undo";
+ undo_button.set_tooltip_text (_("Undo your most recent move"));
+ undo_button.show ();
+ history_box.pack_start (undo_button, true, true, 0);
+
+ /* if (GameWindowFlags.SHOW_REDO in flags)
+ {
+ Button redo_button = new Button.from_icon_name ("edit-redo-symbolic", Gtk.IconSize.BUTTON);
+ redo_button.action_name = "app.redo";
+ redo_button.set_tooltip_text (_("Redo your most recent undone move"));
+ redo_button.show ();
+ history_box.pack_start (redo_button, true, true, 0);
+ } */
+
+ history_box.show ();
+ controls_box.pack_start (history_box, true, true, 0);
+ }
+ /* if (GameWindowFlags.SHOW_HINT in flags)
+ {
+ Button hint_button = new Button.from_icon_name ("dialog-question-symbolic", Gtk.IconSize.BUTTON);
+ hint_button.action_name = "app.hint";
+ hint_button.set_tooltip_text (_("Receive a hint for your next move"));
+ hint_button.show ();
+ controls_box.pack_start (hint_button, true, true, 0);
+ } */
+
+ /* start or not */
+ if (start_now)
+ show_view ();
+ else
+ show_new_game_screen ();
+ }
+
+ /*\
+ * * Window events
+ \*/
+
+ private void size_allocate_cb (Allocation allocation)
+ {
+ if (maximized_state || tiled_state)
+ return;
+ window_width = allocation.width;
+ window_height = allocation.height;
+ }
+
+ private bool window_state_event_cb (Gdk.EventWindowState event)
+ {
+ if ((event.changed_mask & Gdk.WindowState.MAXIMIZED) != 0)
+ maximized_state = (event.new_window_state & Gdk.WindowState.MAXIMIZED) != 0;
+ /* We don’t save this state, but track it for saving size allocation */
+ if ((event.changed_mask & Gdk.WindowState.TILED) != 0)
+ tiled_state = (event.new_window_state & Gdk.WindowState.TILED) != 0;
+ return false;
+ }
+
+ public void save_state (GLib.Settings settings)
+ {
+ settings.set_int ("window-width", window_width);
+ settings.set_int ("window-height", window_height);
+ settings.set_boolean ("window-is-maximized", maximized_state);
+ }
+
+ /*\
+ * * Some public calls
+ \*/
+
+ public void add_to_sidebox (Widget widget)
+ {
+ side_box.pack_start (widget, false, false, 0);
+ }
+
+ public void cannot_undo_more ()
+ {
+ undo_action.set_enabled (false);
+ view.grab_focus ();
+ }
+
+ public void set_subtitle (string? subtitle)
+ {
+ headerbar.set_subtitle (subtitle);
+ }
+
+ public void finish_game ()
+ {
+ game_finished = true;
+ new_game_button.grab_focus ();
+ }
+
+ /* public void about ()
+ {
+ TODO
+ } */
+
+ /*\
+ * * Showing the Stack
+ \*/
+
+ private void show_new_game_screen ()
+ {
+ headerbar.set_subtitle (null); // TODO save / restore?
+
+ stack.set_visible_child_name ("start-box");
+ controls_box.hide ();
+
+ if (!game_finished && back_button.visible)
+ back_button.grab_focus ();
+ else
+ start_game_button.grab_focus ();
+ }
+
+ private void show_view ()
+ {
+ stack.set_visible_child_name ("frame");
+ back_button.hide (); // TODO transition?
+ controls_box.show ();
+
+ if (game_finished)
+ new_game_button.grab_focus ();
+ else
+ view.grab_focus ();
+ }
+
+ /*\
+ * * Switching the Stack
+ \*/
+
+ private void new_game_cb ()
+ {
+ if (stack.get_visible_child_name () != "frame")
+ return;
+
+ wait ();
+
+ stack.set_transition_type (StackTransitionType.SLIDE_LEFT);
+ stack.set_transition_duration (800);
+
+ back_button.show ();
+ back_action.set_enabled (true);
+
+ show_new_game_screen ();
+ }
+
+ private void start_game_cb ()
+ {
+ if (stack.get_visible_child_name () != "start-box")
+ return;
+
+ game_finished = false;
+
+ undo_action.set_enabled (false);
+ redo_action.set_enabled (false);
+
+ play (); // FIXME lag (see in Taquin…)
+
+ stack.set_transition_type (StackTransitionType.SLIDE_DOWN);
+ stack.set_transition_duration (1000);
+ show_view ();
+ }
+
+ private void back_cb ()
+ {
+ if (stack.get_visible_child_name () != "start-box")
+ return;
+ // TODO change back headerbar subtitle?
+ stack.set_transition_type (StackTransitionType.SLIDE_RIGHT);
+ stack.set_transition_duration (800);
+ show_view ();
+
+ back ();
+ }
+
+ /*\
+ * * Controls_box actions
+ \*/
+
+ private void undo_cb ()
+ {
+ if (stack.get_visible_child_name () != "frame")
+ return;
+
+ game_finished = false;
+
+ if (new_game_button.is_focus)
+ view.grab_focus();
+ redo_action.set_enabled (true);
+ undo ();
+ }
+
+ private void redo_cb ()
+ {
+ if (stack.get_visible_child_name () != "frame")
+ return;
+
+ if (new_game_button.is_focus)
+ view.grab_focus();
+ undo_action.set_enabled (true);
+ redo ();
+ }
+
+ private void hint_cb ()
+ {
+ if (stack.get_visible_child_name () != "frame")
+ return;
+ hint ();
+ }
+}
diff --git a/src/taquin-game.vala b/src/taquin-game.vala
index 5d93867..1e33a59 100644
--- a/src/taquin-game.vala
+++ b/src/taquin-game.vala
@@ -22,6 +22,19 @@ public enum GameType
{
FIFTEEN,
SIXTEEN;
+
+ public string to_string ()
+ {
+ switch (this)
+ {
+ case FIFTEEN:
+ return "fifteen";
+ case SIXTEEN:
+ return "sixteen";
+ default:
+ assert_not_reached ();
+ }
+ }
}
public class Game : Object
diff --git a/src/taquin-main.vala b/src/taquin-main.vala
index 21f441e..3de8b00 100644
--- a/src/taquin-main.vala
+++ b/src/taquin-main.vala
@@ -1,6 +1,6 @@
/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
- * Copyright (C) 2014 Arnaud Bonatti <arnaud bonatti gmail com>
+ * Copyright (C) 2014-2015 Arnaud Bonatti <arnaud bonatti gmail com>
*
* This file is part of Taquin.
*
@@ -24,34 +24,22 @@ public class Taquin : Gtk.Application
{
/* Settings */
private GLib.Settings settings;
- private bool is_tiled;
- private bool is_maximized;
- private int window_width;
- private int window_height;
private static int tmp_size = 0;
- private string tmp_type;
+ private GameType? tmp_type = null;
private bool type_changed = false;
private bool size_changed = false;
private bool theme_changed = false;
private static bool? sound = null;
/* Widgets */
- private ApplicationWindow window;
- private HeaderBar headerbar;
- private Button back_button;
- private Button undo_button;
- private Button start_game_button;
- private Button start_over_button;
- private Stack stack;
+ private GameWindow window;
private MenuButton size_button;
private MenuButton theme_button;
private TaquinView view;
/* The game being played */
private Game? game = null;
- private SimpleAction undo_action;
List<string> theme_dirlist;
- private bool game_finished = false;
private static const OptionEntry[] option_entries =
{
@@ -67,16 +55,6 @@ public class Taquin : Gtk.Application
private const GLib.ActionEntry app_actions[] =
{
- {"help", help_cb},
- {"about", about_cb},
- {"quit", quit}
- };
- private const GLib.ActionEntry win_actions[] =
- {
- {"new-game", new_game_cb},
- {"start-game", start_game_cb},
- {"back", back_cb},
-
/* {"change-type", null, "s", null, null, change_type_cb}, TODO SimpleActionChangeStateCallback is
deprecated...
{"change-size", null, "s", null, null, change_size_cb},
http://valadoc.org/#!api=gio-2.0/GLib.SimpleActionChangeStateCallback
{"change-theme", null, "s", null, null, change_theme_cb}, see comments about window.add_action
(settings.create_action (…)) */
@@ -85,7 +63,9 @@ public class Taquin : Gtk.Application
{"change-size", change_size_cb, "s"},
{"change-theme", change_theme_cb, "s"},
- {"undo", undo_cb}
+ {"help", help_cb},
+ {"about", about_cb},
+ {"quit", quit}
};
public static int main (string[] args)
@@ -96,7 +76,6 @@ public class Taquin : Gtk.Application
Intl.textdomain (GETTEXT_PACKAGE);
Environment.set_application_name (_("Taquin"));
-
Window.set_default_icon_name ("gnome-taquin");
return new Taquin ().run (args);
@@ -121,15 +100,15 @@ public class Taquin : Gtk.Application
if (tmp_size != 0 && tmp_size < 2)
tmp_size = 2;
- if (options.contains ("unmute"))
- sound = true;
if (options.contains ("mute"))
sound = false;
+ else if (options.contains ("unmute"))
+ sound = true;
if (options.contains ("fifteen"))
- tmp_type = "fifteen";
+ tmp_type = GameType.FIFTEEN;
else if (options.contains ("sixteen"))
- tmp_type = "sixteen";
+ tmp_type = GameType.SIXTEEN;
return -1;
}
@@ -138,7 +117,7 @@ public class Taquin : Gtk.Application
{
base.startup ();
- var css_provider = new CssProvider ();
+ CssProvider css_provider = new CssProvider ();
css_provider.load_from_resource ("/org/gnome/taquin/ui/taquin.css");
StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), css_provider,
STYLE_PROVIDER_PRIORITY_APPLICATION);
@@ -148,36 +127,34 @@ public class Taquin : Gtk.Application
if (tmp_size > 1)
settings.set_int ("size", tmp_size);
if (tmp_type != null)
- settings.set_string ("type", tmp_type);
+ settings.set_string ("type", tmp_type.to_string()); // TODO better?
- var builder = new Builder.from_resource ("/org/gnome/taquin/ui/taquin.ui");
- window = builder.get_object ("taquin-window") as ApplicationWindow;
- window.size_allocate.connect (size_allocate_cb);
- window.window_state_event.connect (window_state_event_cb);
- window.set_default_size (settings.get_int ("window-width"), settings.get_int ("window-height"));
- if (settings.get_boolean ("window-is-maximized"))
- window.maximize ();
+ /* UI parts */
+ view = new TaquinView ();
- add_action_entries (app_actions, this);
- window.add_action_entries (win_actions, this);
- undo_action = (SimpleAction) window.lookup_action ("undo");
- // TODO window.add_action (settings.create_action ("type")); // Problem: same bug as in
Iagno, the settings are resetted to the first radiobutton found
- // TODO window.add_action (settings.create_action ("size")); // Problem: cannot use this way
for an integer from a menu; works for radiobuttons in Iagno
- // TODO window.add_action (settings.create_action ("theme")); // Problem: a bug that exists in
the three tries, and in Iagno: you cannot manually change the gsetting or it bugs completely (gsetting
between two states)
- set_accels_for_action ("app.help", {"F1"});
- set_accels_for_action ("app.quit", {"<Primary>q"});
+ Builder builder = new Builder.from_resource ("/org/gnome/taquin/ui/taquin-screens.ui");
+
+ /* Window */
+ window = new GameWindow (_("Taquin"),
+ settings.get_int ("window-width"),
+ settings.get_int ("window-height"),
+ settings.get_boolean ("window-is-maximized"),
+ true, // TODO add an option to go to new-game screen?
+ GameWindowFlags.SHOW_UNDO,
+ (Box) builder.get_object ("new-game-screen"),
+ view);
+ window.play.connect (start_game);
+ window.undo.connect (undo_cb);
+
+ // TODO use UI file?
set_accels_for_action ("win.new-game", {"<Primary>n"});
+ set_accels_for_action ("win.start-game", {"<Primary><Shift>n"});
set_accels_for_action ("win.undo", {"<Primary>z"});
- add_action (settings.create_action ("sound"));
+ set_accels_for_action ("win.redo", {"<Primary><Shift>z"});
+ set_accels_for_action ("win.back", {"Escape"});
- headerbar = builder.get_object ("headerbar") as HeaderBar;
- back_button = builder.get_object ("back-button") as Button;
- undo_button = builder.get_object ("undo-button") as Button;
- start_game_button = builder.get_object ("start-game-button") as Button;
- start_over_button = builder.get_object ("start-over-button") as Button;
- stack = builder.get_object ("main-stack") as Stack;
-
- size_button = builder.get_object ("size-button") as MenuButton;
+ /* New-game screen signals */
+ size_button = (MenuButton) builder.get_object ("size-button");
settings.changed["size"].connect (() => {
if (!size_changed)
update_size_button_label (settings.get_int ("size"));
@@ -185,7 +162,7 @@ public class Taquin : Gtk.Application
});
update_size_button_label (settings.get_int ("size"));
- theme_button = builder.get_object ("theme-button") as MenuButton;
+ theme_button = (MenuButton) builder.get_object ("theme-button");
settings.changed["theme"].connect (() => {
if (!theme_changed)
update_theme (settings.get_string ("theme"));
@@ -204,14 +181,15 @@ public class Taquin : Gtk.Application
var button_name = "radio-" + settings.get_string ("type");
((RadioButton) builder.get_object (button_name)).set_active (true);
- var game_box = builder.get_object ("game-box") as Box;
- view = new TaquinView ();
- view.halign = Align.FILL;
- view.show ();
- game_box.pack_start (view, true, true, 0);
+ add_action_entries (app_actions, this);
+ add_action (settings.create_action ("sound"));
+ // TODO window.add_action (settings.create_action ("type")); // Problem: same bug as in
Iagno, the settings are resetted to the first radiobutton found
+ // TODO window.add_action (settings.create_action ("size")); // Problem: cannot use this way
for an integer from a menu; works for radiobuttons in Iagno
+ // TODO window.add_action (settings.create_action ("theme")); // Problem: a bug that exists in
the three tries, and in Iagno: you cannot manually change the gsetting or it bugs completely (gsetting
between two states)
- add_window (window);
start_game ();
+
+ add_window (window);
}
protected override void activate ()
@@ -222,73 +200,7 @@ public class Taquin : Gtk.Application
protected override void shutdown ()
{
base.shutdown ();
-
- /* Save window state; don’t try to query it here */
- settings.set_int ("window-width", window_width);
- settings.set_int ("window-height", window_height);
- settings.set_boolean ("window-is-maximized", is_maximized);
- }
-
- /*\
- * * Window events
- \*/
-
- private void size_allocate_cb (Allocation allocation)
- {
- if (is_maximized || is_tiled)
- return;
- window_width = allocation.width;
- window_height = allocation.height;
- }
-
- private bool window_state_event_cb (Gdk.EventWindowState event)
- {
- if ((event.changed_mask & Gdk.WindowState.MAXIMIZED) != 0)
- is_maximized = (event.new_window_state & Gdk.WindowState.MAXIMIZED) != 0;
- /* We don’t save this state, but track it for saving size allocation */
- if ((event.changed_mask & Gdk.WindowState.TILED) != 0)
- is_tiled = (event.new_window_state & Gdk.WindowState.TILED) != 0;
- return false;
- }
-
- /*\
- * * Switching the Stack
- \*/
-
- private void new_game_cb ()
- {
- headerbar.set_subtitle (null);
- stack.set_transition_type (StackTransitionType.SLIDE_LEFT);
- stack.set_transition_duration (800);
- undo_button.hide ();
- stack.set_visible_child_name ("start-box");
- back_button.show ();
- if (undo_action.enabled)
- back_button.grab_focus ();
- else
- start_game_button.grab_focus ();
- }
-
- private void back_cb ()
- {
- stack.set_transition_type (StackTransitionType.SLIDE_RIGHT);
- stack.set_transition_duration (800);
- back_button.hide ();
- stack.set_visible_child_name ("frame");
- undo_button.show ();
- if (game_finished)
- start_over_button.grab_focus (); // TODO change headerbar subtitle?
- else
- view.grab_focus ();
- }
-
- private void start_game_cb ()
- {
- stack.set_transition_type (StackTransitionType.SLIDE_DOWN);
- stack.set_transition_duration (1500);
- back_button.hide ();
- start_game ();
- undo_button.show ();
+ window.save_state (settings);
}
/*\
@@ -300,32 +212,27 @@ public class Taquin : Gtk.Application
if (game != null)
SignalHandler.disconnect_by_func (game, null, this);
- undo_action.set_enabled (false);
- game_finished = false;
-
- var type = (GameType) settings.get_enum ("type");
- var size = settings.get_int ("size");
+ GameType type = (GameType) settings.get_enum ("type");
+ int size = settings.get_int ("size");
game = new Game (type, size);
view.game = game;
- view.grab_focus ();
- var filename = "";
+ string filename = "";
var dirlist = theme_dirlist.copy ();
do
{
- var random = Random.int_range (0, (int) dirlist.length());
+ int random = Random.int_range (0, (int) dirlist.length());
filename = dirlist.nth_data(random);
unowned List<string> entry = dirlist.find_custom (filename, strcmp);
dirlist.remove_link (entry);
} while (filename[0] == '0' || (filename[0] != '1' && filename[0] != size.to_string ()[0] &&
dirlist.length () != 0));
view.theme = Path.build_filename (DATA_DIRECTORY, "themes", settings.get_string ("theme"), filename);
+ view.realize (); // TODO does that help?
game.complete.connect (game_complete_cb);
game.cannot_move.connect (cannot_move_cb);
- game.cannot_undo_more.connect (cannot_undo_more_cb);
+ game.cannot_undo_more.connect (window.cannot_undo_more);
game.move.connect (move_cb);
-
- stack.set_visible_child_name ("frame"); // FIXME lag…
}
/*\
@@ -346,7 +253,7 @@ public class Taquin : Gtk.Application
show_about_dialog (window,
"name", _("Taquin"),
"version", VERSION,
- "copyright", "Copyright © 2014 Arnaud Bonatti",
+ "copyright", "Copyright © 2014-2015 Arnaud Bonatti",
"license-type", License.GPL_3_0,
"comments", _("A classic 15-puzzle game"),
"authors", authors,
@@ -371,7 +278,7 @@ public class Taquin : Gtk.Application
}
/*\
- * * Undoing and signals from game
+ * * Signals from window
\*/
private void undo_cb ()
@@ -380,27 +287,27 @@ public class Taquin : Gtk.Application
play_sound ("sliding-1");
}
- private void cannot_undo_more_cb ()
- {
- undo_action.set_enabled (false);
- view.grab_focus ();
- }
+ /*\
+ * * Signals from game
+ \*/
+
private void move_cb ()
{
- headerbar.set_subtitle (null);
- undo_action.set_enabled (true);
- play_sound ("sliding-1");
+ window.set_subtitle (null);
+ window.undo_action.set_enabled (true);
+ play_sound ("sliding-1"); // TODO sliding-n??
}
+
private void cannot_move_cb ()
{
- headerbar.set_subtitle (_("You can’t move this tile!"));
+ window.set_subtitle (_("You can’t move this tile!"));
}
+
private void game_complete_cb ()
{
- game_finished = true;
- start_over_button.grab_focus ();
- headerbar.set_subtitle (_("Bravo! You finished the game!"));
- undo_action.set_enabled (false);
+ window.finish_game ();
+ window.set_subtitle (_("Bravo! You finished the game!"));
+ window.undo_action.set_enabled (false); // Taquin specific
play_sound ("gameover");
}
@@ -417,7 +324,7 @@ public class Taquin : Gtk.Application
private void change_size_cb (SimpleAction action, Variant? variant)
{
size_changed = true;
- var size = int.parse (variant.get_string ());
+ int size = int.parse (variant.get_string ());
update_size_button_label (size);
settings.set_int ("size", size);
}
@@ -429,7 +336,7 @@ public class Taquin : Gtk.Application
private void change_theme_cb (SimpleAction action, Variant? variant)
{
theme_changed = true;
- var name = variant.get_string ();
+ string name = variant.get_string ();
update_theme (name);
settings.set_string ("theme", name);
}
diff --git a/src/taquin.gresource.xml b/src/taquin.gresource.xml
index d1d1582..03f9198 100644
--- a/src/taquin.gresource.xml
+++ b/src/taquin.gresource.xml
@@ -5,7 +5,8 @@
<file preprocess="to-pixdata" alias="16-Puzzle.png">../data/schema-16.png</file>
</gresource>
<gresource prefix="/org/gnome/taquin/ui">
- <file preprocess="xml-stripblanks" alias="taquin.ui">../data/taquin.ui</file>
+ <file preprocess="xml-stripblanks" alias="game-window.ui">../data/taquin.ui</file>
+ <file preprocess="xml-stripblanks" alias="taquin-screens.ui">../data/taquin-screens.ui</file>
<file alias="taquin.css">../data/taquin.css</file>
</gresource>
<gresource prefix="/org/gnome/taquin/gtk">
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]