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 Panel corners are disabled for now. They'll be added back eventually.
This commit is contained in:
parent
2c34c8e20f
commit
ab60c628e7
@ -41,6 +41,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/boxpointer.js \
|
ui/boxpointer.js \
|
||||||
ui/calendar.js \
|
ui/calendar.js \
|
||||||
ui/checkBox.js \
|
ui/checkBox.js \
|
||||||
|
ui/centerLayout.js \
|
||||||
ui/ctrlAltTab.js \
|
ui/ctrlAltTab.js \
|
||||||
ui/dash.js \
|
ui/dash.js \
|
||||||
ui/dateMenu.js \
|
ui/dateMenu.js \
|
||||||
|
56
js/ui/centerLayout.js
Normal file
56
js/ui/centerLayout.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// -*- 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(availWidth);
|
||||||
|
let [centerMinWidth, centerNaturalWidth] = center.get_preferred_width(availWidth);
|
||||||
|
let [rightMinWidth, rightNaturalWidth] = right.get_preferred_width(availWidth);
|
||||||
|
|
||||||
|
let sideWidth = (availWidth - centerNaturalWidth) / 2;
|
||||||
|
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
childBox.y1 = box.y1;
|
||||||
|
childBox.y2 = box.y1 + availHeight;
|
||||||
|
|
||||||
|
let leftSide = Math.min(Math.floor(sideWidth), leftNaturalWidth);
|
||||||
|
if (rtl) {
|
||||||
|
childBox.x1 = availWidth - leftSide;
|
||||||
|
childBox.x2 = availWidth;
|
||||||
|
} else {
|
||||||
|
childBox.x1 = 0;
|
||||||
|
childBox.x2 = leftSide;
|
||||||
|
}
|
||||||
|
childBox.x1 += box.x1;
|
||||||
|
left.allocate(childBox, flags);
|
||||||
|
|
||||||
|
childBox.x1 = box.x1 + Math.ceil(sideWidth);
|
||||||
|
childBox.x2 = childBox.x1 + centerNaturalWidth;
|
||||||
|
center.allocate(childBox, flags);
|
||||||
|
|
||||||
|
let rightSide = Math.min(Math.floor(sideWidth), rightNaturalWidth);
|
||||||
|
if (rtl) {
|
||||||
|
childBox.x1 = 0;
|
||||||
|
childBox.x2 = rightSide;
|
||||||
|
} else {
|
||||||
|
childBox.x1 = availWidth - rightSide;
|
||||||
|
childBox.x2 = availWidth;
|
||||||
|
}
|
||||||
|
childBox.x1 += box.x1;
|
||||||
|
right.allocate(childBox, flags);
|
||||||
|
}
|
||||||
|
});
|
121
js/ui/panel.js
121
js/ui/panel.js
@ -15,6 +15,7 @@ const Signals = imports.signals;
|
|||||||
const Atk = imports.gi.Atk;
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
|
|
||||||
|
const CenterLayout = imports.ui.centerLayout;
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
@ -931,12 +932,47 @@ try {
|
|||||||
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
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({
|
const Panel = new Lang.Class({
|
||||||
Name: 'Panel',
|
Name: 'Panel',
|
||||||
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this.actor = new Shell.GenericContainer({ name: 'panel',
|
this.actor = new St.Widget({ name: 'panel',
|
||||||
reactive: true });
|
reactive: true,
|
||||||
|
layoutManager: new PanelLayout() });
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
this.statusArea = {};
|
this.statusArea = {};
|
||||||
@ -961,7 +997,6 @@ const Panel = new Lang.Class({
|
|||||||
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
|
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
|
||||||
else
|
else
|
||||||
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
|
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
|
||||||
|
|
||||||
this.actor.add_actor(this._leftCorner.actor);
|
this.actor.add_actor(this._leftCorner.actor);
|
||||||
|
|
||||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
|
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
|
||||||
@ -970,9 +1005,6 @@ const Panel = new Lang.Class({
|
|||||||
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
|
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
|
||||||
this.actor.add_actor(this._rightCorner.actor);
|
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));
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
|
|
||||||
Main.layoutManager.panelBox.add(this.actor);
|
Main.layoutManager.panelBox.add(this.actor);
|
||||||
@ -983,83 +1015,6 @@ const Panel = new Lang.Class({
|
|||||||
this._updatePanel();
|
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) {
|
_onButtonPress: function(actor, event) {
|
||||||
if (event.get_source() != actor)
|
if (event.get_source() != actor)
|
||||||
return false;
|
return false;
|
||||||
|
30
tests/interactive/center-layout.js
Normal file
30
tests/interactive/center-layout.js
Normal file
@ -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();
|
Loading…
Reference in New Issue
Block a user