[gnome-shell/T27795: 96/138] iconGrid: Reimplement the concept of layered icons in BaseIcon



commit 438ee298951045938e3403f8d59bb01905162f3b
Author: Sam Spilsbury <sam endlessm com>
Date:   Tue May 30 02:14:36 2017 +0800

    iconGrid: Reimplement the concept of layered icons in BaseIcon
    
    These appear to have a separate theme as well, though that has
    not yet been reimplemented.

 js/ui/appDisplay.js | 23 +++++++++++++++++++++++
 js/ui/iconGrid.js   | 43 +++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 64 insertions(+), 2 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index b83fea2539..c821e36524 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -13,6 +13,7 @@ const GrabHelper = imports.ui.grabHelper;
 const IconGrid = imports.ui.iconGrid;
 const IconGridLayout = imports.ui.iconGridLayout;
 const Main = imports.ui.main;
+const MessageTray = imports.ui.messageTray;
 const PageIndicators = imports.ui.pageIndicators;
 const PopupMenu = imports.ui.popupMenu;
 const Search = imports.ui.search;
@@ -1745,6 +1746,19 @@ var AppFolderPopup = class AppFolderPopup {
 };
 Signals.addSignalMethods(AppFolderPopup.prototype);
 
+var AppIconSourceActor = GObject.registerClass(
+class AppIconSourceActor extends MessageTray.SourceActor {
+    _init(source, size) {
+        super._init(source, size);
+        this.setIcon(new St.Bin());
+    }
+
+    _shouldShowCount() {
+        // Always show the counter when there's at least one notification
+        return this.source.count > 0;
+    }
+});
+
 var AppIcon = class AppIcon {
     constructor(app, iconParams = {}) {
         this.app = app;
@@ -1782,6 +1796,7 @@ var AppIcon = class AppIcon {
         delete iconParams['isDraggable'];
 
         iconParams['createIcon'] = this._createIcon.bind(this);
+        iconParams['createExtraIcons'] = this._createExtraIcons.bind(this);
         iconParams['setSizeManually'] = true;
         this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
         this._iconContainer.add_child(this.icon);
@@ -1853,6 +1868,14 @@ var AppIcon = class AppIcon {
         return this.app.create_icon_texture(iconSize);
     }
 
+    _createExtraIcons(iconSize) {
+        if (!this._notificationSource)
+            return [];
+
+        let sourceActor = new AppIconSourceActor(this._notificationSource, iconSize);
+        return [sourceActor.actor];
+    }
+
     _removeMenuTimeout() {
         if (this._menuTimeoutId > 0) {
             GLib.source_remove(this._menuTimeoutId);
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 917a1e54bc..474a9adf59 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -32,6 +32,7 @@ var BaseIcon = GObject.registerClass(
 class BaseIcon extends St.Bin {
     _init(label, params) {
         params = Params.parse(params, { createIcon: null,
+                                        createExtraIcons: null,
                                         setSizeManually: false,
                                         showLabel: true });
 
@@ -51,9 +52,24 @@ class BaseIcon extends St.Bin {
         this.iconSize = ICON_SIZE;
         this._iconBin = new St.Bin({ x_align: St.Align.MIDDLE,
                                      y_align: St.Align.MIDDLE });
+        this._iconBin.add_style_class_name('icon-button');
 
         this._box.add_actor(this._iconBin);
 
+        this._layeredIcon = new St.Widget({ layout_manager: new Clutter.BinLayout(),
+                                            visible: true,
+                                            x_expand: true,
+                                            y_expand: true,
+                                            width: this.iconSize,
+                                            height: this.iconSize });
+        this._iconBin.add_actor(this._layeredIcon);
+
+        let shadow = new St.Widget({ style_class: 'shadow-icon',
+                                     visible: true,
+                                     x_expand: true,
+                                     y_expand: true });
+        this._layeredIcon.add_actor(shadow);
+
         if (params.showLabel) {
             this.label = new St.Label({ text: label });
             this.label.clutter_text.set({
@@ -67,9 +83,12 @@ class BaseIcon extends St.Bin {
 
         if (params.createIcon)
             this.createIcon = params.createIcon;
+        if (params.createExtraIcons)
+            this.createExtraIcons = params.createExtraIcons;
         this._setSizeManually = params.setSizeManually;
 
         this.icon = null;
+        this.extraIcons = [];
 
         let cache = St.TextureCache.get_default();
         this._iconThemeChangedId = cache.connect('icon-theme-changed', this._onIconThemeChanged.bind(this));
@@ -86,6 +105,12 @@ class BaseIcon extends St.Bin {
         throw new GObject.NotImplementedError(`createIcon in ${this.constructor.name}`);
     }
 
+    // This can be overridden by a subclass, or by the createExtraIcons
+    // parameter to _init()
+    createExtraIcons(size) {
+        return [];
+    }
+
     setIconSize(size) {
         if (!this._setSizeManually)
             throw new Error('setSizeManually has to be set to use setIconsize');
@@ -99,10 +124,24 @@ class BaseIcon extends St.Bin {
     _createIconTexture(size) {
         if (this.icon)
             this.icon.destroy();
+        this.extraIcons.forEach(function (i) {
+            i.destroy();
+        });
         this.iconSize = size;
         this.icon = this.createIcon(this.iconSize);
+        this.extraIcons = this.createExtraIcons(this.iconSize);
+
+        this._layeredIcon.add_actor(this.icon);
+        this._layeredIcon.set_child_below_sibling(this.icon, null);
+
+        this.extraIcons.forEach((i) => {
+            this._layeredIcon.add_actor(i);
+        });
 
-        this._iconBin.child = this.icon;
+        // The icon returned by createIcon() might actually be smaller than
+        // the requested icon size (for instance StTextureCache does this
+        // for fallback icons), so set the size explicitly.
+        this._layeredIcon.set_size(this.iconSize, this.iconSize);
     }
 
     vfunc_style_changed() {
@@ -117,7 +156,7 @@ class BaseIcon extends St.Bin {
             size = found ? len : ICON_SIZE;
         }
 
-        if (this.iconSize == size && this._iconBin.child)
+        if (this.iconSize == size && this.icon !== null)
             return;
 
         this._createIconTexture(size);


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