Sfoglia il codice sorgente

Have Layers addChild/addChildAt/getChildAt work the same as Object (close #862)

Pavel Alexandrov 3 anni fa
parent
commit
4c289005f1
4 ha cambiato i file con 77 aggiunte e 26 eliminazioni
  1. 74 23
      h2d/Layers.hx
  2. 1 1
      h2d/Object.hx
  3. 1 1
      h2d/domkit/Style.hx
  4. 1 1
      samples/CollideCheck.hx

+ 74 - 23
h2d/Layers.hx

@@ -23,45 +23,66 @@ class Layers extends Object {
 	}
 
 	/**
-		Adds a child object `s` at the end of the layer 0.
+		Adds a child object `s` at the end of the topmost layer.
 		@param s An object to be added.
 	**/
+	@:dox(show)
 	override function addChild(s) {
-		addChildAt(s, 0);
+		add(s, -1);
 	}
 
 	/**
-		Adds a child object `s` at the end of the given `layer`.
-		`h2d.Layers.addChildAt` can be used as an alternative.
-		@param s An object to be added.
-		@param layer An index of the layer, 0 is the bottom-most layer.
-	**/
-	public inline function add(s, layer) {
-		return addChildAt(s, layer);
-	}
-
-	/**
-		Adds a child object `s` at the end of the given `layer`.
-		`h2d.Layers.addChildAt` can be used as an alternative.
-		@param s An object to be added.
-		@param layer An index of the layer, 0 is the bottom-most layer.
-	**/
-	override function addChildAt( s : Object, layer : Int ) {
-		if( s.parent == this ) {
+	 * Adds a child object `s` at the end of the given `layer`.
+	 * @param s An object to be added.
+	 * @param layer An index of the layer the object should be added at with 0 being the bottom-most layer. Pass -1 to use topmost layer.
+	 * @param index An optional index at which the object should be inserted inside the layer. Pass -1 to append to the end.
+	 */
+	public function add( s : Object, layer : Int = -1, index : Int = -1) {
+		if ( s.parent == this ) {
+			// prevent calling onRemove
 			var old = s.allocated;
 			s.allocated = false;
 			removeChild(s);
 			s.allocated = old;
 		}
-		// new layer
-		while( layer >= layerCount )
+
+		if ( layer == -1 ) layer = layerCount == 0 ? 0 : layerCount - 1;
+
+		// Populate layer list
+		while ( layer >= layerCount )
 			layersIndexes[layerCount++] = children.length;
-		super.addChildAt(s,layersIndexes[layer]);
-		for( i in layer...layerCount )
+		
+		if ( index != -1 ) {
+			// Prevent inserting out of layer bounds.
+			if ( layer == 0 )
+				super.addChildAt(s, hxd.Math.imax(0, hxd.Math.imin(index, layersIndexes[layer])));
+			else if ( index < 0 ) // clamp 0..
+				super.addChildAt(s, layersIndexes[layer - 1]);
+			else // clamp ..layerSize
+				super.addChildAt(s, hxd.Math.imin(layersIndexes[layer - 1] + index, layersIndexes[layer]));
+		} else {
+			super.addChildAt(s, layersIndexes[layer]);
+		}
+		
+		for ( i in layer...layerCount )
 			layersIndexes[i]++;
+		
+	}
+
+	/**
+		Adds a child object `s` at specified `index` on the top topmost layer.
+
+		Warning: Previous behavior of `Layers.addChildAt` is no longer applicable and `Layers.add` should be used instead.
+		@param s The object to be added.
+		@param index The position of the object in the layer.
+	**/
+	@:dox(show)
+	override function addChildAt( s : Object, index : Int ) {
+		add(s, -1, index);
 	}
 
 	override function removeChild( s : Object ) {
+		// Full override due to child index being important for layer tracking.
 		for( i in 0...children.length ) {
 			if( children[i] == s ) {
 				children.splice(i, 1);
@@ -74,6 +95,9 @@ class Layers extends Object {
 					layersIndexes[k]--;
 					k--;
 				}
+				#if domkit
+				if( s.dom != null ) s.dom.onParentChanged();
+				#end
 				onContentChanged();
 				break;
 			}
@@ -149,6 +173,17 @@ class Layers extends Object {
 		return new hxd.impl.ArrayIterator(a);
 	}
 
+	/**
+		Return the `n`th element among the immediate children list on the `layer`, or null if there is none.
+		@param layer The layer children of which are used. Pass -1 to use the topmost layer.
+	**/
+	public function getChildAtLayer( n : Int, layer : Int ) : Object {
+		if ( layer == -1 ) layer = layerCount == 0 ? 0 : layerCount - 1;
+		if ( layer >= layerCount || n < 0 || n >= layersIndexes[layer] ) return null;
+		if ( layer == 0 ) return children[n];
+		return children[layersIndexes[layer - 1] + n];
+	}
+
 	/**
 		Returns the layer on which the child `s` resides on.
 		@param s An object to look up to.
@@ -163,6 +198,22 @@ class Layers extends Object {
 		return -1;
 	}
 
+	/**
+		Return the index of the child within its respective layer.
+		@param o The child to look up index of.
+		@returns `-1` if object is not a child of Layers, index of the child within its current layer otherwise.
+	**/
+	public function getChildIndexInLayer( o : Object ):Int
+	{
+		if ( o.parent != this ) return -1;
+
+		var index = children.indexOf(o);
+		if ( index < layersIndexes[0] ) return index;
+		for ( i in 1...layerCount )
+			if ( layersIndexes[i] > index ) return index - layersIndexes[i - 1];
+		return -1;
+	}
+
 	function drawLayer( ctx : RenderContext, layer : Int ) {
 		if( layer >= layerCount )
 			return;

+ 1 - 1
h2d/Object.hx

@@ -1048,7 +1048,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	/**
 		Return the `n`th element among the immediate children list of this object, or `null` if there is no Object at this position.
 	**/
-	public inline function getChildAt( n ) {
+	public function getChildAt( n ) {
 		return children[n];
 	}
 

+ 1 - 1
h2d/domkit/Style.hx

@@ -94,7 +94,7 @@ class Style extends domkit.CssStyle {
 				if( currentObjects.length == 0 ) return;
 				var scene = currentObjects[0].getScene();
 				var fl = new h2d.Flow();
-				scene.addChildAt(fl,100);
+				scene.add(fl,100);
 				fl.backgroundTile = h2d.Tile.fromColor(0x400000,0.9);
 				fl.padding = 10;
 				errorsText = new h2d.Text(hxd.res.DefaultFont.get(), fl);

+ 1 - 1
samples/CollideCheck.hx

@@ -55,7 +55,7 @@ class CollideCheck extends hxd.App {
 			}
 		var view = new h2d.Bitmap(h2d.Tile.fromPixels(bmp));
 		view.alpha = 0.5;
-		s2d.addChildAt(view, 0);
+		s2d.add(view, 0);
 		bmp.dispose();
 	}