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()