slider.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /// <reference path="../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON.GUI {
  3. export class Slider extends Control {
  4. private _thumbWidth = new ValueAndUnit(30, ValueAndUnit.UNITMODE_PIXEL, false);
  5. private _minimum = 0;
  6. private _maximum = 100;
  7. private _value = 50;
  8. private _background = "black";
  9. private _borderColor = "white";
  10. private _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
  11. private _isThumbCircle = false;
  12. public onValueChangedObservable = new Observable<number>();
  13. public get borderColor(): string {
  14. return this._borderColor;
  15. }
  16. public set borderColor(value: string) {
  17. if (this._borderColor === value) {
  18. return;
  19. }
  20. this._borderColor = value;
  21. this._markAsDirty();
  22. }
  23. public get background(): string {
  24. return this._background;
  25. }
  26. public set background(value: string) {
  27. if (this._background === value) {
  28. return;
  29. }
  30. this._background = value;
  31. this._markAsDirty();
  32. }
  33. public get barOffset(): string | number {
  34. return this._barOffset.toString(this._host);
  35. }
  36. public get barOffsetInPixels(): number {
  37. return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
  38. }
  39. public set barOffset(value: string | number) {
  40. if (this._barOffset.toString(this._host) === value) {
  41. return;
  42. }
  43. if (this._barOffset.fromString(value)) {
  44. this._markAsDirty();
  45. }
  46. }
  47. public get thumbWidth(): string | number {
  48. return this._thumbWidth.toString(this._host);
  49. }
  50. public get thumbWidthInPixels(): number {
  51. return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
  52. }
  53. public set thumbWidth(value: string | number) {
  54. if (this._thumbWidth.toString(this._host) === value) {
  55. return;
  56. }
  57. if (this._thumbWidth.fromString(value)) {
  58. this._markAsDirty();
  59. }
  60. }
  61. public get minimum(): number {
  62. return this._minimum;
  63. }
  64. public set minimum(value: number) {
  65. if (this._minimum === value) {
  66. return;
  67. }
  68. this._minimum = value;
  69. this._markAsDirty();
  70. this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
  71. }
  72. public get maximum(): number {
  73. return this._maximum;
  74. }
  75. public set maximum(value: number) {
  76. if (this._maximum === value) {
  77. return;
  78. }
  79. this._maximum = value;
  80. this._markAsDirty();
  81. this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
  82. }
  83. public get value(): number {
  84. return this._value;
  85. }
  86. public set value(value: number) {
  87. value = Math.max(Math.min(value, this._maximum), this._minimum);
  88. if (this._value === value) {
  89. return;
  90. }
  91. this._value = value;
  92. this._markAsDirty();
  93. this.onValueChangedObservable.notifyObservers(this._value);
  94. }
  95. public get isThumbCircle(): boolean {
  96. return this._isThumbCircle;
  97. }
  98. public set isThumbCircle(value: boolean) {
  99. if (this._isThumbCircle === value) {
  100. return;
  101. }
  102. this._isThumbCircle = value;
  103. this._markAsDirty();
  104. }
  105. constructor(public name?: string) {
  106. super(name);
  107. this.isPointerBlocker = true;
  108. }
  109. protected _getTypeName(): string {
  110. return "Slider";
  111. }
  112. public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
  113. context.save();
  114. this._applyStates(context);
  115. if (this._processMeasures(parentMeasure, context)) {
  116. // Main bar
  117. var effectiveThumbWidth;
  118. var effectiveBarOffset;
  119. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  120. context.shadowColor = this.shadowColor;
  121. context.shadowBlur = this.shadowBlur;
  122. context.shadowOffsetX = this.shadowOffsetX;
  123. context.shadowOffsetY = this.shadowOffsetY;
  124. }
  125. if (this._thumbWidth.isPixel) {
  126. effectiveThumbWidth = Math.min(this._thumbWidth.getValue(this._host), this._currentMeasure.width);
  127. } else {
  128. effectiveThumbWidth = this._currentMeasure.width * this._thumbWidth.getValue(this._host);
  129. }
  130. if (this._barOffset.isPixel) {
  131. effectiveBarOffset = Math.min(this._barOffset.getValue(this._host), this._currentMeasure.height);
  132. } else {
  133. effectiveBarOffset = this._currentMeasure.height * this._barOffset.getValue(this._host);
  134. }
  135. var left = this._currentMeasure.left + effectiveThumbWidth / 2;
  136. var width = this._currentMeasure.width - effectiveThumbWidth;
  137. var thumbPosition = (this._value - this._minimum) / (this._maximum - this._minimum) * width;
  138. // Bar
  139. context.fillStyle = this._background;
  140. context.fillRect(left, this._currentMeasure.top + effectiveBarOffset, width, this._currentMeasure.height - effectiveBarOffset * 2);
  141. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  142. context.shadowBlur = 0;
  143. context.shadowOffsetX = 0;
  144. context.shadowOffsetY = 0;
  145. }
  146. context.fillStyle = this.color;
  147. context.fillRect(left, this._currentMeasure.top + effectiveBarOffset, thumbPosition, this._currentMeasure.height - effectiveBarOffset * 2);
  148. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  149. context.shadowColor = this.shadowColor;
  150. context.shadowBlur = this.shadowBlur;
  151. context.shadowOffsetX = this.shadowOffsetX;
  152. context.shadowOffsetY = this.shadowOffsetY;
  153. }
  154. // Thumb
  155. if (this._isThumbCircle) {
  156. context.beginPath();
  157. context.arc(left + thumbPosition, this._currentMeasure.top + this._currentMeasure.height / 2, effectiveThumbWidth / 2, 0, 2 * Math.PI);
  158. context.fill();
  159. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  160. context.shadowBlur = 0;
  161. context.shadowOffsetX = 0;
  162. context.shadowOffsetY = 0;
  163. }
  164. context.strokeStyle = this._borderColor;
  165. context.stroke();
  166. }
  167. else {
  168. context.fillRect(left + thumbPosition - effectiveThumbWidth / 2, this._currentMeasure.top, effectiveThumbWidth, this._currentMeasure.height);
  169. if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
  170. context.shadowBlur = 0;
  171. context.shadowOffsetX = 0;
  172. context.shadowOffsetY = 0;
  173. }
  174. context.strokeStyle = this._borderColor;
  175. context.strokeRect(left + thumbPosition - effectiveThumbWidth / 2, this._currentMeasure.top, effectiveThumbWidth, this._currentMeasure.height);
  176. }
  177. }
  178. context.restore();
  179. }
  180. // Events
  181. private _pointerIsDown = false;
  182. private _updateValueFromPointer(x: number, y: number): void {
  183. if (this.rotation != 0) {
  184. this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
  185. x = this._transformedPosition.x;
  186. }
  187. this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
  188. }
  189. public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
  190. if (!super._onPointerDown(target, coordinates, buttonIndex)) {
  191. return false;
  192. }
  193. this._pointerIsDown = true;
  194. this._updateValueFromPointer(coordinates.x, coordinates.y);
  195. this._host._capturingControl = this;
  196. return true;
  197. }
  198. public _onPointerMove(target: Control, coordinates: Vector2): void {
  199. if (this._pointerIsDown) {
  200. this._updateValueFromPointer(coordinates.x, coordinates.y);
  201. }
  202. super._onPointerMove(target, coordinates);
  203. }
  204. public _onPointerUp(target: Control, coordinates: Vector2, buttonIndex: number): void {
  205. this._pointerIsDown = false;
  206. this._host._capturingControl = null;
  207. super._onPointerUp(target, coordinates, buttonIndex);
  208. }
  209. }
  210. }