Ticket #3737: optionsReset-v4.patch
File optionsReset-v4.patch, 20.1 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/gui/options/options.js
5 5 { 6 6 if (data && data.callback) 7 7 g_HasCallback = true; 8 let revert = data && data.revert;9 8 g_Controls = {}; 10 9 11 10 var options = Engine.ReadJSONFile("gui/options/options.json"); … … 21 20 let label = Engine.GetGUIObjectByName(category + "Label[" + i + "]"); 22 21 let config = option.parameters.config; 23 22 g_Controls[config] = { 24 "control": setupControl(option, i, category , revert),23 "control": setupControl(option, i, category), 25 24 "type": option.type, 26 "dependencies": option.dependencies || undefined 25 "dependencies": option.dependencies || undefined, 26 "parameters": option.parameters 27 27 }; 28 28 label.caption = translate(option.label); 29 29 label.tooltip = option.tooltip ? translate(option.tooltip) : ""; … … 47 47 continue; 48 48 if (!opt.dependencies || opt.dependencies.indexOf(config) === -1) 49 49 continue; 50 label.caption = " 50 label.caption = " " + label.caption; 51 51 break; 52 52 } 53 53 // Show element. … … 55 55 } 56 56 } 57 57 58 updateDependencies(); 59 if (!revert) 60 updateStatus(); 58 updateOptionPanel(); 61 59 } 62 60 63 61 /** … … 66 64 * @param option Structure containing the data to setup an option. 67 65 * @param prefix Prefix to use when accessing control, for example "generalSetting" when the tickbox name is generalSettingTickbox[i]. 68 66 */ 69 function setupControl(option, i, category , revert)67 function setupControl(option, i, category) 70 68 { 71 69 var control; 72 70 var onUpdate; … … 92 90 { 93 91 case "config": 94 92 keyConfig = option.parameters.config; 95 if (checked === undefined || revert)93 if (checked === undefined) 96 94 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); 102 97 break; 103 98 case "renderer": 104 99 keyRenderer = option.parameters.renderer; … … 111 106 if (checked === undefined) 112 107 checked = Engine["Renderer_Get" + keyRenderer + "Enabled"](); 113 108 else if (Engine["Renderer_Get" + keyRenderer + "Enabled"]() !== checked) 109 { 110 warn(" incompatible renderer option value for " + keyRenderer); 114 111 Engine["Renderer_Set" + keyRenderer + "Enabled"](checked); 112 } 115 113 break; 116 114 default: 117 115 warn("Unknown option source type '" + param + "'"); … … 130 128 if (keyRenderer) 131 129 Engine["Renderer_Set" + keyRenderer + "Enabled"](val); 132 130 if (keyConfig) 131 { 133 132 Engine.ConfigDB_CreateValue("user", keyConfig, String(val)); 134 updateDependencies(); 135 updateStatus(true); 133 Engine.ConfigDB_SetChanges("user", true); 134 } 135 updateOptionPanel(); 136 136 }; 137 137 }(keyRenderer, keyConfig, inverted); 138 138 … … 188 188 if (Engine.ConfigDB_GetValue("user", key) === this.caption) 189 189 return; 190 190 Engine.ConfigDB_CreateValue("user", key, this.caption); 191 Engine.ConfigDB_SetChanges("user", true); 191 192 if (functionBody) 192 193 Engine[functionBody](+this.caption); 193 updateDependencies(); 194 updateStatus(true); 194 updateOptionPanel(); 195 195 }; 196 196 }(key, functionBody, minval, maxval); 197 197 … … 201 201 break; 202 202 case "dropdown": 203 203 control = Engine.GetGUIObjectByName(category + "Dropdown[" + i + "]"); 204 control.onSelectionChange = function(){}; // just the time to setup the value 204 205 var caption; 205 206 var key; 206 207 var functionBody; … … 237 238 if (key === "materialmgr.quality") 238 239 val = val == 0 ? 2 : val == 1 ? 5 : 8; 239 240 Engine.ConfigDB_CreateValue("user", key, val); 240 updateDependencies();241 update Status(true);241 Engine.ConfigDB_SetChanges("user", true); 242 updateOptionPanel(); 242 243 }; 243 244 }(key); 244 245 … … 254 255 return control; 255 256 } 256 257 257 function update Status(val)258 function updateOptionPanel() 258 259 { 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; 263 266 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; 266 275 } 267 276 268 277 /** … … 275 284 g_Controls[item].control.onPress(); 276 285 } 277 286 278 function updateDependencies()287 function resetChanges() 279 288 { 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 295 function reallyResetChanges() 296 { 280 297 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); 285 299 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(); 289 302 } 290 303 291 304 function revertChanges() 292 305 { 293 306 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(); 296 325 } 297 326 298 327 function saveChanges() … … 299 328 { 300 329 registerChanges(); 301 330 Engine.ConfigDB_WriteFile("user", "config/user.cfg"); 302 updateStatus(false); 331 Engine.ConfigDB_SetChanges("user", false); 332 updateOptionPanel(); 303 333 } 304 334 305 335 /** … … 308 338 function closePage() 309 339 { 310 340 registerChanges(); 311 if (Engine.ConfigDB_ GetValue("user", "nosave.haschanges") === "true")341 if (Engine.ConfigDB_HasChanges("user")) 312 342 { 313 343 let btCaptions = [translate("No"), translate("Yes")]; 314 344 let btCode = [null, function(){ closePageWithoutConfirmation(); }]; -
binaries/data/mods/public/gui/options/options.json
68 68 "type": "boolean", 69 69 "label": "Prefer GLSL", 70 70 "tooltip": "Use OpenGL 2.0 shaders (recommended)", 71 "parameters": { " renderer": "PreferGLSL", "config": "preferglsl" }71 "parameters": { "config": "preferglsl", "renderer": "PreferGLSL" } 72 72 }, 73 73 { 74 74 "type": "boolean", 75 75 "label": "Post Processing", 76 76 "tooltip": "Use screen-space postprocessing filters (HDR, Bloom, DOF, etc)", 77 "parameters": { " renderer": "Postproc", "config": "postproc" }77 "parameters": { "config": "postproc", "renderer": "Postproc" } 78 78 }, 79 79 { 80 80 "type": "dropdown", … … 86 86 "type": "boolean", 87 87 "label": "Shadows", 88 88 "tooltip": "Enable shadows", 89 "parameters": { "renderer": "Shadows", "config": "shadows"},89 "parameters": { "config": "shadows", "renderer": "Shadows" }, 90 90 "dependencies": [ "shadowpcf" ] 91 91 }, 92 92 { … … 93 93 "type": "boolean", 94 94 "label": "Shadow Filtering", 95 95 "tooltip": "Smooth shadows", 96 "parameters": { " renderer": "ShadowPCF", "config": "shadowpcf" }96 "parameters": { "config": "shadowpcf", "renderer": "ShadowPCF" } 97 97 }, 98 98 { 99 99 "type": "boolean", 100 100 "label": "Unit Silhouettes", 101 101 "tooltip": "Show outlines of units behind buildings", 102 "parameters": { " renderer": "Silhouettes", "config": "silhouettes" }102 "parameters": { "config": "silhouettes", "renderer": "Silhouettes" } 103 103 }, 104 104 { 105 105 "type": "boolean", 106 106 "label": "Particles", 107 107 "tooltip": "Enable particles", 108 "parameters": { " renderer": "Particles", "config": "particles" }108 "parameters": { "config": "particles", "renderer": "Particles" } 109 109 }, 110 110 { 111 111 "type": "invertedboolean", 112 112 "label": "Activate water effects", 113 113 "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" }, 115 115 "dependencies": [ "waterfancyeffects", "waterrealdepth", "waterreflection", "waterrefraction", "watershadows" ] 116 116 }, 117 117 { … … 118 118 "type": "boolean", 119 119 "label": "HQ Water Effects", 120 120 "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" } 122 122 }, 123 123 { 124 124 "type": "boolean", 125 125 "label": "Real Water Depth", 126 126 "tooltip": "Use actual water depth in rendering calculations", 127 "parameters": { " renderer": "WaterRealDepth", "config": "waterrealdepth" }127 "parameters": { "config": "waterrealdepth", "renderer": "WaterRealDepth" } 128 128 }, 129 129 { 130 130 "type": "boolean", 131 131 "label": "Water Reflections", 132 132 "tooltip": "Allow water to reflect a mirror image", 133 "parameters": { " renderer": "WaterReflection", "config": "waterreflection" }133 "parameters": { "config": "waterreflection", "renderer": "WaterReflection" } 134 134 }, 135 135 { 136 136 "type": "boolean", 137 137 "label": "Water Refraction", 138 138 "tooltip": "Use a real water refraction map and not transparency", 139 "parameters": { " renderer": "WaterRefraction", "config": "waterrefraction" }139 "parameters": { "config": "waterrefraction", "renderer": "WaterRefraction" } 140 140 }, 141 141 { 142 142 "type": "boolean", 143 143 "label": "Shadows on Water", 144 144 "tooltip": "Cast shadows on water", 145 "parameters": { " renderer": "WaterShadows", "config": "watershadows" }145 "parameters": { "config": "watershadows", "renderer": "WaterShadows" } 146 146 }, 147 147 { 148 148 "type": "boolean", 149 149 "label": "Smooth LOS", 150 150 "tooltip": "Lift darkness and fog-of-war smoothly", 151 "parameters": { " renderer": "SmoothLOS", "config": "smoothlos" }151 "parameters": { "config": "smoothlos", "renderer": "SmoothLOS" } 152 152 }, 153 153 { 154 154 "type": "boolean", 155 155 "label": "Show Sky", 156 156 "tooltip": "Render Sky", 157 "parameters": { " renderer": "ShowSky", "config": "showsky" }157 "parameters": { "config": "showsky", "renderer": "ShowSky" } 158 158 }, 159 159 { 160 160 "type": "boolean", -
binaries/data/mods/public/gui/options/options.xml
69 69 </object> 70 70 </repeat> 71 71 </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"> 73 78 <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> 75 80 <action on="Press">revertChanges();</action> 76 81 </object> 77 <object name="save Options" type="button" style="ModernButtonRed" size="50%-62 100%-44 50%+38100%-16">82 <object name="saveChanges" type="button" style="ModernButtonRed" size="50%+4 100%-44 50%+104 100%-16"> 78 83 <translatableAttribute id="caption">Save</translatableAttribute> 79 <translatableAttribute id="tooltip">Save changes</translatableAttribute>84 <translatableAttribute id="tooltip">Saves changes</translatableAttribute> 80 85 <action on="Press">saveChanges();</action> 81 86 </object> 82 <object type="button" style="ModernButtonRed" size="50%+ 70 100%-44 50%+170100%-16">87 <object type="button" style="ModernButtonRed" size="50%+136 100%-44 50%+236 100%-16"> 83 88 <translatableAttribute id="caption">Close</translatableAttribute> 84 89 <translatableAttribute id="tooltip">Unsaved changes affect this session only</translatableAttribute> 85 90 <action on="Press">closePage();</action> -
source/ps/ConfigDB.cpp
29 29 typedef std::map<CStr, CConfigValueSet> TConfigMap; 30 30 TConfigMap CConfigDB::m_Map[CFG_LAST]; 31 31 VfsPath CConfigDB::m_ConfigFile[CFG_LAST]; 32 bool CConfigDB::m_HasChanges[CFG_LAST]; 32 33 33 34 static pthread_mutex_t cfgdb_mutex = PTHREAD_MUTEX_INITIALIZER; 34 35 … … 114 115 GETVAL(std::string) 115 116 #undef GETVAL 116 117 118 bool CConfigDB::HasChanges(EConfigNamespace ns) const 119 { 120 CHECK_NS(false); 121 122 CScopeLock s(&cfgdb_mutex); 123 return m_HasChanges[ns]; 124 } 125 126 void CConfigDB::SetChanges(EConfigNamespace ns, bool& value) 127 { 128 CHECK_NS(;); 129 130 CScopeLock s(&cfgdb_mutex); 131 m_HasChanges[ns] = value; 132 } 133 117 134 void CConfigDB::GetValues(EConfigNamespace ns, const CStr& name, CConfigValueSet& values) const 118 135 { 119 136 CHECK_NS(;); … … 195 212 SetValueString(ns, name, valueString); 196 213 } 197 214 215 void 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 198 226 void CConfigDB::SetConfigFile(EConfigNamespace ns, const VfsPath& path) 199 227 { 200 228 CHECK_NS(;); … … 384 412 char* pos = (char*)buf.get(); 385 413 for (const std::pair<CStr, CConfigValueSet>& p : m_Map[ns]) 386 414 { 387 if (boost::algorithm::starts_with(p.first, "nosave."))388 continue;389 415 size_t i; 390 416 pos += sprintf(pos, "%s = ", p.first.c_str()); 391 417 for (i = 0; i < p.second.size() - 1; ++i) -
source/ps/ConfigDB.h
52 52 { 53 53 static std::map<CStr, CConfigValueSet> m_Map[]; 54 54 static VfsPath m_ConfigFile[]; 55 static bool m_HasChanges[]; 55 56 56 57 public: 57 58 CConfigDB(); … … 72 73 void GetValue(EConfigNamespace ns, const CStr& name, std::string& value); 73 74 74 75 /** 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 /** 75 83 * Attempt to retrieve a vector of values corresponding to the given setting; 76 84 * will search CFG_COMMAND first, and then all namespaces from the specified 77 85 * namespace down. … … 98 106 void SetValueString(EConfigNamespace ns, const CStr& name, const CStr& value); 99 107 100 108 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); 101 114 102 115 /** 103 116 * Set the path to the config file used to populate the specified namespace -
source/ps/scripting/JSInterface_ConfigDB.cpp
42 42 return true; 43 43 } 44 44 45 bool 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 54 bool 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 45 64 std::string JSI_ConfigDB::GetValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const std::string& name) 46 65 { 47 66 EConfigNamespace cfgNs; … … 63 82 return true; 64 83 } 65 84 85 bool 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 66 95 bool JSI_ConfigDB::WriteFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& cfgNsString, const Path& path) 67 96 { 68 97 EConfigNamespace cfgNs; … … 105 134 106 135 void JSI_ConfigDB::RegisterScriptFunctions(ScriptInterface& scriptInterface) 107 136 { 137 scriptInterface.RegisterFunction<bool, std::wstring, &JSI_ConfigDB::HasChanges>("ConfigDB_HasChanges"); 138 scriptInterface.RegisterFunction<bool, std::wstring, bool, &JSI_ConfigDB::SetChanges>("ConfigDB_SetChanges"); 108 139 scriptInterface.RegisterFunction<std::string, std::wstring, std::string, &JSI_ConfigDB::GetValue>("ConfigDB_GetValue"); 109 140 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"); 110 142 scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::WriteFile>("ConfigDB_WriteFile"); 111 143 scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, Path, &JSI_ConfigDB::WriteValueToFile>("ConfigDB_WriteValueToFile"); 112 144 scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::SetFile>("ConfigDB_SetFile"); -
source/ps/scripting/JSInterface_ConfigDB.h
24 24 namespace JSI_ConfigDB 25 25 { 26 26 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); 27 29 std::string GetValue(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name); 28 30 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); 29 32 bool WriteFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const Path& path); 30 33 bool WriteValueToFile(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString, const std::string& name, const std::string& value, const Path& path); 31 34 bool Reload(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& cfgNsString);