onRelease not working when user release outside the button clicked

I saw a similar issue at http://developer.anscamobile.com/forum/2010/04/12/detecting-canceled-button-press but their solution does not helped me to solve my situation. Is it a bug?
Alex [import]uid: 4883 topic_id: 1012 reply_id: 301012[/import]

I suggest using the ui.lua library and ui.newButton.

If you want to do something immediately when the user clicks, then use the “press” event. If you want to do something when the user correctly releases the button when their finger is on the button, then use the “release” event.

The rest you don’t need to worry about for normal buttons.

A lot depends on the context of what you’re doing, providing more information and/or some code would be a big help. [import]uid: 5659 topic_id: 1012 reply_id: 2465[/import]

I am using ui.lua library. My situation is the following:

  1. I have an invisible button positioned on top of a string (button name, optimized for localization). the string color is black
  2. when user click the button, it is changing color to blue (working perfectly on Press and Release, as defined by ui.lua). the Press code changes the string color to white.
  3. when I release the button (if i am on top of it), button return to invisible (as expected) and text color returns to black
  4. problem is when I release the button out of it. button return to invisible but text keeps white (the Release function is not executing). [import]uid: 4883 topic_id: 1012 reply_id: 2470[/import]

Catch the “cancelled” event.

Scott [import]uid: 5659 topic_id: 1012 reply_id: 2473[/import]

Basically copy the ui class and alter for how you want your button to be setup, see how it lets you fire functions at different states of the button, thats where you need to add the code to fire the events you desire

ui.lua is a file included with the download to help you setup buttons [import]uid: 5354 topic_id: 1012 reply_id: 2490[/import]

Scott and Matthew are correct – what you want to do is get the “cancelled” event and do something (change the text color), but probably not the same thing as you want to do on the release event (change the text color + some other action).

Let us know if you need more help with this! As a quick fix, I believe you can go into ui.lua and change this code:

if isWithinBounds then  
 if onEvent then  
 buttonEvent.phase = "release"  
 result = onEvent( buttonEvent )  
 end  
end  

to this code:

if isWithinBounds then  
 if onEvent then  
 buttonEvent.phase = "release"  
 result = onEvent( buttonEvent )  
 end  
else  
 if onEvent then  
 buttonEvent.phase = "cancelled"  
 result = onEvent( buttonEvent )  
 end  
end  

…and then you should get an additional event with a phase of “cancelled” that you can handle as you like.
[import]uid: 3007 topic_id: 1012 reply_id: 2541[/import]

is ansca adding release/releaseOutside phase to the api? or shall we just use the UI class?

please could you expand on that fix… i can’t get it working. i added in some code to check when the release is outside the button , but my event.target ended up being nil

this seemed to work though… although i’m not sure when cancelled is triggered because i wont be picking it up

[lua]…
local onReleaseOutside = self._onReleaseOutside

elseif “ended” == phase or “cancelled” == phase then
if over then
default.isVisible = true
over.isVisible = false
end

if “ended” == phase then
– Only consider this a “click” if the user lifts their finger inside button’s stageBounds
if isWithinBounds then
if onEvent then
buttonEvent.phase = “release”
result = onEvent( buttonEvent )
elseif onRelease then
result = onRelease( event )
end
else
result = onReleaseOutside(event)
end
end

– Allow touch events to be sent normally to the objects they “hit”
display.getCurrentStage():setFocus( self, nil )
self.isFocus = false
end

if ( params.onReleaseOutside and ( type(params.onReleaseOutside) == “function” ) ) then
button._onReleaseOutside = params.onReleaseOutside
end
…[/lua]

to test click the button, drag the mouse, then let go outside of the button
(dont forget to add an onReleaseOutside definition in your ui.newButton call)

thanks
j [import]uid: 6645 topic_id: 1012 reply_id: 10813[/import]

I have the same problem with my buttons. Tried your solution but only get this:

  
Runtime error  
 ...sers/xxxxx/Desktop/apdev/game/ui.lua:100: attempt to call local 'onReleaseOutside' (a nil value)  
  

What to do? [import]uid: 28895 topic_id: 1012 reply_id: 24637[/import]

My temporary solution works for what I’m doing while i wait for a solid solution from you pros. :slight_smile:

ui.lua :

if "ended" == phase then if onEvent then buttonEvent.phase = "release" result = onEvent( buttonEvent ) elseif onRelease then result = onRelease( event ) end end [import]uid: 28895 topic_id: 1012 reply_id: 24639[/import]

My above quick ugly hack does not work on Android. Some workaround for this?

The android does not even notice when i slide out from the button so the roll out is engaged and the button is turn back to it’s original state. [import]uid: 28895 topic_id: 1012 reply_id: 24875[/import]

Has anyone figured anything out with this? It appears that this line does not work properly for Android:

display.getCurrentStage():setFocus( self, event.id )

The ui.lua buttons do not “own” events that take place outside of its bounds. So when a user rolls off a button the last event triggered is “moved”. There is no “ended” or “cancelled” event. Interestingly, this problem exists for Android and not iOS. [import]uid: 29652 topic_id: 1012 reply_id: 26311[/import]

I had a similar problem, when you pressed to say move your guy to the right and you “slid” off the button it would not detect the release and your man would keep running even though you were not on the button anymore.

The ui.lua detects a “moved” event for this, but all it does is change the graphics of the button to take the indent off, so you need to pass a “moved” event back to your button handler

in ui.lua find

 if "moved" == phase then  
 if over then  
 -- The rollover image should only be visible while the finger is within button's contentBounds  
 default.isVisible = not isWithinBounds  
 over.isVisible = isWithinBounds  
  
 end  

and change it to

if "moved" == phase then  
 if over then  
 -- The rollover image should only be visible while the finger is within button's contentBounds  
 default.isVisible = not isWithinBounds  
 over.isVisible = isWithinBounds  
  
 end  
 buttonEvent.phase = "moved"  
 result = onEvent( buttonEvent )  

then for me I just added

 if event.phase == "release" or event.phase == "moved" then  

into the button handler.

Basically this means moving off the button has the same effect as lifting your finger off, so it becomes more like a physical button.

Hope this is a help. [import]uid: 24540 topic_id: 1012 reply_id: 28232[/import]

Moving off the button.

I spent months trying to figure out how to do this (Moving off the button is the same as lifting off). In IOS I put “Touch Up Inside”.

I’ve just tried this and it works great. Delete or cancel out the line that says
" if isWithinBounds then" (You also have to delete or cancel out one of the words “end” a few lines further down). (All This code can be found in the ui.lua)

[code]
if “ended” == phase then
– Only consider this a “click” if the user lifts their finger inside button’s stageBounds
if isWithinBounds then (((((((((( Delete or cancel this line)))))))))))))
if onEvent then
buttonEvent.phase = “release”
result = onEvent( buttonEvent )
elseif onRelease then
result = onRelease( event )
end (((((((((( Delete or cancel this word)))))))))))))
end

(((((((((((((( this is the final code:

if “ended” == phase then
– Only consider this a “click” if the user lifts their finger inside button’s stageBounds

if onEvent then
buttonEvent.phase = “release”
result = onEvent( buttonEvent )
elseif onRelease then
result = onRelease( event )

end [import]uid: 47300 topic_id: 1012 reply_id: 37720[/import]

To anyone who is having this same problem I have used the below method. It’s basically a combination of a few ui library tweaks. Madmusic6’s solution works fine but doesn’t display the over button whist your finger is held down. So you also need to change another line of code. So here is the final product. Starting at line 89 in ui

[lua]if “moved” == phase then
if over then
– The rollover image should only be visible while the finger is within button’s stageBounds
default.isVisible = not isWithinBounds
–over.isVisible = isWithinBounds <<>–

end

elseif “ended” == phase or “cancelled” == phase then
if over then
default.isVisible = true
over.isVisible = false
end

if “ended” == phase then
– Only consider this a “click” if the user lifts their finger inside button’s stageBounds
–<>–
if onEvent then
buttonEvent.phase = “release”
result = onEvent( buttonEvent )
elseif onRelease then
result = onRelease( event )
end
–<>–
end[/lua]

All done your button will now work just like you brought one. [import]uid: 26289 topic_id: 1012 reply_id: 52471[/import]

This is perfect - I hadn’t realized the defect until my 6-year old was testing my software and was able to keep the button functioning while no longer touching it.

Many thanks to Cell.

Cheers! [import]uid: 151653 topic_id: 1012 reply_id: 113750[/import]