mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
Fixed bubble positioning to work with simple toolboxes (PR #2279)
Merge from BeksOmega/fixes/BubbleSimpleToolbox
This commit is contained in:
committed by
Andrew n marshall
parent
18220da483
commit
be7c242f97
146
core/bubble.js
146
core/bubble.js
@@ -175,19 +175,20 @@ Blockly.Bubble.prototype.anchorXY_ = null;
|
||||
Blockly.Bubble.prototype.relativeLeft_ = 0;
|
||||
|
||||
/**
|
||||
* Relative Y coordinate of bubble with respect to the anchor's centre.
|
||||
* Relative Y coordinate of bubble with respect to the anchor's centre, in
|
||||
* workspace units.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.relativeTop_ = 0;
|
||||
|
||||
/**
|
||||
* Width of bubble.
|
||||
* Width of bubble, in workspace units.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.width_ = 0;
|
||||
|
||||
/**
|
||||
* Height of bubble.
|
||||
* Height of bubble, in workspace units.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.height_ = 0;
|
||||
@@ -401,9 +402,15 @@ Blockly.Bubble.prototype.setAnchorLocation = function(xy) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.layoutBubble_ = function() {
|
||||
// Get the metrics in workspace units.
|
||||
var metrics = this.workspace_.getMetrics();
|
||||
metrics.viewWidth /= this.workspace_.scale;
|
||||
metrics.viewLeft /= this.workspace_.scale;
|
||||
metrics.viewWidth /= this.workspace_.scale;
|
||||
metrics.viewTop /= this.workspace_.scale;
|
||||
metrics.viewHeight /= this.workspace_.scale;
|
||||
metrics.flyoutWidth /= this.workspace_.scale;
|
||||
metrics.flyoutHeight /= this.workspace_.scale;
|
||||
|
||||
var optimalLeft = this.getOptimalRelativeLeft_(metrics);
|
||||
var optimalTop = this.getOptimalRelativeTop_(metrics);
|
||||
var bbox = this.shape_.getBBox();
|
||||
@@ -441,6 +448,9 @@ Blockly.Bubble.prototype.layoutBubble_ = function() {
|
||||
this.relativeTop_ = closerPosition.y;
|
||||
return;
|
||||
}
|
||||
// TODO: I believe relativeLeft_ should actually be called relativeStart_
|
||||
// and then the math should be fixed to reflect this. (hopefully it'll
|
||||
// make it look simpler)
|
||||
this.relativeLeft_ = fartherPosition.x;
|
||||
this.relativeTop_ = fartherPosition.y;
|
||||
};
|
||||
@@ -458,27 +468,38 @@ Blockly.Bubble.prototype.layoutBubble_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.getOverlap_ = function(relativeMin, metrics) {
|
||||
// The position of the top-start corner of the bubble in workspace units.
|
||||
// The position of the top-left corner of the bubble in workspace units.
|
||||
var bubbleMin = {
|
||||
x: relativeMin.x + (this.workspace_.RTL ?
|
||||
metrics.viewWidth - this.anchorXY_.x :
|
||||
this.anchorXY_.x),
|
||||
x: this.workspace_.RTL ? (this.anchorXY_.x - relativeMin.x - this.width_) :
|
||||
(relativeMin.x + this.anchorXY_.x),
|
||||
y: relativeMin.y + this.anchorXY_.y
|
||||
};
|
||||
// The position of the bottom-end corner of the bubble in workspace units.
|
||||
// The position of the bottom-right corner of the bubble in workspace units.
|
||||
var bubbleMax = {
|
||||
x: bubbleMin.x + this.width_,
|
||||
y: bubbleMin.y + this.height_
|
||||
};
|
||||
// The position of the top-start corner of the workspace.
|
||||
|
||||
// We could adjust these values to account for the scrollbars, but the
|
||||
// bubbles should have been adjusted to not collide with them anyway, so
|
||||
// giving the workspace a slightly larger "bounding box" shouldn't affect the
|
||||
// calculation.
|
||||
|
||||
// The position of the top-left corner of the workspace.
|
||||
var workspaceMin = {
|
||||
x: this.workspace_.RTL ? -metrics.viewLeft : metrics.viewLeft,
|
||||
y: metrics.viewTop
|
||||
x: metrics.viewLeft + ((metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) ?
|
||||
metrics.flyoutWidth : 0),
|
||||
y: metrics.viewTop + ((metrics.toolboxPosition == Blockly.TOOLBOX_AT_TOP) ?
|
||||
metrics.flyoutHeight : 0)
|
||||
};
|
||||
// The position of the bottom-end corner of the workspace.
|
||||
// The position of the bottom-right corner of the workspace.
|
||||
var workspaceMax = {
|
||||
x: workspaceMin.x + metrics.viewWidth,
|
||||
y: workspaceMin.y + metrics.viewHeight
|
||||
x: metrics.viewLeft + metrics.viewWidth -
|
||||
((metrics.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) ?
|
||||
metrics.flyoutWidth : 0),
|
||||
y: metrics.viewTop + metrics.viewHeight -
|
||||
((metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) ?
|
||||
metrics.flyoutHeight : 0)
|
||||
};
|
||||
|
||||
var overlapWidth = Math.min(bubbleMax.x, workspaceMax.x) -
|
||||
@@ -507,29 +528,56 @@ Blockly.Bubble.prototype.getOptimalRelativeLeft_ = function(metrics) {
|
||||
return relativeLeft;
|
||||
}
|
||||
|
||||
var anchorX = this.anchorXY_.x;
|
||||
if (this.workspace_.RTL) {
|
||||
if (anchorX - metrics.viewLeft - relativeLeft - this.width_ <
|
||||
Blockly.Scrollbar.scrollbarThickness) {
|
||||
// Everything is flipped in RTL.
|
||||
var bubbleRight = this.anchorXY_.x - relativeLeft;
|
||||
var bubbleLeft = bubbleRight - this.width_;
|
||||
var scrollbarRight = 0;
|
||||
// Thickness in workspace units.
|
||||
var scrollbarLeft =
|
||||
Blockly.Scrollbar.scrollbarThickness / this.workspace_.scale;
|
||||
} else {
|
||||
var bubbleLeft = relativeLeft + this.anchorXY_.x;
|
||||
var bubbleRight = bubbleLeft + this.width_;
|
||||
// Thickness in workspace units.
|
||||
var scrollbarRight =
|
||||
Blockly.Scrollbar.scrollbarThickness / this.workspace_.scale;
|
||||
var scrollbarLeft = 0;
|
||||
}
|
||||
|
||||
switch (metrics.toolboxPosition) {
|
||||
case Blockly.TOOLBOX_AT_LEFT:
|
||||
var workspaceLeft = metrics.viewLeft + metrics.flyoutWidth;
|
||||
var workspaceRight =
|
||||
metrics.viewLeft + metrics.viewWidth - scrollbarRight;
|
||||
break;
|
||||
case Blockly.TOOLBOX_AT_RIGHT:
|
||||
var workspaceLeft = metrics.viewLeft + scrollbarLeft;
|
||||
var workspaceRight =
|
||||
metrics.viewLeft + metrics.viewWidth - metrics.flyoutWidth;
|
||||
break;
|
||||
default:
|
||||
var workspaceLeft = metrics.viewLeft + scrollbarLeft;
|
||||
var workspaceRight =
|
||||
metrics.viewLeft + metrics.viewWidth - scrollbarRight;
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.workspace_.RTL) {
|
||||
if (bubbleLeft < workspaceLeft) {
|
||||
// Slide the bubble right until it is onscreen.
|
||||
relativeLeft = anchorX - metrics.viewLeft - this.width_ -
|
||||
Blockly.Scrollbar.scrollbarThickness;
|
||||
} else if (anchorX - metrics.viewLeft - relativeLeft >
|
||||
metrics.viewWidth) {
|
||||
relativeLeft = -(workspaceLeft - this.anchorXY_.x + this.width_);
|
||||
} else if (bubbleRight > workspaceRight) {
|
||||
// Slide the bubble left until it is onscreen.
|
||||
relativeLeft = anchorX - metrics.viewLeft - metrics.viewWidth;
|
||||
relativeLeft = -(workspaceRight - this.anchorXY_.x);
|
||||
}
|
||||
} else {
|
||||
if (anchorX + relativeLeft < metrics.viewLeft) {
|
||||
if (bubbleLeft < workspaceLeft) {
|
||||
// Slide the bubble right until it is onscreen.
|
||||
relativeLeft = metrics.viewLeft - anchorX;
|
||||
} else if (metrics.viewLeft + metrics.viewWidth <
|
||||
anchorX + relativeLeft + this.width_ +
|
||||
Blockly.BlockSvg.SEP_SPACE_X +
|
||||
Blockly.Scrollbar.scrollbarThickness) {
|
||||
relativeLeft = workspaceLeft - this.anchorXY_.x;
|
||||
} else if (bubbleRight > workspaceRight) {
|
||||
// Slide the bubble left until it is onscreen.
|
||||
relativeLeft = metrics.viewLeft + metrics.viewWidth - anchorX -
|
||||
this.width_ - Blockly.Scrollbar.scrollbarThickness;
|
||||
relativeLeft = workspaceRight - this.anchorXY_.x - this.width_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,17 +602,37 @@ Blockly.Bubble.prototype.getOptimalRelativeTop_ = function(metrics) {
|
||||
return relativeTop;
|
||||
}
|
||||
|
||||
var bubbleTop = this.anchorXY_.y + relativeTop;
|
||||
var bubbleBottom = bubbleTop + this.height_;
|
||||
|
||||
// Thickness in workspace units.
|
||||
var scrollbarThickness =
|
||||
Blockly.Scrollbar.scrollbarThickness / this.workspace_.scale;
|
||||
switch (metrics.toolboxPosition) {
|
||||
case Blockly.TOOLBOX_AT_TOP:
|
||||
var workspaceTop = metrics.viewTop + metrics.flyoutHeight;
|
||||
var workspaceBottom = metrics.viewTop + metrics.viewHeight -
|
||||
scrollbarThickness;
|
||||
break;
|
||||
case Blockly.TOOLBOX_AT_BOTTOM:
|
||||
var workspaceTop = metrics.viewTop;
|
||||
var workspaceBottom = metrics.viewTop + metrics.viewHeight
|
||||
- metrics.flyoutHeight;
|
||||
break;
|
||||
default:
|
||||
var workspaceTop = metrics.viewTop;
|
||||
var workspaceBottom = metrics.viewTop + metrics.viewHeight -
|
||||
scrollbarThickness;
|
||||
break;
|
||||
}
|
||||
|
||||
var anchorY = this.anchorXY_.y;
|
||||
if (anchorY + relativeTop < metrics.viewTop) {
|
||||
if (bubbleTop < workspaceTop) {
|
||||
// Slide the bubble down until it is onscreen.
|
||||
relativeTop = metrics.viewTop - anchorY;
|
||||
} else if (metrics.viewTop + metrics.viewHeight <
|
||||
anchorY + relativeTop + this.height_ +
|
||||
Blockly.BlockSvg.SEP_SPACE_Y +
|
||||
Blockly.Scrollbar.scrollbarThickness) {
|
||||
relativeTop = workspaceTop - anchorY;
|
||||
} else if (bubbleBottom > workspaceBottom) {
|
||||
// Slide the bubble up until it is onscreen.
|
||||
relativeTop = metrics.viewTop + metrics.viewHeight - anchorY -
|
||||
this.height_ - Blockly.Scrollbar.scrollbarThickness;
|
||||
relativeTop = workspaceBottom - anchorY - this.height_;
|
||||
}
|
||||
|
||||
return relativeTop;
|
||||
|
||||
Reference in New Issue
Block a user