xiandie/config/animation/art_loader.gd

186 lines
5.7 KiB
GDScript

extends Panel
var config_path = "res://config/animation/frames_config.json"
var scan_path = "res://asset/art/characters/"
@onready var config_edit := %ConfigEdit
@onready var frames_display_grid := %FramesDisplayGrid
@onready var search_edit := %SearchLineEdit as LineEdit
@onready var prev_btn := %PrevButton as Button
@onready var next_btn := %NextButton as Button
@onready var page_label := %PageLabel as Label
var all_keys := []
var matched_keys := []
var all_pages := 1
var current_page := 1
const PAGE_SIZE = 6
# 0.png
# 12.png
# 11.png.import
# 31 - 副本.png.import
var frame_png_regex = RegEx.create_from_string("^[^\\d]*(\\d+)\\.png$")
# {
# "dirs": {},
# "mapping": {},
# }
var original_config: JSON
var displayer = preload("res://config/animation/frames_display_card.tscn")
func _ready() -> void:
# var window = get_viewport() as Window
# if window:
# window.content_scale_stretch = Window.CONTENT_SCALE_STRETCH_FRACTIONAL
# window.content_scale_stretch = Window.CONTENT_SCALE_STRETCH_FRACTIONAL
# window.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND
# window.get_visible_rect().size *= 2
# remove cache and reload config
original_config = ResourceLoader.load(
config_path, "JSON", ResourceLoader.CacheMode.CACHE_MODE_IGNORE
)
original_config.resource_path = config_path
_validate_json()
# scan files
_scan()
load_and_display_pages(search_edit.text)
ResourceSaver.save(original_config)
# ResourceUtils.remove_editor_cache("frames_config")
search_edit.text_submitted.connect(load_and_display_pages)
prev_btn.pressed.connect(_on_prev_btn_pressed)
next_btn.pressed.connect(_on_next_btn_pressed)
func _validate_json():
# first_frame_mapping
if !original_config.data.has("first_frame_mapping"):
original_config.data["first_frame_mapping"] = {}
# mirror_mapping
if !original_config.data.has("mirror_mapping"):
original_config.data["mirror_mapping"] = {}
if !original_config.data.has("dirs"):
original_config.data["dirs"] = {}
if !original_config.data.has("mapping"):
original_config.data["mapping"] = {}
if !original_config.data.has("frames_per_second"):
original_config.data["frames_per_second"] = {}
func _scan():
var dir = DirAccess.open(scan_path)
if !dir:
printerr("Failed to open directory:", scan_path)
return
var dirs = {}
for sub_dir in dir.get_directories():
var sub_path = scan_path + sub_dir
var frames = _scan_subdir_frames(sub_path)
if frames.size() > 0:
print("Found frames in:", sub_dir)
# Add to the config
var ids = frames.keys()
ids.sort_custom(func(a, b): return int(a) < int(b))
dirs[sub_dir] = {
"path": sub_path,
"frames": frames,
"ids": ids,
}
else:
print("No frames found in:", sub_dir)
original_config.data["dirs"] = dirs
func _scan_subdir_frames(path: String) -> Dictionary:
var subdir = DirAccess.open(path)
if !subdir:
printerr("Failed to open subdir:", path)
return {}
var frames := {}
# print(path, subdir.get_files())
for file in subdir.get_files():
var regex_match := frame_png_regex.search(file) as RegExMatch
# print('file:', file,' regex:', regex_match)
if regex_match:
var frame_id = int(regex_match.get_string(1))
frames[str(frame_id)] = path + "/" + file
return frames
func load_and_display_pages(search_text):
all_keys = original_config.data.dirs.keys()
all_keys.sort_custom(func(a, b): return a < b)
if search_edit.text:
var regex = RegEx.create_from_string(search_text)
matched_keys.clear()
for key in all_keys:
if regex.search(key):
matched_keys.append(key)
else:
matched_keys.clear()
matched_keys.append_array(all_keys)
all_pages = ceil(float(matched_keys.size()) / PAGE_SIZE)
current_page = clamp(current_page, 1, all_pages)
_load_current_page()
func _on_prev_btn_pressed():
if current_page <= 1:
current_page = all_pages
else:
current_page -= 1
_load_current_page()
func _on_next_btn_pressed():
if current_page >= all_pages:
current_page = 1
else:
current_page += 1
_load_current_page()
func _load_current_page():
page_label.text = str(current_page) + "/" + str(all_pages)
var start = (current_page - 1) * PAGE_SIZE
var end = min(start + PAGE_SIZE, matched_keys.size())
var current_keys = matched_keys.slice(start, end)
_display_cards(current_keys)
# config_edit show current page
var text = ""
for key in current_keys:
text += key + "\n"
config_edit.text = text
func _display_cards(current_keys: Array):
# clear frames_display_grid
for child in frames_display_grid.get_children():
child.queue_free()
# add cards
for frames_name in current_keys:
var card = displayer.instantiate()
card.frames_config = original_config
card.frame_dir_name = frames_name
#mapping[frames_name] = original_config.data['mapping'][frames_name]
#frames_per_second[frames_name] = original_config.data['frames_per_second'][frames_name]
if not original_config.data["mapping"].has(frames_name):
original_config.data.mapping[frames_name] = frames_name
# frames_per_second
if not original_config.data["frames_per_second"].has(frames_name):
original_config.data.frames_per_second[frames_name] = 5
# mirror_mapping
if not original_config.data["mirror_mapping"].has(frames_name):
original_config.data.mirror_mapping[frames_name] = ""
# first_frame_mapping
if not original_config.data["first_frame_mapping"].has(frames_name):
original_config.data.first_frame_mapping[frames_name] = ""
card.mapping_name = original_config.data.mapping[frames_name]
card.frames_per_sec = original_config.data.frames_per_second[frames_name]
card.mirror_mapping = original_config.data.mirror_mapping[frames_name]
card.first_frame_mapping = original_config.data.first_frame_mapping[frames_name]
frames_display_grid.add_child(card)
card.scale = Vector2(0.5, 0.5)