Skip to content

Instantly share code, notes, and snippets.

@Vavius
Created July 10, 2013 08:05
Show Gist options
  • Save Vavius/5964336 to your computer and use it in GitHub Desktop.
Save Vavius/5964336 to your computer and use it in GitHub Desktop.
Another variant of TouchHandler. Sends touch events to all props under touch location. Also, it supports perspective 3d-view camera for layer. SwallowTouch method is designed to send cancel events to all touched props except the passed one. Used when we touched button and scrolled away to cancel button selected state.
--------------------------------------------------------------------------------
-- Event handler when you touch a layer.
-- @param e Event object
--------------------------------------------------------------------------------
local TMP_TABLE = {}
function TouchHandler:onTouch(e)
if not self.touchLayer.touchEnabled then
return
end
-- props that have received down event before, but thay can be out of raycast check now
local touchProps = self.touchProps[e.idx]
table.removeAllElements(TMP_TABLE)
-- screen to world location.
local props = self:getTouchableProps(e)
-- touch event
local e2 = table.copy(e, self.TOUCH_EVENT)
-- dispatch event
local prop
for i = #props, 1, -1 do
prop = props[i]
if e.type == Event.TOUCH_DOWN then
if not touchProps then
touchProps = {}
self.touchProps[e.idx] = touchProps
end
table.insert(touchProps, prop)
end
TMP_TABLE[prop] = true
e2.prop = prop
self:dispatchTouchEvent(e2, prop)
if e2.stopFlag then
e:stop()
break
end
end
if e.type ~= Event.TOUCH_DOWN and touchProps then
for k, prop2 in pairs(touchProps) do
if not TMP_TABLE[prop2] then
e2.prop = prop2
self:dispatchTouchEvent(e2, prop2)
if e.type == Event.TOUCH_UP or e.type == Event.TOUCH_CANCEL then
touchProps[k] = nil
end
if e2.stopFlag then
e:stop()
break
end
end
end
end
end
function TouchHandler:getTouchableProps(e)
local layer = self.touchLayer
local partition = layer:getPartition()
local sortMode = layer:getSortMode()
local props
if not layer.perspective then
props = {partition:propListForPoint(e.wx, e.wy, 0, sortMode)}
else
props = {partition:propListForRay(e.wx, e.wy, e.wz, e.xn, e.yn, e.zn, sortMode)}
end
for i = #props, 1, -1 do
local prop = props[i]
if prop:getAttr(MOAIProp.ATTR_VISIBLE) == 0 or prop.disableTouch then
table.remove(props, i)
end
-- if prop:getAttr(MOAIProp.ATTR_VISIBLE) > 0 then
-- return prop
-- end
end
return props
end
function TouchHandler:swallowTouch(prop, e)
-- Send cancel event to current active prop.
local propList = self.touchProps[e.idx]
if not propList then
return
end
for k, prop2 in pairs(propList) do
if prop2 ~= prop then
local e2 = table.copy(e, Event())
e2.type = Event.TOUCH_CANCEL
e2.prop = prop2
self:dispatchTouchEvent(e2, prop2)
propList[k] = nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment