[four-in-a-row] HistoryButton DrawingArea.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [four-in-a-row] HistoryButton DrawingArea.
- Date: Fri, 10 Jan 2020 18:04:18 +0000 (UTC)
commit d045a3852d6c6cacb2097ca104a522f547895905
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Thu Jan 9 23:09:38 2020 +0100
HistoryButton DrawingArea.
data/ui/history-button.ui | 22 ++++++++
src/four-in-a-row.vala | 54 +++++++++++++------
src/history-button.vala | 133 ++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 188 insertions(+), 21 deletions(-)
---
diff --git a/data/ui/history-button.ui b/data/ui/history-button.ui
index d63632d..8a53ae0 100644
--- a/data/ui/history-button.ui
+++ b/data/ui/history-button.ui
@@ -24,5 +24,27 @@
<property name="valign">center</property>
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
+ <property name="width-request">56</property>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="visible">True</property>
+ <property name="visible-child">drawing</property>
+ <child>
+ <object class="GtkDrawingArea" id="drawing">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <!-- Translators: label of the game status button (in the headerbar, next to the hamburger
button); please keep the string as small as possible (3~5 characters) -->
+ <property name="label" translatable="yes">End!</property>
+ </object>
+ <packing>
+ <property name="name">label</property>
+ </packing>
+ </child>
+ </object>
+ </child>
</template>
</interface>
diff --git a/src/four-in-a-row.vala b/src/four-in-a-row.vala
index c3b6d1b..d6e8e8f 100644
--- a/src/four-in-a-row.vala
+++ b/src/four-in-a-row.vala
@@ -56,8 +56,8 @@ private class FourInARow : Gtk.Application
private GameBoardView game_board_view;
private GameWindow window;
private NewGameScreen new_game_screen;
- private MenuButton history_button_1;
- private MenuButton history_button_2;
+ private HistoryButton history_button_1;
+ private HistoryButton history_button_2;
// game state
private string vstr;
@@ -268,8 +268,8 @@ private class FourInARow : Gtk.Application
app_menu.freeze ();
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);
+ history_button_1 = new HistoryButton (ref game_menu, theme_manager);
+ history_button_2 = new HistoryButton (ref game_menu, theme_manager);
/* Window */
window = new GameWindow ("/org/gnome/Four-in-a-row/ui/four-in-a-row.css",
@@ -279,8 +279,8 @@ private class FourInARow : Gtk.Application
(Box) new_game_screen,
game_board_view,
app_menu,
- history_button_1,
- history_button_2);
+ (MenuButton) history_button_1,
+ (MenuButton) history_button_2);
scorebox = new Scorebox (window, this, theme_manager);
@@ -544,39 +544,59 @@ private class FourInARow : Gtk.Application
else
/* Translators: text displayed on game end in the headerbar/actionbar, if the game is a tie
*/
set_status_message (_("It’s a draw!"));
+ history_button_1.set_player (Player.NOBODY);
+ history_button_2.set_player (Player.NOBODY);
return;
}
if (one_player_game)
{
- if (human)
+ if (gameover)
{
- if (gameover)
+ history_button_1.set_player (Player.NOBODY);
+ history_button_2.set_player (Player.NOBODY);
+ if (human)
/* Translators: text displayed on a one-player game end in the headerbar/actionbar, if
the human player won */
set_status_message (_("You win!"));
else
- /* Translators: text displayed during a one-player game in the headerbar/actionbar, if
it is the human player's turn */
- set_status_message (_("Your Turn"));
+ /* Translators: text displayed on a one-player game end in the headerbar/actionbar, if
the computer player won */
+ set_status_message (_("I win!"));
}
else
{
- if (gameover)
- /* Translators: text displayed on a one-player game end in the headerbar/actionbar, if
the computer player won */
- set_status_message (_("I win!"));
+ if (human)
+ {
+ history_button_1.set_player (Player.HUMAN);
+ history_button_2.set_player (Player.HUMAN);
+ /* Translators: text displayed during a one-player game in the headerbar/actionbar, if
it is the human player's turn */
+ set_status_message (_("Your Turn"));
+ }
else
+ {
+ history_button_1.set_player (Player.OPPONENT);
+ history_button_2.set_player (Player.OPPONENT);
/* Translators: text displayed during a one-player game in the headerbar/actionbar, if
it is the computer player's turn */
set_status_message (_("I’m Thinking…"));
+ }
}
}
else
{
string who;
if (gameover)
- who = player == HUMAN ? theme_manager.get_player_win (Player.HUMAN)
- : theme_manager.get_player_win (Player.OPPONENT);
+ {
+ history_button_1.set_player (Player.NOBODY);
+ history_button_2.set_player (Player.NOBODY);
+ who = theme_manager.get_player_win (player);
+ }
else
- who = player == HUMAN ? theme_manager.get_player_turn (Player.HUMAN)
- : theme_manager.get_player_turn (Player.OPPONENT);
+ {
+ // player can be NOBODY
+ Player current_player = player == HUMAN ? Player.HUMAN : Player.OPPONENT;
+ history_button_1.set_player (current_player);
+ history_button_2.set_player (current_player);
+ who = theme_manager.get_player_turn (current_player);
+ }
set_status_message (_(who));
}
diff --git a/src/history-button.vala b/src/history-button.vala
index fa5ec0e..693c27c 100644
--- a/src/history-button.vala
+++ b/src/history-button.vala
@@ -23,14 +23,139 @@ using Gtk;
[GtkTemplate (ui = "/org/gnome/Four-in-a-row/ui/history-button.ui")]
private class HistoryButton : MenuButton, AdaptativeWidget
{
- internal HistoryButton (ref GLib.Menu menu, bool invert_arrow)
+ [CCode (notify = false)] public ThemeManager theme_manager { private get; protected construct; }
+
+ [GtkChild] private Stack stack;
+ [GtkChild] private DrawingArea drawing;
+
+ internal HistoryButton (ref GLib.Menu menu, ThemeManager theme_manager)
+ {
+ Object (menu_model: menu, theme_manager: theme_manager);
+ }
+
+ construct
{
- set_menu_model (menu);
- if (invert_arrow)
- set_direction (ArrowType.UP);
+ drawing.configure_event.connect (configure_drawing);
+ drawing.draw.connect (update_drawing);
+ theme_manager.theme_changed.connect (() => {
+ if (!drawing_configured)
+ return;
+ init_pixbuf ();
+ if (current_player != Player.NOBODY)
+ drawing.queue_draw ();
+ });
}
protected override void set_window_size (AdaptativeWidget.WindowSize new_size)
{
}
+
+ internal void set_player (Player player)
+ {
+ current_player = player;
+ if (player == Player.NOBODY)
+ stack.set_visible_child_name ("label");
+ else
+ {
+ stack.set_visible_child (drawing);
+ drawing.queue_draw ();
+ }
+ }
+
+ /*\
+ * * drawing
+ \*/
+
+ private bool drawing_configured = false;
+ private int drawing_height = int.MIN;
+ private int drawing_width = int.MIN;
+ private int pixbuf_size = int.MIN;
+ private double arrow_half_width = - double.MAX;
+ private int board_x = int.MIN;
+ private int board_y = int.MIN;
+ private const int pixbuf_margin = 1;
+
+ private Gdk.Pixbuf tileset_pixbuf;
+
+ private bool configure_drawing ()
+ {
+ int height = drawing.get_allocated_height ();
+ int width = drawing.get_allocated_width ();
+ int new_height = (int) double.min (height, width / 2.0);
+
+ bool refresh_pixbuf = drawing_height != new_height;
+ drawing_height = new_height;
+ pixbuf_size = drawing_height - 2 * pixbuf_margin;
+ if (refresh_pixbuf)
+ init_pixbuf ();
+ arrow_half_width = pixbuf_size / 4.0;
+
+ bool vertical_fill = height == new_height;
+ drawing_width = vertical_fill ? (int) (new_height * 2.0) : width;
+ board_x = vertical_fill ? (int) ((width - drawing_width) / 2.0) : 0;
+ board_y = !vertical_fill ? (int) ((height - drawing_height) / 2.0) : 0;
+
+ drawing_configured = true;
+ return true;
+ }
+ private void init_pixbuf ()
+ {
+ Gdk.Pixbuf? tmp_pixbuf = theme_manager.pb_tileset_raw.scale_simple (pixbuf_size * 6, pixbuf_size,
Gdk.InterpType.BILINEAR);
+ if (tmp_pixbuf == null)
+ assert_not_reached ();
+ tileset_pixbuf = (!) tmp_pixbuf;
+ }
+
+ private bool update_drawing (Cairo.Context cr)
+ {
+ if (!drawing_configured)
+ return false;
+
+ draw_arrow (cr);
+ draw_piece (cr);
+ return true;
+ }
+
+ private const double arrow_margin_top = 3.0;
+ private void draw_arrow (Cairo.Context cr)
+ {
+ cr.save ();
+
+ cr.set_line_cap (Cairo.LineCap.ROUND);
+ cr.set_line_join (Cairo.LineJoin.ROUND);
+
+ cr.set_source_rgba (/* red */ 0.5, /* green */ 0.5, /* blue */ 0.5, 1.0);
+ cr.set_line_width (/* looks good */ 2.0);
+
+ cr.translate (board_x, board_y);
+ cr.move_to ( arrow_half_width, arrow_margin_top);
+ cr.line_to (3.0 * arrow_half_width, drawing_height / 2.0);
+ cr.line_to ( arrow_half_width, drawing_height - arrow_margin_top);
+ cr.stroke ();
+
+ cr.restore ();
+ }
+
+ private Player current_player = Player.NOBODY;
+ private void draw_piece (Cairo.Context cr)
+ {
+ int offset;
+ switch (current_player)
+ {
+ case Player.HUMAN : offset = 0; break;
+ case Player.OPPONENT: offset = pixbuf_size; break;
+ case Player.NOBODY : offset = pixbuf_size * 2; break;
+ default: assert_not_reached ();
+ }
+
+ cr.save ();
+ int x = board_x + drawing_width - pixbuf_margin - pixbuf_size;
+ int y = board_y + pixbuf_margin;
+ Gdk.cairo_set_source_pixbuf (cr, tileset_pixbuf, x - offset, y);
+ cr.rectangle (x, y, pixbuf_size, pixbuf_size);
+
+ cr.clip ();
+ cr.paint ();
+ cr.restore ();
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]