checkbox.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import { Control } from "./control";
  2. import { Measure } from "../measure";
  3. import { Observable, Vector2 } from "babylonjs";
  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(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
  77. context.save();
  78. this._applyStates(context);
  79. if (this._processMeasures(parentMeasure, context)) {
  80. let actualWidth = this._currentMeasure.width - this._thickness;
  81. let actualHeight = this._currentMeasure.height - this._thickness;
  82. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  83. context.shadowColor = this.shadowColor;
  84. context.shadowBlur = this.shadowBlur;
  85. context.shadowOffsetX = this.shadowOffsetX;
  86. context.shadowOffsetY = this.shadowOffsetY;
  87. }
  88. context.fillStyle = this._isEnabled ? this._background : this._disabledColor;
  89. context.fillRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
  90. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  91. context.shadowBlur = 0;
  92. context.shadowOffsetX = 0;
  93. context.shadowOffsetY = 0;
  94. }
  95. if (this._isChecked) {
  96. context.fillStyle = this._isEnabled ? this.color : this._disabledColor;
  97. let offsetWidth = actualWidth * this._checkSizeRatio;
  98. let offseHeight = actualHeight * this._checkSizeRatio;
  99. context.fillRect(this._currentMeasure.left + this._thickness / 2 + (actualWidth - offsetWidth) / 2, this._currentMeasure.top + this._thickness / 2 + (actualHeight - offseHeight) / 2, offsetWidth, offseHeight);
  100. }
  101. context.strokeStyle = this.color;
  102. context.lineWidth = this._thickness;
  103. context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
  104. }
  105. context.restore();
  106. }
  107. // Events
  108. /** @hidden */
  109. public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
  110. if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
  111. return false;
  112. }
  113. this.isChecked = !this.isChecked;
  114. return true;
  115. }
  116. /**
  117. * Utility function to easily create a checkbox with a header
  118. * @param title defines the label to use for the header
  119. * @param onValueChanged defines the callback to call when value changes
  120. * @returns a StackPanel containing the checkbox and a textBlock
  121. */
  122. public static AddCheckBoxWithHeader(title: string, onValueChanged: (value: boolean) => void): StackPanel {
  123. var panel = new StackPanel();
  124. panel.isVertical = false;
  125. panel.height = "30px";
  126. var checkbox = new Checkbox();
  127. checkbox.width = "20px";
  128. checkbox.height = "20px";
  129. checkbox.isChecked = true;
  130. checkbox.color = "green";
  131. checkbox.onIsCheckedChangedObservable.add(onValueChanged);
  132. panel.addControl(checkbox);
  133. var header = new TextBlock();
  134. header.text = title;
  135. header.width = "180px";
  136. header.paddingLeft = "5px";
  137. header.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  138. header.color = "white";
  139. panel.addControl(header);
  140. return panel;
  141. }
  142. }