xiandie/scene/ux/inspector_balloon.gd

90 lines
2.5 KiB
GDScript

class_name InspectorBalloon
extends MarginContainer
signal quitted(is_manually: bool)
@export var prop_title_to_content_wait_time := 3.0
@export var auto_quit_time := 5.0
@onready var character_label = %CharacterLabel as RichTextLabel
@onready var content_label = %ContentLabel as RichTextLabel
enum { DISPLAYING_NONE, DISPLAYING_TITLE, DISPLAYING_CONTENT }
var _display_mutex := Mutex.new()
var _displaying_status := DISPLAYING_NONE
var _pending_content := ""
var _balloon_tween: Tween
func _ready() -> void:
character_label.text = ""
content_label.text = ""
func show_prop_balloon(obtain_str: String, prop_title: String, content: String) -> void:
_display_mutex.lock()
if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill()
_balloon_tween = create_tween()
show()
_pending_content = content
# 如果有获得的物品名称,则显示标题,否则直接显示内容
if not obtain_str.is_empty():
obtain_str = "[color=orange]" + obtain_str + "[/color]"
_displaying_status = DISPLAYING_TITLE
else:
_display_content()
_display_mutex.unlock()
return
character_label.show()
character_label.text = obtain_str
content_label.text = prop_title
if not _pending_content.is_empty():
_balloon_tween.tween_interval(prop_title_to_content_wait_time)
_balloon_tween.tween_callback(_display_content)
else:
_balloon_tween.tween_interval(auto_quit_time)
_balloon_tween.tween_callback(_finished.bind(false))
_display_mutex.unlock()
func _display_content() -> void:
_display_mutex.lock()
if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill()
_balloon_tween = create_tween()
_displaying_status = DISPLAYING_CONTENT
character_label.hide()
content_label.text = _pending_content
_pending_content = ""
_balloon_tween.tween_interval(auto_quit_time)
_balloon_tween.tween_callback(_finished.bind(false))
_display_mutex.unlock()
func _finished(manually: bool) -> void:
_display_mutex.lock()
character_label.text = ""
content_label.text = ""
_displaying_status = DISPLAYING_NONE
hide()
quitted.emit(manually)
_display_mutex.unlock()
func _input(event: InputEvent) -> void:
_display_mutex.lock()
if _displaying_status == DISPLAYING_NONE:
_display_mutex.unlock()
return
if event.is_action_pressed("interact") or event.is_action_pressed("cancel"):
get_viewport().set_input_as_handled()
if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill()
if not _pending_content.is_empty() and _displaying_status == DISPLAYING_TITLE:
_display_content()
else:
_finished(true)
_display_mutex.unlock()