diff --git a/rust/examples/direct-cursor.rs b/rust/examples/direct-cursor.rs index 17f649c75..8c818b0bb 100644 --- a/rust/examples/direct-cursor.rs +++ b/rust/examples/direct-cursor.rs @@ -3,20 +3,6 @@ //! Explore cursor functions in direct mode //! -// utility macro: sleep for $ms milliseconds -macro_rules! sleep { - ($ms:expr) => { - std::thread::sleep(std::time::Duration::from_millis($ms)); - }; -} - -// utility macro: convert the String $s to *mut CString -macro_rules! cstring { - ($s:expr) => { - std::ffi::CString::new($s).unwrap().as_ptr(); - } -} - use libnotcurses_sys::*; fn main() { diff --git a/rust/examples/full-basics.rs b/rust/examples/full-basics.rs index d32f0ad10..154de456d 100644 --- a/rust/examples/full-basics.rs +++ b/rust/examples/full-basics.rs @@ -1,17 +1,3 @@ -// utility macro: sleep for $ms milliseconds -macro_rules! sleep { - ($ms:expr) => { - std::thread::sleep(std::time::Duration::from_millis($ms)); - }; -} - -// utility macro: convert the String $s to *mut CString -// macro_rules! cstring { -// ($s:expr) => { -// std::ffi::CString::new($s).unwrap().as_ptr(); -// } -// } - use libnotcurses_sys::*; fn main() { @@ -22,7 +8,7 @@ fn main() { let stdplane = notcurses_stdplane(nc); for ch in "Initializing cells...".chars() { - let cell = NcCell::with_char(ch); + let cell = NcCell::with_7bitchar(ch); sleep![60]; ncplane_putc(&mut *stdplane, &cell); let _ = notcurses_render(nc); diff --git a/rust/src/cells/tests.rs b/rust/src/cells/tests.rs index f75986228..911854846 100644 --- a/rust/src/cells/tests.rs +++ b/rust/src/cells/tests.rs @@ -7,17 +7,17 @@ use serial_test::serial; #[test] #[serial] fn constructors() { - let _c1 = NcCell::new_blank(); + let _c1 = NcCell::new(); - let _c2 = NcCell::with_char('C'); + let _c2 = NcCell::with_7bitchar('C'); - let _c3 = NcCell::new('c', 0, 0); + let _c3 = NcCell::with_all('c', 0, 0); } #[test] #[serial] fn channels() { - let mut c1 = NcCell::new_blank(); + let mut c1 = NcCell::new(); assert_eq![0, crate::cell_fchannel(&c1)]; assert_eq![0, crate::cell_bchannel(&c1)]; @@ -28,7 +28,7 @@ fn channels() { assert_eq![0xBB445566, crate::cell_bchannel(&c1)]; assert_eq![0xAA112233BB445566, channels]; - let c2 = NcCell::new(' ', 0, 0x0011223300445566); + let c2 = NcCell::with_all(' ', 0, 0x0011223300445566); assert_eq![0x112233, crate::cell_fchannel(&c2)]; assert_eq![0x445566, crate::cell_bchannel(&c2)]; } @@ -38,7 +38,7 @@ fn channels() { fn rgb() { // rgb - let mut c1 = NcCell::new_blank(); + let mut c1 = NcCell::new(); assert_eq![0, crate::cell_fg_rgb(&c1)]; assert_eq![0, crate::cell_bg_rgb(&c1)]; @@ -49,7 +49,7 @@ fn rgb() { // rgb8 - let mut c2 = NcCell::new_blank(); + let mut c2 = NcCell::new(); let (mut r, mut g, mut b) = (0, 0, 0); crate::cell_set_fg_rgb8(&mut c2, 0x11, 0x22, 0x33); @@ -66,7 +66,7 @@ fn rgb() { #[test] #[serial] fn alpha() { - let mut c1 = NcCell::new_blank(); + let mut c1 = NcCell::new(); assert_eq![0, crate::cell_fg_alpha(&c1)]; assert_eq![0, crate::cell_bg_alpha(&c1)]; @@ -80,7 +80,7 @@ fn alpha() { #[test] #[serial] fn default() { - let mut c1 = NcCell::new_blank(); + let mut c1 = NcCell::new(); assert_eq![true, crate::cell_fg_default_p(&c1)]; assert_eq![true, crate::cell_bg_default_p(&c1)]; @@ -116,7 +116,7 @@ fn default() { #[test] #[serial] fn palette() { - let mut c1 = NcCell::new_blank(); + let mut c1 = NcCell::new(); assert_eq![false, crate::cell_fg_palindex_p(&c1)]; assert_eq![false, crate::cell_bg_palindex_p(&c1)]; assert_eq![0, crate::cell_fg_palindex(&c1)]; diff --git a/rust/src/cells/wrapped.rs b/rust/src/cells/wrapped.rs index 7881d5937..796e33978 100644 --- a/rust/src/cells/wrapped.rs +++ b/rust/src/cells/wrapped.rs @@ -1,11 +1,11 @@ //! Handy [NcCell] constructors -pub use crate::{NcCell, NcChannelPair, NcCharBackstop, NcStyleMask}; +pub use crate::{NcCell, NcPlane, NcChannelPair, NcCharBackstop, NcStyleMask, cell_load, NCRESULT_ERR, cstring}; impl NcCell { /// New NcCell, expects a [char], [NcStyleMask] and [NcChannelPair]. #[inline] - pub const fn new(ch: char, stylemask: NcStyleMask, channels: NcChannelPair) -> Self { + pub const fn with_all(ch: char, stylemask: NcStyleMask, channels: NcChannelPair) -> Self { NcCell { gcluster: ch as u32, gcluster_backstop: 0 as NcCharBackstop, @@ -15,15 +15,33 @@ impl NcCell { } } - /// New NcCell, expects a [char]. + /// New NcCell, expects a 7-bit [char]. + /// + /// See also `with_char`. #[inline] - pub const fn with_char(ch: char) -> Self { - Self::new(ch, 0 as NcStyleMask, 0 as NcChannelPair) + pub const fn with_7bitchar(ch: char) -> Self { + Self::with_all(ch, 0 as NcStyleMask, 0 as NcChannelPair) + } + + /// New NcCell, expects an [NcPlane] and a utf-8 [char]. + /// + /// See also `with_7bitchar`. + #[inline] + pub fn with_char(plane: &mut NcPlane, ch: char) -> Self { + let mut cell = Self::new(); + let result = unsafe { + cell_load(plane, + &mut cell, + cstring![ch.to_string()], + ) + }; + debug_assert_ne![NCRESULT_ERR, result]; + cell } /// New NcCell, blank. #[inline] - pub const fn new_blank() -> Self { - Self::with_char(0 as char) + pub const fn new() -> Self { + Self::with_7bitchar(0 as char) } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index e22689d17..3486d437a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -17,6 +17,7 @@ #![allow(non_upper_case_globals, non_camel_case_types, non_snake_case)] #![allow(clippy::too_many_arguments)] + mod bindings; #[doc(inline)] pub use bindings::*; @@ -29,6 +30,7 @@ mod file; mod input; mod key; mod keycodes; +mod macros; mod metric; mod notcurses; mod palette; @@ -46,6 +48,7 @@ pub use file::*; pub use input::*; pub use key::*; pub use keycodes::*; +pub use macros::*; pub use metric::*; pub use notcurses::*; pub use palette::*; diff --git a/rust/src/macros.rs b/rust/src/macros.rs new file mode 100644 index 000000000..9d86c4415 --- /dev/null +++ b/rust/src/macros.rs @@ -0,0 +1,17 @@ +//! Macros + +/// Sleeps for $ms milliseconds +#[macro_export] +macro_rules! sleep { + ($ms:expr) => { + std::thread::sleep(std::time::Duration::from_millis($ms)); + }; +} + +/// Converts an `&str` to `*mut CString`, for when `*const c_char` is needed. +#[macro_export] +macro_rules! cstring { + ($s:expr) => { + std::ffi::CString::new($s).unwrap().as_ptr(); + } +} diff --git a/rust/src/plane/mod.rs b/rust/src/plane/mod.rs index 26f41ef64..3d43c6a17 100644 --- a/rust/src/plane/mod.rs +++ b/rust/src/plane/mod.rs @@ -303,12 +303,12 @@ pub fn ncplane_double_box( #[allow(unused_assignments)] let mut ret = NCRESULT_OK; - let mut ul = NcCell::new_blank(); - let mut ur = NcCell::new_blank(); - let mut ll = NcCell::new_blank(); - let mut lr = NcCell::new_blank(); - let mut hl = NcCell::new_blank(); - let mut vl = NcCell::new_blank(); + let mut ul = NcCell::new(); + let mut ur = NcCell::new(); + let mut ll = NcCell::new(); + let mut lr = NcCell::new(); + let mut hl = NcCell::new(); + let mut vl = NcCell::new(); unsafe { ret = cells_double_box( @@ -401,12 +401,12 @@ pub fn ncplane_perimeter_double( unsafe { ncplane_dim_yx(plane, &mut dimy, &mut dimx); } - let mut ul = NcCell::new_blank(); - let mut ur = NcCell::new_blank(); - let mut ll = NcCell::new_blank(); - let mut lr = NcCell::new_blank(); - let mut hl = NcCell::new_blank(); - let mut vl = NcCell::new_blank(); + let mut ul = NcCell::new(); + let mut ur = NcCell::new(); + let mut ll = NcCell::new(); + let mut lr = NcCell::new(); + let mut hl = NcCell::new(); + let mut vl = NcCell::new(); if unsafe { cells_double_box( plane, @@ -450,12 +450,12 @@ pub fn ncplane_perimeter_rounded( unsafe { ncplane_dim_yx(plane, &mut dimy, &mut dimx); } - let mut ul = NcCell::new_blank(); - let mut ur = NcCell::new_blank(); - let mut ll = NcCell::new_blank(); - let mut lr = NcCell::new_blank(); - let mut hl = NcCell::new_blank(); - let mut vl = NcCell::new_blank(); + let mut ul = NcCell::new(); + let mut ur = NcCell::new(); + let mut ll = NcCell::new(); + let mut lr = NcCell::new(); + let mut hl = NcCell::new(); + let mut vl = NcCell::new(); if unsafe { cells_rounded_box( plane, @@ -506,7 +506,7 @@ pub fn ncplane_putchar(plane: &mut NcPlane, c: char) -> NcResult { // TODO: test char is < 8bit (currently 32bit) pub fn ncplane_putchar_yx(plane: &mut NcPlane, y: i32, x: i32, c: char) -> NcResult { unsafe { - let ce = NcCell::new(c, ncplane_styles(plane), ncplane_channels(plane)); + let ce = NcCell::with_all(c, ncplane_styles(plane), ncplane_channels(plane)); ncplane_putc_yx(plane, y, x, &ce) } } @@ -709,12 +709,12 @@ pub fn ncplane_rounded_box( #[allow(unused_assignments)] let mut ret = NCRESULT_OK; - let mut ul = NcCell::new_blank(); - let mut ur = NcCell::new_blank(); - let mut ll = NcCell::new_blank(); - let mut lr = NcCell::new_blank(); - let mut hl = NcCell::new_blank(); - let mut vl = NcCell::new_blank(); + let mut ul = NcCell::new(); + let mut ur = NcCell::new(); + let mut ll = NcCell::new(); + let mut lr = NcCell::new(); + let mut hl = NcCell::new(); + let mut vl = NcCell::new(); unsafe { ret = cells_rounded_box( diff --git a/rust/src/plane/wrapped.rs b/rust/src/plane/wrapped.rs index 7b0a1db2d..a09a7e7b0 100644 --- a/rust/src/plane/wrapped.rs +++ b/rust/src/plane/wrapped.rs @@ -145,14 +145,22 @@ impl NcPlane { self.dim_yx().1 } + /// Erase every NcCell in the NcPlane, resetting all attributes to normal, + /// all colors to the default color, and all cells to undrawn. + /// + /// All cells associated with this ncplane are invalidated, and must not be + /// used after the call, excluding the base cell. The cursor is homed. + pub fn erase(&mut self) { + unsafe { ncplane_erase(self) } + } + /// - // FIXME segfaults pub fn putc_yx(&mut self, y: i32, x: i32, cell: &NcCell) -> NcResult { unsafe { ncplane_putc_yx(self, y, x, cell) } } - // /// - // pub fn putc(&mut self) -> NcResult { - // unsafe { ncplane_putc(self) } - // } + /// + pub fn putc(&mut self, cell: &NcCell) -> NcResult { + ncplane_putc(self, cell) + } }