#Access character bounds in RichTextLabel

9 messages · Page 1 of 1 (latest)

latent nymph
#

Is there a way to get character bounds in RichTextLabel?
I used to calculate last visible character position in Label with

    var last_character_rect = text.get_character_bounds(index)
    var vector = last_character_rect.get_center()

But I see that this function is missing in RichTextLabel, hmm

Is there any way to get that with RichTextLabel?
What I want is to position an animated sprite at the end of the last character displayed, so I'm trying to get individual character bounds.

Thank you in advance!

craggy tree
#

Use RichTextLabel.get_line_offset() and get_line_count()

#

You also could probably just create a duplicate label only to measure the bounds.

latent nymph
#

OOh! Smart! Thank you, I'll try

rain vessel
# craggy tree Use RichTextLabel.get_line_offset() and get_line_count()

I don't think this quite works -- get_line_offset is the vertical offset, but I don't see a way to get the horizontal offset. I think you could do it with an effect since that gives you the range (so that you can identify the last character) and the transform/offset value. I'm not sure how to best capture the line height from that information for drawing the extra sprite, if you need that.
This is awful, huh? 😄

latent nymph
latent nymph
#

What I did:
Here is a Scene tree (picture attached ↓)
CTC_Sprite should be put at the end of the sentence

This is a [hover speed=30]test[/hover] text. [insert_ctc].[/insert_ctc]
Where insert_ctc tag is CTC should move to

This is code for RichTextEffect insert_ctc

@tool
# Having a class name is handy for picking the effect in the Inspector.
class_name RichTextInsertCtc
extends RichTextEffect

# emit signal with animation name
signal draw_ctc(type :String, position :Vector2)

# To use this effect:
# - Enable BBCode on a RichTextLabel.
# - Register this effect on the label.
# - Use [insert_ctc param=2.0]hello[/insert_ctc] in text.
var bbcode := "insert_ctc"

func _process_custom_fx(char_fx: CharFXTransform) -> bool:
    var param: float = char_fx.env.get("param", 1.0)
    
    var position = char_fx.transform.get_origin()
    
    emit_signal("draw_ctc", "white", position)
    return true

It calls a signal that passes position of the character

And on RichTextLabel I connect to that signal like so and move sprite to a character position that I get from signal.

extends RichTextLabel


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
    for i in range(custom_effects.size()):
        if custom_effects[i] is RichTextInsertCtc:
            custom_effects[i].draw_ctc.connect(_on_show_ctc)

@onready var ctc_sprite: AnimatedSprite2D = $CTC_Sprite

func _on_show_ctc(animation :String, _position :Vector2):
    print("show ctc at %s" % _position)
    ctc_sprite.position = _position

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
    pass
#

I will rewrite so it'll check if character is visible, but yes that's it!
Thanks everyone for the help