Patrick Ryan 6 éve
szülő
commit
b0dc119b45
100 módosított fájl, 23045 hozzáadás és 25886 törlés
  1. 4 0
      .gitignore
  2. 8223 8042
      Playground/babylon.d.txt
  3. 3 2
      Playground/css/index.css
  4. 370 370
      Playground/index-local.html
  5. 7 30
      Playground/js/index.js
  6. 3 587
      Playground/js/libs/split.js
  7. 30 28
      Tools/DevLoader/BabylonLoader.js
  8. 4 2
      Tools/Gulp/config.json
  9. 3 4
      Tools/Gulp/gulpfile.js
  10. 3 5
      Tools/Gulp/package.json
  11. 10500 10377
      dist/preview release/babylon.d.ts
  12. 1 1
      dist/preview release/babylon.js
  13. 625 296
      dist/preview release/babylon.max.js
  14. 625 296
      dist/preview release/babylon.no-module.max.js
  15. 1 1
      dist/preview release/babylon.worker.js
  16. 625 296
      dist/preview release/es6.js
  17. 1 1
      dist/preview release/glTF2Interface/package.json
  18. 64 2
      dist/preview release/gui/babylon.gui.d.ts
  19. 1 1
      dist/preview release/gui/babylon.gui.js
  20. 1 1
      dist/preview release/gui/babylon.gui.min.js
  21. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  22. 128 4
      dist/preview release/gui/babylon.gui.module.d.ts
  23. 2 2
      dist/preview release/gui/package.json
  24. 41 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  25. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js.map
  26. 12 1039
      dist/preview release/inspector/babylon.inspector.d.ts
  27. 29 2368
      dist/preview release/inspector/babylon.inspector.module.d.ts
  28. 5 5
      dist/preview release/inspector/package.json
  29. 2 2
      dist/preview release/inspector/readme.md
  30. 14 7
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  31. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  32. 14 7
      dist/preview release/loaders/babylon.glTFFileLoader.js
  33. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  34. 14 7
      dist/preview release/loaders/babylonjs.loaders.js
  35. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  36. 3 3
      dist/preview release/loaders/package.json
  37. 2 2
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  38. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  39. 2 2
      dist/preview release/materialsLibrary/babylonjs.materials.js
  40. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  41. 2 2
      dist/preview release/materialsLibrary/package.json
  42. 2 2
      dist/preview release/postProcessesLibrary/package.json
  43. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  44. 3 3
      dist/preview release/serializers/package.json
  45. 2 2
      dist/preview release/viewer/babylon.viewer.d.ts
  46. 3 3
      dist/preview release/viewer/babylon.viewer.js
  47. 8 8
      dist/preview release/viewer/babylon.viewer.max.js
  48. 2 2
      dist/preview release/viewer/babylon.viewer.module.d.ts
  49. 6 1
      dist/preview release/what's new.md
  50. 71 20
      gui/src/2D/advancedDynamicTexture.ts
  51. 22 10
      gui/src/2D/controls/colorpicker.ts
  52. 29 2
      gui/src/2D/controls/container.ts
  53. 72 1
      gui/src/2D/controls/control.ts
  54. 59 11
      gui/src/2D/controls/grid.ts
  55. 25 23
      gui/src/2D/controls/inputText.ts
  56. 8 0
      gui/src/3D/controls/control3D.ts
  57. 1 11
      gui/webpack.config.js
  58. 5 4
      inspector/index.html
  59. 26 15
      inspector/package.json
  60. 0 156
      inspector/sass/_detailPanel.scss
  61. 0 18
      inspector/sass/_resizeBar.scss
  62. 0 19
      inspector/sass/_searchbar.scss
  63. 0 74
      inspector/sass/_slider.scss
  64. 0 92
      inspector/sass/_tabPanel.scss
  65. 0 60
      inspector/sass/_tabbar.scss
  66. 0 31
      inspector/sass/_toolbar.scss
  67. 0 14
      inspector/sass/_tooltip.scss
  68. 0 73
      inspector/sass/_tree.scss
  69. 0 16
      inspector/sass/_treeTool.scss
  70. 0 28
      inspector/sass/defines.scss
  71. 0 105
      inspector/sass/main.scss
  72. 0 51
      inspector/sass/tabs/_consoleTab.scss
  73. 0 92
      inspector/sass/tabs/_gltfTab.scss
  74. 0 53
      inspector/sass/tabs/_shaderTab.scss
  75. 0 52
      inspector/sass/tabs/_statsTab.scss
  76. 0 80
      inspector/sass/tabs/_toolsTab.scss
  77. BIN
      inspector/screens/tab_mesh.jpg
  78. BIN
      inspector/screens/tools.jpg
  79. 0 441
      inspector/src/Inspector.ts
  80. 0 43
      inspector/src/adapters/Adapter.ts
  81. 0 56
      inspector/src/adapters/CameraAdapter.ts
  82. 0 48
      inspector/src/adapters/GUIAdapter.ts
  83. 0 51
      inspector/src/adapters/LightAdapter.ts
  84. 0 37
      inspector/src/adapters/MaterialAdapter.ts
  85. 0 116
      inspector/src/adapters/MeshAdapter.ts
  86. 0 59
      inspector/src/adapters/PhysicsImpostorAdapter.ts
  87. 0 52
      inspector/src/adapters/SoundAdapter.ts
  88. 0 40
      inspector/src/adapters/TextureAdapter.ts
  89. 0 9
      inspector/src/adapters/index.ts
  90. 773 0
      inspector/src/components/actionTabs/actionTabs.scss
  91. 133 0
      inspector/src/components/actionTabs/actionTabsComponent.tsx
  92. 70 0
      inspector/src/components/actionTabs/lineContainerComponent.tsx
  93. 31 0
      inspector/src/components/actionTabs/lines/booleanLineComponent.tsx
  94. 21 0
      inspector/src/components/actionTabs/lines/buttonLineComponent.tsx
  95. 79 0
      inspector/src/components/actionTabs/lines/checkBoxLineComponent.tsx
  96. 61 0
      inspector/src/components/actionTabs/lines/color3LineComponent.tsx
  97. 33 0
      inspector/src/components/actionTabs/lines/fileButtonLineComponent.tsx
  98. 89 0
      inspector/src/components/actionTabs/lines/floatLineComponent.tsx
  99. 38 0
      inspector/src/components/actionTabs/lines/messageLineComponent.tsx
  100. 0 0
      inspector/src/components/actionTabs/lines/numericInputComponent.tsx

+ 4 - 0
.gitignore

@@ -189,3 +189,7 @@ Viewer/tests/Lib/**/*.js
 Viewer/tests/commons/**/*.js
 .sass-cache/
 gui/dist/
+/Viewer/tests/tsc
+/Viewer/tests/tsc.cmd
+/Viewer/tests/tsserver
+/Viewer/tests/tsserver.cmd

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 8223 - 8042
Playground/babylon.d.txt


+ 3 - 2
Playground/css/index.css

@@ -246,6 +246,8 @@ body {
     width: 100%;
     height: 100%;
     touch-action: none;
+    display: block;
+    font-size: 0;
 }
 #fpsLabel {
     position: absolute;
@@ -472,7 +474,6 @@ body {
     padding:20px;
     border-radius: 5px;
     color:white;
-    font-family: 'Inconsolata';
 }
 #errorZone button {
     position:absolute;
@@ -508,7 +509,7 @@ body {
 .navbarBottom #statusBar {
     line-height:30px;
     color: #E74C3C;
-    font-family: 'Inconsolata';
+    font-size: 14px;
     padding-left:20px;
 }
 

+ 370 - 370
Playground/index-local.html

@@ -1,455 +1,455 @@
 <!DOCTYPE html>
 <html>
 
-    <head>
-        <title>Babylon.js Playground</title>
-        <meta charset='utf-8' />
-        <meta name="viewport" content="width=device-width, user-scalable=no">
-        <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>
-        <!-- Dependencies -->
-        <script src="../dist/preview%20release/cannon.js"></script>
-        <script src="../dist/preview%20release/Oimo.js"></script>
-        <script src="../dist/preview%20release/gltf_validator.js"></script>
-        <script src="../dist/preview%20release/earcut.min.js"></script>
-        <!-- Monaco -->
-
-        <!-- Babylon.js -->
-        <script src="../tools/DevLoader/BabylonLoader.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">
-            </div>
+<head>
+    <title>Babylon.js Playground</title>
+    <meta charset='utf-8' />
+    <meta name="viewport" content="width=device-width, user-scalable=no">
+    <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>
+    <!-- Dependencies -->
+    <script src="../dist/preview%20release/cannon.js"></script>
+    <script src="../dist/preview%20release/Oimo.js"></script>
+    <script src="../dist/preview%20release/gltf_validator.js"></script>
+    <script src="../dist/preview%20release/earcut.min.js"></script>
+    <!-- Monaco -->
+
+    <!-- Babylon.js -->
+    <script src="../tools/DevLoader/BabylonLoader.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">
+        </div>
 
-            <div class="category">
-                <div class="button run" id="runButton1600">Run
-                    <i class="fa fa-play" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button run" id="runButton1600">Run
+                <i class="fa fa-play" aria-hidden="true"></i>
             </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>
+        <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 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 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 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 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 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="far fa-square" 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="far fa-square" aria-hidden="true"></i>
+                    </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="far fa-square" 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="far fa-square" aria-hidden="true"></i>
+                    </div>
                 </div>
-
-                <div class="button uncheck" id="debugButton1600">Inspector</div>
-                <div class="button" id="metadataButton1600">Metadata</div>
             </div>
 
+            <div class="button uncheck" id="debugButton1600">Inspector</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>
-                </div>
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
+
+        <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>
 
-        <div class="navbar navBar1475">
-            <div class="title">
-                Babylon.js Playground
-            </div>
-            <div class="version" id="mainTitle">
-            </div>
+    <div class="navbar navBar1475">
+        <div class="title">
+            Babylon.js Playground
+        </div>
+        <div class="version" id="mainTitle">
+        </div>
 
-            <div class="category">
-                <div class="button run" id="runButton1475">Run
-                    <i class="fa fa-play" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button run" id="runButton1475">Run
+                <i class="fa fa-play" aria-hidden="true"></i>
             </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>
+        <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 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 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 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 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 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 class="option" id='safemodeToggle1475'>Safe mode
-                            <i class="far fa-square" 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="far fa-square" aria-hidden="true"></i>
+                    </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 class="option" id="debugButton1475">Inspector</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 class="option" id='safemodeToggle1475'>Safe mode
+                        <i class="far fa-square" 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="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="debugButton1475">Inspector</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 class="category right">
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
-                </div>
+        <div class="category right">
+            <div class="button select">
+                <span class="examplesButton">Examples</span>
             </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>
+    <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 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 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 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 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 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 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 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 class="option" id="safemodeToggle1030">Safe mode
-                            <i class="far fa-square" 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="far fa-square" aria-hidden="true"></i>
+                    </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 class="option" id="debugButton1030">Inspector</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 class="option" id="safemodeToggle1030">Safe mode
+                        <i class="far fa-square" 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="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="debugButton1030">Inspector</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 class="category right">
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
-                </div>
+        <div class="category right">
+            <div class="button select">
+                <span class="examplesButton">Examples</span>
             </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>
+    </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>
                 </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>
-                        </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 class="option" id="safemodeToggle750">Safe mode
-                            <i class="far fa-square" 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 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 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="far fa-square" aria-hidden="true"></i>
+                    </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 class="option" id="debugButton750">Inspector</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 class="option" id="safemodeToggle750">Safe mode
+                        <i class="far fa-square" 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="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="debugButton750">Inspector</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 class="category right">
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
-                </div>
+        <div class="category right">
+            <div class="button select">
+                <span class="examplesButton">Examples</span>
             </div>
         </div>
+    </div>
 
-        <div class="wrapper">
-            <div id="jsEditor"></div>
-            <div id="canvasZone">
-                <canvas touch-action="none" id="renderCanvas"></canvas>
-            </div>
+    <div class="wrapper">
+        <div id="jsEditor"></div>
+        <div id="canvasZone">
+            <canvas touch-action="none" id="renderCanvas"></canvas>
         </div>
-        <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 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>
 
-        <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>
+    <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 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>
+                <div id="saveFormButtonOk" class="button">OK</div>
+                <div id="saveFormButtonCancel" class="button">Cancel</div>
             </div>
         </div>
-
-        <div id="waitDiv">
-            <span id="waitTitle">Babylon.js Playground
-                <BR>
-                <BR>
-                <BR>
-            </span>
-            <img src="waitlogo.png" id="waitLogo" />
-        </div>
-
-        <script src="https://code.jquery.com/jquery.js"></script>
-
-        <script src="js/actions.js"></script>
-        <script src="js/pbt.js"></script>
-        <script>
-            BABYLONDEVTOOLS.Loader
-                .require('node_modules/monaco-editor/min/vs/loader.js')
-                .require('js/index.js')
-                .load(function () {
-                    BABYLON.DracoCompression.Configuration.decoder = {
-                        wasmUrl: "../dist/preview%20release/draco_wasm_wrapper_gltf.js",
-                        wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
-                        fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
-                    };
-                });
-        </script>
-    </body>
-
-</html>
+    </div>
+
+    <div id="waitDiv">
+        <span id="waitTitle">Babylon.js Playground
+            <BR>
+            <BR>
+            <BR>
+        </span>
+        <img src="waitlogo.png" id="waitLogo" />
+    </div>
+
+    <script src="https://code.jquery.com/jquery.js"></script>
+
+    <script src="js/actions.js"></script>
+    <script src="js/pbt.js"></script>
+    <script>
+        BABYLONDEVTOOLS.Loader
+            .require('node_modules/monaco-editor/min/vs/loader.js')
+            .require('js/index.js')
+            .load(function() {
+                BABYLON.DracoCompression.Configuration.decoder = {
+                    wasmUrl: "../dist/preview%20release/draco_wasm_wrapper_gltf.js",
+                    wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
+                    fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
+                };
+            });
+    </script>
+</body>
+
+</html>

+ 7 - 30
Playground/js/index.js

@@ -498,29 +498,11 @@ function showError(errorMessage, errorEvent) {
                 }
 
                 var showInspector = false;
-                var showDebugLayer = false;
-                var initialTabIndex = 0;
                 showBJSPGMenu();
                 jsEditor.updateOptions({ readOnly: false });
 
-                if (document.getElementsByClassName('insp-wrapper').length > 0) {
-                    for (var i = 0; i < engine.scenes.length; i++) {
-                        if (engine.scenes[i]._debugLayer) {
-                            //TODO: once inspector is updated on netlify, use getActiveTabIndex instead of the following loop
-                            //initialTabIndex = engine.scenes[i]._debugLayer._inspector.getActiveTabIndex();
-                            var tabs = engine.scenes[i]._debugLayer._inspector._tabbar._tabs;
-                            for (var j = 0; j < tabs.length; j++) {
-                                if (tabs[j].isActive()) {
-                                    initialTabIndex = j;
-                                    break;
-                                }
-                            }
-                            break;
-                        }
-                    }
+                if (BABYLON.Engine.LastCreatedScene && BABYLON.Engine.LastCreatedScene.debugLayer.isVisible()) {
                     showInspector = true;
-                } else if (document.getElementById('DebugLayer')) {
-                    showDebugLayer = true;
                 }
 
                 if (engine) {
@@ -644,12 +626,9 @@ function showError(errorMessage, errorEvent) {
 
                     if (scene) {
                         if (showInspector) {
-                            scene.debugLayer.show({ initialTab: initialTabIndex });
-                            scene.executeWhenReady(function() {
-                                scene.debugLayer._inspector.refresh();
-                            })
-                        } else if (showDebugLayer) {
-                            scene.debugLayer.show();
+                            if (!scene.debugLayer.isVisible()) {
+                                scene.debugLayer.show({ embedMode: true });
+                            }
                         }
                     }
                 });
@@ -905,8 +884,7 @@ function showError(errorMessage, errorEvent) {
             engine.resize();
 
             if (scene.debugLayer.isVisible()) {
-                scene.debugLayer.hide();  // Because when you close it with the cross, it doesn't call hide(), so you have to do it in code
-                scene.debugLayer.show();
+                scene.debugLayer.show({ embedMode: true });
             }
         }
 
@@ -969,12 +947,11 @@ function showError(errorMessage, errorEvent) {
         var toggleDebug = function() {
             // Always showing the debug layer, because you can close it by itself
             var scene = engine.scenes[0];
-            if (document.getElementsByClassName("insp-right-panel")[0]) {
+            if (scene.debugLayer.isVisible()) {
                 scene.debugLayer.hide();
             }
             else {
-                scene.debugLayer.hide(); // Because when you close it with the cross, it doesn't call hide(), so you have to do it in code
-                scene.debugLayer.show();
+                scene.debugLayer.show({ embedMode: true });
             }
         }
 

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 3 - 587
Playground/js/libs/split.js


+ 30 - 28
Tools/DevLoader/BabylonLoader.js

@@ -1,12 +1,12 @@
 // Old Fashion Way for IE 11 Devs. Yes, that still exists ;-)
 
 var BABYLONDEVTOOLS;
-(function (BABYLONDEVTOOLS) {
+(function(BABYLONDEVTOOLS) {
 
-    var getJson = function (url, callback, errorCallback) {
+    var getJson = function(url, callback, errorCallback) {
         var xhr = new XMLHttpRequest();
         xhr.open('GET', url);
-        xhr.onload = function () {
+        xhr.onload = function() {
             if (this.status >= 200 && this.status < 300) {
                 var data = JSON.parse(xhr.response);
                 callback(data)
@@ -17,7 +17,7 @@ var BABYLONDEVTOOLS;
                 });
             }
         };
-        xhr.onerror = function () {
+        xhr.onerror = function() {
             errorCallback({
                 status: this.status,
                 statusText: xhr.statusText
@@ -26,11 +26,12 @@ var BABYLONDEVTOOLS;
         xhr.send();
     }
 
-    var Loader = (function () {
+    var Loader = (function() {
         var queue;
         var callback;
         var dependencies;
         var useDist;
+        var testMode;
         var min;
         var babylonJSPath;
 
@@ -43,10 +44,10 @@ var BABYLONDEVTOOLS;
             babylonJSPath = '';
         }
 
-        Loader.prototype.debugShortcut = function (engine) {
+        Loader.prototype.debugShortcut = function(engine) {
             // Add inspector shortcut
             var map = {};
-            var onkey = function (e) {
+            var onkey = function(e) {
                 e = e || event; // to deal with IE
                 map[e.keyCode] = e.type == 'keydown';
                 if (map[17] && map[16] && map[18] && map[73]) {
@@ -69,12 +70,12 @@ var BABYLONDEVTOOLS;
             document.addEventListener("keyup", onkey);
         }
 
-        Loader.prototype.root = function (newBabylonJSPath) {
+        Loader.prototype.root = function(newBabylonJSPath) {
             babylonJSPath = newBabylonJSPath;
             return this;
         }
 
-        Loader.prototype.require = function (newDependencies) {
+        Loader.prototype.require = function(newDependencies) {
             if (typeof newDependencies === 'string') {
                 dependencies.push(newDependencies);
             }
@@ -86,17 +87,22 @@ var BABYLONDEVTOOLS;
             return this;
         }
 
-        Loader.prototype.onReady = function (newCallback) {
+        Loader.prototype.onReady = function(newCallback) {
             callback = newCallback;
             return this;
         }
 
-        Loader.prototype.useDist = function () {
+        Loader.prototype.testMode = function() {
+            testMode = true;
+            return this;
+        }
+
+        Loader.prototype.useDist = function() {
             useDist = true;
             return this;
         }
 
-        Loader.prototype.dequeue = function () {
+        Loader.prototype.dequeue = function() {
             if (queue.length == 0) {
                 console.log('Scripts loaded');
                 BABYLON.Engine.ShadersRepository = "/src/Shaders/";
@@ -114,17 +120,17 @@ var BABYLONDEVTOOLS;
             script.src = url;
 
             var self = this;
-            script.onload = function () {
+            script.onload = function() {
                 self.dequeue();
             };
             head.appendChild(script);
         }
 
-        Loader.prototype.loadScript = function (url) {
+        Loader.prototype.loadScript = function(url) {
             queue.push(url);
         }
 
-        Loader.prototype.loadCss = function (url) {
+        Loader.prototype.loadCss = function(url) {
             var head = document.getElementsByTagName('head')[0];
 
             var style = document.createElement('link');
@@ -134,13 +140,13 @@ var BABYLONDEVTOOLS;
             document.head.appendChild(style);
         }
 
-        Loader.prototype.loadScripts = function (urls) {
+        Loader.prototype.loadScripts = function(urls) {
             for (var i = 0; i < urls.length; i++) {
                 this.loadScript(urls[i]);
             }
         }
 
-        Loader.prototype.loadLibrary = function (library, module) {
+        Loader.prototype.loadLibrary = function(library, module) {
             if (library.preventLoadLibrary) {
                 return;
             }
@@ -189,7 +195,7 @@ var BABYLONDEVTOOLS;
                 }
             }
             else {
-                if (module.build.distOutputDirectory)
+                if (module.build.distOutputDirectory && (!testMode || !module.build.ignoreInTestMode))
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
             }
 
@@ -201,13 +207,13 @@ var BABYLONDEVTOOLS;
             }
         }
 
-        Loader.prototype.loadModule = function (module) {
+        Loader.prototype.loadModule = function(module) {
             for (var i = 0; i < module.libraries.length; i++) {
                 this.loadLibrary(module.libraries[i], module);
             }
         }
 
-        Loader.prototype.processDependency = function (settings, dependency, filesToLoad) {
+        Loader.prototype.processDependency = function(settings, dependency, filesToLoad) {
             if (dependency.dependUpon) {
                 for (var i = 0; i < dependency.dependUpon.length; i++) {
                     var dependencyName = dependency.dependUpon[i];
@@ -225,7 +231,7 @@ var BABYLONDEVTOOLS;
             }
         }
 
-        Loader.prototype.loadBJSScripts = function (settings) {
+        Loader.prototype.loadBJSScripts = function(settings) {
             var loadModules = true;
 
             // Main bjs files
@@ -262,17 +268,13 @@ var BABYLONDEVTOOLS;
             }
         }
 
-        Loader.prototype.load = function (newCallback) {
+        Loader.prototype.load = function(newCallback) {
             var self = this;
             if (newCallback) {
                 callback = newCallback;
             }
             getJson('/Tools/Gulp/config.json',
-                function (data) {
-                    if (!min) {
-                        self.loadScript('/dist/preview release/split.js');
-                    }
-
+                function(data) {
                     self.loadBJSScripts(data);
                     if (dependencies) {
                         self.loadScripts(dependencies);
@@ -280,7 +282,7 @@ var BABYLONDEVTOOLS;
 
                     self.dequeue();
                 },
-                function (reason) {
+                function(reason) {
                     console.error(reason);
                 }
             );

+ 4 - 2
Tools/Gulp/config.json

@@ -1963,7 +1963,7 @@
                 "main": "../../dist/preview release/gui/build/index.d.ts",
                 "out": "../babylon.gui.module.d.ts",
                 "baseDir": "../../dist/preview release/gui/build/",
-                "headerText": "BabylonJS GUI"
+                "headerText": "Babylon.js GUI"
             },
             "processDeclaration": {
                 "filename": "babylon.gui.module.d.ts",
@@ -1987,10 +1987,12 @@
                 "webpack": "../../inspector/webpack.config.js",
                 "bundle": "true",
                 "extendsRoot": true,
+                "babylonIncluded": false,
                 "useOutputForDebugging": true
             }
         ],
         "build": {
+            "ignoreInTestMode": true,
             "srcOutputDirectory": "../../inspector/src/",
             "distOutputDirectory": "/inspector/",
             "dtsBundle": {
@@ -1998,7 +2000,7 @@
                 "main": "../../dist/preview release/inspector/build/index.d.ts",
                 "out": "../babylon.inspector.module.d.ts",
                 "baseDir": "../../dist/preview release/inspector/build/",
-                "headerText": "BabylonJS Inspector"
+                "headerText": "Babylon.js Inspector"
             },
             "processDeclaration": {
                 "filename": "babylon.inspector.module.d.ts",

+ 3 - 4
Tools/Gulp/gulpfile.js

@@ -274,7 +274,7 @@ gulp.task("build", gulp.series("shaders", function build() {
 * TsLint all typescript files from the src directory.
 */
 gulp.task("typescript-tsLint", function() {
-    const dtsFilter = filter(['**', '!**/*.d.ts'], {restore: false});
+    const dtsFilter = filter(['**', '!**/*.d.ts'], { restore: false });
     return gulp.src(config.typescript)
         .pipe(dtsFilter)
         .pipe(gulpTslint({
@@ -348,7 +348,7 @@ gulp.task("tsLint", gulp.series("typescript-tsLint", "typescript-libraries-tsLin
 * Compiles all typescript files and creating a js and a declaration file.
 */
 gulp.task("typescript-compile", function() {
-    const dtsFilter = filter(['**', '!**/*.d.ts'], {restore: false});
+    const dtsFilter = filter(['**', '!**/*.d.ts'], { restore: false });
     var tsResult = gulp.src(config.typescript)
         .pipe(dtsFilter)
         .pipe(sourcemaps.init())
@@ -686,7 +686,6 @@ var buildExternalLibrary = function(library, settings, watch) {
                         cb();
                     }))
                     .pipe(rename(function(path) {
-                        console.log(path.basename);
                         //path.extname === ".js"
                         path.basename = path.basename.replace(".min", "")
                     })).pipe(gulp.dest(outputDirectory));
@@ -883,7 +882,7 @@ gulp.task("netlify-cleanup", function() {
 
 // this is needed for the modules for the declaration files.
 gulp.task("modules-compile", function() {
-    const dtsFilter = filter(['**', '!**/*.d.ts'], {restore: false});
+    const dtsFilter = filter(['**', '!**/*.d.ts'], { restore: false });
     var tsResult = gulp.src(config.typescript)
         .pipe(dtsFilter)
         .pipe(sourcemaps.init())

+ 3 - 5
Tools/Gulp/package.json

@@ -49,13 +49,11 @@
         "typedoc": "^0.12.0",
         "typescript": "~3.0.1",
         "webpack": "^4.16.3",
-        "webpack-stream": "5.0.0"
+        "webpack-stream": "5.0.0",
+        "dts-bundle": "^0.7.3",
+        "gulp-clean": "^0.4.0"
     },
     "scripts": {
         "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",
-        "gulp-clean": "^0.4.0"
     }
 }

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 10500 - 10377
dist/preview release/babylon.d.ts


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/babylon.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 625 - 296
dist/preview release/babylon.max.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 625 - 296
dist/preview release/babylon.no-module.max.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/babylon.worker.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 625 - 296
dist/preview release/es6.js


+ 1 - 1
dist/preview release/glTF2Interface/package.json

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 64 - 2
dist/preview release/gui/babylon.gui.d.ts

@@ -1,6 +1,6 @@
-/*BabylonJS GUI*/
+/*Babylon.js GUI*/
 // Dependencies for this module:
-//   ../../../../Tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
@@ -60,11 +60,17 @@ declare module BABYLON.GUI {
             _layerToDispose: BABYLON.Nullable<BABYLON.Layer>;
             /** @hidden */
             _linkedControls: Control[];
+            /** @hidden */
+            _needRedraw: boolean;
             /**
                 * BABYLON.Observable event triggered each time an clipboard event is received from the rendering canvas
                 */
             onClipboardObservable: BABYLON.Observable<BABYLON.ClipboardInfo>;
             /**
+                * BABYLON.Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: BABYLON.Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -106,6 +112,19 @@ declare module BABYLON.GUI {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                * @returns an array containing the rootContainer
+                */
+            getChildren(): Array<Container>;
+            /**
+                * Will return all controls that are inside this texture
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: BABYLON.Nullable<IFocusableControl>;
@@ -128,6 +147,11 @@ declare module BABYLON.GUI {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -171,6 +195,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -835,6 +861,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /** @hidden */
             _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean;
             /** @hidden */
             protected _clipForChildren(context: CanvasRenderingContext2D): void;
@@ -897,6 +925,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -925,6 +957,11 @@ declare module BABYLON.GUI {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: BABYLON.Observable<BABYLON.Vector2>;
@@ -968,6 +1005,10 @@ declare module BABYLON.GUI {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -1179,6 +1220,15 @@ declare module BABYLON.GUI {
                 * @param scene defines the hosting scene
                 */
             moveToVector3(position: BABYLON.Vector3, scene: BABYLON.Scene): void;
+            /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /**
+                * Will return all controls that have this control as ascendant
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
             /**
                 * Link current control with a target mesh
                 * @param mesh defines the mesh to link with
@@ -1200,6 +1250,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -1378,7 +1432,10 @@ declare module BABYLON.GUI {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -2473,6 +2530,11 @@ declare module BABYLON.GUI {
                 * Gets a string representing the class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/gui/babylon.gui.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 128 - 4
dist/preview release/gui/babylon.gui.module.d.ts

@@ -1,6 +1,6 @@
-/*BabylonJS GUI*/
+/*Babylon.js GUI*/
 // Dependencies for this module:
-//   ../../../../Tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 
 declare module 'babylonjs-gui' {
     export * from "babylonjs-gui/2D";
@@ -105,11 +105,17 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
             _layerToDispose: Nullable<Layer>;
             /** @hidden */
             _linkedControls: Control[];
+            /** @hidden */
+            _needRedraw: boolean;
             /**
                 * Observable event triggered each time an clipboard event is received from the rendering canvas
                 */
             onClipboardObservable: Observable<ClipboardInfo>;
             /**
+                * Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -151,6 +157,19 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                * @returns an array containing the rootContainer
+                */
+            getChildren(): Array<Container>;
+            /**
+                * Will return all controls that are inside this texture
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: Nullable<IFocusableControl>;
@@ -173,6 +192,11 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: Nullable<Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -216,6 +240,8 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -935,6 +961,8 @@ declare module 'babylonjs-gui/2D/controls/container' {
             /** @hidden */
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /** @hidden */
             _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean;
             /** @hidden */
             protected _clipForChildren(context: CanvasRenderingContext2D): void;
@@ -1005,6 +1033,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -1033,6 +1065,11 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: Observable<Vector2>;
@@ -1076,6 +1113,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -1287,6 +1328,15 @@ declare module 'babylonjs-gui/2D/controls/control' {
                 * @param scene defines the hosting scene
                 */
             moveToVector3(position: Vector3, scene: Scene): void;
+            /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /**
+                * Will return all controls that have this control as ascendant
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
             /**
                 * Link current control with a target mesh
                 * @param mesh defines the mesh to link with
@@ -1308,6 +1358,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -1494,7 +1548,10 @@ declare module 'babylonjs-gui/2D/controls/grid' {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -2664,6 +2721,11 @@ declare module 'babylonjs-gui/3D/controls/control3D' {
                 * Gets a string representing the class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control
@@ -3007,9 +3069,9 @@ declare module 'babylonjs-gui/3D/materials/fluentMaterial' {
 }
 
 
-/*BabylonJS GUI*/
+/*Babylon.js GUI*/
 // Dependencies for this module:
-//   ../../../../Tools/Gulp/babylonjs
+//   ../../../../Tools/gulp/babylonjs
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
@@ -3069,11 +3131,17 @@ declare module BABYLON.GUI {
             _layerToDispose: BABYLON.Nullable<BABYLON.Layer>;
             /** @hidden */
             _linkedControls: Control[];
+            /** @hidden */
+            _needRedraw: boolean;
             /**
                 * BABYLON.Observable event triggered each time an clipboard event is received from the rendering canvas
                 */
             onClipboardObservable: BABYLON.Observable<BABYLON.ClipboardInfo>;
             /**
+                * BABYLON.Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: BABYLON.Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -3115,6 +3183,19 @@ declare module BABYLON.GUI {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                * @returns an array containing the rootContainer
+                */
+            getChildren(): Array<Container>;
+            /**
+                * Will return all controls that are inside this texture
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: BABYLON.Nullable<IFocusableControl>;
@@ -3137,6 +3218,11 @@ declare module BABYLON.GUI {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -3180,6 +3266,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -3844,6 +3932,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /** @hidden */
             _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean;
             /** @hidden */
             protected _clipForChildren(context: CanvasRenderingContext2D): void;
@@ -3906,6 +3996,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -3934,6 +4028,11 @@ declare module BABYLON.GUI {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: BABYLON.Observable<BABYLON.Vector2>;
@@ -3977,6 +4076,10 @@ declare module BABYLON.GUI {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -4188,6 +4291,15 @@ declare module BABYLON.GUI {
                 * @param scene defines the hosting scene
                 */
             moveToVector3(position: BABYLON.Vector3, scene: BABYLON.Scene): void;
+            /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /**
+                * Will return all controls that have this control as ascendant
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
             /**
                 * Link current control with a target mesh
                 * @param mesh defines the mesh to link with
@@ -4209,6 +4321,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -4387,7 +4503,10 @@ declare module BABYLON.GUI {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -5482,6 +5601,11 @@ declare module BABYLON.GUI {
                 * Gets a string representing the class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.7"
+        "babylonjs": "4.0.0-alpha.8"
     },
     "engines": {
         "node": "*"

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 41 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 12 - 1039
dist/preview release/inspector/babylon.inspector.d.ts


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 29 - 2368
dist/preview release/inspector/babylon.inspector.module.d.ts


+ 5 - 5
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,10 +28,10 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.7",
-        "babylonjs-gui": "4.0.0-alpha.7",
-        "babylonjs-loaders": "4.0.0-alpha.7",
-        "babylonjs-serializers": "4.0.0-alpha.7"
+        "babylonjs": "4.0.0-alpha.8",
+        "babylonjs-gui": "4.0.0-alpha.8",
+        "babylonjs-loaders": "4.0.0-alpha.8",
+        "babylonjs-serializers": "4.0.0-alpha.8"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/inspector/readme.md

@@ -1,7 +1,7 @@
 Babylon.js inspector module
 =====================
 
-For usage documentation please visit http://doc.babylonjs.com/how_to/debug_layer and search "inspector".
+For usage documentation please visit http://doc.babylonjs.com/how_to/debug_layer.
 
 # Installation instructions
 
@@ -13,7 +13,7 @@ If you wish however to use a different version of the inspector or host it on yo
 
 The latest compiled js file is offered on our public CDN here:
 
-* https://preview.babylonjs.com/inspector/babylonjs.inspector.bundle.js
+* https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js
 
 ## NPM
 

+ 14 - 7
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -2220,8 +2220,14 @@ var BABYLON;
                 this.logOpen(context + " " + (texture.name || ""));
                 var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this.gltf.samplers, texture.sampler));
                 var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+                var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
+                var textureURL = null;
+                if (image.uri && !BABYLON.Tools.IsBase64(image.uri) && this.babylonScene.getEngine().textureFormatInUse) {
+                    // If an image uri and a texture format is set like (eg. KTX) load from url instead of blob to support texture format and fallback
+                    textureURL = this._uniqueRootUrl + image.uri;
+                }
                 var deferred = new BABYLON.Deferred();
-                var babylonTexture = new BABYLON.Texture(null, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
+                var babylonTexture = new BABYLON.Texture(textureURL, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                     if (!_this._disposed) {
                         deferred.resolve();
                     }
@@ -2231,14 +2237,15 @@ var BABYLON;
                     }
                 });
                 promises.push(deferred.promise);
+                if (!textureURL) {
+                    promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
+                        var name = image.uri || _this._fileName + "#image" + image.index;
+                        var dataUrl = "data:" + _this._uniqueRootUrl + name;
+                        babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                    }));
+                }
                 babylonTexture.wrapU = samplerData.wrapU;
                 babylonTexture.wrapV = samplerData.wrapV;
-                var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
-                promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
-                    var name = image.uri || _this._fileName + "#image" + image.index;
-                    var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                    babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
-                }));
                 assign(babylonTexture);
                 this.logClose();
                 return Promise.all(promises).then(function () {

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 14 - 7
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -4428,8 +4428,14 @@ var BABYLON;
                 this.logOpen(context + " " + (texture.name || ""));
                 var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this.gltf.samplers, texture.sampler));
                 var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+                var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
+                var textureURL = null;
+                if (image.uri && !BABYLON.Tools.IsBase64(image.uri) && this.babylonScene.getEngine().textureFormatInUse) {
+                    // If an image uri and a texture format is set like (eg. KTX) load from url instead of blob to support texture format and fallback
+                    textureURL = this._uniqueRootUrl + image.uri;
+                }
                 var deferred = new BABYLON.Deferred();
-                var babylonTexture = new BABYLON.Texture(null, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
+                var babylonTexture = new BABYLON.Texture(textureURL, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                     if (!_this._disposed) {
                         deferred.resolve();
                     }
@@ -4439,14 +4445,15 @@ var BABYLON;
                     }
                 });
                 promises.push(deferred.promise);
+                if (!textureURL) {
+                    promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
+                        var name = image.uri || _this._fileName + "#image" + image.index;
+                        var dataUrl = "data:" + _this._uniqueRootUrl + name;
+                        babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                    }));
+                }
                 babylonTexture.wrapU = samplerData.wrapU;
                 babylonTexture.wrapV = samplerData.wrapV;
-                var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
-                promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
-                    var name = image.uri || _this._fileName + "#image" + image.index;
-                    var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                    babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
-                }));
                 assign(babylonTexture);
                 this.logClose();
                 return Promise.all(promises).then(function () {

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 14 - 7
dist/preview release/loaders/babylonjs.loaders.js

@@ -5490,8 +5490,14 @@ var BABYLON;
                 this.logOpen(context + " " + (texture.name || ""));
                 var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this.gltf.samplers, texture.sampler));
                 var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+                var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
+                var textureURL = null;
+                if (image.uri && !BABYLON.Tools.IsBase64(image.uri) && this.babylonScene.getEngine().textureFormatInUse) {
+                    // If an image uri and a texture format is set like (eg. KTX) load from url instead of blob to support texture format and fallback
+                    textureURL = this._uniqueRootUrl + image.uri;
+                }
                 var deferred = new BABYLON.Deferred();
-                var babylonTexture = new BABYLON.Texture(null, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
+                var babylonTexture = new BABYLON.Texture(textureURL, this.babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                     if (!_this._disposed) {
                         deferred.resolve();
                     }
@@ -5501,14 +5507,15 @@ var BABYLON;
                     }
                 });
                 promises.push(deferred.promise);
+                if (!textureURL) {
+                    promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
+                        var name = image.uri || _this._fileName + "#image" + image.index;
+                        var dataUrl = "data:" + _this._uniqueRootUrl + name;
+                        babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                    }));
+                }
                 babylonTexture.wrapU = samplerData.wrapU;
                 babylonTexture.wrapV = samplerData.wrapV;
-                var image = ArrayItem.Get(context + "/source", this.gltf.images, texture.source);
-                promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
-                    var name = image.uri || _this._fileName + "#image" + image.index;
-                    var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                    babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
-                }));
                 assign(babylonTexture);
                 this.logClose();
                 return Promise.all(promises).then(function () {

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


+ 3 - 3
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,8 +27,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.0.0-alpha.7",
-        "babylonjs": "4.0.0-alpha.7"
+        "babylonjs-gltf2interface": "4.0.0-alpha.8",
+        "babylonjs": "4.0.0-alpha.8"
     },
     "engines": {
         "node": "*"

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 2 - 2
dist/preview release/materialsLibrary/babylon.gridMaterial.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 2 - 2
dist/preview release/materialsLibrary/babylonjs.materials.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 2 - 2
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.7"
+        "babylonjs": "4.0.0-alpha.8"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.7"
+        "babylonjs": "4.0.0-alpha.8"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.7"
+        "babylonjs": "4.0.0-alpha.8"
     },
     "engines": {
         "node": "*"

+ 3 - 3
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "4.0.0-alpha.7",
+    "version": "4.0.0-alpha.8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,8 +27,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.7",
-        "babylonjs-gltf2interface": "4.0.0-alpha.7"
+        "babylonjs": "4.0.0-alpha.8",
+        "babylonjs-gltf2interface": "4.0.0-alpha.8"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/viewer/babylon.viewer.d.ts

@@ -4,8 +4,8 @@
 declare module "babylonjs-loaders"{ export=BABYLON;}
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
-//   ../../../../../Tools/Gulp/babylonjs
-//   ../../../../../Tools/Gulp/babylonjs-loaders
+//   ../../../../../Tools/gulp/babylonjs
+//   ../../../../../Tools/gulp/babylonjs-loaders
 declare module BabylonViewer {
     /**
         * BabylonJS Viewer

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 3 - 3
dist/preview release/viewer/babylon.viewer.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 8 - 8
dist/preview release/viewer/babylon.viewer.max.js


+ 2 - 2
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -5,8 +5,8 @@ declare module "babylonjs-loaders"{ export=BABYLON;}
 
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
-//   ../../../../../Tools/Gulp/babylonjs
-//   ../../../../../Tools/Gulp/babylonjs-loaders
+//   ../../../../../Tools/gulp/babylonjs
+//   ../../../../../Tools/gulp/babylonjs-loaders
 
 declare module 'babylonjs-viewer' {
     import { mapperManager } from 'babylonjs-viewer/configuration/mappers';

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

@@ -2,6 +2,7 @@
 
 ## Major updates
 
+- [Inspector v2.0](https://doc.babylonjs.com/features/playground_debuglayer). [Dev log](https://medium.com/@babylonjs/dev-log-creating-the-new-inspector-b15c50900205) ([Deltakosh](https://github.com/deltakosh))
 - Added support for [parallel shader compilation](https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/) ([Deltakosh](https://github.com/deltakosh))
 - Added FlyCamera for free navigation in 3D space, with a limited set of settings ([Phuein](https://github.com/phuein)) [@NEED DEMO]
 - Added [Object Based Motion Blur](http://doc.babylonjs.com/how_to/using_motionblurpostprocess) post-process ([julien-moreau](https://github.com/julien-moreau))
@@ -64,12 +65,14 @@
 - `Layer` are now supported in `RenderTargetTexture` ([Sebavan](https://github.com/Sebavan))
 - Make onscreen joystick's canvas public ([TrevorDev](https://github.com/TrevorDev))
 - Added `Tools.CustomRequestHeaders`, `Tools.UseCustomRequestHeaders`, `Tools.InjectCustomRequestHeaders` to send Custom Request Headers alongside XMLHttpRequest's i.e. when loading files (Tools.Loadfile) from resources requiring special headers like 'Authorization' ([susares](https://github.com/susares))
-
+- Added `.serialize` and `.Parse` functions in `ReflectionProbe` to retrieve reflection probes when parsing a previously serialized material ([julien-moreau](https://github.com/julien-moreau))
+- GizmoManager clearGizmoOnEmptyPointerEvent options and onAttachedToMeshObservable event ([TrevorDev](https://github.com/TrevorDev))
 ### glTF Loader
 
 - Added support for mesh instancing for improved performance when multiple nodes point to the same mesh ([bghgary](https://github.com/bghgary))
 - Create `TransformNode` objects instead of `Mesh` objects for glTF nodes without geometry ([bghgary](https://github.com/bghgary))
 - Added glTF JSON pointers to metadata of nodes, materials, and textures ([bghgary](https://github.com/bghgary))
+- Load KTX textures in the gltf2 loader when textureFormat is set on engine ([TrevorDev](https://github.com/TrevorDev))
 
 ### glTF Serializer
 
@@ -78,6 +81,7 @@
 ### Materials Library
 
 ## Bug fixes
+- Fixed FileLoader's loading of a skybox, & added a parsed value for whether to create with PBR or STDMaterial ([Palmer-JC](https://github.com/Palmer-JC))
 - Removed bones from rootNodes where they should never have been ([Deltakosh](https://github.com/deltakosh))
 - Refocusing on input gui with pointer events ([TrevorDev](https://github.com/TrevorDev))
 - Gizmo scaling not consistent when camera is parented ([TrevorDev](https://github.com/TrevorDev))
@@ -89,6 +93,7 @@
 - VR helper would rotate non vr camera while in VR ([TrevorDev](https://github.com/TrevorDev))
 - PointerDragBahavior using Mesh as base type, causing type-checking problems with AbstractMesh ([Poolminer](https://github.com/Poolminer/))
 - TransformNode lookAt not working in world space when node's parent has rotation ([TrevorDev](https://github.com/TrevorDev))
+- MakeNotPickableAndWrapInBoundingBox had unexpected behavior when input had scaling of 0 on an axis ([TrevorDev](https://github.com/TrevorDev))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))

+ 71 - 20
gui/src/2D/advancedDynamicTexture.ts

@@ -68,6 +68,10 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     private _blockNextFocusCheck = false;
     private _renderScale = 1;
     private _rootCanvas: Nullable<HTMLCanvasElement>;
+
+    /** @hidden */
+    public _needRedraw = false;
+
     /**
      * Define type to string to ensure compatibility across browsers
      * Safari doesn't support DataTransfer constructor
@@ -80,6 +84,11 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     public onClipboardObservable = new Observable<ClipboardInfo>();
 
     /**
+     * Observable event triggered each time a pointer down is intercepted by a control
+     */
+    public onControlPickedObservable = new Observable<Control>();
+
+    /**
      * Gets or sets a boolean defining if alpha is stored as premultiplied
      */
     public premulAlpha = false;
@@ -204,6 +213,25 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     }
 
     /**
+     * Returns an array containing the root container.
+     * This is mostly used to let the Inspector introspects the ADT
+     * @returns an array containing the rootContainer
+     */
+    public getChildren(): Array<Container> {
+        return [this._rootContainer];
+    }
+
+    /**
+     * Will return all controls that are inside this texture
+     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+     * @return all child controls
+     */
+    public getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[] {
+        return this._rootContainer.getDescendants(directDescendantsOnly, predicate);
+    }
+
+    /**
      * Gets or sets the current focused control
      */
     public get focusedControl(): Nullable<IFocusableControl> {
@@ -256,15 +284,15 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this._clipboardData = value;
     }
 
-     /**
-     * Creates a new AdvancedDynamicTexture
-     * @param name defines the name of the texture
-     * @param width defines the width of the texture
-     * @param height defines the height of the texture
-     * @param scene defines the hosting scene
-     * @param generateMipMaps defines a boolean indicating if mipmaps must be generated (false by default)
-     * @param samplingMode defines the texture sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
-     */
+    /**
+    * Creates a new AdvancedDynamicTexture
+    * @param name defines the name of the texture
+    * @param width defines the width of the texture
+    * @param height defines the height of the texture
+    * @param scene defines the hosting scene
+    * @param generateMipMaps defines a boolean indicating if mipmaps must be generated (false by default)
+    * @param samplingMode defines the texture sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
+    */
     constructor(name: string, width = 0, height = 0, scene: Nullable<Scene>, generateMipMaps = false, samplingMode = Texture.NEAREST_SAMPLINGMODE) {
         super(name, { width: width, height: height }, scene, generateMipMaps, samplingMode, Engine.TEXTUREFORMAT_RGBA);
 
@@ -302,6 +330,14 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     }
 
     /**
+     * Get the current class name of the texture useful for serialization or dynamic coding.
+     * @returns "AdvancedDynamicTexture"
+     */
+    public getClassName(): string {
+        return "AdvancedDynamicTexture";
+    }
+
+    /**
      * Function used to execute a function on all controls
      * @param func defines the function to execute
      * @param container defines the container where controls belong. If null the root container will be used
@@ -401,6 +437,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
 
         this._rootContainer.dispose();
         this.onClipboardObservable.clear();
+        this.onControlPickedObservable.clear();
 
         super.dispose();
     }
@@ -540,6 +577,11 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         context.strokeStyle = "white";
         var measure = new Measure(0, 0, renderWidth, renderHeight);
         this._rootContainer._draw(measure, context);
+
+        if (this._needRedraw) { // We need to redraw as some elements dynamically adapt to their content
+            this._needRedraw = false;
+            this._render();
+        }
     }
 
     /** @hidden */
@@ -549,6 +591,13 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         }
     }
 
+    /** @hidden */
+    public _registerLastControlDown(control: Control, pointerId: number) {
+        this._lastControlDown[pointerId] = control;
+
+        this.onControlPickedObservable.notifyObservers(control);
+    }
+
     private _doPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): void {
         var scene = this.getScene();
 
@@ -560,8 +609,10 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         var textureSize = this.getSize();
 
         if (this._isFullscreen) {
-            x = x * (textureSize.width / engine.getRenderWidth());
-            y = y * (textureSize.height / engine.getRenderHeight());
+            let camera = scene.cameraToUseForPointers || scene.activeCamera;
+            let viewport = camera!.viewport;
+            x = x * (textureSize.width / (engine.getRenderWidth() * viewport.width));
+            y = y * (textureSize.height / (engine.getRenderHeight() * viewport.height));
         }
 
         if (this._capturingControl[pointerId]) {
@@ -617,7 +668,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
             if (pi.type !== PointerEventTypes.POINTERMOVE
                 && pi.type !== PointerEventTypes.POINTERUP
                 && pi.type !== PointerEventTypes.POINTERDOWN) {
-                    return;
+                return;
             }
 
             if (!scene) {
@@ -630,9 +681,9 @@ export class AdvancedDynamicTexture extends DynamicTexture {
                 return;
             }
             let engine = scene.getEngine();
-            let viewport = camera.viewport;
-            let x = (scene.pointerX / engine.getHardwareScalingLevel() - viewport.x * engine.getRenderWidth()) / viewport.width;
-            let y = (scene.pointerY / engine.getHardwareScalingLevel() - viewport.y * engine.getRenderHeight()) / viewport.height;
+            let viewport = camera.viewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
+            let x = scene.pointerX / engine.getHardwareScalingLevel() - viewport.x;
+            let y = scene.pointerY / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - viewport.y - viewport.height);
 
             this._shouldBlockPointer = false;
             // Do picking modifies _shouldBlockPointer
@@ -653,7 +704,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this.onClipboardObservable.notifyObservers(ev);
         evt.preventDefault();
     }
-     /** @hidden */
+    /** @hidden */
     private onClipboardCut = (evt: ClipboardEvent) => {
         let ev = new ClipboardInfo(ClipboardEventTypes.CUT, evt);
         this.onClipboardObservable.notifyObservers(ev);
@@ -666,9 +717,9 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         evt.preventDefault();
     }
 
-   /**
-    * Register the clipboard Events onto the canvas
-    */
+    /**
+     * Register the clipboard Events onto the canvas
+     */
     public registerClipboardEvents(): void {
         self.addEventListener("copy", this.onClipboardCopy, false);
         self.addEventListener("cut", this.onClipboardCut, false);
@@ -679,7 +730,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
      */
     public unRegisterClipboardEvents(): void {
         self.removeEventListener("copy", this.onClipboardCopy);
-        self.removeEventListener("cut",  this.onClipboardCut);
+        self.removeEventListener("cut", this.onClipboardCut);
         self.removeEventListener("paste", this.onClipboardPaste);
     }
 

+ 22 - 10
gui/src/2D/controls/colorpicker.ts

@@ -359,22 +359,22 @@ export class ColorPicker extends Control {
         this.value = this._tmpColor;
     }
 
-    private _isPointOnSquare(coordinates: Vector2): boolean {
+    private _isPointOnSquare(x: number, y: number): 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) {
+        if (x >= left && x <= left + size &&
+            y >= top && y <= top + size) {
             return true;
         }
 
         return false;
     }
 
-    private _isPointOnWheel(coordinates: Vector2): boolean {
+    private _isPointOnWheel(x: number, y: number): boolean {
         var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
         var centerX = radius + this._currentMeasure.left;
         var centerY = radius + this._currentMeasure.top;
@@ -383,8 +383,8 @@ export class ColorPicker extends Control {
         var radiusSq = radius * radius;
         var innerRadiusSq = innerRadius * innerRadius;
 
-        var dx = coordinates.x - centerX;
-        var dy = coordinates.y - centerY;
+        var dx = x - centerX;
+        var dy = y - centerY;
 
         var distSq = dx * dx + dy * dy;
 
@@ -405,21 +405,33 @@ export class ColorPicker extends Control {
         this._pointerStartedOnSquare = false;
         this._pointerStartedOnWheel = false;
 
-        if (this._isPointOnSquare(coordinates)) {
+        // Invert transform
+        this._invertTransformMatrix.transformCoordinates(coordinates.x, coordinates.y, this._transformedPosition);
+
+        let x = this._transformedPosition.x;
+        let y = this._transformedPosition.y;
+
+        if (this._isPointOnSquare(x, y)) {
             this._pointerStartedOnSquare = true;
-        } else if (this._isPointOnWheel(coordinates)) {
+        } else if (this._isPointOnWheel(x, y)) {
             this._pointerStartedOnWheel = true;
         }
 
-        this._updateValueFromPointer(coordinates.x, coordinates.y);
+        this._updateValueFromPointer(x, y);
         this._host._capturingControl[pointerId] = this;
 
         return true;
     }
 
     public _onPointerMove(target: Control, coordinates: Vector2): void {
+        // Invert transform
+        this._invertTransformMatrix.transformCoordinates(coordinates.x, coordinates.y, this._transformedPosition);
+
+        let x = this._transformedPosition.x;
+        let y = this._transformedPosition.y;
+
         if (this._pointerIsDown) {
-            this._updateValueFromPointer(coordinates.x, coordinates.y);
+            this._updateValueFromPointer(x, y);
         }
 
         super._onPointerMove(target, coordinates);

+ 29 - 2
gui/src/2D/controls/container.ts

@@ -270,6 +270,7 @@ export class Container extends Control {
             }
 
             this._localDraw(context);
+            this._renderHighlight(context);
 
             if (this.clipChildren) {
                 this._clipForChildren(context);
@@ -283,6 +284,7 @@ export class Container extends Control {
                     child._tempParentMeasure.copyFrom(this._measureForChildren);
 
                     child._draw(this._measureForChildren, context);
+                    child._renderHighlight(context);
 
                     if (child.onAfterDrawObservable.hasObservers()) {
                         child.onAfterDrawObservable.notifyObservers(child);
@@ -298,10 +300,16 @@ export class Container extends Control {
             }
 
             if (this.adaptWidthToChildren && computedWidth >= 0) {
-                this.width = computedWidth + "px";
+                if (this.width !== computedWidth + "px") {
+                    this.width = computedWidth + "px";
+                    this._host._needRedraw = true;
+                }
             }
             if (this.adaptHeightToChildren && computedHeight >= 0) {
-                this.height = computedHeight + "px";
+                if (this.height !== computedHeight + "px") {
+                    this.height = computedHeight + "px";
+                    this._host._needRedraw = true;
+                }
             }
         }
         context.restore();
@@ -312,6 +320,25 @@ export class Container extends Control {
     }
 
     /** @hidden */
+    public _getDescendants(results: Control[], directDescendantsOnly: boolean = false, predicate?: (control: Control) => boolean): void {
+        if (!this.children) {
+            return;
+        }
+
+        for (var index = 0; index < this.children.length; index++) {
+            var item = this.children[index];
+
+            if (!predicate || predicate(item)) {
+                results.push(item);
+            }
+
+            if (!directDescendantsOnly) {
+                item._getDescendants(results, false, predicate);
+            }
+        }
+    }
+
+    /** @hidden */
     public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
         if (!this.isVisible || this.notRenderable) {
             return false;

+ 72 - 1
gui/src/2D/controls/control.ts

@@ -73,6 +73,7 @@ export class Control {
     private _cachedOffsetX: number;
     private _cachedOffsetY: number;
     private _isVisible = true;
+    private _isHighlighted = false;
     /** @hidden */
     public _linkedMesh: Nullable<AbstractMesh>;
     private _fontSet = false;
@@ -87,6 +88,11 @@ export class Control {
     public _tag: any;
 
     /**
+     * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+     */
+    public uniqueId: number;
+
+    /**
      * Gets or sets an object used to store user defined information for the node
      */
     public metadata: any = null;
@@ -126,6 +132,14 @@ export class Control {
     }
 
     /**
+     * Get the current class name of the control.
+     * @returns current class name
+     */
+    public getClassName(): string {
+        return this._getTypeName();
+    }
+
+    /**
     * An event triggered when the pointer move over the control.
     */
     public onPointerMoveObservable = new Observable<Vector2>();
@@ -193,6 +207,22 @@ export class Control {
         this._markAsDirty();
     }
 
+    /**
+     * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+     */
+    public get isHighlighted(): boolean {
+        return this._isHighlighted;
+    }
+
+    public set isHighlighted(value: boolean) {
+        if (this._isHighlighted === value) {
+            return;
+        }
+
+        this._isHighlighted = value;
+        this._markAsDirty();
+    }
+
     /** Gets or sets a value indicating the scale factor on X axis (1 by default)
      * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
     */
@@ -852,6 +882,25 @@ export class Control {
         this.notRenderable = false;
     }
 
+    /** @hidden */
+    public _getDescendants(results: Control[], directDescendantsOnly: boolean = false, predicate?: (control: Control) => boolean): void {
+        // Do nothing by default
+    }
+
+    /**
+     * Will return all controls that have this control as ascendant
+     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+     * @return all child controls
+     */
+    public getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[] {
+        var results = new Array<Control>();
+
+        this._getDescendants(results, directDescendantsOnly, predicate);
+
+        return results;
+    }
+
     /**
      * Link current control with a target mesh
      * @param mesh defines the mesh to link with
@@ -946,6 +995,9 @@ export class Control {
     public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
         this._root = root;
         this._host = host;
+        if (this._host) {
+            this.uniqueId = this._host.getScene()!.getUniqueId();
+        }
     }
 
     /** @hidden */
@@ -982,6 +1034,25 @@ export class Control {
     }
 
     /** @hidden */
+    public _renderHighlight(context: CanvasRenderingContext2D): void {
+        if (!this.isHighlighted) {
+            return;
+        }
+
+        context.save();
+        context.strokeStyle = "#4affff";
+        context.lineWidth = 2;
+
+        this._renderHighlightSpecific(context);
+        context.restore();
+    }
+
+    /** @hidden */
+    protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void {
+        context.strokeRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+    }
+
+    /** @hidden */
     protected _applyStates(context: CanvasRenderingContext2D): void {
         if (this._isFontSizeInPercentage) {
             this._fontSet = true;
@@ -1378,7 +1449,7 @@ export class Control {
 
         if (type === PointerEventTypes.POINTERDOWN) {
             this._onPointerDown(this, this._dummyVector2, pointerId, buttonIndex);
-            this._host._lastControlDown[pointerId] = this;
+            this._host._registerLastControlDown(this, pointerId);
             this._host._lastPickedControl = this;
             return true;
         }

+ 59 - 11
gui/src/2D/controls/grid.ts

@@ -286,7 +286,7 @@ export class Grid extends Container {
         return "Grid";
     }
 
-    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+    protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void) {
         let widths = [];
         let heights = [];
         let lefts = [];
@@ -352,23 +352,71 @@ export class Grid extends Container {
             index++;
         }
 
-        // Setting child sizes
+        definitionCallback(lefts, tops, widths, heights);
+    }
+
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._getGridDefinitions((lefts: number[], tops: number[], widths: number[], heights: number[]) => {
+            // 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";
+            }
+        });
+
+        super._additionalProcessing(parentMeasure, context);
+    }
+
+    public _flagDescendantsAsMatrixDirty(): void {
         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 child = this._cells[key];
+            child._markMatrixAsDirty();
         }
+    }
 
-        super._additionalProcessing(parentMeasure, context);
+    protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void {
+        if (!this.isHighlighted) {
+            return;
+        }
+
+        super._renderHighlightSpecific(context);
+
+        this._getGridDefinitions((lefts: number[], tops: number[], widths: number[], heights: number[]) => {
+
+            // Columns
+            for (var index = 0; index < lefts.length; index++) {
+                const left = this._currentMeasure.left + lefts[index] + widths[index];
+                context.beginPath();
+                context.moveTo(left, this._currentMeasure.top);
+                context.lineTo(left, this._currentMeasure.top + this._currentMeasure.height);
+                context.stroke();
+            }
+
+            // Rows
+            for (var index = 0; index < tops.length; index++) {
+                const top = this._currentMeasure.top + tops[index] + heights[index];
+                context.beginPath();
+                context.moveTo(this._currentMeasure.left, top);
+                context.lineTo(this._currentMeasure.left + this._currentMeasure.width, top);
+                context.stroke();
+            }
+        });
+
+        context.restore();
     }
 
     /** Releases associated resources */

+ 25 - 23
gui/src/2D/controls/inputText.ts

@@ -268,10 +268,12 @@ export class InputText extends Control implements IFocusableControl {
     }
 
     public set text(value: string) {
-        if (this._text === value) {
+        let valueAsString = value.toString(); // Forcing convertion
+
+        if (this._text === valueAsString) {
             return;
         }
-        this._text = value;
+        this._text = valueAsString;
         this._markAsDirty();
 
         this.onTextChangedObservable.notifyObservers(this);
@@ -352,21 +354,21 @@ export class InputText extends Control implements IFocusableControl {
 
         this._onClipboardObserver = this._host.onClipboardObservable.add((clipboardInfo) => {
             // process clipboard event, can be configured.
-             switch (clipboardInfo.type){
-                 case ClipboardEventTypes.COPY:
-                         this._onCopyText(clipboardInfo.event);
-                         this.onTextCopyObservable.notifyObservers(this);
-                         break;
-                 case ClipboardEventTypes.CUT:
-                         this._onCutText(clipboardInfo.event);
-                         this.onTextCutObservable.notifyObservers(this);
-                         break;
-                 case ClipboardEventTypes.PASTE:
-                         this._onPasteText(clipboardInfo.event);
-                         this.onTextPasteObservable.notifyObservers(this);
-                         break;
-                 default: return;
-              }
+            switch (clipboardInfo.type) {
+                case ClipboardEventTypes.COPY:
+                    this._onCopyText(clipboardInfo.event);
+                    this.onTextCopyObservable.notifyObservers(this);
+                    break;
+                case ClipboardEventTypes.CUT:
+                    this._onCutText(clipboardInfo.event);
+                    this.onTextCutObservable.notifyObservers(this);
+                    break;
+                case ClipboardEventTypes.PASTE:
+                    this._onPasteText(clipboardInfo.event);
+                    this.onTextPasteObservable.notifyObservers(this);
+                    break;
+                default: return;
+            }
         });
 
         let scene = this._host.getScene();
@@ -433,7 +435,7 @@ export class InputText extends Control implements IFocusableControl {
                     if (this._isTextHighlightOn) {
                         this.text = this._text.slice(0, this._startHighlightIndex) + this._text.slice(this._endHighlightIndex);
                         this._isTextHighlightOn = false;
-                        this._cursorOffset =  this.text.length - this._startHighlightIndex;
+                        this._cursorOffset = this.text.length - this._startHighlightIndex;
                         this._blinkIsEven = false;
                         if (evt) {
                             evt.preventDefault();
@@ -468,7 +470,7 @@ export class InputText extends Control implements IFocusableControl {
                     }
                     return;
                 }
-                if (this._text && this._text.length > 0  && this._cursorOffset > 0) {
+                if (this._text && this._text.length > 0 && this._cursorOffset > 0) {
                     let deletePosition = this._text.length - this._cursorOffset;
                     this.text = this._text.slice(0, deletePosition) + this._text.slice(deletePosition + 1);
                     this._cursorOffset--;
@@ -561,7 +563,7 @@ export class InputText extends Control implements IFocusableControl {
         this._endHighlightIndex = this._startHighlightIndex;
         for (let rWord = /\w+/g, left = 1, right = 1; this._startHighlightIndex > 0 && this._endHighlightIndex < this._text.length && (left || right);) {
             right = (this._text[this._endHighlightIndex].search(rWord) !== -1) ? ++this._endHighlightIndex : 0;
-            left =  (this._text[this._startHighlightIndex - 1 ].search(rWord) !== -1) ? --this._startHighlightIndex : 0;
+            left = (this._text[this._startHighlightIndex - 1].search(rWord) !== -1) ? --this._startHighlightIndex : 0;
         }
         this.onTextHighlightObservable.notifyObservers(this);
         this._isTextHighlightOn = true;
@@ -598,7 +600,7 @@ export class InputText extends Control implements IFocusableControl {
         try {
             ev.clipboardData.setData("text/plain", this._highlightedText);
         }
-        catch {} //pass
+        catch { } //pass
         this._host.clipboardData = this._highlightedText;
     }
     /** @hidden */
@@ -648,7 +650,7 @@ export class InputText extends Control implements IFocusableControl {
             // Background
             if (this._isFocused) {
                 if (this._focusedBackground) {
-                    context.fillStyle = this._isEnabled ?  this._focusedBackground : this._disabledColor;
+                    context.fillStyle = this._isEnabled ? this._focusedBackground : this._disabledColor;
 
                     context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
                 }
@@ -760,7 +762,7 @@ export class InputText extends Control implements IFocusableControl {
                     this._markAsDirty();
                 }, 500);
 
-                 //show the highlighted text
+                //show the highlighted text
                 if (this._isTextHighlightOn) {
                     clearTimeout(this._blinkTimeout);
                     let highlightCursorOffsetWidth = context.measureText(this.text.substring(this._startHighlightIndex)).width;

+ 8 - 0
gui/src/3D/controls/control3D.ts

@@ -201,6 +201,14 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
         return this._getTypeName();
     }
 
+    /**
+     * Get the current class name of the control.
+     * @returns current class name
+     */
+    public getClassName(): string {
+        return this._getTypeName();
+    }
+
     protected _getTypeName(): string {
         return "Control3D";
     }

+ 1 - 11
gui/webpack.config.js

@@ -1,6 +1,5 @@
 const path = require('path');
 const webpack = require('webpack');
-const DtsBundleWebpack = require('dts-bundle-webpack');
 const CleanWebpackPlugin = require('clean-webpack-plugin');
 
 module.exports = {
@@ -17,8 +16,7 @@ module.exports = {
             amd: "babylonjs-gui",
             commonjs: "babylonjs-gui"
         },
-        umdNamedDefine: true,
-        //devtoolModuleFilenameTemplate: "[absolute-resource-path]"
+        umdNamedDefine: true
     },
     resolve: {
         extensions: [".js", '.ts']
@@ -57,14 +55,6 @@ module.exports = {
             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$/

+ 5 - 4
inspector/index.html

@@ -17,18 +17,19 @@
             padding: 0;
             margin: 0
         }
-        
+
         #wrapper {
             width: 100%;
             height: 100%;
             display: flex;
             overflow: hidden;
         }
-        
+
         canvas {
             width: 100%;
+            height: 100%;
         }
-        
+
         #inspector {
             width: 25%;
         }
@@ -46,7 +47,7 @@
 
     <!--Starting the game-->
     <script>
-        BABYLONDEVTOOLS.Loader.require("test/index.js").load(function () {
+        BABYLONDEVTOOLS.Loader.require("test/index.js").load(function() {
             new Test('game-canvas');
         });
     </script>

+ 26 - 15
inspector/package.json

@@ -1,6 +1,6 @@
 {
     "name": "babylonjs-inspector",
-    "version": "1.0.0",
+    "version": "2.0.0",
     "description": "",
     "scripts": {
         "start:server": "webpack-dev-server",
@@ -24,19 +24,30 @@
     },
     "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
     "devDependencies": {
-        "@types/node": "^10.5.3",
-        "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",
+        "@fortawesome/fontawesome-svg-core": "~1.2.8",
+        "@fortawesome/free-regular-svg-icons": "~5.4.1",
+        "@fortawesome/free-solid-svg-icons": "~5.4.1",
+        "@fortawesome/react-fontawesome": "~0.1.3",
+        "@types/react": "~16.4.18",
+        "@types/react-dom": "~16.0.9",
+        "clean-webpack-plugin": "~0.1.19",
+        "css-loader": "~1.0.0",
+        "dts-bundle": "~0.7.3",
+        "file-loader": "~2.0.0",
+        "gulp": "~4.0.0",
+        "gulp-webserver": "~0.9.1",
+        "mini-css-extract-plugin": "~0.4.4",
+        "node-sass": "~4.10.0",
+        "re-resizable": "~4.9.1",
+        "react": "~16.6.1",
+        "react-dom": "~16.6.1",
+        "sass-loader": "~7.1.0",
+        "split.js": "^1.5.9",
+        "style-loader": "~0.23.1",
         "ts-loader": "^4.0.0",
-        "typescript": "~3.0.1",
-        "webpack": "^4.16.2",
-        "webpack-cli": "^3.1.0",
-        "webpack-dev-server": "^3.1.5"
-    },
-    "dependencies": {}
+        "typescript": "~3.1.3",
+        "webpack": "~4.21.0",
+        "webpack-cli": "~3.1.2",
+        "webpack-stream": "5.0.0"
+    }
 }

+ 0 - 156
inspector/sass/_detailPanel.scss

@@ -1,156 +0,0 @@
-// The main class of the detail panel
-.insp-details {
-  background-color: $background;
-  overflow-y: auto;
-  overflow-x: auto;
-  color:$color;
-  font-family: $font;
-
-  .details {
-      padding-left: 5px;
-  }
-
-  // Common defintion between header row and detail row
-  .base-row {      
-    display:flex;
-    width:100%;
-
-    .base-property {
-        padding: 2px 0 2px 0;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-        overflow: hidden;
-    }
-    // Property name
-    .prop-name {
-        @extend .property-name;
-        @extend .base-property;
-        width:35%;
-    }
-    // property value
-    .prop-value {
-        @extend .base-property;
-        width:59%;
-        padding-left:5px;
-        &.clickable {
-            cursor:pointer;
-            &:hover {
-                background-color:$background-lighter2;
-            }
-            &:after {
-                font-family: $font-family-icons;
-                content: "\00a0 \00a0 \00a0 \f105"; // 4 space before + angle-right
-                font-weight: 900; // To display solid font family
-            }
-        }   
-    }
-    
-    // input {
-    //     border:0;
-    //     font-family: $font;
-    //     background-color: $background-lighter;
-    //     color:$color;
-    //     // Remove blue border on focus
-    //     &:focus {
-    //         outline:none;
-    //     }
-    // }
-  }
-  
-  // A line of details composed of name, type, value, id, flagId
-  .row {
-    @extend .base-row;
-    &:nth-child(even) {
-        background-color:$background-lighter;
-    }
-    &.unfolded {          
-        .prop-value.clickable:after {
-            font-family: $font-family-icons;
-            content: "\00a0 \00a0 \00a0 \f107"; // 4 space before + angle-down
-            font-weight: 900; // To display solid font family
-        }
-    }
-  }
-
-  
-  // Name, type, value, Id, FlagId
-  .header-row {
-    @extend .base-row;
-    background-color: $background-lighter; 
-    color           : $color;
-    width           : 100%;
-    max-width       : 100%;
-    
-    // Special definition for text color: the color is the default one
-    // All header columns
-    & > * {
-        color:$color !important;
-        padding:5px 0 5px 5px !important;
-        cursor: pointer;
-        &:hover {
-            background-color:$background-lighter2;
-        }
-    }
-
-    .header-col {
-        display:flex;
-        justify-content: space-between;
-        align-items: center;
-
-        .sort-direction {
-            margin-right:5px;
-        }
-    }
-  }
-  
-  // A div used to view a property in the property line (color, texture...)
-  .element-viewer {
-      position:relative;
-      width:10px;
-      height:10px;
-      display:inline-block;
-      margin-left:5px;
-  }
-
-  // The div displaying a color
-  .color-element {
-      @extend .element-viewer;
-      width: 20px;
-      height: 15px;
-  }
-
-  // The div displaying a texture element
-  .texture-element {
-      @extend .element-viewer;
-      color:$color-top;
-      margin-left:10px; 
-
-      .texture-viewer {
-          
-          color:$color;
-          position:absolute;
-          z-index:10;
-          bottom:0;
-          right:0;
-          display:block;
-          width:150px;
-          height:150px;
-          border: 1px solid $background-lighter3;
-          background-color: $background;
-          transform: translateX(100%) translateY(100%);
-          
-          display: none;
-          flex-direction: column;
-          justify-content: flex-start;
-          align-items: center;
-
-          .texture-viewer-img {
-              margin:10px 0 10px 0;
-              max-width:110px;
-              max-height:110px;
-          }
-      }
-  }
-   
-
-}

+ 0 - 18
inspector/sass/_resizeBar.scss

@@ -1,18 +0,0 @@
-.c2di-resize-bar-v {
-  height:100%;
-  width:$resizebar-width;
-  background-color: $background;
-  cursor: col-resize;
-  flex-shrink: 0;
-  border-left:1px solid $background-lighter;
-  border-right:1px solid $background-lighter;
-}
-.c2di-resize-bar-h {
-  width:100%;
-  height:$resizebar-width;
-  background-color: $background;
-  cursor: row-resize;
-  flex-shrink: 0;
-  border-top: 1px solid $background-lighter;
-  border-bottom: 1px solid $background-lighter;
-}

+ 0 - 19
inspector/sass/_searchbar.scss

@@ -1,19 +0,0 @@
-.searchbar {
-    
-    border       : 1px solid $background-lighter;
-    margin-bottom: 5px;
-    display      : flex;
-    align-items  : center;
-    color:darken($color, 10%);
-    
-    input {
-        background-color: $background;
-        border          : none;
-        width           : 100%;
-        outline         : none;
-        font-family     : $font;
-        color           : darken($color, 10%);
-        padding         : 3px 0 3px 10px;
-        margin          : 6px 0 6px 0;
-    }
-}

+ 0 - 74
inspector/sass/_slider.scss

@@ -1,74 +0,0 @@
-$thumb-height: 15px;
-
-input[type="range"] { 
-  margin: auto;
-  -webkit-appearance: none;
-  position: relative;
-  overflow: hidden;
-  height: $thumb-height;
-  width: 50%;
-  cursor: pointer;
-  border-radius: 0; /* iOS */
-}
-
-::-webkit-slider-runnable-track {
-  background: #ddd;
-}
-
-/*
-* 1. Set to 0 height and width, and remove border for a slider without a thumb
-*/
-::-webkit-slider-thumb {
-  -webkit-appearance: none;
-  width: 20px; /* 1 */
-  height: $thumb-height; /* 1 */
-  background: #fff;
-  box-shadow: -100vw 0 0 100vw dodgerblue;
-  border: 0px solid #999; /* 1 */
-}
-
-::-moz-range-track {
-  height: $thumb-height;
-  background: #ddd;
-}
-
-::-moz-range-thumb {
-  background: #fff;
-  height: $thumb-height;
-  width: 20px;
-  border: 0px solid #999;
-  border-radius: 0 !important;
-  box-shadow: -100vw 0 0 100vw dodgerblue;
-  box-sizing: border-box;
-}
-
-::-ms-fill-lower { 
-  background: dodgerblue;
-}
-
-::-ms-thumb { 
-  background: #fff;
-  border: 0px solid #999;
-  height: $thumb-height;
-  width: 20px;
-  box-sizing: border-box;
-}
-
-::-ms-ticks-after { 
-  display: none; 
-}
-
-::-ms-ticks-before { 
-  display: none; 
-}
-
-::-ms-track { 
-  background: #ddd;
-  color: transparent;
-  height: $thumb-height;
-  border: none;
-}
-
-::-ms-tooltip { 
-  display: none;
-}

+ 0 - 92
inspector/sass/_tabPanel.scss

@@ -1,92 +0,0 @@
-.tab-panel {
-    height:100%;
-
-    &.searchable {
-        height:calc(100% - #{$searchbar-height} - 10px);   
-    }  
-
-    .texture-image {
-        max-height:400px;
-    }
-    
-    .scene-actions {
-        overflow-y: auto;
-        padding-left: 5px;
-        
-        // Action title : Textures/Options/Viewer
-        .actions-title {
-            font-size     : 1.1em;
-            padding-bottom: 10px;
-            border-bottom : 1px solid $color-bot;
-            margin        : 10px 0 10px 0;
-        }
-
-        .defaut-action {            
-            height     : 20px;
-            line-height: 20px;
-            width      : 100%;
-            cursor     : pointer;   
-            
-            &:hover {
-                background-color:$background-lighter;
-            }
-            &:active {                
-                background-color: $background-lighter2;
-            }
-        }
-
-        // Radio button
-        .action-radio {
-            @extend .defaut-action;
-            &:before {
-                width      : 1em;
-                height     : 1em;
-                line-height: 1em;
-                display    : inline-block;
-                font-family: $font-family-icons;
-                content    : "\f111";
-                margin-right:10px;
-            }
-            // radio button active
-            &.active {
-                &:before {
-                    width      : 1em;
-                    height     : 1em;
-                    line-height: 1em;
-                    display    : inline-block;
-                    font-family: $font-family-icons;
-                    content    : "\f192";
-                    color      : $color-bot;
-                    margin-right:10px;
-                }
-            }
-        }
-
-        // Check button
-        .action {             
-            @extend .defaut-action;
-            &:before {
-                width      : 1em;
-                height     : 1em;
-                line-height: 1em;
-                display    : inline-block;
-                font-family: $font-family-icons;
-                content    : "\f0c8";
-                margin-right:10px;
-            }
-                
-            &.active {
-                &:before {
-                    width      : 1em;
-                    height     : 1em;
-                    line-height: 1em;
-                    display    : inline-block;
-                    font-family: $font-family-icons;
-                    content    : "\f14a";
-                    color      : $color-bot;
-                    margin-right:10px;
-                }
-            }
-        }
-    }
-}

+ 0 - 60
inspector/sass/_tabbar.scss

@@ -1,60 +0,0 @@
-.tabbar {
-    height:$tabbar-height;
-    
-    display:flex;
-    align-items: center;
-    border-bottom: 1px solid $background-lighter2;
-    width:100%;
-    overflow-x:auto;
-    overflow-y:hidden;
-    box-sizing: border-box;
-    
-    .tab {
-        height:calc(#{$tabbar-height} - 2px);
-        width:auto;
-        padding: 0 10px 0 10px;
-        color:$color;
-        line-height: $tabbar-height;
-        text-align: center;
-        cursor: pointer;
-        margin: 0 5px 0 5px;
-        box-sizing: border-box;
-       
-        // Hover on it
-        &:hover {
-            border-bottom: 1px solid $color-top;
-            background-color: $background-lighter;
-        }
-        // Clic on it
-        &:active {
-            background-color: $background-lighter2;
-        }
-        // tab selected
-        &.active {
-            border-bottom: 1px solid $color-top;
-        }
-    }
-
-    .more-tabs {
-        width           : $tabbar-height;
-        height          : $tabbar-height;
-        display         : flex;
-        justify-content : center;
-        align-items     : center;
-        cursor          : pointer;
-        position        : relative;
-        border-right    : 1px solid $background-lighter2;
-        &:hover {
-            background-color: $background-lighter2;
-        }
-        &:active {
-            color:$color-top;
-            background-color: $background-lighter3;
-        }
-        // This tool is activated
-        &.active {
-            color:$color-top;
-        }
-
-    }
-}

+ 0 - 31
inspector/sass/_toolbar.scss

@@ -1,31 +0,0 @@
-/**
- * The toolbar contains : 
- * - a refresh tool - refresh the whole panel
- * - a popup tool - Open the inspector in a new panel
- * ...
- */   
-.toolbar {   
-    display:flex;
-     
-    .tool {
-        width          : $tabbar-height;
-        height         : $tabbar-height;
-        display        : flex;
-        justify-content: center;
-        align-items    : center;
-        cursor         : pointer;
-        position       : relative;
-        border-right   : 1px solid $background-lighter2;
-        &:hover {
-            background-color: $background-lighter2;
-        }
-        &:active {
-            color:$color-top;
-            background-color: $background-lighter3;
-        }
-        // This tool is activated
-        &.active {
-            color:$color-top;
-        }
-    }
-}

+ 0 - 14
inspector/sass/_tooltip.scss

@@ -1,14 +0,0 @@
-// Tooltip used when hovering on divisions
-
-.tooltip {
-    position        : absolute;
-    top             : $tabbar-height;
-    right           : 0;
-    color           : $color-top;
-    display         : none;
-    z-index         : 4;
-    font-family     : $font;  
-    padding         : 2px;
-    background-color: $background;
-    border          : 1px solid $background-lighter3;
-}

+ 0 - 73
inspector/sass/_tree.scss

@@ -1,73 +0,0 @@
-
-// Color for a property type
-.property-type {
-  color:$color-bot;
-}
-
-.property-name {
-  color:$color-top;
-}
-
-.insp-tree {
-  overflow-y: auto;
-  overflow-x: hidden;
-  height    : calc(50% - #{$tabbar-height} - #{$searchbar-height});
-  
-    
-    .line {
-        padding:3px;
-        cursor:pointer;
-        // Hover
-        &:hover {
-            background-color:$background-lighter;
-        }
-        // Line active (selected)
-        &.active {
-            background-color:$background-lighter3;
-            .line-content {
-                background-color:$background;
-            }
-        }
-        // > before title names
-        &.unfolded:before{            
-            width      : 1em;
-            height     : 1em;
-            line-height: 1em;
-            display    : inline-block;
-            font-family: $font-family-icons;
-            content    : "\f107";
-            font-weight: 900;          
-        }
-        &.folded:before{            
-            width      : 1em;
-            height     : 1em;
-            line-height: 1em;
-            display    : inline-block;
-            font-family: $font-family-icons;
-            content    : "\f105";
-            font-weight: 900;
-        }
-        
-        &.unfolded.transformNode > span:first-of-type{
-            color:$color-top;
-        }
-        &.folded.transformNode > span:first-of-type{ 
-            color:$color-top;
-        }
-
-        // Sub lines
-        .line-content {
-            padding-left:15px;
-            &:hover { 
-                background-color:$background;
-            }
-            .line:hover:first-child {            
-                background-color:$background-lighter2;
-            }
-            
-        }
-    }
-    .line_invisible {
-        display: none;
-    }
-}

+ 0 - 16
inspector/sass/_treeTool.scss

@@ -1,16 +0,0 @@
-/**
- * A tool contained in the tree panel (available for each item of the tree)
- */
-.treeTool {
-    margin : 3px 8px 3px 3px;
-    cursor:pointer;
-    position:relative;
-   
-    &:hover {        
-        color:$color-bot;
-    }
-    
-    &.active {
-        color:$color-bot;
-    }
-}

+ 0 - 28
inspector/sass/defines.scss

@@ -1,28 +0,0 @@
-// @import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css);
-@import url(https://use.fontawesome.com/releases/v5.0.13/css/all.css);
-@import url(https://fonts.googleapis.com/css?family=Inconsolata);
-
-$font               : 'Inconsolata', sans-serif;
-
-// ------------- //
-// If you update these colors, you should also 
-// replace them in the class Inspector as well, 
-// as it's used for custom themes
-// ------------- //
-
-$color              : #ccc;
-$background         : #242424;
-$background-active  : #2c2c2c;
-$color-top          : #f29766;
-$color-bot          : #5db0d7;
-$color-error        : #fa371d;
-
-$background-lighter : lighten($color: $background, $amount         : 3%);
-$background-lighter2: lighten($color: $background-lighter, $amount : 5%);
-$background-lighter3: lighten($color: $background-lighter2, $amount: 5%);
-
-$resizebar-width    : 10px;
-$tabbar-height      : 50px;
-$searchbar-height   : 30px;
-
-$font-family-icons  : 'Font Awesome 5 Free', sans-serif;

+ 0 - 105
inspector/sass/main.scss

@@ -1,105 +0,0 @@
-
-
-.insp-wrapper {
-  // Import variables, color and font files
-  @import "defines";
-
-  // Style for resize bar
-  .gutter {
-    background-color: $background-lighter;
-    &.gutter-vertical:not(.blocked) {
-      cursor        : ns-resize;
-    }
-    &.gutter-horizontal:not(.blocked) {
-      cursor        : ew-resize;
-    }
-  }
-
-  user-select: none; 
-  display:flex;
-  font-size:0.9em;
-  font-family     : $font;
-  background-color: $background;
-
-  // The panel containing the two subpanel : tree and details
-  .insp-right-panel {
-    width: 750px;
-    overflow-y: auto;
-
-    &.popupmode {
-      width:100% !important;
-    }
-    
-    display:flex; 
-    flex-direction: column;
-    flex-shrink: 0;
-
-    // The tree panel
-    .top-panel {
-      width:100%;
-      height:100%;
-      position:relative;
-      background-color: $background;
-      color           : $color;
-      font-size       : 1em;
-      
-      // The div that will contain the tab div
-      .tab-panel-content {
-        width:100%;
-        height:calc(100% - #{$tabbar-height});   
-      }   
-
-      // The div displaying all invisible tabs (when the tabbar width is small)
-      .more-tabs-panel {
-          position:absolute;
-          z-index:10;
-          top:$tabbar-height;
-          right:0;
-          width:100px;
-          display:none;
-          flex-direction: column;
-          align-items: center;
-          justify-content: center;
-          border: 1px solid $background-lighter3;
-          background-color: $background;
-
-          .invisible-tab {
-            height     : 25px;
-            width      : 100%;
-            line-height: 25px;
-            text-align : center;
-            background-color: $background-lighter;
-            cursor:pointer;
-
-            // Hover on it
-            &:hover {
-              background-color: $background-lighter2;
-            }
-            // Clic on it
-            &:active {
-              background-color: $background-lighter3;
-            }
-          }
-
-      }
-    }
-  }
-
-  @import 'tooltip';
-
-  // All tools used on object in the tree
-  @import 'treeTool';
-  @import "tabPanel";
-  @import "tabs/shaderTab";
-  @import "tabs/consoleTab";
-  @import "tabs/statsTab";
-  @import "tabs/gltfTab";
-  @import "tabs/toolsTab";
-
-  @import "tree";
-  @import "detailPanel";
-  @import "tabbar";
-  @import "toolbar";
-  @import "searchbar";
-  @import "slider";
-}

+ 0 - 51
inspector/sass/tabs/_consoleTab.scss

@@ -1,51 +0,0 @@
-.tab-panel {
-
-    .console-panel {
-        min-height              : 100px;
-        user-select             : text;
-        box-sizing              : border-box;
-        padding                 : 0 15px;    
-        
-        .console-panel-title {
-            height              : 25px;
-            border-bottom       : 1px solid $background-lighter2;
-            text-transform      : uppercase;
-            line-height         : 25px;
-            margin-bottom       : 10px; 
-        }
-        
-        .console-panel-content {            
-            overflow-y              : auto;
-            overflow-x              : hidden;    
-            height                  : calc(100% - 30px);
-        }  
-
-        .defaut-line {
-            word-wrap: break-word;
-            padding: 3px 0 3px 5px;
-        }
-
-        .caller {
-            padding: 3px 0 3px 0;
-            color:darken($color-bot, 10%);
-        }
-
-        .log {  
-            @extend .defaut-line;
-            color:white;
-        }   
-        
-        .warn {
-            @extend .defaut-line;
-            color:orange;
-        }
-        .error {
-            @extend .defaut-line;
-            color:orangered; 
-        }
-        .object {
-            @extend .defaut-line;
-            color:$color-bot;
-        }
-    }
-}

+ 0 - 92
inspector/sass/tabs/_gltfTab.scss

@@ -1,92 +0,0 @@
-.tab-panel {
-    .gltf-actions {
-        overflow-y: auto;
-        padding-left: 5px;
-
-        .gltf-title {
-            font-size     : 1.1em;
-            padding-bottom: 10px;
-            border-bottom : 1px solid $color-bot;
-            margin        : 10px 0 10px 0;
-        }
-
-        .gltf-action {
-            height     : 20px;
-            line-height: 20px;
-            width      : 100%;
-            cursor     : pointer;
-            white-space: nowrap;
-
-            &:hover {
-                background-color: $background-lighter;
-            }
-        }
-
-        .gltf-icon {
-            width      : 1em;
-            height     : 1em;
-            line-height: 1em;
-            display    : inline-block;
-            font-family: $font-family-icons;
-            margin-right:10px;
-        }
-
-        .gltf-checkbox {
-            @extend .gltf-action;
-            &:before {
-                width      : 1em;
-                height     : 1em;
-                line-height: 1em;
-                display    : inline-block;
-                font-family: $font-family-icons;
-                content    : "\f0c8";
-                margin-right:10px;
-            }
-
-            &.active {
-                &:before {
-                    width      : 1em;
-                    height     : 1em;
-                    line-height: 1em;
-                    display    : inline-block;
-                    font-family: $font-family-icons;
-                    content    : "\f14a";
-                    color      : $color-bot;
-                    margin-right:10px;
-                }
-            }
-        }
-
-        .gltf-input {
-            background-color: $background-lighter;
-            border          : none;
-            outline         : none;
-            font-family     : $font;
-            color           : darken($color, 10%);
-            padding         : 5px;
-            margin          : 0px 6px 0px 0;
-
-            &:hover {
-                background-color:$background-lighter2;
-            }
-        }
-
-        .gltf-button {
-            background-color: $background-lighter;
-            border          : none;
-            outline         : none;
-            font-family     : $font;
-            color           : $color;
-            padding         : 5px 10px;
-            margin          : 0px 6px 0px 0;
-
-            &:hover {
-                background-color:$background-lighter2;
-            }
-
-            &:active {
-                background-color:$background-lighter3;
-            }
-        }
-    }
-}

+ 0 - 53
inspector/sass/tabs/_shaderTab.scss

@@ -1,53 +0,0 @@
-.tab-panel {
-
-    .shader-tree-panel {
-        height                  : 30px;
-        
-        // The combo box listing all shaders
-        select {
-            height              : 30px;
-            background-color    : transparent;
-            color               : #ccc;
-            height              : 30px;
-            width               : 100%;
-            max-width           : 300px;
-            padding-left        : 15px;
-            border              : 1px solid $background-lighter;
-            outline             : 1px solid $background-lighter3;
-            option {
-                padding         : 5px;
-                color           : darken($color: $color, $amount: 30%)
-            }
-        }
-        
-    }
-
-    .shader-panel {
-        min-height              : 100px;
-        user-select             : text;
-        box-sizing              : border-box;
-        padding                 : 0 15px;
-        
-        // Shader code style - the syntax highlightinh is done by highlight.js, loaded dynamically
-        pre {
-            margin              : 0;
-            white-space         : pre-wrap;
-            code {
-                // to cancel the background color from zenburn theme of highlight js
-                background-color: $background !important;
-                padding         : 0;
-                margin          : 0;                    
-            }            
-        }
-        
-        .shader-panel-title {
-            height              : 25px;
-            border-bottom       : 1px solid $background-lighter2;
-            text-transform      : uppercase;
-            line-height         : 25px;
-            margin-bottom       : 10px;
-        }
-        
-        
-    }
-}

+ 0 - 52
inspector/sass/tabs/_statsTab.scss

@@ -1,52 +0,0 @@
-.tab-panel {
-
-    &.stats-panel {
-        overflow-y      : auto;
-    }
-    
-    .stats-fps {
-        font-weight:600;
-        color:$color-top;
-    }
-
-    .stat-title1 {        
-        font-size       : 1.1em;
-        padding         : 10px;
-    }
-
-    .stat-title2 {
-        margin          : 10px 0 10px 0;
-        font-size       : 1.05em; 
-        border-bottom   : 1px solid $color-bot;
-        box-sizing      : border-box;
-    }
-
-    .stat-label {
-        display         : inline-block;
-        width           : 80%;
-        padding         : 2px;
-        background-color: $background-lighter;
-        border-bottom   : 1px solid $background;
-        border-top      : 1px solid $background;
-        height          : 30px;
-        line-height     : 30px;
-        box-sizing      : border-box;
-        
-    }
-    .stat-value {
-        display         : inline-block;
-        width           : 20%;
-        padding         : 2px;
-        background-color: $background-lighter;
-        border-top      : 1px solid $background;
-        border-bottom   : 1px solid $background;
-        height          : 30px;
-        line-height     : 30px;
-        box-sizing      : border-box;
-    }
-
-    .stat-infos {
-        width           : 100%;
-        padding         : 4px;
-    }
-}

+ 0 - 80
inspector/sass/tabs/_toolsTab.scss

@@ -1,80 +0,0 @@
-.tab-panel {
-
-    &.tools-panel {
-        overflow-y      : auto;
-    }
-
-    .tool-title1 {        
-        font-size       : 1.1em;
-        padding         : 10px;
-    }
-
-    .tool-title2 {
-        margin          : 10px 0 10px 0;
-        font-size       : 1.05em; 
-        border-bottom   : 1px solid $color-bot;
-        box-sizing      : border-box;
-    }
-
-    .tool-label {
-        background-color: $background-lighter;
-        border          : none;
-        outline         : none;
-        font-family     : $font;
-        color           : darken($color, 10%);
-        padding         : 5px;
-        margin          : 0px 6px 0px 0;
-    }
-
-    .tool-label-line {
-        @extend .tool-label;
-        width           : 100%;
-    }
-
-    .tool-label-error {
-        @extend .tool-label;
-        color           : $color-error;
-        width           : 100%;
-        background-color: none;
-    }
-
-    .tool-value {
-        display         : inline-block;
-        width           : 25%;
-        padding         : 2px;
-        background-color: $background-lighter;
-        border-top      : 1px solid $background;
-        border-bottom   : 1px solid $background;
-        height          : 30px;
-        line-height     : 30px;
-        box-sizing      : border-box;
-    }
-
-    .tool-infos {
-        width           : 100%;
-        padding         : 4px;
-    }
-
-    .tool-input {
-        background-color: $background-lighter;
-        border          : none;
-        outline         : none;
-        font-family     : $font;
-        color           : $color;
-        padding         : 5px 10px;
-        margin          : 0px 6px 0px 0;
-        width           : 100%;
-        border-top      : 1px solid $background;
-        border-bottom   : 1px solid $background;
-        text-align: left;
-
-        &:hover {
-            background-color:$background-lighter2;
-            cursor: pointer;
-        }
-
-        &:active {
-            background-color:$background-lighter3;
-        }
-    }
-}

BIN
inspector/screens/tab_mesh.jpg


BIN
inspector/screens/tools.jpg


+ 0 - 441
inspector/src/Inspector.ts

@@ -1,441 +0,0 @@
-import { AbstractMesh, Nullable, Scene, Tools, Observable } from "babylonjs";
-import "../sass/main.scss";
-import { Helpers } from "./helpers/Helpers";
-import { loadGUIProperties } from "./properties_gui";
-import { Scheduler } from "./scheduler/Scheduler";
-import { TabBar } from "./tabs/TabBar";
-
-import * as Split from "Split";
-
-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 | string;
-
-    private _parentElement: Nullable<HTMLElement>;
-
-    public onGUILoaded: Observable<any>;
-
-    public static GUIObject: any; // should be typeof "babylonjs-gui";
-
-    /** 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 | string = 0, parentElement: Nullable<HTMLElement> = null, newColors?: {
-        backgroundColor?: string,
-        backgroundColorLighter?: string,
-        backgroundColorLighter2?: string,
-        backgroundColorLighter3?: string,
-        color?: string,
-        colorTop?: string,
-        colorBot?: string
-    }) {
-
-        this.onGUILoaded = new Observable();
-
-        import("babylonjs-gui").then((GUI) => {
-            // Load GUI library if not already done
-            if (!GUI || (typeof GUI !== "undefined" && Object.keys(GUI).indexOf("default") !== -1)) {
-                Tools.LoadScript("https://preview.babylonjs.com/gui/babylon.gui.min.js", () => {
-                    Inspector.GUIObject = (<any>BABYLON).GUI;
-                    this.onGUILoaded.notifyObservers(Inspector.GUIObject);
-                    //Load properties of GUI objects now as GUI has to be declared before
-                    loadGUIProperties(Inspector.GUIObject);
-                }, () => {
-                    console.warn('Error : loading "babylon.gui.min.js". Please add script https://preview.babylonjs.com/gui/babylon.min.gui.js to the HTML file.');
-                });
-            }
-            else {
-                Inspector.GUIObject = GUI;
-                this.onGUILoaded.notifyObservers(Inspector.GUIObject);
-                //Load properties of GUI objects now as GUI has to be declared before
-                loadGUIProperties(Inspector.GUIObject);
-            }
-        });
-        //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');
-
-                // copy style from canvas to wrapper
-                for (let prop in this._canvasStyle) {
-                    (<any>this._c2diwrapper.style)[prop] = this._canvasStyle[prop];
-                }
-
-                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;
-
-                // 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`;
-                    }
-                }
-
-                // Check if the parent of the canvas is the body page. If yes, the size ratio is computed
-                let parent = this._getRelativeParent(canvas);
-
-                let parentWidthPx = parent.clientWidth;
-                let parentHeightPx = parent.clientHeight;
-
-                let pWidth = widthPx / parentWidthPx * 100;
-                let pheight = heightPx / parentHeightPx * 100;
-
-                this._c2diwrapper.style.width = pWidth + "%";
-                this._c2diwrapper.style.height = pheight + "%";
-
-                // 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";
-
-                canvas.style.margin = "0";
-                canvas.style.marginBottom = "0";
-                canvas.style.marginLeft = "0";
-                canvas.style.marginTop = "0";
-                canvas.style.marginRight = "0";
-
-                // 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();
-                            }
-                        }
-                    });
-                }
-
-                // Build the inspector
-                this._buildInspector(inspector);
-            }
-            // Send resize event to the window
-            Helpers.SEND_EVENT('resize');
-            this._tabbar.updateWidth();
-        }
-
-        /*
-        * 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
-                }
-            }
-        }
-    }
-
-    /**
-     * 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);
-            }
-        }
-        // 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();
-
-        // Tab panel
-        this._tabPanel = Helpers.CreateDiv('tab-panel-content', this._topPanel);
-
-    }
-
-    public get scene(): 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();
-
-        if (tab) {
-            tab.filter(filter);
-        }
-    }
-
-    /** Display the mesh tab on the given object */
-    public displayObjectDetails(mesh: AbstractMesh) {
-        this._tabbar.switchMeshTab(mesh);
-    }
-
-    /** Clean the whole tree of item and rebuilds it */
-    public refresh() {
-        // Clean top panel
-        Helpers.CleanDiv(this._tabPanel);
-
-        // 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');
-                }
-            }
-        }
-        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) {
-
-        // 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;
-
-            if (popup.document.head) {
-                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();
-    }
-}

+ 0 - 43
inspector/src/adapters/Adapter.ts

@@ -1,43 +0,0 @@
-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 = 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 list of properties to be displayed for this adapter */
-    public abstract getProperties(): Array<PropertyLine>;
-
-    /** Returns true if the given object correspond to this  */
-    public correspondsTo(obj: any) {
-        return obj === this._obj;
-    }
-
-    /** Returns the adapter unique name */
-    public get name(): string {
-        return Adapter._name;
-    }
-
-    /**
-     * 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>;
-}

+ 0 - 56
inspector/src/adapters/CameraAdapter.ts

@@ -1,56 +0,0 @@
-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";
-
-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";
-        }
-    }
-
-}

+ 0 - 48
inspector/src/adapters/GUIAdapter.ts

@@ -1,48 +0,0 @@
-
-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 GUIAdapter
-    extends Adapter
-    implements IToolVisible {
-
-    constructor(obj: any) {
-        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).isVisible = b;
-    }
-
-    public isVisible(): boolean {
-        return (this._obj).isVisible;
-    }
-}

+ 0 - 51
inspector/src/adapters/LightAdapter.ts

@@ -1,51 +0,0 @@
-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`;
-    // }
-}

+ 0 - 37
inspector/src/adapters/MaterialAdapter.ts

@@ -1,37 +0,0 @@
-import { Material } from "babylonjs";
-import { PropertyLine } from "../details/PropertyLine";
-import { Helpers } from "../helpers/Helpers";
-import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
-import { Adapter } from "./Adapter";
-
-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 [];
-    }
-}

+ 0 - 116
inspector/src/adapters/MeshAdapter.ts

@@ -1,116 +0,0 @@
-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);
-    }
-
-    /** 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));
-        tools.push(new DebugArea(this));
-        if (this._obj instanceof AbstractMesh) {
-            if ((this._obj as AbstractMesh).getTotalVertices() > 0) {
-                tools.push(new BoundingBox(this));
-            }
-        }
-
-        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 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 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';
-    }
-
-    /** 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;
-            }
-            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));
-        });
-    }
-}

+ 0 - 59
inspector/src/adapters/PhysicsImpostorAdapter.ts

@@ -1,59 +0,0 @@
-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;
-
-    constructor(obj: PhysicsImpostor, viewer: any) {
-        super(obj);
-        this._viewer = viewer;
-    }
-
-    /** 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 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._isVisible = b;
-        if (b) {
-            this._viewer.showImpostor(this._obj);
-        } else {
-            this._viewer.hideImpostor(this._obj);
-        }
-    }
-
-    public isVisible(): boolean {
-        return this._isVisible;
-    }
-
-}

+ 0 - 52
inspector/src/adapters/SoundAdapter.ts

@@ -1,52 +0,0 @@
-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: Sound) {
-        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 SoundInteractions(this));
-        return tools;
-    }
-
-    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).onEndedObservable.addOnce(() => {
-            callback();
-        });
-    }
-}

+ 0 - 40
inspector/src/adapters/TextureAdapter.ts

@@ -1,40 +0,0 @@
-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 {
-
-    constructor(obj: 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;
-    }
-
-    /** 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> {
-        // Not used in this tab
-        return [];
-    }
-
-    public getTools(): Array<AbstractTreeTool> {
-        let tools = new Array<AbstractTreeTool>();
-        // tools.push(new CameraPOV(this));
-        return tools;
-    }
-
-}

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

@@ -1,9 +0,0 @@
-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';

+ 773 - 0
inspector/src/components/actionTabs/actionTabs.scss

@@ -0,0 +1,773 @@
+#inspector-host {
+    position: absolute;
+    right: 0px;
+    top:0px;
+    bottom: 0px;
+}
+
+#actionTabs {
+    background: #333333;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    display: grid;
+    grid-template-rows: auto 1fr;
+    font: 14px "Arial";    
+    overflow: hidden;
+
+    #header {
+        height: 30px;
+        font-size: 16px;
+        color: white;
+        background: #222222;
+        grid-row: 1;
+        text-align: center;
+        display: grid;
+        grid-template-columns: 30px 1fr 50px;        
+        -webkit-user-select: none; 
+        -moz-user-select: none;   
+        -ms-user-select: none;    
+        user-select: none;                
+
+        #logo {
+            grid-column: 1; 
+            width: 24px;
+            height: 24px;
+            display: flex;
+            align-self: center;   
+            justify-self: center;
+        }        
+
+        #back {
+            grid-column: 1; 
+            display: grid;
+            align-self: center;   
+            justify-self: center;
+            cursor: pointer;
+        }              
+
+        #title {
+            grid-column: 2; 
+            display: grid;
+            align-items: center;   
+            text-align: center;
+        }
+
+        #commands {
+            grid-column: 3; 
+            display: grid;
+            align-items: center;  
+            grid-template-columns: 1fr 1fr;   
+            
+            .expand {
+                grid-column: 1;
+                display: grid;
+                align-items: center;   
+                justify-items: center;
+                cursor: pointer;     
+            }
+
+            .close {
+                grid-column: 2;
+                display: grid;
+                align-items: center;   
+                justify-items: center;
+                cursor: pointer;     
+            }        
+        }
+    }
+
+    .tabs {
+        display: grid;
+        grid-row: 2;
+        grid-template-rows: 40px 1fr;
+        font: 14px "Arial";
+        overflow: hidden;
+
+        .labels {
+            grid-row: 1;
+            display: flex;
+            align-items: center;
+            justify-items: center;
+            border-bottom: 1px solid #ffffff; 
+            margin: 0;
+            padding: 0;         
+
+            .label {
+                font-size: 24px;
+                color: white;
+                width: 40px;
+                display: flex;
+                align-content: center;
+                justify-content: center;
+                border: 1px solid transparent;            
+                border-bottom: none;    
+                background: #333333;
+                padding: 5px;  
+                height: 28px;
+                cursor: pointer;
+
+                &.active {
+                    border-color: #ffffff;  
+                    border-bottom: 2px solid transparent;           
+                    margin-bottom: -2px;
+                }
+            }
+        }
+
+        .panes {
+            grid-row: 2;
+
+            display: grid;
+            grid-template-rows: 1fr;
+
+            overflow: hidden;
+
+            .infoMessage {
+                opacity: 0.5;
+                color: white;
+                margin: 15px 5px 0px 5px;
+                                
+            }
+
+            .pane {
+                color: white;
+
+                overflow-x: hidden;
+                overflow-y: auto;
+
+                -webkit-user-select: none; 
+                -moz-user-select: none;   
+                -ms-user-select: none;    
+                user-select: none;     
+                
+                .textureLinkLine {
+                    display: grid;
+                    grid-template-columns: auto 1fr;
+
+                    .debug {
+                        grid-column: 1;
+                        margin-left: 5px;
+                        display: grid;
+                        align-items: center; 
+                        justify-items: center;                          
+                        cursor: pointer;
+                        opacity: 0.5;
+
+                        &.selected {
+                            opacity: 1.0;
+                        }
+                    }
+
+                    .textLine {
+                        grid-column: 2;
+                    }
+                }
+
+                .messageLine {
+                    text-align: center;
+                    font-size: 12px;
+                    font-style: italic;
+                    opacity: 0.6;
+                }
+
+                .iconMessageLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 30px 1fr;
+
+                    .icon {
+                        grid-column: 1;
+                        display: grid;
+                        align-items: center;
+                        justify-items: center;
+                    }
+
+                    .value {
+                        grid-column: 2;
+                        display: flex;
+                        align-items: center;
+                    }
+                }
+
+                .textLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .link-value {
+                        grid-column: 2;
+                        white-space: nowrap;
+                        text-overflow: ellipsis;
+                        overflow: hidden;
+                        text-align: end;
+                        opacity: 0.8;
+                        margin:5px;
+                        margin-top: 6px;
+                        max-width: 200px;
+                        text-decoration: underline;
+                        cursor: pointer;
+                    }
+
+                    .value {
+                        grid-column: 2;
+                        white-space: nowrap;
+                        text-overflow: ellipsis;
+                        overflow: hidden;
+                        text-align: end;
+                        opacity: 0.8;
+                        margin:5px;
+                        margin-top: 6px;
+                        max-width: 200px;
+
+                        &.check {
+                            color: green;
+                        }
+
+                        &.uncheck {
+                            color: red;
+                        }  
+                    }
+                }
+
+                .textInputLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr 120px;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .value {                        
+                        display: flex;
+                        align-items: center;
+                        grid-column: 2;
+                        
+                        input {
+                            width: 110px;
+                        }
+                    }
+                }
+
+                .buttonLine {
+                    height: 30px;
+                    display: grid;
+                    align-items: center;
+                    justify-items: stretch;
+
+                    input[type="file"] {
+                        display: none;
+                    }
+
+                    .file-upload {
+                        background: transparent;
+                        border: 1px solid rgb(51, 122, 183);
+                        margin: 0px 10px;
+                        color:white;
+                        padding: 4px 5px;
+                        opacity: 0.9;
+                        cursor: pointer;
+                        text-align: center;
+                    }
+
+                    .file-upload:hover {
+                        opacity: 1.0;
+                    }
+
+                    .file-upload:active {
+                        transform: scale(0.98);
+                        transform-origin: 0.5 0.5;
+                    }
+
+                    button {
+                        background: #222222;
+                        border: 1px solid rgb(51, 122, 183);
+                        margin: 5px 10px 5px 10px;
+                        color:white;
+                        padding: 4px 5px;
+                        opacity: 0.9;
+                    }
+
+                    button:hover {
+                        opacity: 1.0;
+                    }
+
+                    button:active {
+                        background: #282828;
+                    }   
+                    
+                    button:focus {
+                        border: 1px solid rgb(51, 122, 183);
+                        outline: 0px;
+                    }  
+                }
+
+                .radioLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr 30px;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .radioContainer {
+                        display: flex;
+                        align-items: center;
+
+                        .radio {
+                            grid-column: 2;                        
+                            display: none;
+
+                            &:checked + label:before {
+                                border-color: rgb(51, 122, 183);
+                            }
+                            &:checked + label:after {
+                                transform: scale(1);
+                            }                        
+                        }
+
+                        .labelForRadio {
+                            display: inline-block;
+                            height: 14px;
+                            position: relative;
+                            padding: 0 24px;
+                            margin-bottom: 0;
+                            cursor: pointer;
+                            vertical-align: bottom;
+                            &:before, &:after {
+                                position: absolute;            
+                                content: '';  
+                                border-radius: 50%;
+                                transition: all .3s ease;
+                                transition-property: transform, border-color;
+                            }
+                            &:before {
+                                left: 0px;
+                                top: 0;
+                                width: 16px;
+                                height: 16px;
+                                border: 2px solid white;
+                            }
+                            &:after {
+                                top: 6px;
+                                left: 6px;
+                                width: 8px;
+                                height: 8px;
+                                transform: scale(0);
+                                background:rgb(51, 122, 183);
+                            }
+                        }
+                    }
+                }
+
+                .vector3Line {
+                    padding-left: 5px;                    
+                    display: grid;
+
+                    .firstLine {
+                        display: grid;
+                        grid-template-columns: 1fr auto 20px;
+                        height: 30px;
+
+                        .label {
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;
+                        }
+
+                        .vector {
+                            grid-column: 2;
+                            display: flex;
+                            align-items: center;
+                            text-align: right;
+                            opacity: 0.8;
+                        }
+
+                        .expand {
+                            grid-column: 3;
+                            display: grid;
+                            align-items: center;
+                            justify-items: center;
+                            cursor: pointer;
+                        }
+                    }
+
+                    .secondLine {
+                        display: grid;
+                        padding-right: 5px;  
+                        border-left: 1px solid rgb(51, 122, 183);
+
+                        .numeric {
+                            display: grid;
+                            grid-template-columns: 1fr auto;
+                        }
+
+                        .numeric-label {
+                            text-align: right;
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;                            
+                            justify-self: right;
+                            margin-right: 10px;                          
+                        }
+
+                        .numeric-value {
+                            width: 120px;
+                            grid-column: 2;
+                            display: flex;
+                            align-items: center;  
+                            border: 1px solid  rgb(51, 122, 183);
+                        }                        
+                    }
+                }
+
+                .checkBoxLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .checkBox {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;
+
+                        .lbl {
+                            position: relative;
+                            display: block;
+                            height: 14px;
+                            width: 34px;
+                            margin-right: 5px;
+                            background: #898989;
+                            border-radius: 100px;
+                            cursor: pointer;
+                            transition: all 0.3s ease;
+                        }
+
+                        .lbl:after {
+                            position: absolute;
+                            left: 3px;
+                            top: 2px;
+                            display: block;
+                            width: 10px;
+                            height: 10px;
+                            border-radius: 100px;
+                            background: #fff;
+                            box-shadow: 0px 3px 3px rgba(0,0,0,0.05);
+                            content: '';
+                            transition: all 0.15s ease;
+                        }
+
+                        .lbl:active:after { 
+                            transform: scale(1.15, 0.85); 
+                        }
+
+                        .cbx:checked ~ label { 
+                            background: rgb(51, 122, 183);
+                        }
+
+                        .cbx:checked ~ label:after {
+                            left: 20px;
+                            background: rgb(22, 73, 117);
+                        }
+
+                        .hidden { 
+                            display: none; 
+                        }               
+                    }                    
+                }                   
+
+                .textureLine {                   
+                    display: grid;
+                    grid-template-rows: 30px auto;
+
+                    .control {
+                        margin-top: 2px;
+                        grid-row: 1;
+                        display: grid;
+                        grid-template-columns: 1fr 40px 40px 40px 40px 40px 1fr;
+
+                        .red {
+                            grid-column: 2;
+                        }
+
+                        .green {
+                            grid-column: 3;
+                        }
+
+                        .blue {
+                            grid-column: 4;
+                        }
+
+                        .alpha {
+                            grid-column: 5;
+                        }                        
+
+                        .all {
+                            grid-column: 6;
+                        }                        
+                    }
+
+                    .control3D {
+                        margin-top: 2px;
+                        grid-row: 1;
+                        display: grid;
+                        grid-template-columns: 1fr 40px 40px 40px 40px 40px 40px 1fr;
+
+                        .px {
+                            grid-column: 2;
+                        }
+
+                        .nx {
+                            grid-column: 3;
+                        }
+
+                        .py {
+                            grid-column: 4;
+                        }
+
+                        .ny {
+                            grid-column: 5;
+                        }   
+
+                        .pz {
+                            grid-column: 6;
+                        }
+
+                        .nz {
+                            grid-column: 7;
+                        }                     
+                    }                    
+
+                    .command {
+                        border: 1px solid transparent;
+                        background:transparent;
+                        color: white;
+                    }
+
+                    .selected {
+                        border: 1px solid rgb(51, 122, 183);
+                    }
+
+                    .preview {
+                        grid-row: 2;
+                        display: grid;
+                        align-self: center;
+                        justify-self: center;
+                        height: 256px;
+                        width: 256px;
+                        margin-top: 5px;
+                        margin-bottom: 5px;
+                        border: 2px solid rgba(255, 255, 255, 0.4);
+                    }
+                }
+
+                .gltf-extension-property {
+                    margin-left: 30px;
+                    border-left: 1px solid rgb(51, 122, 183);
+                }
+
+                .floatLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr 120px;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .value {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;
+                        
+                        input {
+                            width: 110px;
+                        }
+                    }
+                }
+
+                .sliderLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .slider {
+                        grid-column: 2;
+                        margin-right: 5px;
+                        
+                        display: flex;
+                        align-items: center;
+
+                        .range {
+                            -webkit-appearance: none;
+                            width: 120px;
+                            height: 6px;
+                            background: #d3d3d3;
+                            border-radius: 5px;
+                            outline: none;
+                            opacity: 0.7;
+                            -webkit-transition: .2s;
+                            transition: opacity .2s;
+                        }
+                        
+                        .range:hover {
+                            opacity: 1;
+                        }
+                        
+                        .range::-webkit-slider-thumb {
+                            -webkit-appearance: none;
+                            appearance: none;
+                            width: 14px;
+                            height: 14px;
+                            border-radius: 50%;
+                            background: rgb(51, 122, 183);
+                            cursor: pointer;
+                        }
+                        
+                        .range::-moz-range-thumb {
+                            width: 14px;
+                            height: 14px;
+                            border-radius: 50%;
+                            background: rgb(51, 122, 183);
+                            cursor: pointer;
+                        }
+                    }                    
+                }       
+                
+                .color3Line {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .color3 {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;   
+
+                        input[type="color"] {
+                            -webkit-appearance: none;
+                            border: none;
+                            padding: 0;
+                            width: 20px;
+                            height: 20px;
+                        }
+                        input[type="color"]::-webkit-color-swatch-wrapper {
+                            padding: 0;
+                        }
+                        input[type="color"]::-webkit-color-swatch {
+                            border: none;
+                        }
+                        
+                        input {
+                            margin-right: 5px;
+                        }
+                    }                    
+                }     
+                
+                .listLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .options {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;   
+                        margin-right: 5px;
+                    }                    
+                }                   
+
+                .paneContainer {
+                    margin-top: 3px;
+                    
+                    .header {
+                        display: grid;
+                        grid-template-columns: 1fr auto;
+                        background: #555555;    
+                        height: 30px;   
+                        padding-right: 5px;                        
+                        cursor: pointer;
+                        
+                        .title {
+                            margin-left: 5px;
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;
+                        }
+
+                        .collapse {
+                            grid-column: 2;
+                            display: flex;
+                            align-items: center;  
+                            justify-items: center;
+                            transform-origin: center;
+
+                            &.closed {
+                                transform: rotate(180deg);
+                            }
+                        }                        
+                    }
+
+                    .paneList > div:not(:last-child) {
+                        border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
+                    }
+                }
+            }
+        }
+    }
+}

+ 133 - 0
inspector/src/components/actionTabs/actionTabsComponent.tsx

@@ -0,0 +1,133 @@
+import * as React from "react";
+import { Observer, Scene, Nullable } from "babylonjs";
+import { TabsComponent } from "./tabsComponent";
+import { faFileAlt, faWrench, faBug, faChartBar } from '@fortawesome/free-solid-svg-icons';
+import { StatisticsTabComponent } from "./tabs/statisticsTabComponent";
+import { DebugTabComponent } from "./tabs/debugTabComponent";
+import Resizable from "re-resizable";
+import { PropertyGridTabComponent } from "./tabs/propertyGridTabComponent";
+import { HeaderComponent } from "../headerComponent";
+import { ToolsTabComponent } from "./tabs/toolsTabComponent";
+import { GlobalState } from "components/globalState";
+
+require("./actionTabs.scss");
+
+interface IActionTabsComponentProps {
+    scene: Scene,
+    noCommands?: boolean,
+    noHeader?: boolean,
+    noExpand?: boolean,
+    popupMode?: boolean,
+    onPopup?: () => void,
+    onClose?: () => void,
+    globalState: GlobalState
+}
+
+export class ActionTabsComponent extends React.Component<IActionTabsComponentProps, { selectedEntity: any, selectedIndex: number }> {
+    private _onSelectionChangeObserver: Nullable<Observer<any>>;
+    private _onTabChangedObserver: Nullable<Observer<any>>;
+    private _once = true;
+
+    constructor(props: IActionTabsComponentProps) {
+        super(props);
+
+        let initialIndex = 0;
+
+        const validationResutls = this.props.globalState.validationResults;
+        if (validationResutls) {
+            if (validationResutls.issues.numErrors || validationResutls.issues.numWarnings) {
+                initialIndex = 3;
+            }
+        }
+
+        this.state = { selectedEntity: null, selectedIndex: initialIndex }
+    }
+
+    componentWillMount() {
+        this._onSelectionChangeObserver = this.props.globalState.onSelectionChangedObservable.add((entity) => {
+            this.setState({ selectedEntity: entity, selectedIndex: 0 });
+        });
+
+        this._onTabChangedObserver = this.props.globalState.onTabChangedObservable.add(index => {
+            this.setState({ selectedIndex: index });
+        });
+    }
+
+    componentWillUnmount() {
+        if (this._onSelectionChangeObserver) {
+            this.props.globalState.onSelectionChangedObservable.remove(this._onSelectionChangeObserver);
+        }
+
+        if (this._onTabChangedObserver) {
+            this.props.globalState.onTabChangedObservable.remove(this._onTabChangedObserver);
+        }
+    }
+
+    changeSelectedTab(index: number) {
+        this.props.globalState.onTabChangedObservable.notifyObservers(index);
+    }
+
+    renderContent() {
+        return (
+            <TabsComponent selectedIndex={this.state.selectedIndex} onSelectedIndexChange={(value) => this.changeSelectedTab(value)}>
+                <PropertyGridTabComponent
+                    title="Properties" icon={faFileAlt} scene={this.props.scene} selectedEntity={this.state.selectedEntity}
+                    onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.globalState.onPropertyChangedObservable} />
+                <DebugTabComponent title="Debug" icon={faBug} scene={this.props.scene} />
+                <StatisticsTabComponent title="Statistics" icon={faChartBar} scene={this.props.scene} />
+                <ToolsTabComponent title="Tools" icon={faWrench} scene={this.props.scene} globalState={this.props.globalState} />
+            </TabsComponent>
+        )
+    }
+
+    onClose() {
+        if (!this.props.onClose) {
+            return;
+        }
+        this.props.onClose();
+    }
+
+    onPopup() {
+        if (!this.props.onPopup) {
+            return;
+        }
+        this.props.onPopup();
+    }
+
+    render() {
+        if (this.props.popupMode) {
+            return (
+                <div id="actionTabs">
+                    {
+                        !this.props.noHeader &&
+                        <HeaderComponent title="INSPECTOR" handleBack={true} noCommands={this.props.noCommands} onClose={() => this.onClose()} onPopup={() => this.onPopup()} onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable} />
+                    }
+                    {this.renderContent()}
+                </div>
+            );
+        }
+
+        if (this._once) {
+            this._once = false;
+            // A bit hacky but no other way to force the initial width to 300px and not auto
+            setTimeout(() => {
+                const element = document.getElementById("actionTabs");
+                if (!element) {
+                    return;
+                }
+                element.style.width = "300px";
+            }, 150);
+        }
+
+        return (
+            <Resizable id="actionTabs" minWidth={300} maxWidth={600} size={{ height: "100%" }} minHeight="100%" enable={{ top: false, right: false, bottom: false, left: true, topRight: false, bottomRight: false, bottomLeft: false, topLeft: false }}>
+                {
+                    !this.props.noHeader &&
+                    <HeaderComponent title="INSPECTOR" handleBack={true} noExpand={this.props.noExpand} noCommands={this.props.noCommands} onClose={() => this.onClose()} onPopup={() => this.onPopup()} onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable} />
+                }
+                {this.renderContent()}
+            </Resizable>
+        );
+    }
+}

+ 70 - 0
inspector/src/components/actionTabs/lineContainerComponent.tsx

@@ -0,0 +1,70 @@
+import * as React from "react";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
+
+interface ILineContainerComponentProps {
+    title: string,
+    children: any[] | any,
+    closed?: boolean
+}
+
+export class LineContainerComponent extends React.Component<ILineContainerComponentProps, { isExpanded: boolean }> {
+    constructor(props: ILineContainerComponentProps) {
+        super(props);
+
+        let initialState: boolean;
+
+        if (typeof (Storage) !== "undefined" && localStorage.getItem(this.props.title) !== null) {
+            initialState = localStorage.getItem(this.props.title) === "true";
+        } else {
+            initialState = !this.props.closed;
+        }
+
+        this.state = { isExpanded: initialState };
+    }
+
+    switchExpandedState(): void {
+        if (typeof (Storage) !== "undefined") {
+            localStorage.setItem(this.props.title, !this.state.isExpanded ? "true" : "false");
+        }
+        this.setState({ isExpanded: !this.state.isExpanded });
+    }
+
+    renderHeader() {
+        const className = this.state.isExpanded ? "collapse" : "collapse closed";
+
+        return (
+            <div className="header" onClick={() => this.switchExpandedState()}>
+                <div className="title">
+                    {this.props.title}
+                </div>
+                <div className={className}>
+                    <FontAwesomeIcon icon={faChevronDown} />
+                </div>
+            </div>
+        )
+    }
+
+    render() {
+        if (!this.state.isExpanded) {
+            return (
+                <div className="paneContainer">
+                    {
+                        this.renderHeader()
+                    }
+                </div>
+            )
+        }
+
+        return (
+            <div className="paneContainer">
+                {
+                    this.renderHeader()
+                }
+                <div className="paneList">
+                    {this.props.children}
+                </div >
+            </div>
+        );
+    }
+}

+ 31 - 0
inspector/src/components/actionTabs/lines/booleanLineComponent.tsx

@@ -0,0 +1,31 @@
+import * as React from "react";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faCheck, faTimesCircle } from "@fortawesome/free-solid-svg-icons";
+
+export interface IBooleanLineComponentProps {
+    label: string,
+    value: boolean
+}
+
+export class BooleanLineComponent extends React.Component<IBooleanLineComponentProps> {
+    constructor(props: IBooleanLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+
+        const check = this.props.value ? <FontAwesomeIcon icon={faCheck} /> : <FontAwesomeIcon icon={faTimesCircle} />
+        const className = this.props.value ? "value check" : "value uncheck";
+
+        return (
+            <div className="textLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className={className}>
+                    {check}
+                </div>
+            </div>
+        );
+    }
+}

+ 21 - 0
inspector/src/components/actionTabs/lines/buttonLineComponent.tsx

@@ -0,0 +1,21 @@
+import * as React from "react";
+
+export interface IButtonLineComponentProps {
+    label: string,
+    onClick: () => void
+}
+
+export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+    constructor(props: IButtonLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+
+        return (
+            <div className="buttonLine">
+                <button onClick={() => this.props.onClick()}>{this.props.label}</button>
+            </div>
+        );
+    }
+}

+ 79 - 0
inspector/src/components/actionTabs/lines/checkBoxLineComponent.tsx

@@ -0,0 +1,79 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+export interface ICheckBoxLineComponentProps {
+    label: string,
+    target?: any,
+    propertyName?: string,
+    isSelected?: () => boolean,
+    onSelect?: (value: boolean) => void,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class CheckBoxLineComponent extends React.Component<ICheckBoxLineComponentProps, { isSelected: boolean }> {
+    private static _UniqueIdSeed = 0;
+    private _uniqueId: number;
+    private _localChange = false;
+    constructor(props: ICheckBoxLineComponentProps) {
+        super(props);
+
+        this._uniqueId = CheckBoxLineComponent._UniqueIdSeed++;
+
+        if (this.props.isSelected) {
+            this.state = { isSelected: this.props.isSelected() };
+        } else {
+            this.state = { isSelected: this.props.target[this.props.propertyName!] };
+        }
+    }
+
+    shouldComponentUpdate(nextProps: ICheckBoxLineComponentProps, nextState: { isSelected: boolean }) {
+        var currentState: boolean;
+
+        if (this.props.isSelected) {
+            currentState = nextProps.isSelected!();
+        } else {
+            currentState = nextProps.target[nextProps.propertyName!];
+        }
+
+        if (currentState !== nextState.isSelected || this._localChange) {
+            nextState.isSelected = currentState;
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    onChange() {
+        this._localChange = true;
+        if (this.props.onSelect) {
+            this.props.onSelect(!this.state.isSelected);
+        } else {
+            if (this.props.onPropertyChangedObservable) {
+                this.props.onPropertyChangedObservable.notifyObservers({
+                    object: this.props.target,
+                    property: this.props.propertyName!,
+                    value: !this.state.isSelected,
+                    initialValue: this.state.isSelected
+                });
+            }
+
+            this.props.target[this.props.propertyName!] = !this.state.isSelected;
+        }
+        this.setState({ isSelected: !this.state.isSelected });
+    }
+
+    render() {
+        return (
+            <div className="checkBoxLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="checkBox">
+                    <input type="checkbox" id={"checkbox" + this._uniqueId} className="cbx hidden" checked={this.state.isSelected} onChange={() => this.onChange()} />
+                    <label htmlFor={"checkbox" + this._uniqueId} className="lbl"></label>
+                </div>
+            </div>
+        );
+    }
+}

+ 61 - 0
inspector/src/components/actionTabs/lines/color3LineComponent.tsx

@@ -0,0 +1,61 @@
+import * as React from "react";
+import { Observable, Color3 } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+export interface IColor3LineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class Color3LineComponent extends React.Component<IColor3LineComponentProps, { color: Color3 }> {
+    private _localChange = false;
+    constructor(props: IColor3LineComponentProps) {
+        super(props);
+
+        this.state = { color: this.props.target[this.props.propertyName] };
+    }
+
+    shouldComponentUpdate(nextProps: IColor3LineComponentProps, nextState: { color: Color3 }) {
+        const currentState = nextProps.target[nextProps.propertyName];
+
+        if (!currentState.equals(nextState.color) || this._localChange) {
+            nextState.color = currentState;
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    onChange(newValue: string) {
+        this._localChange = true;
+        const newColor = BABYLON.Color3.FromHexString(newValue);
+
+        if (this.props.onPropertyChangedObservable) {
+            this.props.onPropertyChangedObservable.notifyObservers({
+                object: this.props.target,
+                property: this.props.propertyName,
+                value: newColor,
+                initialValue: this.state.color
+            });
+        }
+
+        this.props.target[this.props.propertyName] = newColor;
+
+        this.setState({ color: newColor });
+    }
+
+    render() {
+        return (
+            <div className="color3Line">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="color3">
+                    <input type="color" value={this.state.color.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
+                </div>
+            </div>
+        );
+    }
+}

+ 33 - 0
inspector/src/components/actionTabs/lines/fileButtonLineComponent.tsx

@@ -0,0 +1,33 @@
+import * as React from "react";
+
+interface IFileButtonLineComponentProps {
+    label: string,
+    onClick: (file: File) => void,
+    accept: string
+}
+
+export class FileButtonLineComponent extends React.Component<IFileButtonLineComponentProps> {
+    constructor(props: IFileButtonLineComponentProps) {
+        super(props);
+    }
+
+    onChange(evt: any) {
+        var files: File[] = evt.target.files;
+        if (files && files.length) {
+            this.props.onClick(files[0]);
+        }
+
+        evt.target.value = "";
+    }
+
+    render() {
+        return (
+            <div className="buttonLine">
+                <label htmlFor="file-upload" className="file-upload">
+                    {this.props.label}
+                </label>
+                <input ref="upload" id="file-upload" type="file" accept={this.props.accept} onChange={evt => this.onChange(evt)} />
+            </div>
+        );
+    }
+}

+ 89 - 0
inspector/src/components/actionTabs/lines/floatLineComponent.tsx

@@ -0,0 +1,89 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+interface IFloatLineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    onChange?: (newValue: number) => void,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
+    additionalClass?: string
+}
+
+export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
+    private _localChange = false;
+    private _store: number;
+
+    constructor(props: IFloatLineComponentProps) {
+        super(props);
+
+        let currentValue = this.props.target[this.props.propertyName];
+        this.state = { value: currentValue ? currentValue.toFixed(3) : "0" }
+        this._store = currentValue;
+    }
+
+    shouldComponentUpdate(nextProps: IFloatLineComponentProps, nextState: { value: string }) {
+        if (this._localChange) {
+            this._localChange = false;
+            return true;
+        }
+
+        const newValue = nextProps.target[nextProps.propertyName];
+        if (newValue && newValue !== nextState.value) {
+            nextState.value = newValue.toFixed(3);
+            return true;
+        }
+        return false;
+    }
+
+    raiseOnPropertyChanged(newValue: number, previousValue: number) {
+        if (this.props.onChange) {
+            this.props.onChange(newValue);
+        }
+
+        if (!this.props.onPropertyChangedObservable) {
+            return;
+        }
+        this.props.onPropertyChangedObservable.notifyObservers({
+            object: this.props.target,
+            property: this.props.propertyName,
+            value: newValue,
+            initialValue: previousValue
+        });
+    }
+
+    updateValue(valueString: string) {
+
+        if (/[^0-9\.\-]/g.test(valueString)) {
+            return;
+        }
+
+        let valueAsNumber = parseFloat(valueString);
+
+        this._localChange = true;
+        this.setState({ value: valueString });
+
+        if (isNaN(valueAsNumber)) {
+            return;
+        }
+
+        this.raiseOnPropertyChanged(valueAsNumber, this._store);
+        this.props.target[this.props.propertyName] = valueAsNumber;
+
+        this._store = valueAsNumber;
+    }
+
+    render() {
+        return (
+            <div className={this.props.additionalClass ? this.props.additionalClass + " floatLine" : "floatLine"}>
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="value">
+                    <input className="numeric-input" value={this.state.value} onChange={evt => this.updateValue(evt.target.value)} />
+                </div>
+            </div>
+        );
+    }
+}

+ 38 - 0
inspector/src/components/actionTabs/lines/messageLineComponent.tsx

@@ -0,0 +1,38 @@
+import * as React from "react";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+
+interface IMessageLineComponentProps {
+    text: string,
+    color?: string,
+    icon?: IconProp
+}
+
+export class MessageLineComponent extends React.Component<IMessageLineComponentProps> {
+    constructor(props: IMessageLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+        if (this.props.icon) {
+            return (
+                <div className="iconMessageLine">
+                    <div className="icon" style={{ color: this.props.color ? this.props.color : "" }}>
+                        <FontAwesomeIcon icon={this.props.icon}/>
+                    </div>
+                    <div className="value" title={this.props.text}>
+                        {this.props.text}
+                    </div>
+                </div>
+            );
+        }
+
+        return (
+            <div className="messageLine">
+                <div className="value" title={this.props.text} style={{ color: this.props.color ? this.props.color : "" }}>
+                    {this.props.text}
+                </div>
+            </div>
+        );
+    }
+}

+ 0 - 0
inspector/src/components/actionTabs/lines/numericInputComponent.tsx


Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott