[gnome-games/wip/exalm/views: 108/109] display-view: Handle running and quitting games



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]