Merge pull request #122 from Insality/102-input-priority

WIP #102 Add separate input priority component value
This commit is contained in:
Maxim Tuprikov 2021-04-01 21:11:31 +03:00 committed by GitHub
commit c5782b5cc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 142 additions and 46 deletions

View File

@ -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)
```

View File

@ -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

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -1,4 +1,4 @@
#!/bin/bash
use_latest_bob=false
enable_incremental_version=true
bob_sha="173:fe2b689302e79b7cf8c0bc7d934f23587b268c8a"
bob_sha="180:f34b08dc12af1101ae62c6e880b6373a03206174"