button.ts 8.3 KB

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