[gnome-shell] [panel] Fix AppPanelMenu's allocation



commit d56fbf6d6a27cf347fb58ca00205ffec5422a448
Author: Colin Walters <walters verbum org>
Date:   Sun Feb 28 15:36:13 2010 -0500

    [panel] Fix AppPanelMenu's allocation
    
    Because we were setting the "fixed-position-set" property
    on the internal label, its width/height requests weren't
    being accounted for in the size request of the overall box.
    
    The way we were hooking up to notify::allocation was hacky; do
    this correctly by simply implementing a container.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=611288

 js/ui/panel.js |   66 ++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 50 insertions(+), 16 deletions(-)
---
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 1a989fe..d9e40ce 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -152,15 +152,16 @@ AppPanelMenu.prototype = {
         this._activeSequence = null;
         this._startupSequences = {};
 
-        this.actor = new St.BoxLayout({ name: 'appMenu' });
+        this.actor = new St.Bin({ name: 'appMenu', });
+        this._container = new Shell.GenericContainer();
+        this.actor.set_child(this._container);
+        this._container.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
+        this._container.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
+        this._container.connect('allocate', Lang.bind(this, this._allocate));
         this._iconBox = new Shell.Slicer({ name: 'appMenuIcon' });
-        this.actor.add(this._iconBox);
+        this._container.add_actor(this._iconBox);
         this._label = new TextShadower();
-        this.actor.add(this._label.actor, { expand: true, y_fill: true });
-        this.actor.connect('notify::allocation', Lang.bind(this, this._repositionLabel));
-
-        this._startupBox = new St.BoxLayout();
-        this.actor.add(this._startupBox);
+        this._container.add_actor(this._label.actor);
 
         Main.overview.connect('hiding', Lang.bind(this, function () {
             this.actor.opacity = 255;
@@ -181,14 +182,48 @@ AppPanelMenu.prototype = {
         this._sync();
     },
 
-    _repositionLabel: function() {
-        this._label.actor.x = Math.floor(AppDisplay.APPICON_SIZE / 2);
-        let actorAlloc = this.actor.allocation;
-        let actorHeight = actorAlloc.y2 - actorAlloc.y1;
-        let labelAlloc = this._label.actor.allocation;
-        let labelHeight = labelAlloc.y2 - labelAlloc.y1;
-        this._label.actor.y = Math.floor((actorHeight - labelHeight) / 2);
-        this._label.actor.fixed_position_set = true;
+    _getPreferredWidth: function(actor, forHeight, alloc) {
+        let [minSize, naturalSize] = this._iconBox.get_preferred_width(forHeight);
+        alloc.min_size = Math.floor(minSize / 2);
+        alloc.natural_size = Math.floor(naturalSize / 2);
+        [minSize, naturalSize] = this._label.actor.get_preferred_width(forHeight);
+        alloc.min_size += minSize;
+        alloc.natural_size += naturalSize;
+    },
+
+    _getPreferredHeight: function(actor, forWidth, alloc) {
+        let [minSize, naturalSize] = this._iconBox.get_preferred_height(forWidth);
+        alloc.min_size = minSize;
+        alloc.natural_size = naturalSize;
+        [minSize, naturalSize] = this._label.actor.get_preferred_height(forWidth);
+        if (minSize > alloc.min_size)
+            alloc.min_size = minSize;
+        if (naturalSize > alloc.natural_size)
+            alloc.natural_size = naturalSize;
+    },
+
+    _allocate: function(actor, box, flags) {
+        let allocWidth = box.x2 - box.x1;
+        let allocHeight = box.y2 - box.y1;
+        let childBox = new Clutter.ActorBox();
+
+        let [minWidth, minHeight, naturalWidth, naturalHeight] = this._iconBox.get_preferred_size();
+
+        let yPadding = Math.floor(Math.max(0, allocHeight - naturalHeight) / 2);
+        childBox.x1 = 0;
+        childBox.y1 = yPadding;
+        childBox.x2 = childBox.x1 + Math.min(naturalWidth, allocWidth);
+        childBox.y2 = childBox.y1 + Math.min(allocHeight, naturalHeight);
+        this._iconBox.allocate(childBox, flags);
+
+        let [minWidth, minHeight, naturalWidth, naturalHeight] = this._label.actor.get_preferred_size();
+
+        yPadding = Math.floor(Math.max(0, allocHeight - naturalHeight) / 2);
+        childBox.x1 = Math.floor(childBox.x2 / 2);  // Pull in width of iconBox
+        childBox.y1 = yPadding;
+        childBox.x2 = childBox.x1 + Math.min(naturalWidth, allocWidth);
+        childBox.y2 = childBox.y1 + Math.min(allocHeight, naturalHeight);
+        this._label.actor.allocate(childBox, flags);
     },
 
     _sync: function() {
@@ -234,7 +269,6 @@ AppPanelMenu.prototype = {
             this._iconBox.set_child(faded);
             this._iconBox.show();
         }
-        this._repositionLabel();
 
         this.emit('changed');
     }



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