GUI: should a button represent the current state or the state to be achieved through clicking the button? - user-interface

GUI: should a button represent the current state or the state to be achieved through clicking the button?
I've seen both and it sometimes misleads the user. what do you think?

The label on the button should reflect what the button does, i.e. it should describe the change the button makes.
For example, if you have a call logging system a button should say "Close Call" and the user can click it to close the call. The button should not have the label "Call is Open" and the user clicks to change the call status as that's very counter-intuitive, since the button is effectively doing the opposite to what it says on it.
In my opinion the label - and so the function - of a button should rarely, if ever, change. A button is supposed to be a like a physical button and they usually only do a single thing. (There are a few exceptions like play-pause on a media player where it's OK for the button label/icon to change, but at least this is copying a button from a real physical device.)
To carry on the example from above, I would say usually you would want two buttons, "Open Call" and "Close Call" and disable whichever one is not appropriate. Ideally you'd have a field elsewhere displaying the status of the call.
In summary, buttons are for doing things not for passing on information to the user.

The button should represent the action to be executed, not the state.

Some buttons are actions and are not ambiguous, like "Save", "Print" or "Enable user".
When a button represents a state that can be toggled, like Enable and Disable something, I do one of the following:
Change the button text, and make it always point to the state that will be achieved; (i.e. make the button point to actions, not states);
- Keep the button's text the same, but use one of those sticky buttons that will stay pressed, representing that the current state is "on" or "off". I prefer the former approach, though.

It should represent the action taken when clicking the button. States should always be presented by other means.
But I know what you mean. My car radio has buttons with text that shows the current state. It is really confusing.

This depends on the function which will be triggerd by the button click.
if the click changes the state of an entity i would suggest that the button represents the state the entity will enter after clicking the button
if the click triggers some kind of functionality the button should represent the function.

The appearance of the button is also a clue to its state. It should follow the standards of the environment if any exist (example, beveled edge / shadow appears on mouse click in Windows).

Related

wxHaskell Button State

I'm writing an application using wxHaskell and I want to be able to detect the state of a button (whether or not it is pressed at any given time). I'm having a bit of trouble figuring out how to do this, however. First I thought that there might be a "button is pressed" attribute that I could use, but there didn't seem to be. Then I had the idea of maintaining an IORef which I update on button-up and button-down events. However, that would require that the Button object actually have button-up and button-down events, which is does not appear to. It is an instance of Commanding, but I assume that the command event is fired on button-up only, which isn't enough for that idea. Does anyone have any other suggestions?
Workaround
You can implement this yourself by detecting the low-level actions that trigger those events (eg. mouse button down, space bar down).
In WX you can use the following function and constructor:
mouse :: Reactive w => Event w (EventMouse -> IO ())
data EventMouse = ... | MouseLeftDown !Point !Modifiers
And, as you suggest, you could keep the state yourself in an IORef. My suspicion is that left button here means main button (right for left-handed users).
UI design principles
The second question, which you haven't asked by I'll answer, is whether this is good UI design.
The behaviour of a button (assuming interaction using a mouse) is that click events are reported when the user releases the mouse button in the button area after pressing the mouse button down in the same area. If the user moves away and releases, or presses 'Escape', there is no click.
Taking any action on a button being pressed (not clicked) would feel unnatural for users.
In practice, the only acceptable way to use this would be, imho, to take an action whose effects can only be witnessed after releasing and which is immediately undone if the click is cancelled (ie. mouse button released outside button area).
EDIT: Please, also, take into account that users with accessibility requirements may have OS settings enabled that affect how and when button clicks are reported (but not down/up mouse events).
There is no way to know if a wxButton is pressed or not because it is an abstraction of a push button which intentionally hides this implementation detail. If you need to know the button state, use a wxToggleButton instead.

Do I have the right idea with using SetCapture() for a windowless checkbox?

My Table control uses windowless checkboxes (because there can be an arbitrary number of checkboxes here). Right now, I use TrackMouseEvent(TME_LEAVE) and manually checking if the mouse is in the checkbox rect during a WM_LBUTTONUP. I have TODOs marked in my code for the edge cases that this causes, such as a missing WM_LBUTTONUP when the mouse has left the client area.
Now I notice today's The Old New Thing says buttons use mouse captures. This got me thinking, and after looking into it, mouse captures would fit what I need more appropriately; if my assumptions are correct it would handle the various edge cases I mentioned above and be more correct in general.
In particular, the assumptions I make are: I should abandon any capture-related operations on a WM_CAPTURECHANGED even if every other condition is met. I will get a WM_CAPTURECHANGED after a ReleaseCapture(). After a SetCapture(), I will always end with either a WM_LBUTTONUP or a WM_CAPTURECHANGED, whichever comes first.
I've read both MSDN and a few articles I've found by Googling "setcapture correct use"; I just want to make sure I've got the right idea and will be implementing this correctly. Do I?
on WM_LBUTTONDOWN
if the button is in a checkbox
SetCapture()
mark that we're in checkbox clicking mode
on WM_MOUSEMOVE
if we are in checkbox clicking mode
draw the checkbox in the pressed state
on WM_LBUTTONUP
if we are in checkbox clicking mode
leave checkbox clicking mode
THEN call ReleaseCapture(), so we can ignore its WM_CAPTURECHANGED
if the mouse was released in the same checkbox
toggle it
on WM_CAPTURECHANGED
if we are in checkbox clicking mode
abandon checkbox clicking mode and leave the checkbox untoggled, even if the mouse is hovering over the checkbox
Do I have the right idea here? And in particular, is my order of operations for WM_LBUTTONDOWN correct? Thanks.
What you have said is basically right, although a real checkbox tracks WM_MOUSEMOVE while in "clicking mode" and displays the checkbox in its original state if the mouse moves off of it. So to emulate that you should have:
on WM_MOUSEMOVE
if we are in checkbox clicking mode
if mouse is over the checkbox
draw the checkbox in the pressed (toggled) state
else
draw the checkbox in the original state

How to stop event propagation despite WS_EX_NOACTIVATE?

I have a semi-transparent form (using AlphaBlend) that acts as an overlay. For the user to still be able to interact with the window below I have set WS_EX_NOACTIVATE on my form so all right and left clicks go through to the other window.
However I have a few clickable labels on my form. Clicking those and performing the appropriate action works fine since despite the WS_EX_NOACTIVATE flag the OnClick methods are called, but the click will (obviousely) also propagate to the other window, which I do not want in this case.
So, does anyone know how to "stop" the click being sent through to the window below in case I already handled it in my form ? Basically I would like being able to chose whether the click "belongs to me" and does not get propagated or whether the window below mine receives it.
As Rob explained, WS_EX_NOACTIVATE is not relevant here. Most likely you used WS_EX_TRANSPARENT and that made your window transparent to mouse clicks.
To get finer grained control of mouse click transparency, handle the WM_NCHITTEST message in your top level window. Return HTTRANSPARENT for regions that you want to be "click through". Otherwise return, for example, HTCLIENT.
Wm_ex_NoActivate should be irrelevant here. That just controls whether your window receives the input focus. Indeed, if you start with a scratch program and do nothing but change the extended window style, you'll see that when you click within the bounds of that program's window, the clicks are handled in the usual way, except that the window is never activated; programs behind that window do not receive any click events.
Therefore, to make your label controls eat click events instead of forwarding them to the windows behind them, you need to find out what you did to make them start forwarding those messages and simply stop doing that, whatever that is.

Standard placement order for common buttons

I know that in Microsoft Windows, OK/Cancel buttons normally appear in this respective order. On the other hand, in Linux distros, I often saw Cancel/OK instead.
What about (Yes/No), (Yes/No/Cancel), (Add/Edit/Remove) and other common buttons?
Is there any standard placement order for these?
From the Microsoft Windows User Experience Interaction Guidelines:
Right-align commit buttons in a single row across the bottom of the
dialog box, but above the footnote area. Do this even if there is a
single commit button (such as OK).
Present the commit buttons in the following order:
OK/[Do it]/Yes
[Don't do it]/No
Cancel
Apply (if present)
Help (if present)
From the Apple Human Interface Guidelines:
The buttons at the bottom right of a dialog all dismiss the dialog. A
button that initiates an action is furthest to the right. This action
button confirms the alert message text. The Cancel button is to the
left of this button.
If there’s a third button for dismissing the dialog, it should go to
the left of the Cancel button. If the third button could result in
data loss—Don’t Save, for example—position it at least 24 pixels away
from the “safe” buttons (Cancel and Save, for example).
A button that affects the contents of the dialog itself, such as
Reset, should have its left edge aligned with the main dialog text or
if there is a Help button, 12 pixels to the right of it.
From the Java Look and Feel Design Guidelines:
If a dialog box has a default button, make it the first command button
in the group. For example, in languages that read from left to right,
the default button is the leftmost button.
Some of the above conflict with one another. You may also find that the advice conflicts with the vendors own applications. However, I would follow the guidelines for your operating system of choice and stick with them. At least that way you have consistancy within your own output and hopefully the vast majority of other apps on your platform.
Microsoft recommends one, Apple another.
Survey here shows 50/50 split:
http://measuringuserexperience.com/SubmitCancel/index.htm
This page has also links to official UI guidelines, which answer your question for some OSes.

Should an icon show current state or next state?

When using icon images without text captions, should the icon represent the current state or the next state? For example I have a block of text that I want to minimize / maximize or I want to toggle showing All User Records or just My Records. I'm sure there are compelling arguments for either side and know that consistency is key, but what are the arguments related to good intuitive user design?
There is neither standardization nor general human tendency on this. For example, MS Windows UX Interaction Guidelines specifies four basic kinds of toggling progressive disclosure control. Three out of four show the state-when-activated, while one shows the current state.
I believe if you test a particular approach on your users, you'll get different results depending on what you ask. If you show them a control and ask them what state the app is in, they'll tend to read the icon as if it were indicating the state. If you show them a control and ask them to change the state (where in some cases the state is already changed), they'll read the icon as if it were the state to achieve. It's precisely because of this they invented toggling buttons.
If you're lucky, users use the icon primarily for either reading the state or setting the state, and not both. Then let the icon indicate whatever the users use it for.
If they indeed use it for both reading the state and setting the state, you're basically hosed, but there are a few things you can try to minimize hosehood:
Use text in addition to or instead of an icon. When labeled with a verb (e.g., "Connect"), the control indicates the state the user gets. When labeled with an adjective or noun (e.g., "On Line"), it implies the current state.
If your lib doesn't support toggling icons, then consider using a checkbox control, if that's allowed.
If your lib doesn't support checkboxes, then consider two controls, one to set each state, where the current state is disabled. Not too good for reading the current state, but there's some precedence for this in pulldown menus.
Fiddle with graphic design or placement to make it consistent with the meaning you've chosen. For example:
Command buttons are always labeled with the action they commit, so if your icon indicates the state the user gets, then give the icon a raised appearance like a command button. If the icon indicates the current state, then give it a flat appearance.
Toolbar controls usually show the state they bring about, so put the icon at the top of the window if indicates the state the user gets. In contrast, icons in the "work area" of the window indicate objects or attributes, so icons there should show the current state. Icons at the bottom of the window (in the status bar) should also show the current state.
This has not been truly standardized. Folder icons, for example, show open folders when they are open and closed folders when they are closed. Same for disclosure triangles, etc.
However, in other contexts, this is not always true. In a movie player, the "Play" arrow shows when the movie is not playing, and it shows the pause icon when it is playing. Probably the thing to do is use your best judgment, then poll your users. If a preponderance of the people you test are confused by your icon choices, switch them around. Then test them again and see if your initial test holds up. :)
If you are just going to have one button to toggle between two states, then the button should represent the next state, because that is the action that the button will take when clicked.
You gave the example of text that is minimized/maximized. Think of any expandable tree interface you ever see in Windows. A minimized tree has a [+] next to it, because clicking the button will expand the tree. And a maximized tree has a [-] next to it for the same reason.
You could also try to make a toggle that is highlighted or "pressed down" like mihi says, but that might be more confusing.
I prefer the "next state" approach (click plus to expand, click minus to collapse).
One reason is that this is the most widely used approach, so doing anything else would confuse users (and me as well).
Another reason is that the "next state" approach looks more inviting for the user to click.
May I present Zoom's mute button:
It shows the current state, as an icon, and the action that will occur when you push the button, as text. In other words, the icon on the button is the current state and the label on the button is the new state. The current state and the new state are opposites, so the button appears to contradict itself unless you read it very carefully.
(I hate that button.)

Resources