diff --git a/docs_md/changelog.md b/docs_md/changelog.md index d26860a..4fc0160 100644 --- a/docs_md/changelog.md +++ b/docs_md/changelog.md @@ -138,3 +138,17 @@ Desc - Input component: rename field _selected_ to _is_selected_ (according to the docs) - Add EmmyLua annotations. See how to use it FAQ +- Lang text now can be initialized without default locale id +- **#116** You can pass Text component in Input component instead of text node +- **#124** Add _set_click_zone_ functon to Scroll component (just link to Drag:set_click_zone inside scroll component) +- **#102** __[BREAKING]__ Removed _increase_input_priority_ component function. Use _component:set_input_priority_ function instead. The bigger priority value processed first. The value 10 is default for Druid components, the 100 value is maximum priority for acquire input in _drag_ and _input_ components +-- Add constants for priorities: _const.PRIORITY_INPUT_, _const.PRIORITY_INPUT_HIGH_, _const.PRIORITY_INPUT_MAX_. +-- __[BREAKING]__ If you use in you custom components interest: __component.ON_INPUT_HIGH__ you should replace it with __const.PRIORITY_INPUT_HIGH__ as third param, and place it with usual __component.ON_INPUT__. For example +_before:_ +```lua +local Drag = component.create("drag", { component.ON_INPUT_HIGH }) +``` +_after:_ +```lua +local Drag = component.create("drag", { component.ON_INPUT }, const.PRIORITY_INPUT_HIGH) +``` diff --git a/druid/base/back_handler.lua b/druid/base/back_handler.lua index d6711df..1f2c5f0 100644 --- a/druid/base/back_handler.lua +++ b/druid/base/back_handler.lua @@ -14,7 +14,7 @@ local Event = require("druid.event") local const = require("druid.const") local component = require("druid.component") -local BackHandler = component.create("back_handler", { const.ON_INPUT }) +local BackHandler = component.create("back_handler", { component.ON_INPUT }) --- Component init function diff --git a/druid/base/blocker.lua b/druid/base/blocker.lua index 1017db9..50daf1b 100644 --- a/druid/base/blocker.lua +++ b/druid/base/blocker.lua @@ -10,7 +10,7 @@ local const = require("druid.const") local component = require("druid.component") -local Blocker = component.create("blocker", { const.ON_INPUT }) +local Blocker = component.create("blocker", { component.ON_INPUT }) --- Component init function diff --git a/druid/base/button.lua b/druid/base/button.lua index 3f25c4e..7d524f7 100644 --- a/druid/base/button.lua +++ b/druid/base/button.lua @@ -51,7 +51,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local Button = component.create("button", { const.ON_INPUT }) +local Button = component.create("button", { component.ON_INPUT }) local function is_input_match(self, action_id) diff --git a/druid/base/drag.lua b/druid/base/drag.lua index 7625c29..2908777 100644 --- a/druid/base/drag.lua +++ b/druid/base/drag.lua @@ -48,7 +48,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local Drag = component.create("drag", { const.ON_INPUT_HIGH }) +local Drag = component.create("drag", { component.ON_INPUT }, const.PRIORITY_INPUT_HIGH) local function start_touch(self, touch) @@ -93,7 +93,7 @@ local function process_touch(self, touch) if not self.is_drag and distance >= self.style.DRAG_DEADZONE then self.is_drag = true self.on_drag_start:trigger(self:get_context()) - self:increase_input_priority() + self:set_input_priority(const.PRIORITY_INPUT_MAX) end end @@ -265,9 +265,9 @@ end --- Strict drag click area. Useful for -- restrict events outside stencil node -- @tparam Drag self --- @tparam node zone Gui node -function Drag.set_click_zone(self, zone) - self.click_zone = self:get_node(zone) +-- @tparam node node Gui node +function Drag.set_click_zone(self, node) + self.click_zone = self:get_node(node) end diff --git a/druid/base/hover.lua b/druid/base/hover.lua index 4d61461..b426f58 100644 --- a/druid/base/hover.lua +++ b/druid/base/hover.lua @@ -15,7 +15,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local Hover = component.create("hover", { const.ON_INPUT }) +local Hover = component.create("hover", { component.ON_INPUT }) --- Component init function diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index a01b904..fa41434 100644 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -54,11 +54,10 @@ local Event = require("druid.event") -local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local Scroll = component.create("scroll", { const.ON_UPDATE, const.ON_LAYOUT_CHANGE }) +local Scroll = component.create("scroll", { component.ON_UPDATE, component.ON_LAYOUT_CHANGE }) local function inverse_lerp(min, max, current) @@ -414,6 +413,15 @@ function Scroll.bind_grid(self, grid) end +--- Strict drag scroll area. Useful for +-- restrict events outside stencil node +-- @tparam Drag self +-- @tparam node node Gui node +function Scroll.set_click_zone(self, node) + self.drag:set_click_zone(node) +end + + function Scroll._on_scroll_drag(self, dx, dy) local t = self.target_position local b = self.available_pos diff --git a/druid/base/static_grid.lua b/druid/base/static_grid.lua index 7906588..6191a53 100644 --- a/druid/base/static_grid.lua +++ b/druid/base/static_grid.lua @@ -46,7 +46,7 @@ local Event = require("druid.event") local helper = require("druid.helper") local component = require("druid.component") -local StaticGrid = component.create("static_grid", { const.ON_LAYOUT_CHANGE }) +local StaticGrid = component.create("static_grid", { component.ON_LAYOUT_CHANGE }) local function _extend_border(border, pos, size, pivot) diff --git a/druid/base/swipe.lua b/druid/base/swipe.lua index f248e64..84feff6 100644 --- a/druid/base/swipe.lua +++ b/druid/base/swipe.lua @@ -20,7 +20,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local Swipe = component.create("swipe", { const.ON_INPUT }) +local Swipe = component.create("swipe", { component.ON_INPUT }) local function start_swipe(self, action) diff --git a/druid/base/text.lua b/druid/base/text.lua index ff29f19..2e3c2aa 100644 --- a/druid/base/text.lua +++ b/druid/base/text.lua @@ -43,7 +43,7 @@ local Event = require("druid.event") local const = require("druid.const") local component = require("druid.component") -local Text = component.create("text", { const.ON_LAYOUT_CHANGE }) +local Text = component.create("text", { component.ON_LAYOUT_CHANGE }) local function update_text_size(self) diff --git a/druid/component.lua b/druid/component.lua index f735edf..195a6d5 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -5,10 +5,56 @@ local const = require("druid.const") local class = require("druid.system.middleclass") +local helper = require("druid.helper") + local BaseComponent = class("druid.component") +--- Component Interests +BaseComponent.ALL = const.ALL +BaseComponent.ON_INPUT = const.ON_INPUT +BaseComponent.ON_UPDATE = const.ON_UPDATE +BaseComponent.ON_MESSAGE = const.ON_MESSAGE +BaseComponent.ON_FOCUS_LOST = const.ON_FOCUS_LOST +BaseComponent.ON_FOCUS_GAINED = const.ON_FOCUS_GAINED +BaseComponent.ON_LAYOUT_CHANGE = const.ON_LAYOUT_CHANGE +BaseComponent.ON_LANGUAGE_CHANGE = const.ON_LANGUAGE_CHANGE + + +BaseComponent.ALL_INTERESTS = { + BaseComponent.ALL, + BaseComponent.ON_INPUT, + BaseComponent.ON_UPDATE, + BaseComponent.ON_MESSAGE, + BaseComponent.ON_FOCUS_LOST, + BaseComponent.ON_FOCUS_GAINED, + BaseComponent.ON_LAYOUT_CHANGE, + BaseComponent.ON_LANGUAGE_CHANGE, +} + + +-- Value is method name of component +BaseComponent.SPECIFIC_UI_MESSAGES = { + [BaseComponent.ON_FOCUS_LOST] = "on_focus_lost", + [BaseComponent.ON_FOCUS_GAINED] = "on_focus_gained", + [BaseComponent.ON_LAYOUT_CHANGE] = "on_layout_change", + [BaseComponent.ON_LANGUAGE_CHANGE] = "on_language_change", +} + + +BaseComponent.UI_INPUT = { + [BaseComponent.ON_INPUT] = true +} + + +local uid = 0 +function BaseComponent.static.get_uid() + uid = uid + 1 + return uid +end + + --- Set current component style table. -- Invoke `on_style_change` on component, if exist. BaseComponent should handle -- their style changing and store all style params @@ -50,17 +96,12 @@ end --- Increase input priority in current input stack -- @tparam BaseComponent self +-- @local function BaseComponent.increase_input_priority(self) - self._meta.increased_input_priority = true + helper.deprecated("The component:increase_input_priority is deprecated. Please use component:set_input_priority(druid_const.PRIORITY_INPUT_MAX) instead") end ---- Reset input priority in current input stack --- @tparam BaseComponent self -function BaseComponent.reset_input_priority(self) - self._meta.increased_input_priority = false -end - --- Get node for component by name. -- If component has nodes, node_or_name should be string @@ -110,6 +151,47 @@ function BaseComponent.get_name(self) end +--- Return component input priority +-- @tparam BaseComponent self +-- @treturn number The component input priority +function BaseComponent.get_input_priority(self) + return self._component.input_priority +end + + +--- Set component input priority +-- @tparam BaseComponent self +-- @tparam number value The new input priority value +-- @treturn number The component input priority +function BaseComponent.set_input_priority(self, value) + assert(value) + + if self._component.input_priority ~= value then + self._component.input_priority = value + self._component._is_input_priority_changed = true + end + + return self +end + + +--- Reset component input priority to default value +-- @tparam BaseComponent self +-- @treturn number The component input priority +function BaseComponent.reset_input_priority(self) + self:set_input_priority(self._component.default_input_priority) + return self +end + + +--- Return component uid. UID generated in component creation order +-- @tparam BaseComponent self +-- @treturn number The component uid +function BaseComponent.get_uid(self) + return self._component._uid +end + + --- Set component input state. By default it enabled -- You can disable any input of component by this function -- @tparam BaseComponent self @@ -153,7 +235,6 @@ function BaseComponent.setup_component(self, druid_instance, context, style) nodes = nil, style = nil, druid = druid_instance, - increased_input_priority = false, input_enabled = true, children = {} } @@ -175,17 +256,38 @@ end -- @tparam BaseComponent self -- @tparam string name BaseComponent name -- @tparam[opt={}] table interest List of component's interest +-- @tparam[opt=DEFAULT] number input_priority The input priority. The bigger number processed first -- @local -function BaseComponent.initialize(self, name, interest) +function BaseComponent.initialize(self, name, interest, input_priority) interest = interest or {} self._component = { name = name, - interest = interest + interest = interest, + input_priority = input_priority or const.PRIORITY_INPUT, + default_input_priority = input_priority or const.PRIORITY_INPUT, + _is_input_priority_changed = true, -- Default true for sort once time after GUI init + _uid = BaseComponent.get_uid() } end +--- Return true, if input priority was changed +-- @tparam BaseComponent self +-- @local +function BaseComponent._is_input_priority_changed(self) + return self._component._is_input_priority_changed +end + + +--- Reset is_input_priority_changed field +-- @tparam BaseComponent self +-- @local +function BaseComponent._reset_input_priority_changed(self) + self._component._is_input_priority_changed = false +end + + function BaseComponent.__tostring(self) return self._component.name end @@ -253,13 +355,14 @@ end -- druid component. -- @tparam string name BaseComponent name -- @tparam[opt={}] table interest List of component's interest +-- @tparam[opt=DEFAULT] number input_priority The input priority. The bigger number processed first -- @local -function BaseComponent.static.create(name, interest) +function BaseComponent.static.create(name, interest, input_priority) -- Yea, inheritance here local new_class = class(name, BaseComponent) new_class.initialize = function(self) - BaseComponent.initialize(self, name, interest) + BaseComponent.initialize(self, name, interest, input_priority) end return new_class diff --git a/druid/const.lua b/druid/const.lua index f8016bd..be16750 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -24,31 +24,22 @@ M.PRESSED = "pressed" M.STRING = "string" M.TABLE = "table" M.ZERO = "0" -M.ALL = "all" --- Component Interests +M.ALL = "all" M.ON_INPUT = hash("on_input") M.ON_UPDATE = hash("on_update") M.ON_MESSAGE = hash("on_message") -M.ON_INPUT_HIGH = hash("on_input_high") M.ON_FOCUS_LOST = hash("on_focus_lost") M.ON_FOCUS_GAINED = hash("on_focus_gained") M.ON_LAYOUT_CHANGE = hash("layout_changed") M.ON_LANGUAGE_CHANGE = hash("on_language_change") -M.ALL_INTERESTS = { - M.ALL, - M.ON_INPUT, - M.ON_UPDATE, - M.ON_MESSAGE, - M.ON_FOCUS_LOST, - M.ON_INPUT_HIGH, - M.ON_FOCUS_GAINED, - M.ON_LAYOUT_CHANGE, - M.ON_LANGUAGE_CHANGE, -} +M.PRIORITY_INPUT = 10 +M.PRIORITY_INPUT_HIGH = 20 +M.PRIORITY_INPUT_MAX = 100 M.PIVOTS = { @@ -64,19 +55,8 @@ M.PIVOTS = { } --- Value is method name of component -M.SPECIFIC_UI_MESSAGES = { - [M.ON_FOCUS_LOST] = "on_focus_lost", - [M.ON_FOCUS_GAINED] = "on_focus_gained", - [M.ON_LAYOUT_CHANGE] = "on_layout_change", - [M.ON_LANGUAGE_CHANGE] = "on_language_change", -} - - -M.UI_INPUT = { - [M.ON_INPUT_HIGH] = true, - [M.ON_INPUT] = true -} +M.SYS_INFO = sys.get_sys_info() +M.CURRENT_SYSTEM_NAME = M.SYS_INFO.system_name M.OS = { diff --git a/druid/druid.lua b/druid/druid.lua index 707eb28..041bd04 100644 --- a/druid/druid.lua +++ b/druid/druid.lua @@ -15,8 +15,9 @@ -- @module druid local const = require("druid.const") -local druid_instance = require("druid.system.druid_instance") +local base_component = require("druid.component") local settings = require("druid.system.settings") +local druid_instance = require("druid.system.druid_instance") local default_style = require("druid.styles.default.style") @@ -105,13 +106,13 @@ function M.on_window_callback(event) if event == window.WINDOW_EVENT_FOCUS_LOST then for i = 1, #instances do - msg.post(instances[i].url, const.ON_FOCUS_LOST) + msg.post(instances[i].url, base_component.ON_FOCUS_LOST) end end if event == window.WINDOW_EVENT_FOCUS_GAINED then for i = 1, #instances do - msg.post(instances[i].url, const.ON_FOCUS_GAINED) + msg.post(instances[i].url, base_component.ON_FOCUS_GAINED) end end end @@ -123,7 +124,7 @@ function M.on_layout_change() local instances = get_druid_instances() for i = 1, #instances do - msg.post(instances[i].url, const.ON_LAYOUT_CHANGE) + msg.post(instances[i].url, base_component.ON_LAYOUT_CHANGE) end end @@ -135,7 +136,7 @@ function M.on_language_change() local instances = get_druid_instances() for i = 1, #instances do - msg.post(instances[i].url, const.ON_LANGUAGE_CHANGE) + msg.post(instances[i].url, base_component.ON_LANGUAGE_CHANGE) end end diff --git a/druid/extended/checkbox.lua b/druid/extended/checkbox.lua index 24b5e56..d9d7a8b 100644 --- a/druid/extended/checkbox.lua +++ b/druid/extended/checkbox.lua @@ -16,11 +16,10 @@ -- @tfield Button button -local const = require("druid.const") local Event = require("druid.event") local component = require("druid.component") -local Checkbox = component.create("checkbox", { const.ON_LAYOUT_CHANGE }) +local Checkbox = component.create("checkbox", { component.ON_LAYOUT_CHANGE }) local function on_click(self) diff --git a/druid/extended/component.template.lua b/druid/extended/component.template.lua index fbf33b8..587d0e8 100644 --- a/druid/extended/component.template.lua +++ b/druid/extended/component.template.lua @@ -1,10 +1,9 @@ --- Druid component template -- @module druid.component -- @local -local const = require("druid.const") local component = require("druid.component") -local Component = component.create("my_component_name", { const.ON_UPDATE }) +local Component = component.create("my_component_name", { component.ON_UPDATE }) -- Component constructor @@ -12,12 +11,12 @@ function Component:init(...) end --- Call only if exist interest: const.ON_UPDATE +-- Call only if exist interest: component.ON_UPDATE function Component:update(dt) end --- Call only if exist interest: const.ON_INPUT or const.ON_INPUT_HIGH +-- Call only if exist interest: component.ON_INPUT function Component:on_input(action_id, action) return false end @@ -28,7 +27,7 @@ function Component:on_style_change(style) end --- Call only if exist interest: const.ON_MESSAGE +-- Call only if exist interest: component.ON_MESSAGE function Component:on_message(message_id, message, sender) end diff --git a/druid/extended/dynamic_grid.lua b/druid/extended/dynamic_grid.lua index e8b4413..e8815a9 100644 --- a/druid/extended/dynamic_grid.lua +++ b/druid/extended/dynamic_grid.lua @@ -42,7 +42,7 @@ local Event = require("druid.event") local helper = require("druid.helper") local component = require("druid.component") -local DynamicGrid = component.create("dynamic_grid", { const.ON_LAYOUT_CHANGE }) +local DynamicGrid = component.create("dynamic_grid", { component.ON_LAYOUT_CHANGE }) local SIDE_VECTORS = { diff --git a/druid/extended/input.lua b/druid/extended/input.lua index 0ea8f23..dbb532c 100644 --- a/druid/extended/input.lua +++ b/druid/extended/input.lua @@ -50,7 +50,7 @@ local const = require("druid.const") local component = require("druid.component") local utf8 = require("druid.system.utf8") -local Input = component.create("input", { const.ON_INPUT, const.ON_FOCUS_LOST }) +local Input = component.create("input", { component.ON_INPUT, component.ON_FOCUS_LOST }) --- Mask text by replacing every character with a mask character @@ -68,45 +68,12 @@ local function mask_text(text, mask) end -local function select(self) - gui.reset_keyboard() - self.marked_value = "" - if not self.is_selected then - self:increase_input_priority() - self.button:increase_input_priority() - self.previous_value = self.value - self.is_selected = true - - gui.show_keyboard(self.keyboard_type, false) - self.on_input_select:trigger(self:get_context()) - - self.style.on_select(self, self.button.node) - end -end - - -local function unselect(self) - gui.reset_keyboard() - self.marked_value = "" - if self.is_selected then - self:reset_input_priority() - self.button:reset_input_priority() - self.is_selected = false - - gui.hide_keyboard() - self.on_input_unselect:trigger(self:get_context()) - - self.style.on_unselect(self, self.button.node) - end -end - - local function clear_and_select(self) if self.style.IS_LONGTAP_ERASE then self:set_text("") end - select(self) + self:select() end @@ -116,6 +83,7 @@ end -- @table style -- @tfield[opt=false] bool IS_LONGTAP_ERASE Is long tap will erase current input data -- @tfield[opt=*] string MASK_DEFAULT_CHAR Default character mask for password input +-- @tfield[opt=false] bool IS_UNSELECT_ON_RESELECT If true, call unselect on select selected input -- @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_input_wrong (self, button_node) Callback on wrong user input @@ -125,6 +93,7 @@ function Input.on_style_change(self, style) self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false 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.on_select = style.on_select or function(_, button_node) end self.style.on_unselect = style.on_unselect or function(_, button_node) end @@ -139,11 +108,16 @@ end -- @tparam node click_node Button node to enabled input component --- @tparam node text_node Text node what will be changed on user input +-- @tparam node|druid.text text_node Text node what will be changed on user input. You can pass text component instead of text node name -- @tparam[opt] number keyboard_type Gui keyboard type for input field function Input.init(self, click_node, text_node, keyboard_type) self.druid = self:get_druid(self) - self.text = self.druid:new_text(text_node) + + if type(text_node) == const.TABLE then + self.text = text_node + else + self.text = self.druid:new_text(text_node) + end self.is_selected = false self.value = self.text.last_value @@ -161,9 +135,9 @@ function Input.init(self, click_node, text_node, keyboard_type) self.keyboard_type = keyboard_type or gui.KEYBOARD_TYPE_DEFAULT - self.button = self.druid:new_button(click_node, select) + self.button = self.druid:new_button(click_node, self.select) self.button:set_style(self.button_style) - self.button.on_click_outside:subscribe(unselect) + self.button.on_click_outside:subscribe(self.unselect) self.button.on_long_click:subscribe(clear_and_select) self.on_input_select = Event() @@ -215,17 +189,17 @@ function Input.on_input(self, action_id, action) end if action_id == const.ACTION_ENTER and action.released then - unselect(self) + self:unselect() return true end if action_id == const.ACTION_BACK and action.released then - unselect(self) + self:unselect() return true end if action_id == const.ACTION_ESC and action.released then - unselect(self) + self:unselect() return true end @@ -240,12 +214,12 @@ end function Input.on_focus_lost(self) - unselect(self) + self:unselect() end function Input.on_input_interrupt(self) - -- unselect(self) + -- self:unselect() end @@ -296,6 +270,47 @@ function Input.set_text(self, input_text) end +--- Select input field. It will show the keyboard and trigger on_select events +-- @tparam Input self +function Input.select(self) + gui.reset_keyboard() + self.marked_value = "" + if not self.is_selected then + self:set_input_priority(const.PRIORITY_INPUT_MAX) + self.button:set_input_priority(const.PRIORITY_INPUT_MAX) + self.previous_value = self.value + self.is_selected = true + + gui.show_keyboard(self.keyboard_type, false) + self.on_input_select:trigger(self:get_context()) + + self.style.on_select(self, self.button.node) + else + if self.style.IS_UNSELECT_ON_RESELECT then + self:unselect(self) + end + end +end + + +--- Remove selection from input. It will hide the keyboard and trigger on_unselect events +-- @tparam Input self +function Input.unselect(self) + gui.reset_keyboard() + self.marked_value = "" + if self.is_selected then + self:reset_input_priority() + self.button:reset_input_priority() + self.is_selected = false + + gui.hide_keyboard() + self.on_input_unselect:trigger(self:get_context()) + + self.style.on_unselect(self, self.button.node) + end +end + + --- Return current input field text -- @tparam Input self -- @treturn string The current input field text @@ -331,7 +346,7 @@ end -- @tparam Input self function Input.reset_changes(self) self:set_text(self.previous_value) - unselect(self) + self:unselect() end diff --git a/druid/extended/lang_text.lua b/druid/extended/lang_text.lua index b51992c..64479d1 100644 --- a/druid/extended/lang_text.lua +++ b/druid/extended/lang_text.lua @@ -12,17 +12,16 @@ local Event = require("druid.event") -local const = require("druid.const") local settings = require("druid.system.settings") local component = require("druid.component") -local LangText = component.create("lang_text", { const.ON_LANGUAGE_CHANGE }) +local LangText = component.create("lang_text", { component.ON_LANGUAGE_CHANGE }) --- Component init function -- @tparam LangText self -- @tparam node node The text node --- @tparam string locale_id Default locale id +-- @tparam string locale_id Default locale id, optional -- @tparam bool no_adjust If true, will not correct text size function LangText.init(self, node, locale_id, no_adjust) self.druid = self:get_druid() @@ -31,7 +30,9 @@ function LangText.init(self, node, locale_id, no_adjust) self.on_change = Event() - self:translate(locale_id) + if locale_id then + self:translate(locale_id) + end return self end @@ -60,7 +61,7 @@ end function LangText.translate(self, locale_id, ...) self.last_locale_args = {...} self.last_locale = locale_id or self.last_locale - self.text:set_to(settings.get_text(self.last_locale, ...)) + self.text:set_to(settings.get_text(self.last_locale, ...) or "") end diff --git a/druid/extended/progress.lua b/druid/extended/progress.lua index fb257e1..2cfe229 100644 --- a/druid/extended/progress.lua +++ b/druid/extended/progress.lua @@ -31,7 +31,7 @@ local const = require("druid.const") local helper = require("druid.helper") local component = require("druid.component") -local Progress = component.create("progress", { const.ON_UPDATE, const.ON_LAYOUT_CHANGE }) +local Progress = component.create("progress", { component.ON_UPDATE, component.ON_LAYOUT_CHANGE }) local function check_steps(self, from, to, exactly) diff --git a/druid/extended/slider.lua b/druid/extended/slider.lua index 97b306b..33cfbdd 100644 --- a/druid/extended/slider.lua +++ b/druid/extended/slider.lua @@ -37,7 +37,7 @@ local helper = require("druid.helper") local const = require("druid.const") local component = require("druid.component") -local Slider = component.create("slider", { const.ON_INPUT_HIGH, const.ON_LAYOUT_CHANGE }) +local Slider = component.create("slider", { component.ON_INPUT, component.ON_LAYOUT_CHANGE }, const.PRIORITY_INPUT_HIGH) local function on_change_value(self) diff --git a/druid/extended/timer.lua b/druid/extended/timer.lua index 5ae1ba8..7076543 100644 --- a/druid/extended/timer.lua +++ b/druid/extended/timer.lua @@ -28,12 +28,11 @@ local Event = require("druid.event") -local const = require("druid.const") local formats = require("druid.helper.formats") local helper = require("druid.helper") local component = require("druid.component") -local Timer = component.create("timer", { const.ON_UPDATE }) +local Timer = component.create("timer", { component.ON_UPDATE }) --- Component init function diff --git a/druid/helper.lua b/druid/helper.lua index fb27ef6..6f9824f 100644 --- a/druid/helper.lua +++ b/druid/helper.lua @@ -5,6 +5,7 @@ local const = require("druid.const") local M = {} +local system_name = sys.get_sys_info().system_name --- Text node or icon node can be nil local function get_text_width(text_node) @@ -28,6 +29,11 @@ local function get_icon_width(icon_node) end +local function get_width(node) + return gui.get_text(node) and get_text_width(node) or get_icon_width(node) +end + + --- Center two nodes. -- Nodes will be center around 0 x position -- text_node will be first (at left side) @@ -36,22 +42,7 @@ end -- @tparam[opt] box icon_node Gui box node -- @tparam number margin Offset between nodes function M.centrate_text_with_icon(text_node, icon_node, margin) - margin = margin or 0 - local text_width = get_text_width(text_node) - local icon_width = get_icon_width(icon_node) - local width = text_width + icon_width - - if text_node then - local pos = gui.get_position(text_node) - pos.x = -width/2 + text_width - margin/2 - gui.set_position(text_node, pos) - end - - if icon_node then - local icon_pos = gui.get_position(icon_node) - icon_pos.x = width/2 - icon_width + margin/2 - gui.set_position(icon_node, icon_pos) - end + M.centrate_nodes(margin, text_node, icon_node) end @@ -63,21 +54,43 @@ end -- @tparam[opt] text text_node Gui text node -- @tparam[opt=0] number margin Offset between nodes function M.centrate_icon_with_text(icon_node, text_node, margin) - margin = margin or 0 - local icon_width = get_icon_width(icon_node) - local text_width = get_text_width(text_node) - local width = text_width + icon_width + M.centrate_nodes(margin, icon_node, text_node) +end - if text_node then - local pos = gui.get_position(text_node) - pos.x = width/2 - text_width + margin/2 - gui.set_position(text_node, pos) + +--- Center several nodes nodes. +-- Nodes will be center around 0 x position +-- @function helper.centrate_nodes +-- @tparam[opt=0] number margin Offset between nodes +-- @tparam[opt] Node ... Any count of gui Node +function M.centrate_nodes(margin, ...) + margin = margin or 0 + + local width = 0 + local count = select("#", ...) + local node_widths = {} + + -- We need to get total width + for i = 1, count do + local node = select(i, ...) + node_widths[i] = get_width(node) + width = width + node_widths[i] end - if icon_node then - local icon_pos = gui.get_position(icon_node) - icon_pos.x = -width/2 + icon_width - margin/2 - gui.set_position(icon_node, icon_pos) + -- Posing all elements + local pos_x = 0 + for i = 1, count do + local node = select(i, ...) + local node_width = node_widths[i] + local pos = gui.get_position(node) + + pos_x = pos_x + node_width/2 -- made offset for single item + + local pivot_offset = M.get_pivot_offset(gui.get_pivot(node)) + pos.x = pos_x - width/2 + pivot_offset.x * node_width -- centrate node + gui.set_position(node, pos) + + pos_x = pos_x + node_widths[i]/2 + margin -- add second part of offset end end @@ -170,16 +183,14 @@ end --- Check if device is mobile (Android or iOS) -- @function helper..is_mobile function M.is_mobile() - local system_name = sys.get_sys_info().system_name - return system_name == const.OS.IOS or system_name == const.OS.ANDROID + return const.CURRENT_SYSTEM_NAME == const.OS.IOS or const.CURRENT_SYSTEM_NAME == const.OS.ANDROID end --- Check if device is HTML5 -- @function helper.is_web function M.is_web() - local system_name = sys.get_sys_info().system_name - return system_name == const.OS.BROWSER + return const.CURRENT_SYSTEM_NAME == const.OS.BROWSER end diff --git a/druid/styles/default/style.lua b/druid/styles/default/style.lua index 61e5ee7..111d291 100644 --- a/druid/styles/default/style.lua +++ b/druid/styles/default/style.lua @@ -95,8 +95,9 @@ M["swipe"] = { M["input"] = { IS_LONGTAP_ERASE = true, - BUTTON_SELECT_INCREASE = 1.1, + BUTTON_SELECT_INCREASE = 1.06, MASK_DEFAULT_CHAR = "*", + IS_UNSELECT_ON_RESELECT = false, on_select = function(self, button_node) local target_scale = self.button.start_scale diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index d66f543..7a913d9 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -28,11 +28,11 @@ -- @see Drag -- @see Hover -local const = require("druid.const") local helper = require("druid.helper") -local druid_input = require("druid.helper.druid_input") -local settings = require("druid.system.settings") local class = require("druid.system.middleclass") +local settings = require("druid.system.settings") +local base_component = require("druid.component") +local druid_input = require("druid.helper.druid_input") local back_handler = require("druid.base.back_handler") local blocker = require("druid.base.blocker") @@ -83,19 +83,35 @@ local function input_release(self) end +local function sort_input_stack(self) + local input_components = self.components[base_component.ON_INPUT] + if not input_components then + return + end + + table.sort(input_components, function(a, b) + if a:get_input_priority() ~= b:get_input_priority() then + return a:get_input_priority() < b:get_input_priority() + end + + return a:get_uid() < b:get_uid() + end) +end + + -- Create the component itself local function create(self, instance_class) local instance = instance_class() instance:setup_component(self, self._context, self._style) - table.insert(self.components[const.ALL], instance) + table.insert(self.components[base_component.ALL], instance) local register_to = instance:__get_interests() for i = 1, #register_to do local interest = register_to[i] table.insert(self.components[interest], instance) - if const.UI_INPUT[interest] then + if base_component.UI_INPUT[interest] then input_init(self) end end @@ -104,6 +120,27 @@ local function create(self, instance_class) end +local function check_sort_input_stack(self, components) + if not components or #components == 0 then + return + end + + local is_need_sort_input_stack = false + + for i = #components, 1, -1 do + local component = components[i] + if component:_is_input_priority_changed() then + is_need_sort_input_stack = true + end + component:_reset_input_priority_changed() + end + + if is_need_sort_input_stack then + sort_input_stack(self) + end +end + + local function process_input(action_id, action, components, is_input_consumed) if #components == 0 then return is_input_consumed @@ -111,24 +148,8 @@ local function process_input(action_id, action, components, is_input_consumed) for i = #components, 1, -1 do local component = components[i] - -- Process increased input priority first local meta = component._meta - if meta.input_enabled and meta.increased_input_priority then - if not is_input_consumed then - is_input_consumed = component:on_input(action_id, action) - else - if component.on_input_interrupt then - component:on_input_interrupt() - end - end - end - end - - for i = #components, 1, -1 do - local component = components[i] - -- Process usual input priority next - local meta = component._meta - if meta.input_enabled and not meta.increased_input_priority then + if meta.input_enabled then if not is_input_consumed then is_input_consumed = component:on_input(action_id, action) else @@ -156,8 +177,8 @@ function DruidInstance.initialize(self, context, style) self.url = msg.url() self.components = {} - for i = 1, #const.ALL_INTERESTS do - self.components[const.ALL_INTERESTS[i]] = {} + for i = 1, #base_component.ALL_INTERESTS do + self.components[base_component.ALL_INTERESTS[i]] = {} end end @@ -181,7 +202,7 @@ end -- on all druid components -- @tparam DruidInstance self function DruidInstance.final(self) - local components = self.components[const.ALL] + local components = self.components[base_component.ALL] for i = #components, 1, -1 do if components[i].on_remove then @@ -216,7 +237,7 @@ function DruidInstance.remove(self, component) end component._meta.children = {} - local all_components = self.components[const.ALL] + local all_components = self.components[base_component.ALL] for i = #all_components, 1, -1 do if all_components[i] == component then if component.on_remove then @@ -243,7 +264,7 @@ end -- @tparam DruidInstance self -- @tparam number dt Delta time function DruidInstance.update(self, dt) - local components = self.components[const.ON_UPDATE] + local components = self.components[base_component.ON_UPDATE] for i = 1, #components do components[i]:update(dt) end @@ -258,12 +279,9 @@ function DruidInstance.on_input(self, action_id, action) self._is_input_processing = true local is_input_consumed = false - - is_input_consumed = process_input(action_id, action, - self.components[const.ON_INPUT_HIGH], is_input_consumed) - - is_input_consumed = process_input(action_id, action, - self.components[const.ON_INPUT], is_input_consumed) + local components = self.components[base_component.ON_INPUT] + check_sort_input_stack(self, components) + is_input_consumed = process_input(action_id, action, components, is_input_consumed) self._is_input_processing = false @@ -284,7 +302,7 @@ end -- @tparam table message Message from on_message -- @tparam hash sender Sender from on_message function DruidInstance.on_message(self, message_id, message, sender) - local specific_ui_message = const.SPECIFIC_UI_MESSAGES[message_id] + local specific_ui_message = base_component.SPECIFIC_UI_MESSAGES[message_id] if specific_ui_message then local components = self.components[message_id] @@ -295,7 +313,7 @@ function DruidInstance.on_message(self, message_id, message, sender) end end else - local components = self.components[const.ON_MESSAGE] + local components = self.components[base_component.ON_MESSAGE] for i = 1, #components do components[i]:on_message(message_id, message, sender) end @@ -307,7 +325,7 @@ end -- This one called by on_window_callback by global window listener -- @tparam DruidInstance self function DruidInstance.on_focus_lost(self) - local components = self.components[const.ON_FOCUS_LOST] + local components = self.components[base_component.ON_FOCUS_LOST] for i = 1, #components do components[i]:on_focus_lost() end @@ -318,7 +336,7 @@ end -- This one called by on_window_callback by global window listener -- @tparam DruidInstance self function DruidInstance.on_focus_gained(self) - local components = self.components[const.ON_FOCUS_GAINED] + local components = self.components[base_component.ON_FOCUS_GAINED] for i = 1, #components do components[i]:on_focus_gained() end @@ -329,7 +347,7 @@ end -- Called on update gui layout -- @tparam DruidInstance self function DruidInstance.on_layout_change(self) - local components = self.components[const.ON_LAYOUT_CHANGE] + local components = self.components[base_component.ON_LAYOUT_CHANGE] for i = 1, #components do components[i]:on_layout_change() end @@ -341,7 +359,7 @@ end -- call manualy to update all translations -- @function druid.on_language_change function DruidInstance.on_language_change(self) - local components = self.components[const.ON_LANGUAGE_CHANGE] + local components = self.components[base_component.ON_LANGUAGE_CHANGE] for i = 1, #components do components[i]:on_language_change() end diff --git a/example/kenney.collection b/example/kenney.collection index a8b3693..b983685 100644 --- a/example/kenney.collection +++ b/example/kenney.collection @@ -81,6 +81,7 @@ embedded_instances { "gain: 1.0\\n" "pan: 0.0\\n" "speed: 1.0\\n" + "loopcount: 0\\n" "\"\n" " position {\n" " x: 0.0\n" diff --git a/settings_deployer b/settings_deployer index 91665ba..c94ea4b 100644 --- a/settings_deployer +++ b/settings_deployer @@ -1,4 +1,4 @@ #!/bin/bash use_latest_bob=false enable_incremental_version=true -bob_sha="173:fe2b689302e79b7cf8c0bc7d934f23587b268c8a" +bob_sha="180:f34b08dc12af1101ae62c6e880b6373a03206174"