Event.phase == "cancelled" NOT working [SAMPLE CODE INCLUDED]

Hello, here’s the code ( you can put it into a main.lua and it should work… )

local physics = require("physics") physics.start() ------------------------------------------------------------------------------------------------------------ local touchLeft = display.newRect( display.contentCenterX - 79.8, display.contentCenterY, 160, 570 ) touchLeft.alpha = 0.2 ------------------------------------------------------------------------------------------------------------ local stopBoxLeft = display.newRect( -3, display.contentCenterY, 5, 40 ) physics.addBody( stopBoxLeft, "static", { bounce = 0 }) stopBoxLeft.isSleepingAllowed = false ------------------------------------------------------------------------------------------------------------ local stopBoxRight = display.newRect( 323, display.contentCenterY, 5, 40 ) physics.addBody( stopBoxRight, "static", { bounce = 0 }) stopBoxRight.isSleepingAllowed = false ------------------------------------------------------------------------------------------------------------ local boxLeft = display.newRect( 15, display.contentCenterY, 30, 30 ) boxLeft:setFillColor( 1, 0, 0 ) physics.addBody( boxLeft, "dynamic", { bounce = 0 } ) boxLeft.gravityScale = 0 boxLeft.myName = "boxLeft" boxLeft.isSleepingAllowed = false ------------------------------------------------------------------------------------------------------------ local function moveLeftToRight(event) if event.phase == "began" then boxLeft:setLinearVelocity( 200, 0 ) elseif event.phase == "ended" then boxLeft:setLinearVelocity( -200, 0 ) elseif event.phase == "cancelled" then boxLeft:setLinearVelocity( -200, 0 ) end end touchLeft:addEventListener( "touch", moveLeftToRight ) ------------------------------------------------------------------------------------------------------------

So when you touch the faded white on the left then the box moves to the right and when you let go then it goes back to the left… But if you touch the left and slide your finger to the right then cancelled phase doesnt get called… Any ideas why? Thanks!!

Hi @SonicX278,

See this document for the difference between “ended” and “cancelled”:

https://docs.coronalabs.com/api/event/touch/phase.html

Brent

I’ve looked at that and doesn’t let me use multitouch… And also the cancelled phase doesn’t work…

What ive tried is this ( Code can be tested in any main.lua file. )

local touchLeft = display.newRect( display.contentCenterX - 125, display.contentCenterY, 70, 50 ) touchLeft:setFillColor( 1, 0, 0 ) touchLeft.alpha = 0.2 touchLeft.isSleepingAllowed = false function touchLeft:touch( event ) if event.phase == "began" then --------------- print("began") --------------- display.getCurrentStage():setFocus( self ) self.isFocus = true --------------- elseif self.isFocus then if event.phase == "moved" then elseif event.phase == "ended" or event.phase == "cancelled" then if event.phase == "cancelled" then --------------- print("cancelled") --------------- elseif event.phase == "ended" then --------------- print("ended") --------------- end display.getCurrentStage():setFocus( nil ) self.isFocus = false end end return true end touchLeft:addEventListener( "touch", touchLeft )

So when i press on the touchLeft then the began phase fires… But if i press and slide off the touchLeft the cancelled phase doesn’t fire… I cant see what i’m doing wrong…

Thanks!

Hi again,

As noted in that document, the “cancelled” phase is only triggered by the OS/system, and it’s uncommon. That’s why most code examples show both the “ended” and “cancelled” phases being handled by one combined conditional block.

Brent

Ohh i understand… So is is possible to fix my problem then?(reference back to the latest code example I posted)

Thanks!

i haven’t run your code, but sounds like you’re looking for a (pseudo) “leave” phase, right?

if so, you gotta do it yourself:  during the move phase while focused you’ll need to compare the event’s xy against the rect’s contentBounds, and if they leave those bounds while focused, then unfocus the button for that event

…or leave the focus, but track the entered state…  your particular use will determine if you want to ignore the event for good on leave, requiring a new touch to resume interaction, or if you want to keep the event alive and just suspend reacting to it until you detect a (pseudo) “enter” phase as well (touch, drag off, then drag back on prior to release, reactivating)  same sort of code to do that, just organized a bit differently (you can effectively remain “focused”, but not “entered” – you only actually REACT when BOTH focused and entered)

this gets much harder with multitouch.  imagine a two-fingered touch of a single button, then drag entire hand both fingers together, one’s eventid will probably leave before the other (which might not leave at all).  a simple QA test is:  two non-simultaneous presses of a single button - what if first touch down is last touch up?  did your button behave properly after second touch ended?  (while first touch still down)  if you want your interface to “not suck” then you should work on handling all of the above PER eventid.

fwiw, hth

Thanks for the suggestions guys!

Well it hit me in the head today that all i need it to be is just a button that fires a function!

So i used widget.newButton and that worked perfect!!

The problem i was having was when i pressed on btn1 and then then dragged my finger to btn2 and let go it never called the ended phase for btn1 and then it doesn’t call the began phase for btn2 but calls the ended phase for btn2.

But the widget fixed that issue! Now im back on track!! 

Thanks!

To be clear: touch phases do not happen for buttons. They happen for touches. If a touch starts on button1 and moves to button2, it is good to realise that neither button1 nor button2 will get an “ended” or “cancelled” phase: it is the TOUCH that will get an event phase.

If i press on btn1 and slide my finger off to anywhere and let go it wont call the ended phase but it will call the cancelled phase…

-SonicX278

Hi @SonicX278,

See this document for the difference between “ended” and “cancelled”:

https://docs.coronalabs.com/api/event/touch/phase.html

Brent

I’ve looked at that and doesn’t let me use multitouch… And also the cancelled phase doesn’t work…

What ive tried is this ( Code can be tested in any main.lua file. )

local touchLeft = display.newRect( display.contentCenterX - 125, display.contentCenterY, 70, 50 ) touchLeft:setFillColor( 1, 0, 0 ) touchLeft.alpha = 0.2 touchLeft.isSleepingAllowed = false function touchLeft:touch( event ) if event.phase == "began" then --------------- print("began") --------------- display.getCurrentStage():setFocus( self ) self.isFocus = true --------------- elseif self.isFocus then if event.phase == "moved" then elseif event.phase == "ended" or event.phase == "cancelled" then if event.phase == "cancelled" then --------------- print("cancelled") --------------- elseif event.phase == "ended" then --------------- print("ended") --------------- end display.getCurrentStage():setFocus( nil ) self.isFocus = false end end return true end touchLeft:addEventListener( "touch", touchLeft )

So when i press on the touchLeft then the began phase fires… But if i press and slide off the touchLeft the cancelled phase doesn’t fire… I cant see what i’m doing wrong…

Thanks!

Hi again,

As noted in that document, the “cancelled” phase is only triggered by the OS/system, and it’s uncommon. That’s why most code examples show both the “ended” and “cancelled” phases being handled by one combined conditional block.

Brent

Ohh i understand… So is is possible to fix my problem then?(reference back to the latest code example I posted)

Thanks!

i haven’t run your code, but sounds like you’re looking for a (pseudo) “leave” phase, right?

if so, you gotta do it yourself:  during the move phase while focused you’ll need to compare the event’s xy against the rect’s contentBounds, and if they leave those bounds while focused, then unfocus the button for that event

…or leave the focus, but track the entered state…  your particular use will determine if you want to ignore the event for good on leave, requiring a new touch to resume interaction, or if you want to keep the event alive and just suspend reacting to it until you detect a (pseudo) “enter” phase as well (touch, drag off, then drag back on prior to release, reactivating)  same sort of code to do that, just organized a bit differently (you can effectively remain “focused”, but not “entered” – you only actually REACT when BOTH focused and entered)

this gets much harder with multitouch.  imagine a two-fingered touch of a single button, then drag entire hand both fingers together, one’s eventid will probably leave before the other (which might not leave at all).  a simple QA test is:  two non-simultaneous presses of a single button - what if first touch down is last touch up?  did your button behave properly after second touch ended?  (while first touch still down)  if you want your interface to “not suck” then you should work on handling all of the above PER eventid.

fwiw, hth

Thanks for the suggestions guys!

Well it hit me in the head today that all i need it to be is just a button that fires a function!

So i used widget.newButton and that worked perfect!!

The problem i was having was when i pressed on btn1 and then then dragged my finger to btn2 and let go it never called the ended phase for btn1 and then it doesn’t call the began phase for btn2 but calls the ended phase for btn2.

But the widget fixed that issue! Now im back on track!! 

Thanks!

To be clear: touch phases do not happen for buttons. They happen for touches. If a touch starts on button1 and moves to button2, it is good to realise that neither button1 nor button2 will get an “ended” or “cancelled” phase: it is the TOUCH that will get an event phase.

If i press on btn1 and slide my finger off to anywhere and let go it wont call the ended phase but it will call the cancelled phase…

-SonicX278