Ticket #3737: optionsDependances.patch

File optionsDependances.patch, 9.1 KB (added by mimo, 8 years ago)

I've attached a patch which reorganizes the options, reordering them a bit as proposed in fabio's patch in #2596, and adding some dependences between them (options are now disabled when dependent on an other option which is not active).

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

     
    1 var g_hasCallback = false;
    2 var g_controls;
     1var g_HasCallback = false;
     2var g_Controls;
    33
    44function init(data)
    55{
    66    if (data && data.callback)
    7         g_hasCallback = true;
     7        g_HasCallback = true;
    88    let revert = data && data.revert;
    9     g_controls = [];
     9    g_Controls = {};
    1010
    1111    var options = Engine.ReadJSONFile("gui/options/options.json");
    1212    for (let category of Object.keys(options))
     
    1515        for (let i = 0; i < options[category].length; ++i)
    1616        {
    1717            let option = options[category][i];
    18             if (!option.label)
     18            if (!option.label || !option.parameters || !option.parameters.config)
    1919                continue;
    2020            let body = Engine.GetGUIObjectByName(category + "[" + i + "]");
    2121            let label = Engine.GetGUIObjectByName(category + "Label[" + i + "]");
    22             setupControl(option, i, category, revert);
     22            let config = option.parameters.config;
     23            g_Controls[config] = { "control": setupControl(option, i, category, revert), "type": option.type };
     24            if (option.dependencies)
     25                g_Controls[config].dependencies = option.dependencies;
    2326            label.caption = translate(option.label);
    2427            label.tooltip = option.tooltip ? translate(option.tooltip) : "";
    2528            // Move each element to the correct place.
    26             if (i > 0)
     29            if (lastSize)
    2730            {
    2831                let newSize = new GUISize();
    2932                newSize.left = lastSize.left;
     
    3538            }
    3639            else
    3740                lastSize = body.size;
     41            // small right shift of options which depends on another one
     42            for (let opt of options[category])
     43            {
     44                if (!opt.label || !opt.parameters || !opt.parameters.config)
     45                    continue;
     46                if (!opt.dependencies || opt.dependencies.indexOf(config) === -1)
     47                    continue;
     48                label.caption = "       " + label.caption;
     49                break;
     50            }
    3851            // Show element.
    3952            body.hidden = false;
    4053        }
    4154    }
    4255
     56    updateDependencies();
    4357    if (!revert)
    4458        updateStatus();
    4559}
     
    5872    switch (option.type)
    5973    {
    6074    case "boolean":
     75    case "antiboolean":
    6176        // More space for the label
    6277        let text = Engine.GetGUIObjectByName(category + "Label[" + i + "]");
    6378        let size = text.size;
     
    7893                if (checked === undefined || revert)
    7994                    checked = Engine.ConfigDB_GetValue("user", keyConfig) === "true";
    8095                else if ((Engine.ConfigDB_GetValue("user", keyConfig) === "true") !== checked)
     96                {
    8197                    Engine.ConfigDB_CreateValue("user", keyConfig, String(checked));
     98                    updateStatus(true);
     99                }
    82100                break;
    83101            case "renderer":
    84102                keyRenderer = option.parameters.renderer;
     
    97115                warn("Unknown option source type '" + param + "'");
    98116            }
    99117        }
     118        // antiboolean when we want to display the opposite of the flag value
     119        var anti = false;
     120        if (option.type === "antiboolean")
     121        {
     122            anti = true;
     123            checked = !checked;
     124        }
    100125
    101         onUpdate = function(keyRenderer, keyConfig)
     126        onUpdate = function(keyRenderer, keyConfig, anti)
    102127        {
    103128            return function()
    104129            {
     130                let val = anti ? !this.checked : this.checked;
    105131                if (keyRenderer)
    106                     Engine["Renderer_Set" + keyRenderer + "Enabled"](this.checked);
     132                    Engine["Renderer_Set" + keyRenderer + "Enabled"](val);
    107133                if (keyConfig)
    108                     Engine.ConfigDB_CreateValue("user", keyConfig, String(this.checked));
     134                    Engine.ConfigDB_CreateValue("user", keyConfig, String(val));
     135                updateDependencies();
    109136                updateStatus(true);
    110137            };
    111         }(keyRenderer, keyConfig);
     138        }(keyRenderer, keyConfig, anti);
    112139
    113140        // Load final data to the control element.
    114141        control.checked = checked;
     
    143170                maxval = option.parameters.max;
    144171                break;
    145172            default:
    146                 warn("Unknown option source type '" + action + "'");
     173                warn("Unknown option source type '" + param + "'");
    147174            }
    148175        }
    149176
     
    164191                Engine.ConfigDB_CreateValue("user", key, this.caption);
    165192                if (functionBody)
    166193                    Engine[functionBody](+this.caption);
     194                updateDependencies();
    167195                updateStatus(true);
    168196            };
    169197        }(key, functionBody, minval, maxval);
     
    171199        control.caption = caption;
    172200        control.onPress = onUpdate;
    173201        control.onMouseLeave = onUpdate;
    174         g_controls.push(control);
    175202        break;
    176203    case "dropdown":
    177204        control = Engine.GetGUIObjectByName(category + "Dropdown[" + i + "]");
     
    199226                control.list_data = option.parameters.list_data;
    200227                break;
    201228            default:
    202                 warn("Unknown option source type '" + action + "'");
     229                warn("Unknown option source type '" + param + "'");
    203230            }
    204231        }
    205232
     
    211238                if (key === "materialmgr.quality")
    212239                    val = val == 0 ? 2 : val == 1 ? 5 : 8;
    213240                Engine.ConfigDB_CreateValue("user", key, val);
     241                updateDependencies();
    214242                updateStatus(true);
    215243            };
    216244        }(key);
     
    243271 */
    244272function registerChanges()
    245273{
    246     for (let control of g_controls)
    247         control.onPress();
     274    for (let item in g_Controls)
     275        if (g_Controls[item].type === "number" || g_Controls[item].type === "string")
     276            g_Controls[item].control.onPress();
    248277}
    249278
     279function updateDependencies()
     280{
     281    for (let item in g_Controls)
     282    {
     283        let control = g_Controls[item];
     284        if (control.type !== "boolean" && control.type !== "antiboolean" || !control.dependencies)
     285            continue;
     286        for (let dependency of control.dependencies)
     287            g_Controls[dependency].control.enabled = control.control.checked;
     288    }
     289}
     290
    250291function revertChanges()
    251292{
    252293    Engine.ConfigDB_Reload("user");
     
    280321
    281322function closePageWithoutConfirmation()
    282323{
    283     if (g_hasCallback)
     324    if (g_HasCallback)
    284325        Engine.PopGuiPageCB();
    285326    else
    286327        Engine.PopGuiPage();
  • binaries/data/mods/public/gui/options/options.json

     
    7171            "parameters": { "renderer": "Postproc", "config": "postproc" }
    7272        },
    7373        {
     74            "type": "dropdown",
     75            "label": "Graphics quality",
     76            "tooltip": "Graphics quality. REQUIRES GAME RESTART",
     77            "parameters": { "list": [ "Low", "Medium", "High" ], "config": "materialmgr.quality" }
     78        },
     79        {
    7480            "type": "boolean",
    7581            "label": "Shadows",
    7682            "tooltip": "Enable shadows",
    77             "parameters": { "renderer": "Shadows", "config": "shadows"}
     83            "parameters": { "renderer": "Shadows", "config": "shadows"},
     84            "dependencies": [ "shadowpcf" ]
    7885        },
    7986        {
    8087            "type": "boolean",
    81             "label": "Particles",
    82             "tooltip": "Enable particles",
    83             "parameters": { "renderer": "Particles", "config": "particles" }
     88            "label": "Shadow Filtering",
     89            "tooltip": "Smooth shadows",
     90            "parameters": { "renderer": "ShadowPCF", "config": "shadowpcf" }
    8491        },
    8592        {
    8693            "type": "boolean",
    87             "label": "Show Sky",
    88             "tooltip": "Render Sky",
    89             "parameters": { "renderer": "ShowSky", "config": "showsky" }
    90         },
    91         {
    92             "type": "boolean",
    93             "label": "Smooth LOS",
    94             "tooltip": "Lift darkness and fog-of-war smoothly",
    95             "parameters": { "renderer": "SmoothLOS", "config": "smoothlos" }
    96         },
    97         {
    98             "type": "boolean",
    9994            "label": "Unit Silhouettes",
    10095            "tooltip": "Show outlines of units behind buildings",
    10196            "parameters": { "renderer": "Silhouettes", "config": "silhouettes" }
     
    10297        },
    10398        {
    10499            "type": "boolean",
    105             "label": "Shadow Filtering",
    106             "tooltip": "Smooth shadows",
    107             "parameters": { "renderer": "ShadowPCF", "config": "shadowpcf" }
     100            "label": "Particles",
     101            "tooltip": "Enable particles",
     102            "parameters": { "renderer": "Particles", "config": "particles" }
    108103        },
    109104        {
    110             "type": "boolean",
    111             "label": "Fast & Ugly Water",
    112             "tooltip": "Use the lowest settings possible to render water. This makes other settings irrelevant.",
    113             "parameters": { "renderer": "WaterUgly", "config": "waterugly" }
     105            "type": "antiboolean",
     106            "label": "Activate water effects",
     107            "tooltip": "When OFF, use the lowest settings possible to render water. This makes other settings irrelevant.",
     108            "parameters": { "renderer": "WaterUgly", "config": "waterugly" },
     109            "dependencies": [ "waterfancyeffects", "waterrealdepth", "waterreflection", "waterrefraction", "watershadows" ]
    114110        },
    115111        {
    116112            "type": "boolean",
     
    144140        },
    145141        {
    146142            "type": "boolean",
     143            "label": "Smooth LOS",
     144            "tooltip": "Lift darkness and fog-of-war smoothly",
     145            "parameters": { "renderer": "SmoothLOS", "config": "smoothlos" }
     146        },
     147        {
     148            "type": "boolean",
     149            "label": "Show Sky",
     150            "tooltip": "Render Sky",
     151            "parameters": { "renderer": "ShowSky", "config": "showsky" }
     152        },
     153        {
     154            "type": "boolean",
    147155            "label": "VSync",
    148156            "tooltip": "Run vertical sync to fix screen tearing. REQUIRES GAME RESTART",
    149157            "parameters": { "config": "vsync" }
     
    153161            "label": "Limit FPS in Menus",
    154162            "tooltip": "Limit FPS to 50 in all menus, to save power.",
    155163            "parameters": { "config": "gui.menu.limitfps" }
    156         },
    157         {
    158             "type": "dropdown",
    159             "label": "Graphics quality",
    160             "tooltip": "Graphics quality. REQUIRES GAME RESTART",
    161             "parameters": { "list": [ "Low", "Medium", "High" ], "config": "materialmgr.quality" }
    162 
    163164        }
    164165    ],
    165166    "soundSetting":