[gnome-shell/wip/aggregate-menu: 13/51] popupMenu: Properly implement all-spanning actors



commit 2785e8ed62bee7b3f5da1e11096c7b25cd515282
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Jun 11 17:30:49 2013 -0400

    popupMenu: Properly implement all-spanning actors
    
    All-spanning actors do not have columns, so don't stuff their width
    in the column. Instead, propagate it manually through the API, making
    sure that the menu is never shorter than the greatest spanning actor.

 js/ui/popupMenu.js |   51 +++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 37 insertions(+), 14 deletions(-)
---
diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js
index 2560a6e..9fe0e15 100644
--- a/js/ui/popupMenu.js
+++ b/js/ui/popupMenu.js
@@ -204,17 +204,22 @@ const PopupBaseMenuItem = new Lang.Class({
     // This returns column widths in logical order (i.e. from the dot
     // to the image), not in visual order (left to right)
     getColumnWidths: function() {
+        let maxSpan = 0;
         let widths = [];
         for (let i = 0, col = 0; i < this._children.length; i++) {
             let child = this._children[i];
             let [min, natural] = child.actor.get_preferred_width(-1);
-            widths[col++] = natural;
-            if (child.span > 1) {
-                for (let j = 1; j < child.span; j++)
-                    widths[col++] = 0;
+            if (child.span == -1) {
+                maxSpan = Math.max(maxSpan, natural);
+            } else {
+                widths[col++] = natural;
+                if (child.span > 1) {
+                    for (let j = 1; j < child.span; j++)
+                        widths[col++] = 0;
+                }
             }
         }
-        return widths;
+        return [maxSpan, widths];
     },
 
     setColumnWidths: function(widths) {
@@ -224,11 +229,13 @@ const PopupBaseMenuItem = new Lang.Class({
     _getPreferredWidth: function(actor, forHeight, alloc) {
         let width = 0;
         if (this._columnWidths) {
-            for (let i = 0; i < this._columnWidths.length; i++) {
+            let [maxSpan, widths] = this._columnWidths;
+            for (let i = 0; i < widths.length; i++) {
                 if (i > 0)
                     width += this._spacing;
-                width += this._columnWidths[i];
+                width += widths[i];
             }
+            width = Math.max(width, maxSpan);
         } else {
             for (let i = 0; i < this._children.length; i++) {
                 let child = this._children[i];
@@ -246,12 +253,14 @@ const PopupBaseMenuItem = new Lang.Class({
         for (let i = 0; i < this._children.length; i++) {
             let child = this._children[i];
             if (this._columnWidths) {
+                let [maxSpan, widths] = this._columnWidths;
                 if (child.span == -1) {
                     childWidth = 0;
-                    for (let j = i; j < this._columnWidths.length; j++)
-                        childWidth += this._columnWidths[j]
-                } else
-                    childWidth = this._columnWidths[i];
+                    for (let j = i; j < widths.length; j++)
+                        childWidth += widths[j];
+                } else {
+                    childWidth = widths[i];
+                }
             } else {
                 if (child.span == -1)
                     childWidth = forWidth - x;
@@ -291,6 +300,16 @@ const PopupBaseMenuItem = new Lang.Class({
 
         this._ornamentLabel.allocate(ornamentBox, flags);
 
+        let extraWidth = 0;
+        if (this._columnWidths) {
+            let totalWidth = 0;
+            let [maxSpan, widths] = this._columnWidths;
+            for (let i = 0; i < widths.length; i++)
+                totalWidth += widths[i];
+            totalWidth += this._spacing * (widths.length - 1);
+            extraWidth = Math.max(0, (maxSpan - totalWidth) / widths.length);
+        }
+
         let x = box.x1;
         for (let i = 0, col = 0; i < this._children.length; i++) {
             let child = this._children[i];
@@ -303,12 +322,14 @@ const PopupBaseMenuItem = new Lang.Class({
                 availWidth = box.x2 - x;
             } else {
                 if (this._columnWidths) {
+                    let [maxSpan, widths] = this._columnWidths;
                     availWidth = 0;
                     for (let j = 0; j < child.span; j++)
-                        availWidth += this._columnWidths[col++];
+                        availWidth += widths[col++];
                 } else {
                     availWidth = naturalWidth;
                 }
+                availWidth += extraWidth;
             }
 
             if (direction == Clutter.TextDirection.RTL)
@@ -874,6 +895,7 @@ const PopupMenuBase = new Lang.Class({
     },
 
     getColumnWidths: function() {
+        let maxSpan = 0;
         let columnWidths = [];
         let items = this.box.get_children();
         for (let i = 0; i < items.length; i++) {
@@ -881,14 +903,15 @@ const PopupMenuBase = new Lang.Class({
                 !(items[i]._delegate instanceof PopupSubMenu && items[i-1].visible))
                 continue;
             if (items[i]._delegate instanceof PopupBaseMenuItem || items[i]._delegate instanceof 
PopupMenuBase) {
-                let itemColumnWidths = items[i]._delegate.getColumnWidths();
+                let [itemMaxSpan, itemColumnWidths] = items[i]._delegate.getColumnWidths();
+                maxSpan = Math.max(maxSpan, itemMaxSpan);
                 for (let j = 0; j < itemColumnWidths.length; j++) {
                     if (j >= columnWidths.length || itemColumnWidths[j] > columnWidths[j])
                         columnWidths[j] = itemColumnWidths[j];
                 }
             }
         }
-        return columnWidths;
+        return [maxSpan, columnWidths];
     },
 
     setColumnWidths: function(widths) {


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