Popup
Popup is used to display other widgets in floating panel that could lock input in its own bounds.
How to create
A simple popup with a button could be created using the following code:
#![allow(unused)] fn main() { fn create_popup_with_button(ctx: &mut BuildContext) -> Handle<UiNode> { PopupBuilder::new(WidgetBuilder::new()) .with_content( ButtonBuilder::new(WidgetBuilder::new()) .with_text("Click Me!") .build(ctx), ) .build(ctx) } }
Keep in mind that the popup is closed by default. You need to open it explicitly by sending a PopupMessage::Open
to
it, otherwise you won't see it:
#![allow(unused)] fn main() { fn create_popup_with_button_and_open_it(ui: &mut UserInterface) -> Handle<UiNode> { let popup = PopupBuilder::new(WidgetBuilder::new()) .with_content( ButtonBuilder::new(WidgetBuilder::new()) .with_text("Click Me!") .build(&mut ui.build_ctx()), ) .build(&mut ui.build_ctx()); // Open the popup explicitly. ui.send_message(PopupMessage::open(popup, MessageDirection::ToWidget)); popup } }
Placement
Since popups are usually used to show useful context-specific information (like context menus, drop-down lists, etc.), they're usually open above some other widget with specific alignment (right, left, center, etc.).
#![allow(unused)] fn main() { fn create_popup_with_button_and_placement_and_open_it(ui: &mut UserInterface) -> Handle<UiNode> { let popup = PopupBuilder::new(WidgetBuilder::new()) .with_content( ButtonBuilder::new(WidgetBuilder::new()) .with_text("Click Me!") .build(&mut ui.build_ctx()), ) // Set the placement. For simplicity it is just a cursor position with Handle::NONE as placement target. .with_placement(Placement::Cursor(Handle::NONE)) .build(&mut ui.build_ctx()); // Open the popup explicitly at the current placement. ui.send_message(PopupMessage::open(popup, MessageDirection::ToWidget)); popup } }
The example uses Placement::Cursor
with Handle::NONE
placement target for simplicity reasons, however in
the real-world usages this handle must be a handle of some widget that is located under the popup. It is very
important to specify it correctly, otherwise you will lose the built-in ability to fetch the actual placement target.
For example, imagine that you're building your own custom DropdownList
widget and the popup
is used to display content of the list. In this case, you could specify the placement target like this:
#![allow(unused)] fn main() { fn create_popup_with_button_and_bottom_placement_and_open_it( dropdown_list: Handle<UiNode>, ui: &mut UserInterface, ) -> Handle<UiNode> { let popup = PopupBuilder::new(WidgetBuilder::new()) .with_content( ButtonBuilder::new(WidgetBuilder::new()) .with_text("Click Me!") .build(&mut ui.build_ctx()), ) // Set the placement to the dropdown list. .with_placement(Placement::LeftBottom(dropdown_list)) .build(&mut ui.build_ctx()); // Open the popup explicitly at the current placement. ui.send_message(PopupMessage::open(popup, MessageDirection::ToWidget)); popup } }
In this case, the popup will open at the left bottom corner of the dropdown list automatically. Placement target is also
useful to build context menus, especially for lists with multiple items. Each item in the list usually has the same
context menu, and this is an ideal use case for popups, since the single context menu can be shared across multiple list
items. To find which item cause the context menu to open, catch [PopupMessage::Placement
] and extract the node
handle - this will be your actual item.
Opening mode
By default, when you click outside your popup, it will automatically close. It is pretty common behavior in the UI, you can see it almost every time you use context menus in various apps. There are cases when this behavior is undesired and it can be turned off:
#![allow(unused)] fn main() { fn create_popup_that_stays_open(ctx: &mut BuildContext) -> Handle<UiNode> { PopupBuilder::new(WidgetBuilder::new()) .with_content( ButtonBuilder::new(WidgetBuilder::new()) .with_text("Click Me!") .build(ctx), ) // This forces the popup to stay open when clicked outside of its bounds .stays_open(true) .build(ctx) } }
Smart placement
Popup widget can automatically adjust its position to always remain on screen, which is useful for tooltips, dropdown
lists, etc. To enable this option, use PopupBuilder::with_smart_placement
with true
as the first argument.