Correctly locate and size scrollbar for all toolbox positions.

This commit is contained in:
rachel-fenichel
2016-04-13 13:56:09 -07:00
parent 01955c6615
commit 90b1cce5d5
2 changed files with 92 additions and 59 deletions

View File

@@ -413,7 +413,13 @@ Blockly.hideChaff = function(opt_allowToolbox) {
Blockly.getMainWorkspaceMetrics_ = function() {
var svgSize = Blockly.svgSize(this.getParentSvg());
if (this.toolbox_) {
svgSize.width -= this.toolbox_.width;
// If the toolbox is at the bottom it's laid out separately from the main
// workspace, rather than overlapping.
if (this.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_TOP) {
svgSize.height -= this.toolbox_.height;
} else {
svgSize.width -= this.toolbox_.width;
}
}
// Set the margin to match the flyout's margin so that the workspace does
// not jump as blocks are added.
@@ -448,6 +454,11 @@ Blockly.getMainWorkspaceMetrics_ = function() {
if (this.toolbox_ && this.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) {
absoluteLeft = this.toolbox_.width;
}
var absoluteTop = 0;
if (this.toolbox_ && this.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_TOP) {
absoluteTop = this.toolbox_.height;
}
var metrics = {
viewHeight: svgSize.height,
viewWidth: svgSize.width,
@@ -457,7 +468,7 @@ Blockly.getMainWorkspaceMetrics_ = function() {
viewLeft: -this.scrollX,
contentTop: topEdge,
contentLeft: leftEdge,
absoluteTop: 0,
absoluteTop: absoluteTop,
absoluteLeft: absoluteLeft
};
return metrics;

View File

@@ -270,69 +270,91 @@ Blockly.Scrollbar.prototype.resize = function(opt_metrics) {
* .absoluteLeft: Left-edge of view.
*/
if (this.horizontal_) {
var outerLength = hostMetrics.viewWidth - 1;
if (this.pair_) {
// Shorten the scrollbar to make room for the corner square.
outerLength -= Blockly.Scrollbar.scrollbarThickness;
} else {
// Only show the scrollbar if needed.
// Ideally this would also apply to scrollbar pairs, but that's a bigger
// headache (due to interactions with the corner square).
this.setVisible(outerLength < hostMetrics.contentWidth);
}
this.ratio_ = outerLength / hostMetrics.contentWidth;
if (this.ratio_ === -Infinity || this.ratio_ === Infinity ||
isNaN(this.ratio_)) {
this.ratio_ = 0;
}
var innerLength = hostMetrics.viewWidth * this.ratio_;
var innerOffset = (hostMetrics.viewLeft - hostMetrics.contentLeft) *
this.ratio_;
this.svgKnob_.setAttribute('width', Math.max(0, innerLength));
this.xCoordinate = hostMetrics.absoluteLeft + 0.5;
if (this.pair_ && this.workspace_.RTL) {
this.xCoordinate += hostMetrics.absoluteLeft +
Blockly.Scrollbar.scrollbarThickness;
}
this.yCoordinate = hostMetrics.absoluteTop + hostMetrics.viewHeight -
Blockly.Scrollbar.scrollbarThickness - 0.5;
this.svgGroup_.setAttribute('transform',
'translate(' + this.xCoordinate + ',' + this.yCoordinate + ')');
this.svgBackground_.setAttribute('width', Math.max(0, outerLength));
this.svgKnob_.setAttribute('x', this.constrainKnob_(innerOffset));
this.resizeHorizontal_(hostMetrics);
} else {
var outerLength = hostMetrics.viewHeight - 1;
if (this.pair_) {
// Shorten the scrollbar to make room for the corner square.
outerLength -= Blockly.Scrollbar.scrollbarThickness;
} else {
// Only show the scrollbar if needed.
this.setVisible(outerLength < hostMetrics.contentHeight);
}
this.ratio_ = outerLength / hostMetrics.contentHeight;
if (this.ratio_ === -Infinity || this.ratio_ === Infinity ||
isNaN(this.ratio_)) {
this.ratio_ = 0;
}
var innerLength = hostMetrics.viewHeight * this.ratio_;
var innerOffset = (hostMetrics.viewTop - hostMetrics.contentTop) *
this.ratio_;
this.svgKnob_.setAttribute('height', Math.max(0, innerLength));
this.xCoordinate = hostMetrics.absoluteLeft + 0.5;
if (!this.workspace_.RTL) {
this.xCoordinate += hostMetrics.viewWidth -
Blockly.Scrollbar.scrollbarThickness - 1;
}
this.yCoordinate = hostMetrics.absoluteTop + 0.5;
this.svgGroup_.setAttribute('transform',
'translate(' + this.xCoordinate + ',' + this.yCoordinate + ')');
this.svgBackground_.setAttribute('height', Math.max(0, outerLength));
this.svgKnob_.setAttribute('y', this.constrainKnob_(innerOffset));
this.resizeVertical_(hostMetrics);
}
// Resizing may have caused some scrolling.
this.onScroll_();
};
/**
* Recalculate a horizontal scrollbar's location and length.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host
* object.
* @private
*/
Blockly.Scrollbar.prototype.resizeHorizontal_ = function(hostMetrics) {
var outerLength = hostMetrics.viewWidth - 1;
if (this.pair_) {
// Shorten the scrollbar to make room for the corner square.
outerLength -= Blockly.Scrollbar.scrollbarThickness;
} else {
// Only show the scrollbar if needed.
// Ideally this would also apply to scrollbar pairs, but that's a bigger
// headache (due to interactions with the corner square).
this.setVisible(outerLength < hostMetrics.contentWidth);
}
this.ratio_ = outerLength / hostMetrics.contentWidth;
if (this.ratio_ === -Infinity || this.ratio_ === Infinity ||
isNaN(this.ratio_)) {
this.ratio_ = 0;
}
var innerLength = hostMetrics.viewWidth * this.ratio_;
var innerOffset = (hostMetrics.viewLeft - hostMetrics.contentLeft) *
this.ratio_;
this.svgKnob_.setAttribute('width', Math.max(0, innerLength));
this.xCoordinate = hostMetrics.absoluteLeft + 0.5;
if (this.pair_ && this.workspace_.RTL) {
this.xCoordinate += Blockly.Scrollbar.scrollbarThickness;
}
// Horizontal toolbar should always be just above the bottom of the workspace.
this.yCoordinate = hostMetrics.absoluteTop + hostMetrics.viewHeight -
Blockly.Scrollbar.scrollbarThickness - 0.5;
this.svgGroup_.setAttribute('transform',
'translate(' + this.xCoordinate + ',' + this.yCoordinate + ')');
this.svgBackground_.setAttribute('width', Math.max(0, outerLength));
this.svgKnob_.setAttribute('x', this.constrainKnob_(innerOffset));
};
/**
* Recalculate a vertical scrollbar's location and length.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host
* object.
* @private
*/
Blockly.Scrollbar.prototype.resizeVertical_ = function(hostMetrics) {
var outerLength = hostMetrics.viewHeight - 1;
if (this.pair_) {
// Shorten the scrollbar to make room for the corner square.
outerLength -= Blockly.Scrollbar.scrollbarThickness;
} else {
// Only show the scrollbar if needed.
this.setVisible(outerLength < hostMetrics.contentHeight);
}
this.ratio_ = outerLength / hostMetrics.contentHeight;
if (this.ratio_ === -Infinity || this.ratio_ === Infinity ||
isNaN(this.ratio_)) {
this.ratio_ = 0;
}
var innerLength = hostMetrics.viewHeight * this.ratio_;
var innerOffset = (hostMetrics.viewTop - hostMetrics.contentTop) *
this.ratio_;
this.svgKnob_.setAttribute('height', Math.max(0, innerLength));
this.xCoordinate = hostMetrics.absoluteLeft + 0.5;
if (!this.workspace_.RTL) {
this.xCoordinate += hostMetrics.viewWidth -
Blockly.Scrollbar.scrollbarThickness - 1;
}
this.yCoordinate = hostMetrics.absoluteTop + 0.5;
this.svgGroup_.setAttribute('transform',
'translate(' + this.xCoordinate + ',' + this.yCoordinate + ')');
this.svgBackground_.setAttribute('height', Math.max(0, outerLength));
this.svgKnob_.setAttribute('y', this.constrainKnob_(innerOffset));
};
/**
* Create all the DOM elements required for a scrollbar.
* The resulting widget is not sized.