ReplacePoint — Pseudo widget to replace parts of a dialog
ReplacePoint
( | term | child); |
A ReplacePoint can be used to dynamically change parts of a dialog. It contains one widget. This widget can be replaced by another widget by calling ReplaceWidget( `id( id ), newchild ), where id is the the id of the new child widget of the replace point. The ReplacePoint widget itself has no further effect and no optical representation.
{
UI::OpenDialog(
`VBox(
`ReplacePoint(`id(`rp), `Label("This is a label")),
`PushButton(`id(`change), "Change")));
UI::UserInput();
UI::ReplaceWidget(`id(`rp), `PushButton("This is a PushButton"));
UI::UserInput();
UI::ReplaceWidget(`id(`rp), `CheckBox("This is a CheckBox"));
UI::UserInput();
UI::ReplaceWidget(`id(`rp), `HBox(`PushButton("Button1"), `PushButton("Button2")));
UI::UserInput();
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();
}
{
// Demo for postponed shortcut checking
term b_kilroy = `PushButton(`opt(`hstretch), "&Kilroy");
term b_was = `PushButton(`opt(`hstretch), "&was");
term b_here = `PushButton(`opt(`hstretch), "&here");
UI::OpenDialog(
`VBox(
`VSpacing( 0.3 ),
`HBox(
`HSpacing(),
`Label("Click on one of the upper buttons\n" +
"to exchange them." ),
`HSpacing()
),
`VSpacing( 0.3 ),
`ReplacePoint(`id(1), b_kilroy ),
`ReplacePoint(`id(2), b_was ),
`ReplacePoint(`id(3), b_here ),
`VSpacing(`opt(`vstretch) ),
`Right( `PushButton( `id(`cancel), "&Quit" ) )
)
);
any button = nil;
y2milestone( "Initial state: 'Kilroy was here'" );
button = UI::UserInput(); if ( button == `cancel ) return;
UI::PostponeShortcutCheck(); // "&Kilroy" "&was" "&here"
UI::ReplaceWidget(`id(1), b_was ); // "&was" "&was" "&here"
UI::ReplaceWidget(`id(2), b_kilroy ); // "&was" "&Kilroy" "&here"
UI::CheckShortcuts();
y2milestone( "After change: 'was Kilroy here'" );
button = UI::UserInput(); if ( button == `cancel ) return;
UI::PostponeShortcutCheck(); // "&was" "&Kilroy" "&here"
UI::ReplaceWidget(`id(1), b_here ); // "&here" "&Kilroy" "&here"
UI::ReplaceWidget(`id(2), b_was ); // "&here" "&was" "&here"
UI::ReplaceWidget(`id(3), b_kilroy ); // "&here" "&was" "&Kilroy"
UI::CheckShortcuts();
y2milestone( "After change: 'here was Kilroy'" );
button = UI::UserInput(); if ( button == `cancel ) return;
UI::PostponeShortcutCheck(); // "&here" "&was" "&Kilroy"
UI::ReplaceWidget(`id(1), b_kilroy ); // "&Kilroy" "&was" "&Kilroy"
UI::ReplaceWidget(`id(3), b_here ); // "&Kilroy" "&was" "&here"
// Omitting UI::CheckShortcuts();
y2milestone( "After change: back to 'Kilroy was here'" );
y2milestone( "Expect complaint about missing UI::CheckShortcuts()" );
button = UI::UserInput(); if ( button == `cancel ) return;
y2milestone( "Expect shortcut conflict: '&was' vs. '&was'" );
UI::ReplaceWidget(`id(1), b_was ); // "&was" "&was" "&here"
UI::ReplaceWidget(`id(2), b_kilroy ); // "&was" "&Kilroy" "&here"
y2milestone( "Expect complaint about excess UI::CheckShortcuts()" );
UI::CheckShortcuts();
y2milestone( "After change: 'was Kilroy here'" );
button = UI::UserInput(); if ( button == `cancel ) return;
UI::CloseDialog();
}
{
/**
* Return a text summary of existing buttons.
**/
define string Summary() ``{
string summary =
( UI::WidgetExists(`id(`top ) ) ? "Top button exists" : "No top button" ) +
( UI::WidgetExists(`id(`center ) ) ? "\nCenter button exists" : "\nNo center button" ) +
( UI::WidgetExists(`id(`bottom ) ) ? "\nBottom button exists" : "\nNo bottom button" );
return summary;
};
/**
* Remove button with given id and update summary.
**/
define void RemoveButton( term id ) ``{
UI::ReplaceWidget( id, `Empty() );
UI::ChangeWidget( `id(`summary), `Value, Summary() );
UI::RecalcLayout();
}
/**
* main
**/
UI::OpenDialog(
`VBox(
`ReplacePoint( `id(`rp_top ), `PushButton(`id(`top ), "Top Button" ) ),
`ReplacePoint( `id(`rp_center ), `PushButton(`id(`center ), "Center Button" ) ),
`ReplacePoint( `id(`rp_bottom ), `PushButton(`id(`bottom ), "Bottom Button" ) ),
`VSpacing( 1 ),
`Label(`id(`summary), "" ),
`VSpacing( 1 ),
`PushButton(`id(`close), "&Close")
)
);
// Better wait until now before doing the summary - it isn't much use before UI::OpenDialog()
// since of course all UI::WidgetExists() calls return false until then.
UI::ChangeWidget( `id(`summary), `Value, Summary() );
UI::RecalcLayout();
any button = nil;
repeat
{
button = UI::UserInput();
if ( button == `top ) RemoveButton(`id(`rp_top ) );
else if ( button == `center ) RemoveButton(`id(`rp_center ) );
else if ( button == `bottom ) RemoveButton(`id(`rp_bottom ) );
} until ( button == `close );
UI::CloseDialog();
}