How do you make the setting of a toggle button persist through scene changes?

I've created a button that toggles between on and off in my Options menu. Problem is, if I turn it off, then exit and return to the Options menu, it will read as on again, because of the way I've coded it. In other words, it's state does not persist through scene transitions (I'm using Director Class, if this means anything). To make it work properly, I know I have to specify the button's state on a global level, but I don't know exactly how to do this.

Can anyone help?

My code is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
local musicOn_btn = display.newImageRect("musicOn_btn.png", 343, 72);
musicOn_btn:setReferencePoint(display.CenterReferencePoint);
musicOn_btn.x = _W/2; musicOn_btn.y = 275;
 
local musicOff_btn = display.newImageRect("musicOff_btn.png", 343, 72);
musicOff_btn:setReferencePoint(display.CenterReferencePoint);
musicOff_btn.x = _W/2; musicOff_btn.y = 275;
musicOff_btn.isVisible = false
 
function toggleMusicButton(event)
 
        if(event.phase == "ended") then
                if musicOn_btn.isVisible == true then
                musicOff_btn.isVisible = true
                musicOn_btn.isVisible = false;
                else
                musicOff_btn.isVisible = false
                musicOn_btn.isVisible = true;
                end
        end
end
 
musicOn_btn:addEventListener("touch", toggleMusicButton)
musicOff_btn:addEventListener("touch", toggleMusicButton)

there's plenty of ways to make it work
easies is using _G. variables, but it will only work ingame and all settings will be restored to original when you quit the app

so maybe you want to learn how to save variables and settings, try this:
http://techority.com/2011/04/02/how-to-save-and-load-data-in-your-app/

As DC says, ingame one way is to use what are called _G variables.
These equate to global variables in other languages.

In your main.lua file, add

_G.musicIsOn= true --assume you want music

in your screen setup, do this:

1
2
3
4
5
local musicOn_btn = display.newImageRect("musicOn_btn.png", 343, 72);
musicOn_btn.isVisible = not(_G.musicIsOn)
 
local musicOff_btn = display.newImageRect("musicOff_btn.png", 343, 72);
musicOff_btn.isVisible = G.musicIsOn

Hi jeff472,

Worked great! I had to add a couple of underscores and reverse the visibilities of the two buttons, but this was nothing once I got the theory behind what you were saying.

Like you and DC said, I may want to go one step further and make these settings persist through shut down and restart, but for now, this is a simple and effective solution.

Much thanks!

Steven

Hi DC,

Thanks so much for the link, it looks unbelievably helpful (thank god for Peach). I'm using _G.variables for now , but like you were saying, I'm fairly certain I'm going to be adding this at some point in development (if Flight Control has persistent settings, so must I, haha).

Much thanks,

Steven

Hey guys - what a nice thread to stumble into :)

I'd like to say that using globals as I do in that link is not the best way to do things - although it works it isn't best practice by any means.

However - I have a very new saving and loading system that you should find incredibly useful for things like this.

Take a look at Ego - http://techority.com/2011/12/28/ego-easy-saving-and-loading-in-your-corona-apps/

Peach :)

Hi Peach, nice to hear from you!

I tried adding ego to my code above, but, not having the best grasp on coding, I wasn't sure where to put things, or whether I'm using the arguments properly.

The first thing I did was download ego and copy the ego.lua file into my project folder. Then I created an empty text file which I named musicOnOffValue.txt and put this in my project folder as well.

I setup my main menu as follows:

1
2
3
4
5
6
7
8
9
10
11
-- Set default on for music
_G.musicIsOn= true
 
-- Require ego class for saving variables
local ego = require "ego"
local saveFile = ego.saveFile
local loadFile = ego.loadFile
 
-- Load musicOnOffValue via ego class
_G.musicIsOn = loadFile( "musicOnOffValue.txt" )
--(I want this to override the previously declared _G.musicIsOn value)

As I learn about LUA and Corona, I pick up tips all the time.
I may create a quick and dirty system for this myself (although to be fair, I havent had a look at Ego yet)

But heres a thought:

Global variables can be holding application state.
There will be several items needed.
(musicOn, currentFile, preferredMilkShakeFlavor)
That sounds like a table to me.

We already have a great way to load and save a table: search for JSON encode and decode on these forums.

So if we have a global table

_G.AppSettings = {}
We can add properties to that simply

_G.AppSettings["musicOn"] = true

Then you use JSON encode and save the lot to a single file on application suspend/exit

and you open it , use JSON decode to get all the values back when the application starts or resumes.

See if thats enough to get you started, and as I say, I may upload a module to handle this later, after I look at Ego and see if it isn't already doing something similar or better.

Hi Jeff472,

Yes, please give Ego a try and see how it performs. I don't know how to use it properly, so I can't say at present.

I have to admit I always search for the least labour intensive solution, so I'll likely wait for your verdict on Ego before delving into JSON encode and decode. That said, the concept you are putting forward sounds incredibly intriguing in a good way, perhaps curiosity will get the best of me, haha.

Much thanks,

Steven

edaabs, no worries - it's hard to learn some of this at first.

You don't create the txt file and put it in your project folder - it's actually saved in the application support folder for Corona.

What you'd do if you wanted to save the value as on would be;

saveFile ("musicSettings.txt", on")

Then you could load it like;

music = loadFile ("musicSettings.txt")

Then music would = on.

Did you open ego.lua? It's got a few little examples in there :)

Let me know how you go, can try to help with some sample code later if you are still having issues.

Peach :)

Hi Peach,

Yes, I hate to say it, but still I'm still having issues. My event listener now looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function toggleMusicButton(event)
                if(event.phase == "ended") then
                        if musicOn_btn.isVisible == true then
                        musicOff_btn.isVisible = true
                        musicOn_btn.isVisible = false;
                        saveFile( "musicSettings.txt", false)
                        else
                        musicOff_btn.isVisible = false
                        musicOn_btn.isVisible = true;
                        saveFile( "musicSettings.txt", true)
                        end
                end
                _G.musicIsOn  = musicOn_btn.isVisible           
        end

Sounds like you dont have

require "ego.lua"

at the top of your module.

I've looked at the Ego stuff now, and I will be putting together a different thing over the next few days.

Sounds good.

Let me know when you get it out, or will watch for it

Cheers,

Steven

Ive just uploaded some sample code in the 'Share your code' section, called Load and Save defaults/ preferences.

Basically, I create a global table called
_G.lobal

The global variables are added to that table, and then are available using syntax like this:

_G.lobal.currentScore = 9

As long as you call saveDefaults() when the app suspends or shuts down, and loadDefaults() when it resumes or starts, the rest is totally invisible

Using that system, the code above would become:

1
2
3
4
5
6
7
function toggleMusicButton(event)
if(event.phase == "ended") then
  musicOn_btn.isVisible = not(_G.lobal.musicSettings)
  musicOff_btn.isVisible = _G.lobal.musicSettings
  _G.lobal.musicSettings = not(_G.lobal.musicSettings)
  end
end

Hi jeff472,

Sounds simple enough:) I'm going to to take a look at your sample and see if I can apply it to my code. I'll let you know how things go.

Thank you!

Steven

Let me know how you get on.
I remember the other dat finding that reading numbers from a text file didnt always trigger the LUA coersion between number and text.
The same may be true of 'true'

If so, you might find it trying to set a value to the text value "true" instead of the boolean true.

I have an idea how to handle that transparently too, but it will have to wait for the weekend if so.

views:2262 update:2012/1/9 8:53:30
corona forums © 2003-2011