[gnome-shell/wip/re-search-v2: 19/28] panel: Abstract the centered panel logic out into a ClutterLayoutManager



commit 6973342c770412f3a5bb219bd8edae0d4df1ddf0
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Oct 12 12:00:16 2012 -0300

    panel: Abstract the centered panel logic out into a ClutterLayoutManager
    
    Since we want to use this in the overview as well, put it into centerLayout.js

 js/Makefile.am                     |    1 +
 js/ui/centerLayout.js              |   60 ++++++++++++++++++
 js/ui/panel.js                     |  121 +++++++++++------------------------
 tests/interactive/center-layout.js |   30 +++++++++
 4 files changed, 129 insertions(+), 83 deletions(-)
---
diff --git a/js/Makefile.am b/js/Makefile.am
index 4aa61f7..c55910d 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -41,6 +41,7 @@ nobase_dist_js_DATA = 	\
 	ui/boxpointer.js	\
 	ui/calendar.js		\
 	ui/checkBox.js		\
+	ui/centerLayout.js	\
 	ui/ctrlAltTab.js	\
 	ui/dash.js		\
 	ui/dateMenu.js		\
diff --git a/js/ui/centerLayout.js b/js/ui/centerLayout.js
new file mode 100644
index 0000000..98f8cd3
--- /dev/null
+++ b/js/ui/centerLayout.js
@@ -0,0 +1,60 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Lang = imports.lang;
+const Clutter = imports.gi.Clutter;
+
+const CenterLayout = new Lang.Class({
+    Name: 'CenterLayout',
+    Extends: Clutter.BoxLayout,
+
+    vfunc_allocate: function(container, box, flags) {
+        let rtl = container.get_text_direction() == Clutter.TextDirection.RTL;
+
+        let availWidth = box.x2 - box.x1;
+        let availHeight = box.y2 - box.y1;
+
+        // Assume that these are the first three widgets and they are all visible.
+        let [left, center, right] = container.get_children();
+
+        // Only support horizontal layouts for now.
+        let [leftMinWidth, leftNaturalWidth] = left.get_preferred_width(availHeight);
+        let [centerMinWidth, centerNaturalWidth] = center.get_preferred_width(availHeight);
+        let [rightMinWidth, rightNaturalWidth] = right.get_preferred_width(availHeight);
+
+        let sideWidth = (availWidth - centerMinWidth) / 2;
+
+        let childBox = new Clutter.ActorBox();
+        childBox.y1 = box.y1;
+        childBox.y2 = box.y1 + availHeight;
+
+        let leftSide = Math.min(Math.floor(sideWidth), leftNaturalWidth);
+        let rightSide = Math.min(Math.floor(sideWidth), rightNaturalWidth);
+
+        if (rtl) {
+            childBox.x1 = availWidth - leftSide;
+            childBox.x2 = availWidth;
+        } else {
+            childBox.x1 = 0;
+            childBox.x2 = leftSide;
+        }
+        childBox.x1 += box.x1;
+        left.allocate(childBox, flags);
+
+        let maxSide = Math.max(leftSide, rightSide);
+        let sideWidth = Math.max((availWidth - centerNaturalWidth) / 2, maxSide);
+
+        childBox.x1 = box.x1 + Math.ceil(sideWidth);
+        childBox.x2 = box.x2 - Math.ceil(sideWidth);
+        center.allocate(childBox, flags);
+
+        if (rtl) {
+            childBox.x1 = 0;
+            childBox.x2 = rightSide;
+        } else {
+            childBox.x1 = availWidth - rightSide;
+            childBox.x2 = availWidth;
+        }
+        childBox.x1 += box.x1;
+        right.allocate(childBox, flags);
+    }
+});
diff --git a/js/ui/panel.js b/js/ui/panel.js
index ac2e0ea..2fb0abe 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -15,6 +15,7 @@ const Signals = imports.signals;
 const Atk = imports.gi.Atk;
 
 
+const CenterLayout = imports.ui.centerLayout;
 const Config = imports.misc.config;
 const CtrlAltTab = imports.ui.ctrlAltTab;
 const DND = imports.ui.dnd;
@@ -964,12 +965,47 @@ try {
     log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
 }
 
+const PanelLayout = new Lang.Class({
+    Name: 'PanelLayout',
+    Extends: CenterLayout.CenterLayout,
+
+    vfunc_allocate: function(container, box, flags) {
+        this.parent(container, box, flags);
+
+        let availWidth = box.x2 - box.x1;
+        let availHeight = box.y2 - box.y1;
+
+        let [left, center, right, leftCorner, rightCorner] = container.get_children();
+        let childBox = new Clutter.ActorBox();
+
+        let cornerMinWidth, cornerMinHeight;
+        let cornerWidth, cornerHeight;
+
+        [cornerMinWidth, cornerWidth] = leftCorner.get_preferred_width(-1);
+        [cornerMinHeight, cornerHeight] = leftCorner.get_preferred_height(-1);
+        childBox.x1 = 0;
+        childBox.x2 = cornerWidth;
+        childBox.y1 = availHeight;
+        childBox.y2 = availHeight + cornerHeight;
+        leftCorner.allocate(childBox, flags);
+
+        [cornerMinWidth, cornerWidth] = rightCorner.get_preferred_width(-1);
+        [cornerMinHeight, cornerHeight] = rightCorner.get_preferred_height(-1);
+        childBox.x1 = availWidth - cornerWidth;
+        childBox.x2 = availWidth;
+        childBox.y1 = availHeight;
+        childBox.y2 = availHeight + cornerHeight;
+        rightCorner.allocate(childBox, flags);
+    }
+});
+
 const Panel = new Lang.Class({
     Name: 'Panel',
 
     _init : function() {
-        this.actor = new Shell.GenericContainer({ name: 'panel',
-                                                  reactive: true });
+        this.actor = new St.Widget({ name: 'panel',
+                                     reactive: true,
+                                     layoutManager: new PanelLayout() });
         this.actor._delegate = this;
 
         this._sessionStyle = null;
@@ -989,7 +1025,6 @@ const Panel = new Lang.Class({
             this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
         else
             this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
-
         this.actor.add_actor(this._leftCorner.actor);
 
         if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
@@ -998,9 +1033,6 @@ const Panel = new Lang.Class({
             this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
         this.actor.add_actor(this._rightCorner.actor);
 
-        this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
-        this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
-        this.actor.connect('allocate', Lang.bind(this, this._allocate));
         this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
 
         Main.layoutManager.panelBox.add(this.actor);
@@ -1011,83 +1043,6 @@ const Panel = new Lang.Class({
         this._updatePanel();
     },
 
-    _getPreferredWidth: function(actor, forHeight, alloc) {
-        alloc.min_size = -1;
-        alloc.natural_size = Main.layoutManager.primaryMonitor.width;
-    },
-
-    _getPreferredHeight: function(actor, forWidth, alloc) {
-        // We don't need to implement this; it's forced by the CSS
-        alloc.min_size = -1;
-        alloc.natural_size = -1;
-    },
-
-    _allocate: function(actor, box, flags) {
-        let allocWidth = box.x2 - box.x1;
-        let allocHeight = box.y2 - box.y1;
-
-        let [leftMinWidth, leftNaturalWidth] = this._leftBox.get_preferred_width(-1);
-        let [centerMinWidth, centerNaturalWidth] = this._centerBox.get_preferred_width(-1);
-        let [rightMinWidth, rightNaturalWidth] = this._rightBox.get_preferred_width(-1);
-
-        let sideWidth, centerWidth;
-        centerWidth = centerNaturalWidth;
-        sideWidth = (allocWidth - centerWidth) / 2;
-
-        let childBox = new Clutter.ActorBox();
-
-        childBox.y1 = 0;
-        childBox.y2 = allocHeight;
-        if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
-            childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
-                                                leftNaturalWidth);
-            childBox.x2 = allocWidth;
-        } else {
-            childBox.x1 = 0;
-            childBox.x2 = Math.min(Math.floor(sideWidth),
-                                   leftNaturalWidth);
-        }
-        this._leftBox.allocate(childBox, flags);
-
-        childBox.x1 = Math.ceil(sideWidth);
-        childBox.y1 = 0;
-        childBox.x2 = childBox.x1 + centerWidth;
-        childBox.y2 = allocHeight;
-        this._centerBox.allocate(childBox, flags);
-
-        childBox.y1 = 0;
-        childBox.y2 = allocHeight;
-        if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
-            childBox.x1 = 0;
-            childBox.x2 = Math.min(Math.floor(sideWidth),
-                                   rightNaturalWidth);
-        } else {
-            childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
-                                                rightNaturalWidth);
-            childBox.x2 = allocWidth;
-        }
-        this._rightBox.allocate(childBox, flags);
-
-        let cornerMinWidth, cornerMinHeight;
-        let cornerWidth, cornerHeight;
-
-        [cornerMinWidth, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
-        [cornerMinHeight, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
-        childBox.x1 = 0;
-        childBox.x2 = cornerWidth;
-        childBox.y1 = allocHeight;
-        childBox.y2 = allocHeight + cornerHeight;
-        this._leftCorner.actor.allocate(childBox, flags);
-
-        [cornerMinWidth, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
-        [cornerMinHeight, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
-        childBox.x1 = allocWidth - cornerWidth;
-        childBox.x2 = allocWidth;
-        childBox.y1 = allocHeight;
-        childBox.y2 = allocHeight + cornerHeight;
-        this._rightCorner.actor.allocate(childBox, flags);
-    },
-
     _onButtonPress: function(actor, event) {
         if (event.get_source() != actor)
             return false;
diff --git a/tests/interactive/center-layout.js b/tests/interactive/center-layout.js
new file mode 100644
index 0000000..cdbec4e
--- /dev/null
+++ b/tests/interactive/center-layout.js
@@ -0,0 +1,30 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Clutter = imports.gi.Clutter;
+const St = imports.gi.St;
+
+const CenterLayout = imports.ui.centerLayout;
+const UI = imports.testcommon.ui;
+
+function test() {
+    let stage = new Clutter.Stage({ user_resizable: true });
+    UI.init(stage);
+
+    ////////////////////////////////////////////////////////////////////////////////
+
+    let container = new St.Widget({ style: 'border: 2px solid black;',
+                                    layout_manager: new CenterLayout.CenterLayout() });
+    container.add_constraint(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE, source: stage }));
+    stage.add_actor(container);
+
+    let left = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.RED), width: 300 });
+    let center = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.BLUE), width: 100 });
+    let right = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.YELLOW), width: 200 });
+
+    container.add_actor(left);
+    container.add_actor(center);
+    container.add_actor(right);
+
+    UI.main(stage);
+}
+test();



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