How to detect when a button is released outside of itself

Hello,

I need button that work “on the fly”. I mean if I stay pushed on a button, I get all the events.

The following code stop working good when I stay clicked on the button then I release it outside of the button…

local widget=require(“widget”)
local wbutton

local function onEventButton(evt)
    if evt.phase==“began” then
        display.getCurrentStage():setFocus(evt.target)
        wbutton.isFocus=true
    elseif evt.phase==“ended” then
        display.getCurrentStage():setFocus(nil)
        wbutton.isFocus=false
    end
    return true
end

wbutton=widget.newButton({onEvent=onEventButton})
wbutton.isFocus=false

local function onEnterframe(evt)
    if wbutton.isFocus then print(“OK”) else print(“ko”) end
end

Runtime:addEventListener(“enterFrame”,onEnterframe)

This is the default behaviors of buttons. There also exists “event.moved” to detect when the finger moves while pressing the button,

Ok but “moved” is useless because I still don’t know when the mouse pointer is released. I maybe need use image instead of widget…

Or set up a transparent layer on top over everything that also responds to touch, but does not return true (so the touch bleeds through).  Then detect if this layer AND the button were touched, and do what you need to do when the transparent layer touch is ended.

It sounds an interesting idea, i’ll try it! Thank you

Well, in fact it was a false problem because widget buttons send the “cancelled” event, it was just not specified in the doc which say only : “began”, “moved”, or “ended”

You can check the touch ended event.x against the bounds of the button. That way you will always know if you are releasing on the bottom.

Heres the function i always use for images etc that i want to turn into buttons:

[lua]local function btnTouched(event)

    local t = event.target

    local id = t.id

    if event.phase == “began” then 

        display.getCurrentStage():setFocus( t )

        t.isFocus = true

        t.alpha = 0.6

            

    elseif t.isFocus then 

        if event.phase == “ended”  then 

            display.getCurrentStage():setFocus( nil )

            t.isFocus = false

            t.alpha = 1

            --Check bounds. If we are in it then click!

            local b = t.contentBounds 

            if event.x >= b.xMin and event.x <= b.xMax and event.y >= b.yMin and event.y <= b.yMax then 

                --DO SOMETHING HERE

            end

        end

    end

    return true

end[/lua]

Thanks for this additionnal tip, very useful in some cases:)

This is the default behaviors of buttons. There also exists “event.moved” to detect when the finger moves while pressing the button,

Ok but “moved” is useless because I still don’t know when the mouse pointer is released. I maybe need use image instead of widget…

Or set up a transparent layer on top over everything that also responds to touch, but does not return true (so the touch bleeds through).  Then detect if this layer AND the button were touched, and do what you need to do when the transparent layer touch is ended.

It sounds an interesting idea, i’ll try it! Thank you

Well, in fact it was a false problem because widget buttons send the “cancelled” event, it was just not specified in the doc which say only : “began”, “moved”, or “ended”

You can check the touch ended event.x against the bounds of the button. That way you will always know if you are releasing on the bottom.

Heres the function i always use for images etc that i want to turn into buttons:

[lua]local function btnTouched(event)

    local t = event.target

    local id = t.id

    if event.phase == “began” then 

        display.getCurrentStage():setFocus( t )

        t.isFocus = true

        t.alpha = 0.6

            

    elseif t.isFocus then 

        if event.phase == “ended”  then 

            display.getCurrentStage():setFocus( nil )

            t.isFocus = false

            t.alpha = 1

            --Check bounds. If we are in it then click!

            local b = t.contentBounds 

            if event.x >= b.xMin and event.x <= b.xMax and event.y >= b.yMin and event.y <= b.yMax then 

                --DO SOMETHING HERE

            end

        end

    end

    return true

end[/lua]

Thanks for this additionnal tip, very useful in some cases:)