diff --git a/druid/custom/rich_input/rich_input.gui b/druid/custom/rich_input/rich_input.gui deleted file mode 100644 index c179f20..0000000 --- a/druid/custom/rich_input/rich_input.gui +++ /dev/null @@ -1,160 +0,0 @@ -fonts { - name: "druid_text_bold" - font: "/druid/fonts/druid_text_bold.font" -} -textures { - name: "druid" - texture: "/druid/druid.atlas" -} -nodes { - size { - x: 200.0 - y: 40.0 - } - type: TYPE_BOX - id: "root" - inherit_alpha: true - visible: false -} -nodes { - size { - x: 200.0 - y: 40.0 - } - color { - x: 0.31 - y: 0.318 - z: 0.322 - } - type: TYPE_BOX - texture: "druid/rect_round2_width2" - id: "button" - parent: "root" - inherit_alpha: true - slice9 { - x: 4.0 - y: 4.0 - z: 4.0 - w: 4.0 - } -} -nodes { - scale { - x: 0.5 - y: 0.5 - } - size { - x: 380.0 - y: 50.0 - } - color { - x: 0.31 - y: 0.318 - z: 0.322 - } - type: TYPE_TEXT - text: "Placeholder" - font: "druid_text_bold" - id: "placeholder_text" - outline { - x: 0.4 - y: 0.4 - z: 0.4 - } - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - } - parent: "root" - inherit_alpha: true - outline_alpha: 0.0 - shadow_alpha: 0.0 -} -nodes { - scale { - x: 0.5 - y: 0.5 - } - size { - x: 380.0 - y: 50.0 - } - color { - x: 0.722 - y: 0.741 - z: 0.761 - } - type: TYPE_TEXT - text: "User input" - font: "druid_text_bold" - id: "input_text" - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - } - parent: "root" - inherit_alpha: true - outline_alpha: 0.0 - shadow_alpha: 0.0 -} -nodes { - position { - x: 61.0 - } - scale { - x: 0.5 - y: 0.5 - } - size { - x: 16.0 - y: 50.0 - } - color { - x: 0.631 - y: 0.843 - z: 0.961 - } - type: TYPE_BOX - texture: "druid/ui_circle_16" - id: "cursor_node" - parent: "root" - inherit_alpha: true - slice9 { - x: 8.0 - y: 8.0 - z: 8.0 - w: 8.0 - } - alpha: 0.5 -} -nodes { - position { - x: -1.4 - y: 4.0 - } - size { - x: 20.0 - y: 40.0 - } - color { - x: 0.722 - y: 0.741 - z: 0.761 - } - type: TYPE_TEXT - text: "|" - font: "druid_text_bold" - id: "cursor_text" - shadow { - x: 1.0 - y: 1.0 - z: 1.0 - } - parent: "cursor_node" - outline_alpha: 0.0 - shadow_alpha: 0.0 -} -material: "/builtins/materials/gui.material" -adjust_reference: ADJUST_REFERENCE_PARENT diff --git a/druid/custom/rich_input/rich_input.lua b/druid/custom/rich_input/rich_input.lua deleted file mode 100644 index 213d14d..0000000 --- a/druid/custom/rich_input/rich_input.lua +++ /dev/null @@ -1,301 +0,0 @@ -local component = require("druid.component") -local helper = require("druid.helper") -local const = require("druid.const") -local utf8_lua = require("druid.system.utf8") -local utf8 = utf8 or utf8_lua - ----The component that handles a rich text input field, it's a wrapper around the druid.input component ----@class druid.rich_input: druid.component ----@field root node The root node of the rich input ----@field input druid.input The input component ----@field cursor node The cursor node ----@field cursor_text node The cursor text node ----@field cursor_position vector3 The position of the cursor -local M = component.create("druid.rich_input") - -local DOUBLE_CLICK_TIME = 0.35 - -local function animate_cursor(self) - gui.cancel_animation(self.cursor_text, "color.w") - gui.set_alpha(self.cursor_text, 1) - gui.animate(self.cursor_text, "color.w", 0, gui.EASING_INSINE, 0.8, 0, nil, gui.PLAYBACK_LOOP_PINGPONG) -end - - -local function set_selection_width(self, selection_width) - gui.set_visible(self.cursor, selection_width > 0) - - local width = selection_width / self.input.text.scale.x - local height = gui.get_size(self.cursor).y - gui.set_size(self.cursor, vmath.vector3(width, height, 0)) - - local is_selection_to_right = self.input.cursor_index == self.input.end_index - gui.set_pivot(self.cursor, is_selection_to_right and gui.PIVOT_E or gui.PIVOT_W) -end - - ----@param self druid.rich_input -local function update_text(self) - local full_text = self.input:get_text() - local visible_text = self.input.text:get_text() - - local is_truncated = visible_text ~= full_text - local cursor_index = self.input.cursor_index - if is_truncated then - -- If text is truncated, we need to adjust the cursor index - -- to the last visible character - cursor_index = utf8.len(visible_text) - - end - - local left_text_part = utf8.sub(self.input:get_text(), 0, cursor_index) - local selected_text_part = utf8.sub(self.input:get_text(), self.input.start_index + 1, self.input.end_index) - - local left_part_width = self.input.text:get_text_size(left_text_part) - local selected_part_width = self.input.text:get_text_size(selected_text_part) - - local pivot_text = gui.get_pivot(self.input.text.node) - local pivot_offset = helper.get_pivot_offset(pivot_text) - - self.cursor_position.x = self.text_position.x - self.input.text_width * (0.5 + pivot_offset.x) + left_part_width - - gui.set_position(self.cursor, self.cursor_position) - gui.set_scale(self.cursor, self.input.text.scale) - - set_selection_width(self, selected_part_width) -end - - -local function on_select(self) - gui.set_enabled(self.cursor, true) - gui.set_enabled(self.placeholder.node, false) - gui.set_enabled(self.input.button.node, true) - - animate_cursor(self) - self.drag:set_enabled(true) -end - - -local function on_unselect(self) - gui.cancel_animation(self.cursor, gui.PROP_COLOR) - gui.set_enabled(self.cursor, false) - gui.set_enabled(self.input.button.node, self.is_button_input_enabled) - gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0) - - self.drag:set_enabled(false) -end - - ----Update selection -local function update_selection(self) - update_text(self) -end - - -local TEMP_VECTOR = vmath.vector3(0) -local function get_index_by_touch(self, touch) - local text_node = self.input.text.node - TEMP_VECTOR.x = touch.screen_x - TEMP_VECTOR.y = touch.screen_y - - -- Distance to the text node position - local scene_scale = helper.get_scene_scale(text_node) - local local_pos = gui.screen_to_local(text_node, TEMP_VECTOR) - local_pos.x = local_pos.x / scene_scale.x - - -- Offset to the left side of the text node - local pivot_offset = helper.get_pivot_offset(gui.get_pivot(text_node)) - local_pos.x = local_pos.x + self.input.total_width * (0.5 + pivot_offset.x) - local_pos.x = local_pos.x - self.text_position.x - - local cursor_index = self.input.text:get_text_index_by_width(local_pos.x) - return cursor_index -end - - -local function on_touch_start_callback(self, touch) - local cursor_index = get_index_by_touch(self, touch) - - if self._last_touch_info.cursor_index == cursor_index then - local time = socket.gettime() - if time - self._last_touch_info.time < DOUBLE_CLICK_TIME then - local len = utf8.len(self.input:get_text()) - self.input:select_cursor(len, 0, len) - self._last_touch_info.cursor_index = nil - - return - end - end - - self._last_touch_info.cursor_index = cursor_index - self._last_touch_info.time = socket.gettime() - - if self.input.is_lshift then - local start_index = self.input.start_index - local end_index = self.input.end_index - - if cursor_index < start_index then - self.input:select_cursor(cursor_index, cursor_index, end_index) - elseif cursor_index > end_index then - self.input:select_cursor(cursor_index, start_index, cursor_index) - end - else - self.input:select_cursor(cursor_index) - end -end - - ----@param self druid.rich_input ----@param dx number The delta x position ----@param dy number The delta y position ----@param x number The x position ----@param y number The y position ----@param touch table The touch table -local function on_drag_callback(self, dx, dy, x, y, touch) - if not self._last_touch_info.cursor_index then - return - end - - local index = get_index_by_touch(self, touch) - if self._last_touch_info.cursor_index <= index then - self.input:select_cursor(index, self._last_touch_info.cursor_index, index) - else - self.input:select_cursor(index, index, self._last_touch_info.cursor_index) - end -end - - ----@param template string The template string name ----@param nodes table Nodes table from gui.clone_tree -function M:init(template, nodes) - self.druid = self:get_druid(template, nodes) - self.root = self:get_node("root") - - self._last_touch_info = { - cursor_index = nil, - time = 0, - } - self.is_lshift = false - self.is_lctrl = false - - self.input = self.druid:new_input("button", "input_text") - self.is_button_input_enabled = gui.is_enabled(self.input.button.node) - - self.cursor = self:get_node("cursor_node") - self.cursor_position = gui.get_position(self.cursor) - self.cursor_text = self:get_node("cursor_text") - - self.drag = self.druid:new_drag("button", on_drag_callback) - self.drag.on_touch_start:subscribe(on_touch_start_callback) - self.drag:set_input_priority(const.PRIORITY_INPUT_MAX + 1) - self.drag:set_enabled(false) - - self.input:set_text("") - self.placeholder = self.druid:new_text("placeholder_text") - self.text_position = gui.get_position(self.input.text.node) - - self.input.on_input_text:subscribe(update_text) - self.input.on_input_select:subscribe(on_select) - self.input.on_input_unselect:subscribe(on_unselect) - self.input.on_select_cursor_change:subscribe(update_selection) - - on_unselect(self) - update_text(self) -end - - ----@private ----@param action_id hash Action id from on_input ----@param action table Action table from on_input ----@return boolean is_consumed True if input was consumed -function M:on_input(action_id, action) - if action_id == const.ACTION_LSHIFT then - if action.pressed then - self.is_lshift = true - elseif action.released then - self.is_lshift = false - end - end - - if action_id == const.ACTION_LCTRL or action_id == const.ACTION_LCMD then - if action.pressed then - self.is_lctrl = true - elseif action.released then - self.is_lctrl = false - end - end - - if self.input.is_selected then - if action_id == const.ACTION_LEFT and (action.pressed or action.repeated) then - self.input:move_selection(-1, self.is_lshift, self.is_lctrl) - return true - end - - if action_id == const.ACTION_RIGHT and (action.pressed or action.repeated) then - self.input:move_selection(1, self.is_lshift, self.is_lctrl) - return true - end - end - - return false -end - - ----Set placeholder text ----@param placeholder_text string The placeholder text ----@return druid.rich_input self Current instance -function M:set_placeholder(placeholder_text) - self.placeholder:set_text(placeholder_text) - return self -end - - ----Select input field ----@return druid.rich_input self Current instance -function M:select() - self.input:select() - return self -end - - ----Set input field text ----@param text string The input text ----@return druid.rich_input self Current instance -function M:set_text(text) - self.input:set_text(text) - gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0) - - return self -end - - ----Set input field font ----@param font hash The font hash ----@return druid.rich_input self Current instance -function M:set_font(font) - gui.set_font(self.input.text.node, font) - gui.set_font(self.placeholder.node, font) - - return self -end - - ----Set input field text -function M:get_text() - return self.input:get_text() -end - - ----Set allowed charaters for input field. --- See: https://defold.com/ref/stable/string/ --- ex: [%a%d] for alpha and numeric ----@param characters string Regular expression for validate user input ----@return druid.rich_input self Current instance -function M:set_allowed_characters(characters) - self.input:set_allowed_characters(characters) - - return self -end - - -return M diff --git a/druid/custom/rich_text/module/rt_color.lua b/druid/custom/rich_text/module/rt_color.lua deleted file mode 100644 index 6729998..0000000 --- a/druid/custom/rich_text/module/rt_color.lua +++ /dev/null @@ -1,50 +0,0 @@ --- Source: https://github.com/britzl/defold-richtext version 5.19.0 --- Author: Britzl --- Modified by: Insality - -local M = {} -local cache = {} - -function M.parse_hex(hex) - if cache[hex] then - return cache[hex] - end - - local r,g,b,a = hex:match("#?(%x%x)(%x%x)(%x%x)(%x?%x?)") - if a == "" then a = "ff" end - if r and g and b and a then - local color = vmath.vector4( - tonumber(r, 16) / 255, - tonumber(g, 16) / 255, - tonumber(b, 16) / 255, - tonumber(a, 16) / 255 - ) - - cache[hex] = color - return color - end - return nil -end - - -function M.parse_decimal(dec) - if cache[dec] then - return cache[dec] - end - - local r,g,b,a = dec:match("(%d*%.?%d*),(%d*%.?%d*),(%d*%.?%d*),(%d*%.?%d*)") - if r and g and b and a then - local color = vmath.vector4(tonumber(r) or 0, tonumber(g) or 0, tonumber(b) or 0, tonumber(a) or 1) - cache[dec] = color - return color - end - return nil -end - - -function M.parse(c) - return M.parse_hex(c) or M.parse_decimal(c) -end - - -return M diff --git a/druid/custom/rich_text/module/rt.lua b/druid/extended/rich_text/module/rt.lua similarity index 99% rename from druid/custom/rich_text/module/rt.lua rename to druid/extended/rich_text/module/rt.lua index 871c736..a63aacc 100755 --- a/druid/custom/rich_text/module/rt.lua +++ b/druid/extended/rich_text/module/rt.lua @@ -4,7 +4,7 @@ -- Modified by: Insality local helper = require("druid.helper") -local parser = require("druid.custom.rich_text.module.rt_parse") +local parser = require("druid.extended.rich_text.module.rt_parse") local utf8_lua = require("druid.system.utf8") local utf8 = utf8 or utf8_lua diff --git a/druid/custom/rich_text/module/rt_parse.lua b/druid/extended/rich_text/module/rt_parse.lua similarity index 98% rename from druid/custom/rich_text/module/rt_parse.lua rename to druid/extended/rich_text/module/rt_parse.lua index 632380f..83bb955 100755 --- a/druid/custom/rich_text/module/rt_parse.lua +++ b/druid/extended/rich_text/module/rt_parse.lua @@ -2,7 +2,7 @@ -- Author: Britzl -- Modified by: Insality -local tags = require("druid.custom.rich_text.module.rt_tags") +local tags = require("druid.extended.rich_text.module.rt_tags") local utf8_lua = require("druid.system.utf8") local utf8 = utf8 or utf8_lua diff --git a/druid/custom/rich_text/module/rt_tags.lua b/druid/extended/rich_text/module/rt_tags.lua similarity index 97% rename from druid/custom/rich_text/module/rt_tags.lua rename to druid/extended/rich_text/module/rt_tags.lua index 21c486a..894c98d 100644 --- a/druid/custom/rich_text/module/rt_tags.lua +++ b/druid/extended/rich_text/module/rt_tags.lua @@ -2,7 +2,6 @@ -- Author: Britzl -- Modified by: Insality ---local color = require("druid.custom.rich_text.module.rt_color") local color = require("druid.color") local M = {} diff --git a/druid/custom/rich_text/rich_text.lua b/druid/extended/rich_text/rich_text.lua similarity index 99% rename from druid/custom/rich_text/rich_text.lua rename to druid/extended/rich_text/rich_text.lua index f5ac187..fc4dd01 100644 --- a/druid/custom/rich_text/rich_text.lua +++ b/druid/extended/rich_text/rich_text.lua @@ -1,5 +1,5 @@ local component = require("druid.component") -local rich_text = require("druid.custom.rich_text.module.rt") +local rich_text = require("druid.extended.rich_text.module.rt") ---@class druid.rich_text.settings ---@field parent node