From 8b48560c81c5bbfd3d9cfa9535825ff3a10be111 Mon Sep 17 00:00:00 2001 From: Cosimo Cecchi Date: Thu, 28 Feb 2013 21:19:03 -0500 Subject: [PATCH] overviewControls: add a new messages indicator The new messages indicator will be visible when there are non-resident notifications in the tray. https://bugzilla.gnome.org/show_bug.cgi?id=687787 --- data/theme/gnome-shell.css | 25 ++++++++- js/ui/overview.js | 2 + js/ui/overviewControls.js | 108 +++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index a3575d92b..260962972 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -734,13 +734,36 @@ StScrollBar StButton#vhandle:active { -vertical-spacing: 32px; padding-left: 32px; padding-right: 32px; - padding-bottom: 32px; + padding-bottom: 48px; } .window-picker.external-monitor { padding: 32px; } +.messages-indicator { + color: #999999; + height: 32px; +} + +.messages-indicator-contents { + spacing: 12px; + padding-bottom: 12px; +} + +.messages-indicator-contents:hover { + color: white; + text-shadow: black 0px 2px 2px; +} + +.messages-indicator-highlight { + background-gradient-start: transparent; + background-gradient-end: #999999; + background-gradient-direction: vertical; + + height: 6px; +} + /* Dash */ #dash { diff --git a/js/ui/overview.js b/js/ui/overview.js index 71c321e5b..485a34279 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -308,6 +308,8 @@ const Overview = new Lang.Class({ // Add our same-line elements after the search entry this._overview.add(this._groupStack, { y_fill: true, expand: true }); + 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 13527a55c..4a528e2ff 100644 --- a/js/ui/overviewControls.js +++ b/js/ui/overviewControls.js @@ -367,6 +367,111 @@ 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('source-added', Lang.bind(this, this._onSourceAdded)); + Main.messageTray.connect('source-removed', Lang.bind(this, this._onSourceRemoved)); + + let sources = Main.messageTray.getSources(); + sources.forEach(Lang.bind(this, function(source) { this._onSourceAdded(null, source); })); + + this._viewSelector.connect('page-changed', Lang.bind(this, this._updateVisibility)); + Main.overview.connect('showing', Lang.bind(this, this._updateVisibility)); + }, + + _onSourceAdded: function(tray, source) { + if (source.trayIcon) + return; + + if (source.isTransient) + return; + + source.connect('count-updated', Lang.bind(this, this._updateCount)); + this._sources.push(source); + this._updateCount(); + }, + + _onSourceRemoved: function(tray, source) { + this._sources.splice(this._sources.indexOf(source), 1); + this._updateCount(); + }, + + _updateCount: function() { + let count = 0; + this._sources.forEach(Lang.bind(this, + function(source) { + count += source.indicatorCount; + })); + + this._count = count; + this._label.text = ngettext("%d new message", + "%d new messages", + count).format(count); + + this._updateVisibility(); + }, + + _updateVisibility: function() { + let activePage = this._viewSelector.getActivePage(); + let visible = ((this._count > 0) && (activePage == ViewSelector.ViewPage.WINDOWS)); + + this.actor.visible = visible; + } +}); + const ControlsManager = new Lang.Class({ Name: 'ControlsManager', @@ -379,6 +484,9 @@ const ControlsManager = new Lang.Class({ this._thumbnailsSlider = new ThumbnailsSlider(thumbnails); this.thumbnailsActor = this._thumbnailsSlider.actor; + this._indicator = new MessagesIndicator(viewSelector); + this.indicatorActor = this._indicator.actor; + this._viewSelector = viewSelector; this._viewSelector.connect('page-changed', Lang.bind(this, this._setVisibility)); this._viewSelector.connect('page-empty', Lang.bind(this, this._onPageEmpty));