123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- import { Measure } from "../measure";
- import { Rectangle } from "./rectangle";
- import { Grid } from "./grid";
- import { Control } from "./control";
- import { Slider } from "./slider";
- import { ValueAndUnit } from "../valueAndUnit";
- import { Container } from "./container";
- import { TextBlock } from "./textBlock";
- import { PointerInfo, Observer, Nullable } from "babylonjs";
- /**
- * Class used to hold a viewer window and sliders in a grid
- */
- export class ScrollViewer extends Rectangle {
- private _grid: Grid;
- private _horizontalBarSpace: Rectangle;
- private _verticalBarSpace: Rectangle;
- private _dragSpace: Rectangle;
- private _horizontalBar: Slider;
- private _verticalBar: Slider;
- private _barColor: string = "grey";
- private _barBorderColor: string = "#444444";
- private _barBackground: string = "white";
- private _scrollGridWidth: number = 30;
- private _scrollGridHeight: number = 30;
- private _widthScale: number;
- private _heightScale: number;
- private _endLeft: number;
- private _endTop: number;
- private _window: Container;
- private _windowContents: Control;
- private _pointerIsOver: Boolean = false;
- private _wheelPrecision: number = 0.05;
- private _onPointerObserver: Nullable<Observer<PointerInfo>>;
- /**
- * Adds windowContents to the grid view window
- * @param windowContents the contents to add the grid view window
- */
- public addToWindow(windowContents: Control): void {
- this._window.removeControl(this._windowContents);
- this._windowContents.dispose();
- this._windowContents = windowContents;
- if (windowContents.typeName === "TextBlock") {
- this._updateTextBlock(windowContents);
- }
- else {
- this._updateScroller(windowContents);
- }
- this._window.addControl(windowContents);
- }
- /**
- * Gets or sets a value indicating the padding to use on the left of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingLeft(): string | number {
- return this._windowContents.paddingLeft;
- }
- /**
- * Gets a value indicating the padding in pixels to use on the left of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingLeftInPixels(): number {
- return this._windowContents.paddingLeftInPixels;
- }
- public set paddingLeft(value: string | number) {
- this._windowContents.paddingLeft = value;
- }
- /**
- * Gets or sets a value indicating the padding to use on the right of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingRight(): string | number {
- return this._windowContents.paddingRight;
- }
- /**
- * Gets a value indicating the padding in pixels to use on the right of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingRightInPixels(): number {
- return this._windowContents.paddingRightInPixels;
- }
- public set paddingRight(value: string | number) {
- this._windowContents.paddingRight = value;
- }
- /**
- * Gets or sets a value indicating the padding to use on the top of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingTop(): string | number {
- return this._windowContents.paddingTop;
- }
- /**
- * Gets a value indicating the padding in pixels to use on the top of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingTopInPixels(): number {
- return this._windowContents.paddingTopInPixels;
- }
- public set paddingTop(value: string | number) {
- this._windowContents.paddingTop = value;
- }
- /**
- * Gets or sets a value indicating the padding to use on the bottom of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingBottom(): string | number {
- return this._windowContents.paddingBottom;
- }
- /**
- * Gets a value indicating the padding in pixels to use on the bottom of the viewer window
- * @see http://doc.babylonjs.com/how_to/gui#position-and-size
- */
- public get paddingBottomInPixels(): number {
- return this._windowContents.paddingBottomInPixels;
- }
- public set paddingBottom(value: string | number) {
- this._windowContents.paddingBottom = value;
- }
- /**
- * Creates a new ScrollViewer
- * @param name of ScrollViewer
- */
- constructor(
- /** name of ScrollViewer */
- public name?: string) {
- super(name);
- this.onDirtyObservable.add(() => {
- this._horizontalBarSpace.color = this.color;
- this._verticalBarSpace.color = this.color;
- this._dragSpace.color = this.color;
- this._updateScroller(this._windowContents);
- if (this._windowContents.typeName === "TextBlock") {
- this._updateTextBlock(this._windowContents);
- }
- });
- this.onPointerEnterObservable.add(() => {
- this._pointerIsOver = true;
- });
- this.onPointerOutObservable.add(() => {
- this._pointerIsOver = false;
- });
- this._grid = new Grid();
- this._horizontalBar = new Slider();
- this._verticalBar = new Slider();
- this._window = new Container();
- this._window.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
- this._window.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
- this._windowContents = new Control();
- this._window.addControl(this._windowContents);
- this._width = new ValueAndUnit(0.25, ValueAndUnit.UNITMODE_PERCENTAGE, false);
- this._height = new ValueAndUnit(0.25, ValueAndUnit.UNITMODE_PERCENTAGE, false);
- this._background = "black";
- this.fontSize = "16px";
- this._grid.addColumnDefinition(1, true);
- this._grid.addColumnDefinition(this._scrollGridWidth, true);
- this._grid.addRowDefinition(1, true);
- this._grid.addRowDefinition(this._scrollGridHeight, true);
- this.addControl(this._grid);
- this._grid.addControl(this._window, 0, 0);
- this._verticalBar.paddingLeft = 0;
- this._verticalBar.width = "25px";
- this._verticalBar.value = 0;
- this._verticalBar.maximum = 100;
- this._verticalBar.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
- this._verticalBar.verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
- this._verticalBar.left = 0.05;
- this._verticalBar.isThumbClamped = true;
- this._verticalBar.color = "grey";
- this._verticalBar.borderColor = "#444444";
- this._verticalBar.background = "white";
- this._verticalBar.isVertical = true;
- this._verticalBar.rotation = Math.PI;
- this._verticalBarSpace = new Rectangle();
- this._verticalBarSpace.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
- this._verticalBarSpace.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
- this._verticalBarSpace.color = this.color;
- this._verticalBarSpace.thickness = 1;
- this._grid.addControl(this._verticalBarSpace, 0, 1);
- this._verticalBarSpace.addControl(this._verticalBar);
- this._verticalBar.onValueChangedObservable.add((value) => {
- this._window.top = value * this._endTop / 100 + "px";
- });
- this._horizontalBar.paddingLeft = 0;
- this._horizontalBar.height = "25px";
- this._horizontalBar.value = 0;
- this._horizontalBar.maximum = 100;
- this._horizontalBar.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
- this._horizontalBar.verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
- this._horizontalBar.left = 0.05;
- this._horizontalBar.isThumbClamped = true;
- this._horizontalBar.color = "grey";
- this._horizontalBar.borderColor = "#444444";
- this._horizontalBar.background = "white";
- this._horizontalBarSpace = new Rectangle();
- this._horizontalBarSpace.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
- this._horizontalBarSpace.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
- this._horizontalBarSpace.color = this.color;
- this._horizontalBarSpace.thickness = 1;
- this._grid.addControl(this._horizontalBarSpace, 1, 0);
- this._horizontalBarSpace.addControl(this._horizontalBar);
- this._horizontalBar.onValueChangedObservable.add((value) => {
- this._window.left = value * this._endLeft / 100 + "px";
- });
- this._dragSpace = new Rectangle();
- this._dragSpace.color = this.color;
- this._dragSpace.thickness = 2;
- this._dragSpace.background = this._barColor;
- this._grid.addControl(this._dragSpace, 1, 1);
- }
- /**
- * Gets or sets the mouse wheel precision
- * from 0 to 1 with a default value of 0.05
- * */
- public get wheelPrecision(): number {
- return this._wheelPrecision;
- }
- public set wheelPrecision(value: number) {
- if (this._wheelPrecision === value) {
- return;
- }
- if (value < 0) {
- value = 0;
- }
- if (value > 1) {
- value = 1;
- }
- this._wheelPrecision = value;
- }
- /** Gets or sets the bar color */
- public get barColor(): string {
- return this._barColor;
- }
- public set barColor(color: string) {
- if (this._barColor === color) {
- return;
- }
- this._barColor = color;
- this._horizontalBar.color = color;
- this._verticalBar.color = color;
- this._dragSpace.background = color;
- }
- /** Gets or sets the bar color */
- public get barBorderColor(): string {
- return this._barBorderColor;
- }
- public set barBorderColor(color: string) {
- if (this._barBorderColor === color) {
- return;
- }
- this._barBorderColor = color;
- this._horizontalBar.borderColor = color;
- this._verticalBar.borderColor = color;
- }
- /** Gets or sets the bar background */
- public get barBackground(): string {
- return this._barBackground;
- }
- public set barBackground(color: string) {
- if (this._barBackground === color) {
- return;
- }
- this._barBackground = color;
- this._horizontalBar.background = color;
- this._verticalBar.background = color;
- }
- /** @hidden */
- protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
- super._additionalProcessing(parentMeasure, context);
- let viewerWidth = this._width.getValueInPixel(this._host, parentMeasure.width);
- let viewerHeight = this._height.getValueInPixel(this._host, parentMeasure.height);
- let innerWidth = viewerWidth - this._scrollGridWidth - 2 * this.thickness;
- let innerHeight = viewerHeight - this._scrollGridHeight - 2 * this.thickness;
- this._horizontalBar.width = (innerWidth * 0.8) + "px";
- this._verticalBar.height = (innerHeight * 0.8) + "px";
- this._grid.setColumnDefinition(0, innerWidth, true);
- this._grid.setRowDefinition(0, innerHeight, true);
- this._attachWheel();
- }
- /** @hidden */
- private _updateScroller(windowContents: Control): void {
- let windowContentsWidth: number = parseFloat(windowContents.width.toString());
- if (windowContents._width.unit === 0) {
- this._widthScale = windowContentsWidth / 100;
- windowContentsWidth = this._host.getSize().width * this._widthScale;
- windowContents.width = windowContentsWidth + "px";
- }
- let windowContentsHeight: number = parseFloat(windowContents.height.toString());
- if (windowContents._height.unit === 0) {
- this._heightScale = windowContentsHeight / 100;
- windowContentsHeight = this._host.getSize().height * this._heightScale;
- windowContents.height = this._host.getSize().height * this._heightScale + "px";
- }
- this._window.width = windowContents.width;
- this._window.height = windowContents.height;
- this._windowContents.width = windowContents.width;
- this._windowContents.height = windowContents.height;
- let viewerWidth = this._width.getValueInPixel(this._host, this._host.getSize().width);
- let viewerHeight = this._height.getValueInPixel(this._host, this._host.getSize().height);
- let innerWidth = viewerWidth - this._scrollGridWidth - 2 * this.thickness;
- let innerHeight = viewerHeight - this._scrollGridHeight - 2 * this.thickness;
- if (windowContentsWidth <= innerWidth) {
- this._grid.setRowDefinition(0, viewerHeight - 2 * this.thickness , true);
- this._grid.setRowDefinition(1, 0, true);
- this._horizontalBar.isVisible = false;
- }
- else {
- this._grid.setRowDefinition(0, innerHeight, true);
- this._grid.setRowDefinition(1, this._scrollGridHeight, true);
- this._horizontalBar.isVisible = true;
- }
- if (windowContentsHeight < innerHeight) {
- this._grid.setColumnDefinition(0, viewerWidth - 2 * this.thickness, true);
- this._grid.setColumnDefinition(1, 0, true);
- this._verticalBar.isVisible = false;
- }
- else {
- this._grid.setColumnDefinition(0, innerWidth, true);
- this._grid.setColumnDefinition(1, this._scrollGridWidth, true);
- this._verticalBar.isVisible = true;
- }
- this._endLeft = innerWidth - windowContentsWidth;
- this._endTop = innerHeight - windowContentsHeight;
- }
- /** @hidden */
- private _updateTextBlock(windowContents: Control): void {
- let viewerWidth = this._width.getValueInPixel(this._host, this._host.getSize().width);
- let innerWidth = viewerWidth - this._scrollGridWidth - 2 * this.thickness;
- windowContents.width = innerWidth + "px";
- this._window.width = windowContents.width;
- this._windowContents.width = windowContents.width;
- (<TextBlock>windowContents).onLinesReadyObservable.add(() => {
- let windowContentsHeight = (this.fontOffset.height) * (<TextBlock>windowContents).lines.length + windowContents.paddingTopInPixels + windowContents.paddingBottomInPixels;
- windowContents.height = windowContentsHeight + "px";
- this._window.height = windowContents.height;
- this._windowContents.height = windowContents.height;
- this._updateScroller(windowContents);
- });
- }
- /** @hidden */
- private _attachWheel() {
- let scene = this._host.getScene();
- this._onPointerObserver = scene!.onPointerObservable.add((pi, state) => {
- if (!this._pointerIsOver || pi.type !== BABYLON.PointerEventTypes.POINTERWHEEL) {
- return;
- }
- if (this._verticalBar.isVisible == true) {
- if ((<MouseWheelEvent>pi.event).deltaY < 0 && this._verticalBar.value > 0) {
- this._verticalBar.value -= this._wheelPrecision * 100;
- } else if ((<MouseWheelEvent>pi.event).deltaY > 0 && this._verticalBar.value < this._verticalBar.maximum) {
- this._verticalBar.value += this._wheelPrecision * 100;
- }
- }
- if (this._horizontalBar.isVisible == true) {
- if ((<MouseWheelEvent>pi.event).deltaX < 0 && this._horizontalBar.value < this._horizontalBar.maximum) {
- this._horizontalBar.value += this._wheelPrecision * 100;
- } else if ((<MouseWheelEvent>pi.event).deltaX > 0 && this._horizontalBar.value > 0) {
- this._horizontalBar.value -= this._wheelPrecision * 100;
- }
- }
- });
- }
- /** Releases associated resources */
- public dispose() {
- let scene = this._host.getScene();
- if (scene && this._onPointerObserver) {
- scene.onPointerObservable.remove(this._onPointerObserver);
- }
- super.dispose();
- }
- }
|