mirror of
https://github.com/Insality/druid
synced 2025-06-27 10:27:48 +02:00
Update Rich Input with selection/arrows control. Add template and nodes to self:get_druid
This commit is contained in:
parent
f93d0c7d40
commit
986a4695f6
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -10,7 +10,8 @@
|
|||||||
"after",
|
"after",
|
||||||
"it",
|
"it",
|
||||||
"utf8",
|
"utf8",
|
||||||
"defos"
|
"defos",
|
||||||
|
"clipboard"
|
||||||
],
|
],
|
||||||
"Lua.workspace.checkThirdParty": false,
|
"Lua.workspace.checkThirdParty": false,
|
||||||
"Lua.diagnostics.neededFileStatus": {
|
"Lua.diagnostics.neededFileStatus": {
|
||||||
|
@ -14,6 +14,10 @@ By default, **Druid** utilizes the `/builtins/input/all.input_binding` for input
|
|||||||
- Key trigger: `Back` -> `key_back` (for BackHandler component, Android back button, input component)
|
- Key trigger: `Back` -> `key_back` (for BackHandler component, Android back button, input component)
|
||||||
- Key trigger: `Enter` -> `key_enter` (for Input component, optional)
|
- Key trigger: `Enter` -> `key_enter` (for Input component, optional)
|
||||||
- Key trigger: `Esc` -> `key_esc` (for Input component, optional)
|
- Key trigger: `Esc` -> `key_esc` (for Input component, optional)
|
||||||
|
- Key trigger: `Left` -> `key_left` (for Rich Input component, optional)
|
||||||
|
- Key trigger: `Right` -> `key_right` (for Rich Input component, optional)
|
||||||
|
- Key trigger: `Shift` -> `key_lshift` (for Rich Input component, optional)
|
||||||
|
- Key trigger: `Ctrl` -> `key_lctrl` (for Rich Input component, optional)
|
||||||
- Touch triggers: `Touch multi` -> `touch_multi` (for Scroll component)
|
- Touch triggers: `Touch multi` -> `touch_multi` (for Scroll component)
|
||||||
|
|
||||||

|

|
||||||
@ -37,6 +41,10 @@ input_key_backspace = key_backspace
|
|||||||
input_multitouch = touch_multi
|
input_multitouch = touch_multi
|
||||||
input_scroll_up = mouse_wheel_up
|
input_scroll_up = mouse_wheel_up
|
||||||
input_scroll_down = mouse_wheel_down
|
input_scroll_down = mouse_wheel_down
|
||||||
|
input_key_left = key_left
|
||||||
|
input_key_right = key_right
|
||||||
|
input_key_lshift = key_lshift
|
||||||
|
input_key_lctrl = key_lctrl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -652,6 +652,7 @@ function druid__hover.set_mouse_hover(self, state) end
|
|||||||
---@field on_input_text druid.event On input field text change callback(self, input_text)
|
---@field on_input_text druid.event On input field text change callback(self, input_text)
|
||||||
---@field on_input_unselect druid.event On input field unselect callback(self, input_text)
|
---@field on_input_unselect druid.event On input field unselect callback(self, input_text)
|
||||||
---@field on_input_wrong druid.event On trying user input with not allowed character callback(self, params, button_instance)
|
---@field on_input_wrong druid.event On trying user input with not allowed character callback(self, params, button_instance)
|
||||||
|
---@field on_select_cursor_change druid.event On cursor position change callback(self, cursor_index, selection_start_index, selection_end_index)
|
||||||
---@field style druid.input.style Component style params.
|
---@field style druid.input.style Component style params.
|
||||||
---@field text druid.text Text component
|
---@field text druid.text Text component
|
||||||
local druid__input = {}
|
local druid__input = {}
|
||||||
@ -993,7 +994,7 @@ function druid__rich_text.init(self, template, nodes) end
|
|||||||
|
|
||||||
--- Set text for Rich Text
|
--- Set text for Rich Text
|
||||||
---@param self druid.rich_text @{RichText}
|
---@param self druid.rich_text @{RichText}
|
||||||
---@param text string The text to set
|
---@param text string|nil The text to set
|
||||||
---@return druid.rich_text.word[] words
|
---@return druid.rich_text.word[] words
|
||||||
---@return druid.rich_text.lines_metrics line_metrics
|
---@return druid.rich_text.lines_metrics line_metrics
|
||||||
function druid__rich_text.set_text(self, text) end
|
function druid__rich_text.set_text(self, text) end
|
||||||
|
@ -81,11 +81,10 @@ local const = require("druid.const")
|
|||||||
local helper = require("druid.helper")
|
local helper = require("druid.helper")
|
||||||
local utf8_lua = require("druid.system.utf8")
|
local utf8_lua = require("druid.system.utf8")
|
||||||
local component = require("druid.component")
|
local component = require("druid.component")
|
||||||
local utf8 = utf8 or utf8_lua
|
local utf8 = utf8 or utf8_lua --[[@as utf8]]
|
||||||
|
|
||||||
local Text = component.create("text")
|
local Text = component.create("text")
|
||||||
|
|
||||||
|
|
||||||
local function update_text_size(self)
|
local function update_text_size(self)
|
||||||
local size = vmath.vector3(
|
local size = vmath.vector3(
|
||||||
self.start_size.x * (self.start_scale.x / self.scale.x),
|
self.start_size.x * (self.start_scale.x / self.scale.x),
|
||||||
@ -110,13 +109,12 @@ local function is_fit_info_area(self, metrics)
|
|||||||
return metrics.width * self.scale.x <= self.text_area.x and
|
return metrics.width * self.scale.x <= self.text_area.x and
|
||||||
metrics.height * self.scale.y <= self.text_area.y
|
metrics.height * self.scale.y <= self.text_area.y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Setup scale x, but can only be smaller, than start text scale
|
--- Setup scale x, but can only be smaller, than start text scale
|
||||||
local function update_text_area_size(self)
|
local function update_text_area_size(self)
|
||||||
reset_default_scale(self)
|
reset_default_scale(self)
|
||||||
|
|
||||||
local max_width = self.text_area.x
|
|
||||||
local max_height = self.text_area.y
|
|
||||||
|
|
||||||
local metrics = helper.get_text_metrics_from_node(self.node)
|
local metrics = helper.get_text_metrics_from_node(self.node)
|
||||||
|
|
||||||
if metrics.width == 0 then
|
if metrics.width == 0 then
|
||||||
@ -125,15 +123,56 @@ local function update_text_area_size(self)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local scale_modifier = max_width / metrics.width
|
local text_area_width = self.text_area.x
|
||||||
|
local text_area_height = self.text_area.y
|
||||||
|
|
||||||
|
-- Adjust by width
|
||||||
|
local scale_modifier = text_area_width / metrics.width
|
||||||
|
|
||||||
|
-- Adjust by height
|
||||||
|
if self:is_multiline() then
|
||||||
|
-- Approximate scale by height to start adjust scale
|
||||||
|
scale_modifier = math.sqrt(text_area_height / metrics.height)
|
||||||
|
if metrics.width * scale_modifier > text_area_width then
|
||||||
|
scale_modifier = text_area_width / metrics.width
|
||||||
|
end
|
||||||
|
|
||||||
|
-- #RMME
|
||||||
|
if self._minimal_scale then
|
||||||
|
scale_modifier = math.max(scale_modifier, self._minimal_scale)
|
||||||
|
end
|
||||||
|
-- Limit max scale by initial scale
|
||||||
|
scale_modifier = math.min(scale_modifier, self.start_scale.x)
|
||||||
|
-- #RMME
|
||||||
|
|
||||||
|
local is_fit = is_fit_info_area(self, metrics)
|
||||||
|
local step = is_fit and self.style.ADJUST_SCALE_DELTA or -self.style.ADJUST_SCALE_DELTA
|
||||||
|
|
||||||
|
for i = 1, self.style.ADJUST_STEPS do
|
||||||
|
-- Grow down to check if we fit
|
||||||
|
if step < 0 and is_fit then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
-- Grow up to check if we still fit
|
||||||
|
if step > 0 and not is_fit then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
scale_modifier = scale_modifier + step
|
||||||
|
|
||||||
|
if self._minimal_scale then
|
||||||
|
scale_modifier = math.max(scale_modifier, self._minimal_scale)
|
||||||
|
end
|
||||||
|
-- Limit max scale by initial scale
|
||||||
scale_modifier = math.min(scale_modifier, self.start_scale.x)
|
scale_modifier = math.min(scale_modifier, self.start_scale.x)
|
||||||
|
|
||||||
if self:is_multiline() then
|
self.scale.x = scale_modifier
|
||||||
local scale_modifier_by_height = math.sqrt(max_height / metrics.height)
|
self.scale.y = scale_modifier
|
||||||
scale_modifier = math.min(self.start_scale.y, scale_modifier_by_height)
|
self.scale.z = self.start_scale.z
|
||||||
|
gui.set_scale(self.node, self.scale)
|
||||||
if metrics.width * scale_modifier > max_width then
|
update_text_size(self)
|
||||||
scale_modifier = math.min(max_width / metrics.width, self.start_scale.x)
|
metrics = helper.get_text_metrics_from_node(self.node)
|
||||||
|
is_fit = is_fit_info_area(self, metrics)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -141,12 +180,16 @@ local function update_text_area_size(self)
|
|||||||
scale_modifier = math.max(scale_modifier, self._minimal_scale)
|
scale_modifier = math.max(scale_modifier, self._minimal_scale)
|
||||||
end
|
end
|
||||||
|
|
||||||
local new_scale = vmath.vector3(scale_modifier, scale_modifier, self.start_scale.z)
|
-- Limit max scale by initial scale
|
||||||
gui.set_scale(self.node, new_scale)
|
scale_modifier = math.min(scale_modifier, self.start_scale.x)
|
||||||
self.scale = new_scale
|
|
||||||
|
self.scale.x = scale_modifier
|
||||||
|
self.scale.y = scale_modifier
|
||||||
|
self.scale.z = self.start_scale.z
|
||||||
|
gui.set_scale(self.node, self.scale)
|
||||||
update_text_size(self)
|
update_text_size(self)
|
||||||
|
|
||||||
self.on_update_text_scale:trigger(self:get_context(), new_scale, metrics)
|
self.on_update_text_scale:trigger(self:get_context(), self.scale, metrics)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -177,18 +220,6 @@ local function update_text_with_anchor_shift(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- calculate space width with font
|
|
||||||
local function get_space_width(self, font)
|
|
||||||
if not self._space_width[font] then
|
|
||||||
local no_space = resource.get_text_metrics(font, "1").width
|
|
||||||
local with_space = resource.get_text_metrics(font, " 1").width
|
|
||||||
self._space_width[font] = with_space - no_space
|
|
||||||
end
|
|
||||||
|
|
||||||
return self._space_width[font]
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function update_adjust(self)
|
local function update_adjust(self)
|
||||||
if not self.adjust_type or self.adjust_type == const.TEXT_ADJUST.NO_ADJUST then
|
if not self.adjust_type or self.adjust_type == const.TEXT_ADJUST.NO_ADJUST then
|
||||||
reset_default_scale(self)
|
reset_default_scale(self)
|
||||||
@ -224,18 +255,22 @@ end
|
|||||||
-- @table style
|
-- @table style
|
||||||
-- @tfield string|nil TRIM_POSTFIX The postfix for TRIM adjust type. Default: ...
|
-- @tfield string|nil TRIM_POSTFIX The postfix for TRIM adjust type. Default: ...
|
||||||
-- @tfield string|nil DEFAULT_ADJUST The default adjust type for any text component. Default: DOWNSCALE
|
-- @tfield string|nil DEFAULT_ADJUST The default adjust type for any text component. Default: DOWNSCALE
|
||||||
|
-- @tfield string|nil ADJUST_STEPS Amount of iterations for text adjust by height. Default: 20
|
||||||
|
-- @tfield string|nil ADJUST_SCALE_DELTA Scale step on each height adjust step. Default: 0.02
|
||||||
function Text.on_style_change(self, style)
|
function Text.on_style_change(self, style)
|
||||||
self.style = {}
|
self.style = {}
|
||||||
self.style.TRIM_POSTFIX = style.TRIM_POSTFIX or "..."
|
self.style.TRIM_POSTFIX = style.TRIM_POSTFIX or "..."
|
||||||
self.style.DEFAULT_ADJUST = style.DEFAULT_ADJUST or const.TEXT_ADJUST.DOWNSCALE
|
self.style.DEFAULT_ADJUST = style.DEFAULT_ADJUST or const.TEXT_ADJUST.DOWNSCALE
|
||||||
|
self.style.ADJUST_STEPS = style.ADJUST_STEPS or 20
|
||||||
|
self.style.ADJUST_SCALE_DELTA = style.ADJUST_SCALE_DELTA or 0.02
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- The @{Text} constructor
|
--- The @{Text} constructor
|
||||||
-- @tparam Text self @{Text}
|
-- @tparam Text self @{Text}
|
||||||
-- @tparam string|node node Node name or GUI Text Node itself
|
-- @tparam string|node node Node name or GUI Text Node itself
|
||||||
-- @tparam string|nil value Initial text. Default value is node text from GUI scene.
|
-- @tparam string|nil value Initial text. Default value is node text from GUI scene. Default: nil
|
||||||
-- @tparam string|nil adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: downscale
|
-- @tparam string|nil adjust_type Adjust type for text. By default is DOWNSCALE. Look const.TEXT_ADJUST for reference. Default: DOWNSCALE
|
||||||
function Text.init(self, node, value, adjust_type)
|
function Text.init(self, node, value, adjust_type)
|
||||||
self.node = self:get_node(node)
|
self.node = self:get_node(node)
|
||||||
self.pos = gui.get_position(self.node)
|
self.pos = gui.get_position(self.node)
|
||||||
@ -257,8 +292,6 @@ function Text.init(self, node, value, adjust_type)
|
|||||||
self.on_set_pivot = Event()
|
self.on_set_pivot = Event()
|
||||||
self.on_update_text_scale = Event()
|
self.on_update_text_scale = Event()
|
||||||
|
|
||||||
self._space_width = {}
|
|
||||||
|
|
||||||
self:set_to(value or gui.get_text(self.node))
|
self:set_to(value or gui.get_text(self.node))
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -282,38 +315,66 @@ end
|
|||||||
|
|
||||||
--- Calculate text width with font with respect to trailing space
|
--- Calculate text width with font with respect to trailing space
|
||||||
-- @tparam Text self @{Text}
|
-- @tparam Text self @{Text}
|
||||||
-- @tparam string|nil text
|
-- @tparam string text|nil
|
||||||
-- @treturn number Width
|
-- @treturn number Width
|
||||||
-- @treturn number Height
|
-- @treturn number Height
|
||||||
function Text.get_text_size(self, text)
|
function Text.get_text_size(self, text)
|
||||||
text = text or self.last_value
|
text = text or self.last_value
|
||||||
local font_name = gui.get_font(self.node)
|
local font_name = gui.get_font(self.node)
|
||||||
local font = gui.get_font_resource(font_name)
|
local font = gui.get_font_resource(font_name)
|
||||||
local scale = gui.get_scale(self.node)
|
local scale = self.last_scale or gui.get_scale(self.node)
|
||||||
local linebreak = gui.get_line_break(self.node)
|
local linebreak = gui.get_line_break(self.node)
|
||||||
local metrics = resource.get_text_metrics(font, text, {
|
local dot_width = resource.get_text_metrics(font, ".").width
|
||||||
|
|
||||||
|
local metrics = resource.get_text_metrics(font, text .. ".", {
|
||||||
line_break = linebreak,
|
line_break = linebreak,
|
||||||
leading = 1,
|
leading = 1,
|
||||||
tracking = 0,
|
tracking = 0,
|
||||||
width = self.start_size.x
|
width = self.start_size.x
|
||||||
})
|
})
|
||||||
local width = metrics.width
|
|
||||||
for i = #text, 1, -1 do
|
local width = metrics.width - dot_width
|
||||||
local c = string.sub(text, i, i)
|
return width * scale.x, metrics.height * scale.y
|
||||||
if c ~= ' ' then
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get chars count by width
|
||||||
|
-- @tparam Text self @{Text}
|
||||||
|
-- @tparam number width
|
||||||
|
-- @treturn number Chars count
|
||||||
|
function Text.get_text_index_by_width(self, width)
|
||||||
|
local text = self.last_value
|
||||||
|
local font_name = gui.get_font(self.node)
|
||||||
|
local font = gui.get_font_resource(font_name)
|
||||||
|
local scale = self.last_scale or gui.get_scale(self.node)
|
||||||
|
|
||||||
|
local text_index = 0
|
||||||
|
local text_width = 0
|
||||||
|
local text_length = utf8.len(text)
|
||||||
|
local dot_width = resource.get_text_metrics(font, ".").width
|
||||||
|
local previous_width = 0
|
||||||
|
for i = 1, text_length do
|
||||||
|
local subtext = utf8.sub(text, 1, i) .. "."
|
||||||
|
local subtext_width = resource.get_text_metrics(font, subtext).width
|
||||||
|
subtext_width = subtext_width - dot_width
|
||||||
|
text_width = subtext_width * scale.x
|
||||||
|
local width_delta = text_width - previous_width
|
||||||
|
previous_width = text_width
|
||||||
|
|
||||||
|
if (text_width - width_delta/2) < width then
|
||||||
|
text_index = i
|
||||||
|
else
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
width = width + get_space_width(self, font)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return width * scale.x, metrics.height * scale.y
|
return text_index
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set text to text field
|
--- Set text to text field
|
||||||
-- @tparam Text self @{Text}
|
-- @tparam Text self @{Text}
|
||||||
-- @tparam string|number|boolean set_to Text for node
|
-- @tparam string set_to Text for node
|
||||||
-- @treturn Text Current text instance
|
-- @treturn Text Current text instance
|
||||||
function Text.set_to(self, set_to)
|
function Text.set_to(self, set_to)
|
||||||
set_to = set_to or ""
|
set_to = set_to or ""
|
||||||
|
@ -205,10 +205,22 @@ end
|
|||||||
|
|
||||||
--- Get Druid instance for inner component creation.
|
--- Get Druid instance for inner component creation.
|
||||||
-- @tparam BaseComponent self @{BaseComponent}
|
-- @tparam BaseComponent self @{BaseComponent}
|
||||||
|
-- @tparam string|nil template The template name
|
||||||
|
-- @tparam table|nil nodes The nodes table
|
||||||
-- @treturn DruidInstance Druid instance with component context
|
-- @treturn DruidInstance Druid instance with component context
|
||||||
function BaseComponent.get_druid(self)
|
function BaseComponent.get_druid(self, template, nodes)
|
||||||
local context = { _context = self }
|
local context = { _context = self }
|
||||||
return setmetatable(context, { __index = self._meta.druid })
|
local druid_instance = setmetatable(context, { __index = self._meta.druid })
|
||||||
|
|
||||||
|
if template then
|
||||||
|
self:set_template(template)
|
||||||
|
end
|
||||||
|
|
||||||
|
if nodes then
|
||||||
|
self:set_nodes(nodes)
|
||||||
|
end
|
||||||
|
|
||||||
|
return druid_instance
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ M.ACTION_MULTITOUCH = hash(sys.get_config_string("druid.input_multitouch", "touc
|
|||||||
M.ACTION_BACKSPACE = hash(sys.get_config_string("druid.input_key_backspace", "key_backspace"))
|
M.ACTION_BACKSPACE = hash(sys.get_config_string("druid.input_key_backspace", "key_backspace"))
|
||||||
M.ACTION_SCROLL_UP = hash(sys.get_config_string("druid.input_scroll_up", "mouse_wheel_up"))
|
M.ACTION_SCROLL_UP = hash(sys.get_config_string("druid.input_scroll_up", "mouse_wheel_up"))
|
||||||
M.ACTION_SCROLL_DOWN = hash(sys.get_config_string("druid.input_scroll_down", "mouse_wheel_down"))
|
M.ACTION_SCROLL_DOWN = hash(sys.get_config_string("druid.input_scroll_down", "mouse_wheel_down"))
|
||||||
|
M.ACTION_LEFT = hash(sys.get_config_string("druid.input_key_left", "key_left"))
|
||||||
|
M.ACTION_RIGHT = hash(sys.get_config_string("druid.input_key_right", "key_right"))
|
||||||
|
M.ACTION_LSHIFT = hash(sys.get_config_string("druid.input_key_lshift", "key_lshift"))
|
||||||
|
M.ACTION_LCTRL = hash(sys.get_config_string("druid.input_key_lctrl", "key_lctrl"))
|
||||||
|
|
||||||
M.IS_STENCIL_CHECK = not (sys.get_config_string("druid.no_stencil_check") == "1")
|
M.IS_STENCIL_CHECK = not (sys.get_config_string("druid.no_stencil_check") == "1")
|
||||||
|
|
||||||
|
@ -58,9 +58,7 @@ end
|
|||||||
-- @tparam string template The template string name
|
-- @tparam string template The template string name
|
||||||
-- @tparam table nodes Nodes table from gui.clone_tree
|
-- @tparam table nodes Nodes table from gui.clone_tree
|
||||||
function PinKnob.init(self, callback, template, nodes)
|
function PinKnob.init(self, callback, template, nodes)
|
||||||
self:set_template(template)
|
self.druid = self:get_druid(template, nodes)
|
||||||
self:set_nodes(nodes)
|
|
||||||
self.druid = self:get_druid()
|
|
||||||
self.node = self:get_node(SCHEME.PIN)
|
self.node = self:get_node(SCHEME.PIN)
|
||||||
self.is_drag = false
|
self.is_drag = false
|
||||||
|
|
||||||
|
@ -24,8 +24,13 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
local component = require("druid.component")
|
local component = require("druid.component")
|
||||||
local input = require("druid.extended.input")
|
local helper = require("druid.helper")
|
||||||
|
local const = require("druid.const")
|
||||||
|
local utf8_lua = require("druid.system.utf8")
|
||||||
|
local utf8 = utf8 or utf8_lua
|
||||||
|
|
||||||
|
local hotkey = require("druid.extended.hotkey")
|
||||||
|
local input = require("druid.extended.input")
|
||||||
local RichInput = component.create("druid.rich_input")
|
local RichInput = component.create("druid.rich_input")
|
||||||
|
|
||||||
local SCHEME = {
|
local SCHEME = {
|
||||||
@ -34,34 +39,142 @@ local SCHEME = {
|
|||||||
PLACEHOLDER = "placeholder_text",
|
PLACEHOLDER = "placeholder_text",
|
||||||
INPUT = "input_text",
|
INPUT = "input_text",
|
||||||
CURSOR = "cursor_node",
|
CURSOR = "cursor_node",
|
||||||
|
CURSOR_TEXT = "cursor_text",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local DOUBLE_CLICK_TIME = 0.35
|
||||||
|
|
||||||
local function animate_cursor(self)
|
local function animate_cursor(self)
|
||||||
gui.cancel_animation(self.cursor, gui.PROP_COLOR)
|
gui.cancel_animation(self.cursor_text, "color.w")
|
||||||
gui.set_color(self.cursor, vmath.vector4(1))
|
gui.set_alpha(self.cursor_text, 1)
|
||||||
gui.animate(self.cursor, gui.PROP_COLOR, vmath.vector4(1,1,1,0), gui.EASING_INSINE, 0.8, 0, nil, gui.PLAYBACK_LOOP_PINGPONG)
|
gui.animate(self.cursor_text, "color.w", 0, gui.EASING_INSINE, 0.8, 0, nil, gui.PLAYBACK_LOOP_PINGPONG)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function update_text(self, text)
|
local function set_selection_width(self, selection_width)
|
||||||
local text_width = self.input.total_width
|
gui.set_visible(self.cursor, selection_width > 0)
|
||||||
animate_cursor(self)
|
|
||||||
gui.set_position(self.cursor, vmath.vector3(text_width/2, 0, 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
|
||||||
|
|
||||||
|
|
||||||
|
local function update_text(self)
|
||||||
|
local left_text_part = utf8.sub(self.input:get_text(), 0, self.input.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.total_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)
|
gui.set_scale(self.cursor, self.input.text.scale)
|
||||||
|
|
||||||
|
set_selection_width(self, selected_part_width)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function on_select(self)
|
local function on_select(self)
|
||||||
gui.set_enabled(self.cursor, true)
|
gui.set_enabled(self.cursor, true)
|
||||||
gui.set_enabled(self.placeholder.node, false)
|
gui.set_enabled(self.placeholder.node, false)
|
||||||
|
gui.set_enabled(self.input.button.node, true)
|
||||||
|
|
||||||
animate_cursor(self)
|
animate_cursor(self)
|
||||||
|
self.drag:set_enabled(true)
|
||||||
|
self:_set_hotkeys_enabled(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function on_unselect(self)
|
local function on_unselect(self)
|
||||||
|
gui.cancel_animation(self.cursor, gui.PROP_COLOR)
|
||||||
gui.set_enabled(self.cursor, false)
|
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)
|
gui.set_enabled(self.placeholder.node, true and #self.input:get_text() == 0)
|
||||||
|
|
||||||
|
self.drag:set_enabled(false)
|
||||||
|
self:_set_hotkeys_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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -70,38 +183,112 @@ end
|
|||||||
-- @tparam string template The template string name
|
-- @tparam string template The template string name
|
||||||
-- @tparam table nodes Nodes table from gui.clone_tree
|
-- @tparam table nodes Nodes table from gui.clone_tree
|
||||||
function RichInput.init(self, template, nodes)
|
function RichInput.init(self, template, nodes)
|
||||||
self:set_template(template)
|
self.druid = self:get_druid(template, nodes)
|
||||||
self:set_nodes(nodes)
|
|
||||||
self.druid = self:get_druid()
|
|
||||||
self.root = self:get_node(SCHEME.ROOT)
|
self.root = self:get_node(SCHEME.ROOT)
|
||||||
|
|
||||||
|
self._last_touch_info = {
|
||||||
|
cursor_index = nil,
|
||||||
|
time = 0,
|
||||||
|
}
|
||||||
|
self.is_lshift = false
|
||||||
|
self.is_lctrl = false
|
||||||
|
|
||||||
|
---@type druid.input
|
||||||
self.input = self.druid:new(input, self:get_node(SCHEME.BUTTON), self:get_node(SCHEME.INPUT))
|
self.input = self.druid:new(input, self:get_node(SCHEME.BUTTON), self:get_node(SCHEME.INPUT))
|
||||||
|
self.is_button_input_enabled = gui.is_enabled(self.input.button.node)
|
||||||
|
|
||||||
self.cursor = self:get_node(SCHEME.CURSOR)
|
self.cursor = self:get_node(SCHEME.CURSOR)
|
||||||
|
self.cursor_position = gui.get_position(self.cursor)
|
||||||
|
self.cursor_text = self:get_node(SCHEME.CURSOR_TEXT)
|
||||||
|
|
||||||
|
self.drag = self.druid:new_drag(self:get_node(SCHEME.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.input:set_text("")
|
||||||
self.placeholder = self.druid:new_text(self:get_node(SCHEME.PLACEHOLDER))
|
self.placeholder = self.druid:new_text(self:get_node(SCHEME.PLACEHOLDER))
|
||||||
|
self.text_position = gui.get_position(self.input.text.node)
|
||||||
|
|
||||||
self.input.on_input_text:subscribe(update_text)
|
self.input.on_input_text:subscribe(update_text)
|
||||||
self.input.on_input_select:subscribe(on_select)
|
self.input.on_input_select:subscribe(on_select)
|
||||||
self.input.on_input_unselect:subscribe(on_unselect)
|
self.input.on_input_unselect:subscribe(on_unselect)
|
||||||
|
self.input.on_select_cursor_change:subscribe(update_selection)
|
||||||
|
|
||||||
on_unselect(self)
|
on_unselect(self)
|
||||||
update_text(self, "")
|
update_text(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function RichInput.on_input(self, 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 then
|
||||||
|
if action.pressed then
|
||||||
|
self.is_lctrl = true
|
||||||
|
elseif action.released then
|
||||||
|
self.is_lctrl = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if action_id == const.ACTION_LEFT and (action.pressed or action.repeated) then
|
||||||
|
self.input:move_selection(-1, self.is_lshift, self.is_lctrl)
|
||||||
|
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)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set placeholder text
|
--- Set placeholder text
|
||||||
-- @tparam RichInput self @{RichInput}
|
-- @tparam RichInput self @{RichInput}
|
||||||
-- @tparam string|nil placeholder_text The placeholder text
|
-- @tparam string placeholder_text The placeholder text
|
||||||
-- @treturn RichInput Current instance
|
|
||||||
function RichInput.set_placeholder(self, placeholder_text)
|
function RichInput.set_placeholder(self, placeholder_text)
|
||||||
self.placeholder:set_to(placeholder_text)
|
self.placeholder:set_to(placeholder_text)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---GSet input field text
|
--- Select input field
|
||||||
|
-- @tparam RichInput self @{RichInput}
|
||||||
|
function RichInput.select(self)
|
||||||
|
self.input:select()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set input field text
|
||||||
|
-- @tparam RichInput self @{RichInput}
|
||||||
|
-- @treturn druid.input Current input instance
|
||||||
|
-- @tparam string text The input text
|
||||||
|
function RichInput.set_text(self, 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
|
||||||
|
-- @tparam RichInput self @{RichInput}
|
||||||
|
-- @tparam hash font The font hash
|
||||||
|
-- @treturn druid.input Current input instance
|
||||||
|
function RichInput.set_font(self, font)
|
||||||
|
gui.set_font(self.input.text.node, font)
|
||||||
|
gui.set_font(self.placeholder.node, font)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set input field text
|
||||||
-- @tparam RichInput self @{RichInput}
|
-- @tparam RichInput self @{RichInput}
|
||||||
-- @treturn string Current input text
|
|
||||||
function RichInput.get_text(self)
|
function RichInput.get_text(self)
|
||||||
return self.input:get_text()
|
return self.input:get_text()
|
||||||
end
|
end
|
||||||
|
@ -234,6 +234,9 @@ function M._split_on_lines(words, settings)
|
|||||||
|
|
||||||
repeat
|
repeat
|
||||||
local word = words[i]
|
local word = words[i]
|
||||||
|
if word == nil then
|
||||||
|
break
|
||||||
|
end
|
||||||
if word.image then
|
if word.image then
|
||||||
word.default_animation = settings.default_animation
|
word.default_animation = settings.default_animation
|
||||||
end
|
end
|
||||||
|
@ -117,6 +117,10 @@ function M.parse(text, default_settings, style)
|
|||||||
assert(default_settings)
|
assert(default_settings)
|
||||||
|
|
||||||
text = text:gsub("&zwsp;", "<zwsp>\226\128\139</zwsp>")
|
text = text:gsub("&zwsp;", "<zwsp>\226\128\139</zwsp>")
|
||||||
|
|
||||||
|
-- Replace all \n with <br/> to make it easier to split the text
|
||||||
|
text = text:gsub("\n", "<br/>")
|
||||||
|
|
||||||
local all_words = {}
|
local all_words = {}
|
||||||
local open_tags = {}
|
local open_tags = {}
|
||||||
|
|
||||||
|
@ -109,11 +109,9 @@ local SCHEME = {
|
|||||||
-- @tparam string template The Rich Text template name
|
-- @tparam string template The Rich Text template name
|
||||||
-- @tparam table nodes The node table, if prefab was copied by gui.clone_tree()
|
-- @tparam table nodes The node table, if prefab was copied by gui.clone_tree()
|
||||||
function RichText.init(self, template, nodes)
|
function RichText.init(self, template, nodes)
|
||||||
self:set_template(template)
|
self.druid = self:get_druid(template, nodes)
|
||||||
self:set_nodes(nodes)
|
|
||||||
|
|
||||||
self.root = self:get_node(SCHEME.ROOT)
|
self.root = self:get_node(SCHEME.ROOT)
|
||||||
self.druid = self:get_druid()
|
|
||||||
|
|
||||||
self.text_prefab = self:get_node(SCHEME.TEXT_PREFAB)
|
self.text_prefab = self:get_node(SCHEME.TEXT_PREFAB)
|
||||||
self.icon_prefab = self:get_node(SCHEME.ICON_PREFAB)
|
self.icon_prefab = self:get_node(SCHEME.ICON_PREFAB)
|
||||||
@ -151,7 +149,7 @@ end
|
|||||||
|
|
||||||
--- Set text for Rich Text
|
--- Set text for Rich Text
|
||||||
-- @tparam RichText self @{RichText}
|
-- @tparam RichText self @{RichText}
|
||||||
-- @tparam string text The text to set
|
-- @tparam string text|nil The text to set
|
||||||
-- @treturn druid.rich_text.word[] words
|
-- @treturn druid.rich_text.word[] words
|
||||||
-- @treturn druid.rich_text.lines_metrics line_metrics
|
-- @treturn druid.rich_text.lines_metrics line_metrics
|
||||||
-- @usage
|
-- @usage
|
||||||
@ -198,6 +196,7 @@ end
|
|||||||
-- <img=texture:image,size/>
|
-- <img=texture:image,size/>
|
||||||
-- <img=texture:image,width,height/>
|
-- <img=texture:image,width,height/>
|
||||||
function RichText.set_text(self, text)
|
function RichText.set_text(self, text)
|
||||||
|
text = text or ""
|
||||||
self:clear()
|
self:clear()
|
||||||
self._last_value = text
|
self._last_value = text
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
local component = require("druid.component")
|
local component = require("druid.component")
|
||||||
|
|
||||||
---@class {COMPONENT_TYPE}: druid.base_component{COMPONENT_ANNOTATIONS}
|
---@class {COMPONENT_TYPE}: druid.base_component
|
||||||
---@field druid druid_instance
|
---@field druid druid_instance{COMPONENT_ANNOTATIONS}
|
||||||
local M = component.create("{COMPONENT_TYPE}")
|
local M = component.create("{COMPONENT_TYPE}")
|
||||||
|
|
||||||
local SCHEME = {
|
local SCHEME = {
|
||||||
@ -19,9 +19,7 @@ local SCHEME = {
|
|||||||
---@param template string
|
---@param template string
|
||||||
---@param nodes table<hash, node>
|
---@param nodes table<hash, node>
|
||||||
function M:init(template, nodes)
|
function M:init(template, nodes)
|
||||||
self:set_template(template)
|
self.druid = self:get_druid(template, nodes){COMPONENT_DEFINE}
|
||||||
self:set_nodes(nodes)
|
|
||||||
self.druid = self:get_druid(){COMPONENT_DEFINE}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,7 +80,6 @@ end
|
|||||||
-- @treturn druid.data_list Current DataList instance
|
-- @treturn druid.data_list Current DataList instance
|
||||||
function DataList.set_data(self, data)
|
function DataList.set_data(self, data)
|
||||||
self._data = data or {}
|
self._data = data or {}
|
||||||
self.scroll:set_size(self.grid:get_size_for(#self._data))
|
|
||||||
self:_refresh()
|
self:_refresh()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -102,7 +101,7 @@ end
|
|||||||
-- @tparam number shift_policy The constant from const.SHIFT.*
|
-- @tparam number shift_policy The constant from const.SHIFT.*
|
||||||
-- @local
|
-- @local
|
||||||
function DataList.add(self, data, index, shift_policy)
|
function DataList.add(self, data, index, shift_policy)
|
||||||
index = index or self._data_last_index + 1
|
index = index or #self._data + 1
|
||||||
shift_policy = shift_policy or const.SHIFT.RIGHT
|
shift_policy = shift_policy or const.SHIFT.RIGHT
|
||||||
|
|
||||||
helper.insert_with_shift(self._data, data, index, shift_policy)
|
helper.insert_with_shift(self._data, data, index, shift_policy)
|
||||||
@ -205,6 +204,7 @@ function DataList._add_at(self, index)
|
|||||||
|
|
||||||
local node, instance = self._create_function(self:get_context(), self._data[index], index, self)
|
local node, instance = self._create_function(self:get_context(), self._data[index], index, self)
|
||||||
self._data_visual[index] = {
|
self._data_visual[index] = {
|
||||||
|
data = self._data[index],
|
||||||
node = node,
|
node = node,
|
||||||
component = instance,
|
component = instance,
|
||||||
}
|
}
|
||||||
@ -240,6 +240,8 @@ end
|
|||||||
-- @tparam DataList self @{DataList}
|
-- @tparam DataList self @{DataList}
|
||||||
-- @local
|
-- @local
|
||||||
function DataList._refresh(self)
|
function DataList._refresh(self)
|
||||||
|
self.scroll:set_size(self.grid:get_size_for(#self._data))
|
||||||
|
|
||||||
local start_pos = -self.scroll.position
|
local start_pos = -self.scroll.position
|
||||||
local start_index = self.grid:get_index(start_pos)
|
local start_index = self.grid:get_index(start_pos)
|
||||||
start_index = math.max(1, start_index)
|
start_index = math.max(1, start_index)
|
||||||
@ -258,6 +260,10 @@ function DataList._refresh(self)
|
|||||||
for index, data in pairs(self._data_visual) do
|
for index, data in pairs(self._data_visual) do
|
||||||
if index < start_index or index > end_index then
|
if index < start_index or index > end_index then
|
||||||
self:_remove_at(index)
|
self:_remove_at(index)
|
||||||
|
elseif self._data[index] ~= data.data then
|
||||||
|
-- TODO We want to find currently created data instances and move them to new positions
|
||||||
|
-- Now it will re-create them
|
||||||
|
self:_remove_at(index)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
|
|
||||||
local Event = require("druid.event")
|
local Event = require("druid.event")
|
||||||
local const = require("druid.const")
|
local const = require("druid.const")
|
||||||
|
local helper = require("druid.helper")
|
||||||
local component = require("druid.component")
|
local component = require("druid.component")
|
||||||
local utf8_lua = require("druid.system.utf8")
|
local utf8_lua = require("druid.system.utf8")
|
||||||
local utf8 = utf8 or utf8_lua
|
local utf8 = utf8 or utf8_lua
|
||||||
@ -90,7 +91,6 @@ end
|
|||||||
-- @tfield boolean IS_LONGTAP_ERASE Is long tap will erase current input data. Default: false
|
-- @tfield boolean IS_LONGTAP_ERASE Is long tap will erase current input data. Default: false
|
||||||
-- @tfield string MASK_DEFAULT_CHAR Default character mask for password input. Default: *]
|
-- @tfield string MASK_DEFAULT_CHAR Default character mask for password input. Default: *]
|
||||||
-- @tfield boolean IS_UNSELECT_ON_RESELECT If true, call unselect on select selected input. Default: false
|
-- @tfield boolean IS_UNSELECT_ON_RESELECT If true, call unselect on select selected input. Default: false
|
||||||
-- @tfield boolean NO_CONSUME_INPUT_WHILE_SELECTED If true, will not consume input while input is selected. It's allow to interact with other components while input is selected (text input still captured). Default: false
|
|
||||||
-- @tfield function on_select (self, button_node) Callback on input field selecting
|
-- @tfield function on_select (self, button_node) Callback on input field selecting
|
||||||
-- @tfield function on_unselect (self, button_node) Callback on input field unselecting
|
-- @tfield function on_unselect (self, button_node) Callback on input field unselecting
|
||||||
-- @tfield function on_input_wrong (self, button_node) Callback on wrong user input
|
-- @tfield function on_input_wrong (self, button_node) Callback on wrong user input
|
||||||
@ -101,7 +101,6 @@ function Input.on_style_change(self, style)
|
|||||||
self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false
|
self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false
|
||||||
self.style.MASK_DEFAULT_CHAR = style.MASK_DEFAULT_CHAR or "*"
|
self.style.MASK_DEFAULT_CHAR = style.MASK_DEFAULT_CHAR or "*"
|
||||||
self.style.IS_UNSELECT_ON_RESELECT = style.IS_UNSELECT_ON_RESELECT or false
|
self.style.IS_UNSELECT_ON_RESELECT = style.IS_UNSELECT_ON_RESELECT or false
|
||||||
self.style.NO_CONSUME_INPUT_WHILE_SELECTED = style.NO_CONSUME_INPUT_WHILE_SELECTED or false
|
|
||||||
|
|
||||||
self.style.on_select = style.on_select or function(_, button_node) end
|
self.style.on_select = style.on_select or function(_, button_node) end
|
||||||
self.style.on_unselect = style.on_unselect or function(_, button_node) end
|
self.style.on_unselect = style.on_unselect or function(_, button_node) end
|
||||||
@ -121,7 +120,7 @@ end
|
|||||||
-- @tparam node|Text text_node Text node what will be changed on user input. You can pass text component instead of text node name @{Text}
|
-- @tparam node|Text text_node Text node what will be changed on user input. You can pass text component instead of text node name @{Text}
|
||||||
-- @tparam number|nil keyboard_type Gui keyboard type for input field
|
-- @tparam number|nil keyboard_type Gui keyboard type for input field
|
||||||
function Input.init(self, click_node, text_node, keyboard_type)
|
function Input.init(self, click_node, text_node, keyboard_type)
|
||||||
self.druid = self:get_druid(self)
|
self.druid = self:get_druid()
|
||||||
|
|
||||||
if type(text_node) == "table" then
|
if type(text_node) == "table" then
|
||||||
self.text = text_node
|
self.text = text_node
|
||||||
@ -139,6 +138,9 @@ function Input.init(self, click_node, text_node, keyboard_type)
|
|||||||
self.text_width = 0
|
self.text_width = 0
|
||||||
self.market_text_width = 0
|
self.market_text_width = 0
|
||||||
self.total_width = 0
|
self.total_width = 0
|
||||||
|
self.cursor_index = utf8.len(self.value)
|
||||||
|
self.start_index = self.cursor_index
|
||||||
|
self.end_index = self.cursor_index
|
||||||
|
|
||||||
self.max_length = nil
|
self.max_length = nil
|
||||||
self.allowed_characters = nil
|
self.allowed_characters = nil
|
||||||
@ -150,6 +152,11 @@ function Input.init(self, click_node, text_node, keyboard_type)
|
|||||||
self.button.on_click_outside:subscribe(self.unselect)
|
self.button.on_click_outside:subscribe(self.unselect)
|
||||||
self.button.on_long_click:subscribe(clear_and_select)
|
self.button.on_long_click:subscribe(clear_and_select)
|
||||||
|
|
||||||
|
if defos then
|
||||||
|
self.button.hover.style.ON_HOVER_CURSOR = defos.CURSOR_IBEAM
|
||||||
|
self.button.hover.style.ON_MOUSE_HOVER_CURSOR = defos.CURSOR_IBEAM
|
||||||
|
end
|
||||||
|
|
||||||
if html5 then
|
if html5 then
|
||||||
self.button:set_web_user_interaction(true)
|
self.button:set_web_user_interaction(true)
|
||||||
end
|
end
|
||||||
@ -160,6 +167,7 @@ function Input.init(self, click_node, text_node, keyboard_type)
|
|||||||
self.on_input_empty = Event()
|
self.on_input_empty = Event()
|
||||||
self.on_input_full = Event()
|
self.on_input_full = Event()
|
||||||
self.on_input_wrong = Event()
|
self.on_input_wrong = Event()
|
||||||
|
self.on_select_cursor_change = Event()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,6 +85,12 @@ function Slider.on_layout_change(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function Slider.on_remove(self)
|
||||||
|
-- Return pin to start position
|
||||||
|
gui.set_position(self.node, self.start_pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function Slider.on_window_resized(self)
|
function Slider.on_window_resized(self)
|
||||||
local x_koef, y_koef = helper.get_screen_aspect_koef()
|
local x_koef, y_koef = helper.get_screen_aspect_koef()
|
||||||
self._x_koef = x_koef
|
self._x_koef = x_koef
|
||||||
|
@ -115,11 +115,10 @@ M["swipe"] = {
|
|||||||
|
|
||||||
|
|
||||||
M["input"] = {
|
M["input"] = {
|
||||||
IS_LONGTAP_ERASE = true,
|
IS_LONGTAP_ERASE = false,
|
||||||
BUTTON_SELECT_INCREASE = 1.06,
|
BUTTON_SELECT_INCREASE = 1.08,
|
||||||
MASK_DEFAULT_CHAR = "*",
|
MASK_DEFAULT_CHAR = "*",
|
||||||
IS_UNSELECT_ON_RESELECT = false,
|
IS_UNSELECT_ON_RESELECT = false,
|
||||||
NO_CONSUME_INPUT_WHILE_SELECTED = false,
|
|
||||||
|
|
||||||
on_select = function(self, button_node)
|
on_select = function(self, button_node)
|
||||||
local target_scale = self.button.start_scale
|
local target_scale = self.button.start_scale
|
||||||
|
@ -11,10 +11,8 @@ local SCHEME = {
|
|||||||
|
|
||||||
-- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
|
-- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
|
||||||
function Component:init(template, nodes)
|
function Component:init(template, nodes)
|
||||||
self:set_template(template)
|
self.druid = self:get_druid(template, nodes)
|
||||||
self:set_nodes(nodes)
|
|
||||||
self.root = self:get_node(SCHEME.ROOT)
|
self.root = self:get_node(SCHEME.ROOT)
|
||||||
self.druid = self:get_druid()
|
|
||||||
|
|
||||||
self.button = self.druid:new_button(SCHEME.BUTTON, function() end)
|
self.button = self.druid:new_button(SCHEME.BUTTON, function() end)
|
||||||
end
|
end
|
||||||
|
@ -13,16 +13,13 @@ local SCHEME = {
|
|||||||
-- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
|
-- Component constructor. Template name and nodes are optional. Pass it if you use it in your component
|
||||||
function Component:init(template, nodes)
|
function Component:init(template, nodes)
|
||||||
-- If your component is gui template, pass the template name and set it
|
-- If your component is gui template, pass the template name and set it
|
||||||
self:set_template(template)
|
|
||||||
|
|
||||||
-- If your component is cloned my gui.clone_tree, pass nodes to component and set it
|
-- If your component is cloned my gui.clone_tree, pass nodes to component and set it
|
||||||
self:set_nodes(nodes)
|
-- Use inner druid instance to create components inside this component
|
||||||
|
self.druid = self:get_druid(template, nodes)
|
||||||
|
|
||||||
-- self:get_node will auto process component template and nodes
|
-- self:get_node will auto process component template and nodes
|
||||||
self.root = self:get_node(SCHEME.ROOT)
|
self.root = self:get_node(SCHEME.ROOT)
|
||||||
|
|
||||||
-- Use inner druid instance to create components inside this component
|
|
||||||
self.druid = self:get_druid()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user