Explorar el Código

changed constraint schema

ncannasse hace 8 años
padre
commit
893d54a093
Se han modificado 3 ficheros con 82 adiciones y 36 borrados
  1. 38 21
      h2d/Flow.hx
  2. 14 4
      h2d/Sprite.hx
  3. 30 11
      h2d/Text.hx

+ 38 - 21
h2d/Flow.hx

@@ -11,12 +11,14 @@ enum FlowAlign {
 @:allow(h2d.Flow)
 @:allow(h2d.Flow)
 class FlowProperties {
 class FlowProperties {
 
 
+	var elt : Sprite;
+
 	public var paddingLeft = 0;
 	public var paddingLeft = 0;
 	public var paddingTop = 0;
 	public var paddingTop = 0;
 	public var paddingRight = 0;
 	public var paddingRight = 0;
 	public var paddingBottom = 0;
 	public var paddingBottom = 0;
 
 
-	public var isAbsolute = false;
+	public var isAbsolute(default,set) = false;
 	public var horizontalAlign : Null<FlowAlign>;
 	public var horizontalAlign : Null<FlowAlign>;
 	public var verticalAlign : Null<FlowAlign>;
 	public var verticalAlign : Null<FlowAlign>;
 
 
@@ -31,16 +33,23 @@ class FlowProperties {
 
 
 	public var isBreak(default,null) : Bool;
 	public var isBreak(default,null) : Bool;
 
 
-	public var overflow : Bool = false;
+	/**
+		If our flow have a maximum size, it will constraint the children by using .constraintSize()
+	**/
+	public var constraint = true;
 
 
-	var tf : h2d.Text;
+	public function new(elt) {
+		this.elt = elt;
+	}
 
 
-	public function new() {
+	function set_isAbsolute(a) {
+		if( a ) @:privateAccess elt.constraintSize( -1, -1); // remove constraint
+		return isAbsolute = a;
 	}
 	}
 
 
 }
 }
 
 
-class Flow extends Sprite.Container {
+class Flow extends Sprite {
 
 
 	static var tmpBounds = new h2d.col.Bounds();
 	static var tmpBounds = new h2d.col.Bounds();
 
 
@@ -68,6 +77,7 @@ class Flow extends Sprite.Container {
 	public var minHeight(default, set) : Null<Int>;
 	public var minHeight(default, set) : Null<Int>;
 	public var maxWidth(default, set) : Null<Int>;
 	public var maxWidth(default, set) : Null<Int>;
 	public var maxHeight(default, set) : Null<Int>;
 	public var maxHeight(default, set) : Null<Int>;
+
 	public var lineHeight(default, set) : Null<Int>;
 	public var lineHeight(default, set) : Null<Int>;
 	public var colWidth(default, set) : Null<Int>;
 	public var colWidth(default, set) : Null<Int>;
 
 
@@ -328,11 +338,7 @@ class Flow extends Sprite.Container {
 		if( background != null ) pos++;
 		if( background != null ) pos++;
 		var fp = getProperties(s);
 		var fp = getProperties(s);
 		super.addChildAt(s, pos);
 		super.addChildAt(s, pos);
-		if( fp == null ) {
-			fp = new FlowProperties();
-			fp.tf = Std.instance(s, h2d.Text);
-		} else
-			properties.remove(fp);
+		if( fp == null ) fp = new FlowProperties(s) else properties.remove(fp);
 		properties.insert(pos, fp);
 		properties.insert(pos, fp);
 		needReflow = true;
 		needReflow = true;
 		s.parentContainer = this;
 		s.parentContainer = this;
@@ -344,6 +350,7 @@ class Flow extends Sprite.Container {
 		if( index >= 0 ) {
 		if( index >= 0 ) {
 			needReflow = true;
 			needReflow = true;
 			properties.splice(index, 1);
 			properties.splice(index, 1);
+			s.constraintSize( -1, -1); // remove constraint
 		}
 		}
 	}
 	}
 
 
@@ -464,6 +471,15 @@ class Flow extends Sprite.Container {
 
 
 		onBeforeReflow();
 		onBeforeReflow();
 
 
+		var isConstraintWidth = this.maxWidth != null;
+		var isConstraintHeight = this.maxHeight != null;
+		// outter size
+		var maxTotWidth = maxWidth == null ? 100000000 : maxWidth;
+		var maxTotHeight = maxHeight == null ? 100000000 : maxHeight;
+		// inner size
+		var maxWidth = maxTotWidth - (paddingLeft + paddingRight + borderWidth * 2);
+		var maxHeight = maxTotHeight - (paddingTop + paddingBottom + borderHeight * 2);
+
 		var cw, ch;
 		var cw, ch;
 		if( !isVertical ) {
 		if( !isVertical ) {
 			var halign = horizontalAlign == null ? Left : horizontalAlign;
 			var halign = horizontalAlign == null ? Left : horizontalAlign;
@@ -476,7 +492,6 @@ class Flow extends Sprite.Container {
 			var maxLineHeight = 0.;
 			var maxLineHeight = 0.;
 			var minLineHeight = this.lineHeight != null ? lineHeight : (this.minHeight != null && !multiline) ? (this.minHeight - (paddingTop + paddingBottom + borderHeight * 2)) : 0;
 			var minLineHeight = this.lineHeight != null ? lineHeight : (this.minHeight != null && !multiline) ? (this.minHeight - (paddingTop + paddingBottom + borderHeight * 2)) : 0;
 			var tmpBounds = tmpBounds;
 			var tmpBounds = tmpBounds;
-			var maxWidth = maxWidth == null ? 100000000 : maxWidth - (paddingLeft + paddingRight + borderWidth * 2);
 			var lastIndex = 0;
 			var lastIndex = 0;
 
 
 			inline function alignLine( maxIndex ) {
 			inline function alignLine( maxIndex ) {
@@ -508,8 +523,10 @@ class Flow extends Sprite.Container {
 				var c = childs[i];
 				var c = childs[i];
 				if( !c.visible ) continue;
 				if( !c.visible ) continue;
 
 
-				if( p.tf != null && !p.overflow && this.maxWidth != null )
-					p.tf.maxWidth = maxWidth - (p.paddingLeft + p.paddingRight);
+				c.constraintSize(
+					isConstraintWidth && p.constraint ? maxWidth - (p.paddingLeft + p.paddingRight) : -1,
+					isConstraintHeight && p.constraint ? maxHeight - (p.paddingTop + p.paddingBottom) : -1
+				);
 
 
 				var b = c.getSize(tmpBounds);
 				var b = c.getSize(tmpBounds);
 				var br = false;
 				var br = false;
@@ -517,7 +534,7 @@ class Flow extends Sprite.Container {
 				p.calculatedHeight = b.yMax + p.paddingTop + p.paddingBottom;
 				p.calculatedHeight = b.yMax + p.paddingTop + p.paddingBottom;
 				if( p.minWidth != null && p.calculatedWidth < p.minWidth ) p.calculatedWidth = p.minWidth;
 				if( p.minWidth != null && p.calculatedWidth < p.minWidth ) p.calculatedWidth = p.minWidth;
 				if( p.minHeight != null && p.calculatedHeight < p.minHeight ) p.calculatedHeight = p.minHeight;
 				if( p.minHeight != null && p.calculatedHeight < p.minHeight ) p.calculatedHeight = p.minHeight;
-				if( x + p.calculatedWidth > maxWidth && x > startX ) {
+				if( multiline && x + p.calculatedWidth > maxWidth && x > startX ) {
 					br = true;
 					br = true;
 					alignLine(i);
 					alignLine(i);
 					y += maxLineHeight + verticalSpacing;
 					y += maxLineHeight + verticalSpacing;
@@ -595,8 +612,6 @@ class Flow extends Sprite.Container {
 			var maxColWidth = 0.;
 			var maxColWidth = 0.;
 			var minColWidth = this.colWidth != null ? colWidth : (this.minWidth != null && !multiline) ? (this.minWidth - (paddingLeft + paddingRight + borderWidth * 2)) : 0;
 			var minColWidth = this.colWidth != null ? colWidth : (this.minWidth != null && !multiline) ? (this.minWidth - (paddingLeft + paddingRight + borderWidth * 2)) : 0;
 			var tmpBounds = tmpBounds;
 			var tmpBounds = tmpBounds;
-			var maxWidth = maxWidth == null ? 100000000 : maxWidth - (paddingLeft + paddingRight + borderWidth * 2);
-			var maxHeight = maxHeight == null ? 100000000 : maxHeight - (paddingTop + paddingBottom + borderHeight * 2);
 			var lastIndex = 0;
 			var lastIndex = 0;
 
 
 			inline function alignLine( maxIndex ) {
 			inline function alignLine( maxIndex ) {
@@ -629,8 +644,10 @@ class Flow extends Sprite.Container {
 				var c = childs[i];
 				var c = childs[i];
 				if( !c.visible ) continue;
 				if( !c.visible ) continue;
 
 
-				if( p.tf != null && !p.overflow && this.maxWidth != null )
-					p.tf.maxWidth = maxWidth - (p.paddingLeft + p.paddingRight);
+				c.constraintSize(
+					isConstraintWidth && p.constraint ? maxWidth - (p.paddingLeft + p.paddingRight) : -1,
+					isConstraintHeight && p.constraint ? maxHeight - (p.paddingTop + p.paddingBottom) : -1
+				);
 
 
 				var b = c.getSize(tmpBounds);
 				var b = c.getSize(tmpBounds);
 				var br = false;
 				var br = false;
@@ -640,7 +657,7 @@ class Flow extends Sprite.Container {
 				if( p.minWidth != null && p.calculatedWidth < p.minWidth ) p.calculatedWidth = p.minWidth;
 				if( p.minWidth != null && p.calculatedWidth < p.minWidth ) p.calculatedWidth = p.minWidth;
 				if( p.minHeight != null && p.calculatedHeight < p.minHeight ) p.calculatedHeight = p.minHeight;
 				if( p.minHeight != null && p.calculatedHeight < p.minHeight ) p.calculatedHeight = p.minHeight;
 
 
-				if( y + p.calculatedHeight > maxHeight && y > startY ) {
+				if( multiline && y + p.calculatedHeight > maxHeight && y > startY ) {
 					br = true;
 					br = true;
 					alignLine(i);
 					alignLine(i);
 					x += maxColWidth + horizontalSpacing;
 					x += maxColWidth + horizontalSpacing;
@@ -712,8 +729,8 @@ class Flow extends Sprite.Container {
 		if( minWidth != null && cw < minWidth ) cw = minWidth;
 		if( minWidth != null && cw < minWidth ) cw = minWidth;
 		if( minHeight != null && ch < minHeight ) ch = minHeight;
 		if( minHeight != null && ch < minHeight ) ch = minHeight;
 		if( overflow ) {
 		if( overflow ) {
-			if( maxWidth != null && cw > maxWidth ) cw = maxWidth;
-			if( maxHeight != null && ch > maxHeight ) ch = maxHeight;
+			if( isConstraintWidth && cw > maxTotWidth ) cw = maxTotWidth;
+			if( isConstraintHeight && ch > maxTotHeight ) ch = maxTotHeight;
 		}
 		}
 
 
 		if( interactive != null ) {
 		if( interactive != null ) {

+ 14 - 4
h2d/Sprite.hx

@@ -7,7 +7,7 @@ class Sprite {
 	static var nullDrawable : h2d.Drawable;
 	static var nullDrawable : h2d.Drawable;
 
 
 	var childs : Array<Sprite>;
 	var childs : Array<Sprite>;
-	var parentContainer : Container;
+	var parentContainer : Sprite;
 	public var parent(default, null) : Sprite;
 	public var parent(default, null) : Sprite;
 	public var numChildren(get, never) : Int;
 	public var numChildren(get, never) : Int;
 
 
@@ -717,10 +717,20 @@ class Sprite {
 		return name == null ? c : name + "(" + c + ")";
 		return name == null ? c : name + "(" + c + ")";
 	}
 	}
 
 
-}
+	// ---- additional methods for containers (h2d.Flow)
+
+	/**
+		This is called by our children if we have defined their parentContainer when they get resized
+	**/
+	function contentChanged( s : Sprite ) {
+	}
 
 
-class Container extends Sprite {
-	@:noCompletion public function contentChanged( s : Sprite ) {
+	/**
+		This can be called by a parent container to constraint the size of its children.
+		Negative value mean that constraint is to be disable.
+	**/
+	function constraintSize( maxWidth : Float, maxHeight : Float ) {
 	}
 	}
+
 }
 }
 
 

+ 30 - 11
h2d/Text.hx

@@ -27,6 +27,8 @@ class Text extends Drawable {
 	var calcWidth:Int;
 	var calcWidth:Int;
 	var calcHeight:Int;
 	var calcHeight:Int;
 	var calcSizeHeight:Int;
 	var calcSizeHeight:Int;
+	var constraintWidth:Float = -1;
+	var realMaxWidth:Float = -1;
 
 
 	#if lime
 	#if lime
 	var waShader : h3d.shader.WhiteAlpha;
 	var waShader : h3d.shader.WhiteAlpha;
@@ -80,6 +82,11 @@ class Text extends Drawable {
 		return s;
 		return s;
 	}
 	}
 
 
+	override function constraintSize(width:Float, height:Float) {
+		constraintWidth = width;
+		updateConstraint();
+	}
+
 	override function onAlloc() {
 	override function onAlloc() {
 		super.onAlloc();
 		super.onAlloc();
 		rebuild();
 		rebuild();
@@ -141,7 +148,7 @@ class Text extends Drawable {
 	}
 	}
 
 
 	public function splitText( text : hxd.UString, leftMargin = 0 ) {
 	public function splitText( text : hxd.UString, leftMargin = 0 ) {
-		if( maxWidth == null )
+		if( realMaxWidth < 0 )
 			return text;
 			return text;
 		var lines = [], rest = text, restPos = 0;
 		var lines = [], rest = text, restPos = 0;
 		var x = leftMargin, prevChar = -1;
 		var x = leftMargin, prevChar = -1;
@@ -151,21 +158,21 @@ class Text extends Drawable {
 			var newline = cc == '\n'.code;
 			var newline = cc == '\n'.code;
 			var esize = e.width + e.getKerningOffset(prevChar);
 			var esize = e.width + e.getKerningOffset(prevChar);
 			if( font.charset.isBreakChar(cc) ) {
 			if( font.charset.isBreakChar(cc) ) {
-				if( lines.length == 0 && leftMargin > 0 && x > maxWidth ) {
+				if( lines.length == 0 && leftMargin > 0 && x > realMaxWidth ) {
 					lines.push("");
 					lines.push("");
 					x -= leftMargin;
 					x -= leftMargin;
 				}
 				}
 				var size = x + esize + letterSpacing;
 				var size = x + esize + letterSpacing;
 				var k = i + 1, max = text.length;
 				var k = i + 1, max = text.length;
 				var prevChar = prevChar;
 				var prevChar = prevChar;
-				while( size <= maxWidth && k < max ) {
+				while( size <= realMaxWidth && k < max ) {
 					var cc = text.charCodeAt(k++);
 					var cc = text.charCodeAt(k++);
 					if( font.charset.isSpace(cc) || cc == '\n'.code ) break;
 					if( font.charset.isSpace(cc) || cc == '\n'.code ) break;
 					var e = font.getChar(cc);
 					var e = font.getChar(cc);
 					size += e.width + letterSpacing + e.getKerningOffset(prevChar);
 					size += e.width + letterSpacing + e.getKerningOffset(prevChar);
 					prevChar = cc;
 					prevChar = cc;
 				}
 				}
-				if( size > maxWidth ) {
+				if( size > realMaxWidth ) {
 					newline = true;
 					newline = true;
 					lines.push(text.substr(restPos, i - restPos));
 					lines.push(text.substr(restPos, i - restPos));
 					restPos = i;
 					restPos = i;
@@ -184,7 +191,7 @@ class Text extends Drawable {
 				prevChar = cc;
 				prevChar = cc;
 		}
 		}
 		if( restPos < text.length ) {
 		if( restPos < text.length ) {
-			if( lines.length == 0 && leftMargin > 0 && x > maxWidth )
+			if( lines.length == 0 && leftMargin > 0 && x > realMaxWidth )
 				lines.push("");
 				lines.push("");
 			lines.push(text.substr(restPos, text.length - restPos));
 			lines.push(text.substr(restPos, text.length - restPos));
 		}
 		}
@@ -199,7 +206,7 @@ class Text extends Drawable {
 		case Center, Right:
 		case Center, Right:
 			lines = [];
 			lines = [];
 			initGlyphs(text, false, false, lines);
 			initGlyphs(text, false, false, lines);
-			var max = maxWidth == null ? 0 : Std.int(maxWidth);
+			var max = realMaxWidth < 0 ? 0 : Std.int(realMaxWidth);
 			var k = align == Center ? 1 : 0;
 			var k = align == Center ? 1 : 0;
 			for( i in 0...lines.length )
 			for( i in 0...lines.length )
 				lines[i] = (max - lines[i]) >> k;
 				lines[i] = (max - lines[i]) >> k;
@@ -216,18 +223,18 @@ class Text extends Drawable {
 			var offs = e.getKerningOffset(prevChar);
 			var offs = e.getKerningOffset(prevChar);
 			var esize = e.width + offs;
 			var esize = e.width + offs;
 			// if the next word goes past the max width, change it into a newline
 			// if the next word goes past the max width, change it into a newline
-			if( font.charset.isBreakChar(cc) && maxWidth != null ) {
+			if( font.charset.isBreakChar(cc) && realMaxWidth >= 0 ) {
 				var size = x + esize + letterSpacing;
 				var size = x + esize + letterSpacing;
 				var k = i + 1, max = text.length;
 				var k = i + 1, max = text.length;
 				var prevChar = prevChar;
 				var prevChar = prevChar;
-				while( size <= maxWidth && k < max ) {
+				while( size <= realMaxWidth && k < max ) {
 					var cc = text.charCodeAt(k++);
 					var cc = text.charCodeAt(k++);
 					if( font.charset.isSpace(cc) || cc == '\n'.code ) break;
 					if( font.charset.isSpace(cc) || cc == '\n'.code ) break;
 					var e = font.getChar(cc);
 					var e = font.getChar(cc);
 					size += e.width + letterSpacing + e.getKerningOffset(prevChar);
 					size += e.width + letterSpacing + e.getKerningOffset(prevChar);
 					prevChar = cc;
 					prevChar = cc;
 				}
 				}
-				if( size > maxWidth ) {
+				if( size > realMaxWidth ) {
 					newline = true;
 					newline = true;
 					if( font.charset.isSpace(cc) ) e = null;
 					if( font.charset.isSpace(cc) ) e = null;
 				}
 				}
@@ -280,10 +287,22 @@ class Text extends Drawable {
 	function set_maxWidth(w) {
 	function set_maxWidth(w) {
 		if( maxWidth == w ) return w;
 		if( maxWidth == w ) return w;
 		maxWidth = w;
 		maxWidth = w;
-		rebuild();
+		updateConstraint();
 		return w;
 		return w;
 	}
 	}
 
 
+	function updateConstraint() {
+		var old = realMaxWidth;
+		if( maxWidth == null )
+			realMaxWidth = constraintWidth;
+		else if( constraintWidth < 0 )
+			realMaxWidth = maxWidth;
+		else
+			realMaxWidth = hxd.Math.min(maxWidth, constraintWidth);
+		if( realMaxWidth != old )
+			rebuild();
+	}
+
 	function set_textColor(c) {
 	function set_textColor(c) {
 		if( this.textColor == c ) return c;
 		if( this.textColor == c ) return c;
 		this.textColor = c;
 		this.textColor = c;
@@ -300,7 +319,7 @@ class Text extends Drawable {
 		if( forSize ) {
 		if( forSize ) {
 			x = 0;
 			x = 0;
 			y = 0;
 			y = 0;
-			w = maxWidth != null && textAlign != Left && maxWidth > calcWidth ? maxWidth : calcWidth;
+			w = realMaxWidth >= 0 && textAlign != Left && realMaxWidth > calcWidth ? realMaxWidth : calcWidth;
 			h = calcSizeHeight;
 			h = calcSizeHeight;
 		} else {
 		} else {
 			x = 0;
 			x = 0;