Tutorial: What the F*** is UpdateUI anyway? (wxWidgets)

In this mini tutorial I will try to shear some light on the matter.

What is an Update UI event? What is it used for? Why it's super-cool?

UpdateUI events try to centralize the logic of interface feedback.
Handling these events should make sure that the information showed to the user reflects the state of the application.

Examples:
* Enable/Disable a submit button based on the validity of the form's elements.
* Check/Uncheck a box based on a selected list item, if it should be processed or not.
* Change the text of a menu item according to the visibility of a toolbar (e.g. Show palette/Hide palette)
* Show/Hide controls according to the user permissions.
* Et cetera.

In the form example to change the status of the submit button, instead of having to check on different sorts of "control has changed" event handlers (a whole logic mess), you should do all these checks in the submit button's Update UI event.

How many times you clicked a button and it yelled at you "You don't have permissions to click this button".
If I don't have permission, then it shouldn't be enabled to begin with!

Update UI events are raised on idle time, when all other events have been processed.
By default handlers to these are called for all controls.

Using it!

Update UI events hand you a wxUpdateUIEvent object.
This object allows you to call on common functions (SetText/Check/Enable...) so you don't have to care if you're disabling a button, combo box, gauge or a whole panel!
This object performs the given operation on the real control behind the curtains.

This will be practical sooner than you think (see code below)...

Update UI events are by default broadcasted to the parent if left unhandled, so you can handle all your Frame's children at once instead of defining a handler for each control:

void MyFrame::OnUpdateUI( wxUpdateUIEvent& event )
{
\twxObject *updObj = ev.GetEventObject();
\tif(updObj == myOKButton_ || updObj == myApplyButton_)
\t{
\t\tev.Enable(IsTheFormFilled()); //See? super practical!
\t}
\telse
\t{
\t\tev.Skip()
\t}
}
I find this most useful when I'm using a GUI designer like wxFormBuilder.
You're probably deriving your Frame class from a changing generated base class, and adding UpdateUI events for each control to your custom made derived class is a drag.
Using if's is a great solution if you're not scared to loose a little bit of performance.

My app is sluggish

If Update UI events are making your application slow, no problem you can always call the static function:
wxUpdateUIEvent::SetUpdateInterval( <milliseconds> )
With a delay to wait before sending UpdateUI events, while being idle.

This could cause inconsistency between the application state and the controls, so you're forced to call the window's UpdateWindowUI(wxUPDATE_UI_RECURSE) in order to force the event.
Good places to do so are when you show/activate a window, change the tab in a wxNotebook, etc...

Hope you liked this tutorial
Good luck, and happy coding!
-Martín

0 comments: