From 261959edaed615d5727b5a6168af2ed23b2a8854 Mon Sep 17 00:00:00 2001 From: rowan Date: Mon, 27 Jan 2025 03:20:13 -0600 Subject: [PATCH] feat: allow handler to be set after construction --- src/lib.rs | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ee03df7..80cdbf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,13 @@ use gag::BufferRedirect; use std::{ error::Error, - ffi::{c_char, CString}, + ffi::{c_char, CStr, CString}, io::Read, + str::Utf8Error, }; use wmenu_sys::bindings; -type Callback = fn(menu: &mut Menu, text: &str) -> bool; - unsafe extern "C" fn print_item(menu: *mut bindings::menu, text: *mut i8, exit: bool) { wmenu_sys::bindings::puts(text); wmenu_sys::bindings::fflush(bindings::stdout); @@ -18,10 +17,16 @@ unsafe extern "C" fn print_item(menu: *mut bindings::menu, text: *mut i8, exit: } } +type ItemHandler = unsafe extern "C" fn(menu: *mut bindings::menu, text: *mut i8, exit: bool); + fn to_c_char(text: &str) -> *mut c_char { return CString::new(text).unwrap().into_raw(); } +fn from_c_string(text: *mut c_char) -> Result<&'static str, Utf8Error> { + unsafe { CStr::from_ptr(text).to_str() } +} + enum Output { Stdout(String), Stderr(String), @@ -72,19 +77,32 @@ impl std::fmt::Display for MenuError { impl Error for MenuError {} +trait Handle { + fn handle_item(&self, menu: Menu, text: &str) -> bool; +} + pub struct Menu { - ctx: *mut bindings::menu, + menu: *mut bindings::menu, } impl Menu { - pub fn new(callback: Callback) -> Menu { + pub fn new() -> Menu { Self { - ctx: unsafe { bindings::menu_create(Some(callback)) }, + menu: unsafe { bindings::menu_create(None) }, } } + pub fn from_menu(menu: *mut bindings::menu) -> Self { + Self { menu } + } + fn into_inner(&mut self) -> &mut bindings::menu { - unsafe { &mut *self.ctx } + unsafe { &mut *self.menu } + } + + pub fn handler(&mut self, handler: ItemHandler) -> &mut Self { + self.into_inner().callback = Some(handler); + self } pub fn bottom(&mut self, value: bool) -> &mut Self { @@ -169,7 +187,7 @@ impl Menu { pub fn add_item(&mut self, item: &str) -> &mut Self { unsafe { - bindings::menu_add_item(self.ctx, to_c_char(item)); + bindings::menu_add_item(self.menu, to_c_char(item)); } self @@ -187,7 +205,7 @@ impl Menu { let output = OutputCapture::capture().unwrap(); unsafe { - match (bindings::menu_run(self.ctx), output.get_output()) { + match (bindings::menu_run(self.menu), output.get_output()) { (0, Ok(Output::Stdout(value))) => Ok(value.trim_end().to_string()), (n, Ok(Output::Stdout(value) | Output::Stderr(value))) => { Err(MenuError::new(n, value)) @@ -201,7 +219,7 @@ impl Menu { impl Drop for Menu { fn drop(&mut self) { unsafe { - bindings::menu_destroy(self.ctx); + bindings::menu_destroy(self.menu); } } } @@ -214,7 +232,7 @@ mod tests { fn awawa() { let items = ["roewrn", "sybil", "vex"]; - let mut menu = Menu::new(); + let mut menu = Menu::new(print_item); let menu = menu .font("monospace 12") .height(32)