@ -722,6 +722,13 @@ function Contact:panState(keep_contact)
-- Only accept gestures that require both contacts to have been lifted
if ges_ev.ges == " two_finger_pan " then
ges_ev.ges = " two_finger_swipe "
-- Swap from pan semantics to swipe semantics
ges_ev.pos = ges_ev._start_pos
ges_ev._start_pos = nil
ges_ev.start_pos = nil
ges_ev.end_pos = ges_ev._end_pos
ges_ev._end_pos = nil
ges_ev.relative = nil
elseif ges_ev.ges == " inward_pan " then
ges_ev.ges = " pinch "
elseif ges_ev.ges == " outward_pan " then
@ -873,6 +880,12 @@ function Contact:handleSwipe()
w = 0 ,
h = 0 ,
}
local end_pos = Geom : new {
x = tev.x ,
y = tev.y ,
w = 0 ,
h = 0 ,
}
local ges = " swipe "
local multiswipe_directions
@ -893,8 +906,13 @@ function Contact:handleSwipe()
gesture_detector : dropContact ( self )
return {
ges = ges ,
-- use first pan tev coordination as swipe start point
-- NOTE: Unlike every other gesture, we use the *contact* point as the gesture's position,
-- instead of the *lift* point, mainly because that's what makes the most sense
-- from a hit-detection standpoint (c.f., `GestureRange:match` & `InputContainer:onGesture`),
-- and that's 99% of the use-cases where the position actually matters for a swipe.
pos = start_pos ,
-- And for those rare cases that need it, we provide the lift point separately.
end_pos = end_pos ,
direction = swipe_direction ,
multiswipe_directions = multiswipe_directions ,
distance = swipe_distance ,
@ -932,27 +950,26 @@ function Contact:handlePan()
local pan_ev = {
ges = " pan " ,
relative = {
-- default to pan 0
x = 0 ,
y = 0 ,
x = tev.x - self.initial_tev . x ,
y = tev.y - self.initial_tev . y ,
} ,
start_pos = Geom : new {
x = self.initial_tev . x ,
y = self.initial_tev . y ,
w = 0 ,
h = 0 ,
} ,
pos = Geom : new {
x = tev.x ,
y = tev.y ,
w = 0 ,
h = 0 ,
} ,
pos = nil ,
direction = pan_direction ,
distance = pan_distance ,
time = tev.timev ,
}
-- Regular pan
pan_ev.relative . x = tev.x - self.initial_tev . x
pan_ev.relative . y = tev.y - self.initial_tev . y
pan_ev.pos = Geom : new {
x = tev.x ,
y = tev.y ,
w = 0 ,
h = 0 ,
}
local msd_cnt = # self.multiswipe_directions
local msd_direction_prev = ( msd_cnt > 0 ) and self.multiswipe_directions [ msd_cnt ] [ 1 ] or " "
local prev_ms_ev , fake_initial_tev
@ -1070,9 +1087,21 @@ function Contact:handleTwoFingerPan(buddy_contact)
-- We'll also want to remember the span between both contacts on start & end for some gestures
local start_distance = tstart_pos : distance ( rstart_pos )
local end_distance = tend_pos : distance ( rend_pos )
-- NOTE: "pan" and "hold_pan" use the current/end point as pos,
-- but swipe reports pos as the *starting* point (c.f., `Contact:handleSwipe`).
-- Since this table will be used for both pans and two_finger_swipe (via panState),
-- we stuff a bunch of extra info in there to swap it around as-needed...
local ges_ev = {
ges = " two_finger_pan " ,
pos = start_point ,
relative = {
x = end_point.x - start_point.x ,
y = end_point.y - start_point.y ,
} ,
-- Default to the pan semantics, c.f., note above
pos = end_point ,
start_pos = start_point ,
_start_pos = start_point ,
_end_pos = end_point ,
distance = avg_distance ,
direction = tpan_dir ,
time = self.current_tev . timev ,
@ -1080,8 +1109,18 @@ function Contact:handleTwoFingerPan(buddy_contact)
if tpan_dir ~= rpan_dir then
if start_distance > end_distance then
ges_ev.ges = " inward_pan "
-- Use the end pos (this is the default already)
ges_ev._start_pos = nil
ges_ev._end_pos = nil
else
ges_ev.ges = " outward_pan "
-- Use the start pos, it'll make more sense than the midpoint of the current contacts,
-- given the potentially wide span between the two...
ges_ev.pos = ges_ev._start_pos
ges_ev._start_pos = nil
ges_ev.start_pos = nil
ges_ev.end_pos = ges_ev._end_pos
ges_ev._end_pos = nil
end
ges_ev.direction = gesture_detector.DIRECTION_TABLE [ tpan_dir ]
-- Use the the sum of both contacts' travel for the distance
@ -1089,6 +1128,8 @@ function Contact:handleTwoFingerPan(buddy_contact)
-- Some handlers might also want to know the distance between the two contacts on lift & down.
ges_ev.span = end_distance
ges_ev.start_span = start_distance
-- Drop unnecessary field
ges_ev.relative = nil
elseif self.state == Contact.holdState then
ges_ev.ges = " two_finger_hold_pan "
-- Flag 'em for holdState to discriminate with two_finger_hold_release
@ -1130,6 +1171,14 @@ function Contact:handlePanRelease(keep_contact)
logger.dbg ( " Contact:handlePanRelease: two_finger_pan_release detected " )
pan_ev.ges = " two_finger_pan_release "
-- The pan itself used the midpoint between the two contacts, keep doing that.
local buddy_pos = Geom : new {
x = buddy_contact.current_tev . x ,
y = buddy_contact.current_tev . y ,
w = 0 ,
h = 0 ,
}
pan_ev.pos = release_pos : midpoint ( buddy_pos )
-- Don't drop buddy, voidState will handle it
-- NOTE: This is yet another rotate hack, emanating from voidState into panState.
if not keep_contact then