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

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.

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).

Catch the "cancelled" event.

Scott

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

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:

1
2
3
4
5
6
if isWithinBounds then
        if onEvent then
                buttonEvent.phase = "release"
                result = onEvent( buttonEvent )
        end
end

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
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
..

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

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

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

ui.lua :

1
2
3
4
5
6
7
8
if "ended" == phase then
                                if onEvent then
                                        buttonEvent.phase = "release"
                                        result = onEvent( buttonEvent )
                                elseif onRelease then
                                        result = onRelease( event )
                                end
                        end

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.

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.

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

1
2
3
4
5
6
7
        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

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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 <<<(THIS NEEDS TO BE COMMENTED OUT TO MAKE SURE YOUR BUTTON KEEPS DISPLAYING THE OVER IMAGE)>>--
 
                        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
                --<<(WE DELETE if isWithinBounds then)>>--
                                        if onEvent then
                                                buttonEvent.phase = "release"
                                                result = onEvent( buttonEvent )
                                        elseif onRelease then
                                                result = onRelease( event )
                                        end
                --<<(AND IT"S  end)>>--
                        end
views:1802 update:2011/10/11 22:13:38
corona forums © 2003-2011