rust: add NcMenu methods & fix error_ptr macro

pull/1259/head
joseLuís 4 years ago
parent e75432fcf2
commit e966348321

@ -138,13 +138,14 @@ macro_rules! error {
macro_rules! error_ptr {
($ptr:expr, $msg:expr) => {
if $ptr != core::ptr::null_mut() {
#[allow(unused_unsafe)]
return Ok(unsafe { &mut *$ptr });
} else {
return Err(crate::NcError::with_msg(crate::NCRESULT_ERR, $msg));
}
};
($ptr:expr) => {
error![$ptr, (), ""];
error_ptr![$ptr, ""];
};
}
@ -160,6 +161,7 @@ macro_rules! error_ptr {
macro_rules! error_str {
($str:expr, $msg:expr) => {
if $str != core::ptr::null_mut() {
#[allow(unused_unsafe)]
return Ok(unsafe { (&*$str).to_string() });
} else {
return Err(crate::NcError::with_msg(crate::NCRESULT_ERR, $msg));

@ -1,31 +1,198 @@
//! `NcMenu*` methods and associated functions.
use core::ptr::null_mut;
use crate::{
cstring, ncmenu_create, NcChannelPair, NcInput, NcMenu, NcMenuItem, NcMenuOptions,
NcMenuSection, NcPlane,
cstring, error, error_ptr, error_str, ncmenu_create, NcChannelPair, NcInput, NcMenu,
NcMenuItem, NcMenuOptions, NcMenuSection, NcPlane, NcResult,
};
/// # `NcMenu` Constructors
/// # `NcMenu` constructors & destructors
impl NcMenu {
/// `NcMenu` simple constructor
pub fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
Self::with_options(plane, &NcMenuOptions::new())
/// New NcMenu.
///
/// *C style function: [ncmenu_create()][crate::ncmenu_create].*
pub fn new<'a>(plane: &mut NcPlane) -> NcResult<&'a mut Self> {
Self::with_options(plane, NcMenuOptions::new())
}
/// Creates an [NcMenu] with the specified options.
///
/// Menus are currently bound to an overall [Notcurses][crate::Notcurses]
/// object (as opposed to a particular plane), and are implemented as
/// [NcPlane]s kept atop other NcPlanes.
///
/// *C style function: [ncmenu_create()][crate::ncmenu_create].*
pub fn with_options<'a>(plane: &mut NcPlane, options: NcMenuOptions) -> NcResult<&'a mut Self> {
error_ptr![
unsafe { ncmenu_create(plane, &options) },
"Creating NcMenu"
]
}
/// Destroys an NcMenu created with [create()][NcMenu#method.create].
///
/// *C style function: [ncmenu_destroy()][crate::ncmenu_destroy].*
pub fn ncmenu_destroy(&mut self) -> NcResult<()> {
error![unsafe { crate::ncmenu_destroy(self) }]
}
}
/// # `NcMenu` methods
impl NcMenu {
/// Disables or enables an [NcMenuItem].
///
/// *C style function: [ncmenu_item_set_status()][crate::ncmenu_item_set_status].*
pub fn ncmenu_item_set_status(
&mut self,
section: &str,
item: &str,
enabled: bool,
) -> NcResult<()> {
error![unsafe {
crate::ncmenu_item_set_status(self, cstring![section], cstring![item], enabled)
}]
}
/// Returns the [NcMenuItem] description corresponding to the mouse click `click`.
///
/// The [NcMenuItem] must be on an actively unrolled section, and the click
/// must be in the area of a valid item.
///
/// If `ninput` is provided, and the selected item has a shortcut,
/// it will be filled in with that shortcut.
///
/// *C style function: [ncmenu_mouse_selected()][crate::ncmenu_mouse_selected].*
pub fn ncmenu_mouse_selected(
&self,
click: &NcInput,
shortcut: Option<&mut NcInput>,
) -> NcResult<String> {
let ninput;
if let Some(i) = shortcut {
ninput = i as *mut _;
} else {
ninput = null_mut();
}
error_str![
unsafe { crate::ncmenu_mouse_selected(self, click, ninput) },
"Getting NcMenuItem description"
]
}
/// Moves to the next item within the currently unrolled section.
///
/// If no section is unrolled, the first section will be unrolled.
///
/// *C style function: [ncmenu_nextitem()][crate::ncmenu_nextitem].*
pub fn ncmenu_nextitem(&mut self) -> NcResult<()> {
error![unsafe { crate::ncmenu_nextitem(self) }]
}
/// Unrolls the next section (relative to current unrolled).
///
/// If no section is unrolled, the first section will be unrolled.
///
/// *C style function: [ncmenu_nextsection()][crate::ncmenu_nextsection].*
pub fn ncmenu_nextsection(&mut self) -> NcResult<()> {
error![unsafe { crate::ncmenu_nextsection(self) }]
}
/// Offers the `input` to this NcMenu.
///
/// If it's relevant, this function returns true,
/// and the input ought not be processed further.
/// If it's irrelevant to the menu, false is returned.
///
/// Relevant inputs include:
/// - mouse movement over a hidden menu
/// - a mouse click on a menu section (the section is unrolled)
/// - a mouse click outside of an unrolled menu (the menu is rolled up)
/// - left or right on an unrolled menu (navigates among sections)
/// - up or down on an unrolled menu (navigates among items)
/// - escape on an unrolled menu (the menu is rolled up)
///
/// *C style function: [ncmenu_offer_input()][crate::ncmenu_offer_input].*
pub fn ncmenu_offer_input(&mut self, input: NcInput) -> bool {
unsafe { crate::ncmenu_offer_input(self, &input) }
}
/// Returns the [NcPlane] backing this NcMenu.
///
/// *C style function: [ncmenu_plane()][crate::ncmenu_plane].*
pub fn ncmenu_plane(&mut self) -> NcResult<&NcPlane> {
error_ptr![
unsafe { crate::ncmenu_plane(self) },
"Getting the backing NcPlane"
]
}
/// Moves to the previous item within the currently unrolled section.
///
/// If no section is unrolled, the first section will be unrolled.
///
/// *C style function: [ncmenu_previtem()][crate::ncmenu_previtem].*
pub fn ncmenu_previtem(&mut self) -> NcResult<()> {
error![unsafe{ crate::ncmenu_previtem(self) }]
}
/// Unrolls the previous section (relative to current unrolled).
///
/// If no section is unrolled, the first section will be unrolled.
///
/// *C style function: [ncmenu_prevsection()][crate::ncmenu_prevsection].*
pub fn ncmenu_prevsection(&mut self) -> NcResult<()> {
error![unsafe{ crate::ncmenu_prevsection(self) }]
}
/// Rolls up any unrolled [NcMenuSection],
/// and hides this NcMenu if using hiding.
///
/// *C style function: [ncmenu_rollup()][crate::ncmenu_rollup].*
pub fn ncmenu_rollup(&mut self) -> NcResult<()> {
error![unsafe{ crate::ncmenu_rollup(self) }]
}
/// Returns the selected item description,
/// or an error if no section is unrolled.
///
/// If `shortcut` is provided, and the selected item has a shortcut,
/// it will be filled in with that shortcut--this can allow faster matching.
///
/// *C style function: [ncmenu_selected()][crate::ncmenu_selected].*
pub fn ncmenu_selected(
&mut self,
shortcut: Option<&mut NcInput>,
) -> NcResult<String> {
let ninput;
if let Some(i) = shortcut {
ninput = i as *mut _;
} else {
ninput = null_mut();
}
error_str![
unsafe { crate::ncmenu_selected(self, ninput) },
"Getting the selected NcMenuItem description"
]
}
/// `NcMenu` constructor with options
pub fn with_options<'a>(plane: &mut NcPlane, options: &NcMenuOptions) -> &'a mut Self {
unsafe { &mut *ncmenu_create(plane, options) }
/// Unrolls the specified [NcMenuSection], making the menu visible if it was
/// invisible, and rolling up any NcMenuSection that is already unrolled.
///
/// *C style function: [ncmenu_unroll()][crate::ncmenu_unroll].*
pub fn ncmenu_unroll(&mut self, sectionindex: u32) -> NcResult<()> {
error![unsafe{ crate::ncmenu_unroll(self, sectionindex as i32) }]
}
}
/// # `NcMenuOptions` Constructors
impl NcMenuOptions {
/// `NcMenuOptions` simple constructor
/// New NcMenuOptions.
pub fn new() -> Self {
Self::with_options(&mut [], 0, 0, 0, 0)
}
/// `NcMenuOptions` width options
/// New NcMenuOptions with width options.
pub fn with_options(
sections: &mut [NcMenuSection],
count: u32,
@ -54,7 +221,7 @@ impl NcMenuOptions {
/// # `NcMenuItem` Constructors
impl NcMenuItem {
/// `NcMenuItem` simple constructor
/// New NcMenuItem.
pub fn new(mut desc: i8, shortcut: NcInput) -> Self {
Self {
// utf-8 menu item, NULL for horizontal separator
@ -68,7 +235,7 @@ impl NcMenuItem {
/// # `NcMenuSection` Constructors
impl NcMenuSection {
/// `NcMenuSection` simple constructor
/// New NcMenuSection.
pub fn new(name: &str, itemcount: i32, items: &mut [NcMenuItem], shortcut: NcInput) -> Self {
Self {
// utf-8 name string

@ -2,28 +2,33 @@
// functions already exported by bindgen : 13
// ------------------------------------------
// ncmenu_create
// ncmenu_destroy
// ncmenu_item_set_status
// ncmenu_mouse_selected
// ncmenu_nextitem
// ncmenu_nextsection
// ncmenu_offer_input
// ncmenu_plane
// ncmenu_previtem
// ncmenu_prevsection
// ncmenu_rollup
// ncmenu_selected
// ncmenu_unroll
// (#) test: 0
// (W) wrap: 13
// ------------------------------------------
//W ncmenu_create
//W ncmenu_destroy
//W ncmenu_item_set_status
//W ncmenu_mouse_selected
//W ncmenu_nextitem
//W ncmenu_nextsection
//W ncmenu_offer_input
//W ncmenu_plane
//W ncmenu_previtem
//W ncmenu_prevsection
//W ncmenu_rollup
//W ncmenu_selected
//W ncmenu_unroll
mod methods;
/// menus on the top or bottom rows
///
/// A notcurses instance supports menu bars on the top or bottom row of the true
/// screen.
/// A [Notcurses][crate::Notcurses] instance supports menu bars
/// on the top or bottom row of the true screen.
///
/// An NcMenu is composed of [NcMenuSection]s, which are in turn composed of
/// [NcMenuItem]s.
///
/// A menu is composed of sections, which are in turn composed of items.
/// Either no sections are visible, and the menu is rolled up, or exactly one
/// section is unrolled.
///

Loading…
Cancel
Save