boxpointer: add setPosition method
split out this function from popupMenu https://bugzilla.gnome.org/show_bug.cgi?id=624900
This commit is contained in:
parent
4d18d54d9d
commit
3efc7bf7f1
@ -264,6 +264,92 @@ BoxPointer.prototype = {
|
||||
cr.stroke();
|
||||
},
|
||||
|
||||
setPosition: function(sourceActor, gap, alignment) {
|
||||
let primary = global.get_primary_monitor();
|
||||
|
||||
// We need to show it now to force an allocation,
|
||||
// so that we can query the correct size.
|
||||
this.actor.show();
|
||||
|
||||
// Position correctly relative to the sourceActor
|
||||
let [sourceX, sourceY] = sourceActor.get_transformed_position();
|
||||
let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
|
||||
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||
|
||||
let resX, resY;
|
||||
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
resY = sourceY + sourceHeight + gap;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
resY = sourceY - natHeight - gap;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
resX = sourceX + sourceWidth + gap;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
resX = sourceX - natWidth - gap;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now align and position the pointing axis, making sure
|
||||
// it fits on screen
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
case St.Side.BOTTOM:
|
||||
switch (alignment) {
|
||||
case St.Align.START:
|
||||
resX = sourceX;
|
||||
break;
|
||||
case St.Align.MIDDLE:
|
||||
resX = sourceX - Math.floor((natWidth - sourceWidth) / 2);
|
||||
break;
|
||||
case St.Align.END:
|
||||
resX = sourceX - (natWidth - sourceWidth);
|
||||
break;
|
||||
}
|
||||
|
||||
resX = Math.min(resX, primary.x + primary.width - natWidth);
|
||||
resX = Math.max(resX, primary.x);
|
||||
|
||||
this.setArrowOrigin((sourceX - resX) + Math.floor(sourceWidth / 2));
|
||||
break;
|
||||
|
||||
case St.Side.LEFT:
|
||||
case St.Side.RIGHT:
|
||||
switch (alignment) {
|
||||
case St.Align.START:
|
||||
resY = sourceY;
|
||||
break;
|
||||
case St.Align.MIDDLE:
|
||||
resY = sourceY - Math.floor((natHeight - sourceHeight) / 2);
|
||||
break;
|
||||
case St.Align.END:
|
||||
resY = sourceY - (natHeight - sourceHeight);
|
||||
break;
|
||||
}
|
||||
|
||||
resY = Math.min(resY, primary.y + primary.height - natHeight);
|
||||
resY = Math.max(resY, primary.y);
|
||||
|
||||
this.setArrowOrigin((sourceY - resY) + Math.floor(sourceHeight / 2));
|
||||
break;
|
||||
}
|
||||
|
||||
let parent = this.actor.get_parent();
|
||||
let success, x, y;
|
||||
while (!success) {
|
||||
[success, x, y] = parent.transform_stage_point(resX, resY);
|
||||
parent = parent.get_parent();
|
||||
}
|
||||
|
||||
// Actually set the position
|
||||
this.actor.x = Math.floor(x);
|
||||
this.actor.y = Math.floor(y);
|
||||
},
|
||||
|
||||
// @origin: Coordinate specifying middle of the arrow, along
|
||||
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
|
||||
// the left for St.Side.TOP and St.Side.BOTTOM.
|
||||
|
@ -550,7 +550,6 @@ PopupMenu.prototype = {
|
||||
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||
|
||||
let menuX, menuY;
|
||||
let menuWidth = natWidth, menuHeight = natHeight;
|
||||
|
||||
// Position the non-pointing axis
|
||||
@ -573,68 +572,8 @@ PopupMenu.prototype = {
|
||||
this._boxPointer._arrowSide = this._arrowSide = St.Side.LEFT;
|
||||
}
|
||||
}
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
menuY = sourceY + sourceHeight + this._gap;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
menuY = sourceY - menuHeight - this._gap;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
menuX = sourceX + sourceWidth + this._gap;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
menuX = sourceX - menuWidth - this._gap;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now align and position the pointing axis, making sure
|
||||
// it fits on screen
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
case St.Side.BOTTOM:
|
||||
switch (this._alignment) {
|
||||
case St.Align.START:
|
||||
menuX = sourceX;
|
||||
break;
|
||||
case St.Align.MIDDLE:
|
||||
menuX = sourceX - Math.floor((menuWidth - sourceWidth) / 2);
|
||||
break;
|
||||
case St.Align.END:
|
||||
menuX = sourceX - (menuWidth - sourceWidth);
|
||||
break;
|
||||
}
|
||||
|
||||
menuX = Math.min(menuX, primary.x + primary.width - menuWidth);
|
||||
menuX = Math.max(menuX, primary.x);
|
||||
|
||||
this._boxPointer.setArrowOrigin((sourceX - menuX) + Math.floor(sourceWidth / 2));
|
||||
break;
|
||||
|
||||
case St.Side.LEFT:
|
||||
case St.Side.RIGHT:
|
||||
switch (this._alignment) {
|
||||
case St.Align.START:
|
||||
menuY = sourceY;
|
||||
break;
|
||||
case St.Align.MIDDLE:
|
||||
menuY = sourceY - Math.floor((menuHeight - sourceHeight) / 2);
|
||||
break;
|
||||
case St.Align.END:
|
||||
menuY = sourceY - (menuHeight - sourceHeight);
|
||||
break;
|
||||
}
|
||||
|
||||
menuY = Math.min(menuY, primary.y + primary.height - menuHeight);
|
||||
menuY = Math.max(menuY, primary.y);
|
||||
|
||||
this._boxPointer.setArrowOrigin((sourceY - menuY) + Math.floor(sourceHeight / 2));
|
||||
break;
|
||||
}
|
||||
|
||||
// Actually set the position
|
||||
this.actor.x = Math.floor(menuX);
|
||||
this.actor.y = Math.floor(menuY);
|
||||
this._boxPointer.setPosition(this.sourceActor, this._gap, this._alignment);
|
||||
|
||||
// Now show it
|
||||
this.actor.reactive = true;
|
||||
|
Loading…
Reference in New Issue
Block a user