165 lines
4.7 KiB
Lua
165 lines
4.7 KiB
Lua
--[[
|
|
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.2: Dec. 28, 2010. Throw an error for default/value type mismatches.
|
|
v0.5.1: Dec. 27, 2010. Fix Choices not necessarily being strings.
|
|
v0.5.0: Dec. 15, 2010. Initial version. Not very well tested.
|
|
|
|
vyhd wrote this for sm-ssc
|
|
--]]
|
|
|
|
-- 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 alias to simplify error reporting
|
|
local function GetString( name )
|
|
return THEME:GetString( "ThemePrefsRows", name )
|
|
end
|
|
|
|
local function DefaultLoad( 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 output a warning
|
|
Warn( GetString("NoDefaultInValues"):format(pref) )
|
|
list[1] = true
|
|
end
|
|
end
|
|
|
|
local function DefaultSave( 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
|
|
|
|
-- This function checks for mismatches between the default value and the
|
|
-- values table passed to the ThemePrefRow, e.g. it will return false if
|
|
-- you have a boolean default and an integer value. I'm somewhat stricter
|
|
-- about types than Lua is because I don't like the unpredictability and
|
|
-- complexity of coercing values transparently in a bunch of places.
|
|
local function TypesMatch( Values, Default )
|
|
local DefaultType = type(Default)
|
|
|
|
for i, value in ipairs(Values) do
|
|
local ValueType = type(value)
|
|
if ValueType ~= DefaultType then
|
|
Warn( GetString("TypeMismatch"):format(DefaultType, i, ValueType) )
|
|
return false
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function CreateThemePrefRow( pref, tbl )
|
|
-- can't make an option handler without options
|
|
if not tbl.Choices then return nil end
|
|
|
|
local Choices = tbl.Choices
|
|
local Default = tbl.Default
|
|
local Values = tbl.Values and tbl.Values or Choices
|
|
local Params = tbl.Params and tbl.Params or { }
|
|
|
|
-- if the choices aren't strings, make them strings now
|
|
for i, str in ipairs(Choices) do
|
|
Choices[i] = tostring( Choices[i] )
|
|
end
|
|
|
|
-- check to see that Values and Choices have the same length
|
|
if #Choices ~= #Values then
|
|
Warn( GetString("ChoicesSizeMismatch") )
|
|
return nil
|
|
end
|
|
|
|
-- check to see that everything in Values matches the type of Default
|
|
if not TypesMatch( Values, Default ) then return nil end
|
|
|
|
-- 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 = DefaultLoad( pref, Default, Choices, Values )
|
|
end
|
|
|
|
if not Handler.SaveSelections then
|
|
Handler.SaveSelections = DefaultSave( 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 )" )
|
|
|
|
ThemePrefs.Init( prefs, true )
|
|
ThemePrefsRows.Init( prefs )
|
|
end
|