mirror of
https://github.com/Insality/druid.git
synced 2025-06-27 10:27:47 +02:00
Solve #133 Add hotkey component
This commit is contained in:
parent
53f305734c
commit
e029d1eac3
148
druid/extended/hotkey.lua
Normal file
148
druid/extended/hotkey.lua
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
|
||||||
|
|
||||||
|
--- Druid hotkey component
|
||||||
|
-- @module Hotkey
|
||||||
|
-- @within BaseComponent
|
||||||
|
-- @alias druid.hotkey
|
||||||
|
|
||||||
|
--- On change state callback(self, state)
|
||||||
|
-- @tfield DruidEvent on_change_state @{DruidEvent}
|
||||||
|
|
||||||
|
--- Visual node
|
||||||
|
-- @tfield node node
|
||||||
|
|
||||||
|
--- Button trigger node
|
||||||
|
-- @tfield[opt=node] node click_node
|
||||||
|
|
||||||
|
--- Button component from click_node
|
||||||
|
-- @tfield Button button @{Button}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
local helper = require("druid.helper")
|
||||||
|
local component = require("druid.component")
|
||||||
|
|
||||||
|
local Hotkey = component.create("hotkey")
|
||||||
|
|
||||||
|
|
||||||
|
--- Component init function
|
||||||
|
-- @tparam Hotkey self @{Hotkey}
|
||||||
|
-- @tparam string[]|string keys The keys to be pressed for trigger callback. Should contains one key and any modificator keys
|
||||||
|
-- @tparam function callback The callback function
|
||||||
|
function Hotkey.init(self, keys, callback, callback_argument)
|
||||||
|
self.druid = self:get_druid()
|
||||||
|
|
||||||
|
self._hotkeys = {}
|
||||||
|
self._modificators = {}
|
||||||
|
self._callback = callback
|
||||||
|
|
||||||
|
if keys then
|
||||||
|
self:add_hotkey(keys, callback_argument)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Component style params.
|
||||||
|
-- You can override this component styles params in druid styles table
|
||||||
|
-- or create your own style
|
||||||
|
-- @table style
|
||||||
|
-- @tfield string[] MODIFICATORS The list of action_id as hotkey modificators
|
||||||
|
function Hotkey.on_style_change(self, style)
|
||||||
|
self.style = {}
|
||||||
|
self.style.MODIFICATORS = style.MODIFICATORS or {}
|
||||||
|
|
||||||
|
for index = 1, #style.MODIFICATORS do
|
||||||
|
self.style.MODIFICATORS[index] = hash(self.style.MODIFICATORS[index])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Add hotkey for component callback
|
||||||
|
-- @tparam Hotkey self @{Hotkey}
|
||||||
|
-- @tparam string[]|hash[]|string|hash Keys that have to be pressed before key pressed to activate
|
||||||
|
function Hotkey.add_hotkey(self, keys, callback_argument)
|
||||||
|
keys = keys or {}
|
||||||
|
if type(keys) == "string" then
|
||||||
|
keys = { keys }
|
||||||
|
end
|
||||||
|
|
||||||
|
local modificators = {}
|
||||||
|
local key = nil
|
||||||
|
|
||||||
|
for index = 1, #keys do
|
||||||
|
local key_hash = hash(keys[index])
|
||||||
|
if helper.contains(self.style.MODIFICATORS, key_hash) then
|
||||||
|
table.insert(modificators, key_hash)
|
||||||
|
else
|
||||||
|
if not key then
|
||||||
|
key = key_hash
|
||||||
|
else
|
||||||
|
error("The hotkey keys should contains only one key (except modificator keys)")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(self._hotkeys, {
|
||||||
|
modificators = modificators,
|
||||||
|
key = key,
|
||||||
|
is_processing = false,
|
||||||
|
callback_argument = callback_argument,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Current hotkey status
|
||||||
|
for index = 1, #self.style.MODIFICATORS do
|
||||||
|
local modificator = hash(self.style.MODIFICATORS[index])
|
||||||
|
self._modificators[modificator] = self._modificators[modificator] or false
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function Hotkey.on_input(self, action_id, action)
|
||||||
|
if not action_id then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self._modificators[action_id] ~= nil then
|
||||||
|
if action.pressed then
|
||||||
|
self._modificators[action_id] = true
|
||||||
|
end
|
||||||
|
if action.released then
|
||||||
|
self._modificators[action_id] = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for index = 1, #self._hotkeys do
|
||||||
|
local hotkey = self._hotkeys[index]
|
||||||
|
if action_id == hotkey.key then
|
||||||
|
local is_modificator_ok = true
|
||||||
|
|
||||||
|
-- Check only required modificators pressed
|
||||||
|
for i = 1, #self.style.MODIFICATORS do
|
||||||
|
local mod = self.style.MODIFICATORS[i]
|
||||||
|
if helper.contains(hotkey.modificators, mod) and self._modificators[mod] == false then
|
||||||
|
is_modificator_ok = false
|
||||||
|
end
|
||||||
|
if not helper.contains(hotkey.modificators, mod) and self._modificators[mod] == true then
|
||||||
|
is_modificator_ok = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if action.pressed and is_modificator_ok then
|
||||||
|
hotkey.is_processing = true
|
||||||
|
end
|
||||||
|
if action.released and is_modificator_ok and hotkey.is_processing then
|
||||||
|
hotkey.is_processing = false
|
||||||
|
if hotkey.callback_argument then
|
||||||
|
self._callback(self:get_context(), hotkey.callback_argument)
|
||||||
|
else
|
||||||
|
self._callback(self:get_context())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return Hotkey
|
Loading…
x
Reference in New Issue
Block a user