Commit d045a385 authored by Arnaud B.'s avatar Arnaud B.

HistoryButton DrawingArea.

parent f8fb207f
......@@ -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>
......@@ -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)
{
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 on a one-player game end in the headerbar/actionbar, if the computer player won */
set_status_message (_("I win!"));
}
else
{
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
{
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!"));
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));
}
......
......@@ -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 ();
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment