[gnome-games/wip/exalm/views: 108/109] display-view: Handle running and quitting games
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/wip/exalm/views: 108/109] display-view: Handle running and quitting games
- Date: Sun, 24 Feb 2019 18:40:49 +0000 (UTC)
commit 7ebecdf07ba607fc64c849c872c53419148d07bc
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date: Thu Oct 4 22:54:47 2018 +0500
display-view: Handle running and quitting games
src/ui/application-window.vala | 327 +----------------------------------------
src/ui/display-view.vala | 317 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 324 insertions(+), 320 deletions(-)
---
diff --git a/src/ui/application-window.vala b/src/ui/application-window.vala
index e7d49fec..4c576d52 100644
--- a/src/ui/application-window.vala
+++ b/src/ui/application-window.vala
@@ -3,7 +3,6 @@
[GtkTemplate (ui = "/org/gnome/Games/ui/application-window.ui")]
private class Games.ApplicationWindow : Gtk.ApplicationWindow {
private const uint WINDOW_SIZE_UPDATE_DELAY_MILLISECONDS = 500;
- private const uint FOCUS_OUT_DELAY_MILLISECONDS = 500;
private const string CONTRIBUTE_URI = "https://wiki.gnome.org/Apps/Games/Contribute";
@@ -62,15 +61,7 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
private Binding fullscreen_binding;
private Binding loading_notification_binding;
- private Cancellable run_game_cancellable;
- private Cancellable quit_game_cancellable;
-
- private ResumeDialog resume_dialog;
- private ResumeFailedDialog resume_failed_dialog;
- private QuitDialog quit_dialog;
-
private long window_size_update_timeout;
- private long focus_out_timeout_id;
private uint inhibit_cookie;
private Gtk.ApplicationInhibitFlags inhibit_flags;
@@ -119,7 +110,6 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
konami_code.code_performed.connect (on_konami_code_performed);
window_size_update_timeout = -1;
- focus_out_timeout_id = -1;
inhibit_cookie = 0;
inhibit_flags = 0;
@@ -132,21 +122,8 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
}
public void run_game (Game game) {
- // If there is a game already running we have to quit it first
- if (display_view.box.runner != null && !quit_game ())
- return;
-
- if (run_game_cancellable != null)
- run_game_cancellable.cancel ();
-
- var cancellable = new Cancellable ();
- run_game_cancellable = cancellable;
-
- run_game_with_cancellable (game, cancellable);
-
- // Only reset the cancellable if another one didn't replace it.
- if (run_game_cancellable == cancellable)
- run_game_cancellable = null;
+ current_view = display_view;
+ display_view.run_game (game);
inhibit (Gtk.ApplicationInhibitFlags.IDLE | Gtk.ApplicationInhibitFlags.LOGOUT);
}
@@ -157,22 +134,7 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
if (!visible)
return true;
- if (run_game_cancellable != null)
- run_game_cancellable.cancel ();
-
- if (quit_game_cancellable != null)
- quit_game_cancellable.cancel ();
-
- var cancellable = new Cancellable ();
- quit_game_cancellable = cancellable;
-
- var result = quit_game_with_cancellable (cancellable);
-
- // Only reset the cancellable if another one didn't replace it.
- if (quit_game_cancellable == cancellable)
- quit_game_cancellable = null;
-
- return result;
+ return display_view.quit_game ();
}
public override void size_allocate (Gtk.Allocation allocation) {
@@ -215,7 +177,8 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
settings.set_boolean ("window-maximized", is_maximized);
is_fullscreen = (bool) (event.new_window_state & Gdk.WindowState.FULLSCREEN);
- update_pause (false);
+ if (current_view == display_view)
+ display_view.update_pause (false);
if (!(bool) (event.changed_mask & Gdk.WindowState.FOCUSED))
return false;
@@ -233,36 +196,7 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
}
public bool gamepad_button_press_event (Manette.Event event) {
- if (current_view == collection_view)
- return collection_view.gamepad_button_press_event (event);
- else if (current_view == display_view) {
- if (resume_dialog != null)
- return resume_dialog.is_active && resume_dialog.gamepad_button_press_event
(event);
-
- if (resume_failed_dialog != null)
- return resume_failed_dialog.is_active &&
resume_failed_dialog.gamepad_button_press_event (event);
-
- if (quit_dialog != null)
- return quit_dialog.is_active && quit_dialog.gamepad_button_press_event
(event);
-
- if (!is_active || !get_mapped ())
- return false;
-
- uint16 button;
- if (!event.get_button (out button))
- return false;
-
- switch (button) {
- case EventCode.BTN_MODE:
- current_view = collection_view;
-
- return true;
- default:
- return false;
- }
- }
-
- return false;
+ return current_view.gamepad_button_press_event (event);
}
public bool gamepad_button_release_event (Manette.Event event) {
@@ -292,196 +226,10 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
uninhibit (Gtk.ApplicationInhibitFlags.IDLE | Gtk.ApplicationInhibitFlags.LOGOUT);
}
- private void run_game_with_cancellable (Game game, Cancellable cancellable) {
- display_view.header_bar.game_title = game.name;
- display_view.box.header_bar.game_title = game.name;
- current_view = display_view;
-
- // Reset the UI parts depending on the runner to avoid an
- // inconsistent state is case we couldn't retrieve it.
- reset_display_page ();
-
- var runner = try_get_runner (game);
- if (runner == null)
- return;
-
- display_view.header_bar.can_fullscreen = runner.can_fullscreen;
- display_view.box.header_bar.can_fullscreen = runner.can_fullscreen;
- display_view.header_bar.runner = runner;
- display_view.box.runner = runner;
- display_view.header_bar.media_set = runner.media_set;
- display_view.box.header_bar.media_set = runner.media_set;
-
- is_fullscreen = settings.get_boolean ("fullscreen") && runner.can_fullscreen;
-
- if (!runner.can_resume) {
- try_run_with_cancellable (runner, false, cancellable);
- return;
- }
-
- var response = Gtk.ResponseType.NONE;
- if (runner.can_resume)
- response = prompt_resume_with_cancellable (cancellable);
-
- if (response != Gtk.ResponseType.NONE) {
- var resume = (response == Gtk.ResponseType.ACCEPT);
-
- if (!try_run_with_cancellable (runner, resume, cancellable))
- prompt_resume_fail_with_cancellable (runner, cancellable);
- }
- }
-
- private Runner? try_get_runner (Game game) {
- try {
- var runner = game.get_runner ();
- string error_message;
- if (runner.check_is_valid (out error_message))
- return runner;
-
- reset_display_page ();
- display_view.box.display_running_game_failed (game, error_message);
-
- return null;
- }
- catch (Error e) {
- warning (e.message);
- reset_display_page ();
- display_view.box.display_running_game_failed (game, _("An unexpected error
occurred."));
-
- return null;
- }
- }
-
- private Gtk.ResponseType prompt_resume_with_cancellable (Cancellable cancellable) {
- if (resume_dialog != null)
- return Gtk.ResponseType.NONE;
-
- resume_dialog = new ResumeDialog ();
- resume_dialog.transient_for = this;
-
- cancellable.cancelled.connect (() => {
- resume_dialog.destroy ();
- resume_dialog = null;
- });
-
- var response = resume_dialog.run ();
-
- // The null check is necessary because the dialog could already
- // be canceled by this point
- if (resume_dialog != null) {
- resume_dialog.destroy ();
- resume_dialog = null;
- }
-
- return (Gtk.ResponseType) response;
- }
-
- private bool try_run_with_cancellable (Runner runner, bool resume, Cancellable cancellable) {
- try {
- if (resume)
- display_view.box.runner.resume ();
- else
- runner.start ();
-
- return true;
- }
- catch (Error e) {
- warning (e.message);
-
- return false;
- }
- }
-
- private void prompt_resume_fail_with_cancellable (Runner runner, Cancellable cancellable) {
- if (resume_failed_dialog != null)
- return;
-
- resume_failed_dialog = new ResumeFailedDialog ();
- resume_failed_dialog.transient_for = this;
-
- cancellable.cancelled.connect (() => {
- resume_failed_dialog.destroy ();
- resume_failed_dialog = null;
- });
-
- var response = resume_failed_dialog.run ();
- resume_failed_dialog.destroy ();
- resume_failed_dialog = null;
-
- if (cancellable.is_cancelled ())
- response = Gtk.ResponseType.CANCEL;
-
- if (response == Gtk.ResponseType.CANCEL) {
- display_view.box.runner = null;
- current_view = collection_view;
-
- return;
- }
-
- try {
- runner.start ();
- }
- catch (Error e) {
- warning (e.message);
- }
- }
-
- public bool quit_game_with_cancellable (Cancellable cancellable) {
- if (display_view.box.runner == null)
- return true;
-
- display_view.box.runner.pause ();
-
- if (display_view.box.runner.can_quit_safely) {
- display_view.box.runner.stop ();
-
- return true;
- }
-
- if (quit_dialog != null)
- return false;
-
- quit_dialog = new QuitDialog ();
- quit_dialog.transient_for = this;
-
- cancellable.cancelled.connect (() => {
- quit_dialog.destroy ();
- quit_dialog = null;
- });
-
- var response = quit_dialog.run ();
-
- // The null check is necessary because the dialog could already
- // be canceled by this point
- if (quit_dialog != null) {
- quit_dialog.destroy ();
- quit_dialog = null;
- }
-
- if (cancellable.is_cancelled ())
- return cancel_quitting_game ();
-
- if (response == Gtk.ResponseType.ACCEPT)
- return true;
-
- return cancel_quitting_game ();
- }
-
- private bool cancel_quitting_game () {
- if (display_view.box.runner != null)
- try {
- display_view.box.runner.resume ();
- }
- catch (Error e) {
- warning (e.message);
- }
-
- return false;
- }
-
[GtkCallback]
private void on_active_changed () {
- update_pause (true);
+ if (current_view == display_view)
+ display_view.update_pause (true);
}
private Gdk.Rectangle? get_geometry () {
@@ -521,56 +269,6 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
return false;
}
- private void update_pause (bool with_delay) {
- if (focus_out_timeout_id != -1) {
- Source.remove ((uint) focus_out_timeout_id);
- focus_out_timeout_id = -1;
- }
-
- if (!can_update_pause ())
- return;
-
- if (is_active)
- try {
- display_view.box.runner.resume ();
- }
- catch (Error e) {
- warning (e.message);
- }
- else if (with_delay)
- focus_out_timeout_id = Timeout.add (FOCUS_OUT_DELAY_MILLISECONDS,
on_focus_out_delay_elapsed);
- else
- display_view.box.runner.pause ();
- }
-
- private bool on_focus_out_delay_elapsed () {
- focus_out_timeout_id = -1;
-
- if (!can_update_pause ())
- return false;
-
- if (!is_active)
- display_view.box.runner.pause ();
-
- return false;
- }
-
- private bool can_update_pause () {
- if (current_view != display_view)
- return false;
-
- if (display_view.box.runner == null)
- return false;
-
- if (run_game_cancellable != null)
- return false;
-
- if (quit_game_cancellable != null)
- return false;
-
- return true;
- }
-
private void inhibit (Gtk.ApplicationInhibitFlags flags) {
if ((inhibit_flags & flags) == flags)
return;
@@ -602,15 +300,6 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
inhibit_flags = new_flags;
}
- private void reset_display_page () {
- display_view.header_bar.can_fullscreen = false;
- display_view.box.header_bar.can_fullscreen = false;
- display_view.header_bar.runner = null;
- display_view.box.runner = null;
- display_view.header_bar.media_set = null;
- display_view.box.header_bar.media_set = null;
- }
-
private void on_konami_code_performed () {
if (current_view != collection_view)
return;
diff --git a/src/ui/display-view.vala b/src/ui/display-view.vala
index 007b304b..e5944540 100644
--- a/src/ui/display-view.vala
+++ b/src/ui/display-view.vala
@@ -2,6 +2,8 @@
[GtkTemplate (ui = "/org/gnome/Games/ui/display-view.ui")]
private class Games.DisplayView: Gtk.Bin, ApplicationView {
+ private const uint FOCUS_OUT_DELAY_MILLISECONDS = 500;
+
public signal void back ();
[GtkChild]
@@ -42,6 +44,15 @@ private class Games.DisplayView: Gtk.Bin, ApplicationView {
private Binding box_fullscreen_binding;
private Binding header_bar_fullscreen_binding;
+ private Cancellable run_game_cancellable;
+ private Cancellable quit_game_cancellable;
+
+ private ResumeDialog resume_dialog;
+ private ResumeFailedDialog resume_failed_dialog;
+ private QuitDialog quit_dialog;
+
+ private long focus_out_timeout_id;
+
construct {
settings = new Settings ("org.gnome.Games");
@@ -50,6 +61,8 @@ private class Games.DisplayView: Gtk.Bin, ApplicationView {
header_bar_fullscreen_binding = bind_property ("is-fullscreen", header_bar,
"is-fullscreen",
BindingFlags.BIDIRECTIONAL);
+
+ focus_out_timeout_id = -1;
}
public bool on_button_pressed (Gdk.EventButton event) {
@@ -100,7 +113,30 @@ private class Games.DisplayView: Gtk.Bin, ApplicationView {
}
public bool gamepad_button_press_event (Manette.Event event) {
- return false;
+ if (resume_dialog != null)
+ return resume_dialog.is_active && resume_dialog.gamepad_button_press_event (event);
+
+ if (resume_failed_dialog != null)
+ return resume_failed_dialog.is_active &&
resume_failed_dialog.gamepad_button_press_event (event);
+
+ if (quit_dialog != null)
+ return quit_dialog.is_active && quit_dialog.gamepad_button_press_event (event);
+
+ if (!window.is_active || !get_mapped ())
+ return false;
+
+ uint16 button;
+ if (!event.get_button (out button))
+ return false;
+
+ switch (button) {
+ case EventCode.BTN_MODE:
+ back ();
+
+ return true;
+ default:
+ return false;
+ }
}
public bool gamepad_button_release_event (Manette.Event event) {
@@ -115,4 +151,283 @@ private class Games.DisplayView: Gtk.Bin, ApplicationView {
private void on_display_back () {
back ();
}
+
+ public void run_game (Game game) {
+ // If there is a game already running we have to quit it first
+ if (box.runner != null && !quit_game ())
+ return;
+
+ if (run_game_cancellable != null)
+ run_game_cancellable.cancel ();
+
+ var cancellable = new Cancellable ();
+ run_game_cancellable = cancellable;
+
+ run_game_with_cancellable (game, cancellable);
+
+ // Only reset the cancellable if another one didn't replace it.
+ if (run_game_cancellable == cancellable)
+ run_game_cancellable = null;
+ }
+
+ private void run_game_with_cancellable (Game game, Cancellable cancellable) {
+ header_bar.game_title = game.name;
+ box.header_bar.game_title = game.name;
+
+ // Reset the UI parts depending on the runner to avoid an
+ // inconsistent state is case we couldn't retrieve it.
+ reset_display_page ();
+
+ var runner = try_get_runner (game);
+ if (runner == null)
+ return;
+
+ header_bar.can_fullscreen = runner.can_fullscreen;
+ box.header_bar.can_fullscreen = runner.can_fullscreen;
+ header_bar.runner = runner;
+ box.runner = runner;
+ header_bar.media_set = runner.media_set;
+ box.header_bar.media_set = runner.media_set;
+
+ is_fullscreen = settings.get_boolean ("fullscreen") && runner.can_fullscreen;
+
+ if (!runner.can_resume) {
+ try_run_with_cancellable (runner, false, cancellable);
+ return;
+ }
+
+ var response = Gtk.ResponseType.NONE;
+ if (runner.can_resume)
+ response = prompt_resume_with_cancellable (cancellable);
+
+ if (response != Gtk.ResponseType.NONE) {
+ var resume = (response == Gtk.ResponseType.ACCEPT);
+
+ if (!try_run_with_cancellable (runner, resume, cancellable))
+ prompt_resume_fail_with_cancellable (runner, cancellable);
+ }
+ }
+
+ private Runner? try_get_runner (Game game) {
+ try {
+ var runner = game.get_runner ();
+ string error_message;
+ if (runner.check_is_valid (out error_message))
+ return runner;
+
+ reset_display_page ();
+ box.display_running_game_failed (game, error_message);
+
+ return null;
+ }
+ catch (Error e) {
+ warning (e.message);
+ reset_display_page ();
+ box.display_running_game_failed (game, _("An unexpected error occurred."));
+
+ return null;
+ }
+ }
+
+ private Gtk.ResponseType prompt_resume_with_cancellable (Cancellable cancellable) {
+ if (resume_dialog != null)
+ return Gtk.ResponseType.NONE;
+
+ resume_dialog = new ResumeDialog ();
+ resume_dialog.transient_for = window;
+
+ cancellable.cancelled.connect (() => {
+ resume_dialog.destroy ();
+ resume_dialog = null;
+ });
+
+ var response = resume_dialog.run ();
+
+ // The null check is necessary because the dialog could already
+ // be canceled by this point
+ if (resume_dialog != null) {
+ resume_dialog.destroy ();
+ resume_dialog = null;
+ }
+
+ return (Gtk.ResponseType) response;
+ }
+
+ private bool try_run_with_cancellable (Runner runner, bool resume, Cancellable cancellable) {
+ try {
+ if (resume)
+ box.runner.resume ();
+ else
+ runner.start ();
+
+ return true;
+ }
+ catch (Error e) {
+ warning (e.message);
+
+ return false;
+ }
+ }
+
+ private void prompt_resume_fail_with_cancellable (Runner runner, Cancellable cancellable) {
+ if (resume_failed_dialog != null)
+ return;
+
+ resume_failed_dialog = new ResumeFailedDialog ();
+ resume_failed_dialog.transient_for = window;
+
+ cancellable.cancelled.connect (() => {
+ resume_failed_dialog.destroy ();
+ resume_failed_dialog = null;
+ });
+
+ var response = resume_failed_dialog.run ();
+ resume_failed_dialog.destroy ();
+ resume_failed_dialog = null;
+
+ if (cancellable.is_cancelled ())
+ response = Gtk.ResponseType.CANCEL;
+
+ if (response == Gtk.ResponseType.CANCEL) {
+ box.runner = null;
+ back ();
+
+ return;
+ }
+
+ try {
+ runner.start ();
+ }
+ catch (Error e) {
+ warning (e.message);
+ }
+ }
+
+ public bool quit_game () {
+ if (run_game_cancellable != null)
+ run_game_cancellable.cancel ();
+
+ if (quit_game_cancellable != null)
+ quit_game_cancellable.cancel ();
+
+ var cancellable = new Cancellable ();
+ quit_game_cancellable = cancellable;
+
+ var result = quit_game_with_cancellable (cancellable);
+
+ // Only reset the cancellable if another one didn't replace it.
+ if (quit_game_cancellable == cancellable)
+ quit_game_cancellable = null;
+
+ return result;
+ }
+
+ public bool quit_game_with_cancellable (Cancellable cancellable) {
+ if (box.runner == null)
+ return true;
+
+ box.runner.pause ();
+
+ if (box.runner.can_quit_safely) {
+ box.runner.stop ();
+
+ return true;
+ }
+
+ if (quit_dialog != null)
+ return false;
+
+ quit_dialog = new QuitDialog ();
+ quit_dialog.transient_for = window;
+
+ cancellable.cancelled.connect (() => {
+ quit_dialog.destroy ();
+ quit_dialog = null;
+ });
+
+ var response = quit_dialog.run ();
+
+ // The null check is necessary because the dialog could already
+ // be canceled by this point
+ if (quit_dialog != null) {
+ quit_dialog.destroy ();
+ quit_dialog = null;
+ }
+
+ if (cancellable.is_cancelled ())
+ return cancel_quitting_game ();
+
+ if (response == Gtk.ResponseType.ACCEPT)
+ return true;
+
+ return cancel_quitting_game ();
+ }
+
+ private bool cancel_quitting_game () {
+ if (box.runner != null)
+ try {
+ box.runner.resume ();
+ }
+ catch (Error e) {
+ warning (e.message);
+ }
+
+ return false;
+ }
+
+ private void reset_display_page () {
+ header_bar.can_fullscreen = false;
+ box.header_bar.can_fullscreen = false;
+ header_bar.runner = null;
+ box.runner = null;
+ header_bar.media_set = null;
+ box.header_bar.media_set = null;
+ }
+
+ public void update_pause (bool with_delay) {
+ if (focus_out_timeout_id != -1) {
+ Source.remove ((uint) focus_out_timeout_id);
+ focus_out_timeout_id = -1;
+ }
+
+ if (!can_update_pause ())
+ return;
+
+ if (window.is_active)
+ try {
+ box.runner.resume ();
+ }
+ catch (Error e) {
+ warning (e.message);
+ }
+ else if (with_delay)
+ focus_out_timeout_id = Timeout.add (FOCUS_OUT_DELAY_MILLISECONDS,
on_focus_out_delay_elapsed);
+ else
+ box.runner.pause ();
+ }
+
+ private bool on_focus_out_delay_elapsed () {
+ focus_out_timeout_id = -1;
+
+ if (!can_update_pause ())
+ return false;
+
+ if (!window.is_active)
+ box.runner.pause ();
+
+ return false;
+ }
+
+ private bool can_update_pause () {
+ if (box.runner == null)
+ return false;
+
+ if (run_game_cancellable != null)
+ return false;
+
+ if (quit_game_cancellable != null)
+ return false;
+
+ return true;
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]