Popup Menu
A popup menu is a menu that is displayed outside of the application bar (for example, a menu that appears when the right mouse button is pressed):
Remarks: There is no need to enable the application bar for a popup menu.
There is no special control for a popup menu. A popup menu is a menu that is displayed in a different way. Usually a popup menu is associated with a window, a custom control, or a custom desktop, and using the show_menu method available on all controls:
fn show_menu(&self, handle: Handle<Menu>, x: i32, y: i32, max_size: Option<Size>) {
...
}
where:
handleis a handle to a menu that was registered via theregister_menu(...)method.xandyare coordinates within the current control where the menu should be displayed. By default, AppCUI will try to position the menu to the bottom-right of the provided coordinates. If the menu does not fit in the available space, it will try another position so that it remains visible on the screen.max_sizeis an Option that controls the maximum size of a menu. By default, a menu will attempt to grow its width and height to show all items while staying visible on the screen. This behavior can be overridden by providing a maximum width and height (the maximum width must be at least 5 characters so that at least 3 items are visible).
Example
The following example creates a custom control that can display a popup menu when the user right-clicks it:
use appcui::prelude::*;
#[CustomControl(events : MenuEvents,
overwrite : OnPaint+OnMouseEvent,
commands : A+B+C)]
struct MyCustomControl {
popup_menu: Handle<Menu>,
}
impl MyCustomControl {
fn new() -> Self {
let mut w = MyCustomControl {
base: ControlBase::new(layout!("a:c,w:8,h:2"), true),
popup_menu: Handle::None,
};
// construct a popup menu
let m = menu!("Popup,class: MyCustomControl, items=[
{Command-1,cmd:A},
{Command-2,cmd:B},
{-},
{'Option A',checked:true, cmd:C},
{'Option B',checked:true, cmd:C},
{'Option C',checked:false, cmd:C},
{'Option D',checked:false, cmd:C},
]");
w.popup_menu = w.register_menu(m);
w
}
}
impl MenuEvents for MyCustomControl {
fn on_command(&mut self, _menu: Handle<Menu>, _item: Handle<menu::Command>, command: mycustomcontrol::Commands) {
match command {
mycustomcontrol::Commands::A => { /* do something */ },
mycustomcontrol::Commands::B => { /* do something */ },
mycustomcontrol::Commands::C => { /* do something */ },
}
}
}
impl OnPaint for MyCustomControl {
fn on_paint(&self, surface: &mut Surface, _theme: &Theme) {
surface.clear(char!("' ',White,DarkRed"));
}
}
impl OnMouseEvent for MyCustomControl {
fn on_mouse_event(&mut self, event: &MouseEvent) -> EventProcessStatus {
// if the event is a mouse click
if let MouseEvent::Pressed(ev) = event {
// if the button is the right one
if ev.button == MouseButton::Right {
// show the popup menu at mouse coordinates
self.show_menu(self.popup_menu, ev.x, ev.y, None);
}
}
EventProcessStatus::Ignored
}
}
fn main() -> Result<(), appcui::system::Error> {
let mut a = App::new().build()?;
let mut w = window!("Title,a:c,w:40,h:10");
w.add(MyCustomControl::new());
a.add_window(w);
a.run();
Ok(())
}