diff --git a/docs_md/changelog.md b/docs_md/changelog.md index 4c73051..4fc0160 100644 --- a/docs_md/changelog.md +++ b/docs_md/changelog.md @@ -141,3 +141,14 @@ Desc - 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/drag.lua b/druid/base/drag.lua index 9263e29..18d24db 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", { component.ON_INPUT_HIGH }) +local Drag = component.create("drag", { component.ON_INPUT }, const.PRIORITY_INPUT_HIGH) local function start_touch(self, touch) @@ -91,7 +91,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 diff --git a/druid/component.lua b/druid/component.lua index 07475b4..195a6d5 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -5,6 +5,7 @@ local const = require("druid.const") local class = require("druid.system.middleclass") +local helper = require("druid.helper") local BaseComponent = class("druid.component") @@ -15,7 +16,6 @@ BaseComponent.ALL = const.ALL BaseComponent.ON_INPUT = const.ON_INPUT BaseComponent.ON_UPDATE = const.ON_UPDATE BaseComponent.ON_MESSAGE = const.ON_MESSAGE -BaseComponent.ON_INPUT_HIGH = const.ON_INPUT_HIGH BaseComponent.ON_FOCUS_LOST = const.ON_FOCUS_LOST BaseComponent.ON_FOCUS_GAINED = const.ON_FOCUS_GAINED BaseComponent.ON_LAYOUT_CHANGE = const.ON_LAYOUT_CHANGE @@ -28,7 +28,6 @@ BaseComponent.ALL_INTERESTS = { BaseComponent.ON_UPDATE, BaseComponent.ON_MESSAGE, BaseComponent.ON_FOCUS_LOST, - BaseComponent.ON_INPUT_HIGH, BaseComponent.ON_FOCUS_GAINED, BaseComponent.ON_LAYOUT_CHANGE, BaseComponent.ON_LANGUAGE_CHANGE, @@ -45,11 +44,17 @@ BaseComponent.SPECIFIC_UI_MESSAGES = { BaseComponent.UI_INPUT = { - [BaseComponent.ON_INPUT_HIGH] = true, [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 @@ -91,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 @@ -151,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 @@ -194,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 = {} } @@ -216,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 @@ -294,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 9f1fc0d..0e26fa4 100644 --- a/druid/const.lua +++ b/druid/const.lua @@ -31,13 +31,17 @@ 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.PRIORITY_INPUT = 10 +M.PRIORITY_INPUT_HIGH = 20 +M.PRIORITY_INPUT_MAX = 100 + + M.PIVOTS = { [gui.PIVOT_CENTER] = vmath.vector3(0), [gui.PIVOT_N] = vmath.vector3(0, 0.5, 0), diff --git a/druid/extended/component.template.lua b/druid/extended/component.template.lua index a6956be..587d0e8 100644 --- a/druid/extended/component.template.lua +++ b/druid/extended/component.template.lua @@ -16,7 +16,7 @@ function Component:update(dt) end --- Call only if exist interest: component.ON_INPUT or component.ON_INPUT_HIGH +-- Call only if exist interest: component.ON_INPUT function Component:on_input(action_id, action) return false end diff --git a/druid/extended/input.lua b/druid/extended/input.lua index 4179170..dbb532c 100644 --- a/druid/extended/input.lua +++ b/druid/extended/input.lua @@ -276,8 +276,8 @@ function Input.select(self) gui.reset_keyboard() self.marked_value = "" if not self.is_selected then - self:increase_input_priority() - self.button:increase_input_priority() + 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 diff --git a/druid/extended/slider.lua b/druid/extended/slider.lua index f07d5c8..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", { component.ON_INPUT_HIGH, component.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/system/druid_instance.lua b/druid/system/druid_instance.lua index 88eed5b..6a4fac7 100644 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -82,6 +82,22 @@ 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() @@ -103,6 +119,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 @@ -110,24 +147,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 @@ -257,12 +278,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[base_component.ON_INPUT_HIGH], is_input_consumed) - - is_input_consumed = process_input(action_id, action, - self.components[base_component.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 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"