Right now the only way to change gui.scale is to manually edit one of the *.cfg files, but we might want to add a graphical way to do this.
This depends on D328 because of the wording "UI scale" instead of "UI inverted scale"
Differential D332
Add an option in the Options menu to change the UI scale joskar on Apr 14 2017, 3:48 PM. Authored by
Details
Right now the only way to change gui.scale is to manually edit one of the *.cfg files, but we might want to add a graphical way to do this. This depends on D328 because of the wording "UI scale" instead of "UI inverted scale" Enter the game, change the UI Scale, save, restart the game, check that the UI Scale has changed
Diff Detail
Event TimelineComment Actions You've to change options.xml, because number of objects is increased. Also, as I could see g_GuiScale is used only in realtime, so it'd good to not restart a game (which could annoying, if you couldn't find fastly a needed scale), but just change the variable.
This comment was removed by vladislavbelov. Comment Actions @vladislavbelov I changed options.xml and set a min of 0.01 instead of 0. As for the real-time change of gui.scale I'll tackle this problem in another patch, because it doesn't seem trivial to do and I think it's unrelated to this patch Comment Actions 0.01 is not a sensible minimum - I would have thought perhaps 0.5 is as far as we need to go. Screenshot with 1/gui.scale=0.01: The tiny ripple in the picture on the left is the menu, and the white spec in the bottom right is the feedback area. At 1/gui.scale=0.5 it's still stupidly small but may be useful on extremely low dpi setups - text is just about readable. Comment Actions I partially agree with you @domdomegg, 0.01 is too low to be useful, but i think 0.5 is too high (remember that you're using a 4K screen, so what you're seeing there is actually like a 0.25 scale), so I've set the minimum to 0.25. Comment Actions Mh, I think there should be a failsafe or some type of resolution check for the maximum. If you zoom in too much, you can't see the buttons anymore so you can't change-it back from in-game, and then some people might get sucked "zoomed in" if they can't find the config file. Maybe not a real problem, but I'm wondering. Comment Actions Looks good to me in its current state @wraitii perhaps we could add something later like many other display options do such as a dialogue asking the user to confirm the set scale before reverting back after 10/15 seconds. However I don't think it's really necessary, I think people will realise it must be gui.scale and reset the options accordingly Comment Actions Most people don't know about the config file, so it would be good to have a confirm dialog with automatically reverts back after 10/15 secs. Comment Actions Wouldn't add code for a specific config option. We just got options.js agnostic of options.json. Comment Actions REQUIRES GAME RESTART should be avoided where possible. (One idea would be to remove the global altogether and read the config variable each render call. But that sounds like performance loss.) add a new entry to the GUI manager functions area of ScriptFunctions.cpp that would just update that one variable. Comment Actions I agree, but wasn't there some texture creations depended on the gui scale? Need to check its uses. Comment Actions I can't find any texture dependencies on g_GuiScale (unless the texture creation caches GetDefaultGuiMatrix() in some obscure way). All dependencies I have found are indeed used on g_GuiScale in 'real time'. I have attached a patch which registers a ReloadUserConfig() call, which reloads the saved configuration on the fly and additionally can do sanity checking of the configuration parameters. A drawback is that you would have to press 'Save' in order to see what the actual 'maximum scaling' is allowed to be. (but this should not matter in practice) Perhaps not the most elegant solution, but it was the easiest thing I could think of which hopefully does not mess with other parts of the code. Comment Actions Notice that UpdateResolution` also sends the WindowResized event` even though the window size didn't change. Probably won't matter as long as there is no code that may not be run if the change is kept the same. Comment Actions Regarding the call to UpdateResolution(), this is required in order to flush the cached window sizes. I guess this would be equivalent to changing the window size in a semantic way (even though the physical window size is kept the same), so I don't really think there is a problem here. Otherwise we need another way to flush the cached window sizes. I just found out that options.json already allows for function callbacks, so here is my second (less hacky) attempt at doing the same thing, but applying the gui.scale even before the Save button has been pressed. Updating the gui scaling this way makes it really hard to use a slider for this setting though, so it is a number box for now. Comment Actions The only thing that I noticed is missing from @joskar's patch is that the cursor doesn't get resized until the game is restarted. The cursor needs to be recreated, because the scaling is done at creation time. Comment Actions Build is green Updating workspaces. Build (release)... Build (debug)... Running release tests... Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK! Running debug tests... Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK! Checking XML files... http://jw:8080/job/phabricator/1762/ for more details. Comment Actions Should also add the programming.json change from D749, in case the latter hasn't committed already (we can commit it as a patch by both of you).
Comment Actions Good catch. Fixed in attached patch. However, there doesn't seem to be a "good (exposed) way" to do this other than to remove the cursors which are already loaded and relying on the asset handling system to reload it on the next cursor_draw() call. But maybe relying on this behaviour isn't terrible? Done. Please tell me if I am wrong, but it seems that onValueChange() is only called if a mouse motion event is acting on the slider (as coded in gui/CSlider.cpp). Thus I can't really see how the this.value = ...; could trigger an extra call of onUpdate (which I assume is what you were worried about), because I can't find any overloading of the setter for this.value anywhere either.
I cannot reproduce this behaviour when running a new instance of 0ad. However, if I change something once and then close the Options menu without saving, then it will keep asking me the next time I enter and then try to leave the Options menu (without changing anything). I think this is an unrelated issue, and it seems to be because the settings are not automatically reverted upon exiting the menu (and this is probably even the intended behaviour?). Fixed. (improved, rather) I kept both of these to keep track of whether I had sanitized the value. I don't keep track of that anymore in this new patch, so I renamed value to guiScale as suggested. The reason was to sanitize gui.scale so that the scaling does not get too big (making the scaling too big makes it impossible to revert any changes, because everything will be off-screen). And I set the limit to not exceed the equivalent of a resolution of 1024x768 (which is the current 'minimal supported resolution'). I added a comment in the code to clarify this. Also, I think it is valid even though the user is in windowed mode. Otherwise the user might have to be forced to enter fullscreen mode in order to revert unplayable settings. (which the user might be required to know/remember the keyboard shortcut for, because the setting might be unreachable after making the scaling too big...) The value was already 'saved' to the config file from options.js (by Engine.ConfigDB_CreateValue), and I was only updating the value in case it had to be updated. In this new patch, I always update it. Less code, so it is perhaps cleaner now. Thanks! I was looking for the C++ way to do it, but couldn't find it. C++11 to the rescue! Comment Actions Updated with the latest diff I can confirm the issue where after changing the UI scale and saving the settings it still open the dialog for unsaved settings when closing the options menu Comment Actions Build is green Updating workspaces. Build (release)... Build (debug)... Running release tests... Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK! Running debug tests... Running cxxtest tests (306 tests)..................................................................................................................................................................................................................................................................................................................OK! Checking XML files... http://jw:8080/job/phabricator/1764/ for more details. Comment Actions This update fixes the 'You have unsaved changes' thing, which was caused by converting the caption to a floating point value instead of leaving it as a string. Another thing which was introduced by using std::to_string was the fact that std::to_string always prints a lot of decimals, even when not needed. So now I also reformat the string in options.js when we have a callback which might modify its value. Comment Actions Marking some stuff as 'done', while leaving a couple still open for discussion (no clear 'Definition of Done' on those?).
Comment Actions
Comment Actions It sure is shorter, and updated the diff now to see if there are other comments on it. It should be std::min({}) though in order to have the same behaviour as before. Comment Actions Updated patch accoring to the comments below: Perhaps I have to reconsider the resolution constants and add them for the upper range limit too. Option type:
Number:
Dropdowns are off the table because the values would have to be translated and there are only few values that we can provide. It's a free numeric range, so it shouldn't be a dropdown. C++ part:
ERROR: Trying to use a sprite that doesn't exist ("BackgroundSessionTooltip"). But the sesion code is totally not loaded (these sprites shouldn't be in gui/common/ independent of that). Options sanitization feedback:
Value range:
Rendering issues:
Comment Actions The number input auto-correct issue was addressed by the commit above. Notice posix has an isnan macro, so we can't use std::isnan (http://en.cppreference.com/w/cpp/numeric/math/isnan) Added a scale=0, the UI really didn't like that value, froze and spammed errors. g_OptionType still needs to convert it to a number before calling Engine[option.function](value);. I'm still not happy enough to commit this. The random black lines and fonts look really ugly.
Comment Actions #undef isnan should work, then again just doing if (a != a) { /* a is NaN */ } would also work. (And why is it surprising that IEEE 754 floating point numbers are correctly passed from JS to C++?) Comment Actions
Because POSIX isnan is a macro. If I'd have to implement that it'd be #define isnan(x) ((x)!=(x)), which still has issues if the passed x has side effects (so there'd have to be some internal function eg int __isnan(sometype x) which is then just used by the isnan macro). But as the preprocessor does its work before the compiler does anything you might end up with something like std::((bar)!=(bar)), which is not going to compile. Thus you would need #undef isnan to remove isnan from the list of things the preprocessor will try to replace. Comment Actions This options patch seems correct, but as discussed with Dariost in irc on 2017-09-05, the text rendering and black lines on red buttons are ugly for some UI.scale values, so we shouldn't expose the config value until it's less ugly. Even if some screens really need it and someone experiencing the bug might show up and fix it following the annoyance.
The black lines across the buttons appear even with an UI scale factor of 2.
confirmed, that fixes the text rendering Comment Actions I would commit the patch despite the remaining graphical glitches, but only if it became possible to reset the UI scale to 1 in case the user set it too low or too high to control anything. Comment Actions (Assuming the setting is applied directly) Why not just a dialog with a timeout, that reverts the setting to 1 after e.g. 10 secs? |