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.
<xi:include></xi:include>
{
// 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();
}