Browse Source

Merge pull request #4738 from RaananW/gui-module

GUI and Inspector moving to es module-style
David Catuhe 7 years ago
parent
commit
088687aa17
100 changed files with 10877 additions and 10330 deletions
  1. 6 0
      .gitignore
  2. 1 1
      .vscode/tasks.json
  3. 421 419
      Playground/debug.html
  4. 5 1
      Playground/index-local.html
  5. 10 9
      Playground/index.html
  6. 31 24
      Tools/DevLoader/BabylonLoader.js
  7. 93 151
      Tools/Gulp/config.json
  8. 94 33
      Tools/Gulp/gulpfile.js
  9. 2 1
      Tools/Gulp/package.json
  10. 44 19
      Tools/Gulp/processViewerDeclaration.js
  11. 6 3
      Tools/Publisher/index.js
  12. 139 0
      Tools/WebpackShaderLoader/index.js
  13. 6 4
      Viewer/package.json
  14. 2 1
      Viewer/tests/unit/tsconfig.json
  15. 4 2
      Viewer/tests/unit/webpack.config.js
  16. 1 1
      Viewer/tsconfig-gulp.json
  17. 2 2
      Viewer/tsconfig.json
  18. 4 2
      Viewer/webpack.assets.config.js
  19. 4 3
      Viewer/webpack.config.js
  20. 9 10
      Viewer/webpack.gulp.config.js
  21. 1 2
      dist/preview release/gui/package.json
  22. 3 0
      dist/preview release/inspector/package.json
  23. 1 0
      dist/preview release/what's new.md
  24. 41 0
      gui/package.json
  25. 3 3
      gui/readme.md
  26. 587 589
      gui/src/2D/advancedDynamicTexture.ts
  27. 182 180
      gui/src/2D/controls/button.ts
  28. 118 118
      gui/src/2D/controls/checkbox.ts
  29. 354 356
      gui/src/2D/controls/colorpicker.ts
  30. 261 260
      gui/src/2D/controls/container.ts
  31. 1135 1159
      gui/src/2D/controls/control.ts
  32. 71 71
      gui/src/2D/controls/ellipse.ts
  33. 277 276
      gui/src/2D/controls/grid.ts
  34. 279 279
      gui/src/2D/controls/image.ts
  35. 19 0
      gui/src/2D/controls/index.ts
  36. 10 12
      gui/src/2D/controls/inputPassword.ts
  37. 426 424
      gui/src/2D/controls/inputText.ts
  38. 216 215
      gui/src/2D/controls/line.ts
  39. 187 186
      gui/src/2D/controls/multiLine.ts
  40. 136 136
      gui/src/2D/controls/radioButton.ts
  41. 117 118
      gui/src/2D/controls/rectangle.ts
  42. 359 358
      gui/src/2D/controls/slider.ts
  43. 127 127
      gui/src/2D/controls/stackPanel.ts
  44. 53 0
      gui/src/2D/controls/statics.ts
  45. 329 328
      gui/src/2D/controls/textBlock.ts
  46. 199 196
      gui/src/2D/controls/virtualKeyboard.ts
  47. 8 0
      gui/src/2D/index.ts
  48. 184 186
      gui/src/2D/math2D.ts
  49. 57 60
      gui/src/2D/measure.ts
  50. 106 106
      gui/src/2D/multiLinePoint.ts
  51. 79 79
      gui/src/2D/style.ts
  52. 135 137
      gui/src/2D/valueAndUnit.ts
  53. 17 18
      gui/src/3D/controls/abstractButton3D.ts
  54. 135 134
      gui/src/3D/controls/button3D.ts
  55. 121 122
      gui/src/3D/controls/container3D.ts
  56. 346 345
      gui/src/3D/controls/control3D.ts
  57. 48 48
      gui/src/3D/controls/cylinderPanel.ts
  58. 210 206
      gui/src/3D/controls/holographicButton.ts
  59. 12 0
      gui/src/3D/controls/index.ts
  60. 50 51
      gui/src/3D/controls/meshButton3D.ts
  61. 29 28
      gui/src/3D/controls/planePanel.ts
  62. 91 95
      gui/src/3D/controls/scatterPanel.ts
  63. 49 49
      gui/src/3D/controls/spherePanel.ts
  64. 87 88
      gui/src/3D/controls/stackPanel3D.ts
  65. 155 161
      gui/src/3D/controls/volumeBasedPanel.ts
  66. 180 181
      gui/src/3D/gui3DManager.ts
  67. 5 0
      gui/src/3D/index.ts
  68. 237 235
      gui/src/3D/materials/fluentMaterial.ts
  69. 1 0
      gui/src/3D/materials/index.ts
  70. 12 0
      gui/src/3D/materials/shaders/fluent.ts
  71. 12 14
      gui/src/3D/vector3WithInfo.ts
  72. 2 0
      gui/src/index.ts
  73. 0 12
      gui/src/tsconfig.json
  74. 31 0
      gui/tsconfig.json
  75. 76 0
      gui/webpack.config.js
  76. 47 0
      inspector/package.json
  77. 375 368
      inspector/src/Inspector.ts
  78. 33 31
      inspector/src/adapters/Adapter.ts
  79. 53 49
      inspector/src/adapters/CameraAdapter.ts
  80. 49 43
      inspector/src/adapters/GUIAdapter.ts
  81. 49 46
      inspector/src/adapters/LightAdapter.ts
  82. 34 31
      inspector/src/adapters/MaterialAdapter.ts
  83. 102 94
      inspector/src/adapters/MeshAdapter.ts
  84. 48 43
      inspector/src/adapters/PhysicsImpostorAdapter.ts
  85. 44 39
      inspector/src/adapters/SoundAdapter.ts
  86. 33 30
      inspector/src/adapters/TextureAdapter.ts
  87. 9 0
      inspector/src/adapters/index.ts
  88. 186 182
      inspector/src/details/DetailPanel.ts
  89. 65 65
      inspector/src/details/Property.ts
  90. 491 483
      inspector/src/details/PropertyLine.ts
  91. 3 0
      inspector/src/details/index.ts
  92. 29 29
      inspector/src/gui/BasicElement.ts
  93. 31 30
      inspector/src/gui/ColorElement.ts
  94. 60 56
      inspector/src/gui/ColorPickerElement.ts
  95. 110 108
      inspector/src/gui/CubeTextureElement.ts
  96. 31 30
      inspector/src/gui/HDRCubeTextureElement.ts
  97. 76 73
      inspector/src/gui/SearchBar.ts
  98. 40 38
      inspector/src/gui/TextureElement.ts
  99. 29 28
      inspector/src/gui/Tooltip.ts
  100. 0 0
      inspector/src/gui/index.ts

+ 6 - 0
.gitignore

@@ -13,6 +13,7 @@ TestResults
 *.user
 *.sln.docstates
 *.map
+!dist/**/*.map
 
 # javascript files
 src/**/*.js
@@ -161,8 +162,12 @@ node_modules
 *.js.fx
 *.d.ts
 !dist/**/*.d.ts
+!dist/**/*.js.map
 !lib.d.ts
 
+# Split declaration file
+!ISplit.d.ts
+
 # local dev
 localDev/src/*
 /dist/preview release/babylon.custom.js
@@ -183,3 +188,4 @@ Viewer/tests/unit/src/**/*.js
 Viewer/tests/Lib/**/*.js
 Viewer/tests/commons/**/*.js
 .sass-cache/
+gui/dist/

+ 1 - 1
.vscode/tasks.json

@@ -66,7 +66,7 @@
                     "background": {
                         "activeOnStart": true,
                         "beginsPattern": "Project is running at",
-                        "endsPattern": "webpack: Compiled successfully."
+                        "endsPattern": "Compiled successfully."
                     }
                 }
             ],

+ 421 - 419
Playground/debug.html

@@ -1,510 +1,512 @@
 <!DOCTYPE html>
 <html>
 
-<head>
-    <title>Babylon.js Playground</title>
-    <meta charset='utf-8' />
-    <meta name="viewport" content="width=device-width, user-scalable=no">
-    <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
-    <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
-    <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
-    <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
-    <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
-    <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
-    <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
-    <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
-    <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
-    <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
-    <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
-    <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
-    <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
-    <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
-    <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
-    <meta name="msapplication-TileColor" content="#ffffff">
-    <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
-    <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
-    <meta name="theme-color" content="#ffffff">
-
-    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
-    <!--For canvas/code separator-->
-    <script src="js/libs/split.js"></script>
-
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
-    <!-- jszip -->
-    <script src="js/libs/jszip.min.js"></script>
-    <script src="js/libs/fileSaver.js"></script>
-    <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
-    <!-- Babylon.js -->
-    <script src="https://preview.babylonjs.com/cannon.js"></script>
-    <script src="https://preview.babylonjs.com/Oimo.js"></script>
-    <script src="https://preview.babylonjs.com/babylon.max.js"></script>
-    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
-
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
-
-    <script src="https://preview.babylonjs.com/gui/babylon.gui.js"></script>
-
-    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
-
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
-    <link href="css/index.css" rel="stylesheet" />
-
-</head>
-
-<body>
-    <div class="navbar navBar1600">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-            v3.0-alpha
-        </div>
-
-        <div class="category">
-            <div class="button run" id="runButton1600">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+    <head>
+        <title>Babylon.js Playground</title>
+        <meta charset='utf-8' />
+        <meta name="viewport" content="width=device-width, user-scalable=no">
+        <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
+        <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
+        <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
+        <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
+        <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
+        <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
+        <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
+        <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
+        <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
+        <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
+        <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
+        <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
+        <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
+        <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
+        <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
+        <meta name="msapplication-TileColor" content="#ffffff">
+        <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
+        <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
+        <meta name="theme-color" content="#ffffff">
+
+        <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+        <!--For canvas/code separator-->
+        <script src="js/libs/split.js"></script>
+
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
+        <!-- jszip -->
+        <script src="js/libs/jszip.min.js"></script>
+        <script src="js/libs/fileSaver.js"></script>
+
+        <!-- Babylon.js -->
+        <script src="https://preview.babylonjs.com/cannon.js"></script>
+        <script src="https://preview.babylonjs.com/Oimo.js"></script>
+        <script src="https://preview.babylonjs.com/babylon.max.js"></script>
+        <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
+
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
+
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.js"></script>
+
+        <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
+
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
+        <link href="css/index.css" rel="stylesheet" />
+
+        <!-- Monaco -->
+        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
+    </head>
+
+    <body>
+        <div class="navbar navBar1600">
+            <div class="title">
+                Babylon.js Playground
+            </div>
+            <div class="version" id="mainTitle">
+                v3.0-alpha
+            </div>
+
+            <div class="category">
+                <div class="button run" id="runButton1600">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button" id="newButton1600">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1600">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="newButton1600">New
+                    <i class="fa fa-file" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="clearButton1600">Clear
+                    <i class="fa fa-trash" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
-        <div class="category">
-            <div class="button" id="saveButton1600">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1600">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="saveButton1600">Save
+                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="zipButton1600">Zip
+                    <i class="fa fa-download" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1600">Dark</div>
-                            <div class="option" id="lightTheme1600">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme1600">Dark</div>
+                                <div class="option" id="lightTheme1600">Light</div>
+                            </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1600">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize1600">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
+                        </div>
+                        <div class="option" id="safemodeToggle1600">Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option checked" id="editorButton1600">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton1600">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
+                        <div class="option" id="formatButton1600">Format code</div>
+                        <div class="option" id="minimapToggle1600">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1600">Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1600">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1600">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1600">Format code</div>
-                    <div class="option" id="minimapToggle1600">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
                 </div>
-            </div>
 
-            <div class="button uncheck" id="debugButton1600">Inspector
-                <i class="fa fa-square-o" aria-hidden="true"></i>
+                <div class="button uncheck" id="debugButton1600">Inspector
+                    <i class="fa fa-square-o" aria-hidden="true"></i>
+                </div>
+                <div class="button" id="metadataButton1600">Metadata</div>
             </div>
-            <div class="button" id="metadataButton1600">Metadata</div>
-        </div>
 
 
 
-        <div class="category right">
-            <div class="button select">
-                <span id="currentVersion1600">Version: Latest</span>
-                <div class="toDisplay">
-                    <div class="option" onclick="setVersion('latest');">Latest</div>
-                    <div class="option" onclick="setVersion('2.5');">2.5</div>
+            <div class="category right">
+                <div class="button select">
+                    <span id="currentVersion1600">Version: Latest</span>
+                    <div class="toDisplay">
+                        <div class="option" onclick="setVersion('latest');">Latest</div>
+                        <div class="option" onclick="setVersion('2.5');">2.5</div>
+                    </div>
+                </div>
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
                 </div>
-            </div>
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
             </div>
         </div>
-    </div>
 
-    <div class="navbar navBar1475">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-            v3.0-alpha
-        </div>
+        <div class="navbar navBar1475">
+            <div class="title">
+                Babylon.js Playground
+            </div>
+            <div class="version" id="mainTitle">
+                v3.0-alpha
+            </div>
 
-        <div class="category">
-            <div class="button run" id="runButton1475">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button run" id="runButton1475">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button" id="newButton1475">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1475">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="newButton1475">New
+                    <i class="fa fa-file" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="clearButton1475">Clear
+                    <i class="fa fa-trash" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
-        <div class="category">
-            <div class="button" id="saveButton1475">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1475">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="saveButton1475">Save
+                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="zipButton1475">Zip
+                    <i class="fa fa-download" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1475">Dark</div>
-                            <div class="option" id="lightTheme1475">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme1475">Dark</div>
+                                <div class="option" id="lightTheme1475">Light</div>
+                            </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1475">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize1475">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
                         </div>
-                    </div>
-                    <div class="option" id='safemodeToggle1475'>Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1475">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1475">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1475">Format code</div>
-                    <div class="option" id="minimapToggle1475">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1475">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="metadataButton1475">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1475">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('2.5');">2.5</div>
+                        <div class="option" id='safemodeToggle1475'>Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option checked" id="editorButton1475">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton1475">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
+                        <div class="option" id="formatButton1475">Format code</div>
+                        <div class="option" id="minimapToggle1475">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton1475">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="metadataButton1475">Metadata</div>
+                        <div class="option subSelect">
+                            <span id="currentVersion1475">Vers. : Latest</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setVersion('latest');">Latest</div>
+                                <div class="option" onclick="setVersion('2.5');">2.5</div>
+                            </div>
                         </div>
                     </div>
                 </div>
             </div>
-        </div>
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
         </div>
-    </div>
 
-    <div class="navbar navBar1030">
-        <div class="category">
-            <div class="button run" id="runButton1030">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+        <div class="navbar navBar1030">
+            <div class="category">
+                <div class="button run" id="runButton1030">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button" id="newButton1030">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1030">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="newButton1030">New
+                    <i class="fa fa-file" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="clearButton1030">Clear
+                    <i class="fa fa-trash" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
-        <div class="category">
-            <div class="button" id="saveButton1030">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1030">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="saveButton1030">Save
+                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="zipButton1030">Zip
+                    <i class="fa fa-download" aria-hidden="true"></i>
+                </div>
             </div>
-        </div>
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1030">Dark</div>
-                            <div class="option" id="lightTheme1030">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme1030">Dark</div>
+                                <div class="option" id="lightTheme1030">Light</div>
+                            </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1030">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize1030">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
                         </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1030">Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1030">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1030">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1030">Format code</div>
-                    <div class="option" id="minimapToggle1030">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1030">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="metadataButton1030">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1030">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('2.5');">2.5</div>
+                        <div class="option" id="safemodeToggle1030">Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option checked" id="editorButton1030">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton1030">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
+                        <div class="option" id="formatButton1030">Format code</div>
+                        <div class="option" id="minimapToggle1030">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton1030">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="metadataButton1030">Metadata</div>
+                        <div class="option subSelect">
+                            <span id="currentVersion1030">Vers. : Latest</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setVersion('latest');">Latest</div>
+                                <div class="option" onclick="setVersion('2.5');">2.5</div>
+                            </div>
                         </div>
                     </div>
                 </div>
             </div>
-        </div>
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
         </div>
-    </div>
-
-    <div class="navbar navBar750">
-        <div class="category">
-            <div class="button select">File
-                <div class="toDisplay">
-                    <div class="option" id="runButton750">Run
-                        <i class="fa fa-play" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="newButton750">New
-                        <i class="fa fa-file" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="clearButton750">Clear
-                        <i class="fa fa-trash" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="saveButton750">Save
-                        <i class="fa fa-floppy-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="zipButton750">Zip
-                        <i class="fa fa-download" aria-hidden="true"></i>
+
+        <div class="navbar navBar750">
+            <div class="category">
+                <div class="button select">File
+                    <div class="toDisplay">
+                        <div class="option" id="runButton750">Run
+                            <i class="fa fa-play" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="newButton750">New
+                            <i class="fa fa-file" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="clearButton750">Clear
+                            <i class="fa fa-trash" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="saveButton750">Save
+                            <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="zipButton750">Zip
+                            <i class="fa fa-download" aria-hidden="true"></i>
+                        </div>
                     </div>
                 </div>
             </div>
-        </div>
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme750">Dark</div>
-                            <div class="option" id="lightTheme750">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme750">Dark</div>
+                                <div class="option" id="lightTheme750">Light</div>
+                            </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize750">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize750">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
                         </div>
-                    </div>
-                    <div class="option" id="safemodeToggle750">Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div style="display:none;" class="option checked" id="editorButton750">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton750">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
-                    <div class="option" id="formatButton750">Format code</div>
-                    <div class="option" id="minimapToggle750">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton750">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="metadataButton750">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion750">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('2.5');">2.5</div>
+                        <div class="option" id="safemodeToggle750">Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div style="display:none;" class="option checked" id="editorButton750">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton750">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
+                        <div class="option" id="formatButton750">Format code</div>
+                        <div class="option" id="minimapToggle750">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton750">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="metadataButton750">Metadata</div>
+                        <div class="option subSelect">
+                            <span id="currentVersion750">Vers. : Latest</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setVersion('latest');">Latest</div>
+                                <div class="option" onclick="setVersion('2.5');">2.5</div>
+                            </div>
                         </div>
                     </div>
                 </div>
             </div>
-        </div>
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
         </div>
-    </div>
 
-    <div class="wrapper">
-        <div id="jsEditor"></div>
-        <div id="canvasZone">
-            <canvas touch-action="none" id="renderCanvas"></canvas>
+        <div class="wrapper">
+            <div id="jsEditor"></div>
+            <div id="canvasZone">
+                <canvas touch-action="none" id="renderCanvas"></canvas>
+            </div>
         </div>
-    </div>
-    <div id="exampleList">
-        <div id="exampleBanner">
-            <h1>Examples</h1>
+        <div id="exampleList">
+            <div id="exampleBanner">
+                <h1>Examples</h1>
+            </div>
+            <div class="horizontalSeparator"></div>
+            <input id="filterBar" type="text" placeholder="Filter examples...">
+            <img id="filterBarClear" src="https://d33wubrfki0l68.cloudfront.net/17ca450bae302631f4857cd8c3992234ec5dd9a7/057f9/img/ui/clear_button.png">
         </div>
-        <div class="horizontalSeparator"></div>
-        <input id="filterBar" type="text" placeholder="Filter examples...">
-        <img id="filterBarClear" src="https://d33wubrfki0l68.cloudfront.net/17ca450bae302631f4857cd8c3992234ec5dd9a7/057f9/img/ui/clear_button.png">
-    </div>
 
-    <span class="label" id="fpsLabel">FPS</span>
+        <span class="label" id="fpsLabel">FPS</span>
 
-    <div id="errorZone">
-    </div>
+        <div id="errorZone">
+        </div>
 
-    <div class="navbarBottom">
-        <div id="statusBar"></div>
-        <div class="links">
-            <div class='link'>
-                <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
+        <div class="navbarBottom">
+            <div id="statusBar"></div>
+            <div class="links">
+                <div class='link'>
+                    <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
+                </div>
             </div>
         </div>
-    </div>
 
-    <div id="saveLayer" class="save-layer">
-        <div class="save-form">
-            <label for="saveFormTitle">TITLE</label>
-            <div class="separator"></div>
-            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
+        <div id="saveLayer" class="save-layer">
+            <div class="save-form">
+                <label for="saveFormTitle">TITLE</label>
+                <div class="separator"></div>
+                <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
 
-            <label for="saveFormDescription">DESCRIPTION</label>
-            <div class="separator"></div>
-            <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
+                <label for="saveFormDescription">DESCRIPTION</label>
+                <div class="separator"></div>
+                <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
 
-            <label for="saveFormTags">TAGS (separated by comma)</label>
-            <div class="separator"></div>
-            <textarea id="saveFormTags" rows="4" cols="10"></textarea>
+                <label for="saveFormTags">TAGS (separated by comma)</label>
+                <div class="separator"></div>
+                <textarea id="saveFormTags" rows="4" cols="10"></textarea>
 
-            <div class="save-form-buttons" id="saveFormButtons">
+                <div class="save-form-buttons" id="saveFormButtons">
 
-                <div id="saveFormButtonOk" class="button">OK</div>
-                <div id="saveFormButtonCancel" class="button">Cancel</div>
+                    <div id="saveFormButtonOk" class="button">OK</div>
+                    <div id="saveFormButtonCancel" class="button">Cancel</div>
+                </div>
             </div>
         </div>
-    </div>
 
-    <script src="https://code.jquery.com/jquery.js"></script>
+        <script src="https://code.jquery.com/jquery.js"></script>
 
-    <script src="js/actions.js"></script>
-    <script src="js/pbt.js"></script>
-    <script src="js/index.js"></script>
+        <script src="js/actions.js"></script>
+        <script src="js/pbt.js"></script>
+        <script src="js/index.js"></script>
 
-    <!-- Global site tag (gtag.js) - Google Analytics -->
-    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
-    <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
+        <!-- Global site tag (gtag.js) - Google Analytics -->
+        <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
+        <script>
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
 
-    gtag('config', 'UA-41767310-2');
-    </script>    
-</body>
+            gtag('config', 'UA-41767310-2');
+        </script>
+    </body>
 
 </html>

+ 5 - 1
Playground/index-local.html

@@ -18,7 +18,7 @@
         <script src="../dist/preview%20release/Oimo.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
         <!-- Monaco -->
-        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
         <!-- Babylon.js -->
         <script src="../tools/DevLoader/BabylonLoader.js"></script>
 
@@ -454,6 +454,10 @@
                         wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
                         fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
                     };
+                    var script = document.createElement('script');
+                    script.type = 'text/javascript';
+                    script.src = "node_modules/monaco-editor/min/vs/loader.js";
+                    document.head.appendChild(script);
                 });
         </script>
     </body>

+ 10 - 9
Playground/index.html

@@ -37,8 +37,6 @@
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
-        <!-- Monaco -->
-        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
@@ -48,13 +46,16 @@
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
+        <!-- Monaco -->
+        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
 
         <!-- Extensions -->
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js" async></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.navmesh.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
-                               
+
         <link href="css/index.css" rel="stylesheet" />
     </head>
 
@@ -479,16 +480,16 @@
         <script src="js/actions.js"></script>
         <script src="js/pbt.js"></script>
         <script src="js/index.js"></script>
-        
+
         <!-- Global site tag (gtag.js) - Google Analytics -->
         <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
         <script>
-        window.dataLayer = window.dataLayer || [];
-        function gtag(){dataLayer.push(arguments);}
-        gtag('js', new Date());
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
 
-        gtag('config', 'UA-41767310-2');
-        </script>        
+            gtag('config', 'UA-41767310-2');
+        </script>
     </body>
 
 </html>

+ 31 - 24
Tools/DevLoader/BabylonLoader.js

@@ -141,36 +141,44 @@ var BABYLONDEVTOOLS;
         }
 
         Loader.prototype.loadLibrary = function (library, module) {
+            if (library.preventLoadLibrary) {
+                return;
+            }
+
             if (!useDist) {
-                var i = 0;
-                for (; i < library.files.length; i++) {
-                    var file = library.files[i];
-                    if (file.indexOf('lib.d.ts') > 0) {
-                        continue;
-                    }
+                if (library.useOutputForDebugging) {
+                    this.loadScript(babylonJSPath + '/.temp' + module.build.distOutputDirectory + library.output);
+                } else {
+                    var i = 0;
+                    for (; i < library.files.length; i++) {
+                        var file = library.files[i];
+                        if (file.indexOf('lib.d.ts') > 0) {
+                            continue;
+                        }
 
-                    file = file.replace('.ts', '.js');
-                    file = file.replace('../', '');
-                    file = babylonJSPath + '/' + file;
-                    this.loadScript(file);
-                }
+                        file = file.replace('.ts', '.js');
+                        file = file.replace('../', '');
+                        file = babylonJSPath + '/' + file;
+                        this.loadScript(file);
+                    }
 
-                if (library.shaderFiles && library.shaderFiles.length > 0) {
-                    var shaderFile = library.shaderFiles[0];
-                    var endDirectoryIndex = shaderFile.lastIndexOf('/');
-                    shaderFile = shaderFile.substring(0, endDirectoryIndex + 1);
-                    shaderFile += library.output.replace('.js', '.js.fx');
-                    this.loadScript(shaderFile);
-                    if (library.shadersIncludeFiles) {
-                        var includeShaderFile = shaderFile.replace('.js.fx', '.js.include.fx');
-                        this.loadScript(includeShaderFile);
+                    if (library.shaderFiles && library.shaderFiles.length > 0) {
+                        var shaderFile = library.shaderFiles[0];
+                        var endDirectoryIndex = shaderFile.lastIndexOf('/');
+                        shaderFile = shaderFile.substring(0, endDirectoryIndex + 1);
+                        shaderFile += library.output.replace('.js', '.js.fx');
+                        this.loadScript(shaderFile);
+                        if (library.shadersIncludeFiles) {
+                            var includeShaderFile = shaderFile.replace('.js.fx', '.js.include.fx');
+                            this.loadScript(includeShaderFile);
+                        }
                     }
                 }
             }
             else if (min) {
                 if (library.webpack) {
                     if (module.build.distOutputDirectory)
-                        this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.bundle.js'));
+                        this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
                 }
                 else {
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.min.js'));
@@ -181,6 +189,7 @@ var BABYLONDEVTOOLS;
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
             }
 
+            // Currently not being used
             if (!min && library.sassFiles && library.sassFiles.length > 0) {
                 var cssFile = library.output.replace('.js', '.css');
                 cssFile = babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + cssFile;
@@ -242,10 +251,8 @@ var BABYLONDEVTOOLS;
 
             // Modules
             if (loadModules) {
+
                 for (var i = 0; i < settings.modules.length; i++) {
-                    if (settings.modules[i] === "viewer") {
-                        continue;
-                    }
                     this.loadModule(settings[settings.modules[i]]);
                 }
             }

+ 93 - 151
Tools/Gulp/config.json

@@ -8,6 +8,7 @@
         "declarationModuleFilename": "babylon.module.d.ts",
         "outputDirectory": "../../dist/preview release",
         "playgroundDirectory": "../../Playground/",
+        "tempDirectory": "../../.temp/",
         "intellisenseFile": "babylon.d.txt",
         "intellisenseSources": [
             "../../dist/preview release/babylon.d.ts",
@@ -136,7 +137,7 @@
             "picking",
             "backgroundMaterial",
             "videoDome"
-        ]      
+        ]
     },
     "workloads": {
         "core": {
@@ -227,7 +228,7 @@
                 "fresnelFunction",
                 "reflectionFunction",
                 "imageProcessingDeclaration",
-                "imageProcessingFunctions",                
+                "imageProcessingFunctions",
                 "bumpFragmentFunctions",
                 "clipPlaneFragmentDeclaration",
                 "fogFragmentDeclaration",
@@ -246,7 +247,7 @@
                 "core",
                 "debug"
             ]
-        },          
+        },
         "occlusionQuery": {
             "files": [
                 "../../src/Engine/Extensions/babylon.engine.occlusionQuery.js"
@@ -255,7 +256,7 @@
                 "core",
                 "debug"
             ]
-        },          
+        },
         "behaviors": {
             "files": [
                 "../../src/Behaviors/babylon.behavior.js"
@@ -263,7 +264,7 @@
             "dependUpon": [
                 "core"
             ]
-        },   
+        },
         "imageProcessing": {
             "files": [
                 "../../src/Materials/babylon.imageProcessingConfiguration.js",
@@ -273,8 +274,8 @@
             "dependUpon": [
                 "core"
             ]
-        },  
-        "noise" : {
+        },
+        "noise": {
             "files": [
                 "../../src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.js"
             ],
@@ -285,7 +286,7 @@
             "shaders": [
                 "noise.fragment"
             ]
-        },      
+        },
         "particles": {
             "files": [
                 "../../src/Particles/babylon.particle.js",
@@ -1083,7 +1084,7 @@
             ]
         },
         "textureFormats": {
-            "files": [ ],
+            "files": [],
             "dependUpon": [
                 "dds",
                 "tga",
@@ -1208,7 +1209,7 @@
             "shaders": [
                 "anaglyph.fragment"
             ]
-        },       
+        },
         "stereoscopic": {
             "files": [
                 "../../src/PostProcess/babylon.stereoscopicInterlacePostProcess.js",
@@ -1226,7 +1227,7 @@
             "shaders": [
                 "stereoscopicInterlace.fragment"
             ]
-        },           
+        },
         "vr": {
             "files": [
                 "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
@@ -1409,8 +1410,8 @@
         "proceduralTexturesLibrary",
         "loaders",
         "serializers",
-        "inspector",
         "gui",
+        "inspector",
         "viewer",
         "viewer-assets"
     ],
@@ -1844,146 +1845,72 @@
     "gui": {
         "libraries": [
             {
-                "files": [
-                    "../../gui/src/2D/style.ts",
-                    "../../gui/src/2D/valueAndUnit.ts",
-                    "../../gui/src/2D/advancedDynamicTexture.ts",
-                    "../../gui/src/2D/measure.ts",
-                    "../../gui/src/2D/math2D.ts",
-                    "../../gui/src/2D/multiLinePoint.ts",
-                    "../../gui/src/2D/controls/control.ts",
-                    "../../gui/src/2D/controls/container.ts",
-                    "../../gui/src/2D/controls/stackPanel.ts",
-                    "../../gui/src/2D/controls/rectangle.ts",
-                    "../../gui/src/2D/controls/ellipse.ts",
-                    "../../gui/src/2D/controls/line.ts",
-                    "../../gui/src/2D/controls/slider.ts",
-                    "../../gui/src/2D/controls/checkbox.ts",
-                    "../../gui/src/2D/controls/radioButton.ts",
-                    "../../gui/src/2D/controls/textBlock.ts",
-                    "../../gui/src/2D/controls/image.ts",
-                    "../../gui/src/2D/controls/button.ts",
-                    "../../gui/src/2D/controls/colorpicker.ts",
-                    "../../gui/src/2D/controls/inputText.ts",
-                    "../../gui/src/2D/controls/inputPassword.ts",
-                    "../../gui/src/2D/controls/virtualKeyboard.ts",
-                    "../../gui/src/2D/controls/multiLine.ts",
-                    "../../gui/src/2D/controls/grid.ts",                    
-                    "../../gui/src/3D/gui3DManager.ts",
-                    "../../gui/src/3D/materials/fluentMaterial.ts",
-                    "../../gui/src/3D/vector3WithInfo.ts",
-                    "../../gui/src/3D/controls/control3D.ts",
-                    "../../gui/src/3D/controls/container3D.ts",
-                    "../../gui/src/3D/controls/abstractButton3D.ts",
-                    "../../gui/src/3D/controls/button3D.ts",
-                    "../../gui/src/3D/controls/meshButton3D.ts",
-                    "../../gui/src/3D/controls/holographicButton.ts",
-                    "../../gui/src/3D/controls/stackPanel3D.ts",
-                    "../../gui/src/3D/controls/volumeBasedPanel.ts",
-                    "../../gui/src/3D/controls/spherePanel.ts",
-                    "../../gui/src/3D/controls/planePanel.ts",
-                    "../../gui/src/3D/controls/scatterPanel.ts",
-                    "../../gui/src/3D/controls/cylinderPanel.ts"
-                ],
-                "shaderFiles": [
-                    "../../gui/src/3D/materials/shaders/fluent.vertex.fx",
-                    "../../gui/src/3D/materials/shaders/fluent.fragment.fx"
-                ],
-                "output": "babylon.gui.js",
-                "buildAsModule": true,
-                "moduleName": "babylonjs-gui",
-                "moduleDeclaration": {
-                    "name": "GUI",
-                    "module": "babylonjs-gui"
-                }
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.gui.min.js",
+                "webpack": "../../gui/webpack.config.js",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true
             }
         ],
         "build": {
-            "srcOutputDirectory": "../../gui/",
-            "distOutputDirectory": "/gui/"
+            "srcOutputDirectory": "../../gui/src/",
+            "distOutputDirectory": "/gui/",
+            "dtsBundle": {
+                "name": "babylonjs-gui",
+                "main": "../../dist/preview release/gui/build/index.d.ts",
+                "out": "../babylon.gui.module.d.ts",
+                "baseDir": "../../dist/preview release/gui/build/",
+                "headerText": "BabylonJS GUI"
+            },
+            "processDeclaration": {
+                "filename": "babylon.gui.module.d.ts",
+                "packageName": "babylonjs-gui",
+                "moduleName": "BABYLON.GUI",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON"
+                }
+            }
         }
     },
     "inspector": {
         "libraries": [
             {
-                "files": [
-                    "../../inspector/src/Inspector.ts",
-                    "../../inspector/src/properties.ts",
-                    "../../inspector/src/properties_gui.ts",
-                    "../../inspector/src/gui/BasicElement.ts",
-                    "../../inspector/src/adapters/Adapter.ts",
-                    "../../inspector/src/adapters/CameraAdapter.ts",
-                    "../../inspector/src/adapters/PhysicsImpostorAdapter.ts",
-                    "../../inspector/src/adapters/GUIAdapter.ts",
-                    "../../inspector/src/adapters/SoundAdapter.ts",
-                    "../../inspector/src/adapters/TextureAdapter.ts",
-                    "../../inspector/src/adapters/LightAdapter.ts",
-                    "../../inspector/src/adapters/MaterialAdapter.ts",
-                    "../../inspector/src/adapters/MeshAdapter.ts",
-                    "../../inspector/src/adapters/PhysicsImpostorAdapter.ts",
-                    "../../inspector/src/details/DetailPanel.ts",
-                    "../../inspector/src/details/Property.ts",
-                    "../../inspector/src/details/PropertyLine.ts",
-                    "../../inspector/src/gui/ColorElement.ts",
-                    "../../inspector/src/gui/ColorPickerElement.ts",
-                    "../../inspector/src/gui/CubeTextureElement.ts",
-                    "../../inspector/src/gui/HDRCubeTextureElement.ts",
-                    "../../inspector/src/gui/SearchBar.ts",
-                    "../../inspector/src/gui/TextureElement.ts",
-                    "../../inspector/src/gui/Tooltip.ts",
-                    "../../inspector/src/helpers/Helpers.ts",
-                    "../../inspector/src/scheduler/Scheduler.ts",
-                    "../../inspector/src/tabs/Tab.ts",
-                    "../../inspector/src/tabs/PropertyTab.ts",
-                    "../../inspector/src/tabs/CameraTab.ts",
-                    "../../inspector/src/tabs/GUITab.ts",
-                    "../../inspector/src/tabs/PhysicsTab.ts",
-                    "../../inspector/src/tabs/SoundTab.ts",
-                    "../../inspector/src/tabs/TextureTab.ts",
-                    "../../inspector/src/tabs/LightTab.ts",
-                    "../../inspector/src/tabs/MaterialTab.ts",
-                    "../../inspector/src/tabs/MeshTab.ts",
-                    "../../inspector/src/tabs/SceneTab.ts",
-                    "../../inspector/src/tabs/ConsoleTab.ts",
-                    "../../inspector/src/tabs/StatsTab.ts",
-                    "../../inspector/src/tabs/GLTFTab.ts",
-                    "../../inspector/src/tabs/ToolsTab.ts",
-                    "../../inspector/src/tabs/TabBar.ts",
-                    "../../inspector/src/tools/AbstractTool.ts",
-                    "../../inspector/src/tools/PauseScheduleTool.ts",
-                    "../../inspector/src/tools/PickTool.ts",
-                    "../../inspector/src/tools/PopupTool.ts",
-                    "../../inspector/src/tools/RefreshTool.ts",
-                    "../../inspector/src/tools/LabelTool.ts",
-                    "../../inspector/src/tools/Toolbar.ts",
-                    "../../inspector/src/tools/DisposeTool.ts",
-                    "../../inspector/src/tools/FullscreenTool.ts",
-                    "../../inspector/src/tree/TreeItem.ts",
-                    "../../inspector/src/treetools/AbstractTreeTool.ts",
-                    "../../inspector/src/treetools/BoundingBox.ts",
-                    "../../inspector/src/treetools/CameraPOV.ts",
-                    "../../inspector/src/treetools/SoundInteractions.ts",
-                    "../../inspector/src/treetools/Checkbox.ts",
-                    "../../inspector/src/treetools/DebugArea.ts",
-                    "../../inspector/src/treetools/Info.ts",
-                    "../../inspector/src/lib.d.ts"
-                ],
-                "sassFiles": [
-                    "../../inspector/sass/**/*.scss"
-                ],
-                "output": "babylon.inspector.js",
+                "files": [],
+                "sassFiles": [],
+                "output": "babylon.inspector.bundle.js",
                 "webpack": "../../inspector/webpack.config.js",
                 "bundle": "true",
-                "moduleDeclaration": {
-                    "name": "INSPECTOR",
-                    "module": "babylonjs-inspector"
-                },
-                "extendsRoot": true
+                "extendsRoot": true,
+                "useOutputForDebugging": true
             }
         ],
         "build": {
-            "srcOutputDirectory": "../../inspector/",
-            "distOutputDirectory": "/inspector/"
+            "srcOutputDirectory": "../../inspector/src/",
+            "distOutputDirectory": "/inspector/",
+            "dtsBundle": {
+                "name": "babylonjs-inspector",
+                "main": "../../dist/preview release/inspector/build/index.d.ts",
+                "out": "../babylon.inspector.module.d.ts",
+                "baseDir": "../../dist/preview release/inspector/build/",
+                "headerText": "BabylonJS Inspector"
+            },
+            "processDeclaration": {
+                "filename": "babylon.inspector.module.d.ts",
+                "packageName": "babylonjs-inspector",
+                "moduleName": "INSPECTOR",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON",
+                    "babylonjs-gui": "BABYLON.GUI"
+                }
+            }
         }
     },
     "viewer": {
@@ -1998,18 +1925,32 @@
                     "name": "BabylonViewer",
                     "module": "babylonjs-viewer"
                 },
-                "babylonIncluded": true
+                "babylonIncluded": true,
+                "noWatch": true,
+                "preventLoadLibrary": true
             }
         ],
         "build": {
             "srcOutputDirectory": "../../Viewer/",
+            "distOutputDirectory": "/viewer/",
             "dtsBundle": {
                 "name": "babylonjs-viewer",
-                "main": "../../Viewer/dist/build/src/index.d.ts",
-                "out": "../../../../dist/preview release/viewer/babylon.viewer.module.d.ts",
-                "legacyDeclaration": true,
+                "main": "../../dist/preview release/viewer/build/src/index.d.ts",
+                "out": "../../babylon.viewer.module.d.ts",
                 "prependText": "/// <reference path=\"./babylon.d.ts\"/>\n/// <reference path=\"./babylon.glTF2Interface.d.ts\"/>\n/// <reference path=\"./babylonjs.loaders.d.ts\"/>\ndeclare module \"babylonjs-loaders\"{ export=BABYLON;}\n"
             },
+            "processDeclaration": {
+                "packageName": "babylonjs-viewer",
+                "moduleName": "BabylonViewer",
+                "importsToRemove": [
+                    "pep",
+                    "babylonjs-loaders"
+                ],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON"
+                }
+            },
             "outputs": [
                 {
                     "destination": [
@@ -2026,8 +1967,7 @@
                                 "glTF2Interface/babylon.glTF2Interface.d.ts"
                             ]
                         }
-                    ],
-                    "minified": true
+                    ]
                 },
                 {
                     "destination": [
@@ -2056,23 +1996,25 @@
                     "name": "BabylonViewerAssets",
                     "module": "babylonjs-viewer-assets"
                 },
-                "babylonIncluded": true
+                "babylonIncluded": true,
+                "noWatch": true,
+                "preventLoadLibrary": true
             }
         ],
         "build": {
             "srcOutputDirectory": "../../Viewer/",
+            "distOutputDirectory": "/viewer/",
             "dtsBundle": {
                 "name": "babylonjs-viewer-assets",
-                "baseDir": "../../Viewer/dist/build/src/assets/",
-                "main": "../../Viewer/dist/build/src/assets/index.d.ts",
-                "out": "../../../build/assets/babylon.viewer.assets.module.d.ts"
+                "main": "../../dist/preview release/viewer/build/src/assets/index.d.ts",
+                "out": "../../../../../../Viewer/build/assets/babylon.viewer.assets.module.d.ts"
             },
             "outputs": [
                 {
                     "destination": [
                         {
                             "filename": "babylon.viewer.assets.js",
-                            "outputDirectory": "/../../Viewer/dist/build/assets/"
+                            "outputDirectory": "/../../Viewer/build/assets/"
                         }
                     ],
                     "minified": true
@@ -2080,4 +2022,4 @@
             ]
         }
     }
-}
+}

+ 94 - 33
Tools/Gulp/gulpfile.js

@@ -16,7 +16,6 @@ var merge2 = require("merge2");
 var concat = require("gulp-concat");
 var rename = require("gulp-rename");
 var cleants = require("gulp-clean-ts-extends");
-var changedInPlace = require("gulp-changed-in-place");
 var runSequence = require("run-sequence");
 var replace = require("gulp-replace");
 var uncommentShader = require("./gulp-removeShaderComments");
@@ -25,17 +24,17 @@ var optimisejs = require("gulp-optimize-js");
 var webserver = require("gulp-webserver");
 var path = require("path");
 var sass = require("gulp-sass");
-var webpack = require("webpack-stream");
+const webpack = require('webpack');
+var webpackStream = require("webpack-stream");
 var typedoc = require("gulp-typedoc");
 var validateTypedoc = require("./gulp-validateTypedoc");
-var request = require('request');
 var fs = require("fs");
 var dtsBundle = require('dts-bundle');
 const through = require('through2');
 var karmaServer = require('karma').Server;
 
 //viewer declaration
-var processViewerDeclaration = require('./processViewerDeclaration');
+var processDeclaration = require('./processViewerDeclaration');
 
 var config = require("./config.json");
 
@@ -448,7 +447,7 @@ var buildExternalLibrary = function (library, settings, watch) {
 
         if (library.webpack) {
             let sequence = [waitAll];
-            let wpBuild = webpack(require(library.webpack));
+            let wpBuild = webpackStream(require(library.webpack), webpack);
             if (settings.build.outputs) {
                 //shoud dtsBundle create the declaration?
                 if (settings.build.dtsBundle) {
@@ -459,7 +458,7 @@ var buildExternalLibrary = function (library, settings, watch) {
                             if (isdts) this.push(file);
                             cb();
                         }))
-                        .pipe(gulp.dest('.'));
+                        .pipe(gulp.dest(outputDirectory));
                     // dts-bundle does NOT support (gulp) streams, so files have to be saved and reloaded, 
                     // until I fix it
                     event.on("end", function () {
@@ -471,8 +470,8 @@ var buildExternalLibrary = function (library, settings, watch) {
                             if (err) throw err;
                             data = (settings.build.dtsBundle.prependText || "") + '\n' + data.toString();
                             fs.writeFile(fileLocation, data);
-                            if (settings.build.dtsBundle.legacyDeclaration) {
-                                var newData = processViewerDeclaration(data);
+                            if (settings.build.processDeclaration) {
+                                var newData = processDeclaration(data, settings.build.processDeclaration);
                                 fs.writeFile(fileLocation.replace('.module', ''), newData);
                             }
                         });
@@ -541,14 +540,50 @@ var buildExternalLibrary = function (library, settings, watch) {
                 sequence.push(build);
 
             } else {
+
+                let buildEvent = wpBuild
+                    .pipe(gulp.dest(outputDirectory))
+                    //back-compat
+                    .pipe(through.obj(function (file, enc, cb) {
+                        // only js files
+                        const isjs = /\.js$/.test(file.path);
+                        if (isjs) this.push(file);
+                        cb();
+                    }))
+                    .pipe(rename(library.output.replace(".js", ".max.js")))
+                    .pipe(rename(library.output.replace(".min.max.", ".")))
+                    .pipe(rename(library.output.replace(".bundle.max.", ".")))
+                    .pipe(gulp.dest(outputDirectory));
                 sequence.push(
-                    wpBuild
-                        .pipe(rename(library.output.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
-                        .pipe(addModuleExports(library.moduleDeclaration, { subModule: false, extendsRoot: library.extendsRoot, externalUsingBabylon: true }))
-                        .pipe(uglify())
-                        .pipe(optimisejs())
-                        .pipe(gulp.dest(outputDirectory))
-                )
+                    buildEvent
+                );
+                if (settings.build.dtsBundle || settings.build.processDeclaration) {
+                    buildEvent.on("end", function () {
+                        if (settings.build.dtsBundle) {
+                            dtsBundle.bundle(settings.build.dtsBundle);
+                        } if (settings.build.processDeclaration) {
+                            let fileLocation = path.join(outputDirectory, settings.build.processDeclaration.filename);
+                            fs.readFile(fileLocation, function (err, data) {
+                                if (err) throw err;
+                                var newData = processDeclaration(data, settings.build.processDeclaration);
+                                fs.writeFile(fileLocation.replace('.module', ''), newData);
+                            });
+                        }
+                    });
+                }
+                /*if (settings.build.processDeclaration) {
+                    sequence.push(
+                        wpBuild
+                            .pipe(through.obj(function (file, enc, cb) {
+                                // only js files
+                                const isDts = /\.d.ts$/.test(file.path);
+                                file.contents = new Buffer(processDeclaration(file.contents, settings.build.processDeclaration));
+                                if (isDts) this.push(file);
+                                cb();
+                            }))
+                            .pipe(gulp.dest(outputDirectory))
+                    )
+                }*/
             }
 
             return merge2(sequence);
@@ -600,7 +635,7 @@ gulp.task("build-custom", function (cb) {
  * Do it all.
  */
 gulp.task("typescript-all", function (cb) {
-    runSequence("typescript", "typescript-libraries", cb);
+    runSequence("typescript", "typescript-libraries", "netlify-cleanup", cb);
 });
 
 /**
@@ -623,22 +658,35 @@ gulp.task("watch", ["srcTscWatch"], function () {
     var tasks = [];
 
     config.modules.map(function (module) {
+
         config[module].libraries.map(function (library) {
-            tasks.push(gulp.watch(library.files, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug());
-            }));
-            tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug())
-            }));
-            tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug())
-            }));
+            if (library.webpack) {
+                if (library.noWatch) return;
+                var outputDirectory = config.build.tempDirectory + config[module].build.distOutputDirectory;
+                let wpconfig = require(library.webpack);
+                wpconfig.watch = true;
+                // dev mode and absolute path sourcemaps for debugging
+                wpconfig.mode = "development";
+                wpconfig.output.devtoolModuleFilenameTemplate = "[absolute-resource-path]";
+                //config.stats = "minimal";
+                tasks.push(webpackStream(wpconfig, webpack).pipe(gulp.dest(outputDirectory)))
+            } else {
+                tasks.push(gulp.watch(library.files, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug());
+                }));
+                tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug())
+                }));
+                tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug())
+                }));
+            }
         });
     });
 
@@ -696,6 +744,19 @@ gulp.task("clean-JS-MAP", function () {
     ], { force: true });
 });
 
+gulp.task("netlify-cleanup", function () {
+    //set by netlify
+    if (process.env.REPOSITORY_URL) {
+        return del([
+            "../../inspector/node_modules/**/*", "../../gui/node_modules/**/*",
+            "../../Viewer/node_modules/**/*"
+        ], { force: true });
+    }
+    else {
+        return true;
+    }
+})
+
 // this is needed for the modules for the declaration files.
 gulp.task("modules-compile", function () {
     var tsResult = gulp.src(config.typescript)
@@ -1131,7 +1192,7 @@ gulp.task("tests-viewer-validation-browserstack", ["tests-viewer-validation-tran
  */
 gulp.task("tests-viewer-validation-transpile", function (done) {
 
-    let wpBuild = webpack(require('../../Viewer//webpack.gulp.config.js'));
+    let wpBuild = webpackStream(require('../../Viewer/webpack.gulp.config.js'), webpack);
 
     // clean the built directory
     rmDir("../../Viewer/tests/build/");
@@ -1150,7 +1211,7 @@ gulp.task("tests-viewer-validation-transpile", function (done) {
  */
 gulp.task("tests-viewer-transpile", function (done) {
 
-    let wpBuild = webpack(require('../../Viewer/tests/unit/webpack.config.js'));
+    let wpBuild = webpackStream(require('../../Viewer/tests/unit/webpack.config.js'), webpack);
 
     // clean the built directory
     rmDir("../../Viewer/tests/build/");

+ 2 - 1
Tools/Gulp/package.json

@@ -59,10 +59,11 @@
         "ts-loader": "^2.3.7",
         "typedoc": "^0.9.0",
         "typescript": "~2.8.1",
+        "webpack": "^4.16.0",
         "webpack-stream": "^4.0.1"
     },
     "scripts": {
-        "install": "npm --prefix ../../Playground/ install ../../Playground/ && npm --prefix ../../tests/unit/ install ../../tests/unit/ && npm --prefix ../../Viewer/tests/ install ../../Viewer/tests/ && cd ../../Viewer && npm install && cd ../Tools/Gulp/ && gulp deployLocalDev"
+        "install": "cd ../../gui && npm install && cd ../Tools/Gulp/ &&  cd ../../inspector && npm install && cd ../Tools/Gulp/ && npm --prefix ../../Playground/ install ../../Playground/ && npm --prefix ../../tests/unit/ install ../../tests/unit/ && npm --prefix ../../Viewer/tests/ install ../../Viewer/tests/ && cd ../../Viewer && npm install && cd ../Tools/Gulp/ && gulp deployLocalDev"
     },
     "dependencies": {
         "dts-bundle": "^0.7.3",

+ 44 - 19
Tools/Gulp/processViewerDeclaration.js

@@ -1,4 +1,13 @@
-module.exports = function (data) {
+module.exports = function (data, options) {
+
+    /*
+    {
+        packageName: string,
+        moduleName: string,
+        importsToRemove: Array<string>,
+        classMap
+    }
+    */
 
     var str = "" + data;
 
@@ -6,35 +15,51 @@ module.exports = function (data) {
     // str = str.replace(/declare module 'babylonjs-viewer\/' {((?!(declare))(.|\n))*\n}/g, '');
 
     let lines = str.split('\n');
-    var firstIndex = lines.findIndex((line => { return line.indexOf("'babylonjs-viewer/'") !== -1 }));
+    var firstIndex = lines.findIndex((line => { return line.indexOf(`'${options.packageName}/'`) !== -1 }));
     var lastIndex = lines.findIndex(((line, idx) => { return line.trim() === '}' && idx > firstIndex }));
     lines.splice(firstIndex, lastIndex - firstIndex + 1);
     str = lines.join('\n');
 
-    str = str.replace(/declare module (.*) {/g, 'declare module BabylonViewer {').replace("import * as BABYLON from 'babylonjs';", "");
-    str = str.replace(/import {(.*)} from ['"]babylonjs-viewer(.*)['"];/g, '').replace(/import 'babylonjs-loaders';/, '').replace(/import 'pep';/, '');
+    str = str.replace(/declare module (.*) {/g, `declare module ${options.moduleName} {`);
+
+    str = str.replace("import * as BABYLON from 'babylonjs';", "");
+    let regexp = new RegExp(`import {(.*)} from ['"]${options.packageName}(.*)['"];`, 'g');
+    str = str.replace(regexp, '');
+
+    if (options.importsToRemove) {
+        while (options.importsToRemove.length) {
+            let remove = options.importsToRemove.pop();
+            str = str.replace(new RegExp(`import '${remove}';`), '');
+        }
+    }
 
     //find all used BABYLON and BABYLON-Loaders classes:
 
-    var babylonRegex = /import {(.*)} from ['"](babylonjs|babylonjs-loaders)['"];/g
+    if ((options.classMap)) {
+        Object.keys(options.classMap).forEach(package => {
+            var babylonRegex = new RegExp(`import {(.*)} from ['"](${package})['"];`, "g");
 
-    var match = babylonRegex.exec(str);
-    let classes = new Set();
-    while (match != null) {
-        if (match[1]) {
-            match[1].split(",").forEach(element => {
-                classes.add(element.trim());
+            var match = babylonRegex.exec(str);
+            let classes = new Set();
+            while (match != null) {
+                if (match[1]) {
+                    match[1].split(",").forEach(element => {
+                        classes.add(element.trim());
+                    });
+                }
+                match = babylonRegex.exec(str);
+            }
+            str = str.replace(babylonRegex, '');
+            classes.forEach(cls => {
+                let rg = new RegExp(`([ <])(${cls})([^\\w])`, "g")
+                str = str.replace(rg, `$1${options.classMap[package]}.$2$3`);
             });
-        }
-        match = babylonRegex.exec(str);
+        })
     }
-    str = str.replace(babylonRegex, '');
-    classes.forEach(cls => {
-        let rg = new RegExp(`([ <])(${cls})([^\\w])`, "g")
-        str = str.replace(rg, "$1BABYLON.$2$3");
-    });
 
-    str = str.replace(/export {(.*)};/g, '')
+    str = str.replace(/export {(.*)};/g, '');
+
+    str = str.split("\n").filter(line => line.trim()).filter(line => line.indexOf("export * from") === -1).join("\n");
 
     return str;
 }

+ 6 - 3
Tools/Publisher/index.js

@@ -56,7 +56,7 @@ let packages = [
     },
     {
         name: 'viewer-assets',
-        path: basePath + '/../../Viewer/dist/build/assets/',
+        path: basePath + '/../../Viewer/build/assets/',
         required: [
             basePath + '/../../Viewer/assets/readme.md',
             basePath + '/../../Viewer/assets/package.json',
@@ -215,7 +215,7 @@ function processCore(package, version) {
 
 function processViewer(package, version) {
 
-    let buildPath = package.path + "dist/build/src/";
+    let buildPath = package.path + "build/src/";
     let projectPath = '../../Viewer';
 
     if (package.required) {
@@ -257,7 +257,10 @@ function publish(version, packageName, basePath) {
 
     //publish the respected package
     console.log("executing " + 'npm publish \"' + basePath + "\"" + ' ' + tagDef);
-    shelljs.exec('npm publish \"' + basePath + "\"" + ' ' + tagDef);
+    if (process.argv.indexOf('--no-publish') === -1) {
+        shelljs.exec('npm publish \"' + basePath + "\"" + ' ' + tagDef);
+    }
+
 }
 
 function getFiles(dir, files_) {

+ 139 - 0
Tools/WebpackShaderLoader/index.js

@@ -0,0 +1,139 @@
+//modified https://github.com/grieve/webpack-glsl-loader/blob/master/index.js
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+
+
+function parse(loader, source, context, cb) {
+    var imports = [];
+    var importPattern = /@import ([.\/\w_-]+);/gi;
+    var match = importPattern.exec(source);
+
+    while (match != null) {
+        imports.push({
+            key: match[1],
+            target: match[0],
+            content: ''
+        });
+        match = importPattern.exec(source);
+    }
+
+    source = uncomment(source);
+
+    processImports(loader, source, context, imports, cb);
+}
+
+var singleComment = 1;
+var multiComment = 2;
+
+function uncomment(str) {
+
+    var currentChar;
+    var nextChar;
+    var insideString = false;
+    var insideComment = 0;
+    var offset = 0;
+    var ret = '';
+
+    str = str.replace(/\r\n/g, '\n');
+    str = str.replace(/[ \f\t\v]+/g, ' ');
+    str = str.replace(/^\s*\n/gm, '');
+    str = str.replace(/ \+ /g, '+');
+    str = str.replace(/ \- /g, '-');
+    str = str.replace(/ \/ /g, '/');
+    str = str.replace(/ \* /g, '*');
+    str = str.replace(/ > /g, '>');
+    str = str.replace(/ < /g, '<');
+    str = str.replace(/ >= /g, '>=');
+    str = str.replace(/ <= /g, '<=');
+    str = str.replace(/ \+= /g, '+=');
+    str = str.replace(/ \-= /g, '-=');
+    str = str.replace(/ \/= /g, '/=');
+    str = str.replace(/ \*= /g, '*=');
+    str = str.replace(/ = /g, '=');
+    str = str.replace(/, /g, ',');
+    str = str.replace(/\n\n/g, '\n');
+    str = str.replace(/\n /g, '\n');
+
+    for (var i = 0; i < str.length; i++) {
+        currentChar = str[i];
+        nextChar = str[i + 1];
+
+        if (!insideComment && currentChar === '"') {
+            var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\';
+            if (!escaped) {
+                insideString = !insideString;
+            }
+        }
+
+        if (insideString) {
+            continue;
+        }
+
+        if (!insideComment && currentChar + nextChar === '//') {
+            ret += str.slice(offset, i);
+            offset = i;
+            insideComment = singleComment;
+            i++;
+        } else if (insideComment === singleComment && currentChar === '\n') {
+            insideComment = 0;
+            offset = i;
+        } else if (!insideComment && currentChar + nextChar === '/*') {
+            ret += str.slice(offset, i);
+            offset = i;
+            insideComment = multiComment;
+            i++;
+            continue;
+        } else if (insideComment === multiComment && currentChar + nextChar === '*/') {
+            i++;
+            insideComment = 0;
+            offset = i + 1;
+            continue;
+        }
+    }
+
+    return ret + (insideComment ? '' : str.substr(offset));
+}
+
+function processImports(loader, source, context, imports, cb) {
+    if (imports.length === 0) {
+        return cb(null, source);
+    }
+
+    var imp = imports.pop();
+
+    loader.resolve(context, imp.key + '.fx', function (err, resolved) {
+        if (err) {
+            return cb(err);
+        }
+
+        loader.addDependency(resolved);
+        fs.readFile(resolved, 'utf-8', function (err, src) {
+            if (err) {
+                return cb(err);
+            }
+
+            parse(loader, src, path.dirname(resolved), function (err, bld) {
+                if (err) {
+                    return cb(err);
+                }
+
+                source = source.replace(imp.target, bld);
+                processImports(loader, source, context, imports, cb);
+            });
+        });
+    });
+}
+
+module.exports = function (source) {
+    this.cacheable();
+    var cb = this.async();
+    parse(this, source, this.context, function (err, bld) {
+        if (err) {
+            return cb(err);
+        }
+
+        cb(null, 'module.exports = ' + JSON.stringify(bld));
+    });
+};

+ 6 - 4
Viewer/package.json

@@ -27,15 +27,17 @@
         "@types/node": "^8.9.4",
         "base64-font-loader": "0.0.4",
         "base64-image-loader": "^1.2.1",
+        "base64-inline-loader": "^1.1.1",
         "deepmerge": "^2.1.1",
         "handlebars": "^4.0.11",
         "html-loader": "^0.5.5",
         "json-loader": "^0.5.7",
-        "ts-loader": "^2.3.7",
-        "typescript": "^2.7.2",
+        "ts-loader": "^4.4.0",
+        "typescript": "^2.9.2",
         "uglifyjs-webpack-plugin": "^1.2.2",
-        "webpack": "^3.11.0",
-        "webpack-dev-server": "^2.11.2"
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
     },
     "dependencies": {
         "pepjs": "^0.4.3"

+ 2 - 1
Viewer/tests/unit/tsconfig.json

@@ -20,7 +20,7 @@
         "skipDefaultLibCheck": true,
         "skipLibCheck": true,
         "baseUrl": "./src/",
-        "rootDir": "./",
+        "rootDir": "../../",
         "paths": {
             "babylonjs": [
                 "../../../../dist/preview release/babylon.d.ts"
@@ -35,6 +35,7 @@
                 "../../src/assets/"
             ]
         },
+        "outDir": "./build"
     },
     "include": [
         "./src/**/*.ts"

+ 4 - 2
Viewer/tests/unit/webpack.config.js

@@ -1,6 +1,7 @@
 const path = require('path');
 
 module.exports = {
+    context: __dirname,
     entry: {
         'test': __dirname + '/src/index.ts'
     },
@@ -24,9 +25,10 @@ module.exports = {
         oimo: 'OIMO',
         "earcut": true
     },
+    mode: "development",
     devtool: 'source-map',
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             loader: 'ts-loader',
             exclude: /node_modules/
@@ -46,7 +48,7 @@ module.exports = {
         },
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
     },
     devServer: {

+ 1 - 1
Viewer/tsconfig-gulp.json

@@ -41,7 +41,7 @@
                 "./assets/"
             ]
         },
-        "outDir": "./dist/build"
+        "outDir": "./build"
     },
     "exclude": [
         "node_modules",

+ 2 - 2
Viewer/tsconfig.json

@@ -1,6 +1,6 @@
 {
     "compilerOptions": {
-        "target": "es2015",
+        "target": "es5",
         "module": "commonjs",
         "declaration": true,
         "experimentalDecorators": true,
@@ -44,6 +44,6 @@
                 "./assets/*"
             ]
         },
-        "outDir": "./dist/build"
+        "outDir": "./build"
     }
 }

+ 4 - 2
Viewer/webpack.assets.config.js

@@ -1,4 +1,5 @@
 module.exports = {
+    context: __dirname,
     entry: [
         __dirname + '/src/assets/index.ts'
     ],
@@ -10,8 +11,9 @@ module.exports = {
     resolve: {
         extensions: ['.ts']
     },
+    mode: "production",
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             use: {
                 loader: 'ts-loader',
@@ -36,7 +38,7 @@ module.exports = {
         },
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
     }
 }

+ 4 - 3
Viewer/webpack.config.js

@@ -54,7 +54,7 @@ module.exports = /*[
             libraryTarget: 'umd',
             library: 'BabylonViewer',
             umdNamedDefine: true,
-            devtoolModuleFilenameTemplate: '[relative-resource-path]'
+            devtoolModuleFilenameTemplate: '[absolute-resource-path]'
         },
         resolve: {
             extensions: ['.ts', '.js'],
@@ -71,6 +71,7 @@ module.exports = /*[
             oimo: 'OIMO',
             earcut: true
         },
+        mode: "development",
         devtool: 'source-map',
         plugins: [
             new webpack.WatchIgnorePlugin([
@@ -78,7 +79,7 @@ module.exports = /*[
             ])
         ],
         module: {
-            loaders: [{
+            rules: [{
                 test: /\.tsx?$/,
                 loader: 'ts-loader',
                 exclude: /node_modules/
@@ -98,7 +99,7 @@ module.exports = /*[
             },
             {
                 test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-                loader: 'base64-font-loader'
+                loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
             }]
         },
         devServer: {

+ 9 - 10
Viewer/webpack.gulp.config.js

@@ -1,7 +1,10 @@
+const path = require('path');
+const webpack = require('webpack');
+
 module.exports = {
-    //context: __dirname,
+    context: __dirname,
     entry: [
-        __dirname + '/src/index.ts'
+        path.resolve(__dirname, './src/index.ts')
     ],
     output: {
         libraryTarget: 'var',
@@ -22,15 +25,11 @@ module.exports = {
             "babylonjs-viewer-assets": __dirname + '/src/assets/index.ts'
         }
     },
+    mode: "production",
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
-            use: {
-                loader: 'ts-loader',
-                options: {
-                    configFile: 'tsconfig-gulp.json'
-                }
-            },
+            loader: 'ts-loader',
             exclude: /node_modules/
         },
         {
@@ -48,7 +47,7 @@ module.exports = {
         },
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
     }
 }

+ 1 - 2
dist/preview release/gui/package.json

@@ -11,9 +11,8 @@
     },
     "main": "babylon.gui.min.js",
     "files": [
-        "babylon.gui.js",
         "babylon.gui.min.js",
-        "babylon.gui.d.ts",
+        "babylon.gui.min.js.map",
         "babylon.gui.module.d.ts",
         "readme.md",
         "package.json"

+ 3 - 0
dist/preview release/inspector/package.json

@@ -12,9 +12,12 @@
     "main": "babylon.inspector.bundle.js",
     "files": [
         "babylon.inspector.bundle.js",
+        "babylon.inspector.bundle.js.map",
+        "babylon.inspector.module.d.ts",
         "readme.md",
         "package.json"
     ],
+    "typings": "babylon.inspector.module.d.ts",
     "keywords": [
         "3D",
         "javascript",

+ 1 - 0
dist/preview release/what's new.md

@@ -29,6 +29,7 @@
 - Playground can now be used with TypeScript directly!. [Demo](https://www.babylonjs-playground.com/ts.html) ([Deltakosh](https://github.com/deltakosh), [NasimiAsl](https://github.com/NasimiAsl))
 - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
 - Added dead key support and before key add observable to InputText. [Doc](https://doc.babylonjs.com/how_to/gui#using-onbeforekeyaddobservable-for-extended-keyboard-layouts-and-input-masks)([theom](https://github.com/theom))
+- GUI and Inspector are now ES-Modules ([RaananW](https://github.com/RaananW))
 - Added support for noise procedural textures. [Doc](http://doc.babylonjs.com/how_to/how_to_use_procedural_textures#noise-procedural-texture) ([Deltakosh](https://github.com/deltakosh))
 
 ## Updates

+ 41 - 0
gui/package.json

@@ -0,0 +1,41 @@
+{
+    "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",
+        "start:watch": "webpack -w",
+        "build:dev": "webpack",
+        "build:prod": "webpack --mode=production",
+        "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": {
+        "@types/node": "^10.5.2",
+        "clean-webpack-plugin": "^0.1.19",
+        "ts-loader": "^4.0.0",
+        "typescript": "^2.9.2",
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
+    },
+    "peerDependencies": {
+        "babylonjs": ">3.2.0"
+    },
+    "dependencies": {
+        "dts-bundle-webpack": "^1.0.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

File diff suppressed because it is too large
+ 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();
         }
-    }    
-}
+    }
+}   

File diff suppressed because it is too large
+ 1135 - 1159
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 };

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

@@ -0,0 +1,19 @@
+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";
+export * from "./stackPanel";
+export * from "./textBlock";
+export * from "./virtualKeyboard";
+export * from "./slider";
+export * from "./rectangle";
+
+export * from "./statics";

+ 10 - 12
gui/src/2D/controls/inputPassword.ts

@@ -1,16 +1,14 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { InputText } from "./inputText";
 
-module BABYLON.GUI {
-    /**
-     * Class used to create a password control
-     */
-    export class InputPassword extends InputText {
-        protected _beforeRenderText(text: string): string {
-            let txt = "";
-            for (let i = 0; i < text.length; i++) {
-                txt += "\u2022";
-            }
-            return txt;
+/**
+ * Class used to create a password control
+ */
+export class InputPassword extends InputText {
+    protected _beforeRenderText(text: string): string {
+        let txt = "";
+        for (let i = 0; i < text.length; i++) {
+            txt += "\u2022";
         }
+        return txt;
     }
 }

+ 426 - 424
gui/src/2D/controls/inputText.ts

@@ -1,536 +1,538 @@
-/// <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>;
+    private _deadKey = false;
+    private _addKey = true;
+    private _currentKey = "";
+
+    /** 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 just before an entered character is to be added */
+    public onBeforeKeyAddObservable = 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>;
-        private _deadKey = false;
-        private _addKey = true;
-        private _currentKey = "";
-
-        /** 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 just before an entered character is to be added */
-        public onBeforeKeyAddObservable = 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 dead key flag */
+    public get deadKey(): boolean {
+        return this._deadKey;
+    }
 
-        public set placeholderText(value: string) {
-            if (this._placeholderText === value) {
-                return;
-            }
-            this._placeholderText = value;
-            this._markAsDirty();
-        }
+    public set deadKey(flag: boolean) {
+        this._deadKey = flag;
+    }
 
-        /** Gets or sets the dead key flag */
-        public get deadKey(): boolean {
-            return this._deadKey;
-        }
+    /** Gets or sets if the current key should be added */
+    public get addKey(): boolean {
+        return this._addKey;
+    }
 
-        public set deadKey(flag: boolean) {
-            this._deadKey = flag;
-        }
+    public set addKey(flag: boolean) {
+        this._addKey = flag;
+    }
 
-        /** Gets or sets if the current key should be added */
-        public get addKey(): boolean {
-            return this._addKey;
-        }
+    /** Gets or sets the value of the current key being entered */
+    public get currentKey(): string {
+        return this._currentKey;
+    }
 
-        public set addKey(flag: boolean) {
-            this._addKey = flag;
-        }
+    public set currentKey(key: string) {
+        this._currentKey = key;
+    }
 
-        /** Gets or sets the value of the current key being entered */
-        public get currentKey(): string {
-            return this._currentKey;
-        }
+    /** Gets or sets the text displayed in the control */
+    public get text(): string {
+        return this._text;
+    }
 
-        public set currentKey(key: string) {
-            this._currentKey = key;
+    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;
-                case 222: // Dead
-                    this.deadKey = true;
-                    return;
-            }
+                }
+                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;
+            case 222: // Dead
+                this.deadKey = true;
+                return;
+        }
 
-            // Printable characters
-            if (key &&
-                ((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
-                this._currentKey = key;
-                this.onBeforeKeyAddObservable.notifyObservers(this);
-                key = this._currentKey;
-                if (this._addKey) {
-                    if (this._cursorOffset === 0) {
-                        this.text += key;
-                    } else {
-                        let insertPosition = this._text.length - this._cursorOffset;
+        // Printable characters
+        if (key &&
+            ((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
+            this._currentKey = key;
+            this.onBeforeKeyAddObservable.notifyObservers(this);
+            key = this._currentKey;
+            if (this._addKey) {
+                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);
-                    }
+                    this.text = this._text.slice(0, insertPosition) + key + this._text.slice(insertPosition);
                 }
             }
         }
+    }
 
-        /** @hidden */
-        public processKeyboard(evt: KeyboardEvent): void {
-            this.processKey(evt.keyCode, evt.key);
-        }
-
-        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._beforeRenderText(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._beforeRenderText(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 = <any>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;
-
-            return true;
         }
+        context.restore();
+    }
 
-        public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
         }
 
-        protected _beforeRenderText(text: string): string {
-            return text;
+        this._clickedCoordinate = coordinates.x;
+        if (this._host.focusedControl === this) {
+            // Move cursor
+            clearTimeout(this._blinkTimeout);
+            this._markAsDirty();
+            return true;
         }
+        this._host.focusedControl = this;
+
+        return true;
+    }
 
-        public dispose() {
-            super.dispose();
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
 
-            this.onBlurObservable.clear();
-            this.onFocusObservable.clear();
-            this.onTextChangedObservable.clear();
-        }
+    protected _beforeRenderText(text: string): string {
+        return text;
+    }
+
+    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);
+    }
+}  

+ 53 - 0
gui/src/2D/controls/statics.ts

@@ -0,0 +1,53 @@
+import { Control } from "./control";
+import { StackPanel } from "./stackPanel";
+import { TextBlock } from "./textBlock";
+
+/**
+ * Forcing an export so that this code will execute
+ * @hidden
+ */
+const name = "Statics";
+
+export { name };
+
+/**
+ * Creates a stack panel that can be used to render headers
+ * @param control defines the control to associate with the header
+ * @param text defines the text of the header
+ * @param size defines the size of the header
+ * @param options defines options used to configure the header
+ * @returns a new StackPanel
+ */
+Control.AddHeader = function (control: Control, text: string, size: string | number, options: { isHorizontal: boolean, controlFirst: boolean }): StackPanel {
+    let panel = new StackPanel("panel");
+    let isHorizontal = options ? options.isHorizontal : true;
+    let controlFirst = options ? options.controlFirst : true;
+
+    panel.isVertical = !isHorizontal;
+
+    let header = new TextBlock("header");
+    header.text = text;
+    header.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+    if (isHorizontal) {
+        header.width = size;
+    } else {
+        header.height = size;
+    }
+
+    if (controlFirst) {
+        panel.addControl(control);
+        panel.addControl(header);
+        header.paddingLeft = "5px";
+    } else {
+        panel.addControl(header);
+        panel.addControl(control);
+        header.paddingRight = "5px";
+    }
+
+    header.shadowBlur = control.shadowBlur;
+    header.shadowColor = control.shadowColor;
+    header.shadowOffsetX = control.shadowOffsetX;
+    header.shadowOffsetY = control.shadowOffsetY;
+
+    return panel;
+}

+ 329 - 328
gui/src/2D/controls/textBlock.ts

@@ -1,414 +1,415 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Observable } from "babylonjs";
+import { Measure } from "../measure";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Control } from "./control";
+
+/**
+ * Enum that determines the text-wrapping mode to use.
+ */
+export enum TextWrapping {
+    /**
+     * Clip the text when it's larger than Control.width; this is the default mode.
+     */
+    Clip = 0,
 
-module BABYLON.GUI {
     /**
-     * Enum that determines the text-wrapping mode to use.
+     * Wrap the text word-wise, i.e. try to add line-breaks at word boundary to fit within Control.width.
      */
-    export enum TextWrapping {
-        /**
-         * Clip the text when it's larger than Control.width; this is the default mode.
-         */
-        Clip = 0,
+    WordWrap = 1,
 
-        /**
-         * Wrap the text word-wise, i.e. try to add line-breaks at word boundary to fit within Control.width.
-         */
-        WordWrap = 1,
+    /**
+     * Ellipsize the text, i.e. shrink with trailing … when text is larger than Control.width.
+     */
+    Ellipsis,
+}
+
+/**
+ * Class used to create text block control
+ */
+export class TextBlock extends Control {
+    private _text = "";
+    private _textWrapping = TextWrapping.Clip;
+    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>();
 
-        /**
-         * Ellipsize the text, i.e. shrink with trailing … when text is larger than Control.width.
-         */
-        Ellipsis,
+    /**
+    * An event triggered after the text was broken up into lines
+    */
+    public onLinesReadyObservable = new Observable<TextBlock>();
+
+    /**
+     * 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;
     }
 
     /**
-     * Class used to create text block control
+     * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
      */
-    export class TextBlock extends Control {
-        private _text = "";
-        private _textWrapping = TextWrapping.Clip;
-        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 resizeToFit(): boolean {
+        return this._resizeToFit;
+    }
 
-        /**
-        * 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 set resizeToFit(value: boolean) {
+        this._resizeToFit = value;
 
-        /**
-         * 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;
+        if (this._resizeToFit) {
+            this._width.ignoreAdaptiveScaling = true;
+            this._height.ignoreAdaptiveScaling = true;
         }
+    }
 
-        /**
-         * 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;
-            }
-        }
+    /**
+     * Gets or sets a boolean indicating if text must be wrapped
+     */
+    public get textWrapping(): TextWrapping | boolean {
+        return this._textWrapping;
+    }
 
-        /**
-         * Gets or sets a boolean indicating if text must be wrapped
-         */
-        public get textWrapping(): TextWrapping | boolean {
-            return this._textWrapping;
+    /**
+     * Gets or sets a boolean indicating if text must be wrapped
+     */
+    public set textWrapping(value: TextWrapping | 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: TextWrapping | 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 (BABYLON.GUI.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 (BABYLON.GUI.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 (BABYLON.GUI.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 (BABYLON.GUI.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 = this._breakLines(this._currentMeasure.width, context);
+        this.onLinesReadyObservable.notifyObservers(this);
+    }
 
-            if (this._processMeasures(parentMeasure, context)) {
-                // Render lines
-                this._renderLines(context);
-            }
-            context.restore();
-        }
+    protected _breakLines(refWidth: number, context: CanvasRenderingContext2D): object[] {
+        var lines = [];
+        var _lines = this.text.split("\n");
 
-        protected _applyStates(context: CanvasRenderingContext2D): void {
-            super._applyStates(context);
-            if (this.outlineWidth) {
-                context.lineWidth = this.outlineWidth;
-                context.strokeStyle = this.outlineColor;
+        if (this._textWrapping === TextWrapping.Ellipsis && !this._resizeToFit) {
+            for (var _line of _lines) {
+                lines.push(this._parseLineEllipsis(_line, refWidth, context));
+            }
+        } else if (this._textWrapping === TextWrapping.WordWrap && !this._resizeToFit) {
+            for (var _line of _lines) {
+                lines.push(...this._parseLineWordWrap(_line, refWidth, context));
+            }
+        } else {
+            for (var _line of _lines) {
+                lines.push(this._parseLine(_line, context));
             }
         }
 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            this._lines = this._breakLines(this._currentMeasure.width, context);
-            this.onLinesReadyObservable.notifyObservers(this);
-        }
+        return lines;
+    }
 
-        protected _breakLines(refWidth: number, context: CanvasRenderingContext2D): object[] {
-            var lines = [];
-            var _lines = this.text.split("\n");
+    protected _parseLine(line: string = '', context: CanvasRenderingContext2D): object {
+        return { text: line, width: context.measureText(line).width };
+    }
 
-            if (this._textWrapping === TextWrapping.Ellipsis && !this._resizeToFit) {
-                for (var _line of _lines) {
-                    lines.push(this._parseLineEllipsis(_line, refWidth, context));
-                }
-            } else if (this._textWrapping === TextWrapping.WordWrap && !this._resizeToFit) {
-                for (var _line of _lines) {
-                    lines.push(...this._parseLineWordWrap(_line, refWidth, context));
-                }
-            } else {
-                for (var _line of _lines) {
-                    lines.push(this._parseLine(_line, context));
-                }
-            }
+    protected _parseLineEllipsis(line: string = '', width: number,
+        context: CanvasRenderingContext2D): object {
+        var lineWidth = context.measureText(line).width;
 
-            return lines;
+        if (lineWidth > width) {
+            line += '…';
         }
-
-        protected _parseLine(line: string = '', context: CanvasRenderingContext2D): object {
-            return { text: line, width: context.measureText(line).width };
+        while (line.length > 2 && lineWidth > width) {
+            line = line.slice(0, -2) + '…';
+            lineWidth = context.measureText(line).width;
         }
 
-        protected _parseLineEllipsis(line: string = '', width: number,
-                                     context: CanvasRenderingContext2D): object {
-            var lineWidth = context.measureText(line).width;
+        return { text: line, width: lineWidth };
+    }
 
-            if (lineWidth > width) {
-                line += '…';
-            }
-            while (line.length > 2 && lineWidth > width) {
-                line = line.slice(0, -2) + '…';
+    protected _parseLineWordWrap(line: string = '', width: number,
+        context: CanvasRenderingContext2D): object[] {
+        var lines = [];
+        var words = line.split(' ');
+        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) {
+                lines.push({ text: line, width: lineWidth });
+                line = words[n];
                 lineWidth = context.measureText(line).width;
             }
-
-            return { text: line, width: lineWidth };
-        }
-
-        protected _parseLineWordWrap(line: string = '', width: number,
-                                     context: CanvasRenderingContext2D): object[] {
-            var lines = [];
-            var words = line.split(' ');
-            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) {
-                    lines.push({ text: line, width: lineWidth });
-                    line = words[n];
-                    lineWidth = context.measureText(line).width;
-                }
-                else {
-                    lineWidth = testWidth;
-                    line = testLine;
-                }
+            else {
+                lineWidth = testWidth;
+                line = testLine;
             }
-            lines.push({ text: line, width: lineWidth });
-
-            return lines;
         }
+        lines.push({ text: line, width: lineWidth });
 
-        protected _renderLines(context: CanvasRenderingContext2D): void {
-            var height = this._currentMeasure.height;
+        return lines;
+    }
 
-            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;
 
-            rootY += this._currentMeasure.top;
+        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;
+        }
 
-            var maxLineWidth: number = 0;
+        rootY += this._currentMeasure.top;
 
-            for (let i = 0; i < this._lines.length; i++) {
-                const line = this._lines[i];
+        var maxLineWidth: number = 0;
 
-                if (i !== 0 && this._lineSpacing.internalValue !== 0) {
+        for (let i = 0; i < this._lines.length; i++) {
+            const line = this._lines[i];
 
-                    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 (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));
                 }
+            }
 
-                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';
         }
+    }
 
-        /**
-         * Given a width constraint applied on the text block, find the expected height
-         * @returns expected height
-         */
-        public computeExpectedHeight(): number {
-            if (this.text && this.widthInPixels) {
-                const context = document.createElement('canvas').getContext('2d');
-                if (context) {
-                    this._applyStates(context);
-                    if (!this._fontOffset) {
-                        this._fontOffset = Control._GetFontOffset(context.font);
-                    }
-                    const lines = this._lines ? this._lines : this._breakLines(
-                        this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context);
-                    return this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
+    /**
+     * Given a width constraint applied on the text block, find the expected height
+     * @returns expected height
+     */
+    public computeExpectedHeight(): number {
+        if (this.text && this.widthInPixels) {
+            const context = document.createElement('canvas').getContext('2d');
+            if (context) {
+                this._applyStates(context);
+                if (!this._fontOffset) {
+                    this._fontOffset = Control._GetFontOffset(context.font);
                 }
+                const lines = this._lines ? this._lines : this._breakLines(
+                    this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context);
+                return this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
             }
-            return 0;
         }
+        return 0;
+    }
 
-        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();
         }
     }
 }

+ 121 - 122
gui/src/3D/controls/container3D.ts

@@ -1,161 +1,160 @@
-/// <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;
 
-        /**
-         * Force the container to update the layout. Please note that it will not take blockLayout property in account
-         * @returns the current container
-         */
-        public updateLayout(): Container3D {
+        if (!this._blockLayout) {
             this._arrangeChildren();
-            return this;
         }
+    }
 
-        /**
-         * 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;
-        }
+    /**
+     * Creates a new container
+     * @param name defines the container name
+     */
+    constructor(name?: string) {
+        super(name);
+    }
+
+    /**
+     * Force the container to update the layout. Please note that it will not take blockLayout property in account
+     * @returns the current container
+     */
+    public updateLayout(): Container3D {
+        this._arrangeChildren();
+        return this;
+    }
 
-        /**
-         * 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);
+    /**
+     * 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 (index !== -1) {
-                return this;
-            }
-            control.parent = this;
-            control._host = this._host;
+    /**
+     * 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);
 
-            this._children.push(control);
+        if (index !== -1) {
+            return this;
+        }
+        control.parent = this;
+        control._host = this._host;
 
-            if (this._host.utilityLayer) {
-                control._prepareNode(this._host.utilityLayer.utilityLayerScene);
+        this._children.push(control);
 
-                if (control.node) {
-                    control.node.parent = this.node;
-                }
+        if (this._host.utilityLayer) {
+            control._prepareNode(this._host.utilityLayer.utilityLayerScene);
 
-                if (!this.blockLayout) {
-                    this._arrangeChildren();
-                }
+            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 = [];
 
-        /** Control will rotate to make it look at sphere central axis */
-        public static readonly FACEORIGIN_ORIENTATION = 1;
+        super.dispose();
+    }
 
-        /** Control will rotate to make it look back at sphere central axis */
-        public static readonly FACEORIGINREVERSED_ORIENTATION = 2;
+    /** Control rotation will remain unchanged  */
+    public static readonly UNSET_ORIENTATION = 0;
 
-        /** Control will rotate to look at z axis (0, 0, 1) */
-        public static readonly FACEFORWARD_ORIENTATION = 3;
+    /** Control will rotate to make it look at sphere central axis */
+    public static readonly FACEORIGIN_ORIENTATION = 1;
 
-        /** Control will rotate to look at negative z axis (0, 0, -1) */
-        public static readonly FACEFORWARDREVERSED_ORIENTATION = 4;
+    /** Control will rotate to make it look back at sphere central axis */
+    public static readonly FACEORIGINREVERSED_ORIENTATION = 2;
 
-    }
-}
+    /** 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,64 +1,64 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { float, 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 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, newPos.y, -newPos.z));
-                    break;
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(2 * newPos.x, newPos.y, 2 * newPos.z));
-                    break;
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                    mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
-                    break;
-            }            
+        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(2 * newPos.x, newPos.y, 2 * newPos.z));
+                break;
+            case Container3D.FACEFORWARD_ORIENTATION:
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+                mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
+                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) {
     }
 }

+ 29 - 28
gui/src/3D/controls/planePanel.ts

@@ -1,35 +1,36 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Tmp, Vector3 } from "babylonjs";
+import { Container3D } from "./container3D";
+import { Control3D } from "./control3D";
+import { VolumeBasedPanel } from "./volumeBasedPanel";
 
-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();
-            let target = Tmp.Vector3[0];
+        control.position = nodePosition.clone();
+        let target = Tmp.Vector3[0];
 
-            target.copyFrom(nodePosition);
+        target.copyFrom(nodePosition);
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    target.addInPlace(new BABYLON.Vector3(0, 0, -1));
-                    mesh.lookAt(target);
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    target.addInPlace(new BABYLON.Vector3(0, 0, 1));
-                    mesh.lookAt(target);
-                    break;
-            }
-            
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+            case Container3D.FACEFORWARD_ORIENTATION:
+                target.addInPlace(new BABYLON.Vector3(0, 0, -1));
+                mesh.lookAt(target);
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                target.addInPlace(new BABYLON.Vector3(0, 0, 1));
+                mesh.lookAt(target);
+                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,66 +1,66 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { float, 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(): float {
+        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: 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;
-            }
+        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(2 * newPos.x, 2 * newPos.y, 2 * newPos.z));
-                    break;
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                    mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
-                    break;
-            }           
+        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(2 * newPos.x, 2 * newPos.y, 2 * newPos.z));
+                break;
+            case Container3D.FACEFORWARD_ORIENTATION:
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+                mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
+                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)
         }
     }
-}
+}

+ 155 - 161
gui/src/3D/controls/volumeBasedPanel.ts

@@ -1,197 +1,191 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container3D } from "./container3D";
+import { Tools, int, Matrix, Tmp, Vector3 } from "babylonjs";
+import { Control3D } from "./control3D";
+
+/**
+ * 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 (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) |
      */
-    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(): int {
+        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: int) {
+        if (this._columns === value) {
+            return;
         }
 
-        public set columns(value: int) {
-            if (this._columns === value) {
-                return;
-            }
+        this._columns = value;
+        this._rowThenColum = true;
 
-            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;
-        }
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-        public set rows(value: int) {
-            if (this._rows === value) {
-                return;
-            }
+    /**
+     * 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;
+    }
 
-            this._rows = value;
-            this._rowThenColum = false;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }           
-
-        /**
-         * Creates new VolumeBasedPanel
-         */
-        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;
-                }
+    public set rows(value: int) {
+        if (this._rows === value) {
+            return;
+        }
 
-                controlCount++;
-                child.mesh.computeWorldMatrix(true);
-             //   child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
+        this._rows = value;
+        this._rowThenColum = false;
 
-                let boundingBox = child.mesh.getHierarchyBoundingVectors();
-                let extendSize = Tmp.Vector3[0];
-                let diff = Tmp.Vector3[1];
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
-                boundingBox.max.subtractToRef(boundingBox.min, diff);
+    /**
+     * Creates new VolumeBasedPanel
+     */
+    public constructor() {
+        super();
+    }
 
-                diff.scaleInPlace(0.5);
+    protected _arrangeChildren() {
+        this._cellWidth = 0;
+        this._cellHeight = 0;
+        let rows = 0;
+        let columns = 0;
+        let controlCount = 0;
 
-                Vector3.TransformNormalToRef(diff, currentInverseWorld, extendSize);
+        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.getHierarchyBoundingVectors();
+            let extendSize = Tmp.Vector3[0];
+            let diff = Tmp.Vector3[1];
+
+            boundingBox.max.subtractToRef(boundingBox.min, diff);
+
+            diff.scaleInPlace(0.5);
+
+            Vector3.TransformNormalToRef(diff, currentInverseWorld, extendSize);
+
+            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";

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

@@ -1,279 +1,281 @@
-/// <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";
+
+import { registerShader } from "./shaders/fluent";
+
+// register shaders
+registerShader();
+
+/** @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;
 
-            var engine = scene.getEngine();
-            // Get correct effect      
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
+    /**
+     * Gets or sets a value indicating the smoothing value applied to border edges (0.02 by default)
+     */
+    @serialize()
+    public edgeSmoothingValue = 0.02;
 
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-                attribs.push(VertexBuffer.NormalKind);
-                attribs.push(VertexBuffer.UVKind);
+    /**
+     * Gets or sets the minimum value that can be applied to border width (default is 0.1)
+     */
+    @serialize()
+    public borderMinValue = 0.1;
 
-                var shaderName = "fluent";
+    /**
+     * Gets or sets a boolean indicating if hover light must be rendered (default is false)
+     */
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public renderHoverLight = false;
 
-                var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue",
-                                "hoverColor", "hoverPosition", "hoverRadius"
-                ];
+    /**
+     * Gets or sets the radius used to render the hover light (default is 0.15)
+     */
+    @serialize()
+    public hoverRadius = 1.0;
 
-                var samplers = new Array<String>();
-                var uniformBuffers = new Array<string>();
+    /**
+     * 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);
 
-                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));            
-                
-            }
+    /**
+     * 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);
+    }
+
+    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 - 0
gui/src/3D/materials/shaders/fluent.ts

@@ -0,0 +1,12 @@
+import { Effect } from "babylonjs";
+
+const fShader = require("./fluent.fragment.fx");
+const vShader = require("./fluent.vertex.fx");
+
+export function registerShader() {
+    // register shaders
+    Effect.ShadersStore["fluentVertexShader"] = vShader;
+    Effect.ShadersStore["fluentPixelShader"] = fShader;
+}
+
+export { fShader, vShader };

+ 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": "./src/",
+        "paths": {
+            "babylonjs": [
+                "../../dist/preview release/babylon.d.ts"
+            ]
+        },
+        "outDir": "./build"
+    }
+}

+ 76 - 0
gui/webpack.config.js

@@ -0,0 +1,76 @@
+const path = require('path');
+const webpack = require('webpack');
+const DtsBundleWebpack = require('dts-bundle-webpack');
+const CleanWebpackPlugin = require('clean-webpack-plugin');
+
+module.exports = {
+    context: __dirname,
+    entry: {
+        'babylonjs-gui': path.resolve(__dirname, './src/index.ts'),
+    },
+    output: {
+        path: path.resolve(__dirname, '../dist/preview release/gui'),
+        filename: 'babylon.gui.min.js',
+        libraryTarget: 'umd',
+        library: {
+            root: ["BABYLON", "GUI"],
+            amd: "babylonjs-gui",
+            commonjs: "babylonjs-gui"
+        },
+        umdNamedDefine: true,
+        //devtoolModuleFilenameTemplate: "[absolute-resource-path]"
+    },
+    resolve: {
+        extensions: [".js", '.ts']
+    },
+    externals: {
+        babylonjs: {
+            root: "BABYLON",
+            commonjs: "babylonjs",
+            commonjs2: "babylonjs",
+            amd: "babylonjs"
+        }
+    },
+    devtool: "source-map",
+    module: {
+        rules: [{
+            test: /\.tsx?$/,
+            loader: "ts-loader",
+            exclude: /node_modules/
+        },
+        {
+            test: /\.fx$/,
+            use: [{
+                loader: path.resolve(__dirname, '../Tools/WebpackShaderLoader/index.js')
+            }]
+        }]
+    },
+    mode: "production",
+    devServer: {
+        contentBase: path.join(__dirname, "dist"),
+        compress: false,
+        //open: true,
+        port: 9000
+    },
+    plugins: [
+        new CleanWebpackPlugin([
+            path.resolve(__dirname, './src/**/*.js'),
+            path.resolve(__dirname, './src/**/*.map')
+        ]),
+        // moved out of here due to the way gulp works...
+        /*new DtsBundleWebpack({
+            name: "babylonjs-gui",
+            main: path.resolve(__dirname, '../dist/preview release/gui/build/index.d.ts'),
+            out: path.resolve(__dirname, '../dist/preview release/gui/babylon.gui.module.d.ts'),
+            baseDir: path.resolve(__dirname, '../dist/preview release/gui/build/'),
+            headerText: "BabylonJS GUI"
+        }),*/
+        new webpack.WatchIgnorePlugin([
+            /\.js$/,
+            /\.d\.ts$/
+        ])
+    ],
+    watchOptions: {
+        ignored: [path.resolve(__dirname, './dist/**/*.*'), 'node_modules']
+    }
+}

+ 47 - 0
inspector/package.json

@@ -0,0 +1,47 @@
+{
+    "name": "babylonjs-inspector",
+    "version": "1.0.0",
+    "description": "",
+    "scripts": {
+        "start:server": "webpack-dev-server",
+        "start:watch": "webpack -w",
+        "build:dev": "webpack",
+        "build:prod": "webpack --mode=production",
+        "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": {
+        "@types/node": "^10.5.2",
+        "clean-webpack-plugin": "^0.1.19",
+        "css-loader": "^1.0.0",
+        "dts-bundle-webpack": "^1.0.0",
+        "mini-css-extract-plugin": "^0.4.1",
+        "node-sass": "^4.9.2",
+        "sass-loader": "^7.0.3",
+        "style-loader": "^0.21.0",
+        "ts-loader": "^4.0.0",
+        "typescript": "^2.9.2",
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
+    },
+    "peerDependencies": {
+        "babylonjs": ">3.2.0",
+        "babylonjs-gui": ">3.2.0",
+        "babylonjs-loaders": ">3.2.0"
+    },
+    "dependencies": {}
+}

+ 375 - 368
inspector/src/Inspector.ts

@@ -1,421 +1,428 @@
-module INSPECTOR {
-    export class Inspector {
-
-        private _c2diwrapper: HTMLElement;
-        // private _detailsPanel: DetailPanel;
-        /** The panel displayed at the top of the inspector */
-        private _topPanel: HTMLElement;
-        /** The div containing the content of the active tab */
-        private _tabPanel: HTMLElement;
-        /** The panel containing the list if items */
-        // private _treePanel   : HTMLElement;
-        private _tabbar: TabBar;
-        private _scene: BABYLON.Scene;
-        /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
-        public static DOCUMENT: HTMLDocument;
-        /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
-        public static WINDOW: Window;
-        /** True if the inspector is built as a popup tab */
-        private _popupMode: boolean = false;
-        /** The original canvas style, before applying the inspector*/
-        private _canvasStyle: any;
-
-        private _initialTab: number;
-
-        private _parentElement: BABYLON.Nullable<HTMLElement>;
-
-        /** The inspector is created with the given engine.
-         * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
-         * If the parameter 'popup' is true, the inspector is created in another popup.
-         */
-        constructor(scene: BABYLON.Scene, popup?: boolean, initialTab: number = 0, parentElement: BABYLON.Nullable<HTMLElement> = null, newColors?: {
-            backgroundColor?: string,
-            backgroundColorLighter?: string,
-            backgroundColorLighter2?: string,
-            backgroundColorLighter3?: string,
-            color?: string,
-            colorTop?: string,
-            colorBot?: string
-        }) {
-
-            // Load GUI library if not already done
-            if (!BABYLON.GUI) {
-                BABYLON.Tools.LoadScript("https://preview.babylonjs.com/gui/babylon.gui.js", () => {
-                    //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
-                    loadGUIProperties();
-                }, () => {
-                    console.warn('Error : loading "babylon.gui.js". Please add script https://preview.babylonjs.com/gui/babylon.gui.js to the HTML file.');
-                });
-            }
-            else {
-                //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
+import { AbstractMesh, Nullable, Scene, Tools } from "babylonjs";
+import * as GUI from "babylonjs-gui";
+import "../sass/main.scss";
+import { Helpers } from "./helpers/Helpers";
+import { loadGUIProperties } from "./properties_gui";
+import { Scheduler } from "./scheduler/Scheduler";
+import { TabBar } from "./tabs/TabBar";
+
+
+export class Inspector {
+
+    private _c2diwrapper: HTMLElement;
+    // private _detailsPanel: DetailPanel;
+    /** The panel displayed at the top of the inspector */
+    private _topPanel: HTMLElement;
+    /** The div containing the content of the active tab */
+    private _tabPanel: HTMLElement;
+    /** The panel containing the list if items */
+    // private _treePanel   : HTMLElement;
+    private _tabbar: TabBar;
+    private _scene: Scene;
+    /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
+    public static DOCUMENT: HTMLDocument;
+    /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
+    public static WINDOW: Window;
+    /** True if the inspector is built as a popup tab */
+    private _popupMode: boolean = false;
+    /** The original canvas style, before applying the inspector*/
+    private _canvasStyle: any;
+
+    private _initialTab: number;
+
+    private _parentElement: Nullable<HTMLElement>;
+
+    /** The inspector is created with the given engine.
+     * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
+     * If the parameter 'popup' is true, the inspector is created in another popup.
+     */
+    constructor(scene: Scene, popup?: boolean, initialTab: number = 0, parentElement: Nullable<HTMLElement> = null, newColors?: {
+        backgroundColor?: string,
+        backgroundColorLighter?: string,
+        backgroundColorLighter2?: string,
+        backgroundColorLighter3?: string,
+        color?: string,
+        colorTop?: string,
+        colorBot?: string
+    }) {
+
+        // Load GUI library if not already done
+        if (!GUI) {
+            Tools.LoadScript("https://preview.babylonjs.com/gui/gui.js", () => {
+                //Load properties of GUI objects now as GUI has to be declared before 
                 loadGUIProperties();
-            }
+            }, () => {
+                console.warn('Error : loading "gui.js". Please add script https://preview.babylonjs.com/gui/gui.js to the HTML file.');
+            });
+        }
+        else {
+            //Load properties of GUI objects now as GUI has to be declared before 
+            loadGUIProperties();
+        }
 
-            //get Tabbar initialTab
-            this._initialTab = initialTab;
+        //get Tabbar initialTab
+        this._initialTab = initialTab;
+
+        //get parentElement of our Inspector
+        this._parentElement = parentElement;
+
+        // get canvas parent only if needed.
+        this._scene = scene;
+
+        // Save HTML document and window
+        Inspector.DOCUMENT = window.document;
+        Inspector.WINDOW = window;
+
+        // POPUP MODE
+        if (popup) {
+            // Build the inspector in the given parent
+            this.openPopup(true);// set to true in order to NOT dispose the inspector (done in openPopup), as it's not existing yet
+        } else {
+            // Get canvas and its DOM parent
+            let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
+            let canvasParent = canvas.parentElement;
+
+            // get canvas style                
+            let canvasComputedStyle = Inspector.WINDOW.getComputedStyle(canvas);
+
+            this._canvasStyle = {
+                width: Helpers.Css(canvas, 'width'),
+                height: Helpers.Css(canvas, 'height'),
+
+                position: canvasComputedStyle.position,
+                top: canvasComputedStyle.top,
+                bottom: canvasComputedStyle.bottom,
+                left: canvasComputedStyle.left,
+                right: canvasComputedStyle.right,
+
+                padding: canvasComputedStyle.padding,
+                paddingBottom: canvasComputedStyle.paddingBottom,
+                paddingLeft: canvasComputedStyle.paddingLeft,
+                paddingTop: canvasComputedStyle.paddingTop,
+                paddingRight: canvasComputedStyle.paddingRight,
+
+                margin: canvasComputedStyle.margin,
+                marginBottom: canvasComputedStyle.marginBottom,
+                marginLeft: canvasComputedStyle.marginLeft,
+                marginTop: canvasComputedStyle.marginTop,
+                marginRight: canvasComputedStyle.marginRight
+
+            };
+
+            if (this._parentElement) {
+                // Build the inspector wrapper
+                this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', this._parentElement);
+                this._c2diwrapper.style.width = '100%';
+                this._c2diwrapper.style.height = '100%';
+                this._c2diwrapper.style.paddingLeft = '5px';
+
+                // add inspector     
+                let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+                inspector.style.width = '100%';
+                inspector.style.height = '100%';
+                // and build it in the popup  
+                this._buildInspector(inspector);
+            } else {
+                // Create c2di wrapper
+                this._c2diwrapper = Helpers.CreateDiv('insp-wrapper');
 
-            //get parentElement of our Inspector
-            this._parentElement = parentElement;
+                // copy style from canvas to wrapper
+                for (let prop in this._canvasStyle) {
+                    (<any>this._c2diwrapper.style)[prop] = this._canvasStyle[prop];
+                }
 
-            // get canvas parent only if needed.
-            this._scene = scene;
+                if (!canvasComputedStyle.width || !canvasComputedStyle.height || !canvasComputedStyle.left) {
+                    return;
+                }
 
-            // Save HTML document and window
-            Inspector.DOCUMENT = window.document;
-            Inspector.WINDOW = window;
+                // Convert wrapper size in % (because getComputedStyle returns px only)
+                let widthPx = parseFloat(canvasComputedStyle.width.substr(0, canvasComputedStyle.width.length - 2)) || 0;
+                let heightPx = parseFloat(canvasComputedStyle.height.substr(0, canvasComputedStyle.height.length - 2)) || 0;
 
-            // POPUP MODE
-            if (popup) {
-                // Build the inspector in the given parent
-                this.openPopup(true);// set to true in order to NOT dispose the inspector (done in openPopup), as it's not existing yet
-            } else {
-                // Get canvas and its DOM parent
-                let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
-                let canvasParent = canvas.parentElement;
-
-                // get canvas style                
-                let canvasComputedStyle = Inspector.WINDOW.getComputedStyle(canvas);
-
-                this._canvasStyle = {
-                    width: Helpers.Css(canvas, 'width'),
-                    height: Helpers.Css(canvas, 'height'),
-
-                    position: canvasComputedStyle.position,
-                    top: canvasComputedStyle.top,
-                    bottom: canvasComputedStyle.bottom,
-                    left: canvasComputedStyle.left,
-                    right: canvasComputedStyle.right,
-
-                    padding: canvasComputedStyle.padding,
-                    paddingBottom: canvasComputedStyle.paddingBottom,
-                    paddingLeft: canvasComputedStyle.paddingLeft,
-                    paddingTop: canvasComputedStyle.paddingTop,
-                    paddingRight: canvasComputedStyle.paddingRight,
-
-                    margin: canvasComputedStyle.margin,
-                    marginBottom: canvasComputedStyle.marginBottom,
-                    marginLeft: canvasComputedStyle.marginLeft,
-                    marginTop: canvasComputedStyle.marginTop,
-                    marginRight: canvasComputedStyle.marginRight
-
-                };
-
-                if (this._parentElement) {
-                    // Build the inspector wrapper
-                    this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', this._parentElement);
-                    this._c2diwrapper.style.width = '100%';
-                    this._c2diwrapper.style.height = '100%';
-                    this._c2diwrapper.style.paddingLeft = '5px';
-
-                    // add inspector     
-                    let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
-                    inspector.style.width = '100%';
-                    inspector.style.height = '100%';
-                    // and build it in the popup  
-                    this._buildInspector(inspector);
-                } else {
-                    // Create c2di wrapper
-                    this._c2diwrapper = Helpers.CreateDiv('insp-wrapper');
-
-                    // copy style from canvas to wrapper
-                    for (let prop in this._canvasStyle) {
-                        (<any>this._c2diwrapper.style)[prop] = this._canvasStyle[prop];
+                // If the canvas position is absolute, restrain the wrapper width to the window width + left positionning
+                if (canvasComputedStyle.position === "absolute" || canvasComputedStyle.position === "relative") {
+                    // compute only left as it takes predominance if right is also specified (and it will be for the wrapper)
+                    let leftPx = parseFloat(canvasComputedStyle.left.substr(0, canvasComputedStyle.left.length - 2)) || 0;
+                    if (widthPx + leftPx >= Inspector.WINDOW.innerWidth) {
+                        this._c2diwrapper.style.maxWidth = `${widthPx - leftPx}px`;
                     }
+                }
 
-                    if (!canvasComputedStyle.width || !canvasComputedStyle.height || !canvasComputedStyle.left) {
-                        return;
-                    }
 
-                    // Convert wrapper size in % (because getComputedStyle returns px only)
-                    let widthPx = parseFloat(canvasComputedStyle.width.substr(0, canvasComputedStyle.width.length - 2)) || 0;
-                    let heightPx = parseFloat(canvasComputedStyle.height.substr(0, canvasComputedStyle.height.length - 2)) || 0;
+                // Check if the parent of the canvas is the body page. If yes, the size ratio is computed
+                let parent = this._getRelativeParent(canvas);
 
-                    // If the canvas position is absolute, restrain the wrapper width to the window width + left positionning
-                    if (canvasComputedStyle.position === "absolute" || canvasComputedStyle.position === "relative") {
-                        // compute only left as it takes predominance if right is also specified (and it will be for the wrapper)
-                        let leftPx = parseFloat(canvasComputedStyle.left.substr(0, canvasComputedStyle.left.length - 2)) || 0;
-                        if (widthPx + leftPx >= Inspector.WINDOW.innerWidth) {
-                            this._c2diwrapper.style.maxWidth = `${widthPx - leftPx}px`;
-                        }
-                    }
+                let parentWidthPx = parent.clientWidth;
+                let parentHeightPx = parent.clientHeight;
 
+                let pWidth = widthPx / parentWidthPx * 100;
+                let pheight = heightPx / parentHeightPx * 100;
 
-                    // Check if the parent of the canvas is the body page. If yes, the size ratio is computed
-                    let parent = this._getRelativeParent(canvas);
+                this._c2diwrapper.style.width = pWidth + "%";
+                this._c2diwrapper.style.height = pheight + "%";
 
-                    let parentWidthPx = parent.clientWidth;
-                    let parentHeightPx = parent.clientHeight;
+                // reset canvas style
+                canvas.style.position = "static";
+                canvas.style.width = "100%";
+                canvas.style.height = "100%";
+                canvas.style.paddingBottom = "0";
+                canvas.style.paddingLeft = "0";
+                canvas.style.paddingTop = "0";
+                canvas.style.paddingRight = "0";
 
-                    let pWidth = widthPx / parentWidthPx * 100;
-                    let pheight = heightPx / parentHeightPx * 100;
+                canvas.style.margin = "0";
+                canvas.style.marginBottom = "0";
+                canvas.style.marginLeft = "0";
+                canvas.style.marginTop = "0";
+                canvas.style.marginRight = "0";
 
-                    this._c2diwrapper.style.width = pWidth + "%";
-                    this._c2diwrapper.style.height = pheight + "%";
+                // Replace canvas with the wrapper...
+                if (canvasParent) {
+                    canvasParent.replaceChild(this._c2diwrapper, canvas);
+                }
+                // ... and add canvas to the wrapper
+                this._c2diwrapper.appendChild(canvas);
+
+                // add inspector
+                let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+
+                // Add split bar
+                if (!this._parentElement) {
+                    Split([canvas, inspector], {
+                        direction: 'horizontal',
+                        sizes: [75, 25],
+                        onDrag: () => {
+                            Helpers.SEND_EVENT('resize');
+                            if (this._tabbar) {
+                                this._tabbar.updateWidth()
+                            }
+                        }
+                    });
+                }
 
-                    // reset canvas style
-                    canvas.style.position = "static";
-                    canvas.style.width = "100%";
-                    canvas.style.height = "100%";
-                    canvas.style.paddingBottom = "0";
-                    canvas.style.paddingLeft = "0";
-                    canvas.style.paddingTop = "0";
-                    canvas.style.paddingRight = "0";
+                // Build the inspector
+                this._buildInspector(inspector);
+            }
+            // Send resize event to the window
+            Helpers.SEND_EVENT('resize');
+            this._tabbar.updateWidth();
+        }
 
-                    canvas.style.margin = "0";
-                    canvas.style.marginBottom = "0";
-                    canvas.style.marginLeft = "0";
-                    canvas.style.marginTop = "0";
-                    canvas.style.marginRight = "0";
+        /*
+        * Refresh the inspector if the browser is not edge
+        *   Why not ?! Condition commented on 180525
+        *   To be tested
+        */
+        // if (!Helpers.IsBrowserEdge()) {
+        this.refresh();
+        // }
 
-                    // Replace canvas with the wrapper...
-                    if (canvasParent) {
-                        canvasParent.replaceChild(this._c2diwrapper, canvas);
-                    }
-                    // ... and add canvas to the wrapper
-                    this._c2diwrapper.appendChild(canvas);
-
-                    // add inspector
-                    let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
-
-                    // Add split bar
-                    if (!this._parentElement) {
-                        Split([canvas, inspector], {
-                            direction: 'horizontal',
-                            sizes: [75, 25],
-                            onDrag: () => {
-                                Helpers.SEND_EVENT('resize');
-                                if (this._tabbar) {
-                                    this._tabbar.updateWidth()
-                                }
-                            }
-                        });
-                    }
+        // Check custom css colors
+        if (newColors) {
 
-                    // Build the inspector
-                    this._buildInspector(inspector);
-                }
-                // Send resize event to the window
-                Helpers.SEND_EVENT('resize');
-                this._tabbar.updateWidth();
-            }
+            let bColor = newColors.backgroundColor || '#242424';
+            let bColorl1 = newColors.backgroundColorLighter || '#2c2c2c';
+            let bColorl2 = newColors.backgroundColorLighter2 || '#383838';
+            let bColorl3 = newColors.backgroundColorLighter3 || '#454545';
 
-            /*
-            * Refresh the inspector if the browser is not edge
-            *   Why not ?! Condition commented on 180525
-            *   To be tested
-            */
-            // if (!Helpers.IsBrowserEdge()) {
-                this.refresh();
-            // }
-
-            // Check custom css colors
-            if (newColors) {
-
-                let bColor = newColors.backgroundColor || '#242424';
-                let bColorl1 = newColors.backgroundColorLighter || '#2c2c2c';
-                let bColorl2 = newColors.backgroundColorLighter2 || '#383838';
-                let bColorl3 = newColors.backgroundColorLighter3 || '#454545';
-
-                let color = newColors.color || '#ccc';
-                let colorTop = newColors.colorTop || '#f29766';
-                let colorBot = newColors.colorBot || '#5db0d7';
-
-                let styles = Inspector.DOCUMENT.querySelectorAll('style');
-                for (let s = 0; s < styles.length; s++) {
-                    let style = styles[s];
-
-                    if (style.innerHTML.indexOf('insp-wrapper') != -1) {
-
-                        styles[s].innerHTML = styles[s].innerHTML
-                            .replace(/#242424/g, bColor) // background color
-                            .replace(/#2c2c2c/g, bColorl1) // background-lighter
-                            .replace(/#383838/g, bColorl2) // background-lighter2
-                            .replace(/#454545/g, bColorl3) // background-lighter3
-                            .replace(/#ccc/g, color) // color
-                            .replace(/#f29766/g, colorTop) // color-top
-                            .replace(/#5db0d7/g, colorBot) // color-bot
-                    }
+            let color = newColors.color || '#ccc';
+            let colorTop = newColors.colorTop || '#f29766';
+            let colorBot = newColors.colorBot || '#5db0d7';
+
+            let styles = Inspector.DOCUMENT.querySelectorAll('style');
+            for (let s = 0; s < styles.length; s++) {
+                let style = styles[s];
+
+                if (style.innerHTML.indexOf('insp-wrapper') != -1) {
+
+                    styles[s].innerHTML = styles[s].innerHTML
+                        .replace(/#242424/g, bColor) // background color
+                        .replace(/#2c2c2c/g, bColorl1) // background-lighter
+                        .replace(/#383838/g, bColorl2) // background-lighter2
+                        .replace(/#454545/g, bColorl3) // background-lighter3
+                        .replace(/#ccc/g, color) // color
+                        .replace(/#f29766/g, colorTop) // color-top
+                        .replace(/#5db0d7/g, colorBot) // color-bot
                 }
             }
         }
+    }
 
-        /**
-         * If the given element has a position 'asbolute' or 'relative', 
-         * returns the first parent of the given element that has a position 'relative' or 'absolute'.
-         * If the given element has no position, returns the first parent
-         * 
-         */
-        private _getRelativeParent(elem: HTMLElement, lookForAbsoluteOrRelative?: boolean): HTMLElement {
-            // If the elem has no parent, returns himself
-            if (!elem.parentElement) {
+    /**
+     * If the given element has a position 'asbolute' or 'relative', 
+     * returns the first parent of the given element that has a position 'relative' or 'absolute'.
+     * If the given element has no position, returns the first parent
+     * 
+     */
+    private _getRelativeParent(elem: HTMLElement, lookForAbsoluteOrRelative?: boolean): HTMLElement {
+        // If the elem has no parent, returns himself
+        if (!elem.parentElement) {
+            return elem;
+        }
+        let computedStyle = Inspector.WINDOW.getComputedStyle(elem);
+        // looking for the first element absolute or relative
+        if (lookForAbsoluteOrRelative) {
+            // if found, return this one
+            if (computedStyle.position === "relative" || computedStyle.position === "absolute") {
                 return elem;
+            } else {
+                // otherwise keep looking
+                return this._getRelativeParent(elem.parentElement, true);
             }
-            let computedStyle = Inspector.WINDOW.getComputedStyle(elem);
-            // looking for the first element absolute or relative
-            if (lookForAbsoluteOrRelative) {
-                // if found, return this one
-                if (computedStyle.position === "relative" || computedStyle.position === "absolute") {
-                    return elem;
-                } else {
-                    // otherwise keep looking
-                    return this._getRelativeParent(elem.parentElement, true);
-                }
-            }
-            // looking for the relative parent of the element 
-            else {
-                if (computedStyle.position == "static") {
-                    return elem.parentElement;
-                } else {
-                    // the elem has a position relative or absolute, look for the closest relative/absolute parent
-                    return this._getRelativeParent(elem.parentElement, true);
-                }
+        }
+        // looking for the relative parent of the element 
+        else {
+            if (computedStyle.position == "static") {
+                return elem.parentElement;
+            } else {
+                // the elem has a position relative or absolute, look for the closest relative/absolute parent
+                return this._getRelativeParent(elem.parentElement, true);
             }
         }
+    }
 
-        /** Build the inspector panel in the given HTML element */
-        private _buildInspector(parent: HTMLElement) {
-            // tabbar
-            this._tabbar = new TabBar(this, this._initialTab);
-
-            // Top panel
-            this._topPanel = Helpers.CreateDiv('top-panel', parent);
-            // Add tabbar
-            this._topPanel.appendChild(this._tabbar.toHtml());
-            this._tabbar.updateWidth();
+    /** Build the inspector panel in the given HTML element */
+    private _buildInspector(parent: HTMLElement) {
+        // tabbar
+        this._tabbar = new TabBar(this, this._initialTab);
 
-            // Tab panel
-            this._tabPanel = Helpers.CreateDiv('tab-panel-content', this._topPanel);
+        // Top panel
+        this._topPanel = Helpers.CreateDiv('top-panel', parent);
+        // Add tabbar
+        this._topPanel.appendChild(this._tabbar.toHtml());
+        this._tabbar.updateWidth();
 
-        }
+        // Tab panel
+        this._tabPanel = Helpers.CreateDiv('tab-panel-content', this._topPanel);
 
-        public get scene(): BABYLON.Scene {
-            return this._scene;
-        }
-        public get popupMode(): boolean {
-            return this._popupMode;
-        }
+    }
 
-        /**  
-         * Filter the list of item present in the tree.
-         * All item returned should have the given filter contained in the item id.
-        */
-        public filterItem(filter: string) {
-            let tab = this._tabbar.getActiveTab();
+    public get scene(): Scene {
+        return this._scene;
+    }
+    public get popupMode(): boolean {
+        return this._popupMode;
+    }
 
-            if (tab) {
-                tab.filter(filter);
-            }
-        }
+    /**  
+     * Filter the list of item present in the tree.
+     * All item returned should have the given filter contained in the item id.
+    */
+    public filterItem(filter: string) {
+        let tab = this._tabbar.getActiveTab();
 
-        /** Display the mesh tab on the given object */
-        public displayObjectDetails(mesh: BABYLON.AbstractMesh) {
-            this._tabbar.switchMeshTab(mesh);
+        if (tab) {
+            tab.filter(filter);
         }
+    }
 
-        /** Clean the whole tree of item and rebuilds it */
-        public refresh() {
-            // Clean top panel
-            Helpers.CleanDiv(this._tabPanel);
+    /** Display the mesh tab on the given object */
+    public displayObjectDetails(mesh: AbstractMesh) {
+        this._tabbar.switchMeshTab(mesh);
+    }
 
-            // Get the active tab and its items
-            let activeTab = this._tabbar.getActiveTab();
+    /** Clean the whole tree of item and rebuilds it */
+    public refresh() {
+        // Clean top panel
+        Helpers.CleanDiv(this._tabPanel);
 
-            if (!activeTab) {
-                return;
-            }
-            activeTab.update();
-            this._tabPanel.appendChild(activeTab.getPanel());
-            Helpers.SEND_EVENT('resize');
+        // Get the active tab and its items
+        let activeTab = this._tabbar.getActiveTab();
 
+        if (!activeTab) {
+            return;
         }
+        activeTab.update();
+        this._tabPanel.appendChild(activeTab.getPanel());
+        Helpers.SEND_EVENT('resize');
 
-        /** Remove the inspector panel when it's built as a right panel:
-         * remove the right panel and remove the wrapper
-         */
-        public dispose() {
-            if (!this._popupMode) {
-                let activeTab = this._tabbar.getActiveTab();
-                if (activeTab) {
-                    activeTab.dispose();
-                }
-
-                // Get canvas
-                let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
+    }
 
-                // restore canvas style
-                for (let prop in this._canvasStyle) {
-                    (<any>canvas.style)[prop] = this._canvasStyle[prop];
-                }
-                // Get parent of the wrapper 
-                if (canvas.parentElement) {
-                    let canvasParent = canvas.parentElement.parentElement;
-
-                    if (canvasParent) {
-                        canvasParent.insertBefore(canvas, this._c2diwrapper);
-                        // Remove wrapper
-                        Helpers.CleanDiv(this._c2diwrapper);
-                        this._c2diwrapper.remove();
-                        // Send resize event to the window
-                        Helpers.SEND_EVENT('resize');
-                    }
-                }
+    /** Remove the inspector panel when it's built as a right panel:
+     * remove the right panel and remove the wrapper
+     */
+    public dispose() {
+        if (!this._popupMode) {
+            let activeTab = this._tabbar.getActiveTab();
+            if (activeTab) {
+                activeTab.dispose();
             }
-            Scheduler.getInstance().dispose();
-        }
 
-        /** Open the inspector in a new popup
-         * Set 'firstTime' to true if there is no inspector created beforehands
-         */
-        public openPopup(firstTime?: boolean) {
+            // Get canvas
+            let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
 
-            // Create popup
-            let popup = window.open('', 'Babylon.js INSPECTOR', 'toolbar=no,resizable=yes,menubar=no,width=750,height=1000');
-            if (!popup) {
-                alert("Please update your browser to open the Babylon.js inspector in an external view.");
-                return;
-            }
-            popup.document.title = "Babylon.js INSPECTOR";
-            // Get the inspector style      
-            let styles = Inspector.DOCUMENT.querySelectorAll('style');
-            for (let s = 0; s < styles.length; s++) {
-                popup.document.body.appendChild(styles[s].cloneNode(true));
-            }
-            let links = document.querySelectorAll('link');
-            for (let l = 0; l < links.length; l++) {
-                let link = popup.document.createElement("link");
-                link.rel = "stylesheet";
-                link.href = (links[l] as HTMLLinkElement).href;
-                popup.document.head.appendChild(link);
-            }
-            // Dispose the right panel if existing
-            if (!firstTime) {
-                this.dispose();
+            // restore canvas style
+            for (let prop in this._canvasStyle) {
+                (<any>canvas.style)[prop] = this._canvasStyle[prop];
             }
-            // set the mode as popup
-            this._popupMode = true;
-            // Save the HTML document
-            Inspector.DOCUMENT = popup.document;
-            Inspector.WINDOW = popup;
-            // Build the inspector wrapper
-            this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', popup.document.body);
-            // add inspector     
-            let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
-            inspector.classList.add('popupmode');
-            // and build it in the popup  
-            this._buildInspector(inspector);
-            // Rebuild it
-            this.refresh();
-
-            popup.addEventListener('resize', () => {
-                if (this._tabbar) {
-                    this._tabbar.updateWidth()
+            // Get parent of the wrapper 
+            if (canvas.parentElement) {
+                let canvasParent = canvas.parentElement.parentElement;
+
+                if (canvasParent) {
+                    canvasParent.insertBefore(canvas, this._c2diwrapper);
+                    // Remove wrapper
+                    Helpers.CleanDiv(this._c2diwrapper);
+                    this._c2diwrapper.remove();
+                    // Send resize event to the window
+                    Helpers.SEND_EVENT('resize');
                 }
-            });
+            }
         }
+        Scheduler.getInstance().dispose();
+    }
 
-        public getActiveTabIndex(): number {
-            return this._tabbar.getActiveTabIndex();
+    /** Open the inspector in a new popup
+     * Set 'firstTime' to true if there is no inspector created beforehands
+     */
+    public openPopup(firstTime?: boolean) {
+
+        // Create popup
+        let popup = window.open('', 'js INSPECTOR', 'toolbar=no,resizable=yes,menubar=no,width=750,height=1000');
+        if (!popup) {
+            alert("Please update your browser to open the js inspector in an external view.");
+            return;
+        }
+        popup.document.title = "js INSPECTOR";
+        // Get the inspector style      
+        let styles = Inspector.DOCUMENT.querySelectorAll('style');
+        for (let s = 0; s < styles.length; s++) {
+            popup.document.body.appendChild(styles[s].cloneNode(true));
         }
+        let links = document.querySelectorAll('link');
+        for (let l = 0; l < links.length; l++) {
+            let link = popup.document.createElement("link");
+            link.rel = "stylesheet";
+            link.href = (links[l] as HTMLLinkElement).href;
+            popup.document.head.appendChild(link);
+        }
+        // Dispose the right panel if existing
+        if (!firstTime) {
+            this.dispose();
+        }
+        // set the mode as popup
+        this._popupMode = true;
+        // Save the HTML document
+        Inspector.DOCUMENT = popup.document;
+        Inspector.WINDOW = popup;
+        // Build the inspector wrapper
+        this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', popup.document.body);
+        // add inspector     
+        let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+        inspector.classList.add('popupmode');
+        // and build it in the popup  
+        this._buildInspector(inspector);
+        // Rebuild it
+        this.refresh();
+
+        popup.addEventListener('resize', () => {
+            if (this._tabbar) {
+                this._tabbar.updateWidth()
+            }
+        });
+    }
+
+    public getActiveTabIndex(): number {
+        return this._tabbar.getActiveTabIndex();
     }
 }

+ 33 - 31
inspector/src/adapters/Adapter.ts

@@ -1,43 +1,45 @@
-module INSPECTOR {
+import { Geometry } from "babylonjs";
+import { PropertyLine } from "../details/PropertyLine";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
 
-    export abstract class Adapter {
 
-        protected _obj: any;
-        // a unique name for this adapter, to retrieve its own key in the local storage
-        private static _name: string = BABYLON.Geometry.RandomId();
+export abstract class Adapter {
 
-        constructor(obj: any) {
-            this._obj = obj;
-        }
+    protected _obj: any;
+    // a unique name for this adapter, to retrieve its own key in the local storage
+    private static _name: string = Geometry.RandomId();
 
+    constructor(obj: any) {
+        this._obj = obj;
+    }
 
-        /** Returns the name displayed in the tree */
-        public abstract id(): string;
 
-        /** Returns the type of this object - displayed in the tree */
-        public abstract type(): string;
+    /** Returns the name displayed in the tree */
+    public abstract id(): string;
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public abstract getProperties(): Array<PropertyLine>;
+    /** Returns the type of this object - displayed in the tree */
+    public abstract type(): string;
 
-        /** Returns true if the given object correspond to this  */
-        public correspondsTo(obj: any) {
-            return obj === this._obj;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public abstract getProperties(): Array<PropertyLine>;
 
-        /** Returns the adapter unique name */
-        public get name(): string {
-            return Adapter._name;
-        }
+    /** Returns true if the given object correspond to this  */
+    public correspondsTo(obj: any) {
+        return obj === this._obj;
+    }
 
-        /**
-         * Returns the actual object used for this adapter
-         */
-        public get object(): any {
-            return this._obj;
-        }
+    /** Returns the adapter unique name */
+    public get name(): string {
+        return Adapter._name;
+    }
 
-        /** Returns the list of tools available for this adapter */
-        public abstract getTools(): Array<AbstractTreeTool>;
+    /**
+     * Returns the actual object used for this adapter
+     */
+    public get object(): any {
+        return this._obj;
     }
-}
+
+    /** Returns the list of tools available for this adapter */
+    public abstract getTools(): Array<AbstractTreeTool>;
+}

+ 53 - 49
inspector/src/adapters/CameraAdapter.ts

@@ -1,55 +1,59 @@
-module INSPECTOR {
-    
-    export class CameraAdapter 
-        extends Adapter 
-         implements ICameraPOV{
-        
-        constructor(obj:BABYLON.Camera) {
-            super(obj);
-        }
-        
-        /** Returns the name displayed in the tree */
-        public id() : string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-        
-        /** Returns the type of this object - displayed in the tree */
-        public type() : string{
-            return Helpers.GET_TYPE(this._obj);
-        }
-        
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties() : Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-        
-        public getTools() : Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new CameraPOV(this));
-            return tools;
-        }
+import { Camera } from "babylonjs";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { CameraPOV, ICameraPOV } from "../treetools/CameraPOV";
+import { Adapter } from "./Adapter";
 
-        // Set the point of view of the chosen camera
-        public setPOV() {
-           (this._obj as BABYLON.Camera).getScene().switchActiveCamera(this._obj);
-        }
 
-        // Return the name of the current active camera
-        public getCurrentActiveCamera() {
-            let activeCamera = (this._obj as BABYLON.Camera).getScene().activeCamera;
-            if(activeCamera != null)
-            {
-                return activeCamera.name;
-            }else{
-                return "0";
-            }
-        }
+export class CameraAdapter
+    extends Adapter
+    implements ICameraPOV {
+
+    constructor(obj: Camera) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
 
-        
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new CameraPOV(this));
+        return tools;
     }
+
+    // Set the point of view of the chosen camera
+    public setPOV() {
+        (this._obj as Camera).getScene().switchActiveCamera(this._obj);
+    }
+
+    // Return the name of the current active camera
+    public getCurrentActiveCamera() {
+        let activeCamera = (this._obj as Camera).getScene().activeCamera;
+        if (activeCamera != null) {
+            return activeCamera.name;
+        } else {
+            return "0";
+        }
+    }
+
+
+
 }

+ 49 - 43
inspector/src/adapters/GUIAdapter.ts

@@ -1,44 +1,50 @@
-module INSPECTOR {
-    
-    export class GUIAdapter 
-        extends Adapter 
-        implements IToolVisible {
-
-        constructor(obj: BABYLON.GUI.Control) {
-            super(obj);
-        }
-
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
-
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            return tools;
-        }
-
-        public setVisible(b: boolean){
-            (this._obj as BABYLON.GUI.Control).isVisible = b;
-        }
-
-        public isVisible(): boolean{
-            return (this._obj as BABYLON.GUI.Control).isVisible;
-        }
+
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { Checkbox, IToolVisible } from "../treetools/Checkbox";
+import { Adapter } from "./Adapter";
+import { Control } from "babylonjs-gui";
+
+
+export class GUIAdapter
+    extends Adapter
+    implements IToolVisible {
+
+    constructor(obj: Control) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
+
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        return tools;
+    }
+
+    public setVisible(b: boolean) {
+        (this._obj as Control).isVisible = b;
+    }
+
+    public isVisible(): boolean {
+        return (this._obj as Control).isVisible;
     }
-}
+}

+ 49 - 46
inspector/src/adapters/LightAdapter.ts

@@ -1,48 +1,51 @@
-module INSPECTOR {
-    
-    export class LightAdapter 
-        extends Adapter 
-        implements IToolVisible{
-        
-        constructor(obj:BABYLON.Light) {
-            super(obj);
-        }
-        
-        /** Returns the name displayed in the tree */
-        public id() : string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-        
-        /** Returns the type of this object - displayed in the tree */
-        public type() : string{
-            return Helpers.GET_TYPE(this._obj);
-        }
-        
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties() : Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-        
-        public getTools() : Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            return tools;
-        }
-        
-        public setVisible(b:boolean) {
-            this._obj.setEnabled(b);
-        }        
-        public isVisible() : boolean {
-            return this._obj.isEnabled(); 
-        }
-
-        /** Returns some information about this mesh */
-        // public getInfo() : string {
-        //     return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
-        // }
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { Checkbox, IToolVisible } from "../treetools/Checkbox";
+import { Adapter } from "./Adapter";
+
+export class LightAdapter
+    extends Adapter
+    implements IToolVisible {
+
+    constructor(obj: BABYLON.Light) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
+
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        return tools;
     }
+
+    public setVisible(b: boolean) {
+        this._obj.setEnabled(b);
+    }
+    public isVisible(): boolean {
+        return this._obj.isEnabled();
+    }
+
+    /** Returns some information about this mesh */
+    // public getInfo() : string {
+    //     return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
+    // }
 }

+ 34 - 31
inspector/src/adapters/MaterialAdapter.ts

@@ -1,34 +1,37 @@
-module INSPECTOR {
-    
-    export class MaterialAdapter 
-        extends Adapter {
+import { Material } from "babylonjs";
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { Adapter } from "./Adapter";
 
-        constructor(obj:BABYLON.Material) {
-            super(obj);
-        }
-        
-        /** Returns the name displayed in the tree */
-        public id() : string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-        
-        /** Returns the type of this object - displayed in the tree */
-        public type() : string{
-            return Helpers.GET_TYPE(this._obj);
-        }
-        
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties() : Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-        
-        /** No tools for a material adapter */
-        public getTools() : Array<AbstractTreeTool> {
-            return [];
-        }
+export class MaterialAdapter
+    extends Adapter {
+
+    constructor(obj: Material) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
+
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    /** No tools for a material adapter */
+    public getTools(): Array<AbstractTreeTool> {
+        return [];
     }
 }

+ 102 - 94
inspector/src/adapters/MeshAdapter.ts

@@ -1,110 +1,118 @@
-module INSPECTOR {
-
-    export class MeshAdapter
-        extends Adapter
-        implements IToolVisible, IToolDebug, IToolBoundingBox, IToolInfo {
-
-        /** Keep track of the axis of the actual object */
-        private _axesViewer: BABYLON.Nullable<any>;
-        private onBeforeRenderObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Scene>>;
+import { AbstractMesh, Debug, Node, Nullable, Observer, Scene, TransformNode, Vector3 } from "babylonjs";
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { BoundingBox, IToolBoundingBox } from "../treetools/BoundingBox";
+import { Checkbox, IToolVisible } from "../treetools/Checkbox";
+import { DebugArea, IToolDebug } from "../treetools/DebugArea";
+import { Info, IToolInfo } from "../treetools/Info";
+import { Adapter } from "./Adapter";
+
+
+export class MeshAdapter
+    extends Adapter
+    implements IToolVisible, IToolDebug, IToolBoundingBox, IToolInfo {
+
+    /** Keep track of the axis of the actual object */
+    private _axesViewer: Nullable<any>;
+    private onBeforeRenderObserver: Nullable<Observer<Scene>>;
+
+    constructor(mesh: Node) {
+        super(mesh);
+    }
 
-        constructor(mesh: BABYLON.Node) {
-            super(mesh);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        tools.push(new DebugArea(this));
+        if (this._obj instanceof AbstractMesh) {
+            if ((this._obj as AbstractMesh).getTotalVertices() > 0) {
+                tools.push(new BoundingBox(this));
+            }
         }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            tools.push(new DebugArea(this));
-            if (this._obj instanceof BABYLON.AbstractMesh) {
-                if ((this._obj as BABYLON.AbstractMesh).getTotalVertices() > 0) {
-                    tools.push(new BoundingBox(this));
-                }
-            }
 
+        tools.push(new Info(this));
+        return tools;
+    }
 
-            tools.push(new Info(this));
-            return tools;
-        }
+    public setVisible(b: boolean) {
+        this._obj.setEnabled(b);
+        this._obj.isVisible = b;
+    }
+    public isVisible(): boolean {
+        return this._obj.isEnabled() && (this._obj.isVisible === undefined || this._obj.isVisible);
+    }
+    public isBoxVisible(): boolean {
+        return (this._obj as AbstractMesh).showBoundingBox;
+    }
+    public setBoxVisible(b: boolean) {
+        return (this._obj as AbstractMesh).showBoundingBox = b;
+    }
 
-        public setVisible(b: boolean) {
-            this._obj.setEnabled(b);
-            this._obj.isVisible = b;
+    public debug(enable: boolean) {
+        // Draw axis the first time
+        if (!this._axesViewer) {
+            this._drawAxis();
         }
-        public isVisible(): boolean {
-            return this._obj.isEnabled() && (this._obj.isVisible === undefined || this._obj.isVisible);
-        }
-        public isBoxVisible(): boolean {
-            return (this._obj as BABYLON.AbstractMesh).showBoundingBox;
-        }
-        public setBoxVisible(b: boolean) {
-            return (this._obj as BABYLON.AbstractMesh).showBoundingBox = b;
+        // Display or hide axis
+        if (!enable && this._axesViewer) {
+            let mesh = this._obj as AbstractMesh;
+            mesh.getScene().onBeforeRenderObservable.remove(this.onBeforeRenderObserver);
+            this._axesViewer.dispose();
+            this._axesViewer = null;
         }
+    }
 
-        public debug(enable: boolean) {
-            // Draw axis the first time
-            if (!this._axesViewer) {
-                this._drawAxis();
-            }
-            // Display or hide axis
-            if (!enable && this._axesViewer) {
-                let mesh = this._obj as BABYLON.AbstractMesh;
-                mesh.getScene().onBeforeRenderObservable.remove(this.onBeforeRenderObserver);
-                this._axesViewer.dispose();
-                this._axesViewer = null;
-            }
+    /** Returns some information about this mesh */
+    public getInfo(): string {
+        if (this._obj instanceof AbstractMesh) {
+            return `${(this._obj as AbstractMesh).getTotalVertices()} vertices`;
         }
+        return '0 vertices';
+    }
 
-        /** Returns some information about this mesh */
-        public getInfo(): string {
-            if (this._obj instanceof BABYLON.AbstractMesh) {
-                return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
+    /** Draw X, Y and Z axis for the actual object if this adapter.
+     * Should be called only one time as it will fill this._axis
+     */
+    private _drawAxis() {
+        this._obj.computeWorldMatrix();
+
+        // Axis
+        var x = new Vector3(1, 0, 0);
+        var y = new Vector3(0, 1, 0);
+        var z = new Vector3(0, 0, 1);
+
+        this._axesViewer = new Debug.AxesViewer(this._obj.getScene());
+
+        let mesh = this._obj as TransformNode;
+        this.onBeforeRenderObserver = mesh.getScene().onBeforeRenderObservable.add(() => {
+            let matrix = mesh.getWorldMatrix();
+            let extend = new Vector3(1, 1, 1);
+            if (mesh instanceof AbstractMesh) {
+                extend = mesh.getBoundingInfo().boundingBox.extendSizeWorld;
             }
-            return '0 vertices';
-        }
-
-        /** Draw X, Y and Z axis for the actual object if this adapter.
-         * Should be called only one time as it will fill this._axis
-         */
-        private _drawAxis() {
-            this._obj.computeWorldMatrix();
-
-            // Axis
-            var x = new BABYLON.Vector3(1, 0, 0);
-            var y = new BABYLON.Vector3(0, 1, 0);
-            var z = new BABYLON.Vector3(0, 0, 1);
-
-            this._axesViewer = new BABYLON.Debug.AxesViewer(this._obj.getScene());
-
-            let mesh = this._obj as BABYLON.TransformNode;
-            this.onBeforeRenderObserver = mesh.getScene().onBeforeRenderObservable.add(() => {
-                let matrix = mesh.getWorldMatrix();
-                let extend = new BABYLON.Vector3(1, 1, 1);
-                if (mesh instanceof BABYLON.AbstractMesh) {
-                    extend = mesh.getBoundingInfo().boundingBox.extendSizeWorld;
-                }
-                this._axesViewer!.scaleLines = Math.max(extend.x, extend.y, extend.z) * 2;
-                this._axesViewer!.update(this._obj.position, BABYLON.Vector3.TransformNormal(x, matrix), BABYLON.Vector3.TransformNormal(y, matrix), BABYLON.Vector3.TransformNormal(z, matrix));
-            });
-        }
+            this._axesViewer!.scaleLines = Math.max(extend.x, extend.y, extend.z) * 2;
+            this._axesViewer!.update(this._obj.position, Vector3.TransformNormal(x, matrix), Vector3.TransformNormal(y, matrix), Vector3.TransformNormal(z, matrix));
+        });
     }
-}
+}

+ 48 - 43
inspector/src/adapters/PhysicsImpostorAdapter.ts

@@ -1,55 +1,60 @@
-module INSPECTOR {
+import { AbstractMesh, PhysicsImpostor } from "babylonjs";
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { Checkbox, IToolVisible } from "../treetools/Checkbox";
+import { Adapter } from "./Adapter";
 
-    export class PhysicsImpostorAdapter
-        extends Adapter
-        implements IToolVisible {
 
-        private _viewer: any;
-        private _isVisible = false;
+export class PhysicsImpostorAdapter
+    extends Adapter
+    implements IToolVisible {
 
-        constructor(obj: BABYLON.PhysicsImpostor, viewer: any) {
-            super(obj);
-            this._viewer = viewer;
-        }
+    private _viewer: any;
+    private _isVisible = false;
 
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            let physicsImposter = (<BABYLON.PhysicsImpostor>this._obj);
-            if (physicsImposter && physicsImposter.object) {
-                str = (<BABYLON.AbstractMesh>physicsImposter.object).name || "";
-            } // otherwise nothing displayed        
-            return str;
-        }
+    constructor(obj: PhysicsImpostor, viewer: any) {
+        super(obj);
+        this._viewer = viewer;
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        let physicsImposter = (<PhysicsImpostor>this._obj);
+        if (physicsImposter && physicsImposter.object) {
+            str = (<AbstractMesh>physicsImposter.object).name || "";
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            return tools;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
 
-        public setVisible(b: boolean) {
-            this._isVisible = b;
-            if (b) {
-                this._viewer.showImpostor(this._obj);
-            } else {
-                this._viewer.hideImpostor(this._obj);
-            }
-        }
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        return tools;
+    }
 
-        public isVisible(): boolean {
-            return this._isVisible;
+    public setVisible(b: boolean) {
+        this._isVisible = b;
+        if (b) {
+            this._viewer.showImpostor(this._obj);
+        } else {
+            this._viewer.hideImpostor(this._obj);
         }
+    }
 
+    public isVisible(): boolean {
+        return this._isVisible;
     }
-}
+
+}

+ 44 - 39
inspector/src/adapters/SoundAdapter.ts

@@ -1,48 +1,53 @@
-module INSPECTOR {
+import { Sound } from "babylonjs";
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { ISoundInteractions, SoundInteractions } from "../treetools/SoundInteractions";
+import { Adapter } from "./Adapter";
 
-    export class SoundAdapter
-        extends Adapter
-        implements ISoundInteractions {
 
-        constructor(obj: BABYLON.Sound) {
-            super(obj);
-        }
+export class SoundAdapter
+    extends Adapter
+    implements ISoundInteractions {
 
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
+    constructor(obj: Sound) {
+        super(obj);
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new SoundInteractions(this));
-            return tools;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new SoundInteractions(this));
+        return tools;
+    }
 
-        public setPlaying(callback: Function) {
-            if ((this._obj as BABYLON.Sound).isPlaying) {
-                (this._obj as BABYLON.Sound).pause();
-            }
-            else {
-                (this._obj as BABYLON.Sound).play();
-            }
-            (this._obj as BABYLON.Sound).onended = () => {
-                callback();
-            }
+    public setPlaying(callback: Function) {
+        if ((this._obj as Sound).isPlaying) {
+            (this._obj as Sound).pause();
+        }
+        else {
+            (this._obj as Sound).play();
+        }
+        (this._obj as Sound).onended = () => {
+            callback();
         }
     }
-}
+}

+ 33 - 30
inspector/src/adapters/TextureAdapter.ts

@@ -1,37 +1,40 @@
-module INSPECTOR {
+import { Adapter } from "./Adapter";
+import { BaseTexture } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
 
-    export class TextureAdapter
-        extends Adapter {
+export class TextureAdapter
+    extends Adapter {
 
-        constructor(obj: BABYLON.BaseTexture) {
-            super(obj);
-        }
-
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
+    constructor(obj: BaseTexture) {
+        super(obj);
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            // Not used in this tab
-            return [];
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = new Array<AbstractTreeTool>();
-            // tools.push(new CameraPOV(this));
-            return tools;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        // Not used in this tab
+        return [];
+    }
 
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = new Array<AbstractTreeTool>();
+        // tools.push(new CameraPOV(this));
+        return tools;
     }
-}
+
+}

+ 9 - 0
inspector/src/adapters/index.ts

@@ -0,0 +1,9 @@
+export * from './Adapter';
+export * from './CameraAdapter';
+export * from './GUIAdapter';
+export * from './LightAdapter';
+export * from './MaterialAdapter';
+export * from './MeshAdapter';
+export * from './PhysicsImpostorAdapter';
+export * from './SoundAdapter';
+export * from './TextureAdapter';

+ 186 - 182
inspector/src/details/DetailPanel.ts

@@ -1,211 +1,215 @@
- module INSPECTOR {
-    export interface SortDirection {
-        [property: string]: number;
+import { BasicElement } from "../gui/BasicElement";
+import { SearchBarDetails } from "../gui/SearchBar";
+import { Helpers } from "../helpers/Helpers";
+import { Inspector } from "../Inspector";
+import { PropertyLine } from "./PropertyLine";
+
+export interface SortDirection {
+    [property: string]: number;
+}
+
+export class DetailPanel extends BasicElement {
+
+    // The header row
+    private _headerRow: HTMLElement;
+    // Contains all details rows that belongs to the item above
+    private _detailRows: Array<PropertyLine> = [];
+    // Store the sort direction of each header column
+    private _sortDirection: SortDirection = {};
+    // The search bar
+    private _searchDetails: SearchBarDetails;
+    private _details: HTMLDivElement;
+
+    constructor(dr?: Array<PropertyLine>) {
+        super();
+        this._build();
+
+        if (dr) {
+            this._detailRows = dr;
+            this.update();
+        }
     }
 
-    export class DetailPanel extends BasicElement {
-
-        // The header row
-        private _headerRow : HTMLElement;
-        // Contains all details rows that belongs to the item above
-        private _detailRows : Array<PropertyLine> = [];
-        // Store the sort direction of each header column
-        private _sortDirection : SortDirection = {};
-        // The search bar
-        private _searchDetails : SearchBarDetails;
-        private _details : HTMLElement;
-
-        constructor(dr? : Array<PropertyLine>) {
-            super();
-            this._build();
-            
-            if (dr) {
-                this._detailRows = dr;
-                this.update();
-            }
-        }
+    set details(detailsRow: Array<PropertyLine>) {
+        this.clean();
+        //add the searchBar
+        this._addSearchBarDetails();
+        this._details = Helpers.CreateDiv('details', this._div);
+        this._detailRows = detailsRow;
+        // Refresh HTML
+        this.update();
+    }
 
-        set details(detailsRow : Array<PropertyLine>) {
-            this.clean();
-            //add the searchBar
-            this._addSearchBarDetails();
-            this._details = Helpers.CreateDiv('details', this._div);
-            this._detailRows = detailsRow;
-            // Refresh HTML
-            this.update();
-        }
+    protected _build() {
+        this._div.className = 'insp-details';
+        this._div.id = 'insp-details';
+        // Create header row
+        this._createHeaderRow();
+        this._div.appendChild(this._headerRow);
 
-        protected _build() {
-            this._div.className = 'insp-details';
-            this._div.id = 'insp-details';
-            // Create header row
-            this._createHeaderRow();
-            this._div.appendChild(this._headerRow);
-            
-        } 
-        
-        /** Updates the HTML of the detail panel */
-        public update(_items?: Array<PropertyLine>) {            
-            this._sortDetails('name', 1);
-            // Check the searchbar
-            if (_items) {
-                this.cleanRow();
-                this._addSearchDetails(_items);
-                //console.log(_items);
-            } else {
-                this._addDetails();
-                //console.log("np");
-            }
+    }
+
+    /** Updates the HTML of the detail panel */
+    public update(_items?: Array<PropertyLine>) {
+        this._sortDetails('name', 1);
+        // Check the searchbar
+        if (_items) {
+            this.cleanRow();
+            this._addSearchDetails(_items);
+            //console.log(_items);
+        } else {
+            this._addDetails();
+            //console.log("np");
         }
+    }
 
-         /** Add the search bar for the details */
-        private _addSearchBarDetails() {
-            let searchDetails = Helpers.CreateDiv('searchbar-details', this._div);
-            // Create search bar
-            this._searchDetails = new SearchBarDetails(this);
+    /** Add the search bar for the details */
+    private _addSearchBarDetails() {
+        let searchDetails = Helpers.CreateDiv('searchbar-details', this._div);
+        // Create search bar
+        this._searchDetails = new SearchBarDetails(this);
 
-            searchDetails.appendChild(this._searchDetails.toHtml());
-            this._div.appendChild(searchDetails);
-        }
+        searchDetails.appendChild(this._searchDetails.toHtml());
+        this._div.appendChild(searchDetails);
+    }
 
-        /** Search an element by name  */
-        public searchByName(searchName: string) {
-            let rows = [];
-            for (let row of this._detailRows) {
-                if(row.name.indexOf(searchName) >= 0){
-                    rows.push(row);
-                }
+    /** Search an element by name  */
+    public searchByName(searchName: string) {
+        let rows = [];
+        for (let row of this._detailRows) {
+            if (row.name.indexOf(searchName) >= 0) {
+                rows.push(row);
             }
-            this.update(rows);
         }
+        this.update(rows);
+    }
 
-        /** Add all lines in the html div. Does not sort them! */
-        private _addDetails() {
-            for (let row of this._detailRows) {
-                this._details.appendChild(row.toHtml());
-            }
+    /** Add all lines in the html div. Does not sort them! */
+    private _addDetails() {
+        for (let row of this._detailRows) {
+            this._details.appendChild(row.toHtml());
         }
+    }
 
-        private _addSearchDetails(_items: Array<PropertyLine>) {
-            for (let row of _items) {
-                this._details.appendChild(row.toHtml());
-            }   
+    private _addSearchDetails(_items: Array<PropertyLine>) {
+        for (let row of _items) {
+            this._details.appendChild(row.toHtml());
         }
+    }
 
-        /**
-         * Sort the details row by comparing the given property of each row
-         */
-        private _sortDetails(property:string, _direction?:number) {
-                
-            // Clean header
-            let elems = Inspector.DOCUMENT.querySelectorAll('.sort-direction');
-            for (let e=0; e<elems.length; e++) {
-                elems[e].classList.remove('fa-chevron-up');
-                elems[e].classList.remove('fa-chevron-down');
-            }
+    /**
+     * Sort the details row by comparing the given property of each row
+     */
+    private _sortDetails(property: string, _direction?: number) {
 
+        // Clean header
+        let elems = Inspector.DOCUMENT.querySelectorAll('.sort-direction');
+        for (let e = 0; e < elems.length; e++) {
+            elems[e].classList.remove('fa-chevron-up');
+            elems[e].classList.remove('fa-chevron-down');
+        }
 
-            if (_direction || !this._sortDirection[property]) {
-                this._sortDirection[property] = _direction || 1;
-            } else {
-                this._sortDirection[property] *= -1;
-            }
-            let direction = this._sortDirection[property];
-            let query = this._headerRow.querySelector(`#sort-direction-${property}`);
-            if (query) {
-                if (direction == 1) {
-                    query.classList.remove('fa-chevron-down');
-                    query.classList.add('fa-chevron-up');
-                } else {
-                    query.classList.remove('fa-chevron-up');
-                    query.classList.add('fa-chevron-down');
-                }
-            }
 
-            let isString = (s: any) => {
-                return typeof(s) === 'string' || s instanceof String;
-            };
-
-            this._detailRows.forEach((property) => {
-                property.closeDetails();
-            })
-
-            this._detailRows.sort((detail1: any, detail2: any) : number => {
-                let str1 = String(detail1[property]);
-                let str2 = String(detail2[property]);
-                if (!isString(str1)) {
-                    str1 = detail1[property].toString();
-                }
-                if (!isString(str2)) {
-                    str2 = detail2[property].toString();
-                }
-                // Compare numbers as numbers and string as string with 'numeric=true'
-                return str1.localeCompare(str2, [], {numeric:true}) * direction;
-            });
+        if (_direction || !this._sortDirection[property]) {
+            this._sortDirection[property] = _direction || 1;
+        } else {
+            this._sortDirection[property] *= -1;
         }
-
-        /**
-         * Removes all data in the detail panel but keep the header row
-         */
-        public clean() {         
-            // Delete all details row
-            for (let pline of this._detailRows) {
-                pline.dispose();
+        let direction = this._sortDirection[property];
+        let query = this._headerRow.querySelector(`#sort-direction-${property}`);
+        if (query) {
+            if (direction == 1) {
+                query.classList.remove('fa-chevron-down');
+                query.classList.add('fa-chevron-up');
+            } else {
+                query.classList.remove('fa-chevron-up');
+                query.classList.add('fa-chevron-down');
             }
-            Helpers.CleanDiv(this._div);
-            // Header row
-            this._div.appendChild(this._headerRow);
         }
 
-        /**
-         * Clean the rows only
-         */
-        public cleanRow() {           
-            // Delete all details row
-            for (let pline of this._detailRows) {
-                pline.dispose();
+        let isString = (s: any) => {
+            return typeof (s) === 'string' || s instanceof String;
+        };
+
+        this._detailRows.forEach((property) => {
+            property.closeDetails();
+        })
+
+        this._detailRows.sort((detail1: any, detail2: any): number => {
+            let str1 = String(detail1[property]);
+            let str2 = String(detail2[property]);
+            if (!isString(str1)) {
+                str1 = detail1[property].toString();
             }
-            Helpers.CleanDiv(this._details);
+            if (!isString(str2)) {
+                str2 = detail2[property].toString();
+            }
+            // Compare numbers as numbers and string as string with 'numeric=true'
+            return str1.localeCompare(str2, [], { numeric: true }) * direction;
+        });
+    }
+
+    /**
+     * Removes all data in the detail panel but keep the header row
+     */
+    public clean() {
+        // Delete all details row
+        for (let pline of this._detailRows) {
+            pline.dispose();
         }
+        Helpers.CleanDiv(this._div);
+        // Header row
+        this._div.appendChild(this._headerRow);
+    }
 
-        /** Overrides basicelement.dispose */
-        public dispose() {
-            // Delete all details row
-            for (let pline of this._detailRows) {
-                pline.dispose();
-            }
+    /**
+     * Clean the rows only
+     */
+    public cleanRow() {
+        // Delete all details row
+        for (let pline of this._detailRows) {
+            pline.dispose();
         }
+        Helpers.CleanDiv(this._details);
+    }
 
-        /**
-         * Creates the header row : name, value, id
-         */
-        private _createHeaderRow() {   
-            this._headerRow = Helpers.CreateDiv('header-row');
-
-            let createDiv = (name:string, cssClass:string)  : HTMLElement => {
-                let div =  Helpers.CreateDiv(cssClass+' header-col');
-
-                // Column title - first letter in uppercase
-                let spanName = Inspector.DOCUMENT.createElement('span');
-                spanName.textContent = name.charAt(0).toUpperCase() + name.slice(1);
-                
-                // sort direction
-                let spanDirection = Inspector.DOCUMENT.createElement('i');
-                spanDirection.className = 'sort-direction fa';
-                spanDirection.id = 'sort-direction-'+name; 
-
-                div.appendChild(spanName);
-                div.appendChild(spanDirection);
-
-                div.addEventListener('click', (e) => {
-                    this._sortDetails(name);
-                    this._addDetails();
-                });
-                return div;
-            };
-
-            this._headerRow.appendChild(createDiv('name', 'prop-name'));
-            this._headerRow.appendChild(createDiv('value', 'prop-value'));
+    /** Overrides basicelement.dispose */
+    public dispose() {
+        // Delete all details row
+        for (let pline of this._detailRows) {
+            pline.dispose();
         }
     }
- }
+
+    /**
+     * Creates the header row : name, value, id
+     */
+    private _createHeaderRow() {
+        this._headerRow = Helpers.CreateDiv('header-row');
+
+        let createDiv = (name: string, cssClass: string): HTMLElement => {
+            let div = Helpers.CreateDiv(cssClass + ' header-col');
+
+            // Column title - first letter in uppercase
+            let spanName = Inspector.DOCUMENT.createElement('span');
+            spanName.textContent = name.charAt(0).toUpperCase() + name.slice(1);
+
+            // sort direction
+            let spanDirection = Inspector.DOCUMENT.createElement('i');
+            spanDirection.className = 'sort-direction fa';
+            spanDirection.id = 'sort-direction-' + name;
+
+            div.appendChild(spanName);
+            div.appendChild(spanDirection);
+
+            div.addEventListener('click', (e) => {
+                this._sortDetails(name);
+                this._addDetails();
+            });
+            return div;
+        };
+
+        this._headerRow.appendChild(createDiv('name', 'prop-name'));
+        this._headerRow.appendChild(createDiv('value', 'prop-value'));
+    }
+}

+ 65 - 65
inspector/src/details/Property.ts

@@ -1,84 +1,84 @@
-module INSPECTOR {
+import { Scene } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
 
-    /**
-     * A property is a link between a data (string) and an object.
-     */
-    export class Property {
+/**
+ * A property is a link between a data (string) and an object.
+ */
+export class Property {
 
-        /** The property name */
-        private _property: string;
-        /** The obj this property refers to */
-        private _obj: any;
-        /** The obj parent  */
-        private _parentObj: any;
+    /** The property name */
+    private _property: string;
+    /** The obj this property refers to */
+    private _obj: any;
+    /** The obj parent  */
+    private _parentObj: any;
 
-        constructor(prop: string, obj: any, parentObj?: any) {
-            this._property = prop;
-            this._obj = obj;
-            this._parentObj = parentObj || null;
-        }
+    constructor(prop: string, obj: any, parentObj?: any) {
+        this._property = prop;
+        this._obj = obj;
+        this._parentObj = parentObj || null;
+    }
 
-        public get name(): string {
-            return this._property;
-        }
+    public get name(): string {
+        return this._property;
+    }
 
-        public get value(): any {
-            return this._obj[this._property];
-        }
-        public set value(newValue: any) {
-            if (newValue != undefined && this._obj[this._property] != undefined) {
-                if (this._obj instanceof BABYLON.Scene) {
-                    (<BABYLON.Scene>this._obj).debugLayer.onPropertyChangedObservable.notifyObservers({
-                        object: this._obj,
-                        property: this._property,
-                        value: newValue,
-                        initialValue: (<any>this._obj)[this._property]
-                    });
-                }
-                else {
-                    if(this._parentObj != null) {
-                        // Object that have "children" properties : Color, Vector, imageProcessingConfiguration
+    public get value(): any {
+        return this._obj[this._property];
+    }
+    public set value(newValue: any) {
+        if (newValue != undefined && this._obj[this._property] != undefined) {
+            if (this._obj instanceof Scene) {
+                (<Scene>this._obj).debugLayer.onPropertyChangedObservable.notifyObservers({
+                    object: this._obj,
+                    property: this._property,
+                    value: newValue,
+                    initialValue: (<any>this._obj)[this._property]
+                });
+            }
+            else {
+                if (this._parentObj != null) {
+                    // Object that have "children" properties : Color, Vector, imageProcessingConfiguration
 
-                        if (this._parentObj instanceof BABYLON.Scene) {
-                            (<BABYLON.Scene>this._parentObj).debugLayer.onPropertyChangedObservable.notifyObservers({
-                                object: this._parentObj,
-                                property: this._property,
-                                value: newValue,
-                                initialValue: (<any>this._obj)[this._property]
-                            });
-                        }
-                        else {
-                            this._parentObj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
-                                object: this._parentObj,
-                                property: this._property,
-                                value: newValue,
-                                initialValue: this._obj[this._property]
-                            });
-                        }
+                    if (this._parentObj instanceof Scene) {
+                        (<Scene>this._parentObj).debugLayer.onPropertyChangedObservable.notifyObservers({
+                            object: this._parentObj,
+                            property: this._property,
+                            value: newValue,
+                            initialValue: (<any>this._obj)[this._property]
+                        });
                     }
                     else {
-                        this._obj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
-                            object: this._obj,
+                        this._parentObj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
+                            object: this._parentObj,
                             property: this._property,
                             value: newValue,
                             initialValue: this._obj[this._property]
                         });
                     }
                 }
+                else {
+                    this._obj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
+                        object: this._obj,
+                        property: this._property,
+                        value: newValue,
+                        initialValue: this._obj[this._property]
+                    });
+                }
             }
-            this._obj[this._property] = newValue;
-        }
-
-        public get type(): string {
-            return Helpers.GET_TYPE(this.value);
         }
+        this._obj[this._property] = newValue;
+    }
 
-        public get obj(): any {
-            return this._obj;
-        }
-        public set obj(newObj: any) {
-            this._obj = newObj;
-        }
+    public get type(): string {
+        return Helpers.GET_TYPE(this.value);
+    }
 
+    public get obj(): any {
+        return this._obj;
+    }
+    public set obj(newObj: any) {
+        this._obj = newObj;
     }
-}
+
+}

File diff suppressed because it is too large
+ 491 - 483
inspector/src/details/PropertyLine.ts


+ 3 - 0
inspector/src/details/index.ts

@@ -0,0 +1,3 @@
+export * from './DetailPanel';
+export * from './Property';
+export * from './PropertyLine';

+ 29 - 29
inspector/src/gui/BasicElement.ts

@@ -1,32 +1,32 @@
- module INSPECTOR {
+import { Helpers } from "../helpers/Helpers";
+
+/**
+ * Represents a html div element. 
+ * The div is built when an instance of BasicElement is created.
+ */
+export abstract class BasicElement {
+
+    protected _div: HTMLDivElement;
+
+    constructor() {
+        this._div = Helpers.CreateDiv();
+    }
+
     /**
-     * Represents a html div element. 
-     * The div is built when an instance of BasicElement is created.
+     * Returns the div element
      */
-    export abstract class BasicElement {
-        
-        protected _div : HTMLElement;
-        
-        constructor() {        
-            this._div = Helpers.CreateDiv();  
-        }
-            
-        /**
-         * Returns the div element
-         */
-        public toHtml() : HTMLElement {
-            return this._div;
-        }
-        
-        /**
-         * Build the html element
-         */
-        protected _build(){};
-        
-        public abstract update(data?:any): void;
-        
-        /** Default dispose method if needed */
-        public dispose() {};
-        
+    public toHtml(): HTMLDivElement {
+        return this._div;
     }
-}
+
+    /**
+     * Build the html element
+     */
+    protected _build() { };
+
+    public abstract update(data?: any): void;
+
+    /** Default dispose method if needed */
+    public dispose() { };
+
+}

+ 31 - 30
inspector/src/gui/ColorElement.ts

@@ -1,35 +1,36 @@
- module INSPECTOR {
-     /**
-     * Display a very small div corresponding to the given color
-     */
-    export class ColorElement extends BasicElement{
-                
-        // The color as hexadecimal string
-        constructor(color:BABYLON.Color4|BABYLON.Color3) {
-            super();
-            this._div.className = 'color-element';
+import { Color3, Color4 } from "babylonjs";
+import { BasicElement } from "./BasicElement";
+
+/**
+* Display a very small div corresponding to the given color
+*/
+export class ColorElement extends BasicElement {
+
+    // The color as hexadecimal string
+    constructor(color: Color4 | Color3) {
+        super();
+        this._div.className = 'color-element';
+        this._div.style.backgroundColor = this._toRgba(color);
+    }
+
+    public update(color?: Color4 | Color3) {
+        if (color) {
             this._div.style.backgroundColor = this._toRgba(color);
         }
-        
-        public update(color?:BABYLON.Color4|BABYLON.Color3) {
-            if (color) {
-                this._div.style.backgroundColor = this._toRgba(color);
-            }
-        }
-        
-        private _toRgba(color:BABYLON.Color4|BABYLON.Color3) : string {
-            if (color) {
-                let r = (color.r * 255) | 0;
-                let g = (color.g * 255) | 0;
-                let b = (color.b * 255) | 0;
-                let a = 1;
-                if (color instanceof BABYLON.Color4) {
-                    a = (color as BABYLON.Color4).a;
-                }
-                return `rgba(${r}, ${g}, ${b}, ${a})`;
-            } else {
-                return '';
+    }
+
+    private _toRgba(color: Color4 | Color3): string {
+        if (color) {
+            let r = (color.r * 255) | 0;
+            let g = (color.g * 255) | 0;
+            let b = (color.b * 255) | 0;
+            let a = 1;
+            if (color instanceof Color4) {
+                a = (color as Color4).a;
             }
+            return `rgba(${r}, ${g}, ${b}, ${a})`;
+        } else {
+            return '';
         }
     }
- }
+}

+ 60 - 56
inspector/src/gui/ColorPickerElement.ts

@@ -1,63 +1,67 @@
-module INSPECTOR {
-    /**
-     * Represents a html div element. 
-     * The div is built when an instance of BasicElement is created.
-     */
-    export class ColorPickerElement extends BasicElement {
-        
-        protected _input : HTMLInputElement;
-        private pline : PropertyLine;
-        
-        constructor(color:BABYLON.Color4|BABYLON.Color3, propertyLine: PropertyLine) {
-            super();
-            let scheduler = Scheduler.getInstance();
-            this._div.className = 'color-element';
-            this._div.style.backgroundColor = this._toRgba(color);
-            this.pline = propertyLine;
+import { Color3, Color4 } from "babylonjs";
+import { PropertyLine } from "../details/PropertyLine";
+import { Helpers } from "../helpers/Helpers";
+import { Scheduler } from "../scheduler/Scheduler";
+import { BasicElement } from "./BasicElement";
 
-            this._input = Helpers.CreateInput();  
-            this._input.type = 'color';
-            this._input.style.opacity = "0";
-            this._input.style.width = '10px';
-            this._input.style.height = '15px';
-            this._input.value = color.toHexString();
-            
-            this._input.addEventListener('input', (e) => {
-                let color = BABYLON.Color3.FromHexString(this._input.value);
-                color.r = parseFloat(color.r.toPrecision(2));
-                color.g = parseFloat(color.g.toPrecision(2));
-                color.b = parseFloat(color.b.toPrecision(2));
-                this.pline.validateInput(color);
-                scheduler.pause = false;
-            });
-            
-            this._div.appendChild(this._input);
-
-            this._input.addEventListener('click', (e) => {
-                scheduler.pause = true;
-            });
-        }
+/**
+ * Represents a html div element. 
+ * The div is built when an instance of BasicElement is created.
+ */
+export class ColorPickerElement extends BasicElement {
 
-        public update(color?:BABYLON.Color4|BABYLON.Color3) {
-            if (color) {
-                this._div.style.backgroundColor = this._toRgba(color);
-                this._input.value = color.toHexString();
-            }
+    protected _input: HTMLInputElement;
+    private pline: PropertyLine;
+
+    constructor(color: Color4 | Color3, propertyLine: PropertyLine) {
+        super();
+        let scheduler = Scheduler.getInstance();
+        this._div.className = 'color-element';
+        this._div.style.backgroundColor = this._toRgba(color);
+        this.pline = propertyLine;
+
+        this._input = Helpers.CreateInput();
+        this._input.type = 'color';
+        this._input.style.opacity = "0";
+        this._input.style.width = '10px';
+        this._input.style.height = '15px';
+        this._input.value = color.toHexString();
+
+        this._input.addEventListener('input', (e) => {
+            let color = Color3.FromHexString(this._input.value);
+            color.r = parseFloat(color.r.toPrecision(2));
+            color.g = parseFloat(color.g.toPrecision(2));
+            color.b = parseFloat(color.b.toPrecision(2));
+            this.pline.validateInput(color);
+            scheduler.pause = false;
+        });
+
+        this._div.appendChild(this._input);
+
+        this._input.addEventListener('click', (e) => {
+            scheduler.pause = true;
+        });
+    }
+
+    public update(color?: Color4 | Color3) {
+        if (color) {
+            this._div.style.backgroundColor = this._toRgba(color);
+            this._input.value = color.toHexString();
         }
+    }
 
-        private _toRgba(color:BABYLON.Color4|BABYLON.Color3) : string {
-            if (color) {
-                let r = (color.r * 255) | 0;
-                let g = (color.g * 255) | 0;
-                let b = (color.b * 255) | 0;
-                let a = 1;
-                if (color instanceof BABYLON.Color4) {
-                    a = (color as BABYLON.Color4).a;
-                }
-                return `rgba(${r}, ${g}, ${b}, ${a})`;
-            } else {
-                return '';
+    private _toRgba(color: Color4 | Color3): string {
+        if (color) {
+            let r = (color.r * 255) | 0;
+            let g = (color.g * 255) | 0;
+            let b = (color.b * 255) | 0;
+            let a = 1;
+            if (color instanceof Color4) {
+                a = (color as Color4).a;
             }
+            return `rgba(${r}, ${g}, ${b}, ${a})`;
+        } else {
+            return '';
         }
     }
-}
+}

+ 110 - 108
inspector/src/gui/CubeTextureElement.ts

@@ -1,119 +1,121 @@
- module INSPECTOR {
-     /**
-     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the 
-     * cube texture in a cube
-     */
-    export class CubeTextureElement extends BasicElement{
-
-        /** The big div displaying the full image */
-        private _textureDiv: HTMLElement;
-        
-        private _engine    : BABYLON.Engine;
-        protected _scene     : BABYLON.Scene;
-        protected _cube      : BABYLON.Mesh;
-        private _canvas    : HTMLCanvasElement;
-        protected _textureUrl: string;
-        
-        // On pause the engine will not render anything
-        private _pause     : boolean = false;
-            
-        /** The texture given as a parameter should be cube. */
-        constructor(tex : BABYLON.Texture) {
-            super();
-            this._div.className    = 'fa fa-search texture-element';
-            
-            // Create the texture viewer
-            this._textureDiv       = Helpers.CreateDiv('texture-viewer', this._div);
-            // canvas
-            this._canvas             = Helpers.CreateElement('canvas', 'texture-viewer-img', this._textureDiv) as HTMLCanvasElement;
-            
-            if (tex) {
-                this._textureUrl = tex.name;
-            }
+import { Color4, CubeTexture, Engine, Mesh, Scene, StandardMaterial, Texture } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
+import { BasicElement } from "./BasicElement";
 
-            this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
-            this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none')); 
+/**
+* Display a very small div. A new canvas is created, with a new js scene, containing only the 
+* cube texture in a cube
+*/
+export class CubeTextureElement extends BasicElement {
 
-        }
-        
-        public update(tex?:BABYLON.Texture) {
-            if (tex && tex.url === this._textureUrl) {
-                // Nothing to do, as the old texture is the same as the old one
-            } else {                    
-                if (tex) {
-                    this._textureUrl = tex.name;
-                }
-                if (this._engine) {
-                    // Dispose old material and cube
-                    if (this._cube.material) {
-                        this._cube.material.dispose(true, true);
-                    }
-                    this._cube.dispose();
-                } else {
-                    this._initEngine();
-                }
-                // and create it again
-                this._populateScene();
-            }       
-        }
-        
-        /** Creates the box  */
-        protected _populateScene() {
-            // Create the hdr texture
-            let hdrTexture                      = new BABYLON.CubeTexture(this._textureUrl, this._scene);
-            hdrTexture.coordinatesMode          = BABYLON.Texture.SKYBOX_MODE;
-            
-            this._cube                          = BABYLON.Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
-            let hdrSkyboxMaterial               = new BABYLON.StandardMaterial("skyBox", this._scene);
-            hdrSkyboxMaterial.backFaceCulling   = false;
-            hdrSkyboxMaterial.reflectionTexture = hdrTexture;
-            hdrSkyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;        
-            hdrSkyboxMaterial.disableLighting   = true;
-            this._cube.material                 = hdrSkyboxMaterial;
-            this._cube.registerBeforeRender(() => {
-                this._cube.rotation.y += 0.01;
-            })
-        }
-        
-        /** Init the babylon engine */
-        private _initEngine() {
-            this._engine           = new BABYLON.Engine(this._canvas);
-            this._scene            = new BABYLON.Scene(this._engine);
-            this._scene.clearColor = new BABYLON.Color4(0,0,0, 0);
-            
-            this._engine.runRenderLoop(() => {
-                if (!this._pause) {
-                    this._scene.render();
-                }
-            });
-            
-            this._canvas.setAttribute('width', '110');
-            this._canvas.setAttribute('height', '110');
+    /** The big div displaying the full image */
+    private _textureDiv: HTMLElement;
+
+    private _engine: Engine;
+    protected _scene: Scene;
+    protected _cube: Mesh;
+    private _canvas: HTMLCanvasElement;
+    protected _textureUrl: string;
+
+    // On pause the engine will not render anything
+    private _pause: boolean = false;
+
+    /** The texture given as a parameter should be cube. */
+    constructor(tex: Texture) {
+        super();
+        this._div.className = 'fa fa-search texture-element';
+
+        // Create the texture viewer
+        this._textureDiv = Helpers.CreateDiv('texture-viewer', this._div);
+        // canvas
+        this._canvas = Helpers.CreateElement('canvas', 'texture-viewer-img', this._textureDiv) as HTMLCanvasElement;
+
+        if (tex) {
+            this._textureUrl = tex.name;
         }
 
-        private _showViewer(mode:string) {
-            // If displaying...
-            if (mode != 'none') {
-                // ... and the canvas is not initialized                
-                if (!this._engine) {
-                    this._initEngine();
-                    this._populateScene();
+        this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
+        this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none'));
+
+    }
+
+    public update(tex?: Texture) {
+        if (tex && tex.url === this._textureUrl) {
+            // Nothing to do, as the old texture is the same as the old one
+        } else {
+            if (tex) {
+                this._textureUrl = tex.name;
+            }
+            if (this._engine) {
+                // Dispose old material and cube
+                if (this._cube.material) {
+                    this._cube.material.dispose(true, true);
                 }
-                // In every cases, unpause the engine
-                this._pause = false;
+                this._cube.dispose();
             } else {
-                // hide : pause the engine
-                this._pause = true;
+                this._initEngine();
             }
-            this._textureDiv.style.display = mode;
+            // and create it again
+            this._populateScene();
         }
-        
-        /** Removes properly the babylon engine */
-        public dispose () {
-            if (this._engine) {
-                this._engine.dispose();
-                (<any>this._engine) = null;
+    }
+
+    /** Creates the box  */
+    protected _populateScene() {
+        // Create the hdr texture
+        let hdrTexture = new CubeTexture(this._textureUrl, this._scene);
+        hdrTexture.coordinatesMode = Texture.SKYBOX_MODE;
+
+        this._cube = Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
+        let hdrSkyboxMaterial = new StandardMaterial("skyBox", this._scene);
+        hdrSkyboxMaterial.backFaceCulling = false;
+        hdrSkyboxMaterial.reflectionTexture = hdrTexture;
+        hdrSkyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE;
+        hdrSkyboxMaterial.disableLighting = true;
+        this._cube.material = hdrSkyboxMaterial;
+        this._cube.registerBeforeRender(() => {
+            this._cube.rotation.y += 0.01;
+        })
+    }
+
+    /** Init the babylon engine */
+    private _initEngine() {
+        this._engine = new Engine(this._canvas);
+        this._scene = new Scene(this._engine);
+        this._scene.clearColor = new Color4(0, 0, 0, 0);
+
+        this._engine.runRenderLoop(() => {
+            if (!this._pause) {
+                this._scene.render();
             }
+        });
+
+        this._canvas.setAttribute('width', '110');
+        this._canvas.setAttribute('height', '110');
+    }
+
+    private _showViewer(mode: string) {
+        // If displaying...
+        if (mode != 'none') {
+            // ... and the canvas is not initialized                
+            if (!this._engine) {
+                this._initEngine();
+                this._populateScene();
+            }
+            // In every cases, unpause the engine
+            this._pause = false;
+        } else {
+            // hide : pause the engine
+            this._pause = true;
+        }
+        this._textureDiv.style.display = mode;
+    }
+
+    /** Removes properly the babylon engine */
+    public dispose() {
+        if (this._engine) {
+            this._engine.dispose();
+            (<any>this._engine) = null;
         }
     }
- }
+}

+ 31 - 30
inspector/src/gui/HDRCubeTextureElement.ts

@@ -1,32 +1,33 @@
- module INSPECTOR {
-     /**
-     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the 
-     * cube texture in a cube
-     */
-    export class HDRCubeTextureElement extends CubeTextureElement{
+import { HDRCubeTexture, Mesh, PBRMaterial, Texture } from "babylonjs";
+import { CubeTextureElement } from "./CubeTextureElement";
 
-            
-        /** The texture given as a parameter should be cube. */
-        constructor(tex : BABYLON.Texture) {
-            super(tex);
-        }
-        
-        /** Creates the box  */
-        protected _populateScene() {
-            // Create the hdr texture
-            let hdrTexture                      = new BABYLON.HDRCubeTexture(this._textureUrl, this._scene, 512);
-            hdrTexture.coordinatesMode          = BABYLON.Texture.SKYBOX_MODE;
-            
-            this._cube                          = BABYLON.Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
-            let hdrSkyboxMaterial               = new BABYLON.PBRMaterial("skyBox", this._scene);
-            hdrSkyboxMaterial.backFaceCulling   = false;
-            hdrSkyboxMaterial.reflectionTexture = hdrTexture;
-            hdrSkyboxMaterial.microSurface      = 1.0;
-            hdrSkyboxMaterial.disableLighting   = true;
-            this._cube.material                 = hdrSkyboxMaterial;
-            this._cube.registerBeforeRender(() => {
-                this._cube.rotation.y += 0.01;
-            })
-        }        
+/**
+* Display a very small div. A new canvas is created, with a new js scene, containing only the 
+* cube texture in a cube
+*/
+export class HDRCubeTextureElement extends CubeTextureElement {
+
+
+    /** The texture given as a parameter should be cube. */
+    constructor(tex: Texture) {
+        super(tex);
+    }
+
+    /** Creates the box  */
+    protected _populateScene() {
+        // Create the hdr texture
+        let hdrTexture = new HDRCubeTexture(this._textureUrl, this._scene, 512);
+        hdrTexture.coordinatesMode = Texture.SKYBOX_MODE;
+
+        this._cube = Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
+        let hdrSkyboxMaterial = new PBRMaterial("skyBox", this._scene);
+        hdrSkyboxMaterial.backFaceCulling = false;
+        hdrSkyboxMaterial.reflectionTexture = hdrTexture;
+        hdrSkyboxMaterial.microSurface = 1.0;
+        hdrSkyboxMaterial.disableLighting = true;
+        this._cube.material = hdrSkyboxMaterial;
+        this._cube.registerBeforeRender(() => {
+            this._cube.rotation.y += 0.01;
+        })
     }
- }
+}

+ 76 - 73
inspector/src/gui/SearchBar.ts

@@ -1,78 +1,81 @@
-module INSPECTOR {
-
-    /**
-     * A search bar can be used to filter elements in the tree panel.
-     * At each keypress on the input, the treepanel will be filtered.
-     */
-    export class SearchBar extends BasicElement {
-
-        private _propTab   : PropertyTab;
-        private _inputElement: HTMLInputElement;
-
-        constructor(tab:PropertyTab) {
-            super();
-            this._propTab = tab;
-            this._div.classList.add('searchbar');
-            
-            let filter = Inspector.DOCUMENT.createElement('i');
-            filter.className = 'fa fa-search';
-            
-            this._div.appendChild(filter);
-            // Create input
-            this._inputElement = Inspector.DOCUMENT.createElement('input');
-            this._inputElement.placeholder = 'Filter by name...';
-            this._div.appendChild(this._inputElement);
-            
-            this._inputElement.addEventListener('keyup', (evt : KeyboardEvent)=> {
-                let filter = this._inputElement.value;
-                this._propTab.filter(filter);
-            })
-        }
-
-        /** Delete all characters typped in the input element */
-        public reset() {
-            this._inputElement.value = '';
-        }
-
-        public update() {
-            // Nothing to update
-        }
+import { DetailPanel } from "../details/DetailPanel";
+import { Inspector } from "../Inspector";
+import { PropertyTab } from "../tabs/PropertyTab";
+import { BasicElement } from "./BasicElement";
 
+
+/**
+ * A search bar can be used to filter elements in the tree panel.
+ * At each keypress on the input, the treepanel will be filtered.
+ */
+export class SearchBar extends BasicElement {
+
+    private _propTab: PropertyTab;
+    private _inputElement: HTMLInputElement;
+
+    constructor(tab: PropertyTab) {
+        super();
+        this._propTab = tab;
+        this._div.classList.add('searchbar');
+
+        let filter = Inspector.DOCUMENT.createElement('i');
+        filter.className = 'fa fa-search';
+
+        this._div.appendChild(filter);
+        // Create input
+        this._inputElement = Inspector.DOCUMENT.createElement('input');
+        this._inputElement.placeholder = 'Filter by name...';
+        this._div.appendChild(this._inputElement);
+
+        this._inputElement.addEventListener('keyup', (evt: KeyboardEvent) => {
+            let filter = this._inputElement.value;
+            this._propTab.filter(filter);
+        })
+    }
+
+    /** Delete all characters typped in the input element */
+    public reset() {
+        this._inputElement.value = '';
+    }
+
+    public update() {
+        // Nothing to update
     }
 
-    export class SearchBarDetails extends BasicElement {
-
-        private _detailTab  : DetailPanel;
-        private _inputElement: HTMLInputElement;
-
-        constructor(tab:DetailPanel) {
-            super();
-            this._detailTab = tab;
-            this._div.classList.add('searchbar');
-            
-            let filter = Inspector.DOCUMENT.createElement('i');
-            filter.className = 'fa fa-search';
-            
-            this._div.appendChild(filter);
-            // Create input
-            this._inputElement = Inspector.DOCUMENT.createElement('input');
-            this._inputElement.placeholder = 'Filter by name...';
-            this._div.appendChild(this._inputElement);
-            
-            this._inputElement.addEventListener('keyup', (evt : KeyboardEvent)=> {
-                let filter = this._inputElement.value;
-                this._detailTab.searchByName(filter);
-            })
-        }
-
-        /** Delete all characters typped in the input element */
-        public reset() {
-            this._inputElement.value = '';
-        }
-
-        public update() {
-            // Nothing to update
-        }
+}
 
+export class SearchBarDetails extends BasicElement {
+
+    private _detailTab: DetailPanel;
+    private _inputElement: HTMLInputElement;
+
+    constructor(tab: DetailPanel) {
+        super();
+        this._detailTab = tab;
+        this._div.classList.add('searchbar');
+
+        let filter = Inspector.DOCUMENT.createElement('i');
+        filter.className = 'fa fa-search';
+
+        this._div.appendChild(filter);
+        // Create input
+        this._inputElement = Inspector.DOCUMENT.createElement('input');
+        this._inputElement.placeholder = 'Filter by name...';
+        this._div.appendChild(this._inputElement);
+
+        this._inputElement.addEventListener('keyup', (evt: KeyboardEvent) => {
+            let filter = this._inputElement.value;
+            this._detailTab.searchByName(filter);
+        })
     }
-}
+
+    /** Delete all characters typped in the input element */
+    public reset() {
+        this._inputElement.value = '';
+    }
+
+    public update() {
+        // Nothing to update
+    }
+
+}

+ 40 - 38
inspector/src/gui/TextureElement.ts

@@ -1,42 +1,44 @@
- module INSPECTOR {
-     /**
-     * Display a very small div corresponding to the given texture. On mouse over, display the full image
-     */
-    export class TextureElement extends BasicElement{
-
-        /** The big div displaying the full image */
-        private _textureDiv : HTMLElement;
-            
-        constructor(tex : BABYLON.Texture) {
-            super();
-            this._div.className = 'fa fa-search texture-element';
-
-            // Create the texture viewer
-            this._textureDiv = Helpers.CreateDiv('texture-viewer', this._div);
-            // Img
-            let imgDiv = Helpers.CreateDiv('texture-viewer-img', this._textureDiv);
-
-            // Texture size
-            let sizeDiv = Helpers.CreateDiv(null, this._textureDiv);
-            
-            if (tex) {
-                sizeDiv.textContent = `${tex.getBaseSize().width}px x ${tex.getBaseSize().height}px`;
-                imgDiv.style.backgroundImage = `url('${tex.url}')`;     
-                imgDiv.style.width = `${tex.getBaseSize().width}px`;
-                imgDiv.style.height = `${tex.getBaseSize().height}px`;
-            }
-
-            this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
-            this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none')); 
+import { Texture } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
+import { BasicElement } from "./BasicElement";
 
-        }
-        
-        public update(tex?:BABYLON.Texture) {
-            
-        }
+/**
+* Display a very small div corresponding to the given texture. On mouse over, display the full image
+*/
+export class TextureElement extends BasicElement {
+
+    /** The big div displaying the full image */
+    private _textureDiv: HTMLElement;
+
+    constructor(tex: Texture) {
+        super();
+        this._div.className = 'fa fa-search texture-element';
 
-        private _showViewer(mode:string) {
-            this._textureDiv.style.display = mode;
+        // Create the texture viewer
+        this._textureDiv = Helpers.CreateDiv('texture-viewer', this._div);
+        // Img
+        let imgDiv = Helpers.CreateDiv('texture-viewer-img', this._textureDiv);
+
+        // Texture size
+        let sizeDiv = Helpers.CreateDiv(null, this._textureDiv);
+
+        if (tex) {
+            sizeDiv.textContent = `${tex.getBaseSize().width}px x ${tex.getBaseSize().height}px`;
+            imgDiv.style.backgroundImage = `url('${tex.url}')`;
+            imgDiv.style.width = `${tex.getBaseSize().width}px`;
+            imgDiv.style.height = `${tex.getBaseSize().height}px`;
         }
+
+        this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
+        this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none'));
+
+    }
+
+    public update(tex?: Texture) {
+
+    }
+
+    private _showViewer(mode: string) {
+        this._textureDiv.style.display = mode;
     }
- }
+}

+ 29 - 28
inspector/src/gui/Tooltip.ts

@@ -1,30 +1,31 @@
-module INSPECTOR {
-    
-    /**
-     * Creates a tooltip for the parent of the given html element
-     */
-    export class Tooltip {
-        
-        /** The tooltip is displayed for this element */
-        private _elem : HTMLElement;
-        
-        /** The tooltip div */
-        private _infoDiv : HTMLDivElement;
-        
-        constructor(elem: HTMLElement, tip:string, attachTo: BABYLON.Nullable<HTMLElement> = null) {
-            
-            this._elem = elem;
-            if (!attachTo) {
-                attachTo = this._elem.parentElement;
-            }
-            this._infoDiv = Helpers.CreateDiv('tooltip', <HTMLElement>attachTo) as HTMLDivElement;
-            
-
-            this._elem.addEventListener('mouseover', () => { 
-                this._infoDiv.textContent = tip;
-                this._infoDiv.style.display = 'block'
-            });
-            this._elem.addEventListener('mouseout', () => { this._infoDiv.style.display = 'none'});
+import { Nullable } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
+
+
+/**
+ * Creates a tooltip for the parent of the given html element
+ */
+export class Tooltip {
+
+    /** The tooltip is displayed for this element */
+    private _elem: HTMLElement;
+
+    /** The tooltip div */
+    private _infoDiv: HTMLDivElement;
+
+    constructor(elem: HTMLElement, tip: string, attachTo: Nullable<HTMLElement> = null) {
+
+        this._elem = elem;
+        if (!attachTo) {
+            attachTo = this._elem.parentElement;
         }
+        this._infoDiv = Helpers.CreateDiv('tooltip', <HTMLElement>attachTo) as HTMLDivElement;
+
+
+        this._elem.addEventListener('mouseover', () => {
+            this._infoDiv.textContent = tip;
+            this._infoDiv.style.display = 'block'
+        });
+        this._elem.addEventListener('mouseout', () => { this._infoDiv.style.display = 'none' });
     }
-}
+}

+ 0 - 0
inspector/src/gui/index.ts


Some files were not shown because too many files changed in this diff