Skip to content

Instantly share code, notes, and snippets.

@andrew-wilkes
Created November 30, 2020 10:02
Show Gist options
  • Save andrew-wilkes/c3c39c7e3e86c7f6c361c6432e1d7af4 to your computer and use it in GitHub Desktop.
Save andrew-wilkes/c3c39c7e3e86c7f6c361c6432e1d7af4 to your computer and use it in GitHub Desktop.
Add a Line2D above tagged ranges of text in a Label in Godot
extends Control
# Scene structure:
# Main (Control Node)
# - HBox
# -- Multi-line Text label of 400px min width containing a bunch of text
# -- Control node that expands horizontally
# c (canvas node)
export var token = "#" # Marks start and end points of text to draw a line over
enum { IGNORE, START, END }
func _ready():
var tbox = $HBox/Text
var chunks = tbox.text.split(token)
tbox.text = chunks.join("")
var box_width = tbox.rect_size.x
var pos = Vector2(0, 0)
var points = []
var line = ""
var size_before = Vector2(0, 0)
var idx = 0
var state = IGNORE
while idx < chunks.size():
var l_size
var words = chunks[idx].split(" ")
var n = 0
while n < words.size():
if line == "":
line = words[n]
else:
line = line + " " + words[n]
var label = Label.new()
$c.add_child(label)
label.visible = false
label.text = line
# Resume execution the next frame.
yield(get_tree(), "idle_frame")
l_size = label.rect_size
label.queue_free()
if l_size.x > box_width:
# New line
size_before = Vector2(0,0)
pos.y += (l_size.y + 3)
# Spill word over to new line
line = words[n]
n += 1
if state == START:
pos.x = size_before.x
points.append(pos)
state = END
idx += 1
# Control the state at end of current chunk processing
if state == IGNORE:
size_before = l_size
state = START
else: # END
pos.x = l_size.x
points.append(pos)
state = IGNORE
idx = 0
while idx < points.size():
if idx + 1 < points.size():
var l = Line2D.new()
l.width = 4
l.add_point(points[idx])
l.add_point(points[idx + 1])
tbox.add_child(l)
idx += 1
idx += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment