Ticket #3737: optionsReset-v4.patch

File optionsReset-v4.patch, 20.1 KB (added by mimo, 8 years ago)

updated version of the patch, after r17737 and r17738

  • binaries/data/mods/public/gui/options/options.js

     
    55{
    66    if (data && data.callback)
    77        g_HasCallback = true;
    8     let revert = data && data.revert;
    98    g_Controls = {};
    109
    1110    var options = Engine.ReadJSONFile("gui/options/options.json");
     
    2120            let label = Engine.GetGUIObjectByName(category + "Label[" + i + "]");
    2221            let config = option.parameters.config;
    2322            g_Controls[config] = {
    24                 "control": setupControl(option, i, category, revert),
     23                "control": setupControl(option, i, category),
    2524                "type": option.type,
    26                 "dependencies": option.dependencies || undefined
     25                "dependencies": option.dependencies || undefined,
     26                "parameters": option.parameters
    2727            };
    2828            label.caption = translate(option.label);
    2929            label.tooltip = option.tooltip ? translate(option.tooltip) : "";
     
    4747                    continue;
    4848                if (!opt.dependencies || opt.dependencies.indexOf(config) === -1)
    4949                    continue;
    50                 label.caption = "       " + label.caption;
     50                label.caption = "      " + label.caption;
    5151                break;
    5252            }
    5353            // Show element.
     
    5555        }
    5656    }
    5757
    58     updateDependencies();
    59     if (!revert)
    60         updateStatus();
     58    updateOptionPanel();
    6159}
    6260
    6361/**
     
    6664 * @param option Structure containing the data to setup an option.
    6765 * @param prefix Prefix to use when accessing control, for example "generalSetting" when the tickbox name is generalSettingTickbox[i].
    6866 */
    69 function setupControl(option, i, category, revert)
     67function setupControl(option, i, category)
    7068{
    7169    var control;
    7270    var onUpdate;
     
    9290            {
    9391            case "config":
    9492                keyConfig = option.parameters.config;
    95                 if (checked === undefined || revert)
     93                if (checked === undefined)
    9694                    checked = Engine.ConfigDB_GetValue("user", keyConfig) === "true";
    97                 else if ((Engine.ConfigDB_GetValue("user", keyConfig) === "true") !== checked)
    98                 {
    99                     Engine.ConfigDB_CreateValue("user", keyConfig, String(checked));
    100                     updateStatus(true);
    101                 }
     95                else if (checked !== (Engine.ConfigDB_GetValue("user", keyConfig) === "true"))
     96                    warn(" incompatible config option value for " + keyconfig);
    10297                break;
    10398            case "renderer":
    10499                keyRenderer = option.parameters.renderer;
     
    111106                if (checked === undefined)
    112107                    checked = Engine["Renderer_Get" + keyRenderer + "Enabled"]();
    113108                else if (Engine["Renderer_Get" + keyRenderer + "Enabled"]() !== checked)
     109                {
     110                    warn(" incompatible renderer option value for " + keyRenderer);
    114111                    Engine["Renderer_Set" + keyRenderer + "Enabled"](checked);
     112                }
    115113                break;
    116114            default:
    117115                warn("Unknown option source type '" + param + "'");
     
    130128                if (keyRenderer)
    131129                    Engine["Renderer_Set" + keyRenderer + "Enabled"](val);
    132130                if (keyConfig)
     131                {
    133132                    Engine.ConfigDB_CreateValue("user", keyConfig, String(val));
    134                 updateDependencies();
    135                 updateStatus(true);
     133                    Engine.ConfigDB_SetChanges("user", true);
     134                }
     135                updateOptionPanel();
    136136            };
    137137        }(keyRenderer, keyConfig, inverted);
    138138
     
    188188                if (Engine.ConfigDB_GetValue("user", key) === this.caption)
    189189                    return;
    190190                Engine.ConfigDB_CreateValue("user", key, this.caption);
     191                Engine.ConfigDB_SetChanges("user", true);
    191192                if (functionBody)
    192193                    Engine[functionBody](+this.caption);
    193                 updateDependencies();
    194                 updateStatus(true);
     194                updateOptionPanel();
    195195            };
    196196        }(key, functionBody, minval, maxval);
    197197
     
    201201        break;
    202202    case "dropdown":
    203203        control = Engine.GetGUIObjectByName(category + "Dropdown[" + i + "]");
     204        control.onSelectionChange = function(){};  // just the time to setup the value
    204205        var caption;
    205206        var key;
    206207        var functionBody;
     
    237238                if (key === "materialmgr.quality")
    238239                    val = val == 0 ? 2 : val == 1 ? 5 : 8;
    239240                Engine.ConfigDB_CreateValue("user", key, val);
    240                 updateDependencies();
    241                 updateStatus(true);
     241                Engine.ConfigDB_SetChanges("user", true);
     242                updateOptionPanel();
    242243            };
    243244        }(key);
    244245
     
    254255    return control;
    255256}
    256257
    257 function updateStatus(val)
     258function updateOptionPanel()
    258259{
    259     if (typeof val == "boolean")
    260         Engine.ConfigDB_CreateValue("user", "nosave.haschanges", String(val));
    261     else
    262         val = Engine.ConfigDB_GetValue("user", "nosave.haschanges") === "true";
     260    // Update dependencies
     261    for (let item in g_Controls)
     262    {
     263        let control = g_Controls[item];
     264        if (control.type !== "boolean" && control.type !== "invertedboolean" || !control.dependencies)
     265            continue;
    263266
    264     Engine.GetGUIObjectByName("loadOptions").enabled = val;
    265     Engine.GetGUIObjectByName("saveOptions").enabled = val;
     267        for (let dependency of control.dependencies)
     268            g_Controls[dependency].control.enabled = control.control.checked;
     269    }
     270
     271    // And main buttons
     272    let hasChanges = Engine.ConfigDB_HasChanges("user");;
     273    Engine.GetGUIObjectByName("revertChanges").enabled = hasChanges;
     274    Engine.GetGUIObjectByName("saveChanges").enabled = hasChanges;
    266275}
    267276
    268277/**
     
    275284            g_Controls[item].control.onPress();
    276285}
    277286
    278 function updateDependencies()
     287function resetChanges()
    279288{
     289    let btCaptions = [translate("No"), translate("Yes")];
     290    let btCode = [null, function(){ reallyResetChanges(); }];
     291    messageBox(500, 200, translate("Resetting the options will erase your saved settings. Do you want to continue ?"),
     292        translate("Warning"), 0, btCaptions, btCode);
     293}
     294
     295function reallyResetChanges()
     296{
    280297    for (let item in g_Controls)
    281     {
    282         let control = g_Controls[item];
    283         if (control.type !== "boolean" && control.type !== "invertedboolean" || !control.dependencies)
    284             continue;
     298        Engine.ConfigDB_RemoveValue("user", item);
    285299
    286         for (let dependency of control.dependencies)
    287             g_Controls[dependency].control.enabled = control.control.checked;
    288     }
     300    Engine.ConfigDB_WriteFile("user", "config/user.cfg");
     301    revertChanges();
    289302}
    290303
    291304function revertChanges()
    292305{
    293306    Engine.ConfigDB_Reload("user");
    294     updateStatus(false);
    295     init({ "revert": true });
     307    // needs to update renderer values (which are all of boolean type)
     308    for (let item in g_Controls)
     309    {
     310        let control = g_Controls[item];
     311        if (!control.parameters.renderer)
     312            continue;
     313        if (control.type !== "boolean" && control.type !== "invertedboolean")
     314        {
     315            warn("Invalid type option defined in renderer '" + control.type + "': will not be reverted");
     316            continue;
     317        }
     318        let checked = Engine.ConfigDB_GetValue("user", item) === "true";
     319        let keyRenderer = control.parameters.renderer;
     320        if (Engine["Renderer_Get" + keyRenderer + "Enabled"]() !== checked)
     321            Engine["Renderer_Set" + keyRenderer + "Enabled"](checked);
     322    }
     323    Engine.ConfigDB_SetChanges("user", false);
     324    init();
    296325}
    297326
    298327function saveChanges()
     
    299328{
    300329    registerChanges();
    301330    Engine.ConfigDB_WriteFile("user", "config/user.cfg");
    302     updateStatus(false);
     331    Engine.ConfigDB_SetChanges("user", false);
     332    updateOptionPanel();
    303333}
    304334
    305335/**
     
    308338function closePage()
    309339{
    310340    registerChanges();
    311     if (Engine.ConfigDB_GetValue("user", "nosave.haschanges") === "true")
     341    if (Engine.ConfigDB_HasChanges("user"))
    312342    {
    313343        let btCaptions = [translate("No"), translate("Yes")];
    314344        let btCode = [null, function(){ closePageWithoutConfirmation(); }];
  • binaries/data/mods/public/gui/options/options.json

     
    6868            "type": "boolean",
    6969            "label": "Prefer GLSL",
    7070            "tooltip": "Use OpenGL 2.0 shaders (recommended)",
    71             "parameters": { "renderer": "PreferGLSL", "config": "preferglsl" }
     71            "parameters": { "config": "preferglsl", "renderer": "PreferGLSL" }
    7272        },
    7373        {
    7474            "type": "boolean",
    7575            "label": "Post Processing",
    7676            "tooltip": "Use screen-space postprocessing filters (HDR, Bloom, DOF, etc)",
    77             "parameters": { "renderer": "Postproc", "config": "postproc" }
     77            "parameters": { "config": "postproc", "renderer": "Postproc" }
    7878        },
    7979        {
    8080            "type": "dropdown",
     
    8686            "type": "boolean",
    8787            "label": "Shadows",
    8888            "tooltip": "Enable shadows",
    89             "parameters": { "renderer": "Shadows", "config": "shadows"},
     89            "parameters": {  "config": "shadows", "renderer": "Shadows" },
    9090            "dependencies": [ "shadowpcf" ]
    9191        },
    9292        {
     
    9393            "type": "boolean",
    9494            "label": "Shadow Filtering",
    9595            "tooltip": "Smooth shadows",
    96             "parameters": { "renderer": "ShadowPCF", "config": "shadowpcf" }
     96            "parameters": { "config": "shadowpcf", "renderer": "ShadowPCF" }
    9797        },
    9898        {
    9999            "type": "boolean",
    100100            "label": "Unit Silhouettes",
    101101            "tooltip": "Show outlines of units behind buildings",
    102             "parameters": { "renderer": "Silhouettes", "config": "silhouettes" }
     102            "parameters": { "config": "silhouettes", "renderer": "Silhouettes" }
    103103        },
    104104        {
    105105            "type": "boolean",
    106106            "label": "Particles",
    107107            "tooltip": "Enable particles",
    108             "parameters": { "renderer": "Particles", "config": "particles" }
     108            "parameters": { "config": "particles", "renderer": "Particles" }
    109109        },
    110110        {
    111111            "type": "invertedboolean",
    112112            "label": "Activate water effects",
    113113            "tooltip": "When OFF, use the lowest settings possible to render water. This makes other settings irrelevant.",
    114             "parameters": { "renderer": "WaterUgly", "config": "waterugly" },
     114            "parameters": { "config": "waterugly", "renderer": "WaterUgly" },
    115115            "dependencies": [ "waterfancyeffects", "waterrealdepth", "waterreflection", "waterrefraction", "watershadows" ]
    116116        },
    117117        {
     
    118118            "type": "boolean",
    119119            "label": "HQ Water Effects",
    120120            "tooltip": "Use higher-quality effects for water, rendering coastal waves, shore foam, and ships trails.",
    121             "parameters": { "renderer": "WaterFancyEffects", "config": "waterfancyeffects" }
     121            "parameters": { "config": "waterfancyeffects", "renderer": "WaterFancyEffects" }
    122122        },
    123123        {
    124124            "type": "boolean",
    125125            "label": "Real Water Depth",
    126126            "tooltip": "Use actual water depth in rendering calculations",
    127             "parameters": { "renderer": "WaterRealDepth", "config": "waterrealdepth" }
     127            "parameters": { "config": "waterrealdepth", "renderer": "WaterRealDepth" }
    128128        },
    129129        {
    130130            "type": "boolean",
    131131            "label": "Water Reflections",
    132132            "tooltip": "Allow water to reflect a mirror image",
    133             "parameters": { "renderer": "WaterReflection", "config": "waterreflection" }
     133            "parameters": { "config": "waterreflection", "renderer": "WaterReflection" }
    134134        },
    135135        {
    136136            "type": "boolean",
    137137            "label": "Water Refraction",
    138138            "tooltip": "Use a real water refraction map and not transparency",
    139             "parameters": { "renderer": "WaterRefraction", "config": "waterrefraction" }
     139            "parameters": { "config": "waterrefraction", "renderer": "WaterRefraction" }
    140140        },
    141141        {
    142142            "type": "boolean",
    143143            "label": "Shadows on Water",
    144144            "tooltip": "Cast shadows on water",
    145             "parameters": { "renderer": "WaterShadows", "config": "watershadows" }
     145            "parameters": { "config": "watershadows", "renderer": "WaterShadows" }
    146146        },
    147147        {
    148148            "type": "boolean",
    149149            "label": "Smooth LOS",
    150150            "tooltip": "Lift darkness and fog-of-war smoothly",
    151             "parameters": { "renderer": "SmoothLOS", "config": "smoothlos" }
     151            "parameters": { "config": "smoothlos", "renderer": "SmoothLOS" }
    152152        },
    153153        {
    154154            "type": "boolean",
    155155            "label": "Show Sky",
    156156            "tooltip": "Render Sky",
    157             "parameters": { "renderer": "ShowSky", "config": "showsky" }
     157            "parameters": { "config": "showsky", "renderer": "ShowSky" }
    158158        },
    159159        {
    160160            "type": "boolean",
  • binaries/data/mods/public/gui/options/options.xml

     
    6969                </object>
    7070            </repeat>
    7171        </object>
    72         <object name="loadOptions" type="button" style="ModernButtonRed" size="50%-170 100%-44 50%-70 100%-16" hotkey="cancel">
     72        <object name="resetChanges" type="button" style="ModernButtonRed" size="50%-236 100%-44 50%-136 100%-16">
     73            <translatableAttribute id="caption">Reset</translatableAttribute>
     74            <translatableAttribute id="tooltip">Resets user settings to their game default</translatableAttribute>
     75            <action on="Press">resetChanges();</action>
     76        </object>
     77        <object name="revertChanges" type="button" style="ModernButtonRed" size="50%-104 100%-44 50%-4 100%-16">
    7378            <translatableAttribute id="caption">Revert</translatableAttribute>
    74             <translatableAttribute id="tooltip">Revert to previous saved settings</translatableAttribute>
     79            <translatableAttribute id="tooltip">Reverts to previous saved settings</translatableAttribute>
    7580            <action on="Press">revertChanges();</action>
    7681        </object>
    77         <object name="saveOptions" type="button" style="ModernButtonRed" size="50%-62 100%-44 50%+38 100%-16">
     82        <object name="saveChanges" type="button" style="ModernButtonRed" size="50%+4 100%-44 50%+104 100%-16">
    7883            <translatableAttribute id="caption">Save</translatableAttribute>
    79             <translatableAttribute id="tooltip">Save changes</translatableAttribute>
     84            <translatableAttribute id="tooltip">Saves changes</translatableAttribute>
    8085            <action on="Press">saveChanges();</action>
    8186        </object>
    82         <object type="button" style="ModernButtonRed" size="50%+70 100%-44 50%+170 100%-16">
     87        <object type="button" style="ModernButtonRed" size="50%+136 100%-44 50%+236 100%-16">
    8388            <translatableAttribute id="caption">Close</translatableAttribute>
    8489            <translatableAttribute id="tooltip">Unsaved changes affect this session only</translatableAttribute>
    8590            <action on="Press">closePage();</action>
  • source/ps/ConfigDB.cpp

     
    2929typedef std::map<CStr, CConfigValueSet> TConfigMap;
    3030TConfigMap CConfigDB::m_Map[CFG_LAST];
    3131VfsPath CConfigDB::m_ConfigFile[CFG_LAST];
     32bool CConfigDB::m_HasChanges[CFG_LAST];
    3233
    3334static pthread_mutex_t cfgdb_mutex = PTHREAD_MUTEX_INITIALIZER;
    3435
     
    114115GETVAL(std::string)
    115116#undef GETVAL
    116117
     118bool CConfigDB::HasChanges(EConfigNamespace ns) const
     119{
     120    CHECK_NS(false);
     121
     122    CScopeLock s(&cfgdb_mutex);
     123    return m_HasChanges[ns];
     124}
     125
     126void CConfigDB::SetChanges(EConfigNamespace ns, bool& value)
     127{
     128    CHECK_NS(;);
     129
     130    CScopeLock s(&cfgdb_mutex);
     131    m_HasChanges[ns] = value;
     132}
     133
    117134void CConfigDB::GetValues(EConfigNamespace ns, const CStr& name, CConfigValueSet& values) const
    118135{
    119136    CHECK_NS(;);
     
    195212    SetValueString(ns, name, valueString);
    196213}
    197214
     215void CConfigDB::RemoveValue(EConfigNamespace ns, const CStr& name)
     216{
     217    CHECK_NS(;);
     218
     219    CScopeLock s(&cfgdb_mutex);
     220    TConfigMap::iterator it = m_Map[ns].find(name);
     221    if (it == m_Map[ns].end())
     222        return;
     223    m_Map[ns].erase(it);
     224}
     225
    198226void CConfigDB::SetConfigFile(EConfigNamespace ns, const VfsPath& path)
    199227{
    200228    CHECK_NS(;);
     
    384412    char* pos = (char*)buf.get();
    385413    for (const std::pair<CStr, CConfigValueSet>& p : m_Map[ns])
    386414    {
    387         if (boost::algorithm::starts_with(p.first, "nosave."))
    388             continue;
    389415        size_t i;
    390416        pos += sprintf(pos, "%s = ", p.first.c_str());
    391417        for (i = 0; i < p.second.size() - 1; ++i)
  • source/ps/ConfigDB.h

     
    5252{
    5353    static std::map<CStr, CConfigValueSet> m_Map[];
    5454    static VfsPath m_ConfigFile[];
     55    static bool m_HasChanges[];
    5556
    5657public:
    5758    CConfigDB();
     
    7273    void GetValue(EConfigNamespace ns, const CStr& name, std::string& value);
    7374
    7475    /**
     76     * Returns true if changed with respect to last write on file
     77     */
     78    bool HasChanges(EConfigNamespace ns) const;
     79
     80    void SetChanges(EConfigNamespace ns, bool& value);
     81
     82    /**
    7583     * Attempt to retrieve a vector of values corresponding to the given setting;
    7684     * will search CFG_COMMAND first, and then all namespaces from the specified
    7785     * namespace down.
     
    98106    void SetValueString(EConfigNamespace ns, const CStr& name, const CStr& value);
    99107
    100108    void SetValueBool(EConfigNamespace ns, const CStr& name, const bool value);
     109
     110    /**
     111     * Remove a config value in the specified namespace.
     112     */
     113    void RemoveValue(EConfigNamespace ns, const CStr& name);
    101114   
    102115    /**
    103116     * Set the path to the config file used to populate the specified namespace
  • source/ps/scripting/JSInterface_ConfigDB.cpp

     
    4242    return true;
    4343}
    4444
     45bool JSI_ConfigDB::HasChanges(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString)
     46{
     47    EConfigNamespace cfgNs;
     48    if (!GetConfigNamespace(cfgNsString, cfgNs))
     49        return false;
     50
     51    return g_ConfigDB.HasChanges(cfgNs);
     52}
     53
     54bool JSI_ConfigDB::SetChanges(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, bool value)
     55{
     56    EConfigNamespace cfgNs;
     57    if (!GetConfigNamespace(cfgNsString, cfgNs))
     58        return false;
     59
     60    g_ConfigDB.SetChanges(cfgNs, value);
     61    return true;
     62}
     63
    4564std::string JSI_ConfigDB::GetValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const std::string& name)
    4665{
    4766    EConfigNamespace cfgNs;
     
    6382    return true;
    6483}
    6584
     85bool JSI_ConfigDB::RemoveValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const std::string& name)
     86{
     87    EConfigNamespace cfgNs;
     88    if (!GetConfigNamespace(cfgNsString, cfgNs))
     89        return false;
     90
     91    g_ConfigDB.RemoveValue(cfgNs, name);
     92    return true;
     93}
     94
    6695bool JSI_ConfigDB::WriteFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const Path& path)
    6796{
    6897    EConfigNamespace cfgNs;
     
    105134
    106135void JSI_ConfigDB::RegisterScriptFunctions(ScriptInterface& scriptInterface)
    107136{
     137    scriptInterface.RegisterFunction<bool, std::wstring, &JSI_ConfigDB::HasChanges>("ConfigDB_HasChanges");
     138    scriptInterface.RegisterFunction<bool, std::wstring, bool, &JSI_ConfigDB::SetChanges>("ConfigDB_SetChanges");
    108139    scriptInterface.RegisterFunction<std::string, std::wstring, std::string, &JSI_ConfigDB::GetValue>("ConfigDB_GetValue");
    109140    scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, &JSI_ConfigDB::CreateValue>("ConfigDB_CreateValue");
     141    scriptInterface.RegisterFunction<bool, std::wstring, std::string, &JSI_ConfigDB::RemoveValue>("ConfigDB_RemoveValue");
    110142    scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::WriteFile>("ConfigDB_WriteFile");
    111143    scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, Path, &JSI_ConfigDB::WriteValueToFile>("ConfigDB_WriteValueToFile");
    112144    scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::SetFile>("ConfigDB_SetFile");
  • source/ps/scripting/JSInterface_ConfigDB.h

     
    2424namespace JSI_ConfigDB
    2525{
    2626    bool GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs);
     27    bool HasChanges(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString);
     28    bool SetChanges(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, bool value);
    2729    std::string GetValue(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name);
    2830    bool CreateValue(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value);
     31    bool RemoveValue(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name);
    2932    bool WriteFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const Path& path);
    3033    bool WriteValueToFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path);
    3134    bool Reload(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString);