mirror of
https://github.com/Insality/druid.git
synced 2025-06-27 02:17:52 +02:00
#111 Add druid.stencil_check for auto stencil check to call set_click_zone
This commit is contained in:
parent
063e4f4a31
commit
91fb8ced52
10
README.md
10
README.md
@ -63,6 +63,16 @@ If you don't need this behaviour, you can disable it by settings `druid.no_auto_
|
||||
no_auto_input = 1
|
||||
```
|
||||
|
||||
|
||||
### Stencil check [optional]
|
||||
|
||||
When creating input components inside stencil nodes, you probably will use `component:set_click_zone()` to restrict clicks outside this stencil zone.
|
||||
Druid can do it automatically on _late_init_ component step. To enable this feature add next field in your _game.project_ file
|
||||
```
|
||||
[druid]
|
||||
stencil_check = 1
|
||||
```
|
||||
|
||||
### Code [optional]
|
||||
|
||||
Adjust **Druid** settings, if needed:
|
||||
|
@ -23,7 +23,7 @@ end
|
||||
function M.update(self, dt)
|
||||
end
|
||||
|
||||
-- Call only if exist interest: component.ON_INPUT or component.ON_INPUT_HIGH
|
||||
-- Call only if exist interest: component.ON_INPUT
|
||||
function M.on_input(self, action_id, action)
|
||||
end
|
||||
|
||||
@ -60,6 +60,10 @@ end
|
||||
function M.on_focus_gained(self)
|
||||
end
|
||||
|
||||
-- Call only if exist interest: component.ON_LATE_INIT
|
||||
function M.on_late_init(self)
|
||||
end
|
||||
|
||||
-- Call on component remove or on druid:final
|
||||
function M.on_remove(self)
|
||||
end
|
||||
@ -117,6 +121,8 @@ There is next interests in druid:
|
||||
|
||||
- **ON_FOCUS_GAINED** will call _on_focust_gained_ function in on focus gained event. You need to pass window_callback to global `druid:on_window_callback`
|
||||
|
||||
- **ON_LATE_INIT** will call _on_late_init_ function once after component init on update step.
|
||||
|
||||
## Best practice on custom components
|
||||
On each component recommended describe component scheme in next way:
|
||||
|
||||
|
@ -237,4 +237,8 @@ Have a good day.
|
||||
- `value` - optional field for several actions. For example value is text for **TEXT_SET**
|
||||
- Add Druid component interest: `component.ON_MESSAGE_INPUT`
|
||||
- Implement new interest via function `component:on_message_input(node_id, message)`
|
||||
- See **System: Message input** example
|
||||
- See **System: Message input** example
|
||||
- **#111**: Add autocheck for input and stencil nodes. To enable this feature, add `druid.stencil_check = 1` to your game.project file.
|
||||
- Add `helper.get_closest_stencil_node` function to get closest parent non inverted stencil node
|
||||
- Add `component.ON_LATE_INIT` interest. If component with with interest, it will call `component.on_late_init` function once after component init on update step. This can be used to do something after all gui components are was initialized and setup.
|
||||
- This feature is using for auto setup `component:set_click_zone` to restrict clicks outside scrolls zone for example. Now you can don't think about click zone and let Druid do it instead of you!
|
@ -57,7 +57,11 @@ local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
local component = require("druid.component")
|
||||
|
||||
local Button = component.create("button", { component.ON_INPUT, component.ON_MESSAGE_INPUT })
|
||||
local Button = component.create("button", {
|
||||
component.ON_INPUT,
|
||||
component.ON_MESSAGE_INPUT,
|
||||
component.ON_LATE_INIT
|
||||
})
|
||||
|
||||
|
||||
local function is_input_match(self, action_id)
|
||||
@ -221,6 +225,16 @@ function Button.init(self, node, callback, params, anim_node)
|
||||
end
|
||||
|
||||
|
||||
function Button.on_late_init(self)
|
||||
if not self.click_zone and const.IS_STENCIL_CHECK then
|
||||
local stencil_node = helper.get_closest_stencil_node(self.node)
|
||||
if stencil_node then
|
||||
self:set_click_zone(stencil_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Button.on_input(self, action_id, action)
|
||||
if not is_input_match(self, action_id) then
|
||||
return false
|
||||
|
@ -51,7 +51,7 @@ local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
local component = require("druid.component")
|
||||
|
||||
local Drag = component.create("drag", { component.ON_INPUT }, const.PRIORITY_INPUT_HIGH)
|
||||
local Drag = component.create("drag", { component.ON_INPUT, component.ON_LATE_INIT }, const.PRIORITY_INPUT_HIGH)
|
||||
|
||||
|
||||
local function start_touch(self, touch)
|
||||
@ -189,6 +189,16 @@ function Drag.init(self, node, on_drag_callback)
|
||||
end
|
||||
|
||||
|
||||
function Drag.on_late_init(self)
|
||||
if not self.click_zone and const.IS_STENCIL_CHECK then
|
||||
local stencil_node = helper.get_closest_stencil_node(self.node)
|
||||
if stencil_node then
|
||||
self:set_click_zone(stencil_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Drag.on_input_interrupt(self)
|
||||
if self.is_drag or self.is_touch then
|
||||
end_touch(self)
|
||||
|
@ -18,7 +18,7 @@ local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
local component = require("druid.component")
|
||||
|
||||
local Hover = component.create("hover", { component.ON_INPUT })
|
||||
local Hover = component.create("hover", { component.ON_INPUT, component.ON_LATE_INIT })
|
||||
|
||||
|
||||
--- Component init function
|
||||
@ -38,6 +38,16 @@ function Hover.init(self, node, on_hover_callback)
|
||||
end
|
||||
|
||||
|
||||
function Hover.on_late_init(self)
|
||||
if not self.click_zone and const.IS_STENCIL_CHECK then
|
||||
local stencil_node = helper.get_closest_stencil_node(self.node)
|
||||
if stencil_node then
|
||||
self:set_click_zone(stencil_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Hover.on_input(self, action_id, action)
|
||||
if action_id ~= const.ACTION_TOUCH and action_id ~= nil then
|
||||
return false
|
||||
|
@ -61,7 +61,12 @@ local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
local component = require("druid.component")
|
||||
|
||||
local Scroll = component.create("scroll", { component.ON_INPUT, component.ON_UPDATE, component.ON_LAYOUT_CHANGE })
|
||||
local Scroll = component.create("scroll", {
|
||||
component.ON_INPUT,
|
||||
component.ON_UPDATE,
|
||||
component.ON_LAYOUT_CHANGE,
|
||||
component.ON_LATE_INIT
|
||||
})
|
||||
|
||||
|
||||
local function inverse_lerp(min, max, current)
|
||||
@ -172,6 +177,16 @@ function Scroll.init(self, view_node, content_node)
|
||||
end
|
||||
|
||||
|
||||
function Scroll.on_late_init(self)
|
||||
if not self.click_zone and const.IS_STENCIL_CHECK then
|
||||
local stencil_node = helper.get_closest_stencil_node(self.node)
|
||||
if stencil_node then
|
||||
self:set_click_zone(stencil_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Scroll.on_layout_change(self)
|
||||
gui.set_position(self.content_node, self.position)
|
||||
end
|
||||
|
@ -23,7 +23,7 @@ local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
local component = require("druid.component")
|
||||
|
||||
local Swipe = component.create("swipe", { component.ON_INPUT })
|
||||
local Swipe = component.create("swipe", { component.ON_INPUT, component.ON_LATE_INIT })
|
||||
|
||||
|
||||
local function start_swipe(self, action)
|
||||
@ -99,6 +99,16 @@ function Swipe.init(self, node, on_swipe_callback)
|
||||
end
|
||||
|
||||
|
||||
function Swipe.on_late_init(self)
|
||||
if not self.click_zone and const.IS_STENCIL_CHECK then
|
||||
local stencil_node = helper.get_closest_stencil_node(self.node)
|
||||
if stencil_node then
|
||||
self:set_click_zone(stencil_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Swipe.on_input(self, action_id, action)
|
||||
if action_id ~= const.ACTION_TOUCH then
|
||||
return false
|
||||
|
@ -18,6 +18,7 @@ BaseComponent.ALL = const.ALL
|
||||
BaseComponent.ON_INPUT = const.ON_INPUT
|
||||
BaseComponent.ON_UPDATE = const.ON_UPDATE
|
||||
BaseComponent.ON_MESSAGE = const.ON_MESSAGE
|
||||
BaseComponent.ON_LATE_INIT = const.ON_LATE_INIT
|
||||
BaseComponent.ON_FOCUS_LOST = const.ON_FOCUS_LOST
|
||||
BaseComponent.ON_FOCUS_GAINED = const.ON_FOCUS_GAINED
|
||||
BaseComponent.ON_LAYOUT_CHANGE = const.ON_LAYOUT_CHANGE
|
||||
@ -30,6 +31,7 @@ BaseComponent.ALL_INTERESTS = {
|
||||
BaseComponent.ON_INPUT,
|
||||
BaseComponent.ON_UPDATE,
|
||||
BaseComponent.ON_MESSAGE,
|
||||
BaseComponent.ON_LATE_INIT,
|
||||
BaseComponent.ON_FOCUS_LOST,
|
||||
BaseComponent.ON_FOCUS_GAINED,
|
||||
BaseComponent.ON_LAYOUT_CHANGE,
|
||||
|
@ -21,6 +21,9 @@ M.ACTION_SCROLL_UP = hash(sys.get_config("druid.input_scroll_up", "scroll_up"))
|
||||
M.ACTION_SCROLL_DOWN = hash(sys.get_config("druid.input_scroll_down", "scroll_down"))
|
||||
|
||||
|
||||
M.IS_STENCIL_CHECK = sys.get_config("druid.stencil_check") == 1
|
||||
|
||||
|
||||
M.RELEASED = "released"
|
||||
M.PRESSED = "pressed"
|
||||
M.STRING = "string"
|
||||
@ -33,6 +36,7 @@ M.ALL = "all"
|
||||
M.ON_INPUT = hash("on_input")
|
||||
M.ON_UPDATE = hash("on_update")
|
||||
M.ON_MESSAGE = hash("on_message")
|
||||
M.ON_LATE_INIT = hash("on_late_init")
|
||||
M.ON_FOCUS_LOST = hash("on_focus_lost")
|
||||
M.ON_FOCUS_GAINED = hash("on_focus_gained")
|
||||
M.ON_LAYOUT_CHANGE = hash("layout_changed")
|
||||
|
@ -171,6 +171,32 @@ function M.is_enabled(node)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Return closest non inverted clipping parent node for node
|
||||
-- @function helper.get_closest_stencil_node
|
||||
-- @tparam node node Gui node
|
||||
-- @treturn node|nil The clipping node
|
||||
function M.get_closest_stencil_node(node)
|
||||
if not node then
|
||||
return nil
|
||||
end
|
||||
|
||||
local parent = gui.get_parent(node)
|
||||
while parent do
|
||||
local clipping_mode = gui.get_clipping_mode(parent)
|
||||
local is_clipping_normal = not gui.get_clipping_inverted(parent)
|
||||
|
||||
if is_clipping_normal and clipping_mode == gui.CLIPPING_MODE_STENCIL then
|
||||
return parent
|
||||
end
|
||||
|
||||
parent = gui.get_parent(parent)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Get node offset for given gui pivot
|
||||
-- @function helper.get_pivot_offset
|
||||
-- @tparam gui.pivot pivot The node pivot
|
||||
|
@ -225,13 +225,7 @@ end
|
||||
function DruidInstance.create(self, component, ...)
|
||||
helper.deprecated("The druid:create is deprecated. Please use druid:new instead")
|
||||
|
||||
local instance = create(self, component)
|
||||
|
||||
if instance.init then
|
||||
instance:init(...)
|
||||
end
|
||||
|
||||
return instance
|
||||
return DruidInstance.new(self, component, ...)
|
||||
end
|
||||
|
||||
|
||||
@ -316,6 +310,12 @@ end
|
||||
-- @tparam DruidInstance self
|
||||
-- @tparam number dt Delta time
|
||||
function DruidInstance.update(self, dt)
|
||||
local late_init_components = self.components[base_component.ON_LATE_INIT]
|
||||
while late_init_components[1] do
|
||||
late_init_components[1]:on_late_init()
|
||||
table.remove(late_init_components, 1)
|
||||
end
|
||||
|
||||
local components = self.components[base_component.ON_UPDATE]
|
||||
for i = 1, #components do
|
||||
components[i]:update(dt)
|
||||
|
@ -25,6 +25,7 @@ use_accelerometer = 0
|
||||
|
||||
[druid]
|
||||
no_auto_input = 0
|
||||
stencil_check = 0
|
||||
input_text = text
|
||||
input_touch = touch
|
||||
input_marked_text = marked_text
|
||||
|
Loading…
x
Reference in New Issue
Block a user