xiandie/manager/archive_manager/savings_panel.gd

315 lines
8.9 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends Control
# UI References
@onready var quit_debug_button: Button = %QuitDebugModeButton
@onready var archive_grid: GridContainer = %ArchiveGrid
@onready var scroll_container: ScrollContainer = %ScrollContainer
@onready var current_archive_label: Label = %CurrentArchiveLabel
@onready var name_input: LineEdit = %NameInput
@onready var save_button: Button = %SaveButton
@onready var refresh_button: Button = %RefreshButton
# Constants
const MAX_MANUAL_ARCHIVES = 99
const GRID_COLUMNS = 4
# Variables
var manual_archives: Dictionary = {} # {id: {name: String, path: String, time: String}}
var next_available_id: int = 2 # Start from 2 since 1 is reserved for main archive
func _ready() -> void:
get_parent().layer = GlobalConfig.CANVAS_LAYER_SETTINGS
# Setup UI
archive_grid.columns = GRID_COLUMNS
# Connect signals
quit_debug_button.pressed.connect(_on_quit_debug_button_pressed)
save_button.pressed.connect(_on_save_button_pressed)
refresh_button.pressed.connect(_refresh_archive_list)
name_input.text_submitted.connect(_on_name_submitted)
# Set default name
_update_default_name()
# Initial load
_refresh_archive_list()
_update_current_archive_label()
func _update_current_archive_label() -> void:
current_archive_label.text = "当前使用存档1号存档主存档"
func _update_default_name() -> void:
name_input.placeholder_text = "输入存档名称"
var chapter_name = EventManager.get_chapter_stage()
if chapter_name == 1:
chapter_name = "序章"
elif chapter_name <= 5:
chapter_name = "%s" % (chapter_name - 1)
elif chapter_name == 6:
chapter_name = "结尾"
else:
chapter_name = "未知"
var scene_name = SceneManager.get_current_scene_name()
var saving_name = chapter_name + "_" + scene_name
name_input.text = _get_unique_archive_name(saving_name)
func _on_name_submitted(_text: String) -> void:
_on_save_button_pressed()
func _on_quit_debug_button_pressed() -> void:
# 不写入配置
GlobalConfig.DEBUG = false
quit()
func _on_save_button_pressed() -> void:
# Check limit
if manual_archives.size() >= MAX_MANUAL_ARCHIVES:
_show_notification("已达到最大存档数量限制99个")
return
# Get and validate name
var archive_name = name_input.text.strip_edges()
if archive_name.is_empty():
archive_name = "未命名存档_" + Time.get_datetime_string_from_system()
# Save current progress
ArchiveManager.save_all()
# Get unique name
archive_name = _get_unique_archive_name(archive_name)
# Copy current archive
_copy_current_archive(archive_name)
# Reset input field
_update_default_name()
name_input.select_all()
func _get_unique_archive_name(base_name: String) -> String:
var final_name = base_name
var counter = 1
# Check if name already exists
var name_exists = true
while name_exists:
name_exists = false
for data in manual_archives.values():
if data.name == final_name:
name_exists = true
final_name = base_name + "_" + str(counter)
counter += 1
break
return final_name
func _copy_current_archive(archive_name: String) -> void:
# Get current archive path
var current_archive = ArchiveManager.archive
if not current_archive:
_show_notification("当前没有活动存档")
return
# Find next available ID
while manual_archives.has(next_available_id) and next_available_id <= MAX_MANUAL_ARCHIVES + 1:
next_available_id += 1
if next_available_id > MAX_MANUAL_ARCHIVES + 1:
_show_notification("无法创建更多存档")
return
# Create new archive path
var new_archive_path = (
ArchiveManager.user_archives_dir
+ "manual_"
+ str(next_available_id)
+ "_"
+ archive_name.validate_filename()
+ GlobalConfig.RES_FILE_FORMAT
)
# Copy the archive file
var source_path = current_archive.resource_path
var dir = DirAccess.open(ArchiveManager.user_archives_dir)
if dir:
var error = dir.copy(source_path, new_archive_path)
print("Copying archive from: ", source_path, " to: ", new_archive_path)
if error == OK:
# Save manual archive info
manual_archives[next_available_id] = {
"name": archive_name,
"path": new_archive_path,
"time": Time.get_datetime_string_from_system(false, true)
}
# Save manual archives data
_save_manual_archives_data()
# Refresh UI
_refresh_archive_list()
_show_notification("存档已保存:" + archive_name)
next_available_id += 1
else:
_show_notification("存档复制失败:" + error_string(error))
else:
_show_notification("无法访问存档目录")
func _refresh_archive_list() -> void:
# refresh savings name
_update_default_name()
# Clear existing items
for child in archive_grid.get_children():
child.queue_free()
# Load manual archives data
_load_manual_archives_data()
# Create UI items for each manual archive
var sorted_ids = manual_archives.keys()
sorted_ids.sort()
for id in sorted_ids:
var data = manual_archives[id]
_create_archive_item(id, data)
func _create_archive_item(id: int, data: Dictionary) -> void:
# Create container for the archive item
var item_container = PanelContainer.new()
item_container.custom_minimum_size = Vector2(200, 60)
var vbox = VBoxContainer.new()
vbox.add_theme_constant_override("separation", 4)
item_container.add_child(vbox)
# Archive name (editable)
var name_edit = LineEdit.new()
name_edit.text = data.name
name_edit.tooltip_text = "创建时间:" + data.time
vbox.add_child(name_edit)
# Time label
var time_label = Label.new()
time_label.text = data.time
time_label.add_theme_font_size_override("font_size", 12)
time_label.modulate.a = 0.7
vbox.add_child(time_label)
# Action buttons container
var button_container = HBoxContainer.new()
button_container.add_theme_constant_override("separation", 4)
# Load button
var load_btn = Button.new()
load_btn.text = "加载"
load_btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL
button_container.add_child(load_btn)
# Delete button
var delete_btn = Button.new()
delete_btn.text = "删除"
delete_btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL
button_container.add_child(delete_btn)
vbox.add_child(button_container)
# Connect signals
name_edit.text_changed.connect(func(new_text): _on_archive_renamed(id, new_text))
load_btn.pressed.connect(func(): _load_manual_archive(id, data))
delete_btn.pressed.connect(func(): _delete_manual_archive(id))
archive_grid.add_child(item_container)
func _on_archive_renamed(id: int, new_name: String) -> void:
if new_name.strip_edges().is_empty():
return
# Update name in data
manual_archives[id].name = new_name.strip_edges()
# Save changes
_save_manual_archives_data()
func _load_manual_archive(_id: int, data: Dictionary) -> void:
# Save current state first
ArchiveManager.save_all()
# Copy manual archive to archive 1
var dir = DirAccess.open(ArchiveManager.user_archives_dir)
if dir:
var saving_archive = load(data.path)
if saving_archive:
var target_path = ArchiveManager.get_archive_path(1)
print("Loading archive from: ", data.path, " to: ", target_path)
GlobalConfigManager.config.current_selected_archive_id = 1
if ArchiveManager.archive:
saving_archive.take_over_path(target_path)
else:
saving_archive.resource_path = target_path
ArchiveManager.archives_dict[1] = saving_archive
ArchiveManager.archive = saving_archive
print("Loading archive from: ", data.path, " to: ", target_path)
# Reload current scene
get_tree().reload_current_scene()
else:
_show_notification("加载存档失败:" + data.name)
func _delete_manual_archive(id: int) -> void:
var data = manual_archives[id]
# Delete file
var dir = DirAccess.open(ArchiveManager.user_archives_dir)
if dir:
dir.remove(data.path)
# Remove from dictionary
manual_archives.erase(id)
# Save changes
_save_manual_archives_data()
# Refresh UI
_refresh_archive_list()
_show_notification("已删除存档:" + data.name)
func _save_manual_archives_data() -> void:
var save_path = ArchiveManager.user_data_root_dir + "test_manual_archives.dat"
var file = FileAccess.open(save_path, FileAccess.WRITE)
if file:
file.store_var(manual_archives)
file.close()
func _load_manual_archives_data() -> void:
var save_path = ArchiveManager.user_data_root_dir + "test_manual_archives.dat"
if FileAccess.file_exists(save_path):
var file = FileAccess.open(save_path, FileAccess.READ)
if file:
manual_archives = file.get_var()
file.close()
# Find next available ID
next_available_id = 2
for id in manual_archives.keys():
if id >= next_available_id:
next_available_id = id + 1
func _show_notification(message: String) -> void:
SceneManager.pop_notification(message)
func _enter_tree() -> void:
SceneManager.toggle_pause_counter(true, "savings")
func _exit_tree() -> void:
SceneManager.toggle_pause_counter(false, "savings")
func quit() -> void:
queue_free()
func _unhandled_input(event: InputEvent) -> void:
# savings 界面接受所有输入事件
get_viewport().set_input_as_handled()
if (
event.is_action_pressed("savings")
or event.is_action_pressed("cancel")
or event.is_action_pressed("escape")
):
quit()