Popup Menu
A popup menu is a meniu that is display outside of a menubar (for example a menu that appears when right click is being pressed):

Remarks: There is no need to enable the mouse bar when creating for a popup menu.
There is no special control for a popup menu. A popup menu is a menu that is being displayed differently. Usually a popup menu is associated with either a window, a custom control or a custom desktop and it implies using the method show_menu
available on all controls:
fn show_menu(&self, handle: Handle<Menu>, x: i32, y: i32, max_size: Option<Size>) {
...
}
where:
handle
is a handle to a menu that was registered viaregister_menu(...)
methodx
andy
are coordonates within the current control where the menu should be displayed. Keep in mind that by default AppCUI will try to position the menu to the bottom-right side of the provided coordonates. However, if the menu does not fit in the available space, it will try to position the menu in a different way so that it is visible on the screen.max_size
an Option that allows one to control the maximum size of a menu. By default, a menu will attemp to increase its width and height to show all items while being visible on the screen. This behavior can be overwritten by providing a maximum width and height (keep in mind that the maximum width has to be at least 5 characters - to have at least 3 items visible)
Example
The following example creates a custom control that can display a popup menu when the use right click the mouse on 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::new("d: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,d:c,w:40,h:10");
w.add(MyCustomControl::new());
a.add_window(w);
a.run();
Ok(())
}