[gnome-shell/wip/new-notifications: 6/13] messageTray: Add a new message tray indicator



commit 7da3899b3ab2189b2c1a90bdd1217191ce80fcc5
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Dec 4 21:09:23 2013 -0500

    messageTray: Add a new message tray indicator

 data/theme/gnome-shell.css |   21 +++++++++++
 js/ui/layout.js            |   41 +++++++++++++--------
 js/ui/messageTray.js       |   80 +++++++++++++++++++++++++++++++++++++++++
 js/ui/overview.js          |    2 -
 js/ui/overviewControls.js  |   84 --------------------------------------------
 5 files changed, 126 insertions(+), 102 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index d3e8a75..e6f0865 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -1450,6 +1450,27 @@ StScrollBar StButton#vhandle:active {
     color: #999999;
 }
 
+.message-tray-indicator {
+    spacing: 4px;
+}
+
+.message-tray-indicator-count {
+    font-weight: bold;
+
+    color: black;
+    background-color: rgba(255, 255, 255, 0.7);
+    border-radius: 1em;
+    width: 1em;
+    height: 1em;
+}
+
+.message-tray-indicator-glow {
+    height: 4px;
+    background-gradient-start: rgba(255, 255, 255, 0);
+    background-gradient-end: rgba(255, 255, 255, 1);
+    background-gradient-direction: vertical;
+}
+
 .notification {
     border-radius: 10px 10px 0px 0px;
     background: rgba(0,0,0,0.9);
diff --git a/js/ui/layout.js b/js/ui/layout.js
index c74033b..344db37 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -442,12 +442,12 @@ const LayoutManager = new Lang.Class({
     },
 
     _setupTrayPressure: function() {
-        this._trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD,
-                                                 MESSAGE_TRAY_PRESSURE_TIMEOUT,
-                                                 Shell.KeyBindingMode.NORMAL |
-                                                 Shell.KeyBindingMode.OVERVIEW);
-        this._trayPressure.setEventFilter(this._trayBarrierEventFilter);
-        this._trayPressure.connect('trigger', function(barrier) {
+        this.trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD,
+                                                MESSAGE_TRAY_PRESSURE_TIMEOUT,
+                                                Shell.KeyBindingMode.NORMAL |
+                                                Shell.KeyBindingMode.OVERVIEW);
+        this.trayPressure.setEventFilter(this._trayBarrierEventFilter);
+        this.trayPressure.connect('trigger', function(barrier) {
             if (Main.layoutManager.bottomMonitor.inFullscreen)
                 return;
 
@@ -459,7 +459,7 @@ const LayoutManager = new Lang.Class({
         let monitor = this.bottomMonitor;
 
         if (this._trayBarrier) {
-            this._trayPressure.removeBarrier(this._trayBarrier);
+            this.trayPressure.removeBarrier(this._trayBarrier);
             this._trayBarrier.destroy();
             this._trayBarrier = null;
         }
@@ -468,7 +468,7 @@ const LayoutManager = new Lang.Class({
                                                x1: monitor.x, x2: monitor.x + monitor.width,
                                                y1: monitor.y + monitor.height, y2: monitor.y + 
monitor.height,
                                                directions: Meta.BarrierDirection.NEGATIVE_Y });
-        this._trayPressure.addBarrier(this._trayBarrier);
+        this.trayPressure.addBarrier(this._trayBarrier);
     },
 
     _trayBarrierEventFilter: function(event) {
@@ -1247,8 +1247,8 @@ const PressureBarrier = new Lang.Class({
     Name: 'PressureBarrier',
 
     _init: function(threshold, timeout, keybindingMode) {
-        this._threshold = threshold;
-        this._timeout = timeout;
+        this.threshold = threshold;
+        this.timeout = timeout;
         this._keybindingMode = keybindingMode;
         this._barriers = [];
         this._eventFilter = null;
@@ -1285,8 +1285,8 @@ const PressureBarrier = new Lang.Class({
 
     _reset: function() {
         this._barrierEvents = [];
-        this._currentPressure = 0;
         this._lastTime = 0;
+        this.currentPressure = 0;
     },
 
     _isHorizontal: function(barrier) {
@@ -1307,12 +1307,21 @@ const PressureBarrier = new Lang.Class({
             return Math.abs(event.dy);
     },
 
+    get currentPressure() {
+        return this._currentPressure;
+    },
+
+    set currentPressure(value) {
+        this._currentPressure = value;
+        this.emit('pressure-changed');
+    },
+
     _trimBarrierEvents: function() {
         // Events are guaranteed to be sorted in time order from
         // oldest to newest, so just look for the first old event,
         // and then chop events after that off.
         let i = 0;
-        let threshold = this._lastTime - this._timeout;
+        let threshold = this._lastTime - this.timeout;
 
         while (i < this._barrierEvents.length) {
             let [time, distance] = this._barrierEvents[i];
@@ -1325,7 +1334,7 @@ const PressureBarrier = new Lang.Class({
 
         for (i = 0; i < firstNewEvent; i++) {
             let [time, distance] = this._barrierEvents[i];
-            this._currentPressure -= distance;
+            this.currentPressure = distance;
         }
 
         this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
@@ -1358,7 +1367,7 @@ const PressureBarrier = new Lang.Class({
         let slide = this._getDistanceAlongBarrier(barrier, event);
         let distance = this._getDistanceAcrossBarrier(barrier, event);
 
-        if (distance >= this._threshold) {
+        if (distance >= this.threshold) {
             this._trigger();
             return;
         }
@@ -1375,9 +1384,9 @@ const PressureBarrier = new Lang.Class({
         distance = Math.min(15, distance);
 
         this._barrierEvents.push([event.time, distance]);
-        this._currentPressure += distance;
+        this.currentPressure += distance;
 
-        if (this._currentPressure >= this._threshold)
+        if (this.currentPressure >= this.threshold)
             this._trigger();
     }
 });
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index dc630b3..24880bb 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -1723,6 +1723,81 @@ const MessageTrayMenuButton = new Lang.Class({
     },
 });
 
+const MessageTrayIndicator = new Lang.Class({
+    Name: 'MessageTrayIndicator',
+
+    _init: function(tray, pressureBarrier) {
+        this._tray = tray;
+
+        this.actor = new St.BoxLayout({ style_class: 'message-tray-indicator',
+                                        reactive: true,
+                                        track_hover: true,
+                                        vertical: true,
+                                        x_expand: true,
+                                        y_expand: true,
+                                        y_align: Clutter.ActorAlign.START });
+        this.actor.connect('notify::height', Lang.bind(this, function() {
+            this.actor.translation_y = -this.actor.height;
+        }));
+        this.actor.connect('button-press-event', Lang.bind(this, function() {
+            this._tray.openTray();
+        }));
+
+        this._count = new St.Label({ style_class: 'message-tray-indicator-count',
+                                     x_expand: true,
+                                     x_align: Clutter.ActorAlign.CENTER });
+        this.actor.add_child(this._count);
+
+        this._tray.connect('indicator-count-updated', Lang.bind(this, this._syncCount));
+        this._syncCount();
+
+        this._glow = new St.Widget({ style_class: 'message-tray-indicator-glow',
+                                     x_expand: true });
+        this.actor.add_child(this._glow);
+
+        this._pressureBarrier = pressureBarrier;
+        this._pressureBarrier.connect('pressure-changed', Lang.bind(this, this._updatePressure));
+        this._pressureValue = 0;
+        this._syncGlow();
+    },
+
+    _syncCount: function() {
+        let count = this._tray.indicatorCount;
+        this._count.visible = (count > 0);
+        this._count.text = '' + count;
+    },
+
+    _syncGlow: function() {
+        let value = this._pressureValue;
+        let percent = value / this._pressureBarrier.threshold;
+        this.actor.opacity = Math.min(percent * 255, 255);
+        this.actor.visible = (value > 0);
+    },
+
+    get pressureValue() {
+        return this._pressureValue;
+    },
+
+    set pressureValue(value) {
+        this._pressureValue = value;
+        this._syncGlow();
+   },
+
+    _updatePressure: function() {
+        let value = this._pressureBarrier.currentPressure;
+        this.pressureValue = value;
+        if (value > 0) {
+            Tweener.removeTweens(this);
+            Tweener.addTween(this, { time: this._pressureBarrier.timeout / 1000,
+                                     pressureValue: 0 });
+        }
+    },
+
+    destroy: function() {
+        this.actor.destroy();
+    },
+});
+
 const MessageTray = new Lang.Class({
     Name: 'MessageTray',
 
@@ -1900,6 +1975,11 @@ const MessageTray = new Lang.Class({
 
         this._messageTrayMenuButton = new MessageTrayMenuButton(this);
         this.actor.add_actor(this._messageTrayMenuButton.actor);
+
+        this._indicator = new MessageTrayIndicator(this, Main.layoutManager.trayPressure);
+        Main.layoutManager.trayBox.add_child(this._indicator.actor);
+        Main.layoutManager.trackChrome(this._indicator.actor);
+        this._grabHelper.addActor(this._indicator.actor);
     },
 
     close: function() {
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 1809fe4..a8bcd48 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -269,8 +269,6 @@ const Overview = new Lang.Class({
         this._overview.add(this._controls.actor, { y_fill: true, expand: true });
         this._controls.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
 
-        this._stack.add_actor(this._controls.indicatorActor);
-
         // TODO - recalculate everything when desktop size changes
         this.dashIconSize = this._dash.iconSize;
         this._dash.connect('icon-size-changed',
diff --git a/js/ui/overviewControls.js b/js/ui/overviewControls.js
index de6142d..0f12e8b 100644
--- a/js/ui/overviewControls.js
+++ b/js/ui/overviewControls.js
@@ -391,87 +391,6 @@ const DashSpacer = new Lang.Class({
     }
 });
 
-const MessagesIndicator = new Lang.Class({
-    Name: 'MessagesIndicator',
-
-    _init: function(viewSelector) {
-        this._count = 0;
-        this._sources = [];
-        this._viewSelector = viewSelector;
-
-        this._container = new St.BoxLayout({ style_class: 'messages-indicator-contents',
-                                             reactive: true,
-                                             track_hover: true,
-                                             x_expand: true,
-                                             y_expand: true,
-                                             x_align: Clutter.ActorAlign.CENTER });
-
-        this._icon = new St.Icon({ icon_name: 'user-idle-symbolic',
-                                   icon_size: 16 });
-        this._container.add_actor(this._icon);
-
-        this._label = new St.Label();
-        this._container.add_actor(this._label);
-
-        this._highlight = new St.Widget({ style_class: 'messages-indicator-highlight',
-                                          x_expand: true,
-                                          y_expand: true,
-                                          y_align: Clutter.ActorAlign.END,
-                                          visible: false });
-
-        this._container.connect('notify::hover', Lang.bind(this,
-            function() {
-                this._highlight.visible = this._container.hover;
-            }));
-
-        let clickAction = new Clutter.ClickAction();
-        this._container.add_action(clickAction);
-        clickAction.connect('clicked', Lang.bind(this,
-            function() {
-                Main.messageTray.openTray();
-            }));
-
-        Main.messageTray.connect('showing', Lang.bind(this,
-            function() {
-                this._highlight.visible = false;
-                this._container.hover = false;
-            }));
-
-        let layout = new Clutter.BinLayout();
-        this.actor = new St.Widget({ layout_manager: layout,
-                                     style_class: 'messages-indicator',
-                                     y_expand: true,
-                                     y_align: Clutter.ActorAlign.END,
-                                     visible: false });
-        this.actor.add_actor(this._container);
-        this.actor.add_actor(this._highlight);
-
-        Main.messageTray.connect('indicator-count-updated', Lang.bind(this, this._sync));
-        this._sync();
-
-        this._viewSelector.connect('page-changed', Lang.bind(this, this._updateVisibility));
-        Main.overview.connect('showing', Lang.bind(this, this._updateVisibility));
-    },
-
-    _sync: function() {
-        let count = Main.messageTray.indicatorCount;
-        this._count = count;
-        this._label.text = ngettext("%d new message",
-                                    "%d new messages",
-                                   count).format(count);
-
-        this._icon.visible = Main.messageTray.hasChatSources;
-        this._updateVisibility();
-    },
-
-    _updateVisibility: function() {
-        let activePage = this._viewSelector.getActivePage();
-        let visible = ((this._count > 0) && (activePage == ViewSelector.ViewPage.WINDOWS));
-
-        this.actor.visible = visible;
-    }
-});
-
 const ControlsLayout = new Lang.Class({
     Name: 'ControlsLayout',
     Extends: Clutter.BinLayout,
@@ -500,9 +419,6 @@ const ControlsManager = new Lang.Class({
         this.viewSelector.connect('page-changed', Lang.bind(this, this._setVisibility));
         this.viewSelector.connect('page-empty', Lang.bind(this, this._onPageEmpty));
 
-        this._indicator = new MessagesIndicator(this.viewSelector);
-        this.indicatorActor = this._indicator.actor;
-
         let layout = new ControlsLayout();
         this.actor = new St.Widget({ layout_manager: layout,
                                      reactive: true,


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