From 4aa3110e253fbe31906d502268b0702c5f04f104 Mon Sep 17 00:00:00 2001 From: Mark Cannon Date: Wed, 15 Dec 2010 04:50:00 -0500 Subject: [PATCH] Updated IniFile to match source's function calls, added initial version of new ThemePrefs and ThemePrefsRows implementations and added a quick example into the default theme code. Not fully functional yet, fyi. --- Themes/_fallback/Scripts/03 IniFile.lua | 4 +- Themes/_fallback/Scripts/03 ThemePrefs.lua | 134 ++++++++++++++++++ .../_fallback/Scripts/03 ThemePrefsRows.lua | 125 ++++++++++++++++ Themes/default/Scripts/03 ThemePrefs.lua | 16 ++- 4 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 Themes/_fallback/Scripts/03 ThemePrefs.lua create mode 100644 Themes/_fallback/Scripts/03 ThemePrefsRows.lua diff --git a/Themes/_fallback/Scripts/03 IniFile.lua b/Themes/_fallback/Scripts/03 IniFile.lua index 0745c8ae43..2bad1403db 100644 --- a/Themes/_fallback/Scripts/03 IniFile.lua +++ b/Themes/_fallback/Scripts/03 IniFile.lua @@ -50,12 +50,13 @@ IniFile = end, ReadFile = function( file_path ) + Trace( "IniFile.ReadFile( " .. file_path .. " )" ) local file = RageFileUtil.CreateRageFile() if not file:Open(file_path, RageFile.READ) then Warn( string.format("ReadFile(%s): %s",file_path,file:GetError()) ) file:destroy() - return nil + return { } -- return a blank table end local tbl = { } @@ -87,6 +88,7 @@ IniFile = end, WriteFile = function( file_path, tbl ) + Trace( "IniFile.WriteFile( " .. file_path .. " )" ) local file = RageFileUtil.CreateRageFile() if not file:Open(file_path, RageFile.WRITE) then diff --git a/Themes/_fallback/Scripts/03 ThemePrefs.lua b/Themes/_fallback/Scripts/03 ThemePrefs.lua new file mode 100644 index 0000000000..0bf146e460 --- /dev/null +++ b/Themes/_fallback/Scripts/03 ThemePrefs.lua @@ -0,0 +1,134 @@ +--[[ +ThemePrefs: handles the underlying structure for ThemePrefs, so any themes +built off of this can simply declare their prefs and default values, and +access them through this system. + +v0.7: Dec. 15, 2010. Initial version. +--]] + +-- If we don't have IniFile, we can't read to or write from disk +if not IniFile then + Warn( "ThemePrefs: IniFile missing. Can't read/write from disk :(" ) +end + +function PrintTable( tbl ) + Trace( "Printing table" ) + for k,v in pairs(tbl) do + Trace( ("[%s] -> %s"):format(tostring(k),tostring(v)) ) + end +end + +local ThemePrefsPath = "Save/ThemePrefs.ini"; +local FallbackTheme = "_fallback"; + +-- This will be set on load. +local PrefsTable = nil; + +-- Gets the name of the current theme using themeInfo +-- if available and the ThemeManager name otherwise. +local function GetThemeName() + return themeInfo and themeInfo.Name or THEME:GetThemeDisplayName() +end + +-- Given a preference name, returns the table it's in. Checks the current +-- theme first, then _fallback, then all other sections, in that order. +local function ResolveTable( pref ) + -- check the section for this theme + local name = GetThemeName() + local val = PrefsTable[name][pref] + + if val ~= nil then + Trace( ("ResolveTable(%s): found in %s"):format(pref,name) ) + return PrefsTable[name] + end + + -- not in the current theme; check the fallback if it exists + if PrefsTable[FallbackTheme] then + val = PrefsTable[FallbackTheme][pref] + if val ~= nil then + Trace( ("ResolveTable(%s): found in fallback"):format(pref) ) + return PrefsTable[FallbackTheme] + end + end + + -- not there either. check every section. + -- XXX: we should do this less redundantly. + for section, _ in pairs(PrefsTable) do + val = PrefsTable[section][pref] + if val ~= nil then + Trace( ("ResolveTable(%s): found in section %s"):format(pref,section) ) + return PrefsTable[section] end + end + + -- not found at all + Trace( ("ResolveTable(%s): pref not found"):format(pref) ) + return nil +end + +ThemePrefs = +{ + NeedsSaved = false, + + -- Loads preferences from Save/ThemePrefs.ini, then adds theme + -- preferences (and default values if applicable) to PrefsTable. + -- Only read from disk once, when _fallback calls this; we just + -- need the base set once to add prefs onto. + Init = function( prefs, bLoadFromDisk ) + Trace( ("ThemePrefs.Init(prefs, %s)"):format(tostring(bLoadFromDisk)) ) + if bLoadFromDisk then + Trace( "ThemePrefs.Init: loading from disk" ) + if not ThemePrefs.Load() then return false end + end + + Trace( "ThemePrefs.Init: not loading from disk" ) + + -- create the section if it doesn't exist + local name = GetThemeName() + PrefsTable[name] = PrefsTable[name] and PrefsTable[name] or { } + + Trace( "Using section " .. name ) + + -- if the key doesn't exist, add it with our default value + for k, tbl in pairs(prefs) do + if not PrefsTable[name][k] then + Trace( k .. " doesn't exist, creating" ) + PrefsTable[name][k] = tbl.Default + end + end + + PrintTable( PrefsTable[name] ) + end, + + Load = function() + if not IniFile then return false end + PrefsTable = IniFile.ReadFile( ThemePrefsPath ) + return true + end, + + Save = function() + Trace( "ThemePrefs.Save" ) + if not IniFile then return false end + if not NeedsSaved then return end + NeedsSaved = false + IniFile.WriteFile( ThemePrefsPath, PrefsTable ) + end, + + Get = function( name ) + Trace( ("ThemePrefs.Get(%s)"):format(name) ) + local tbl = ResolveTable(name) + if tbl then return tbl[name] end + Warn( ("GetThemePref: unknown preference \"%s\""):format(name) ) + return nil + end, + + Set = function( name, value ) + Trace( ("ThemePrefs.Set(%s, %s)"):format(name, tostring(value)) ) + local tbl = ResolveTable(name) + if tbl then tbl[name] = value; NeedsSaved = true; return end + Warn( ("SetThemePref: unknown preference \"%s\""):format(name) ) + end, +}; + +-- global aliases +GetThemePref = ThemePrefs.Get +SetThemePref = ThemePrefs.Set diff --git a/Themes/_fallback/Scripts/03 ThemePrefsRows.lua b/Themes/_fallback/Scripts/03 ThemePrefsRows.lua new file mode 100644 index 0000000000..75abf05af8 --- /dev/null +++ b/Themes/_fallback/Scripts/03 ThemePrefsRows.lua @@ -0,0 +1,125 @@ +--[[ +ThemePrefsRows: you give it the choices, values, and params, and it'll +generate the rest; quirky behavior to be outlined below. Documentation +will be provided once this system is stabilized. + +v0.5: Dec. 15, 2010. Initial version. Not very well tested. +--]] + +-- unless overridden, these parameters will be used for the OptionsRow +local DefaultParams = +{ + LayoutType = "ShowAllInRow", + SelectType = "SelectOne", + OneChoiceForAllPlayers = true, + ExportOnChange = false, + EnabledForPlayers = nil, + ReloadRowMessages = nil, + + -- takes a function(self, list, pn); + -- if not used, we use the default + LoadSelections = nil, + SaveSelections = nil, +} + +local function DefaultLoadSelections( pref, default, choices, values ) + return function(self, list, pn) + local val = ThemePrefs.Get( pref ) + + -- if our current value is here, set focus to that + for i=1, #choices do + if values[i] == val then list[i] = true return end + end + + -- try the default value + for i=1, #choices do + if values[i] == default then list[i] = true return end + end + + -- set to the first value and throw a warning + Warn( ("LoadSelections: preference \"%s\"'s default not in Values"):format(pref) ) + list[1] = true + end +end + +local function DefaultSaveSelections( pref, choices, values ) + local msg = "ThemePrefChanged" + local params = { Name = pref } + + return function(self, list, pn) + for i=1, #choices do + if list[i] then ThemePrefs.Set( pref, values[i] ) break end + MESSAGEMAN:Broadcast( msg, params ) + end + end +end + + +local function CreateThemePrefRow( pref, tbl ) + Trace( "CreateThemePrefRow( " .. pref .. " )" ) + + -- can't make an option handler without options + if not tbl.Choices then return nil end + + local Choices = tbl.Choices + local Values = tbl.Values and tbl.Values or Choices + local Params = tbl.Params and tbl.Params or { } + + -- set the name and choices here; we'll do the rest below + local Handler = { Name = pref, Choices = Choices } + + -- add all the keys in DefaultParams, get the value from + -- Params if it exists and DefaultParams otherwise + -- (note that we explicitly check for nil, due to bools.) + for k, _ in pairs(DefaultParams) do + Handler[k] = Params[k] ~= nil and Params[k] or DefaultParams[k] + end + + -- if we don't have LoadSelections and SaveSelections, make them + if not Handler.LoadSelections then + Handler.LoadSelections = DefaultLoadSelections( pref, tbl.Default, Choices, Values ) + end + + if not Handler.SaveSelections then + Handler.SaveSelections = DefaultSaveSelections( pref, Choices, Values ) + end + + return Handler +end + +-- All OptionsRows for preferences are stuck in this table, accessible +-- through GetRow('name') in the namespace or ThemePrefRow('name') in +-- the global namespace. (I like to keep pollution to a minimum.) +local Rows = { } + +ThemePrefsRows = +{ + IsInitted = false, + + Init = function( prefs ) + for pref, tbl in pairs(prefs) do + Rows[pref] = CreateThemePrefRow( pref, tbl ) + end + end, + + GetRow = function( pref ) + Trace( ("GetRow(%s), type %s"):format(pref, type(Rows[pref])) ) + return Rows[pref] + end, + +} + +-- Global namespace alias +ThemePrefRow = ThemePrefsRows.GetRow + +-- UGLY: declare this here, even though it's in the previous namespace, +-- so we can have one call to initialize both systems (ThemePrefsRow is +-- declared after ThemePrefs, so it can't actually be in that file...) + +ThemePrefs.InitAll = function( prefs ) + Trace( "ThemePrefs.InitAll( prefs )" ) + + -- HACK: for now, don't worry about extraneous file I/O + ThemePrefs.Init( prefs, true ) + ThemePrefsRows.Init( prefs ) +end diff --git a/Themes/default/Scripts/03 ThemePrefs.lua b/Themes/default/Scripts/03 ThemePrefs.lua index 137747bf7b..a5889c1d24 100644 --- a/Themes/default/Scripts/03 ThemePrefs.lua +++ b/Themes/default/Scripts/03 ThemePrefs.lua @@ -1,5 +1,19 @@ -- sm-ssc Default Theme Preferences Handler +-- Example usage of new system (not really implemented yet) + +local Prefs = +{ + AutoSetStyle = + { + Default = false, + Choices = { "ON", "OFF" }, + Values = { true, false } + }, +}; + +ThemePrefs.InitAll( Prefs ) + function InitUserPrefs() if GetUserPref("UserPrefGameplayShowStepsDisplay") == nil then SetUserPref("UserPrefGameplayShowStepsDisplay", true); @@ -500,4 +514,4 @@ function UserPrefAdjustSpeed() setmetatable( t, t ); return t; end ---[[ end option rows ]] \ No newline at end of file +--[[ end option rows ]]