summaryrefslogtreecommitdiff
path: root/src/widgets/menu.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/menu.rs')
-rw-r--r--src/widgets/menu.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/widgets/menu.rs b/src/widgets/menu.rs
new file mode 100644
index 0000000..fe899e3
--- /dev/null
+++ b/src/widgets/menu.rs
@@ -0,0 +1,80 @@
+use std::ffi::c_void;
+
+use crate::bindings;
+use crate::util;
+
+pub struct Menu {
+ ptr: *mut bindings::Menuwidget,
+ data: *mut bindings::Menudata,
+}
+
+pub struct Data {
+ items: Vec<Item>,
+}
+
+pub struct Item {
+ text: String,
+ hotkey: i32,
+ func: Option<unsafe extern "C" fn(index: i32)>,
+}
+
+pub enum KeyResult {
+ Handled, Ignored, Quit, Called,
+}
+
+impl Menu {
+ pub fn new(lefttop: (u32, u32), data: Data) -> Menu {
+ unsafe {
+ let mdata = util::malloc::<bindings::Menudata>(1);
+ let mitems = util::malloc::<bindings::Menuitem>(data.items.len());
+
+ (*mdata).nitems = data.items.len() as i32;
+ (*mdata).items = mitems;
+
+ for i in 0..data.items.len() {
+ (*mitems.add(i)).text = util::strdup(&data.items[i].text);
+ (*mitems.add(i)).hotkey = data.items[i].hotkey;
+ (*mitems.add(i)).func = data.items[i].func;
+ }
+
+ Menu {
+ ptr: bindings::menu_make(
+ lefttop.0 as i32, lefttop.1 as i32,
+ mdata),
+ data: mdata,
+ }
+ }
+ }
+
+ pub fn redraw(&self) {
+ unsafe { bindings::menu_redraw(self.ptr); }
+ }
+
+ pub fn handle_key(&mut self, key: i32) -> KeyResult {
+ match unsafe { bindings::menu_handlekey(self.ptr, key) } {
+ bindings::Menukey_MENUKEY_HANDLED => KeyResult::Handled,
+ bindings::Menukey_MENUKEY_IGNORED => KeyResult::Ignored,
+ bindings::Menukey_MENUKEY_QUIT => KeyResult::Quit,
+ bindings::Menukey_MENUKEY_CALLED => KeyResult::Called,
+ _ => panic!("Invalid Menukey received from termio"),
+ }
+ }
+}
+
+impl Drop for Menu {
+ fn drop(&mut self) {
+ unsafe {
+ bindings::menu_destroy(self.ptr);
+
+ let nitems = (*self.data).nitems as usize;
+ let mitems = (*self.data).items;
+
+ for i in 0..nitems {
+ libc::free((*mitems.add(i)).text as *mut c_void);
+ }
+
+ libc::free(mitems as *mut c_void);
+ libc::free(self.data as *mut c_void);
+ }
+ }
+}