mirror of
https://github.com/google/blockly.git
synced 2026-01-07 17:10:11 +01:00
factor out getX and getY methods for flyouts (#4463)
This commit is contained in:
committed by
GitHub
parent
7fce707161
commit
b5c77137bd
@@ -118,6 +118,62 @@ Blockly.HorizontalFlyout.prototype.setMetrics_ = function(xyRatio) {
|
||||
this.workspace_.scrollY + metrics.absoluteTop);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the x coordinate for the flyout position.
|
||||
* @return {number} X coordinate.
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.getX = function() {
|
||||
// X is always 0 since this is a horizontal flyout.
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the y coordinate for the flyout position.
|
||||
* @return {number} Y coordinate.
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.getY = function() {
|
||||
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
|
||||
if (!targetWorkspaceMetrics) {
|
||||
// Hidden components will return null.
|
||||
return 0;
|
||||
}
|
||||
|
||||
var y = 0;
|
||||
// If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
|
||||
// If there is a category toolbox.
|
||||
if (targetWorkspaceMetrics.toolboxHeight) {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
y = targetWorkspaceMetrics.toolboxHeight;
|
||||
} else {
|
||||
y = targetWorkspaceMetrics.viewHeight - this.height_;
|
||||
}
|
||||
// Simple (flyout-only) toolbox.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
y = 0;
|
||||
} else {
|
||||
// The simple flyout does not cover the workspace.
|
||||
y = targetWorkspaceMetrics.viewHeight;
|
||||
}
|
||||
}
|
||||
// Trashcan flyout is opposite the main flyout.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
y = 0;
|
||||
} else {
|
||||
// Because the anchor point of the flyout is on the top, but we want
|
||||
// to align the bottom edge of the flyout with the bottom edge of the
|
||||
// blocklyDiv, we calculate the full height of the div minus the height
|
||||
// of the flyout.
|
||||
y = targetWorkspaceMetrics.viewHeight +
|
||||
targetWorkspaceMetrics.absoluteTop - this.height_;
|
||||
}
|
||||
}
|
||||
|
||||
return y;
|
||||
};
|
||||
|
||||
/**
|
||||
* Move the flyout to the edge of the workspace.
|
||||
*/
|
||||
@@ -137,36 +193,9 @@ Blockly.HorizontalFlyout.prototype.position = function() {
|
||||
var edgeHeight = this.height_ - this.CORNER_RADIUS;
|
||||
this.setBackgroundPath_(edgeWidth, edgeHeight);
|
||||
|
||||
// X is always 0 since this is a horizontal flyout.
|
||||
var x = 0;
|
||||
// If this flyout is the toolbox flyout.
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
|
||||
// If there is a toolbox.
|
||||
if (targetWorkspaceMetrics.toolboxHeight) {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
var y = targetWorkspaceMetrics.toolboxHeight;
|
||||
} else {
|
||||
var y = targetWorkspaceMetrics.viewHeight - this.height_;
|
||||
}
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
var y = 0;
|
||||
} else {
|
||||
var y = targetWorkspaceMetrics.viewHeight;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
var y = 0;
|
||||
} else {
|
||||
// Because the anchor point of the flyout is on the top, but we want
|
||||
// to align the bottom edge of the flyout with the bottom edge of the
|
||||
// blocklyDiv, we calculate the full height of the div minus the height
|
||||
// of the flyout.
|
||||
var y = targetWorkspaceMetrics.viewHeight +
|
||||
targetWorkspaceMetrics.absoluteTop - this.height_;
|
||||
}
|
||||
}
|
||||
var x = this.getX();
|
||||
var y = this.getY();
|
||||
|
||||
this.positionAt_(this.width_, this.height_, x, y);
|
||||
};
|
||||
|
||||
|
||||
@@ -121,6 +121,63 @@ Blockly.VerticalFlyout.prototype.setMetrics_ = function(xyRatio) {
|
||||
this.workspace_.scrollY + metrics.absoluteTop);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the x coordinate for the flyout position.
|
||||
* @return {number} X coordinate.
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.getX = function() {
|
||||
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
|
||||
if (!targetWorkspaceMetrics) {
|
||||
// Hidden components will return null.
|
||||
return 0;
|
||||
}
|
||||
|
||||
var x = 0;
|
||||
|
||||
// If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
|
||||
// If there is a category toolbox.
|
||||
if (targetWorkspaceMetrics.toolboxWidth) {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
x = targetWorkspaceMetrics.toolboxWidth;
|
||||
} else {
|
||||
x = targetWorkspaceMetrics.viewWidth - this.width_;
|
||||
}
|
||||
// Simple (flyout-only) toolbox.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
x = 0;
|
||||
} else {
|
||||
// The simple flyout does not cover the workspace.
|
||||
x = targetWorkspaceMetrics.viewWidth;
|
||||
}
|
||||
}
|
||||
// Trashcan flyout is opposite the main flyout.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
x = 0;
|
||||
} else {
|
||||
// Because the anchor point of the flyout is on the left, but we want
|
||||
// to align the right edge of the flyout with the right edge of the
|
||||
// blocklyDiv, we calculate the full width of the div minus the width
|
||||
// of the flyout.
|
||||
x = targetWorkspaceMetrics.viewWidth +
|
||||
targetWorkspaceMetrics.absoluteLeft - this.width_;
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the y coordinate for the flyout position.
|
||||
* @return {number} Y coordinate.
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.getY = function() {
|
||||
// Y is always 0 since this is a vertical flyout.
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Move the flyout to the edge of the workspace.
|
||||
*/
|
||||
@@ -140,36 +197,9 @@ Blockly.VerticalFlyout.prototype.position = function() {
|
||||
var edgeHeight = targetWorkspaceMetrics.viewHeight - 2 * this.CORNER_RADIUS;
|
||||
this.setBackgroundPath_(edgeWidth, edgeHeight);
|
||||
|
||||
// Y is always 0 since this is a vertical flyout.
|
||||
var y = 0;
|
||||
// If this flyout is the toolbox flyout.
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
|
||||
// If there is a category toolbox.
|
||||
if (targetWorkspaceMetrics.toolboxWidth) {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
var x = targetWorkspaceMetrics.toolboxWidth;
|
||||
} else {
|
||||
var x = targetWorkspaceMetrics.viewWidth - this.width_;
|
||||
}
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
var x = 0;
|
||||
} else {
|
||||
var x = targetWorkspaceMetrics.viewWidth;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
var x = 0;
|
||||
} else {
|
||||
// Because the anchor point of the flyout is on the left, but we want
|
||||
// to align the right edge of the flyout with the right edge of the
|
||||
// blocklyDiv, we calculate the full width of the div minus the width
|
||||
// of the flyout.
|
||||
var x = targetWorkspaceMetrics.viewWidth +
|
||||
targetWorkspaceMetrics.absoluteLeft - this.width_;
|
||||
}
|
||||
}
|
||||
var x = this.getX();
|
||||
var y = this.getY();
|
||||
|
||||
this.positionAt_(this.width_, this.height_, x, y);
|
||||
};
|
||||
|
||||
|
||||
@@ -161,6 +161,18 @@ Blockly.IFlyout.prototype.reflow;
|
||||
*/
|
||||
Blockly.IFlyout.prototype.isScrollable;
|
||||
|
||||
/**
|
||||
* Calculates the x coordinate for the flyout position.
|
||||
* @return {number} X coordinate.
|
||||
*/
|
||||
Blockly.IFlyout.prototype.getX;
|
||||
|
||||
/**
|
||||
* Calculates the y coordinate for the flyout position.
|
||||
* @return {number} Y coordinate.
|
||||
*/
|
||||
Blockly.IFlyout.prototype.getY;
|
||||
|
||||
/**
|
||||
* Position the flyout.
|
||||
* @return {void}
|
||||
|
||||
@@ -29,6 +29,176 @@ suite('Flyout', function() {
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
suite('position', function() {
|
||||
suite('vertical flyout', function() {
|
||||
suite('simple flyout', function() {
|
||||
setup(function() {
|
||||
this.flyout = this.workspace.getFlyout();
|
||||
});
|
||||
test('y is always 0', function() {
|
||||
chai.assert.equal(this.flyout.getY(), 0, 'y coordinate in vertical flyout should be 0');
|
||||
});
|
||||
test('x is right of workspace if flyout at right', function() {
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
viewWidth: 100,
|
||||
});
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;
|
||||
chai.assert.equal(this.flyout.getX(), 100, 'x should be right of workspace');
|
||||
});
|
||||
test('x is 0 if flyout at left', function() {
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_LEFT;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_LEFT;
|
||||
chai.assert.equal(this.flyout.getX(), 0, 'x should be 0 if the flyout is on the left');
|
||||
});
|
||||
});
|
||||
suite('toolbox flyout', function() {
|
||||
setup(function() {
|
||||
var toolbox = document.getElementById('toolbox-categories');
|
||||
this.workspace = Blockly.inject('blocklyDiv',
|
||||
{
|
||||
toolbox: toolbox
|
||||
});
|
||||
this.flyout = this.workspace.getToolbox().getFlyout();
|
||||
});
|
||||
teardown(function() {
|
||||
workspaceTeardown.call(this, this.workspace);
|
||||
});
|
||||
test('x is aligned with toolbox at left', function() {
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
toolboxWidth: 20,
|
||||
});
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_LEFT;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_LEFT;
|
||||
chai.assert.equal(this.flyout.getX(), 20, 'x should be aligned with toolbox');
|
||||
});
|
||||
test('x is aligned with toolbox at right', function() {
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
toolboxWidth: 20,
|
||||
viewWidth: 100,
|
||||
});
|
||||
this.flyout.width_ = 10;
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;
|
||||
chai.assert.equal(this.flyout.getX(), 90,'x + width should be aligned with toolbox');
|
||||
});
|
||||
});
|
||||
// These tests simulate a trashcan flyout, i.e. the flyout under test is on the
|
||||
// opposite side of the workspace toolbox setting.
|
||||
suite('trashcan flyout', function() {
|
||||
setup(function() {
|
||||
this.flyout = this.workspace.getFlyout();
|
||||
});
|
||||
test('x is 0 if trashcan on left', function() {
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
viewWidth: 100,
|
||||
});
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_LEFT;
|
||||
chai.assert.equal(this.flyout.getX(), 0, 'x should be aligned with left edge');
|
||||
});
|
||||
test('trashcan on right covers right edge of workspace', function() {
|
||||
this.flyout.width_ = 20;
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
viewWidth: 100,
|
||||
absoluteLeft: 10,
|
||||
});
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_LEFT;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;
|
||||
chai.assert.equal(this.flyout.getX(), 90, 'x + width should be aligned with right edge');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('horizontal flyout', function() {
|
||||
setup(function() {
|
||||
this.workspace = Blockly.inject('blocklyDiv',
|
||||
{
|
||||
toolbox: this.toolboxXml,
|
||||
horizontalLayout: true,
|
||||
});
|
||||
});
|
||||
teardown(function() {
|
||||
workspaceTeardown.call(this, this.workspace);
|
||||
});
|
||||
suite('simple flyout', function() {
|
||||
setup(function() {
|
||||
this.flyout = this.workspace.getFlyout();
|
||||
});
|
||||
test('x is always 0', function() {
|
||||
chai.assert.equal(this.flyout.getX(), 0, 'x coordinate in horizontal flyout should be 0');
|
||||
});
|
||||
test('y is 0 if flyout at top', function() {
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_TOP;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_TOP;
|
||||
chai.assert.equal(this.flyout.getY(), 0, 'y should be 0 if flyout is at the top');
|
||||
});
|
||||
test('y is below workspace if flyout at bottom', function() {
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_BOTTOM;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_BOTTOM;
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
viewHeight: 50,
|
||||
});
|
||||
chai.assert.equal(this.flyout.getY(), 50, 'y should be below the workspace');
|
||||
});
|
||||
});
|
||||
suite('toolbox flyout', function() {
|
||||
setup(function() {
|
||||
var toolbox = document.getElementById('toolbox-categories');
|
||||
this.workspace = Blockly.inject('blocklyDiv',
|
||||
{
|
||||
toolbox: toolbox,
|
||||
horizontalLayout: true,
|
||||
});
|
||||
this.flyout = this.workspace.getToolbox().getFlyout();
|
||||
});
|
||||
teardown(function() {
|
||||
workspaceTeardown.call(this, this.workspace);
|
||||
});
|
||||
test('y is aligned with toolbox at top', function() {
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
toolboxHeight: 20,
|
||||
});
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_TOP;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_TOP;
|
||||
chai.assert.equal(this.flyout.getY(), 20, 'y should be aligned with toolbox');
|
||||
});
|
||||
test('y is aligned with toolbox at bottom', function() {
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
toolboxHeight: 20,
|
||||
viewHeight: 100,
|
||||
});
|
||||
this.flyout.height_ = 30;
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_BOTTOM;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_BOTTOM;
|
||||
chai.assert.equal(this.flyout.getY(), 70, 'y + height should be aligned with toolbox');
|
||||
});
|
||||
});
|
||||
// These tests simulate a trashcan flyout, i.e. the flyout under test is on the
|
||||
// opposite side of the workspace toolbox setting.
|
||||
suite('trashcan flyout', function() {
|
||||
setup(function() {
|
||||
this.flyout = this.workspace.getFlyout();
|
||||
});
|
||||
test('y is 0 if trashcan at top', function() {
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_BOTTOM;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_TOP;
|
||||
chai.assert.equal(this.flyout.getY(), 0, 'y should be aligned with top');
|
||||
});
|
||||
test('trashcan on bottom covers bottom of workspace', function() {
|
||||
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_TOP;
|
||||
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_BOTTOM;
|
||||
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
|
||||
viewHeight: 50,
|
||||
absoluteTop: 10,
|
||||
});
|
||||
this.flyout.height_ = 20;
|
||||
chai.assert.equal(this.flyout.getY(), 40, 'y + height should be aligned with bottom');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('createFlyoutInfo_', function() {
|
||||
setup(function() {
|
||||
this.simpleToolboxJSON = getSimpleJSON();
|
||||
|
||||
Reference in New Issue
Block a user