[gnome-shell/T27795: 34/138] endlessButton: Add the Endless button to the bottom panel



commit a02df4e50b5d059d4482383cde391e3ce8797991
Author: Mario Sanchez Prada <mario endlessm com>
Date:   Thu Sep 14 15:26:44 2017 +0100

    endlessButton: Add the Endless button to the bottom panel
    
    It acts as the Super key, toggling between the apps view
    and the last opened window if there is at least one running
    application, otherwise it shows a "No apps are open" message.
    
    https://phabricator.endlessm.com/T17227
    https://phabricator.endlessm.com/T17435
    https://phabricator.endlessm.com/T17506
    https://phabricator.endlessm.com/T17520
    https://phabricator.endlessm.com/T18327
    https://phabricator.endlessm.com/T18565
    https://phabricator.endlessm.com/T20325

 data/gnome-shell-theme.gresource.xml      |   1 +
 data/theme/endless-button-symbolic.svg    |  96 +++++++++++++++++++++++
 data/theme/gnome-shell-sass/_endless.scss |  32 ++++++++
 js/js-resources.gresource.xml             |   1 +
 js/ui/endlessButton.js                    | 125 ++++++++++++++++++++++++++++++
 js/ui/panel.js                            |   1 +
 js/ui/sessionMode.js                      |   2 +-
 po/POTFILES.in                            |   1 +
 8 files changed, 258 insertions(+), 1 deletion(-)
---
diff --git a/data/gnome-shell-theme.gresource.xml b/data/gnome-shell-theme.gresource.xml
index 435f0fecb5..079c83bdaa 100644
--- a/data/gnome-shell-theme.gresource.xml
+++ b/data/gnome-shell-theme.gresource.xml
@@ -34,6 +34,7 @@
 
     <!-- Endless-specific resources beyond this point -->
 
+    <file>endless-button-symbolic.svg</file>
     <file>mini-icon-active-indicator.png</file>
   </gresource>
 </gresources>
diff --git a/data/theme/endless-button-symbolic.svg b/data/theme/endless-button-symbolic.svg
new file mode 100644
index 0000000000..38616ec204
--- /dev/null
+++ b/data/theme/endless-button-symbolic.svg
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   viewBox="0 0 39.999999 40"
+   height="40"
+   width="40"
+   xml:space="preserve"
+   id="svg2"
+   version="1.1"
+   sodipodi:docname="endless-button-symbolic.svg"
+   inkscape:version="0.92.1 r"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1136"
+     id="namedview26"
+     showgrid="false"
+     inkscape:zoom="22.625"
+     inkscape:cx="20"
+     inkscape:cy="20"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><clipPath
+       id="clipPath22"
+       clipPathUnits="userSpaceOnUse"><path
+         id="path20"
+         d="M 0,0 H 842 V 370 H 0 Z"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath34"
+       clipPathUnits="userSpaceOnUse"><path
+         id="path32"
+         d="M 0,0 H 842 V 370 H 0 Z"
+         inkscape:connector-curvature="0" /></clipPath><clipPath
+       id="clipPath46"
+       clipPathUnits="userSpaceOnUse"><path
+         id="path44"
+         d="M 0,0 H 842 V 370 H 0 Z"
+         inkscape:connector-curvature="0" /></clipPath></defs><g
+     transform="matrix(0.03851744,0,0,-0.03851744,3.7866422,27.120379)"
+     id="g10"
+     style=""><g
+       id="g12"
+       style=""><g
+         transform="translate(0,-0.279053)"
+         id="g14"
+         style=""><g
+           id="g16"
+           style=""><g
+             clip-path="url(#clipPath22)"
+             id="g18"
+             style=""><g
+               id="g24"
+               style=""><g
+                 id="g26"
+                 style=""><g
+                   id="g28"
+                   style=""><g
+                     clip-path="url(#clipPath34)"
+                     id="g30"
+                     style=""><g
+                       id="g36"
+                       style=""><g
+                         id="g38"
+                         style=""><g
+                           id="g40"
+                           style=""><g
+                             clip-path="url(#clipPath46)"
+                             id="g42"
+                             style=""><g
+                               id="g48"
+                               style=""><path
+                                 id="path50"
+                                 style="fill-opacity:1;fill-rule:nonzero;"
+                                 d="m 737.449,259.547 c -68.324,0 -162.289,-38.004 -249.566,-82.977 l 
-84.555,42.922 c 69.09,38.477 129.34,77.633 162.465,99.922 l 15.125,10.176 c 6.363,4.472 7.52,13.836 
2.586,20.805 l -8.586,12.156 c -4.93,6.98 -13.465,9.511 -18.984,5.629 l -3.34,-2.168 C 526.133,347.973 
463.277,306.184 389.91,264.746 377.23,257.582 364.82,250.758 352.695,244.27 238.098,292.867 154.598,317.5 
104.441,317.5 55.816,317.5 0,305.93 0,215.852 0,167.578 18.121,110.035 104.441,110.035 c 68.317,0 162.27,38 
249.551,82.977 L 438.547,150.09 C 373.215,113.695 315.859,76.75 281.809,54 h -0.016 C 263.352,41.664 
262.109,40.812 262.109,40.812 255.137,35.895 253.438,26.164 258.363,19.18 l 8.594,-12.157 c 4.926,-6.964 
14.395,-8.851 21.051,-4.164 0,0 0.058,0.032 12.25,8.161 L 300.285,11 c 30.629,20.582 87.078,57.34 
151.676,93.836 12.699,7.172 25.086,13.996 37.219,20.476 114.597,-48.585 198.093,-73.218 248.269,-73.218 
48.617,0 104.422,11.551 104.422,101.636 0,48.282 -18.121,105.
 817 -104
 .422,105.817 M 104.441,155.984 c -48.925,0 -58.496,21.95 -58.496,59.868 0,47.281 15.332,55.691 58.496,55.691 
38.411,0 105.094,-18.813 194.399,-54.711 C 215.957,176.82 149.695,155.984 104.441,155.984 M 737.449,98.031 c 
-38.41,0 -105.113,18.828 -194.398,54.731 82.863,39.996 149.133,60.847 194.398,60.847 48.906,0 58.469,-21.961 
58.469,-59.879 0,-47.277 -15.305,-55.699 -58.469,-55.699"
+                                 inkscape:connector-curvature="0" 
/></g></g></g></g></g></g></g></g></g></g></g></g></g></g></svg>
\ No newline at end of file
diff --git a/data/theme/gnome-shell-sass/_endless.scss b/data/theme/gnome-shell-sass/_endless.scss
index b246469827..8653068187 100644
--- a/data/theme/gnome-shell-sass/_endless.scss
+++ b/data/theme/gnome-shell-sass/_endless.scss
@@ -211,3 +211,35 @@
         }
     }
 }
+
+// Endless Button
+
+%endless-button-hover {
+    color: #f15a22;
+    background-gradient-start: rgba(255, 255, 255, 0.12);
+    transition: 300ms;
+}
+
+%endless-button-clicked {
+    @extend %endless-button-hover;
+    color: white;
+    box-shadow: none;
+}
+
+.endless-button {
+    color: rgba(255, 255, 255, 0.8);
+    background-gradient-start: rgba(255, 255, 255, 0.08);
+    background-gradient-end: transparent;
+    background-gradient-direction: radial;
+    background-gradient-position: 0 20px;
+    background-gradient-radius: 65px;
+    background-gradient-stop: 63px;
+    height: 40px;
+    width: 65px;
+    padding: 0px;
+
+    .single-icon-button { icon-size: 34px; }
+
+    &:hover { @extend %endless-button-hover; }
+    &:clicked { @extend %endless-button-clicked; }
+}
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
index fc66f81c4e..79bee9c9a0 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -142,6 +142,7 @@
 
     <file>ui/appActivation.js</file>
     <file>ui/appIconBar.js</file>
+    <file>ui/endlessButton.js</file>
     <file>ui/forceAppExitDialog.js</file>
     <file>ui/monitor.js</file>
   </gresource>
diff --git a/js/ui/endlessButton.js b/js/ui/endlessButton.js
new file mode 100644
index 0000000000..2af8602b4a
--- /dev/null
+++ b/js/ui/endlessButton.js
@@ -0,0 +1,125 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const { Clutter, Gio, GObject, St } = imports.gi;
+
+const Main = imports.ui.main;
+const PanelMenu = imports.ui.panelMenu;
+const ViewSelector = imports.ui.viewSelector;
+
+var EndlessButton = GObject.registerClass(
+class EndlessButton extends PanelMenu.SingleIconButton {
+    _init() {
+        super._init(_("Endless Button"));
+        this.add_style_class_name('endless-button');
+        this.connect('style-changed', () => {
+            this.width = this.get_theme_node().get_length('width');
+            this.height = this.get_theme_node().get_length('height');
+        });
+        this.connect('notify::hover', this._onHoverChanged.bind(this));
+        this.connect('button-press-event', this._onButtonPressEvent.bind(this));
+        this.connect('button-release-event', this._onButtonReleaseEvent.bind(this));
+
+        let iconFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/endless-button-symbolic.svg');
+        this.setIcon(new Gio.FileIcon({ file: iconFile }));
+
+        this._setupTooltipText();
+    }
+
+    _setupTooltipText() {
+
+        // Create a new tooltip label
+        this._label = new St.Label({ style_class: 'app-icon-hover-label' });
+
+        this._labelOffsetX = 0;
+        this._labelOffsetY = 0;
+        this._label.connect('style-changed', () => {
+            this._labelOffsetX = this._label.get_theme_node().get_length('-label-offset-x');
+            this._labelOffsetY = this._label.get_theme_node().get_length('-label-offset-y');
+        });
+
+        let pageChangedId = Main.overview.connect('page-changed', this._onOverviewPageChanged.bind(this));
+        let showingId = Main.overview.connect('showing', this._onOverviewShowing.bind(this));
+        let hidingId = Main.overview.connect('hiding', this._onOverviewHiding.bind(this));
+
+        this.connect('destroy', () => {
+            Main.overview.disconnect(pageChangedId);
+            Main.overview.disconnect(showingId);
+            Main.overview.disconnect(hidingId);
+        });
+
+        this._updateHoverLabel(false);
+    }
+
+    _updateHoverLabel(hiding) {
+        let viewSelector = Main.overview.viewSelector;
+        let newText = _("Show Desktop");
+
+        if (!hiding &&
+            viewSelector &&
+            viewSelector.getActivePage() === ViewSelector.ViewPage.APPS)
+            newText = _("Show Apps");
+
+        this._label.text = newText;
+    }
+
+    _onOverviewPageChanged() {
+        this._updateHoverLabel(false);
+    }
+
+    _onOverviewShowing() {
+        this._updateHoverLabel(false);
+    }
+
+    _onOverviewHiding() {
+        this._updateHoverLabel(true);
+    }
+
+    // overrides default implementation from PanelMenu.Button
+    _onEvent(actor, event) {
+        if (this.menu &&
+            (event.type() == Clutter.EventType.TOUCH_BEGIN ||
+             event.type() == Clutter.EventType.BUTTON_PRESS)) {
+
+            Main.overview.toggleApps();
+        }
+
+        return Clutter.EVENT_PROPAGATE;
+    }
+
+    _onHoverChanged() {
+        if (!this._label)
+            return;
+
+        if (this.hover) {
+            if (this._label.get_parent())
+                return;
+
+            Main.uiGroup.add_actor(this._label);
+            this._label.raise_top();
+
+            // Update the tooltip position
+            let monitor = Main.layoutManager.findMonitorForActor(this._label);
+            let iconMidpoint = this.get_transformed_position()[0] + this.width / 2;
+            this._label.translation_x = Math.floor(iconMidpoint - this._label.width / 2) + 
this._labelOffsetX;
+            this._label.translation_y = Math.floor(this.get_transformed_position()[1] - this._labelOffsetY);
+
+            // Clip left edge to be the left edge of the screen
+            this._label.translation_x = Math.max(this._label.translation_x, monitor.x + this._labelOffsetX);
+        } else {
+            // Remove the tooltip from uiGroup
+            if (this._label.get_parent() != null)
+                Main.uiGroup.remove_actor(this._label);
+        }
+    }
+
+    _onButtonPressEvent (actor, event) {
+        // This is the CSS active state
+        this.add_style_pseudo_class('clicked');
+        return Clutter.EVENT_PROPAGATE;
+    }
+
+    _onButtonReleaseEvent (actor, event) {
+        this.remove_style_pseudo_class('clicked');
+        return Clutter.EVENT_PROPAGATE;
+    }
+});
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 456447f136..d85efd0459 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -804,6 +804,7 @@ class PopoverMenu extends PanelMenu.SingleIconButton {
 });
 
 const PANEL_ITEM_IMPLEMENTATIONS = {
+    'endlessButton': imports.ui.endlessButton.EndlessButton,
     'activities': ActivitiesButton,
     'aggregateMenu': AggregateMenu,
     'appIcons': imports.ui.appIconBar.AppIconBar,
diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js
index 453aa22ddd..78c35072d6 100644
--- a/js/ui/sessionMode.js
+++ b/js/ui/sessionMode.js
@@ -99,7 +99,7 @@ const _modes = {
                'keyring', 'autorunManager', 'automountManager'],
 
         panel: {
-            left: ['appIcons'],
+            left: ['endlessButton', 'appIcons'],
             center: [],
             right: ['dwellClick', 'a11y', 'keyboard', 'aggregateMenu', 'dateMenu']
         }
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e5f6996146..099f4359ce 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -94,4 +94,5 @@ src/shell-util.c
 subprojects/gvc/gvc-mixer-control.c
 # Endless-specific files beyond this point
 js/ui/appIconBar.js
+js/ui/endlessButton.js
 js/ui/forceAppExitDialog.js


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