Download CommonLua/X/XGesture.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 6.39 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/X/XGesture.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/X/XGesture.lua
-
curl -L -o XGesture.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/X/XGesture.lua
6.39 kB
| if not Platform.switch then return end | |
| DefineClass.XGestureWindow = { | |
| __parents = { "XWindow" }, | |
| gesture_time = 300, | |
| tap_dist = 20*20, -- square of the tap max tap offset | |
| taps = false, | |
| last_gesture = false, | |
| swipe_dist = 50, | |
| } | |
| -- recognised gestures | |
| -- tap - fast press and release without moving | |
| -- swipe - fast move to left, right, top or bottom | |
| -- drag - continuous move | |
| -- parallel tap - tap simultaneously with two fingers | |
| -- pinch/rotation/pan - pres two fingers to zoom, rotate and move | |
| 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 | |
| -- new gesture | |
| 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) | |
| -- offset | |
| self:OnPinchMove((gesture[1].pos - gesture[1].start_pos + gesture[2].pos - gesture[2].start_pos) / 2, gesture) | |
| -- zoom | |
| 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) | |
| -- rotate | |
| 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 | |
| --[[ | |
| function OnMsg.DesktopCreated() | |
| local win = XGestureWindow:new(terminal.desktop) | |
| win:SetPos(point20) | |
| win:SetSize(terminal.desktop:GetSize()) | |
| end | |
| --]] | |