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:

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 endend musicOn_btn:addEventListener("touch", toggleMusicButton)musicOff_btn:addEventListener("touch", toggleMusicButton)[/code]Thanks in advance,Steven [import]uid: 79394 topic_id: 19896 reply_id: 319896[/import]

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/ [import]uid: 16142 topic_id: 19896 reply_id: 77289[/import]

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:

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  

and the last few lines of the event listener:

  
end  
G.musicIsOn = musicOff\_btn.isVisible   
  
end  

You need the load/save stuff to make these settings persist if your app is shut down and restarted. [import]uid: 108660 topic_id: 19896 reply_id: 77291[/import]

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

[import]uid: 79394 topic_id: 19896 reply_id: 77372[/import]

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

[import]uid: 79394 topic_id: 19896 reply_id: 77378[/import]

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

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 :slight_smile: [import]uid: 52491 topic_id: 19896 reply_id: 77499[/import]

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:
-- Set default on for music_G.musicIsOn= true-- Require ego class for saving variableslocal ego = require "ego"local saveFile = ego.saveFilelocal loadFile = ego.loadFile-- Load musicOnOffValue via ego class_G.musicIsOn = loadFile( "musicOnOffValue.txt" )--(I want this to override the previously declared _G.musicIsOn value)[/code]Finally, I added a line saving the user's setting of the music On/Off button to the event listener in my Options menu: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 _G.musicIsOn = musicOn_btn.isVisible saveFile( "musicOnOffValue.txt", _G.musicIsOn)endmusicOn_btn:addEventListener("touch", toggleMusicButton)musicOff_btn:addEventListener("touch", toggleMusicButton)[/code]I know I've made some glaringly obvious mistakes, but I don't know where or how. Can you point out where I've gone wrong?Much thanks!Steven [import]uid: 79394 topic_id: 19896 reply_id: 77523[/import]

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.

[import]uid: 108660 topic_id: 19896 reply_id: 77533[/import]

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

[import]uid: 79394 topic_id: 19896 reply_id: 77692[/import]

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;

[lua]saveFile (“musicSettings.txt”, on")[/lua]

Then you could load it like;

[lua]music = loadFile (“musicSettings.txt”)[/lua]

Then music would = on.

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

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

Peach :slight_smile: [import]uid: 52491 topic_id: 19896 reply_id: 77695[/import]

Hi Peach,

Yes, I hate to say it, but still I’m still having issues. My event listener now looks like this:
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[/code].. but I'm getting an error that reads: ... lua:6: attempt to call global 'saveFile' (a nil value)I have checked the examples in the commented out header of ego.lua, but I think what I really need to know is how to setup properly? [import]uid: 79394 topic_id: 19896 reply_id: 77725[/import]

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. [import]uid: 108660 topic_id: 19896 reply_id: 77727[/import]

Sounds good.

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

Cheers,

Steven [import]uid: 79394 topic_id: 19896 reply_id: 77736[/import]

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:

[code]
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

[/code] [import]uid: 108660 topic_id: 19896 reply_id: 77750[/import]

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 [import]uid: 79394 topic_id: 19896 reply_id: 78052[/import]

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.
[import]uid: 108660 topic_id: 19896 reply_id: 78071[/import]

Hi Jeff472,

Just want to let you know that I got your code working! It took a couple of tries due to my inexperience, but once I finally got the gist of how it works, everything went smoothly:)

All I had to do was paste your sample at the top of my code (swapping in my variables, of course), immediately follow it with loadDefaults(), set my button visibilities like so:
local musicOn_btn = display.newImageRect("Music On Button for Options Menu.png", 343, 72); musicOn_btn:setReferencePoint(display.CenterReferencePoint); musicOn_btn.x = _W/2 - 5; musicOn_btn.y = 275; musicOn_btn.isVisible = _G.lobal.musicSettings local musicOff_btn = display.newImageRect("Music Off Button for Options Menu.png", 343, 72); musicOff_btn:setReferencePoint(display.CenterReferencePoint); musicOff_btn.x = _W/2 - 5; musicOff_btn.y = 275; musicOff_btn.isVisible = not(_G.lobal.musicSettings)[/code]and finally change my button function to this: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) endsaveDefaults()loadDefaults()end[/code]I'm ecstatic. Thank you so much for your help, I really appreciate the wording of your posts and the code snippets you provided. They all made sense and were very easy to follow!Cheers,Steven [import]uid: 79394 topic_id: 19896 reply_id: 79219[/import]