diff options
Diffstat (limited to 'src/widgets/menu.rs')
-rw-r--r-- | src/widgets/menu.rs | 80 |
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); + } + } +} |