checkbox.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import { Observable } from "babylonjs/Misc/observable";
  2. import { Vector2 } from "babylonjs/Maths/math";
  3. import { Control } from "./control";
  4. import { StackPanel } from "./stackPanel";
  5. import { TextBlock } from "./textBlock";
  6. /**
  7. * Class used to represent a 2D checkbox
  8. */
  9. export class Checkbox extends Control {
  10. private _isChecked = false;
  11. private _background = "black";
  12. private _checkSizeRatio = 0.8;
  13. private _thickness = 1;
  14. /** Gets or sets border thickness */
  15. public get thickness(): number {
  16. return this._thickness;
  17. }
  18. public set thickness(value: number) {
  19. if (this._thickness === value) {
  20. return;
  21. }
  22. this._thickness = value;
  23. this._markAsDirty();
  24. }
  25. /**
  26. * Observable raised when isChecked property changes
  27. */
  28. public onIsCheckedChangedObservable = new Observable<boolean>();
  29. /** Gets or sets a value indicating the ratio between overall size and check size */
  30. public get checkSizeRatio(): number {
  31. return this._checkSizeRatio;
  32. }
  33. public set checkSizeRatio(value: number) {
  34. value = Math.max(Math.min(1, value), 0);
  35. if (this._checkSizeRatio === value) {
  36. return;
  37. }
  38. this._checkSizeRatio = value;
  39. this._markAsDirty();
  40. }
  41. /** Gets or sets background color */
  42. public get background(): string {
  43. return this._background;
  44. }
  45. public set background(value: string) {
  46. if (this._background === value) {
  47. return;
  48. }
  49. this._background = value;
  50. this._markAsDirty();
  51. }
  52. /** Gets or sets a boolean indicating if the checkbox is checked or not */
  53. public get isChecked(): boolean {
  54. return this._isChecked;
  55. }
  56. public set isChecked(value: boolean) {
  57. if (this._isChecked === value) {
  58. return;
  59. }
  60. this._isChecked = value;
  61. this._markAsDirty();
  62. this.onIsCheckedChangedObservable.notifyObservers(value);
  63. }
  64. /**
  65. * Creates a new CheckBox
  66. * @param name defines the control name
  67. */
  68. constructor(public name?: string) {
  69. super(name);
  70. this.isPointerBlocker = true;
  71. }
  72. protected _getTypeName(): string {
  73. return "Checkbox";
  74. }
  75. /** @hidden */
  76. public _draw(context: CanvasRenderingContext2D): void {
  77. context.save();
  78. this._applyStates(context);
  79. let actualWidth = this._currentMeasure.width - this._thickness;
  80. let actualHeight = this._currentMeasure.height - this._thickness;
  81. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  82. context.shadowColor = this.shadowColor;
  83. context.shadowBlur = this.shadowBlur;
  84. context.shadowOffsetX = this.shadowOffsetX;
  85. context.shadowOffsetY = this.shadowOffsetY;
  86. }
  87. context.fillStyle = this._isEnabled ? this._background : this._disabledColor;
  88. context.fillRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
  89. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  90. context.shadowBlur = 0;
  91. context.shadowOffsetX = 0;
  92. context.shadowOffsetY = 0;
  93. }
  94. if (this._isChecked) {
  95. context.fillStyle = this._isEnabled ? this.color : this._disabledColor;
  96. let offsetWidth = actualWidth * this._checkSizeRatio;
  97. let offseHeight = actualHeight * this._checkSizeRatio;
  98. context.fillRect(this._currentMeasure.left + this._thickness / 2 + (actualWidth - offsetWidth) / 2, this._currentMeasure.top + this._thickness / 2 + (actualHeight - offseHeight) / 2, offsetWidth, offseHeight);
  99. }
  100. context.strokeStyle = this.color;
  101. context.lineWidth = this._thickness;
  102. context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
  103. context.restore();
  104. }
  105. // Events
  106. /** @hidden */
  107. public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
  108. if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
  109. return false;
  110. }
  111. this.isChecked = !this.isChecked;
  112. return true;
  113. }
  114. /**
  115. * Utility function to easily create a checkbox with a header
  116. * @param title defines the label to use for the header
  117. * @param onValueChanged defines the callback to call when value changes
  118. * @returns a StackPanel containing the checkbox and a textBlock
  119. */
  120. public static AddCheckBoxWithHeader(title: string, onValueChanged: (value: boolean) => void): StackPanel {
  121. var panel = new StackPanel();
  122. panel.isVertical = false;
  123. panel.height = "30px";
  124. var checkbox = new Checkbox();
  125. checkbox.width = "20px";
  126. checkbox.height = "20px";
  127. checkbox.isChecked = true;
  128. checkbox.color = "green";
  129. checkbox.onIsCheckedChangedObservable.add(onValueChanged);
  130. panel.addControl(checkbox);
  131. var header = new TextBlock();
  132. header.text = title;
  133. header.width = "180px";
  134. header.paddingLeft = "5px";
  135. header.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  136. header.color = "white";
  137. panel.addControl(header);
  138. return panel;
  139. }
  140. }