button.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. import { Nullable } from "babylonjs/types";
  2. import { Vector2 } from "babylonjs/Maths/math";
  3. import { Rectangle } from "./rectangle";
  4. import { Control } from "./control";
  5. import { TextBlock } from "./textBlock";
  6. import { Image } from "./image";
  7. import { _TypeStore } from 'babylonjs/Misc/typeStore';
  8. /**
  9. * Class used to create 2D buttons
  10. */
  11. export class Button extends Rectangle {
  12. /**
  13. * Function called to generate a pointer enter animation
  14. */
  15. public pointerEnterAnimation: () => void;
  16. /**
  17. * Function called to generate a pointer out animation
  18. */
  19. public pointerOutAnimation: () => void;
  20. /**
  21. * Function called to generate a pointer down animation
  22. */
  23. public pointerDownAnimation: () => void;
  24. /**
  25. * Function called to generate a pointer up animation
  26. */
  27. public pointerUpAnimation: () => void;
  28. /**
  29. * Gets or sets a boolean indicating that the button will let internal controls handle picking instead of doing it directly using its bounding info
  30. */
  31. public delegatePickingToChildren = false;
  32. private _image: Nullable<Image>;
  33. /**
  34. * Returns the image part of the button (if any)
  35. */
  36. public get image(): Nullable<Image> {
  37. return this._image;
  38. }
  39. private _textBlock: Nullable<TextBlock>;
  40. /**
  41. * Returns the image part of the button (if any)
  42. */
  43. public get textBlock(): Nullable<TextBlock> {
  44. return this._textBlock;
  45. }
  46. /**
  47. * Creates a new Button
  48. * @param name defines the name of the button
  49. */
  50. constructor(public name?: string) {
  51. super(name);
  52. this.thickness = 1;
  53. this.isPointerBlocker = true;
  54. let alphaStore: Nullable<number> = null;
  55. this.pointerEnterAnimation = () => {
  56. alphaStore = this.alpha;
  57. this.alpha -= 0.1;
  58. };
  59. this.pointerOutAnimation = () => {
  60. if (alphaStore !== null) {
  61. this.alpha = alphaStore;
  62. }
  63. };
  64. this.pointerDownAnimation = () => {
  65. this.scaleX -= 0.05;
  66. this.scaleY -= 0.05;
  67. };
  68. this.pointerUpAnimation = () => {
  69. this.scaleX += 0.05;
  70. this.scaleY += 0.05;
  71. };
  72. }
  73. protected _getTypeName(): string {
  74. return "Button";
  75. }
  76. // While being a container, the button behaves like a control.
  77. /** @hidden */
  78. public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
  79. if (!this._isEnabled || !this.isHitTestVisible || !this.isVisible || this.notRenderable) {
  80. return false;
  81. }
  82. if (!super.contains(x, y)) {
  83. return false;
  84. }
  85. if (this.delegatePickingToChildren) {
  86. let contains = false;
  87. for (var index = this._children.length - 1; index >= 0; index--) {
  88. var child = this._children[index];
  89. if (child.isEnabled && child.isHitTestVisible && child.isVisible && !child.notRenderable && child.contains(x, y)) {
  90. contains = true;
  91. break;
  92. }
  93. }
  94. if (!contains) {
  95. return false;
  96. }
  97. }
  98. this._processObservables(type, x, y, pointerId, buttonIndex);
  99. return true;
  100. }
  101. /** @hidden */
  102. public _onPointerEnter(target: Control): boolean {
  103. if (!super._onPointerEnter(target)) {
  104. return false;
  105. }
  106. if (this.pointerEnterAnimation) {
  107. this.pointerEnterAnimation();
  108. }
  109. return true;
  110. }
  111. /** @hidden */
  112. public _onPointerOut(target: Control, force = false): void {
  113. if (this.pointerOutAnimation) {
  114. this.pointerOutAnimation();
  115. }
  116. super._onPointerOut(target, force);
  117. }
  118. /** @hidden */
  119. public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
  120. if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
  121. return false;
  122. }
  123. if (this.pointerDownAnimation) {
  124. this.pointerDownAnimation();
  125. }
  126. return true;
  127. }
  128. /** @hidden */
  129. public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
  130. if (this.pointerUpAnimation) {
  131. this.pointerUpAnimation();
  132. }
  133. super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
  134. }
  135. // Statics
  136. /**
  137. * Creates a new button made with an image and a text
  138. * @param name defines the name of the button
  139. * @param text defines the text of the button
  140. * @param imageUrl defines the url of the image
  141. * @returns a new Button
  142. */
  143. public static CreateImageButton(name: string, text: string, imageUrl: string): Button {
  144. var result = new Button(name);
  145. // Adding text
  146. var textBlock = new TextBlock(name + "_button", text);
  147. textBlock.textWrapping = true;
  148. textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
  149. textBlock.paddingLeft = "20%";
  150. result.addControl(textBlock);
  151. // Adding image
  152. var iconImage = new Image(name + "_icon", imageUrl);
  153. iconImage.width = "20%";
  154. iconImage.stretch = Image.STRETCH_UNIFORM;
  155. iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  156. result.addControl(iconImage);
  157. // Store
  158. result._image = iconImage;
  159. result._textBlock = textBlock;
  160. return result;
  161. }
  162. /**
  163. * Creates a new button made with an image
  164. * @param name defines the name of the button
  165. * @param imageUrl defines the url of the image
  166. * @returns a new Button
  167. */
  168. public static CreateImageOnlyButton(name: string, imageUrl: string): Button {
  169. var result = new Button(name);
  170. // Adding image
  171. var iconImage = new Image(name + "_icon", imageUrl);
  172. iconImage.stretch = Image.STRETCH_FILL;
  173. iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  174. result.addControl(iconImage);
  175. // Store
  176. result._image = iconImage;
  177. return result;
  178. }
  179. /**
  180. * Creates a new button made with a text
  181. * @param name defines the name of the button
  182. * @param text defines the text of the button
  183. * @returns a new Button
  184. */
  185. public static CreateSimpleButton(name: string, text: string): Button {
  186. var result = new Button(name);
  187. // Adding text
  188. var textBlock = new TextBlock(name + "_button", text);
  189. textBlock.textWrapping = true;
  190. textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
  191. result.addControl(textBlock);
  192. // Store
  193. result._textBlock = textBlock;
  194. return result;
  195. }
  196. /**
  197. * Creates a new button made with an image and a centered text
  198. * @param name defines the name of the button
  199. * @param text defines the text of the button
  200. * @param imageUrl defines the url of the image
  201. * @returns a new Button
  202. */
  203. public static CreateImageWithCenterTextButton(name: string, text: string, imageUrl: string): Button {
  204. var result = new Button(name);
  205. // Adding image
  206. var iconImage = new Image(name + "_icon", imageUrl);
  207. iconImage.stretch = Image.STRETCH_FILL;
  208. result.addControl(iconImage);
  209. // Adding text
  210. var textBlock = new TextBlock(name + "_button", text);
  211. textBlock.textWrapping = true;
  212. textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
  213. result.addControl(textBlock);
  214. // Store
  215. result._image = iconImage;
  216. result._textBlock = textBlock;
  217. return result;
  218. }
  219. }
  220. _TypeStore.RegisteredTypes["BABYLON.GUI.Button"] = Button;