custom_popup/
custom_popup.rs1use fltk::{enums::*, prelude::*, *};
2use std::cell::RefCell;
3use std::ops::{Deref, DerefMut};
4use std::rc::Rc;
5
6pub struct PopupButton {
7 but: button::Button,
8}
9
10impl PopupButton {
11 pub fn new(label: &str) -> Self {
12 let mut but = button::Button::default().with_label(label);
13 but.set_frame(FrameType::FlatBox);
14 but.handle(|b, ev| match ev {
15 Event::Enter => {
16 b.set_color(Color::Blue);
17 b.top_window().unwrap().redraw();
18 true
19 }
20 Event::Leave => {
21 b.set_color(Color::Background);
22 b.top_window().unwrap().redraw();
23 true
24 }
25 _ => false,
26 });
27 Self { but }
28 }
29}
30
31impl Deref for PopupButton {
32 type Target = button::Button;
33
34 fn deref(&self) -> &Self::Target {
35 &self.but
36 }
37}
38
39impl DerefMut for PopupButton {
40 fn deref_mut(&mut self) -> &mut Self::Target {
41 &mut self.but
42 }
43}
44
45pub struct MyPopup {
46 win: window::Window,
47 val: Rc<RefCell<String>>,
48}
49
50impl MyPopup {
51 pub fn new(choices: &[&str]) -> Self {
52 let val = Rc::from(RefCell::from(String::from("")));
53 let mut win = window::Window::default().with_size(120, choices.len() as i32 * 25);
54 let mut pack = group::Pack::default().size_of_parent();
55 pack.set_frame(FrameType::ThinUpFrame);
56 pack.set_color(Color::Black);
57 win.set_border(false);
58 win.make_modal(true);
59 win.end();
60 for choice in choices {
61 let mut but = PopupButton::new(choice);
62 but.clear_visible_focus();
63 but.set_callback({
64 let mut win = win.clone();
65 let val = val.clone();
66 move |b| {
67 *val.borrow_mut() = b.label().unwrap();
68 win.hide();
69 }
70 });
71 pack.add(&*but);
72 }
73 pack.auto_layout();
74 Self { win, val }
75 }
76 pub fn popup(&mut self, x: i32, y: i32) -> String {
77 self.win.show();
78 self.win.resize(x, y, self.win.w(), self.win.h());
79 self.win.redraw();
80 while self.win.shown() {
81 app::wait();
82 }
83 self.val.borrow().to_string()
84 }
85}
86
87fn main() {
88 let app = app::App::default();
89 let mut win = window::Window::default().with_size(400, 300);
90 let mut frame = frame::Frame::default()
91 .with_size(200, 100)
92 .with_label("Right click me!")
93 .center_of_parent();
94 frame.set_frame(FrameType::BorderFrame);
95 frame.set_color(Color::Red);
96 win.end();
97 win.show();
98 let mut menu = MyPopup::new(&["1st item", "2nd item", &format!("{:?}", frame.frame())]);
99 frame.handle(move |_, ev| match ev {
100 Event::Push => {
101 if app::event_mouse_button() == app::MouseButton::Right {
102 println!("{}", menu.popup(app::event_x_root(), app::event_y_root()));
103 true
104 } else {
105 false
106 }
107 }
108 _ => false,
109 });
110 app.run().unwrap();
111}