--[[ 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.2: Jan. 10, 2012. Added ThemePrefs.ForceSave function [freem] v0.7.1: Dec. 28, 2010. Added language support. v0.7.0: Dec. 15, 2010. Initial version. vyhd wrote this for sm-ssc. <3 you guys --]] -- local function to handle themed error strings -- (and to ensure we're getting all of them from the same section) local function GetString( name ) return THEME:GetString( "ThemePrefs", name ) 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() -- When loading a fallback theme, the theme manager pretends that the theme -- being loaded is the current theme. THEME:GetCurThemeName and everything -- else that relies on the current theme will think that the fallback theme -- is the current theme. -- This includes the themeInfo table that some themes create in -- "00 ThemeInfo.lua". -- In diagram form, imagine the "home" theme, which falls back on -- "default", which falls back on "_fallback". -- Scripts being loaded | Current theme name. | themeInfo source -- ----------------------------------------------------------------- -- _fallback/Scripts | _fallback | _fallback/Scripts/ -- default/Scripts | default | default/Scripts/ -- home/Scripts | home | home/Scripts/ -- So when default calls ThemePrefs.Init at the end of its script loading, -- ThemePrefs thinks the current theme is "default", even if the player -- chose "home". Thus, the ThemePrefs entry for "home" is not created. -- Then later when a preference is used, ResolveTable thinks the current -- theme is "home", but fails because there is no "home" entry in -- PrefsTable. return PREFSMAN:GetPreference("Theme") 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 = nil if PrefsTable[name] then val = PrefsTable[name][pref] if val ~= nil then --Trace( ("ResolveTable(%s): found in %s"):format(pref,name) ) return PrefsTable[name] end 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 ) -- If we don't have IniFile, we can't read/write from/to disk if not IniFile then Warn( GetString("IniFileMissing") ) end -- 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 section = GetThemeName() -- Trace( ("ThemePrefs.Init: Theme name is \"%s\""):format(section) ) PrefsTable[section] = PrefsTable[section] and PrefsTable[section] or { } --Trace( "Using section " .. section ) -- if the key doesn't exist, add it with our default value for k, tbl in pairs(prefs) do if PrefsTable[section][k] == nil then Trace( k .. " doesn't exist, creating" ) PrefsTable[section][k] = tbl.Default end end -- PrintTable( PrefsTable[section] ) end, Load = function() if not IniFile then return false end PrefsTable = IniFile.ReadFile( ThemePrefsPath ) return true end, Save = function() -- Trace( "ThemePrefs.Save" ) if IniFile and ThemePrefs.NeedsSaved then IniFile.WriteFile( ThemePrefsPath, PrefsTable ) ThemePrefs.NeedsSaved = false return end end, -- for when you absolutely have to save, no matter what NeedsSaved says. ForceSave = function() if not IniFile then return false end ThemePrefs.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( "Get: "..GetString("UnknownPreference"):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 ThemePrefs.NeedsSaved = true tbl[name] = value return end Warn( "Set: "..GetString("UnknownPreference"):format(name) ) end, CopyPrefsFrom = function(name) local curr_prefs = PrefsTable[GetThemeName()] local from_prefs = PrefsTable[name] if curr_prefs and from_prefs then for pref_name, pref_value in pairs(from_prefs) do curr_prefs[pref_name] = pref_value end end end, }; -- global aliases GetThemePref = ThemePrefs.Get SetThemePref = ThemePrefs.Set -- bring in SpecialScoring from default. function InitUserPrefs() if GetUserPref("UserPrefScoringMode") == nil then SetUserPref("UserPrefScoringMode", 'DDR Extreme'); end; end;