[four-in-a-row] Move scores in game menu.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [four-in-a-row] Move scores in game menu.
- Date: Thu, 26 Dec 2019 17:11:59 +0000 (UTC)
commit 3eb7b6b2bb9f41fbaba88a4aff489f7812e68ef7
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Sun Dec 22 21:13:28 2019 +0100
Move scores in game menu.
data/ui/history-button.ui | 15 ----
src/four-in-a-row.vala | 196 +++++++++++++++++++++++++++++++++-------------
src/history-button.vala | 3 +-
3 files changed, 142 insertions(+), 72 deletions(-)
---
diff --git a/data/ui/history-button.ui b/data/ui/history-button.ui
index 0cefaf2..d63632d 100644
--- a/data/ui/history-button.ui
+++ b/data/ui/history-button.ui
@@ -19,25 +19,10 @@
-->
<interface>
<requires lib="gtk+" version="3.12"/>
- <menu id="game-menu">
- <section>
- <item>
- <!-- Translators: during a game, entry in the game menu, for undoing the last move -->
- <attribute name="label" translatable="yes">_Undo last move</attribute>
- <attribute name="action">ui.undo</attribute>
- </item>
- <item>
- <!-- Translators: during a game, entry in the game menu, for suggesting where to play -->
- <attribute name="label" translatable="yes">_Hint</attribute>
- <attribute name="action">ui.hint</attribute>
- </item>
- </section>
- </menu>
<template class="HistoryButton" parent="GtkMenuButton">
<property name="visible">True</property>
<property name="valign">center</property>
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
- <property name="menu-model">game-menu</property>
</template>
</interface>
diff --git a/src/four-in-a-row.vala b/src/four-in-a-row.vala
index f040c89..24abb40 100644
--- a/src/four-in-a-row.vala
+++ b/src/four-in-a-row.vala
@@ -61,10 +61,9 @@ private class FourInARow : Gtk.Application
/**
* score:
*
- * The scores for the current instance (Player 1, Player 2, Draw)
+ * The scores for the current instance (Human, Opponent, Draw)
*/
private uint [] score = { 0, 0, 0 };
- private bool reset_score = true;
private uint playgame_timeout = 0;
// widgets
@@ -102,6 +101,8 @@ private class FourInARow : Gtk.Application
private const GLib.ActionEntry app_entries [] = // see also add_actions()
{
{ "game-type", null, "s", "'dark'", change_game_type },
+ { "next-round", on_next_round },
+ { "give-up", on_give_up },
{ "scores", on_game_scores },
{ "quit", on_game_exit },
{ "help", on_help_contents },
@@ -162,12 +163,6 @@ private class FourInARow : Gtk.Application
section.freeze ();
app_menu.append_section (null, section);
- section = new GLib.Menu ();
- /* Translators: hamburger menu entry; opens the Scores dialog (with a mnemonic that appears pressing
Alt) */
- section.append (_("_Scores"), "app.scores");
- section.freeze ();
- app_menu.append_section (null, section);
-
section = new GLib.Menu ();
/* Translators: hamburger menu entry; opens the Keyboard Shortcuts dialog (with a mnemonic that
appears pressing Alt) */
section.append (_("_Keyboard Shortcuts"), "win.show-help-overlay");
@@ -184,8 +179,9 @@ private class FourInARow : Gtk.Application
app_menu.freeze ();
- history_button_1 = new HistoryButton (/* direction: down */ false);
- history_button_2 = new HistoryButton (/* direction: up */ true);
+ generate_game_menu ();
+ history_button_1 = new HistoryButton (ref game_menu, /* direction: down */ false);
+ history_button_2 = new HistoryButton (ref game_menu, /* direction: up */ true);
/* Window */
window = new GameWindow ("/org/gnome/Four-in-a-row/ui/four-in-a-row.css",
@@ -222,7 +218,7 @@ private class FourInARow : Gtk.Application
window.allow_undo (false);
prompt_player ();
- game_reset ();
+ game_reset (/* reload settings */ true);
add_window (window);
}
@@ -247,7 +243,9 @@ private class FourInARow : Gtk.Application
add_action_entries (app_entries, this);
- game_type_action = (SimpleAction) lookup_action ("game-type");
+ game_type_action = (SimpleAction) lookup_action ("game-type");
+ next_round_action = (SimpleAction) lookup_action ("next-round");
+ next_round_action.set_enabled (false);
settings.changed ["first-player"].connect (() => {
if (settings.get_int ("num-players") == 2)
@@ -261,31 +259,49 @@ private class FourInARow : Gtk.Application
settings.changed ["num-players"].connect (() => {
bool solo = settings.get_int ("num-players") == 1;
new_game_screen.update_sensitivity (solo);
- reset_score = true;
- if (!solo)
- game_type_action.set_state (new Variant.string ("two"));
- else if (settings.get_string ("first-player") == "human")
- game_type_action.set_state (new Variant.string ("human"));
- else
- game_type_action.set_state (new Variant.string ("computer"));
if (solo)
+ {
+ new_game_screen.update_sensitivity (true);
+ if (settings.get_string ("first-player") == "human")
+ {
+ game_type_action.set_state (new Variant.string ("human"));
+ last_first_player = PlayerID.HUMAN;
+ }
+ else
+ {
+ game_type_action.set_state (new Variant.string ("computer"));
+ last_first_player = PlayerID.OPPONENT;
+ }
+ }
+ else
+ {
+ new_game_screen.update_sensitivity (false);
+ game_type_action.set_state (new Variant.string ("two"));
last_first_player = PlayerID.NOBODY;
+ }
});
bool solo = settings.get_int ("num-players") == 1;
new_game_screen.update_sensitivity (solo);
-
- if (settings.get_int ("num-players") == 2)
- game_type_action.set_state (new Variant.string ("two"));
- else if (settings.get_string ("first-player") == "human")
- game_type_action.set_state (new Variant.string ("human"));
+ if (solo)
+ {
+ new_game_screen.update_sensitivity (true);
+ if (settings.get_string ("first-player") == "human")
+ {
+ game_type_action.set_state (new Variant.string ("human"));
+ last_first_player = PlayerID.HUMAN;
+ }
+ else
+ {
+ game_type_action.set_state (new Variant.string ("computer"));
+ last_first_player = PlayerID.OPPONENT;
+ }
+ }
else
- game_type_action.set_state (new Variant.string ("computer"));
-
- settings.changed ["opponent"].connect (() => {
- if (settings.get_int ("num-players") != 1)
- return;
- reset_score = true;
- });
+ {
+ new_game_screen.update_sensitivity (false);
+ game_type_action.set_state (new Variant.string ("two"));
+ last_first_player = PlayerID.NOBODY;
+ }
}
protected override void activate ()
@@ -297,7 +313,7 @@ private class FourInARow : Gtk.Application
* * various
\*/
- internal void game_reset ()
+ internal void game_reset (bool reload_settings)
{
stop_anim ();
if (playgame_timeout != 0)
@@ -309,31 +325,27 @@ private class FourInARow : Gtk.Application
window.allow_undo (false);
window.allow_hint (false);
- one_player_game = settings.get_int ("num-players") == 1;
- if (reset_score)
+ set_gameover (false);
+
+ if (reload_settings)
{
+ one_player_game = settings.get_int ("num-players") == 1;
score = { 0, 0, 0 };
scorebox.update (score, one_player_game);
- reset_score = false;
- }
- if (one_player_game)
- {
- player = settings.get_string ("first-player") == "computer" ? PlayerID.OPPONENT : PlayerID.HUMAN;
- settings.set_string ("first-player", player == PlayerID.HUMAN ? "computer" : "human");
- ai_level = (uint8) settings.get_int ("opponent");
- }
- else
- {
- switch (last_first_player)
+
+ if (one_player_game)
{
- case PlayerID.HUMAN : player = PlayerID.OPPONENT; break;
- case PlayerID.OPPONENT:
- case PlayerID.NOBODY : player = PlayerID.HUMAN; break;
+ player = settings.get_string ("first-player") == "computer" ? PlayerID.OPPONENT :
PlayerID.HUMAN;
+ // we keep inverting that, because it would be surprising that all people use the "next
round" thing
+ settings.set_string ("first-player", player == PlayerID.HUMAN ? "computer" : "human");
+ ai_level = (uint8) settings.get_int ("opponent");
}
- last_first_player = player;
+ else
+ switch_players ();
}
+ else
+ switch_players ();
- gameover = true;
winner = NOBODY;
column = 3;
column_moveto = 3;
@@ -345,7 +357,6 @@ private class FourInARow : Gtk.Application
game_board_view.queue_draw ();
move_cursor (column);
- gameover = false;
prompt_player ();
if (!is_player_human ())
{
@@ -362,6 +373,16 @@ private class FourInARow : Gtk.Application
});
}
}
+ private void switch_players ()
+ {
+ switch (last_first_player)
+ {
+ case PlayerID.HUMAN : player = PlayerID.OPPONENT; break;
+ case PlayerID.OPPONENT:
+ case PlayerID.NOBODY : player = PlayerID.HUMAN; break;
+ }
+ last_first_player = player;
+ }
private void blink_winner (uint8 n) /* blink the winner's line(s) n times */
// requires (n < 128)
@@ -423,6 +444,7 @@ private class FourInARow : Gtk.Application
bool human = is_player_human ();
window.allow_hint (human && !gameover);
+ update_round_section ();
if (one_player_game)
window.allow_undo ((human && moves > 1) || (!human && gameover));
@@ -507,7 +529,7 @@ private class FourInARow : Gtk.Application
vstr [0] = vlevel [ai_level];
int col = playgame ((string) vstr) - 1;
if (col < 0)
- gameover = true;
+ set_gameover (true);
else if (col > BOARD_COLUMNS_MINUS_ONE)
assert_not_reached ();
var nm = new NextMove ((uint8) col, this);
@@ -522,7 +544,7 @@ private class FourInARow : Gtk.Application
{
if (game_board.is_line_at (player, row, column))
{
- gameover = true;
+ set_gameover (true);
winner = player;
if (one_player_game)
play_sound (is_player_human () ? SoundID.YOU_WIN : SoundID.I_WIN);
@@ -532,7 +554,7 @@ private class FourInARow : Gtk.Application
}
else if (moves == 42)
{
- gameover = true;
+ set_gameover (true);
winner = NOBODY;
play_sound (SoundID.DRAWN_GAME);
}
@@ -752,7 +774,7 @@ private class FourInARow : Gtk.Application
private inline void on_game_new ()
{
stop_anim ();
- game_reset ();
+ game_reset (/* reload settings */ true);
}
private inline void on_game_hint ()
@@ -811,7 +833,7 @@ private class FourInARow : Gtk.Application
{
score [winner]--;
scorebox.update (score, one_player_game);
- gameover = false;
+ set_gameover (false);
prompt_player ();
}
else
@@ -858,6 +880,13 @@ private class FourInARow : Gtk.Application
}
}
+ private SimpleAction next_round_action;
+ private void set_gameover (bool new_value)
+ {
+ gameover = new_value;
+ next_round_action.set_enabled (new_value);
+ }
+
private inline void on_game_scores (/* SimpleAction action, Variant? parameter */)
{
scorebox.present ();
@@ -1109,6 +1138,61 @@ private class FourInARow : Gtk.Application
warning(e.message);
}
}
+
+ /*\
+ * * game menu
+ \*/
+
+ private GLib.Menu game_menu = new GLib.Menu ();
+ private GLib.Menu round_section = new GLib.Menu ();
+
+ private inline void generate_game_menu ()
+ {
+ GLib.Menu section = new GLib.Menu ();
+ /* Translators: during a game, entry in the game menu, for undoing the last move */
+ section.append (_("_Undo last move"), "ui.undo");
+
+
+ /* Translators: during a game, entry in the game menu, for suggesting where to play */
+ section.append (_("_Hint"), "ui.hint");
+ section.freeze ();
+ game_menu.append_section (null, section);
+
+ update_round_section ();
+ game_menu.append_section (null, round_section);
+ }
+
+ private void update_round_section ()
+ {
+ round_section.remove_all ();
+ if (gameover)
+ round_section.append (_("Next _Round"), "app.next-round");
+ else
+ round_section.append (_("_Give Up"), "app.give-up");
+
+ if (score [PlayerID.HUMAN] + score [PlayerID.OPPONENT] + score [PlayerID.NOBODY] == 0)
+ return;
+ /* Translators: hamburger menu entry; opens the Scores dialog (with a mnemonic that appears pressing
Alt) */
+ round_section.append (_("_Scores"), "app.scores");
+ }
+
+ private inline void on_give_up (/* SimpleAction action, Variant? parameter */)
+ {
+ if (player == PlayerID.HUMAN)
+ score [PlayerID.OPPONENT]++;
+ else if (player == PlayerID.OPPONENT)
+ score [PlayerID.HUMAN]++;
+ else
+ assert_not_reached ();
+ scorebox.update (score, one_player_game);
+
+ game_reset (/* reload settings */ false);
+ }
+
+ private inline void on_next_round (/* SimpleAction action, Variant? parameter */)
+ {
+ game_reset (/* reload settings */ false);
+ }
}
private enum PlayerID {
diff --git a/src/history-button.vala b/src/history-button.vala
index d90712b..fa5ec0e 100644
--- a/src/history-button.vala
+++ b/src/history-button.vala
@@ -23,8 +23,9 @@ using Gtk;
[GtkTemplate (ui = "/org/gnome/Four-in-a-row/ui/history-button.ui")]
private class HistoryButton : MenuButton, AdaptativeWidget
{
- internal HistoryButton (bool invert_arrow)
+ internal HistoryButton (ref GLib.Menu menu, bool invert_arrow)
{
+ set_menu_model (menu);
if (invert_arrow)
set_direction (ArrowType.UP);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]