GUI Themes/TODO
We plan to implement a new GUI look & feel in ScummVM, roughly based on the new look of our web site. Some concept drafts of the new look can be found here: http://kressline.de/wip/scummvm/
See also specs
To Do
General
- Add tab-focus support, i.e. make it at least possible to use the "tab" key (and also "shift-tab" to cycle through the edit fields.
- Even nicer would be general "tab cycle" support, allowing tab to cycle the focus for all items where it makes sense (buttons, checkboxes, etc.), to make the GUI fully keyboard controllable
- SPEED: The GUI is relatively sluggish these days on my 1.5 GHz PowerBook :-/. I'll try to list some bottle necks and possible solutions:
- A lot of time is spent in ThemeModern::openDialog for dimming the screen.
- The code calls a function pointer for each pixel of the screen, which results in code which the compiler can't properly optimize, essentially doing a couple hundred thousand tight read-call-write ops, which can't be inlined / improved upon.
- Better: change _dialogShadingCallback to not work on a single pixel but on the whole better
- Even better: Get rid of the _system->RGBToColor / _system->colorToRGB which are terrible for performance, too (can't be inlined). So, at least provide a 555 / 565 color mode version, which works efficient on targets using these color modes, and only fall back to the OSystem API if an unsupported color mode is in use
- A lot of time is spent in ThemeModern::openDialog for dimming the screen.
- Implemented better layouting code. It should be possible to layout widgets in a grid (typical example: a 2 by n "grid", each row contains a label on the left side (to be right aligned) and a widget on the right side (to be left aligned).
- Change the monolithic DrawStep struct into a class hierarchy. To this end, we probably should also change the XML format (which sadly closely mirrors this monolithic struct). Namely, replace the <drawstep> element by one element for each kind of drawstep. In each of these specialized "drawsteps", allow only those attributes that make sense.
Widgets
- EditableWidget: Make it possible to specify a min/max length for the text
- EditableWidget: Let setEditString filter the string it gets
- EditableWidget: Right now, custom filtering requires the user to subclass; it would be nice if there was simply a "validator hook" or so. Maybe take some inspiration from Java's Swing in this matter.
- ScrollBarWidget: Add auto-repeat: if user clicks & holds on one of the arrows, then after a brief delay, it should start to contiously scroll.
- List widget
- get mock-up from Krest
- Glitches when entering very long strings. The cursor overlaps the scrollbar. Possibly the scroll bar width should be automatically added to the right-side paddings, but I don't have the time to experiment with it right now.
- PopUp widget (aka drop-down list)
- get mock-up from Krest
- Scrollbar widget
- The handle of the scrollbar widget leaves trails in 320xY resolution. Possibly, the shadow of the handle is drawn too wide.
- Add a new "BoxWidget" / "GroupBoxWidget", which can be used to group other widgets
- This widget makes it easy to group widgets and control them together; e.g. disable the box widget, and all children get disabled, too
- Here is the equivalent of this control in Qt: http://doc.trolltech.com/4.3/widgets-groupbox.html
- (optionally) draws a border around itself
- (optionally) draws a title
- The ideal version of this would also support a checkbox in the title, and would automatically disable/enable all contained widgets if the checkbox gets activated (this is also demonstrated in the above Qt example)
- If we ever add radio buttons, then those could be grouped via a GroupBoxWidget, too
- Clearly this widget would be of great use for the options dialogs, for the "Override XYZ" checkboxes
- ButtonWidget: Allow drawing the 'default' button in a visually distinct way
Dialogs
- Add a new "options" dialog which is used by all frontends: for this, we'd agree on a hotkey used in all engines to invoke that dialog; it would sport settings for the volume, graphics, paths, etc.; it would co-exist with the engines "native" option dialogs. The about dialog would be reachable from here, too, as well as a quit button. Justification: This ensures that all settings are really reachable from all of the engines, which is not the case currently. Problem: It's not fully clear to me how to "best" deal with global vs. local settings here...
- About dialog
- looks bad. Probably add some shadows and text padding
- fix glitch at the top of the dialog where part of the characters get stuck (see FIXME in about.cpp)
- [Classic theme] Text seems to be drawn over the dialog frame. At least at the top of the dialog.
- The grey text (color 2, kStateDisabled) is hard to read in both the new and the classic theme.
- Add a "fade" effect for the top/bottom text lines
- Maybe prerender all of the text into another surface, and then simply compose that over the screen surface in the right way.
- Chooser aka Add game dialog
- [Classic Theme] Adjust size and position of the chooser to Launcher
- Options dialog
- There is currently no way to unset/reset-to-default the path settings from the GUIsettings.
- To this end. maybe add an (optional) "reset to default" button to the browser dialog. (This would save space in the options dialog)
- Alternatively, add "Reset to Default" buttons to each path setting, possible similar to the one used with the soundfont (which is a rather too cryptic, IMO)
- Several texts, e.g. vcMusicText, have their alignment set to kTextAlignRight, but are still drawn as left-aligned.
- [Classic Theme] Adjust size and position of the "Options" dialog to Launcher
- It would be nice if you could select theme from the GUI. The "Graphics" tab, perhaps?
- There is currently no way to unset/reset-to-default the path settings from the GUIsettings.
- Edit game dialog
- [Classic Theme] Adjust size and position of the "Edit game" dialog to Launcher
- The sliding action of the debug console takes a lot more CPU now than it used to. On my 450 MHz P3, I don't even see it slide in 2x mode. It seems to appear/disappear all at once.
- File browser dialog
- Add a "show hidden files" checbox
- Right now we "visualize" that an entry is a folder/directory by appending a slash "/" to the name. This is not really intuitive for non-Unix users. Maybe we could add small file / directory icons? And maybe also an up-arrow for the "up" button.
Fonts
- The BDF fonts can have characters that are both wider and taller than expected. For instance, the letter Ã… extends one pixel above the top of the line. This can lead to glitches since we update the screen based on font height and character width, not bounding boxes. The List widget is one example of this.
- Antialiased fonts
- This could be tricky, since the BDF fonts are bitmaps. Is it even possible, within this format, to store the alpha channel needed (?) to represent an anti-aliased glyph? One possibility might be to store a larger version of the font and scale it down to the desired size, but that seems wasteful.
- BDF fonts aren't suitable here since they're 1bpp. It could be done if font data would be 8bpp and thus, contain just the alpha channel, i.e. shades of gray which will be blended on rendering stage.
- Fingolfin says: It's *still* possible to use 1bpp fonts for antialiasing, by implemnting oversampling: By downscaling a 4x fold or 8x too big character, one can compute & render the antialiased output on the fly -- this worked even on some old 90 MHz PowerPC Macs, so it should be doable. Main concern would be memory usage, and the need to have a big version of all fonts around. Or we switch to a vector based font system (TrueType plus Freetype), at the cost of resources and possibly some portability -- we would have to research this a bit. Another advantage of using FreeType: Unicode support in the GUI would be possible.
- This could be tricky, since the BDF fonts are bitmaps. Is it even possible, within this format, to store the alpha channel needed (?) to represent an anti-aliased glyph? One possibility might be to store a larger version of the font and scale it down to the desired size, but that seems wasteful.
Collaborative work with the OpenUsability Project
Given that usability is one of the primary driving forces behind the design of user interfaces, it seems logical to pay close to attention to it while redesigning ScummVM's GUI.
The OpenUsability project (http://openusability.org/) provides usability consulting and advice for open sourced applications. It would be a sensible opportunity to contact them, seeking assistance to improve ScummVM in the usability front.
Some ideas about theme caching
Solution will look something like this:
./scummvm --gui-theme=classic --create-gui-cache 320x200
you get classic-320x200.tcc file
./scummvm --gui-theme=classic --create-gui-cache 320x240
you get classic-320x240.tcc file
Then concatenate the two and probably dump it into C array. Porters should do that by themselves for all resolutions supported by their platform. I.e. we have generic XxY theme, and all specific resolutions are derived from it.
tcc (theme cache) file format
This theme cache will be plainly a dump of all evaluated variables from HashMap. They will be loaded with loadAll() method in HashMap.
'RESL', length, "320x200", number of vars, dumped vars
dumped vars are:
"varname", int16 value,...
This format will let easily concatenate several generated theme cache files.
Probably there will be some optimisations in loadAll() method, which will malloc one big chunk of those vars, and since we have their keys as const char *, then it can alloc one big chunk for variables name as well and then pass pointers inside of it to respective members. Of course, that will be specially flagged as it will not be possible to free() any of those chunks deliberately.
Launcher hints
On June 27th 2007 12:45 -- 14:10) on #scummvm (Log is here) there was a discussion about implementing launcher hints to our detector.
The main idea behind this is that engines will hint launcher on available per-game options. Say, it will provide lists of languages, supported sound formats. Also this could be used for those rarely used options which we miss now in GUI, such as turning on or off copy protection or selection of different intro.
To this end, query the responsible engine plugin when the user hits the 'Edit Game' button. Then it returns back a structure (or just a StringMap) describing the capabilities of the game. This structure could contain:
- a list of languages that game instances support (empty = unknown/any; one language; or multiple language for multi-lang games)
- the native resolution of the game (320x200, 320x240, 640x480) etc. -- this info can be used to select an appropriate default scaler (could also be used on-the-fly when starting a game)
- List of supported audio/sound modes (MIDI, pcspk, adlib, digital audio, ...)
- Whether copyprotection can be toggled
- Whether aspect ratio correction makes sense for that game
List of rarely used options which aren't reflected in GUI:
- cdrom
- joystick_num
- alsa_port (or any other midi driver config stuff, there is an open FR for adding better MIDI config options, too, of course)
- tempo (do we still need/want that, anyway?)
- This was discussed briefly on the scummvm-devel mailing list in 2006.
- midi_gain
- copy_protection
- debuglevel (could help with bug reports)
- music_mute and sfx_mute
- alt_intro (For Beneath a Steel Sky)
- demo_mode (For Maniac Mansion)
- object_labels (For Broken Sword 2 and COMI)
- reverse_stereo (For Broken Sword 2)
- walkspeed (For The Legend of Kyrandia)
List of values which are currently showed in GUI:
- Language
- Platform (do we really need to allow user to change that?)
- Graphics mode (640x480 games with 2x selected now behave incorrectly)
- Render mode (only few games support CGA or Hercules rendering)
- Aspect ratio (FM-TOWNS games run in 320x240, NES MM doesn't use aspect correction too)
- Music driver
- Text and speech (for subtitle-less games or games without voice-overs)
- Subtitle speed (disable in Simon1 CD)
- Volume --> closely related to text and speech, so perhaps just disable speech volume for text-only games
- SoundFont (no need to enable if game doesn't have MIDI music)
- This should probably also depend on the music driver, since only a few of them implement it.
- Mixed Adlib/MIDI (only couple games feature that)
- True Roland (supported only by games with MT-32 tracks)
- Roland GS (same as above)