|
YCP UI Widget Reference
Back to the widget index
DumbTab
|
Simplistic tab widget that behaves like push buttons
|
|
Description
This is a very simplistic approach to tabbed dialogs: The application
specifies a number of tab headers and the page contents and takes care of
most other things all by itself, in particular page switching. Each tab
header behaves very much like a PushButton - as the user activates a tab
header, the DumbTab widget simply returns the ID of that tab (or its text if
it has no ID). The application should then take care of changing the page
contents accordingly - call UI::ReplaceWidget() on the ReplacePoint
specified as tab contents or similar actions (it might even just replace
data in a Table or RichText widget if this is the tab contents). Hence the
name DumbTab.
The items in the item list can either be simple strings or `item() terms
with an optional ID for each individual item (which will be returned upon
UI::UserInput() and related when the user selects this tab), a (mandatory)
user-visible label and an (optional) flag that indicates that this tab is
initially selected. If you specify only a string, UI::UserInput() will
return this string.
Style Guide Note:
Please notice that using this kind of widget more often than not is the
result of poor dialog or workflow design.
Using tabs only hides complexity, but the complexity remains there. They do
little to make problems simpler. This however should be the approach of
choice for good user interfaces.
It is very common for tabs to be overlooked by users if there are just two
tabs to select from, so in this case better use an "Expert..." or
"Details..." button - this gives much more clue to the user that there is
more information available while at the same time clearly indicating that
those other options are much less commonly used.
If there are very many different views on data or if there are lots and lots
of settings, you might consider using a tree for much better navigation. The
Qt UI's wizard even has a built-in tree that can be used instead of the help
panel.
If you use a tree for navigation, unter all circumstances avoid using tabs
at the same time - there is no way for the user to tell which tree nodes
have tabs and which have not, making navigation even more difficult.
KDE's control center or Mozilla's settings are very good examples
how not to do that - you become bogged down for sure in all those
tree nodes and tabs hidden within so many of them.
Technical Usage Note:
This is a "special" widget, i.e. not all UIs necessarily support it. Check
for availability with HasSpecialWidget( `DownloadProgress ) before
using it.
Arguments
list
|
tabs
|
page headers
|
term
|
contents
|
page contents - usually a ReplacePoint
|
Special Properties
any
|
CurrentItem
|
the currently selected tab
|
Sample Usage
if ( HasSpecialWidget( `DumbTab) {...
`DumbTab( [ `item(`id(`page1), "Page &1" ), `item(`id(`page2), "Page &2" ) ], contents; }
Examples
// Minimalistic example for tab widget
{
if ( ! UI::HasSpecialWidget(`DumbTab ) )
{
UI::OpenDialog(
`VBox(
`Label("Error: This UI doesn't support the DumbTab widget!"),
`PushButton(`opt(`default), "&OK")
)
);
UI::UserInput();
UI::CloseDialog();
return;
}
UI::OpenDialog(
`VBox(
`DumbTab(
[ "Page 1", "Page 2", "Page 3" ],
`RichText(`id(`contents), "Contents" )
),
`Right(`PushButton(`id(`close), "&Close" ) )
)
);
UI::DumpWidgetTree();
any input = nil;
repeat
{
input = UI::UserInput();
if ( is( input, string ) )
{
UI::ChangeWidget(`contents, `Value, (string) input );
}
} until ( input == `close );
UI::CloseDialog();
}
|
// Typical usage example for tab widget
{
term address_page =
`VBox(
`Left( `Heading( "Address" ) ),
`VSpacing(),
`HCenter(
`HSquash(
`VBox(
`HSpacing( 50 ),
`TextEntry( "Name" ),
`TextEntry( "E-Mail" ),
`TextEntry( "Phone" ),
`VSpacing(),
`MultiLineEdit( "Comments" ),
`VStretch()
)
)
)
);
term overview_page =
`VBox(
`Left( `Heading( "DumbTab Widget Overview" ) ),
`VSpacing(),
`Label( "This kind of tab is pretty dumb - hence the name DumbTab.\n"
+ "You need to do most everything yourself.\n"
+ "Each tab behaves very much like a push button;\n"
+ "the YCP application is notified when the user clicks on a tab.\n"
+ "The application must take care to exchange the tab contents." )
);
term style_hints_page =
`VBox(
`Left( `Heading( "GUI Style Hints" ) ),
`VSpacing(),
`Heading( "Using tabs is usually a result of poor dialog design." ),
`VSpacing(),
`Left(
`Label( "Tabs hide complexity, they do not resolve it.\n"
+ "The problem remains just as complex as before,\n"
+ "only the user can no longer see it."
)
)
);
UI::OpenDialog(`opt(`defaultsize),
`VBox(
`DumbTab( [
`item(`id(`address ), "&Address" ),
`item(`id(`overview ), "&Overview" ),
`item(`id(`style ), "GUI &Style Hints", true ) // true: selected
],
`Left(
`Top(
`HVSquash(
`VBox(
`VSpacing(0.3),
`HBox(
`HSpacing(1),
`ReplacePoint(`id(`tabContents ), style_hints_page )
)
)
)
)
)
),
`Right(`PushButton(`id(`close), "Cl&ose" ) )
)
);
while ( true )
{
symbol widget = (symbol) UI::UserInput();
if ( widget == `close ) break;
else if ( widget == `address ) UI::ReplaceWidget(`tabContents, address_page );
else if ( widget == `overview ) UI::ReplaceWidget(`tabContents, overview_page );
else if ( widget == `style ) UI::ReplaceWidget(`tabContents, style_hints_page );
}
UI::CloseDialog();
}
|
Back to the widget index
|