Ver código fonte

Merge pull request #2951 from royibernthal/master

GUI Event Bubbling
David Catuhe 7 anos atrás
pai
commit
9d9c43533f

+ 3 - 3
gui/src/advancedDynamicTexture.ts

@@ -322,7 +322,7 @@ module BABYLON.GUI {
 
                 if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (this._lastControlOver) {
-                        this._lastControlOver._onPointerOut();
+                        this._lastControlOver._onPointerOut(this._lastControlOver);
                     }
                     
                     this._lastControlOver = null;
@@ -378,7 +378,7 @@ module BABYLON.GUI {
                     this.focusedControl = null;
                 } else if (pi.type === BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (this._lastControlOver) {
-                        this._lastControlOver._onPointerOut();
+                        this._lastControlOver._onPointerOut(this._lastControlOver);
                     }              
                     this._lastControlOver = null;
                 }
@@ -416,7 +416,7 @@ module BABYLON.GUI {
         private _attachToOnPointerOut(scene: Scene): void {
             this._canvasPointerOutObserver = scene.getEngine().onCanvasPointerOutObservable.add(() => {
                 if (this._lastControlOver) {
-                    this._lastControlOver._onPointerOut();
+                    this._lastControlOver._onPointerOut(this._lastControlOver);
                 }            
                 this._lastControlOver = null;
 

+ 8 - 8
gui/src/controls/button.ts

@@ -51,8 +51,8 @@ module BABYLON.GUI {
             return true;
         }
 
-        protected _onPointerEnter(): boolean {
-            if (!super._onPointerEnter()) {
+        public _onPointerEnter(target: Control): boolean {
+            if (!super._onPointerEnter(target)) {
                 return false;
             }
 
@@ -63,16 +63,16 @@ module BABYLON.GUI {
             return true;
         }
 
-        public _onPointerOut(): void {
+        public _onPointerOut(target: Control): void {
             if (this.pointerOutAnimation) {
                 this.pointerOutAnimation();
             }
 
-            super._onPointerOut();
+            super._onPointerOut(target);
         }
 
-        protected _onPointerDown(coordinates: Vector2, buttonIndex: number): boolean {
-            if (!super._onPointerDown(coordinates, buttonIndex)) {
+        public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
+            if (!super._onPointerDown(target, coordinates, buttonIndex)) {
                 return false;
             }
 
@@ -84,12 +84,12 @@ module BABYLON.GUI {
             return true;
         }
 
-        protected _onPointerUp(coordinates: Vector2, buttonIndex: number): void {
+        public _onPointerUp(target: Control, coordinates: Vector2, buttonIndex: number): void {
             if (this.pointerUpAnimation) {
                 this.pointerUpAnimation();
             }
 
-            super._onPointerUp(coordinates, buttonIndex);
+            super._onPointerUp(target, coordinates, buttonIndex);
         }        
 
         // Statics

+ 2 - 2
gui/src/controls/checkbox.ts

@@ -102,8 +102,8 @@ module BABYLON.GUI {
         }
 
         // Events
-        protected _onPointerDown(coordinates: Vector2, buttonIndex: number): boolean {
-            if (!super._onPointerDown(coordinates, buttonIndex)) {
+        public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
+            if (!super._onPointerDown(target, coordinates, buttonIndex)) {
                 return false;
             }
 

+ 6 - 6
gui/src/controls/colorpicker.ts

@@ -362,8 +362,8 @@ module BABYLON.GUI {
             return false;
         }
 
-        protected _onPointerDown(coordinates: Vector2, buttonIndex: number): boolean {
-            if (!super._onPointerDown(coordinates, buttonIndex)) {
+        public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
+            if (!super._onPointerDown(target, coordinates, buttonIndex)) {
                 return false;
             }            
 
@@ -384,19 +384,19 @@ module BABYLON.GUI {
             return true;
         }
 
-        protected _onPointerMove(coordinates: Vector2): void {
+        public _onPointerMove(target: Control, coordinates: Vector2): void {
             if (this._pointerIsDown) {
                 this._updateValueFromPointer(coordinates.x, coordinates.y);
             }
 
-            super._onPointerMove(coordinates);
+            super._onPointerMove(target, coordinates);
         }
 
-        protected _onPointerUp (coordinates: Vector2, buttonIndex: number): void {
+        public _onPointerUp (target: Control, coordinates: Vector2, buttonIndex: number): void {
             this._pointerIsDown = false;
             
             this._host._capturingControl = null;
-            super._onPointerUp(coordinates, buttonIndex);
+            super._onPointerUp(target, coordinates, buttonIndex);
         }     
     }    
 }

+ 4 - 0
gui/src/controls/container.ts

@@ -76,6 +76,8 @@ module BABYLON.GUI {
 
             if (index !== -1) {
                 this._children.splice(index, 1);
+
+                control.parent = null;
             }
 
             this._markAsDirty();
@@ -94,6 +96,8 @@ module BABYLON.GUI {
 
             this._children.push(control);
 
+            control.parent = this;
+
             this._markAsDirty();
         }
 

+ 32 - 27
gui/src/controls/control.ts

@@ -7,6 +7,7 @@ module BABYLON.GUI {
         private _zIndex = 0;
         public _root: Container;
         public _host: AdvancedDynamicTexture;
+        public parent: Container;
         public _currentMeasure = Measure.Empty();
         private _fontFamily = "Arial";
         private _fontStyle = "";
@@ -835,68 +836,72 @@ module BABYLON.GUI {
             return true;
         }
 
-        protected _onPointerMove(coordinates: Vector2): void {
-            if (this.onPointerMoveObservable.hasObservers()) {
-                this.onPointerMoveObservable.notifyObservers(coordinates);
-            }
+        public _onPointerMove(target: Control, coordinates: Vector2): void {
+            var canNotify: boolean = this.onPointerMoveObservable.notifyObservers(coordinates, -1, target, this);
+
+            if (canNotify && this.parent != null) this.parent._onPointerMove(target, coordinates);
         }
 
-        protected _onPointerEnter(): boolean {
+        public _onPointerEnter(target: Control): boolean {
             if (this._enterCount !== 0) {
                 return false;
             }
 
             this._enterCount++;
-            if (this.onPointerEnterObservable.hasObservers()) {
-                this.onPointerEnterObservable.notifyObservers(this);
-            }
+
+            var canNotify: boolean = this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
+
+            if (canNotify && this.parent != null) this.parent._onPointerEnter(target);
 
             return true;
         }
 
-        public _onPointerOut(): void {
+        public _onPointerOut(target: Control): void {
             this._enterCount = 0;
-            if (this.onPointerOutObservable.hasObservers()) {
-                this.onPointerOutObservable.notifyObservers(this);
-            }
+
+            var canNotify: boolean = this.onPointerOutObservable.notifyObservers(this, -1, target, this);
+
+            if (canNotify && this.parent != null) this.parent._onPointerOut(target);
         }
 
-        protected _onPointerDown(coordinates: Vector2, buttonIndex: number): boolean {
+        public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
             if (this._downCount !== 0) {
                 return false;
             }
 
-            this._downCount++;            
-            if (this.onPointerDownObservable.hasObservers()) {
-                this.onPointerDownObservable.notifyObservers(new Vector2WithInfo(coordinates, buttonIndex));
-            }
+            this._downCount++;
+
+            var canNotify: boolean = this.onPointerDownObservable.notifyObservers(new Vector2WithInfo(coordinates, buttonIndex), -1, target, this);
+
+            if (canNotify && this.parent != null) this.parent._onPointerDown(target, coordinates, buttonIndex);
 
             return true;
         }
 
-        protected _onPointerUp(coordinates: Vector2, buttonIndex: number): void {
+        public _onPointerUp(target: Control, coordinates: Vector2, buttonIndex: number): void {
             this._downCount = 0;
-            if (this.onPointerUpObservable.hasObservers()) {
-                this.onPointerUpObservable.notifyObservers(new Vector2WithInfo(coordinates, buttonIndex));
-            }           
+            
+            var canNotify: boolean = this.onPointerUpObservable.notifyObservers(new Vector2WithInfo(coordinates, buttonIndex), -1, target, this);
+            
+            if (canNotify && this.parent != null) this.parent._onPointerUp(target, coordinates, buttonIndex);
         }
 
         public forcePointerUp() {
-            this._onPointerUp(Vector2.Zero(), 0);
+            this._onPointerUp(this, Vector2.Zero(), 0);
         }
 
         public _processObservables(type: number, x: number, y: number, buttonIndex: number): boolean {
             this._dummyVector2.copyFromFloats(x, y);
             if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
-                this._onPointerMove(this._dummyVector2);
+                this._onPointerMove(this, this._dummyVector2);
 
                 var previousControlOver = this._host._lastControlOver;
                 if (previousControlOver && previousControlOver !== this) {
-                    previousControlOver._onPointerOut();                
+                    previousControlOver._onPointerOut(this);                
                 }
 
                 if (previousControlOver !== this) {
-                    this._onPointerEnter();
+                    this._onPointerEnter(this);
                 }
 
                 this._host._lastControlOver = this;
@@ -904,7 +909,7 @@ module BABYLON.GUI {
             }
 
             if (type === BABYLON.PointerEventTypes.POINTERDOWN) {
-                this._onPointerDown(this._dummyVector2, buttonIndex);
+                this._onPointerDown(this, this._dummyVector2, buttonIndex);
                 this._host._lastControlDown = this;
                 this._host._lastPickedControl = this;
                 return true;
@@ -912,7 +917,7 @@ module BABYLON.GUI {
 
             if (type === BABYLON.PointerEventTypes.POINTERUP) {
                 if (this._host._lastControlDown) {
-                    this._host._lastControlDown._onPointerUp(this._dummyVector2, buttonIndex);
+                    this._host._lastControlDown._onPointerUp(this, this._dummyVector2, buttonIndex);
                 }
                 this._host._lastControlDown = null;
                 return true;

+ 4 - 4
gui/src/controls/inputText.ts

@@ -400,8 +400,8 @@ module BABYLON.GUI {
             context.restore();
         }
 
-        protected _onPointerDown(coordinates: Vector2, buttonIndex: number): boolean {
-            if (!super._onPointerDown(coordinates, buttonIndex)) {
+        public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
+            if (!super._onPointerDown(target, coordinates, buttonIndex)) {
                 return false;
             }
 
@@ -417,8 +417,8 @@ module BABYLON.GUI {
             return true;
         }
 
-        protected _onPointerUp(coordinates: Vector2, buttonIndex: number): void {
-            super._onPointerUp(coordinates, buttonIndex);
+        public _onPointerUp(target: Control, coordinates: Vector2, buttonIndex: number): void {
+            super._onPointerUp(target, coordinates, buttonIndex);
         }  
 
         public dispose() {

+ 2 - 2
gui/src/controls/radioButton.ts

@@ -131,8 +131,8 @@ module BABYLON.GUI {
         }
 
         // Events
-        protected _onPointerDown(coordinates: Vector2, buttonIndex: number): boolean {
-            if (!super._onPointerDown(coordinates, buttonIndex)) {
+        public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
+            if (!super._onPointerDown(target, coordinates, buttonIndex)) {
                 return false;
             }
             this.isChecked = !this.isChecked;

+ 7 - 5
gui/src/controls/slider.ts

@@ -179,8 +179,8 @@ module BABYLON.GUI {
             this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
         }
 
-        protected _onPointerDown(coordinates: Vector2, buttonIndex: number): boolean {
-            if (!super._onPointerDown(coordinates, buttonIndex)) {
+        public _onPointerDown(target: Control, coordinates: Vector2, buttonIndex: number): boolean {
+            if (!super._onPointerDown(target, coordinates, buttonIndex)) {
                 return false;
             }
 
@@ -192,17 +192,19 @@ module BABYLON.GUI {
             return true;
         }
 
-        protected _onPointerMove(coordinates: Vector2): void {
+        public _onPointerMove(target: Control, coordinates: Vector2): void {
             if (this._pointerIsDown) {
                 this._updateValueFromPointer(coordinates.x);
             }
+
+            super._onPointerMove(target, coordinates);
         }
 
-        protected _onPointerUp (coordinates: Vector2, buttonIndex: number): void {
+        public _onPointerUp (target: Control, coordinates: Vector2, buttonIndex: number): void {
             this._pointerIsDown = false;
             
             this._host._capturingControl = null;
-            super._onPointerUp(coordinates, buttonIndex);
+            super._onPointerUp(target, coordinates, buttonIndex);
         }         
     }    
 }

+ 18 - 4
src/Tools/babylon.observable.ts

@@ -8,13 +8,15 @@
         /**
         * If the callback of a given Observer set skipNextObservers to true the following observers will be ignored
         */
-        constructor(mask: number, skipNextObservers = false) {
-            this.initalize(mask, skipNextObservers);
+        constructor(mask: number, skipNextObservers = false, target?: any, currentTarget?: any) {
+            this.initalize(mask, skipNextObservers, target, currentTarget);
         }
 
-        public initalize(mask: number, skipNextObservers = false): EventState {
+        public initalize(mask: number, skipNextObservers = false, target?: any, currentTarget?: any): EventState {
             this.mask = mask;
             this.skipNextObservers = skipNextObservers;
+            this.target = target;
+            this.currentTarget = currentTarget;
             return this;
         }
 
@@ -27,6 +29,16 @@
          * Get the mask value that were used to trigger the event corresponding to this EventState object
          */
         public mask: number;
+
+        /**
+         * The object that originally notified the event
+         */
+        public target?: any;
+        
+        /**
+         * The current object in the bubbling phase
+         */
+        public currentTarget?: any;
     }
 
     /**
@@ -153,9 +165,11 @@
          * @param eventData
          * @param mask
          */
-        public notifyObservers(eventData: T, mask: number = -1): boolean {
+        public notifyObservers(eventData: T, mask: number = -1, target?: any, currentTarget?: any): boolean {
             let state = this._eventState;
             state.mask = mask;
+            state.target = target;
+            state.currentTarget = currentTarget;
             state.skipNextObservers = false;
 
             for (var obs of this._observers) {