[gnome-games/wip/exalm/buildable] ui: Add FullscreenBox



commit 05499aa015981ad7285143edb3e87bbc02925b6d
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date:   Sun Oct 14 17:48:33 2018 +0500

    ui: Add FullscreenBox
    
    This will be used in the next commit to move fullscreen-related code out
    of DisplayBox.

 data/org.gnome.Games.gresource.xml |   1 +
 data/ui/fullscreen-box.ui          |  26 ++++++++
 src/meson.build                    |   1 +
 src/ui/fullscreen-box.vala         | 131 +++++++++++++++++++++++++++++++++++++
 4 files changed, 159 insertions(+)
---
diff --git a/data/org.gnome.Games.gresource.xml b/data/org.gnome.Games.gresource.xml
index 3ba283c0..53d30df2 100644
--- a/data/org.gnome.Games.gresource.xml
+++ b/data/org.gnome.Games.gresource.xml
@@ -22,6 +22,7 @@
     <file preprocess="xml-stripblanks">ui/empty-collection.ui</file>
     <file preprocess="xml-stripblanks">ui/error-display.ui</file>
     <file preprocess="xml-stripblanks">ui/error-info-bar.ui</file>
+    <file preprocess="xml-stripblanks">ui/fullscreen-box.ui</file>
     <file preprocess="xml-stripblanks">ui/gamepad-mapper.ui</file>
     <file preprocess="xml-stripblanks">ui/gamepad-tester.ui</file>
     <file preprocess="xml-stripblanks">ui/game-icon-view.ui</file>
diff --git a/data/ui/fullscreen-box.ui b/data/ui/fullscreen-box.ui
new file mode 100644
index 00000000..27b453da
--- /dev/null
+++ b/data/ui/fullscreen-box.ui
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.16"/>
+  <template class="GamesFullscreenBox" parent="GtkEventBox">
+    <property name="visible">True</property>
+    <property name="events">GDK_POINTER_MOTION_MASK</property>
+    <signal name="notify::is-fullscreen" handler="on_fullscreen_changed"/>
+    <signal name="motion-notify-event" handler="on_motion_event"/>
+    <child>
+      <object class="GtkOverlay" id="overlay">
+        <property name="visible">True</property>
+        <child type="overlay">
+          <object class="GtkRevealer" id="header_bar_revealer">
+            <property name="visible">True</property>
+            <property name="valign">start</property>
+            <property name="hexpand">True</property>
+            <property name="transition-type">slide-down</property>
+            <property name="events">GDK_POINTER_MOTION_MASK</property>
+            <signal name="notify::is-fullscreen" handler="on_fullscreen_changed"/>
+            <signal name="motion-notify-event" handler="on_motion_event"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/meson.build b/src/meson.build
index 9a886051..7d57fcb0 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -137,6 +137,7 @@ vala_sources = [
   'ui/empty-collection.vala',
   'ui/error-display.vala',
   'ui/error-info-bar.vala',
+  'ui/fullscreen-box.vala',
   'ui/gamepad-browse.vala',
   'ui/gamepad-mapper.vala',
   'ui/gamepad-tester.vala',
diff --git a/src/ui/fullscreen-box.vala b/src/ui/fullscreen-box.vala
new file mode 100644
index 00000000..35226c9a
--- /dev/null
+++ b/src/ui/fullscreen-box.vala
@@ -0,0 +1,131 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[GtkTemplate (ui = "/org/gnome/Games/ui/fullscreen-box.ui")]
+private class Games.FullscreenBox : Gtk.EventBox, Gtk.Buildable {
+       private const uint INACTIVITY_TIME_MILLISECONDS = 2000;
+
+       public signal void back ();
+
+       public bool is_fullscreen { get; set; }
+
+       private Gtk.Widget _header_bar;
+       public Gtk.Widget header_bar {
+               get { return _header_bar; }
+               set {
+                       if (header_bar == value)
+                               return;
+
+                       if (fullscreen_binding != null) {
+                               fullscreen_binding.unbind ();
+                               fullscreen_binding = null;
+                       }
+
+                       _header_bar = value;
+
+                       if (header_bar != null)
+                               fullscreen_binding = bind_property ("is-fullscreen", header_bar,
+                                                                       "is-fullscreen",
+                                                                       BindingFlags.BIDIRECTIONAL);
+               }
+       }
+
+       [GtkChild]
+       private Gtk.Overlay overlay;
+       [GtkChild]
+       private Gtk.Revealer header_bar_revealer;
+       private Binding visible_binding;
+       private Binding fullscreen_binding;
+
+       private long timeout_id;
+
+       construct {
+               visible_binding = bind_property ("is-fullscreen", header_bar_revealer,
+                                                "visible", BindingFlags.BIDIRECTIONAL);
+               timeout_id = -1;
+       }
+
+       public void add_child (Gtk.Builder builder, Object child, string? type) {
+               var widget = child as Gtk.Widget;
+
+               if (overlay == null || header_bar_revealer == null) {
+                       add (widget);
+                       return;
+               }
+
+               if (type == "titlebar") {
+                       header_bar_revealer.add (widget);
+                       header_bar = widget;
+               }
+               else
+                       overlay.add (widget);
+       }
+
+       [GtkCallback]
+       private void on_fullscreen_changed () {
+               if (is_fullscreen)
+                       on_activity ();
+               else
+                       on_restore ();
+       }
+
+       [GtkCallback]
+       private bool on_motion_event (Gdk.EventMotion event) {
+               on_activity ();
+
+               return false;
+       }
+
+       private void on_activity () {
+               if (timeout_id != -1) {
+                       Source.remove ((uint) timeout_id);
+                       timeout_id = -1;
+               }
+
+               if (!is_fullscreen)
+                       return;
+
+               timeout_id = Timeout.add (INACTIVITY_TIME_MILLISECONDS, on_inactivity);
+               header_bar_revealer.reveal_child = true;
+               show_cursor (true);
+       }
+
+       private bool on_inactivity () {
+               timeout_id = -1;
+
+               if (!is_fullscreen)
+                       return false;
+
+               header_bar_revealer.reveal_child = false;
+               show_cursor (false);
+               overlay.grab_focus ();
+
+               return false;
+       }
+
+       private void on_restore () {
+               if (timeout_id != -1) {
+                       Source.remove ((uint) timeout_id);
+                       timeout_id = -1;
+               }
+
+               header_bar_revealer.reveal_child = false;
+               show_cursor (true);
+       }
+
+       private void show_cursor (bool show) {
+               var window = get_window ();
+               if (window == null)
+                       return;
+
+               if ((show && window.cursor == null) ||
+                   (!show && window.cursor != null))
+                       return;
+
+               if (!show) {
+                       var display = window.get_display ();
+                       window.cursor = new Gdk.Cursor.for_display (display, Gdk.CursorType.BLANK_CURSOR);
+               }
+               else
+                       window.cursor = null;
+       }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]