[iagno] Prepare for libgames-support.
- From: Arnaud Bonatti <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [iagno] Prepare for libgames-support.
- Date: Sun, 1 Mar 2015 04:44:53 +0000 (UTC)
commit a6cc42de036f670062b20755802a5e7f507e7fce
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Sun Mar 1 05:40:49 2015 +0100
Prepare for libgames-support.
data/Makefile.am | 1 +
data/iagno-screens.ui | 237 +++++++++++++++++++++++++++++++++
data/iagno.ui | 330 ++++++----------------------------------------
po/POTFILES.in | 2 +
src/Makefile.am | 7 +-
src/game-window.vala | 338 +++++++++++++++++++++++++++++++++++++++++++++++
src/iagno.gresource.xml | 3 +-
src/iagno.vala | 251 +++++++++++++----------------------
8 files changed, 712 insertions(+), 457 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 51c6360..7efacf4 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -3,6 +3,7 @@ SUBDIRS = \
themes
dist_noinst_DATA = \
+ iagno-screens.ui \
iagno-themes.ui \
iagno-menus.ui \
iagno.ui \
diff --git a/data/iagno-screens.ui b/data/iagno-screens.ui
new file mode 100644
index 0000000..3a7c8b9
--- /dev/null
+++ b/data/iagno-screens.ui
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <object class="GtkBox" id="new-game-screen">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="valign">fill</property>
+ <property name="spacing">18</property>
+ <property name="margin-bottom">25</property><!-- TODO better -->
+ <property name="height-request">263</property>
+ <property name="width-request">400</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes">Players</property>
+ <style>
+ <class name="bold-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="one">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes">_One</property>
+ <property name="action-name">app.num-players</property>
+ <property name="action-target">1</property>
+ <property name="draw-indicator">False</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioButton">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes">_Two</property>
+ <property name="action-name">app.num-players</property>
+ <property name="action-target">2</property>
+ <property name="group">one</property>
+ <property name="draw-indicator">False</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes">Difficulty</property>
+ <style>
+ <class name="bold-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="difficulty-box">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="easy">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes">_Easy</property>
+ <property name="action-name">app.computer-level</property>
+ <property name="action-target">1</property>
+ <property name="draw-indicator">False</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioButton">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes">_Medium</property>
+ <property name="action-name">app.computer-level</property>
+ <property name="action-target">2</property>
+ <property name="group">easy</property>
+ <property name="draw-indicator">False</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioButton">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes">_Hard</property>
+ <property name="action-name">app.computer-level</property>
+ <property name="action-target">3</property>
+ <property name="group">easy</property>
+ <property name="draw-indicator">False</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes">Color</property>
+ <style>
+ <class name="bold-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="color-box">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="play_dark">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes">_Dark</property>
+ <property name="action-name">app.color</property>
+ <property name="action-target">'dark'</property>
+ <property name="draw-indicator">False</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioButton">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="label" translatable="yes">_Light</property>
+ <property name="action-name">app.color</property>
+ <property name="action-target">'light'</property>
+ <property name="group">play_dark</property>
+ <property name="draw-indicator">False</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkGrid" id="scoregrid">
+ <property name="name">scoreboard</property>
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="column-spacing">12</property>
+ <property name="row-spacing">0</property>
+ <property name="column-homogeneous">True</property>
+ <property name="row-homogeneous">True</property>
+ <property name="margin-end">12</property>
+ <child>
+ <object class="GtkDrawingArea" id="scoredrawing">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property><!-- yeah, this sounds stupid, but... -->
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="dark-score-label">
+ <property name="visible">True</property>
+ <property name="label">00</property>
+ <style>
+ <class name="bold-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="light-score-label">
+ <property name="visible">True</property>
+ <property name="label">00</property>
+ <style>
+ <class name="bold-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/data/iagno.ui b/data/iagno.ui
index 2b9b31a..c15cb7d 100644
--- a/data/iagno.ui
+++ b/data/iagno.ui
@@ -1,33 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
- <object class="GtkApplicationWindow" id="window">
- <property name="title" translatable="yes">Iagno</property>
+ <template class="GameWindow" parent="GtkApplicationWindow">
+ <!-- <initial-focus name="view"/> -->
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="show_close_button">True</property>
- <property name="title" translatable="yes">Iagno</property>
+ <property name="show-close-button">True</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">app.undo-move</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>
@@ -36,16 +19,14 @@
<property name="halign">center</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Go back to the current game</property>
- <property name="use_underline">True</property>
- <property name="action-name">app.back</property>
- <style>
- <class name="image-button"/>
- </style>
+ <property name="use-underline">True</property>
+ <property name="action-name">win.back</property>
+ <style><class name="image-button"/></style>
<child>
- <object class="GtkImage" id="back_image">
- <property name="icon_name">go-previous-symbolic</property>
+ <object class="GtkImage">
+ <property name="icon-name">go-previous-symbolic</property>
<property name="visible">True</property>
- <property name="icon_size">1</property>
+ <property name="icon-size">1</property>
</object>
</child>
</object>
@@ -53,212 +34,36 @@
</object>
</child>
<child>
- <object class="GtkStack" id="main_stack">
+ <object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="homogeneous">True</property>
- <property name="transition-duration">800</property>
<child>
- <object class="GtkBox" id="start-box">
+ <object class="GtkBox" id="new_game_box">
<property name="orientation">vertical</property>
<property name="visible">True</property>
- <property name="homogeneous">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
- <property name="spacing">18</property>
<property name="margin">25</property>
- <property name="height-request">370</property>
- <property name="width-request">410</property>
+ <property name="width-request">350</property>
+ <property name="height-request">350</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
+ <object class="GtkButton" id="start_game_button">
<property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes">Players</property>
- <style>
- <class name="bold-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkRadioButton" id="one">
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_One</property>
- <property name="action-name">app.num-players</property>
- <property name="action-target">1</property>
- <property name="draw-indicator">False</property>
- <style>
- <class name="button"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkRadioButton">
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_Two</property>
- <property name="action-name">app.num-players</property>
- <property name="action-target">2</property>
- <property name="group">one</property>
- <property name="draw-indicator">False</property>
- <style>
- <class name="button"/>
- </style>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- </packing>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes">Difficulty</property>
- <style>
- <class name="bold-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkBox" id="difficulty-box">
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkRadioButton" id="easy">
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_Easy</property>
- <property name="action-name">app.computer-level</property>
- <property name="action-target">1</property>
- <property name="draw-indicator">False</property>
- <style>
- <class name="button"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkRadioButton">
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_Medium</property>
- <property name="action-name">app.computer-level</property>
- <property name="action-target">2</property>
- <property name="group">easy</property>
- <property name="draw-indicator">False</property>
- <style>
- <class name="button"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkRadioButton">
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_Hard</property>
- <property name="action-name">app.computer-level</property>
- <property name="action-target">3</property>
- <property name="group">easy</property>
- <property name="draw-indicator">False</property>
- <style>
- <class name="button"/>
- </style>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- </packing>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes">Color</property>
- <style>
- <class name="bold-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkBox" id="color-box">
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkRadioButton" id="play_dark">
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_Dark</property>
- <property name="action-name">app.color</property>
- <property name="action-target">'dark'</property>
- <property name="draw-indicator">False</property>
- <style>
- <class name="button"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkRadioButton">
- <property name="visible">True</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_Light</property>
- <property name="action-name">app.color</property>
- <property name="action-target">'light'</property>
- <property name="group">play_dark</property>
- <property name="draw-indicator">False</property>
- <style>
- <class name="button"/>
- </style>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- </packing>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="visible">True</property>
- <property name="height-request">60</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>
<property name="halign">center</property>
- <property name="valign">end</property>
- <property name="use_underline">True</property>
- <property name="label" translatable="yes">_Start Game</property>
- <property name="action-name">app.start-game</property>
- <property name="tooltip-text" translatable="yes">Start a game</property>
- <style>
- <class name="suggested-action"/>
- </style>
+ <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>
</child>
</object>
<packing>
@@ -266,90 +71,31 @@
</packing>
</child>
<child>
- <object class="GtkAspectFrame" id="frame">
+ <object class="GtkAspectFrame">
<property name="visible">True</property>
<property name="shadow-type">GTK_SHADOW_NONE</property>
<property name="obey-child">false</property>
<property name="ratio">1.4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</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="GtkGrid">
- <property name="name">scoreboard</property>
- <property name="visible">True</property>
- <property name="halign">center</property>
- <property name="column-spacing">12</property>
- <property name="row-spacing">0</property>
- <property name="column-homogeneous">True</property>
- <property name="row-homogeneous">True</property>
- <property name="margin-end">12</property>
- <child>
- <object class="GtkDrawingArea" id="scoreboard">
- <property name="visible">True</property>
- </object>
- <packing>
- <property name="left-attach">0</property>
- <property name="top-attach">0</property>
- <property name="width">2</property><!-- yeah, this sounds stupid, but... -->
- <property name="height">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="dark-score-label">
- <property name="visible">True</property>
- <property name="label">00</property>
- <style>
- <class name="bold-label"/>
- </style>
- </object>
- <packing>
- <property name="left-attach">2</property>
- <property name="top-attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="light-score-label">
- <property name="visible">True</property>
- <property name="label">00</property>
- <style>
- <class name="bold-label"/>
- </style>
- </object>
- <packing>
- <property name="left-attach">2</property>
- <property name="top-attach">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="pack-type">start</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="padding">6</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton">
+ <object class="GtkButton" id="new_game_button">
<property name="visible">True</property>
- <property name="use_underline">True</property>
+ <property name="use-underline">True</property>
<property name="label" translatable="yes">_New Game</property>
+ <property name="tooltip-text" translatable="yes">Configure a new game</property>
<property name="halign">center</property>
- <property name="valign">end</property>
- <property name="action-name">app.new-game</property>
+ <property name="valign">center</property>
+ <property name="action-name">win.new-game</property>
<property name="tooltip-text" translatable="yes">Start a new game</property>
<property name="width-request">120</property>
<property name="height-request">60</property>
@@ -379,5 +125,5 @@
</child>
</object>
</child>
- </object>
+ </template>
</interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 31a9e62..51a9955 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,7 @@
data/iagno.appdata.xml.in
data/iagno.desktop.in
[type: gettext/glade]data/iagno-menus.ui
+[type: gettext/glade]data/iagno-screens.ui
[type: gettext/glade]data/iagno-themes.ui
[type: gettext/glade]data/iagno.ui
[type: gettext/ini]data/themes/adwaita.theme.in
@@ -14,6 +15,7 @@ data/org.gnome.iagno.gschema.xml
src/computer-player.vala
src/game.vala
src/game-view.vala
+src/game-window.vala
src/iagno.vala
src/player.vala
src/themes-dialog.vala
diff --git a/src/Makefile.am b/src/Makefile.am
index 8fb45ba..e8a1f1f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,7 @@ iagno_SOURCES = \
computer-player.vala \
game.vala \
game-view.vala \
+ game-window.vala \
iagno.vala \
player.vala \
themes-dialog.vala \
@@ -42,7 +43,7 @@ test_iagno_SOURCES = \
test_iagno_VALAFLAGS = \
--pkg gio-2.0 \
- --target-glib 2.40
+ --target-glib $(GLIB_REQUIRED)
test_iagno_CFLAGS = $(IAGNO_CFLAGS)
@@ -51,8 +52,8 @@ test_iagno_LDADD = $(IAGNO_LIBS)
check-local: $(check_PROGRAMS)
$(GTESTER) --keep-going --verbose $(check_PROGRAMS)
-iagno-resources.c: $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies iagno.gresource.xml)
- $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-source
iagno.gresource.xml
+iagno-resources.c: iagno.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies
iagno.gresource.xml)
+ $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-source $<
CLEANFILES = \
$(patsubst %.vala,%.c,$(filter %.vala, $(SOURCES))) \
diff --git a/src/game-window.vala b/src/game-window.vala
new file mode 100644
index 0000000..ad37ec5
--- /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/iagno/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/iagno.gresource.xml b/src/iagno.gresource.xml
index be67380..dd0a6e4 100644
--- a/src/iagno.gresource.xml
+++ b/src/iagno.gresource.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/iagno/ui">
- <file preprocess="xml-stripblanks" alias="iagno.ui">../data/iagno.ui</file>
+ <file preprocess="xml-stripblanks" alias="game-window.ui">../data/iagno.ui</file>
<file preprocess="xml-stripblanks" alias="themes.ui">../data/iagno-themes.ui</file>
+ <file preprocess="xml-stripblanks" alias="iagno-screens.ui">../data/iagno-screens.ui</file>
<file alias="iagno.css">../data/iagno.css</file>
</gresource>
<gresource prefix="/org/gnome/iagno/gtk">
diff --git a/src/iagno.vala b/src/iagno.vala
index 5bda7eb..44d2c4a 100644
--- a/src/iagno.vala
+++ b/src/iagno.vala
@@ -18,20 +18,18 @@
* along with Iagno. If not, see <http://www.gnu.org/licenses/>.
*/
+using Gtk;
+
public class Iagno : Gtk.Application
{
/* Application settings */
- private Settings settings;
- private bool is_tiled;
- private bool is_maximized;
- private int window_width;
- private int window_height;
+ private GLib.Settings settings;
private static bool fast_mode;
private static bool alternative_start;
private static int computer_level = 0;
private static int size = 8;
- private static bool begin_with_new_game_screen = false;
- private static string color;
+ private static bool start_now = false; // could be replaced one day with (two_players != null)
+ private static string color; // TODO Player
private static bool? sound = null;
private static bool? two_players = null;
@@ -41,19 +39,12 @@ public class Iagno : Gtk.Application
private static const double SLOW_MOVE_DELAY = 2.0;
/* Widgets */
- private Gtk.Window window;
- private Gtk.HeaderBar headerbar;
+ private GameWindow window;
private GameView view;
- private Gtk.Label dark_score_label;
- private Gtk.Label light_score_label;
- private Gtk.Stack main_stack;
+ private Label dark_score_label;
+ private Label light_score_label;
private ThemesDialog themes_dialog;
- private Gtk.Button back_button;
- private Gtk.Button undo_button;
-
- private SimpleAction back_action;
-
/* Computer player (if there is one) */
private ComputerPlayer? computer = null;
@@ -80,12 +71,6 @@ public class Iagno : Gtk.Application
private const GLib.ActionEntry app_actions[] =
{
- {"new-game", new_game_cb},
- {"start-game", start_game_cb},
-
- {"undo-move", undo_move_cb},
- {"back", back_cb},
-
{"theme", theme_cb},
{"help", help_cb},
{"about", about_cb},
@@ -100,8 +85,7 @@ public class Iagno : Gtk.Application
Intl.textdomain (GETTEXT_PACKAGE);
Environment.set_application_name (_("Iagno"));
-
- Gtk.Window.set_default_icon_name ("iagno");
+ Window.set_default_icon_name ("iagno");
return new Iagno ().run (args);
}
@@ -129,10 +113,10 @@ public class Iagno : Gtk.Application
return Posix.EXIT_FAILURE;
}
- if (options.contains ("unmute"))
- sound = true;
if (options.contains ("mute"))
sound = false;
+ else if (options.contains ("unmute"))
+ sound = true;
/* TODO message should be displayed if "--level 0" */
if (computer_level < 0 || computer_level > 3)
@@ -140,14 +124,15 @@ public class Iagno : Gtk.Application
if (options.contains ("two-players")) {
two_players = true;
+ start_now = true;
} else if (options.contains ("first")) {
color = "dark";
two_players = false;
+ start_now = true;
} else if (options.contains ("second")) {
color = "light";
two_players = false;
- } else {
- begin_with_new_game_screen = true;
+ start_now = true;
}
/* Activate */
@@ -158,14 +143,12 @@ public class Iagno : Gtk.Application
{
base.startup ();
- var css_provider = new Gtk.CssProvider ();
+ CssProvider css_provider = new CssProvider ();
css_provider.load_from_resource ("/org/gnome/iagno/ui/iagno.css");
- Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), css_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
-
- var builder = new Gtk.Builder.from_resource ("/org/gnome/iagno/ui/iagno.ui");
+ StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), css_provider,
STYLE_PROVIDER_PRIORITY_APPLICATION);
/* Settings */
- settings = new Settings ("org.gnome.iagno");
+ settings = new GLib.Settings ("org.gnome.iagno");
if (sound != null)
settings.set_boolean ("sound", sound);
@@ -185,10 +168,41 @@ public class Iagno : Gtk.Application
else /* hack, part 3 of 4 */
computer_level = settings.get_int ("computer-level");
+ /* UI parts */
+ Builder builder = new Builder.from_resource ("/org/gnome/iagno/ui/iagno-screens.ui");
+
+ view = new GameView ();
+ view.move.connect (player_move_cb);
+
+ DrawingArea scoredrawing = (DrawingArea) builder.get_object ("scoredrawing");
+ view.scoreboard = scoredrawing;
+ view.theme = settings.get_string ("theme");
+
+ /* Window */
+ window = new GameWindow (_("Iagno"),
+ settings.get_int ("window-width"),
+ settings.get_int ("window-height"),
+ settings.get_boolean ("window-is-maximized"),
+ start_now,
+ GameWindowFlags.SHOW_UNDO,
+ (Box) builder.get_object ("new-game-screen"),
+ view);
+
+ Widget scoregrid = (Widget) builder.get_object ("scoregrid");
+ window.add_to_sidebox (scoregrid);
+
+ window.play.connect (start_game);
+ window.wait.connect (wait_cb);
+ window.back.connect (back_cb);
+ window.undo.connect (undo_cb);
+
/* Actions and preferences */
add_action_entries (app_actions, this);
- set_accels_for_action ("app.new-game", {"<Primary>n"});
- set_accels_for_action ("app.undo-move", {"<Primary>z"});
+ 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"});
+ set_accels_for_action ("win.redo", {"<Primary><Shift>z"});
+ set_accels_for_action ("win.back", {"Escape"});
add_action (settings.create_action ("sound"));
/* TODO bugs when changing manually the gsettings key (not for sound);
* solving this bug may remove the need of the hack in three parts */
@@ -196,62 +210,34 @@ public class Iagno : Gtk.Application
add_action (settings.create_action ("num-players"));
add_action (settings.create_action ("computer-level"));
- var level_box = builder.get_object ("difficulty-box") as Gtk.Box;
+ var level_box = (Box) builder.get_object ("difficulty-box");
settings.changed["num-players"].connect (() => {
level_box.sensitive = settings.get_int ("num-players") == 1;
});
level_box.sensitive = settings.get_int ("num-players") == 1;
- var color_box = builder.get_object ("color-box") as Gtk.Box;
+ var color_box = (Box) builder.get_object ("color-box");
settings.changed["num-players"].connect (() => {
color_box.sensitive = settings.get_int ("num-players") == 1;
});
color_box.sensitive = settings.get_int ("num-players") == 1;
- /* Window construction */
- window = builder.get_object ("window") as Gtk.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 ();
- add_window (window);
-
/* Hack for restoring radiobuttons settings, part 4 of 4.
* When you add_window(), settings are initialized with the value
* of the first radiobutton of the group found in the UI file. */
- Settings.sync ();
+ GLib.Settings.sync ();
settings.set_string ("color", color);
settings.set_int ("computer-level", computer_level);
settings.set_int ("num-players", two_players ? 2 : 1);
- /* View construction */
- view = new GameView ();
- view.scoreboard = builder.get_object ("scoreboard") as Gtk.DrawingArea;
- view.move.connect (player_move_cb);
- view.theme = settings.get_string ("theme");
- view.halign = Gtk.Align.FILL;
- view.show ();
-
- var game_box = builder.get_object ("game-box") as Gtk.Box;
- game_box.pack_start (view);
-
/* Information widgets */
- headerbar = builder.get_object ("headerbar") as Gtk.HeaderBar;
- light_score_label = builder.get_object ("light-score-label") as Gtk.Label;
- dark_score_label = builder.get_object ("dark-score-label") as Gtk.Label;
-
- /* Changing screen */
- main_stack = builder.get_object ("main_stack") as Gtk.Stack;
- back_button = builder.get_object ("back_button") as Gtk.Button;
- undo_button = builder.get_object ("undo_button") as Gtk.Button;
-
- back_action = (SimpleAction) lookup_action ("back");
+ light_score_label = (Label) builder.get_object ("light-score-label");
+ dark_score_label = (Label) builder.get_object ("dark-score-label");
- if (begin_with_new_game_screen)
- show_new_game_screen ();
- else
+ if (start_now)
start_game ();
+
+ add_window (window);
}
protected override void activate ()
@@ -262,33 +248,7 @@ public class Iagno : Gtk.Application
protected override void shutdown ()
{
base.shutdown ();
-
- /* Save window state */
- 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 (Gtk.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;
+ window.save_state (settings);
}
/*\
@@ -310,7 +270,7 @@ public class Iagno : Gtk.Application
{
try
{
- Gtk.show_uri (window.get_screen (), "help:iagno", Gtk.get_current_event_time ());
+ show_uri (window.get_screen (), "help:iagno", get_current_event_time ());
}
catch (Error e)
{
@@ -323,70 +283,40 @@ public class Iagno : Gtk.Application
string[] authors = { "Ian Peters", "Robert Ancell", null };
string[] documenters = { "Tiffany Antopolski", null };
- Gtk.show_about_dialog (window,
- "name", _("Iagno"),
- "version", VERSION,
- "copyright",
- "Copyright © 1998–2008 Ian Peters\n"+
- "Copyright © 2013–2015 Michael Catanzaro\n"+
- "Copyright © 2014–2015 Arnaud Bonatti",
- "license-type", Gtk.License.GPL_3_0,
- "comments",
- _("A disk flipping game derived from Reversi"),
- "authors", authors,
- "documenters", documenters,
- "translator-credits", _("translator-credits"),
- "logo-icon-name", "iagno",
- "website", "https://wiki.gnome.org/Apps/Iagno",
- null);
+ show_about_dialog (window,
+ "name", _("Iagno"),
+ "version", VERSION,
+ "copyright",
+ "Copyright © 1998–2008 Ian Peters\n"+
+ "Copyright © 2013–2015 Michael Catanzaro\n"+
+ "Copyright © 2014–2015 Arnaud Bonatti",
+ "license-type", License.GPL_3_0,
+ "comments",
+ _("A disk flipping game derived from Reversi"),
+ "authors", authors,
+ "documenters", documenters,
+ "translator-credits", _("translator-credits"),
+ "logo-icon-name", "iagno",
+ "website", "https://wiki.gnome.org/Apps/Iagno",
+ null);
}
/*\
* * Internal calls
\*/
- private void start_game_cb ()
- {
- main_stack.set_transition_type (Gtk.StackTransitionType.SLIDE_DOWN);
- back_button.visible = false;
- start_game ();
- }
-
private void back_cb ()
{
- main_stack.set_transition_type (Gtk.StackTransitionType.SLIDE_RIGHT);
- show_game_board ();
- back_action.set_enabled (false);
-
if (game.current_color != player_one && computer != null && !game.is_complete)
computer.move_async.begin (SLOW_MOVE_DELAY);
else if (game.is_complete)
game_complete (false);
}
- private void show_game_board ()
- {
- main_stack.set_visible_child_name ("frame");
- back_button.visible = false;
- undo_button.visible = true;
- }
-
- private void show_new_game_screen ()
+ private void wait_cb ()
{
if (computer != null)
computer.cancel_move ();
-
- main_stack.set_visible_child_name ("start-box");
- undo_button.visible = false;
- }
-
- private void new_game_cb ()
- {
- main_stack.set_transition_type (Gtk.StackTransitionType.SLIDE_LEFT);
- show_new_game_screen ();
- headerbar.set_subtitle (null);
- back_button.visible = true;
- back_action.set_enabled (true);
}
private void start_game ()
@@ -397,8 +327,6 @@ public class Iagno : Gtk.Application
if (computer != null)
computer.cancel_move ();
- show_game_board ();
-
game = new Game (alternative_start, size);
game.turn_ended.connect (turn_ended_cb);
view.game = game;
@@ -421,20 +349,19 @@ public class Iagno : Gtk.Application
private void update_ui ()
{
- headerbar.set_subtitle (null);
+ window.set_subtitle (null);
- var undo_action = (SimpleAction) lookup_action ("undo-move");
if (player_one == Player.DARK || computer == null)
- undo_action.set_enabled (game.number_of_moves >= 1);
+ window.undo_action.set_enabled (game.number_of_moves >= 1);
else
- undo_action.set_enabled (game.number_of_moves >= 2);
+ window.undo_action.set_enabled (game.number_of_moves >= 2);
/* Translators: this is a 2 digit representation of the current score. */
dark_score_label.set_text (_("%.2d").printf (game.n_dark_tiles));
light_score_label.set_text (_("%.2d").printf (game.n_light_tiles));
}
- private void undo_move_cb ()
+ private void undo_cb ()
{
if (computer == null)
{
@@ -503,31 +430,33 @@ public class Iagno : Gtk.Application
if (game.current_color == Player.DARK)
{
/* Message to display when Light has no possible moves */
- headerbar.set_subtitle (_("Light must pass, Dark’s move"));
+ window.set_subtitle (_("Light must pass, Dark’s move"));
}
else
{
/* Message to display when Dark has no possible moves */
- headerbar.set_subtitle (_("Dark must pass, Light’s move"));
+ window.set_subtitle (_("Dark must pass, Light’s move"));
}
}
private void game_complete (bool play_gameover_sound = true)
{
+ window.finish_game ();
+
if (game.n_light_tiles > game.n_dark_tiles)
{
/* Message to display when Light has won the game */
- headerbar.set_subtitle (_("Light wins!"));
+ window.set_subtitle (_("Light wins!"));
}
else if (game.n_dark_tiles > game.n_light_tiles)
{
/* Message to display when Dark has won the game */
- headerbar.set_subtitle (_("Dark wins!"));
+ window.set_subtitle (_("Dark wins!"));
}
else
{
/* Message to display when the game is a draw */
- headerbar.set_subtitle (_("The game is draw."));
+ window.set_subtitle (_("The game is draw."));
}
if (play_gameover_sound)
@@ -543,7 +472,7 @@ public class Iagno : Gtk.Application
if (game.place_tile (x, y) == 0)
{
/* Message to display when the player tries to make an illegal move */
- headerbar.set_subtitle (_("You can’t move there!"));
+ window.set_subtitle (_("You can’t move there!"));
}
}
@@ -579,6 +508,6 @@ public class Iagno : Gtk.Application
Canberra.PROP_MEDIA_NAME, name,
Canberra.PROP_MEDIA_FILENAME, path);
if (r != 0)
- warning ("Error playing file: %s\nfilepath should be:%s", name, path);
+ warning ("Error playing file: %s\nfilepath should be:%s\n", name, path);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]