[gnome-shell/wip/fmuellner/notification-redux+sass: 132/141] messageTray: Add NotificationBanner actor



commit 00435b9d64ca7740d34bf2c83caf033f085caa47
Author: Florian Müllner <fmuellner gnome org>
Date:   Tue Feb 17 01:13:48 2015 +0100

    messageTray: Add NotificationBanner actor
    
    We no longer have a single notification actor that is either displayed
    as banner or reparented to the summary depending on state - both the
    lock screen and the notification section of the message list create
    their own UI based on the information attached to the notification
    object. Adding to this that different representations of a notification
    may now exist simultaneously (as they are included in the message list
    immediately rather than after the banner has been displayed), it no
    longer makes sense to keep the banner actor in the notification itself.
    
    Add a new NotificationBanner class that provides a separate banner
    implementation based on the message list's NotificationMessage that will
    soon replace the existing notification banners.

 data/theme/_common.scss    |   28 +++++++++++++
 data/theme/gnome-shell.css |   33 ++++++++++++++++
 js/ui/messageTray.js       |   92 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 153 insertions(+), 0 deletions(-)
---
diff --git a/data/theme/_common.scss b/data/theme/_common.scss
index 4faa547..8547448 100644
--- a/data/theme/_common.scss
+++ b/data/theme/_common.scss
@@ -1321,6 +1321,34 @@ StScrollBar {
   .url-highlighter { link-color: $selected_bg_color; }
   
   // Banners
+  .notification-banner {
+    font-size: 11pt;
+    width: 34em;
+    margin: 5px;
+    border-radius: 6px;
+    color: $_bubble_fg_color;
+    background-color: $_bubble_bg_color;
+    border: 1px solid $borders_color;
+    //box-shadow: 0 1px 4px black;
+    &:hover { background-color: $_bubble_bg_color; }
+    &:focus { background-color: $_bubble_bg_color; }
+
+    .notification-icon { padding: 5px; }
+    .notification-content { padding: 5px; spacing: 5px; }
+    .secondary-icon { icon-size: 1.09em; }
+    .notification-actions {
+      background-color: $borders_color;
+      padding-top: 2px;
+      spacing: 1px;
+    }
+    .notification-button {
+      padding: 4px 4px 5px;
+      background-color: darken($_bubble_bg_color,5%);
+      &:first-child { border-radius: 0 0 0 6px; }
+      &:last-child { border-radius: 0 0 6px 0; }
+      &:hover, &focus { background-color: darken($_bubble_bg_color,2%); }
+    }
+  }
   .notification { 
     font-size: 11pt;
     width: 34em;
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index f712ca0..c24eb46 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -1146,6 +1146,39 @@ StScrollBar {
 .url-highlighter {
   link-color: #215d9c; }
 
+.notification-banner {
+  font-size: 11pt;
+  width: 34em;
+  margin: 5px;
+  border-radius: 6px;
+  color: #eeeeec;
+  background-color: #2e3436;
+  border: 1px solid #1c1f1f; }
+  .notification-banner:hover {
+    background-color: #2e3436; }
+  .notification-banner:focus {
+    background-color: #2e3436; }
+  .notification-banner .notification-icon {
+    padding: 5px; }
+  .notification-banner .notification-content {
+    padding: 5px;
+    spacing: 5px; }
+  .notification-banner .secondary-icon {
+    icon-size: 1.09em; }
+  .notification-banner .notification-actions {
+    background-color: #1c1f1f;
+    padding-top: 2px;
+    spacing: 1px; }
+  .notification-banner .notification-button {
+    padding: 4px 4px 5px;
+    background-color: #222728; }
+    .notification-banner .notification-button:first-child {
+      border-radius: 0 0 0 6px; }
+    .notification-banner .notification-button:last-child {
+      border-radius: 0 0 6px 0; }
+    .notification-banner .notification-button:hover, .notification-banner .notification-buttonfocus {
+      background-color: #292f30; }
+
 .notification {
   font-size: 11pt;
   width: 34em;
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index a9ee24f..32f8578 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -13,6 +13,7 @@ const Shell = imports.gi.Shell;
 const Signals = imports.signals;
 const St = imports.gi.St;
 
+const Calendar = imports.ui.calendar;
 const GnomeSession = imports.misc.gnomeSession;
 const Main = imports.ui.main;
 const Params = imports.misc.params;
@@ -1105,6 +1106,97 @@ const Notification = new Lang.Class({
 });
 Signals.addSignalMethods(Notification.prototype);
 
+const NotificationBanner = new Lang.Class({
+    Name: 'NotificationBanner',
+    Extends: Calendar.NotificationMessage,
+
+    _init: function(notification) {
+        this.parent(notification);
+
+        this.actor.add_style_class_name('notification-banner');
+        this.actor.connect('destroy', Lang.bind(this, this._onDestroyed));
+
+        this._buttonBox = null;
+
+        this._addActions();
+        this._addSecondaryIcon();
+
+        this._activatedId = this.notification.connect('activated',
+            Lang.bind(this, function() {
+                // We hide all types of notifications once the user clicks on
+                // them because the common outcome of clicking should be the
+                // relevant window being brought forward and the user's
+                // attention switching to the window.
+                this.emit('done-displaying');
+            }));
+    },
+
+    _onDestroyed: function() {
+        this.notification.disconnect(this._activatedId);
+    },
+
+    _onUpdated: function(n, clear) {
+        this.parent(n, clear);
+
+        if (clear) {
+            this.setSecondaryActor(null);
+            this.setActionArea(null);
+            this._buttonBox = null;
+        }
+
+        this._addActions();
+        this._addSecondaryIcon();
+    },
+
+    _addActions: function() {
+        this.notification.actions.forEach(Lang.bind(this,
+            function(action) {
+                this.addAction(action.label, action.callback);
+            }));
+    },
+
+    _addSecondaryIcon: function() {
+        if (this.notification.secondaryGIcon) {
+            let icon = new St.Icon({ gicon: this.notification.secondaryGIcon });
+            this.setSecondaryActor(icon);
+        }
+    },
+
+    addButton: function(button, callback) {
+        if (!this._buttonBox) {
+            this._buttonBox = new St.BoxLayout({ style_class: 'notification-actions',
+                                                 x_expand: true });
+            this.setActionArea(this._buttonBox);
+            global.focus_manager.add_group(this._buttonBox);
+        }
+
+        this._buttonBox.add(button);
+        button.connect('clicked', Lang.bind(this, function() {
+            callback();
+
+            if (!this.notification.resident) {
+                // We don't hide a resident notification when the user invokes one of its actions,
+                // because it is common for such notifications to update themselves with new
+                // information based on the action. We'd like to display the updated information
+                // in place, rather than pop-up a new notification.
+                this.emit('done-displaying');
+                this.notification.destroy();
+            }
+        }));
+
+        return button;
+    },
+
+    addAction: function(label, callback) {
+        let button = new St.Button({ style_class: 'notification-button',
+                                     label: label,
+                                     x_expand: true,
+                                     can_focus: true });
+
+        return this.addButton(button, callback);
+    }
+});
+
 const SourceActor = new Lang.Class({
     Name: 'SourceActor',
 


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