forked from cloudwu/deepfuture
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtouch.lua
More file actions
216 lines (200 loc) · 4.56 KB
/
touch.lua
File metadata and controls
216 lines (200 loc) · 4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
local mouse = require "core.mouse"
local TOUCH_LONG_PRESS_FRAMES <const> = 18
local TOUCH_MOVE_THRESHOLD2 <const> = 12 * 12
-- Regions that require a confirmation tap.
local DOUBLE_TAP_REGIONS <const> = {
hand = true,
neutral = true,
homeworld = true,
colony = true,
discard = true,
deck = true,
card = true,
}
local REGION_CONFIRM_DOUBLE <const> = {
deck = true,
}
local touch = {}
local current_frame = 0
local pending_clear_focus
local function dist2(x1, y1, x2, y2)
local dx = x1 - x2
local dy = y1 - y2
return dx * dx + dy * dy
end
local state = {
active = false,
pressing = false,
double_candidate = false,
require_double = false,
moved = false,
start_frame = 0,
start_x = 0,
start_y = 0,
x = 0,
y = 0,
}
local last_tap = {
require_double = false,
object = nil,
region = nil,
x = 0,
y = 0,
}
local function clear_last_tap()
last_tap.require_double = false
last_tap.object = nil
last_tap.region = nil
last_tap.x = 0
last_tap.y = 0
end
local function store_last_tap(focus_object, region, x, y)
if focus_object then
last_tap.require_double = true
last_tap.object = focus_object
last_tap.region = region
last_tap.x = x
last_tap.y = y
return true
end
if region and REGION_CONFIRM_DOUBLE[region] then
last_tap.require_double = true
last_tap.object = nil
last_tap.region = region
last_tap.x = x
last_tap.y = y
return true
end
clear_last_tap()
end
local function reset_state()
state.active = false
state.pressing = false
state.double_candidate = false
state.require_double = false
state.moved = false
state.start_frame = 0
state.start_x = 0
state.start_y = 0
state.x = 0
state.y = 0
end
local function apply_press()
if state.pressing then
return
end
mouse.mouse_button("left", true)
state.pressing = true
state.double_candidate = false
clear_last_tap()
end
function touch.begin(x, y)
mouse.mouse_move(x, y)
state.active = true
state.pressing = false
state.moved = false
state.start_frame = current_frame
state.start_x = x
state.start_y = y
state.x = x
state.y = y
state.double_candidate = false
state.require_double = false
local region = mouse.focus_region()
if region and DOUBLE_TAP_REGIONS[region] then
state.require_double = true
end
if last_tap.require_double then
local focus_object = mouse.focus_object()
local same_object = focus_object and focus_object == last_tap.object
local same_region = (focus_object == nil and last_tap.object == nil and region ~= nil and REGION_CONFIRM_DOUBLE[region] and region == last_tap.region)
if same_object or same_region then
state.double_candidate = true
else
clear_last_tap()
end
end
end
function touch.moved(x, y)
mouse.mouse_move(x, y)
state.x = x
state.y = y
if not state.active then
return
end
if not state.moved and dist2(x, y, state.start_x, state.start_y) > TOUCH_MOVE_THRESHOLD2 then
state.moved = true
state.double_candidate = false
end
end
function touch.ended(x, y)
mouse.mouse_move(x, y)
state.x = x
state.y = y
local region = mouse.focus_region()
if state.pressing then
mouse.mouse_button("left", false)
clear_last_tap()
reset_state()
return
end
if state.active then
if not state.moved then
if state.require_double then
if state.double_candidate then
mouse.mouse_button("left", true)
mouse.mouse_button("left", false)
clear_last_tap()
pending_clear_focus = true
else
local focus_object = mouse.focus_object()
if not store_last_tap(focus_object, region, state.x, state.y) then
reset_state()
return
end
end
else
mouse.mouse_button("left", true)
mouse.mouse_button("left", false)
clear_last_tap()
end
else
clear_last_tap()
end
end
reset_state()
end
function touch.update(frame)
current_frame = frame
if pending_clear_focus then
mouse.mouse_move(0, 0)
pending_clear_focus = nil
end
if not state.active then
return
end
local region = mouse.focus_region()
local need_double = region and DOUBLE_TAP_REGIONS[region] or false
state.require_double = need_double
if need_double then
local candidate = false
if last_tap.require_double then
local focus_object = mouse.focus_object()
if focus_object and focus_object == last_tap.object then
candidate = true
elseif focus_object == nil and last_tap.object == nil and REGION_CONFIRM_DOUBLE[region] and region == last_tap.region then
candidate = true
end
end
state.double_candidate = candidate
else
state.double_candidate = false
end
if state.pressing or state.moved then
return
end
if frame - state.start_frame >= TOUCH_LONG_PRESS_FRAMES then
apply_press()
end
end
return touch