瀏覽代碼

ImageBasedSlider - step2 - #5316

David Catuhe 6 年之前
父節點
當前提交
8df0cba577

+ 284 - 0
gui/src/2D/controls/baseSlider.ts

@@ -0,0 +1,284 @@
+import { Control } from "./control";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Observable, Vector2 } from "babylonjs";
+
+/**
+ * Class used to create slider controls
+ */
+export class BaseSlider extends Control {
+    protected _thumbWidth = new ValueAndUnit(20, ValueAndUnit.UNITMODE_PIXEL, false);
+    private _minimum = 0;
+    private _maximum = 100;
+    private _value = 50;
+    private _isVertical = false;
+    protected _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
+    private _isThumbClamped = false;
+
+    // Shared rendering info
+    protected _effectiveBarOffset = 0;
+    protected _renderLeft: number;
+    protected _renderTop: number;
+    protected _renderWidth: number;
+    protected _renderHeight: number;
+    protected _backgroundBoxLength: number;
+    protected _backgroundBoxThickness: number;
+    protected _effectiveThumbThickness: number;
+
+    /** Observable raised when the sldier value changes */
+    public onValueChangedObservable = new Observable<number>();
+
+    /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
+    public get barOffset(): string | number {
+        return this._barOffset.toString(this._host);
+    }
+
+    /** Gets main bar offset in pixels*/
+    public get barOffsetInPixels(): number {
+        return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
+
+    public set barOffset(value: string | number) {
+        if (this._barOffset.toString(this._host) === value) {
+            return;
+        }
+
+        if (this._barOffset.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
+
+    /** Gets or sets thumb width */
+    public get thumbWidth(): string | number {
+        return this._thumbWidth.toString(this._host);
+    }
+
+    /** Gets thumb width in pixels */
+    public get thumbWidthInPixels(): number {
+        return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
+
+    public set thumbWidth(value: string | number) {
+        if (this._thumbWidth.toString(this._host) === value) {
+            return;
+        }
+
+        if (this._thumbWidth.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
+
+    /** Gets or sets minimum value */
+    public get minimum(): number {
+        return this._minimum;
+    }
+
+    public set minimum(value: number) {
+        if (this._minimum === value) {
+            return;
+        }
+
+        this._minimum = value;
+        this._markAsDirty();
+
+        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    }
+
+    /** Gets or sets maximum value */
+    public get maximum(): number {
+        return this._maximum;
+    }
+
+    public set maximum(value: number) {
+        if (this._maximum === value) {
+            return;
+        }
+
+        this._maximum = value;
+        this._markAsDirty();
+
+        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    }
+
+    /** Gets or sets current value */
+    public get value(): number {
+        return this._value;
+    }
+
+    public set value(value: number) {
+        value = Math.max(Math.min(value, this._maximum), this._minimum);
+
+        if (this._value === value) {
+            return;
+        }
+
+        this._value = value;
+        this._markAsDirty();
+        this.onValueChangedObservable.notifyObservers(this._value);
+    }
+
+    /**Gets or sets a boolean indicating if the slider should be vertical or horizontal */
+    public get isVertical(): boolean {
+        return this._isVertical;
+    }
+
+    public set isVertical(value: boolean) {
+        if (this._isVertical === value) {
+            return;
+        }
+
+        this._isVertical = value;
+        this._markAsDirty();
+    }
+
+
+    /** Gets or sets a value indicating if the thumb can go over main bar extends */
+    public get isThumbClamped(): boolean {
+        return this._isThumbClamped;
+    }
+
+    public set isThumbClamped(value: boolean) {
+        if (this._isThumbClamped === value) {
+            return;
+        }
+
+        this._isThumbClamped = value;
+        this._markAsDirty();
+    }
+
+    /**
+     * Creates a new BaseSlider
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+
+        this.isPointerBlocker = true;
+    }
+
+    protected _getTypeName(): string {
+        return "BaseSlider";
+    }
+
+    protected _getThumbPosition() {
+        if (this.isVertical) {
+            return ((this.maximum - this.value) / (this.maximum - this.minimum)) * this._backgroundBoxLength;
+        }
+
+        return ((this.value - this.minimum) / (this.maximum - this.minimum)) * this._backgroundBoxLength;
+    }
+
+    protected _getThumbThickness(type: string): number {
+        var thumbThickness = 0;
+        switch (type) {
+            case "circle":
+                if (this._thumbWidth.isPixel) {
+                    thumbThickness = Math.max(this._thumbWidth.getValue(this._host), this._backgroundBoxThickness);
+                }
+                else {
+                    thumbThickness = this._backgroundBoxThickness * this._thumbWidth.getValue(this._host);
+                }
+                break;
+            case "rectangle":
+                if (this._thumbWidth.isPixel) {
+                    thumbThickness = Math.min(this._thumbWidth.getValue(this._host), this._backgroundBoxThickness);
+                }
+                else {
+                    thumbThickness = this._backgroundBoxThickness * this._thumbWidth.getValue(this._host);
+                }
+        }
+        return thumbThickness;
+    }
+
+    protected _prepareRenderingData(type: string) {
+        // Main bar
+        this._effectiveBarOffset = 0;
+        this._renderLeft = this._currentMeasure.left;
+        this._renderTop = this._currentMeasure.top;
+        this._renderWidth = this._currentMeasure.width;
+        this._renderHeight = this._currentMeasure.height;
+
+        this._backgroundBoxLength = Math.max(this._currentMeasure.width, this._currentMeasure.height);
+        this._backgroundBoxThickness = Math.min(this._currentMeasure.width, this._currentMeasure.height);
+        this._effectiveThumbThickness = this._getThumbThickness(type);
+
+        this._backgroundBoxLength -= this._effectiveThumbThickness;
+        //throw error when height is less than width for vertical slider
+        if ((this.isVertical && this._currentMeasure.height < this._currentMeasure.width)) {
+            console.error("Height should be greater than width");
+            return;
+        }
+        if (this._barOffset.isPixel) {
+            this._effectiveBarOffset = Math.min(this._barOffset.getValue(this._host), this._backgroundBoxThickness);
+        }
+        else {
+            this._effectiveBarOffset = this._backgroundBoxThickness * this._barOffset.getValue(this._host);
+        }
+
+        this._backgroundBoxThickness -= (this._effectiveBarOffset * 2);
+
+        if (this.isVertical) {
+            this._renderLeft += this._effectiveBarOffset;
+            if (!this.isThumbClamped) {
+                this._renderTop += (this._effectiveThumbThickness / 2);
+            }
+
+            this._renderHeight = this._backgroundBoxLength;
+            this._renderWidth = this._backgroundBoxThickness;
+
+        }
+        else {
+            this._renderTop += this._effectiveBarOffset;
+            if (!this.isThumbClamped) {
+                this._renderLeft += (this._effectiveThumbThickness / 2);
+            }
+            this._renderHeight = this._backgroundBoxThickness;
+            this._renderWidth = this._backgroundBoxLength;
+        }
+    }
+
+    // Events
+    private _pointerIsDown = false;
+
+    private _updateValueFromPointer(x: number, y: number): void {
+        if (this.rotation != 0) {
+            this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
+            x = this._transformedPosition.x;
+            y = this._transformedPosition.y;
+        }
+
+        if (this._isVertical) {
+            this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
+        }
+        else {
+            this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
+        }
+    }
+
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
+        }
+
+        this._pointerIsDown = true;
+
+        this._updateValueFromPointer(coordinates.x, coordinates.y);
+        this._host._capturingControl[pointerId] = this;
+
+        return true;
+    }
+
+    public _onPointerMove(target: Control, coordinates: Vector2): void {
+        if (this._pointerIsDown) {
+            this._updateValueFromPointer(coordinates.x, coordinates.y);
+        }
+
+        super._onPointerMove(target, coordinates);
+    }
+
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        this._pointerIsDown = false;
+
+        delete this._host._capturingControl[pointerId];
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
+}

+ 20 - 1
gui/src/2D/controls/image.ts

@@ -1,5 +1,5 @@
 import { Control } from "./control";
-import { Nullable, Tools } from "babylonjs";
+import { Nullable, Tools, Observable } from "babylonjs";
 import { Measure } from "../measure";
 
 /**
@@ -24,6 +24,18 @@ export class Image extends Control {
     private _cellId: number = -1;
 
     /**
+     * Observable notified when the content is loaded
+     */
+    public onImageLoadedObservable = new Observable<Image>();
+
+    /**
+     * Gets a boolean indicating that the content is loaded
+     */
+    public get isLoaded(): boolean {
+        return this._loaded;
+    }
+
+    /**
      * Gets or sets the left coordinate in the source image
      */
     public get sourceLeft(): number {
@@ -155,6 +167,8 @@ export class Image extends Control {
             this.synchronizeSizeWithContent();
         }
 
+        this.onImageLoadedObservable.notifyObservers(this);
+
         this._markAsDirty();
     }
 
@@ -321,6 +335,11 @@ export class Image extends Control {
         context.restore();
     }
 
+    public dispose() {
+        super.dispose();
+        this.onImageLoadedObservable.clear();
+    }
+
     // Static
     /** STRETCH_NONE */
     public static readonly STRETCH_NONE = 0;

+ 107 - 0
gui/src/2D/controls/imageBasedSlider.ts

@@ -0,0 +1,107 @@
+import { BaseSlider } from "./baseslider";
+import { Measure } from "../measure";
+import { Image } from "./image";
+
+/**
+ * Class used to create slider controls based on images
+ */
+export class ImageBasedSlider extends BaseSlider {
+    private _backgroundImage: Image;
+    private _thumbImage: Image;
+    private _valueBarImage: Image;
+
+    private _tempMeasure = new Measure(0, 0, 0, 0);
+
+    /**
+     * Gets or sets the image used to render the background
+     */
+    public get backgroundImage(): Image {
+        return this._backgroundImage;
+    }
+
+    public set backgroundImage(value: Image) {
+        if (this._backgroundImage === value) {
+            return;
+        }
+
+        this._backgroundImage = value;
+
+        if (value && !value.isLoaded) {
+            value.onImageLoadedObservable.addOnce(() => this._markAsDirty());
+        }
+
+        this._markAsDirty();
+    }
+
+    /**
+     * Gets or sets the image used to render the thumb
+     */
+    public get thumbImage(): Image {
+        return this._thumbImage;
+    }
+
+    public set thumbImage(value: Image) {
+        if (this._thumbImage === value) {
+            return;
+        }
+
+        this._thumbImage = value;
+
+        if (value && !value.isLoaded) {
+            value.onImageLoadedObservable.addOnce(() => this._markAsDirty());
+        }
+
+        this._markAsDirty();
+    }
+
+    /**
+     * Creates a new ImageBasedSlider
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
+
+    protected _getTypeName(): string {
+        return "ImageBasedSlider";
+    }
+
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+
+            this._prepareRenderingData("rectangle");
+            const thumbPosition = this._getThumbPosition();
+            var left = this._renderLeft;
+            var top = this._renderTop;
+            var width = this._renderWidth;
+            var height = this._renderHeight;
+
+
+            // Background
+            if (this._backgroundImage) {
+                this._tempMeasure.copyFromFloats(left, top, width, height);
+                this._backgroundImage._draw(this._tempMeasure, context);
+            }
+
+            // Bar
+            if (this._valueBarImage) {
+
+            }
+
+            // Thumb
+            if (this._thumbImage) {
+                if (this.isVertical) {
+                    this._tempMeasure.copyFromFloats(left - this._effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, this._effectiveThumbThickness);
+                } else {
+                    this._tempMeasure.copyFromFloats(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, this._effectiveThumbThickness, this._currentMeasure.height);
+                }
+                this._thumbImage._draw(this._tempMeasure, context);
+            }
+        }
+
+        context.restore();
+    }
+}

+ 3 - 1
gui/src/2D/controls/index.ts

@@ -15,8 +15,10 @@ export * from "./stackPanel";
 export * from "./selector";
 export * from "./textBlock";
 export * from "./virtualKeyboard";
-export * from "./slider";
 export * from "./rectangle";
 export * from "./displayGrid";
+export * from "./baseslider";
+export * from "./slider";
+export * from "./imageBasedSlider";
 
 export * from "./statics";

+ 31 - 270
gui/src/2D/controls/slider.ts

@@ -1,27 +1,15 @@
-import { Control } from "./control";
-import { ValueAndUnit } from "../valueAndUnit";
-import { Observable, Vector2 } from "babylonjs";
 import { Measure } from "../measure";
+import { BaseSlider } from "./baseSlider";
 
 /**
  * Class used to create slider controls
  */
-export class Slider extends Control {
-    private _thumbWidth = new ValueAndUnit(20, ValueAndUnit.UNITMODE_PIXEL, false);
-    private _minimum = 0;
-    private _maximum = 100;
-    private _value = 50;
-    private _isVertical = false;
+export class Slider extends BaseSlider {
     private _background = "black";
     private _borderColor = "white";
-    private _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
     private _isThumbCircle = false;
-    private _isThumbClamped = false;
     private _displayThumb = true;
 
-    /** Observable raised when the sldier value changes */
-    public onValueChangedObservable = new Observable<number>();
-
     /** Gets or sets a boolean indicating if the thumb must be rendered */
     public get displayThumb(): boolean {
         return this._displayThumb;
@@ -64,109 +52,6 @@ export class Slider extends Control {
         this._markAsDirty();
     }
 
-    /** Gets or sets main bar offset */
-    public get barOffset(): string | number {
-        return this._barOffset.toString(this._host);
-    }
-
-    /** Gets main bar offset in pixels*/
-    public get barOffsetInPixels(): number {
-        return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
-    }
-
-    public set barOffset(value: string | number) {
-        if (this._barOffset.toString(this._host) === value) {
-            return;
-        }
-
-        if (this._barOffset.fromString(value)) {
-            this._markAsDirty();
-        }
-    }
-
-    /** Gets or sets thumb width */
-    public get thumbWidth(): string | number {
-        return this._thumbWidth.toString(this._host);
-    }
-
-    /** Gets thumb width in pixels */
-    public get thumbWidthInPixels(): number {
-        return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
-    }
-
-    public set thumbWidth(value: string | number) {
-        if (this._thumbWidth.toString(this._host) === value) {
-            return;
-        }
-
-        if (this._thumbWidth.fromString(value)) {
-            this._markAsDirty();
-        }
-    }
-
-    /** Gets or sets minimum value */
-    public get minimum(): number {
-        return this._minimum;
-    }
-
-    public set minimum(value: number) {
-        if (this._minimum === value) {
-            return;
-        }
-
-        this._minimum = value;
-        this._markAsDirty();
-
-        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
-    }
-
-    /** Gets or sets maximum value */
-    public get maximum(): number {
-        return this._maximum;
-    }
-
-    public set maximum(value: number) {
-        if (this._maximum === value) {
-            return;
-        }
-
-        this._maximum = value;
-        this._markAsDirty();
-
-        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
-    }
-
-    /** Gets or sets current value */
-    public get value(): number {
-        return this._value;
-    }
-
-    public set value(value: number) {
-        value = Math.max(Math.min(value, this._maximum), this._minimum);
-
-        if (this._value === value) {
-            return;
-        }
-
-        this._value = value;
-        this._markAsDirty();
-        this.onValueChangedObservable.notifyObservers(this._value);
-    }
-
-    /**Gets or sets a boolean indicating if the slider should be vertical or horizontal */
-    public get isVertical(): boolean {
-        return this._isVertical;
-    }
-
-    public set isVertical(value: boolean) {
-        if (this._isVertical === value) {
-            return;
-        }
-
-        this._isVertical = value;
-        this._markAsDirty();
-    }
-
     /** Gets or sets a boolean indicating if the thumb should be round or square */
     public get isThumbCircle(): boolean {
         return this._isThumbCircle;
@@ -181,122 +66,44 @@ export class Slider extends Control {
         this._markAsDirty();
     }
 
-    /** Gets or sets a value indicating if the thumb can go over main bar extends */
-    public get isThumbClamped(): boolean {
-        return this._isThumbClamped;
-    }
-
-    public set isThumbClamped(value: boolean) {
-        if (this._isThumbClamped === value) {
-            return;
-        }
-
-        this._isThumbClamped = value;
-        this._markAsDirty();
-    }
-
     /**
      * Creates a new Slider
      * @param name defines the control name
      */
     constructor(public name?: string) {
         super(name);
-
-        this.isPointerBlocker = true;
     }
 
     protected _getTypeName(): string {
         return "Slider";
     }
 
-    protected _getThumbThickness(type: string, backgroundLength: number): number {
-        var thumbThickness = 0;
-        switch (type) {
-            case "circle":
-                if (this._thumbWidth.isPixel) {
-                    thumbThickness = Math.max(this._thumbWidth.getValue(this._host), backgroundLength);
-                }
-                else {
-                    thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
-                }
-                break;
-            case "rectangle":
-                if (this._thumbWidth.isPixel) {
-                    thumbThickness = Math.min(this._thumbWidth.getValue(this._host), backgroundLength);
-                }
-                else {
-                    thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
-                }
-        }
-        return thumbThickness;
-    }
-
     public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
         context.save();
 
         this._applyStates(context);
         if (this._processMeasures(parentMeasure, context)) {
-            // Main bar
-            var effectiveBarOffset = 0;
-            var type = this.isThumbCircle ? "circle" : "rectangle";
-            var left = this._currentMeasure.left;
-            var top = this._currentMeasure.top;
-            var width = this._currentMeasure.width;
-            var height = this._currentMeasure.height;
-
-            var backgroundBoxLength = Math.max(this._currentMeasure.width, this._currentMeasure.height);
-            var backgroundBoxThickness = Math.min(this._currentMeasure.width, this._currentMeasure.height);
 
-            var effectiveThumbThickness = this._getThumbThickness(type, backgroundBoxThickness);
-            backgroundBoxLength -= effectiveThumbThickness;
+            this._prepareRenderingData(this.isThumbCircle ? "circle" : "rectangle");
+            var left = this._renderLeft;
+            var top = this._renderTop;
+            var width = this._renderWidth;
+            var height = this._renderHeight;
 
             var radius = 0;
 
-            //throw error when height is less than width for vertical slider
-            if ((this._isVertical && this._currentMeasure.height < this._currentMeasure.width)) {
-                console.error("Height should be greater than width");
-                return;
-            }
-            if (this._barOffset.isPixel) {
-                effectiveBarOffset = Math.min(this._barOffset.getValue(this._host), backgroundBoxThickness);
-            }
-            else {
-                effectiveBarOffset = backgroundBoxThickness * this._barOffset.getValue(this._host);
-            }
-
-            backgroundBoxThickness -= (effectiveBarOffset * 2);
-
-            if (this._isVertical) {
-                left += effectiveBarOffset;
-                if (!this.isThumbClamped) {
-                    top += (effectiveThumbThickness / 2);
-                }
-
-                height = backgroundBoxLength;
-                width = backgroundBoxThickness;
-
-            }
-            else {
-                top += effectiveBarOffset;
-                if (!this.isThumbClamped) {
-                    left += (effectiveThumbThickness / 2);
-                }
-                height = backgroundBoxThickness;
-                width = backgroundBoxLength;
-            }
-
             if (this.isThumbClamped && this.isThumbCircle) {
-                if (this._isVertical) {
-                    top += (effectiveThumbThickness / 2);
+                if (this.isVertical) {
+                    top += (this._effectiveThumbThickness / 2);
                 }
                 else {
-                    left += (effectiveThumbThickness / 2);
+                    left += (this._effectiveThumbThickness / 2);
                 }
 
-                radius = backgroundBoxThickness / 2;
+                radius = this._backgroundBoxThickness / 2;
             }
             else {
-                radius = (effectiveThumbThickness - effectiveBarOffset) / 2;
+                radius = (this._effectiveThumbThickness - this._effectiveBarOffset) / 2;
             }
 
             if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
@@ -306,19 +113,19 @@ export class Slider extends Control {
                 context.shadowOffsetY = this.shadowOffsetY;
             }
 
-            var thumbPosition = (this._isVertical) ? ((this._maximum - this._value) / (this._maximum - this._minimum)) * backgroundBoxLength : ((this._value - this._minimum) / (this._maximum - this._minimum)) * backgroundBoxLength;
+            const thumbPosition = this._getThumbPosition();
             context.fillStyle = this._background;
 
-            if (this._isVertical) {
+            if (this.isVertical) {
                 if (this.isThumbClamped) {
                     if (this.isThumbCircle) {
                         context.beginPath();
-                        context.arc(left + backgroundBoxThickness / 2, top, radius, Math.PI, 2 * Math.PI);
+                        context.arc(left + this._backgroundBoxThickness / 2, top, radius, Math.PI, 2 * Math.PI);
                         context.fill();
                         context.fillRect(left, top, width, height);
                     }
                     else {
-                        context.fillRect(left, top, width, height + effectiveThumbThickness);
+                        context.fillRect(left, top, width, height + this._effectiveThumbThickness);
                     }
                 }
                 else {
@@ -329,12 +136,12 @@ export class Slider extends Control {
                 if (this.isThumbClamped) {
                     if (this.isThumbCircle) {
                         context.beginPath();
-                        context.arc(left + backgroundBoxLength, top + (backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
+                        context.arc(left + this._backgroundBoxLength, top + (this._backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
                         context.fill();
                         context.fillRect(left, top, width, height);
                     }
                     else {
-                        context.fillRect(left, top, width + effectiveThumbThickness, height);
+                        context.fillRect(left, top, width + this._effectiveThumbThickness, height);
                     }
                 }
                 else {
@@ -350,11 +157,11 @@ export class Slider extends Control {
 
             // Value bar
             context.fillStyle = this.color;
-            if (this._isVertical) {
+            if (this.isVertical) {
                 if (this.isThumbClamped) {
                     if (this.isThumbCircle) {
                         context.beginPath();
-                        context.arc(left + backgroundBoxThickness / 2, top + backgroundBoxLength, radius, 0, 2 * Math.PI);
+                        context.arc(left + this._backgroundBoxThickness / 2, top + this._backgroundBoxLength, radius, 0, 2 * Math.PI);
                         context.fill();
                         context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
                     }
@@ -370,7 +177,7 @@ export class Slider extends Control {
                 if (this.isThumbClamped) {
                     if (this.isThumbCircle) {
                         context.beginPath();
-                        context.arc(left, top + backgroundBoxThickness / 2, radius, 0, 2 * Math.PI);
+                        context.arc(left, top + this._backgroundBoxThickness / 2, radius, 0, 2 * Math.PI);
                         context.fill();
                         context.fillRect(left, top, thumbPosition, height);
                     }
@@ -384,7 +191,7 @@ export class Slider extends Control {
             }
 
             // Thumb
-            if (this._displayThumb) {
+            if (this.displayThumb) {
                 if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                     context.shadowColor = this.shadowColor;
                     context.shadowBlur = this.shadowBlur;
@@ -393,11 +200,11 @@ export class Slider extends Control {
                 }
                 if (this._isThumbCircle) {
                     context.beginPath();
-                    if (this._isVertical) {
-                        context.arc(left + backgroundBoxThickness / 2, top + thumbPosition, radius, 0, 2 * Math.PI);
+                    if (this.isVertical) {
+                        context.arc(left + this._backgroundBoxThickness / 2, top + thumbPosition, radius, 0, 2 * Math.PI);
                     }
                     else {
-                        context.arc(left + thumbPosition, top + (backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
+                        context.arc(left + thumbPosition, top + (this._backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
                     }
                     context.fill();
                     if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
@@ -409,11 +216,11 @@ export class Slider extends Control {
                     context.stroke();
                 }
                 else {
-                    if (this._isVertical) {
-                        context.fillRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
+                    if (this.isVertical) {
+                        context.fillRect(left - this._effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, this._effectiveThumbThickness);
                     }
                     else {
-                        context.fillRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
+                        context.fillRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, this._effectiveThumbThickness, this._currentMeasure.height);
                     }
                     if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                         context.shadowBlur = 0;
@@ -421,61 +228,15 @@ export class Slider extends Control {
                         context.shadowOffsetY = 0;
                     }
                     context.strokeStyle = this._borderColor;
-                    if (this._isVertical) {
-                        context.strokeRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
+                    if (this.isVertical) {
+                        context.strokeRect(left - this._effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, this._effectiveThumbThickness);
                     }
                     else {
-                        context.strokeRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
+                        context.strokeRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, this._effectiveThumbThickness, this._currentMeasure.height);
                     }
                 }
             }
         }
         context.restore();
     }
-
-    // Events
-    private _pointerIsDown = false;
-
-    private _updateValueFromPointer(x: number, y: number): void {
-        if (this.rotation != 0) {
-            this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
-            x = this._transformedPosition.x;
-            y = this._transformedPosition.y;
-        }
-
-        if (this._isVertical) {
-            this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
-        }
-        else {
-            this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
-        }
-    }
-
-    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
-        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-            return false;
-        }
-
-        this._pointerIsDown = true;
-
-        this._updateValueFromPointer(coordinates.x, coordinates.y);
-        this._host._capturingControl[pointerId] = this;
-
-        return true;
-    }
-
-    public _onPointerMove(target: Control, coordinates: Vector2): void {
-        if (this._pointerIsDown) {
-            this._updateValueFromPointer(coordinates.x, coordinates.y);
-        }
-
-        super._onPointerMove(target, coordinates);
-    }
-
-    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
-        this._pointerIsDown = false;
-
-        delete this._host._capturingControl[pointerId];
-        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
-    }
 }

+ 14 - 0
gui/src/2D/measure.ts

@@ -34,6 +34,20 @@ export class Measure {
     }
 
     /**
+     * Copy from a group of 4 floats
+     * @param left defines left coordinate
+     * @param top defines top coordinate
+     * @param width defines width dimension
+     * @param height defines height dimension
+     */
+    public copyFromFloats(left: number, top: number, width: number, height: number): void {
+        this.left = left;
+        this.top = top;
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
      * Check equality between this measure and another one
      * @param other defines the other measures
      * @returns true if both measures are equals