tools_panel.gd 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. @tool
  2. class_name ModToolsPanel
  3. extends Control
  4. # passed from the EditorPlugin
  5. var mod_tool_store: ModToolStore
  6. var editor_plugin: EditorPlugin: set = set_editor_plugin
  7. var context_actions: FileSystemContextActions
  8. var tab_parent_bottom_panel: PanelContainer
  9. var log_richtext_label: RichTextLabel
  10. var log_dock_button: Button
  11. @onready var mod_tool_store_node: ModToolStore = get_node_or_null("/root/ModToolStore")
  12. @onready var tab_container := $"%TabContainer"
  13. @onready var create_mod := $"%CreateMod"
  14. @onready var select_mod := $"%SelectMod"
  15. @onready var label_output := $"%Output"
  16. @onready var mod_id := $"%ModId"
  17. @onready var manifest_editor := $"%Manifest Editor"
  18. @onready var export_path := $"%ExportPath"
  19. @onready var file_dialog := $"%FileDialog"
  20. @onready var hook_gen: ModToolInterfaceHookGen = %HookGen
  21. @onready var hook_restore: ModToolInterfaceHookRestore = %HookRestore
  22. @onready var button_add_hooks: Button = %AddHooks
  23. @onready var button_restore: Button = %Restore
  24. func _ready() -> void:
  25. tab_parent_bottom_panel = get_parent().get_parent() as PanelContainer
  26. get_log_nodes()
  27. if mod_tool_store:
  28. if mod_tool_store.is_hook_generation_done:
  29. button_add_hooks.hide()
  30. else:
  31. button_restore.hide()
  32. # Load manifest.json file
  33. if _ModLoaderFile.file_exists(mod_tool_store.path_manifest):
  34. manifest_editor.load_manifest()
  35. manifest_editor.update_ui()
  36. else:
  37. # Load template Manifest
  38. var template_manifest_data := _ModLoaderFile.get_json_as_dict("res://addons/mod_tool/templates/minimal/manifest.json")
  39. mod_tool_store.manifest_data = ModManifest.new(template_manifest_data, "")
  40. _update_ui()
  41. func set_editor_plugin(plugin: EditorPlugin) -> void:
  42. editor_plugin = plugin
  43. mod_tool_store.editor_plugin = editor_plugin
  44. mod_tool_store.editor_file_system = EditorInterface.get_resource_filesystem()
  45. mod_tool_store.editor_base_control = EditorInterface.get_base_control()
  46. context_actions = FileSystemContextActions.new(
  47. mod_tool_store,
  48. EditorInterface.get_file_system_dock()
  49. )
  50. func get_log_nodes() -> void:
  51. var editor_log := get_parent().get_child(0)
  52. log_richtext_label = editor_log.get_child(1) as RichTextLabel
  53. if not log_richtext_label:
  54. # on project load it can happen that these nodes don't exist yet, wait for parent
  55. await get_parent().ready
  56. log_richtext_label = editor_log.get_child(1) as RichTextLabel
  57. # The button hbox should be last, but here it is second from last for some reason
  58. var dock_tool_button_bar: HBoxContainer = get_parent().get_child(get_parent().get_child_count() -2)
  59. log_dock_button = dock_tool_button_bar.get_child(0).get_child(0)
  60. # Removes the last error line from the output console as if nothing happened
  61. # used in the json validation since the error is displayed right there and
  62. # it causes a lot of clutter otherwise
  63. func discard_last_console_error() -> void:
  64. # If the console is flooded anyway, ignore
  65. var line_count := log_richtext_label.get_line_count()
  66. if line_count > 1000:
  67. return
  68. # The last line is an empty line, remove the one before that
  69. log_richtext_label.remove_line(line_count -2)
  70. log_richtext_label.add_text("\n")
  71. # If there is an error in the console already, leave the circle on the tool button
  72. # All error lines have a space in the beginnig to separate from the circle image
  73. # Not the safest way to check, but it's the only one it seems
  74. for line in log_richtext_label.text.split("\n"):
  75. if (line as String).begins_with(" "):
  76. return
  77. # If there were no other error lines, remove the icon
  78. # Setting to null will crash the editor occasionally, this does not
  79. if log_dock_button:
  80. log_dock_button.icon = CompressedTexture2D.new()
  81. func show_manifest_editor() -> void:
  82. tab_container.current_tab = 0
  83. func show_config_editor() -> void:
  84. tab_container.current_tab = 1
  85. func _update_ui() -> void:
  86. if not mod_tool_store:
  87. return
  88. mod_id.input_text = mod_tool_store.name_mod_dir
  89. export_path.input_text = mod_tool_store.path_export_dir
  90. func _is_mod_dir_valid() -> bool:
  91. # Check if Mod ID is given
  92. if mod_tool_store.name_mod_dir == '':
  93. ModToolUtils.output_error("Please provide a Mod ID")
  94. return false
  95. # Check if mod dir exists
  96. if not _ModLoaderFile.dir_exists(mod_tool_store.path_mod_dir):
  97. ModToolUtils.output_error("Mod folder %s does not exist" % mod_tool_store.path_mod_dir)
  98. return false
  99. return true
  100. func load_mod(name_mod_dir: String) -> void:
  101. # Set the dir name
  102. mod_tool_store.name_mod_dir = name_mod_dir
  103. # Load Manifest
  104. manifest_editor.load_manifest()
  105. manifest_editor.update_ui()
  106. # TODO: Load Mod Config if existing
  107. ModToolUtils.output_info("Mod \"%s\" loaded." % name_mod_dir)
  108. func _on_export_pressed() -> void:
  109. if _is_mod_dir_valid():
  110. var zipper := ModToolZipBuilder.new()
  111. zipper.build_zip(mod_tool_store)
  112. func _on_clear_output_pressed() -> void:
  113. label_output.clear()
  114. func _on_copy_output_pressed() -> void:
  115. DisplayServer.clipboard_set(label_output.text)
  116. func _on_save_manifest_pressed() -> void:
  117. manifest_editor.save_manifest()
  118. func _on_export_settings_create_new_mod_pressed() -> void:
  119. create_mod.popup_centered()
  120. create_mod.clear_mod_id_input()
  121. func _on_CreateMod_mod_dir_created() -> void:
  122. create_mod.hide()
  123. _update_ui()
  124. manifest_editor.load_manifest()
  125. manifest_editor.update_ui()
  126. func _on_ConnectMod_pressed() -> void:
  127. # Opens a popup that displays the mod directory names in the mods-unpacked directory
  128. select_mod.generate_dir_buttons(ModLoaderMod.get_unpacked_dir())
  129. select_mod.popup_centered()
  130. func _on_SelectMod_dir_selected(dir_path: String) -> void:
  131. var mod_dir_name := dir_path.split("/")[-1]
  132. load_mod(mod_dir_name)
  133. select_mod.hide()
  134. _update_ui()
  135. func _on_ButtonExportPath_pressed() -> void:
  136. file_dialog.current_path = mod_tool_store.path_export_dir
  137. file_dialog.popup_centered()
  138. func _on_FileDialog_dir_selected(dir: String) -> void:
  139. mod_tool_store.path_export_dir = dir
  140. export_path.input_text = dir
  141. file_dialog.hide()
  142. func _on_add_hooks_pressed() -> void:
  143. hook_gen.show()
  144. func _on_restore_pressed() -> void:
  145. hook_restore.show()
  146. func _on_hook_gen_hooks_exist_pressed() -> void:
  147. button_add_hooks.hide()
  148. button_restore.show()