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 @@
+
+
+
+
+ True
+ True
+ never
+
+
+
+
+
+
\ 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;
+ }
}