123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- /// <reference path="../../../dist/preview release/babylon.d.ts"/>
- module BABYLON.GUI {
- export class Control {
- private _zIndex = 0;
- public _root: Container;
- public _host: AdvancedDynamicTexture;
- public _currentMeasure = Measure.Empty();
- private _fontFamily: string;
- private _fontSize = 18;
- private _font: string;
- private _width = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
- private _height = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
- private _lastMeasuredFont: string;
- protected _fontOffset: {ascent: number, height: number, descent: number};
- private _color: string;
- private _horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
- private _verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
- private _isDirty = true;
- private _cachedParentMeasure = Measure.Empty();
- private _marginLeft = new ValueAndUnit(0);
- private _marginRight = new ValueAndUnit(0);
- private _marginTop = new ValueAndUnit(0);
- private _marginBottom = new ValueAndUnit(0);
- private _left = new ValueAndUnit(0);
- private _top = new ValueAndUnit(0);
-
- // Properties
- /**
- * An event triggered when the pointer move over the control.
- * @type {BABYLON.Observable}
- */
- public onPointerMoveObservable = new Observable<Control>();
- /**
- * An event triggered when the pointer move out of the control.
- * @type {BABYLON.Observable}
- */
- public onPointerOutObservable = new Observable<Control>();
- /**
- * An event triggered when the pointer taps the control
- * @type {BABYLON.Observable}
- */
- public onPointerDownObservable = new Observable<Control>();
- /**
- * An event triggered when pointer up
- * @type {BABYLON.Observable}
- */
- public onPointerUpObservable = new Observable<Control>();
- public get horizontalAlignment(): number {
- return this._horizontalAlignment;
- }
- public set horizontalAlignment(value: number) {
- if (this._horizontalAlignment === value) {
- return;
- }
- this._horizontalAlignment = value;
- this._markAsDirty();
- }
- public get verticalAlignment(): number {
- return this._verticalAlignment;
- }
- public set verticalAlignment(value: number) {
- if (this._verticalAlignment === value) {
- return;
- }
- this._verticalAlignment = value;
- this._markAsDirty();
- }
- public get width(): string {
- return this._width.toString();
- }
- public set width(value: string) {
- if (this._width.toString() === value) {
- return;
- }
- if (this._width.fromString(value)) {
- this._markAsDirty();
- }
- }
- public get height(): string {
- return this._height.toString();
- }
- public set height(value: string) {
- if (this._height.toString() === value) {
- return;
- }
- if (this._height.fromString(value)) {
- this._markAsDirty();
- }
- }
- public get fontFamily(): string {
- return this._fontFamily;
- }
- public set fontFamily(value: string) {
- if (this._fontFamily === value) {
- return;
- }
- this._fontFamily = value;
- this._prepareFont();
- }
- public get fontSize(): number {
- return this._fontSize;
- }
- public set fontSize(value: number) {
- if (this._fontSize === value) {
- return;
- }
- this._fontSize = value;
- this._prepareFont();
- }
- public get color(): string {
- return this._color;
- }
- public set color(value: string) {
- if (this._color === value) {
- return;
- }
- this._color = value;
- this._markAsDirty();
- }
- public get zIndex(): number {
- return this._zIndex;
- }
- public set zIndex(value: number) {
- if (this.zIndex === value) {
- return;
- }
- this._zIndex = value;
- this._root._reOrderControl(this);
- }
- public get isDirty(): boolean {
- return this._isDirty;
- }
-
- public get marginLeft(): string {
- return this._marginLeft.toString();
- }
- public set marginLeft(value: string) {
- if (this._marginLeft.fromString(value)) {
- this._markAsDirty();
- }
- }
- public get marginRight(): string {
- return this._marginRight.toString();
- }
- public set marginRight(value: string) {
- if (this._marginRight.fromString(value)) {
- this._markAsDirty();
- }
- }
- public get marginTop(): string {
- return this._marginTop.toString();
- }
- public set marginTop(value: string) {
- if (this._marginTop.fromString(value)) {
- this._markAsDirty();
- }
- }
- public get marginBottom(): string {
- return this._marginBottom.toString();
- }
- public set marginBottom(value: string) {
- if (this._marginBottom.fromString(value)) {
- this._markAsDirty();
- }
- }
- public get left(): string {
- return this._left.toString();
- }
- public set left(value: string) {
- if (this._left.fromString(value)) {
- this._markAsDirty();
- }
- }
- public get top(): string {
- return this._top.toString();
- }
- public set top(value: string) {
- if (this._top.fromString(value)) {
- this._markAsDirty();
- }
- }
- // Functions
- constructor(public name: string) {
- this.fontFamily = "Arial";
- }
- protected _markAsDirty(): void {
- this._isDirty = true;
- if (!this._host) {
- return; // Not yet connected
- }
- this._host.markAsDirty();
- }
- public _link(root: Container, host: AdvancedDynamicTexture): void {
- this._root = root;
- this._host = host;
- }
- protected applyStates(context: CanvasRenderingContext2D): void {
- if (this._font) {
- context.font = this._font;
- }
- if (this._color) {
- context.fillStyle = this._color;
- }
- }
- protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D) {
- if (this._isDirty || !this._cachedParentMeasure.isEqualsTo(parentMeasure)) {
- this._currentMeasure.copyFrom(parentMeasure);
- this._measure(parentMeasure, context);
- this._computeAlignment(parentMeasure, context);
- // Convert to int values
- this._currentMeasure.left = this._currentMeasure.left | 0;
- this._currentMeasure.top = this._currentMeasure.top | 0;
- this._currentMeasure.width = this._currentMeasure.width | 0;
- this._currentMeasure.height = this._currentMeasure.height | 0;
- // Let children add more features
- this._additionalProcessing(parentMeasure, context);
- this._isDirty = false;
- this._cachedParentMeasure.copyFrom(parentMeasure);
- }
-
- // Clip
- this._clip(context);
- context.clip();
- }
- protected _clip( context: CanvasRenderingContext2D) {
- context.beginPath();
- context.rect(this._currentMeasure.left ,this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
- }
- protected _measure(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
- // Width / Height
- if (this._width.isPixel) {
- this._currentMeasure.width = this._width.value;
- } else {
- this._currentMeasure.width *= this._width.value;
- }
- if (this._height.isPixel) {
- this._currentMeasure.height = this._height.value;
- } else {
- this._currentMeasure.height *= this._height.value;
- }
- }
- protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
- var width = this._currentMeasure.width;
- var height = this._currentMeasure.height;
- var parentWidth = parentMeasure.width;
- var parentHeight = parentMeasure.height;
- // Left / top
- var x = 0;
- var y = 0;
- switch (this.horizontalAlignment) {
- case Control.HORIZONTAL_ALIGNMENT_LEFT:
- x = 0
- break;
- case Control.HORIZONTAL_ALIGNMENT_RIGHT:
- x = parentWidth - width;
- break;
- case Control.HORIZONTAL_ALIGNMENT_CENTER:
- x = (parentWidth - width) / 2;
- break;
- }
- switch (this.verticalAlignment) {
- case Control.VERTICAL_ALIGNMENT_TOP:
- y = 0;
- break;
- case Control.VERTICAL_ALIGNMENT_BOTTOM:
- y = parentHeight - height;
- break;
- case Control.VERTICAL_ALIGNMENT_CENTER:
- y = (parentHeight - height) / 2;
- break;
- }
-
- if (this._marginLeft.isPixel) {
- this._currentMeasure.left += this._marginLeft.value;
- this._currentMeasure.width -= this._marginRight.value;
- } else {
- this._currentMeasure.left += parentWidth * this._marginLeft.value;
- this._currentMeasure.width -= parentWidth * this._marginLeft.value;
- }
- if (this._marginRight.isPixel) {
- this._currentMeasure.width -= this._marginRight.value;
- } else {
- this._currentMeasure.width -= parentWidth * this._marginRight.value;
- }
- if (this._marginTop.isPixel) {
- this._currentMeasure.top += this._marginTop.value;
- this._currentMeasure.height -= this._marginTop.value;
- } else {
- this._currentMeasure.top += parentHeight * this._marginTop.value;
- this._currentMeasure.height -= parentHeight * this._marginTop.value;
- }
- if (this._marginBottom.isPixel) {
- this._currentMeasure.height -= this._marginBottom.value;
- } else {
- this._currentMeasure.height -= parentHeight * this._marginBottom.value;
- }
- if (this._left.isPixel) {
- this._currentMeasure.left += this._left.value;
- } else {
- this._currentMeasure.left += parentWidth * this._left.value;
- }
- if (this._top.isPixel) {
- this._currentMeasure.top += this._top.value;
- } else {
- this._currentMeasure.top += parentHeight * this._top.value;
- }
- this._currentMeasure.left += x;
- this._currentMeasure.top += y;
- }
- protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
- // Do nothing
- }
- public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
- // Do nothing
- }
- protected _contains(x: number, y: number) : boolean {
- if (x < this._currentMeasure.left) {
- return false;
- }
- if (x > this._currentMeasure.left + this._currentMeasure.width) {
- return false;
- }
- if (y < this._currentMeasure.top) {
- return false;
- }
- if (y > this._currentMeasure.top + this._currentMeasure.height) {
- return false;
- }
- return true;
- }
- public _processPicking(x: number, y: number, type: number): boolean {
- if (!this._contains(x, y)) {
- return false;
- }
- this._processObservables(type);
- return true;
- }
- protected _processObservables(type: number): boolean {
- if (type === BABYLON.PointerEventTypes.POINTERMOVE && this.onPointerMoveObservable.hasObservers()) {
- this.onPointerMoveObservable.notifyObservers(this);
- var previousControlOver = this._host._lastControlOver;
- if (previousControlOver && previousControlOver !== this && previousControlOver.onPointerOutObservable.hasObservers()) {
- previousControlOver.onPointerOutObservable.notifyObservers(previousControlOver);
- }
- this._host._lastControlOver = this;
- return true;
- }
- if (type === BABYLON.PointerEventTypes.POINTERDOWN && this.onPointerDownObservable.hasObservers()) {
- this.onPointerDownObservable.notifyObservers(this);
- return true;
- }
- if (type === BABYLON.PointerEventTypes.POINTERUP && this.onPointerUpObservable.hasObservers()) {
- this.onPointerUpObservable.notifyObservers(this);
- return true;
- }
-
- return false;
- }
- private _prepareFont() {
- if (!this._fontFamily) {
- return;
- }
- this._font = this._fontSize + "px " + this._fontFamily;
-
- this._fontOffset = Control._GetFontOffset(this._font);
- this._markAsDirty();
- }
- // Statics
- private static _HORIZONTAL_ALIGNMENT_LEFT = 0;
- private static _HORIZONTAL_ALIGNMENT_RIGHT = 1;
- private static _HORIZONTAL_ALIGNMENT_CENTER = 2;
-
- private static _VERTICAL_ALIGNMENT_TOP = 0;
- private static _VERTICAL_ALIGNMENT_BOTTOM = 1;
- private static _VERTICAL_ALIGNMENT_CENTER = 2;
- public static get HORIZONTAL_ALIGNMENT_LEFT(): number {
- return Control._HORIZONTAL_ALIGNMENT_LEFT;
- }
- public static get HORIZONTAL_ALIGNMENT_RIGHT(): number {
- return Control._HORIZONTAL_ALIGNMENT_RIGHT;
- }
- public static get HORIZONTAL_ALIGNMENT_CENTER(): number {
- return Control._HORIZONTAL_ALIGNMENT_CENTER;
- }
- public static get VERTICAL_ALIGNMENT_TOP(): number {
- return Control._VERTICAL_ALIGNMENT_TOP;
- }
- public static get VERTICAL_ALIGNMENT_BOTTOM(): number {
- return Control._VERTICAL_ALIGNMENT_BOTTOM;
- }
- public static get VERTICAL_ALIGNMENT_CENTER(): number {
- return Control._VERTICAL_ALIGNMENT_CENTER;
- }
- private static _FontHeightSizes = {};
- public static _GetFontOffset(font: string): {ascent: number, height: number, descent: number} {
- if (Control._FontHeightSizes[font]) {
- return Control._FontHeightSizes[font];
- }
- var text = document.createElement("span");
- text.innerHTML = "Hg";
- text.style.font = font;
- var block = document.createElement("div");
- block.style.display = "inline-block";
- block.style.width = "1px";
- block.style.height = "0px";
- block.style.verticalAlign = "bottom";
- var div = document.createElement("div");
- div.appendChild(text);
- div.appendChild(block);
- document.body.appendChild(div);
- var fontAscent = 0;
- var fontHeight = 0;
- try {
- fontHeight = block.getBoundingClientRect().top - text.getBoundingClientRect().top;
- block.style.verticalAlign = "baseline";
- fontAscent = block.getBoundingClientRect().top - text.getBoundingClientRect().top;
- } finally {
- div.remove();
- }
- var result = { ascent: fontAscent, height: fontHeight, descent: fontHeight - fontAscent };
- Control._FontHeightSizes[font] = result;
- return result;
- };
- }
- }
|