|
@@ -1,7 +1,8 @@
|
|
/// <reference path="../../../dist/preview release/babylon.d.ts"/>
|
|
/// <reference path="../../../dist/preview release/babylon.d.ts"/>
|
|
|
|
|
|
module BABYLON.GUI {
|
|
module BABYLON.GUI {
|
|
- export class Control {
|
|
|
|
|
|
+ export class Control {
|
|
|
|
+ private _alpha = 1;
|
|
private _zIndex = 0;
|
|
private _zIndex = 0;
|
|
public _root: Container;
|
|
public _root: Container;
|
|
public _host: AdvancedDynamicTexture;
|
|
public _host: AdvancedDynamicTexture;
|
|
@@ -14,8 +15,8 @@ module BABYLON.GUI {
|
|
private _lastMeasuredFont: string;
|
|
private _lastMeasuredFont: string;
|
|
protected _fontOffset: {ascent: number, height: number, descent: number};
|
|
protected _fontOffset: {ascent: number, height: number, descent: number};
|
|
private _color: string;
|
|
private _color: string;
|
|
- private _horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
|
|
|
|
- private _verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
|
|
|
|
|
|
+ protected _horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
|
|
|
|
+ protected _verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
|
|
private _isDirty = true;
|
|
private _isDirty = true;
|
|
private _cachedParentMeasure = Measure.Empty();
|
|
private _cachedParentMeasure = Measure.Empty();
|
|
private _marginLeft = new ValueAndUnit(0);
|
|
private _marginLeft = new ValueAndUnit(0);
|
|
@@ -31,12 +32,17 @@ module BABYLON.GUI {
|
|
private _transformCenterY = 0.5;
|
|
private _transformCenterY = 0.5;
|
|
private _transformMatrix = Matrix2D.Identity();
|
|
private _transformMatrix = Matrix2D.Identity();
|
|
private _invertTransformMatrix = Matrix2D.Identity();
|
|
private _invertTransformMatrix = Matrix2D.Identity();
|
|
|
|
+ private _transformedPosition = Vector2.Zero();
|
|
private _isMatrixDirty = true;
|
|
private _isMatrixDirty = true;
|
|
private _cachedOffsetX: number;
|
|
private _cachedOffsetX: number;
|
|
private _cachedOffsetY: number;
|
|
private _cachedOffsetY: number;
|
|
|
|
+ public _linkedMesh: AbstractMesh;
|
|
|
|
|
|
public isHitTestVisible = true;
|
|
public isHitTestVisible = true;
|
|
public isPointerBlocker = false;
|
|
public isPointerBlocker = false;
|
|
|
|
+
|
|
|
|
+ public linkOffsetX = 0;
|
|
|
|
+ public linkOffsetY = 0;
|
|
|
|
|
|
// Properties
|
|
// Properties
|
|
|
|
|
|
@@ -68,7 +74,26 @@ module BABYLON.GUI {
|
|
* An event triggered when pointer enters the control
|
|
* An event triggered when pointer enters the control
|
|
* @type {BABYLON.Observable}
|
|
* @type {BABYLON.Observable}
|
|
*/
|
|
*/
|
|
- public onPointerEnterObservable = new Observable<Control>();
|
|
|
|
|
|
+ public onPointerEnterObservable = new Observable<Control>();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * An event triggered when the control is marked as dirty
|
|
|
|
+ * @type {BABYLON.Observable}
|
|
|
|
+ */
|
|
|
|
+ public onDirtyObservable = new Observable<Control>();
|
|
|
|
+
|
|
|
|
+ public get alpha(): number {
|
|
|
|
+ return this._alpha;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public set alpha(value: number) {
|
|
|
|
+ if (this._alpha === value) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._alpha = value;
|
|
|
|
+ this._markAsDirty();
|
|
|
|
+ }
|
|
|
|
|
|
public get scaleX(): number {
|
|
public get scaleX(): number {
|
|
return this._scaleX;
|
|
return this._scaleX;
|
|
@@ -81,7 +106,7 @@ module BABYLON.GUI {
|
|
|
|
|
|
this._scaleX = value;
|
|
this._scaleX = value;
|
|
this._markAsDirty();
|
|
this._markAsDirty();
|
|
- this._isMatrixDirty = true;
|
|
|
|
|
|
+ this._markMatrixAsDirty();
|
|
}
|
|
}
|
|
|
|
|
|
public get scaleY(): number {
|
|
public get scaleY(): number {
|
|
@@ -95,7 +120,7 @@ module BABYLON.GUI {
|
|
|
|
|
|
this._scaleY = value;
|
|
this._scaleY = value;
|
|
this._markAsDirty();
|
|
this._markAsDirty();
|
|
- this._isMatrixDirty = true;
|
|
|
|
|
|
+ this._markMatrixAsDirty();
|
|
}
|
|
}
|
|
|
|
|
|
public get rotation(): number {
|
|
public get rotation(): number {
|
|
@@ -109,7 +134,7 @@ module BABYLON.GUI {
|
|
|
|
|
|
this._rotation = value;
|
|
this._rotation = value;
|
|
this._markAsDirty();
|
|
this._markAsDirty();
|
|
- this._isMatrixDirty = true;
|
|
|
|
|
|
+ this._markMatrixAsDirty();
|
|
}
|
|
}
|
|
|
|
|
|
public get transformCenterY(): number {
|
|
public get transformCenterY(): number {
|
|
@@ -123,7 +148,7 @@ module BABYLON.GUI {
|
|
|
|
|
|
this._transformCenterY = value;
|
|
this._transformCenterY = value;
|
|
this._markAsDirty();
|
|
this._markAsDirty();
|
|
- this._isMatrixDirty = true;
|
|
|
|
|
|
+ this._markMatrixAsDirty();
|
|
}
|
|
}
|
|
|
|
|
|
public get transformCenterX(): number {
|
|
public get transformCenterX(): number {
|
|
@@ -137,7 +162,7 @@ module BABYLON.GUI {
|
|
|
|
|
|
this._transformCenterX = value;
|
|
this._transformCenterX = value;
|
|
this._markAsDirty();
|
|
this._markAsDirty();
|
|
- this._isMatrixDirty = true;
|
|
|
|
|
|
+ this._markMatrixAsDirty();
|
|
}
|
|
}
|
|
|
|
|
|
public get horizontalAlignment(): number {
|
|
public get horizontalAlignment(): number {
|
|
@@ -243,7 +268,10 @@ module BABYLON.GUI {
|
|
}
|
|
}
|
|
|
|
|
|
this._zIndex = value;
|
|
this._zIndex = value;
|
|
- this._root._reOrderControl(this);
|
|
|
|
|
|
+
|
|
|
|
+ if (this._root) {
|
|
|
|
+ this._root._reOrderControl(this);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
public get isDirty(): boolean {
|
|
public get isDirty(): boolean {
|
|
@@ -308,6 +336,14 @@ module BABYLON.GUI {
|
|
if (this._top.fromString(value)) {
|
|
if (this._top.fromString(value)) {
|
|
this._markAsDirty();
|
|
this._markAsDirty();
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public get centerX(): number {
|
|
|
|
+ return this._currentMeasure.left + this._currentMeasure.width / 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public get centerY(): number {
|
|
|
|
+ return this._currentMeasure.top + this._currentMeasure.height / 2;
|
|
}
|
|
}
|
|
|
|
|
|
// Functions
|
|
// Functions
|
|
@@ -315,6 +351,32 @@ module BABYLON.GUI {
|
|
this.fontFamily = "Arial";
|
|
this.fontFamily = "Arial";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public linkWithMesh(mesh: AbstractMesh): void {
|
|
|
|
+ if (!this._host || this._root !== this._host._rootContainer) {
|
|
|
|
+ Tools.Error("Cannot link a control to a mesh if the control is not at root level");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this._host._linkedControls.indexOf(this) !== -1) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ this.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
|
|
|
|
+ this.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
|
|
|
|
+ this._linkedMesh = mesh;
|
|
|
|
+ this._host._linkedControls.push(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public _moveToProjectedPosition(projectedPosition: Vector3): void {
|
|
|
|
+ this.left = ((projectedPosition.x + this.linkOffsetX) - this._currentMeasure.width / 2) + "px";
|
|
|
|
+ this.top = ((projectedPosition.y + this.linkOffsetY) - this._currentMeasure.height / 2) + "px";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public _markMatrixAsDirty(): void {
|
|
|
|
+ this._isMatrixDirty = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
protected _markAsDirty(): void {
|
|
protected _markAsDirty(): void {
|
|
this._isDirty = true;
|
|
this._isDirty = true;
|
|
|
|
|
|
@@ -330,7 +392,7 @@ module BABYLON.GUI {
|
|
}
|
|
}
|
|
|
|
|
|
protected _transform(context: CanvasRenderingContext2D): void {
|
|
protected _transform(context: CanvasRenderingContext2D): void {
|
|
- if (this._scaleX === 1 && this._scaleY ===1 && this._rotation === 0) {
|
|
|
|
|
|
+ if (!this._isMatrixDirty && this._scaleX === 1 && this._scaleY ===1 && this._rotation === 0) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -348,14 +410,13 @@ module BABYLON.GUI {
|
|
// postTranslate
|
|
// postTranslate
|
|
context.translate(-offsetX, -offsetY);
|
|
context.translate(-offsetX, -offsetY);
|
|
|
|
|
|
-
|
|
|
|
// Need to update matrices?
|
|
// Need to update matrices?
|
|
if (this._isMatrixDirty || this._cachedOffsetX !== offsetX || this._cachedOffsetY !== offsetY) {
|
|
if (this._isMatrixDirty || this._cachedOffsetX !== offsetX || this._cachedOffsetY !== offsetY) {
|
|
this._cachedOffsetX = offsetX;
|
|
this._cachedOffsetX = offsetX;
|
|
this._cachedOffsetY = offsetY;
|
|
this._cachedOffsetY = offsetY;
|
|
this._isMatrixDirty = false;
|
|
this._isMatrixDirty = false;
|
|
|
|
|
|
- Matrix2D.ComposeToRef(offsetX, offsetY, this._rotation, this._scaleX, this._scaleY, this._root ? this._root._transformMatrix : null, this._transformMatrix);
|
|
|
|
|
|
+ Matrix2D.ComposeToRef(-offsetX, -offsetY, this._rotation, this._scaleX, this._scaleY, this._root ? this._root._transformMatrix : null, this._transformMatrix);
|
|
|
|
|
|
this._transformMatrix.invertToRef(this._invertTransformMatrix);
|
|
this._transformMatrix.invertToRef(this._invertTransformMatrix);
|
|
}
|
|
}
|
|
@@ -369,13 +430,16 @@ module BABYLON.GUI {
|
|
if (this._color) {
|
|
if (this._color) {
|
|
context.fillStyle = this._color;
|
|
context.fillStyle = this._color;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ context.globalAlpha = this._alpha;
|
|
}
|
|
}
|
|
|
|
|
|
protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D) {
|
|
protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D) {
|
|
if (this._isDirty || !this._cachedParentMeasure.isEqualsTo(parentMeasure)) {
|
|
if (this._isDirty || !this._cachedParentMeasure.isEqualsTo(parentMeasure)) {
|
|
|
|
+ this._isDirty = false;
|
|
this._currentMeasure.copyFrom(parentMeasure);
|
|
this._currentMeasure.copyFrom(parentMeasure);
|
|
|
|
|
|
- this._measure(parentMeasure, context);
|
|
|
|
|
|
+ this._measure();
|
|
this._computeAlignment(parentMeasure, context);
|
|
this._computeAlignment(parentMeasure, context);
|
|
|
|
|
|
// Convert to int values
|
|
// Convert to int values
|
|
@@ -387,8 +451,11 @@ module BABYLON.GUI {
|
|
// Let children add more features
|
|
// Let children add more features
|
|
this._additionalProcessing(parentMeasure, context);
|
|
this._additionalProcessing(parentMeasure, context);
|
|
|
|
|
|
- this._isDirty = false;
|
|
|
|
this._cachedParentMeasure.copyFrom(parentMeasure);
|
|
this._cachedParentMeasure.copyFrom(parentMeasure);
|
|
|
|
+
|
|
|
|
+ if (this.onDirtyObservable.hasObservers()) {
|
|
|
|
+ this.onDirtyObservable.notifyObservers(this);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// Transform
|
|
// Transform
|
|
@@ -404,7 +471,7 @@ module BABYLON.GUI {
|
|
context.rect(this._currentMeasure.left ,this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
|
|
context.rect(this._currentMeasure.left ,this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
|
|
}
|
|
}
|
|
|
|
|
|
- protected _measure(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
|
|
|
|
|
|
+ public _measure(): void {
|
|
// Width / Height
|
|
// Width / Height
|
|
if (this._width.isPixel) {
|
|
if (this._width.isPixel) {
|
|
this._currentMeasure.width = this._width.value;
|
|
this._currentMeasure.width = this._width.value;
|
|
@@ -508,9 +575,10 @@ module BABYLON.GUI {
|
|
|
|
|
|
public contains(x: number, y: number) : boolean {
|
|
public contains(x: number, y: number) : boolean {
|
|
// Invert transform
|
|
// Invert transform
|
|
- if (this._scaleX !== 1 || this._scaleY !== 1 || this.rotation !== 0) {
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
|
|
|
|
+
|
|
|
|
+ x = this._transformedPosition.x;
|
|
|
|
+ y = this._transformedPosition.y;
|
|
|
|
|
|
// Check
|
|
// Check
|
|
if (x < this._currentMeasure.left) {
|
|
if (x < this._currentMeasure.left) {
|
|
@@ -536,6 +604,10 @@ module BABYLON.GUI {
|
|
}
|
|
}
|
|
|
|
|
|
public _processPicking(x: number, y: number, type: number): boolean {
|
|
public _processPicking(x: number, y: number, type: number): boolean {
|
|
|
|
+ if (!this.isHitTestVisible) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!this.contains(x, y)) {
|
|
if (!this.contains(x, y)) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -576,10 +648,6 @@ module BABYLON.GUI {
|
|
}
|
|
}
|
|
|
|
|
|
protected _processObservables(type: number): boolean {
|
|
protected _processObservables(type: number): boolean {
|
|
- if (!this.isHitTestVisible) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
|
|
if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
|
|
this._onPointerMove();
|
|
this._onPointerMove();
|
|
|
|
|
|
@@ -603,11 +671,10 @@ module BABYLON.GUI {
|
|
}
|
|
}
|
|
|
|
|
|
if (type === BABYLON.PointerEventTypes.POINTERUP) {
|
|
if (type === BABYLON.PointerEventTypes.POINTERUP) {
|
|
- this._onPointerUp();
|
|
|
|
- if (this._host._lastControlDown !== this) {
|
|
|
|
|
|
+ if (this._host._lastControlDown) {
|
|
this._host._lastControlDown._onPointerUp();
|
|
this._host._lastControlDown._onPointerUp();
|
|
- this._host._lastControlDown = null;
|
|
|
|
}
|
|
}
|
|
|
|
+ this._host._lastControlDown = null;
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|