popup-menu: Allow adjusting where in the source the arrow points to
Currently BoxPointer/Menus always point to the center of the associated source actor. This is generally what we want, but add some API to adjust that behavior for the cases where it isn't. https://bugzilla.gnome.org/show_bug.cgi?id=659274
This commit is contained in:
parent
d0edd970e1
commit
85520e34ab
@ -46,6 +46,7 @@ BoxPointer.prototype = {
|
||||
this._yOffset = 0;
|
||||
this._xPosition = 0;
|
||||
this._yPosition = 0;
|
||||
this._sourceAlignment = 0.5;
|
||||
},
|
||||
|
||||
show: function(animate, onComplete) {
|
||||
@ -180,7 +181,7 @@ BoxPointer.prototype = {
|
||||
this.bin.allocate(childBox, flags);
|
||||
|
||||
if (this._sourceActor && this._sourceActor.mapped)
|
||||
this._reposition(this._sourceActor, this._alignment);
|
||||
this._reposition(this._sourceActor, this._arrowAlignment);
|
||||
},
|
||||
|
||||
_drawBorder: function(area) {
|
||||
@ -312,18 +313,31 @@ BoxPointer.prototype = {
|
||||
this.actor.show();
|
||||
|
||||
this._sourceActor = sourceActor;
|
||||
this._alignment = alignment;
|
||||
this._arrowAlignment = alignment;
|
||||
|
||||
this._reposition(sourceActor, alignment);
|
||||
},
|
||||
|
||||
setSourceAlignment: function(alignment) {
|
||||
this._sourceAlignment = alignment;
|
||||
|
||||
if (!this._sourceActor)
|
||||
return;
|
||||
|
||||
// We need to show it now to force an allocation,
|
||||
// so that we can query the correct size.
|
||||
this.actor.show();
|
||||
|
||||
this._reposition(this._sourceActor, this._arrowAlignment);
|
||||
},
|
||||
|
||||
_reposition: function(sourceActor, alignment) {
|
||||
// Position correctly relative to the sourceActor
|
||||
let sourceNode = sourceActor.get_theme_node();
|
||||
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
|
||||
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
|
||||
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2;
|
||||
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2;
|
||||
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
|
||||
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||
|
||||
// We also want to keep it onscreen, and separated from the
|
||||
|
@ -1142,10 +1142,10 @@ function PopupMenu() {
|
||||
PopupMenu.prototype = {
|
||||
__proto__: PopupMenuBase.prototype,
|
||||
|
||||
_init: function(sourceActor, alignment, arrowSide) {
|
||||
_init: function(sourceActor, arrowAlignment, arrowSide) {
|
||||
PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content');
|
||||
|
||||
this._alignment = alignment;
|
||||
this._arrowAlignment = arrowAlignment;
|
||||
this._arrowSide = arrowSide;
|
||||
|
||||
this._boxPointer = new BoxPointer.BoxPointer(arrowSide,
|
||||
@ -1198,13 +1198,17 @@ PopupMenu.prototype = {
|
||||
this._boxPointer.setArrowOrigin(origin);
|
||||
},
|
||||
|
||||
setSourceAlignment: function(alignment) {
|
||||
this._boxPointer.setSourceAlignment(alignment);
|
||||
},
|
||||
|
||||
open: function(animate) {
|
||||
if (this.isOpen)
|
||||
return;
|
||||
|
||||
this.isOpen = true;
|
||||
|
||||
this._boxPointer.setPosition(this.sourceActor, this._alignment);
|
||||
this._boxPointer.setPosition(this.sourceActor, this._arrowAlignment);
|
||||
this._boxPointer.show(animate);
|
||||
|
||||
this.actor.raise_top();
|
||||
|
Loading…
Reference in New Issue
Block a user