Option Dialog Design ==================== We currently have the following "option" dialogs (that is, dialogs derived from the OptionsDialog class, and which are used to edit the configuration in some way) in ScummVM: (1) Global options dialog (in launcher) (2) Game target edit dialog (in launcher) (3) Options dialog (in SCUMM engine) In detail: re (1): This modifies the "base" settings (i.e. in the [scummvm] section in the config file). Changes made here while in the launcher usually would take immediate effect when the user selects "Apply" or "Save", or even in the instant the change is made (like, when you click on a checkbox etc.) re (2): This is what you get when you "Edit..." a target in the launcher. Changes made here do not have an immediate effect. Rather, you see the effect when you later launch the edited target. re (3): Changes made here affect the running target only, and aren't global; like in (1), they should take "immediate" effect. Problems -------- The current dialogs suffer from some inconsistencies. For example, if you open the global options dialog, it will show you a popup with the available graphics drivers. The currently active driver will be selected. Now, press one of the Ctrl-Alt- key combos (assuming you are using the SDL backend). This will cause the active graphics dialog to be changed. However, the visible dialog will still show the old state; in other words, it got out of sync with the actual state. If you then proceed by pressing OK, your graphics mode would be switched back to the old value (which is still selected in the graphics popup). This is probably not the behavior most users would expect (would *you* expect it to work like that? Forget about what you might know about the implementation, but rather try to imagine it from a neutral point of view) A second problem is the discrepancy between permanent settings (i.e. settings as given in the config file, and edited via one of the current options dialogs), and temporary settings: When you use the options dialog to switch the graphics mode, this becomes permanent. But when you use a backend hotkey, the change is only temporary. Clearly, this is once again an inconsistency, and will lead to unexpected results. Another Problem... ------------------ Consider this scenario: You start ScummVM into the launcher; you open the global options dialog. In here, you switch to the 2xSAI filter, then close the dialog. The kTransientDomain gets updated accordingly. Now you start Monkey Island by double clicking it in the launcher. For it, you had explicitly set the graphics mode to "AdvMame3x". Question: Which graphics mode should Monkey Island use now? 2xSAI or AdvMame3x ? This is a tough one, and it has no ultimate answer. I am torn between the two myself... both have important pro's and con's. The current implementation would use "AdvMame3x". This is important if you normally use 2x or 3x scaling, but are starting a game like COMI which you prefer to run with a 1x scaler. And of course you can always change the graphics mode in-game later on via hot keys. OTOH, you just did set this graphics mode a few seconds ago -- so why should ScummVM suddenly switch to yet another one? Is that really matching the expectations of the user (I honestly don't know -- it is simply impossible for me to view this from a neutral point of view; we'd have to run our own usability lab to find out, I think...) Solutions --------- One possible solution for the latter problem would be to only allow editing the permanent settings. That is, make the hot keys change the settings in the config file, too (the opposite, only allow editing the temporary settings, seems undesirable, since this way the user has no way to edit his config file, short of using a text editor). While personally I prefer this (it seems to me like the most intuitive approach), clearly, I am somewhat biased, and I do not claim to know the absolute truth about this matter (hey, wouldn't it be cool if we had a big budget to spend on a usability lab? ). The other approach that comes to mind is to keep having both perm and temp settings; the hot keys will still edit the temp settings; the config dialogs (1) and (3) will also edit the temp settings; but they will also sport some kind of GUI control to "save" the current temp settings as perm settings (e.g. a "Save" button). It has the advantage that if you selected e.g. a bad graphics mode which your graphics card doesn't support, and you have to force kill ScummVM; well in that scenario, ScummVM won't write the "bad" graphics mode settings to your config file. Phew, so you can still use it as normal. Many people seem to prefer the second way, so from now on I'll base my examples on it, to keep the length of this already far too long document a bit down. The first problem ("inconsistency") can be solved by updating the dialog contents on the fly whenever settings get modified (e.g. via a hotkey). That then leads to the question: should changes made in the (global) options dialog be *immediately* activated, or only after pressing an "OK" button? Both approaches have merits: (a) Delayed activation (only after "OK") makes it very easy to implement "Cancel": just close the dialog and do nothing. Note that this is purely a bonus for the (lazy) programmer, but not one for the end user. A small advantage for the end user is that you have a little more protection from activating "bad" changes, i.e. if you accidentally click the fullscreen checkbox, you just click it again or press "Cancel". I don't think that's a reasonable argument, though, and don't see any other merits to this approach, but please feel free to fill in this gap and step forward with your ideas... (b) Immediate activation: IMO this is more consistent overall: With delayed activation, imagine you have just opened the options dialog; it shows AAA as active graphics mode. You now select BBB. Then you press a hotkey to activate yet another graphics mode, CCC. Should the popup now say: AAA, BBB, or CCC ? IMO There is no way to handle this "correctly", you'd just have to arbitrarily choose one behavior... unless you use immediate activation. Then this problem simply doesn't exist at all. Furthermore, it makes it very convenient for the user to "play" with settings, and switch between different graphics modes, change volumes, etc. Maybe you guessed it: I am in favor of (b) :-). Whichever of those two routes we go, of course the activation of the changes (pressing "OK" in the options dialog) does *not* cause them to be written to your config file. To do that, you have to explicitly click the "Save" button. Thus even if you switch to a graphics mode not supported by your display, you do not render your config file unusable. How does this affect the GUI? ----------------------------- Let's take a look at how these ideas might manifest in the actual UI. The easiest to consider is dialog (2): Editing a game target in the launcher. Since the changes here aren't affecting the active target, they never are immediate, hence the current implementation is sufficient: we have an "OK" and a "Cancel" button; when opening the dialog, it's set up with the current settings. We do nothing special while it is open, and once the user presses "OK", we store the changes into the config file. If "Cancel is pressed, we close the dialog and do nothing. So no changes at all. Dialog (1): The global options dialog. Now this one affects the currently active settings. If we choose to go with route (b) [see above], we'd do this: - "OK" basically does nothing (all changes are already active) - "Cancel" has to revert to the previous settings. Not a big deal either. - "Save" saves the changes to the config file So UI wise, the most notable changes would be the immediate activation of changes, and the addition of a "Save" button. Implementation wise, this means more work, but I actually already have a partial implementation sitting on my HD; it's not so hard to do overall. Finally, dialog (3) is similar to dialog 1. The main difference is that here we do not edit the kApplicationDomain, but rather the "active domain" (the domain of the running "target"). Implementation -------------- We need a way to update an options dialog whenever the active settings are changed (e.g. graphics mode switch via hot key). One possibility is to detect the EVENT_SCREEN_CHANGED event, and whenever we receive it, update the dialog. This is not a clean solution (it only will catch changes made to display settings, and even that only if the backend actually sends the optional EVENT_SCREEN_CHANGED event). A better solution seems to be to use the kTransientDomain for this. So first write all changes to the kTransientDomain. Then only when the changes are saved, write through to the actual domain being edited (usually that means either the kApplicationDomain or the "active domain"). In addition, the ConfigManager::(un)registerCallback() API would be implemented. With that in place, backends could update the values in the transient domain whenever hot keys are used. The options dialogs simply would register a callback for all relevant config keys. Any change would automatically trigger an update of the GUI display. Voila! This approach, too, has some problems, esp. depending on what we decide regarding the question covered under "Another Problem...". But those are mostly implementation problems (instead of conceptual ones), and are fixable by adjusting the ConfigManager (in a way which I had considered for some time now anyway). Further ideas ------------- As far as I know the non-SCUMM frontends mostly lack any kind of GUI for graphic settings (scaler / fullscreen / aspect ratio), and possibly for some other settings as well. It might be worthwhile to consider adding a common way to all frontends which gives access to a global options dialog. For the sound settings, it might be neat to play a little sound when the volume is changed, to help the user... maybe add a little "Test it" button next to each volume slider, which when pressed plays a sound (using the specified volume, of course).