Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Help with SODA

Hi, i've been using soda to develop an app, but for some reason i don't know how to handle the touch events in the library, if someone could be so kind to teach me how to implement them
here are the ones that i want to use

-- zoom gesture
function Sensor:onZoom(callback)
    self:register("onZoom", self.zoomUpdate, callback)
end
-- zoom is complex because we need to manage 2 touches that begin inside the object, and no more
function Sensor.zoomUpdate(event,self,t,tpos)
    event.touches = event.touches or {} -- init table
    local touches = event.touches
    local t1 = touches[1]
    local t2 = touches[2]
    if t.state == BEGAN then -- a new finger has come, remember it
        if #touches >= 2 then
            -- this is a 3rd finger, dont use it
        else
            -- register this touch and reset
            table.insert(touches,t)
        end
    elseif t.state == MOVING then 
        -- this is a zoom, if we have exactly 2 touches and t is one of them
        if t1 and t2 and ( t1.id == t.id or t2.id == t.id ) then 
            local tm,ts -- m moving, s static
            if t1.id == t.id 
            then touches[1]=t ; tm = t ; ts = t2
            else touches[2]=t ; tm = t ; ts = t1
            end
            -- convert deltaX and deltaY into a variation in width and height (dw and dh)
            local dw,dh
            if tm.x>ts.x 
            then dw = tm.deltaX
            else dw = - tm.deltaX
            end
            if tm.y>ts.y
            then dh = tm.deltaY
            else dh = - tm.deltaY
            end
            -- store the information in event, then fire callback
            event.dw = dw
            event.dh = dh
            event:callback()
        end
    else
        -- when a finger is gone, remove it from the table of touches
        if t1 and t1.id == t.id then table.remove(touches,1) end
        if t2 and t2.id == t.id then table.remove(touches,2) end
    end
end

-- drag gesture
function Sensor:onDrag(callback)
    self:register("onDrag", self.dragUpdate, callback)
end
-- just echo the touch data and position via the callback
function Sensor.dragUpdate(event,self,t,tpos)
    if self.touches[t.id] then
        -- integrate finger movement (can be used as a threshold)
        if t.state == BEGAN then
            event.totalMove = 0
            event.startTime = ElapsedTime
        elseif t.state == MOVING then
            event.totalMove = event.totalMove + abs(t.deltaX) + abs(t.deltaY)
        end
        event.touch = t
        event.tpos = tpos
        event:callback()
    end
end

-- drop gesture
function Sensor:onDrop(callback)
    self:register("onDrop", self.dropUpdate, callback)
end
-- drop occurs when the finger is lifted from the screen (ENDED)
-- but it is complex because you want to detect 2 objects: 
--      the object that is dropped
--      the object that receive the drop
-- register both objects with onDrop, and appropriate callbacks
local droppedObject, droppedTime
function Sensor.dropUpdate(event,self,t,tpos)
    if self:inbox(tpos) and t.state == ENDED then
        -- this is a 2 branches mechanism, so 2 objects can have the onDrop, but we need to
        -- differenciate the 1rst one (dropped) from the second one (receiving the drop)
        if droppedTime ~= ElapsedTime then
            droppedTime = ElapsedTime   -- so next object will go to the other branch
            droppedObject = self.parent
            self.doNotInterceptOnce = true
        else
            event.object = droppedObject
            event:callback()
        end
    end
end

-- touched gesture (this is like CODEA touched function)
function Sensor:onTouched(callback)
    self:register("onTouched", self.touchedUpdate, callback)
end
function Sensor.touchedUpdate(event,self,t,tpos)
    if self.touches[t.id] or self:inbox(tpos) then 
        event.touch = t
        event.tpos = tpos
        event:callback()
    end
end

-- touch gesture
function Sensor:onTouch(callback)
    self:register("onTouch", self.touchUpdate, callback)
end
function Sensor.touchUpdate(event,self,t,tpos)
    self.touching = self.touching or {} -- track touches, not only BEGAN
    -- current touch
    if self:inbox(tpos) then 
        if t.state == BEGAN then 
            event.t0 = ElapsedTime
        end
        if t.state == BEGAN or t.state == MOVING then 
            self.touching[t.id] = true -- this is touching
        else
            self.touching[t.id] = nil -- this is not
        end
    else
        self.touching[t.id] = nil 
    end
    -- final state
    local state1 = false -- one touch is enough to be touched
    for i,t in pairs(self.touching) do state1= true ; break end
    --if state has changed, send callback
    if state1 ~= event.state then
        event.state = state1
        event.touch = t
        event.tpos = tpos
        event:callback()
    end
end

Sign In or Register to comment.