فهرست منبع

Fix/improve h2d.Layers (#528)

Changed onParentChanged to onHierarchyMoved, fixed interactives reordering in layers.
Pavel Alexandrov 6 سال پیش
والد
کامیت
76b160d500
4فایلهای تغییر یافته به همراه52 افزوده شده و 14 حذف شده
  1. 5 3
      h2d/Interactive.hx
  2. 38 3
      h2d/Layers.hx
  3. 4 3
      h2d/Mask.hx
  4. 5 5
      h2d/Object.hx

+ 5 - 3
h2d/Interactive.hx

@@ -72,13 +72,15 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
 		if( backgroundColor != null || forSize ) addBounds(relativeTo, out, 0, 0, Std.int(width), Std.int(height));
 	}
 
-	override function onParentChanged() {
-		super.onParentChanged();
+	override private function onHierarchyMoved(parentChanged:Bool)
+	{
+		super.onHierarchyMoved(parentChanged);
 		if( scene != null ) {
 			scene.removeEventTarget(this);
 			scene.addEventTarget(this);
 		}
-		updateMask();
+		if ( parentChanged )
+			updateMask();
 	}
 
 	function updateMask() {

+ 38 - 3
h2d/Layers.hx

@@ -54,6 +54,9 @@ class Layers extends Object {
 		}
 	}
 
+	/**
+		Moves Object to the bottom of its layer (rendered first, behind the other Objects in layer).
+	**/
 	public function under( s : Object ) {
 		for( i in 0...children.length )
 			if( children[i] == s ) {
@@ -69,10 +72,16 @@ class Layers extends Object {
 					p--;
 				}
 				children[pos] = s;
-				break;
+				// Force Interactive to reattach to scene in order to keep interaction order.
+				if ( s.allocated )
+					s.onHierarchyMoved(false);
+				return;
 			}
 	}
 
+	/**
+		Moves Object to the top of its layer (rendered last, in front of other Objects in layer).
+	**/
 	public function over( s : Object ) {
 		for( i in 0...children.length )
 			if( children[i] == s ) {
@@ -81,12 +90,20 @@ class Layers extends Object {
 						for( p in i...l-1 )
 							children[p] = children[p + 1];
 						children[l - 1] = s;
-						break;
+						// Force Interactive to reattach to scene in order to keep interaction order.
+						if ( s.allocated )
+							s.onHierarchyMoved(false);
+						return;
 					}
-				break;
+				return;
 			}
 	}
 
+	/**
+		Returns Iterator of objects contained in specified layer.  
+		Returns empty iterator if layer does not exists.  
+		Objects added or removed from Layers during iteration are not added/removed from the Iterator.
+	**/
 	public function getLayer( layer : Int ) : Iterator<Object> {
 		var a;
 		if( layer >= layerCount )
@@ -99,6 +116,19 @@ class Layers extends Object {
 		return new hxd.impl.ArrayIterator(a);
 	}
 
+	/**
+		Finds the layer on which child object resides.  
+		Always returns -1 if provided Object is not a child of Layers.
+	**/
+	public function getChildLayer( s : Object ) : Int {
+		if ( s.parent != this ) return -1;
+
+		var index = children.indexOf(s);
+		for ( i in 0...layerCount )
+			if ( layersIndexes[i] > index ) return i;
+		return -1;
+	}
+
 	function drawLayer( ctx : RenderContext, layer : Int ) {
 		if( layer >= layerCount )
 			return;
@@ -114,6 +144,9 @@ class Layers extends Object {
 		ctx.globalAlpha = old;
 	}
 
+	/**
+		Sorts specified layer based on Y value of it's Objects.
+	**/
 	public function ysort( layer : Int ) {
 		if( layer >= layerCount ) return;
 		var start = layer == 0 ? 0 : layersIndexes[layer - 1];
@@ -133,6 +166,8 @@ class Layers extends Object {
 					p--;
 				}
 				children[p + 1] = c;
+				if ( c.allocated )
+					c.onHierarchyMoved(false);
 			} else
 				ymax = c.y;
 			pos++;

+ 4 - 3
h2d/Mask.hx

@@ -12,9 +12,10 @@ class Mask extends Object {
 		this.height = height;
 	}
 
-	override function onParentChanged() {
-		super.onParentChanged();
-		updateMask();
+	override private function onHierarchyMoved(parentChanged:Bool) {
+		super.onHierarchyMoved(parentChanged);
+		if ( parentChanged )
+			updateMask();
 	}
 
 	override function onAdd() {

+ 5 - 5
h2d/Object.hx

@@ -347,7 +347,7 @@ class Object {
 			if( !s.allocated )
 				s.onAdd();
 			else
-				s.onParentChanged();
+				s.onHierarchyMoved(true);
 		}
 		onContentChanged();
 	}
@@ -357,9 +357,9 @@ class Object {
 	}
 
 	// called when we're allocated already but moved in hierarchy
-	function onParentChanged() {
-		for( c in children )
-			c.onParentChanged();
+	function onHierarchyMoved( parentChanged : Bool ) {
+		for ( c in children )
+			c.onHierarchyMoved(parentChanged);
 	}
 
 	// kept for internal init
@@ -418,7 +418,7 @@ class Object {
 
 	/**
 		Same as parent.removeChild(this), but does nothing if parent is null.
-		In order to capture add/removal from scene, you can override onAdd/onRemove/onParentChanged
+		In order to capture add/removal from scene, you can override onAdd/onRemove/onHierarchyMoved
 	**/
 	public inline function remove() {
 		if( this != null && parent != null ) parent.removeChild(this);