143 lines
4.0 KiB
GDScript
143 lines
4.0 KiB
GDScript
@tool
|
||
extends Control
|
||
|
||
@export var locked := false:
|
||
set(val):
|
||
locked = val
|
||
if is_node_ready() and locked:
|
||
display = false
|
||
@export var display := false:
|
||
set(val):
|
||
if is_node_ready() and display != val:
|
||
_toggle_display()
|
||
display = val
|
||
@export var boundart_rect := Rect2(0, 0, 1000, 1000):
|
||
set(val):
|
||
boundart_rect = val
|
||
queue_redraw()
|
||
@export_group("Tip", "tip_")
|
||
@export var tip_content := "":
|
||
set(val):
|
||
tip_content = val
|
||
if is_node_ready():
|
||
reload()
|
||
@export var tip_font_size := 12
|
||
@export var tip_font_color := Color(1, 1, 1)
|
||
@export var tip_item_position := Vector2(220, 220)
|
||
|
||
@onready var tip_container = $Tips as GridContainer
|
||
@onready var items_root = $ItemsRoot as Node2D
|
||
|
||
var sty_box_empty := StyleBoxEmpty.new()
|
||
|
||
var item_scene := preload("res://scene/journal/journal_item.tscn")
|
||
var tip_script := preload("res://scene/journal/journal_tip.gd")
|
||
var item_script := preload("res://scene/journal/journal_item.gd")
|
||
var items_dict := {}
|
||
|
||
|
||
func _ready() -> void:
|
||
reload()
|
||
if GlobalConfig.DEBUG:
|
||
locked = false
|
||
display = true
|
||
else:
|
||
locked = true
|
||
display = false
|
||
_toggle_display(false)
|
||
|
||
|
||
func reload():
|
||
for c in tip_container.get_children():
|
||
c.queue_free()
|
||
for v in items_dict.values():
|
||
v.queue_free()
|
||
items_dict.clear()
|
||
var btn_name_prefix = "tip_btn_"
|
||
for i in range(tip_content.length()):
|
||
var tip = tip_content[i] as String
|
||
var btn_margin = MarginContainer.new()
|
||
btn_margin.set("theme_override_constants/margin_left", -5)
|
||
btn_margin.set("theme_override_constants/margin_right", -5)
|
||
btn_margin.set("theme_override_constants/margin_top", -4)
|
||
btn_margin.set("theme_override_constants/margin_bottom", -4)
|
||
var tip_btn = Button.new()
|
||
tip_btn.flat = true
|
||
tip_btn.text = tip
|
||
tip_btn.toggle_mode = true
|
||
tip_btn.set("theme_override_styles/focus", sty_box_empty)
|
||
tip_btn.set("theme_override_font_sizes/font_size", tip_font_size)
|
||
tip_btn.custom_minimum_size = Vector2(tip_font_size, tip_font_size)
|
||
tip_btn.add_theme_color_override("font_color", tip_font_color)
|
||
tip_btn.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||
tip_btn.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||
tip_btn.set_script(tip_script)
|
||
tip_btn.toggled.connect(_on_toggle_btn.bind(tip, tip_btn))
|
||
tip_btn.name = btn_name_prefix + str(i)
|
||
btn_margin.add_child(tip_btn)
|
||
tip_container.add_child(btn_margin)
|
||
# items_dict[tip] = tip_btn
|
||
|
||
|
||
func _on_toggle_btn(toggled_on: bool, content: String, btn) -> void:
|
||
if not toggled_on and items_dict.has(btn.name):
|
||
items_dict[btn.name].queue_free()
|
||
items_dict.erase(content)
|
||
elif toggled_on:
|
||
var item = item_scene.instantiate()
|
||
item.label_text = content
|
||
item.boundart_rect = boundart_rect
|
||
item.position = tip_item_position + Vector2(randf_range(-10, 10), randf_range(-10, 10))
|
||
items_root.add_child(item)
|
||
items_dict[btn.name] = item
|
||
|
||
|
||
func _draw() -> void:
|
||
if Engine.is_editor_hint():
|
||
# draw boundart_rect frame
|
||
draw_rect(boundart_rect, Color(1, 0, 0), false, 2)
|
||
|
||
|
||
var display_tween: Tween
|
||
|
||
|
||
func _toggle_display(use_tween := true):
|
||
if display_tween and display_tween.is_running():
|
||
display_tween.kill()
|
||
if display:
|
||
if use_tween:
|
||
display_tween = create_tween()
|
||
# from bottom to top
|
||
display_tween.tween_property(self, "position:y", 0.0, 0.5).set_trans(Tween.TRANS_CUBIC)
|
||
# unlock items after display
|
||
display_tween.tween_callback(_toggle_items_lock.bind(false))
|
||
else:
|
||
position.y = 0
|
||
_toggle_items_lock(false)
|
||
else:
|
||
# lock items before hide
|
||
_toggle_items_lock(true)
|
||
if use_tween:
|
||
display_tween = create_tween()
|
||
# from top to bottom
|
||
display_tween.tween_property(self, "position:y", 320.0, 0.5).set_trans(
|
||
Tween.TRANS_CUBIC
|
||
)
|
||
else:
|
||
position.y = 320.0
|
||
|
||
|
||
func _toggle_items_lock(lock: bool) -> void:
|
||
for v in items_dict.values():
|
||
v.locked = lock
|
||
|
||
|
||
func _unhandled_input(event: InputEvent) -> void:
|
||
if event.is_action_pressed("toggle_journal"):
|
||
if locked:
|
||
# TODO 使用 icon,去重
|
||
SceneManager.pop_notification("🔒")
|
||
return
|
||
display = !display
|
||
get_viewport().set_input_as_handled()
|