@babylonjs/gui
Version:
Babylon.js GUI module =====================
587 lines • 20.6 kB
JavaScript
import { __decorate } from "@babylonjs/core/tslib.es6.js";
import { Rectangle } from "../rectangle.js";
import { Grid } from "../grid.js";
import { Control } from "../control.js";
import { _ScrollViewerWindow } from "./scrollViewerWindow.js";
import { ScrollBar } from "../sliders/scrollBar.js";
import { ImageScrollBar } from "../sliders/imageScrollBar.js";
import { RegisterClass } from "@babylonjs/core/Misc/typeStore.js";
import { serialize } from "@babylonjs/core/Misc/decorators.js";
/**
* Class used to hold a viewer window and sliders in a grid
*/
export class ScrollViewer extends Rectangle {
/**
* Gets the horizontal scrollbar
*/
get horizontalBar() {
return this._horizontalBar;
}
/**
* Gets the vertical scrollbar
*/
get verticalBar() {
return this._verticalBar;
}
/**
* Adds a new control to the current container
* @param control defines the control to add
* @returns the current container
*/
addControl(control) {
if (!control) {
return this;
}
this._window.addControl(control);
return this;
}
/**
* Removes a control from the current container
* @param control defines the control to remove
* @returns the current container
*/
removeControl(control) {
this._window.removeControl(control);
return this;
}
/** Gets the list of children */
get children() {
return this._window.children;
}
_flagDescendantsAsMatrixDirty() {
for (const child of this._children) {
child._markMatrixAsDirty();
}
}
/**
* Freezes or unfreezes the controls in the window.
* When controls are frozen, the scroll viewer can render a lot more quickly but updates to positions/sizes of controls
* are not taken into account. If you want to change positions/sizes, unfreeze, perform the changes then freeze again
*/
get freezeControls() {
return this._window.freezeControls;
}
set freezeControls(value) {
this._window.freezeControls = value;
}
/** Gets the bucket width */
get bucketWidth() {
return this._window.bucketWidth;
}
/** Gets the bucket height */
get bucketHeight() {
return this._window.bucketHeight;
}
/**
* Sets the bucket sizes.
* When freezeControls is true, setting a non-zero bucket size will improve performances by updating only
* controls that are visible. The bucket sizes is used to subdivide (internally) the window area to smaller areas into which
* controls are dispatched. So, the size should be roughly equals to the mean size of all the controls of
* the window. To disable the usage of buckets, sets either width or height (or both) to 0.
* Please note that using this option will raise the memory usage (the higher the bucket sizes, the less memory
* used), that's why it is not enabled by default.
* @param width width of the bucket
* @param height height of the bucket
*/
setBucketSizes(width, height) {
this._window.setBucketSizes(width, height);
}
/**
* Forces the horizontal scroll bar to be displayed
*/
get forceHorizontalBar() {
return this._forceHorizontalBar;
}
set forceHorizontalBar(value) {
this._grid.setRowDefinition(1, value ? this._barSize : 0, true);
this._horizontalBar.isVisible = value;
this._forceHorizontalBar = value;
}
/**
* Forces the vertical scroll bar to be displayed
*/
get forceVerticalBar() {
return this._forceVerticalBar;
}
set forceVerticalBar(value) {
this._grid.setColumnDefinition(1, value ? this._barSize : 0, true);
this._verticalBar.isVisible = value;
this._forceVerticalBar = value;
}
/**
* Creates a new ScrollViewer
* @param name of ScrollViewer
* @param isImageBased
*/
constructor(name, isImageBased) {
super(name);
this._barSize = 20;
this._pointerIsOver = false;
this._wheelPrecision = 0.05;
this._thumbLength = 0.5;
this._thumbHeight = 1;
this._barImageHeight = 1;
this._horizontalBarImageHeight = 1;
this._verticalBarImageHeight = 1;
this._oldWindowContentsWidth = 0;
this._oldWindowContentsHeight = 0;
this._forceHorizontalBar = false;
this._forceVerticalBar = false;
this._useImageBar = isImageBased ? isImageBased : false;
this.onDirtyObservable.add(() => {
this._horizontalBarSpace.color = this.color;
this._verticalBarSpace.color = this.color;
this._dragSpace.color = this.color;
});
this.onPointerEnterObservable.add(() => {
this._pointerIsOver = true;
});
this.onPointerOutObservable.add(() => {
this._pointerIsOver = false;
});
this._grid = new Grid();
if (this._useImageBar) {
this._horizontalBar = new ImageScrollBar();
this._verticalBar = new ImageScrollBar();
}
else {
this._horizontalBar = new ScrollBar();
this._verticalBar = new ScrollBar();
}
this._window = new _ScrollViewerWindow("scrollViewer_window");
this._window.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
this._window.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
this._grid.addColumnDefinition(1);
this._grid.addColumnDefinition(0, true);
this._grid.addRowDefinition(1);
this._grid.addRowDefinition(0, true);
super.addControl(this._grid);
this._grid.addControl(this._window, 0, 0);
this._verticalBarSpace = new Rectangle();
this._verticalBarSpace.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
this._verticalBarSpace.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
this._verticalBarSpace.thickness = 1;
this._grid.addControl(this._verticalBarSpace, 0, 1);
this._addBar(this._verticalBar, this._verticalBarSpace, true, Math.PI);
this._horizontalBarSpace = new Rectangle();
this._horizontalBarSpace.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
this._horizontalBarSpace.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
this._horizontalBarSpace.thickness = 1;
this._grid.addControl(this._horizontalBarSpace, 1, 0);
this._addBar(this._horizontalBar, this._horizontalBarSpace, false, 0);
this._dragSpace = new Rectangle();
this._dragSpace.thickness = 1;
this._grid.addControl(this._dragSpace, 1, 1);
this._grid.clipChildren = false;
// Colors
if (!this._useImageBar) {
this.barColor = "grey";
this.barBackground = "transparent";
}
}
/** Reset the scroll viewer window to initial size */
resetWindow() {
this._window.width = "100%";
this._window.height = "100%";
}
_getTypeName() {
return "ScrollViewer";
}
_buildClientSizes() {
const ratio = this.host.idealRatio;
this._window.parentClientWidth = this._currentMeasure.width - (this._verticalBar.isVisible || this.forceVerticalBar ? this._barSize * ratio : 0) - 2 * this.thickness;
this._window.parentClientHeight = this._currentMeasure.height - (this._horizontalBar.isVisible || this.forceHorizontalBar ? this._barSize * ratio : 0) - 2 * this.thickness;
this._clientWidth = this._window.parentClientWidth;
this._clientHeight = this._window.parentClientHeight;
}
_additionalProcessing(parentMeasure, context) {
super._additionalProcessing(parentMeasure, context);
this._buildClientSizes();
}
_postMeasure() {
super._postMeasure();
this._updateScroller();
this._setWindowPosition(false);
}
/**
* Gets or sets the mouse wheel precision
* from 0 to 1 with a default value of 0.05
* */
get wheelPrecision() {
return this._wheelPrecision;
}
set wheelPrecision(value) {
if (this._wheelPrecision === value) {
return;
}
if (value < 0) {
value = 0;
}
if (value > 1) {
value = 1;
}
this._wheelPrecision = value;
}
/** Gets or sets the scroll bar container background color */
get scrollBackground() {
return this._horizontalBarSpace.background;
}
set scrollBackground(color) {
if (this._horizontalBarSpace.background === color) {
return;
}
this._horizontalBarSpace.background = color;
this._verticalBarSpace.background = color;
}
/** Gets or sets the bar color */
get barColor() {
return this._barColor;
}
set barColor(color) {
if (this._barColor === color) {
return;
}
this._barColor = color;
this._horizontalBar.color = color;
this._verticalBar.color = color;
}
/** Gets or sets the bar image */
get thumbImage() {
return this._barImage;
}
set thumbImage(value) {
if (this._barImage === value) {
return;
}
this._barImage = value;
const hb = this._horizontalBar;
const vb = this._verticalBar;
hb.thumbImage = value;
vb.thumbImage = value;
}
/** Gets or sets the horizontal bar image */
get horizontalThumbImage() {
return this._horizontalBarImage;
}
set horizontalThumbImage(value) {
if (this._horizontalBarImage === value) {
return;
}
this._horizontalBarImage = value;
const hb = this._horizontalBar;
hb.thumbImage = value;
}
/** Gets or sets the vertical bar image */
get verticalThumbImage() {
return this._verticalBarImage;
}
set verticalThumbImage(value) {
if (this._verticalBarImage === value) {
return;
}
this._verticalBarImage = value;
const vb = this._verticalBar;
vb.thumbImage = value;
}
/** Gets or sets the size of the bar */
get barSize() {
return this._barSize;
}
set barSize(value) {
if (this._barSize === value) {
return;
}
this._barSize = value;
this._markAsDirty();
if (this._horizontalBar.isVisible) {
this._grid.setRowDefinition(1, this._barSize, true);
}
if (this._verticalBar.isVisible) {
this._grid.setColumnDefinition(1, this._barSize, true);
}
}
/** Gets or sets the length of the thumb */
get thumbLength() {
return this._thumbLength;
}
set thumbLength(value) {
if (this._thumbLength === value) {
return;
}
if (value <= 0) {
value = 0.1;
}
if (value > 1) {
value = 1;
}
this._thumbLength = value;
const hb = this._horizontalBar;
const vb = this._verticalBar;
hb.thumbLength = value;
vb.thumbLength = value;
this._markAsDirty();
}
/** Gets or sets the height of the thumb */
get thumbHeight() {
return this._thumbHeight;
}
set thumbHeight(value) {
if (this._thumbHeight === value) {
return;
}
if (value <= 0) {
value = 0.1;
}
if (value > 1) {
value = 1;
}
this._thumbHeight = value;
const hb = this._horizontalBar;
const vb = this._verticalBar;
hb.thumbHeight = value;
vb.thumbHeight = value;
this._markAsDirty();
}
/** Gets or sets the height of the bar image */
get barImageHeight() {
return this._barImageHeight;
}
set barImageHeight(value) {
if (this._barImageHeight === value) {
return;
}
if (value <= 0) {
value = 0.1;
}
if (value > 1) {
value = 1;
}
this._barImageHeight = value;
const hb = this._horizontalBar;
const vb = this._verticalBar;
hb.barImageHeight = value;
vb.barImageHeight = value;
this._markAsDirty();
}
/** Gets or sets the height of the horizontal bar image */
get horizontalBarImageHeight() {
return this._horizontalBarImageHeight;
}
set horizontalBarImageHeight(value) {
if (this._horizontalBarImageHeight === value) {
return;
}
if (value <= 0) {
value = 0.1;
}
if (value > 1) {
value = 1;
}
this._horizontalBarImageHeight = value;
const hb = this._horizontalBar;
hb.barImageHeight = value;
this._markAsDirty();
}
/** Gets or sets the height of the vertical bar image */
get verticalBarImageHeight() {
return this._verticalBarImageHeight;
}
set verticalBarImageHeight(value) {
if (this._verticalBarImageHeight === value) {
return;
}
if (value <= 0) {
value = 0.1;
}
if (value > 1) {
value = 1;
}
this._verticalBarImageHeight = value;
const vb = this._verticalBar;
vb.barImageHeight = value;
this._markAsDirty();
}
/** Gets or sets the bar background */
get barBackground() {
return this._barBackground;
}
set barBackground(color) {
if (this._barBackground === color) {
return;
}
this._barBackground = color;
const hb = this._horizontalBar;
const vb = this._verticalBar;
hb.background = color;
vb.background = color;
this._dragSpace.background = color;
}
/** Gets or sets the bar background image */
get barImage() {
return this._barBackgroundImage;
}
set barImage(value) {
this._barBackgroundImage = value;
const hb = this._horizontalBar;
const vb = this._verticalBar;
hb.backgroundImage = value;
vb.backgroundImage = value;
}
/** Gets or sets the horizontal bar background image */
get horizontalBarImage() {
return this._horizontalBarBackgroundImage;
}
set horizontalBarImage(value) {
this._horizontalBarBackgroundImage = value;
const hb = this._horizontalBar;
hb.backgroundImage = value;
}
/** Gets or sets the vertical bar background image */
get verticalBarImage() {
return this._verticalBarBackgroundImage;
}
set verticalBarImage(value) {
this._verticalBarBackgroundImage = value;
const vb = this._verticalBar;
vb.backgroundImage = value;
}
_setWindowPosition(force = true) {
const ratio = this.host.idealRatio;
const windowContentsWidth = this._window._currentMeasure.width;
const windowContentsHeight = this._window._currentMeasure.height;
if (!force && this._oldWindowContentsWidth === windowContentsWidth && this._oldWindowContentsHeight === windowContentsHeight) {
return;
}
this._oldWindowContentsWidth = windowContentsWidth;
this._oldWindowContentsHeight = windowContentsHeight;
const _endLeft = this._clientWidth - windowContentsWidth;
const _endTop = this._clientHeight - windowContentsHeight;
const newLeft = (this._horizontalBar.value / ratio) * _endLeft + "px";
const newTop = (this._verticalBar.value / ratio) * _endTop + "px";
if (newLeft !== this._window.left) {
this._window.left = newLeft;
if (!this.freezeControls) {
this._rebuildLayout = true;
}
}
if (newTop !== this._window.top) {
this._window.top = newTop;
if (!this.freezeControls) {
this._rebuildLayout = true;
}
}
}
/** @internal */
_updateScroller() {
const windowContentsWidth = this._window._currentMeasure.width;
const windowContentsHeight = this._window._currentMeasure.height;
if (this._horizontalBar.isVisible && windowContentsWidth <= this._clientWidth && !this.forceHorizontalBar) {
this._grid.setRowDefinition(1, 0, true);
this._horizontalBar.isVisible = false;
this._horizontalBar.value = 0;
this._rebuildLayout = true;
}
else if (!this._horizontalBar.isVisible && (windowContentsWidth > this._clientWidth || this.forceHorizontalBar)) {
this._grid.setRowDefinition(1, this._barSize, true);
this._horizontalBar.isVisible = true;
this._rebuildLayout = true;
}
if (this._verticalBar.isVisible && windowContentsHeight <= this._clientHeight && !this.forceVerticalBar) {
this._grid.setColumnDefinition(1, 0, true);
this._verticalBar.isVisible = false;
this._verticalBar.value = 0;
this._rebuildLayout = true;
}
else if (!this._verticalBar.isVisible && (windowContentsHeight > this._clientHeight || this.forceVerticalBar)) {
this._grid.setColumnDefinition(1, this._barSize, true);
this._verticalBar.isVisible = true;
this._rebuildLayout = true;
}
this._buildClientSizes();
const ratio = this.host.idealRatio;
this._horizontalBar.thumbWidth = this._thumbLength * 0.9 * (this._clientWidth / ratio) + "px";
this._verticalBar.thumbWidth = this._thumbLength * 0.9 * (this._clientHeight / ratio) + "px";
}
_link(host) {
super._link(host);
this._attachWheel();
}
/**
* @internal
*/
_addBar(barControl, barContainer, isVertical, rotation) {
barControl.paddingLeft = 0;
barControl.width = "100%";
barControl.height = "100%";
barControl.barOffset = 0;
barControl.value = 0;
barControl.maximum = 1;
barControl.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
barControl.verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
barControl.isVertical = isVertical;
barControl.rotation = rotation;
barControl.isVisible = false;
barContainer.addControl(barControl);
barControl.onValueChangedObservable.add(() => {
this._setWindowPosition();
});
}
/** @internal */
_attachWheel() {
if (!this._host || this._onWheelObserver) {
return;
}
this._onWheelObserver = this.onWheelObservable.add((pi) => {
if (!this._pointerIsOver || this.isReadOnly) {
return;
}
if (this._verticalBar.isVisible == true) {
if (pi.y < 0 && this._verticalBar.value > 0) {
this._verticalBar.value -= this._wheelPrecision;
}
else if (pi.y > 0 && this._verticalBar.value < this._verticalBar.maximum) {
this._verticalBar.value += this._wheelPrecision;
}
}
if (this._horizontalBar.isVisible == true) {
if (pi.x < 0 && this._horizontalBar.value < this._horizontalBar.maximum) {
this._horizontalBar.value += this._wheelPrecision;
}
else if (pi.x > 0 && this._horizontalBar.value > 0) {
this._horizontalBar.value -= this._wheelPrecision;
}
}
});
}
_renderHighlightSpecific(context) {
if (!this.isHighlighted) {
return;
}
super._renderHighlightSpecific(context);
this._grid._renderHighlightSpecific(context);
context.restore();
}
/** Releases associated resources */
dispose() {
this.onWheelObservable.remove(this._onWheelObserver);
this._onWheelObserver = null;
super.dispose();
}
}
__decorate([
serialize()
], ScrollViewer.prototype, "wheelPrecision", null);
__decorate([
serialize()
], ScrollViewer.prototype, "scrollBackground", null);
__decorate([
serialize()
], ScrollViewer.prototype, "barColor", null);
__decorate([
serialize()
], ScrollViewer.prototype, "barSize", null);
__decorate([
serialize()
], ScrollViewer.prototype, "barBackground", null);
RegisterClass("BABYLON.GUI.ScrollViewer", ScrollViewer);
//# sourceMappingURL=scrollViewer.js.map