Accessing image in widget button

Hi there,

Does anyone know if there’s a way to access the defaultFile or overFile in a widget image button? I want to swap the images out when the button is pressed.

I know I can change the label through setLabel() but it’s the images I need to change.

Thanks,

Ian

  • 1 here,

I’d be interested in this - my interest is in changing the tint/fillcolor - which requires access to defaultFile or overFile.

How many potential images would you be iterating through?

T.

I showed this example in another post recently which doesn’t exactly “point” to the image files used for the button, but shows how you can create another display object, “link” it to the button, and then take actions on that object when the button is manipulated.

[lua]

local function handleButtonEvent( event )

    if ( event.phase == “began” ) then

        event.target.buttonRect:setFillColor(0.7,0.1,0.2)

    elseif ( event.phase == “ended” ) then

        event.target.buttonRect:setFillColor(1,0,0)

    end

end

local myButton = widget.newButton

{

    left=240,

    top=100,

    width = 240,

    height = 120,

    label = “button”,

    labelColor = { default={1,1,1}, over={0,0,0,1} },

    fontSize = 30,

    onEvent = handleButtonEvent

}

local bv = myButton._view

myButton.buttonRect = display.newRect( bv.x, bv.y, bv.width, bv.height )

myButton.buttonRect:setFillColor(1,0,0)

myButton.buttonRect:toBack()

myButton.buttonRect.x = myButton.x

myButton.buttonRect.y = myButton.y

[/lua]

This example puts a basic vector rectangle behind the text-only button and toggles its color upon press/unpress. However, that rectangle could be an image that a tint could be set on, or in @keystagefun’s case, it could be a sprite object that you change the frame of to swap which image appears at different times on press.

@keystagefun, even if you had access to the internal default and over images, you probably couldn’t change the over image between several options, since it’s just one non-sprite image and you can’t change the texture on it directly. I suppose you could change the fill parameter and specify which texture to use for the fill, but that gets a bit complex and I think maybe the above solution is more elegant for your needs.

Hope this helps,

Brent

Excellent idea. Thanks for sharing.

Thanks Rob - i’ll try it out - as an aside Q When we use widgets I assume Corona adds in the whole widget library to our builds correct? What kind of size (KB)  does this add to our builds? Is it worth creating your own quasi widget if perhaps you only use the widget button & no other widgets?

@keystagefun

One other possible way in theory is - 

Create a rect/or image as your base (constant) for touch events - then attach some type of counter combined with object.isVisible = true/false statements which cycle through your images which are placed above your touch handler. But as Rob says it would get complex; and it would take you away from the simplicity of the widget - you kind of create your own quasi widget.

It all depends on the number of images you want to iterate through? as texture Mem might come into play -  unless you clean up your old images as you go, or somehow shuffle the images (don’t know if possible).

The result would appear as if your users are touching a particular image but in reality they are touching a button beneath which makes images above visible/invisible.

T.

While widget.newButton() is a pretty useful API,  it’s not the only way to do buttons in Corona SDK and frankly sometimes doing it by hand makes more sense:

You can use this tutorial:  http://coronalabs.com/blog/2013/11/26/tutorial-techniques-for-swapping-images/

To see simple image swapping techniques there and add a touch handler which  you’re already writing for your widget.newButton() and away you go.

Yep - thats the Link you needed - great memory there Rob, and if i may add to your statement "…frankly sometimes doing it by hand makes more sense’ - and is a great learning opportunity as well’

I had a lot of images of different colour and frankly cost me a lot of time creating the different colour versions - so when i saw the setFillcolor thing with G2 - I thought to myself Hey create one image and use fill - But i used the image button widget so had a problem

  • i like the widget style of touch / release - but could not find a way to make it work -

so went searching the forum - found some mentioning how to tell if the touch has moved off the object

—> end result made my own quasi widget function which allows me to predefine the colour theme of start colour and touch colour & then identify which widget was touched - which allows me to use a function to do what i want the button to do.

But does not actually swap images - which is what you wanted - but looking at the Tutorial Rob did - you could combine the codes to produce something i think might get what you want.

I’ve still not figured out how to make it a separate module - as yet so it is a local function within your storyboard/composer scene

[lua]
local outside = true
local whatDo
local function widgat( event )
– print(“called”)
if event.phase == “began” then
display.getCurrentStage():setFocus( event.target )
event.target.isFocus = true

outside = false
event.target:setFillColor( wToucR1, wToucG1, wToucB1 )

elseif event.phase == “moved” and event.target.isFocus then

if event.x > event.target.contentBounds.xMax or event.x < event.target.contentBounds.xMin or
event.y > event.target.contentBounds.yMax or event.y < event.target.contentBounds.yMin then
– print(“The touch is outside the object”);
event.target:setFillColor( wStrtR1, wStrtG1, wStrtB1 )
outside = true
else
– print(“Touch is moving”);
event.target:setFillColor( wToucR1, wToucG1, wToucB1 )
outside = false
end

elseif event.phase == “ended” then
display.getCurrentStage():setFocus(nil);
event.target.isFocus = nil;

if outside == false then
event.target:setFillColor( wStrtR1, wStrtG1, wStrtB1 )

– print(“Touch is endedYeah”);

if event.target == WidjBut[1] then
whatDo = 1
elseif event.target == WidjBut[2] then
whatDo = 2
elseif event.target == WidjBut[3] then
whatDo = 3
elseif event.target == WidjBut[4] then
whatDo = 4
elseif event.target == WidjBut[5] then
whatDo = 5
elseif event.target == WidjBut[6] then
whatDo = 6
end
heyDoThis()
else
– print(“ended”);
end
end
end

WidjBut[1]:addEventListener(“touch”, widgat);

[/lua]

the whatDo is just a flag that is used in a heyDoThis() function to decide what to do.{ change scene…etc…}

So the above code can give you a widget like experience - and combine it with the swapping image code from the tutorial link Rob suggested and i think what you desire is possible.
More complex than the simplicity of the widget, and with the more images that you use, the more chance of causing problems ( more logic to keep track of).

I’d be interested in seeing what you come up with.

T.

  • 1 here,

I’d be interested in this - my interest is in changing the tint/fillcolor - which requires access to defaultFile or overFile.

How many potential images would you be iterating through?

T.

I showed this example in another post recently which doesn’t exactly “point” to the image files used for the button, but shows how you can create another display object, “link” it to the button, and then take actions on that object when the button is manipulated.

[lua]

local function handleButtonEvent( event )

    if ( event.phase == “began” ) then

        event.target.buttonRect:setFillColor(0.7,0.1,0.2)

    elseif ( event.phase == “ended” ) then

        event.target.buttonRect:setFillColor(1,0,0)

    end

end

local myButton = widget.newButton

{

    left=240,

    top=100,

    width = 240,

    height = 120,

    label = “button”,

    labelColor = { default={1,1,1}, over={0,0,0,1} },

    fontSize = 30,

    onEvent = handleButtonEvent

}

local bv = myButton._view

myButton.buttonRect = display.newRect( bv.x, bv.y, bv.width, bv.height )

myButton.buttonRect:setFillColor(1,0,0)

myButton.buttonRect:toBack()

myButton.buttonRect.x = myButton.x

myButton.buttonRect.y = myButton.y

[/lua]

This example puts a basic vector rectangle behind the text-only button and toggles its color upon press/unpress. However, that rectangle could be an image that a tint could be set on, or in @keystagefun’s case, it could be a sprite object that you change the frame of to swap which image appears at different times on press.

@keystagefun, even if you had access to the internal default and over images, you probably couldn’t change the over image between several options, since it’s just one non-sprite image and you can’t change the texture on it directly. I suppose you could change the fill parameter and specify which texture to use for the fill, but that gets a bit complex and I think maybe the above solution is more elegant for your needs.

Hope this helps,

Brent

Excellent idea. Thanks for sharing.

Thanks Rob - i’ll try it out - as an aside Q When we use widgets I assume Corona adds in the whole widget library to our builds correct? What kind of size (KB)  does this add to our builds? Is it worth creating your own quasi widget if perhaps you only use the widget button & no other widgets?

@keystagefun

One other possible way in theory is - 

Create a rect/or image as your base (constant) for touch events - then attach some type of counter combined with object.isVisible = true/false statements which cycle through your images which are placed above your touch handler. But as Rob says it would get complex; and it would take you away from the simplicity of the widget - you kind of create your own quasi widget.

It all depends on the number of images you want to iterate through? as texture Mem might come into play -  unless you clean up your old images as you go, or somehow shuffle the images (don’t know if possible).

The result would appear as if your users are touching a particular image but in reality they are touching a button beneath which makes images above visible/invisible.

T.

While widget.newButton() is a pretty useful API,  it’s not the only way to do buttons in Corona SDK and frankly sometimes doing it by hand makes more sense:

You can use this tutorial:  http://coronalabs.com/blog/2013/11/26/tutorial-techniques-for-swapping-images/

To see simple image swapping techniques there and add a touch handler which  you’re already writing for your widget.newButton() and away you go.

Yep - thats the Link you needed - great memory there Rob, and if i may add to your statement "…frankly sometimes doing it by hand makes more sense’ - and is a great learning opportunity as well’

I had a lot of images of different colour and frankly cost me a lot of time creating the different colour versions - so when i saw the setFillcolor thing with G2 - I thought to myself Hey create one image and use fill - But i used the image button widget so had a problem

  • i like the widget style of touch / release - but could not find a way to make it work -

so went searching the forum - found some mentioning how to tell if the touch has moved off the object

—> end result made my own quasi widget function which allows me to predefine the colour theme of start colour and touch colour & then identify which widget was touched - which allows me to use a function to do what i want the button to do.

But does not actually swap images - which is what you wanted - but looking at the Tutorial Rob did - you could combine the codes to produce something i think might get what you want.

I’ve still not figured out how to make it a separate module - as yet so it is a local function within your storyboard/composer scene

[lua]
local outside = true
local whatDo
local function widgat( event )
– print(“called”)
if event.phase == “began” then
display.getCurrentStage():setFocus( event.target )
event.target.isFocus = true

outside = false
event.target:setFillColor( wToucR1, wToucG1, wToucB1 )

elseif event.phase == “moved” and event.target.isFocus then

if event.x > event.target.contentBounds.xMax or event.x < event.target.contentBounds.xMin or
event.y > event.target.contentBounds.yMax or event.y < event.target.contentBounds.yMin then
– print(“The touch is outside the object”);
event.target:setFillColor( wStrtR1, wStrtG1, wStrtB1 )
outside = true
else
– print(“Touch is moving”);
event.target:setFillColor( wToucR1, wToucG1, wToucB1 )
outside = false
end

elseif event.phase == “ended” then
display.getCurrentStage():setFocus(nil);
event.target.isFocus = nil;

if outside == false then
event.target:setFillColor( wStrtR1, wStrtG1, wStrtB1 )

– print(“Touch is endedYeah”);

if event.target == WidjBut[1] then
whatDo = 1
elseif event.target == WidjBut[2] then
whatDo = 2
elseif event.target == WidjBut[3] then
whatDo = 3
elseif event.target == WidjBut[4] then
whatDo = 4
elseif event.target == WidjBut[5] then
whatDo = 5
elseif event.target == WidjBut[6] then
whatDo = 6
end
heyDoThis()
else
– print(“ended”);
end
end
end

WidjBut[1]:addEventListener(“touch”, widgat);

[/lua]

the whatDo is just a flag that is used in a heyDoThis() function to decide what to do.{ change scene…etc…}

So the above code can give you a widget like experience - and combine it with the swapping image code from the tutorial link Rob suggested and i think what you desire is possible.
More complex than the simplicity of the widget, and with the more images that you use, the more chance of causing problems ( more logic to keep track of).

I’d be interested in seeing what you come up with.

T.