Browse Source

Added <a> tag support for HtmlText (#883)

Azrou 5 years ago
parent
commit
a382c8f9b0
1 changed files with 44 additions and 0 deletions
  1. 44 0
      h2d/HtmlText.hx

+ 44 - 0
h2d/HtmlText.hx

@@ -62,6 +62,8 @@ class HtmlText extends Text {
 	var dropMatrix : h3d.shader.ColorMatrix;
 	var dropMatrix : h3d.shader.ColorMatrix;
 	var prevChar : Int;
 	var prevChar : Int;
 	var newLine : Bool;
 	var newLine : Bool;
+	var aHrefs : Array<String>;
+	var aInteractive : Interactive;
 
 
 	override function draw(ctx:RenderContext) {
 	override function draw(ctx:RenderContext) {
 		if( dropShadow != null ) {
 		if( dropShadow != null ) {
@@ -109,6 +111,12 @@ class HtmlText extends Text {
 		else return f;
 		else return f;
 	}
 	}
 
 
+	/**
+		Called on a <a> tag click
+	**/
+	public dynamic function onHyperlink(url:String) : Void {
+	}
+
 	public dynamic function formatText( text : String ) : String {
 	public dynamic function formatText( text : String ) : String {
 		return defaultFormatText(text);
 		return defaultFormatText(text);
 	}
 	}
@@ -512,11 +520,33 @@ class HtmlText extends Text {
 	}
 	}
 
 
 	function addNode( e : Xml, font : Font, align : Align, rebuild : Bool, metrics : Array<LineInfo> ) {
 	function addNode( e : Xml, font : Font, align : Align, rebuild : Bool, metrics : Array<LineInfo> ) {
+		inline function createInteractive() {
+			if(aHrefs == null || aHrefs.length == 0)
+				return;
+			aInteractive = new Interactive(0, metrics[sizePos].height, this);
+			var href = aHrefs[aHrefs.length-1];
+			aInteractive.onClick = function(event) {
+				onHyperlink(href);
+			}
+			aInteractive.x = xPos;
+			aInteractive.y = yPos;
+			elements.push(aInteractive);
+		}
+
+		inline function finalizeInteractive() {
+			if(aInteractive != null) {
+				aInteractive.width = xPos - aInteractive.x;
+				aInteractive = null;
+			}
+		}
+
 		inline function makeLineBreak()
 		inline function makeLineBreak()
 		{
 		{
+			finalizeInteractive();
 			if( xPos > xMax ) xMax = xPos;
 			if( xPos > xMax ) xMax = xPos;
 			yPos += metrics[sizePos].height + lineSpacing;
 			yPos += metrics[sizePos].height + lineSpacing;
 			nextLine(align, metrics[++sizePos].width);
 			nextLine(align, metrics[++sizePos].width);
+			createInteractive();
 		}
 		}
 		if( e.nodeType == Xml.Element ) {
 		if( e.nodeType == Xml.Element ) {
 			var prevColor = null, prevGlyphs = null;
 			var prevColor = null, prevGlyphs = null;
@@ -612,6 +642,14 @@ class HtmlText extends Text {
 				newLine = false;
 				newLine = false;
 				prevChar = -1;
 				prevChar = -1;
 				xPos += i.width + imageSpacing;
 				xPos += i.width + imageSpacing;
+			case "a":
+				if( e.exists("href") ) {
+					finalizeInteractive();
+					if( aHrefs == null )
+						aHrefs = [];
+					aHrefs.push(e.get("href"));
+					createInteractive();
+				}
 			default:
 			default:
 			}
 			}
 			for( child in e )
 			for( child in e )
@@ -627,6 +665,12 @@ class HtmlText extends Text {
 					newLine = true;
 					newLine = true;
 					prevChar = -1;
 					prevChar = -1;
 				}
 				}
+			case "a":
+				if( aHrefs.length > 0 ) {
+					finalizeInteractive();
+					aHrefs.pop();
+					createInteractive();
+				}
 			default:
 			default:
 			}
 			}
 			if( prevGlyphs != null )
 			if( prevGlyphs != null )