[gnome-shell/wip/notif-d3: 7/7] preview



commit 50395cded88773f86200a51ebffc1c9cc0579379
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Jun 13 12:08:09 2014 -0400

    preview

 data/theme/gnome-shell.css |    4 ++
 js/ui/main.js              |    2 +-
 js/ui/messageTray.js       |   89 +++++++++++++++++++++++++++++++++++++++++++-
 js/ui/panel.js             |   47 ++++++++++++++++++++++-
 4 files changed, 139 insertions(+), 3 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 73f6f20..fa378db 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -2591,3 +2591,7 @@ StScrollBar StButton#vhandle:active {
     -boxpointer-gap: 4px;
     -arrow-rise: 0px;
 }
+
+.top-bar-notification-preview {
+    font-weight: normal;
+}
diff --git a/js/ui/main.js b/js/ui/main.js
index 36c374f..50b22fb 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -150,8 +150,8 @@ function _initializeUI() {
     if (LoginManager.canLock())
         screenShield = new ScreenShield.ScreenShield();
 
-    panel = new Panel.Panel();
     messageTray = new MessageTray.MessageTray();
+    panel = new Panel.Panel();
     keyboard = new Keyboard.Keyboard();
     notificationDaemon = new NotificationDaemon.NotificationDaemon();
     windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index c6e8c55..8613805 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -559,6 +559,8 @@ const Notification = new Lang.Class({
             this._buttonBox.destroy_all_children();
         }
 
+        this.gicon = params.gicon;
+
         if (this._icon && (params.gicon || params.clear)) {
             this._icon.destroy();
             this._icon = null;
@@ -603,6 +605,8 @@ const Notification = new Lang.Class({
         // is done correctly automatically.
         this.actor.set_text_direction(titleDirection);
 
+        this.bannerBodyText = banner;
+
         this._bodyUrlHighlighter.setMarkup(banner, params.bannerMarkup);
 
         if (this._soundName != params.soundName ||
@@ -918,11 +922,94 @@ const Source = new Lang.Class({
 });
 Signals.addSignalMethods(Source.prototype);
 
+const TopBarNotificationPreview = new Lang.Class({
+    Name: 'TopBarNotificationPreview',
+
+    _init: function() {
+        this.actor = new St.BoxLayout({ style_class: 'top-bar-notification-preview' });
+
+        this._icon = new St.Icon({ icon_size: 22 });
+        this.actor.add_child(this._icon);
+
+        this._title = new St.Label({ style_class: 'top-bar-notification-preview-title' });
+        this.actor.add_child(this._title);
+
+        this._body = new St.Label({ style_class: 'top-bar-notification-preview-body' });
+        this.actor.add_child(this._body);
+    },
+
+    setNotification: function(notification) {
+        this._icon.gicon = notification.gicon;
+
+        let title = notification.title;
+        title = title ? _fixMarkup(title.replace(/\n/g, ' '), false) : '';
+        this._title.clutter_text.set_markup('<b>' + title + '</b>');
+
+        this._body.clutter_text.set_text(_fixMarkup(notification.bannerBodyText, false));
+    },
+});
+
+const TopBarNotificationController = new Lang.Class({
+    Name: 'TopBarNotificationController',
+
+    _init: function() {
+        this.actor = new St.Widget();
+
+        this._notificationPreview = new TopBarNotificationPreview();
+        this.actor.add_child(this._notificationPreview.actor);
+
+        this._notificationQueue = [];
+        this._timeoutId = 0;
+    },
+
+    _timeout: function() {
+        this._notificationQueue.shift();
+        this._update();
+        this._timeoutId = 0;
+        return GLib.SOURCE_REMOVE;
+    },
+
+    _ensureTimeout: function() {
+        if (this._timeoutId == 0)
+            this._timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, Lang.bind(this, 
this._timeout));
+    },
+
+    get hasNotification() {
+        return (this._notificationQueue.length > 0);
+    },
+
+    _update: function() {
+        if (this._notificationQueue.length > 0) {
+            let notification = this._notificationQueue[0];
+            this._notificationPreview.setNotification(notification);
+
+            this._ensureTimeout();
+        }
+
+        this.emit('updated');
+    },
+
+    pushNotification: function(notification) {
+        this._notificationQueue.push(notification);
+
+        notification.connect('destroy', Lang.bind(this, function() {
+            let idx = this._notificationQueue.indexOf(notification);
+            this._notificationQueue.splice(idx, 1);
+            this._update();
+        }));
+
+        this._update();
+    },
+});
+Signals.addSignalMethods(TopBarNotificationController.prototype);
+
 const MessageTray = new Lang.Class({
     Name: 'MessageTray',
 
     _init: function() {
         this._sources = new Map();
+
+        this.notificationPreview = new TopBarNotificationController();
     },
 
     _expireNotification: function() {
@@ -1003,7 +1090,7 @@ const MessageTray = new Lang.Class({
     },
 
     _onNotify: function(source, notification) {
-        // Fill in here.
+        this.notificationPreview.pushNotification(notification);
     },
 });
 Signals.addSignalMethods(MessageTray.prototype);
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 750149e..d750a5a 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -862,11 +862,56 @@ const AggregateMenu = new Lang.Class({
     },
 });
 
+const DateMenuButton2 = new Lang.Class({
+    Name: 'DateMenuButton2',
+
+    _init: function() {
+        this.container = new St.Widget({ layout_manager: new Clutter.BinLayout() });
+
+        this._notificationPreview = Main.messageTray.notificationPreview;
+        this.container.add_child(this._notificationPreview.actor);
+        this._notificationPreview.actor.x_expand = true;
+        this._notificationPreview.actor.x_align = Clutter.ActorAlign.CENTER;
+        this._notificationPreview.connect('updated', Lang.bind(this, this._sync));
+
+        let dateMenu = new imports.ui.dateMenu.DateMenuButton();
+        this._clock = dateMenu.container;
+        this._clock.x_expand = true;
+        this._clock.x_align = Clutter.ActorAlign.CENTER;
+        this.container.add_child(this._clock);
+
+        this._currentlyShowing = 'clock';
+        this._sync();
+    },
+
+    _show: function(which, animate) {
+        if (this._currentlyShowing == which)
+            return;
+
+        this._currentlyShowing = which;
+        if (this._currentlyShowing == 'clock') {
+            this._notificationPreview.actor.visible = false;
+            this._clock.visible = true;
+        } else if (this._currentlyShowing == 'notification') {
+            this._notificationPreview.actor.visible = true;
+            this._clock.visible = false;
+        }
+    },
+
+    _sync: function() {
+        if (this._currentlyShowing == 'clock' && this._notificationPreview.hasNotification)
+            this._show('notification', true);
+        else if (this._currentlyShowing == 'notification' && !this._notificationPreview.hasNotification)
+            this._show('clock', false);
+    },
+});
+Signals.addSignalMethods(DateMenuButton2.prototype);
+
 const PANEL_ITEM_IMPLEMENTATIONS = {
     'activities': ActivitiesButton,
     'aggregateMenu': AggregateMenu,
     'appMenu': AppMenuButton,
-    'dateMenu': imports.ui.dateMenu.DateMenuButton,
+    'dateMenu': DateMenuButton2,
     'a11y': imports.ui.status.accessibility.ATIndicator,
     'a11yGreeter': imports.ui.status.accessibility.ATGreeterIndicator,
     'keyboard': imports.ui.status.keyboard.InputSourceIndicator,


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