From 54bf90472788552925a4aa244f475e4f988656a3 Mon Sep 17 00:00:00 2001 From: Insality Date: Sun, 9 Nov 2025 19:16:04 +0200 Subject: [PATCH] Up --- druid/component.lua | 3 +- druid/editor_scripts/core/path_replacer.lua | 144 ++++++++++++++++++++ druid/system/druid_instance.lua | 2 +- 3 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 druid/editor_scripts/core/path_replacer.lua diff --git a/druid/component.lua b/druid/component.lua index 4ed835c..79ef59a 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -410,7 +410,7 @@ local WIDGET_METATABLE = { __index = M } function M.create_widget(self, widget_class, context) local instance = setmetatable({}, { __index = setmetatable(widget_class, WIDGET_METATABLE) - }) + }) --[[@as druid.widget]] instance._component = { _uid = M.create_uid(), @@ -440,7 +440,6 @@ function M.create_widget(self, widget_class, context) instance._meta.parent:__add_child(instance) end - ---@cast instance druid.widget return instance end diff --git a/druid/editor_scripts/core/path_replacer.lua b/druid/editor_scripts/core/path_replacer.lua new file mode 100644 index 0000000..53e5947 --- /dev/null +++ b/druid/editor_scripts/core/path_replacer.lua @@ -0,0 +1,144 @@ +--- Module for replacing widget paths in installed files +--- Handles path replacement from original widget structure to user's installation path + +local system = require("druid.editor_scripts.defold_parser.system.parser_internal") + +local M = {} + + +---Detect the original path structure from item data +---Builds widget/author/widget_id path +---@param author string|nil - Author name +---@param widget_id string - Widget ID +---@return string|nil - Original path prefix (e.g., "widget/Insality/fps_panel") or nil +local function detect_original_path_from_item(author, widget_id) + if not author or not widget_id then + return nil + end + + local original_path = "widget/" .. author .. "/" .. widget_id + print("Detected original path from item:", original_path) + return original_path +end + + +---Replace paths in file content +---@param content string - File content +---@param original_path string - Original path to replace (e.g., "widget/Insality/fps_panel") +---@param target_path string - Target path (e.g., "widget/fps_panel") +---@return string - Modified content +local function replace_paths_in_content(content, original_path, target_path) + if not content or not original_path or not target_path then + return content + end + + -- Escape special characters for literal string replacement + local function escape_pattern(str) + return str:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") + end + + -- Replace paths with forward slashes: widget/Insality/fps_panel -> widget/fps_panel + local escaped_original = escape_pattern(original_path) + content = content:gsub(escaped_original, target_path) + + -- Replace require statements with dots: widget.Insality.fps_panel -> widget.fps_panel + local original_dots = original_path:gsub("/", ".") + local target_dots = target_path:gsub("/", ".") + local escaped_original_dots = escape_pattern(original_dots) + content = content:gsub(escaped_original_dots, target_dots) + + return content +end + + +---Process widget paths in all files +---@param folder_path string - Path to the unpacked widget folder +---@param install_folder string - Installation folder (e.g., "widget") +---@param widget_id string - Widget ID (e.g., "fps_panel") +---@param author string|nil - Author name (e.g., "Insality") +---@param file_list table - Optional list of file paths from zip content +---@return boolean, string|nil - Success status and error message if any +function M.process_widget_paths(folder_path, install_folder, widget_id, author, file_list) + print("Processing widget paths in:", folder_path) + + -- Detect original path structure from item data + local original_path = detect_original_path_from_item(author, widget_id) + + if not original_path then + print("Warning: Could not detect original path structure (missing author or widget_id), skipping path replacement") + return true, nil + end + + -- Construct target path + -- Remove leading / from install_folder if present + local clean_install_folder = install_folder + if clean_install_folder:sub(1, 1) == "/" then + clean_install_folder = clean_install_folder:sub(2) + end + + local target_path = clean_install_folder + if widget_id then + if target_path ~= "" then + target_path = target_path .. "/" .. widget_id + else + target_path = widget_id + end + end + + print("Replacing paths from:", original_path, "to:", target_path) + + -- Get absolute project path + local absolute_project_path = editor.external_file_attributes(".").path + if not absolute_project_path:match("[\\/]$") then + absolute_project_path = absolute_project_path .. "/" + end + + -- Clean folder_path + local clean_folder_path = folder_path + if clean_folder_path:sub(1, 1) == "." then + clean_folder_path = clean_folder_path:sub(2) + end + if clean_folder_path:sub(1, 1) == "/" then + clean_folder_path = clean_folder_path:sub(2) + end + + -- Process each file from the list + local processed_count = 0 + for _, file_path_in_zip in ipairs(file_list) do + -- Build full path to the file after unpacking + local file_path = clean_folder_path .. "/" .. file_path_in_zip + + -- Get absolute path + local clean_file_path = file_path + if clean_file_path:sub(1, 1) == "/" then + clean_file_path = clean_file_path:sub(2) + end + local absolute_file_path = absolute_project_path .. clean_file_path + + -- Read file content + local content, err = system.read_file(absolute_file_path) + if not content then + print("Warning: Could not read file:", file_path, err) + else + -- Replace paths + local modified_content = replace_paths_in_content(content, original_path, target_path) + if modified_content ~= content then + -- Write modified content back + local success, write_err = system.write_file(absolute_file_path, modified_content) + if success then + processed_count = processed_count + 1 + print("Processed:", file_path) + else + print("Warning: Could not write file:", file_path, write_err) + end + end + end + end + + print("Path replacement complete. Processed", processed_count, "files") + return true, nil +end + + +return M + diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 52c8b1b..f38b4d5 100755 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -357,7 +357,7 @@ function M:on_input(action_id, action) for i = #components, 1, -1 do local component = components[i] - local input_enabled = component:get_input_enabled() + local input_enabled = component._meta.input_enabled if input_enabled and self:_can_use_input_component(component) then if not is_input_consumed then