Mostly finished VN textbox

This commit is contained in:
2025-09-16 23:27:02 -05:00
parent 96b5bae9d0
commit 1e83200bba
7 changed files with 132 additions and 126 deletions

View File

@@ -1,51 +1,49 @@
class_name VNTextbox extends PanelContainer
const VN_REVEAL_TIME = 0.01
const VISIBLE_LINES:int = 4
var label:RichTextLabel;
var text:String = ""
var label:AdvancedRichText;
var parsedOutText = ""
var visibleCharacters:int = 0;
var revealTimer:float = 0;
var lineStarts:Array[int] = [];
var newlineIndexes:Array[int] = [];
var wrappedText:String = "";
var currentLine = 0;
var currentViewScrolled = true;
var isSpeedupDown = false;
var isMoreViews = false;
var isClosed = true;
var isClosed:bool = false:
get():
return !self.visible;
set(value):
self.visible = !value;
signal textboxClosing
func _ready() -> void:
label = $MarginContainer/Label
self.visible = false;
isClosed = true
func _process(delta: float) -> void:
if text == "":
if label.getFinalText() == "":
isClosed = true;
return;
if currentViewScrolled:
if Input.is_action_just_pressed("interact"):
if isMoreViews:
visibleCharacters = 0;
currentLine += VISIBLE_LINES;
if label.visible_characters >= label.getCharactersDisplayedCount():
if (label.maxLines + label.startLine) < label.getTotalLineCount():
# Not on last page.
if Input.is_action_just_pressed("interact"):
label.startLine += label.maxLines;
label.visible_characters = 0;
currentViewScrolled = false;
recalculateWrapping();
return
setText("");
textboxClosing.emit();
return;
if visibleCharacters >= getCountOfCharactersToScrollInView():
currentViewScrolled = true;
#print("Scrolled view");
#if isMoreViews:
#print("More views");
currentViewScrolled = true;
else:
# On last page
if Input.is_action_just_released("interact"):
textboxClosing.emit();
isClosed = true;
currentViewScrolled = true
return;
if Input.is_action_just_pressed("interact"):
@@ -61,63 +59,15 @@ func _process(delta: float) -> void:
if revealTimer > VN_REVEAL_TIME:
revealTimer = 0;
visibleCharacters += 1;
label.visible_characters = visibleCharacters;
func getCountOfCharactersToScrollInView() -> int:
if lineStarts.size() <= VISIBLE_LINES:
return wrappedText.length();
if currentLine + VISIBLE_LINES >= lineStarts.size():
return wrappedText.length() - lineStarts[currentLine];
return lineStarts[min(lineStarts.size(), currentLine + VISIBLE_LINES)] - lineStarts[currentLine];
func recalculateWrapping():
# Reset label to default.
label.advancedText = text;
label.visible_characters = -1;
label.fit_content = true;
isMoreViews = false;
# Determine where the wrapped newlines are
lineStarts = [ 0 ];
var line = 0;
var wasNewLine = false;
for i in range(0, text.length()):
var tLine = label.get_character_line(i);
if tLine == line:
wasNewLine = false
if text[i] == "\n":
wasNewLine = true
continue;
if !wasNewLine:
newlineIndexes.append(i);
lineStarts.append(i);
line = tLine;
# Create fake pre-wrapped text.
wrappedText = "";
for i in range(lineStarts[currentLine], text.length()):
if newlineIndexes.find(i) != -1 and i != lineStarts[currentLine]:
wrappedText += "\n";
wrappedText += text[i];
label.advancedText = wrappedText;
label.fit_content = false;
label.visible_characters = 0;
if lineStarts.size() > currentLine + VISIBLE_LINES:
isMoreViews = true;
label.visible_characters += 1;
func setText(text:String) -> void:
self.text = text;
if text == "":
self.visible = false;
return;
isClosed = false;
revealTimer = 0;
visibleCharacters = 0;
currentLine = 0;
currentViewScrolled = false;
recalculateWrapping();
self.visible = true;
label.visible_characters = 0;
label.startLine = 0;
label.text = ""
await get_tree().process_frame# Absolutely needed to make the text wrap
label.text = text;
label.visible_characters = 0;