extends Control var config_path = "res://config/animation/frames_config.json" var scan_path = "res://asset/art/animation/" @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 = 14 # 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] = 6 # 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)