mirror of
https://github.com/Insality/druid
synced 2025-09-27 18:12:21 +02:00
Add simple swipe component
This commit is contained in:
@@ -70,7 +70,7 @@ function M.set_hover(self, state)
|
||||
end
|
||||
|
||||
|
||||
--- Strict button click area. Useful for
|
||||
--- Strict hover click area. Useful for
|
||||
-- no click events outside stencil node
|
||||
-- @function hover:set_click_zone
|
||||
-- @tparam node zone Gui node
|
||||
|
129
druid/base/swipe.lua
Normal file
129
druid/base/swipe.lua
Normal file
@@ -0,0 +1,129 @@
|
||||
--- Component to handle swipe gestures on node.
|
||||
-- Swipe will be triggered, if swipe was started and
|
||||
-- ended on one node
|
||||
-- @module druid.swipe
|
||||
|
||||
--- Component events
|
||||
-- @table Events
|
||||
-- @tfield druid_event on_swipe Trigger on swipe event
|
||||
|
||||
--- Component style params
|
||||
-- @table Style
|
||||
-- @tfield number SWIPE_TIME Maximum time for swipe trigger
|
||||
-- @tfield number SWIPE_THRESHOLD Minimum distance for swipe trigger
|
||||
-- @tfield bool SWIPE_TRIGGER_ON_MOVE If true, trigger on swipe moving, not only release action
|
||||
|
||||
local Event = require("druid.event")
|
||||
local const = require("druid.const")
|
||||
local helper = require("druid.helper")
|
||||
local component = require("druid.component")
|
||||
|
||||
local M = component.create("swipe", { const.ON_INPUT })
|
||||
|
||||
|
||||
local function start_swipe(self, action)
|
||||
self._swipe_start_time = socket.gettime()
|
||||
self.start_pos.x = action.x
|
||||
self.start_pos.y = action.y
|
||||
end
|
||||
|
||||
|
||||
local function reset_swipe(self, action)
|
||||
self._swipe_start_time = false
|
||||
end
|
||||
|
||||
|
||||
local function check_swipe(self, action)
|
||||
local dx = action.x - self.start_pos.x
|
||||
local dy = action.y - self.start_pos.y
|
||||
local dist = helper.distance(self.start_pos.x, self.start_pos.y, action.x, action.y)
|
||||
local delta_time = socket.gettime() - self._swipe_start_time
|
||||
local is_swipe = self.style.SWIPE_THRESHOLD <= dist and delta_time <= self.style.SWIPE_TIME
|
||||
|
||||
if is_swipe then
|
||||
local is_x_swipe = math.abs(dx) >= math.abs(dy)
|
||||
local swipe_side = false
|
||||
if is_x_swipe and dx > 0 then
|
||||
swipe_side = const.SWIPE.RIGHT
|
||||
end
|
||||
if is_x_swipe and dx < 0 then
|
||||
swipe_side = const.SWIPE.LEFT
|
||||
end
|
||||
if not is_x_swipe and dy > 0 then
|
||||
swipe_side = const.SWIPE.UP
|
||||
end
|
||||
if not is_x_swipe and dy < 0 then
|
||||
swipe_side = const.SWIPE.DOWN
|
||||
end
|
||||
|
||||
self.on_swipe:trigger(self:get_context(), swipe_side, dist, delta_time)
|
||||
reset_swipe(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Component init function
|
||||
-- @function swipe:init
|
||||
-- @tparam node node Gui node
|
||||
-- @tparam function on_swipe_callback Swipe callback for on_swipe_end event
|
||||
function M.init(self, node, on_swipe_callback)
|
||||
self.style = self:get_style()
|
||||
self._trigger_on_move = self.style.SWIPE_TRIGGER_ON_MOVE
|
||||
self.node = self:get_node(node)
|
||||
|
||||
self._swipe_start_time = false
|
||||
self.start_pos = vmath.vector3(0)
|
||||
|
||||
self.click_zone = nil
|
||||
self.on_swipe = Event(on_swipe_callback)
|
||||
end
|
||||
|
||||
|
||||
function M.on_input(self, action_id, action)
|
||||
if action_id ~= const.ACTION_TOUCH then
|
||||
return
|
||||
end
|
||||
|
||||
if not helper.is_enabled(self.node) then
|
||||
return false
|
||||
end
|
||||
|
||||
local is_pick = gui.pick_node(self.node, action.x, action.y)
|
||||
if self.click_zone then
|
||||
is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y)
|
||||
end
|
||||
|
||||
if not is_pick then
|
||||
reset_swipe(self, action)
|
||||
return false
|
||||
end
|
||||
|
||||
if self._swipe_start_time and (self._trigger_on_move or action.released) then
|
||||
check_swipe(self, action)
|
||||
end
|
||||
|
||||
if action.pressed then
|
||||
start_swipe(self, action)
|
||||
end
|
||||
|
||||
if action.released then
|
||||
reset_swipe(self, action)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function M.on_input_interrupt(self)
|
||||
reset_swipe(self)
|
||||
end
|
||||
|
||||
|
||||
--- Strict swipe click area. Useful for
|
||||
-- restrict events outside stencil node
|
||||
-- @function swipe:set_click_zone
|
||||
-- @tparam node zone Gui node
|
||||
function M.set_click_zone(self, zone)
|
||||
self.click_zone = self:get_node(zone)
|
||||
end
|
||||
|
||||
|
||||
return M
|
Reference in New Issue
Block a user