[gnome-mines] Sidebar buttons moved to headerbar
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-mines] Sidebar buttons moved to headerbar
- Date: Fri, 15 Oct 2021 12:25:10 +0000 (UTC)
commit 388b225f8e97128078192ec0b2d82b9be8cc3120
Author: lajonss <l3n1 dupaw eu>
Date: Sat Jan 2 16:08:11 2021 +0100
Sidebar buttons moved to headerbar
In the existing layout sidebar buttons (new game, pause, clear board and
high scores) were taking big amount of screen space. When window had
a vertical aspect ratio more space was wasted above and below the
minefield. The loss of space was especially painfull on a smartphone
screen.
This commit introduces changes in layout to minimize the loss of screen
space:
- new game, pause and clear board buttons were moved to the headerbar
- high scores button was removed (the action remains available in the
primary menu)
- clock and mines counter may be moved below the minefield if the window
has vertical aspect ratio
Semi-related changes:
- primary menu definition was moved from vala to interface.ui
- minimum tile size was increased to 30
src/gnome-mines.vala | 163 ++++++++++++++++---------------
src/interface.ui | 251 +++++++++++++++++++++++++-----------------------
src/minefield-view.vala | 3 +-
3 files changed, 219 insertions(+), 198 deletions(-)
---
diff --git a/src/gnome-mines.vala b/src/gnome-mines.vala
index 9e633ef..cee8d4c 100644
--- a/src/gnome-mines.vala
+++ b/src/gnome-mines.vala
@@ -33,23 +33,21 @@ public class Mines : Gtk.Application
public const string KEY_USE_ANIMATIONS = "use-animations";
private Widget main_screen;
+ private Box main_screen_layout;
+ private Box main_screen_sidebar;
+
private Button play_pause_button;
- private Label play_pause_label;
+ private Image play_pause_image;
private Button replay_button;
- private Button high_scores_button;
private Button new_game_button;
- private AspectFrame minefield_aspect;
private Overlay minefield_overlay;
- private Box aspect_child;
- private Box buttons_box;
private Box paused_box;
- private ScrolledWindow scrolled;
+ private AspectFrame aspect_frame;
private Stack stack;
private ThemeSelectorDialog theme_dialog;
private Label clock_label;
- private GLib.Menu app_main_menu;
private Gtk.MenuButton menu_button;
/* Main window */
@@ -59,9 +57,7 @@ public class Mines : Gtk.Application
private bool window_is_maximized;
private bool window_is_fullscreen;
private bool window_is_tiled;
-
- /* true when the new game minefield draws once */
- private bool first_draw = false;
+ private Orientation current_layout = Orientation.VERTICAL;
/* true when the user has requested the game to pause. */
private bool pause_requested;
@@ -221,30 +217,7 @@ public class Mines : Gtk.Application
window.maximize ();
add_window (window);
- var headerbar = new HeaderBar ();
- headerbar.show_close_button = true;
- headerbar.set_title (_("Mines"));
- headerbar.show ();
- window.set_titlebar (headerbar);
-
- var menu = new GLib.Menu ();
- app_main_menu = new GLib.Menu ();
- menu.append_section (null, app_main_menu);
- app_main_menu.append (_("_Scores"), "app.scores");
- app_main_menu.append (_("A_ppearance"), "app.preferences");
- var section = new GLib.Menu ();
- menu.append_section (null, section);
- section.append (_("_Use Question Flags"), "app.%s".printf (KEY_USE_QUESTION_MARKS));
- section = new GLib.Menu ();
- menu.append_section (null, section);
- section.append (_("_Keyboard Shortcuts"), "win.show-help-overlay");
- section.append (_("_Help"), "app.help");
- section.append (_("_About Mines"), "app.about");
- menu_button = new MenuButton ();
- menu_button.set_image (new Image.from_icon_name ("open-menu-symbolic", IconSize.BUTTON));
- menu_button.show ();
- menu_button.set_menu_model (menu);
- headerbar.pack_end (menu_button);
+ menu_button = (Gtk.MenuButton) ui_builder.get_object ("menu_button");
set_accels_for_action ("app.new-game", {"<Primary>n"});
set_accels_for_action ("app.silent-new-game", {"Escape"});
@@ -261,45 +234,16 @@ public class Mines : Gtk.Application
minefield_view = new MinefieldView (settings);
minefield_view.show ();
- /* Hook a resize on the first minefield draw so that the ratio
- calculation in minefield_aspect.size-allocate runs one more time
- with stable allocation sizes for the current minefield configutation */
- minefield_view.draw.connect ((context, data) => {
- if(!first_draw) {
- minefield_aspect.queue_resize ();
- minefield_view.queue_draw ();
- first_draw = true;
- return true;
- };
- return false;
- });
-
stack = (Stack) ui_builder.get_object ("stack");
- scrolled = (ScrolledWindow) ui_builder.get_object ("scrolled");
- scrolled.add (minefield_view);
- scrolled.show ();
+ aspect_frame = (AspectFrame) ui_builder.get_object ("aspect_frame");
+ aspect_frame.add (minefield_view);
+ aspect_frame.show ();
minefield_overlay = (Overlay) ui_builder.get_object ("minefield_overlay");
minefield_overlay.show ();
- minefield_aspect = (AspectFrame) ui_builder.get_object ("minefield_aspect");
- minefield_aspect.show ();
-
- minefield_aspect.size_allocate.connect ((allocation) => {
- uint width = minefield_view.mine_size * minefield_view.minefield.width;
- width += aspect_child.spacing;
- width += buttons_box.get_allocated_width ();
- float new_ratio = (float) width / (minefield_view.minefield.height * minefield_view.mine_size);
- if (new_ratio != minefield_aspect.ratio) {
- minefield_aspect.ratio = new_ratio;
- first_draw = false;
- };
- });
-
paused_box = (Box) ui_builder.get_object ("paused_box");
- buttons_box = (Box) ui_builder.get_object ("buttons_box");
- aspect_child = (Box) ui_builder.get_object ("aspect_child");
paused_box.button_press_event.connect (view_button_press_event);
minefield_overlay.add_overlay (paused_box);
@@ -307,6 +251,9 @@ public class Mines : Gtk.Application
main_screen = (Widget) ui_builder.get_object ("main_screen");
main_screen.show_all ();
+ main_screen_layout = (Box) ui_builder.get_object ("main_screen_layout");
+ main_screen_sidebar = (Box) ui_builder.get_object ("main_screen_sidebar");
+
/* Initialize New Game Screen */
startup_new_game_screen (ui_builder);
@@ -326,11 +273,12 @@ public class Mines : Gtk.Application
clock_label = (Label) ui_builder.get_object ("clock_label");
play_pause_button = (Button) ui_builder.get_object ("play_pause_button");
- play_pause_label = (Label) ui_builder.get_object ("play_pause_label");
+ play_pause_image = (Image) ui_builder.get_object ("play_pause_image");
- high_scores_button = (Button) ui_builder.get_object ("high_scores_button");
replay_button = (Button) ui_builder.get_object ("replay_button");
+
new_game_button = (Button) ui_builder.get_object ("new_game_button");
+ new_game_button.tooltip_text = translate_and_strip_underlines ("Change _Difficulty");
if (game_mode != -1)
start_game ();
@@ -435,14 +383,34 @@ public class Mines : Gtk.Application
private void size_allocate_cb (Allocation allocation)
{
+ int width, height;
+ window.get_size (out width, out height);
if (!window_is_maximized && !window_is_fullscreen && !window_is_tiled && !window_skip_configure)
{
- window.get_size (out window_width, out window_height);
+ window_width = width;
+ window_height = height;
}
+ set_main_screen_layout (width > height ? Orientation.HORIZONTAL : Orientation.VERTICAL);
window_skip_configure = false;
}
+ private void set_main_screen_layout (Orientation orientation)
+ {
+ if (orientation == current_layout)
+ return;
+
+ main_screen_layout.orientation = orientation;
+ main_screen_sidebar.orientation = current_layout;
+
+ current_layout = orientation;
+ }
+
+ private string translate_and_strip_underlines (string key)
+ {
+ return _(key).replace ("_", "");
+ }
+
private const Gdk.WindowState tiled_state = Gdk.WindowState.TILED
| Gdk.WindowState.TOP_TILED
| Gdk.WindowState.BOTTOM_TILED
@@ -627,6 +595,7 @@ public class Mines : Gtk.Application
size_actions_toggle (true);
stack.visible_child_name = "new_game";
+ disable_game_buttons ();
}
private void size_actions_toggle (bool enabled)
@@ -643,10 +612,9 @@ public class Mines : Gtk.Application
minefield_view.has_focus = true;
repeat_size_action.set_enabled (false);
- play_pause_label.label = _("_Pause");
- replay_button.label = _("St_art Over");
- play_pause_button.show ();
- high_scores_button.hide ();
+ set_play_pause_visuals_unpaused ();
+ set_replay_tooltip ("St_art Over");
+ enable_game_buttons ();
int x, y, n;
switch (settings.get_int (KEY_MODE))
@@ -674,6 +642,8 @@ public class Mines : Gtk.Application
break;
}
+ aspect_frame.ratio = ((float) x) / y;
+
if (minefield != null)
SignalHandler.disconnect_by_func (minefield, null, this);
minefield = new Minefield (x, y, n);
@@ -697,6 +667,44 @@ public class Mines : Gtk.Application
tick_cb ();
}
+ private void set_play_pause_visuals_unpaused ()
+ {
+ set_play_pause_visuals ("media-playback-pause-symbolic", "_Pause");
+ }
+
+ private void set_play_pause_visuals_paused ()
+ {
+ set_play_pause_visuals ("media-playback-start-symbolic", "_Resume");
+ }
+
+ private void set_play_pause_visuals (string icon_name, string tooltip_text)
+ {
+ play_pause_image.icon_name = icon_name;
+ play_pause_button.tooltip_text = translate_and_strip_underlines (tooltip_text);
+ }
+
+ private void set_replay_tooltip (string tooltip_text)
+ {
+ replay_button.tooltip_text = translate_and_strip_underlines (tooltip_text);
+ }
+
+ private void enable_game_buttons ()
+ {
+ set_game_buttons_enabled (true);
+ }
+
+ private void disable_game_buttons ()
+ {
+ set_game_buttons_enabled (false);
+ }
+
+ private void set_game_buttons_enabled (bool value)
+ {
+ new_game_button.visible = value;
+ replay_button.visible = value;
+ play_pause_button.visible = value;
+ }
+
private void new_game_cb ()
{
if (can_start_new_game ())
@@ -731,9 +739,9 @@ public class Mines : Gtk.Application
private void paused_changed_cb ()
{
if (minefield.paused)
- play_pause_label.label = _("_Resume");
+ set_play_pause_visuals_paused ();
else if (minefield.elapsed > 0)
- play_pause_label.label = _("_Pause");
+ set_play_pause_visuals_unpaused ();
paused_box.visible = minefield.paused;
}
@@ -749,12 +757,11 @@ public class Mines : Gtk.Application
private void game_ended ()
{
- replay_button.label = _("Play _Again");
+ set_replay_tooltip ("Play _Again");
pause_action.set_enabled (false);
replay_button.sensitive = true;
repeat_size_action.set_enabled (true);
play_pause_button.hide ();
- high_scores_button.show ();
}
private void cleared_cb (Minefield minefield)
@@ -782,7 +789,7 @@ public class Mines : Gtk.Application
private void clock_started_cb ()
{
- play_pause_label.label = _("_Pause");
+ set_play_pause_visuals_unpaused ();
replay_button.sensitive = true;
pause_action.set_enabled (true);
repeat_size_action.set_enabled (true);
diff --git a/src/interface.ui b/src/interface.ui
index 51c49cf..22cc1da 100644
--- a/src/interface.ui
+++ b/src/interface.ui
@@ -2,21 +2,112 @@
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
- <object class="GtkSizeGroup" id="buttons_size_group">
+ <object class="GtkSizeGroup" id="labels_size_group">
<property name="mode">both</property>
<widgets>
- <widget name="play_pause_button"/>
- <widget name="high_scores_button"/>
- <widget name="new_game_button"/>
- <widget name="replay_button"/>
+ <widget name="flag_label"/>
+ <widget name="clock_label"/>
</widgets>
</object>
+ <menu id="primary-menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Scores</attribute>
+ <attribute name="action">app.scores</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">A_ppearance</attribute>
+ <attribute name="action">app.preferences</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Use Question Flags</attribute>
+ <attribute name="action">app.use-question-marks</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
+ <attribute name="action">win.show-help-overlay</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_Help</attribute>
+ <attribute name="action">app.help</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_About Mines</attribute>
+ <attribute name="action">app.about</attribute>
+ </item>
+ </section>
+ </menu>
<object class="GtkApplicationWindow" id="main_window">
- <property name="width_request">590</property>
- <property name="height_request">460</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Mines</property>
<property name="icon_name">gnome-mines</property>
+ <child type="titlebar">
+ <object class="GtkHeaderBar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Mines</property>
+ <property name="show_close_button">True</property>
+ <child>
+ <object class="GtkButton" id="new_game_button">
+ <property name="action_name">app.new-game</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="icon_name">go-previous-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="replay_button">
+ <property name="action_name">app.repeat-size</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="icon_name">view-refresh-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="menu_button">
+ <property name="visible">True</property>
+ <property name="menu_model">primary-menu</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="icon_name">open-menu-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="play_pause_button">
+ <property name="action_name">app.pause</property>
+ <child>
+ <object class="GtkImage" id="play_pause_image">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="icon_name">media-playback-pause-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
<child>
<object class="GtkBox" id="main_vbox">
<property name="visible">True</property>
@@ -239,47 +330,49 @@
<object class="GtkBox" id="main_screen">
<property name="can_focus">False</property>
<child>
- <object class="GtkAspectFrame" id="minefield_aspect">
+ <object class="GtkBox" id="main_screen_layout">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <property name="xalign">0.5</property>
- <property name="obey_child">False</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkBox" id="aspect_child">
+ <object class="GtkOverlay" id="minefield_overlay">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="spacing">24</property>
<child>
- <object class="GtkOverlay" id="minefield_overlay">
+ <object class="GtkScrolledWindow" id="scrolled">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
<child>
- <object class="GtkScrolledWindow" id="scrolled">
+ <object class="GtkAspectFrame" id="aspect_frame">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="can_focus">False</property>
+ <property name="obey_child">False</property>
+ <property name="shadow_type">none</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="main_screen_sidebar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">24</property>
+ <property name="margin">24</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
<child>
- <object class="GtkBox" id="buttons_box">
- <property name="width_request">150</property>
+ <object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="spacing">6</property>
<property name="orientation">vertical</property>
- <property name="spacing">4</property>
<child>
<object class="GtkImage" id="flag_image">
<property name="visible">True</property>
@@ -306,6 +399,14 @@
<property name="position">1</property>
</packing>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="orientation">vertical</property>
<child>
<object class="GtkImage" id="clock_image">
<property name="visible">True</property>
@@ -326,6 +427,7 @@
<property name="margin_bottom">12</property>
<property name="yalign">0</property>
<property name="label">0:00</property>
+ <property name="width_request">90</property>
</object>
<packing>
<property name="expand">True</property>
@@ -333,89 +435,14 @@
<property name="position">3</property>
</packing>
</child>
- <child>
- <object class="GtkButton" id="play_pause_button">
- <property name="width_request">120</property>
- <property name="height_request">60</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">app.pause</property>
- <property name="use_underline">True</property>
- <child>
- <object class="GtkLabel" id="play_pause_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Pause</property>
- <property name="use_underline">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="new_game_button">
- <property name="width_request">120</property>
- <property name="height_request">60</property>
- <property name="label" translatable="yes">Change _Difficulty</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">app.new-game</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">6</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="high_scores_button">
- <property name="width_request">120</property>
- <property name="height_request">60</property>
- <property name="label" translatable="yes">_Best Times</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">app.scores</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">6</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="replay_button">
- <property name="width_request">120</property>
- <property name="height_request">60</property>
- <property name="label" translatable="yes">_Play Again</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">app.repeat-size</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">7</property>
- </packing>
- </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
<packing>
@@ -430,22 +457,10 @@
</packing>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
</object>
</child>
</object>
- <object class="GtkSizeGroup" id="buttons_matcher">
- <property name="mode">vertical</property>
- <widgets>
- <widget name="buttons_box"/>
- <widget name="minefield_overlay"/>
- </widgets>
- </object>
<object class="GtkBox" id="paused_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
diff --git a/src/minefield-view.vala b/src/minefield-view.vala
index 59f20cb..57c75bf 100644
--- a/src/minefield-view.vala
+++ b/src/minefield-view.vala
@@ -134,8 +134,7 @@ public class MinefieldView : Gtk.Grid
var w = 320 / minefield.width;
var h = 200 / minefield.height;
var s = uint.min (w, h);
- if (s < 20)
- s = 20;
+ s = uint.max(30, s);
return s;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]