Ticket #3511: cleanOptions.2.diff
File cleanOptions.2.diff, 9.0 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/gui/options/options.js
87 87 body.hidden = false; 88 88 } 89 89 } 90 91 if (!reload) 92 updateChanges(); 90 93 } 91 94 92 95 /** … … 98 101 function setupControl(option, i, prefix, reload) 99 102 { 100 103 var control; 101 var onPress = function(){ g_hasChanges = true; };102 104 103 105 switch (option[3]) 104 106 { … … 110 112 text.size = size; 111 113 control = Engine.GetGUIObjectByName(prefix + "Tickbox[" + i + "]"); 112 114 var checked; 113 // Different option action load and save differently, so this switch is needed. 115 var keyRenderer; 116 var keyConfig; 117 var functionBody; 118 114 119 for (let action of Object.keys(option[2])) 115 120 { 116 121 switch (action) 117 122 { 118 123 case "config": 119 // Load initial value if not yet loaded. 120 if (!checked || typeof checked != "boolean") 121 checked = Engine.ConfigDB_GetValue("user", option[2][action]) === "true"; 122 // Hacky macro to create the callback. 123 var callback = function(key) 124 { 125 return function() 126 Engine.ConfigDB_CreateValue("user", key, String(this.checked)); 127 }(option[2][action]); 128 // Merge the new callback with any existing callbacks. 129 onPress = mergeFunctions(callback, onPress); 124 keyConfig = option[2].config; 125 if (checked === undefined || reload) 126 checked = Engine.ConfigDB_GetValue("user", keyConfig) === "true"; 127 else if ((Engine.ConfigDB_GetValue("user", keyConfig) === "true") !== checked) 128 Engine.ConfigDB_CreateValue("user", keyConfig, String(checked)); 130 129 break; 131 130 case "renderer": 132 // If reloading, config values have priority, otherwise load initial value if not yet loaded 133 if (reload && option[2].config) 134 { 135 checked = Engine.ConfigDB_GetValue("user", option[2].config) === "true"; 136 let rendererChecked = eval("Engine.Renderer_Get" + option[2].renderer + "Enabled()"); 137 if (rendererChecked != checked) 138 eval("Engine.Renderer_Set" + option[2].renderer + "Enabled(" + checked + ")"); 139 } 140 else if (!checked || typeof checked != "boolean") 141 checked = eval("Engine.Renderer_Get" + option[2][action] + "Enabled()"); 142 // Hacky macro to create the callback (updating also the config value if any). 143 var callback = function(key, keyConfig) 144 { 145 return function() 146 { 147 eval("Engine.Renderer_Set" + key + "Enabled(" + this.checked + ")"); 148 if (keyConfig) 149 Engine.ConfigDB_CreateValue("user", keyConfig, String(this.checked)); 150 }; 151 }(option[2][action], option[2].config); 152 // Merge the new callback with any existing callbacks. 153 onPress = mergeFunctions(callback, onPress); 131 keyRenderer = option[2].renderer; 132 if (checked === undefined) 133 checked = eval("Engine.Renderer_Get" + keyRenderer + "Enabled()"); 134 else if (eval("Engine.Renderer_Get" + keyRenderer + "Enabled()") !== checked) 135 eval("Engine.Renderer_Set" + keyRenderer + "Enabled(" + checked + ")"); 154 136 break; 155 137 case "function": 156 138 // This allows for doing low-level actions, like hiding/showing UI elements. 157 onPress = mergeFunctions(eval("function(){" + option[2][action] + "}"), onPress);139 functionBody = option[2].function; 158 140 break; 159 141 default: 160 142 warn("Unknown option source type '" + action + "'"); 161 143 } 162 144 } 145 146 var onPress = function(keyRenderer, keyConfig, functionBody) 147 { 148 return function() 149 { 150 if (keyRenderer) 151 eval("Engine.Renderer_Set" + keyRenderer + "Enabled(" + this.checked + ")"); 152 if (keyConfig) 153 Engine.ConfigDB_CreateValue("user", keyConfig, String(this.checked)); 154 if (functionBody) 155 eval(functionBody); 156 updateChanges(true); 157 }; 158 }(keyRenderer, keyConfig, functionBody); 159 163 160 // Load final data to the control element. 164 161 control.checked = checked; 165 162 control.onPress = onPress; … … 169 166 case "string": 170 167 control = Engine.GetGUIObjectByName(prefix + "Input[" + i + "]"); 171 168 var caption; 169 var key; 170 var functionBody; 171 172 172 for (let action of Object.keys(option[2])) 173 173 { 174 174 switch (action) 175 175 { 176 176 case "config": 177 onPress = function(){}; 178 caption = Engine.ConfigDB_GetValue("user", option[2][action]); 179 // Hacky macro to create the callback. 180 var callback = function(key) 181 { 182 return function() 183 { 184 if (Engine.ConfigDB_GetValue("user", key) == this.caption) 185 return; 186 Engine.ConfigDB_CreateValue("user", key, String(this.caption)); 187 g_hasChanges = true; 188 }; 189 }(option[2][action]); 190 // Merge the new callback with any existing callbacks. 191 onPress = mergeFunctions(callback, onPress); 177 key = option[2].config; 178 caption = Engine.ConfigDB_GetValue("user", key); 192 179 break; 193 180 case "function": 194 181 // This allows for doing low-level actions, like hiding/showing UI elements. 195 onPress = mergeFunctions(function(){eval(option[2][action]);}, onPress);182 functionBody = option[2].function; 196 183 break; 197 184 default: 198 185 warn("Unknown option source type '" + action + "'"); 199 186 } 200 187 } 188 189 // as we use MouseLeave events, we must ensure that something has been modified 190 var onMouseLeave = function(key, functionBody) 191 { 192 return function() 193 { 194 if (Engine.ConfigDB_GetValue("user", key) === this.caption) 195 return; 196 Engine.ConfigDB_CreateValue("user", key, String(this.caption)); 197 if (functionBody) 198 eval(functionBody); 199 updateChanges(true); 200 }; 201 }(key, functionBody); 202 201 203 control.caption = caption; 202 control.onPress = onPress; 203 control.onMouseLeave = onPress; 204 control.onMouseLeave = onMouseLeave; 204 205 break; 205 206 default: 206 warn("Unknown option type '" + option s[3] + "', assuming string. Valid types are 'number', 'string', or 'bool'.");207 warn("Unknown option type '" + option[3] + "', assuming string. Valid types are 'number', 'string', or 'bool'."); 207 208 control = Engine.GetGUIObjectByName(prefix + "Input[" + i + "]"); 208 209 break; 209 210 } … … 212 213 return control; 213 214 } 214 215 215 /** 216 * Merge two functions which don't expect arguments. 217 * 218 * @return Merged function. 219 */ 220 function mergeFunctions(function1, function2) 216 function updateChanges(val) 221 217 { 222 return function() 223 { 224 function1.apply(this); 225 function2.apply(this); 226 }; 218 if (typeof val == "boolean") 219 Engine.ConfigDB_CreateValue("user", "nosave.haschanges", String(val)); 220 else 221 val = Engine.ConfigDB_GetValue("user", "nosave.haschanges") === "true"; 222 223 Engine.GetGUIObjectByName("loadOptions").enabled = val; 224 Engine.GetGUIObjectByName("saveOptions").enabled = val; 227 225 } 228 226 229 227 function reloadDefaults() 230 228 { 231 229 Engine.ConfigDB_Reload("user"); 230 updateChanges(false); 232 231 init({ "reload": true }); 233 g_hasChanges = false;234 232 } 235 233 236 234 function saveDefaults() 237 235 { 238 g_hasChanges = false;239 236 Engine.ConfigDB_WriteFile("user", "config/user.cfg"); 237 updateChanges(false); 240 238 } 241 239 242 240 /** … … 244 242 **/ 245 243 function closePage() 246 244 { 247 if ( g_hasChanges)245 if (Engine.ConfigDB_GetValue("user", "nosave.haschanges") === "true") 248 246 { 249 247 let btCaptions = [translate("No"), translate("Yes")]; 250 248 let btCode = [null, function(){ closePageWithoutConfirmation(); }]; -
binaries/data/mods/public/gui/options/options.xml
65 65 </object> 66 66 </repeat> 67 67 </object> 68 <object type="button" style="ModernButtonRed" size="50%-170 100%-44 50%-70 100%-16" hotkey="cancel">68 <object name="loadOptions" type="button" style="ModernButtonRed" size="50%-170 100%-44 50%-70 100%-16" hotkey="cancel"> 69 69 <translatableAttribute id="caption">Reload</translatableAttribute> 70 <translatableAttribute id="tooltip">Reload default values from file</translatableAttribute>70 <translatableAttribute id="tooltip">Reload previous saved settings</translatableAttribute> 71 71 <action on="Press">reloadDefaults();</action> 72 72 </object> 73 <object type="button" style="ModernButtonRed" size="50%-62 100%-44 50%+38 100%-16">73 <object name="saveOptions" type="button" style="ModernButtonRed" size="50%-62 100%-44 50%+38 100%-16"> 74 74 <translatableAttribute id="caption">Save</translatableAttribute> 75 <translatableAttribute id="tooltip">Save changes to file</translatableAttribute>75 <translatableAttribute id="tooltip">Save changes</translatableAttribute> 76 76 <action on="Press">saveDefaults();</action> 77 77 </object> 78 78 <object type="button" style="ModernButtonRed" size="50%+70 100%-44 50%+170 100%-16"> -
source/ps/ConfigDB.cpp
378 378 char* pos = (char*)buf.get(); 379 379 for (const std::pair<CStr, CConfigValueSet>& p : m_Map[ns]) 380 380 { 381 if (boost::algorithm::starts_with(p.first, "nosave.")) 382 continue; 381 383 size_t i; 382 384 pos += sprintf(pos, "%s = ", p.first.c_str()); 383 385 for (i = 0; i < p.second.size() - 1; ++i)