@onerjs/gui 8.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/2D/FrameGraph/guiTask.d.ts +34 -0
  2. package/2D/FrameGraph/guiTask.js +62 -0
  3. package/2D/FrameGraph/guiTask.js.map +1 -0
  4. package/2D/FrameGraph/renderGraphGUIBlock.d.ts +43 -0
  5. package/2D/FrameGraph/renderGraphGUIBlock.js +66 -0
  6. package/2D/FrameGraph/renderGraphGUIBlock.js.map +1 -0
  7. package/2D/adtInstrumentation.d.ts +52 -0
  8. package/2D/adtInstrumentation.js +107 -0
  9. package/2D/adtInstrumentation.js.map +1 -0
  10. package/2D/advancedDynamicTexture.d.ts +548 -0
  11. package/2D/advancedDynamicTexture.js +1522 -0
  12. package/2D/advancedDynamicTexture.js.map +1 -0
  13. package/2D/controls/button.d.ts +109 -0
  14. package/2D/controls/button.js +246 -0
  15. package/2D/controls/button.js.map +1 -0
  16. package/2D/controls/checkbox.d.ts +53 -0
  17. package/2D/controls/checkbox.js +164 -0
  18. package/2D/controls/checkbox.js.map +1 -0
  19. package/2D/controls/colorpicker.d.ts +101 -0
  20. package/2D/controls/colorpicker.js +1396 -0
  21. package/2D/controls/colorpicker.js.map +1 -0
  22. package/2D/controls/container.d.ts +179 -0
  23. package/2D/controls/container.js +616 -0
  24. package/2D/controls/container.js.map +1 -0
  25. package/2D/controls/control.d.ts +943 -0
  26. package/2D/controls/control.js +2460 -0
  27. package/2D/controls/control.js.map +1 -0
  28. package/2D/controls/displayGrid.d.ts +53 -0
  29. package/2D/controls/displayGrid.js +202 -0
  30. package/2D/controls/displayGrid.js.map +1 -0
  31. package/2D/controls/ellipse.d.ts +25 -0
  32. package/2D/controls/ellipse.js +93 -0
  33. package/2D/controls/ellipse.js.map +1 -0
  34. package/2D/controls/focusableButton.d.ts +17 -0
  35. package/2D/controls/focusableButton.js +25 -0
  36. package/2D/controls/focusableButton.js.map +1 -0
  37. package/2D/controls/focusableControl.d.ts +43 -0
  38. package/2D/controls/focusableControl.js +2 -0
  39. package/2D/controls/focusableControl.js.map +1 -0
  40. package/2D/controls/gradient/BaseGradient.d.ts +69 -0
  41. package/2D/controls/gradient/BaseGradient.js +84 -0
  42. package/2D/controls/gradient/BaseGradient.js.map +1 -0
  43. package/2D/controls/gradient/LinearGradient.d.ts +45 -0
  44. package/2D/controls/gradient/LinearGradient.js +73 -0
  45. package/2D/controls/gradient/LinearGradient.js.map +1 -0
  46. package/2D/controls/gradient/RadialGradient.d.ts +53 -0
  47. package/2D/controls/gradient/RadialGradient.js +89 -0
  48. package/2D/controls/gradient/RadialGradient.js.map +1 -0
  49. package/2D/controls/grid.d.ts +151 -0
  50. package/2D/controls/grid.js +528 -0
  51. package/2D/controls/grid.js.map +1 -0
  52. package/2D/controls/image.d.ts +228 -0
  53. package/2D/controls/image.js +915 -0
  54. package/2D/controls/image.js.map +1 -0
  55. package/2D/controls/index.d.ts +34 -0
  56. package/2D/controls/index.js +35 -0
  57. package/2D/controls/index.js.map +1 -0
  58. package/2D/controls/inputPassword.d.ts +9 -0
  59. package/2D/controls/inputPassword.js +22 -0
  60. package/2D/controls/inputPassword.js.map +1 -0
  61. package/2D/controls/inputText.d.ts +197 -0
  62. package/2D/controls/inputText.js +1035 -0
  63. package/2D/controls/inputText.js.map +1 -0
  64. package/2D/controls/inputTextArea.d.ts +142 -0
  65. package/2D/controls/inputTextArea.js +1025 -0
  66. package/2D/controls/inputTextArea.js.map +1 -0
  67. package/2D/controls/line.d.ts +73 -0
  68. package/2D/controls/line.js +227 -0
  69. package/2D/controls/line.js.map +1 -0
  70. package/2D/controls/multiLine.d.ts +75 -0
  71. package/2D/controls/multiLine.js +237 -0
  72. package/2D/controls/multiLine.js.map +1 -0
  73. package/2D/controls/radioButton.d.ts +49 -0
  74. package/2D/controls/radioButton.js +185 -0
  75. package/2D/controls/radioButton.js.map +1 -0
  76. package/2D/controls/rectangle.d.ts +43 -0
  77. package/2D/controls/rectangle.js +204 -0
  78. package/2D/controls/rectangle.js.map +1 -0
  79. package/2D/controls/scrollViewers/scrollViewer.d.ts +178 -0
  80. package/2D/controls/scrollViewers/scrollViewer.js +587 -0
  81. package/2D/controls/scrollViewers/scrollViewer.js.map +1 -0
  82. package/2D/controls/scrollViewers/scrollViewerWindow.d.ts +51 -0
  83. package/2D/controls/scrollViewers/scrollViewerWindow.js +254 -0
  84. package/2D/controls/scrollViewers/scrollViewerWindow.js.map +1 -0
  85. package/2D/controls/selector.d.ts +237 -0
  86. package/2D/controls/selector.js +579 -0
  87. package/2D/controls/selector.js.map +1 -0
  88. package/2D/controls/sliders/baseSlider.d.ts +80 -0
  89. package/2D/controls/sliders/baseSlider.js +299 -0
  90. package/2D/controls/sliders/baseSlider.js.map +1 -0
  91. package/2D/controls/sliders/imageBasedSlider.d.ts +47 -0
  92. package/2D/controls/sliders/imageBasedSlider.js +168 -0
  93. package/2D/controls/sliders/imageBasedSlider.js.map +1 -0
  94. package/2D/controls/sliders/imageScrollBar.d.ts +67 -0
  95. package/2D/controls/sliders/imageScrollBar.js +248 -0
  96. package/2D/controls/sliders/imageScrollBar.js.map +1 -0
  97. package/2D/controls/sliders/scrollBar.d.ts +50 -0
  98. package/2D/controls/sliders/scrollBar.js +175 -0
  99. package/2D/controls/sliders/scrollBar.js.map +1 -0
  100. package/2D/controls/sliders/slider.d.ts +46 -0
  101. package/2D/controls/sliders/slider.js +281 -0
  102. package/2D/controls/sliders/slider.js.map +1 -0
  103. package/2D/controls/stackPanel.d.ts +64 -0
  104. package/2D/controls/stackPanel.js +244 -0
  105. package/2D/controls/stackPanel.js.map +1 -0
  106. package/2D/controls/statics.d.ts +6 -0
  107. package/2D/controls/statics.js +50 -0
  108. package/2D/controls/statics.js.map +1 -0
  109. package/2D/controls/textBlock.d.ts +219 -0
  110. package/2D/controls/textBlock.js +670 -0
  111. package/2D/controls/textBlock.js.map +1 -0
  112. package/2D/controls/textWrapper.d.ts +13 -0
  113. package/2D/controls/textWrapper.js +88 -0
  114. package/2D/controls/textWrapper.js.map +1 -0
  115. package/2D/controls/toggleButton.d.ts +93 -0
  116. package/2D/controls/toggleButton.js +229 -0
  117. package/2D/controls/toggleButton.js.map +1 -0
  118. package/2D/controls/virtualKeyboard.d.ts +102 -0
  119. package/2D/controls/virtualKeyboard.js +275 -0
  120. package/2D/controls/virtualKeyboard.js.map +1 -0
  121. package/2D/index.d.ts +11 -0
  122. package/2D/index.js +13 -0
  123. package/2D/index.js.map +1 -0
  124. package/2D/math2D.d.ts +136 -0
  125. package/2D/math2D.js +235 -0
  126. package/2D/math2D.js.map +1 -0
  127. package/2D/measure.d.ts +77 -0
  128. package/2D/measure.js +138 -0
  129. package/2D/measure.js.map +1 -0
  130. package/2D/multiLinePoint.d.ts +47 -0
  131. package/2D/multiLinePoint.js +110 -0
  132. package/2D/multiLinePoint.js.map +1 -0
  133. package/2D/style.d.ts +46 -0
  134. package/2D/style.js +80 -0
  135. package/2D/style.js.map +1 -0
  136. package/2D/valueAndUnit.d.ts +89 -0
  137. package/2D/valueAndUnit.js +194 -0
  138. package/2D/valueAndUnit.js.map +1 -0
  139. package/2D/xmlLoader.d.ts +60 -0
  140. package/2D/xmlLoader.js +348 -0
  141. package/2D/xmlLoader.js.map +1 -0
  142. package/3D/behaviors/defaultBehavior.d.ts +73 -0
  143. package/3D/behaviors/defaultBehavior.js +103 -0
  144. package/3D/behaviors/defaultBehavior.js.map +1 -0
  145. package/3D/controls/MRTK3/touchHolographicButton.d.ts +220 -0
  146. package/3D/controls/MRTK3/touchHolographicButton.js +868 -0
  147. package/3D/controls/MRTK3/touchHolographicButton.js.map +1 -0
  148. package/3D/controls/abstractButton3D.d.ts +15 -0
  149. package/3D/controls/abstractButton3D.js +22 -0
  150. package/3D/controls/abstractButton3D.js.map +1 -0
  151. package/3D/controls/button3D.d.ts +51 -0
  152. package/3D/controls/button3D.js +98 -0
  153. package/3D/controls/button3D.js.map +1 -0
  154. package/3D/controls/container3D.d.ts +72 -0
  155. package/3D/controls/container3D.js +126 -0
  156. package/3D/controls/container3D.js.map +1 -0
  157. package/3D/controls/contentDisplay3D.d.ts +42 -0
  158. package/3D/controls/contentDisplay3D.js +81 -0
  159. package/3D/controls/contentDisplay3D.js.map +1 -0
  160. package/3D/controls/control3D.d.ts +183 -0
  161. package/3D/controls/control3D.js +401 -0
  162. package/3D/controls/control3D.js.map +1 -0
  163. package/3D/controls/cylinderPanel.d.ts +17 -0
  164. package/3D/controls/cylinderPanel.js +57 -0
  165. package/3D/controls/cylinderPanel.js.map +1 -0
  166. package/3D/controls/handMenu.d.ts +28 -0
  167. package/3D/controls/handMenu.js +39 -0
  168. package/3D/controls/handMenu.js.map +1 -0
  169. package/3D/controls/holographicBackplate.d.ts +49 -0
  170. package/3D/controls/holographicBackplate.js +104 -0
  171. package/3D/controls/holographicBackplate.js.map +1 -0
  172. package/3D/controls/holographicButton.d.ts +84 -0
  173. package/3D/controls/holographicButton.js +300 -0
  174. package/3D/controls/holographicButton.js.map +1 -0
  175. package/3D/controls/holographicSlate.d.ts +134 -0
  176. package/3D/controls/holographicSlate.js +413 -0
  177. package/3D/controls/holographicSlate.js.map +1 -0
  178. package/3D/controls/index.d.ts +22 -0
  179. package/3D/controls/index.js +24 -0
  180. package/3D/controls/index.js.map +1 -0
  181. package/3D/controls/meshButton3D.d.ts +21 -0
  182. package/3D/controls/meshButton3D.js +58 -0
  183. package/3D/controls/meshButton3D.js.map +1 -0
  184. package/3D/controls/nearMenu.d.ts +44 -0
  185. package/3D/controls/nearMenu.js +103 -0
  186. package/3D/controls/nearMenu.js.map +1 -0
  187. package/3D/controls/planePanel.d.ts +9 -0
  188. package/3D/controls/planePanel.js +30 -0
  189. package/3D/controls/planePanel.js.map +1 -0
  190. package/3D/controls/scatterPanel.d.ts +18 -0
  191. package/3D/controls/scatterPanel.js +98 -0
  192. package/3D/controls/scatterPanel.js.map +1 -0
  193. package/3D/controls/slider3D.d.ts +95 -0
  194. package/3D/controls/slider3D.js +256 -0
  195. package/3D/controls/slider3D.js.map +1 -0
  196. package/3D/controls/spherePanel.d.ts +17 -0
  197. package/3D/controls/spherePanel.js +58 -0
  198. package/3D/controls/spherePanel.js.map +1 -0
  199. package/3D/controls/stackPanel3D.d.ts +22 -0
  200. package/3D/controls/stackPanel3D.js +95 -0
  201. package/3D/controls/stackPanel3D.js.map +1 -0
  202. package/3D/controls/touchButton3D.d.ts +77 -0
  203. package/3D/controls/touchButton3D.js +205 -0
  204. package/3D/controls/touchButton3D.js.map +1 -0
  205. package/3D/controls/touchHolographicButton.d.ts +110 -0
  206. package/3D/controls/touchHolographicButton.js +400 -0
  207. package/3D/controls/touchHolographicButton.js.map +1 -0
  208. package/3D/controls/touchHolographicMenu.d.ts +61 -0
  209. package/3D/controls/touchHolographicMenu.js +139 -0
  210. package/3D/controls/touchHolographicMenu.js.map +1 -0
  211. package/3D/controls/touchMeshButton3D.d.ts +21 -0
  212. package/3D/controls/touchMeshButton3D.js +58 -0
  213. package/3D/controls/touchMeshButton3D.js.map +1 -0
  214. package/3D/controls/volumeBasedPanel.d.ts +53 -0
  215. package/3D/controls/volumeBasedPanel.js +158 -0
  216. package/3D/controls/volumeBasedPanel.js.map +1 -0
  217. package/3D/gizmos/gizmoHandle.d.ts +108 -0
  218. package/3D/gizmos/gizmoHandle.js +175 -0
  219. package/3D/gizmos/gizmoHandle.js.map +1 -0
  220. package/3D/gizmos/index.d.ts +2 -0
  221. package/3D/gizmos/index.js +3 -0
  222. package/3D/gizmos/index.js.map +1 -0
  223. package/3D/gizmos/slateGizmo.d.ts +57 -0
  224. package/3D/gizmos/slateGizmo.js +353 -0
  225. package/3D/gizmos/slateGizmo.js.map +1 -0
  226. package/3D/gui3DManager.d.ts +94 -0
  227. package/3D/gui3DManager.js +233 -0
  228. package/3D/gui3DManager.js.map +1 -0
  229. package/3D/index.d.ts +5 -0
  230. package/3D/index.js +7 -0
  231. package/3D/index.js.map +1 -0
  232. package/3D/materials/fluent/fluentMaterial.d.ts +91 -0
  233. package/3D/materials/fluent/fluentMaterial.js +286 -0
  234. package/3D/materials/fluent/fluentMaterial.js.map +1 -0
  235. package/3D/materials/fluent/index.d.ts +1 -0
  236. package/3D/materials/fluent/index.js +2 -0
  237. package/3D/materials/fluent/index.js.map +1 -0
  238. package/3D/materials/fluent/shaders/fluent.fragment.d.ts +5 -0
  239. package/3D/materials/fluent/shaders/fluent.fragment.js +41 -0
  240. package/3D/materials/fluent/shaders/fluent.fragment.js.map +1 -0
  241. package/3D/materials/fluent/shaders/fluent.vertex.d.ts +5 -0
  242. package/3D/materials/fluent/shaders/fluent.vertex.js +40 -0
  243. package/3D/materials/fluent/shaders/fluent.vertex.js.map +1 -0
  244. package/3D/materials/fluentBackplate/fluentBackplateMaterial.d.ts +155 -0
  245. package/3D/materials/fluentBackplate/fluentBackplateMaterial.js +466 -0
  246. package/3D/materials/fluentBackplate/fluentBackplateMaterial.js.map +1 -0
  247. package/3D/materials/fluentBackplate/index.d.ts +1 -0
  248. package/3D/materials/fluentBackplate/index.js +2 -0
  249. package/3D/materials/fluentBackplate/index.js.map +1 -0
  250. package/3D/materials/fluentBackplate/shaders/fluentBackplate.fragment.d.ts +5 -0
  251. package/3D/materials/fluentBackplate/shaders/fluentBackplate.fragment.js +60 -0
  252. package/3D/materials/fluentBackplate/shaders/fluentBackplate.fragment.js.map +1 -0
  253. package/3D/materials/fluentBackplate/shaders/fluentBackplate.vertex.d.ts +5 -0
  254. package/3D/materials/fluentBackplate/shaders/fluentBackplate.vertex.js +127 -0
  255. package/3D/materials/fluentBackplate/shaders/fluentBackplate.vertex.js.map +1 -0
  256. package/3D/materials/fluentButton/fluentButtonMaterial.d.ts +190 -0
  257. package/3D/materials/fluentButton/fluentButtonMaterial.js +536 -0
  258. package/3D/materials/fluentButton/fluentButtonMaterial.js.map +1 -0
  259. package/3D/materials/fluentButton/index.d.ts +1 -0
  260. package/3D/materials/fluentButton/index.js +2 -0
  261. package/3D/materials/fluentButton/index.js.map +1 -0
  262. package/3D/materials/fluentButton/shaders/fluentButton.fragment.d.ts +5 -0
  263. package/3D/materials/fluentButton/shaders/fluentButton.fragment.js +57 -0
  264. package/3D/materials/fluentButton/shaders/fluentButton.fragment.js.map +1 -0
  265. package/3D/materials/fluentButton/shaders/fluentButton.vertex.d.ts +5 -0
  266. package/3D/materials/fluentButton/shaders/fluentButton.vertex.js +162 -0
  267. package/3D/materials/fluentButton/shaders/fluentButton.vertex.js.map +1 -0
  268. package/3D/materials/fluentMaterial.d.ts +4 -0
  269. package/3D/materials/fluentMaterial.js +5 -0
  270. package/3D/materials/fluentMaterial.js.map +1 -0
  271. package/3D/materials/handle/handleMaterial.d.ts +68 -0
  272. package/3D/materials/handle/handleMaterial.js +114 -0
  273. package/3D/materials/handle/handleMaterial.js.map +1 -0
  274. package/3D/materials/handle/index.d.ts +1 -0
  275. package/3D/materials/handle/index.js +2 -0
  276. package/3D/materials/handle/index.js.map +1 -0
  277. package/3D/materials/handle/shaders/handle.fragment.d.ts +5 -0
  278. package/3D/materials/handle/shaders/handle.fragment.js +11 -0
  279. package/3D/materials/handle/shaders/handle.fragment.js.map +1 -0
  280. package/3D/materials/handle/shaders/handle.vertex.d.ts +5 -0
  281. package/3D/materials/handle/shaders/handle.vertex.js +11 -0
  282. package/3D/materials/handle/shaders/handle.vertex.js.map +1 -0
  283. package/3D/materials/index.d.ts +5 -0
  284. package/3D/materials/index.js +7 -0
  285. package/3D/materials/index.js.map +1 -0
  286. package/3D/materials/mrdl/index.d.ts +3 -0
  287. package/3D/materials/mrdl/index.js +4 -0
  288. package/3D/materials/mrdl/index.js.map +1 -0
  289. package/3D/materials/mrdl/mrdlBackglowMaterial.d.ts +87 -0
  290. package/3D/materials/mrdl/mrdlBackglowMaterial.js +302 -0
  291. package/3D/materials/mrdl/mrdlBackglowMaterial.js.map +1 -0
  292. package/3D/materials/mrdl/mrdlBackplateMaterial.d.ts +148 -0
  293. package/3D/materials/mrdl/mrdlBackplateMaterial.js +433 -0
  294. package/3D/materials/mrdl/mrdlBackplateMaterial.js.map +1 -0
  295. package/3D/materials/mrdl/mrdlFrontplateMaterial.d.ts +186 -0
  296. package/3D/materials/mrdl/mrdlFrontplateMaterial.js +532 -0
  297. package/3D/materials/mrdl/mrdlFrontplateMaterial.js.map +1 -0
  298. package/3D/materials/mrdl/mrdlInnerquadMaterial.d.ts +56 -0
  299. package/3D/materials/mrdl/mrdlInnerquadMaterial.js +230 -0
  300. package/3D/materials/mrdl/mrdlInnerquadMaterial.js.map +1 -0
  301. package/3D/materials/mrdl/mrdlSliderBarMaterial.d.ts +337 -0
  302. package/3D/materials/mrdl/mrdlSliderBarMaterial.js +855 -0
  303. package/3D/materials/mrdl/mrdlSliderBarMaterial.js.map +1 -0
  304. package/3D/materials/mrdl/mrdlSliderThumbMaterial.d.ts +337 -0
  305. package/3D/materials/mrdl/mrdlSliderThumbMaterial.js +855 -0
  306. package/3D/materials/mrdl/mrdlSliderThumbMaterial.js.map +1 -0
  307. package/3D/materials/mrdl/shaders/mrdlBackglow.fragment.d.ts +5 -0
  308. package/3D/materials/mrdl/shaders/mrdlBackglow.fragment.js +25 -0
  309. package/3D/materials/mrdl/shaders/mrdlBackglow.fragment.js.map +1 -0
  310. package/3D/materials/mrdl/shaders/mrdlBackglow.vertex.d.ts +5 -0
  311. package/3D/materials/mrdl/shaders/mrdlBackglow.vertex.js +12 -0
  312. package/3D/materials/mrdl/shaders/mrdlBackglow.vertex.js.map +1 -0
  313. package/3D/materials/mrdl/shaders/mrdlBackplate.fragment.d.ts +5 -0
  314. package/3D/materials/mrdl/shaders/mrdlBackplate.fragment.js +88 -0
  315. package/3D/materials/mrdl/shaders/mrdlBackplate.fragment.js.map +1 -0
  316. package/3D/materials/mrdl/shaders/mrdlBackplate.vertex.d.ts +5 -0
  317. package/3D/materials/mrdl/shaders/mrdlBackplate.vertex.js +96 -0
  318. package/3D/materials/mrdl/shaders/mrdlBackplate.vertex.js.map +1 -0
  319. package/3D/materials/mrdl/shaders/mrdlFrontplate.fragment.d.ts +5 -0
  320. package/3D/materials/mrdl/shaders/mrdlFrontplate.fragment.js +48 -0
  321. package/3D/materials/mrdl/shaders/mrdlFrontplate.fragment.js.map +1 -0
  322. package/3D/materials/mrdl/shaders/mrdlFrontplate.vertex.d.ts +5 -0
  323. package/3D/materials/mrdl/shaders/mrdlFrontplate.vertex.js +158 -0
  324. package/3D/materials/mrdl/shaders/mrdlFrontplate.vertex.js.map +1 -0
  325. package/3D/materials/mrdl/shaders/mrdlInnerquad.fragment.d.ts +5 -0
  326. package/3D/materials/mrdl/shaders/mrdlInnerquad.fragment.js +27 -0
  327. package/3D/materials/mrdl/shaders/mrdlInnerquad.fragment.js.map +1 -0
  328. package/3D/materials/mrdl/shaders/mrdlInnerquad.vertex.d.ts +5 -0
  329. package/3D/materials/mrdl/shaders/mrdlInnerquad.vertex.js +13 -0
  330. package/3D/materials/mrdl/shaders/mrdlInnerquad.vertex.js.map +1 -0
  331. package/3D/materials/mrdl/shaders/mrdlSliderBar.fragment.d.ts +5 -0
  332. package/3D/materials/mrdl/shaders/mrdlSliderBar.fragment.js +236 -0
  333. package/3D/materials/mrdl/shaders/mrdlSliderBar.fragment.js.map +1 -0
  334. package/3D/materials/mrdl/shaders/mrdlSliderBar.vertex.d.ts +5 -0
  335. package/3D/materials/mrdl/shaders/mrdlSliderBar.vertex.js +137 -0
  336. package/3D/materials/mrdl/shaders/mrdlSliderBar.vertex.js.map +1 -0
  337. package/3D/materials/mrdl/shaders/mrdlSliderThumb.fragment.d.ts +5 -0
  338. package/3D/materials/mrdl/shaders/mrdlSliderThumb.fragment.js +236 -0
  339. package/3D/materials/mrdl/shaders/mrdlSliderThumb.fragment.js.map +1 -0
  340. package/3D/materials/mrdl/shaders/mrdlSliderThumb.vertex.d.ts +5 -0
  341. package/3D/materials/mrdl/shaders/mrdlSliderThumb.vertex.js +137 -0
  342. package/3D/materials/mrdl/shaders/mrdlSliderThumb.vertex.js.map +1 -0
  343. package/3D/vector3WithInfo.d.ts +16 -0
  344. package/3D/vector3WithInfo.js +18 -0
  345. package/3D/vector3WithInfo.js.map +1 -0
  346. package/index.d.ts +2 -0
  347. package/index.js +4 -0
  348. package/index.js.map +1 -0
  349. package/legacy/legacy.d.ts +1 -0
  350. package/legacy/legacy.js +17 -0
  351. package/legacy/legacy.js.map +1 -0
  352. package/license.md +71 -0
  353. package/package.json +47 -0
  354. package/readme.md +31 -0
@@ -0,0 +1,1522 @@
1
+ import { Observable } from "@babylonjs/core/Misc/observable.js";
2
+ import { Vector2, Vector3, TmpVectors } from "@babylonjs/core/Maths/math.vector.js";
3
+ import { Tools } from "@babylonjs/core/Misc/tools.js";
4
+ import { PointerEventTypes } from "@babylonjs/core/Events/pointerEvents.js";
5
+ import { ClipboardEventTypes, ClipboardInfo } from "@babylonjs/core/Events/clipboardEvents.js";
6
+ import { KeyboardEventTypes } from "@babylonjs/core/Events/keyboardEvents.js";
7
+ import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
8
+ import { DynamicTexture } from "@babylonjs/core/Materials/Textures/dynamicTexture.js";
9
+ import { Layer } from "@babylonjs/core/Layers/layer.js";
10
+ import { Container } from "./controls/container.js";
11
+ import { Control } from "./controls/control.js";
12
+ import { Style } from "./style.js";
13
+ import { Measure } from "./measure.js";
14
+ import { Constants } from "@babylonjs/core/Engines/constants.js";
15
+ import { Viewport } from "@babylonjs/core/Maths/math.viewport.js";
16
+ import { Color3 } from "@babylonjs/core/Maths/math.color.js";
17
+ import { WebRequest } from "@babylonjs/core/Misc/webRequest.js";
18
+ import { RandomGUID } from "@babylonjs/core/Misc/guid.js";
19
+ import { GetClass } from "@babylonjs/core/Misc/typeStore.js";
20
+ import { DecodeBase64ToBinary } from "@babylonjs/core/Misc/stringTools.js";
21
+ /**
22
+ * Class used to create texture to support 2D GUI elements
23
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui
24
+ */
25
+ export class AdvancedDynamicTexture extends DynamicTexture {
26
+ /** Gets the number of layout calls made the last time the ADT has been rendered */
27
+ get numLayoutCalls() {
28
+ return this._numLayoutCalls;
29
+ }
30
+ /** Gets the number of render calls made the last time the ADT has been rendered */
31
+ get numRenderCalls() {
32
+ return this._numRenderCalls;
33
+ }
34
+ /**
35
+ * If set to true, the renderScale will be adjusted automatically to the engine's hardware scaling
36
+ * If this is set to true, manually setting the renderScale will be ignored
37
+ * This is useful when the engine's hardware scaling is set to a value other than 1
38
+ */
39
+ get adjustToEngineHardwareScalingLevel() {
40
+ return this._adjustToEngineHardwareScalingLevel;
41
+ }
42
+ set adjustToEngineHardwareScalingLevel(value) {
43
+ if (this._adjustToEngineHardwareScalingLevel === value) {
44
+ return;
45
+ }
46
+ this._adjustToEngineHardwareScalingLevel = value;
47
+ this._onResize();
48
+ }
49
+ /**
50
+ * Gets or sets a number used to scale rendering size (2 means that the texture will be twice bigger).
51
+ * Useful when you want more antialiasing
52
+ */
53
+ get renderScale() {
54
+ return this._renderScale;
55
+ }
56
+ set renderScale(value) {
57
+ if (value === this._renderScale) {
58
+ return;
59
+ }
60
+ this._renderScale = value;
61
+ this._onResize();
62
+ }
63
+ /** Gets or sets the background color */
64
+ get background() {
65
+ return this._background;
66
+ }
67
+ set background(value) {
68
+ if (this._background === value) {
69
+ return;
70
+ }
71
+ this._background = value;
72
+ this.markAsDirty();
73
+ }
74
+ /**
75
+ * Gets or sets the ideal width used to design controls.
76
+ * The GUI will then rescale everything accordingly
77
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#adaptive-scaling
78
+ */
79
+ get idealWidth() {
80
+ return this._idealWidth;
81
+ }
82
+ set idealWidth(value) {
83
+ if (this._idealWidth === value) {
84
+ return;
85
+ }
86
+ this._idealWidth = value;
87
+ this.markAsDirty();
88
+ this._rootContainer._markAllAsDirty();
89
+ }
90
+ /**
91
+ * Gets or sets the ideal height used to design controls.
92
+ * The GUI will then rescale everything accordingly
93
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#adaptive-scaling
94
+ */
95
+ get idealHeight() {
96
+ return this._idealHeight;
97
+ }
98
+ set idealHeight(value) {
99
+ if (this._idealHeight === value) {
100
+ return;
101
+ }
102
+ this._idealHeight = value;
103
+ this.markAsDirty();
104
+ this._rootContainer._markAllAsDirty();
105
+ }
106
+ /**
107
+ * Gets or sets a boolean indicating if the smallest ideal value must be used if idealWidth and idealHeight are both set
108
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#adaptive-scaling
109
+ */
110
+ get useSmallestIdeal() {
111
+ return this._useSmallestIdeal;
112
+ }
113
+ set useSmallestIdeal(value) {
114
+ if (this._useSmallestIdeal === value) {
115
+ return;
116
+ }
117
+ this._useSmallestIdeal = value;
118
+ this.markAsDirty();
119
+ this._rootContainer._markAllAsDirty();
120
+ }
121
+ /**
122
+ * Gets or sets a boolean indicating if adaptive scaling must be used
123
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#adaptive-scaling
124
+ */
125
+ get renderAtIdealSize() {
126
+ return this._renderAtIdealSize;
127
+ }
128
+ set renderAtIdealSize(value) {
129
+ if (this._renderAtIdealSize === value) {
130
+ return;
131
+ }
132
+ this._renderAtIdealSize = value;
133
+ this._onResize();
134
+ }
135
+ /**
136
+ * Gets the ratio used when in "ideal mode"
137
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#adaptive-scaling
138
+ * */
139
+ get idealRatio() {
140
+ let rwidth = 0;
141
+ let rheight = 0;
142
+ if (this._idealWidth) {
143
+ rwidth = this.getSize().width / this._idealWidth;
144
+ }
145
+ if (this._idealHeight) {
146
+ rheight = this.getSize().height / this._idealHeight;
147
+ }
148
+ if (this._useSmallestIdeal && this._idealWidth && this._idealHeight) {
149
+ return window.innerWidth < window.innerHeight ? rwidth : rheight;
150
+ }
151
+ if (this._idealWidth) {
152
+ // horizontal
153
+ return rwidth;
154
+ }
155
+ if (this._idealHeight) {
156
+ // vertical
157
+ return rheight;
158
+ }
159
+ return 1;
160
+ }
161
+ /**
162
+ * Gets the underlying layer used to render the texture when in fullscreen mode
163
+ */
164
+ get layer() {
165
+ return this._layerToDispose;
166
+ }
167
+ /**
168
+ * Gets the root container control
169
+ */
170
+ get rootContainer() {
171
+ return this._rootContainer;
172
+ }
173
+ /**
174
+ * Returns an array containing the root container.
175
+ * This is mostly used to let the Inspector introspects the ADT
176
+ * @returns an array containing the rootContainer
177
+ */
178
+ getChildren() {
179
+ return [this._rootContainer];
180
+ }
181
+ /**
182
+ * Will return all controls that are inside this texture
183
+ * @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
184
+ * @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
185
+ * @returns all child controls
186
+ */
187
+ getDescendants(directDescendantsOnly, predicate) {
188
+ return this._rootContainer.getDescendants(directDescendantsOnly, predicate);
189
+ }
190
+ /**
191
+ * Will return all controls with the given type name
192
+ * @param typeName defines the type name to search for
193
+ * @returns an array of all controls found
194
+ */
195
+ getControlsByType(typeName) {
196
+ return this._rootContainer.getDescendants(false, (control) => control.typeName === typeName);
197
+ }
198
+ /**
199
+ * Will return the first control with the given name
200
+ * @param name defines the name to search for
201
+ * @returns the first control found or null
202
+ */
203
+ getControlByName(name) {
204
+ return this._getControlByKey("name", name);
205
+ }
206
+ _getControlByKey(key, value) {
207
+ return this._rootContainer.getDescendants().find((control) => control[key] === value) || null;
208
+ }
209
+ /**
210
+ * Gets or sets the current focused control
211
+ */
212
+ get focusedControl() {
213
+ return this._focusedControl;
214
+ }
215
+ set focusedControl(control) {
216
+ if (this._focusedControl == control) {
217
+ return;
218
+ }
219
+ if (this._focusedControl) {
220
+ this._focusedControl.onBlur();
221
+ }
222
+ if (control) {
223
+ control.onFocus();
224
+ }
225
+ this._focusedControl = control;
226
+ }
227
+ /**
228
+ * Gets or sets a boolean indicating if the texture must be rendered in background or foreground when in fullscreen mode
229
+ */
230
+ get isForeground() {
231
+ if (!this.layer) {
232
+ return true;
233
+ }
234
+ return !this.layer.isBackground;
235
+ }
236
+ set isForeground(value) {
237
+ if (!this.layer) {
238
+ return;
239
+ }
240
+ if (this.layer.isBackground === !value) {
241
+ return;
242
+ }
243
+ this.layer.isBackground = !value;
244
+ }
245
+ /**
246
+ * Gets or set information about clipboardData
247
+ */
248
+ get clipboardData() {
249
+ return this._clipboardData;
250
+ }
251
+ set clipboardData(value) {
252
+ this._clipboardData = value;
253
+ }
254
+ /** @internal */
255
+ constructor(name, widthOrOptions, _height = 0, scene, generateMipMaps = false, samplingMode = Texture.NEAREST_SAMPLINGMODE, invertY = true) {
256
+ widthOrOptions = widthOrOptions ?? 0;
257
+ const width = typeof widthOrOptions === "object" && widthOrOptions !== undefined ? (widthOrOptions.width ?? 0) : (widthOrOptions ?? 0);
258
+ const height = typeof widthOrOptions === "object" && widthOrOptions !== undefined ? (widthOrOptions.height ?? 0) : _height;
259
+ super(name, { width, height }, typeof widthOrOptions === "object" && widthOrOptions !== undefined ? widthOrOptions : scene, generateMipMaps, samplingMode, Constants.TEXTUREFORMAT_RGBA, invertY);
260
+ /** Indicates whether the ADT is used autonomously */
261
+ this.useStandalone = false;
262
+ /** Observable that fires when the GUI is ready */
263
+ this.onGuiReadyObservable = new Observable();
264
+ this._isDirty = false;
265
+ /** @internal */
266
+ this._rootContainer = new Container("root");
267
+ /** @internal */
268
+ this._lastControlOver = {};
269
+ /** @internal */
270
+ this._lastControlDown = {};
271
+ /** @internal */
272
+ this._capturingControl = {};
273
+ /** @internal */
274
+ this._linkedControls = new Array();
275
+ /** @internal */
276
+ this._isFullscreen = false;
277
+ this._fullscreenViewport = new Viewport(0, 0, 1, 1);
278
+ this._idealWidth = 0;
279
+ this._idealHeight = 0;
280
+ this._useSmallestIdeal = false;
281
+ this._renderAtIdealSize = false;
282
+ this._blockNextFocusCheck = false;
283
+ this._renderScale = 1;
284
+ this._cursorChanged = false;
285
+ this._defaultMousePointerId = 0;
286
+ this._rootChildrenHaveChanged = false;
287
+ this._adjustToEngineHardwareScalingLevel = false;
288
+ /** @internal */
289
+ this._capturedPointerIds = new Set();
290
+ /** @internal */
291
+ this._numLayoutCalls = 0;
292
+ /** @internal */
293
+ this._numRenderCalls = 0;
294
+ /**
295
+ * Define type to string to ensure compatibility across browsers
296
+ * Safari doesn't support DataTransfer constructor
297
+ */
298
+ this._clipboardData = "";
299
+ /**
300
+ * Observable event triggered each time an clipboard event is received from the rendering canvas
301
+ */
302
+ this.onClipboardObservable = new Observable();
303
+ /**
304
+ * Observable event triggered each time a pointer down is intercepted by a control
305
+ */
306
+ this.onControlPickedObservable = new Observable();
307
+ /**
308
+ * Observable event triggered before layout is evaluated
309
+ */
310
+ this.onBeginLayoutObservable = new Observable();
311
+ /**
312
+ * Observable event triggered after the layout was evaluated
313
+ */
314
+ this.onEndLayoutObservable = new Observable();
315
+ /**
316
+ * Observable event triggered before the texture is rendered
317
+ */
318
+ this.onBeginRenderObservable = new Observable();
319
+ /**
320
+ * Observable event triggered after the texture was rendered
321
+ */
322
+ this.onEndRenderObservable = new Observable();
323
+ /**
324
+ * Gets or sets a boolean defining if alpha is stored as premultiplied
325
+ */
326
+ this.premulAlpha = false;
327
+ /**
328
+ * Gets or sets a boolean indicating that the canvas must be reverted on Y when updating the texture
329
+ */
330
+ // eslint-disable-next-line @typescript-eslint/naming-convention
331
+ this.applyYInversionOnUpdate = true;
332
+ /**
333
+ * A boolean indicating whether or not the elements can be navigated to using the tab key.
334
+ * Defaults to false.
335
+ */
336
+ this.disableTabNavigation = false;
337
+ /**
338
+ * A boolean indicating whether controls can be picked/clicked on or not. Defaults to false.
339
+ */
340
+ this.disablePicking = false;
341
+ /**
342
+ * If set to true, the POINTERTAP event type will be used for "click", instead of POINTERUP
343
+ */
344
+ this.usePointerTapForClickEvent = false;
345
+ /**
346
+ * If this is set, even when a control is pointer blocker, some events can still be passed through to the scene.
347
+ * Options from values are PointerEventTypes
348
+ * POINTERDOWN, POINTERUP, POINTERMOVE, POINTERWHEEL, POINTERPICK, POINTERTAP, POINTERDOUBLETAP
349
+ */
350
+ this.skipBlockEvents = 0;
351
+ /**
352
+ * If set to true, every scene render will trigger a pointer event for the GUI
353
+ * if it is linked to a mesh or has controls linked to a mesh. This will allow
354
+ * you to catch the pointer moving around the GUI due to camera or mesh movements,
355
+ * but it has a performance cost.
356
+ */
357
+ this.checkPointerEveryFrame = false;
358
+ this._useInvalidateRectOptimization = true;
359
+ // Invalidated rectangle which is the combination of all invalidated controls after they have been rotated into absolute position
360
+ this._invalidatedRectangle = null;
361
+ this._alreadyRegisteredForRender = false;
362
+ this._clearMeasure = new Measure(0, 0, 0, 0);
363
+ this._focusProperties = { index: 0, total: -1 };
364
+ /**
365
+ * @internal
366
+ */
367
+ this._onClipboardCopy = (rawEvt) => {
368
+ const evt = rawEvt;
369
+ const ev = new ClipboardInfo(ClipboardEventTypes.COPY, evt);
370
+ this.onClipboardObservable.notifyObservers(ev);
371
+ evt.preventDefault();
372
+ };
373
+ /**
374
+ * @internal
375
+ */
376
+ this._onClipboardCut = (rawEvt) => {
377
+ const evt = rawEvt;
378
+ const ev = new ClipboardInfo(ClipboardEventTypes.CUT, evt);
379
+ this.onClipboardObservable.notifyObservers(ev);
380
+ evt.preventDefault();
381
+ };
382
+ /**
383
+ * @internal
384
+ */
385
+ this._onClipboardPaste = (rawEvt) => {
386
+ const evt = rawEvt;
387
+ const ev = new ClipboardInfo(ClipboardEventTypes.PASTE, evt);
388
+ this.onClipboardObservable.notifyObservers(ev);
389
+ evt.preventDefault();
390
+ };
391
+ /**
392
+ * Recreate the content of the ADT from a JSON object
393
+ * @param serializedObject define the JSON serialized object to restore from
394
+ * @param scaleToSize defines whether to scale to texture to the saved size
395
+ * @param urlRewriter defines an url rewriter to update urls before sending them to the controls
396
+ * @deprecated Please use parseSerializedObject instead
397
+ */
398
+ this.parseContent = this.parseSerializedObject;
399
+ scene = this.getScene();
400
+ if (!scene || !this._texture) {
401
+ return;
402
+ }
403
+ this.applyYInversionOnUpdate = invertY;
404
+ this._rootElement = scene.getEngine().getInputElement();
405
+ const adtOptions = widthOrOptions;
406
+ this.useStandalone = !!adtOptions?.useStandalone;
407
+ if (!this.useStandalone) {
408
+ this._renderObserver = scene.onBeforeCameraRenderObservable.add((camera) => this._checkUpdate(camera));
409
+ }
410
+ /** Whenever a control is added or removed to the root, we have to recheck the camera projection as it can have changed */
411
+ this._controlAddedObserver = this._rootContainer.onControlAddedObservable.add((control) => {
412
+ if (control) {
413
+ this._rootChildrenHaveChanged = true;
414
+ }
415
+ });
416
+ this._controlRemovedObserver = this._rootContainer.onControlRemovedObservable.add((control) => {
417
+ if (control) {
418
+ this._rootChildrenHaveChanged = true;
419
+ }
420
+ });
421
+ this._preKeyboardObserver = scene.onPreKeyboardObservable.add((info) => {
422
+ // check if tab is pressed
423
+ if (!this.disableTabNavigation && info.type === KeyboardEventTypes.KEYDOWN && info.event.code === "Tab") {
424
+ const forward = !info.event.shiftKey;
425
+ if ((forward && this._focusProperties.index === this._focusProperties.total - 1) ||
426
+ (!forward && this._focusProperties.index === 0 && this._focusProperties.total > 0)) {
427
+ this.focusedControl = null;
428
+ this._focusProperties.index = 0;
429
+ this._focusProperties.total = -1;
430
+ return;
431
+ }
432
+ this._focusNextElement(forward);
433
+ info.event.preventDefault();
434
+ return;
435
+ }
436
+ if (!this._focusedControl) {
437
+ return;
438
+ }
439
+ if (info.type === KeyboardEventTypes.KEYDOWN) {
440
+ this._focusedControl.processKeyboard(info.event);
441
+ }
442
+ info.skipOnPointerObservable = true;
443
+ });
444
+ this._rootContainer._link(this);
445
+ this.hasAlpha = true;
446
+ if (!width || !height) {
447
+ this._resizeObserver = scene.getEngine().onResizeObservable.add(() => this._onResize());
448
+ this._onResize();
449
+ }
450
+ this._texture.isReady = true;
451
+ }
452
+ /**
453
+ * Get the current class name of the texture useful for serialization or dynamic coding.
454
+ * @returns "AdvancedDynamicTexture"
455
+ */
456
+ getClassName() {
457
+ return "AdvancedDynamicTexture";
458
+ }
459
+ /**
460
+ * Function used to execute a function on all controls
461
+ * @param func defines the function to execute
462
+ * @param container defines the container where controls belong. If null the root container will be used
463
+ */
464
+ executeOnAllControls(func, container) {
465
+ if (!container) {
466
+ container = this._rootContainer;
467
+ }
468
+ func(container);
469
+ for (const child of container.children) {
470
+ if (child.children) {
471
+ this.executeOnAllControls(func, child);
472
+ continue;
473
+ }
474
+ func(child);
475
+ }
476
+ }
477
+ /**
478
+ * Gets or sets a boolean indicating if the InvalidateRect optimization should be turned on
479
+ */
480
+ get useInvalidateRectOptimization() {
481
+ return this._useInvalidateRectOptimization;
482
+ }
483
+ set useInvalidateRectOptimization(value) {
484
+ this._useInvalidateRectOptimization = value;
485
+ }
486
+ /**
487
+ * Invalidates a rectangle area on the gui texture
488
+ * @param invalidMinX left most position of the rectangle to invalidate in the texture
489
+ * @param invalidMinY top most position of the rectangle to invalidate in the texture
490
+ * @param invalidMaxX right most position of the rectangle to invalidate in the texture
491
+ * @param invalidMaxY bottom most position of the rectangle to invalidate in the texture
492
+ */
493
+ invalidateRect(invalidMinX, invalidMinY, invalidMaxX, invalidMaxY) {
494
+ if (!this._useInvalidateRectOptimization) {
495
+ return;
496
+ }
497
+ if (!this._invalidatedRectangle) {
498
+ this._invalidatedRectangle = new Measure(invalidMinX, invalidMinY, invalidMaxX - invalidMinX + 1, invalidMaxY - invalidMinY + 1);
499
+ }
500
+ else {
501
+ // Compute intersection
502
+ const maxX = Math.ceil(Math.max(this._invalidatedRectangle.left + this._invalidatedRectangle.width - 1, invalidMaxX));
503
+ const maxY = Math.ceil(Math.max(this._invalidatedRectangle.top + this._invalidatedRectangle.height - 1, invalidMaxY));
504
+ this._invalidatedRectangle.left = Math.floor(Math.min(this._invalidatedRectangle.left, invalidMinX));
505
+ this._invalidatedRectangle.top = Math.floor(Math.min(this._invalidatedRectangle.top, invalidMinY));
506
+ this._invalidatedRectangle.width = maxX - this._invalidatedRectangle.left + 1;
507
+ this._invalidatedRectangle.height = maxY - this._invalidatedRectangle.top + 1;
508
+ }
509
+ }
510
+ /**
511
+ * Marks the texture as dirty forcing a complete update
512
+ */
513
+ markAsDirty() {
514
+ this._isDirty = true;
515
+ }
516
+ /**
517
+ * Helper function used to create a new style
518
+ * @returns a new style
519
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#styles
520
+ */
521
+ createStyle() {
522
+ return new Style(this);
523
+ }
524
+ /**
525
+ * Adds a new control to the root container
526
+ * @param control defines the control to add
527
+ * @returns the current texture
528
+ */
529
+ addControl(control) {
530
+ this._rootContainer.addControl(control);
531
+ return this;
532
+ }
533
+ /**
534
+ * Removes a control from the root container
535
+ * @param control defines the control to remove
536
+ * @returns the current texture
537
+ */
538
+ removeControl(control) {
539
+ this._rootContainer.removeControl(control);
540
+ return this;
541
+ }
542
+ /**
543
+ * Moves overlapped controls towards a position where it is not overlapping anymore.
544
+ * Please note that this method alters linkOffsetXInPixels and linkOffsetYInPixels.
545
+ * @param overlapGroup the overlap group which will be processed or undefined to process all overlap groups
546
+ * @param deltaStep the step size (speed) to reach the target non overlapping position (default 0.1)
547
+ * @param repelFactor how much is the control repelled by other controls
548
+ */
549
+ moveToNonOverlappedPosition(overlapGroup, deltaStep = 1, repelFactor = 1) {
550
+ let controlsForGroup;
551
+ if (Array.isArray(overlapGroup)) {
552
+ controlsForGroup = overlapGroup;
553
+ }
554
+ else {
555
+ const descendants = this.getDescendants(true);
556
+ // get only the controls with an overlapGroup property set
557
+ // if the overlapGroup parameter is set, filter the controls and get only the controls belonging to that overlapGroup
558
+ controlsForGroup = overlapGroup === undefined ? descendants.filter((c) => c.overlapGroup !== undefined) : descendants.filter((c) => c.overlapGroup === overlapGroup);
559
+ }
560
+ for (const control1 of controlsForGroup) {
561
+ let velocity = Vector2.Zero();
562
+ const center = new Vector2(control1.centerX, control1.centerY);
563
+ for (const control2 of controlsForGroup) {
564
+ if (control1 !== control2 && AdvancedDynamicTexture._Overlaps(control1, control2)) {
565
+ // if the two controls overlaps get a direction vector from one control's center to another control's center
566
+ const diff = center.subtract(new Vector2(control2.centerX, control2.centerY));
567
+ const diffLength = diff.length();
568
+ if (diffLength > 0) {
569
+ // calculate the velocity
570
+ velocity = velocity.add(diff.normalize().scale(repelFactor / diffLength));
571
+ }
572
+ }
573
+ }
574
+ if (velocity.length() > 0) {
575
+ // move the control along the direction vector away from the overlapping control
576
+ velocity = velocity.normalize().scale(deltaStep * (control1.overlapDeltaMultiplier ?? 1));
577
+ control1.linkOffsetXInPixels += velocity.x;
578
+ control1.linkOffsetYInPixels += velocity.y;
579
+ }
580
+ }
581
+ }
582
+ /**
583
+ * Release all resources
584
+ */
585
+ dispose() {
586
+ const scene = this.getScene();
587
+ if (!scene) {
588
+ return;
589
+ }
590
+ this._rootElement = null;
591
+ scene.onBeforeCameraRenderObservable.remove(this._renderObserver);
592
+ if (this._resizeObserver) {
593
+ scene.getEngine().onResizeObservable.remove(this._resizeObserver);
594
+ }
595
+ if (this._prePointerObserver) {
596
+ scene.onPrePointerObservable.remove(this._prePointerObserver);
597
+ }
598
+ if (this._sceneRenderObserver) {
599
+ scene.onBeforeRenderObservable.remove(this._sceneRenderObserver);
600
+ }
601
+ if (this._pointerObserver) {
602
+ scene.onPointerObservable.remove(this._pointerObserver);
603
+ }
604
+ if (this._preKeyboardObserver) {
605
+ scene.onPreKeyboardObservable.remove(this._preKeyboardObserver);
606
+ }
607
+ if (this._canvasPointerOutObserver) {
608
+ scene.getEngine().onCanvasPointerOutObservable.remove(this._canvasPointerOutObserver);
609
+ }
610
+ if (this._canvasBlurObserver) {
611
+ scene.getEngine().onCanvasBlurObservable.remove(this._canvasBlurObserver);
612
+ }
613
+ if (this._controlAddedObserver) {
614
+ this._rootContainer.onControlAddedObservable.remove(this._controlAddedObserver);
615
+ }
616
+ if (this._controlRemovedObserver) {
617
+ this._rootContainer.onControlRemovedObservable.remove(this._controlRemovedObserver);
618
+ }
619
+ if (this._layerToDispose) {
620
+ this._layerToDispose.texture = null;
621
+ this._layerToDispose.dispose();
622
+ this._layerToDispose = null;
623
+ }
624
+ this._rootContainer.dispose();
625
+ this.onClipboardObservable.clear();
626
+ this.onControlPickedObservable.clear();
627
+ this.onBeginRenderObservable.clear();
628
+ this.onEndRenderObservable.clear();
629
+ this.onBeginLayoutObservable.clear();
630
+ this.onEndLayoutObservable.clear();
631
+ this.onGuiReadyObservable.clear();
632
+ super.dispose();
633
+ }
634
+ _onResize() {
635
+ const scene = this.getScene();
636
+ if (!scene) {
637
+ return;
638
+ }
639
+ // Check size
640
+ const engine = scene.getEngine();
641
+ if (this.adjustToEngineHardwareScalingLevel) {
642
+ // force the renderScale to the engine's hardware scaling level
643
+ this._renderScale = engine.getHardwareScalingLevel();
644
+ // calculate the max renderScale, based on the max texture size of engine.getCaps().maxTextureSize (enforced by some mobile devices)
645
+ this._renderScale =
646
+ 1 / Math.max(this._renderScale, engine.getRenderWidth() / engine.getCaps().maxTextureSize, engine.getRenderHeight() / engine.getCaps().maxTextureSize);
647
+ }
648
+ const textureSize = this.getSize();
649
+ let renderWidth = engine.getRenderWidth() * this._renderScale;
650
+ let renderHeight = engine.getRenderHeight() * this._renderScale;
651
+ if (this._renderAtIdealSize) {
652
+ if (this._idealWidth) {
653
+ renderHeight = (renderHeight * this._idealWidth) / renderWidth;
654
+ renderWidth = this._idealWidth;
655
+ }
656
+ else if (this._idealHeight) {
657
+ renderWidth = (renderWidth * this._idealHeight) / renderHeight;
658
+ renderHeight = this._idealHeight;
659
+ }
660
+ }
661
+ if (textureSize.width !== renderWidth || textureSize.height !== renderHeight) {
662
+ this.scaleTo(renderWidth, renderHeight);
663
+ if (this.adjustToEngineHardwareScalingLevel) {
664
+ const engineRenderScale = 1 / engine.getHardwareScalingLevel();
665
+ const scale = this._renderScale * engineRenderScale;
666
+ this._rootContainer.scaleX = scale;
667
+ this._rootContainer.scaleY = scale;
668
+ this._rootContainer.widthInPixels = renderWidth / scale;
669
+ this._rootContainer.heightInPixels = renderHeight / scale;
670
+ }
671
+ this.markAsDirty();
672
+ if (this._idealWidth || this._idealHeight) {
673
+ this._rootContainer._markAllAsDirty();
674
+ }
675
+ if (!this._alreadyRegisteredForRender) {
676
+ this._alreadyRegisteredForRender = true;
677
+ Tools.SetImmediate(() => {
678
+ // We want to force an update so the texture can be set as ready
679
+ this.update(this.applyYInversionOnUpdate, this.premulAlpha, AdvancedDynamicTexture.AllowGPUOptimizations);
680
+ this._alreadyRegisteredForRender = false;
681
+ });
682
+ }
683
+ }
684
+ this.invalidateRect(0, 0, textureSize.width - 1, textureSize.height - 1);
685
+ }
686
+ /** @internal */
687
+ _getGlobalViewport() {
688
+ const size = this.getSize();
689
+ const globalViewPort = this._fullscreenViewport.toGlobal(size.width, size.height);
690
+ const targetX = Math.round(globalViewPort.width / this._rootContainer.scaleX);
691
+ const targetY = Math.round(globalViewPort.height / this._rootContainer.scaleY);
692
+ const scale = this._adjustToEngineHardwareScalingLevel ? this._renderScale / (this.getScene()?.getEngine().getHardwareScalingLevel() || 1) : 1;
693
+ globalViewPort.x += (globalViewPort.width / scale - targetX) / 2;
694
+ globalViewPort.y += (globalViewPort.height / scale - targetY) / 2;
695
+ globalViewPort.width = targetX;
696
+ globalViewPort.height = targetY;
697
+ return globalViewPort;
698
+ }
699
+ /**
700
+ * Get screen coordinates for a vector3
701
+ * @param position defines the position to project
702
+ * @param worldMatrix defines the world matrix to use
703
+ * @returns the projected position
704
+ */
705
+ getProjectedPosition(position, worldMatrix) {
706
+ const result = this.getProjectedPositionWithZ(position, worldMatrix);
707
+ return new Vector2(result.x, result.y);
708
+ }
709
+ /**
710
+ * Get screen coordinates for a vector3
711
+ * @param position defines the position to project
712
+ * @param worldMatrix defines the world matrix to use
713
+ * @returns the projected position with Z
714
+ */
715
+ getProjectedPositionWithZ(position, worldMatrix) {
716
+ const scene = this.getScene();
717
+ if (!scene) {
718
+ return Vector3.Zero();
719
+ }
720
+ const globalViewport = this._getGlobalViewport();
721
+ const projectedPosition = Vector3.Project(position, worldMatrix, scene.getTransformMatrix(), globalViewport);
722
+ return new Vector3(projectedPosition.x, projectedPosition.y, projectedPosition.z);
723
+ }
724
+ /** @internal */
725
+ _checkUpdate(camera, skipUpdate) {
726
+ if (this._layerToDispose && camera) {
727
+ if ((camera.layerMask & this._layerToDispose.layerMask) === 0) {
728
+ return;
729
+ }
730
+ }
731
+ if (this._isFullscreen && this._linkedControls.length) {
732
+ const scene = this.getScene();
733
+ if (!scene) {
734
+ return;
735
+ }
736
+ const globalViewport = this._getGlobalViewport();
737
+ for (const control of this._linkedControls) {
738
+ if (!control.isVisible) {
739
+ continue;
740
+ }
741
+ const mesh = control._linkedMesh;
742
+ if (!mesh || mesh.isDisposed()) {
743
+ Tools.SetImmediate(() => {
744
+ control.linkWithMesh(null);
745
+ });
746
+ continue;
747
+ }
748
+ const position = mesh.getBoundingInfo ? mesh.getBoundingInfo().boundingSphere.center : Vector3.ZeroReadOnly;
749
+ const projectedPosition = Vector3.Project(position, mesh.getWorldMatrix(), scene.getTransformMatrix(), globalViewport);
750
+ if (projectedPosition.z < 0 || projectedPosition.z > 1) {
751
+ control.notRenderable = true;
752
+ continue;
753
+ }
754
+ control.notRenderable = false;
755
+ if (this.useInvalidateRectOptimization) {
756
+ control.invalidateRect();
757
+ }
758
+ control._moveToProjectedPosition(projectedPosition);
759
+ }
760
+ }
761
+ if (!this._isDirty && !this._rootContainer.isDirty) {
762
+ return;
763
+ }
764
+ this._isDirty = false;
765
+ this._render(skipUpdate);
766
+ if (!skipUpdate) {
767
+ this.update(this.applyYInversionOnUpdate, this.premulAlpha, AdvancedDynamicTexture.AllowGPUOptimizations);
768
+ }
769
+ }
770
+ _render(skipRender) {
771
+ const textureSize = this.getSize();
772
+ const renderWidth = textureSize.width;
773
+ const renderHeight = textureSize.height;
774
+ const context = this.getContext();
775
+ context.font = "18px Arial";
776
+ context.strokeStyle = "white";
777
+ if (this.onGuiReadyObservable.hasObservers()) {
778
+ this._checkGuiIsReady();
779
+ }
780
+ /** We have to recheck the camera projection in the case the root control's children have changed */
781
+ if (this._rootChildrenHaveChanged) {
782
+ const camera = this.getScene()?.activeCamera;
783
+ if (camera) {
784
+ this._rootChildrenHaveChanged = false;
785
+ this._checkUpdate(camera, true);
786
+ }
787
+ }
788
+ // Layout
789
+ this.onBeginLayoutObservable.notifyObservers(this);
790
+ const measure = new Measure(0, 0, renderWidth, renderHeight);
791
+ this._numLayoutCalls = 0;
792
+ this._rootContainer._layout(measure, context);
793
+ this.onEndLayoutObservable.notifyObservers(this);
794
+ this._isDirty = false; // Restoring the dirty state that could have been set by controls during layout processing
795
+ if (skipRender) {
796
+ return;
797
+ }
798
+ // Clear
799
+ if (this._invalidatedRectangle) {
800
+ this._clearMeasure.copyFrom(this._invalidatedRectangle);
801
+ }
802
+ else {
803
+ this._clearMeasure.copyFromFloats(0, 0, renderWidth, renderHeight);
804
+ }
805
+ context.clearRect(this._clearMeasure.left, this._clearMeasure.top, this._clearMeasure.width, this._clearMeasure.height);
806
+ if (this._background) {
807
+ context.save();
808
+ context.fillStyle = this._background;
809
+ context.fillRect(this._clearMeasure.left, this._clearMeasure.top, this._clearMeasure.width, this._clearMeasure.height);
810
+ context.restore();
811
+ }
812
+ // Render
813
+ this.onBeginRenderObservable.notifyObservers(this);
814
+ this._numRenderCalls = 0;
815
+ this._rootContainer._render(context, this._invalidatedRectangle);
816
+ this.onEndRenderObservable.notifyObservers(this);
817
+ this._invalidatedRectangle = null;
818
+ }
819
+ /**
820
+ * @internal
821
+ */
822
+ _changeCursor(cursor) {
823
+ if (this._rootElement) {
824
+ this._rootElement.style.cursor = cursor;
825
+ this._cursorChanged = true;
826
+ }
827
+ }
828
+ /**
829
+ * @internal
830
+ */
831
+ _registerLastControlDown(control, pointerId) {
832
+ this._lastControlDown[pointerId] = control;
833
+ this.onControlPickedObservable.notifyObservers(control);
834
+ }
835
+ _doPicking(x, y, pi, type, pointerId, buttonIndex, deltaX, deltaY) {
836
+ const scene = this.getScene();
837
+ if (!scene || this.disablePicking) {
838
+ return;
839
+ }
840
+ const engine = scene.getEngine();
841
+ const textureSize = this.getSize();
842
+ if (this._isFullscreen) {
843
+ const camera = scene.cameraToUseForPointers || scene.activeCamera;
844
+ if (!camera) {
845
+ return;
846
+ }
847
+ const viewport = camera.viewport;
848
+ x = x * (textureSize.width / (engine.getRenderWidth() * viewport.width));
849
+ y = y * (textureSize.height / (engine.getRenderHeight() * viewport.height));
850
+ }
851
+ if (this._capturingControl[pointerId]) {
852
+ if (this._capturingControl[pointerId].isPointerBlocker) {
853
+ this._shouldBlockPointer = true;
854
+ }
855
+ this._capturingControl[pointerId]._processObservables(type, x, y, pi, pointerId, buttonIndex);
856
+ return;
857
+ }
858
+ this._cursorChanged = false;
859
+ if (!this._rootContainer._processPicking(x, y, pi, type, pointerId, buttonIndex, deltaX, deltaY)) {
860
+ if (!scene.doNotHandleCursors) {
861
+ this._changeCursor("");
862
+ }
863
+ if (type === PointerEventTypes.POINTERMOVE) {
864
+ if (this._lastControlOver[pointerId]) {
865
+ this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId], pi);
866
+ delete this._lastControlOver[pointerId];
867
+ }
868
+ }
869
+ }
870
+ if (!this._cursorChanged && !scene.doNotHandleCursors) {
871
+ this._changeCursor("");
872
+ }
873
+ this._manageFocus();
874
+ }
875
+ /**
876
+ * @internal
877
+ */
878
+ _cleanControlAfterRemovalFromList(list, control) {
879
+ for (const pointerId in list) {
880
+ if (!Object.prototype.hasOwnProperty.call(list, pointerId)) {
881
+ continue;
882
+ }
883
+ const lastControlOver = list[pointerId];
884
+ if (lastControlOver === control) {
885
+ delete list[pointerId];
886
+ }
887
+ }
888
+ }
889
+ /**
890
+ * @internal
891
+ */
892
+ _cleanControlAfterRemoval(control) {
893
+ this._cleanControlAfterRemovalFromList(this._lastControlDown, control);
894
+ this._cleanControlAfterRemovalFromList(this._lastControlOver, control);
895
+ }
896
+ /**
897
+ * This function will run a pointer event on this ADT and will trigger any pointer events on any controls
898
+ * This will work on a fullscreen ADT only. For mesh based ADT, simulate pointer events using the scene directly.
899
+ * @param x pointer X on the canvas for the picking
900
+ * @param y pointer Y on the canvas for the picking
901
+ * @param pi optional pointer information
902
+ */
903
+ pick(x, y, pi = null) {
904
+ if (this._isFullscreen && this._scene) {
905
+ this._translateToPicking(this._scene, new Viewport(0, 0, 0, 0), pi, x, y);
906
+ }
907
+ }
908
+ _translateToPicking(scene, tempViewport, pi, x = scene.pointerX, y = scene.pointerY) {
909
+ const camera = scene.cameraToUseForPointers || scene.activeCamera;
910
+ const engine = scene.getEngine();
911
+ const originalCameraToUseForPointers = scene.cameraToUseForPointers;
912
+ if (!camera) {
913
+ tempViewport.x = 0;
914
+ tempViewport.y = 0;
915
+ tempViewport.width = engine.getRenderWidth();
916
+ tempViewport.height = engine.getRenderHeight();
917
+ }
918
+ else {
919
+ if (camera.rigCameras.length) {
920
+ // rig camera - we need to find the camera to use for this event
921
+ const rigViewport = new Viewport(0, 0, 1, 1);
922
+ for (const rigCamera of camera.rigCameras) {
923
+ // generate the viewport of this camera
924
+ rigCamera.viewport.toGlobalToRef(engine.getRenderWidth(), engine.getRenderHeight(), rigViewport);
925
+ const transformedX = x / engine.getHardwareScalingLevel() - rigViewport.x;
926
+ const transformedY = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - rigViewport.y - rigViewport.height);
927
+ // check if the pointer is in the camera's viewport
928
+ if (transformedX < 0 || transformedY < 0 || x > rigViewport.width || y > rigViewport.height) {
929
+ // out of viewport - don't use this camera
930
+ return;
931
+ }
932
+ // set the camera to use for pointers until this pointer loop is over
933
+ scene.cameraToUseForPointers = rigCamera;
934
+ // set the viewport
935
+ tempViewport.x = rigViewport.x;
936
+ tempViewport.y = rigViewport.y;
937
+ tempViewport.width = rigViewport.width;
938
+ tempViewport.height = rigViewport.height;
939
+ }
940
+ }
941
+ else {
942
+ camera.viewport.toGlobalToRef(engine.getRenderWidth(), engine.getRenderHeight(), tempViewport);
943
+ }
944
+ }
945
+ const transformedX = x / engine.getHardwareScalingLevel() - tempViewport.x;
946
+ const transformedY = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - tempViewport.y - tempViewport.height);
947
+ this._shouldBlockPointer = false;
948
+ // Do picking modifies _shouldBlockPointer
949
+ if (pi) {
950
+ const pointerId = pi.event.pointerId || this._defaultMousePointerId;
951
+ this._doPicking(transformedX, transformedY, pi, pi.type, pointerId, pi.event.button, pi.event.deltaX, pi.event.deltaY);
952
+ // Avoid overwriting a true skipOnPointerObservable to false
953
+ if ((this._shouldBlockPointer && !(pi.type & this.skipBlockEvents)) || this._capturingControl[pointerId]) {
954
+ pi.skipOnPointerObservable = true;
955
+ }
956
+ }
957
+ else {
958
+ this._doPicking(transformedX, transformedY, null, PointerEventTypes.POINTERMOVE, this._defaultMousePointerId, 0);
959
+ }
960
+ // if overridden by a rig camera - reset back to the original value
961
+ scene.cameraToUseForPointers = originalCameraToUseForPointers;
962
+ }
963
+ /** Attach to all scene events required to support pointer events */
964
+ attach() {
965
+ const scene = this.getScene();
966
+ if (!scene) {
967
+ return;
968
+ }
969
+ const tempViewport = new Viewport(0, 0, 0, 0);
970
+ this._prePointerObserver = scene.onPrePointerObservable.add((pi) => {
971
+ if (scene.isPointerCaptured(pi.event.pointerId) &&
972
+ pi.type === PointerEventTypes.POINTERUP &&
973
+ !this._capturedPointerIds.has(pi.event.pointerId)) {
974
+ return;
975
+ }
976
+ if (pi.type !== PointerEventTypes.POINTERMOVE &&
977
+ pi.type !== PointerEventTypes.POINTERUP &&
978
+ pi.type !== PointerEventTypes.POINTERDOWN &&
979
+ pi.type !== PointerEventTypes.POINTERWHEEL &&
980
+ pi.type !== PointerEventTypes.POINTERTAP) {
981
+ return;
982
+ }
983
+ if (pi.type === PointerEventTypes.POINTERMOVE) {
984
+ // Avoid pointerMove events firing while the pointer is captured by the scene
985
+ if (scene.isPointerCaptured(pi.event.pointerId)) {
986
+ return;
987
+ }
988
+ if (pi.event.pointerId) {
989
+ this._defaultMousePointerId = pi.event.pointerId; // This is required to make sure we have the correct pointer ID for wheel
990
+ }
991
+ }
992
+ this._translateToPicking(scene, tempViewport, pi);
993
+ });
994
+ this._attachPickingToSceneRender(scene, () => this._translateToPicking(scene, tempViewport, null), false);
995
+ this._attachToOnPointerOut(scene);
996
+ this._attachToOnBlur(scene);
997
+ }
998
+ _focusNextElement(forward = true) {
999
+ // generate the order of tab-able controls
1000
+ const sortedTabbableControls = [];
1001
+ this.executeOnAllControls((control) => {
1002
+ if (control.isFocusInvisible || !control.isVisible || control.tabIndex < 0) {
1003
+ return;
1004
+ }
1005
+ sortedTabbableControls.push(control);
1006
+ });
1007
+ // if no control is tab-able, return
1008
+ if (sortedTabbableControls.length === 0) {
1009
+ return;
1010
+ }
1011
+ sortedTabbableControls.sort((a, b) => {
1012
+ // if tabIndex is 0, put it in the end of the list, otherwise sort by tabIndex
1013
+ return a.tabIndex === 0 ? 1 : b.tabIndex === 0 ? -1 : a.tabIndex - b.tabIndex;
1014
+ });
1015
+ this._focusProperties.total = sortedTabbableControls.length;
1016
+ // if no control is focused, focus the first one
1017
+ let nextIndex = -1;
1018
+ if (!this._focusedControl) {
1019
+ nextIndex = forward ? 0 : sortedTabbableControls.length - 1;
1020
+ }
1021
+ else {
1022
+ const currentIndex = sortedTabbableControls.indexOf(this._focusedControl);
1023
+ nextIndex = currentIndex + (forward ? 1 : -1);
1024
+ if (nextIndex < 0) {
1025
+ nextIndex = sortedTabbableControls.length - 1;
1026
+ }
1027
+ else if (nextIndex >= sortedTabbableControls.length) {
1028
+ nextIndex = 0;
1029
+ }
1030
+ }
1031
+ sortedTabbableControls[nextIndex].focus();
1032
+ this._focusProperties.index = nextIndex;
1033
+ }
1034
+ /**
1035
+ * Register the clipboard Events onto the canvas
1036
+ */
1037
+ registerClipboardEvents() {
1038
+ self.addEventListener("copy", this._onClipboardCopy, false);
1039
+ self.addEventListener("cut", this._onClipboardCut, false);
1040
+ self.addEventListener("paste", this._onClipboardPaste, false);
1041
+ }
1042
+ /**
1043
+ * Unregister the clipboard Events from the canvas
1044
+ */
1045
+ unRegisterClipboardEvents() {
1046
+ self.removeEventListener("copy", this._onClipboardCopy);
1047
+ self.removeEventListener("cut", this._onClipboardCut);
1048
+ self.removeEventListener("paste", this._onClipboardPaste);
1049
+ }
1050
+ /**
1051
+ * Transform uvs from mesh space to texture space, taking the texture into account
1052
+ * @param uv the uvs in mesh space
1053
+ * @returns the uvs in texture space
1054
+ */
1055
+ _transformUvs(uv) {
1056
+ const textureMatrix = this.getTextureMatrix();
1057
+ let result;
1058
+ if (textureMatrix.isIdentityAs3x2()) {
1059
+ result = uv;
1060
+ }
1061
+ else {
1062
+ const homogeneousTextureMatrix = TmpVectors.Matrix[0];
1063
+ textureMatrix.getRowToRef(0, TmpVectors.Vector4[0]);
1064
+ textureMatrix.getRowToRef(1, TmpVectors.Vector4[1]);
1065
+ textureMatrix.getRowToRef(2, TmpVectors.Vector4[2]);
1066
+ const r0 = TmpVectors.Vector4[0];
1067
+ const r1 = TmpVectors.Vector4[1];
1068
+ const r2 = TmpVectors.Vector4[2];
1069
+ homogeneousTextureMatrix.setRowFromFloats(0, r0.x, r0.y, 0, 0);
1070
+ homogeneousTextureMatrix.setRowFromFloats(1, r1.x, r1.y, 0, 0);
1071
+ homogeneousTextureMatrix.setRowFromFloats(2, 0, 0, 1, 0);
1072
+ homogeneousTextureMatrix.setRowFromFloats(3, r2.x, r2.y, 0, 1);
1073
+ result = TmpVectors.Vector2[0];
1074
+ Vector2.TransformToRef(uv, homogeneousTextureMatrix, result);
1075
+ }
1076
+ // In wrap and mirror mode, the texture coordinate for coordinates more than 1 is the fractional part of the coordinate
1077
+ if (this.wrapU === Texture.WRAP_ADDRESSMODE || this.wrapU === Texture.MIRROR_ADDRESSMODE) {
1078
+ if (result.x > 1) {
1079
+ let fX = result.x - Math.trunc(result.x);
1080
+ // In mirror mode, the sign of the texture coordinate depends on the integer part -
1081
+ // odd integers means it is mirrored from the original coordinate
1082
+ if (this.wrapU === Texture.MIRROR_ADDRESSMODE && Math.trunc(result.x) % 2 === 1) {
1083
+ fX = 1 - fX;
1084
+ }
1085
+ result.x = fX;
1086
+ }
1087
+ }
1088
+ if (this.wrapV === Texture.WRAP_ADDRESSMODE || this.wrapV === Texture.MIRROR_ADDRESSMODE) {
1089
+ if (result.y > 1) {
1090
+ let fY = result.y - Math.trunc(result.y);
1091
+ if (this.wrapV === Texture.MIRROR_ADDRESSMODE && Math.trunc(result.x) % 2 === 1) {
1092
+ fY = 1 - fY;
1093
+ }
1094
+ result.y = fY;
1095
+ }
1096
+ }
1097
+ return result;
1098
+ }
1099
+ /**
1100
+ * Connect the texture to a hosting mesh to enable interactions
1101
+ * @param mesh defines the mesh to attach to
1102
+ * @param supportPointerMove defines a boolean indicating if pointer move events must be catched as well
1103
+ */
1104
+ attachToMesh(mesh, supportPointerMove = true) {
1105
+ const scene = this.getScene();
1106
+ if (!scene) {
1107
+ return;
1108
+ }
1109
+ if (this._pointerObserver) {
1110
+ scene.onPointerObservable.remove(this._pointerObserver);
1111
+ }
1112
+ this._pointerObserver = scene.onPointerObservable.add((pi) => {
1113
+ if (pi.type !== PointerEventTypes.POINTERMOVE &&
1114
+ pi.type !== PointerEventTypes.POINTERUP &&
1115
+ pi.type !== PointerEventTypes.POINTERDOWN &&
1116
+ pi.type !== PointerEventTypes.POINTERWHEEL) {
1117
+ return;
1118
+ }
1119
+ if (pi.type === PointerEventTypes.POINTERMOVE && pi.event.pointerId) {
1120
+ this._defaultMousePointerId = pi.event.pointerId; // This is required to make sure we have the correct pointer ID for wheel
1121
+ }
1122
+ const pointerId = pi.event.pointerId || this._defaultMousePointerId;
1123
+ if (pi.pickInfo && pi.pickInfo.hit && pi.pickInfo.pickedMesh === mesh) {
1124
+ let uv = pi.pickInfo.getTextureCoordinates();
1125
+ if (uv) {
1126
+ uv = this._transformUvs(uv);
1127
+ const size = this.getSize();
1128
+ this._doPicking(uv.x * size.width, (this.applyYInversionOnUpdate ? 1.0 - uv.y : uv.y) * size.height, pi, pi.type, pointerId, pi.event.button, pi.event.deltaX, pi.event.deltaY);
1129
+ }
1130
+ }
1131
+ else if (pi.type === PointerEventTypes.POINTERUP) {
1132
+ if (this._lastControlDown[pointerId]) {
1133
+ this._lastControlDown[pointerId]._forcePointerUp(pointerId);
1134
+ }
1135
+ delete this._lastControlDown[pointerId];
1136
+ if (this.focusedControl) {
1137
+ const friendlyControls = this.focusedControl.keepsFocusWith();
1138
+ let canMoveFocus = true;
1139
+ if (friendlyControls) {
1140
+ for (const control of friendlyControls) {
1141
+ // Same host, no need to keep the focus
1142
+ if (this === control._host) {
1143
+ continue;
1144
+ }
1145
+ // Different hosts
1146
+ const otherHost = control._host;
1147
+ if (otherHost._lastControlOver[pointerId] && otherHost._lastControlOver[pointerId].isAscendant(control)) {
1148
+ canMoveFocus = false;
1149
+ break;
1150
+ }
1151
+ }
1152
+ }
1153
+ if (canMoveFocus) {
1154
+ this.focusedControl = null;
1155
+ }
1156
+ }
1157
+ }
1158
+ else if (pi.type === PointerEventTypes.POINTERMOVE) {
1159
+ if (this._lastControlOver[pointerId]) {
1160
+ this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId], pi, true);
1161
+ }
1162
+ delete this._lastControlOver[pointerId];
1163
+ }
1164
+ });
1165
+ mesh.enablePointerMoveEvents = supportPointerMove;
1166
+ this._attachPickingToSceneRender(scene, () => {
1167
+ const pointerId = this._defaultMousePointerId;
1168
+ const pick = scene?.pick(scene.pointerX, scene.pointerY);
1169
+ if (pick && pick.hit && pick.pickedMesh === mesh) {
1170
+ let uv = pick.getTextureCoordinates();
1171
+ if (uv) {
1172
+ uv = this._transformUvs(uv);
1173
+ const size = this.getSize();
1174
+ this._doPicking(uv.x * size.width, (this.applyYInversionOnUpdate ? 1.0 - uv.y : uv.y) * size.height, null, PointerEventTypes.POINTERMOVE, pointerId, 0);
1175
+ }
1176
+ }
1177
+ else {
1178
+ if (this._lastControlOver[pointerId]) {
1179
+ this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId], null, true);
1180
+ }
1181
+ delete this._lastControlOver[pointerId];
1182
+ }
1183
+ }, true);
1184
+ this._attachToOnPointerOut(scene);
1185
+ this._attachToOnBlur(scene);
1186
+ }
1187
+ /**
1188
+ * Move the focus to a specific control
1189
+ * @param control defines the control which will receive the focus
1190
+ */
1191
+ moveFocusToControl(control) {
1192
+ this.focusedControl = control;
1193
+ this._lastPickedControl = control;
1194
+ this._blockNextFocusCheck = true;
1195
+ }
1196
+ _manageFocus() {
1197
+ if (this._blockNextFocusCheck) {
1198
+ this._blockNextFocusCheck = false;
1199
+ this._lastPickedControl = this._focusedControl;
1200
+ return;
1201
+ }
1202
+ // Focus management
1203
+ if (this._focusedControl) {
1204
+ if (this._focusedControl !== this._lastPickedControl) {
1205
+ if (this._lastPickedControl.isFocusInvisible) {
1206
+ return;
1207
+ }
1208
+ this.focusedControl = null;
1209
+ }
1210
+ }
1211
+ }
1212
+ _attachPickingToSceneRender(scene, pickFunction, forcePicking) {
1213
+ this._sceneRenderObserver = scene.onBeforeRenderObservable.add(() => {
1214
+ if (!this.checkPointerEveryFrame) {
1215
+ return;
1216
+ }
1217
+ if (this._linkedControls.length > 0 || forcePicking) {
1218
+ pickFunction();
1219
+ }
1220
+ });
1221
+ }
1222
+ _attachToOnPointerOut(scene) {
1223
+ this._canvasPointerOutObserver = scene.getEngine().onCanvasPointerOutObservable.add((pointerEvent) => {
1224
+ if (this._lastControlOver[pointerEvent.pointerId]) {
1225
+ this._lastControlOver[pointerEvent.pointerId]._onPointerOut(this._lastControlOver[pointerEvent.pointerId], null);
1226
+ }
1227
+ delete this._lastControlOver[pointerEvent.pointerId];
1228
+ if (this._lastControlDown[pointerEvent.pointerId] && this._lastControlDown[pointerEvent.pointerId] !== this._capturingControl[pointerEvent.pointerId]) {
1229
+ this._lastControlDown[pointerEvent.pointerId]._forcePointerUp(pointerEvent.pointerId);
1230
+ delete this._lastControlDown[pointerEvent.pointerId];
1231
+ }
1232
+ });
1233
+ }
1234
+ _attachToOnBlur(scene) {
1235
+ this._canvasBlurObserver = scene.getEngine().onCanvasBlurObservable.add(() => {
1236
+ Object.entries(this._lastControlDown).forEach(([, value]) => {
1237
+ value._onCanvasBlur();
1238
+ });
1239
+ this.focusedControl = null;
1240
+ this._lastControlDown = {};
1241
+ });
1242
+ }
1243
+ /**
1244
+ * Serializes the entire GUI system
1245
+ * @returns an object with the JSON serialized data
1246
+ */
1247
+ serializeContent() {
1248
+ const size = this.getSize();
1249
+ const serializationObject = {
1250
+ root: {},
1251
+ width: size.width,
1252
+ height: size.height,
1253
+ };
1254
+ this._rootContainer.serialize(serializationObject.root);
1255
+ return serializationObject;
1256
+ }
1257
+ /**
1258
+ * Recreate the content of the ADT from a JSON object
1259
+ * @param serializedObject define the JSON serialized object to restore from
1260
+ * @param scaleToSize defines whether to scale to texture to the saved size
1261
+ * @param urlRewriter defines an url rewriter to update urls before sending them to the controls
1262
+ */
1263
+ parseSerializedObject(serializedObject, scaleToSize, urlRewriter) {
1264
+ this._rootContainer = Control.Parse(serializedObject.root, this, urlRewriter);
1265
+ if (scaleToSize) {
1266
+ const width = serializedObject.width;
1267
+ const height = serializedObject.height;
1268
+ if (typeof width === "number" && typeof height === "number" && width >= 0 && height >= 0) {
1269
+ this.scaleTo(width, height);
1270
+ }
1271
+ else {
1272
+ // scales the GUI to a default size if none was available in the serialized content
1273
+ this.scaleTo(1920, 1080);
1274
+ }
1275
+ }
1276
+ }
1277
+ /**
1278
+ * Clones the ADT. If no mesh is defined, the GUI will be considered as a fullscreen GUI
1279
+ * @param newName defines the name of the new ADT
1280
+ * @param attachToMesh defines if the new ADT should be attached to a mesh
1281
+ * @returns the clone of the ADT
1282
+ */
1283
+ clone(newName, attachToMesh) {
1284
+ const scene = this.getScene();
1285
+ if (!scene) {
1286
+ return this;
1287
+ }
1288
+ const size = this.getSize();
1289
+ const data = this.serializeContent();
1290
+ let clone;
1291
+ if (!this._isFullscreen) {
1292
+ if (attachToMesh) {
1293
+ clone = AdvancedDynamicTexture.CreateForMesh(attachToMesh, size.width, size.height);
1294
+ }
1295
+ else {
1296
+ clone = new AdvancedDynamicTexture(newName ?? "Clone of " + this.name, size.width, size.height, scene, !this.noMipmap, this.samplingMode);
1297
+ }
1298
+ }
1299
+ else {
1300
+ clone = AdvancedDynamicTexture.CreateFullscreenUI(newName ?? "Clone of " + this.name);
1301
+ }
1302
+ clone.parseSerializedObject(data);
1303
+ return clone;
1304
+ }
1305
+ /**
1306
+ * Recreate the content of the ADT from a snippet saved by the GUI editor
1307
+ * @param snippetId defines the snippet to load
1308
+ * @param scaleToSize defines whether to scale to texture to the saved size
1309
+ * @param appendToAdt if provided the snippet will be appended to the adt. Otherwise a fullscreen ADT will be created.
1310
+ * @param urlRewriter defines an url rewriter to update urls before sending them to the controls
1311
+ * @returns a promise that will resolve on success
1312
+ */
1313
+ static async ParseFromSnippetAsync(snippetId, scaleToSize, appendToAdt, urlRewriter) {
1314
+ const adt = appendToAdt ?? AdvancedDynamicTexture.CreateFullscreenUI("ADT from snippet");
1315
+ if (snippetId === "_BLANK") {
1316
+ return adt;
1317
+ }
1318
+ const serialized = await AdvancedDynamicTexture._LoadURLContentAsync(AdvancedDynamicTexture.SnippetUrl + "/" + snippetId.replace(/#/g, "/"), true);
1319
+ adt.parseSerializedObject(serialized, scaleToSize, urlRewriter);
1320
+ return adt;
1321
+ }
1322
+ /**
1323
+ * Recreate the content of the ADT from a snippet saved by the GUI editor
1324
+ * @param snippetId defines the snippet to load
1325
+ * @param scaleToSize defines whether to scale to texture to the saved size
1326
+ * @param urlRewriter defines an url rewriter to update urls before sending them to the controls
1327
+ * @returns a promise that will resolve on success
1328
+ */
1329
+ async parseFromSnippetAsync(snippetId, scaleToSize, urlRewriter) {
1330
+ return await AdvancedDynamicTexture.ParseFromSnippetAsync(snippetId, scaleToSize, this, urlRewriter);
1331
+ }
1332
+ /**
1333
+ * Recreate the content of the ADT from a url json
1334
+ * @param url defines the url to load
1335
+ * @param scaleToSize defines whether to scale to texture to the saved size
1336
+ * @param appendToAdt if provided the snippet will be appended to the adt. Otherwise a fullscreen ADT will be created.
1337
+ * @param urlRewriter defines an url rewriter to update urls before sending them to the controls
1338
+ * @returns a promise that will resolve on success
1339
+ */
1340
+ static async ParseFromFileAsync(url, scaleToSize, appendToAdt, urlRewriter) {
1341
+ const adt = appendToAdt ?? AdvancedDynamicTexture.CreateFullscreenUI("ADT from URL");
1342
+ const serialized = await AdvancedDynamicTexture._LoadURLContentAsync(url);
1343
+ adt.parseSerializedObject(serialized, scaleToSize, urlRewriter);
1344
+ return adt;
1345
+ }
1346
+ /**
1347
+ * Recreate the content of the ADT from a url json
1348
+ * @param url defines the url to load
1349
+ * @param scaleToSize defines whether to scale to texture to the saved size
1350
+ * @param urlRewriter defines an url rewriter to update urls before sending them to the controls
1351
+ * @returns a promise that will resolve on success
1352
+ */
1353
+ async parseFromURLAsync(url, scaleToSize, urlRewriter) {
1354
+ return await AdvancedDynamicTexture.ParseFromFileAsync(url, scaleToSize, this, urlRewriter);
1355
+ }
1356
+ static async _LoadURLContentAsync(url, snippet = false) {
1357
+ if (url === "") {
1358
+ throw new Error("No URL provided");
1359
+ }
1360
+ return await new Promise((resolve, reject) => {
1361
+ const request = new WebRequest();
1362
+ request.addEventListener("readystatechange", () => {
1363
+ if (request.readyState == 4) {
1364
+ if (request.status == 200) {
1365
+ let gui;
1366
+ if (snippet) {
1367
+ const payload = JSON.parse(JSON.parse(request.responseText).jsonPayload);
1368
+ gui = payload.encodedGui ? new TextDecoder("utf-8").decode(DecodeBase64ToBinary(payload.encodedGui)) : payload.gui;
1369
+ }
1370
+ else {
1371
+ gui = request.responseText;
1372
+ }
1373
+ const serializationObject = JSON.parse(gui);
1374
+ resolve(serializationObject);
1375
+ }
1376
+ else {
1377
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
1378
+ reject("Unable to load");
1379
+ }
1380
+ }
1381
+ });
1382
+ request.open("GET", url);
1383
+ request.send();
1384
+ });
1385
+ }
1386
+ // Statics
1387
+ /**
1388
+ * Compares two rectangle based controls for pixel overlap
1389
+ * @param control1 The first control to compare
1390
+ * @param control2 The second control to compare
1391
+ * @returns true if overlaps, otherwise false
1392
+ */
1393
+ static _Overlaps(control1, control2) {
1394
+ return !(control1.centerX > control2.centerX + control2.widthInPixels ||
1395
+ control1.centerX + control1.widthInPixels < control2.centerX ||
1396
+ control1.centerY + control1.heightInPixels < control2.centerY ||
1397
+ control1.centerY > control2.centerY + control2.heightInPixels);
1398
+ }
1399
+ /**
1400
+ * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh)
1401
+ * @param mesh defines the mesh which will receive the texture
1402
+ * @param width defines the texture width (1024 by default)
1403
+ * @param height defines the texture height (1024 by default)
1404
+ * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
1405
+ * @param onlyAlphaTesting defines a boolean indicating that alpha blending will not be used (only alpha testing) (false by default)
1406
+ * @param invertY defines if the texture needs to be inverted on the y axis during loading (true by default)
1407
+ * @param materialSetupCallback defines a custom way of creating and setting up the material on the mesh
1408
+ * @param sampling defines the texture sampling mode (Texture.TRILINEAR_SAMPLINGMODE by default)
1409
+ * @returns a new AdvancedDynamicTexture
1410
+ */
1411
+ static CreateForMesh(mesh, width = 1024, height = 1024, supportPointerMove = true, onlyAlphaTesting = false, invertY, materialSetupCallback = this._CreateMaterial, sampling = Texture.TRILINEAR_SAMPLINGMODE) {
1412
+ // use a unique ID in name so serialization will work even if you create two ADTs for a single mesh
1413
+ const uniqueId = RandomGUID();
1414
+ const result = new AdvancedDynamicTexture(`AdvancedDynamicTexture for ${mesh.name} [${uniqueId}]`, width, height, mesh.getScene(), true, sampling, invertY);
1415
+ materialSetupCallback(mesh, uniqueId, result, onlyAlphaTesting);
1416
+ result.attachToMesh(mesh, supportPointerMove);
1417
+ return result;
1418
+ }
1419
+ static _CreateMaterial(mesh, uniqueId, texture, onlyAlphaTesting) {
1420
+ const internalClassType = GetClass("BABYLON.StandardMaterial");
1421
+ if (!internalClassType) {
1422
+ // eslint-disable-next-line no-throw-literal
1423
+ throw "StandardMaterial needs to be imported before as it contains a side-effect required by your code.";
1424
+ }
1425
+ const material = new internalClassType(`AdvancedDynamicTextureMaterial for ${mesh.name} [${uniqueId}]`, mesh.getScene());
1426
+ material.backFaceCulling = false;
1427
+ material.diffuseColor = Color3.Black();
1428
+ material.specularColor = Color3.Black();
1429
+ if (onlyAlphaTesting) {
1430
+ material.diffuseTexture = texture;
1431
+ material.emissiveTexture = texture;
1432
+ texture.hasAlpha = true;
1433
+ }
1434
+ else {
1435
+ material.emissiveTexture = texture;
1436
+ material.opacityTexture = texture;
1437
+ }
1438
+ mesh.material = material;
1439
+ }
1440
+ /**
1441
+ * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh) BUT do not create a new material for the mesh. You will be responsible for connecting the texture
1442
+ * @param mesh defines the mesh which will receive the texture
1443
+ * @param width defines the texture width (1024 by default)
1444
+ * @param height defines the texture height (1024 by default)
1445
+ * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
1446
+ * @param invertY defines if the texture needs to be inverted on the y axis during loading (true by default)
1447
+ * @param sampling defines the texture sampling mode (Texture.TRILINEAR_SAMPLINGMODE by default)
1448
+ * @returns a new AdvancedDynamicTexture
1449
+ */
1450
+ static CreateForMeshTexture(mesh, width = 1024, height = 1024, supportPointerMove = true, invertY, sampling = Texture.TRILINEAR_SAMPLINGMODE) {
1451
+ const result = new AdvancedDynamicTexture(mesh.name + " AdvancedDynamicTexture", width, height, mesh.getScene(), true, sampling, invertY);
1452
+ result.attachToMesh(mesh, supportPointerMove);
1453
+ return result;
1454
+ }
1455
+ /**
1456
+ * Creates a new AdvancedDynamicTexture in fullscreen mode.
1457
+ * In this mode the texture will rely on a layer for its rendering.
1458
+ * This allows it to be treated like any other layer.
1459
+ * As such, if you have a multi camera setup, you can set the layerMask on the GUI as well.
1460
+ * LayerMask is set through advancedTexture.layer.layerMask
1461
+ * @param name defines name for the texture
1462
+ * @param foreground defines a boolean indicating if the texture must be rendered in foreground (default is true)
1463
+ * @param sceneOrOptions defines the hosting scene or options (IAdvancedDynamicTextureOptions)
1464
+ * @param sampling defines the texture sampling mode (Texture.BILINEAR_SAMPLINGMODE by default)
1465
+ * @param adaptiveScaling defines whether to automatically scale root to match hardwarescaling (false by default)
1466
+ * @returns a new AdvancedDynamicTexture
1467
+ */
1468
+ static CreateFullscreenUI(name, foreground = true, sceneOrOptions = null, sampling = Texture.BILINEAR_SAMPLINGMODE, adaptiveScaling = false) {
1469
+ const isScene = !sceneOrOptions || sceneOrOptions._isScene;
1470
+ const result = isScene
1471
+ ? new AdvancedDynamicTexture(name, 0, 0, sceneOrOptions, false, sampling)
1472
+ : new AdvancedDynamicTexture(name, sceneOrOptions);
1473
+ // Display
1474
+ const resultScene = result.getScene();
1475
+ const layer = new Layer(name + "_layer", null, resultScene, !foreground);
1476
+ layer.texture = result;
1477
+ result._layerToDispose = layer;
1478
+ result._isFullscreen = true;
1479
+ if (result.useStandalone) {
1480
+ // Make sure the layer is not rendered by the layer component!
1481
+ layer.layerMask = 0;
1482
+ }
1483
+ result.adjustToEngineHardwareScalingLevel = adaptiveScaling;
1484
+ // Attach
1485
+ result.attach();
1486
+ return result;
1487
+ }
1488
+ /**
1489
+ * Scales the texture
1490
+ * @param ratio the scale factor to apply to both width and height
1491
+ */
1492
+ scale(ratio) {
1493
+ super.scale(ratio);
1494
+ this.markAsDirty();
1495
+ }
1496
+ /**
1497
+ * Resizes the texture
1498
+ * @param width the new width
1499
+ * @param height the new height
1500
+ */
1501
+ scaleTo(width, height) {
1502
+ super.scaleTo(width, height);
1503
+ this.markAsDirty();
1504
+ }
1505
+ _checkGuiIsReady() {
1506
+ if (this.guiIsReady()) {
1507
+ this.onGuiReadyObservable.notifyObservers(this);
1508
+ this.onGuiReadyObservable.clear();
1509
+ }
1510
+ }
1511
+ /**
1512
+ * @returns true if all the GUI components are ready to render
1513
+ */
1514
+ guiIsReady() {
1515
+ return this._rootContainer.isReady();
1516
+ }
1517
+ }
1518
+ /** Define the url to load snippets */
1519
+ AdvancedDynamicTexture.SnippetUrl = Constants.SnippetUrl;
1520
+ /** Indicates if some optimizations can be performed in GUI GPU management (the downside is additional memory/GPU texture memory used) */
1521
+ AdvancedDynamicTexture.AllowGPUOptimizations = true;
1522
+ //# sourceMappingURL=advancedDynamicTexture.js.map