Bläddra i källkod

Moving to modules - initial commit

Raanan Weber 7 år sedan
förälder
incheckning
56b22596f0
49 ändrade filer med 7757 tillägg och 7628 borttagningar
  1. 34 0
      gui/package.json
  2. 3 3
      gui/readme.md
  3. 587 589
      gui/src/2D/advancedDynamicTexture.ts
  4. 182 180
      gui/src/2D/controls/button.ts
  5. 118 118
      gui/src/2D/controls/checkbox.ts
  6. 354 356
      gui/src/2D/controls/colorpicker.ts
  7. 261 260
      gui/src/2D/controls/container.ts
  8. 1164 1158
      gui/src/2D/controls/control.ts
  9. 71 71
      gui/src/2D/controls/ellipse.ts
  10. 277 276
      gui/src/2D/controls/grid.ts
  11. 279 279
      gui/src/2D/controls/image.ts
  12. 12 0
      gui/src/2D/controls/index.ts
  13. 390 388
      gui/src/2D/controls/inputText.ts
  14. 216 215
      gui/src/2D/controls/line.ts
  15. 187 186
      gui/src/2D/controls/multiLine.ts
  16. 136 136
      gui/src/2D/controls/radioButton.ts
  17. 117 118
      gui/src/2D/controls/rectangle.ts
  18. 359 358
      gui/src/2D/controls/slider.ts
  19. 127 127
      gui/src/2D/controls/stackPanel.ts
  20. 278 277
      gui/src/2D/controls/textBlock.ts
  21. 199 196
      gui/src/2D/controls/virtualKeyboard.ts
  22. 8 0
      gui/src/2D/index.ts
  23. 184 186
      gui/src/2D/math2D.ts
  24. 57 60
      gui/src/2D/measure.ts
  25. 106 106
      gui/src/2D/multiLinePoint.ts
  26. 79 79
      gui/src/2D/style.ts
  27. 135 137
      gui/src/2D/valueAndUnit.ts
  28. 17 18
      gui/src/3D/controls/abstractButton3D.ts
  29. 135 134
      gui/src/3D/controls/button3D.ts
  30. 113 114
      gui/src/3D/controls/container3D.ts
  31. 346 345
      gui/src/3D/controls/control3D.ts
  32. 48 48
      gui/src/3D/controls/cylinderPanel.ts
  33. 210 206
      gui/src/3D/controls/holographicButton.ts
  34. 12 0
      gui/src/3D/controls/index.ts
  35. 50 51
      gui/src/3D/controls/meshButton3D.ts
  36. 24 23
      gui/src/3D/controls/planePanel.ts
  37. 91 95
      gui/src/3D/controls/scatterPanel.ts
  38. 49 49
      gui/src/3D/controls/spherePanel.ts
  39. 87 88
      gui/src/3D/controls/stackPanel3D.ts
  40. 150 156
      gui/src/3D/controls/volumeBasedPanel.ts
  41. 180 181
      gui/src/3D/gui3DManager.ts
  42. 5 0
      gui/src/3D/index.ts
  43. 232 235
      gui/src/3D/materials/fluentMaterial.ts
  44. 1 0
      gui/src/3D/materials/index.ts
  45. 12 14
      gui/src/3D/vector3WithInfo.ts
  46. 2 0
      gui/src/index.ts
  47. 0 12
      gui/src/tsconfig.json
  48. 31 0
      gui/tsconfig.json
  49. 42 0
      gui/webpack.config.js

+ 34 - 0
gui/package.json

@@ -0,0 +1,34 @@
+{
+    "name": "babylonjs-gui",
+    "version": "1.0.0",
+    "description": "The js GUI library is an extension you can use to generate interactive user interface.\r It is build on top of the DynamicTexture.",
+    "scripts": {
+        "start:server": "webpack-dev-server",
+        "build": "webpack",
+        "test": "echo \"Error: no test specified\" && exit 1"
+    },
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/BabylonJS/Babylon.js.git"
+    },
+    "keywords": [
+        "3d",
+        "webgl",
+        "viewer"
+    ],
+    "license": "Apache2",
+    "bugs": {
+        "url": "https://github.com/BabylonJS/Babylon.js/issues"
+    },
+    "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
+    "devDependencies": {
+        "ts-loader": "^4.0.0",
+        "typescript": "^2.9.2",
+        "webpack": "^4.15.1",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
+    },
+    "peerDependencies": {
+        "babylonjs": ">3.2.0"
+    }
+}

+ 3 - 3
gui/readme.md

@@ -1,6 +1,6 @@
-# Babylon.js GUI library
-The Babylon.js GUI library is an extension you can use to generate interactive user interface.
+# js GUI library
+The js GUI library is an extension you can use to generate interactive user interface.
 It is build on top of the DynamicTexture.
 
 Documentation: http://doc.babylonjs.com/how_to/gui
-API: http://doc.babylonjs.com/api/modules/babylon.gui
+API: http://doc.babylonjs.com/api/modules/gui

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 587 - 589
gui/src/2D/advancedDynamicTexture.ts


+ 182 - 180
gui/src/2D/controls/button.ts

@@ -1,207 +1,209 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Rectangle } from "./rectangle";
+import { Control } from "./control";
+import { TextBlock } from "./textBlock";
+import { Image } from "./image";
+import { Vector2 } from "babylonjs";
+
+/**
+ * Class used to create 2D buttons
+ */
+export class Button extends Rectangle {
+    /**
+     * Function called to generate a pointer enter animation
+     */
+    public pointerEnterAnimation: () => void;
+    /**
+     * Function called to generate a pointer out animation
+     */
+    public pointerOutAnimation: () => void;
+    /**
+     * Function called to generate a pointer down animation
+     */
+    public pointerDownAnimation: () => void;
+    /**
+     * Function called to generate a pointer up animation
+     */
+    public pointerUpAnimation: () => void;
 
-module BABYLON.GUI {
     /**
-     * Class used to create 2D buttons
+     * Creates a new Button
+     * @param name defines the name of the button
      */
-    export class Button extends Rectangle {    
-        /**
-         * Function called to generate a pointer enter animation
-         */
-        public pointerEnterAnimation: () => void;
-        /**
-         * Function called to generate a pointer out animation
-         */        
-        public pointerOutAnimation: () => void;
-        /**
-         * Function called to generate a pointer down animation
-         */        
-        public pointerDownAnimation: () => void;
-        /**
-         * Function called to generate a pointer up animation
-         */        
-        public pointerUpAnimation: () => void;
-
-        /**
-         * Creates a new Button
-         * @param name defines the name of the button
-         */
-        constructor(public name?: string) {
-            super(name);
-          
-            this.thickness = 1;
-            this.isPointerBlocker = true;
-
-            this.pointerEnterAnimation = () => {
-                this.alpha -= 0.1;
-            }
-
-            this.pointerOutAnimation = () => {
-                this.alpha += 0.1;
-            }    
-
-            this.pointerDownAnimation = () => {
-                this.scaleX -= 0.05;
-                this.scaleY -= 0.05;
-            }
-
-            this.pointerUpAnimation = () => {
-                this.scaleX += 0.05;
-                this.scaleY += 0.05;
-            }                      
+    constructor(public name?: string) {
+        super(name);
+
+        this.thickness = 1;
+        this.isPointerBlocker = true;
+
+        this.pointerEnterAnimation = () => {
+            this.alpha -= 0.1;
         }
 
-        protected _getTypeName(): string {
-            return "Button";
+        this.pointerOutAnimation = () => {
+            this.alpha += 0.1;
         }
 
-        // While being a container, the button behaves like a control.
-        /** @hidden */
-        public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
-            if (!this.isHitTestVisible || !this.isVisible || this.notRenderable) {
-                return false;
-            }
+        this.pointerDownAnimation = () => {
+            this.scaleX -= 0.05;
+            this.scaleY -= 0.05;
+        }
 
-            if (!super.contains(x, y)) {
-                return false;
-            }
+        this.pointerUpAnimation = () => {
+            this.scaleX += 0.05;
+            this.scaleY += 0.05;
+        }
+    }
 
-            this._processObservables(type, x, y, pointerId, buttonIndex);
+    protected _getTypeName(): string {
+        return "Button";
+    }
 
-            return true;
+    // While being a container, the button behaves like a control.
+    /** @hidden */
+    public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
+        if (!this.isHitTestVisible || !this.isVisible || this.notRenderable) {
+            return false;
         }
 
-        /** @hidden */
-        public _onPointerEnter(target: Control): boolean {
-            if (!super._onPointerEnter(target)) {
-                return false;
-            }
+        if (!super.contains(x, y)) {
+            return false;
+        }
 
-            if (this.pointerEnterAnimation) {
-                this.pointerEnterAnimation();
-            }
+        this._processObservables(type, x, y, pointerId, buttonIndex);
 
-            return true;
-        }
+        return true;
+    }
 
-        /** @hidden */
-        public _onPointerOut(target: Control): void {
-            if (this.pointerOutAnimation) {
-                this.pointerOutAnimation();
-            }
+    /** @hidden */
+    public _onPointerEnter(target: Control): boolean {
+        if (!super._onPointerEnter(target)) {
+            return false;
+        }
 
-            super._onPointerOut(target);
+        if (this.pointerEnterAnimation) {
+            this.pointerEnterAnimation();
         }
 
-        /** @hidden */
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
+        return true;
+    }
 
+    /** @hidden */
+    public _onPointerOut(target: Control): void {
+        if (this.pointerOutAnimation) {
+            this.pointerOutAnimation();
+        }
 
-            if (this.pointerDownAnimation) {
-                this.pointerDownAnimation();
-            }
+        super._onPointerOut(target);
+    }
 
-            return true;
+    /** @hidden */
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
         }
 
-        /** @hidden */
-        public _onPointerUp(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            if (this.pointerUpAnimation) {
-                this.pointerUpAnimation();
-            }
-
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
-        }        
-
-        // Statics
-        /**
-         * Creates a new button made with an image and a text
-         * @param name defines the name of the button
-         * @param text defines the text of the button
-         * @param imageUrl defines the url of the image
-         * @returns a new Button
-         */
-        public static CreateImageButton(name: string, text: string, imageUrl: string): Button {
-            var result = new Button(name);
-
-            // Adding text
-            var textBlock = new BABYLON.GUI.TextBlock(name + "_button", text);
-            textBlock.textWrapping = true;
-            textBlock.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
-            textBlock.paddingLeft = "20%";
-            result.addControl(textBlock);   
-
-            // Adding image
-            var iconImage = new BABYLON.GUI.Image(name + "_icon", imageUrl);
-            iconImage.width = "20%";
-            iconImage.stretch = BABYLON.GUI.Image.STRETCH_UNIFORM;
-            iconImage.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
-            result.addControl(iconImage);            
-
-            return result;
-        }
 
-        /**
-         * Creates a new button made with an image
-         * @param name defines the name of the button
-         * @param imageUrl defines the url of the image
-         * @returns a new Button
-         */
-        public static CreateImageOnlyButton(name: string, imageUrl: string): Button {
-            var result = new Button(name);
-
-            // Adding image
-            var iconImage = new BABYLON.GUI.Image(name + "_icon", imageUrl);
-            iconImage.stretch = BABYLON.GUI.Image.STRETCH_FILL;
-            iconImage.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
-            result.addControl(iconImage);            
-
-            return result;
+        if (this.pointerDownAnimation) {
+            this.pointerDownAnimation();
         }
 
-        /**
-         * Creates a new button made with a text
-         * @param name defines the name of the button
-         * @param text defines the text of the button
-         * @returns a new Button
-         */        
-        public static CreateSimpleButton(name: string, text: string): Button {
-            var result = new Button(name);
-
-            // Adding text
-            var textBlock = new BABYLON.GUI.TextBlock(name + "_button", text);
-            textBlock.textWrapping = true;
-            textBlock.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
-            result.addControl(textBlock);           
-
-            return result;
-        }
-        
-        /**
-         * Creates a new button made with an image and a centered text
-         * @param name defines the name of the button
-         * @param text defines the text of the button
-         * @param imageUrl defines the url of the image
-         * @returns a new Button
-         */        
-        public static CreateImageWithCenterTextButton(name: string, text: string, imageUrl: string): Button {
-            var result = new Button(name);
-
-            // Adding image
-            var iconImage = new BABYLON.GUI.Image(name + "_icon", imageUrl);
-            iconImage.stretch = BABYLON.GUI.Image.STRETCH_FILL;
-            result.addControl(iconImage);         
-            
-            // Adding text
-            var textBlock = new BABYLON.GUI.TextBlock(name + "_button", text);
-            textBlock.textWrapping = true;
-            textBlock.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
-            result.addControl(textBlock);   
-
-            return result;
+        return true;
+    }
+
+    /** @hidden */
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        if (this.pointerUpAnimation) {
+            this.pointerUpAnimation();
         }
-    }    
-}
+
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
+
+    // Statics
+    /**
+     * Creates a new button made with an image and a text
+     * @param name defines the name of the button
+     * @param text defines the text of the button
+     * @param imageUrl defines the url of the image
+     * @returns a new Button
+     */
+    public static CreateImageButton(name: string, text: string, imageUrl: string): Button {
+        var result = new Button(name);
+
+        // Adding text
+        var textBlock = new TextBlock(name + "_button", text);
+        textBlock.textWrapping = true;
+        textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+        textBlock.paddingLeft = "20%";
+        result.addControl(textBlock);
+
+        // Adding image
+        var iconImage = new Image(name + "_icon", imageUrl);
+        iconImage.width = "20%";
+        iconImage.stretch = Image.STRETCH_UNIFORM;
+        iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        result.addControl(iconImage);
+
+        return result;
+    }
+
+    /**
+     * Creates a new button made with an image
+     * @param name defines the name of the button
+     * @param imageUrl defines the url of the image
+     * @returns a new Button
+     */
+    public static CreateImageOnlyButton(name: string, imageUrl: string): Button {
+        var result = new Button(name);
+
+        // Adding image
+        var iconImage = new Image(name + "_icon", imageUrl);
+        iconImage.stretch = Image.STRETCH_FILL;
+        iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        result.addControl(iconImage);
+
+        return result;
+    }
+
+    /**
+     * Creates a new button made with a text
+     * @param name defines the name of the button
+     * @param text defines the text of the button
+     * @returns a new Button
+     */
+    public static CreateSimpleButton(name: string, text: string): Button {
+        var result = new Button(name);
+
+        // Adding text
+        var textBlock = new TextBlock(name + "_button", text);
+        textBlock.textWrapping = true;
+        textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+        result.addControl(textBlock);
+
+        return result;
+    }
+
+    /**
+     * Creates a new button made with an image and a centered text
+     * @param name defines the name of the button
+     * @param text defines the text of the button
+     * @param imageUrl defines the url of the image
+     * @returns a new Button
+     */
+    public static CreateImageWithCenterTextButton(name: string, text: string, imageUrl: string): Button {
+        var result = new Button(name);
+
+        // Adding image
+        var iconImage = new Image(name + "_icon", imageUrl);
+        iconImage.stretch = Image.STRETCH_FILL;
+        result.addControl(iconImage);
+
+        // Adding text
+        var textBlock = new TextBlock(name + "_button", text);
+        textBlock.textWrapping = true;
+        textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+        result.addControl(textBlock);
+
+        return result;
+    }
+}    

+ 118 - 118
gui/src/2D/controls/checkbox.ts

@@ -1,145 +1,145 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { Measure } from "../measure";
+import { Observable, Vector2 } from "babylonjs";
+
+/**
+ * Class used to represent a 2D checkbox
+ */
+export class Checkbox extends Control {
+    private _isChecked = false;
+    private _background = "black";
+    private _checkSizeRatio = 0.8;
+    private _thickness = 1;
+
+    /** Gets or sets border thickness  */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
+        }
+
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
-module BABYLON.GUI {
     /**
-     * Class used to represent a 2D checkbox
+     * Observable raised when isChecked property changes
      */
-    export class Checkbox extends Control {
-        private _isChecked = false;
-        private _background = "black";   
-        private _checkSizeRatio = 0.8;
-        private _thickness = 1;
-        
-        /** Gets or sets border thickness  */
-        public get thickness(): number {
-            return this._thickness;
-        }
-
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+    public onIsCheckedChangedObservable = new Observable<boolean>();
 
-            this._thickness = value;
-            this._markAsDirty();
-        }           
+    /** Gets or sets a value indicating the ratio between overall size and check size */
+    public get checkSizeRatio(): number {
+        return this._checkSizeRatio;
+    }
 
-        /**
-         * Observable raised when isChecked property changes
-         */
-        public onIsCheckedChangedObservable = new Observable<boolean>();
+    public set checkSizeRatio(value: number) {
+        value = Math.max(Math.min(1, value), 0);
 
-        /** Gets or sets a value indicating the ratio between overall size and check size */
-        public get checkSizeRatio(): number {
-            return this._checkSizeRatio;
+        if (this._checkSizeRatio === value) {
+            return;
         }
 
-        public set checkSizeRatio(value: number) {
-            value = Math.max(Math.min(1, value), 0);
+        this._checkSizeRatio = value;
+        this._markAsDirty();
+    }
 
-            if (this._checkSizeRatio === value) {
-                return;
-            }
-
-            this._checkSizeRatio = value;
-            this._markAsDirty();
-        }             
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
-            this._background = value;
-            this._markAsDirty();
-        }     
+    /** Gets or sets a boolean indicating if the checkbox is checked or not */
+    public get isChecked(): boolean {
+        return this._isChecked;
+    }
 
-        /** Gets or sets a boolean indicating if the checkbox is checked or not */
-        public get isChecked(): boolean {
-            return this._isChecked;
+    public set isChecked(value: boolean) {
+        if (this._isChecked === value) {
+            return;
         }
 
-        public set isChecked(value: boolean) {
-            if (this._isChecked === value) {
-                return;
-            }
+        this._isChecked = value;
+        this._markAsDirty();
 
-            this._isChecked = value;
-            this._markAsDirty();
+        this.onIsCheckedChangedObservable.notifyObservers(value);
+    }
 
-            this.onIsCheckedChangedObservable.notifyObservers(value);
-        }                             
+    /**
+     * Creates a new CheckBox
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+        this.isPointerBlocker = true;
+    }
+
+    protected _getTypeName(): string {
+        return "CheckBox";
+    }
+
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            let actualWidth = this._currentMeasure.width - this._thickness;
+            let actualHeight = this._currentMeasure.height - this._thickness;
+
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
 
-        /**
-         * Creates a new CheckBox
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-            this.isPointerBlocker = true;
-        }
+            context.fillStyle = this._background;
+            context.fillRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
 
-        protected _getTypeName(): string {
-            return "CheckBox";
-        }
-        
-        /** @hidden */
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                let actualWidth = this._currentMeasure.width - this._thickness;
-                let actualHeight = this._currentMeasure.height - this._thickness;
-
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
-                
-                context.fillStyle = this._background;
-                context.fillRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);   
-
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
-
-                if (this._isChecked) {
-                    context.fillStyle = this.color;
-                    let offsetWidth = actualWidth * this._checkSizeRatio;
-                    let offseHeight = actualHeight * this._checkSizeRatio;
-
-                    context.fillRect(this._currentMeasure.left + this._thickness / 2 + (actualWidth - offsetWidth) / 2, this._currentMeasure.top + this._thickness / 2 + (actualHeight - offseHeight) / 2, offsetWidth, offseHeight);
-                }
-
-                context.strokeStyle = this.color;
-                context.lineWidth = this._thickness;
-
-                context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);                       
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
-            context.restore();
-        }
 
-        // Events
+            if (this._isChecked) {
+                context.fillStyle = this.color;
+                let offsetWidth = actualWidth * this._checkSizeRatio;
+                let offseHeight = actualHeight * this._checkSizeRatio;
 
-        /** @hidden */
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
+                context.fillRect(this._currentMeasure.left + this._thickness / 2 + (actualWidth - offsetWidth) / 2, this._currentMeasure.top + this._thickness / 2 + (actualHeight - offseHeight) / 2, offsetWidth, offseHeight);
             }
 
-            this.isChecked = !this.isChecked;
+            context.strokeStyle = this.color;
+            context.lineWidth = this._thickness;
 
-            return true;
+            context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
         }
-    }    
-}
+        context.restore();
+    }
+
+    // Events
+
+    /** @hidden */
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
+        }
+
+        this.isChecked = !this.isChecked;
+
+        return true;
+    }
+}   

+ 354 - 356
gui/src/2D/controls/colorpicker.ts

@@ -1,430 +1,428 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to create color pickers */
-    export class ColorPicker extends Control {
-        private _colorWheelCanvas: HTMLCanvasElement;
-        
-        private _value: Color3 = Color3.Red();
-        private _tmpColor = new Color3();
-
-        private _pointerStartedOnSquare = false;
-        private _pointerStartedOnWheel = false;
-        
-        private _squareLeft = 0;
-        private _squareTop = 0;
-        private _squareSize = 0;
-
-        private _h = 360;
-        private _s = 1;
-        private _v = 1;
-        
-        /**
-         * Observable raised when the value changes
-         */
-        public onValueChangedObservable = new Observable<Color3>();
-
-        /** Gets or sets the color of the color picker */
-        public get value(): Color3 {
-            return this._value;
-        }
+import { Control } from "./control";
+import { Color3, Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
 
-        public set value(value: Color3) {
-            if (this._value.equals(value)) {
-                return;
-            }
+/** Class used to create color pickers */
+export class ColorPicker extends Control {
+    private _colorWheelCanvas: HTMLCanvasElement;
 
-            this._value.copyFrom(value);
+    private _value: Color3 = Color3.Red();
+    private _tmpColor = new Color3();
 
-            this._RGBtoHSV(this._value, this._tmpColor);
-            
-            this._h = this._tmpColor.r;
-            this._s = Math.max(this._tmpColor.g, 0.00001);
-            this._v = Math.max(this._tmpColor.b, 0.00001);
+    private _pointerStartedOnSquare = false;
+    private _pointerStartedOnWheel = false;
 
-            this._markAsDirty();
+    private _squareLeft = 0;
+    private _squareTop = 0;
+    private _squareSize = 0;
 
-            this.onValueChangedObservable.notifyObservers(this._value);
-        }
+    private _h = 360;
+    private _s = 1;
+    private _v = 1;
 
-        /** Gets or sets control width */
-        public set width(value: string | number ) {
-            if (this._width.toString(this._host) === value) {
-                return;
-            }
+    /**
+     * Observable raised when the value changes
+     */
+    public onValueChangedObservable = new Observable<Color3>();
 
-            if (this._width.fromString(value)) {
-                this._height.fromString(value);
-                this._markAsDirty();
-            }
+    /** Gets or sets the color of the color picker */
+    public get value(): Color3 {
+        return this._value;
+    }
+
+    public set value(value: Color3) {
+        if (this._value.equals(value)) {
+            return;
         }
 
-        /** Gets or sets control height */
-        public set height(value: string | number ) {
-            if (this._height.toString(this._host) === value) {
-                return;
-            }
+        this._value.copyFrom(value);
 
-            if (this._height.fromString(value)) {
-                this._width.fromString(value);
-                this._markAsDirty();
-            }
-        }
+        this._RGBtoHSV(this._value, this._tmpColor);
 
-        /** Gets or sets control size */
-        public get size(): string | number {
-            return this.width;
-        }
+        this._h = this._tmpColor.r;
+        this._s = Math.max(this._tmpColor.g, 0.00001);
+        this._v = Math.max(this._tmpColor.b, 0.00001);
+
+        this._markAsDirty();
+
+        this.onValueChangedObservable.notifyObservers(this._value);
+    }
 
-        public set size(value: string | number){
-            this.width = value;
-        }              
-
-        /**
-         * Creates a new ColorPicker
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-            this.value = new BABYLON.Color3(.88, .1, .1);
-            this.size = "200px";
-            this.isPointerBlocker = true;
+    /** Gets or sets control width */
+    public set width(value: string | number) {
+        if (this._width.toString(this._host) === value) {
+            return;
         }
 
-        protected _getTypeName(): string {
-            return "ColorPicker";
-        }        
+        if (this._width.fromString(value)) {
+            this._height.fromString(value);
+            this._markAsDirty();
+        }
+    }
 
-        private _updateSquareProps():void {
-            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-            var wheelThickness = radius*.2;
-            var innerDiameter = (radius-wheelThickness)*2;
-            var squareSize = innerDiameter/(Math.sqrt(2));
-            var offset = radius - squareSize*.5;
+    /** Gets or sets control height */
+    public set height(value: string | number) {
+        if (this._height.toString(this._host) === value) {
+            return;
+        }
 
-            this._squareLeft = this._currentMeasure.left + offset;
-            this._squareTop = this._currentMeasure.top + offset;
-            this._squareSize = squareSize;
+        if (this._height.fromString(value)) {
+            this._width.fromString(value);
+            this._markAsDirty();
         }
+    }
+
+    /** Gets or sets control size */
+    public get size(): string | number {
+        return this.width;
+    }
+
+    public set size(value: string | number) {
+        this.width = value;
+    }
+
+    /**
+     * Creates a new ColorPicker
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+        this.value = new Color3(.88, .1, .1);
+        this.size = "200px";
+        this.isPointerBlocker = true;
+    }
+
+    protected _getTypeName(): string {
+        return "ColorPicker";
+    }
+
+    private _updateSquareProps(): void {
+        var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+        var wheelThickness = radius * .2;
+        var innerDiameter = (radius - wheelThickness) * 2;
+        var squareSize = innerDiameter / (Math.sqrt(2));
+        var offset = radius - squareSize * .5;
+
+        this._squareLeft = this._currentMeasure.left + offset;
+        this._squareTop = this._currentMeasure.top + offset;
+        this._squareSize = squareSize;
+    }
+
+    private _drawGradientSquare(hueValue: number, left: number, top: number, width: number, height: number, context: CanvasRenderingContext2D) {
+        var lgh = context.createLinearGradient(left, top, width + left, top);
+        lgh.addColorStop(0, '#fff');
+        lgh.addColorStop(1, 'hsl(' + hueValue + ', 100%, 50%)');
+
+        context.fillStyle = lgh;
+        context.fillRect(left, top, width, height);
+
+        var lgv = context.createLinearGradient(left, top, left, height + top);
+        lgv.addColorStop(0, 'rgba(0,0,0,0)');
+        lgv.addColorStop(1, '#000');
+
+        context.fillStyle = lgv;
+        context.fillRect(left, top, width, height);
+    }
+
+    private _drawCircle(centerX: number, centerY: number, radius: number, context: CanvasRenderingContext2D) {
+        context.beginPath();
+        context.arc(centerX, centerY, radius + 1, 0, 2 * Math.PI, false);
+        context.lineWidth = 3;
+        context.strokeStyle = '#333333';
+        context.stroke();
+        context.beginPath();
+        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
+        context.lineWidth = 3;
+        context.strokeStyle = '#ffffff';
+        context.stroke();
+    }
+
+    private _createColorWheelCanvas(radius: number, thickness: number): HTMLCanvasElement {
+        var canvas = document.createElement("canvas");
+        canvas.width = radius * 2;
+        canvas.height = radius * 2;
+        var context = <CanvasRenderingContext2D>canvas.getContext("2d");
+        var image = context.getImageData(0, 0, radius * 2, radius * 2);
+        var data = image.data;
+
+        var color = this._tmpColor;
+        var maxDistSq = radius * radius;
+        var innerRadius = radius - thickness;
+        var minDistSq = innerRadius * innerRadius;
+
+        for (var x = -radius; x < radius; x++) {
+            for (var y = -radius; y < radius; y++) {
+
+                var distSq = x * x + y * y;
+
+                if (distSq > maxDistSq || distSq < minDistSq) {
+                    continue;
+                }
 
-        private _drawGradientSquare(hueValue:number, left:number, top:number, width:number, height:number, context: CanvasRenderingContext2D) {
-            var lgh = context.createLinearGradient(left, top, width+left, top);
-            lgh.addColorStop(0, '#fff');
-            lgh.addColorStop(1,  'hsl(' + hueValue + ', 100%, 50%)');
+                var dist = Math.sqrt(distSq);
+                var ang = Math.atan2(y, x);
 
-            context.fillStyle = lgh;
-            context.fillRect(left, top,  width, height);
+                this._HSVtoRGB(ang * 180 / Math.PI + 180, dist / radius, 1, color);
 
-            var lgv = context.createLinearGradient(left, top, left, height+top);
-            lgv.addColorStop(0, 'rgba(0,0,0,0)');
-            lgv.addColorStop(1,  '#000');
+                var index = ((x + radius) + ((y + radius) * 2 * radius)) * 4;
 
-            context.fillStyle = lgv;
-            context.fillRect(left, top, width, height);
-        }
+                data[index] = color.r * 255;
+                data[index + 1] = color.g * 255;
+                data[index + 2] = color.b * 255;
+                var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
 
-        private _drawCircle(centerX:number, centerY:number, radius:number, context: CanvasRenderingContext2D) {
-            context.beginPath();
-            context.arc(centerX, centerY, radius+1, 0, 2 * Math.PI, false);
-            context.lineWidth = 3;
-            context.strokeStyle = '#333333';
-            context.stroke();
-            context.beginPath();
-            context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
-            context.lineWidth = 3;
-            context.strokeStyle = '#ffffff';
-            context.stroke();
-        }
+                //apply less alpha to bigger color pickers
+                var alphaAmount = .2;
+                var maxAlpha = .2;
+                var minAlpha = .04;
+                var lowerRadius = 50;
+                var upperRadius = 150;
+
+                if (radius < lowerRadius) {
+                    alphaAmount = maxAlpha;
+                } else if (radius > upperRadius) {
+                    alphaAmount = minAlpha;
+                } else {
+                    alphaAmount = (minAlpha - maxAlpha) * (radius - lowerRadius) / (upperRadius - lowerRadius) + maxAlpha;
+                }
 
-        private _createColorWheelCanvas(radius:number, thickness:number): HTMLCanvasElement {
-            var canvas = document.createElement("canvas");
-            canvas.width = radius * 2;
-            canvas.height = radius * 2;
-            var context = <CanvasRenderingContext2D>canvas.getContext("2d");
-            var image = context.getImageData(0, 0, radius * 2, radius * 2);
-            var data = image.data;
-            
-            var color = this._tmpColor;
-            var maxDistSq = radius*radius;
-            var innerRadius = radius - thickness;
-            var minDistSq = innerRadius*innerRadius;
-
-            for (var x = -radius; x < radius; x++) {
-                for (var y = -radius; y < radius; y++) {
-                    
-                    var distSq = x*x + y*y;
-                    
-                    if (distSq > maxDistSq || distSq < minDistSq) {
-                        continue;
-                    }
-
-                    var dist = Math.sqrt(distSq);
-                    var ang = Math.atan2(y, x);
-                    
-                    this._HSVtoRGB(ang * 180/Math.PI + 180, dist/radius, 1, color);
-                    
-                    var index = ((x + radius) + ((y + radius)*2*radius)) * 4;
-                    
-                    data[index] = color.r*255;
-                    data[index + 1] = color.g*255;
-                    data[index + 2] = color.b*255;      
-                    var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
-
-                    //apply less alpha to bigger color pickers
-                    var alphaAmount = .2;
-                    var maxAlpha = .2;
-                    var minAlpha = .04;
-                    var lowerRadius = 50;
-                    var upperRadius = 150;
-
-                    if(radius < lowerRadius){
-                        alphaAmount = maxAlpha;
-                    }else if(radius > upperRadius){
-                        alphaAmount = minAlpha;
-                    }else{
-                        alphaAmount = (minAlpha - maxAlpha)*(radius - lowerRadius)/(upperRadius - lowerRadius) + maxAlpha;
-                    }
-                    
-                    var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
-
-                    if (alphaRatio < alphaAmount) {
-                        data[index + 3] = 255 * (alphaRatio / alphaAmount);
-                    } else if (alphaRatio > 1 - alphaAmount) {
-                        data[index + 3] = 255 * (1.0 - ((alphaRatio - (1 - alphaAmount)) / alphaAmount));
-                    } else {
-                        data[index + 3] = 255;
-                    }
+                var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
 
+                if (alphaRatio < alphaAmount) {
+                    data[index + 3] = 255 * (alphaRatio / alphaAmount);
+                } else if (alphaRatio > 1 - alphaAmount) {
+                    data[index + 3] = 255 * (1.0 - ((alphaRatio - (1 - alphaAmount)) / alphaAmount));
+                } else {
+                    data[index + 3] = 255;
                 }
+
             }
+        }
 
-            context.putImageData(image, 0, 0);
+        context.putImageData(image, 0, 0);
 
-            return canvas;
-        }
+        return canvas;
+    }
 
-        private _RGBtoHSV(color:Color3, result:Color3){
-            var r = color.r;
-            var g = color.g;
-            var b = color.b;
-
-            var max = Math.max(r, g, b);
-            var min = Math.min(r, g, b);
-            var h = 0;
-            var s = 0;
-            var v = max;
-            
-            var dm = max - min;
-            
-            if(max !== 0){
-                s = dm / max;
-            }
+    private _RGBtoHSV(color: Color3, result: Color3) {
+        var r = color.r;
+        var g = color.g;
+        var b = color.b;
+
+        var max = Math.max(r, g, b);
+        var min = Math.min(r, g, b);
+        var h = 0;
+        var s = 0;
+        var v = max;
+
+        var dm = max - min;
+
+        if (max !== 0) {
+            s = dm / max;
+        }
 
-            if(max != min) {
-                if(max == r){
-                    h = (g - b) / dm;
-                    if(g < b){
-                        h += 6;
-                    }
-                }else if(max == g){
-                    h = (b - r) / dm + 2;
-                }else if(max == b){
-                    h = (r - g) / dm + 4;
+        if (max != min) {
+            if (max == r) {
+                h = (g - b) / dm;
+                if (g < b) {
+                    h += 6;
                 }
-                h *= 60;
+            } else if (max == g) {
+                h = (b - r) / dm + 2;
+            } else if (max == b) {
+                h = (r - g) / dm + 4;
             }
-            
-            result.r = h;
-            result.g = s;
-            result.b = v;
+            h *= 60;
         }
 
-        private _HSVtoRGB(hue:number, saturation:number, value:number, result:Color3) {
-            var chroma = value * saturation;
-            var h = hue / 60;
-            var x = chroma * (1- Math.abs((h % 2) - 1));
-            var r = 0;
-            var g = 0;
-            var b = 0;
-
-            if (h >= 0 && h <= 1) {
-                r = chroma;
-                g = x;
-            } else if (h >= 1 && h <= 2) {
-                r = x;
-                g = chroma;
-            } else if (h >= 2 && h <= 3) {
-                g = chroma;
-                b = x;
-            } else if (h >= 3 && h <= 4) {
-                g = x;
-                b = chroma;
-            } else if (h >= 4 && h <= 5) {
-                r = x;
-                b = chroma;
-            } else if (h >= 5 && h <= 6) {
-                r = chroma;
-                b = x;
-            }
-            
-            var m = value - chroma;
-            result.set((r+m), (g+m), (b+m));            
+        result.r = h;
+        result.g = s;
+        result.b = v;
+    }
+
+    private _HSVtoRGB(hue: number, saturation: number, value: number, result: Color3) {
+        var chroma = value * saturation;
+        var h = hue / 60;
+        var x = chroma * (1 - Math.abs((h % 2) - 1));
+        var r = 0;
+        var g = 0;
+        var b = 0;
+
+        if (h >= 0 && h <= 1) {
+            r = chroma;
+            g = x;
+        } else if (h >= 1 && h <= 2) {
+            r = x;
+            g = chroma;
+        } else if (h >= 2 && h <= 3) {
+            g = chroma;
+            b = x;
+        } else if (h >= 3 && h <= 4) {
+            g = x;
+            b = chroma;
+        } else if (h >= 4 && h <= 5) {
+            r = x;
+            b = chroma;
+        } else if (h >= 5 && h <= 6) {
+            r = chroma;
+            b = x;
         }
 
-        /** @hidden */
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+        var m = value - chroma;
+        result.set((r + m), (g + m), (b + m));
+    }
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
-                var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-                var wheelThickness = radius*.2;
-                var left = this._currentMeasure.left;
-                var top = this._currentMeasure.top;
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
 
-                if(!this._colorWheelCanvas || this._colorWheelCanvas.width != radius*2){
-                    this._colorWheelCanvas = this._createColorWheelCanvas(radius, wheelThickness);
-                }
+            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+            var wheelThickness = radius * .2;
+            var left = this._currentMeasure.left;
+            var top = this._currentMeasure.top;
 
-                this._updateSquareProps();
+            if (!this._colorWheelCanvas || this._colorWheelCanvas.width != radius * 2) {
+                this._colorWheelCanvas = this._createColorWheelCanvas(radius, wheelThickness);
+            }
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){                
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY; 
-                    
-                    context.fillRect(this._squareLeft, this._squareTop, this._squareSize, this._squareSize);
-                }
+            this._updateSquareProps();
 
-                context.drawImage(this._colorWheelCanvas, left, top);
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+                context.fillRect(this._squareLeft, this._squareTop, this._squareSize, this._squareSize);
+            }
 
-                this._drawGradientSquare(this._h, 
-                                        this._squareLeft,
-                                        this._squareTop,
-                                        this._squareSize, 
-                                        this._squareSize,
-                                        context);
-                
-                var cx = this._squareLeft + this._squareSize*this._s;
-                var cy = this._squareTop + this._squareSize*(1 - this._v);
-                
-                this._drawCircle(cx, cy, radius*.04, context);
-
-                var dist = radius - wheelThickness*.5;
-                cx = left + radius + Math.cos((this._h-180)*Math.PI/180)*dist;
-                cy = top + radius + Math.sin((this._h-180)*Math.PI/180)*dist;
-                this._drawCircle(cx, cy, wheelThickness*.35, context);
+            context.drawImage(this._colorWheelCanvas, left, top);
 
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
-            context.restore();
-        }
 
-        // Events
-        private _pointerIsDown = false;
+            this._drawGradientSquare(this._h,
+                this._squareLeft,
+                this._squareTop,
+                this._squareSize,
+                this._squareSize,
+                context);
 
-        private _updateValueFromPointer(x: number, y:number): void {
-            if(this._pointerStartedOnWheel)
-            {
-                var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-                var centerX = radius + this._currentMeasure.left;
-                var centerY = radius + this._currentMeasure.top;
-                this._h = Math.atan2(y - centerY, x - centerX)*180/Math.PI + 180;
-            }
-            else if(this._pointerStartedOnSquare)
-            {
-                this._updateSquareProps();
-                this._s = (x - this._squareLeft) / this._squareSize;
-                this._v = 1 - (y - this._squareTop) / this._squareSize;
-                this._s = Math.min(this._s, 1);
-                this._s = Math.max(this._s, 0.00001);
-                this._v = Math.min(this._v, 1);
-                this._v = Math.max(this._v, 0.00001);
-            }
+            var cx = this._squareLeft + this._squareSize * this._s;
+            var cy = this._squareTop + this._squareSize * (1 - this._v);
+
+            this._drawCircle(cx, cy, radius * .04, context);
 
-            this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
+            var dist = radius - wheelThickness * .5;
+            cx = left + radius + Math.cos((this._h - 180) * Math.PI / 180) * dist;
+            cy = top + radius + Math.sin((this._h - 180) * Math.PI / 180) * dist;
+            this._drawCircle(cx, cy, wheelThickness * .35, context);
 
-            this.value = this._tmpColor;
         }
+        context.restore();
+    }
 
-        private _isPointOnSquare(coordinates: Vector2):boolean {
+    // Events
+    private _pointerIsDown = false;
+
+    private _updateValueFromPointer(x: number, y: number): void {
+        if (this._pointerStartedOnWheel) {
+            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+            var centerX = radius + this._currentMeasure.left;
+            var centerY = radius + this._currentMeasure.top;
+            this._h = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI + 180;
+        }
+        else if (this._pointerStartedOnSquare) {
             this._updateSquareProps();
+            this._s = (x - this._squareLeft) / this._squareSize;
+            this._v = 1 - (y - this._squareTop) / this._squareSize;
+            this._s = Math.min(this._s, 1);
+            this._s = Math.max(this._s, 0.00001);
+            this._v = Math.min(this._v, 1);
+            this._v = Math.max(this._v, 0.00001);
+        }
 
-            var left = this._squareLeft;
-            var top = this._squareTop;
-            var size = this._squareSize;
+        this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
 
-            if(coordinates.x >= left && coordinates.x <= left + size &&
-               coordinates.y >= top && coordinates.y <= top + size){
-                return true;
-            }
+        this.value = this._tmpColor;
+    }
 
-            return false;
+    private _isPointOnSquare(coordinates: Vector2): boolean {
+        this._updateSquareProps();
+
+        var left = this._squareLeft;
+        var top = this._squareTop;
+        var size = this._squareSize;
+
+        if (coordinates.x >= left && coordinates.x <= left + size &&
+            coordinates.y >= top && coordinates.y <= top + size) {
+            return true;
         }
 
-        private _isPointOnWheel(coordinates: Vector2):boolean {
-            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-            var centerX = radius + this._currentMeasure.left;
-            var centerY = radius + this._currentMeasure.top;
-            var wheelThickness = radius*.2;
-            var innerRadius = radius-wheelThickness;
-            var radiusSq = radius*radius;
-            var innerRadiusSq = innerRadius*innerRadius;
+        return false;
+    }
 
-            var dx = coordinates.x - centerX;
-            var dy = coordinates.y - centerY;
+    private _isPointOnWheel(coordinates: Vector2): boolean {
+        var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+        var centerX = radius + this._currentMeasure.left;
+        var centerY = radius + this._currentMeasure.top;
+        var wheelThickness = radius * .2;
+        var innerRadius = radius - wheelThickness;
+        var radiusSq = radius * radius;
+        var innerRadiusSq = innerRadius * innerRadius;
 
-            var distSq = dx*dx + dy*dy;
+        var dx = coordinates.x - centerX;
+        var dy = coordinates.y - centerY;
 
-            if(distSq <= radiusSq && distSq >= innerRadiusSq){
-                return true;
-            }
+        var distSq = dx * dx + dy * dy;
+
+        if (distSq <= radiusSq && distSq >= innerRadiusSq) {
+            return true;
+        }
 
+        return false;
+    }
+
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
             return false;
         }
 
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }            
+        this._pointerIsDown = true;
 
-            this._pointerIsDown = true;
+        this._pointerStartedOnSquare = false;
+        this._pointerStartedOnWheel = false;
 
-            this._pointerStartedOnSquare = false;
-            this._pointerStartedOnWheel = false;
+        if (this._isPointOnSquare(coordinates)) {
+            this._pointerStartedOnSquare = true;
+        } else if (this._isPointOnWheel(coordinates)) {
+            this._pointerStartedOnWheel = true;
+        }
 
-            if(this._isPointOnSquare(coordinates)){
-                this._pointerStartedOnSquare = true;
-            }else if(this._isPointOnWheel(coordinates)){
-                this._pointerStartedOnWheel = true;
-            }
+        this._updateValueFromPointer(coordinates.x, coordinates.y);
+        this._host._capturingControl[pointerId] = this;
 
-            this._updateValueFromPointer(coordinates.x, coordinates.y);
-            this._host._capturingControl[pointerId] = this;
+        return true;
+    }
 
-            return true;
+    public _onPointerMove(target: Control, coordinates: Vector2): void {
+        if (this._pointerIsDown) {
+            this._updateValueFromPointer(coordinates.x, coordinates.y);
         }
 
-        public _onPointerMove(target: Control, coordinates: Vector2): void {
-            if (this._pointerIsDown) {
-                this._updateValueFromPointer(coordinates.x, coordinates.y);
-            }
+        super._onPointerMove(target, coordinates);
+    }
 
-            super._onPointerMove(target, coordinates);
-        }
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        this._pointerIsDown = false;
 
-        public _onPointerUp (target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            this._pointerIsDown = false;
-            
-            delete this._host._capturingControl[pointerId];
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
-        }     
-    }    
-}
+        delete this._host._capturingControl[pointerId];
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
+}  

+ 261 - 260
gui/src/2D/controls/container.ts

@@ -1,339 +1,340 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /**
-     * Root class for 2D containers
-     * @see http://doc.babylonjs.com/how_to/gui#containers
-     */
-    export class Container extends Control {
-        /** @hidden */
-        protected _children = new Array<Control>();
-        /** @hidden */
-        protected _measureForChildren = Measure.Empty();  
-        /** @hidden */
-        protected _background: string;   
-        /** @hidden */
-        protected _adaptWidthToChildren = false;
-        /** @hidden */
-        protected _adaptHeightToChildren = false;
-
-        /** Gets or sets a boolean indicating if the container should try to adapt to its children height */
-        public get adaptHeightToChildren(): boolean {
-            return this._adaptHeightToChildren;
+import { Control } from "./control";
+import { Measure } from "../measure";
+import { Nullable } from "babylonjs";
+import { AdvancedDynamicTexture } from "../advancedDynamicTexture";
+
+/**
+ * Root class for 2D containers
+ * @see http://doc.babylonjs.com/how_to/gui#containers
+ */
+export class Container extends Control {
+    /** @hidden */
+    protected _children = new Array<Control>();
+    /** @hidden */
+    protected _measureForChildren = Measure.Empty();
+    /** @hidden */
+    protected _background: string;
+    /** @hidden */
+    protected _adaptWidthToChildren = false;
+    /** @hidden */
+    protected _adaptHeightToChildren = false;
+
+    /** Gets or sets a boolean indicating if the container should try to adapt to its children height */
+    public get adaptHeightToChildren(): boolean {
+        return this._adaptHeightToChildren;
+    }
+
+    public set adaptHeightToChildren(value: boolean) {
+        if (this._adaptHeightToChildren === value) {
+            return;
         }
 
-        public set adaptHeightToChildren(value: boolean) {
-            if (this._adaptHeightToChildren === value) {
-                return;
-            }
-
-            this._adaptHeightToChildren = value;
-
-            if (value) {
-                this.height = "100%";
-            }
+        this._adaptHeightToChildren = value;
 
-            this._markAsDirty();
-        }       
-        
-        /** Gets or sets a boolean indicating if the container should try to adapt to its children width */
-        public get adaptWidthToChildren(): boolean {
-            return this._adaptWidthToChildren;
+        if (value) {
+            this.height = "100%";
         }
 
-        public set adaptWidthToChildren(value: boolean) {
-            if (this._adaptWidthToChildren === value) {
-                return;
-            }
+        this._markAsDirty();
+    }
 
-            this._adaptWidthToChildren = value;
+    /** Gets or sets a boolean indicating if the container should try to adapt to its children width */
+    public get adaptWidthToChildren(): boolean {
+        return this._adaptWidthToChildren;
+    }
 
-            if (value) {
-                this.width = "100%";
-            }
+    public set adaptWidthToChildren(value: boolean) {
+        if (this._adaptWidthToChildren === value) {
+            return;
+        }
 
-            this._markAsDirty();
-        }           
+        this._adaptWidthToChildren = value;
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+        if (value) {
+            this.width = "100%";
         }
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._markAsDirty();
+    }
+
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
-            this._background = value;
-            this._markAsDirty();
-        }  
-
-        /** Gets the list of children */
-        public get children(): Control[] {
-            return this._children;
-        }        
-
-        /**
-         * Creates a new Container
-         * @param name defines the name of the container
-         */
-        constructor(public name?: string) {
-            super(name);
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
 
-        protected _getTypeName(): string {
-            return "Container";
-        }           
-
-        /**
-         * Gets a child using its name
-         * @param name defines the child name to look for
-         * @returns the child control if found
-         */
-        public getChildByName(name: string): Nullable<Control> {
-            for (var child of this.children) {
-                if (child.name === name) {
-                    return child;
-                }
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
-            return null;
-        }       
-
-        /**
-         * Gets a child using its type and its name
-         * @param name defines the child name to look for
-         * @param type defines the child type to look for
-         * @returns the child control if found
-         */        
-        public getChildByType(name: string, type: string): Nullable<Control> {
-            for (var child of this.children) {
-                if (child.typeName === type) {
-                    return child;
-                }
-            }
+    /** Gets the list of children */
+    public get children(): Control[] {
+        return this._children;
+    }
 
-            return null;
-        }            
+    /**
+     * Creates a new Container
+     * @param name defines the name of the container
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
 
-        /**
-         * Search for a specific control in children
-         * @param control defines the control to look for
-         * @returns true if the control is in child list
-         */
-        public containsControl(control: Control): boolean {
-            return this.children.indexOf(control) !== -1;
-        }
+    protected _getTypeName(): string {
+        return "Container";
+    }
 
-        /**
-         * Adds a new control to the current container
-         * @param control defines the control to add
-         * @returns the current container
-         */
-        public addControl(control: Nullable<Control>): Container {
-            if (!control) {
-                return this;
+    /**
+     * Gets a child using its name
+     * @param name defines the child name to look for
+     * @returns the child control if found
+     */
+    public getChildByName(name: string): Nullable<Control> {
+        for (var child of this.children) {
+            if (child.name === name) {
+                return child;
             }
+        }
 
-           var index = this._children.indexOf(control);
+        return null;
+    }
 
-            if (index !== -1) {
-                return this;
+    /**
+     * Gets a child using its type and its name
+     * @param name defines the child name to look for
+     * @param type defines the child type to look for
+     * @returns the child control if found
+     */
+    public getChildByType(name: string, type: string): Nullable<Control> {
+        for (var child of this.children) {
+            if (child.typeName === type) {
+                return child;
             }
-            control._link(this, this._host);
+        }
 
-            control._markAllAsDirty();
+        return null;
+    }
 
-            this._reOrderControl(control);
+    /**
+     * Search for a specific control in children
+     * @param control defines the control to look for
+     * @returns true if the control is in child list
+     */
+    public containsControl(control: Control): boolean {
+        return this.children.indexOf(control) !== -1;
+    }
 
-            this._markAsDirty();
+    /**
+     * Adds a new control to the current container
+     * @param control defines the control to add
+     * @returns the current container
+     */
+    public addControl(control: Nullable<Control>): Container {
+        if (!control) {
             return this;
         }
 
-        /**
-         * Removes a control from the current container
-         * @param control defines the control to remove
-         * @returns the current container
-         */        
-        public removeControl(control: Control): Container {
-            var index = this._children.indexOf(control);
+        var index = this._children.indexOf(control);
 
-            if (index !== -1) {
-                this._children.splice(index, 1);
+        if (index !== -1) {
+            return this;
+        }
+        control._link(this, this._host);
 
-                control.parent = null;
-            }
+        control._markAllAsDirty();
 
-            control.linkWithMesh(null);
+        this._reOrderControl(control);
 
-            if (this._host) {
-                this._host._cleanControlAfterRemoval(control);
-            }
+        this._markAsDirty();
+        return this;
+    }
 
-            this._markAsDirty();
-            return this;
+    /**
+     * Removes a control from the current container
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control): Container {
+        var index = this._children.indexOf(control);
+
+        if (index !== -1) {
+            this._children.splice(index, 1);
+
+            control.parent = null;
         }
 
-        /** @hidden */
-        public _reOrderControl(control: Control): void {
-            this.removeControl(control);
+        control.linkWithMesh(null);
 
-            for (var index = 0; index < this._children.length; index++) {
-                if (this._children[index].zIndex > control.zIndex) {
-                    this._children.splice(index, 0, control);
-                    return;
-                }
-            }
+        if (this._host) {
+            this._host._cleanControlAfterRemoval(control);
+        }
 
-            this._children.push(control);
+        this._markAsDirty();
+        return this;
+    }
 
-            control.parent = this;
+    /** @hidden */
+    public _reOrderControl(control: Control): void {
+        this.removeControl(control);
 
-            this._markAsDirty();
+        for (var index = 0; index < this._children.length; index++) {
+            if (this._children[index].zIndex > control.zIndex) {
+                this._children.splice(index, 0, control);
+                return;
+            }
         }
 
-        /** @hidden */       
-        public _markMatrixAsDirty(): void {
-            super._markMatrixAsDirty();
+        this._children.push(control);
 
-            for (var index = 0; index < this._children.length; index++) {
-                this._children[index]._markMatrixAsDirty();
-            }
+        control.parent = this;
+
+        this._markAsDirty();
+    }
+
+    /** @hidden */
+    public _markMatrixAsDirty(): void {
+        super._markMatrixAsDirty();
+
+        for (var index = 0; index < this._children.length; index++) {
+            this._children[index]._markMatrixAsDirty();
         }
+    }
 
-        /** @hidden */ 
-        public _markAllAsDirty(): void {
-            super._markAllAsDirty();
+    /** @hidden */
+    public _markAllAsDirty(): void {
+        super._markAllAsDirty();
 
-            for (var index = 0; index < this._children.length; index++) {
-                this._children[index]._markAllAsDirty();
-            }
+        for (var index = 0; index < this._children.length; index++) {
+            this._children[index]._markAllAsDirty();
         }
+    }
+
+    /** @hidden */
+    protected _localDraw(context: CanvasRenderingContext2D): void {
+        if (this._background) {
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
 
-        /** @hidden */ 
-        protected _localDraw(context: CanvasRenderingContext2D): void {
-            if (this._background) {
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
-                
-                context.fillStyle = this._background;
-                context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+            context.fillStyle = this._background;
+            context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
         }
+    }
 
-        /** @hidden */ 
-        public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
-            super._link(root, host);
+    /** @hidden */
+    public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
+        super._link(root, host);
 
-            for (var child of this._children) {
-                child._link(root, host);
-            }
+        for (var child of this._children) {
+            child._link(root, host);
         }
+    }
 
-        /** @hidden */ 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {      
-            if (!this.isVisible || this.notRenderable) {
-                return;
-            }
-            context.save();
-           
-            this._applyStates(context);
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        if (!this.isVisible || this.notRenderable) {
+            return;
+        }
+        context.save();
 
-            if (this._processMeasures(parentMeasure, context)) {
-                this._localDraw(context);
+        this._applyStates(context);
 
-                this._clipForChildren(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            this._localDraw(context);
 
-                let computedWidth = -1;
-                let computedHeight = -1;
+            this._clipForChildren(context);
 
-                for (var child of this._children) {
-                    if (child.isVisible && !child.notRenderable) {
-                        child._tempParentMeasure.copyFrom(this._measureForChildren);
-                        child._draw(this._measureForChildren, context);
+            let computedWidth = -1;
+            let computedHeight = -1;
 
-                        if (child.onAfterDrawObservable.hasObservers()) {
-                            child.onAfterDrawObservable.notifyObservers(child);
-                        }
+            for (var child of this._children) {
+                if (child.isVisible && !child.notRenderable) {
+                    child._tempParentMeasure.copyFrom(this._measureForChildren);
+                    child._draw(this._measureForChildren, context);
 
-                        if (this.adaptWidthToChildren && child._width.isPixel) {
-                            computedWidth = Math.max(computedWidth, child._currentMeasure.width);
-                        }
-                        if (this.adaptHeightToChildren && child._height.isPixel) {
-                            computedHeight = Math.max(computedHeight, child._currentMeasure.height);
-                        }                        
+                    if (child.onAfterDrawObservable.hasObservers()) {
+                        child.onAfterDrawObservable.notifyObservers(child);
                     }
-                }
 
-                if (this.adaptWidthToChildren && computedWidth >= 0) {
-                    this.width = computedWidth + "px";
+                    if (this.adaptWidthToChildren && child._width.isPixel) {
+                        computedWidth = Math.max(computedWidth, child._currentMeasure.width);
+                    }
+                    if (this.adaptHeightToChildren && child._height.isPixel) {
+                        computedHeight = Math.max(computedHeight, child._currentMeasure.height);
+                    }
                 }
-                if (this.adaptHeightToChildren && computedHeight >= 0) {
-                    this.height = computedHeight + "px";
-                }                
             }
-            context.restore();
 
-            if (this.onAfterDrawObservable.hasObservers()) {
-                this.onAfterDrawObservable.notifyObservers(this);
+            if (this.adaptWidthToChildren && computedWidth >= 0) {
+                this.width = computedWidth + "px";
+            }
+            if (this.adaptHeightToChildren && computedHeight >= 0) {
+                this.height = computedHeight + "px";
             }
         }
+        context.restore();
 
-        /** @hidden */ 
-        public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
-            if (!this.isVisible || this.notRenderable) {
-                return false;
-            }
+        if (this.onAfterDrawObservable.hasObservers()) {
+            this.onAfterDrawObservable.notifyObservers(this);
+        }
+    }
 
-            if (!super.contains(x, y)) {
-                return false;
-            }
+    /** @hidden */
+    public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
+        if (!this.isVisible || this.notRenderable) {
+            return false;
+        }
 
-            // Checking backwards to pick closest first
-            for (var index = this._children.length - 1; index >= 0; index--) {
-                var child = this._children[index];
-                if (child._processPicking(x, y, type, pointerId, buttonIndex)) {
-                    return true;
-                }
-            }
+        if (!super.contains(x, y)) {
+            return false;
+        }
 
-            if (!this.isHitTestVisible) {
-                return false;
+        // Checking backwards to pick closest first
+        for (var index = this._children.length - 1; index >= 0; index--) {
+            var child = this._children[index];
+            if (child._processPicking(x, y, type, pointerId, buttonIndex)) {
+                return true;
             }
-
-            return this._processObservables(type, x, y, pointerId, buttonIndex);
         }
 
-        /** @hidden */ 
-        protected _clipForChildren(context: CanvasRenderingContext2D): void {
-            // DO nothing
+        if (!this.isHitTestVisible) {
+            return false;
         }
 
-        /** @hidden */ 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {  
-            super._additionalProcessing(parentMeasure, context);
+        return this._processObservables(type, x, y, pointerId, buttonIndex);
+    }
 
-            this._measureForChildren.copyFrom(this._currentMeasure);
-        }
+    /** @hidden */
+    protected _clipForChildren(context: CanvasRenderingContext2D): void {
+        // DO nothing
+    }
 
-        /** Releases associated resources */
-        public dispose() {
-            super.dispose();
+    /** @hidden */
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        super._additionalProcessing(parentMeasure, context);
 
-            for (var control of this._children) {
-                control.dispose();
-            }
+        this._measureForChildren.copyFrom(this._currentMeasure);
+    }
+
+    /** Releases associated resources */
+    public dispose() {
+        super.dispose();
+
+        for (var control of this._children) {
+            control.dispose();
         }
-    }    
-}
+    }
+}   

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1164 - 1158
gui/src/2D/controls/control.ts


+ 71 - 71
gui/src/2D/controls/ellipse.ts

@@ -1,87 +1,87 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to create 2D ellipse containers */
-    export class Ellipse extends Container {
-        private _thickness = 1;       
-        
-        /** Gets or sets border thickness */
-        public get thickness(): number {
-            return this._thickness;
+import { Container } from "./container";
+import { Control } from "./control";
+import { Measure } from "../measure";
+
+/** Class used to create 2D ellipse containers */
+export class Ellipse extends Container {
+    private _thickness = 1;
+
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
-
-            this._thickness = value;
-            this._markAsDirty();
-        }                
-     
-        /**
-         * Creates a new Ellipse
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
+        this._thickness = value;
+        this._markAsDirty();
+    }
+
+    /**
+     * Creates a new Ellipse
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
+
+    protected _getTypeName(): string {
+        return "Ellipse";
+    }
+
+    protected _localDraw(context: CanvasRenderingContext2D): void {
+        context.save();
+
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
         }
 
-        protected _getTypeName(): string {
-            return "Ellipse";
-        }              
-
-        protected _localDraw(context: CanvasRenderingContext2D): void {
-            context.save();
+        Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2,
+            this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
 
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+        if (this._background) {
+            context.fillStyle = this._background;
 
-            Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, 
-                            this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
+            context.fill();
+        }
 
-            if (this._background) {
-                context.fillStyle = this._background;
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowBlur = 0;
+            context.shadowOffsetX = 0;
+            context.shadowOffsetY = 0;
+        }
 
-                context.fill();
+        if (this._thickness) {
+            if (this.color) {
+                context.strokeStyle = this.color;
             }
+            context.lineWidth = this._thickness;
 
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowBlur = 0;
-                context.shadowOffsetX = 0;
-                context.shadowOffsetY = 0;
-            }
+            context.stroke();
+        }
 
-            if (this._thickness) {
-                if (this.color) {
-                    context.strokeStyle = this.color;
-                }
-                context.lineWidth = this._thickness;
+        context.restore();
+    }
 
-                context.stroke();
-            }
-        
-            context.restore();
-        }
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        super._additionalProcessing(parentMeasure, context);
 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {  
-            super._additionalProcessing(parentMeasure, context);
+        this._measureForChildren.width -= 2 * this._thickness;
+        this._measureForChildren.height -= 2 * this._thickness;
+        this._measureForChildren.left += this._thickness;
+        this._measureForChildren.top += this._thickness;
+    }
 
-            this._measureForChildren.width -= 2 * this._thickness;
-            this._measureForChildren.height -= 2 * this._thickness;
-            this._measureForChildren.left += this._thickness;
-            this._measureForChildren.top += this._thickness;            
-        }
+    protected _clipForChildren(context: CanvasRenderingContext2D) {
 
-       protected _clipForChildren(context: CanvasRenderingContext2D) {
+        Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, this._currentMeasure.width / 2, this._currentMeasure.height / 2, context);
 
-            Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, this._currentMeasure.width / 2, this._currentMeasure.height / 2, context);
-            
-            context.clip();
-        }
-    }    
-}
+        context.clip();
+    }
+}   

+ 277 - 276
gui/src/2D/controls/grid.ts

@@ -1,350 +1,351 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container } from "./container";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Control } from "./control";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create a 2D grid container
+ */
+export class Grid extends Container {
+    private _rowDefinitions = new Array<ValueAndUnit>();
+    private _columnDefinitions = new Array<ValueAndUnit>();
+    private _cells: { [key: string]: Container } = {};
+    private _childControls = new Array<Control>();
+
+    /** Gets the list of children */
+    public get children(): Control[] {
+        return this._childControls;
+    }
 
-module BABYLON.GUI {
     /**
-     * Class used to create a 2D grid container
+     * Adds a new row to the grid
+     * @param height defines the height of the row (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the height is expressed in pixel (or in percentage)
+     * @returns the current grid
      */
-    export class Grid extends Container {
-        private _rowDefinitions = new Array<ValueAndUnit>();
-        private _columnDefinitions = new Array<ValueAndUnit>();
-        private _cells: {[key: string]:Container} = {};
-        private _childControls = new Array<Control>();
-
-        /** Gets the list of children */
-        public get children(): Control[] {
-            return this._childControls;
-        }             
-
-        /**
-         * Adds a new row to the grid
-         * @param height defines the height of the row (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the height is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public addRowDefinition(height: number, isPixel = false): Grid {
-            this._rowDefinitions.push(new ValueAndUnit(height, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
-
-            this._markAsDirty();
+    public addRowDefinition(height: number, isPixel = false): Grid {
+        this._rowDefinitions.push(new ValueAndUnit(height, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
 
-            return this;
-        }
+        this._markAsDirty();
 
-        /**
-         * Adds a new column to the grid
-         * @param width defines the width of the column (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the width is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public addColumnDefinition(width: number, isPixel = false): Grid {
-            this._columnDefinitions.push(new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
-            
-            this._markAsDirty();
+        return this;
+    }
 
-            return this;
-        }     
-
-        /**
-         * Update a row definition
-         * @param index defines the index of the row to update
-         * @param height defines the height of the row (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the weight is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public setRowDefinition(index: number, height: number, isPixel = false): Grid {
-            if (index < 0 || index >= this._rowDefinitions.length) {
-                return this;
-            }
+    /**
+     * Adds a new column to the grid
+     * @param width defines the width of the column (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the width is expressed in pixel (or in percentage)
+     * @returns the current grid
+     */
+    public addColumnDefinition(width: number, isPixel = false): Grid {
+        this._columnDefinitions.push(new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
 
-            this._rowDefinitions[index] = new ValueAndUnit(height,isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
+        this._markAsDirty();
 
-            this._markAsDirty();
+        return this;
+    }
 
+    /**
+     * Update a row definition
+     * @param index defines the index of the row to update
+     * @param height defines the height of the row (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the weight is expressed in pixel (or in percentage)
+     * @returns the current grid
+     */
+    public setRowDefinition(index: number, height: number, isPixel = false): Grid {
+        if (index < 0 || index >= this._rowDefinitions.length) {
             return this;
         }
 
-        /**
-         * Update a column definition
-         * @param index defines the index of the column to update
-         * @param width defines the width of the column (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the width is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public setColumnDefinition(index: number, width: number, isPixel = false): Grid {
-            if (index < 0 || index >= this._columnDefinitions.length) {
-                return this;
-            }
+        this._rowDefinitions[index] = new ValueAndUnit(height, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
 
-            this._columnDefinitions[index] = new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
+        this._markAsDirty();
 
-            this._markAsDirty();
+        return this;
+    }
 
+    /**
+     * Update a column definition
+     * @param index defines the index of the column to update
+     * @param width defines the width of the column (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the width is expressed in pixel (or in percentage)
+     * @returns the current grid
+     */
+    public setColumnDefinition(index: number, width: number, isPixel = false): Grid {
+        if (index < 0 || index >= this._columnDefinitions.length) {
             return this;
-        }        
+        }
 
-        private _removeCell(cell: Container, key: string) {
-            if (!cell) {
-                return;
-            }
+        this._columnDefinitions[index] = new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
+
+        this._markAsDirty();
+
+        return this;
+    }
+
+    private _removeCell(cell: Container, key: string) {
+        if (!cell) {
+            return;
+        }
 
-            super.removeControl(cell);
+        super.removeControl(cell);
 
-            for (var control of cell.children) {
-                let childIndex = this._childControls.indexOf(control);
+        for (var control of cell.children) {
+            let childIndex = this._childControls.indexOf(control);
 
-                if (childIndex !== -1) {
-                    this._childControls.splice(childIndex, 1);
-                }
+            if (childIndex !== -1) {
+                this._childControls.splice(childIndex, 1);
             }
+        }
+
+        delete this._cells[key];
+    }
 
-            delete this._cells[key];
+    private _offsetCell(previousKey: string, key: string) {
+        if (!this._cells[key]) {
+            return;
         }
 
-        private _offsetCell(previousKey: string, key: string) {
-            if (!this._cells[key]) {
-                return;
-            }
+        this._cells[previousKey] = this._cells[key];
 
-            this._cells[previousKey] = this._cells[key];
+        for (var control of this._cells[previousKey].children) {
+            control._tag = previousKey;
+        }
 
-            for (var control of this._cells[previousKey].children) {
-                control._tag = previousKey;
-            } 
+        delete this._cells[key];
+    }
 
-            delete this._cells[key];
+    /**
+     * Remove a column definition at specified index
+     * @param index defines the index of the column to remove
+     * @returns the current grid
+     */
+    public removeColumnDefinition(index: number): Grid {
+        if (index < 0 || index >= this._columnDefinitions.length) {
+            return this;
         }
 
-        /**
-         * Remove a column definition at specified index
-         * @param index defines the index of the column to remove
-         * @returns the current grid
-         */
-        public removeColumnDefinition(index: number): Grid {
-            if (index < 0 || index >= this._columnDefinitions.length) {
-                return this;
-            }
+        for (var x = 0; x < this._rowDefinitions.length; x++) {
+            let key = `${x}:${index}`;
+            let cell = this._cells[key];
+
+            this._removeCell(cell, key);
+        }
 
-            for (var x = 0; x < this._rowDefinitions.length; x++) {
-                let key = `${x}:${index}`;
-                let cell = this._cells[key];
+        for (var x = 0; x < this._rowDefinitions.length; x++) {
+            for (var y = index + 1; y < this._columnDefinitions.length; y++) {
+                let previousKey = `${x}:${y - 1}`;
+                let key = `${x}:${y}`;
 
-                this._removeCell(cell, key);
+                this._offsetCell(previousKey, key);
             }
+        }
 
-            for (var x = 0; x < this._rowDefinitions.length; x++) {
-                for (var y = index + 1; y < this._columnDefinitions.length; y++) {
-                    let previousKey = `${x}:${y - 1}`;
-                    let key = `${x}:${y}`;
+        this._columnDefinitions.splice(index, 1);
 
-                    this._offsetCell(previousKey, key);
-                }
-            }
-            
-            this._columnDefinitions.splice(index, 1);
+        this._markAsDirty();
 
-            this._markAsDirty();
+        return this;
+    }
 
+    /**
+     * Remove a row definition at specified index
+     * @param index defines the index of the row to remove
+     * @returns the current grid
+     */
+    public removeRowDefinition(index: number): Grid {
+        if (index < 0 || index >= this._rowDefinitions.length) {
             return this;
         }
 
-        /**
-         * Remove a row definition at specified index
-         * @param index defines the index of the row to remove
-         * @returns the current grid
-         */
-        public removeRowDefinition(index: number): Grid {
-            if (index < 0 || index >= this._rowDefinitions.length) {
-                return this;
-            }
+        for (var y = 0; y < this._columnDefinitions.length; y++) {
+            let key = `${index}:${y}`;
+            let cell = this._cells[key];
 
-            for (var y = 0; y < this._columnDefinitions.length; y++) {
-                let key = `${index}:${y}`;
-                let cell = this._cells[key];
+            this._removeCell(cell, key);
+        }
 
-                this._removeCell(cell, key);
+        for (var y = 0; y < this._columnDefinitions.length; y++) {
+            for (var x = index + 1; x < this._rowDefinitions.length; x++) {
+                let previousKey = `${x - 1}:${y}`;
+                let key = `${x}:${y}`;
+
+                this._offsetCell(previousKey, key);
             }
+        }
 
-            for (var y = 0; y < this._columnDefinitions.length; y++) {
-                for (var x = index + 1; x < this._rowDefinitions.length; x++) {
-                    let previousKey = `${x - 1}:${y}`;
-                    let key = `${x}:${y}`;
+        this._rowDefinitions.splice(index, 1);
 
-                    this._offsetCell(previousKey, key);
-                }
-            }
-            
-            this._rowDefinitions.splice(index, 1);
+        this._markAsDirty();
 
-            this._markAsDirty();
+        return this;
+    }
 
-            return this;
+    /**
+     * Adds a new control to the current grid
+     * @param control defines the control to add
+     * @param row defines the row where to add the control (0 by default)
+     * @param column defines the column where to add the control (0 by default)
+     * @returns the current grid
+     */
+    public addControl(control: Control, row: number = 0, column: number = 0): Grid {
+        if (this._rowDefinitions.length === 0) {
+            // Add default row definition
+            this.addRowDefinition(1, false);
         }
 
-        /**
-         * Adds a new control to the current grid
-         * @param control defines the control to add
-         * @param row defines the row where to add the control (0 by default)
-         * @param column defines the column where to add the control (0 by default)
-         * @returns the current grid
-         */
-        public addControl(control: Control, row: number = 0, column: number = 0): Grid {
-            if (this._rowDefinitions.length === 0) {
-                // Add default row definition
-                this.addRowDefinition(1, false);
-            }
+        if (this._columnDefinitions.length === 0) {
+            // Add default column definition
+            this.addColumnDefinition(1, false);
+        }
 
-            if (this._columnDefinitions.length === 0) {
-                // Add default column definition
-                this.addColumnDefinition(1, false);
-            }
+        let x = Math.min(row, this._rowDefinitions.length - 1);
+        let y = Math.min(column, this._columnDefinitions.length - 1);
+        let key = `${x}:${y}`;
+        let goodContainer = this._cells[key];
+
+        if (!goodContainer) {
+            goodContainer = new Container(key);
+            this._cells[key] = goodContainer;
+            goodContainer.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+            goodContainer.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
+            super.addControl(goodContainer);
+        }
 
-            let x = Math.min(row, this._rowDefinitions.length - 1);
-            let y = Math.min(column, this._columnDefinitions.length - 1);
-            let key = `${x}:${y}`;
-            let goodContainer = this._cells[key];
-
-            if (!goodContainer) {
-                goodContainer = new Container(key);
-                this._cells[key] = goodContainer;
-                goodContainer.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
-                goodContainer.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
-                super.addControl(goodContainer);
-            }
+        goodContainer.addControl(control);
+        this._childControls.push(control);
+        control._tag = key;
 
-            goodContainer.addControl(control);
-            this._childControls.push(control);
-            control._tag = key;
+        this._markAsDirty();
 
-            this._markAsDirty();            
+        return this;
+    }
 
-            return this;
+    /**
+     * Removes a control from the current container
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control): Container {
+        var index = this._childControls.indexOf(control);
+
+        if (index !== -1) {
+            this._childControls.splice(index, 1);
         }
 
-        /**
-         * Removes a control from the current container
-         * @param control defines the control to remove
-         * @returns the current container
-         */        
-        public removeControl(control: Control): Container {
-            var index = this._childControls.indexOf(control);
+        let cell = this._cells[control._tag];
 
-            if (index !== -1) {
-                this._childControls.splice(index, 1);
-            }
+        if (cell) {
+            cell.removeControl(control);
+        }
 
-            let cell = this._cells[control._tag];
+        this._markAsDirty();
+        return this;
+    }
 
-            if (cell) {
-                cell.removeControl(control);
-            }
+    /**
+     * Creates a new Grid
+     * @param name defines control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
 
-            this._markAsDirty();
-            return this;
-        }        
-
-        /**
-         * Creates a new Grid
-         * @param name defines control name
-         */
-        constructor(public name?: string) {
-            super(name);
-        }
+    protected _getTypeName(): string {
+        return "Grid";
+    }
 
-        protected _getTypeName(): string {
-            return "Grid";
-        }   
-
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            let widths = [];
-            let heights = [];
-            let lefts = [];
-            let tops = [];
-
-            let availableWidth = this._currentMeasure.width;
-            let globalWidthPercentage = 0;
-            let availableHeight = this._currentMeasure.height;
-            let globalHeightPercentage = 0;
-
-            // Heights
-            let index = 0;
-            for (var value of this._rowDefinitions) {
-                if (value.isPixel) {
-                    let height = value.getValue(this._host);
-                    availableHeight -= height;
-                    heights[index] = height;
-                } else {
-                    globalHeightPercentage += value.internalValue;
-                }
-                index++;
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        let widths = [];
+        let heights = [];
+        let lefts = [];
+        let tops = [];
+
+        let availableWidth = this._currentMeasure.width;
+        let globalWidthPercentage = 0;
+        let availableHeight = this._currentMeasure.height;
+        let globalHeightPercentage = 0;
+
+        // Heights
+        let index = 0;
+        for (var value of this._rowDefinitions) {
+            if (value.isPixel) {
+                let height = value.getValue(this._host);
+                availableHeight -= height;
+                heights[index] = height;
+            } else {
+                globalHeightPercentage += value.internalValue;
             }
+            index++;
+        }
 
-            let top = 0;
-            index = 0;
-            for (var value of this._rowDefinitions) {
-                tops.push(top);
-
-                if (!value.isPixel) {
-                    let height = (value.internalValue / globalHeightPercentage) * availableHeight;
-                    top += height;
-                    heights[index] = height;
-                } else {
-                    top += value.getValue(this._host);
-                }
-                index++;
+        let top = 0;
+        index = 0;
+        for (var value of this._rowDefinitions) {
+            tops.push(top);
+
+            if (!value.isPixel) {
+                let height = (value.internalValue / globalHeightPercentage) * availableHeight;
+                top += height;
+                heights[index] = height;
+            } else {
+                top += value.getValue(this._host);
             }
+            index++;
+        }
 
-            // Widths
-            index = 0;
-            for (var value of this._columnDefinitions) {
-                if (value.isPixel) {
-                    let width = value.getValue(this._host);
-                    availableWidth -= width;
-                    widths[index] = width;
-                } else {
-                    globalWidthPercentage += value.internalValue;
-                }
-                index++;
+        // Widths
+        index = 0;
+        for (var value of this._columnDefinitions) {
+            if (value.isPixel) {
+                let width = value.getValue(this._host);
+                availableWidth -= width;
+                widths[index] = width;
+            } else {
+                globalWidthPercentage += value.internalValue;
             }
+            index++;
+        }
 
-            let left = 0;
-            index = 0;
-            for (var value of this._columnDefinitions) {
-                lefts.push(left);
-                if (!value.isPixel) {
-                    let width = (value.internalValue / globalWidthPercentage) * availableWidth;
-                    left += width;
-                    widths[index] = width;
-                }  else {
-                    left += value.getValue(this._host);
-                }
-                index++;
-            }       
-            
-            // Setting child sizes
-            for (var key in this._cells) {
-                if (!this._cells.hasOwnProperty(key)) {
-                    continue;
-                }
-                let split = key.split(":");
-                let x = parseInt(split[0]);
-                let y = parseInt(split[1]);
-                let cell = this._cells[key];
-
-                cell.left = lefts[y] + "px";
-                cell.top = tops[x] + "px";
-                cell.width = widths[y] + "px";
-                cell.height = heights[x] + "px";
+        let left = 0;
+        index = 0;
+        for (var value of this._columnDefinitions) {
+            lefts.push(left);
+            if (!value.isPixel) {
+                let width = (value.internalValue / globalWidthPercentage) * availableWidth;
+                left += width;
+                widths[index] = width;
+            } else {
+                left += value.getValue(this._host);
             }
+            index++;
+        }
 
-            super._additionalProcessing(parentMeasure, context);
+        // Setting child sizes
+        for (var key in this._cells) {
+            if (!this._cells.hasOwnProperty(key)) {
+                continue;
+            }
+            let split = key.split(":");
+            let x = parseInt(split[0]);
+            let y = parseInt(split[1]);
+            let cell = this._cells[key];
+
+            cell.left = lefts[y] + "px";
+            cell.top = tops[x] + "px";
+            cell.width = widths[y] + "px";
+            cell.height = heights[x] + "px";
         }
 
-        /** Releases associated resources */
-        public dispose() {
-            super.dispose();
+        super._additionalProcessing(parentMeasure, context);
+    }
+
+    /** Releases associated resources */
+    public dispose() {
+        super.dispose();
 
-            for (var control of this._childControls) {
-                control.dispose();
-            }
+        for (var control of this._childControls) {
+            control.dispose();
         }
     }
 }

+ 279 - 279
gui/src/2D/controls/image.ts

@@ -1,351 +1,351 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { Nullable, Tools } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create 2D images
+ */
+class GUIImage extends Control {
+    private _domImage: HTMLImageElement;
+    private _imageWidth: number;
+    private _imageHeight: number;
+    private _loaded = false;
+    private _stretch = GUIImage.STRETCH_FILL;
+    private _source: Nullable<string>;
+    private _autoScale = false;
+
+    private _sourceLeft = 0;
+    private _sourceTop = 0;
+    private _sourceWidth = 0;
+    private _sourceHeight = 0;
+
+    private _cellWidth: number = 0;
+    private _cellHeight: number = 0;
+    private _cellId: number = -1;
 
-var DOMImage = Image;
-
-module BABYLON.GUI {
     /**
-     * Class used to create 2D images
+     * Gets or sets the left coordinate in the source image
      */
-    export class Image extends Control {
-        private _domImage: HTMLImageElement;
-        private _imageWidth: number;
-        private _imageHeight: number;
-        private _loaded = false;
-        private _stretch = Image.STRETCH_FILL;
-        private _source: Nullable<string>;
-        private _autoScale = false;
-
-        private _sourceLeft = 0;
-        private _sourceTop = 0;
-        private _sourceWidth = 0;
-        private _sourceHeight = 0;
-
-        private _cellWidth: number = 0;
-        private _cellHeight: number = 0;
-        private _cellId: number = -1;
-
-        /**
-         * Gets or sets the left coordinate in the source image
-         */
-        public get sourceLeft(): number {
-            return this._sourceLeft;
+    public get sourceLeft(): number {
+        return this._sourceLeft;
+    }
+
+    public set sourceLeft(value: number) {
+        if (this._sourceLeft === value) {
+            return;
         }
 
-        public set sourceLeft(value: number) {
-            if (this._sourceLeft === value) {
-                return;
-            }
+        this._sourceLeft = value;
 
-            this._sourceLeft = value;
+        this._markAsDirty();
+    }
 
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets the top coordinate in the source image
+     */
+    public get sourceTop(): number {
+        return this._sourceTop;
+    }
 
-        /**
-         * Gets or sets the top coordinate in the source image
-         */        
-        public get sourceTop(): number {
-            return this._sourceTop;
+    public set sourceTop(value: number) {
+        if (this._sourceTop === value) {
+            return;
         }
 
-        public set sourceTop(value: number) {
-            if (this._sourceTop === value) {
-                return;
-            }
+        this._sourceTop = value;
 
-            this._sourceTop = value;
+        this._markAsDirty();
+    }
 
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets the width to capture in the source image
+     */
+    public get sourceWidth(): number {
+        return this._sourceWidth;
+    }
 
-        /**
-         * Gets or sets the width to capture in the source image
-         */        
-        public get sourceWidth(): number {
-            return this._sourceWidth;
+    public set sourceWidth(value: number) {
+        if (this._sourceWidth === value) {
+            return;
         }
 
-        public set sourceWidth(value: number) {
-            if (this._sourceWidth === value) {
-                return;
-            }
+        this._sourceWidth = value;
 
-            this._sourceWidth = value;
+        this._markAsDirty();
+    }
 
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets the height to capture in the source image
+     */
+    public get sourceHeight(): number {
+        return this._sourceHeight;
+    }
 
-        /**
-         * Gets or sets the height to capture in the source image
-         */        
-        public get sourceHeight(): number {
-            return this._sourceHeight;
+    public set sourceHeight(value: number) {
+        if (this._sourceHeight === value) {
+            return;
         }
 
-        public set sourceHeight(value: number) {
-            if (this._sourceHeight === value) {
-                return;
-            }
+        this._sourceHeight = value;
 
-            this._sourceHeight = value;
+        this._markAsDirty();
+    }
 
-            this._markAsDirty();
-        }
+    /** 
+     * Gets or sets a boolean indicating if the image can force its container to adapt its size 
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    public get autoScale(): boolean {
+        return this._autoScale;
+    }
 
-        /** 
-         * Gets or sets a boolean indicating if the image can force its container to adapt its size 
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        public get autoScale(): boolean {
-            return this._autoScale;
+    public set autoScale(value: boolean) {
+        if (this._autoScale === value) {
+            return;
         }
 
-        public set autoScale(value: boolean) {
-            if (this._autoScale === value) {
-                return;
-            }
-
-            this._autoScale = value;
+        this._autoScale = value;
 
-            if (value && this._loaded) {
-                this.synchronizeSizeWithContent();
-            }
+        if (value && this._loaded) {
+            this.synchronizeSizeWithContent();
         }
+    }
 
-        /** Gets or sets the streching mode used by the image */
-        public get stretch(): number {
-            return this._stretch;
-        }
+    /** Gets or sets the streching mode used by the image */
+    public get stretch(): number {
+        return this._stretch;
+    }
 
-        public set stretch(value: number) {
-            if (this._stretch === value) {
-                return;
-            }
+    public set stretch(value: number) {
+        if (this._stretch === value) {
+            return;
+        }
 
-            this._stretch = value;
+        this._stretch = value;
 
-            this._markAsDirty();
-        }
+        this._markAsDirty();
+    }
 
-        /**
-         * Gets or sets the internal DOM image used to render the control
-         */
-        public set domImage(value: HTMLImageElement) {
-            this._domImage = value;
-            this._loaded = false;
+    /**
+     * Gets or sets the internal DOM image used to render the control
+     */
+    public set domImage(value: HTMLImageElement) {
+        this._domImage = value;
+        this._loaded = false;
 
-            if (this._domImage.width) {
+        if (this._domImage.width) {
+            this._onImageLoaded();
+        } else {
+            this._domImage.onload = () => {
                 this._onImageLoaded();
-            } else {
-                this._domImage.onload = () => {
-                    this._onImageLoaded();
-                }
             }
         }
+    }
 
-        public get domImage(): HTMLImageElement {
-            return this._domImage;
-        }
-
-        private _onImageLoaded(): void {
-            this._imageWidth = this._domImage.width;
-            this._imageHeight = this._domImage.height;
-            this._loaded = true;
+    public get domImage(): HTMLImageElement {
+        return this._domImage;
+    }
 
-            if (this._autoScale) {
-                this.synchronizeSizeWithContent();
-            }
+    private _onImageLoaded(): void {
+        this._imageWidth = this._domImage.width;
+        this._imageHeight = this._domImage.height;
+        this._loaded = true;
 
-            this._markAsDirty();
+        if (this._autoScale) {
+            this.synchronizeSizeWithContent();
         }
 
-        /**
-         * Gets or sets image source url
-         */
-        public set source(value: Nullable<string>) {
-            if (this._source === value) {
-                return;
-            }
+        this._markAsDirty();
+    }
 
-            this._loaded = false;
-            this._source = value;
+    /**
+     * Gets or sets image source url
+     */
+    public set source(value: Nullable<string>) {
+        if (this._source === value) {
+            return;
+        }
 
-            this._domImage = new DOMImage();
+        this._loaded = false;
+        this._source = value;
 
-            this._domImage.onload = () => {
-                this._onImageLoaded();
-            }
-            if (value) {
-                Tools.SetCorsBehavior(value, this._domImage);
-                this._domImage.src = value;
-            }
-        }
+        this._domImage = new Image();
 
-        /** 
-         * Gets or sets the cell width to use when animation sheet is enabled 
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        get cellWidth(): number {
-            return this._cellWidth;
+        this._domImage.onload = () => {
+            this._onImageLoaded();
         }
-        set cellWidth(value: number) {
-            if(this._cellWidth === value){
-                return;
-            }
-            
-            this._cellWidth = value;
-            this._markAsDirty();
+        if (value) {
+            Tools.SetCorsBehavior(value, this._domImage);
+            this._domImage.src = value;
         }
+    }
 
-        /** 
-         * Gets or sets the cell height to use when animation sheet is enabled 
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        get cellHeight(): number {
-            return this._cellHeight;
-        }
-        set cellHeight(value: number) {
-            if(this._cellHeight === value){
-                return;
-            }
-            
-            this._cellHeight = value;
-            this._markAsDirty();
-        }
-    
-        /** 
-         * Gets or sets the cell id to use (this will turn on the animation sheet mode)
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        get cellId(): number {
-            return this._cellId;
-        }
-        set cellId(value: number) {
-            if (this._cellId === value) {
-                 return;
-             }
-            
-            this._cellId = value;
-            this._markAsDirty();
+    /** 
+     * Gets or sets the cell width to use when animation sheet is enabled 
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    get cellWidth(): number {
+        return this._cellWidth;
+    }
+    set cellWidth(value: number) {
+        if (this._cellWidth === value) {
+            return;
         }
 
-        /**
-         * Creates a new Image
-         * @param name defines the control name
-         * @param url defines the image url
-         */
-        constructor(public name?: string, url: Nullable<string> = null) {
-            super(name);
+        this._cellWidth = value;
+        this._markAsDirty();
+    }
 
-            this.source = url;
+    /** 
+     * Gets or sets the cell height to use when animation sheet is enabled 
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    get cellHeight(): number {
+        return this._cellHeight;
+    }
+    set cellHeight(value: number) {
+        if (this._cellHeight === value) {
+            return;
         }
 
-        protected _getTypeName(): string {
-            return "Image";
+        this._cellHeight = value;
+        this._markAsDirty();
+    }
+
+    /** 
+     * Gets or sets the cell id to use (this will turn on the animation sheet mode)
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    get cellId(): number {
+        return this._cellId;
+    }
+    set cellId(value: number) {
+        if (this._cellId === value) {
+            return;
         }
 
-        /** Force the control to synchronize with its content */
-        public synchronizeSizeWithContent() {
-            if (!this._loaded) {
-                return;
-            }
+        this._cellId = value;
+        this._markAsDirty();
+    }
 
-            this.width = this._domImage.width + "px";
-            this.height = this._domImage.height + "px";
+    /**
+     * Creates a new Image
+     * @param name defines the control name
+     * @param url defines the image url
+     */
+    constructor(public name?: string, url: Nullable<string> = null) {
+        super(name);
+
+        this.source = url;
+    }
+
+    protected _getTypeName(): string {
+        return "Image";
+    }
+
+    /** Force the control to synchronize with its content */
+    public synchronizeSizeWithContent() {
+        if (!this._loaded) {
+            return;
         }
 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+        this.width = this._domImage.width + "px";
+        this.height = this._domImage.height + "px";
+    }
 
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
-            let x, y, width, height;
-            if (this.cellId == -1) {
-                x = this._sourceLeft;
-                y = this._sourceTop;
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
+        }
 
-                width = this._sourceWidth ? this._sourceWidth : this._imageWidth;
-                height = this._sourceHeight ? this._sourceHeight : this._imageHeight;
-            }
-            else {
-                let rowCount = this._domImage.naturalWidth / this.cellWidth;
-                let column = (this.cellId / rowCount) >> 0;
-                let row = this.cellId % rowCount;
-
-                x = this.cellWidth * row;
-                y = this.cellHeight * column;
-                width = this.cellWidth;
-                height = this.cellHeight;
-            }
+        let x, y, width, height;
+        if (this.cellId == -1) {
+            x = this._sourceLeft;
+            y = this._sourceTop;
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                if (this._loaded) {
-                    switch (this._stretch) {
-                        case Image.STRETCH_NONE:
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                            break;
-                        case Image.STRETCH_FILL:
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                            break;
-                        case Image.STRETCH_UNIFORM:
-                            var hRatio = this._currentMeasure.width / width;
-                            var vRatio = this._currentMeasure.height / height;
-                            var ratio = Math.min(hRatio, vRatio);
-                            var centerX = (this._currentMeasure.width - width * ratio) / 2;
-                            var centerY = (this._currentMeasure.height - height * ratio) / 2;
-
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left + centerX, this._currentMeasure.top + centerY, width * ratio, height * ratio);
-                            break;
-                        case Image.STRETCH_EXTEND:
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                            if (this._autoScale) {
-                                this.synchronizeSizeWithContent();
-                            }
-                            if (this._root && this._root.parent) { // Will update root size if root is not the top root
-                                this._root.width = this.width;
-                                this._root.height = this.height;
-                            }
-                            break;
-                    }
+            width = this._sourceWidth ? this._sourceWidth : this._imageWidth;
+            height = this._sourceHeight ? this._sourceHeight : this._imageHeight;
+        }
+        else {
+            let rowCount = this._domImage.naturalWidth / this.cellWidth;
+            let column = (this.cellId / rowCount) >> 0;
+            let row = this.cellId % rowCount;
+
+            x = this.cellWidth * row;
+            y = this.cellHeight * column;
+            width = this.cellWidth;
+            height = this.cellHeight;
+        }
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            if (this._loaded) {
+                switch (this._stretch) {
+                    case GUIImage.STRETCH_NONE:
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+                        break;
+                    case GUIImage.STRETCH_FILL:
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+                        break;
+                    case GUIImage.STRETCH_UNIFORM:
+                        var hRatio = this._currentMeasure.width / width;
+                        var vRatio = this._currentMeasure.height / height;
+                        var ratio = Math.min(hRatio, vRatio);
+                        var centerX = (this._currentMeasure.width - width * ratio) / 2;
+                        var centerY = (this._currentMeasure.height - height * ratio) / 2;
+
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left + centerX, this._currentMeasure.top + centerY, width * ratio, height * ratio);
+                        break;
+                    case GUIImage.STRETCH_EXTEND:
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+                        if (this._autoScale) {
+                            this.synchronizeSizeWithContent();
+                        }
+                        if (this._root && this._root.parent) { // Will update root size if root is not the top root
+                            this._root.width = this.width;
+                            this._root.height = this.height;
+                        }
+                        break;
                 }
             }
-            context.restore();
         }
+        context.restore();
+    }
 
-        // Static
-        private static _STRETCH_NONE = 0;
-        private static _STRETCH_FILL = 1;
-        private static _STRETCH_UNIFORM = 2;
-        private static _STRETCH_EXTEND = 3;
+    // Static
+    private static _STRETCH_NONE = 0;
+    private static _STRETCH_FILL = 1;
+    private static _STRETCH_UNIFORM = 2;
+    private static _STRETCH_EXTEND = 3;
 
-        /** STRETCH_NONE */
-        public static get STRETCH_NONE(): number {
-            return Image._STRETCH_NONE;
-        }
+    /** STRETCH_NONE */
+    public static get STRETCH_NONE(): number {
+        return GUIImage._STRETCH_NONE;
+    }
 
-        /** STRETCH_FILL */
-        public static get STRETCH_FILL(): number {
-            return Image._STRETCH_FILL;
-        }
+    /** STRETCH_FILL */
+    public static get STRETCH_FILL(): number {
+        return GUIImage._STRETCH_FILL;
+    }
 
-        /** STRETCH_UNIFORM */
-        public static get STRETCH_UNIFORM(): number {
-            return Image._STRETCH_UNIFORM;
-        }
+    /** STRETCH_UNIFORM */
+    public static get STRETCH_UNIFORM(): number {
+        return GUIImage._STRETCH_UNIFORM;
+    }
 
-        /** STRETCH_EXTEND */
-        public static get STRETCH_EXTEND(): number {
-            return Image._STRETCH_EXTEND;
-        }
+    /** STRETCH_EXTEND */
+    public static get STRETCH_EXTEND(): number {
+        return GUIImage._STRETCH_EXTEND;
     }
 }
+
+export { GUIImage as Image };

+ 12 - 0
gui/src/2D/controls/index.ts

@@ -0,0 +1,12 @@
+export * from "./button";
+export * from "./checkbox";
+export * from "./colorpicker";
+export * from "./container";
+export * from "./control";
+export * from "./ellipse";
+export * from "./grid";
+export * from "./image";
+export * from "./inputText";
+export * from "./line";
+export * from "./multiLine";
+export * from "./radioButton";

+ 390 - 388
gui/src/2D/controls/inputText.ts

@@ -1,492 +1,494 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { IFocusableControl } from "../advancedDynamicTexture";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Nullable, Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create input text control
+ */
+export class InputText extends Control implements IFocusableControl {
+    private _text = "";
+    private _placeholderText = "";
+    private _background = "#222222";
+    private _focusedBackground = "#000000";
+    private _placeholderColor = "gray";
+    private _thickness = 1;
+    private _margin = new ValueAndUnit(10, ValueAndUnit.UNITMODE_PIXEL);
+    private _autoStretchWidth = true;
+    private _maxWidth = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
+    private _isFocused = false;
+    private _blinkTimeout: number;
+    private _blinkIsEven = false;
+    private _cursorOffset = 0;
+    private _scrollLeft: Nullable<number>;
+    private _textWidth: number;
+    private _clickedCoordinate: Nullable<number>;
+
+    /** Gets or sets a string representing the message displayed on mobile when the control gets the focus */
+    public promptMessage = "Please enter text:";
+
+    /** Observable raised when the text changes */
+    public onTextChangedObservable = new Observable<InputText>();
+    /** Observable raised when the control gets the focus */
+    public onFocusObservable = new Observable<InputText>();
+    /** Observable raised when the control loses the focus */
+    public onBlurObservable = new Observable<InputText>();
+
+    /** Gets or sets the maximum width allowed by the control */
+    public get maxWidth(): string | number {
+        return this._maxWidth.toString(this._host);
+    }
 
-module BABYLON.GUI {
-    /**
-     * Class used to create input text control
-     */
-    export class InputText extends Control implements IFocusableControl {
-        private _text = "";
-        private _placeholderText = "";
-        private _background = "#222222";
-        private _focusedBackground = "#000000";
-        private _placeholderColor = "gray";
-        private _thickness = 1;
-        private _margin = new ValueAndUnit(10, ValueAndUnit.UNITMODE_PIXEL);
-        private _autoStretchWidth = true;
-        private _maxWidth = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
-        private _isFocused = false;
-        private _blinkTimeout: number;
-        private _blinkIsEven = false;
-        private _cursorOffset = 0;
-        private _scrollLeft: Nullable<number>;
-        private _textWidth: number;
-        private _clickedCoordinate: Nullable<number>;
-
-        /** Gets or sets a string representing the message displayed on mobile when the control gets the focus */
-        public promptMessage = "Please enter text:";
-
-        /** Observable raised when the text changes */
-        public onTextChangedObservable = new Observable<InputText>();
-        /** Observable raised when the control gets the focus */
-        public onFocusObservable = new Observable<InputText>();
-        /** Observable raised when the control loses the focus */
-        public onBlurObservable = new Observable<InputText>();
-
-        /** Gets or sets the maximum width allowed by the control */
-        public get maxWidth(): string | number {
-            return this._maxWidth.toString(this._host);
+    /** Gets the maximum width allowed by the control in pixels */
+    public get maxWidthInPixels(): number {
+        return this._maxWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
+
+    public set maxWidth(value: string | number) {
+        if (this._maxWidth.toString(this._host) === value) {
+            return;
         }
 
-        /** Gets the maximum width allowed by the control in pixels */
-        public get maxWidthInPixels(): number {
-            return this._maxWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._maxWidth.fromString(value)) {
+            this._markAsDirty();
         }
+    }
 
-        public set maxWidth(value: string | number) {
-            if (this._maxWidth.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets control margin */
+    public get margin(): string {
+        return this._margin.toString(this._host);
+    }
 
-            if (this._maxWidth.fromString(value)) {
-                this._markAsDirty();
-            }
-        }
+    /** Gets control margin in pixels */
+    public get marginInPixels(): number {
+        return this._margin.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
 
-        /** Gets or sets control margin */
-        public get margin(): string {
-            return this._margin.toString(this._host);
+    public set margin(value: string) {
+        if (this._margin.toString(this._host) === value) {
+            return;
         }
 
-        /** Gets control margin in pixels */
-        public get marginInPixels(): number {
-            return this._margin.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._margin.fromString(value)) {
+            this._markAsDirty();
         }
+    }
 
-        public set margin(value: string) {
-            if (this._margin.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets a boolean indicating if the control can auto stretch its width to adapt to the text */
+    public get autoStretchWidth(): boolean {
+        return this._autoStretchWidth;
+    }
 
-            if (this._margin.fromString(value)) {
-                this._markAsDirty();
-            }
+    public set autoStretchWidth(value: boolean) {
+        if (this._autoStretchWidth === value) {
+            return;
         }
 
-        /** Gets or sets a boolean indicating if the control can auto stretch its width to adapt to the text */
-        public get autoStretchWidth(): boolean {
-            return this._autoStretchWidth;
-        }
+        this._autoStretchWidth = value;
+        this._markAsDirty();
+    }
 
-        public set autoStretchWidth(value: boolean) {
-            if (this._autoStretchWidth === value) {
-                return;
-            }
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
 
-            this._autoStretchWidth = value;
-            this._markAsDirty();
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
 
-        /** Gets or sets border thickness */
-        public get thickness(): number {
-            return this._thickness;
-        }
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+    /** Gets or sets the background color when focused */
+    public get focusedBackground(): string {
+        return this._focusedBackground;
+    }
 
-            this._thickness = value;
-            this._markAsDirty();
+    public set focusedBackground(value: string) {
+        if (this._focusedBackground === value) {
+            return;
         }
 
-        /** Gets or sets the background color when focused */
-        public get focusedBackground(): string {
-            return this._focusedBackground;
-        }
+        this._focusedBackground = value;
+        this._markAsDirty();
+    }
 
-        public set focusedBackground(value: string) {
-            if (this._focusedBackground === value) {
-                return;
-            }
+    /** Gets or sets the background color */
+    public get background(): string {
+        return this._background;
+    }
 
-            this._focusedBackground = value;
-            this._markAsDirty();
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
 
-        /** Gets or sets the background color */
-        public get background(): string {
-            return this._background;
-        }
+        this._background = value;
+        this._markAsDirty();
+    }
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+    /** Gets or sets the placeholder color */
+    public get placeholderColor(): string {
+        return this._placeholderColor;
+    }
 
-            this._background = value;
-            this._markAsDirty();
+    public set placeholderColor(value: string) {
+        if (this._placeholderColor === value) {
+            return;
         }
 
-        /** Gets or sets the placeholder color */
-        public get placeholderColor(): string {
-            return this._placeholderColor;
-        }
+        this._placeholderColor = value;
+        this._markAsDirty();
+    }
 
-        public set placeholderColor(value: string) {
-            if (this._placeholderColor === value) {
-                return;
-            }
+    /** Gets or sets the text displayed when the control is empty */
+    public get placeholderText(): string {
+        return this._placeholderText;
+    }
 
-            this._placeholderColor = value;
-            this._markAsDirty();
+    public set placeholderText(value: string) {
+        if (this._placeholderText === value) {
+            return;
         }
+        this._placeholderText = value;
+        this._markAsDirty();
+    }
 
-        /** Gets or sets the text displayed when the control is empty */
-        public get placeholderText(): string {
-            return this._placeholderText;
-        }
+    /** Gets or sets the text displayed in the control */
+    public get text(): string {
+        return this._text;
+    }
 
-        public set placeholderText(value: string) {
-            if (this._placeholderText === value) {
-                return;
-            }
-            this._placeholderText = value;
-            this._markAsDirty();
+    public set text(value: string) {
+        if (this._text === value) {
+            return;
         }
+        this._text = value;
+        this._markAsDirty();
 
-        /** Gets or sets the text displayed in the control */
-        public get text(): string {
-            return this._text;
-        }
+        this.onTextChangedObservable.notifyObservers(this);
+    }
 
-        public set text(value: string) {
-            if (this._text === value) {
-                return;
-            }
-            this._text = value;
-            this._markAsDirty();
+    /** Gets or sets control width */
+    public get width(): string | number {
+        return this._width.toString(this._host);
+    }
 
-            this.onTextChangedObservable.notifyObservers(this);
+    public set width(value: string | number) {
+        if (this._width.toString(this._host) === value) {
+            return;
         }
 
-        /** Gets or sets control width */
-        public get width(): string | number {
-            return this._width.toString(this._host);
+        if (this._width.fromString(value)) {
+            this._markAsDirty();
         }
 
-        public set width(value: string | number) {
-            if (this._width.toString(this._host) === value) {
-                return;
-            }
-
-            if (this._width.fromString(value)) {
-                this._markAsDirty();
-            }
-
-            this.autoStretchWidth = false;
-        }
+        this.autoStretchWidth = false;
+    }
 
-        /**
-         * Creates a new InputText
-         * @param name defines the control name
-         * @param text defines the text of the control
-         */
-        constructor(public name?: string, text: string = "") {
-            super(name);
+    /**
+     * Creates a new InputText
+     * @param name defines the control name
+     * @param text defines the text of the control
+     */
+    constructor(public name?: string, text: string = "") {
+        super(name);
 
-            this.text = text;
-        }
+        this.text = text;
+    }
 
-        /** @hidden */
-        public onBlur(): void {
-            this._isFocused = false;
-            this._scrollLeft = null;
-            this._cursorOffset = 0;
-            clearTimeout(this._blinkTimeout);
-            this._markAsDirty();
+    /** @hidden */
+    public onBlur(): void {
+        this._isFocused = false;
+        this._scrollLeft = null;
+        this._cursorOffset = 0;
+        clearTimeout(this._blinkTimeout);
+        this._markAsDirty();
 
-            this.onBlurObservable.notifyObservers(this);
-        }
+        this.onBlurObservable.notifyObservers(this);
+    }
 
-        /** @hidden */
-        public onFocus(): void {
-            this._scrollLeft = null;
-            this._isFocused = true;
-            this._blinkIsEven = false;
-            this._cursorOffset = 0;
-            this._markAsDirty();
+    /** @hidden */
+    public onFocus(): void {
+        this._scrollLeft = null;
+        this._isFocused = true;
+        this._blinkIsEven = false;
+        this._cursorOffset = 0;
+        this._markAsDirty();
 
-            this.onFocusObservable.notifyObservers(this);
+        this.onFocusObservable.notifyObservers(this);
 
-            if (navigator.userAgent.indexOf("Mobile") !== -1) {
-                let value = prompt(this.promptMessage);
+        if (navigator.userAgent.indexOf("Mobile") !== -1) {
+            let value = prompt(this.promptMessage);
 
-                if (value !== null) {
-                    this.text = value;
-                }
-                this._host.focusedControl = null;
-                return;
+            if (value !== null) {
+                this.text = value;
             }
+            this._host.focusedControl = null;
+            return;
         }
+    }
 
-        protected _getTypeName(): string {
-            return "InputText";
-        }
+    protected _getTypeName(): string {
+        return "InputText";
+    }
 
-        /** @hidden */
-        public processKey(keyCode: number, key?: string) {
-            // Specific cases
-            switch (keyCode) {
-                case 32: //SPACE
-                    key = " "; //ie11 key for space is "Spacebar" 
-                    break;
-                case 8: // BACKSPACE
-                    if (this._text && this._text.length > 0) {
-                        if (this._cursorOffset === 0) {
-                            this.text = this._text.substr(0, this._text.length - 1);
-                        } else {
-                            let deletePosition = this._text.length - this._cursorOffset;
-                            if (deletePosition > 0) {
-                                this.text = this._text.slice(0, deletePosition - 1) + this._text.slice(deletePosition);
-                            }
-                        }
-                    }
-                    return;
-                case 46: // DELETE
-                    if (this._text && this._text.length > 0) {
+    /** @hidden */
+    public processKey(keyCode: number, key?: string) {
+        // Specific cases
+        switch (keyCode) {
+            case 32: //SPACE
+                key = " "; //ie11 key for space is "Spacebar" 
+                break;
+            case 8: // BACKSPACE
+                if (this._text && this._text.length > 0) {
+                    if (this._cursorOffset === 0) {
+                        this.text = this._text.substr(0, this._text.length - 1);
+                    } else {
                         let deletePosition = this._text.length - this._cursorOffset;
-                        this.text = this._text.slice(0, deletePosition) + this._text.slice(deletePosition + 1);
-                        this._cursorOffset--;
-                    }
-                    return;
-                case 13: // RETURN
-                    this._host.focusedControl = null;
-                    return;
-                case 35: // END
-                    this._cursorOffset = 0;
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-                case 36: // HOME
-                    this._cursorOffset = this._text.length;
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-                case 37: // LEFT
-                    this._cursorOffset++;
-                    if (this._cursorOffset > this._text.length) {
-                        this._cursorOffset = this._text.length;
+                        if (deletePosition > 0) {
+                            this.text = this._text.slice(0, deletePosition - 1) + this._text.slice(deletePosition);
+                        }
                     }
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-                case 39: // RIGHT
+                }
+                return;
+            case 46: // DELETE
+                if (this._text && this._text.length > 0) {
+                    let deletePosition = this._text.length - this._cursorOffset;
+                    this.text = this._text.slice(0, deletePosition) + this._text.slice(deletePosition + 1);
                     this._cursorOffset--;
-                    if (this._cursorOffset < 0) {
-                        this._cursorOffset = 0;
-                    }
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-            }
-
-            // Printable characters
-            if (
-                (keyCode === -1) ||                     // Direct access
-                (keyCode === 32) ||                     // Space
-                (keyCode > 47 && keyCode < 58) ||       // Numbers
-                (keyCode > 64 && keyCode < 91) ||       // Letters
-                (keyCode > 185 && keyCode < 193) ||     // Special characters
-                (keyCode > 218 && keyCode < 223) ||    // Special characters
-                (keyCode > 95 && keyCode < 112)) {      // Numpad
-                if (this._cursorOffset === 0) {
-                    this.text += key;
-                } else {
-                    let insertPosition = this._text.length - this._cursorOffset;
-
-                    this.text = this._text.slice(0, insertPosition) + key + this._text.slice(insertPosition);
                 }
-            }
+                return;
+            case 13: // RETURN
+                this._host.focusedControl = null;
+                return;
+            case 35: // END
+                this._cursorOffset = 0;
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
+            case 36: // HOME
+                this._cursorOffset = this._text.length;
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
+            case 37: // LEFT
+                this._cursorOffset++;
+                if (this._cursorOffset > this._text.length) {
+                    this._cursorOffset = this._text.length;
+                }
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
+            case 39: // RIGHT
+                this._cursorOffset--;
+                if (this._cursorOffset < 0) {
+                    this._cursorOffset = 0;
+                }
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
         }
 
-        /** @hidden */       
-        public processKeyboard(evt: KeyboardEvent): void {
-            this.processKey(evt.keyCode, evt.key);
+        // Printable characters
+        if (
+            (keyCode === -1) ||                     // Direct access
+            (keyCode === 32) ||                     // Space
+            (keyCode > 47 && keyCode < 58) ||       // Numbers
+            (keyCode > 64 && keyCode < 91) ||       // Letters
+            (keyCode > 185 && keyCode < 193) ||     // Special characters
+            (keyCode > 218 && keyCode < 223) ||    // Special characters
+            (keyCode > 95 && keyCode < 112)) {      // Numpad
+            if (this._cursorOffset === 0) {
+                this.text += key;
+            } else {
+                let insertPosition = this._text.length - this._cursorOffset;
+
+                this.text = this._text.slice(0, insertPosition) + key + this._text.slice(insertPosition);
+            }
         }
+    }
 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+    /** @hidden */
+    public processKeyboard(evt: KeyboardEvent): void {
+        this.processKey(evt.keyCode, evt.key);
+    }
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
-                if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
 
-                // Background
-                if (this._isFocused) {
-                    if (this._focusedBackground) {
-                        context.fillStyle = this._focusedBackground;
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
 
-                        context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                    }
-                } else if (this._background) {
-                    context.fillStyle = this._background;
+            // Background
+            if (this._isFocused) {
+                if (this._focusedBackground) {
+                    context.fillStyle = this._focusedBackground;
 
                     context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
                 }
+            } else if (this._background) {
+                context.fillStyle = this._background;
 
-                if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+                context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+            }
 
-                if (!this._fontOffset) {
-                    this._fontOffset = Control._GetFontOffset(context.font);
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
+            }
 
-                // Text
-                let clipTextLeft = this._currentMeasure.left + this._margin.getValueInPixel(this._host, parentMeasure.width);
-                if (this.color) {
-                    context.fillStyle = this.color;
-                }
+            if (!this._fontOffset) {
+                this._fontOffset = Control._GetFontOffset(context.font);
+            }
 
-                let text = this._text;
+            // Text
+            let clipTextLeft = this._currentMeasure.left + this._margin.getValueInPixel(this._host, parentMeasure.width);
+            if (this.color) {
+                context.fillStyle = this.color;
+            }
 
-                if (!this._isFocused && !this._text && this._placeholderText) {
-                    text = this._placeholderText;
+            let text = this._text;
 
-                    if (this._placeholderColor) {
-                        context.fillStyle = this._placeholderColor;
-                    }
-                }
+            if (!this._isFocused && !this._text && this._placeholderText) {
+                text = this._placeholderText;
 
-                this._textWidth = context.measureText(text).width;
-                let marginWidth = this._margin.getValueInPixel(this._host, parentMeasure.width) * 2;
-                if (this._autoStretchWidth) {
-                    this.width = Math.min(this._maxWidth.getValueInPixel(this._host, parentMeasure.width), this._textWidth + marginWidth) + "px";
+                if (this._placeholderColor) {
+                    context.fillStyle = this._placeholderColor;
                 }
+            }
 
-                let rootY = this._fontOffset.ascent + (this._currentMeasure.height - this._fontOffset.height) / 2;
-                let availableWidth = this._width.getValueInPixel(this._host, parentMeasure.width) - marginWidth;
-                context.save();
-                context.beginPath();
-                context.rect(clipTextLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, availableWidth + 2, this._currentMeasure.height);
-                context.clip();
-
-                if (this._isFocused && this._textWidth > availableWidth) {
-                    let textLeft = clipTextLeft - this._textWidth + availableWidth;
-                    if (!this._scrollLeft) {
-                        this._scrollLeft = textLeft;
-                    }
-                } else {
-                    this._scrollLeft = clipTextLeft;
+            this._textWidth = context.measureText(text).width;
+            let marginWidth = this._margin.getValueInPixel(this._host, parentMeasure.width) * 2;
+            if (this._autoStretchWidth) {
+                this.width = Math.min(this._maxWidth.getValueInPixel(this._host, parentMeasure.width), this._textWidth + marginWidth) + "px";
+            }
+
+            let rootY = this._fontOffset.ascent + (this._currentMeasure.height - this._fontOffset.height) / 2;
+            let availableWidth = this._width.getValueInPixel(this._host, parentMeasure.width) - marginWidth;
+            context.save();
+            context.beginPath();
+            context.rect(clipTextLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, availableWidth + 2, this._currentMeasure.height);
+            context.clip();
+
+            if (this._isFocused && this._textWidth > availableWidth) {
+                let textLeft = clipTextLeft - this._textWidth + availableWidth;
+                if (!this._scrollLeft) {
+                    this._scrollLeft = textLeft;
                 }
+            } else {
+                this._scrollLeft = clipTextLeft;
+            }
 
-                context.fillText(text, this._scrollLeft, this._currentMeasure.top + rootY);
-
-                // Cursor
-                if (this._isFocused) {
-
-                    // Need to move cursor
-                    if (this._clickedCoordinate) {
-                        var rightPosition = this._scrollLeft + this._textWidth;
-                        var absoluteCursorPosition = rightPosition - this._clickedCoordinate;
-                        var currentSize = 0;
-                        this._cursorOffset = 0;
-                        var previousDist = 0;
-                        do {
-                            if (this._cursorOffset) {
-                                previousDist = Math.abs(absoluteCursorPosition - currentSize);
-                            }
-                            this._cursorOffset++;
-                            currentSize = context.measureText(text.substr(text.length - this._cursorOffset, this._cursorOffset)).width;
-
-                        } while (currentSize < absoluteCursorPosition && (text.length >= this._cursorOffset));
-
-                        // Find closest move
-                        if (Math.abs(absoluteCursorPosition - currentSize) > previousDist) {
-                            this._cursorOffset--;
-                        }
+            context.fillText(text, this._scrollLeft, this._currentMeasure.top + rootY);
 
-                        this._blinkIsEven = false;
-                        this._clickedCoordinate = null;
-                    }
+            // Cursor
+            if (this._isFocused) {
 
-                    // Render cursor
-                    if (!this._blinkIsEven) {
-                        let cursorOffsetText = this.text.substr(this._text.length - this._cursorOffset);
-                        let cursorOffsetWidth = context.measureText(cursorOffsetText).width;
-                        let cursorLeft = this._scrollLeft + this._textWidth - cursorOffsetWidth;
-
-                        if (cursorLeft < clipTextLeft) {
-                            this._scrollLeft += (clipTextLeft - cursorLeft);
-                            cursorLeft = clipTextLeft;
-                            this._markAsDirty();
-                        } else if (cursorLeft > clipTextLeft + availableWidth) {
-                            this._scrollLeft += (clipTextLeft + availableWidth - cursorLeft);
-                            cursorLeft = clipTextLeft + availableWidth;
-                            this._markAsDirty();
+                // Need to move cursor
+                if (this._clickedCoordinate) {
+                    var rightPosition = this._scrollLeft + this._textWidth;
+                    var absoluteCursorPosition = rightPosition - this._clickedCoordinate;
+                    var currentSize = 0;
+                    this._cursorOffset = 0;
+                    var previousDist = 0;
+                    do {
+                        if (this._cursorOffset) {
+                            previousDist = Math.abs(absoluteCursorPosition - currentSize);
                         }
-                        context.fillRect(cursorLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, 2, this._fontOffset.height);
+                        this._cursorOffset++;
+                        currentSize = context.measureText(text.substr(text.length - this._cursorOffset, this._cursorOffset)).width;
+
+                    } while (currentSize < absoluteCursorPosition && (text.length >= this._cursorOffset));
+
+                    // Find closest move
+                    if (Math.abs(absoluteCursorPosition - currentSize) > previousDist) {
+                        this._cursorOffset--;
                     }
 
-                    clearTimeout(this._blinkTimeout);
-                    this._blinkTimeout = setTimeout(() => {
-                        this._blinkIsEven = !this._blinkIsEven;
-                        this._markAsDirty();
-                    }, 500);
+                    this._blinkIsEven = false;
+                    this._clickedCoordinate = null;
                 }
 
-                context.restore();
+                // Render cursor
+                if (!this._blinkIsEven) {
+                    let cursorOffsetText = this.text.substr(this._text.length - this._cursorOffset);
+                    let cursorOffsetWidth = context.measureText(cursorOffsetText).width;
+                    let cursorLeft = this._scrollLeft + this._textWidth - cursorOffsetWidth;
 
-                // Border
-                if (this._thickness) {
-                    if (this.color) {
-                        context.strokeStyle = this.color;
+                    if (cursorLeft < clipTextLeft) {
+                        this._scrollLeft += (clipTextLeft - cursorLeft);
+                        cursorLeft = clipTextLeft;
+                        this._markAsDirty();
+                    } else if (cursorLeft > clipTextLeft + availableWidth) {
+                        this._scrollLeft += (clipTextLeft + availableWidth - cursorLeft);
+                        cursorLeft = clipTextLeft + availableWidth;
+                        this._markAsDirty();
                     }
-                    context.lineWidth = this._thickness;
-
-                    context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
-                        this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
+                    context.fillRect(cursorLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, 2, this._fontOffset.height);
                 }
+
+                clearTimeout(this._blinkTimeout);
+                this._blinkTimeout = setTimeout(() => {
+                    this._blinkIsEven = !this._blinkIsEven;
+                    this._markAsDirty();
+                }, 500);
             }
+
             context.restore();
-        }
 
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
+            // Border
+            if (this._thickness) {
+                if (this.color) {
+                    context.strokeStyle = this.color;
+                }
+                context.lineWidth = this._thickness;
 
-            this._clickedCoordinate = coordinates.x;
-            if (this._host.focusedControl === this) {
-                // Move cursor
-                clearTimeout(this._blinkTimeout);
-                this._markAsDirty();
-                return true;
+                context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
+                    this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
             }
-            this._host.focusedControl = this;
+        }
+        context.restore();
+    }
 
-            return true;
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
         }
 
-        public _onPointerUp(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+        this._clickedCoordinate = coordinates.x;
+        if (this._host.focusedControl === this) {
+            // Move cursor
+            clearTimeout(this._blinkTimeout);
+            this._markAsDirty();
+            return true;
         }
+        this._host.focusedControl = this;
 
-        public dispose() {
-            super.dispose();
+        return true;
+    }
 
-            this.onBlurObservable.clear();
-            this.onFocusObservable.clear();
-            this.onTextChangedObservable.clear();
-        }
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
+
+    public dispose() {
+        super.dispose();
+
+        this.onBlurObservable.clear();
+        this.onFocusObservable.clear();
+        this.onTextChangedObservable.clear();
     }
 }

+ 216 - 215
gui/src/2D/controls/line.ts

@@ -1,244 +1,245 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to render 2D lines */
-    export class Line extends Control {
-        private _lineWidth = 1;
-        private _x1 = new ValueAndUnit(0);
-        private _y1 = new ValueAndUnit(0);
-        private _x2 = new ValueAndUnit(0);
-        private _y2 = new ValueAndUnit(0);
-        private _dash = new Array<number>();
-        private _connectedControl: Control;
-        private _connectedControlDirtyObserver: Nullable<Observer<Control>>;
-
-        /** Gets or sets the dash pattern */
-        public get dash(): Array<number> {
-            return this._dash;
-        }
-
-        public set dash(value: Array<number>) {
-            if (this._dash === value) {
-                return;
-            }
-
-            this._dash = value;
-            this._markAsDirty();
-        }     
-
-        /** Gets or sets the control connected with the line end */
-        public get connectedControl(): Control {
-            return this._connectedControl;
+import { Control } from "./control";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Nullable, Observer, Vector3, Scene, Tools, Matrix } from "babylonjs";
+import { Measure } from "../measure";
+
+/** Class used to render 2D lines */
+export class Line extends Control {
+    private _lineWidth = 1;
+    private _x1 = new ValueAndUnit(0);
+    private _y1 = new ValueAndUnit(0);
+    private _x2 = new ValueAndUnit(0);
+    private _y2 = new ValueAndUnit(0);
+    private _dash = new Array<number>();
+    private _connectedControl: Control;
+    private _connectedControlDirtyObserver: Nullable<Observer<Control>>;
+
+    /** Gets or sets the dash pattern */
+    public get dash(): Array<number> {
+        return this._dash;
+    }
+
+    public set dash(value: Array<number>) {
+        if (this._dash === value) {
+            return;
         }
 
-        public set connectedControl(value: Control) {
-            if (this._connectedControl === value) {
-                return;
-            }
+        this._dash = value;
+        this._markAsDirty();
+    }
 
-            if (this._connectedControlDirtyObserver && this._connectedControl) {
-                this._connectedControl.onDirtyObservable.remove(this._connectedControlDirtyObserver);
-                this._connectedControlDirtyObserver = null;
-            }
+    /** Gets or sets the control connected with the line end */
+    public get connectedControl(): Control {
+        return this._connectedControl;
+    }
 
-            if (value) {
-                this._connectedControlDirtyObserver = value.onDirtyObservable.add(() => this._markAsDirty());
-            }            
+    public set connectedControl(value: Control) {
+        if (this._connectedControl === value) {
+            return;
+        }
 
-            this._connectedControl = value;
-            this._markAsDirty();
-        }              
+        if (this._connectedControlDirtyObserver && this._connectedControl) {
+            this._connectedControl.onDirtyObservable.remove(this._connectedControlDirtyObserver);
+            this._connectedControlDirtyObserver = null;
+        }
 
-        /** Gets or sets start coordinates on X axis */
-        public get x1(): string | number  {
-            return this._x1.toString(this._host);
+        if (value) {
+            this._connectedControlDirtyObserver = value.onDirtyObservable.add(() => this._markAsDirty());
         }
 
-        public set x1(value: string | number ) {
-            if (this._x1.toString(this._host) === value) {
-                return;
-            }
+        this._connectedControl = value;
+        this._markAsDirty();
+    }
 
-            if (this._x1.fromString(value)) {
-                this._markAsDirty();
-            }
-        }    
+    /** Gets or sets start coordinates on X axis */
+    public get x1(): string | number {
+        return this._x1.toString(this._host);
+    }
 
-        /** Gets or sets start coordinates on Y axis */        
-        public get y1(): string | number  {
-            return this._y1.toString(this._host);
+    public set x1(value: string | number) {
+        if (this._x1.toString(this._host) === value) {
+            return;
         }
 
-        public set y1(value: string | number ) {
-            if (this._y1.toString(this._host) === value) {
-                return;
-            }
+        if (this._x1.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
 
-            if (this._y1.fromString(value)) {
-                this._markAsDirty();
-            }
-        }     
+    /** Gets or sets start coordinates on Y axis */
+    public get y1(): string | number {
+        return this._y1.toString(this._host);
+    }
 
-        /** Gets or sets end coordinates on X axis */        
-        public get x2(): string | number  {
-            return this._x2.toString(this._host);
+    public set y1(value: string | number) {
+        if (this._y1.toString(this._host) === value) {
+            return;
         }
 
-        public set x2(value: string | number ) {
-            if (this._x2.toString(this._host) === value) {
-                return;
-            }
+        if (this._y1.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
 
-            if (this._x2.fromString(value)) {
-                this._markAsDirty();
-            }
-        }    
+    /** Gets or sets end coordinates on X axis */
+    public get x2(): string | number {
+        return this._x2.toString(this._host);
+    }
 
-        /** Gets or sets end coordinates on Y axis */        
-        public get y2(): string | number  {
-            return this._y2.toString(this._host);
+    public set x2(value: string | number) {
+        if (this._x2.toString(this._host) === value) {
+            return;
         }
 
-        public set y2(value: string | number ) {
-            if (this._y2.toString(this._host) === value) {
-                return;
-            }
-
-            if (this._y2.fromString(value)) {
-                this._markAsDirty();
-            }
-        }                       
-        
-        /** Gets or sets line width */
-        public get lineWidth(): number {
-            return this._lineWidth;
+        if (this._x2.fromString(value)) {
+            this._markAsDirty();
         }
+    }
 
-        public set lineWidth(value: number) {
-            if (this._lineWidth === value) {
-                return;
-            }
+    /** Gets or sets end coordinates on Y axis */
+    public get y2(): string | number {
+        return this._y2.toString(this._host);
+    }
 
-            this._lineWidth = value;
+    public set y2(value: string | number) {
+        if (this._y2.toString(this._host) === value) {
+            return;
+        }
+
+        if (this._y2.fromString(value)) {
             this._markAsDirty();
-        }   
+        }
+    }
+
+    /** Gets or sets line width */
+    public get lineWidth(): number {
+        return this._lineWidth;
+    }
 
-        /** Gets or sets horizontal alignment */
-        public set horizontalAlignment(value: number) {
+    public set lineWidth(value: number) {
+        if (this._lineWidth === value) {
             return;
-        } 
+        }
+
+        this._lineWidth = value;
+        this._markAsDirty();
+    }
+
+    /** Gets or sets horizontal alignment */
+    public set horizontalAlignment(value: number) {
+        return;
+    }
+
+    /** Gets or sets vertical alignment */
+    public set verticalAlignment(value: number) {
+        return;
+    }
+
+    private get _effectiveX2(): number {
+        return (this._connectedControl ? this._connectedControl.centerX : 0) + this._x2.getValue(this._host);
+    }
+
+    private get _effectiveY2(): number {
+        return (this._connectedControl ? this._connectedControl.centerY : 0) + this._y2.getValue(this._host);
+    }
+
+    /**
+     * Creates a new Line
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+
+        this.isHitTestVisible = false;
+        this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
+    }
+
+    protected _getTypeName(): string {
+        return "Line";
+    }
+
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
+
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
+        }
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            context.strokeStyle = this.color;
+            context.lineWidth = this._lineWidth;
+            context.setLineDash(this._dash);
+
+            context.beginPath();
+            context.moveTo(this._x1.getValue(this._host), this._y1.getValue(this._host));
+
+            context.lineTo(this._effectiveX2, this._effectiveY2);
 
-        /** Gets or sets vertical alignment */
-        public set verticalAlignment(value: number) {
+            context.stroke();
+        }
+
+        context.restore();
+    }
+
+    public _measure(): void {
+        // Width / Height
+        this._currentMeasure.width = Math.abs(this._x1.getValue(this._host) - this._effectiveX2) + this._lineWidth;
+        this._currentMeasure.height = Math.abs(this._y1.getValue(this._host) - this._effectiveY2) + this._lineWidth;
+    }
+
+    protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._currentMeasure.left = Math.min(this._x1.getValue(this._host), this._effectiveX2) - this._lineWidth / 2;
+        this._currentMeasure.top = Math.min(this._y1.getValue(this._host), this._effectiveY2) - this._lineWidth / 2;
+    }
+
+    /**
+     * Move one end of the line given 3D cartesian coordinates.
+     * @param position Targeted world position
+     * @param scene Scene
+     * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
+     */
+    public moveToVector3(position: Vector3, scene: Scene, end: boolean = false): void {
+        if (!this._host || this._root !== this._host._rootContainer) {
+            Tools.Error("Cannot move a control to a vector3 if the control is not at root level");
             return;
-        }    
+        }
+
+        var globalViewport = this._host._getGlobalViewport(scene);
+        var projectedPosition = Vector3.Project(position, Matrix.Identity(), scene.getTransformMatrix(), globalViewport);
 
-        private get _effectiveX2(): number {
-            return (this._connectedControl ? this._connectedControl.centerX : 0) + this._x2.getValue(this._host);
-        }   
-
-        private get _effectiveY2(): number {
-            return (this._connectedControl ? this._connectedControl.centerY : 0) + this._y2.getValue(this._host);
-        }           
-
-        /**
-         * Creates a new Line
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-
-            this.isHitTestVisible = false;
-            this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
-            this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;            
-        }
-
-        protected _getTypeName(): string {
-            return "Line";
-        }              
-
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
-
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                context.strokeStyle = this.color;
-                context.lineWidth = this._lineWidth;
-                context.setLineDash(this._dash);
-
-                context.beginPath();
-                context.moveTo(this._x1.getValue(this._host), this._y1.getValue(this._host));
-
-                context.lineTo(this._effectiveX2, this._effectiveY2);
-
-                context.stroke();
-            }
-
-            context.restore();
-        }
-
-        public _measure(): void {  
-            // Width / Height
-            this._currentMeasure.width = Math.abs(this._x1.getValue(this._host) - this._effectiveX2) + this._lineWidth;
-            this._currentMeasure.height = Math.abs(this._y1.getValue(this._host) - this._effectiveY2) + this._lineWidth;
-        }
-
-        protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {          
-            this._currentMeasure.left = Math.min(this._x1.getValue(this._host), this._effectiveX2) - this._lineWidth / 2;
-            this._currentMeasure.top = Math.min(this._y1.getValue(this._host), this._effectiveY2) - this._lineWidth / 2;            
-        }
-
-        /**
-         * Move one end of the line given 3D cartesian coordinates.
-         * @param position Targeted world position
-         * @param scene Scene
-         * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
-         */
-        public moveToVector3(position: Vector3, scene: Scene, end: boolean = false): void {
-            if (!this._host || this._root !== this._host._rootContainer) {
-                Tools.Error("Cannot move a control to a vector3 if the control is not at root level");
-                return;
-            }
-
-            var globalViewport = this._host._getGlobalViewport(scene);
-            var projectedPosition = Vector3.Project(position, Matrix.Identity(), scene.getTransformMatrix(), globalViewport);
-
-            this._moveToProjectedPosition(projectedPosition, end)
-
-            if (projectedPosition.z < 0 || projectedPosition.z > 1) {
-                this.notRenderable = true;
-                return;
-            }
-            this.notRenderable = false;
-        }
-
-        /**
-         * Move one end of the line to a position in screen absolute space.
-         * @param projectedPosition Position in screen absolute space (X, Y)
-         * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
-         */
-        public _moveToProjectedPosition(projectedPosition: Vector3, end: boolean = false): void {
-            let x: string = (projectedPosition.x + this._linkOffsetX.getValue(this._host)) + "px";
-            let y: string = (projectedPosition.y + this._linkOffsetY.getValue(this._host)) + "px";
-
-            if (end) {
-                this.x2 = x;
-                this.y2 = y;
-                this._x2.ignoreAdaptiveScaling = true;
-                this._y2.ignoreAdaptiveScaling = true;
-            } else {
-                this.x1 = x;
-                this.y1 = y;
-                this._x1.ignoreAdaptiveScaling = true;
-                this._y1.ignoreAdaptiveScaling = true;
-            }
-        }
-    }    
-}
+        this._moveToProjectedPosition(projectedPosition, end)
+
+        if (projectedPosition.z < 0 || projectedPosition.z > 1) {
+            this.notRenderable = true;
+            return;
+        }
+        this.notRenderable = false;
+    }
+
+    /**
+     * Move one end of the line to a position in screen absolute space.
+     * @param projectedPosition Position in screen absolute space (X, Y)
+     * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
+     */
+    public _moveToProjectedPosition(projectedPosition: Vector3, end: boolean = false): void {
+        let x: string = (projectedPosition.x + this._linkOffsetX.getValue(this._host)) + "px";
+        let y: string = (projectedPosition.y + this._linkOffsetY.getValue(this._host)) + "px";
+
+        if (end) {
+            this.x2 = x;
+            this.y2 = y;
+            this._x2.ignoreAdaptiveScaling = true;
+            this._y2.ignoreAdaptiveScaling = true;
+        } else {
+            this.x1 = x;
+            this.y1 = y;
+            this._x1.ignoreAdaptiveScaling = true;
+            this._y1.ignoreAdaptiveScaling = true;
+        }
+    }
+}   

+ 187 - 186
gui/src/2D/controls/multiLine.ts

@@ -1,248 +1,249 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { MultiLinePoint } from "../multiLinePoint";
+import { Nullable, AbstractMesh } from "babylonjs";
+import { Measure } from "../measure";
 
-module BABYLON.GUI {
+
+/**
+ * Class used to create multi line control
+ */
+export class MultiLine extends Control {
+
+    private _lineWidth: number = 1;
+    private _dash: number[];
+    private _points: Nullable<MultiLinePoint>[];
+
+    private _minX: Nullable<number>;
+    private _minY: Nullable<number>;
+    private _maxX: Nullable<number>;
+    private _maxY: Nullable<number>;
 
     /**
-     * Class used to create multi line control
+     * Creates a new MultiLine
+     * @param name defines the control name
      */
-    export class MultiLine extends Control {
-
-        private _lineWidth: number = 1;
-        private _dash: number[];
-        private _points: Nullable<MultiLinePoint>[];
-
-        private _minX: Nullable<number>;
-        private _minY: Nullable<number>;
-        private _maxX: Nullable<number>;
-        private _maxY: Nullable<number>;
-
-        /**
-         * Creates a new MultiLine
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-
-            this.isHitTestVisible = false;
-            this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
-            this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
-
-            this._dash = [];
-            this._points = [];
-        }
+    constructor(public name?: string) {
+        super(name);
 
-        /** Gets or sets dash pattern */
-        public get dash(): Array<number> {
-            return this._dash;
-        }
+        this.isHitTestVisible = false;
+        this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
 
-        public set dash(value: Array<number>) {
-            if (this._dash === value) {
-                return;
-            }
+        this._dash = [];
+        this._points = [];
+    }
+
+    /** Gets or sets dash pattern */
+    public get dash(): Array<number> {
+        return this._dash;
+    }
 
-            this._dash = value;
-            this._markAsDirty();
+    public set dash(value: Array<number>) {
+        if (this._dash === value) {
+            return;
         }
 
-        /**
-         * Gets point stored at specified index
-         * @param index defines the index to look for
-         * @returns the requested point if found
-         */
-        public getAt(index: number): MultiLinePoint {
-            if (!this._points[index]) {
-                this._points[index] = new MultiLinePoint(this);
-            }
+        this._dash = value;
+        this._markAsDirty();
+    }
 
-            return this._points[index] as MultiLinePoint;
+    /**
+     * Gets point stored at specified index
+     * @param index defines the index to look for
+     * @returns the requested point if found
+     */
+    public getAt(index: number): MultiLinePoint {
+        if (!this._points[index]) {
+            this._points[index] = new MultiLinePoint(this);
         }
 
-        /** Function called when a point is updated */
-        public onPointUpdate = (): void => {
-            this._markAsDirty();
-        }
+        return this._points[index] as MultiLinePoint;
+    }
 
-        /**
-         * Adds new points to the point collection
-         * @param items defines the list of items (mesh, control or 2d coordiantes) to add 
-         * @returns the list of created MultiLinePoint
-         */
-        public add(...items: (AbstractMesh | Control | { x: string | number, y: string | number })[]): MultiLinePoint[] {
-            return items.map(item => this.push(item));
-        }
+    /** Function called when a point is updated */
+    public onPointUpdate = (): void => {
+        this._markAsDirty();
+    }
 
-        /**
-         * Adds a new point to the point collection
-         * @param item defines the item (mesh, control or 2d coordiantes) to add 
-         * @returns the created MultiLinePoint
-         */
-        public push(item?: (AbstractMesh | Control | { x: string | number, y: string | number })): MultiLinePoint {
-            var point: MultiLinePoint = this.getAt(this._points.length);
+    /**
+     * Adds new points to the point collection
+     * @param items defines the list of items (mesh, control or 2d coordiantes) to add 
+     * @returns the list of created MultiLinePoint
+     */
+    public add(...items: (AbstractMesh | Control | { x: string | number, y: string | number })[]): MultiLinePoint[] {
+        return items.map(item => this.push(item));
+    }
 
-            if (item == null) return point;
+    /**
+     * Adds a new point to the point collection
+     * @param item defines the item (mesh, control or 2d coordiantes) to add 
+     * @returns the created MultiLinePoint
+     */
+    public push(item?: (AbstractMesh | Control | { x: string | number, y: string | number })): MultiLinePoint {
+        var point: MultiLinePoint = this.getAt(this._points.length);
 
-            if (item instanceof AbstractMesh) {
-                point.mesh = item;
-            }
-            else if (item instanceof Control) {
-                point.control = item;
-            }
-            else if (item.x != null && item.y != null) {
-                point.x = item.x;
-                point.y = item.y;
-            }
+        if (item == null) return point;
 
-            return point;
+        if (item instanceof AbstractMesh) {
+            point.mesh = item;
+        }
+        else if (item instanceof Control) {
+            point.control = item;
+        }
+        else if (item.x != null && item.y != null) {
+            point.x = item.x;
+            point.y = item.y;
         }
 
-        /**
-         * Remove a specific value or point from the active point collection
-         * @param value defines the value or point to remove
-         */
-        public remove(value: number | MultiLinePoint): void {
-            var index: number;
-            
-            if (value instanceof MultiLinePoint) {
-                index = this._points.indexOf(value);
-
-                if (index === -1) {
-                    return;
-                }
-            }
-            else {
-                index = value;
-            }
-            
-            var point: Nullable<MultiLinePoint> = this._points[index];
+        return point;
+    }
 
-            if (!point) {
+    /**
+     * Remove a specific value or point from the active point collection
+     * @param value defines the value or point to remove
+     */
+    public remove(value: number | MultiLinePoint): void {
+        var index: number;
+
+        if (value instanceof MultiLinePoint) {
+            index = this._points.indexOf(value);
+
+            if (index === -1) {
                 return;
             }
+        }
+        else {
+            index = value;
+        }
 
-            point.dispose();
+        var point: Nullable<MultiLinePoint> = this._points[index];
 
-            this._points.splice(index, 1);
-        }
-        
-        /** Gets or sets line width */
-        public get lineWidth(): number {
-            return this._lineWidth;
+        if (!point) {
+            return;
         }
 
-        public set lineWidth(value: number) {
-            if (this._lineWidth === value) {
-                return;
-            }
+        point.dispose();
 
-            this._lineWidth = value;
-            this._markAsDirty();
-        }   
+        this._points.splice(index, 1);
+    }
 
-        public set horizontalAlignment(value: number) {
-            return;
-        } 
+    /** Gets or sets line width */
+    public get lineWidth(): number {
+        return this._lineWidth;
+    }
 
-        public set verticalAlignment(value: number) {
+    public set lineWidth(value: number) {
+        if (this._lineWidth === value) {
             return;
         }
 
-        protected _getTypeName(): string {
-            return "MultiLine";
-        }              
-
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+        this._lineWidth = value;
+        this._markAsDirty();
+    }
 
-            this._applyStates(context);
+    public set horizontalAlignment(value: number) {
+        return;
+    }
 
-            if (this._processMeasures(parentMeasure, context)) {
-                context.strokeStyle = this.color;
-                context.lineWidth = this._lineWidth;
-                context.setLineDash(this._dash);
+    public set verticalAlignment(value: number) {
+        return;
+    }
 
-                context.beginPath();
+    protected _getTypeName(): string {
+        return "MultiLine";
+    }
 
-                var first: boolean = true; //first index is not necessarily 0
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
-                this._points.forEach(point => {
-                    if (!point) {
-                        return;
-                    }
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
+        }
 
-                    if (first) {
-                        context.moveTo(point._point.x, point._point.y);
+        this._applyStates(context);
 
-                        first = false;
-                    }
-                    else {
-                        context.lineTo(point._point.x, point._point.y);
-                    }
-                });
+        if (this._processMeasures(parentMeasure, context)) {
+            context.strokeStyle = this.color;
+            context.lineWidth = this._lineWidth;
+            context.setLineDash(this._dash);
 
-                context.stroke();
-            }
+            context.beginPath();
 
-            context.restore();
-        }
+            var first: boolean = true; //first index is not necessarily 0
 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            this._minX = null;
-            this._minY = null;
-            this._maxX = null;
-            this._maxY = null;
-            
-            this._points.forEach((point, index) => {
+            this._points.forEach(point => {
                 if (!point) {
                     return;
                 }
 
-                point.translate();
+                if (first) {
+                    context.moveTo(point._point.x, point._point.y);
 
-                if (this._minX == null || point._point.x < this._minX) this._minX = point._point.x;
-                if (this._minY == null || point._point.y < this._minY) this._minY = point._point.y;
-                if (this._maxX == null || point._point.x > this._maxX) this._maxX = point._point.x;
-                if (this._maxY == null || point._point.y > this._maxY) this._maxY = point._point.y;
+                    first = false;
+                }
+                else {
+                    context.lineTo(point._point.x, point._point.y);
+                }
             });
 
-            if (this._minX == null) this._minX = 0;
-            if (this._minY == null) this._minY = 0;
-            if (this._maxX == null) this._maxX = 0;
-            if (this._maxY == null) this._maxY = 0;
+            context.stroke();
         }
 
-        public _measure(): void {
-            if (this._minX == null || this._maxX == null || this._minY == null || this._maxY == null) {
+        context.restore();
+    }
+
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._minX = null;
+        this._minY = null;
+        this._maxX = null;
+        this._maxY = null;
+
+        this._points.forEach((point, index) => {
+            if (!point) {
                 return;
             }
 
-            this._currentMeasure.width = Math.abs(this._maxX - this._minX) + this._lineWidth;
-            this._currentMeasure.height = Math.abs(this._maxY - this._minY) + this._lineWidth;
+            point.translate();
+
+            if (this._minX == null || point._point.x < this._minX) this._minX = point._point.x;
+            if (this._minY == null || point._point.y < this._minY) this._minY = point._point.y;
+            if (this._maxX == null || point._point.x > this._maxX) this._maxX = point._point.x;
+            if (this._maxY == null || point._point.y > this._maxY) this._maxY = point._point.y;
+        });
+
+        if (this._minX == null) this._minX = 0;
+        if (this._minY == null) this._minY = 0;
+        if (this._maxX == null) this._maxX = 0;
+        if (this._maxY == null) this._maxY = 0;
+    }
+
+    public _measure(): void {
+        if (this._minX == null || this._maxX == null || this._minY == null || this._maxY == null) {
+            return;
         }
 
-        protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            if (this._minX == null || this._minY == null) {
-                return;
-            }
+        this._currentMeasure.width = Math.abs(this._maxX - this._minX) + this._lineWidth;
+        this._currentMeasure.height = Math.abs(this._maxY - this._minY) + this._lineWidth;
+    }
 
-            this._currentMeasure.left = this._minX - this._lineWidth / 2;
-            this._currentMeasure.top = this._minY - this._lineWidth / 2;  
+    protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        if (this._minX == null || this._minY == null) {
+            return;
         }
 
-        public dispose(): void {
-            while (this._points.length > 0) {
-                this.remove(this._points.length - 1);
-            }
+        this._currentMeasure.left = this._minX - this._lineWidth / 2;
+        this._currentMeasure.top = this._minY - this._lineWidth / 2;
+    }
 
-            super.dispose();
+    public dispose(): void {
+        while (this._points.length > 0) {
+            this.remove(this._points.length - 1);
         }
 
-    }    
-}
+        super.dispose();
+    }
+
+}    

+ 136 - 136
gui/src/2D/controls/radioButton.ts

@@ -1,172 +1,172 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /**
-     * Class used to create radio button controls
-     */
-    export class RadioButton extends Control {
-        private _isChecked = false;
-        private _background = "black";   
-        private _checkSizeRatio = 0.8;
-        private _thickness = 1;
-        
-        /** Gets or sets border thickness */
-        public get thickness(): number {
-            return this._thickness;
+import { Control } from "./control";
+import { Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create radio button controls
+ */
+export class RadioButton extends Control {
+    private _isChecked = false;
+    private _background = "black";
+    private _checkSizeRatio = 0.8;
+    private _thickness = 1;
+
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
-            this._thickness = value;
-            this._markAsDirty();
-        }           
+    /** Gets or sets group name */
+    public group = "";
 
-        /** Gets or sets group name */
-        public group = "";        
+    /** Observable raised when isChecked is changed */
+    public onIsCheckedChangedObservable = new Observable<boolean>();
 
-        /** Observable raised when isChecked is changed */
-        public onIsCheckedChangedObservable = new Observable<boolean>();
+    /** Gets or sets a value indicating the ratio between overall size and check size */
+    public get checkSizeRatio(): number {
+        return this._checkSizeRatio;
+    }
 
-        /** Gets or sets a value indicating the ratio between overall size and check size */
-        public get checkSizeRatio(): number {
-            return this._checkSizeRatio;
-        }
+    public set checkSizeRatio(value: number) {
+        value = Math.max(Math.min(1, value), 0);
 
-        public set checkSizeRatio(value: number) {
-            value = Math.max(Math.min(1, value), 0);
+        if (this._checkSizeRatio === value) {
+            return;
+        }
 
-            if (this._checkSizeRatio === value) {
-                return;
-            }
+        this._checkSizeRatio = value;
+        this._markAsDirty();
+    }
 
-            this._checkSizeRatio = value;
-            this._markAsDirty();
-        }             
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
-            this._background = value;
-            this._markAsDirty();
-        }     
+    /** Gets or sets a boolean indicating if the checkbox is checked or not */
+    public get isChecked(): boolean {
+        return this._isChecked;
+    }
 
-        /** Gets or sets a boolean indicating if the checkbox is checked or not */
-        public get isChecked(): boolean {
-            return this._isChecked;
+    public set isChecked(value: boolean) {
+        if (this._isChecked === value) {
+            return;
         }
 
-        public set isChecked(value: boolean) {
-            if (this._isChecked === value) {
-                return;
-            }
+        this._isChecked = value;
+        this._markAsDirty();
 
-            this._isChecked = value;
-            this._markAsDirty();
-
-            this.onIsCheckedChangedObservable.notifyObservers(value);
-
-            if (this._isChecked && this._host) {
-                // Update all controls from same group
-                this._host.executeOnAllControls((control) => {
-                    if (control === this) {
-                        return;
-                    }
-
-                    if ((<any>control).group === undefined) {
-                        return;
-                    }
-                    var childRadio = (<RadioButton>control);
-                    if (childRadio.group === this.group) {
-                        childRadio.isChecked = false;
-                    }
-                });
-            }
-        }                             
+        this.onIsCheckedChangedObservable.notifyObservers(value);
 
-        /**
-         * Creates a new RadioButton
-         * @param name defines the control name
-         */        
-        constructor(public name?: string) {
-            super(name);
+        if (this._isChecked && this._host) {
+            // Update all controls from same group
+            this._host.executeOnAllControls((control) => {
+                if (control === this) {
+                    return;
+                }
 
-            this.isPointerBlocker = true;
+                if ((<any>control).group === undefined) {
+                    return;
+                }
+                var childRadio = (<RadioButton>control);
+                if (childRadio.group === this.group) {
+                    childRadio.isChecked = false;
+                }
+            });
         }
+    }
+
+    /**
+     * Creates a new RadioButton
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
 
-        protected _getTypeName(): string {
-            return "RadioButton";
-        }              
+        this.isPointerBlocker = true;
+    }
 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+    protected _getTypeName(): string {
+        return "RadioButton";
+    }
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                let actualWidth = this._currentMeasure.width - this._thickness;
-                let actualHeight = this._currentMeasure.height - this._thickness;
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
-                
-                // Outer
-                Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, 
-                            this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
-                
-                context.fillStyle = this._background;
-                context.fill();
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            let actualWidth = this._currentMeasure.width - this._thickness;
+            let actualHeight = this._currentMeasure.height - this._thickness;
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
+
+            // Outer
+            Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2,
+                this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
 
-                context.strokeStyle = this.color;
-                context.lineWidth = this._thickness;
+            context.fillStyle = this._background;
+            context.fill();
 
-                context.stroke();
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
+            }
 
-                // Inner
-                if (this._isChecked) {
-                    context.fillStyle = this.color;
-                    let offsetWidth = actualWidth * this._checkSizeRatio;
-                    let offseHeight = actualHeight * this._checkSizeRatio;
+            context.strokeStyle = this.color;
+            context.lineWidth = this._thickness;
 
-                    Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, 
-                                    offsetWidth / 2 - this._thickness / 2, offseHeight / 2  - this._thickness / 2, context);
+            context.stroke();
 
-                    context.fill();
-                }
+            // Inner
+            if (this._isChecked) {
+                context.fillStyle = this.color;
+                let offsetWidth = actualWidth * this._checkSizeRatio;
+                let offseHeight = actualHeight * this._checkSizeRatio;
 
+                Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2,
+                    offsetWidth / 2 - this._thickness / 2, offseHeight / 2 - this._thickness / 2, context);
+
+                context.fill();
             }
-            context.restore();
+
         }
+        context.restore();
+    }
 
-        // Events
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
-            
-            if (!this.isChecked) {
-                this.isChecked = true;
-            }
+    // Events
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
+        }
 
-            return true;
+        if (!this.isChecked) {
+            this.isChecked = true;
         }
-    }    
-}
+
+        return true;
+    }
+}   

+ 117 - 118
gui/src/2D/controls/rectangle.ts

@@ -1,136 +1,135 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to create rectangle container */
-    export class Rectangle extends Container {
-        private _thickness = 1;
-        private _cornerRadius = 0;
-        
-        /** Gets or sets border thickness */        
-        public get thickness(): number {
-            return this._thickness;
+import { Container } from "./container";
+import { Measure } from "../measure";
+
+/** Class used to create rectangle container */
+export class Rectangle extends Container {
+    private _thickness = 1;
+    private _cornerRadius = 0;
+
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
-            this._thickness = value;
-            this._markAsDirty();
-        }   
-        
-        /** Gets or sets the corner radius angle */
-        public get cornerRadius(): number {
-            return this._cornerRadius;
-        }
+    /** Gets or sets the corner radius angle */
+    public get cornerRadius(): number {
+        return this._cornerRadius;
+    }
 
-        public set cornerRadius(value: number) {
-            if (value < 0) {
-                value = 0;
-            }
+    public set cornerRadius(value: number) {
+        if (value < 0) {
+            value = 0;
+        }
 
-            if (this._cornerRadius === value) {
-                return;
-            }
+        if (this._cornerRadius === value) {
+            return;
+        }
 
-            this._cornerRadius = value;
-            this._markAsDirty();
-        }   
-     
-        /**
-         * Creates a new Rectangle
-         * @param name defines the control name
-         */       
-        constructor(public name?: string) {
-            super(name);
+        this._cornerRadius = value;
+        this._markAsDirty();
+    }
+
+    /**
+     * Creates a new Rectangle
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
+
+    protected _getTypeName(): string {
+        return "Rectangle";
+    }
+
+    protected _localDraw(context: CanvasRenderingContext2D): void {
+        context.save();
+
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
         }
 
-        protected _getTypeName(): string {
-            return "Rectangle";
-        }              
-
-        protected _localDraw(context: CanvasRenderingContext2D): void {
-            context.save();
-            
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
+        if (this._background) {
+            context.fillStyle = this._background;
+
+            if (this._cornerRadius) {
+                this._drawRoundedRect(context, this._thickness / 2);
+                context.fill();
+            } else {
+                context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
             }
+        }
 
-            if (this._background) {
-                context.fillStyle = this._background;
+        if (this._thickness) {
 
-                if (this._cornerRadius) {
-                    this._drawRoundedRect(context, this._thickness / 2);
-                    context.fill();
-                } else {
-                    context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
 
-            if (this._thickness) {
-
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
-
-                if (this.color) {
-                    context.strokeStyle = this.color;
-                }
-                context.lineWidth = this._thickness;
-
-                if (this._cornerRadius) {
-                    this._drawRoundedRect(context, this._thickness / 2);
-                    context.stroke();
-                } else {                
-                    context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, 
-                                       this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
-                }
+            if (this.color) {
+                context.strokeStyle = this.color;
             }
+            context.lineWidth = this._thickness;
 
-            context.restore();
-        }
-
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {  
-            super._additionalProcessing(parentMeasure, context);
-
-            this._measureForChildren.width -= 2 * this._thickness;
-            this._measureForChildren.height -= 2 * this._thickness;
-            this._measureForChildren.left += this._thickness;
-            this._measureForChildren.top += this._thickness;            
-        }
-
-        private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0): void {
-            var x = this._currentMeasure.left + offset;
-            var y = this._currentMeasure.top + offset;
-            var width = this._currentMeasure.width - offset * 2;
-            var height = this._currentMeasure.height - offset * 2;
-
-            var radius = Math.min(height / 2 - 2, Math.min(width / 2 - 2, this._cornerRadius));
-
-            context.beginPath();
-            context.moveTo(x + radius, y);
-            context.lineTo(x + width - radius, y);
-            context.quadraticCurveTo(x + width, y, x + width, y + radius);
-            context.lineTo(x + width, y + height - radius);
-            context.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
-            context.lineTo(x + radius, y + height);
-            context.quadraticCurveTo(x, y + height, x, y + height - radius);
-            context.lineTo(x, y + radius);
-            context.quadraticCurveTo(x, y, x + radius, y);
-            context.closePath();
-        } 
-
-        protected _clipForChildren(context: CanvasRenderingContext2D) {
             if (this._cornerRadius) {
-                this._drawRoundedRect(context, this._thickness);
-                context.clip();
+                this._drawRoundedRect(context, this._thickness / 2);
+                context.stroke();
+            } else {
+                context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
+                    this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
             }
         }
-    }    
-}
+
+        context.restore();
+    }
+
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        super._additionalProcessing(parentMeasure, context);
+
+        this._measureForChildren.width -= 2 * this._thickness;
+        this._measureForChildren.height -= 2 * this._thickness;
+        this._measureForChildren.left += this._thickness;
+        this._measureForChildren.top += this._thickness;
+    }
+
+    private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0): void {
+        var x = this._currentMeasure.left + offset;
+        var y = this._currentMeasure.top + offset;
+        var width = this._currentMeasure.width - offset * 2;
+        var height = this._currentMeasure.height - offset * 2;
+
+        var radius = Math.min(height / 2 - 2, Math.min(width / 2 - 2, this._cornerRadius));
+
+        context.beginPath();
+        context.moveTo(x + radius, y);
+        context.lineTo(x + width - radius, y);
+        context.quadraticCurveTo(x + width, y, x + width, y + radius);
+        context.lineTo(x + width, y + height - radius);
+        context.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+        context.lineTo(x + radius, y + height);
+        context.quadraticCurveTo(x, y + height, x, y + height - radius);
+        context.lineTo(x, y + radius);
+        context.quadraticCurveTo(x, y, x + radius, y);
+        context.closePath();
+    }
+
+    protected _clipForChildren(context: CanvasRenderingContext2D) {
+        if (this._cornerRadius) {
+            this._drawRoundedRect(context, this._thickness);
+            context.clip();
+        }
+    }
+}    

+ 359 - 358
gui/src/2D/controls/slider.ts

@@ -1,463 +1,464 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create slider controls
+ */
+export class Slider extends Control {
+    private _thumbWidth = new ValueAndUnit(20, ValueAndUnit.UNITMODE_PIXEL, false);
+    private _minimum = 0;
+    private _maximum = 100;
+    private _value = 50;
+    private _isVertical = false;
+    private _background = "black";
+    private _borderColor = "white";
+    private _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
+    private _isThumbCircle = false;
+    private _isThumbClamped = false;
+
+    /** Observable raised when the sldier value changes */
+    public onValueChangedObservable = new Observable<number>();
+
+    /** Gets or sets border color */
+    public get borderColor(): string {
+        return this._borderColor;
+    }
 
-module BABYLON.GUI {
-    /**
-     * Class used to create slider controls
-     */
-    export class Slider extends Control {
-        private _thumbWidth = new ValueAndUnit(20, ValueAndUnit.UNITMODE_PIXEL, false);
-        private _minimum = 0;
-        private _maximum = 100;
-        private _value = 50;
-        private _isVertical = false;
-        private _background = "black";
-        private _borderColor = "white";
-        private _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
-        private _isThumbCircle = false;
-        private _isThumbClamped = false;
-
-        /** Observable raised when the sldier value changes */
-        public onValueChangedObservable = new Observable<number>();
-
-        /** Gets or sets border color */
-        public get borderColor(): string {
-            return this._borderColor;
+    public set borderColor(value: string) {
+        if (this._borderColor === value) {
+            return;
         }
 
-        public set borderColor(value: string) {
-            if (this._borderColor === value) {
-                return;
-            }
+        this._borderColor = value;
+        this._markAsDirty();
+    }
 
-            this._borderColor = value;
-            this._markAsDirty();
-        }
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
-            this._background = value;
-            this._markAsDirty();
-        }
+    /** Gets or sets main bar offset */
+    public get barOffset(): string | number {
+        return this._barOffset.toString(this._host);
+    }
 
-        /** Gets or sets main bar offset */
-        public get barOffset(): string | number {
-            return this._barOffset.toString(this._host);
+    /** Gets main bar offset in pixels*/
+    public get barOffsetInPixels(): number {
+        return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
+
+    public set barOffset(value: string | number) {
+        if (this._barOffset.toString(this._host) === value) {
+            return;
         }
 
-        /** Gets main bar offset in pixels*/
-        public get barOffsetInPixels(): number {
-            return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._barOffset.fromString(value)) {
+            this._markAsDirty();
         }
+    }
 
-        public set barOffset(value: string | number) {
-            if (this._barOffset.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets thumb width */
+    public get thumbWidth(): string | number {
+        return this._thumbWidth.toString(this._host);
+    }
 
-            if (this._barOffset.fromString(value)) {
-                this._markAsDirty();
-            }
-        }
+    /** Gets thumb width in pixels */
+    public get thumbWidthInPixels(): number {
+        return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
 
-        /** Gets or sets thumb width */
-        public get thumbWidth(): string | number {
-            return this._thumbWidth.toString(this._host);
+    public set thumbWidth(value: string | number) {
+        if (this._thumbWidth.toString(this._host) === value) {
+            return;
         }
 
-        /** Gets thumb width in pixels */       
-        public get thumbWidthInPixels(): number {
-            return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._thumbWidth.fromString(value)) {
+            this._markAsDirty();
         }
+    }
 
-        public set thumbWidth(value: string | number) {
-            if (this._thumbWidth.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets minimum value */
+    public get minimum(): number {
+        return this._minimum;
+    }
 
-            if (this._thumbWidth.fromString(value)) {
-                this._markAsDirty();
-            }
+    public set minimum(value: number) {
+        if (this._minimum === value) {
+            return;
         }
 
-        /** Gets or sets minimum value */
-        public get minimum(): number {
-            return this._minimum;
-        }
+        this._minimum = value;
+        this._markAsDirty();
 
-        public set minimum(value: number) {
-            if (this._minimum === value) {
-                return;
-            }
+        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    }
 
-            this._minimum = value;
-            this._markAsDirty();
+    /** Gets or sets maximum value */
+    public get maximum(): number {
+        return this._maximum;
+    }
 
-            this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    public set maximum(value: number) {
+        if (this._maximum === value) {
+            return;
         }
 
-        /** Gets or sets maximum value */        
-        public get maximum(): number {
-            return this._maximum;
-        }
+        this._maximum = value;
+        this._markAsDirty();
 
-        public set maximum(value: number) {
-            if (this._maximum === value) {
-                return;
-            }
+        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    }
 
-            this._maximum = value;
-            this._markAsDirty();
+    /** Gets or sets current value */
+    public get value(): number {
+        return this._value;
+    }
 
-            this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
-        }
+    public set value(value: number) {
+        value = Math.max(Math.min(value, this._maximum), this._minimum);
 
-        /** Gets or sets current value */
-        public get value(): number {
-            return this._value;
+        if (this._value === value) {
+            return;
         }
 
-        public set value(value: number) {
-            value = Math.max(Math.min(value, this._maximum), this._minimum);
+        this._value = value;
+        this._markAsDirty();
+        this.onValueChangedObservable.notifyObservers(this._value);
+    }
 
-            if (this._value === value) {
-                return;
-            }
+    /**Gets or sets a boolean indicating if the slider should be vertical or horizontal */
+    public get isVertical(): boolean {
+        return this._isVertical;
+    }
 
-            this._value = value;
-            this._markAsDirty();
-            this.onValueChangedObservable.notifyObservers(this._value);
+    public set isVertical(value: boolean) {
+        if (this._isVertical === value) {
+            return;
         }
 
-        /**Gets or sets a boolean indicating if the slider should be vertical or horizontal */
-        public get isVertical(): boolean {
-            return this._isVertical;
-        }
+        this._isVertical = value;
+        this._markAsDirty();
+    }
 
-        public set isVertical(value: boolean) {
-            if(this._isVertical === value){
-                return;
-            }
+    /** Gets or sets a boolean indicating if the thumb should be round or square */
+    public get isThumbCircle(): boolean {
+        return this._isThumbCircle;
+    }
 
-            this._isVertical = value;
-            this._markAsDirty();
+    public set isThumbCircle(value: boolean) {
+        if (this._isThumbCircle === value) {
+            return;
         }
 
-        /** Gets or sets a boolean indicating if the thumb should be round or square */
-        public get isThumbCircle(): boolean {
-            return this._isThumbCircle;
-        }
+        this._isThumbCircle = value;
+        this._markAsDirty();
+    }
 
-        public set isThumbCircle(value: boolean) {
-            if (this._isThumbCircle === value) {
-                return;
-            }
+    /** Gets or sets a value indicating if the thumb can go over main bar extends */
+    public get isThumbClamped(): boolean {
+        return this._isThumbClamped;
+    }
 
-            this._isThumbCircle = value;
-            this._markAsDirty();
+    public set isThumbClamped(value: boolean) {
+        if (this._isThumbClamped === value) {
+            return;
         }
 
-        /** Gets or sets a value indicating if the thumb can go over main bar extends */
-        public get isThumbClamped(): boolean {
-            return this._isThumbClamped;
-        }
+        this._isThumbClamped = value;
+        this._markAsDirty();
+    }
 
-        public set isThumbClamped(value: boolean) {
-            if (this._isThumbClamped === value) {
-                return;
-            }
+    /**
+     * Creates a new Slider
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
 
-            this._isThumbClamped = value;
-            this._markAsDirty();
-        }
+        this.isPointerBlocker = true;
+    }
 
-       /**
-        * Creates a new Slider
-        * @param name defines the control name
-        */
-        constructor(public name?: string) {
-            super(name);
+    protected _getTypeName(): string {
+        return "Slider";
+    }
 
-            this.isPointerBlocker = true;
+    protected _getThumbThickness(type: string, backgroundLength: number): number {
+        var thumbThickness = 0;
+        switch (type) {
+            case "circle":
+                if (this._thumbWidth.isPixel) {
+                    thumbThickness = Math.max(this._thumbWidth.getValue(this._host), backgroundLength);
+                }
+                else {
+                    thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
+                }
+                break;
+            case "rectangle":
+                if (this._thumbWidth.isPixel) {
+                    thumbThickness = Math.min(this._thumbWidth.getValue(this._host), backgroundLength);
+                }
+                else {
+                    thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
+                }
         }
+        return thumbThickness;
+    }
 
-        protected _getTypeName(): string {
-            return "Slider";
-        }
 
-        protected _getThumbThickness(type:string, backgroundLength:number): number {
-            var thumbThickness = 0;
-            switch(type) {
-                case "circle":
-                    if (this._thumbWidth.isPixel) {
-                        thumbThickness = Math.max(this._thumbWidth.getValue(this._host), backgroundLength);
-                    }
-                    else {
-                        thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
-                    }
-                    break;
-                case "rectangle":
-                    if (this._thumbWidth.isPixel) {
-                        thumbThickness = Math.min(this._thumbWidth.getValue(this._host), backgroundLength);
-                    }
-                    else {
-                        thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
-                    }
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            // Main bar
+            var effectiveBarOffset = 0;
+            var type = this.isThumbCircle ? "circle" : "rectangle";
+            var left = this._currentMeasure.left;
+            var top = this._currentMeasure.top;
+            var width = this._currentMeasure.width;
+            var height = this._currentMeasure.height;
+
+            var backgroundBoxLength = Math.max(this._currentMeasure.width, this._currentMeasure.height);
+            var backgroundBoxThickness = Math.min(this._currentMeasure.width, this._currentMeasure.height);
+
+            var effectiveThumbThickness = this._getThumbThickness(type, backgroundBoxThickness);
+            backgroundBoxLength -= effectiveThumbThickness;
+
+            var radius = 0;
+
+
+            //throw error when height is less than width for vertical slider
+            if ((this._isVertical && this._currentMeasure.height < this._currentMeasure.width)) {
+                console.error("Height should be greater than width");
+                return;
+            }
+            if (this._barOffset.isPixel) {
+                effectiveBarOffset = Math.min(this._barOffset.getValue(this._host), backgroundBoxThickness);
+            }
+            else {
+                effectiveBarOffset = backgroundBoxThickness * this._barOffset.getValue(this._host);
             }
-            return thumbThickness;
-        }
 
+            backgroundBoxThickness -= (effectiveBarOffset * 2);
 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                // Main bar
-                var effectiveBarOffset = 0;
-                var type = this.isThumbCircle ? "circle" : "rectangle";
-                var left = this._currentMeasure.left;
-                var top = this._currentMeasure.top;
-                var width = this._currentMeasure.width;
-                var height = this._currentMeasure.height;
-            
-                var backgroundBoxLength = Math.max(this._currentMeasure.width, this._currentMeasure.height);
-                var backgroundBoxThickness = Math.min(this._currentMeasure.width, this._currentMeasure.height);
-                
-                var effectiveThumbThickness = this._getThumbThickness(type, backgroundBoxThickness);
-                backgroundBoxLength -= effectiveThumbThickness;
-
-                var radius = 0;
-
-
-                //throw error when height is less than width for vertical slider
-                if ((this._isVertical && this._currentMeasure.height < this._currentMeasure.width)) {
-                    console.error("Height should be greater than width");
-                    return;
-                }
-                if (this._barOffset.isPixel) {
-                    effectiveBarOffset = Math.min(this._barOffset.getValue(this._host), backgroundBoxThickness);
+            if (this._isVertical) {
+                left += effectiveBarOffset;
+                if (!this.isThumbClamped) {
+                    top += (effectiveThumbThickness / 2);
                 }
-                else {
-                    effectiveBarOffset = backgroundBoxThickness * this._barOffset.getValue(this._host);
+
+                height = backgroundBoxLength;
+                width = backgroundBoxThickness;
+
+            }
+            else {
+                top += effectiveBarOffset;
+                if (!this.isThumbClamped) {
+                    left += (effectiveThumbThickness / 2);
                 }
+                height = backgroundBoxThickness;
+                width = backgroundBoxLength;
+            }
 
-                backgroundBoxThickness -= (effectiveBarOffset * 2);
+            if (this.isThumbClamped && this.isThumbCircle) {
+                if (this._isVertical)
+                    top += (effectiveThumbThickness / 2);
+                else
+                    left += (effectiveThumbThickness / 2);
 
-                if (this._isVertical) {
-                    left += effectiveBarOffset;
-                    if(!this.isThumbClamped) {
-                       top += (effectiveThumbThickness / 2);
-                    }
-    
-                    height = backgroundBoxLength;
-                    width = backgroundBoxThickness;
+                radius = backgroundBoxThickness / 2;
+            }
+            else {
+                radius = (effectiveThumbThickness - effectiveBarOffset) / 2;
+            }
+
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
+
+            var thumbPosition = (this._isVertical) ? ((this._maximum - this._value) / (this._maximum - this._minimum)) * backgroundBoxLength : ((this._value - this._minimum) / (this._maximum - this._minimum)) * backgroundBoxLength;
+            context.fillStyle = this._background;
 
+            if (this._isVertical) {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left + backgroundBoxThickness / 2, top, radius, Math.PI, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top, width, height);
+                    }
+                    else {
+                        context.fillRect(left, top, width, height + effectiveThumbThickness);
+                    }
                 }
                 else {
-                    top += effectiveBarOffset;
-                    if(!this.isThumbClamped) {
-                       left += (effectiveThumbThickness / 2);
-                    }
-                    height = backgroundBoxThickness;
-                    width = backgroundBoxLength;
+                    context.fillRect(left, top, width, height);
                 }
-
-                if(this.isThumbClamped && this.isThumbCircle){
-                    if(this._isVertical)
-                        top += (effectiveThumbThickness / 2);
-                    else 
-                        left += (effectiveThumbThickness / 2);
-
-                    radius = backgroundBoxThickness / 2;
+            }
+            else {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left + backgroundBoxLength, top + (backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top, width, height);
+                    }
+                    else {
+                        context.fillRect(left, top, width + effectiveThumbThickness, height);
+                    }
                 }
-                else{
-                    radius = (effectiveThumbThickness- effectiveBarOffset) / 2;
+                else {
+                    context.fillRect(left, top, width, height);
                 }
+            }
 
-                if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
+            }
 
-                var thumbPosition = (this._isVertical) ? ((this._maximum - this._value) / (this._maximum - this._minimum)) * backgroundBoxLength : ((this._value - this._minimum) / (this._maximum - this._minimum)) * backgroundBoxLength;
-                context.fillStyle = this._background;
-                
-                if(this._isVertical){
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left + backgroundBoxThickness / 2, top, radius, Math.PI, 2 * Math.PI);
-                            context.fill();
-                            context.fillRect(left, top, width , height);
-                        }
-                        else {
-                            context.fillRect(left, top, width, height + effectiveThumbThickness);
-                        }
+            context.fillStyle = this.color;
+            if (this._isVertical) {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left + backgroundBoxThickness / 2, top + backgroundBoxLength, radius, 0, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
                     }
                     else {
-                        context.fillRect(left, top , width, height);
+                        context.fillRect(left, top + thumbPosition, width, this._currentMeasure.height - thumbPosition);
                     }
                 }
-                else{
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left + backgroundBoxLength , top + (backgroundBoxThickness/2), radius, 0,  2* Math.PI);
-                            context.fill();
-                            context.fillRect(left, top, width, height);
-                        }
-                        else {
-                            context.fillRect(left, top, width + effectiveThumbThickness, height);
-                        }
+                else {
+                    context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
+                }
+            }
+            else {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left, top + backgroundBoxThickness / 2, radius, 0, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top, thumbPosition, height);
                     }
                     else {
-                        context.fillRect(left, top, width, height);
+                        context.fillRect(left, top, thumbPosition, height);
                     }
                 }
+                else {
+                    context.fillRect(left, top, thumbPosition, height);
+                }
+            }
+
 
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
+            if (this._isThumbCircle) {
+                context.beginPath();
+                if (this._isVertical) {
+                    context.arc(left + backgroundBoxThickness / 2, top + thumbPosition, radius, 0, 2 * Math.PI);
+                }
+                else {
+                    context.arc(left + thumbPosition, top + (backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
+                }
+                context.fill();
                 if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                     context.shadowBlur = 0;
                     context.shadowOffsetX = 0;
                     context.shadowOffsetY = 0;
                 }
-                
-                context.fillStyle = this.color;
-                if(this._isVertical){
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left + backgroundBoxThickness / 2, top + backgroundBoxLength, radius, 0, 2 * Math.PI);
-                            context.fill();
-                            context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
-                        }
-                        else {
-                            context.fillRect(left, top + thumbPosition, width, this._currentMeasure.height - thumbPosition);
-                        }
-                    }
-                    else {
-                        context.fillRect(left, top + thumbPosition ,width,  height - thumbPosition);
-                    }
+                context.strokeStyle = this._borderColor;
+                context.stroke();
+            }
+            else {
+                if (this._isVertical) {
+                    context.fillRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
                 }
-                else{
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left , top + backgroundBoxThickness/2 , radius, 0, 2 * Math.PI);
-                            context.fill();
-                            context.fillRect(left, top, thumbPosition, height);
-                        }
-                        else {
-                            context.fillRect(left, top, thumbPosition, height);
-                        }
-                    }
-                    else {
-                        context.fillRect(left , top, thumbPosition,  height);
-                    }
+                else {
+                    context.fillRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
                 }
-               
-               
                 if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
+                    context.shadowBlur = 0;
+                    context.shadowOffsetX = 0;
+                    context.shadowOffsetY = 0;
                 }
-                if (this._isThumbCircle) {
-                    context.beginPath();
-                    if (this._isVertical) {
-                        context.arc(left + backgroundBoxThickness / 2, top + thumbPosition, radius, 0, 2 * Math.PI);
-                    }
-                    else {
-                        context.arc(left + thumbPosition, top + ( backgroundBoxThickness/2), radius, 0, 2 * Math.PI);
-                    }
-                    context.fill();
-                    if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                        context.shadowBlur = 0;
-                        context.shadowOffsetX = 0;
-                        context.shadowOffsetY = 0;
-                    }
-                    context.strokeStyle = this._borderColor;
-                    context.stroke();
+                context.strokeStyle = this._borderColor;
+                if (this._isVertical) {
+                    context.strokeRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
                 }
                 else {
-                    if (this._isVertical) {
-                        context.fillRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
-                    }
-                    else {
-                        context.fillRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
-                    }
-                    if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                        context.shadowBlur = 0;
-                        context.shadowOffsetX = 0;
-                        context.shadowOffsetY = 0;
-                    }
-                    context.strokeStyle = this._borderColor;
-                    if (this._isVertical) {
-                        context.strokeRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
-                    }
-                    else {
-                        context.strokeRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
-                    }
+                    context.strokeRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
                 }
             }
-            context.restore();
         }
+        context.restore();
+    }
 
 
-        // Events
-        private _pointerIsDown = false;
+    // Events
+    private _pointerIsDown = false;
 
-        private _updateValueFromPointer(x: number, y: number): void {
-            if (this.rotation != 0) {
-                this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
-                x = this._transformedPosition.x;
-                y = this._transformedPosition.y;
-            }
-            
-            if(this._isVertical){
-                this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
-            }
-            else{
-                this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
-            }
+    private _updateValueFromPointer(x: number, y: number): void {
+        if (this.rotation != 0) {
+            this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
+            x = this._transformedPosition.x;
+            y = this._transformedPosition.y;
         }
 
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
+        if (this._isVertical) {
+            this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
+        }
+        else {
+            this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
+        }
+    }
 
-            this._pointerIsDown = true;
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
+        }
 
-            this._updateValueFromPointer(coordinates.x, coordinates.y);
-            this._host._capturingControl[pointerId] = this;
+        this._pointerIsDown = true;
 
-            return true;
-        }
+        this._updateValueFromPointer(coordinates.x, coordinates.y);
+        this._host._capturingControl[pointerId] = this;
 
-        public _onPointerMove(target: Control, coordinates: Vector2): void {
-            if (this._pointerIsDown) {
-                this._updateValueFromPointer(coordinates.x, coordinates.y);
-            }
+        return true;
+    }
 
-            super._onPointerMove(target, coordinates);
+    public _onPointerMove(target: Control, coordinates: Vector2): void {
+        if (this._pointerIsDown) {
+            this._updateValueFromPointer(coordinates.x, coordinates.y);
         }
 
-        public _onPointerUp(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            this._pointerIsDown = false;
+        super._onPointerMove(target, coordinates);
+    }
 
-            delete this._host._capturingControl[pointerId];
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
-        }
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        this._pointerIsDown = false;
+
+        delete this._host._capturingControl[pointerId];
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
     }
 }

+ 127 - 127
gui/src/2D/controls/stackPanel.ts

@@ -1,153 +1,153 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container } from "./container";
+import { Measure } from "../measure";
+import { Control } from "./control";
+
+/**
+ * Class used to create a 2D stack panel container
+ */
+export class StackPanel extends Container {
+    private _isVertical = true;
+    private _manualWidth = false;
+    private _manualHeight = false;
+    private _doNotTrackManualChanges = false;
+    private _tempMeasureStore = Measure.Empty();
+
+    /** Gets or sets a boolean indicating if the stack panel is vertical or horizontal*/
+    public get isVertical(): boolean {
+        return this._isVertical;
+    }
+
+    public set isVertical(value: boolean) {
+        if (this._isVertical === value) {
+            return;
+        }
 
-module BABYLON.GUI {
-    /**
-     * Class used to create a 2D stack panel container
-     */
-    export class StackPanel extends Container {
-        private _isVertical = true;
-        private _manualWidth = false;
-        private _manualHeight = false;
-        private _doNotTrackManualChanges = false;
-        private _tempMeasureStore = Measure.Empty();
-
-        /** Gets or sets a boolean indicating if the stack panel is vertical or horizontal*/
-        public get isVertical(): boolean {
-            return this._isVertical;
+        this._isVertical = value;
+        this._markAsDirty();
+    }
+
+    /** Gets or sets panel width */
+    public set width(value: string | number) {
+        if (!this._doNotTrackManualChanges) {
+            this._manualWidth = true;
         }
 
-        public set isVertical(value: boolean) {
-            if (this._isVertical === value) {
-                return;
-            }
+        if (this._width.toString(this._host) === value) {
+            return;
+        }
 
-            this._isVertical = value;
+        if (this._width.fromString(value)) {
             this._markAsDirty();
         }
-       
-        /** Gets or sets panel width */
-        public set width(value: string | number ) {
-            if (!this._doNotTrackManualChanges) {
-                this._manualWidth = true;
-            }
+    }
 
-            if (this._width.toString(this._host) === value) {
-                return;
-            }
+    public get width(): string | number {
+        return this._width.toString(this._host);
+    }
 
-            if (this._width.fromString(value)) {
-                this._markAsDirty();
-            }
+    /** Gets or sets panel height */
+    public set height(value: string | number) {
+        if (!this._doNotTrackManualChanges) {
+            this._manualHeight = true;
         }
 
-        public get width(): string | number {
-            return this._width.toString(this._host);
-        }        
+        if (this._height.toString(this._host) === value) {
+            return;
+        }
 
-        /** Gets or sets panel height */
-        public set height(value: string | number ) {
-            if (!this._doNotTrackManualChanges) {
-                this._manualHeight = true;
-            }
+        if (this._height.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
 
-            if (this._height.toString(this._host) === value) {
-                return;
-            }
+    public get height(): string | number {
+        return this._height.toString(this._host);
+    }
 
-            if (this._height.fromString(value)) {
-                this._markAsDirty();
+    /**
+     * Creates a new StackPanel
+     * @param name defines control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
+
+    protected _getTypeName(): string {
+        return "StackPanel";
+    }
+
+    protected _preMeasure(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        var stackWidth = 0;
+        var stackHeight = 0;
+        for (var child of this._children) {
+            this._tempMeasureStore.copyFrom(child._currentMeasure);
+            child._currentMeasure.copyFrom(parentMeasure);
+            child._measure();
+
+            if (this._isVertical) {
+                child.top = stackHeight + "px";
+                if (!child._top.ignoreAdaptiveScaling) {
+                    child._markAsDirty();
+                }
+                child._top.ignoreAdaptiveScaling = true;
+                stackHeight += child._currentMeasure.height;
+                if (child._currentMeasure.width > stackWidth) {
+                    stackWidth = child._currentMeasure.width;
+                }
+                child.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
+            } else {
+                child.left = stackWidth + "px";
+                if (!child._left.ignoreAdaptiveScaling) {
+                    child._markAsDirty();
+                }
+                child._left.ignoreAdaptiveScaling = true;
+                stackWidth += child._currentMeasure.width;
+                if (child._currentMeasure.height > stackHeight) {
+                    stackHeight = child._currentMeasure.height;
+                }
+                child.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
             }
-        }        
-                
-        public get height(): string | number  {
-            return this._height.toString(this._host);
-        }
-    
-        /**
-         * Creates a new StackPanel
-         * @param name defines control name
-         */
-        constructor(public name?: string) {
-            super(name);
+
+            child._currentMeasure.copyFrom(this._tempMeasureStore);
         }
 
-        protected _getTypeName(): string {
-            return "StackPanel";
-        }              
-
-        protected _preMeasure(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            var stackWidth = 0;
-            var stackHeight = 0;
-            for (var child of this._children) {
-                this._tempMeasureStore.copyFrom(child._currentMeasure);
-                child._currentMeasure.copyFrom(parentMeasure);
-                child._measure();
-                
-                if (this._isVertical) {
-                    child.top = stackHeight + "px";
-                    if (!child._top.ignoreAdaptiveScaling) {
-                        child._markAsDirty();
-                    }
-                    child._top.ignoreAdaptiveScaling = true;
-                    stackHeight += child._currentMeasure.height;
-                    if(child._currentMeasure.width > stackWidth) {
-                        stackWidth = child._currentMeasure.width;                        
-                    }
-                    child.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
-                } else {
-                    child.left = stackWidth + "px";
-                    if (!child._left.ignoreAdaptiveScaling) {
-                        child._markAsDirty();
-                    }                    
-                    child._left.ignoreAdaptiveScaling = true;
-                    stackWidth += child._currentMeasure.width;
-                    if(child._currentMeasure.height > stackHeight) {
-                        stackHeight = child._currentMeasure.height;                        
-                    }
-                    child.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
-                }
+        this._doNotTrackManualChanges = true;
 
-                child._currentMeasure.copyFrom(this._tempMeasureStore);
-            }
-            
-            this._doNotTrackManualChanges = true;
+        // Let stack panel width and height default to stackHeight and stackWidth if dimensions are not specified.
+        // User can now define their own height and width for stack panel.
 
-            // Let stack panel width and height default to stackHeight and stackWidth if dimensions are not specified.
-            // User can now define their own height and width for stack panel.
+        let panelWidthChanged = false;
+        let panelHeightChanged = false;
 
-            let panelWidthChanged = false;
-            let panelHeightChanged = false;
+        let previousHeight = this.height;
+        let previousWidth = this.width;
 
-            let previousHeight = this.height;
-            let previousWidth = this.width;
+        if (!this._manualHeight) {
+            // do not specify height if strictly defined by user
+            this.height = stackHeight + "px";
+        }
+        if (!this._manualWidth) {
+            // do not specify width if strictly defined by user
+            this.width = stackWidth + "px";
+        }
 
-            if (!this._manualHeight) {
-                // do not specify height if strictly defined by user
-                this.height = stackHeight + "px";
-            }
-            if (!this._manualWidth) {
-                // do not specify width if strictly defined by user
-                this.width = stackWidth + "px";
-            }
+        panelWidthChanged = previousWidth !== this.width || !this._width.ignoreAdaptiveScaling;
+        panelHeightChanged = previousHeight !== this.height || !this._height.ignoreAdaptiveScaling;
 
-            panelWidthChanged = previousWidth !== this.width || !this._width.ignoreAdaptiveScaling;
-            panelHeightChanged = previousHeight !== this.height || !this._height.ignoreAdaptiveScaling;
+        if (panelHeightChanged) {
+            this._height.ignoreAdaptiveScaling = true;
+        }
 
-            if (panelHeightChanged) {
-                this._height.ignoreAdaptiveScaling = true;
-            }
+        if (panelWidthChanged) {
+            this._width.ignoreAdaptiveScaling = true;
+        }
 
-            if (panelWidthChanged) {
-                this._width.ignoreAdaptiveScaling = true;
-            }
+        this._doNotTrackManualChanges = false;
 
-            this._doNotTrackManualChanges = false;
+        if (panelWidthChanged || panelHeightChanged) {
+            this._markAllAsDirty();
+        }
 
-            if (panelWidthChanged || panelHeightChanged) {
-                this._markAllAsDirty();
-            }
-            
-            super._preMeasure(parentMeasure, context);
-        }    
-    }    
-}
+        super._preMeasure(parentMeasure, context);
+    }
+}  

+ 278 - 277
gui/src/2D/controls/textBlock.ts

@@ -1,348 +1,349 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Observable } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create text block control
+ */
+export class TextBlock extends Control {
+    private _text = "";
+    private _textWrapping = false;
+    private _textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+    private _textVerticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
+
+    private _lines: any[];
+    private _resizeToFit: boolean = false;
+    private _lineSpacing: ValueAndUnit = new ValueAndUnit(0);
+    private _outlineWidth: number = 0;
+    private _outlineColor: string = "white";
+    /**
+    * An event triggered after the text is changed
+    */
+    public onTextChangedObservable = new Observable<TextBlock>();
+
+    /**
+    * An event triggered after the text was broken up into lines
+    */
+    public onLinesReadyObservable = new Observable<TextBlock>();
 
-module BABYLON.GUI {
     /**
-     * Class used to create text block control
+     * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
      */
-    export class TextBlock extends Control {
-        private _text = "";
-        private _textWrapping = false;
-        private _textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
-        private _textVerticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
-
-        private _lines: any[];
-        private _resizeToFit: boolean = false;
-        private _lineSpacing: ValueAndUnit = new ValueAndUnit(0);
-        private _outlineWidth: number = 0;
-        private _outlineColor: string = "white";
-        /**
-        * An event triggered after the text is changed
-        */
-        public onTextChangedObservable = new Observable<TextBlock>();
+    public get lines(): any[] {
+        return this._lines;
+    }
 
-        /**
-        * An event triggered after the text was broken up into lines
-        */
-        public onLinesReadyObservable = new Observable<TextBlock>();
+    /**
+     * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+     */
+    public get resizeToFit(): boolean {
+        return this._resizeToFit;
+    }
 
-        /**
-         * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
-         */
-        public get lines(): any[] {
-            return this._lines;
-        }
-        
-        /**
-         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
-         */
-        public get resizeToFit(): boolean {
-            return this._resizeToFit;
-        }
+    /**
+     * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+     */
+    public set resizeToFit(value: boolean) {
+        this._resizeToFit = value;
 
-        /**
-         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
-         */        
-        public set resizeToFit(value: boolean) {
-            this._resizeToFit = value;
-
-            if (this._resizeToFit) {
-                this._width.ignoreAdaptiveScaling = true;
-                this._height.ignoreAdaptiveScaling = true;
-            }
+        if (this._resizeToFit) {
+            this._width.ignoreAdaptiveScaling = true;
+            this._height.ignoreAdaptiveScaling = true;
         }
+    }
 
-        /**
-         * Gets or sets a boolean indicating if text must be wrapped
-         */
-        public get textWrapping(): boolean {
-            return this._textWrapping;
-        }
+    /**
+     * Gets or sets a boolean indicating if text must be wrapped
+     */
+    public get textWrapping(): boolean {
+        return this._textWrapping;
+    }
 
-        /**
-         * Gets or sets a boolean indicating if text must be wrapped
-         */        
-        public set textWrapping(value: boolean) {
-            if (this._textWrapping === value) {
-                return;
-            }
-            this._textWrapping = value;
-            this._markAsDirty();
+    /**
+     * Gets or sets a boolean indicating if text must be wrapped
+     */
+    public set textWrapping(value: boolean) {
+        if (this._textWrapping === value) {
+            return;
         }
+        this._textWrapping = value;
+        this._markAsDirty();
+    }
 
-        /**
-         * Gets or sets text to display
-         */
-        public get text(): string {
-            return this._text;
+    /**
+     * Gets or sets text to display
+     */
+    public get text(): string {
+        return this._text;
+    }
+
+    /**
+     * Gets or sets text to display
+     */
+    public set text(value: string) {
+        if (this._text === value) {
+            return;
         }
+        this._text = value;
+        this._markAsDirty();
 
-        /**
-         * Gets or sets text to display
-         */
-        public set text(value: string) {
-            if (this._text === value) {
-                return;
-            }
-            this._text = value;
-            this._markAsDirty();
+        this.onTextChangedObservable.notifyObservers(this);
+    }
 
-            this.onTextChangedObservable.notifyObservers(this);
-        }
+    /**
+     * Gets or sets text horizontal alignment (Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+     */
+    public get textHorizontalAlignment(): number {
+        return this._textHorizontalAlignment;
+    }
 
-        /**
-         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
-         */
-        public get textHorizontalAlignment(): number {
-            return this._textHorizontalAlignment;
+    /**
+     * Gets or sets text horizontal alignment (Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+     */
+    public set textHorizontalAlignment(value: number) {
+        if (this._textHorizontalAlignment === value) {
+            return;
         }
 
-        /**
-         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
-         */        
-        public set textHorizontalAlignment(value: number) {
-            if (this._textHorizontalAlignment === value) {
-                return;
-            }
+        this._textHorizontalAlignment = value;
+        this._markAsDirty();
+    }
 
-            this._textHorizontalAlignment = value;
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets text vertical alignment (Control.VERTICAL_ALIGNMENT_CENTER by default)
+     */
+    public get textVerticalAlignment(): number {
+        return this._textVerticalAlignment;
+    }
 
-        /**
-         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
-         */        
-        public get textVerticalAlignment(): number {
-            return this._textVerticalAlignment;
+    /**
+     * Gets or sets text vertical alignment (Control.VERTICAL_ALIGNMENT_CENTER by default)
+     */
+    public set textVerticalAlignment(value: number) {
+        if (this._textVerticalAlignment === value) {
+            return;
         }
 
-        /**
-         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
-         */           
-        public set textVerticalAlignment(value: number) {
-            if (this._textVerticalAlignment === value) {
-                return;
-            }
+        this._textVerticalAlignment = value;
+        this._markAsDirty();
+    }
 
-            this._textVerticalAlignment = value;
+    /**
+     * Gets or sets line spacing value
+     */
+    public set lineSpacing(value: string | number) {
+        if (this._lineSpacing.fromString(value)) {
             this._markAsDirty();
         }
+    }
 
-        /**
-         * Gets or sets line spacing value
-         */
-        public set lineSpacing(value: string | number) {
-            if (this._lineSpacing.fromString(value)) {
-                this._markAsDirty();
-            }
-        }
+    /**
+     * Gets or sets line spacing value
+     */
+    public get lineSpacing(): string | number {
+        return this._lineSpacing.toString(this._host);
+    }
 
-        /**
-         * Gets or sets line spacing value
-         */        
-        public get lineSpacing(): string | number {
-            return this._lineSpacing.toString(this._host);
-        }
+    /**
+     * Gets or sets outlineWidth of the text to display
+     */
+    public get outlineWidth(): number {
+        return this._outlineWidth;
+    }
 
-        /**
-         * Gets or sets outlineWidth of the text to display
-         */
-        public get outlineWidth(): number {
-            return this._outlineWidth;
+    /**
+     * Gets or sets outlineWidth of the text to display
+     */
+    public set outlineWidth(value: number) {
+        if (this._outlineWidth === value) {
+            return;
         }
+        this._outlineWidth = value;
+        this._markAsDirty();
+    }
 
-        /**
-         * Gets or sets outlineWidth of the text to display
-         */
-        public set outlineWidth(value: number) {
-            if (this._outlineWidth === value) {
-                return;
-            }
-            this._outlineWidth = value;
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets outlineColor of the text to display
+     */
+    public get outlineColor(): string {
+        return this._outlineColor;
+    }
 
-        /**
-         * Gets or sets outlineColor of the text to display
-         */
-        public get outlineColor(): string {
-            return this._outlineColor;
+    /**
+     * Gets or sets outlineColor of the text to display
+     */
+    public set outlineColor(value: string) {
+        if (this._outlineColor === value) {
+            return;
         }
+        this._outlineColor = value;
+        this._markAsDirty();
+    }
 
+    /**
+     * Creates a new TextBlock object
+     * @param name defines the name of the control
+     * @param text defines the text to display (emptry string by default)
+     */
+    constructor(
         /**
-         * Gets or sets outlineColor of the text to display
+         * Defines the name of the control
          */
-        public set outlineColor(value: string) {
-            if (this._outlineColor === value) {
-                return;
-            }
-            this._outlineColor = value;
-            this._markAsDirty();
+        public name?: string,
+        text: string = "") {
+        super(name);
+
+        this.text = text;
+    }
+
+    protected _getTypeName(): string {
+        return "TextBlock";
+    }
+
+    private _drawText(text: string, textWidth: number, y: number, context: CanvasRenderingContext2D): void {
+        var width = this._currentMeasure.width;
+        var x = 0;
+        switch (this._textHorizontalAlignment) {
+            case Control.HORIZONTAL_ALIGNMENT_LEFT:
+                x = 0
+                break;
+            case Control.HORIZONTAL_ALIGNMENT_RIGHT:
+                x = width - textWidth;
+                break;
+            case Control.HORIZONTAL_ALIGNMENT_CENTER:
+                x = (width - textWidth) / 2;
+                break;
         }
 
-        /**
-         * Creates a new TextBlock object
-         * @param name defines the name of the control
-         * @param text defines the text to display (emptry string by default)
-         */
-        constructor(
-            /**
-             * Defines the name of the control
-             */
-            public name?: string, 
-            text: string = "") {
-            super(name);
-
-            this.text = text;
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
         }
 
-        protected _getTypeName(): string {
-            return "TextBlock";
+        if (this.outlineWidth) {
+            context.strokeText(text, this._currentMeasure.left + x, y);
         }
+        context.fillText(text, this._currentMeasure.left + x, y);
+    }
 
-        private _drawText(text: string, textWidth: number, y: number, context: CanvasRenderingContext2D): void {
-            var width = this._currentMeasure.width;
-            var x = 0;
-            switch (this._textHorizontalAlignment) {
-                case Control.HORIZONTAL_ALIGNMENT_LEFT:
-                    x = 0
-                    break;
-                case Control.HORIZONTAL_ALIGNMENT_RIGHT:
-                    x = width - textWidth;
-                    break;
-                case Control.HORIZONTAL_ALIGNMENT_CENTER:
-                    x = (width - textWidth) / 2;
-                    break;
-            }
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
-            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+        this._applyStates(context);
 
-            if (this.outlineWidth) {
-                context.strokeText(text, this._currentMeasure.left + x, y);
-            }
-            context.fillText(text, this._currentMeasure.left + x, y);
+        if (this._processMeasures(parentMeasure, context)) {
+            // Render lines
+            this._renderLines(context);
         }
+        context.restore();
+    }
 
-        /** @hidden */
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+    protected _applyStates(context: CanvasRenderingContext2D): void {
+        super._applyStates(context);
+        if (this.outlineWidth) {
+            context.lineWidth = this.outlineWidth;
+            context.strokeStyle = this.outlineColor;
+        }
+    }
 
-            this._applyStates(context);
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._lines = [];
+        var _lines = this.text.split("\n");
 
-            if (this._processMeasures(parentMeasure, context)) {
-                // Render lines
-                this._renderLines(context);
+        if (this._textWrapping && !this._resizeToFit) {
+            for (var _line of _lines) {
+                this._lines.push(this._parseLineWithTextWrapping(_line, context));
             }
-            context.restore();
-        }
-
-        protected _applyStates(context: CanvasRenderingContext2D): void {
-            super._applyStates(context);
-            if (this.outlineWidth) {
-                context.lineWidth = this.outlineWidth;
-                context.strokeStyle = this.outlineColor;
+        } else {
+            for (var _line of _lines) {
+                this._lines.push(this._parseLine(_line, context));
             }
         }
 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            this._lines = [];
-            var _lines = this.text.split("\n");
+        this.onLinesReadyObservable.notifyObservers(this);
+    }
 
-            if (this._textWrapping && !this._resizeToFit) {
-                for (var _line of _lines) {
-                    this._lines.push(this._parseLineWithTextWrapping(_line, context));
-                }
-            } else {
-                for (var _line of _lines) {
-                    this._lines.push(this._parseLine(_line, context));
-                }
-            }
+    protected _parseLine(line: string = '', context: CanvasRenderingContext2D): object {
+        return { text: line, width: context.measureText(line).width };
+    }
 
-            this.onLinesReadyObservable.notifyObservers(this);
+    protected _parseLineWithTextWrapping(line: string = '', context: CanvasRenderingContext2D): object {
+        var words = line.split(' ');
+        var width = this._currentMeasure.width;
+        var lineWidth = 0;
+
+        for (var n = 0; n < words.length; n++) {
+            var testLine = n > 0 ? line + " " + words[n] : words[0];
+            var metrics = context.measureText(testLine);
+            var testWidth = metrics.width;
+            if (testWidth > width && n > 0) {
+                this._lines.push({ text: line, width: lineWidth });
+                line = words[n];
+                lineWidth = context.measureText(line).width;
+            }
+            else {
+                lineWidth = testWidth;
+                line = testLine;
+            }
         }
 
-        protected _parseLine(line: string = '', context: CanvasRenderingContext2D): object {
-            return { text: line, width: context.measureText(line).width };
-        }
+        return { text: line, width: lineWidth };
+    }
 
-        protected _parseLineWithTextWrapping(line: string = '', context: CanvasRenderingContext2D): object {
-            var words = line.split(' ');
-            var width = this._currentMeasure.width;
-            var lineWidth = 0;
-
-            for (var n = 0; n < words.length; n++) {
-                var testLine = n > 0 ? line + " " + words[n] : words[0];
-                var metrics = context.measureText(testLine);
-                var testWidth = metrics.width;
-                if (testWidth > width && n > 0) {
-                    this._lines.push({ text: line, width: lineWidth });
-                    line = words[n];
-                    lineWidth = context.measureText(line).width;
-                }
-                else {
-                    lineWidth = testWidth;
-                    line = testLine;
-                }
-            }
+    protected _renderLines(context: CanvasRenderingContext2D): void {
+        var height = this._currentMeasure.height;
 
-            return { text: line, width: lineWidth };
+        if (!this._fontOffset) {
+            this._fontOffset = Control._GetFontOffset(context.font);
+        }
+        var rootY = 0;
+        switch (this._textVerticalAlignment) {
+            case Control.VERTICAL_ALIGNMENT_TOP:
+                rootY = this._fontOffset.ascent;
+                break;
+            case Control.VERTICAL_ALIGNMENT_BOTTOM:
+                rootY = height - this._fontOffset.height * (this._lines.length - 1) - this._fontOffset.descent;
+                break;
+            case Control.VERTICAL_ALIGNMENT_CENTER:
+                rootY = this._fontOffset.ascent + (height - this._fontOffset.height * this._lines.length) / 2;
+                break;
         }
 
-        protected _renderLines(context: CanvasRenderingContext2D): void {
-            var height = this._currentMeasure.height;
-
-            if (!this._fontOffset) {
-                this._fontOffset = Control._GetFontOffset(context.font);
-            }
-            var rootY = 0;
-            switch (this._textVerticalAlignment) {
-                case Control.VERTICAL_ALIGNMENT_TOP:
-                    rootY = this._fontOffset.ascent;
-                    break;
-                case Control.VERTICAL_ALIGNMENT_BOTTOM:
-                    rootY = height - this._fontOffset.height * (this._lines.length - 1) - this._fontOffset.descent;
-                    break;
-                case Control.VERTICAL_ALIGNMENT_CENTER:
-                    rootY = this._fontOffset.ascent + (height - this._fontOffset.height * this._lines.length) / 2;
-                    break;
-            }
-
-            rootY += this._currentMeasure.top;
+        rootY += this._currentMeasure.top;
 
-            var maxLineWidth: number = 0;
+        var maxLineWidth: number = 0;
 
-            for (let i = 0; i < this._lines.length; i++) {
-                const line = this._lines[i];
+        for (let i = 0; i < this._lines.length; i++) {
+            const line = this._lines[i];
 
-                if (i !== 0 && this._lineSpacing.internalValue !== 0) {
+            if (i !== 0 && this._lineSpacing.internalValue !== 0) {
 
-                    if (this._lineSpacing.isPixel) {
-                        rootY += this._lineSpacing.getValue(this._host);
-                    } else {                        
-                        rootY = rootY + (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host,  this._cachedParentMeasure.height));
-                    }
+                if (this._lineSpacing.isPixel) {
+                    rootY += this._lineSpacing.getValue(this._host);
+                } else {
+                    rootY = rootY + (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
                 }
+            }
 
-                this._drawText(line.text, line.width, rootY, context);
-                rootY += this._fontOffset.height;
+            this._drawText(line.text, line.width, rootY, context);
+            rootY += this._fontOffset.height;
 
-                if (line.width > maxLineWidth) maxLineWidth = line.width;
-            }
+            if (line.width > maxLineWidth) maxLineWidth = line.width;
+        }
 
-            if (this._resizeToFit) {
-                this.width = this.paddingLeftInPixels + this.paddingRightInPixels + maxLineWidth + 'px';
-                this.height = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * this._lines.length + 'px';
-            }
+        if (this._resizeToFit) {
+            this.width = this.paddingLeftInPixels + this.paddingRightInPixels + maxLineWidth + 'px';
+            this.height = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * this._lines.length + 'px';
         }
+    }
 
-        dispose(): void {
-            super.dispose();
+    dispose(): void {
+        super.dispose();
 
-            this.onTextChangedObservable.clear();
-        }
+        this.onTextChangedObservable.clear();
     }
 }

+ 199 - 196
gui/src/2D/controls/virtualKeyboard.ts

@@ -1,238 +1,241 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
+import { StackPanel } from "./stackPanel";
+import { Observable, Nullable, Observer } from "babylonjs";
+import { Button } from "./button";
+import { Container } from "./container";
+import { TextBlock } from "./textBlock";
+import { InputText } from "./inputText";
+
+
+/**
+ * Class used to store key control properties
+ */
+export class KeyPropertySet {
+    /** Width */
+    width?: string;
+    /** Height */
+    height?: string;
+    /** Left padding */
+    paddingLeft?: string;
+    /** Right padding */
+    paddingRight?: string;
+    /** Top padding */
+    paddingTop?: string;
+    /** Bottom padding */
+    paddingBottom?: string;
+    /** Foreground color */
+    color?: string;
+    /** Background color */
+    background?: string;
+}
 
-    /**
-     * Class used to store key control properties
-     */
-    export class KeyPropertySet {
-        /** Width */
-        width?: string;
-        /** Height */
-        height?: string;
-        /** Left padding */
-        paddingLeft?: string;
-        /** Right padding */
-        paddingRight?: string;
-        /** Top padding */
-        paddingTop?: string;
-        /** Bottom padding */
-        paddingBottom?: string;
-        /** Foreground color */
-        color?: string;
-        /** Background color */
-        background?: string;
+/**
+ * Class used to create virtual keyboard
+ */
+export class VirtualKeyboard extends StackPanel {
+    /** Observable raised when a key is pressed */
+    public onKeyPressObservable = new Observable<string>();
+
+    /** Gets or sets default key button width */
+    public defaultButtonWidth = "40px";
+    /** Gets or sets default key button height */
+    public defaultButtonHeight = "40px";
+
+    /** Gets or sets default key button left padding */
+    public defaultButtonPaddingLeft = "2px";
+    /** Gets or sets default key button right padding */
+    public defaultButtonPaddingRight = "2px";
+    /** Gets or sets default key button top padding */
+    public defaultButtonPaddingTop = "2px";
+    /** Gets or sets default key button bottom padding */
+    public defaultButtonPaddingBottom = "2px";
+
+    /** Gets or sets default key button foreground color */
+    public defaultButtonColor = "#DDD";
+    /** Gets or sets default key button background color */
+    public defaultButtonBackground = "#070707";
+
+    /** Gets or sets shift button foreground color */
+    public shiftButtonColor = "#7799FF";
+    /** Gets or sets shift button thickness*/
+    public selectedShiftThickness = 1;
+
+    /** Gets shift key state */
+    public shiftState = 0;
+
+    protected _getTypeName(): string {
+        return "VirtualKeyboard";
     }
 
-    /**
-     * Class used to create virtual keyboard
-     */
-    export class VirtualKeyboard extends StackPanel {
-        /** Observable raised when a key is pressed */
-        public onKeyPressObservable = new Observable<string>();
-
-        /** Gets or sets default key button width */
-        public defaultButtonWidth = "40px";
-        /** Gets or sets default key button height */
-        public defaultButtonHeight = "40px";
-
-        /** Gets or sets default key button left padding */
-        public defaultButtonPaddingLeft = "2px";
-        /** Gets or sets default key button right padding */
-        public defaultButtonPaddingRight = "2px";
-        /** Gets or sets default key button top padding */
-        public defaultButtonPaddingTop = "2px";
-        /** Gets or sets default key button bottom padding */
-        public defaultButtonPaddingBottom = "2px";
-
-        /** Gets or sets default key button foreground color */
-        public defaultButtonColor = "#DDD";
-        /** Gets or sets default key button background color */
-        public defaultButtonBackground = "#070707";
-
-        /** Gets or sets shift button foreground color */
-        public shiftButtonColor = "#7799FF";
-        /** Gets or sets shift button thickness*/
-        public selectedShiftThickness = 1;
-
-        /** Gets shift key state */
-        public shiftState = 0;
-
-        protected _getTypeName(): string {
-            return "VirtualKeyboard";
-        }
+    private _createKey(key: string, propertySet: Nullable<KeyPropertySet>) {
+        var button = Button.CreateSimpleButton(key, key);
 
-        private _createKey(key: string, propertySet: Nullable<KeyPropertySet>) {
-            var button = Button.CreateSimpleButton(key, key);
+        button.width = propertySet && propertySet.width ? propertySet.width : this.defaultButtonWidth;
+        button.height = propertySet && propertySet.height ? propertySet.height : this.defaultButtonHeight;
+        button.color = propertySet && propertySet.color ? propertySet.color : this.defaultButtonColor;
+        button.background = propertySet && propertySet.background ? propertySet.background : this.defaultButtonBackground;
+        button.paddingLeft = propertySet && propertySet.paddingLeft ? propertySet.paddingLeft : this.defaultButtonPaddingLeft;
+        button.paddingRight = propertySet && propertySet.paddingRight ? propertySet.paddingRight : this.defaultButtonPaddingRight;
+        button.paddingTop = propertySet && propertySet.paddingTop ? propertySet.paddingTop : this.defaultButtonPaddingTop;
+        button.paddingBottom = propertySet && propertySet.paddingBottom ? propertySet.paddingBottom : this.defaultButtonPaddingBottom;
 
-            button.width = propertySet && propertySet.width ? propertySet.width : this.defaultButtonWidth;
-            button.height = propertySet && propertySet.height ? propertySet.height : this.defaultButtonHeight;
-            button.color = propertySet && propertySet.color ? propertySet.color : this.defaultButtonColor;
-            button.background = propertySet && propertySet.background ? propertySet.background : this.defaultButtonBackground;
-            button.paddingLeft = propertySet && propertySet.paddingLeft ? propertySet.paddingLeft : this.defaultButtonPaddingLeft;
-            button.paddingRight = propertySet && propertySet.paddingRight ? propertySet.paddingRight : this.defaultButtonPaddingRight;
-            button.paddingTop = propertySet && propertySet.paddingTop ? propertySet.paddingTop : this.defaultButtonPaddingTop;
-            button.paddingBottom = propertySet && propertySet.paddingBottom ? propertySet.paddingBottom : this.defaultButtonPaddingBottom;
+        button.thickness = 0;
+        button.isFocusInvisible = true;
 
-            button.thickness = 0;
-            button.isFocusInvisible = true;
+        button.shadowColor = this.shadowColor;
+        button.shadowBlur = this.shadowBlur;
+        button.shadowOffsetX = this.shadowOffsetX;
+        button.shadowOffsetY = this.shadowOffsetY;
 
-            button.shadowColor = this.shadowColor;
-            button.shadowBlur = this.shadowBlur;
-            button.shadowOffsetX = this.shadowOffsetX;
-            button.shadowOffsetY = this.shadowOffsetY;
+        button.onPointerUpObservable.add(() => {
+            this.onKeyPressObservable.notifyObservers(key);
+        });
 
-            button.onPointerUpObservable.add(() => {
-                this.onKeyPressObservable.notifyObservers(key);
-            });
+        return button;
+    }
 
-            return button;
-        }
+    /**
+     * Adds a new row of keys
+     * @param keys defines the list of keys to add
+     * @param propertySets defines the associated property sets
+     */
+    public addKeysRow(keys: Array<string>, propertySets?: Array<KeyPropertySet>): void {
+        let panel = new StackPanel();
+        panel.isVertical = false;
+        panel.isFocusInvisible = true;
 
-        /**
-         * Adds a new row of keys
-         * @param keys defines the list of keys to add
-         * @param propertySets defines the associated property sets
-         */
-        public addKeysRow(keys: Array<string>, propertySets?: Array<KeyPropertySet>): void {
-            let panel = new StackPanel();
-            panel.isVertical = false;
-            panel.isFocusInvisible = true;
-
-            for (var i = 0; i < keys.length; i++) {
-                let properties = null;
-
-                if (propertySets && propertySets.length === keys.length) {
-                    properties = propertySets[i];
-                }
+        for (var i = 0; i < keys.length; i++) {
+            let properties = null;
 
-                panel.addControl(this._createKey(keys[i], properties));
+            if (propertySets && propertySets.length === keys.length) {
+                properties = propertySets[i];
             }
 
-            this.addControl(panel);
+            panel.addControl(this._createKey(keys[i], properties));
         }
 
-        /**
-         * Set the shift key to a specific state
-         * @param shiftState defines the new shift state
-         */
-        public applyShiftState(shiftState: number): void {
-            if (!this.children) {
-                return;
-            }
+        this.addControl(panel);
+    }
 
-            for (var i = 0; i < this.children.length; i++) {
-                let row = this.children[i];
-                if (!row || !(<Container>row).children) {
-                    continue;
-                }
+    /**
+     * Set the shift key to a specific state
+     * @param shiftState defines the new shift state
+     */
+    public applyShiftState(shiftState: number): void {
+        if (!this.children) {
+            return;
+        }
 
-                let rowContainer = <Container>row;
-                for (var j = 0; j < rowContainer.children.length; j++) {
-                    let button = rowContainer.children[j] as Button;
+        for (var i = 0; i < this.children.length; i++) {
+            let row = this.children[i];
+            if (!row || !(<Container>row).children) {
+                continue;
+            }
 
-                    if (!button || !button.children[0]) {
-                        continue;
-                    }
+            let rowContainer = <Container>row;
+            for (var j = 0; j < rowContainer.children.length; j++) {
+                let button = rowContainer.children[j] as Button;
 
-                    let button_tblock = button.children[0] as TextBlock;
+                if (!button || !button.children[0]) {
+                    continue;
+                }
 
-                    if (button_tblock.text === "\u21E7") {
-                        button.color = (shiftState ? this.shiftButtonColor : this.defaultButtonColor);
-                        button.thickness = (shiftState > 1 ? this.selectedShiftThickness : 0);
-                    }
+                let button_tblock = button.children[0] as TextBlock;
 
-                    button_tblock.text = (shiftState > 0 ? button_tblock.text.toUpperCase() : button_tblock.text.toLowerCase());
+                if (button_tblock.text === "\u21E7") {
+                    button.color = (shiftState ? this.shiftButtonColor : this.defaultButtonColor);
+                    button.thickness = (shiftState > 1 ? this.selectedShiftThickness : 0);
                 }
-            }
-        }
-
-        private _connectedInputText: Nullable<InputText>;
-        private _onFocusObserver: Nullable<Observer<InputText>>;
-        private _onBlurObserver: Nullable<Observer<InputText>>;
-        private _onKeyPressObserver: Nullable<Observer<string>>;
 
-        /** Gets the input text control attached with the keyboard */
-        public get connectedInputText(): Nullable<InputText> {
-            return this._connectedInputText;
+                button_tblock.text = (shiftState > 0 ? button_tblock.text.toUpperCase() : button_tblock.text.toLowerCase());
+            }
         }
+    }
 
-        /**
-         * Connects the keyboard with an input text control
-         * @param input defines the target control
-         */
-        public connect(input: InputText): void {
-            this.isVisible = false;
-            this._connectedInputText = input;
+    private _connectedInputText: Nullable<InputText>;
+    private _onFocusObserver: Nullable<Observer<InputText>>;
+    private _onBlurObserver: Nullable<Observer<InputText>>;
+    private _onKeyPressObserver: Nullable<Observer<string>>;
 
-            // Events hooking
-            this._onFocusObserver = input.onFocusObservable.add(() => {
-                this.isVisible = true;
-            });
+    /** Gets the input text control attached with the keyboard */
+    public get connectedInputText(): Nullable<InputText> {
+        return this._connectedInputText;
+    }
 
-            this._onBlurObserver = input.onBlurObservable.add(() => {
-                this.isVisible = false;
-            });
+    /**
+     * Connects the keyboard with an input text control
+     * @param input defines the target control
+     */
+    public connect(input: InputText): void {
+        this.isVisible = false;
+        this._connectedInputText = input;
 
-            this._onKeyPressObserver = this.onKeyPressObservable.add((key) => {
-                if (!this._connectedInputText) {
-                    return;
-                }
-                switch (key) {
-                    case "\u21E7":
-                        this.shiftState++;
-                        if (this.shiftState > 2) {
-                            this.shiftState = 0;
-                        }
-                        this.applyShiftState(this.shiftState);
-                        return;
-                    case "\u2190":
-                        this._connectedInputText.processKey(8);
-                        return;
-                    case "\u21B5":
-                        this._connectedInputText.processKey(13);
-                        return;
-                }
-                this._connectedInputText.processKey(-1, (this.shiftState ? key.toUpperCase() : key));
+        // Events hooking
+        this._onFocusObserver = input.onFocusObservable.add(() => {
+            this.isVisible = true;
+        });
 
-                if (this.shiftState === 1) {
-                    this.shiftState = 0;
-                    this.applyShiftState(this.shiftState);
-                }
-            });
-        }
+        this._onBlurObserver = input.onBlurObservable.add(() => {
+            this.isVisible = false;
+        });
 
-        /**
-         * Disconnects the keyboard from an input text control
-         */
-        public disconnect(): void {
+        this._onKeyPressObserver = this.onKeyPressObservable.add((key) => {
             if (!this._connectedInputText) {
                 return;
             }
+            switch (key) {
+                case "\u21E7":
+                    this.shiftState++;
+                    if (this.shiftState > 2) {
+                        this.shiftState = 0;
+                    }
+                    this.applyShiftState(this.shiftState);
+                    return;
+                case "\u2190":
+                    this._connectedInputText.processKey(8);
+                    return;
+                case "\u21B5":
+                    this._connectedInputText.processKey(13);
+                    return;
+            }
+            this._connectedInputText.processKey(-1, (this.shiftState ? key.toUpperCase() : key));
 
-            this._connectedInputText.onFocusObservable.remove(this._onFocusObserver);
-            this._connectedInputText.onBlurObservable.remove(this._onBlurObserver);
-            this.onKeyPressObservable.remove(this._onKeyPressObserver);
+            if (this.shiftState === 1) {
+                this.shiftState = 0;
+                this.applyShiftState(this.shiftState);
+            }
+        });
+    }
 
-            this._connectedInputText = null;
+    /**
+     * Disconnects the keyboard from an input text control
+     */
+    public disconnect(): void {
+        if (!this._connectedInputText) {
+            return;
         }
 
-        // Statics
+        this._connectedInputText.onFocusObservable.remove(this._onFocusObserver);
+        this._connectedInputText.onBlurObservable.remove(this._onBlurObserver);
+        this.onKeyPressObservable.remove(this._onKeyPressObserver);
 
-        /**
-         * Creates a new keyboard using a default layout
-         * @returns a new VirtualKeyboard
-         */
-        public static CreateDefaultLayout(): VirtualKeyboard {
-            let returnValue = new VirtualKeyboard();
+        this._connectedInputText = null;
+    }
 
-            returnValue.addKeysRow(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\u2190"]);
-            returnValue.addKeysRow(["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]);
-            returnValue.addKeysRow(["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "\u21B5"]);
-            returnValue.addKeysRow(["\u21E7", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/"]);
-            returnValue.addKeysRow([" "], [{ width: "200px" }]);
+    // Statics
 
-            return returnValue;
-        }
+    /**
+     * Creates a new keyboard using a default layout
+     * @returns a new VirtualKeyboard
+     */
+    public static CreateDefaultLayout(): VirtualKeyboard {
+        let returnValue = new VirtualKeyboard();
+
+        returnValue.addKeysRow(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\u2190"]);
+        returnValue.addKeysRow(["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]);
+        returnValue.addKeysRow(["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "\u21B5"]);
+        returnValue.addKeysRow(["\u21E7", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/"]);
+        returnValue.addKeysRow([" "], [{ width: "200px" }]);
+
+        return returnValue;
     }
 }

+ 8 - 0
gui/src/2D/index.ts

@@ -0,0 +1,8 @@
+export * from "./controls";
+
+export * from "./advancedDynamicTexture";
+export * from "./math2D";
+export * from "./measure";
+export * from "./multiLinePoint";
+export * from "./style";
+export * from "./valueAndUnit";

+ 184 - 186
gui/src/2D/math2D.ts

@@ -1,207 +1,205 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { Vector2, Epsilon, Nullable } from "babylonjs";
 
-module BABYLON.GUI {
+/**
+ * Class used to transport Vector2 information for pointer events
+ */
+export class Vector2WithInfo extends Vector2 {
     /**
-     * Class used to transport Vector2 information for pointer events
-     */    
-    export class Vector2WithInfo extends Vector2 {    
-        /**
-         * Creates a new Vector2WithInfo
-         * @param source defines the vector2 data to transport
-         * @param buttonIndex defines the current mouse button index
-         */    
-        public constructor(source: Vector2, 
-            /** defines the current mouse button index */
-            public buttonIndex: number = 0) {
-            super(source.x, source.y);
-        }
+     * Creates a new Vector2WithInfo
+     * @param source defines the vector2 data to transport
+     * @param buttonIndex defines the current mouse button index
+     */
+    public constructor(source: Vector2,
+        /** defines the current mouse button index */
+        public buttonIndex: number = 0) {
+        super(source.x, source.y);
     }
+}
 
-    /** Class used to provide 2D matrix features */
-    export class Matrix2D {
-        /** Gets the internal array of 6 floats used to store matrix data */
-        public m = new Float32Array(6);
-
-        /**
-         * Creates a new matrix
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1) 
-         * @param m10 defines value for (1, 0) 
-         * @param m11 defines value for (1, 1) 
-         * @param m20 defines value for (2, 0) 
-         * @param m21 defines value for (2, 1) 
-         */
-        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) {
-            this.fromValues(m00, m01, m10, m11, m20, m21);
-        }
+/** Class used to provide 2D matrix features */
+export class Matrix2D {
+    /** Gets the internal array of 6 floats used to store matrix data */
+    public m = new Float32Array(6);
 
-        /**
-         * Fills the matrix from direct values
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         * @returns the current modified matrix
-         */
-        public fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D {
-            this.m[0] = m00; this.m[1] = m01; 
-            this.m[2] = m10; this.m[3] = m11;
-            this.m[4] = m20; this.m[5] = m21;
-            return this;
-        }
+    /**
+     * Creates a new matrix
+     * @param m00 defines value for (0, 0)
+     * @param m01 defines value for (0, 1) 
+     * @param m10 defines value for (1, 0) 
+     * @param m11 defines value for (1, 1) 
+     * @param m20 defines value for (2, 0) 
+     * @param m21 defines value for (2, 1) 
+     */
+    constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) {
+        this.fromValues(m00, m01, m10, m11, m20, m21);
+    }
 
-        /** 
-         * Gets matrix determinant
-         * @returns the determinant
-         */
-        public determinant(): number {
-            return this.m[0] * this.m[3] - this.m[1] * this.m[2];
-        }
+    /**
+     * Fills the matrix from direct values
+     * @param m00 defines value for (0, 0)
+     * @param m01 defines value for (0, 1)
+     * @param m10 defines value for (1, 0)
+     * @param m11 defines value for (1, 1)
+     * @param m20 defines value for (2, 0)
+     * @param m21 defines value for (2, 1)
+     * @returns the current modified matrix
+     */
+    public fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D {
+        this.m[0] = m00; this.m[1] = m01;
+        this.m[2] = m10; this.m[3] = m11;
+        this.m[4] = m20; this.m[5] = m21;
+        return this;
+    }
 
-        /**
-         * Inverses the matrix and stores it in a target matrix
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        public invertToRef(result: Matrix2D): Matrix2D {
-            let l0 = this.m[0]; let l1 = this.m[1];
-            let l2 = this.m[2]; let l3 = this.m[3];
-            let l4 = this.m[4]; let l5 = this.m[5];
-
-            let det = this.determinant();
-            if (det < (Epsilon * Epsilon)) {
-                result.m[0] = 0;     result.m[1] = 0;
-                result.m[2] = 0;    result.m[3] = 0;
-                result.m[4] = 0;   result.m[5] = 0;
-                return this;
-            }
-
-            let detDiv = 1 / det;
-
-            let det4 = l2 * l5 - l3 * l4;
-            let det5 = l1 * l4 - l0 * l5;
-
-            result.m[0] = l3 * detDiv;     result.m[1] = -l1 * detDiv;
-            result.m[2] = -l2 * detDiv;    result.m[3] = l0 * detDiv;
-            result.m[4] = det4 * detDiv;   result.m[5] = det5 * detDiv;
+    /** 
+     * Gets matrix determinant
+     * @returns the determinant
+     */
+    public determinant(): number {
+        return this.m[0] * this.m[3] - this.m[1] * this.m[2];
+    }
 
+    /**
+     * Inverses the matrix and stores it in a target matrix
+     * @param result defines the target matrix
+     * @returns the current matrix
+     */
+    public invertToRef(result: Matrix2D): Matrix2D {
+        let l0 = this.m[0]; let l1 = this.m[1];
+        let l2 = this.m[2]; let l3 = this.m[3];
+        let l4 = this.m[4]; let l5 = this.m[5];
+
+        let det = this.determinant();
+        if (det < (Epsilon * Epsilon)) {
+            result.m[0] = 0; result.m[1] = 0;
+            result.m[2] = 0; result.m[3] = 0;
+            result.m[4] = 0; result.m[5] = 0;
             return this;
         }
 
-        /**
-         * Multiplies the current matrix with another one
-         * @param other defines the second operand
-         * @param result defines the target matrix 
-         * @returns the current matrix
-         */
-        public multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D {
-            let l0 = this.m[0];     let l1 = this.m[1];
-            let l2 = this.m[2];     let l3 = this.m[3];
-            let l4 = this.m[4];     let l5 = this.m[5];
-
-            let r0 = other.m[0];    let r1 = other.m[1];
-            let r2 = other.m[2];    let r3 = other.m[3];
-            let r4 = other.m[4];    let r5 = other.m[5];
-
-            result.m[0] = l0 * r0 + l1 * r2;        result.m[1] = l0 * r1 + l1 * r3;
-            result.m[2] = l2 * r0 + l3 * r2;        result.m[3] = l2 * r1 + l3 * r3;
-            result.m[4] = l4 * r0 + l5 * r2 + r4;   result.m[5] = l4 * r1 + l5 * r3 + r5;
+        let detDiv = 1 / det;
 
-            return this;
-        }
+        let det4 = l2 * l5 - l3 * l4;
+        let det5 = l1 * l4 - l0 * l5;
 
-        /**
-         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
-         * @param x defines the x coordinate to transform
-         * @param y defines the x coordinate to transform 
-         * @param result defines the target vector2 
-         * @returns the current matrix
-         */
-        public transformCoordinates(x: number, y: number, result: Vector2): Matrix2D {
-            result.x = x * this.m[0] + y * this.m[2] + this.m[4];
-            result.y = x * this.m[1] + y * this.m[3] + this.m[5];
+        result.m[0] = l3 * detDiv; result.m[1] = -l1 * detDiv;
+        result.m[2] = -l2 * detDiv; result.m[3] = l0 * detDiv;
+        result.m[4] = det4 * detDiv; result.m[5] = det5 * detDiv;
 
-            return this;
-        }
+        return this;
+    }
 
-        // Statics
-        /**
-         * Creates an identity matrix
-         * @returns a new matrix
-         */
-        public static Identity(): Matrix2D {
-            return new Matrix2D(1, 0, 0, 1, 0, 0);
-        }
+    /**
+     * Multiplies the current matrix with another one
+     * @param other defines the second operand
+     * @param result defines the target matrix 
+     * @returns the current matrix
+     */
+    public multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D {
+        let l0 = this.m[0]; let l1 = this.m[1];
+        let l2 = this.m[2]; let l3 = this.m[3];
+        let l4 = this.m[4]; let l5 = this.m[5];
+
+        let r0 = other.m[0]; let r1 = other.m[1];
+        let r2 = other.m[2]; let r3 = other.m[3];
+        let r4 = other.m[4]; let r5 = other.m[5];
+
+        result.m[0] = l0 * r0 + l1 * r2; result.m[1] = l0 * r1 + l1 * r3;
+        result.m[2] = l2 * r0 + l3 * r2; result.m[3] = l2 * r1 + l3 * r3;
+        result.m[4] = l4 * r0 + l5 * r2 + r4; result.m[5] = l4 * r1 + l5 * r3 + r5;
+
+        return this;
+    }
 
-        /**
-         * Creates a translation matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the translation
-         * @param y defines the y coordinate of the translation 
-         * @param result defines the target matrix
-         */
-        public static TranslationToRef(x: number, y: number, result: Matrix2D): void {
-            result.fromValues(1, 0, 0, 1, x, y);
-        }
+    /**
+     * Applies the current matrix to a set of 2 floats and stores the result in a vector2
+     * @param x defines the x coordinate to transform
+     * @param y defines the x coordinate to transform 
+     * @param result defines the target vector2 
+     * @returns the current matrix
+     */
+    public transformCoordinates(x: number, y: number, result: Vector2): Matrix2D {
+        result.x = x * this.m[0] + y * this.m[2] + this.m[4];
+        result.y = x * this.m[1] + y * this.m[3] + this.m[5];
+
+        return this;
+    }
 
-        /**
-         * Creates a scaling matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the scaling
-         * @param y defines the y coordinate of the scaling 
-         * @param result defines the target matrix
-         */
-        public static ScalingToRef(x: number, y: number, result: Matrix2D): void {
-            result.fromValues(x, 0, 0, y,  0, 0);
-        }
+    // Statics
+    /**
+     * Creates an identity matrix
+     * @returns a new matrix
+     */
+    public static Identity(): Matrix2D {
+        return new Matrix2D(1, 0, 0, 1, 0, 0);
+    }
 
-        /**
-         * Creates a rotation matrix and stores it in a target matrix
-         * @param angle defines the rotation angle
-         * @param result defines the target matrix
-         */        
-        public static RotationToRef(angle: number, result: Matrix2D): void {
-            var s = Math.sin(angle);
-            var c = Math.cos(angle);
+    /**
+     * Creates a translation matrix and stores it in a target matrix
+     * @param x defines the x coordinate of the translation
+     * @param y defines the y coordinate of the translation 
+     * @param result defines the target matrix
+     */
+    public static TranslationToRef(x: number, y: number, result: Matrix2D): void {
+        result.fromValues(1, 0, 0, 1, x, y);
+    }
 
-            result.fromValues(c, s, -s, c,  0, 0);
-        }
+    /**
+     * Creates a scaling matrix and stores it in a target matrix
+     * @param x defines the x coordinate of the scaling
+     * @param y defines the y coordinate of the scaling 
+     * @param result defines the target matrix
+     */
+    public static ScalingToRef(x: number, y: number, result: Matrix2D): void {
+        result.fromValues(x, 0, 0, y, 0, 0);
+    }
+
+    /**
+     * Creates a rotation matrix and stores it in a target matrix
+     * @param angle defines the rotation angle
+     * @param result defines the target matrix
+     */
+    public static RotationToRef(angle: number, result: Matrix2D): void {
+        var s = Math.sin(angle);
+        var c = Math.cos(angle);
+
+        result.fromValues(c, s, -s, c, 0, 0);
+    }
 
-        private static _TempPreTranslationMatrix = Matrix2D.Identity();
-        private static _TempPostTranslationMatrix = Matrix2D.Identity();
-        private static _TempRotationMatrix = Matrix2D.Identity();
-        private static _TempScalingMatrix = Matrix2D.Identity();
-        private static _TempCompose0 = Matrix2D.Identity();
-        private static _TempCompose1 = Matrix2D.Identity();
-        private static _TempCompose2 = Matrix2D.Identity();
-
-        /**
-         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix 
-         * @param tx defines the x coordinate of the translation
-         * @param ty defines the y coordinate of the translation 
-         * @param angle defines the rotation angle 
-         * @param scaleX defines the x coordinate of the scaling
-         * @param scaleY defines the y coordinate of the scaling 
-         * @param parentMatrix defines the parent matrix to multiply by (can be null)
-         * @param result defines the target matrix 
-         */
-        public static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: Nullable<Matrix2D>,  result: Matrix2D): void {
-            Matrix2D.TranslationToRef(tx, ty, Matrix2D._TempPreTranslationMatrix);
-
-            Matrix2D.ScalingToRef(scaleX, scaleY, Matrix2D._TempScalingMatrix);
-
-            Matrix2D.RotationToRef(angle, Matrix2D._TempRotationMatrix);
-
-            Matrix2D.TranslationToRef(-tx, -ty, Matrix2D._TempPostTranslationMatrix);
-
-            Matrix2D._TempPreTranslationMatrix.multiplyToRef(Matrix2D._TempScalingMatrix, Matrix2D._TempCompose0);
-            Matrix2D._TempCompose0.multiplyToRef(Matrix2D._TempRotationMatrix, Matrix2D._TempCompose1);
-            if (parentMatrix) {
-                Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, Matrix2D._TempCompose2);
-                Matrix2D._TempCompose2.multiplyToRef(parentMatrix, result);
-            } else {
-                Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, result);
-            }
+    private static _TempPreTranslationMatrix = Matrix2D.Identity();
+    private static _TempPostTranslationMatrix = Matrix2D.Identity();
+    private static _TempRotationMatrix = Matrix2D.Identity();
+    private static _TempScalingMatrix = Matrix2D.Identity();
+    private static _TempCompose0 = Matrix2D.Identity();
+    private static _TempCompose1 = Matrix2D.Identity();
+    private static _TempCompose2 = Matrix2D.Identity();
+
+    /**
+     * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix 
+     * @param tx defines the x coordinate of the translation
+     * @param ty defines the y coordinate of the translation 
+     * @param angle defines the rotation angle 
+     * @param scaleX defines the x coordinate of the scaling
+     * @param scaleY defines the y coordinate of the scaling 
+     * @param parentMatrix defines the parent matrix to multiply by (can be null)
+     * @param result defines the target matrix 
+     */
+    public static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: Nullable<Matrix2D>, result: Matrix2D): void {
+        Matrix2D.TranslationToRef(tx, ty, Matrix2D._TempPreTranslationMatrix);
+
+        Matrix2D.ScalingToRef(scaleX, scaleY, Matrix2D._TempScalingMatrix);
+
+        Matrix2D.RotationToRef(angle, Matrix2D._TempRotationMatrix);
+
+        Matrix2D.TranslationToRef(-tx, -ty, Matrix2D._TempPostTranslationMatrix);
+
+        Matrix2D._TempPreTranslationMatrix.multiplyToRef(Matrix2D._TempScalingMatrix, Matrix2D._TempCompose0);
+        Matrix2D._TempCompose0.multiplyToRef(Matrix2D._TempRotationMatrix, Matrix2D._TempCompose1);
+        if (parentMatrix) {
+            Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, Matrix2D._TempCompose2);
+            Matrix2D._TempCompose2.multiplyToRef(parentMatrix, result);
+        } else {
+            Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, result);
         }
-    }    
-}
+    }
+}   

+ 57 - 60
gui/src/2D/measure.ts

@@ -1,72 +1,69 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
-module BABYLON.GUI {
+/**
+ * Class used to store 2D control sizes
+ */
+export class Measure {
     /**
-     * Class used to store 2D control sizes
+     * Creates a new measure
+     * @param left defines left coordinate
+     * @param top defines top coordinate 
+     * @param width defines width dimension
+     * @param height defines height dimension
      */
-    export class Measure {
-        /**
-         * Creates a new measure
-         * @param left defines left coordinate
-         * @param top defines top coordinate 
-         * @param width defines width dimension
-         * @param height defines height dimension
-         */
-        public constructor(
-            /** defines left coordinate */
-            public left: number, 
-            /** defines top coordinate  */
-            public top: number, 
-            /** defines width dimension  */
-            public width: number, 
-            /** defines height dimension */
-            public height: number) {
+    public constructor(
+        /** defines left coordinate */
+        public left: number,
+        /** defines top coordinate  */
+        public top: number,
+        /** defines width dimension  */
+        public width: number,
+        /** defines height dimension */
+        public height: number) {
 
-        }
-
-        /**
-         * Copy from another measure
-         * @param other defines the other measure to copy from
-         */
-        public copyFrom(other: Measure): void {
-            this.left = other.left;
-            this.top = other.top;
-            this.width = other.width;
-            this.height = other.height;
-        }
-
-        /**
-         * Check equality between this measure and another one
-         * @param other defines the other measures
-         * @returns true if both measures are equals
-         */
-        public isEqualsTo(other: Measure): boolean {
+    }
 
-            if (this.left !== other.left) {
-                return false;
-            }
+    /**
+     * Copy from another measure
+     * @param other defines the other measure to copy from
+     */
+    public copyFrom(other: Measure): void {
+        this.left = other.left;
+        this.top = other.top;
+        this.width = other.width;
+        this.height = other.height;
+    }
 
-            if (this.top !== other.top) {
-                return false;
-            }
+    /**
+     * Check equality between this measure and another one
+     * @param other defines the other measures
+     * @returns true if both measures are equals
+     */
+    public isEqualsTo(other: Measure): boolean {
 
-            if (this.width !== other.width) {
-                return false;
-            }
+        if (this.left !== other.left) {
+            return false;
+        }
 
-            if (this.height !== other.height) {
-                return false;
-            }
+        if (this.top !== other.top) {
+            return false;
+        }
 
-            return true;
+        if (this.width !== other.width) {
+            return false;
         }
 
-        /**
-         * Creates an empty measure
-         * @returns a new measure
-         */
-        public static Empty(): Measure {
-            return new Measure(0, 0, 0, 0);
+        if (this.height !== other.height) {
+            return false;
         }
-    }    
-}
+
+        return true;
+    }
+
+    /**
+     * Creates an empty measure
+     * @returns a new measure
+     */
+    public static Empty(): Measure {
+        return new Measure(0, 0, 0, 0);
+    }
+}   

+ 106 - 106
gui/src/2D/multiLinePoint.ts

@@ -1,150 +1,150 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { MultiLine } from "./controls/multiLine";
+import { ValueAndUnit } from "./valueAndUnit";
+import { Control } from "./controls/control";
+import { AbstractMesh, Nullable, Observer, Camera, Vector2 } from "babylonjs";
 
-module BABYLON.GUI {
 
-    /**
-     * Class used to store a point for a MultiLine object.
-     * The point can be pure 2D coordinates, a mesh or a control
-     */
-    export class MultiLinePoint {
+/**
+ * Class used to store a point for a MultiLine object.
+ * The point can be pure 2D coordinates, a mesh or a control
+ */
+export class MultiLinePoint {
+
+    private _multiLine: MultiLine;
+
+    private _x: ValueAndUnit;
+    private _y: ValueAndUnit;
+    private _control: Nullable<Control>;
+    private _mesh: Nullable<AbstractMesh>;
 
-        private _multiLine: MultiLine;
+    private _controlObserver: Nullable<Observer<Control>>;
+    private _meshObserver: Nullable<Observer<Camera>>;
 
-        private _x: ValueAndUnit;
-        private _y: ValueAndUnit;
-        private _control: Nullable<Control>;
-        private _mesh: Nullable<AbstractMesh>;
+    /** @hidden */
+    public _point: Vector2;
 
-        private _controlObserver: Nullable< Observer<Control> >;
-        private _meshObserver: Nullable< Observer<Camera> >;
+    /**
+     * Creates a new MultiLinePoint
+     * @param multiLine defines the source MultiLine object
+     */
+    constructor(multiLine: MultiLine) {
+        this._multiLine = multiLine;
 
-        /** @hidden */
-        public _point: Vector2;
+        this._x = new ValueAndUnit(0);
+        this._y = new ValueAndUnit(0);
 
-        /**
-         * Creates a new MultiLinePoint
-         * @param multiLine defines the source MultiLine object
-         */
-        constructor(multiLine: MultiLine) {
-            this._multiLine = multiLine;
+        this._point = new Vector2(0, 0);
+    }
 
-            this._x = new ValueAndUnit(0);
-            this._y = new ValueAndUnit(0);
+    /** Gets or sets x coordinate */
+    public get x(): string | number {
+        return this._x.toString(this._multiLine._host);
+    }
 
-            this._point = new Vector2(0, 0);
+    public set x(value: string | number) {
+        if (this._x.toString(this._multiLine._host) === value) {
+            return;
         }
 
-        /** Gets or sets x coordinate */
-        public get x(): string | number {
-            return this._x.toString(this._multiLine._host);
+        if (this._x.fromString(value)) {
+            this._multiLine._markAsDirty();
         }
+    }
 
-        public set x(value: string | number) {
-            if (this._x.toString(this._multiLine._host) === value) {
-                return;
-            }
+    /** Gets or sets y coordinate */
+    public get y(): string | number {
+        return this._y.toString(this._multiLine._host);
+    }
 
-            if (this._x.fromString(value)) {
-                this._multiLine._markAsDirty();
-            }
+    public set y(value: string | number) {
+        if (this._y.toString(this._multiLine._host) === value) {
+            return;
         }
 
-        /** Gets or sets y coordinate */
-        public get y(): string | number {
-            return this._y.toString(this._multiLine._host);
+        if (this._y.fromString(value)) {
+            this._multiLine._markAsDirty();
         }
+    }
 
-        public set y(value: string | number) {
-            if (this._y.toString(this._multiLine._host) === value) {
-                return;
-            }
+    /** Gets or sets the control associated with this point */
+    public get control(): Nullable<Control> {
+        return this._control;
+    }
 
-            if (this._y.fromString(value)) {
-                this._multiLine._markAsDirty();
-            }
+    public set control(value: Nullable<Control>) {
+        if (this._control === value) {
+            return;
         }
 
-        /** Gets or sets the control associated with this point */
-        public get control(): Nullable<Control> {
-            return this._control;
-        }
+        if (this._control && this._controlObserver) {
+            this._control.onDirtyObservable.remove(this._controlObserver);
 
-        public set control(value: Nullable<Control>) {
-            if (this._control === value) {
-                return;
-            }
+            this._controlObserver = null;
+        }
 
-            if (this._control && this._controlObserver) {
-                this._control.onDirtyObservable.remove(this._controlObserver);
+        this._control = value;
 
-                this._controlObserver = null;
-            }
+        if (this._control) {
+            this._controlObserver = this._control.onDirtyObservable.add(this._multiLine.onPointUpdate);
+        }
 
-            this._control = value;
+        this._multiLine._markAsDirty();
+    }
 
-            if (this._control) {
-                this._controlObserver = this._control.onDirtyObservable.add(this._multiLine.onPointUpdate);
-            }
+    /** Gets or sets the mesh associated with this point */
+    public get mesh(): Nullable<AbstractMesh> {
+        return this._mesh;
+    }
 
-            this._multiLine._markAsDirty();
+    public set mesh(value: Nullable<AbstractMesh>) {
+        if (this._mesh === value) {
+            return;
         }
 
-        /** Gets or sets the mesh associated with this point */
-        public get mesh(): Nullable<AbstractMesh> {
-            return this._mesh;
+        if (this._mesh && this._meshObserver) {
+            this._mesh.getScene().onAfterCameraRenderObservable.remove(this._meshObserver);
         }
 
-        public set mesh(value: Nullable<AbstractMesh>) {
-            if (this._mesh === value) {
-                return;
-            }
-
-            if (this._mesh && this._meshObserver) {
-                this._mesh.getScene().onAfterCameraRenderObservable.remove(this._meshObserver);
-            }
+        this._mesh = value;
 
-            this._mesh = value;
+        if (this._mesh) {
+            this._meshObserver = this._mesh.getScene().onAfterCameraRenderObservable.add(this._multiLine.onPointUpdate);
+        }
 
-            if (this._mesh) {
-                this._meshObserver = this._mesh.getScene().onAfterCameraRenderObservable.add(this._multiLine.onPointUpdate);
-            }
+        this._multiLine._markAsDirty();
+    }
 
-            this._multiLine._markAsDirty();
-        }
+    /** 
+     * Gets a translation vector
+     * @returns the translation vector
+     */
+    public translate(): Vector2 {
+        this._point = this._translatePoint();
 
-        /** 
-         * Gets a translation vector
-         * @returns the translation vector
-         */
-        public translate(): Vector2 {
-            this._point = this._translatePoint();
+        return this._point;
+    }
 
-            return this._point;
+    private _translatePoint(): Vector2 {
+        if (this._mesh != null) {
+            return this._multiLine._host.getProjectedPosition(this._mesh.getBoundingInfo().boundingSphere.center, this._mesh.getWorldMatrix());
         }
-
-        private _translatePoint(): Vector2 {
-            if (this._mesh != null) {
-                return this._multiLine._host.getProjectedPosition(this._mesh.getBoundingInfo().boundingSphere.center, this._mesh.getWorldMatrix());
-            }
-            else if (this._control != null) {
-                return new Vector2(this._control.centerX, this._control.centerY);
-            }
-            else {
-                var host: any = this._multiLine._host as any;
-
-                var xValue: number = this._x.getValueInPixel(host, Number(host._canvas.width));
-                var yValue: number = this._y.getValueInPixel(host, Number(host._canvas.height));
-                
-                return new Vector2(xValue, yValue);
-            }
+        else if (this._control != null) {
+            return new Vector2(this._control.centerX, this._control.centerY);
         }
+        else {
+            var host: any = this._multiLine._host as any;
+
+            var xValue: number = this._x.getValueInPixel(host, Number(host._canvas.width));
+            var yValue: number = this._y.getValueInPixel(host, Number(host._canvas.height));
 
-        /** Release associated resources */
-        public dispose(): void {
-            this.control = null;
-            this.mesh = null;
+            return new Vector2(xValue, yValue);
         }
+    }
 
+    /** Release associated resources */
+    public dispose(): void {
+        this.control = null;
+        this.mesh = null;
     }
 
 }

+ 79 - 79
gui/src/2D/style.ts

@@ -1,98 +1,98 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { IDisposable, Observable } from "babylonjs";
+import { AdvancedDynamicTexture } from "./advancedDynamicTexture";
+import { ValueAndUnit } from "./valueAndUnit";
+
+/**
+ * Define a style used by control to automatically setup properties based on a template.
+ * Only support font related properties so far
+ */
+export class Style implements IDisposable {
+    private _fontFamily = "Arial";
+    private _fontStyle = "";
+    private _fontWeight = "";
+    /** @hidden */
+    public _host: AdvancedDynamicTexture;
+    /** @hidden */
+    public _fontSize = new ValueAndUnit(18, ValueAndUnit.UNITMODE_PIXEL, false);
 
-module BABYLON.GUI {
     /**
-     * Define a style used by control to automatically setup properties based on a template.
-     * Only support font related properties so far
+     * Observable raised when the style values are changed
      */
-    export class Style implements BABYLON.IDisposable {
-        private _fontFamily = "Arial";
-        private _fontStyle = "";       
-        private _fontWeight = "";     
-        /** @hidden */ 
-        public _host: AdvancedDynamicTexture;
-        /** @hidden */
-        public _fontSize = new ValueAndUnit(18, ValueAndUnit.UNITMODE_PIXEL, false);
-
-        /**
-         * Observable raised when the style values are changed
-         */
-        public onChangedObservable = new BABYLON.Observable<Style>();
-
-        /**
-         * Creates a new style object
-         * @param host defines the AdvancedDynamicTexture which hosts this style
-         */
-        public constructor(host: AdvancedDynamicTexture) {
-            this._host = host;
-        }
+    public onChangedObservable = new Observable<Style>();
 
-        /**
-         * Gets or sets the font size
-         */
-        public get fontSize(): string | number {
-            return this._fontSize.toString(this._host);
-        }
+    /**
+     * Creates a new style object
+     * @param host defines the AdvancedDynamicTexture which hosts this style
+     */
+    public constructor(host: AdvancedDynamicTexture) {
+        this._host = host;
+    }
 
-        public set fontSize(value: string | number) {
-            if (this._fontSize.toString(this._host) === value) {
-                return;
-            }
-
-            if (this._fontSize.fromString(value)) {
-                this.onChangedObservable.notifyObservers(this);
-            }
-        }        
-        
-        /**
-         * Gets or sets the font family
-         */
-        public get fontFamily(): string {
-            return this._fontFamily;
-        }
+    /**
+     * Gets or sets the font size
+     */
+    public get fontSize(): string | number {
+        return this._fontSize.toString(this._host);
+    }
 
-        public set fontFamily(value: string) {
-            if (this._fontFamily === value) {
-                return;
-            }
+    public set fontSize(value: string | number) {
+        if (this._fontSize.toString(this._host) === value) {
+            return;
+        }
 
-            this._fontFamily = value;
+        if (this._fontSize.fromString(value)) {
             this.onChangedObservable.notifyObservers(this);
         }
+    }
 
-        /**
-         * Gets or sets the font style 
-         */
-        public get fontStyle(): string {
-            return this._fontStyle;
+    /**
+     * Gets or sets the font family
+     */
+    public get fontFamily(): string {
+        return this._fontFamily;
+    }
+
+    public set fontFamily(value: string) {
+        if (this._fontFamily === value) {
+            return;
         }
 
-        public set fontStyle(value: string) {
-            if (this._fontStyle === value) {
-                return;
-            }
+        this._fontFamily = value;
+        this.onChangedObservable.notifyObservers(this);
+    }
 
-            this._fontStyle = value;
-            this.onChangedObservable.notifyObservers(this);
-        }
+    /**
+     * Gets or sets the font style 
+     */
+    public get fontStyle(): string {
+        return this._fontStyle;
+    }
 
-        /** Gets or sets font weight */
-        public get fontWeight(): string {
-            return this._fontWeight;
+    public set fontStyle(value: string) {
+        if (this._fontStyle === value) {
+            return;
         }
 
-        public set fontWeight(value: string) {
-            if (this._fontWeight === value) {
-                return;
-            }
+        this._fontStyle = value;
+        this.onChangedObservable.notifyObservers(this);
+    }
 
-            this._fontWeight = value;            
-            this.onChangedObservable.notifyObservers(this);
-        }          
+    /** Gets or sets font weight */
+    public get fontWeight(): string {
+        return this._fontWeight;
+    }
 
-        /** Dispose all associated resources */
-        public dispose() {
-            this.onChangedObservable.clear();
+    public set fontWeight(value: string) {
+        if (this._fontWeight === value) {
+            return;
         }
-    }    
-}
+
+        this._fontWeight = value;
+        this.onChangedObservable.notifyObservers(this);
+    }
+
+    /** Dispose all associated resources */
+    public dispose() {
+        this.onChangedObservable.clear();
+    }
+}    

+ 135 - 137
gui/src/2D/valueAndUnit.ts

@@ -1,165 +1,163 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { AdvancedDynamicTexture } from "./advancedDynamicTexture";
 
-module BABYLON.GUI {
+/**
+ * Class used to specific a value and its associated unit
+ */
+export class ValueAndUnit {
+    private _value = 1;
     /**
-     * Class used to specific a value and its associated unit
+     * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
+     * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
      */
-    export class ValueAndUnit {
-        private _value = 1;
-        /**
-         * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
-         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
-         */
-        public ignoreAdaptiveScaling = false;
-
-        /**
-         * Creates a new ValueAndUnit
-         * @param value defines the value to store
-         * @param unit defines the unit to store
-         * @param negativeValueAllowed defines a boolean indicating if the value can be negative
-         */
-        public constructor(value: number, 
-            /** defines the unit to store */
-            public unit = ValueAndUnit.UNITMODE_PIXEL, 
-            /** defines a boolean indicating if the value can be negative */
-            public negativeValueAllowed = true) {
-            this._value = value;
-        }
+    public ignoreAdaptiveScaling = false;
 
-        /** Gets a boolean indicating if the value is a percentage */
-        public get isPercentage(): boolean {
-            return this.unit === ValueAndUnit.UNITMODE_PERCENTAGE;
-        }
+    /**
+     * Creates a new ValueAndUnit
+     * @param value defines the value to store
+     * @param unit defines the unit to store
+     * @param negativeValueAllowed defines a boolean indicating if the value can be negative
+     */
+    public constructor(value: number,
+        /** defines the unit to store */
+        public unit = ValueAndUnit.UNITMODE_PIXEL,
+        /** defines a boolean indicating if the value can be negative */
+        public negativeValueAllowed = true) {
+        this._value = value;
+    }
+
+    /** Gets a boolean indicating if the value is a percentage */
+    public get isPercentage(): boolean {
+        return this.unit === ValueAndUnit.UNITMODE_PERCENTAGE;
+    }
+
+    /** Gets a boolean indicating if the value is store as pixel */
+    public get isPixel(): boolean {
+        return this.unit === ValueAndUnit.UNITMODE_PIXEL;
+    }
+
+    /** Gets direct internal value */
+    public get internalValue(): number {
+        return this._value;
+    }
 
-        /** Gets a boolean indicating if the value is store as pixel */
-        public get isPixel(): boolean {
-            return this.unit === ValueAndUnit.UNITMODE_PIXEL;
+    /**
+     * Gets value as pixel
+     * @param host defines the root host
+     * @param refValue defines the reference value for percentages
+     * @returns the value as pixel
+     */
+    public getValueInPixel(host: AdvancedDynamicTexture, refValue: number): number {
+        if (this.isPixel) {
+            return this.getValue(host);
         }
 
-        /** Gets direct internal value */
-        public get internalValue(): number {
-            return this._value;
-        }
+        return this.getValue(host) * refValue;
+    }
 
-        /**
-         * Gets value as pixel
-         * @param host defines the root host
-         * @param refValue defines the reference value for percentages
-         * @returns the value as pixel
-         */
-        public getValueInPixel(host: AdvancedDynamicTexture, refValue: number): number {
-            if (this.isPixel) {
-                return this.getValue(host);
+    /**
+     * Gets the value accordingly to its unit
+     * @param host  defines the root host
+     * @returns the value
+     */
+    public getValue(host: AdvancedDynamicTexture): number {
+        if (host && !this.ignoreAdaptiveScaling && this.unit !== ValueAndUnit.UNITMODE_PERCENTAGE) {
+            var width: number = 0;
+            var height: number = 0;
+
+            if (host.idealWidth) {
+                width = (this._value * host.getSize().width) / host.idealWidth;
             }
 
-            return this.getValue(host) * refValue;
-        }
+            if (host.idealHeight) {
+                height = (this._value * host.getSize().height) / host.idealHeight;
+            }
 
-        /**
-         * Gets the value accordingly to its unit
-         * @param host  defines the root host
-         * @returns the value
-         */
-        public getValue(host: AdvancedDynamicTexture): number {
-            if (host && !this.ignoreAdaptiveScaling && this.unit !== ValueAndUnit.UNITMODE_PERCENTAGE) {
-                var width: number = 0;
-                var height: number = 0;
-
-                if (host.idealWidth) {
-                    width = (this._value * host.getSize().width) / host.idealWidth;
-                }
-                
-                if (host.idealHeight) {
-                    height = (this._value * host.getSize().height) / host.idealHeight;
-                }
-
-                if (host.useSmallestIdeal && host.idealWidth && host.idealHeight) {
-                    return window.innerWidth < window.innerHeight ? width : height;
-                }
-
-                if (host.idealWidth) { // horizontal
-                    return width;
-                }
-                
-                if (host.idealHeight) { // vertical
-                    return height;
-                }
+            if (host.useSmallestIdeal && host.idealWidth && host.idealHeight) {
+                return window.innerWidth < window.innerHeight ? width : height;
+            }
+
+            if (host.idealWidth) { // horizontal
+                return width;
             }
-            return this._value;
-        }
 
-        /**
-         * Gets a string representation of the value
-         * @param host defines the root host
-         * @returns a string
-         */
-        public toString(host: AdvancedDynamicTexture): string {
-            switch (this.unit) {
-                case ValueAndUnit.UNITMODE_PERCENTAGE:
-                    return (this.getValue(host) * 100) + "%";
-                case ValueAndUnit.UNITMODE_PIXEL:
-                    return this.getValue(host) + "px";
+            if (host.idealHeight) { // vertical
+                return height;
             }
+        }
+        return this._value;
+    }
 
-            return this.unit.toString();
+    /**
+     * Gets a string representation of the value
+     * @param host defines the root host
+     * @returns a string
+     */
+    public toString(host: AdvancedDynamicTexture): string {
+        switch (this.unit) {
+            case ValueAndUnit.UNITMODE_PERCENTAGE:
+                return (this.getValue(host) * 100) + "%";
+            case ValueAndUnit.UNITMODE_PIXEL:
+                return this.getValue(host) + "px";
         }
 
-        /**
-         * Store a value parsed from a string
-         * @param source defines the source string
-         * @returns true if the value was successfully parsed
-         */
-        public fromString(source: string | number ): boolean {
-            var match = ValueAndUnit._Regex.exec(source.toString());
+        return this.unit.toString();
+    }
 
-            if (!match || match.length === 0) {
-                return false;
-            }
+    /**
+     * Store a value parsed from a string
+     * @param source defines the source string
+     * @returns true if the value was successfully parsed
+     */
+    public fromString(source: string | number): boolean {
+        var match = ValueAndUnit._Regex.exec(source.toString());
 
-            var sourceValue = parseFloat(match[1]);
-            var sourceUnit = this.unit;
+        if (!match || match.length === 0) {
+            return false;
+        }
 
-            if (!this.negativeValueAllowed) {
-                if (sourceValue < 0) {
-                    sourceValue = 0;
-                }
-            }
-            
-            if (match.length === 4) {
-                switch(match[3]) {
-                    case "px":
-                        sourceUnit = ValueAndUnit.UNITMODE_PIXEL;
-                        break;
-                    case "%":
-                        sourceUnit = ValueAndUnit.UNITMODE_PERCENTAGE;
-                        sourceValue /= 100.0;
-                        break;
-                }
-            }
+        var sourceValue = parseFloat(match[1]);
+        var sourceUnit = this.unit;
 
-            if (sourceValue === this._value && sourceUnit === this.unit) {
-                return false;
+        if (!this.negativeValueAllowed) {
+            if (sourceValue < 0) {
+                sourceValue = 0;
             }
+        }
 
-            this._value = sourceValue;
-            this.unit = sourceUnit;
+        if (match.length === 4) {
+            switch (match[3]) {
+                case "px":
+                    sourceUnit = ValueAndUnit.UNITMODE_PIXEL;
+                    break;
+                case "%":
+                    sourceUnit = ValueAndUnit.UNITMODE_PERCENTAGE;
+                    sourceValue /= 100.0;
+                    break;
+            }
+        }
 
-            return true;
+        if (sourceValue === this._value && sourceUnit === this.unit) {
+            return false;
         }
 
-        // Static
-        private static _Regex = /(^-?\d*(\.\d+)?)(%|px)?/;
-        private static _UNITMODE_PERCENTAGE = 0;
-        private static _UNITMODE_PIXEL = 1;
+        this._value = sourceValue;
+        this.unit = sourceUnit;
 
-        /** UNITMODE_PERCENTAGE */
-        public static get UNITMODE_PERCENTAGE(): number {
-            return ValueAndUnit._UNITMODE_PERCENTAGE;
-        }
+        return true;
+    }
+
+    // Static
+    private static _Regex = /(^-?\d*(\.\d+)?)(%|px)?/;
+    private static _UNITMODE_PERCENTAGE = 0;
+    private static _UNITMODE_PIXEL = 1;
+
+    /** UNITMODE_PERCENTAGE */
+    public static get UNITMODE_PERCENTAGE(): number {
+        return ValueAndUnit._UNITMODE_PERCENTAGE;
+    }
 
-        /** UNITMODE_PIXEL */
-        public static get UNITMODE_PIXEL(): number {
-            return ValueAndUnit._UNITMODE_PIXEL;
-        }   
-    }    
-}
+    /** UNITMODE_PIXEL */
+    public static get UNITMODE_PIXEL(): number {
+        return ValueAndUnit._UNITMODE_PIXEL;
+    }
+}  

+ 17 - 18
gui/src/3D/controls/abstractButton3D.ts

@@ -1,25 +1,24 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control3D } from "./control3D";
+import { TransformNode, Scene } from "babylonjs";
 
-module BABYLON.GUI {
+/**
+ * Class used as a root to all buttons
+ */
+export class AbstractButton3D extends Control3D {
     /**
-     * Class used as a root to all buttons
+     * Creates a new button
+     * @param name defines the control name
      */
-    export class AbstractButton3D extends Control3D {
-        /**
-         * Creates a new button
-         * @param name defines the control name
-         */
-        constructor(name?: string) {
-            super(name);
-        }
+    constructor(name?: string) {
+        super(name);
+    }
 
-        protected _getTypeName(): string {
-            return "AbstractButton3D";
-        }        
+    protected _getTypeName(): string {
+        return "AbstractButton3D";
+    }
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            return new TransformNode("button" + this.name);
-        }    
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        return new TransformNode("button" + this.name);
     }
 }

+ 135 - 134
gui/src/3D/controls/button3D.ts

@@ -1,177 +1,178 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { AbstractButton3D } from "./abstractButton3D";
+import { Material, Nullable, int, Color3, StandardMaterial, Texture, Scene, TransformNode, Vector4, MeshBuilder, AbstractMesh } from "babylonjs";
+import { AdvancedDynamicTexture } from "../../2D/advancedDynamicTexture";
+import { Control } from "../../2D/controls/control";
+
+/**
+ * Class used to create a button in 3D
+ */
+export class Button3D extends AbstractButton3D {
+    /** @hidden */
+    protected _currentMaterial: Material;
+    private _facadeTexture: Nullable<AdvancedDynamicTexture>;
+    private _content: Control;
+    private _contentResolution = 512;
+    private _contentScaleRatio = 2;
 
-module BABYLON.GUI {
     /**
-     * Class used to create a button in 3D
+     * Gets or sets the texture resolution used to render content (512 by default)
      */
-    export class Button3D extends AbstractButton3D {
-        /** @hidden */
-        protected _currentMaterial: Material;
-        private _facadeTexture: Nullable<AdvancedDynamicTexture>;
-        private _content: Control;
-        private _contentResolution = 512;
-        private _contentScaleRatio = 2;
-
-        /**
-         * Gets or sets the texture resolution used to render content (512 by default)
-         */
-        public get contentResolution(): int {
-            return this._contentResolution;
+    public get contentResolution(): int {
+        return this._contentResolution;
+    }
+
+    public set contentResolution(value: int) {
+        if (this._contentResolution === value) {
+            return;
         }
 
-        public set contentResolution(value: int) {
-            if (this._contentResolution === value) {
-                return;
-            }
+        this._contentResolution = value;
+        this._resetContent();
+    }
 
-            this._contentResolution = value;
-            this._resetContent();
+    /**
+     * Gets or sets the texture scale ratio used to render content (2 by default)
+     */
+    public get contentScaleRatio(): number {
+        return this._contentScaleRatio;
+    }
+
+    public set contentScaleRatio(value: number) {
+        if (this._contentScaleRatio === value) {
+            return;
         }
 
-        /**
-         * Gets or sets the texture scale ratio used to render content (2 by default)
-         */
-        public get contentScaleRatio(): number {
-            return this._contentScaleRatio;
+        this._contentScaleRatio = value;
+        this._resetContent();
+    }
+
+    protected _disposeFacadeTexture() {
+        if (this._facadeTexture) {
+            this._facadeTexture.dispose();
+            this._facadeTexture = null;
         }
+    }
 
-        public set contentScaleRatio(value: number) {
-            if (this._contentScaleRatio === value) {
-                return;
-            }
+    protected _resetContent() {
+        this._disposeFacadeTexture();
+        this.content = this._content;
+    }
+
+    /**
+     * Creates a new button
+     * @param name defines the control name
+     */
+    constructor(name?: string) {
+        super(name);
+
+        // Default animations
 
-            this._contentScaleRatio = value;
-            this._resetContent();
-        }   
-        
-        protected _disposeFacadeTexture() {
-            if (this._facadeTexture) {
-                this._facadeTexture.dispose();
-                this._facadeTexture = null;
+        this.pointerEnterAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
+            (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Red();
         }
 
-        protected _resetContent() {
-            this._disposeFacadeTexture();
-            this.content = this._content;
+        this.pointerOutAnimation = () => {
+            (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Black();
         }
 
-        /**
-         * Creates a new button
-         * @param name defines the control name
-         */
-        constructor(name?: string) {
-            super(name);
+        this.pointerDownAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
 
-            // Default animations
+            this.mesh.scaling.scaleInPlace(0.95);
+        }
 
-            this.pointerEnterAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Red();
+        this.pointerUpAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
 
-            this.pointerOutAnimation = () => {
-                (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Black();
-            }    
-
-            this.pointerDownAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
+            this.mesh.scaling.scaleInPlace(1.0 / 0.95);
+        }
+    }
 
-                this.mesh.scaling.scaleInPlace(0.95);
-            }
+    /**
+     * Gets or sets the GUI 2D content used to display the button's facade
+     */
+    public get content(): Control {
+        return this._content;
+    }
 
-            this.pointerUpAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
+    public set content(value: Control) {
+        this._content = value;
 
-                this.mesh.scaling.scaleInPlace(1.0 / 0.95);
-            }                     
+        if (!this._host || !this._host.utilityLayer) {
+            return;
         }
 
-        /**
-         * Gets or sets the GUI 2D content used to display the button's facade
-         */
-        public get content(): Control {
-            return this._content;
+        if (!this._facadeTexture) {
+            this._facadeTexture = new AdvancedDynamicTexture("Facade", this._contentResolution, this._contentResolution, this._host.utilityLayer.utilityLayerScene, true, Texture.TRILINEAR_SAMPLINGMODE);
+            this._facadeTexture.rootContainer.scaleX = this._contentScaleRatio;
+            this._facadeTexture.rootContainer.scaleY = this._contentScaleRatio;
+            this._facadeTexture.premulAlpha = true;
         }
 
-        public set content(value: Control) {
-            this._content = value;
+        this._facadeTexture.addControl(value);
 
-            if (!this._host || !this._host.utilityLayer) {
-                return;
-            }
+        this._applyFacade(this._facadeTexture);
+    }
 
-            if (!this._facadeTexture) {
-                this._facadeTexture = new BABYLON.GUI.AdvancedDynamicTexture("Facade", this._contentResolution, this._contentResolution, this._host.utilityLayer.utilityLayerScene, true, BABYLON.Texture.TRILINEAR_SAMPLINGMODE);
-                this._facadeTexture.rootContainer.scaleX = this._contentScaleRatio;
-                this._facadeTexture.rootContainer.scaleY = this._contentScaleRatio;
-                this._facadeTexture.premulAlpha = true;
-            }
-            
-            this._facadeTexture.addControl(value);
+    /**
+     * Apply the facade texture (created from the content property).
+     * This function can be overloaded by child classes
+     * @param facadeTexture defines the AdvancedDynamicTexture to use
+     */
+    protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
+        (<any>this._currentMaterial).emissiveTexture = facadeTexture;
+    }
 
-            this._applyFacade(this._facadeTexture);
-        }
+    protected _getTypeName(): string {
+        return "Button3D";
+    }
 
-        /**
-         * Apply the facade texture (created from the content property).
-         * This function can be overloaded by child classes
-         * @param facadeTexture defines the AdvancedDynamicTexture to use
-         */
-        protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
-            (<any>this._currentMaterial).emissiveTexture = facadeTexture;
-        }
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        var faceUV = new Array(6);
 
-        protected _getTypeName(): string {
-            return "Button3D";
-        }        
+        for (var i = 0; i < 6; i++) {
+            faceUV[i] = new Vector4(0, 0, 0, 0);
+        }
+        faceUV[1] = new Vector4(0, 0, 1, 1);
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            var faceUV = new Array(6);
+        let mesh = MeshBuilder.CreateBox(this.name + "_rootMesh", {
+            width: 1.0,
+            height: 1.0,
+            depth: 0.08,
+            faceUV: faceUV
+        }, scene);
 
-            for (var i = 0; i < 6; i++) {
-                faceUV[i] = new BABYLON.Vector4(0, 0, 0, 0);
-            }
-            faceUV[1] = new BABYLON.Vector4(0, 0, 1, 1);
-
-            let mesh = MeshBuilder.CreateBox(this.name + "_rootMesh", {
-                width: 1.0, 
-                height: 1.0,
-                depth: 0.08,
-                faceUV: faceUV
-            }, scene); 
-           
-            return mesh;
-        }
+        return mesh;
+    }
 
-        protected _affectMaterial(mesh: AbstractMesh) {
-            let material = new StandardMaterial(this.name + "Material", mesh.getScene());
-            material.specularColor = Color3.Black();
+    protected _affectMaterial(mesh: AbstractMesh) {
+        let material = new StandardMaterial(this.name + "Material", mesh.getScene());
+        material.specularColor = Color3.Black();
 
-            mesh.material = material;
-            this._currentMaterial = material;
+        mesh.material = material;
+        this._currentMaterial = material;
 
-            this._resetContent();
-        }
+        this._resetContent();
+    }
 
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            super.dispose();
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        super.dispose();
 
-            this._disposeFacadeTexture();
+        this._disposeFacadeTexture();
 
-            if (this._currentMaterial) {
-                this._currentMaterial.dispose();
-            }
+        if (this._currentMaterial) {
+            this._currentMaterial.dispose();
         }
     }
 }

+ 113 - 114
gui/src/3D/controls/container3D.ts

@@ -1,152 +1,151 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control3D } from "./control3D";
+import { Scene, Nullable, TransformNode } from "babylonjs";
+
+/**
+ * Class used to create containers for controls
+ */
+export class Container3D extends Control3D {
+    private _blockLayout = false;
 
-module BABYLON.GUI {
     /**
-     * Class used to create containers for controls
+     * Gets the list of child controls
      */
-    export class Container3D extends Control3D {
-        private _blockLayout = false;
-
-        /**
-         * Gets the list of child controls
-         */
-        protected _children = new Array<Control3D>();
-
-        /**
-         * Gets the list of child controls
-         */
-        public get children(): Array<Control3D> {
-            return this._children;
-        }
-
-        /**
-         * Gets or sets a boolean indicating if the layout must be blocked (default is false).
-         * This is helpful to optimize layout operation when adding multiple children in a row
-         */
-        public get blockLayout(): boolean {
-            return this._blockLayout;
-        }
+    protected _children = new Array<Control3D>();
 
-        public set blockLayout(value: boolean) {
-            if (this._blockLayout === value) {
-                return;
-            }
+    /**
+     * Gets the list of child controls
+     */
+    public get children(): Array<Control3D> {
+        return this._children;
+    }
 
-            this._blockLayout = value;
+    /**
+     * Gets or sets a boolean indicating if the layout must be blocked (default is false).
+     * This is helpful to optimize layout operation when adding multiple children in a row
+     */
+    public get blockLayout(): boolean {
+        return this._blockLayout;
+    }
 
-            if (!this._blockLayout) {
-                this._arrangeChildren();
-            }
+    public set blockLayout(value: boolean) {
+        if (this._blockLayout === value) {
+            return;
         }
 
-        /**
-         * Creates a new container
-         * @param name defines the container name
-         */
-        constructor(name?: string) {
-            super(name);
-        }
+        this._blockLayout = value;
 
-        /**
-         * Gets a boolean indicating if the given control is in the children of this control
-         * @param control defines the control to check
-         * @returns true if the control is in the child list
-         */
-        public containsControl(control: Control3D): boolean {
-            return this._children.indexOf(control) !== -1;
+        if (!this._blockLayout) {
+            this._arrangeChildren();
         }
+    }
 
-        /**
-         * Adds a control to the children of this control
-         * @param control defines the control to add
-         * @returns the current container
-         */
-        public addControl(control: Control3D): Container3D {
-           var index = this._children.indexOf(control);
+    /**
+     * Creates a new container
+     * @param name defines the container name
+     */
+    constructor(name?: string) {
+        super(name);
+    }
 
-            if (index !== -1) {
-                return this;
-            }
-            control.parent = this;
-            control._host = this._host;
+    /**
+     * Gets a boolean indicating if the given control is in the children of this control
+     * @param control defines the control to check
+     * @returns true if the control is in the child list
+     */
+    public containsControl(control: Control3D): boolean {
+        return this._children.indexOf(control) !== -1;
+    }
 
-            this._children.push(control);
+    /**
+     * Adds a control to the children of this control
+     * @param control defines the control to add
+     * @returns the current container
+     */
+    public addControl(control: Control3D): Container3D {
+        var index = this._children.indexOf(control);
 
-            if (this._host.utilityLayer) {
-                control._prepareNode(this._host.utilityLayer.utilityLayerScene);
+        if (index !== -1) {
+            return this;
+        }
+        control.parent = this;
+        control._host = this._host;
 
-                if (control.node) {
-                    control.node.parent = this.node;
-                }
+        this._children.push(control);
 
-                if (!this.blockLayout) {
-                    this._arrangeChildren();
-                }
+        if (this._host.utilityLayer) {
+            control._prepareNode(this._host.utilityLayer.utilityLayerScene);
+
+            if (control.node) {
+                control.node.parent = this.node;
             }
 
-            return this;
+            if (!this.blockLayout) {
+                this._arrangeChildren();
+            }
         }
 
+        return this;
+    }
 
-        /**
-         * This function will be called everytime a new control is added 
-         */
-        protected _arrangeChildren() {
-        }
 
-        protected _createNode(scene: Scene): Nullable<TransformNode> {
-            return new TransformNode("ContainerNode", scene);
-        }
+    /**
+     * This function will be called everytime a new control is added 
+     */
+    protected _arrangeChildren() {
+    }
 
-        /**
-         * Removes a control from the children of this control
-         * @param control defines the control to remove
-         * @returns the current container
-         */
-        public removeControl(control: Control3D): Container3D {
-            var index = this._children.indexOf(control);
+    protected _createNode(scene: Scene): Nullable<TransformNode> {
+        return new TransformNode("ContainerNode", scene);
+    }
 
-            if (index !== -1) {
-                this._children.splice(index, 1);
+    /**
+     * Removes a control from the children of this control
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control3D): Container3D {
+        var index = this._children.indexOf(control);
 
-                control.parent = null;
-                control._disposeNode();
-            }
+        if (index !== -1) {
+            this._children.splice(index, 1);
 
-            return this;
+            control.parent = null;
+            control._disposeNode();
         }
 
-        protected _getTypeName(): string {
-            return "Container3D";
-        }
-        
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            for (var control of this._children) {
-                control.dispose();
-            }
+        return this;
+    }
 
-            this._children = [];
+    protected _getTypeName(): string {
+        return "Container3D";
+    }
 
-            super.dispose();
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        for (var control of this._children) {
+            control.dispose();
         }
 
-        /** Control rotation will remain unchanged  */
-        public static readonly UNSET_ORIENTATION = 0;
+        this._children = [];
+
+        super.dispose();
+    }
 
-        /** Control will rotate to make it look at sphere central axis */
-        public static readonly FACEORIGIN_ORIENTATION = 1;
+    /** Control rotation will remain unchanged  */
+    public static readonly UNSET_ORIENTATION = 0;
 
-        /** Control will rotate to make it look back at sphere central axis */
-        public static readonly FACEORIGINREVERSED_ORIENTATION = 2;
+    /** Control will rotate to make it look at sphere central axis */
+    public static readonly FACEORIGIN_ORIENTATION = 1;
 
-        /** Control will rotate to look at z axis (0, 0, 1) */
-        public static readonly FACEFORWARD_ORIENTATION = 3;
+    /** Control will rotate to make it look back at sphere central axis */
+    public static readonly FACEORIGINREVERSED_ORIENTATION = 2;
 
-        /** Control will rotate to look at negative z axis (0, 0, -1) */
-        public static readonly FACEFORWARDREVERSED_ORIENTATION = 4;
+    /** Control will rotate to look at z axis (0, 0, 1) */
+    public static readonly FACEFORWARD_ORIENTATION = 3;
+
+    /** Control will rotate to look at negative z axis (0, 0, -1) */
+    public static readonly FACEFORWARDREVERSED_ORIENTATION = 4;
 
-    }
 }

+ 346 - 345
gui/src/3D/controls/control3D.ts

@@ -1,424 +1,425 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { IDisposable, IBehaviorAware, Nullable, TransformNode, Vector3, Observable, Behavior, AbstractMesh, Scene, PointerEventTypes } from "babylonjs";
+import { GUI3DManager } from "../gui3DManager";
+import { Vector3WithInfo } from "../vector3WithInfo";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used as base class for controls
+ */
+export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
+    /** @hidden */
+    public _host: GUI3DManager;
+    private _node: Nullable<TransformNode>;
+    private _downCount = 0;
+    private _enterCount = -1;
+    private _downPointerIds: { [id: number]: boolean } = {};
+    private _isVisible = true;
+
+    /** Gets or sets the control position  in world space */
+    public get position(): Vector3 {
+        if (!this._node) {
+            return Vector3.Zero();
+        }
 
-module BABYLON.GUI {
-    /**
-     * Class used as base class for controls
-     */
-    export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
-        /** @hidden */
-        public _host: GUI3DManager;
-        private _node: Nullable<TransformNode>;
-        private _downCount = 0;
-        private _enterCount = -1;
-        private _downPointerIds:{[id:number] : boolean} = {};
-        private _isVisible = true;
-    
-        /** Gets or sets the control position  in world space */
-        public get position(): Vector3 {
-            if (!this._node) {
-                return Vector3.Zero();
-            }
+        return this._node.position;
+    }
 
-            return this._node.position;
+    public set position(value: Vector3) {
+        if (!this._node) {
+            return;
         }
 
-        public set position(value: Vector3) {
-            if (!this._node) {
-                return;
-            }
+        this._node.position = value;;
+    }
 
-            this._node.position = value;;
+    /** Gets or sets the control scaling  in world space */
+    public get scaling(): Vector3 {
+        if (!this._node) {
+            return new Vector3(1, 1, 1);
         }
 
-        /** Gets or sets the control scaling  in world space */
-        public get scaling(): Vector3 {
-            if (!this._node) {
-                return new Vector3(1, 1, 1);
-            }
+        return this._node.scaling;
+    }
 
-            return this._node.scaling;
+    public set scaling(value: Vector3) {
+        if (!this._node) {
+            return;
         }
 
-        public set scaling(value: Vector3) {
-            if (!this._node) {
-                return;
-            }
+        this._node.scaling = value;;
+    }
 
-            this._node.scaling = value;;
-        }
+    /** Callback used to start pointer enter animation */
+    public pointerEnterAnimation: () => void;
+    /** Callback used to start pointer out animation */
+    public pointerOutAnimation: () => void;
+    /** Callback used to start pointer down animation */
+    public pointerDownAnimation: () => void;
+    /** Callback used to start pointer up animation */
+    public pointerUpAnimation: () => void;
 
-        /** Callback used to start pointer enter animation */
-        public pointerEnterAnimation: () => void;
-        /** Callback used to start pointer out animation */
-        public pointerOutAnimation: () => void;
-        /** Callback used to start pointer down animation */
-        public pointerDownAnimation: () => void;
-        /** Callback used to start pointer up animation */
-        public pointerUpAnimation: () => void;
-
-        /**
-        * An event triggered when the pointer move over the control
-        */
-        public onPointerMoveObservable = new Observable<Vector3>();
-
-        /**
-         * An event triggered when the pointer move out of the control
-         */
-        public onPointerOutObservable = new Observable<Control3D>();
-
-        /**
-         * An event triggered when the pointer taps the control
-         */
-        public onPointerDownObservable = new Observable<Vector3WithInfo>();
-
-        /**
-         * An event triggered when pointer is up
-         */
-        public onPointerUpObservable = new Observable<Vector3WithInfo>();
-
-        /**
-         * An event triggered when a control is clicked on (with a mouse)
-         */
-        public onPointerClickObservable = new Observable<Vector3WithInfo>();
-
-        /**
-         * An event triggered when pointer enters the control
-         */
-        public onPointerEnterObservable = new Observable<Control3D>();
-        
-        /**
-         * Gets or sets the parent container
-         */
-        public parent: Nullable<Container3D>;
+    /**
+    * An event triggered when the pointer move over the control
+    */
+    public onPointerMoveObservable = new Observable<Vector3>();
 
-        // Behaviors
-        private _behaviors = new Array<Behavior<Control3D>>();
-
-        /**
-         * Gets the list of attached behaviors
-         * @see http://doc.babylonjs.com/features/behaviour
-         */
-        public get behaviors(): Behavior<Control3D>[] {
-            return this._behaviors;
-        }        
-
-        /**
-         * Attach a behavior to the control
-         * @see http://doc.babylonjs.com/features/behaviour
-         * @param behavior defines the behavior to attach
-         * @returns the current control
-         */
-        public addBehavior(behavior: Behavior<Control3D>): Control3D {
-            var index = this._behaviors.indexOf(behavior);
-
-            if (index !== -1) {
-                return this;
-            }
+    /**
+     * An event triggered when the pointer move out of the control
+     */
+    public onPointerOutObservable = new Observable<Control3D>();
 
-            behavior.init();
-            let scene = this._host.scene;
-            if (scene.isLoading) {
-                // We defer the attach when the scene will be loaded
-                scene.onDataLoadedObservable.addOnce(() => {
-                    behavior.attach(this);
-                });
-            } else {
-                behavior.attach(this);
-            }
-            this._behaviors.push(behavior);
+    /**
+     * An event triggered when the pointer taps the control
+     */
+    public onPointerDownObservable = new Observable<Vector3WithInfo>();
+
+    /**
+     * An event triggered when pointer is up
+     */
+    public onPointerUpObservable = new Observable<Vector3WithInfo>();
+
+    /**
+     * An event triggered when a control is clicked on (with a mouse)
+     */
+    public onPointerClickObservable = new Observable<Vector3WithInfo>();
 
+    /**
+     * An event triggered when pointer enters the control
+     */
+    public onPointerEnterObservable = new Observable<Control3D>();
+
+    /**
+     * Gets or sets the parent container
+     */
+    public parent: Nullable<Container3D>;
+
+    // Behaviors
+    private _behaviors = new Array<Behavior<Control3D>>();
+
+    /**
+     * Gets the list of attached behaviors
+     * @see http://doc.babylonjs.com/features/behaviour
+     */
+    public get behaviors(): Behavior<Control3D>[] {
+        return this._behaviors;
+    }
+
+    /**
+     * Attach a behavior to the control
+     * @see http://doc.babylonjs.com/features/behaviour
+     * @param behavior defines the behavior to attach
+     * @returns the current control
+     */
+    public addBehavior(behavior: Behavior<Control3D>): Control3D {
+        var index = this._behaviors.indexOf(behavior);
+
+        if (index !== -1) {
             return this;
         }
 
-        /**
-         * Remove an attached behavior
-         * @see http://doc.babylonjs.com/features/behaviour
-         * @param behavior defines the behavior to attach
-         * @returns the current control
-         */
-        public removeBehavior(behavior: Behavior<Control3D>): Control3D {
-            var index = this._behaviors.indexOf(behavior);
-
-            if (index === -1) {
-                return this;
-            }
+        behavior.init();
+        let scene = this._host.scene;
+        if (scene.isLoading) {
+            // We defer the attach when the scene will be loaded
+            scene.onDataLoadedObservable.addOnce(() => {
+                behavior.attach(this);
+            });
+        } else {
+            behavior.attach(this);
+        }
+        this._behaviors.push(behavior);
 
-            this._behaviors[index].detach();
-            this._behaviors.splice(index, 1);
+        return this;
+    }
 
-            return this;
-        }        
-
-        /**
-         * Gets an attached behavior by name
-         * @param name defines the name of the behavior to look for
-         * @see http://doc.babylonjs.com/features/behaviour
-         * @returns null if behavior was not found else the requested behavior
-         */
-        public getBehaviorByName(name: string): Nullable<Behavior<Control3D>> {
-            for (var behavior of this._behaviors) {
-                if (behavior.name === name) {
-                    return behavior;
-                }
-            }
+    /**
+     * Remove an attached behavior
+     * @see http://doc.babylonjs.com/features/behaviour
+     * @param behavior defines the behavior to attach
+     * @returns the current control
+     */
+    public removeBehavior(behavior: Behavior<Control3D>): Control3D {
+        var index = this._behaviors.indexOf(behavior);
 
-            return null;
-        }      
-        
-        /** Gets or sets a boolean indicating if the control is visible */
-        public get isVisible(): boolean {
-            return this._isVisible;
+        if (index === -1) {
+            return this;
         }
 
-        public set isVisible(value: boolean) {
-            if (this._isVisible === value) {
-                return;
-            }
+        this._behaviors[index].detach();
+        this._behaviors.splice(index, 1);
 
-            this._isVisible = value;
+        return this;
+    }
 
-            let mesh = this.mesh;
-            if (mesh) {
-                mesh.setEnabled(value);
+    /**
+     * Gets an attached behavior by name
+     * @param name defines the name of the behavior to look for
+     * @see http://doc.babylonjs.com/features/behaviour
+     * @returns null if behavior was not found else the requested behavior
+     */
+    public getBehaviorByName(name: string): Nullable<Behavior<Control3D>> {
+        for (var behavior of this._behaviors) {
+            if (behavior.name === name) {
+                return behavior;
             }
         }
 
-        /**
-         * Creates a new control
-         * @param name defines the control name
-         */
-        constructor(
-            /** Defines the control name */
-            public name?: string) {
-        }
+        return null;
+    }
+
+    /** Gets or sets a boolean indicating if the control is visible */
+    public get isVisible(): boolean {
+        return this._isVisible;
+    }
 
-        /**
-         * Gets a string representing the class name
-         */
-        public get typeName(): string {
-            return this._getTypeName();
+    public set isVisible(value: boolean) {
+        if (this._isVisible === value) {
+            return;
         }
 
-        protected _getTypeName(): string {
-            return "Control3D";
+        this._isVisible = value;
+
+        let mesh = this.mesh;
+        if (mesh) {
+            mesh.setEnabled(value);
         }
+    }
+
+    /**
+     * Creates a new control
+     * @param name defines the control name
+     */
+    constructor(
+        /** Defines the control name */
+        public name?: string) {
+    }
+
+    /**
+     * Gets a string representing the class name
+     */
+    public get typeName(): string {
+        return this._getTypeName();
+    }
 
-        /**
-         * Gets the transform node used by this control
-         */
-        public get node(): Nullable<TransformNode> {
-            return this._node;
+    protected _getTypeName(): string {
+        return "Control3D";
+    }
+
+    /**
+     * Gets the transform node used by this control
+     */
+    public get node(): Nullable<TransformNode> {
+        return this._node;
+    }
+
+    /**
+     * Gets the mesh used to render this control
+     */
+    public get mesh(): Nullable<AbstractMesh> {
+        if (this._node instanceof AbstractMesh) {
+            return this._node as AbstractMesh;
         }
 
-        /**
-         * Gets the mesh used to render this control
-         */
-        public get mesh(): Nullable<AbstractMesh> {
-            if (this._node instanceof AbstractMesh) {
-                return this._node as AbstractMesh;
-            }
+        return null;
+    }
 
-            return null;
+    /**
+     * Link the control as child of the given node
+     * @param node defines the node to link to. Use null to unlink the control
+     * @returns the current control
+     */
+    public linkToTransformNode(node: Nullable<TransformNode>): Control3D {
+        if (this._node) {
+            this._node.parent = node;
         }
+        return this;
+    }
 
-        /**
-         * Link the control as child of the given node
-         * @param node defines the node to link to. Use null to unlink the control
-         * @returns the current control
-         */
-        public linkToTransformNode(node: Nullable<TransformNode>): Control3D {
-            if (this._node) {
-                this._node.parent = node;
+    /** @hidden **/
+    public _prepareNode(scene: Scene): void {
+        if (!this._node) {
+            this._node = this._createNode(scene);
+
+            if (!this.node) {
+                return;
             }
-            return this;
-        }    
-
-        /** @hidden **/      
-        public _prepareNode(scene: Scene): void{
-            if (!this._node) {
-                this._node = this._createNode(scene);
-
-                if (!this.node) {
-                    return;
-                }
-                this._node!.metadata = this; // Store the control on the metadata field in order to get it when picking
-                this._node!.position = this.position;
-                this._node!.scaling = this.scaling;
-
-                let mesh = this.mesh;
-                if (mesh) {
-                    mesh.isPickable = true;
-
-                    this._affectMaterial(mesh);
-                }
+            this._node!.metadata = this; // Store the control on the metadata field in order to get it when picking
+            this._node!.position = this.position;
+            this._node!.scaling = this.scaling;
+
+            let mesh = this.mesh;
+            if (mesh) {
+                mesh.isPickable = true;
+
+                this._affectMaterial(mesh);
             }
         }
+    }
+
+    /**
+     * Node creation.
+     * Can be overriden by children
+     * @param scene defines the scene where the node must be attached
+     * @returns the attached node or null if none. Must return a Mesh or AbstractMesh if there is an atttached visible object
+     */
+    protected _createNode(scene: Scene): Nullable<TransformNode> {
+        // Do nothing by default
+        return null;
+    }
+
+    /**
+     * Affect a material to the given mesh
+     * @param mesh defines the mesh which will represent the control
+     */
+    protected _affectMaterial(mesh: AbstractMesh) {
+        mesh.material = null;
+    }
+
+    // Pointers
 
-        /**
-         * Node creation.
-         * Can be overriden by children
-         * @param scene defines the scene where the node must be attached
-         * @returns the attached node or null if none. Must return a Mesh or AbstractMesh if there is an atttached visible object
-         */
-        protected _createNode(scene: Scene): Nullable<TransformNode> {
-            // Do nothing by default
-            return null;
+    /** @hidden */
+    public _onPointerMove(target: Control3D, coordinates: Vector3): void {
+        this.onPointerMoveObservable.notifyObservers(coordinates, -1, target, this);
+    }
+
+    /** @hidden */
+    public _onPointerEnter(target: Control3D): boolean {
+        if (this._enterCount > 0) {
+            return false;
         }
 
-        /**
-         * Affect a material to the given mesh
-         * @param mesh defines the mesh which will represent the control
-         */
-        protected _affectMaterial(mesh: AbstractMesh) {
-            mesh.material = null;
+        if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
+            this._enterCount = 0;
         }
 
-        // Pointers
+        this._enterCount++;
 
-        /** @hidden */
-        public _onPointerMove(target: Control3D, coordinates: Vector3): void {
-            this.onPointerMoveObservable.notifyObservers(coordinates, -1, target, this);
-        }
+        this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
 
-        /** @hidden */
-        public _onPointerEnter(target: Control3D): boolean {
-            if (this._enterCount > 0) {
-                return false;
-            }
+        if (this.pointerEnterAnimation) {
+            this.pointerEnterAnimation();
+        }
 
-            if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
-                this._enterCount = 0;
-            }
+        return true;
+    }
 
-            this._enterCount++;
+    /** @hidden */
+    public _onPointerOut(target: Control3D): void {
+        this._enterCount = 0;
 
-            this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
+        this.onPointerOutObservable.notifyObservers(this, -1, target, this);
 
-            if (this.pointerEnterAnimation) {
-                this.pointerEnterAnimation();
-            }
+        if (this.pointerOutAnimation) {
+            this.pointerOutAnimation();
+        }
+    }
 
-            return true;
+    /** @hidden */
+    public _onPointerDown(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number): boolean {
+        if (this._downCount !== 0) {
+            return false;
         }
 
-        /** @hidden */
-        public _onPointerOut(target: Control3D): void {
-            this._enterCount = 0;
+        this._downCount++;
 
-            this.onPointerOutObservable.notifyObservers(this, -1, target, this);
+        this._downPointerIds[pointerId] = true;
 
-            if (this.pointerOutAnimation) {
-                this.pointerOutAnimation();
-            }            
-        }
+        this.onPointerDownObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
 
-        /** @hidden */
-        public _onPointerDown(target: Control3D, coordinates: Vector3, pointerId:number, buttonIndex: number): boolean {
-            if (this._downCount !== 0) {
-                return false;
-            }
+        if (this.pointerDownAnimation) {
+            this.pointerDownAnimation();
+        }
 
-            this._downCount++;
+        return true;
+    }
 
-            this._downPointerIds[pointerId] = true;
+    /** @hidden */
+    public _onPointerUp(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        this._downCount = 0;
 
-            this.onPointerDownObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
+        delete this._downPointerIds[pointerId];
 
-            if (this.pointerDownAnimation) {
-                this.pointerDownAnimation();
-            }                 
+        if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
+            this.onPointerClickObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
+        }
+        this.onPointerUpObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
 
-            return true;
+        if (this.pointerUpAnimation) {
+            this.pointerUpAnimation();
         }
+    }
 
-        /** @hidden */
-        public _onPointerUp(target: Control3D, coordinates: Vector3, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            this._downCount = 0;
-
-            delete this._downPointerIds[pointerId];
-
-			if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
-				this.onPointerClickObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
-			}
-			this.onPointerUpObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);            
-
-            if (this.pointerUpAnimation) {
-                this.pointerUpAnimation();
-            }          
-        }  
-
-        /** @hidden */
-        public forcePointerUp(pointerId: Nullable<number> = null) {
-            if(pointerId !== null){
-                this._onPointerUp(this, Vector3.Zero(), pointerId, 0, true);
-            }else{
-                for(var key in this._downPointerIds){
-                    this._onPointerUp(this, Vector3.Zero(), +key as number, 0, true);
-                }
+    /** @hidden */
+    public forcePointerUp(pointerId: Nullable<number> = null) {
+        if (pointerId !== null) {
+            this._onPointerUp(this, Vector3.Zero(), pointerId, 0, true);
+        } else {
+            for (var key in this._downPointerIds) {
+                this._onPointerUp(this, Vector3.Zero(), +key as number, 0, true);
             }
         }
-        
-        /** @hidden */
-        public _processObservables(type: number, pickedPoint: Vector3, pointerId:number, buttonIndex: number): boolean {
-            if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
-                this._onPointerMove(this, pickedPoint);
-
-                var previousControlOver = this._host._lastControlOver[pointerId];
-                if (previousControlOver && previousControlOver !== this) {
-                    previousControlOver._onPointerOut(this);
-                }
-
-                if (previousControlOver !== this) {
-                    this._onPointerEnter(this);
-                }
-
-                this._host._lastControlOver[pointerId] = this;
-                return true;
-            }
+    }
+
+    /** @hidden */
+    public _processObservables(type: number, pickedPoint: Vector3, pointerId: number, buttonIndex: number): boolean {
+        if (type === PointerEventTypes.POINTERMOVE) {
+            this._onPointerMove(this, pickedPoint);
 
-            if (type === BABYLON.PointerEventTypes.POINTERDOWN) {
-                this._onPointerDown(this, pickedPoint, pointerId, buttonIndex);
-                this._host._lastControlDown[pointerId] = this;
-                this._host._lastPickedControl = this;
-                return true;
+            var previousControlOver = this._host._lastControlOver[pointerId];
+            if (previousControlOver && previousControlOver !== this) {
+                previousControlOver._onPointerOut(this);
             }
 
-            if (type === BABYLON.PointerEventTypes.POINTERUP) {
-                if (this._host._lastControlDown[pointerId]) {
-                    this._host._lastControlDown[pointerId]._onPointerUp(this, pickedPoint, pointerId, buttonIndex, true);
-                }
-                delete this._host._lastControlDown[pointerId];
-                return true;
+            if (previousControlOver !== this) {
+                this._onPointerEnter(this);
             }
 
-            return false;
-        }        
+            this._host._lastControlOver[pointerId] = this;
+            return true;
+        }
 
-        /** @hidden */
-        public _disposeNode(): void {
-            if (this._node) {
-                this._node.dispose();
-                this._node = null;
-            }
+        if (type === PointerEventTypes.POINTERDOWN) {
+            this._onPointerDown(this, pickedPoint, pointerId, buttonIndex);
+            this._host._lastControlDown[pointerId] = this;
+            this._host._lastPickedControl = this;
+            return true;
         }
 
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            this.onPointerDownObservable.clear();
-            this.onPointerEnterObservable.clear();
-            this.onPointerMoveObservable.clear();
-            this.onPointerOutObservable.clear();
-            this.onPointerUpObservable.clear();
-            this.onPointerClickObservable.clear();
-
-            this._disposeNode();
-
-            // Behaviors
-            for (var behavior of this._behaviors) {
-                behavior.detach();
+        if (type === PointerEventTypes.POINTERUP) {
+            if (this._host._lastControlDown[pointerId]) {
+                this._host._lastControlDown[pointerId]._onPointerUp(this, pickedPoint, pointerId, buttonIndex, true);
             }
+            delete this._host._lastControlDown[pointerId];
+            return true;
+        }
+
+        return false;
+    }
+
+    /** @hidden */
+    public _disposeNode(): void {
+        if (this._node) {
+            this._node.dispose();
+            this._node = null;
+        }
+    }
+
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        this.onPointerDownObservable.clear();
+        this.onPointerEnterObservable.clear();
+        this.onPointerMoveObservable.clear();
+        this.onPointerOutObservable.clear();
+        this.onPointerUpObservable.clear();
+        this.onPointerClickObservable.clear();
+
+        this._disposeNode();
+
+        // Behaviors
+        for (var behavior of this._behaviors) {
+            behavior.detach();
         }
     }
 }

+ 48 - 48
gui/src/3D/controls/cylinderPanel.ts

@@ -1,65 +1,65 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { float, Tools, Vector3, Matrix, Tmp } from "babylonjs";
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { Control3D } from "./control3D";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used to create a container panel deployed on the surface of a cylinder
+ */
+export class CylinderPanel extends VolumeBasedPanel {
+    private _radius = 5.0;
 
-module BABYLON.GUI {
     /**
-     * Class used to create a container panel deployed on the surface of a cylinder
+     * Gets or sets the radius of the cylinder where to project controls (5 by default)
      */
-    export class CylinderPanel extends VolumeBasedPanel {
-        private _radius = 5.0;
+    public get radius(): float {
+        return this._radius;
+    }
 
-        /**
-         * Gets or sets the radius of the cylinder where to project controls (5 by default)
-         */
-        public get radius(): float {
-            return this._radius;
+    public set radius(value: float) {
+        if (this._radius === value) {
+            return;
         }
 
-        public set radius(value: float) {
-            if (this._radius === value) {
-                return;
-            }
+        this._radius = value;
 
-            this._radius = value;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }              
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
 
-            if (!mesh) {
-                return;
-            }
-            let newPos = this._cylindricalMapping(nodePosition);
-            control.position = newPos;
+        if (!mesh) {
+            return;
+        }
+        let newPos = this._cylindricalMapping(nodePosition);
+        control.position = newPos;
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(-newPos.x, 0, -newPos.z));
-                    break;
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(newPos.x, 0, newPos.z));
-                    break;
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, 1));
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, -1));
-                    break;
-            }            
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+                mesh.lookAt(new Vector3(-newPos.x, 0, -newPos.z));
+                break;
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                mesh.lookAt(new Vector3(newPos.x, 0, newPos.z));
+                break;
+            case Container3D.FACEFORWARD_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, 1));
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, -1));
+                break;
         }
+    }
 
-        private _cylindricalMapping(source: Vector3)
-        {
-            let newPos = new Vector3(0, source.y, this._radius);
+    private _cylindricalMapping(source: Vector3) {
+        let newPos = new Vector3(0, source.y, this._radius);
 
-            let yAngle = (source.x / this._radius);
+        let yAngle = (source.x / this._radius);
 
-            Matrix.RotationYawPitchRollToRef(yAngle, 0, 0, Tmp.Matrix[0]);
+        Matrix.RotationYawPitchRollToRef(yAngle, 0, 0, Tmp.Matrix[0]);
 
-            return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
-        }
+        return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
     }
 }

+ 210 - 206
gui/src/3D/controls/holographicButton.ts

@@ -1,243 +1,247 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Button3D } from "./button3D";
+import { Mesh, StandardMaterial, Nullable, Observer, Vector3, Scene, TransformNode, MeshBuilder, Color3 } from "babylonjs";
+import { FluentMaterial } from "../materials/fluentMaterial";
+import { StackPanel } from "../../2D/controls/stackPanel";
+import { Image } from "../../2D/controls/image";
+import { TextBlock } from "../../2D/controls/textBlock";
+import { AdvancedDynamicTexture } from "../../2D/advancedDynamicTexture";
+
+/**
+ * Class used to create a holographic button in 3D
+ */
+export class HolographicButton extends Button3D {
+    private _backPlate: Mesh;
+    private _textPlate: Mesh;
+    private _frontPlate: Mesh;
+    private _text: string;
+    private _imageUrl: string;
+    private _shareMaterials = true;
+    private _frontMaterial: FluentMaterial;
+    private _backMaterial: FluentMaterial;
+    private _plateMaterial: StandardMaterial;
+    private _pickedPointObserver: Nullable<Observer<Nullable<Vector3>>>;
 
-module BABYLON.GUI {
     /**
-     * Class used to create a holographic button in 3D
+     * Gets or sets text for the button
      */
-    export class HolographicButton extends Button3D {
-        private _backPlate: Mesh;
-        private _textPlate: Mesh;
-        private _frontPlate: Mesh;
-        private _text: string;
-        private _imageUrl: string;
-        private _shareMaterials = true;
-        private _frontMaterial: FluentMaterial;
-        private _backMaterial: FluentMaterial;
-        private _plateMaterial: StandardMaterial;
-        private _pickedPointObserver: Nullable<Observer<Nullable<Vector3>>>;
-
-        /**
-         * Gets or sets text for the button
-         */
-        public get text(): string {
-            return this._text;
+    public get text(): string {
+        return this._text;
+    }
+
+    public set text(value: string) {
+        if (this._text === value) {
+            return;
         }
 
-        public set text(value: string) {
-            if (this._text === value) {
-                return;
-            }
+        this._text = value;
+        this._rebuildContent();
+    }
 
-            this._text = value;
-            this._rebuildContent();
-        }
+    /**
+     * Gets or sets the image url for the button
+     */
+    public get imageUrl(): string {
+        return this._imageUrl;
+    }
 
-        /**
-         * Gets or sets the image url for the button
-         */
-        public get imageUrl(): string {
-            return this._imageUrl;
+    public set imageUrl(value: string) {
+        if (this._imageUrl === value) {
+            return;
         }
 
-        public set imageUrl(value: string) {
-            if (this._imageUrl === value) {
-                return;
-            }
+        this._imageUrl = value;
+        this._rebuildContent();
+    }
 
-            this._imageUrl = value;
-            this._rebuildContent();
-        }        
+    /**
+     * Gets the back material used by this button
+     */
+    public get backMaterial(): FluentMaterial {
+        return this._backMaterial;
+    }
 
-        /**
-         * Gets the back material used by this button
-         */
-        public get backMaterial(): FluentMaterial {
-            return this._backMaterial;
-        }
+    /**
+     * Gets the front material used by this button
+     */
+    public get frontMaterial(): FluentMaterial {
+        return this._frontMaterial;
+    }
 
-        /**
-         * Gets the front material used by this button
-         */
-        public get frontMaterial(): FluentMaterial {
-            return this._frontMaterial;
-        }       
-        
-        /**
-         * Gets the plate material used by this button
-         */
-        public get plateMaterial(): StandardMaterial {
-            return this._plateMaterial;
-        }          
-
-        /**
-         * Gets a boolean indicating if this button shares its material with other HolographicButtons
-         */
-        public get shareMaterials(): boolean {
-            return this._shareMaterials;
-        }
+    /**
+     * Gets the plate material used by this button
+     */
+    public get plateMaterial(): StandardMaterial {
+        return this._plateMaterial;
+    }
 
-        /**
-         * Creates a new button
-         * @param name defines the control name
-         */
-        constructor(name?: string, shareMaterials = true) {
-            super(name);
-
-            this._shareMaterials = shareMaterials;
-
-            // Default animations
-            this.pointerEnterAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this._frontPlate.setEnabled(true);
-            }
+    /**
+     * Gets a boolean indicating if this button shares its material with other HolographicButtons
+     */
+    public get shareMaterials(): boolean {
+        return this._shareMaterials;
+    }
 
-            this.pointerOutAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this._frontPlate.setEnabled(false);
-            }                      
-        }
-    
-        protected _getTypeName(): string {
-            return "HolographicButton";
-        }        
-
-        private _rebuildContent(): void {
-            this._disposeFacadeTexture();
-
-            let panel = new StackPanel();
-            panel.isVertical = true;
-
-            if (this._imageUrl) {
-                let image = new BABYLON.GUI.Image();
-                image.source = this._imageUrl;
-                image.paddingTop = "40px";
-                image.height = "180px";
-                image.width = "100px";
-                image.paddingBottom = "40px";
-                panel.addControl(image);                
-            }
+    /**
+     * Creates a new button
+     * @param name defines the control name
+     */
+    constructor(name?: string, shareMaterials = true) {
+        super(name);
 
-            if (this._text) {
-                let text = new BABYLON.GUI.TextBlock();
-                text.text = this._text;
-                text.color = "white";
-                text.height = "30px";
-                text.fontSize = 24;
-                panel.addControl(text);
-            }
+        this._shareMaterials = shareMaterials;
 
-            if (this._frontPlate) {
-                this.content = panel;
+        // Default animations
+        this.pointerEnterAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
+            this._frontPlate.setEnabled(true);
         }
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            this._backPlate = MeshBuilder.CreateBox(this.name + "BackMesh", {
-                width: 1.0, 
-                height: 1.0,
-                depth: 0.08
-            }, scene); 
-
-            this._frontPlate = MeshBuilder.CreateBox(this.name + "FrontMesh", {
-                width: 1.0, 
-                height: 1.0,
-                depth: 0.08
-            }, scene); 
-
-            this._frontPlate.parent = this._backPlate;
-            this._frontPlate.position.z = -0.08;
-            this._frontPlate.isPickable = false;
+        this.pointerOutAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
             this._frontPlate.setEnabled(false);
+        }
+    }
+
+    protected _getTypeName(): string {
+        return "HolographicButton";
+    }
+
+    private _rebuildContent(): void {
+        this._disposeFacadeTexture();
+
+        let panel = new StackPanel();
+        panel.isVertical = true;
 
-            this._textPlate= <Mesh>super._createNode(scene);
-            this._textPlate.parent = this._backPlate;
-            this._textPlate.position.z = -0.08;
-            this._textPlate.isPickable = false;            
-           
-            return this._backPlate;
+        if (this._imageUrl) {
+            let image = new Image();
+            image.source = this._imageUrl;
+            image.paddingTop = "40px";
+            image.height = "180px";
+            image.width = "100px";
+            image.paddingBottom = "40px";
+            panel.addControl(image);
         }
 
-        protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
-            this._plateMaterial.emissiveTexture = facadeTexture;
-            this._plateMaterial.opacityTexture = facadeTexture;
-        }   
-        
-        private _createBackMaterial(mesh: Mesh) {
-            this._backMaterial = new FluentMaterial(this.name + "Back Material", mesh.getScene());
-            this._backMaterial.renderHoverLight = true;
-            this._pickedPointObserver = this._host.onPickedPointChangedObservable.add(pickedPoint => {
-                if (pickedPoint) {
-                    this._backMaterial.hoverPosition = pickedPoint;
-                    this._backMaterial.hoverColor.a = 1.0;
-                } else {
-                    this._backMaterial.hoverColor.a = 0;
-                }
-            });
+        if (this._text) {
+            let text = new TextBlock();
+            text.text = this._text;
+            text.color = "white";
+            text.height = "30px";
+            text.fontSize = 24;
+            panel.addControl(text);
         }
 
-        private _createFrontMaterial(mesh: Mesh) {
-            this._frontMaterial = new FluentMaterial(this.name + "Front Material", mesh.getScene());
-            this._frontMaterial.innerGlowColorIntensity = 0; // No inner glow
-            this._frontMaterial.alpha = 0.5; // Additive
-            this._frontMaterial.renderBorders = true;
-        }     
-        
-        private _createPlateMaterial(mesh: Mesh) {
-            this._plateMaterial = new StandardMaterial(this.name + "Plate Material", mesh.getScene());
-            this._plateMaterial.specularColor = Color3.Black();
+        if (this._frontPlate) {
+            this.content = panel;
         }
+    }
+
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        this._backPlate = MeshBuilder.CreateBox(this.name + "BackMesh", {
+            width: 1.0,
+            height: 1.0,
+            depth: 0.08
+        }, scene);
+
+        this._frontPlate = MeshBuilder.CreateBox(this.name + "FrontMesh", {
+            width: 1.0,
+            height: 1.0,
+            depth: 0.08
+        }, scene);
+
+        this._frontPlate.parent = this._backPlate;
+        this._frontPlate.position.z = -0.08;
+        this._frontPlate.isPickable = false;
+        this._frontPlate.setEnabled(false);
+
+        this._textPlate = <Mesh>super._createNode(scene);
+        this._textPlate.parent = this._backPlate;
+        this._textPlate.position.z = -0.08;
+        this._textPlate.isPickable = false;
+
+        return this._backPlate;
+    }
+
+    protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
+        this._plateMaterial.emissiveTexture = facadeTexture;
+        this._plateMaterial.opacityTexture = facadeTexture;
+    }
 
-        protected _affectMaterial(mesh: Mesh) {
-            // Back
-            if (this._shareMaterials) {
-                if (!this._host._sharedMaterials["backFluentMaterial"]) {
-                    this._createBackMaterial(mesh);
-                    this._host._sharedMaterials["backFluentMaterial"] =  this._backMaterial;
-                } else {
-                    this._backMaterial = this._host._sharedMaterials["backFluentMaterial"] as FluentMaterial;
-                }
-
-                // Front
-                if (!this._host._sharedMaterials["frontFluentMaterial"]) {
-                    this._createFrontMaterial(mesh);
-                    this._host._sharedMaterials["frontFluentMaterial"] = this._frontMaterial;                
-                } else {
-                    this._frontMaterial = this._host._sharedMaterials["frontFluentMaterial"] as FluentMaterial;
-                }  
+    private _createBackMaterial(mesh: Mesh) {
+        this._backMaterial = new FluentMaterial(this.name + "Back Material", mesh.getScene());
+        this._backMaterial.renderHoverLight = true;
+        this._pickedPointObserver = this._host.onPickedPointChangedObservable.add(pickedPoint => {
+            if (pickedPoint) {
+                this._backMaterial.hoverPosition = pickedPoint;
+                this._backMaterial.hoverColor.a = 1.0;
             } else {
+                this._backMaterial.hoverColor.a = 0;
+            }
+        });
+    }
+
+    private _createFrontMaterial(mesh: Mesh) {
+        this._frontMaterial = new FluentMaterial(this.name + "Front Material", mesh.getScene());
+        this._frontMaterial.innerGlowColorIntensity = 0; // No inner glow
+        this._frontMaterial.alpha = 0.5; // Additive
+        this._frontMaterial.renderBorders = true;
+    }
+
+    private _createPlateMaterial(mesh: Mesh) {
+        this._plateMaterial = new StandardMaterial(this.name + "Plate Material", mesh.getScene());
+        this._plateMaterial.specularColor = Color3.Black();
+    }
+
+    protected _affectMaterial(mesh: Mesh) {
+        // Back
+        if (this._shareMaterials) {
+            if (!this._host._sharedMaterials["backFluentMaterial"]) {
                 this._createBackMaterial(mesh);
+                this._host._sharedMaterials["backFluentMaterial"] = this._backMaterial;
+            } else {
+                this._backMaterial = this._host._sharedMaterials["backFluentMaterial"] as FluentMaterial;
+            }
+
+            // Front
+            if (!this._host._sharedMaterials["frontFluentMaterial"]) {
                 this._createFrontMaterial(mesh);
+                this._host._sharedMaterials["frontFluentMaterial"] = this._frontMaterial;
+            } else {
+                this._frontMaterial = this._host._sharedMaterials["frontFluentMaterial"] as FluentMaterial;
             }
+        } else {
+            this._createBackMaterial(mesh);
+            this._createFrontMaterial(mesh);
+        }
 
-            this._createPlateMaterial(mesh);
-            this._backPlate.material =  this._backMaterial;
-            this._frontPlate.material = this._frontMaterial;
-            this._textPlate.material = this._plateMaterial;
+        this._createPlateMaterial(mesh);
+        this._backPlate.material = this._backMaterial;
+        this._frontPlate.material = this._frontMaterial;
+        this._textPlate.material = this._plateMaterial;
 
-            this._rebuildContent();
-        }
+        this._rebuildContent();
+    }
+
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        super.dispose(); // will dispose main mesh ie. back plate
 
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            super.dispose(); // will dispose main mesh ie. back plate
-            
-            if (!this.shareMaterials) {
-                this._backMaterial.dispose();
-                this._frontMaterial.dispose();
-                this._plateMaterial.dispose();
-
-                if (this._pickedPointObserver) {
-                    this._host.onPickedPointChangedObservable.remove(this._pickedPointObserver);
-                    this._pickedPointObserver = null;
-                }
+        if (!this.shareMaterials) {
+            this._backMaterial.dispose();
+            this._frontMaterial.dispose();
+            this._plateMaterial.dispose();
+
+            if (this._pickedPointObserver) {
+                this._host.onPickedPointChangedObservable.remove(this._pickedPointObserver);
+                this._pickedPointObserver = null;
             }
-        }        
+        }
     }
 }

+ 12 - 0
gui/src/3D/controls/index.ts

@@ -0,0 +1,12 @@
+export * from "./abstractButton3D";
+export * from "./button3D";
+export * from "./container3D";
+export * from "./control3D";
+export * from "./cylinderPanel";
+export * from "./holographicButton";
+export * from "./meshButton3D";
+export * from "./planePanel";
+export * from "./scatterPanel";
+export * from "./spherePanel";
+export * from "./stackPanel3D";
+export * from "./volumeBasedPanel";

+ 50 - 51
gui/src/3D/controls/meshButton3D.ts

@@ -1,68 +1,67 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Scene, TransformNode, AbstractMesh, Mesh } from "babylonjs";
+import { Button3D } from "./button3D";
+
+/**
+ * Class used to create an interactable object. It's a 3D button using a mesh coming from the current scene
+ */
+export class MeshButton3D extends Button3D {
+    /** @hidden */
+    protected _currentMesh: Mesh;
 
-module BABYLON.GUI {
     /**
-     * Class used to create an interactable object. It's a 3D button using a mesh coming from the current scene
+     * Creates a new 3D button based on a mesh
+     * @param mesh mesh to become a 3D button
+     * @param name defines the control name
      */
-    export class MeshButton3D extends Button3D {
-        /** @hidden */
-        protected _currentMesh: Mesh;
+    constructor(mesh: Mesh, name?: string) {
+        super(name);
+        this._currentMesh = mesh;
 
         /**
-         * Creates a new 3D button based on a mesh
-         * @param mesh mesh to become a 3D button
-         * @param name defines the control name
+         * Provides a default behavior on hover/out & up/down
+         * Override those function to create your own desired behavior specific to your mesh
          */
-        constructor(mesh: Mesh, name?: string) {
-            super(name);
-            this._currentMesh = mesh; 
-
-            /**
-             * Provides a default behavior on hover/out & up/down
-             * Override those function to create your own desired behavior specific to your mesh
-             */
-            this.pointerEnterAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(1.1);
+        this.pointerEnterAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
+            this.mesh.scaling.scaleInPlace(1.1);
+        }
 
-            this.pointerOutAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(1.0 / 1.1);
-            }    
+        this.pointerOutAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
+            this.mesh.scaling.scaleInPlace(1.0 / 1.1);
+        }
 
-            this.pointerDownAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(0.95);
+        this.pointerDownAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
+            this.mesh.scaling.scaleInPlace(0.95);
+        }
 
-            this.pointerUpAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(1.0 / 0.95);
-            }                     
+        this.pointerUpAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
+            this.mesh.scaling.scaleInPlace(1.0 / 0.95);
         }
+    }
 
-        protected _getTypeName(): string {
-            return "MeshButton3D";
-        }        
+    protected _getTypeName(): string {
+        return "MeshButton3D";
+    }
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            this._currentMesh.getChildMeshes().forEach((mesh)=>{
-                mesh.metadata = this;
-            });
-            return this._currentMesh;
-        }
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        this._currentMesh.getChildMeshes().forEach((mesh) => {
+            mesh.metadata = this;
+        });
+        return this._currentMesh;
+    }
 
-        protected _affectMaterial(mesh: AbstractMesh) {
-        }
+    protected _affectMaterial(mesh: AbstractMesh) {
     }
 }

+ 24 - 23
gui/src/3D/controls/planePanel.ts

@@ -1,30 +1,31 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { Control3D } from "./control3D";
+import { Vector3 } from "babylonjs";
+import { Container3D } from "./container3D";
 
-module BABYLON.GUI {
-    /**
-     * Class used to create a container panel deployed on the surface of a plane
-     */
-    export class PlanePanel extends VolumeBasedPanel {    
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
+/**
+ * Class used to create a container panel deployed on the surface of a plane
+ */
+export class PlanePanel extends VolumeBasedPanel {
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
 
-            if (!mesh) {
-                return;
-            }
+        if (!mesh) {
+            return;
+        }
 
-            control.position = nodePosition.clone();
+        control.position = nodePosition.clone();
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, -1));
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, 1));
-                    break;
-            }
-            
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+            case Container3D.FACEFORWARD_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, -1));
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, 1));
+                break;
         }
+
     }
 }

+ 91 - 95
gui/src/3D/controls/scatterPanel.ts

@@ -1,117 +1,113 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { float, Tools, Vector3, Tmp } from "babylonjs";
+import { Control3D } from "./control3D";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used to create a container panel where items get randomized planar mapping
+ */
+export class ScatterPanel extends VolumeBasedPanel {
+    private _iteration = 100.0;
 
-module BABYLON.GUI {
     /**
-     * Class used to create a container panel where items get randomized planar mapping
+     * Gets or sets the number of iteration to use to scatter the controls (100 by default)
      */
-    export class ScatterPanel extends VolumeBasedPanel {    
-        private _iteration = 100.0;
-
-        /**
-         * Gets or sets the number of iteration to use to scatter the controls (100 by default)
-         */
-        public get iteration(): float {
-            return this._iteration;
+    public get iteration(): float {
+        return this._iteration;
+    }
+
+    public set iteration(value: float) {
+        if (this._iteration === value) {
+            return;
         }
 
-        public set iteration(value: float) {
-            if (this._iteration === value) {
-                return;
-            }
+        this._iteration = value;
+
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-            this._iteration = value;
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
+        let newPos = this._scatterMapping(nodePosition);
 
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }    
+        if (!mesh) {
+            return;
+        }
 
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
-            let newPos = this._scatterMapping(nodePosition);
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+            case Container3D.FACEFORWARD_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, -1));
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, 1));
+                break;
+        }
 
-            if (!mesh) {
-                return;
-            }
+        control.position = newPos;
+    }
+
+    private _scatterMapping(source: Vector3): Vector3 {
+        source.x = (1.0 - Math.random() * 2.0) * this._cellWidth;
+        source.y = (1.0 - Math.random() * 2.0) * this._cellHeight;
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, -1));
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, 1));
-                    break;
+        return source;
+    }
+
+    protected _finalProcessing() {
+        var meshes = [];
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
-            
-            control.position = newPos;
+
+            meshes.push(child.mesh);
         }
 
-        private _scatterMapping(source: Vector3): Vector3
-        {
-            source.x = (1.0 - Math.random() * 2.0) * this._cellWidth;
-            source.y = (1.0 - Math.random() * 2.0) * this._cellHeight;
-
-            return source;
-        }   
-        
-        protected _finalProcessing() {
-            var meshes = [];
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }                
-
-                meshes.push(child.mesh);
-            }
+        for (var count = 0; count < this._iteration; count++) {
+            meshes.sort((a, b) => {
+                let distance1 = a.position.lengthSquared();
+                let distance2 = b.position.lengthSquared();
 
-            for (var count = 0; count < this._iteration; count++) {
-                meshes.sort((a, b) => {
-                    let distance1 = a.position.lengthSquared();
-                    let distance2 = b.position.lengthSquared();
+                if (distance1 < distance2) {
+                    return 1;
+                } else if (distance1 > distance2) {
+                    return -1;
+                }
 
-                    if (distance1 < distance2) {
-                        return 1;
-                    } else if (distance1 > distance2) {
-                        return -1;
-                    }
+                return 0;
+            });
 
-                    return 0;
-                });
-
-                let radiusPaddingSquared = Math.pow(this.margin, 2.0);
-                let cellSize = Math.max(this._cellWidth, this._cellHeight);
-                let difference2D = Tmp.Vector2[0];
-                let difference = Tmp.Vector3[0];
-
-                for (let i = 0; i < meshes.length - 1; i++)
-                {
-                    for (let j = i + 1; j < meshes.length; j++)
-                    {
-                        if (i != j)
-                        {
-                            meshes[j].position.subtractToRef(meshes[i].position, difference);
-
-                            // Ignore Z axis
-                            difference2D.x = difference.x;
-                            difference2D.y = difference.y;
-                            let combinedRadius = cellSize;
-                            let distance = difference2D.lengthSquared()- radiusPaddingSquared;
-                            let minSeparation = Math.min(distance, radiusPaddingSquared);
-                            distance -= minSeparation;
-
-                            if (distance < (Math.pow(combinedRadius, 2.0)))
-                            {
-                                difference2D.normalize();
-                                difference.scaleInPlace((combinedRadius - Math.sqrt(distance)) * 0.5);
-                                meshes[j].position.addInPlace(difference);
-                                meshes[i].position.subtractInPlace(difference);
-                            }
+            let radiusPaddingSquared = Math.pow(this.margin, 2.0);
+            let cellSize = Math.max(this._cellWidth, this._cellHeight);
+            let difference2D = Tmp.Vector2[0];
+            let difference = Tmp.Vector3[0];
+
+            for (let i = 0; i < meshes.length - 1; i++) {
+                for (let j = i + 1; j < meshes.length; j++) {
+                    if (i != j) {
+                        meshes[j].position.subtractToRef(meshes[i].position, difference);
+
+                        // Ignore Z axis
+                        difference2D.x = difference.x;
+                        difference2D.y = difference.y;
+                        let combinedRadius = cellSize;
+                        let distance = difference2D.lengthSquared() - radiusPaddingSquared;
+                        let minSeparation = Math.min(distance, radiusPaddingSquared);
+                        distance -= minSeparation;
+
+                        if (distance < (Math.pow(combinedRadius, 2.0))) {
+                            difference2D.normalize();
+                            difference.scaleInPlace((combinedRadius - Math.sqrt(distance)) * 0.5);
+                            meshes[j].position.addInPlace(difference);
+                            meshes[i].position.subtractInPlace(difference);
                         }
                     }
                 }
-            }        
+            }
         }
     }
 }

+ 49 - 49
gui/src/3D/controls/spherePanel.ts

@@ -1,67 +1,67 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { Tools, Vector3, Matrix, Tmp } from "babylonjs";
+import { Control3D } from "./control3D";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used to create a container panel deployed on the surface of a sphere
+ */
+export class SpherePanel extends VolumeBasedPanel {
+    private _radius = 5.0;
 
-module BABYLON.GUI {
     /**
-     * Class used to create a container panel deployed on the surface of a sphere
+     * Gets or sets the radius of the sphere where to project controls (5 by default)
      */
-    export class SpherePanel extends VolumeBasedPanel {
-        private _radius = 5.0;
+    public get radius(): number {
+        return this._radius;
+    }
 
-        /**
-         * Gets or sets the radius of the sphere where to project controls (5 by default)
-         */
-        public get radius(): float {
-            return this._radius;
+    public set radius(value: number) {
+        if (this._radius === value) {
+            return;
         }
 
-        public set radius(value: float) {
-            if (this._radius === value) {
-                return;
-            }
+        this._radius = value;
 
-            this._radius = value;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }              
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
 
-            if (!mesh) {
-                return;
-            }
+        if (!mesh) {
+            return;
+        }
 
-            let newPos = this._sphericalMapping(nodePosition);
-            control.position = newPos;
+        let newPos = this._sphericalMapping(nodePosition);
+        control.position = newPos;
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(-newPos.x, -newPos.y, -newPos.z));
-                    break;
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(newPos.x, newPos.y, newPos.z));
-                    break;
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, 1));
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, -1));
-                    break;
-            }           
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+                mesh.lookAt(new Vector3(-newPos.x, -newPos.y, -newPos.z));
+                break;
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                mesh.lookAt(new Vector3(newPos.x, newPos.y, newPos.z));
+                break;
+            case Container3D.FACEFORWARD_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, 1));
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, -1));
+                break;
         }
+    }
 
-        private _sphericalMapping(source: Vector3)
-        {
-            let newPos = new Vector3(0, 0, this._radius);
+    private _sphericalMapping(source: Vector3) {
+        let newPos = new Vector3(0, 0, this._radius);
 
-            let xAngle = (source.y / this._radius);
-            let yAngle = -(source.x / this._radius);
+        let xAngle = (source.y / this._radius);
+        let yAngle = -(source.x / this._radius);
 
-            Matrix.RotationYawPitchRollToRef(yAngle, xAngle, 0, Tmp.Matrix[0]);
+        Matrix.RotationYawPitchRollToRef(yAngle, xAngle, 0, Tmp.Matrix[0]);
 
-            return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
-        }
+        return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
     }
 }

+ 87 - 88
gui/src/3D/controls/stackPanel3D.ts

@@ -1,109 +1,108 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container3D } from "./container3D";
+import { Tools, Matrix, Tmp, Vector3 } from "babylonjs";
+
+/**
+ * Class used to create a stack panel in 3D on XY plane
+ */
+export class StackPanel3D extends Container3D {
+    private _isVertical = false;
 
-module BABYLON.GUI {
     /**
-     * Class used to create a stack panel in 3D on XY plane
+     * Gets or sets a boolean indicating if the stack panel is vertical or horizontal (horizontal by default)
      */
-    export class StackPanel3D extends Container3D {
-        private _isVertical = false;
-
-        /**
-         * Gets or sets a boolean indicating if the stack panel is vertical or horizontal (horizontal by default)
-         */
-        public get isVertical(): boolean {
-            return this._isVertical;
+    public get isVertical(): boolean {
+        return this._isVertical;
+    }
+
+    public set isVertical(value: boolean) {
+        if (this._isVertical === value) {
+            return;
         }
 
-        public set isVertical(value: boolean) {
-            if (this._isVertical === value) {
-                return;
-            }
+        this._isVertical = value;
 
-            this._isVertical = value;
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }
+    /**
+     * Gets or sets the distance between elements
+     */
+    public margin = 0.1;
 
-        /**
-         * Gets or sets the distance between elements
-         */
-        public margin = 0.1;
-        
-        /**
-         * Creates new StackPanel
-         * @param isVertical 
-         */
-        public constructor(isVertical = false) {
-            super();
-
-            this._isVertical = isVertical;
-        }
+    /**
+     * Creates new StackPanel
+     * @param isVertical 
+     */
+    public constructor(isVertical = false) {
+        super();
+
+        this._isVertical = isVertical;
+    }
 
-        protected _arrangeChildren() {
-            let width = 0;
-            let height = 0;
-            let controlCount = 0;
-            let extendSizes = [];
-
-            let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
-
-            // Measure
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }
-
-                controlCount++;
-                child.mesh.computeWorldMatrix(true);
-                child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
-
-                let boundingBox = child.mesh.getBoundingInfo().boundingBox;
-                let extendSize = Vector3.TransformNormal(boundingBox.extendSize, Tmp.Matrix[0]);
-                extendSizes.push(extendSize);
-
-                if (this._isVertical) {
-                    height += extendSize.y;
-                } else {
-                    width += extendSize.x;
-                }
+    protected _arrangeChildren() {
+        let width = 0;
+        let height = 0;
+        let controlCount = 0;
+        let extendSizes = [];
+
+        let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
+
+        // Measure
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
 
+            controlCount++;
+            child.mesh.computeWorldMatrix(true);
+            child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
+
+            let boundingBox = child.mesh.getBoundingInfo().boundingBox;
+            let extendSize = Vector3.TransformNormal(boundingBox.extendSize, Tmp.Matrix[0]);
+            extendSizes.push(extendSize);
+
             if (this._isVertical) {
-                height += (controlCount - 1) * this.margin / 2;
+                height += extendSize.y;
             } else {
-                width += (controlCount - 1) * this.margin / 2;
+                width += extendSize.x;
+            }
+        }
+
+        if (this._isVertical) {
+            height += (controlCount - 1) * this.margin / 2;
+        } else {
+            width += (controlCount - 1) * this.margin / 2;
+        }
+
+        // Arrange
+        let offset: number;
+        if (this._isVertical) {
+            offset = -height;
+        } else {
+            offset = -width;
+        }
+
+        let index = 0;
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
+            controlCount--;
+            let extendSize = extendSizes[index++];
 
-            // Arrange
-            let offset: number;
             if (this._isVertical) {
-                offset = -height;
+                child.position.y = offset + extendSize.y;
+                child.position.x = 0;
+                offset += extendSize.y * 2;
             } else {
-                offset = -width;
+                child.position.x = offset + extendSize.x;
+                child.position.y = 0;
+                offset += extendSize.x * 2;
             }
 
-            let index = 0;
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }                
-                controlCount--;
-                let extendSize = extendSizes[index++];
-
-                if (this._isVertical) {
-                    child.position.y = offset + extendSize.y;
-                    child.position.x = 0;
-                    offset += extendSize.y * 2;
-                } else {
-                    child.position.x = offset + extendSize.x;
-                    child.position.y = 0;
-                    offset += extendSize.x * 2;
-                }
-
-                offset += (controlCount > 0 ? this.margin : 0)
-            }
+            offset += (controlCount > 0 ? this.margin : 0)
         }
     }
-}
+}

+ 150 - 156
gui/src/3D/controls/volumeBasedPanel.ts

@@ -1,190 +1,184 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control3D } from "./control3D";
+import { Vector3, Tools, Matrix, Tmp } from "babylonjs";
+import { Container3D } from "./container3D";
+
+/**
+ * Abstract class used to create a container panel deployed on the surface of a volume
+ */
+export abstract class VolumeBasedPanel extends Container3D {
+    private _columns = 10;
+    private _rows = 0;
+    private _rowThenColum = true;
+
+    private _orientation = Container3D.FACEORIGIN_ORIENTATION;
+
+    protected _cellWidth: number;
+    protected _cellHeight: number;
+
+    /**
+     * Gets or sets the distance between elements
+     */
+    public margin = 0;
 
-module BABYLON.GUI {
     /**
-     * Abstract class used to create a container panel deployed on the surface of a volume
+     * Gets or sets the orientation to apply to all controls (Container3D.FaceOriginReversedOrientation by default)
+    * | Value | Type                                | Description |
+    * | ----- | ----------------------------------- | ----------- |
+    * | 0     | UNSET_ORIENTATION                   |  Control rotation will remain unchanged |
+    * | 1     | FACEORIGIN_ORIENTATION              |  Control will rotate to make it look at sphere central axis |
+    * | 2     | FACEORIGINREVERSED_ORIENTATION      |  Control will rotate to make it look back at sphere central axis |
+    * | 3     | FACEFORWARD_ORIENTATION             |  Control will rotate to look at z axis (0, 0, 1) |
+    * | 4     | FACEFORWARDREVERSED_ORIENTATION     |  Control will rotate to look at negative z axis (0, 0, -1) |
      */
-    export abstract class VolumeBasedPanel extends Container3D {
-        private _columns = 10;
-        private _rows = 0;
-        private _rowThenColum = true;
-        
-        private _orientation = Container3D.FACEORIGIN_ORIENTATION;
-
-        protected _cellWidth: number;
-        protected _cellHeight: number;
-
-        /**
-         * Gets or sets the distance between elements
-         */
-        public margin = 0;        
-
-        /**
-         * Gets or sets the orientation to apply to all controls (BABYLON.Container3D.FaceOriginReversedOrientation by default)
-        * | Value | Type                                | Description |
-        * | ----- | ----------------------------------- | ----------- |
-        * | 0     | UNSET_ORIENTATION                   |  Control rotation will remain unchanged |
-        * | 1     | FACEORIGIN_ORIENTATION              |  Control will rotate to make it look at sphere central axis |
-        * | 2     | FACEORIGINREVERSED_ORIENTATION      |  Control will rotate to make it look back at sphere central axis |
-        * | 3     | FACEFORWARD_ORIENTATION             |  Control will rotate to look at z axis (0, 0, 1) |
-        * | 4     | FACEFORWARDREVERSED_ORIENTATION     |  Control will rotate to look at negative z axis (0, 0, -1) |
-         */
-        public get orientation(): number {
-            return this._orientation;
+    public get orientation(): number {
+        return this._orientation;
+    }
+
+    public set orientation(value: number) {
+        if (this._orientation === value) {
+            return;
         }
 
-        public set orientation(value: number) {
-            if (this._orientation === value) {
-                return;
-            }
+        this._orientation = value;
 
-            this._orientation = value;
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }             
+    /**
+     * Gets or sets the number of columns requested (10 by default). 
+     * The panel will automatically compute the number of rows based on number of child controls. 
+     */
+    public get columns(): number {
+        return this._columns;
+    }
 
-        /**
-         * Gets or sets the number of columns requested (10 by default). 
-         * The panel will automatically compute the number of rows based on number of child controls. 
-         */
-        public get columns(): int {
-            return this._columns;
+    public set columns(value: number) {
+        if (this._columns === value) {
+            return;
         }
 
-        public set columns(value: int) {
-            if (this._columns === value) {
-                return;
-            }
+        this._columns = value;
+        this._rowThenColum = true;
+
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-            this._columns = value;
-            this._rowThenColum = true;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }     
-        
-        /**
-         * Gets or sets a the number of rows requested. 
-         * The panel will automatically compute the number of columns based on number of child controls. 
-         */
-        public get rows(): int {
-            return this._rows;
+    /**
+     * Gets or sets a the number of rows requested. 
+     * The panel will automatically compute the number of columns based on number of child controls. 
+     */
+    public get rows(): number {
+        return this._rows;
+    }
+
+    public set rows(value: number) {
+        if (this._rows === value) {
+            return;
         }
 
-        public set rows(value: int) {
-            if (this._rows === value) {
-                return;
-            }
+        this._rows = value;
+        this._rowThenColum = false;
 
-            this._rows = value;
-            this._rowThenColum = false;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }           
-
-        /**
-         * Creates new SpherePanel
-         */
-        public constructor() {
-            super();
-        }        
-
-        protected _arrangeChildren() {
-            this._cellWidth = 0;
-            this._cellHeight = 0;
-            let rows = 0;
-            let columns = 0;
-            let controlCount = 0;
-
-            let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
-
-            // Measure
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
+
+    /**
+     * Creates new SpherePanel
+     */
+    public constructor() {
+        super();
+    }
 
-                controlCount++;
-                child.mesh.computeWorldMatrix(true);
-                child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
+    protected _arrangeChildren() {
+        this._cellWidth = 0;
+        this._cellHeight = 0;
+        let rows = 0;
+        let columns = 0;
+        let controlCount = 0;
 
-                let boundingBox = child.mesh.getBoundingInfo().boundingBox;
-                let extendSize = Vector3.TransformNormal(boundingBox.extendSize, Tmp.Matrix[0]);
+        let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
 
-                this._cellWidth = Math.max(this._cellWidth, extendSize.x * 2);
-                this._cellHeight = Math.max(this._cellHeight, extendSize.y * 2);
+        // Measure
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
 
-            this._cellWidth += this.margin * 2;
-            this._cellHeight += this.margin * 2;
+            controlCount++;
+            child.mesh.computeWorldMatrix(true);
+            child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
 
-            // Arrange
-            if (this._rowThenColum) {
-                columns = this._columns;
-                rows = Math.ceil(controlCount / this._columns);
-            } else {
-                rows = this._rows;
-                columns = Math.ceil(controlCount / this._rows);
-            }
+            let boundingBox = child.mesh.getBoundingInfo().boundingBox;
+            let extendSize = Vector3.TransformNormal(boundingBox.extendSize, Tmp.Matrix[0]);
+
+            this._cellWidth = Math.max(this._cellWidth, extendSize.x * 2);
+            this._cellHeight = Math.max(this._cellHeight, extendSize.y * 2);
+        }
+
+        this._cellWidth += this.margin * 2;
+        this._cellHeight += this.margin * 2;
 
-            let startOffsetX = (columns * 0.5) * this._cellWidth;
-            let startOffsetY = (rows * 0.5) * this._cellHeight;
-            let nodeGrid = [];
-            let cellCounter = 0;
-
-            if (this._rowThenColum) {
-                for (var r = 0; r < rows; r++)
-                {
-                    for (var c = 0; c < columns; c++)
-                    {
-                        nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
-                        cellCounter++;
-                        if (cellCounter > controlCount)
-                        {
-                            break;
-                        }
+        // Arrange
+        if (this._rowThenColum) {
+            columns = this._columns;
+            rows = Math.ceil(controlCount / this._columns);
+        } else {
+            rows = this._rows;
+            columns = Math.ceil(controlCount / this._rows);
+        }
+
+        let startOffsetX = (columns * 0.5) * this._cellWidth;
+        let startOffsetY = (rows * 0.5) * this._cellHeight;
+        let nodeGrid = [];
+        let cellCounter = 0;
+
+        if (this._rowThenColum) {
+            for (var r = 0; r < rows; r++) {
+                for (var c = 0; c < columns; c++) {
+                    nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
+                    cellCounter++;
+                    if (cellCounter > controlCount) {
+                        break;
                     }
                 }
-            } else {
-                for (var c = 0; c < columns; c++)
-                {
-                    for (var r = 0; r < rows; r++)
-                    {
-                        nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
-                        cellCounter++;
-                        if (cellCounter > controlCount)
-                        {
-                            break;
-                        }
+            }
+        } else {
+            for (var c = 0; c < columns; c++) {
+                for (var r = 0; r < rows; r++) {
+                    nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
+                    cellCounter++;
+                    if (cellCounter > controlCount) {
+                        break;
                     }
                 }
             }
+        }
 
-            cellCounter = 0;
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }                
-
-                this._mapGridNode(child, nodeGrid[cellCounter]);
-
-                cellCounter++;
+        cellCounter = 0;
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
 
-            this._finalProcessing();
+            this._mapGridNode(child, nodeGrid[cellCounter]);
+
+            cellCounter++;
         }
 
-        /** Child classes must implement this function to provide correct control positioning */
-        protected abstract _mapGridNode(control: Control3D, nodePosition: Vector3): void;
+        this._finalProcessing();
+    }
 
-        /** Child classes can implement this function to provide additional processing */
-        protected _finalProcessing() {
+    /** Child classes must implement this function to provide correct control positioning */
+    protected abstract _mapGridNode(control: Control3D, nodePosition: Vector3): void;
+
+    /** Child classes can implement this function to provide additional processing */
+    protected _finalProcessing() {
 
-        }
     }
-}
+}

+ 180 - 181
gui/src/3D/gui3DManager.ts

@@ -1,222 +1,221 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { IDisposable, Scene, Nullable, Observer, UtilityLayerRenderer, PointerInfo, Observable, Vector3, Material, AbstractMesh, Engine, HemisphericLight, PointerEventTypes } from "babylonjs";
+import { Container3D } from "./controls/container3D";
+import { Control3D } from "./controls/control3D";
+
+/**
+ * Class used to manage 3D user interface
+ * @see http://doc.babylonjs.com/how_to/gui3d
+ */
+export class GUI3DManager implements IDisposable {
+    private _scene: Scene;
+    private _sceneDisposeObserver: Nullable<Observer<Scene>>;
+    private _utilityLayer: Nullable<UtilityLayerRenderer>;
+    private _rootContainer: Container3D;
+    private _pointerObserver: Nullable<Observer<PointerInfo>>;
+    private _pointerOutObserver: Nullable<Observer<number>>;
+    /** @hidden */
+    public _lastPickedControl: Control3D;
+    /** @hidden */
+    public _lastControlOver: { [pointerId: number]: Control3D } = {};
+    /** @hidden */
+    public _lastControlDown: { [pointerId: number]: Control3D } = {};
 
+    /**
+     * Observable raised when the point picked by the pointer events changed
+     */
+    public onPickedPointChangedObservable = new Observable<Nullable<Vector3>>();
+
+    // Shared resources
+    /** @hidden */
+    public _sharedMaterials: { [key: string]: Material } = {};
+
+    /** Gets the hosting scene */
+    public get scene(): Scene {
+        return this._scene;
+    }
+
+    /** Gets associated utility layer */
+    public get utilityLayer(): Nullable<UtilityLayerRenderer> {
+        return this._utilityLayer;
+    }
 
-module BABYLON.GUI {
     /**
-     * Class used to manage 3D user interface
-     * @see http://doc.babylonjs.com/how_to/gui3d
+     * Creates a new GUI3DManager
+     * @param scene 
      */
-    export class GUI3DManager implements BABYLON.IDisposable {
-        private _scene: Scene;
-        private _sceneDisposeObserver: Nullable<Observer<Scene>>;
-        private _utilityLayer: Nullable<UtilityLayerRenderer>;
-        private _rootContainer: Container3D;
-        private _pointerObserver: Nullable<Observer<PointerInfo>>;
-        private _pointerOutObserver: Nullable<Observer<number>>;
-        /** @hidden */
-        public _lastPickedControl: Control3D;
-        /** @hidden */
-        public _lastControlOver: {[pointerId:number]: Control3D} = {};
-        /** @hidden */
-        public _lastControlDown: {[pointerId:number]: Control3D} = {};      
-
-        /**
-         * Observable raised when the point picked by the pointer events changed
-         */
-        public onPickedPointChangedObservable = new Observable<Nullable<Vector3>>();
-
-        // Shared resources
-        /** @hidden */
-        public _sharedMaterials: {[key:string]: Material} = {};     
-
-        /** Gets the hosting scene */
-        public get scene(): Scene {
-            return this._scene;
+    public constructor(scene?: Scene) {
+        this._scene = scene || Engine.LastCreatedScene!;
+        this._sceneDisposeObserver = this._scene.onDisposeObservable.add(() => {
+            this._sceneDisposeObserver = null;
+            this._utilityLayer = null;
+            this.dispose();
+        })
+
+        this._utilityLayer = new UtilityLayerRenderer(this._scene);
+        this._utilityLayer.onlyCheckPointerDownEvents = false;
+        this._utilityLayer.mainSceneTrackerPredicate = (mesh: Nullable<AbstractMesh>) => {
+            return mesh && mesh.metadata && mesh.metadata._node;
         }
 
-        /** Gets associated utility layer */
-        public get utilityLayer(): Nullable<UtilityLayerRenderer> {
-            return this._utilityLayer;
-        }
+        // Root
+        this._rootContainer = new Container3D("RootContainer");
+        this._rootContainer._host = this;
+        let utilityLayerScene = this._utilityLayer.utilityLayerScene;
 
-        /**
-         * Creates a new GUI3DManager
-         * @param scene 
-         */
-        public constructor(scene?: Scene) {
-            this._scene = scene || Engine.LastCreatedScene!;
-            this._sceneDisposeObserver = this._scene.onDisposeObservable.add(() => {
-                this._sceneDisposeObserver = null;
-                this._utilityLayer = null;
-                this.dispose();
-            })
-
-            this._utilityLayer = new UtilityLayerRenderer(this._scene);
-            this._utilityLayer.onlyCheckPointerDownEvents = false;
-            this._utilityLayer.mainSceneTrackerPredicate = (mesh: Nullable<AbstractMesh>) => {
-                return mesh && mesh.metadata && mesh.metadata._node;
-            }
+        // Events
+        this._pointerOutObserver = this._utilityLayer.onPointerOutObservable.add((pointerId) => {
+            this._handlePointerOut(pointerId, true);
+        });
 
-            // Root
-            this._rootContainer = new Container3D("RootContainer");
-            this._rootContainer._host = this;
-            let utilityLayerScene = this._utilityLayer.utilityLayerScene;
-            
-            // Events
-            this._pointerOutObserver = this._utilityLayer.onPointerOutObservable.add((pointerId) => {
-                this._handlePointerOut(pointerId, true);
-            });
-
-            this._pointerObserver = utilityLayerScene.onPointerObservable.add((pi, state) => {
-                this._doPicking(pi);
-            });
-
-            // Scene
-            this._utilityLayer.utilityLayerScene.autoClear = false;
-            this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
-            new BABYLON.HemisphericLight("hemi", Vector3.Up(), this._utilityLayer.utilityLayerScene);
-        }
+        this._pointerObserver = utilityLayerScene.onPointerObservable.add((pi, state) => {
+            this._doPicking(pi);
+        });
 
-        private _handlePointerOut(pointerId: number, isPointerUp: boolean) {
-            var previousControlOver = this._lastControlOver[pointerId];
-            if (previousControlOver) {
-                previousControlOver._onPointerOut(previousControlOver);
-                delete this._lastControlOver[pointerId];
-            }               
-            
-            if (isPointerUp) {
-                if (this._lastControlDown[pointerId]) {
-                    this._lastControlDown[pointerId].forcePointerUp();
-                    delete this._lastControlDown[pointerId];
-                }
-            }        
-            
-            this.onPickedPointChangedObservable.notifyObservers(null);
+        // Scene
+        this._utilityLayer.utilityLayerScene.autoClear = false;
+        this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
+        new HemisphericLight("hemi", Vector3.Up(), this._utilityLayer.utilityLayerScene);
+    }
+
+    private _handlePointerOut(pointerId: number, isPointerUp: boolean) {
+        var previousControlOver = this._lastControlOver[pointerId];
+        if (previousControlOver) {
+            previousControlOver._onPointerOut(previousControlOver);
+            delete this._lastControlOver[pointerId];
         }
 
-        private _doPicking(pi: PointerInfo): boolean {
-            if (!this._utilityLayer || !this._utilityLayer.utilityLayerScene.activeCamera) {
-                return false;                
+        if (isPointerUp) {
+            if (this._lastControlDown[pointerId]) {
+                this._lastControlDown[pointerId].forcePointerUp();
+                delete this._lastControlDown[pointerId];
             }
+        }
 
-            let pointerEvent = <PointerEvent>(pi.event);
+        this.onPickedPointChangedObservable.notifyObservers(null);
+    }
 
-            let pointerId = pointerEvent.pointerId || 0;
-            let buttonIndex = pointerEvent.button;
-            
-            let pickingInfo = pi.pickInfo;
-            if (!pickingInfo || !pickingInfo.hit) {
-                this._handlePointerOut(pointerId, pi.type === BABYLON.PointerEventTypes.POINTERUP);
-                return false;
-            }
+    private _doPicking(pi: PointerInfo): boolean {
+        if (!this._utilityLayer || !this._utilityLayer.utilityLayerScene.activeCamera) {
+            return false;
+        }
 
-            let control = <Control3D>(pickingInfo.pickedMesh!.metadata);
-            if (pickingInfo.pickedPoint) {
-                this.onPickedPointChangedObservable.notifyObservers(pickingInfo.pickedPoint);
-            }
+        let pointerEvent = <PointerEvent>(pi.event);
 
-            if (!control._processObservables(pi.type, pickingInfo.pickedPoint!, pointerId, buttonIndex)) {
+        let pointerId = pointerEvent.pointerId || 0;
+        let buttonIndex = pointerEvent.button;
 
-                if (pi.type === BABYLON.PointerEventTypes.POINTERMOVE) {
-                    if (this._lastControlOver[pointerId]) {
-                        this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId]);
-                    }
+        let pickingInfo = pi.pickInfo;
+        if (!pickingInfo || !pickingInfo.hit) {
+            this._handlePointerOut(pointerId, pi.type === PointerEventTypes.POINTERUP);
+            return false;
+        }
 
-                    delete this._lastControlOver[pointerId];
-                }
-            }
+        let control = <Control3D>(pickingInfo.pickedMesh!.metadata);
+        if (pickingInfo.pickedPoint) {
+            this.onPickedPointChangedObservable.notifyObservers(pickingInfo.pickedPoint);
+        }
 
-            if (pi.type === BABYLON.PointerEventTypes.POINTERUP) {
-                if (this._lastControlDown[pointerEvent.pointerId]) {
-                    this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
-                    delete this._lastControlDown[pointerEvent.pointerId];
-                }
+        if (!control._processObservables(pi.type, pickingInfo.pickedPoint!, pointerId, buttonIndex)) {
 
-                if (pointerEvent.pointerType === "touch") {
-                    this._handlePointerOut(pointerId, false);
+            if (pi.type === PointerEventTypes.POINTERMOVE) {
+                if (this._lastControlOver[pointerId]) {
+                    this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId]);
                 }
-            }
 
-            return true;
+                delete this._lastControlOver[pointerId];
+            }
         }
 
-        /**
-         * Gets the root container
-         */
-        public get rootContainer(): Container3D {
-            return this._rootContainer;
-        }
+        if (pi.type === PointerEventTypes.POINTERUP) {
+            if (this._lastControlDown[pointerEvent.pointerId]) {
+                this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
+                delete this._lastControlDown[pointerEvent.pointerId];
+            }
 
-        /**
-         * Gets a boolean indicating if the given control is in the root child list
-         * @param control defines the control to check
-         * @returns true if the control is in the root child list
-         */
-        public containsControl(control: Control3D): boolean {
-            return this._rootContainer.containsControl(control);
+            if (pointerEvent.pointerType === "touch") {
+                this._handlePointerOut(pointerId, false);
+            }
         }
 
-        /**
-         * Adds a control to the root child list
-         * @param control defines the control to add
-         * @returns the current manager
-         */
-        public addControl(control: Control3D): GUI3DManager {
-           this._rootContainer.addControl(control);
-           return this;
-        }
+        return true;
+    }
 
-        /**
-         * Removes a control from the root child list
-         * @param control defines the control to remove
-         * @returns the current container
-         */
-        public removeControl(control: Control3D): GUI3DManager {
-            this._rootContainer.removeControl(control);
-            return this;
-        }        
-
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            this._rootContainer.dispose();
-
-            for (var materialName in this._sharedMaterials) {
-                if (!this._sharedMaterials.hasOwnProperty(materialName)) {
-                    continue;
-                }
+    /**
+     * Gets the root container
+     */
+    public get rootContainer(): Container3D {
+        return this._rootContainer;
+    }
 
-                this._sharedMaterials[materialName].dispose();
-            }
+    /**
+     * Gets a boolean indicating if the given control is in the root child list
+     * @param control defines the control to check
+     * @returns true if the control is in the root child list
+     */
+    public containsControl(control: Control3D): boolean {
+        return this._rootContainer.containsControl(control);
+    }
+
+    /**
+     * Adds a control to the root child list
+     * @param control defines the control to add
+     * @returns the current manager
+     */
+    public addControl(control: Control3D): GUI3DManager {
+        this._rootContainer.addControl(control);
+        return this;
+    }
+
+    /**
+     * Removes a control from the root child list
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control3D): GUI3DManager {
+        this._rootContainer.removeControl(control);
+        return this;
+    }
 
-            this._sharedMaterials = {};
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        this._rootContainer.dispose();
 
-            if (this._pointerOutObserver && this._utilityLayer) {
-                this._utilityLayer.onPointerOutObservable.remove(this._pointerOutObserver);
-                this._pointerOutObserver = null;
+        for (var materialName in this._sharedMaterials) {
+            if (!this._sharedMaterials.hasOwnProperty(materialName)) {
+                continue;
             }
 
-            this.onPickedPointChangedObservable.clear();
+            this._sharedMaterials[materialName].dispose();
+        }
 
-            let utilityLayerScene = this._utilityLayer ? this._utilityLayer.utilityLayerScene : null;
+        this._sharedMaterials = {};
 
-            if (utilityLayerScene) {
-                if (this._pointerObserver) {
-                    utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
-                    this._pointerObserver = null;
-                }
+        if (this._pointerOutObserver && this._utilityLayer) {
+            this._utilityLayer.onPointerOutObservable.remove(this._pointerOutObserver);
+            this._pointerOutObserver = null;
+        }
+
+        this.onPickedPointChangedObservable.clear();
+
+        let utilityLayerScene = this._utilityLayer ? this._utilityLayer.utilityLayerScene : null;
+
+        if (utilityLayerScene) {
+            if (this._pointerObserver) {
+                utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
+                this._pointerObserver = null;
             }
-            if (this._scene) {
-                 if (this._sceneDisposeObserver) {
-                    this._scene.onDisposeObservable.remove(this._sceneDisposeObserver);
-                    this._sceneDisposeObserver = null;
-                }                
+        }
+        if (this._scene) {
+            if (this._sceneDisposeObserver) {
+                this._scene.onDisposeObservable.remove(this._sceneDisposeObserver);
+                this._sceneDisposeObserver = null;
             }
+        }
 
-            if (this._utilityLayer) {
-                this._utilityLayer.dispose();
-            }
+        if (this._utilityLayer) {
+            this._utilityLayer.dispose();
         }
     }
 }

+ 5 - 0
gui/src/3D/index.ts

@@ -0,0 +1,5 @@
+export * from "./controls";
+export * from "./materials";
+
+export * from "./gui3DManager";
+export * from "./vector3WithInfo";

+ 232 - 235
gui/src/3D/materials/fluentMaterial.ts

@@ -1,279 +1,276 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-
-    /** @hidden */
-    export class FluentMaterialDefines extends MaterialDefines {
-        public INNERGLOW = false;
-        public BORDER = false;
-        public HOVERLIGHT = false;
-    
-        constructor() {
-            super();
-            this.rebuild();
-        }
+import { MaterialDefines, PushMaterial, serialize, expandToProperty, serializeAsColor3, Color3, serializeAsColor4, Color4, serializeAsVector3, Vector3, Scene, Nullable, BaseTexture, AbstractMesh, SubMesh, VertexBuffer, MaterialHelper, EffectCreationOptions, Matrix, Mesh, Tmp, SerializationHelper } from "babylonjs";
+
+/** @hidden */
+export class FluentMaterialDefines extends MaterialDefines {
+    public INNERGLOW = false;
+    public BORDER = false;
+    public HOVERLIGHT = false;
+
+    constructor() {
+        super();
+        this.rebuild();
     }
+}
+
+/**
+ * Class used to render controls with fluent desgin
+ */
+export class FluentMaterial extends PushMaterial {
 
     /**
-     * Class used to render controls with fluent desgin
+     * Gets or sets inner glow intensity. A value of 0 means no glow (default is 0.5)
      */
-    export class FluentMaterial extends PushMaterial {    
-
-        /**
-         * Gets or sets inner glow intensity. A value of 0 means no glow (default is 0.5)
-         */
-        @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public innerGlowColorIntensity = 0.5;
-
-        /**
-         * Gets or sets the inner glow color (white by default)
-         */
-        @serializeAsColor3()
-        public innerGlowColor = new Color3(1.0, 1.0, 1.0);
-
-        /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        @serialize()
-        public alpha = 1.0;        
-
-        /**
-         * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
-         */
-        @serializeAsColor3()
-        public albedoColor = new Color3(0.3, 0.35, 0.4);
-
-        /**
-         * Gets or sets a boolean indicating if borders must be rendered (default is false)
-         */
-        @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public renderBorders = false;        
-
-        /**
-         * Gets or sets border width (default is 0.5)
-         */
-        @serialize()
-        public borderWidth = 0.5;      
-        
-        /**
-         * Gets or sets a value indicating the smoothing value applied to border edges (0.02 by default)
-         */
-        @serialize()
-        public edgeSmoothingValue = 0.02;
-        
-        /**
-         * Gets or sets the minimum value that can be applied to border width (default is 0.1)
-         */
-        @serialize()
-        public borderMinValue = 0.1;      
-        
-        /**
-         * Gets or sets a boolean indicating if hover light must be rendered (default is false)
-         */
-        @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public renderHoverLight = false;         
-        
-        /**
-         * Gets or sets the radius used to render the hover light (default is 0.15)
-         */
-        @serialize()
-        public hoverRadius = 1.0;            
-        
-        /**
-         * Gets or sets the color used to render the hover light (default is Color4(0.3, 0.3, 0.3, 1.0))
-         */
-        @serializeAsColor4()
-        public hoverColor = new Color4(0.3, 0.3, 0.3, 1.0);           
-        
-        /**
-         * Gets or sets the hover light position in world space (default is Vector3.Zero())
-         */
-        @serializeAsVector3()
-        public hoverPosition = Vector3.Zero();             
-        
-        /**
-         * Creates a new Fluent material
-         * @param name defines the name of the material
-         * @param scene defines the hosting scene
-         */
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public innerGlowColorIntensity = 0.5;
 
-        public needAlphaBlending(): boolean {
-            return this.alpha !== 1.0;
-        }
+    /**
+     * Gets or sets the inner glow color (white by default)
+     */
+    @serializeAsColor3()
+    public innerGlowColor = new Color3(1.0, 1.0, 1.0);
 
-        public needAlphaTesting(): boolean {
-            return false;
-        }
+    /**
+     * Gets or sets alpha value (default is 1.0)
+     */
+    @serialize()
+    public alpha = 1.0;
 
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        } 
-        
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
+    /**
+     * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
+     */
+    @serializeAsColor3()
+    public albedoColor = new Color3(0.3, 0.35, 0.4);
 
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new FluentMaterialDefines();
-            }
+    /**
+     * Gets or sets a boolean indicating if borders must be rendered (default is false)
+     */
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public renderBorders = false;
 
-            var scene = this.getScene();
-            var defines = <FluentMaterialDefines>subMesh._materialDefines;
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (defines._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }            
-
-            if (defines._areTexturesDirty) {
-                defines.INNERGLOW = this.innerGlowColorIntensity > 0;
-                defines.BORDER = this.renderBorders;
-                defines.HOVERLIGHT = this.renderHoverLight;
-            }
+    /**
+     * Gets or sets border width (default is 0.5)
+     */
+    @serialize()
+    public borderWidth = 0.5;
+
+    /**
+     * Gets or sets a value indicating the smoothing value applied to border edges (0.02 by default)
+     */
+    @serialize()
+    public edgeSmoothingValue = 0.02;
 
-            var engine = scene.getEngine();
-            // Get correct effect      
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
+    /**
+     * Gets or sets the minimum value that can be applied to border width (default is 0.1)
+     */
+    @serialize()
+    public borderMinValue = 0.1;
 
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-                attribs.push(VertexBuffer.NormalKind);
-                attribs.push(VertexBuffer.UVKind);
+    /**
+     * Gets or sets a boolean indicating if hover light must be rendered (default is false)
+     */
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public renderHoverLight = false;
 
-                var shaderName = "fluent";
+    /**
+     * Gets or sets the radius used to render the hover light (default is 0.15)
+     */
+    @serialize()
+    public hoverRadius = 1.0;
+
+    /**
+     * Gets or sets the color used to render the hover light (default is Color4(0.3, 0.3, 0.3, 1.0))
+     */
+    @serializeAsColor4()
+    public hoverColor = new Color4(0.3, 0.3, 0.3, 1.0);
 
-                var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue",
-                                "hoverColor", "hoverPosition", "hoverRadius"
-                ];
+    /**
+     * Gets or sets the hover light position in world space (default is Vector3.Zero())
+     */
+    @serializeAsVector3()
+    public hoverPosition = Vector3.Zero();
 
-                var samplers = new Array<String>();
-                var uniformBuffers = new Array<string>();
+    /**
+     * Creates a new Fluent material
+     * @param name defines the name of the material
+     * @param scene defines the hosting scene
+     */
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
 
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: 4
-                });            
-
-                var join = defines.toString();
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: null,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: 4 }
-                    }, engine));            
-                
-            }
+    public needAlphaBlending(): boolean {
+        return this.alpha !== 1.0;
+    }
 
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
             }
+        }
 
-            defines._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new FluentMaterialDefines();
+        }
 
-            return true;
+        var scene = this.getScene();
+        var defines = <FluentMaterialDefines>subMesh._materialDefines;
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (defines._renderId === scene.getRenderId()) {
+                return true;
+            }
         }
 
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
+        if (defines._areTexturesDirty) {
+            defines.INNERGLOW = this.innerGlowColorIntensity > 0;
+            defines.BORDER = this.renderBorders;
+            defines.HOVERLIGHT = this.renderHoverLight;
+        }
 
-            var defines = <FluentMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }            
+        var engine = scene.getEngine();
+        // Get correct effect      
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+            attribs.push(VertexBuffer.NormalKind);
+            attribs.push(VertexBuffer.UVKind);
+
+            var shaderName = "fluent";
+
+            var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue",
+                "hoverColor", "hoverPosition", "hoverRadius"
+            ];
+
+            var samplers = new Array<String>();
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: 4
+            });
+
+            var join = defines.toString();
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: null,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: 4 }
+                }, engine));
 
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
+        }
 
-            // Matrices        
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
 
+        defines._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
 
-            if (this._mustRebind(scene, effect)) {   
-                this._activeEffect.setColor4("albedoColor", this.albedoColor, this.alpha);
+        return true;
+    }
 
-                if (defines.INNERGLOW) {
-                    this._activeEffect.setColor4("innerGlowColor", this.innerGlowColor, this.innerGlowColorIntensity);
-                }
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
 
-                if (defines.BORDER) {
-                    this._activeEffect.setFloat("borderWidth", this.borderWidth);
-                    this._activeEffect.setFloat("edgeSmoothingValue", this.edgeSmoothingValue);
-                    this._activeEffect.setFloat("borderMinValue", this.borderMinValue);
+        var defines = <FluentMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
 
-                    mesh.getBoundingInfo().boundingBox.extendSize.multiplyToRef(mesh.scaling, Tmp.Vector3[0]);
-                    this._activeEffect.setVector3("scaleFactor", Tmp.Vector3[0]);
-                }
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
 
-                if (defines.HOVERLIGHT) {
-                    this._activeEffect.setDirectColor4("hoverColor", this.hoverColor);
-                    this._activeEffect.setFloat("hoverRadius", this.hoverRadius);
-                    this._activeEffect.setVector3("hoverPosition", this.hoverPosition);
-                }
-            }
+        // Matrices        
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
-            this._afterBind(mesh, this._activeEffect);
-        }    
 
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
+        if (this._mustRebind(scene, effect)) {
+            this._activeEffect.setColor4("albedoColor", this.albedoColor, this.alpha);
 
-            return activeTextures;
-        }        
+            if (defines.INNERGLOW) {
+                this._activeEffect.setColor4("innerGlowColor", this.innerGlowColor, this.innerGlowColorIntensity);
+            }
 
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
+            if (defines.BORDER) {
+                this._activeEffect.setFloat("borderWidth", this.borderWidth);
+                this._activeEffect.setFloat("edgeSmoothingValue", this.edgeSmoothingValue);
+                this._activeEffect.setFloat("borderMinValue", this.borderMinValue);
+
+                mesh.getBoundingInfo().boundingBox.extendSize.multiplyToRef(mesh.scaling, Tmp.Vector3[0]);
+                this._activeEffect.setVector3("scaleFactor", Tmp.Vector3[0]);
             }
 
-            return false;
-        }        
-        
-        public dispose(forceDisposeEffect?: boolean): void {
-            super.dispose(forceDisposeEffect);
+            if (defines.HOVERLIGHT) {
+                this._activeEffect.setDirectColor4("hoverColor", this.hoverColor);
+                this._activeEffect.setFloat("hoverRadius", this.hoverRadius);
+                this._activeEffect.setVector3("hoverPosition", this.hoverPosition);
+            }
         }
 
-        public clone(name: string): FluentMaterial {
-            return SerializationHelper.Clone(() => new FluentMaterial(name, this.getScene()), this);
-        }
+        this._afterBind(mesh, this._activeEffect);
+    }
 
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.GUI.FluentMaterial";
-            return serializationObject;
-        }
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
 
-        public getClassName(): string {
-            return "FluentMaterial";
-        }
+        return activeTextures;
+    }
 
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): FluentMaterial {
-            return SerializationHelper.Parse(() => new FluentMaterial(source.name, scene), source, scene, rootUrl);
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
         }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): FluentMaterial {
+        return SerializationHelper.Clone(() => new FluentMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.GUI.FluentMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "FluentMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): FluentMaterial {
+        return SerializationHelper.Parse(() => new FluentMaterial(source.name, scene), source, scene, rootUrl);
     }
 }

+ 1 - 0
gui/src/3D/materials/index.ts

@@ -0,0 +1 @@
+export * from "./fluentMaterial";

+ 12 - 14
gui/src/3D/vector3WithInfo.ts

@@ -1,19 +1,17 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { Vector3 } from "babylonjs";
 
-module BABYLON.GUI {
+/**
+ * Class used to transport Vector3 information for pointer events
+ */
+export class Vector3WithInfo extends Vector3 {
     /**
-     * Class used to transport Vector3 information for pointer events
+     * Creates a new Vector3WithInfo
+     * @param source defines the vector3 data to transport
+     * @param buttonIndex defines the current mouse button index
      */
-    export class Vector3WithInfo extends Vector3 {        
-        /**
-         * Creates a new Vector3WithInfo
-         * @param source defines the vector3 data to transport
-         * @param buttonIndex defines the current mouse button index
-         */
-        public constructor(source: Vector3, 
-            /** defines the current mouse button index */
-            public buttonIndex: number = 0) {
-            super(source.x, source.y, source.z);
-        }
+    public constructor(source: Vector3,
+        /** defines the current mouse button index */
+        public buttonIndex: number = 0) {
+        super(source.x, source.y, source.z);
     }
 }

+ 2 - 0
gui/src/index.ts

@@ -0,0 +1,2 @@
+export * from "./2D";
+export * from "./3D";

+ 0 - 12
gui/src/tsconfig.json

@@ -1,12 +0,0 @@
-{
-  "compilerOptions": {
-    "experimentalDecorators": true,
-    "module": "commonjs",
-    "target": "es5",
-    "noImplicitAny": true,
-    "noImplicitReturns": true,
-    "noImplicitThis": true,
-    "noUnusedLocals": true,    
-    "strictNullChecks": true    
-  }
-}

+ 31 - 0
gui/tsconfig.json

@@ -0,0 +1,31 @@
+{
+    "compilerOptions": {
+        "experimentalDecorators": true,
+        "module": "commonjs",
+        "target": "es5",
+        "noImplicitAny": true,
+        "noImplicitReturns": true,
+        "noImplicitThis": true,
+        "noUnusedLocals": true,
+        "strictNullChecks": true,
+        "declaration": true,
+        "sourceMap": true,
+        "lib": [
+            "es5",
+            "dom",
+            "es2015.promise",
+            "es2015.collection",
+            "es2015.iterable"
+        ],
+        "skipDefaultLibCheck": true,
+        "skipLibCheck": true,
+        "baseUrl": "./src/",
+        "rootDir": "./",
+        "paths": {
+            "babylonjs": [
+                "../../dist/preview release/babylon.d.ts"
+            ]
+        },
+        "outDir": "./dist/build"
+    }
+}

+ 42 - 0
gui/webpack.config.js

@@ -0,0 +1,42 @@
+const path = require('path');
+const webpack = require('webpack');
+
+module.exports = {
+    entry: {
+        'babylonjs-gui': './src/index.ts',
+    },
+    output: {
+        path: path.resolve(__dirname, 'dist'),
+        filename: '[name].js',
+        libraryTarget: 'umd',
+        library: 'BABYLON.GUI',
+        umdNamedDefine: true,
+        devtoolModuleFilenameTemplate: '[relative-resource-path]'
+    },
+    resolve: {
+        extensions: [".js", '.ts'],
+        /*alias: {
+            "babylonjs": __dirname + '/../dist/preview release/babylon.max.js'
+        }*/
+    },
+    externals: {
+        babylonjs: true
+    },
+    devtool: 'source-map',
+    plugins: [
+        new webpack.WatchIgnorePlugin([
+            /\.d\.ts$/
+        ])
+    ],
+    module: {
+        rules: [{ test: /\.tsx?$/, loader: "ts-loader", exclude: /node_modules/ }]
+    },
+    mode: "development",
+    devServer: {
+        contentBase: path.join(__dirname, "dist"),
+        compress: false,
+        //open: true,
+        port: 9000
+    }
+}
+//]