Menu usability guidelines

Started by a1ex, February 10, 2014, 06:12:04 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

a1ex

Now that menu API is more or less solid, I thought it's time to write down some guidelines. Should be useful both for developing new stuff and for polishing old features.

Feel free to come up with better suggestions, or post some screenshots that I could reuse to illustrate the points below. However, if you feel like suggesting some facelift or a new keybinding, it may be a good idea to use this thread: http://www.magiclantern.fm/forum/index.php?topic=4386.325

Clutter:
- (I start with this because I think it's the biggest usability problem right now)
- Think twice before adding YAMLMO (yet another ml menu option). There are already hundreds (if not one thousand).
- Try to avoid vertical scrolling (otherwise you can no longer see at a glance what settings are enabled).
- If you end up with a menu with lots of items, hide less-common options under the Advanced option, or in a submenu.

Submenus: (now we have multi-level submenus too)
- Prefer a top-level boolean option that turns your feature on and off, and put all the settings in the submenu.
- Sometimes you need a submenu just for grouping some items (e.g. benchmarks, or some general preferences), but there's no feature to be turned on and off. That's fine too. Try to put these items at the end of the menu though.
- Try to summarize the important submenu settings in the top-level menu (so you can tell at a glance what setting you are using). Example: most items from Shoot and Overlay menus.
- Do not abuse multi-level submenus: unrolled menu structures are generally quicker to navigate and easier to survey.

Values:
- Prefer pickboxes whenever possible (tip: use the CHOICES macro).
- Try to provide reasonable default settings (make your feature usable out of the box).
- When the toggled variable (.priv) is 0, try to interpret this setting as "OFF" (of course, only if it makes sense).
- Make sure your setting appears on the Delta menu when you change it from default, and also make sure it disappears from there when you go back to default value.
- Use reasonable .min and .max limits (e.g. instead of providing 1000 choices, try to select 5 or 10 choices that will make a difference).

Icons:
- in most cases, the icon type is autodetected (you may override it if autodetection is not smart enough)
- IT_ACTION: when you click on the item and something starts running (e.g. a task); do not use it for things that can be toggled on or off, for example.
- IT_BOOL: simplest setting (you toggle it on or off)
- IT_PERCENT: a scalar value (quantity)
- IT_PERCENT_OFF: a scalar value with an OFF position (zero is interpreted as OFF)
- IT_DICE: a set of discrete choices without an OFF position (historically this was represented by a dice icon)
- IT_DICE_OFF: a set of discrete choices with an OFF position.
- IT_SUBMENU: on submenus without top-level value.

Colors:
- green: something that can be turned off
- light blue: something that can't be turned off
- if an item is turned off, its value should be grayed out (but not its name)
- if an item can't be used in the current context, gray it out completely (see below)

Warnings:
- if an item can't be used (e.g. a photo-only feature in movie mode), gray it out (MENU_WARN_NOT_WORKING) and explain what to do in order to use it.
- use depends_on to check for some common things like LiveView or movie/photo mode, and use a MENU_UPDATE_FUNC for more complex logic.
- you can provide usage tips (MENU_WARN_INFO), especially non-obvious stuff.

Alignment:
- Try to keep the menus nicely aligned (just like you do with code indentation)
- Extend submenu_width as needed (so your menu feels neither too cramped nor too loose - just right)

Ordering:
- Try to group similar items (avoid things like boolean/action/boolean/action/scalar, try boolean/boolean/scalar/action/action instead)
- Try to move action items at the end of the menu
- Same for grouping submenus (try to place them at the end of the menu)

Help:
- Each item should include a short description (.help, optionally .help2).
- For items with multiple choices, help2 can be used to describe every single choice (simply describe one choice per line).
- Make sure the help text actually fits on the screen!
- For modules: also include a short description in the README.rst file (details here). Make sure your description fits in the ML menu!

Marsu42

Quote from: a1ex on February 10, 2014, 06:12:04 PM
- If you end up with a menu with lots of items, hide less-common options under the Advanced option, or in a submenu.

Could you add an option or change this that the advanced option isn't forced to be visible if it's changed from the default state?

Quote from: a1ex on February 10, 2014, 06:12:04 PM
- Do not abuse multi-level submenus: unrolled menu structures are generally quicker to navigate and easier to survey.

Well said, and I agree about yamlmo :-> though we have to face ML is for power users, so a lot of options are ok as long as they make sense to configure the feature behavior.

Quote from: a1ex on February 10, 2014, 06:12:04 PM
- Each item should include a short description (.help, optionally .help2).
- For items with multiple choices, help2 can be used to describe every single choice (simply describe one choice per line).

Problem is this .help2 gets overwritten by warnings and such, so often you cannot be sure the user will be able to read it - maybe it would be a good idea to "blink" the warning and alternate it with the help2 line (just an idea)?

a1ex

Advanced option: can you be more explicit? (I don't understand)

helps: once you solve the warning, you should be able to read the full help. Do you have an example where this doesn't happen?

The "well said" and "yamlmo" parts were copied from you :P

Marsu42

Quote from: a1ex on February 10, 2014, 07:20:35 PM
helps: once you solve the warning, you should be able to read the full help. Do you have an example where this doesn't happen?

In my modules :-p ... I use the last line for various information with green text. But if you think it doesn't collide in the core options, no problem.

Quote from: a1ex on February 10, 2014, 07:20:35 PM
The "well said" and "yamlmo" parts were copied from you :P

Were they indeed :-p ?

Quote from: a1ex on February 10, 2014, 07:20:35 PM
Advanced option: can you be more explicit? (I don't understand)

Forget it for the time being, I seem to be doing something wrong and have to check. If I change an advanced option in my modules to a non-default value, it moves to the "simple" menu - but I seem to be doing something wrong as it works as expected for example in your ettr module.

a1ex

Yeah, I show non-default options in the simple menu too (so you don't forget that you have turned on some obscure thing).

dmilligan

Quote from: a1ex on February 10, 2014, 06:12:04 PM
- Use reasonable .min and .max limits (e.g. instead of providing 1000 choices, try to select 5 or 10 choices that will make a difference).

I have a solution for allowing much easier input of large values: https://bitbucket.org/dmilligan/magic-lantern/branch/menu_carret

It should be pretty easy to customize this for values that aren't strictly base 10 numeric, but this is mostly just an example.

What do you think?

Audionut

Some S/S's you may find useful.

Alignment:


Choices/help:


Help:


Also I've linked some of the code descriptions to code.

a1ex

Quote from: dmilligan on February 10, 2014, 10:31:07 PM
I have a solution for allowing much easier input of large values: https://bitbucket.org/dmilligan/magic-lantern/branch/menu_carret

Looks interesting (didn't try it though). However, I wouldn't replace R20 (I'd rather add it as an option for those cases where you need finer tuning).

There is a portability problem with hijacking the left and right keys: on some cameras (500D, probably also EOS-M) the scrollwheel simply doesn't work in certain modes. So, you have to toggle the actual value with "left" and "right". That's why I prefer the scrollwheels to be just accelerators, not mandatory.

The rationale behind R20: I can imagine a situation where you need 2, 3, 5 or 10 pictures, 1000, 1500 or 2000, but I can't imagine why would you ever choose exactly 1005 pictures. Same for most other settings, with very few exceptions (like editing a hex address with memory browser, or tweaking the raw value of a register in iso_regs).

More info: http://en.wikipedia.org/wiki/Preferred_number

Marsu42

Quote from: a1ex on February 10, 2014, 07:55:51 PM
Yeah, I show non-default options in the simple menu too (so you don't forget that you have turned on some obscure thing).

So it's really a feature, not a bug? In this case, please do add an alternative .advanced=2 so the option stays hidden, I understand your intention but "forced visibility" only makes sense for dangerous options, not for plain boring or seldom used ones.

a1ex

Well... the multi-level submenus are doing exactly that, no?

Marsu42

Quote from: a1ex on February 11, 2014, 08:14:12 AM
Well... the multi-level submenus are doing exactly that, no?

I knew you'd say that :-p ... but no, adding a submenu for 1-2 items is imho completely over the top and only applicable for items that modify a parent option. If I have some singular/independent "ObscureOption=0" in .advanced, I don't want to clutter the simple menu only because I set it to =1.

Adding and .advanced=2 option would enable (module) authors to decide if an option is dangerous/critical if modified or simply boring, I think adding that little code complexity is well worth it.

dmilligan

Quote from: a1ex on February 11, 2014, 07:29:16 AM
There is a portability problem with hijacking the left and right keys: on some cameras (500D, probably also EOS-M) the scrollwheel simply doesn't work in certain modes. So, you have to toggle the actual value with "left" and "right". That's why I prefer the scrollwheels to be just accelerators, not mandatory.
Simple solution: it only operates in edit mode and up and down modify the value, left and right move the carret (this makes more since anyway, it's counter-inuitive that left and right should modify the value). You actually don't need a scroll wheel at all to make this work.

Quote from: a1ex on February 11, 2014, 07:29:16 AM
The rationale behind R20: I can imagine a situation where you need 2, 3, 5 or 10 pictures, 1000, 1500 or 2000, but I can't imagine why would you ever choose exactly 1005 pictures. Same for most other settings, with very few exceptions (like editing a hex address with memory browser, or tweaking the raw value of a register in iso_regs).
Then I must be a wierdo b/c one of my personal tweaks that I compile into the builds that I actually use is to basically override this functionality. I can't stand this and I use values like '1005' all the time.

Here's an example: in astro I might be doing very long bulb exposures, I want a small period between the end of one shot and the start of the next. For example a 10 minute exposure and the next exposure start 5 seconds later. To do this I need the intervalometer period to be 10:05, not possible with the current implementation. In fact if I wanted any space between shots at all with the current system it would have to be 5 mins!

Since moving the carret left/right is a logarithmic operation anyway, this solution essentially gives the same advantages as using perfered numbers (aka a logarithmic scale), with the added benefit of being able to enter precise values if one so desires.

dmilligan


a1ex

Simply feels great. Just tag a menu entry with UNIT_HEX, UNIT_DEC or UNIT_TIME and you get both fast toggling and fine-tuning at digit level, and it just feels intuitive. Thanks for another great contribution!

(will merge tonight; looking for more menu entries that may benefit from this feature)

chris_overseas

This sounds great! The memory browser could certainly use this, I was getting quite frustrated with it yesterday. mem_spy needs it even more.
EOS R5 1.1.0 | Canon 16-35mm f4.0L | Tamron SP 24-70mm f/2.8 Di VC USD G2 | Canon 70-200mm f2.8L IS II | Canon 100-400mm f4.5-5.6L II | Canon 800mm f5.6L | Canon 100mm f2.8L macro | Sigma 14mm f/1.8 DG HSM Art | Yongnuo YN600EX-RT II

a1ex

Already applied it to memory browser.

Marsu42

Quote from: a1ex on February 15, 2014, 10:21:29 AM
Already applied it to memory browser.

I'd suggest 2x in Focus Stacking / Num. of pictures + 1x Focus Settings / Start Delay

Marsu42

How is the icon type of the topmenu supposed to work? I just tried a submenu with two items, a main IT_DICE setting and then some unimportant IT_BOOL - but the icon of the submenu item latches onto the IT_BOOL even though that's the second item in the submenu.

Do I need to update the icon manually with an update function to set it to what I want?

a1ex

If you use a submenu that just groups some menus, the submenu icon is ON if any of the submenu items is ON.

IT_DICE doesn't influcence the truth value of the submenu, because it can't be turned off. But if you have something IT_DICE_OFF, that can be casted to boolean and influence the truth value.

So, if you have for example LiveView zoom settings, and any of the tweaks from there is enabled, the icon will be green (so you know you've enabled something from there). If the icon is gray, you know for sure all tweaks from that submenu are turned off (that's the rationale behind it).

If the submenu has a top-level variable (like most features in ML - on/off from top-level and all settings in submenu), it's easy.

If that's not the logic you are looking for, you can override it with an .update function (but I'd like to know the use case).

Marsu42

After trying the submenus in my modules and in one core patch request, I have the impression that an option to switch/toggle the main submenu item would be a good idea. With the current approach, the submenu line is essentially "dead space", as you can only enter the submenu.

Currently, the on/off icon is automatically generated from *any* bool in the submenu. You can add some information via RINFO I guess and via a dynamic help line - but there is no way to separate a "main" toggle/switch from options in the submenu. As a result you have to enter the submenu  all the time creating a lag, this also seem to be the reason why my pull request won't be merged (see comments go get an impression of a real life problem): https://bitbucket.org/hudson/magic-lantern/pull-request/396/wheel-actions-is-in-play-also-trigger-w/diff

The one reason for this behavior is that SET enters the submenu - would it be feasible to use another key for that, and keep SET for switching this option? It would be less intuitive, but imho it would have a huge usability benefit because entering the submenu would be less often required for toggling a "main" option.

a1ex

This was discussed and argued many times in this thread: http://www.magiclantern.fm/forum/index.php?topic=4386
and may be a good idea re-reading it just to remember the stuff.

You could set the Q button to go forward whenever possible, but then you need some other key to go back. Same if you use SET to always enter the submenus and let's say MENU to go back.

And yes, some requests stay longer in the queue until they get merged; I just can't find a good solution overnight in all cases, sorry. When something is clearly not wanted, it gets declined by us; if it's not declined, it means we like the idea, but it's either too complex (not the case here) or there's some subtle issue where we prefer to think a bit more about it.

Same with your dual ISO patch: I liked the idea, but I wanted to find a simpler solution without special cases for ETTR. I couldn't find one in a timely manner, so you declined it; again, sorry for not being able to find a solution quicker.

Marsu42

Quote from: a1ex on February 19, 2014, 07:23:54 AM
This was discussed and argued many times in this thread

I don't doubt arguments were presented on both sides, it's just that real implementation might shed some new light on former theoretical views, that's why I brought it up again.

Quote from: a1ex on February 19, 2014, 07:23:54 AM
And yes, some requests stay longer in the queue until they get merged; I just can't find a good solution overnight in all cases, sorry.

It's not about how long it takes, I can be patient enough alright, the auto_iso stayed in the queue for over a month, but I often seem have a hard time understanding what the issue is - is the expectancy that the patch author changes something, or is it simply being evaluated by the devs... and when gets a patch merged at all by "we" (who's that?), in this case the patch got an approvement by a dev.

My personal feeling is that merging a working patch first and then keep improving it would be more preferable to finding a perfect solution in the patch queue - but of course that's not up for me to decide,  so sorry for being a nuisance, I really don't want to annoy you and you know I think you're doing a great job. So at the end of the day I see everything is progressing steadily and has been discussed at length with conclusive results, so I'll stop worrying :-)

a1ex

Quote"we" (who's that?)

From the active commiters, it's just g3gg0 and nanomad, besides me. Coutts is trying to catch up with school, and from the old team, Indy prefers to do just research (we still exchange ideas), Trammell is quite busy IRL, and AJ upgraded to Red.

For auto_iso, the issue was my personal time (I wanted to do some cleanup to the module myself, that's why I asked you for commit access). Usually I choose small things to work on (things that I can finish within 5-30 minutes while waiting for something else not related to ML), or stuff that just needs tinkering around (like poking registers). Reviewing a large module and trying out stuff takes a bit more time (since I usually also modify the code to understand how it works, why it does this and that), and I prefer contiguous blocks of time (these are harder to find, just like with allocating RAM). For tiny commits or commenting around, I can just do them from the web browser, even when I don't have the camera or dev environment with me.

And yeah, I admit it, the CMOS research was a lot more interesting.

But anyone else is free to comment on code contributions and try them; there are many people with good coding skills around who follow ML from bitbucket (I see their activity from e-mail when they update their repos). I tend to weigh their opinion quite a bit more than the ones from regular forum users.

Audionut

Speaking of which, it would be a good idea not to cc people in the commit description.  Can anyone say email spam!

Bitbucket used to provide fork notices.  I don't recall changing anything in my settings, but I don't get them anymore.

a1ex

Bitbucket account settings -> notifications.