mirror of
https://github.com/Insality/druid
synced 2025-06-27 10:27:48 +02:00
242 lines
8.2 KiB
Lua
242 lines
8.2 KiB
Lua
local M = {}
|
|
|
|
local druid_input = require "druid.help_modules.druid_input"
|
|
local ui_animate = require "druid.help_modules.druid_animate"
|
|
|
|
M.START = hash("START")
|
|
M.FINISH = hash("FINISH")
|
|
|
|
M.SCROLLING = hash("SCROLLING")
|
|
M.INTEREST_MOVE = hash("INTEREST_MOVE")
|
|
M.OUT_OF_ZONE_MOVE = hash("OUT_OF_ZONE_MOVE")
|
|
|
|
M.BACK_TIME = 0.2
|
|
M.ANIM_TIME = 0.4
|
|
|
|
local function callback(instance, event, type, param)
|
|
if instance.callback then
|
|
instance.callback(instance.parent.parent, event, type, param)
|
|
end
|
|
end
|
|
|
|
local function checkSwipeDirection(swipe, action)
|
|
swipe.xDistance = math.abs(swipe.endX - swipe.beginX)
|
|
swipe.yDistance = math.abs(swipe.endY - swipe.beginY)
|
|
if swipe.is_x and swipe.xDistance > swipe.yDistance then
|
|
if swipe.beginX > swipe.endX then
|
|
swipe.totalSwipeDistanceLeft = swipe.beginX - swipe.endX
|
|
if swipe.totalSwipeDistanceLeft > swipe.minSwipeDistance then
|
|
swipe.speed.x = action.dx * swipe.speed_up_coef.x * swipe.end_move_coef_x
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
else
|
|
swipe.totalSwipeDistanceRight = swipe.endX - swipe.beginX
|
|
if swipe.totalSwipeDistanceRight > swipe.minSwipeDistance then
|
|
swipe.speed.x = action.dx * swipe.speed_up_coef.x * swipe.end_move_coef_x
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
elseif swipe.is_y and swipe.xDistance < swipe.yDistance then
|
|
if swipe.beginY > swipe.endY then
|
|
swipe.totalSwipeDistanceUp = swipe.beginY - swipe.endY
|
|
if swipe.totalSwipeDistanceUp > swipe.minSwipeDistance then
|
|
swipe.speed.y = action.dy * swipe.speed_up_coef.y * swipe.end_move_coef_y
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
else
|
|
swipe.totalSwipeDistanceDown = swipe.endY - swipe.beginY
|
|
if swipe.totalSwipeDistanceDown > swipe.minSwipeDistance then
|
|
swipe.speed.y = action.dy * swipe.speed_up_coef.y * swipe.end_move_coef_y
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function lenght(x1, y1, x2, y2)
|
|
local a, b = x1 - x2, y1 - y2
|
|
return math.sqrt(a * a + b * b)
|
|
end
|
|
|
|
local function back_move(instance)
|
|
if not instance.swipe.end_position_x and not instance.swipe.end_position_y then
|
|
if instance.points_of_interest then
|
|
local min_index, min_lenght = 0, math.huge
|
|
local len
|
|
for k, v in pairs(instance.points_of_interest) do
|
|
len = lenght(instance.pos.x, instance.pos.y, v.x, v.y)
|
|
if len < min_lenght then
|
|
min_lenght = len
|
|
min_index = k
|
|
end
|
|
end
|
|
instance.swipe.speed.x = 0
|
|
instance.swipe.speed.y = 0
|
|
gui.cancel_animation(instance.node, gui.PROP_POSITION)
|
|
instance.swipe.special_move = true
|
|
callback(instance, M.START, M.INTEREST_MOVE, instance.points_of_interest[min_index])
|
|
gui.animate(instance.node, gui.PROP_POSITION, instance.points_of_interest[min_index],
|
|
gui.EASING_LINEAR, M.ANIM_TIME, 0,
|
|
function()
|
|
instance.swipe.special_move = false
|
|
instance.pos.x = instance.points_of_interest[min_index].x
|
|
instance.pos.y = instance.points_of_interest[min_index].y
|
|
callback(instance, M.FINISH, M.SCROLLING, instance.pos)
|
|
callback(instance, M.FINISH, M.INTEREST_MOVE, instance.pos)
|
|
end
|
|
)
|
|
else
|
|
callback(instance, M.FINISH, M.SCROLLING, instance.pos)
|
|
end
|
|
end
|
|
|
|
if instance.swipe.end_position_x then
|
|
local swipe = instance.swipe
|
|
swipe.speed.x = 0
|
|
instance.pos.x = swipe.end_position_x
|
|
swipe.special_move = true
|
|
callback(instance, M.START, M.OUT_OF_ZONE_MOVE, instance.pos)
|
|
gui.animate(instance.node, ui_animate.PROP_POS_X, swipe.end_position_x, gui.EASING_INSINE, M.BACK_TIME, 0,
|
|
function()
|
|
swipe.special_move = false
|
|
callback(instance, M.FINISH, M.SCROLLING, instance.pos)
|
|
callback(instance, M.FINISH, M.OUT_OF_ZONE_MOVE, instance.pos)
|
|
end
|
|
)
|
|
swipe.end_position_x = nil
|
|
end
|
|
if instance.swipe.end_position_y then
|
|
local swipe = instance.swipe
|
|
swipe.speed.y = 0
|
|
instance.pos.y = swipe.end_position_y
|
|
swipe.special_move = true
|
|
callback(instance, M.START, M.OUT_OF_ZONE_MOVE, instance.pos)
|
|
gui.animate(instance.node, ui_animate.PROP_POS_Y, swipe.end_position_y, gui.EASING_INSINE, M.BACK_TIME, 0,
|
|
function()
|
|
swipe.special_move = false
|
|
callback(instance, M.FINISH, M.SCROLLING, instance.pos)
|
|
callback(instance, M.FINISH, M.OUT_OF_ZONE_MOVE, instance.pos)
|
|
end
|
|
)
|
|
swipe.end_position_y = nil
|
|
end
|
|
end
|
|
|
|
--- Set text to text field
|
|
-- @param action_id - input action id
|
|
-- @param action - input action
|
|
function M.on_input(instance, action_id, action)
|
|
if action_id == druid_input.A_CLICK then
|
|
if gui.pick_node(instance.scrolling_zone, action.x, action.y) then
|
|
local swipe = instance.swipe
|
|
if action.pressed then
|
|
swipe.pressed = true
|
|
swipe.beginX = action.x
|
|
swipe.beginY = action.y
|
|
druid_input.is_swipe = false
|
|
swipe.end_move_coef_x = 1
|
|
elseif not action.released and not action.pressed and not swipe.special_move then
|
|
swipe.endX = action.x
|
|
swipe.endY = action.y
|
|
local before = swipe.is_swipe
|
|
swipe.is_swipe = checkSwipeDirection(swipe, action)
|
|
if not before and swipe.is_swipe and not swipe.special_move and not swipe.waiting_for_back_move then
|
|
callback(instance, M.START, M.SCROLLING, instance.pos)
|
|
end
|
|
return swipe.is_swipe or swipe.special_move
|
|
elseif action.released then
|
|
swipe.beginX = 0
|
|
swipe.beginY = 0
|
|
swipe.endX = 0
|
|
swipe.endY = 0
|
|
swipe.pressed = false
|
|
if swipe.waiting_for_back_move then
|
|
back_move(instance)
|
|
swipe.waiting_for_back_move = false
|
|
end
|
|
return swipe.is_swipe or swipe.special_move
|
|
end
|
|
elseif action.released then
|
|
instance.swipe.pressed = false
|
|
if instance.swipe.waiting_for_back_move then
|
|
back_move(instance)
|
|
instance.swipe.waiting_for_back_move = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Called when update
|
|
-- @param dt - delta time
|
|
function M.on_updated(instance, dt)
|
|
if instance.swipe.speed.x ~= 0 or instance.swipe.speed.y ~= 0 then
|
|
local swipe = instance.swipe
|
|
instance.pos.x = instance.pos.x + swipe.speed.x
|
|
instance.pos.y = instance.pos.y + swipe.speed.y
|
|
if instance.pos.x < instance.start_pos.x then
|
|
swipe.end_move_coef_x = swipe.back_slow_coef
|
|
swipe.end_position_x = instance.start_pos.x
|
|
elseif instance.pos.x > instance.maximum.x then
|
|
swipe.end_move_coef_x = swipe.back_slow_coef
|
|
swipe.end_position_x = instance.maximum.x
|
|
else
|
|
swipe.end_move_coef_x = 1
|
|
swipe.end_position_x = nil
|
|
end
|
|
if instance.pos.y < instance.start_pos.y then
|
|
swipe.end_move_coef_y = swipe.back_slow_coef
|
|
swipe.end_position_y = instance.start_pos.y
|
|
elseif instance.pos.y > instance.maximum.y then
|
|
swipe.end_move_coef_y = swipe.back_slow_coef
|
|
swipe.end_position_y = instance.maximum.y
|
|
else
|
|
swipe.end_move_coef_y = 1
|
|
swipe.end_position_y = nil
|
|
end
|
|
gui.set_position(instance.node, instance.pos)
|
|
swipe.speed.x = swipe.speed.x / swipe.speed_down_coef * swipe.end_move_coef_x
|
|
swipe.speed.y = swipe.speed.y / swipe.speed_down_coef * swipe.end_move_coef_y
|
|
if swipe.speed.x < swipe.min_speed and swipe.speed.x > - swipe.min_speed then
|
|
swipe.speed.x = 0
|
|
if not swipe.pressed then
|
|
back_move(instance)
|
|
else
|
|
swipe.waiting_for_back_move = true
|
|
end
|
|
if swipe.speed.y < swipe.min_speed and swipe.speed.y > - swipe.min_speed then
|
|
swipe.speed.y = 0
|
|
end
|
|
if swipe.speed.y == 0 and swipe.speed.x == 0 then
|
|
swipe.is_swipe = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Scroll position to
|
|
-- @param pos - positon for set
|
|
-- @param is_animate - is animated set
|
|
function M.scroll_to(instance, pos, is_animate, cb, time_scrolling)
|
|
local time = is_animate and M.ANIM_TIME or 0
|
|
time = time_scrolling or time
|
|
instance.pos.x = pos.x
|
|
instance.pos.y = pos.y
|
|
gui.animate(instance.node, gui.PROP_POSITION, instance.pos, gui.EASING_INSINE, time, 0,
|
|
function()
|
|
if cb then
|
|
cb(instance.parent.parent)
|
|
end
|
|
end
|
|
)
|
|
end
|
|
|
|
return M
|