Files
Dawn-Godot/ui/component/VNTextbox.gd
2026-01-09 21:02:01 -06:00

96 lines
2.4 KiB
GDScript

class_name VNTextbox extends PanelContainer
const VN_REVEAL_TIME = 0.01
var label:AdvancedRichText;
var parsedOutText = ""
var revealTimer:float = 0;
var lineStarts:Array[int] = [];
var newlineIndexes:Array[int] = [];
var currentViewScrolled = true;
var isSpeedupDown = false;
var hasLetGoOfInteract:bool = true;
var isClosed:bool = false:
get():
return !self.visible;
set(value):
self.visible = !value;
signal textboxClosing
func _ready() -> void:
label = $MarginContainer/Label
isClosed = true
func _process(delta: float) -> void:
if isClosed:
return;
if label.getFinalText() == "":
isClosed = true;
return;
if Input.is_action_just_released("interact") && !hasLetGoOfInteract:
hasLetGoOfInteract = true;
return
# Have we finished displaying the current page?
if label.visible_characters >= label.getCharactersDisplayedCount():
# Not finished displaying current page
if (label.maxLines + label.startLine) < label.getTotalLineCount():
if Input.is_action_just_pressed("interact") && hasLetGoOfInteract:
label.startLine += label.maxLines;
label.visible_characters = 0;
currentViewScrolled = false;
return
currentViewScrolled = true;
else:
# On last page
if Input.is_action_just_released("interact") && hasLetGoOfInteract:
textboxClosing.emit();
isClosed = true;
currentViewScrolled = true
return;
# This prevents the game trying to advance if the player is still holding
# down interact.
if Input.is_action_just_pressed("interact") && hasLetGoOfInteract:
isSpeedupDown = true;
elif Input.is_action_just_released("interact") && hasLetGoOfInteract:
isSpeedupDown = false;
elif !Input.is_action_pressed("interact") && hasLetGoOfInteract:
isSpeedupDown = false;
revealTimer += delta;
if isSpeedupDown:
revealTimer += delta;
if revealTimer > VN_REVEAL_TIME:
revealTimer = 0;
label.visible_characters += 1;
func setText(text:String) -> void:
# Prepare textbox for scrolling
# Resets scroll
revealTimer = 0;
currentViewScrolled = false;
label.startLine = 0;
# I had a frame wait here before.
label.text = text;
label.visible_characters = 0;
# Resets speedup and advancing
hasLetGoOfInteract = !Input.is_action_pressed("interact");
isSpeedupDown = false
isClosed = false;
func setTextAndWait(text:String) -> void:
self.setText(text);
await self.textboxClosing