mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
position toolbox
This commit is contained in:
parent
02160ec6b5
commit
3462a5a2c1
7 changed files with 88 additions and 52 deletions
|
@ -62,6 +62,11 @@ Blockly.Flyout = function(workspaceOptions) {
|
|||
*/
|
||||
this.horizontalLayout_ = workspaceOptions.horizontalLayout;
|
||||
|
||||
this.atStart_ = workspaceOptions.toolboxAtStart;
|
||||
|
||||
this.atRight_ = !this.horizontalLayout_ &&
|
||||
((this.RTL && this.atStart_) || (!this.RTL && !this.atStart_));
|
||||
|
||||
/**
|
||||
* Opaque data that can be passed to Blockly.unbindEvent_.
|
||||
* @type {!Array.<!Array>}
|
||||
|
@ -263,7 +268,7 @@ Blockly.Flyout.prototype.setMetrics_ = function(xyRatio) {
|
|||
this.workspace_.scrollY =
|
||||
-metrics.contentHeight * xyRatio.y - metrics.contentTop;
|
||||
} else if (this.horizontalLayout_ && goog.isNumber(xyRatio.x)) {
|
||||
if (this.RTL) {
|
||||
if (this.atRight_) {
|
||||
this.workspace_.scrollX =
|
||||
-metrics.contentWidth * xyRatio.x + metrics.contentLeft;
|
||||
} else {
|
||||
|
@ -293,7 +298,7 @@ Blockly.Flyout.prototype.position = function() {
|
|||
}
|
||||
var edgeWidth = this.horizontalLayout_ ? metrics.viewWidth : this.width_;
|
||||
edgeWidth -= this.CORNER_RADIUS;
|
||||
if (this.RTL) {
|
||||
if (this.atRight_) {
|
||||
edgeWidth *= -1;
|
||||
}
|
||||
|
||||
|
@ -301,7 +306,7 @@ Blockly.Flyout.prototype.position = function() {
|
|||
this.horizontalLayout_ ? this.height_ + this.verticalOffset_ : metrics.viewHeight);
|
||||
|
||||
var x = metrics.absoluteLeft;
|
||||
if (this.RTL) {
|
||||
if (this.atRight_) {
|
||||
x += metrics.viewWidth;
|
||||
x -= this.width_;
|
||||
}
|
||||
|
@ -332,20 +337,20 @@ Blockly.Flyout.prototype.position = function() {
|
|||
*/
|
||||
Blockly.Flyout.prototype.setBackgroundPath_ = function(width, height) {
|
||||
// Decide whether to start on the left or right.
|
||||
var path = ['M ' + (this.RTL ? this.width_ : 0) + ',0'];
|
||||
var path = ['M ' + (this.atRight_ ? this.width_ : 0) + ',0'];
|
||||
// Top.
|
||||
path.push('h', width);
|
||||
// Rounded corner.
|
||||
path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
|
||||
this.RTL ? 0 : 1,
|
||||
this.RTL ? -this.CORNER_RADIUS : this.CORNER_RADIUS,
|
||||
this.atRight_ ? 0 : 1,
|
||||
this.atRight_ ? -this.CORNER_RADIUS : this.CORNER_RADIUS,
|
||||
this.CORNER_RADIUS);
|
||||
// Side closest to workspace.
|
||||
path.push('v', Math.max(0, height - this.CORNER_RADIUS * 2));
|
||||
// Rounded corner.
|
||||
path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
|
||||
this.RTL ? 0 : 1,
|
||||
this.RTL ? this.CORNER_RADIUS : -this.CORNER_RADIUS,
|
||||
this.atRight_ ? 0 : 1,
|
||||
this.atRight_ ? this.CORNER_RADIUS : -this.CORNER_RADIUS,
|
||||
this.CORNER_RADIUS);
|
||||
// Bottom.
|
||||
path.push('h', -width);
|
||||
|
@ -464,7 +469,7 @@ Blockly.Flyout.prototype.show = function(xmlList) {
|
|||
|
||||
// Lay out the blocks.
|
||||
var cursorX = margin / this.workspace_.scale + Blockly.BlockSvg.TAB_WIDTH;
|
||||
if (this.RTL) {
|
||||
if (this.atRight_) {
|
||||
cursorX = this.width_ - cursorX;
|
||||
}
|
||||
var cursorY = margin;
|
||||
|
@ -481,7 +486,7 @@ Blockly.Flyout.prototype.show = function(xmlList) {
|
|||
var blockHW = block.getHeightWidth();
|
||||
block.moveBy(cursorX, cursorY);
|
||||
if (this.horizontalLayout_) {
|
||||
if (this.RTL) {
|
||||
if (this.atRight_) {
|
||||
cursorX -= (blockHW.width + gaps[i]);
|
||||
} else {
|
||||
cursorX += blockHW.width + gaps[i];
|
||||
|
@ -690,7 +695,7 @@ Blockly.Flyout.prototype.createBlockFunc_ = function(originBlock) {
|
|||
}
|
||||
var xyOld = Blockly.getSvgXY_(svgRootOld, workspace);
|
||||
// Scale the scroll (getSvgXY_ did not do this).
|
||||
if (flyout.RTL) {
|
||||
if (this.atRight_) {
|
||||
var width = workspace.getMetrics().viewWidth - flyout.width_;
|
||||
xyOld.x += width / workspace.scale - width;
|
||||
} else {
|
||||
|
@ -756,7 +761,7 @@ Blockly.Flyout.prototype.getRect = function() {
|
|||
return new goog.math.Rect(-BIG_NUM, y, BIG_NUM * 2,
|
||||
BIG_NUM + this.height_ * scale);
|
||||
} else {
|
||||
if (!this.RTL) {
|
||||
if (!this.atRight_) {
|
||||
x -= BIG_NUM;
|
||||
}
|
||||
return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + this.width_ * scale,
|
||||
|
@ -817,7 +822,7 @@ Blockly.Flyout.prototype.reflowHorizontal = function() {
|
|||
var blockXY = block.getRelativeToSurfaceXY();
|
||||
block.flyoutRect_.setAttribute('y', blockXY.y);
|
||||
block.flyoutRect_.setAttribute('x',
|
||||
this.RTL ? blockXY.x - blockHW.width + tab : blockXY.x - tab);
|
||||
this.atRight_? blockXY.x - blockHW.width + tab : blockXY.x - tab);
|
||||
}
|
||||
}
|
||||
// Record the width for .getMetrics_ and .position.
|
||||
|
@ -847,7 +852,7 @@ Blockly.Flyout.prototype.reflowVertical = function() {
|
|||
if (this.width_ != flyoutWidth) {
|
||||
for (var x = 0, block; block = blocks[x]; x++) {
|
||||
var blockHW = block.getHeightWidth();
|
||||
if (this.RTL) {
|
||||
if (this.atRight_) {
|
||||
// With the flyoutWidth known, right-align the blocks.
|
||||
var oldX = block.getRelativeToSurfaceXY().x;
|
||||
var dx = flyoutWidth - margin;
|
||||
|
@ -862,7 +867,7 @@ Blockly.Flyout.prototype.reflowVertical = function() {
|
|||
var tab = block.outputConnection ? Blockly.BlockSvg.TAB_WIDTH : 0;
|
||||
var blockXY = block.getRelativeToSurfaceXY();
|
||||
block.flyoutRect_.setAttribute('x',
|
||||
this.RTL ? blockXY.x - blockHW.width + tab : blockXY.x - tab);
|
||||
this.atRight_ ? blockXY.x - blockHW.width + tab : blockXY.x - tab);
|
||||
block.flyoutRect_.setAttribute('y', blockXY.y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,10 +125,16 @@ Blockly.parseOptions_ = function(options) {
|
|||
if (hasSounds === undefined) {
|
||||
hasSounds = true;
|
||||
}
|
||||
var horizontalLayout = options['horizontalLayout'];
|
||||
if (horizontalLayout === undefined) {
|
||||
horizontalLayout = false;
|
||||
}
|
||||
}
|
||||
var horizontalLayout = options['horizontalLayout'];
|
||||
if (horizontalLayout === undefined) {
|
||||
horizontalLayout = false;
|
||||
}
|
||||
var toolboxPosition = options['toolboxPosition'];
|
||||
if (toolboxPosition === 'end') {
|
||||
var toolboxAtStart = false;
|
||||
} else {
|
||||
var toolboxAtStart = true;
|
||||
}
|
||||
var hasScrollbars = options['scrollbars'];
|
||||
if (hasScrollbars === undefined) {
|
||||
|
@ -210,7 +216,8 @@ Blockly.parseOptions_ = function(options) {
|
|||
gridOptions: gridOptions,
|
||||
zoomOptions: zoomOptions,
|
||||
enableRealtime: enableRealtime,
|
||||
realtimeOptions: realtimeOptions
|
||||
realtimeOptions: realtimeOptions,
|
||||
toolboxAtStart: toolboxAtStart
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -66,16 +66,22 @@ Blockly.Toolbox = function(workspace) {
|
|||
*/
|
||||
this.horizontalLayout_ = workspace.options.horizontalLayout;
|
||||
|
||||
this.atRight_ = !this.horizontalLayout_ &&
|
||||
((workspace.RTL && workspace.atStart_) || (!workspace.RTL && !workspace.atStart_));
|
||||
|
||||
if (this.horizontalLayout_) {
|
||||
this.CONFIG_['cssTreeRow'] =
|
||||
this.CONFIG_['cssTreeRow']
|
||||
+ (workspace.RTL ? ' blocklyHorizontalTreeRtl' : ' blocklyHorizontalTree');
|
||||
+ (this.atRight_ ? ' blocklyHorizontalTreeRtl' : ' blocklyHorizontalTree');
|
||||
|
||||
Blockly.Toolbox.TreeSeparator.CONFIG_['cssTreeRow'] =
|
||||
'blocklyTreeSeparatorHorizontal'
|
||||
+ (workspace.RTL ? ' blocklyHorizontalTreeRtl' : ' blocklyHorizontalTree');
|
||||
+ (this.atRight_ ? ' blocklyHorizontalTreeRtl' : ' blocklyHorizontalTree');
|
||||
this.CONFIG_['cssTreeIcon'] = '';
|
||||
}
|
||||
|
||||
this.atStart_ = workspace.options.toolboxAtStart;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -149,7 +155,8 @@ Blockly.Toolbox.prototype.init = function() {
|
|||
disabledPatternId: workspace.options.disabledPatternId,
|
||||
parentWorkspace: workspace,
|
||||
RTL: workspace.RTL,
|
||||
horizontalLayout: workspace.horizontalLayout
|
||||
horizontalLayout: workspace.horizontalLayout,
|
||||
toolboxAtStart: this.atStart_
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -162,7 +169,7 @@ Blockly.Toolbox.prototype.init = function() {
|
|||
|
||||
this.CONFIG_['cleardotPath'] = workspace.options.pathToMedia + '1x1.gif';
|
||||
this.CONFIG_['cssCollapsedFolderIcon'] =
|
||||
'blocklyTreeIconClosed' + (workspace.RTL ? 'Rtl' : 'Ltr');
|
||||
'blocklyTreeIconClosed' + (this.atRight_ ? 'Rtl' : 'Ltr');
|
||||
var tree = new Blockly.Toolbox.TreeControl(this, this.CONFIG_);
|
||||
this.tree_ = tree;
|
||||
tree.setShowRootNode(false);
|
||||
|
@ -199,7 +206,7 @@ Blockly.Toolbox.prototype.position = function() {
|
|||
var svgPosition = goog.style.getPageOffset(svg);
|
||||
var svgSize = Blockly.svgSize(svg);
|
||||
if (!this.horizontalLayout_) {
|
||||
if (this.workspace_.RTL) { // Right
|
||||
if (this.atRight_) { // Right
|
||||
treeDiv.style.left =
|
||||
(svgPosition.x + svgSize.width - treeDiv.offsetWidth) + 'px';
|
||||
} else { // Left
|
||||
|
@ -208,7 +215,7 @@ Blockly.Toolbox.prototype.position = function() {
|
|||
treeDiv.style.height = svgSize.height + 'px';
|
||||
treeDiv.style.top = svgPosition.y + 'px';
|
||||
this.width = treeDiv.offsetWidth;
|
||||
if (!this.workspace_.RTL) {
|
||||
if (!this.atRight_) {
|
||||
// For some reason the LTR toolbox now reports as 1px too wide.
|
||||
this.width -= 1;
|
||||
}
|
||||
|
@ -323,7 +330,7 @@ Blockly.Toolbox.prototype.addColour_ = function(opt_tree) {
|
|||
} else {
|
||||
var border = 'none';
|
||||
}
|
||||
if (this.workspace_.RTL) {
|
||||
if (this.atRight_) {
|
||||
element.style.borderRight = border;
|
||||
} else {
|
||||
element.style.borderLeft = border;
|
||||
|
@ -354,7 +361,7 @@ Blockly.Toolbox.prototype.getRect = function() {
|
|||
if (!this.horizontalLayout_) {
|
||||
// Assumes that the toolbox is on the SVG edge. If this changes
|
||||
// (e.g. toolboxes in mutators) then this code will need to be more complex.
|
||||
if (!this.workspace_.RTL) {
|
||||
if (!this.atRight_) {
|
||||
x = -BIG_NUM;
|
||||
}
|
||||
return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + this.width, 2 * BIG_NUM);
|
||||
|
|
|
@ -45,6 +45,8 @@ Blockly.Workspace = function(opt_options) {
|
|||
this.RTL = !!this.options.RTL;
|
||||
/** @type {boolean} */
|
||||
this.horizontalLayout = !!this.options.horizontalLayout;
|
||||
/** @type {boolean} */
|
||||
this.toolboxAtStart = !!this.options.toolboxAtStart;
|
||||
/** @type {!Array.<!Blockly.Block>} */
|
||||
this.topBlocks_ = [];
|
||||
};
|
||||
|
|
|
@ -295,7 +295,8 @@ Blockly.WorkspaceSvg.prototype.addFlyout_ = function() {
|
|||
disabledPatternId: this.options.disabledPatternId,
|
||||
parentWorkspace: this,
|
||||
RTL: this.RTL,
|
||||
horizontalLayout: this.horizontalLayout
|
||||
horizontalLayout: this.horizontalLayout,
|
||||
toolboxAtStart: this.toolboxAtStart,
|
||||
};
|
||||
/** @type {Blockly.Flyout} */
|
||||
this.flyout_ = new Blockly.Flyout(workspaceOptions);
|
||||
|
|
|
@ -34,6 +34,7 @@ function start() {
|
|||
toolbox: toolbox,
|
||||
trashcan: true,
|
||||
horizontalLayout: true,
|
||||
toolboxPosition: 'start',
|
||||
zoom: {
|
||||
controls: true,
|
||||
wheel: false,
|
||||
|
@ -105,19 +106,24 @@ h1 {
|
|||
<div id="collaborators"></div>
|
||||
|
||||
<div id="blocklyDiv"></div>
|
||||
|
||||
<xml id="toolbox" style="display: none">
|
||||
<block type="event_whenflagclicked"></block>
|
||||
<block type="motion_moveright"></block>
|
||||
<!-- <block type="control_repeat"></block> -->
|
||||
<block type="control_forever"></block>
|
||||
<block type="control_repeat">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<category name="Events">
|
||||
<block type="event_whenflagclicked"></block>
|
||||
</category>
|
||||
<category name="Motion">
|
||||
<block type="motion_moveright"></block>
|
||||
</category>
|
||||
<!-- <block type="control_repeat"></block> -->
|
||||
<category name="Pants">
|
||||
<block type="control_forever"></block>
|
||||
<block type="control_repeat">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
</xml>
|
||||
|
||||
<h1>Horizontal block rendering!</h1>
|
||||
|
|
|
@ -32,6 +32,7 @@ function start() {
|
|||
rtl: rtl,
|
||||
scrollbars: true,
|
||||
toolbox: toolbox,
|
||||
toolboxPosition: 'start',
|
||||
trashcan: true,
|
||||
zoom: {
|
||||
controls: true,
|
||||
|
@ -106,19 +107,26 @@ h1 {
|
|||
<div id="blocklyDiv"></div>
|
||||
|
||||
<xml id="toolbox" style="display: none">
|
||||
<block type="event_whenflagclicked"></block>
|
||||
<block type="motion_moveright"></block>
|
||||
<!-- <block type="control_repeat"></block> -->
|
||||
<block type="control_forever"></block>
|
||||
<block type="control_repeat">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<category name="Events">
|
||||
<block type="event_whenflagclicked"></block>
|
||||
</category>
|
||||
<category name="Motion">
|
||||
<block type="motion_moveright"></block>
|
||||
</category>
|
||||
<!-- <block type="control_repeat"></block> -->
|
||||
<category name="Pants">
|
||||
<block type="control_forever"></block>
|
||||
<block type="control_repeat">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
</xml>
|
||||
|
||||
|
||||
<h1>Vertical block rendering!</h1>
|
||||
|
||||
<p><a href="javascript:void(workspace.setVisible(true))">Show</a>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue