|
if not Platform.switch then return end |
|
|
|
DefineClass.XGestureWindow = { |
|
__parents = { "XWindow" }, |
|
gesture_time = 300, |
|
tap_dist = 20*20, |
|
taps = false, |
|
last_gesture = false, |
|
swipe_dist = 50, |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function XGestureWindow:Init() |
|
self.taps = {} |
|
end |
|
|
|
function XGestureWindow:TapCount(pos) |
|
local time = RealTime() - self.gesture_time |
|
for i = #self.taps, 1, -1 do |
|
local tap = self.taps[i] |
|
if tap.time - time < 0 then |
|
table.remove(self.taps[i]) |
|
else |
|
if pos:Dist2D2(tap.pos) < self.tap_dist then |
|
table.remove(self.taps, i) |
|
return tap.count |
|
end |
|
end |
|
end |
|
return 0 |
|
end |
|
|
|
function XGestureWindow:RegisterTap(pos, count) |
|
self.taps[#self.taps + 1] = { pos = pos, time = RealTime(), count = count } |
|
end |
|
|
|
function XGestureWindow:OnTouchBegan(id, pos, touch) |
|
touch.start_pos = pos |
|
touch.start_time = RealTime() |
|
local gesture = self.last_gesture |
|
if not gesture or gesture.done or #gesture == 2 or RealTime() - gesture.start_time > self.gesture_time then |
|
|
|
gesture = { start_time = RealTime(), start_pos = pos, taps = self:TapCount(pos) + 1 } |
|
self.last_gesture = gesture |
|
CreateRealTimeThread(function() |
|
Sleep(self.gesture_time) |
|
if not gesture.done then |
|
self:GestureTime(gesture) |
|
end |
|
end) |
|
end |
|
touch.gesture = gesture |
|
gesture[#gesture + 1] = touch |
|
self:GestureTouch(gesture, touch) |
|
return "break" |
|
end |
|
|
|
function XGestureWindow:OnTouchMoved(id, pos, touch) |
|
local gesture = touch.gesture |
|
if gesture then |
|
self:GestureMove(gesture, touch) |
|
end |
|
return "break" |
|
end |
|
|
|
function XGestureWindow:OnTouchEnded(id, pos, touch) |
|
local gesture = touch.gesture |
|
if gesture then |
|
self:GestureRelease(gesture, touch) |
|
end |
|
return "break" |
|
end |
|
|
|
function XGestureWindow:OnTouchCancelled(id, pos, touch) |
|
local gesture = touch.gesture |
|
if gesture then |
|
self:GestureRelease(gesture, touch) |
|
end |
|
return "break" |
|
end |
|
|
|
function XGestureWindow:GestureTouch(gesture, touch) |
|
if #gesture == 2 then |
|
if gesture.type == "drag" then |
|
self:OnDragStop(gesture[1].start_pos, gesture) |
|
gesture.type = "pinch" |
|
self:OnPinchStart((gesture[1].start_pos + gesture[2].start_pos) / 2, gesture) |
|
self:UpdatePinch(gesture) |
|
end |
|
end |
|
end |
|
|
|
function XGestureWindow:GestureTime(gesture) |
|
if #gesture == 1 and not gesture.type then |
|
gesture.type = "drag" |
|
self:OnDragStart(gesture[1].start_pos, gesture) |
|
end |
|
end |
|
|
|
function XGestureWindow:GestureMove(gesture, touch) |
|
local tap = touch.start_pos:Dist2D2(touch.pos) < self.tap_dist |
|
if #gesture == 1 then |
|
if gesture.type == "drag" then |
|
self:OnDragMove(touch.pos, gesture) |
|
elseif not tap and not gesture.type then |
|
gesture.type = "drag" |
|
self:OnDragStart(gesture.start_pos, gesture) |
|
end |
|
elseif #gesture == 2 and not tap then |
|
if gesture.type ~= "pinch" then |
|
gesture.type = "pinch" |
|
self:OnPinchStart((gesture[1].start_pos + gesture[2].start_pos) / 2, gesture) |
|
end |
|
self:UpdatePinch(gesture) |
|
end |
|
end |
|
|
|
function XGestureWindow:GestureRelease(gesture, touch) |
|
local tap = touch.start_pos:Dist2D2(touch.pos) < self.tap_dist |
|
gesture.done = true |
|
if #gesture == 1 then |
|
if gesture.type == "drag" then |
|
self:OnDragEnd(touch.pos, gesture) |
|
return |
|
end |
|
assert(RealTime() - gesture.start_time < self.gesture_time and tap) |
|
self:RegisterTap(touch.pos, gesture.taps) |
|
self:OnTap(touch.pos, gesture) |
|
elseif #gesture == 2 then |
|
if gesture.type == "pinch" then |
|
self:UpdatePinch(gesture) |
|
self:OnPinchEnd(gesture) |
|
end |
|
if RealTime() - gesture.start_time < self.gesture_time and tap then |
|
self:OnParallelTap(gesture) |
|
end |
|
end |
|
end |
|
|
|
function XGestureWindow:UpdatePinch(gesture) |
|
|
|
self:OnPinchMove((gesture[1].pos - gesture[1].start_pos + gesture[2].pos - gesture[2].start_pos) / 2, gesture) |
|
|
|
gesture.start_dist = gesture.start_dist or (gesture[1].start_pos:Dist2D(gesture[2].start_pos)) |
|
self:OnPinchZoom(gesture[1].pos:Dist2D(gesture[2].pos) * 1000 / gesture.start_dist, gesture) |
|
|
|
self:OnPinchRotate(CalcAngleBetween2D( |
|
gesture[1].start_pos - gesture[2].start_pos, |
|
gesture[1].pos - gesture[2].pos |
|
), gesture) |
|
end |
|
|
|
|
|
function XGestureWindow:OnTap(pos, gesture) |
|
print("tap", pos, gesture.taps) |
|
end |
|
|
|
function XGestureWindow:OnDragStart(pos, gesture) |
|
end |
|
|
|
function XGestureWindow:OnDragMove(pos, gesture) |
|
local offset = pos - gesture[1].start_pos |
|
if gesture.swipe then |
|
if gesture.swipe == "h" then |
|
self:OnHSwipeUpdate(offset:x(), gesture) |
|
end |
|
if gesture.swipe == "v" then |
|
self:OnVSwipeUpdate(offset:y(), gesture) |
|
end |
|
else |
|
if abs(offset:x()) > self.swipe_dist then |
|
gesture.swipe = "h" |
|
self:OnHSwipeStart(offset:x(), gesture) |
|
elseif abs(offset:y()) > self.swipe_dist then |
|
gesture.swipe = "v" |
|
self:OnVSwipeStart(offset:y(), gesture) |
|
end |
|
end |
|
end |
|
|
|
function XGestureWindow:OnDragEnd(pos, gesture) |
|
local offset = pos - gesture[1].start_pos |
|
if gesture.swipe then |
|
if gesture.swipe == "h" then |
|
self:OnHSwipeEnd(offset:x(), gesture, offset:x() * 1000 / (RealTime() - gesture.start_time + 1)) |
|
end |
|
if gesture.swipe == "v" then |
|
self:OnVSwipeEnd(offset:y(), gesture, offset:y() * 1000 / (RealTime() - gesture.start_time + 1)) |
|
end |
|
end |
|
end |
|
|
|
function XGestureWindow:OnHSwipeStart(offs, gesture) |
|
end |
|
|
|
function XGestureWindow:OnHSwipeUpdate(offs, gesture) |
|
end |
|
|
|
function XGestureWindow:OnHSwipeEnd(offs, gesture) |
|
end |
|
|
|
function XGestureWindow:OnVSwipeStart(offs, gesture) |
|
end |
|
|
|
function XGestureWindow:OnVSwipeUpdate(offs, gesture) |
|
end |
|
|
|
function XGestureWindow:OnVSwipeEnd(offs, gesture) |
|
end |
|
|
|
function XGestureWindow:OnParallelTap(gesture) |
|
print("parallel tap", gesture[1].pos) |
|
end |
|
|
|
function XGestureWindow:OnPinchStart(gesture) |
|
print("pinch start") |
|
end |
|
|
|
function XGestureWindow:OnPinchMove(offset, gesture) |
|
print("move", offset) |
|
end |
|
|
|
function XGestureWindow:OnPinchZoom(zoom, gesture) |
|
print("zoom", zoom) |
|
end |
|
|
|
function XGestureWindow:OnPinchRotate(angle, gesture) |
|
print("rotate", angle) |
|
end |
|
|
|
function XGestureWindow:OnPinchEnd(gesture) |
|
print("pinch end") |
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|