diff --git a/data/org.gnome.Games.gresource.xml b/data/org.gnome.Games.gresource.xml index 9cf2e1bc16f3cbb37782121a37496892e7298315..04d7c31cc4bf3b1ced79c9e1b5c5eb76e4ae2672 100644 --- a/data/org.gnome.Games.gresource.xml +++ b/data/org.gnome.Games.gresource.xml @@ -15,6 +15,7 @@ ui/collection-box.ui ui/collection-header-bar.ui ui/collection-icon-view.ui + ui/description-display.ui ui/developer-list-item.ui ui/display-box.ui ui/display-header-bar.ui diff --git a/data/ui/description-display.ui b/data/ui/description-display.ui new file mode 100644 index 0000000000000000000000000000000000000000..c0c38fdfbba8314a67111c0e05eec07735eda564 --- /dev/null +++ b/data/ui/description-display.ui @@ -0,0 +1,261 @@ + + + + + \ No newline at end of file diff --git a/data/ui/display-box.ui b/data/ui/display-box.ui index 2e7d8aadcb8bc43340c205e76874c10b4a45ba4e..563680e940df14d2174c7e5529afae7e6e76e525 100644 --- a/data/ui/display-box.ui +++ b/data/ui/display-box.ui @@ -32,6 +32,11 @@ display + + + True + + diff --git a/data/ui/display-header-bar.ui b/data/ui/display-header-bar.ui index a8942d2cd430b59eeda52ffde0bdf4e4348a92cc..b1c107153b24d27c3188e0397aad49156600538c 100644 --- a/data/ui/display-header-bar.ui +++ b/data/ui/display-header-bar.ui @@ -29,6 +29,13 @@ + + + True + Details + + + False diff --git a/po/POTFILES.in b/po/POTFILES.in index a30a8a132805d9d5e264bd918070956134482515..799b91923308f70d24d5764c38986d7747706b89 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -5,6 +5,7 @@ data/org.gnome.Games.desktop.in.in data/org.gnome.Games.gschema.xml data/ui/collection-box.ui data/ui/collection-header-bar.ui +data/ui/description-display.ui data/ui/display-header-bar.ui data/ui/dummy-display.ui data/ui/empty-collection.ui diff --git a/src/meson.build b/src/meson.build index 88beca3b2e1f58dbce0349be14aaa52564d481e9..cb860d26eac5a7150b0f06efb929d1261d88a0bd 100644 --- a/src/meson.build +++ b/src/meson.build @@ -130,6 +130,7 @@ vala_sources = [ 'ui/collection-box.vala', 'ui/collection-icon-view.vala', 'ui/collection-header-bar.vala', + 'ui/description-display.vala', 'ui/developer-list-item.vala', 'ui/developers-view.vala', 'ui/display-box.vala', diff --git a/src/ui/application-window.vala b/src/ui/application-window.vala index 443036a7fb1e467c1014dd74a8f68192cbc81c0d..6ec0626e8cc0e888f0f6c0437208b42fe9809475 100644 --- a/src/ui/application-window.vala +++ b/src/ui/application-window.vala @@ -55,6 +55,27 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow { } } + private bool _toggle; + public bool toggle { + get { return _toggle; } + set { + _toggle = value; + + if (value) + display_box.runner.pause (); + else + try { + display_box.runner.resume (); + } + catch (Error e) { + warning (e.message); + } + + display_box.on_toggle (value); + } + default = false; + } + private bool _search_mode; public bool search_mode { get { return _search_mode; } @@ -88,6 +109,7 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow { private Binding header_bar_fullscreen_binding; private Binding header_bar_empty_collection_binding; private Binding loading_notification_binding; + private Binding toggle_button_binding; private Cancellable run_game_cancellable; private Cancellable quit_game_cancellable; @@ -138,6 +160,8 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow { BindingFlags.BIDIRECTIONAL); header_bar_fullscreen_binding = bind_property ("is-fullscreen", display_header_bar, "is-fullscreen", BindingFlags.BIDIRECTIONAL); + toggle_button_binding = bind_property ("toggle", display_header_bar, "is-active", + BindingFlags.BIDIRECTIONAL); box_empty_collection_binding = bind_property ("is-collection-empty", collection_box, "is-collection-empty", BindingFlags.BIDIRECTIONAL); @@ -343,6 +367,7 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow { // Reset the UI parts depending on the runner to avoid an // inconsistent state is case we couldn't retrieve it. reset_display_page (); + display_box.game = game; var runner = try_get_runner (game); if (runner == null) @@ -557,7 +582,7 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow { if (!can_update_pause ()) return; - if (is_active) + if (is_active && !toggle) try { display_box.runner.resume (); } diff --git a/src/ui/description-display.vala b/src/ui/description-display.vala new file mode 100644 index 0000000000000000000000000000000000000000..71e5412e0cfba921501ff5166247f14483024319 --- /dev/null +++ b/src/ui/description-display.vala @@ -0,0 +1,244 @@ +// This file is part of GNOME Games. License: GPL-3.0+. + +[GtkTemplate (ui = "/org/gnome/Games/ui/description-display.ui")] +private class Games.DescriptionDisplay : Gtk.ScrolledWindow { + private Game _game; + public Game game { + set { + if (_game == value) + return; + + _game = value; + + queue_draw (); + + initialize (); + } + + get{ return _game; } + } + + private ulong developer_changed_id; + private Developer _developer; + public Developer developer { + get { return _developer; } + set { + _developer = value; + if (_developer != null) + developer_changed_id = _developer.changed.connect (update_developer); + + update_developer (); + } + } + + private void update_developer () { + var developer_name = developer.get_developer (); + if (developer_name != null) + developer_label.label = developer_name; + else + developer_label.label = "-"; + } + + private ulong publisher_changed_id; + private Publisher _publisher; + public Publisher publisher { + get { return _publisher; } + set { + _publisher = value; + publisher_changed_id = _publisher.changed.connect (update_publisher); + + update_publisher (); + } + } + + private void update_publisher () { + var publisher_name = publisher.get_publisher (); + if (publisher_name != null) + publisher_label.label = publisher_name; + else + publisher_label.label = "-"; + } + + private ulong coop_changed_id; + private Cooperative _coop; + public Cooperative coop { + get { return _coop; } + set { + _coop = value; + coop_changed_id = _coop.changed.connect (update_coop); + + update_coop (); + } + } + + private void update_coop () { + if (coop is DummyCooperative) + coop_label.label = "-"; + else if (coop.get_cooperative ()) + coop_label.label = _("Yes"); + else + coop_label.label = _("No"); + } + + private ulong player_changed_id; + private Players _player; + public Players player { + get { return _player; } + set { + _player = value; + player_changed_id = _player.changed.connect (update_player); + + update_player (); + } + default = null; + } + + private void update_player () { + var player_count = player.get_players (); + if (player_count != null) + players_label.label = player_count; + else + players_label.label = "-"; + } + + private ulong release_date_changed_id; + private ReleaseDate _release_date; + public ReleaseDate release_date { + get { return _release_date; } + set { + _release_date = value; + release_date_changed_id = _release_date.changed.connect (update_release_date); + + update_release_date (); + } + } + + private void update_release_date () { + var date = release_date.get_release_date (); + if (date != null) + release_date_label.label = date.to_string ().substring (0, 10); + else + release_date_label.label = "-"; + } + + private ulong genre_changed_id; + private Genre _genre; + public Genre genre { + get { return _genre; } + set { + _genre = value; + genre_changed_id = _genre.changed.connect (update_genre); + + update_genre (); + } + default = null; + } + + private void update_genre () { + unowned List genre_list = genre.get_genre(); + string[] genres = {}; + + genre_list.foreach ((item) => { + genres += item; + }); + + if (genres != null) { + genre_label.label = string.joinv (", ", genres); + } + else if (genre_list.length() == 0) + genre_label.label = "-"; + } + + private ulong description_changed_id; + private Description _description; + public Description description { + get { return _description; } + set { + _description = value; + description_changed_id = _description.changed.connect (update_description); + + update_description (); + } + } + + private void update_description () { + var description_text = description.get_description (); + if (description_text != null) + description_label.label = description_text; + else + description_label.label = _("No description available."); + } + + private ulong rating_changed_id; + private Rating _rating; + public Rating rating { + get { return _rating; } + set { + _rating = value; + rating_changed_id = _rating.changed.connect (update_rating); + + update_rating (); + } + } + + private void update_rating () { + var stars = rating.get_rating (); + + GLib.List children = rating_box.get_children (); + foreach (Gtk.Widget element in children) + rating_box.remove (element); + + var rate = (int) GLib.Math.roundf (stars); + for (int i = 1; i <= 5; i++) { + var star = new Gtk.Image.from_icon_name ("starred-symbolic", Gtk.IconSize.BUTTON); + star.visible = true; + var context = star.get_style_context (); + if (i <= rate) + context.add_class ("star-enabled"); + else + context.add_class ("star-disabled"); + rating_box.add (star); + } + } + + [GtkChild] + private GameThumbnail thumbnail; + [GtkChild] + private Gtk.Label title; + [GtkChild] + private Gtk.Box rating_box; + [GtkChild] + private Gtk.Label description_label; + [GtkChild] + private Gtk.Label genre_label; + [GtkChild] + private Gtk.Label coop_label; + [GtkChild] + private Gtk.Label players_label; + [GtkChild] + private Gtk.Label developer_label; + [GtkChild] + private Gtk.Label publisher_label; + [GtkChild] + private Gtk.Label release_date_label; + + static construct { + set_css_name ("gamesdescriptiondisplay"); + } + + private void initialize () { + thumbnail.icon = _game.get_icon (); + thumbnail.cover = _game.get_cover (); + title.label = game.name; + + description = _game.get_description (); + rating = _game.get_rating (); + developer = _game.get_developer (); + publisher = _game.get_publisher (); + coop = _game.get_cooperative (); + player = _game.get_players (); + release_date = _game.get_release_date (); + genre = _game.get_genre (); + } + +} diff --git a/src/ui/display-box.vala b/src/ui/display-box.vala index 97e96039f9b1a0f2d1d6528d62a8e37eaa83ac9e..cdfd17a3ef14d00ef9dc1c5aac39411806e57ff1 100644 --- a/src/ui/display-box.vala +++ b/src/ui/display-box.vala @@ -10,6 +10,12 @@ private class Games.DisplayBox : Gtk.Bin { get { return fullscreen_header_bar; } } + public Game game { + set { + description_display.game = value; + } + } + private Runner _runner; public Runner runner { get { return _runner; } @@ -31,6 +37,8 @@ private class Games.DisplayBox : Gtk.Bin { [GtkChild] private FullscreenBox fullscreen_box; [GtkChild] + private DescriptionDisplay description_display; + [GtkChild] private Gtk.Stack stack; [GtkChild] private ErrorDisplay error_display; @@ -54,6 +62,15 @@ private class Games.DisplayBox : Gtk.Bin { error_display.running_game_failed (game, error_message); } + public void on_toggle (bool active) { + if (active){ + stack.visible_child = description_display; + } + else { + stack.visible_child = display_bin; + } + } + [GtkCallback] private void on_fullscreen_header_bar_back () { back (); diff --git a/src/ui/display-header-bar.vala b/src/ui/display-header-bar.vala index 8e5bf941dad5659ee828ad7aac946aedc9ed4e75..d1fdbabbca79ceb22463fe5551078ff67e8caaf2 100644 --- a/src/ui/display-header-bar.vala +++ b/src/ui/display-header-bar.vala @@ -11,8 +11,9 @@ private class Games.DisplayHeaderBar : Gtk.HeaderBar { set { title = value; } } - public bool can_fullscreen { get; set; } - public bool is_fullscreen { get; set; } + public bool can_fullscreen { set; get; } + public bool is_fullscreen { set; get; } + public bool is_active { set; get; } public MediaSet? media_set { set { @@ -43,6 +44,9 @@ private class Games.DisplayHeaderBar : Gtk.HeaderBar { [GtkChild] private Gtk.Button restore; + [GtkChild] + private Gtk.ToggleButton details; + private Settings settings; construct { @@ -65,6 +69,7 @@ private class Games.DisplayHeaderBar : Gtk.HeaderBar { [GtkCallback] private void on_back_clicked () { back (); + details.set_active (false); } [GtkCallback] @@ -78,4 +83,9 @@ private class Games.DisplayHeaderBar : Gtk.HeaderBar { is_fullscreen = false; settings.set_boolean ("fullscreen", false); } + + [GtkCallback] + private void on_toggle () { + is_active = details.active; + } }