#81 Add simple input control via messages

This commit is contained in:
Insality 2021-10-22 00:56:46 +03:00
parent bbdf2b405d
commit 1da5476837
10 changed files with 1672 additions and 3 deletions

View File

@ -223,4 +223,16 @@ Have a good day.
- const.TEXT_ADJUST.NO_ADJUST - No any adjust, like default Defold text node
- const.TEXT_ADJUST.DOWNSCALE_LIMITED - Change text's scale list downscale, but there is limit for text's scale
- const.TEXT_ADJUST.SCROLL - Change text's pivot to imitate scrolling in the text box. Use with stencil node for better effect.
- const.TEXT_ADJUST.SCALE_THEN_SCROLL - Combine two modes: first limited downscale, then scroll
- const.TEXT_ADJUST.SCALE_THEN_SCROLL - Combine two modes: first limited downscale, then scroll
- **#81** Add ability to interact with Druid input via messages
- Currently add only Druid Button component:
- Send to _gui.script_ message: `druid_const.ON_MESSAGE_INPUT`. The message table params:
- `node_id` - the name of the node with button component on it
- `action` - value from `druid_const.MESSAGE_INPUT`. Available values:
- **BUTTON_CLICK** - usual button click callback
- **BUTTON_LONG_CLICK** - button long click callback
- **BUTTON_DOUBLE_CLICK** - button double click callback
- **BUTTON_REPEATED_CLICK** - button repeated click callback
- 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

View File

@ -24,6 +24,9 @@
---Trigger node
-- @tfield node node
---The hash of trigger node
-- @tfield node_id hash
---Animation node
-- @tfield[opt=node] node anim_node
@ -52,7 +55,7 @@ local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
local Button = component.create("button", { component.ON_INPUT })
local Button = component.create("button", { component.ON_INPUT, component.ON_MESSAGE_INPUT })
local function is_input_match(self, action_id)
@ -95,6 +98,7 @@ local function on_button_repeated_click(self)
self.style.on_click(self, self.anim_node)
self.click_in_row = self.click_in_row + 1
self.on_repeated_click:trigger(self:get_context(), self.params, self, self.click_in_row)
end
@ -190,6 +194,7 @@ end
function Button.init(self, node, callback, params, anim_node)
self.druid = self:get_druid()
self.node = self:get_node(node)
self.node_id = gui.get_id(self.node)
self.anim_node = anim_node and self:get_node(anim_node) or self.node
self.start_scale = gui.get_scale(self.anim_node)
@ -288,6 +293,31 @@ function Button.on_input_interrupt(self)
end
function Button.on_message_input(self, node_id, message)
if node_id ~= self.node_id or self.disabled or not helper.is_enabled(self.node) then
return false
end
if message.action == const.MESSAGE_INPUT.BUTTON_CLICK then
on_button_click(self)
end
if message.action == const.MESSAGE_INPUT.BUTTON_LONG_CLICK then
on_button_long_click(self)
end
if message.action == const.MESSAGE_INPUT.BUTTON_DOUBLE_CLICK then
on_button_double_click(self)
end
if message.action == const.MESSAGE_INPUT.BUTTON_REPEATED_CLICK then
on_button_repeated_click(self)
self.is_repeated_started = false
self.last_pressed_time = socket.gettime()
end
end
--- Set enabled button component state
-- @tparam Button self
-- @tparam bool state Enabled state

View File

@ -19,6 +19,7 @@ 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_MESSAGE_INPUT = const.ON_MESSAGE_INPUT
BaseComponent.ON_LANGUAGE_CHANGE = const.ON_LANGUAGE_CHANGE
@ -30,6 +31,7 @@ BaseComponent.ALL_INTERESTS = {
BaseComponent.ON_FOCUS_LOST,
BaseComponent.ON_FOCUS_GAINED,
BaseComponent.ON_LAYOUT_CHANGE,
BaseComponent.ON_MESSAGE_INPUT,
BaseComponent.ON_LANGUAGE_CHANGE,
}
@ -39,6 +41,7 @@ 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_MESSAGE_INPUT] = "on_message_input",
[BaseComponent.ON_LANGUAGE_CHANGE] = "on_language_change",
}

View File

@ -34,6 +34,7 @@ M.ON_MESSAGE = hash("on_message")
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_MESSAGE_INPUT = hash("on_message_input")
M.ON_LANGUAGE_CHANGE = hash("on_language_change")
@ -42,6 +43,14 @@ M.PRIORITY_INPUT_HIGH = 20
M.PRIORITY_INPUT_MAX = 100
M.MESSAGE_INPUT = {
BUTTON_CLICK = "button_click",
BUTTON_LONG_CLICK = "button_long_click",
BUTTON_DOUBLE_CLICK = "button_double_click",
BUTTON_REPEATED_CLICK = "button_repeated_click",
}
M.PIVOTS = {
[gui.PIVOT_CENTER] = vmath.vector3(0),
[gui.PIVOT_N] = vmath.vector3(0, 0.5, 0),

View File

@ -352,9 +352,21 @@ end
-- @tparam table message Message from on_message
-- @tparam hash sender Sender from on_message
function DruidInstance.on_message(self, message_id, message, sender)
-- TODO: refactor for more juicy code
local specific_ui_message = base_component.SPECIFIC_UI_MESSAGES[message_id]
local on_message_input_message = base_component.SPECIFIC_UI_MESSAGES[base_component.ON_MESSAGE_INPUT]
if specific_ui_message then
if specific_ui_message == on_message_input_message then
local components = self.components[message_id]
if components then
for i = 1, #components do
local component = components[i]
if can_use_input_component(self, component) then
component[specific_ui_message](component, hash(message.node_id), message)
end
end
end
elseif specific_ui_message then
local components = self.components[message_id]
if components then
for i = 1, #components do

View File

@ -1184,3 +1184,66 @@ embedded_instances {
z: 1.0
}
}
embedded_instances {
id: "system_message_input"
data: "components {\n"
" id: \"screen_factory\"\n"
" component: \"/monarch/screen_factory.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" properties {\n"
" id: \"screen_id\"\n"
" value: \"system_message_input\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"popup\"\n"
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionfactory\"\n"
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/example/examples/system/message_input/message_input.collection\\\"\\n"
"load_dynamically: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

View File

@ -141,6 +141,7 @@ local function init_lobby(self)
self.lobby_grid:add(get_button_disabled(self, "Custom components"))
self.lobby_grid:add(get_button_disabled(self, "Component interests"))
self.lobby_grid:add(get_button_disabled(self, "Nested Druids"))
self.lobby_grid:add(get_button(self, "Message input", "system_message_input"))
self.lobby_grid:add(get_button_disabled(self, "Input priority"))
end

View File

@ -0,0 +1,37 @@
name: "message_input"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"message_input\"\n"
" component: \"/example/examples/system/message_input/message_input.gui\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,72 @@
local druid = require("druid.druid")
local const = require("druid.const")
local function click_callback(self, text, some)
print("Button tap callback:", text, some)
end
local function trigger_callback(self, params)
msg.post(".", const.ON_MESSAGE_INPUT, {
node_id = params.node_id,
action = params.action
})
end
function init(self)
self.druid = druid.new(self)
self.button_left = self.druid:new_button("button_left/button", click_callback)
self.button_left.on_long_click:subscribe(function() print("long click") end)
self.button_left.on_double_click:subscribe(function() print("double click") end)
self.button_left.on_repeated_click:subscribe(function() print("repeated_click") end)
self.button_right = self.druid:new_button("button_right/button", click_callback)
self.druid:new_button("button_trigger_left/button", trigger_callback, {
node_id = "button_left/button",
action = const.MESSAGE_INPUT.BUTTON_CLICK
})
self.druid:new_button("button_trigger_left_double/button", trigger_callback, {
node_id = "button_left/button",
action = const.MESSAGE_INPUT.BUTTON_DOUBLE_CLICK
})
self.druid:new_button("button_trigger_left_long/button", trigger_callback, {
node_id = "button_left/button",
action = const.MESSAGE_INPUT.BUTTON_LONG_CLICK
})
self.druid:new_button("button_trigger_left_repeated/button", trigger_callback, {
node_id = "button_left/button",
action = const.MESSAGE_INPUT.BUTTON_REPEATED_CLICK
})
self.druid:new_button("button_trigger_right/button", trigger_callback, {
node_id = "button_right/button",
action = const.MESSAGE_INPUT.BUTTON_CLICK
})
end
function final(self)
self.druid:final()
end
function update(self, dt)
self.druid:update(dt)
end
function on_message(self, message_id, message, sender)
self.druid:on_message(message_id, message, sender)
end
function on_input(self, action_id, action)
return self.druid:on_input(action_id, action)
end