diff --git a/rust/src/cells/methods.rs b/rust/src/cells/methods.rs index 71b3d2b9b..717bb2b5c 100644 --- a/rust/src/cells/methods.rs +++ b/rust/src/cells/methods.rs @@ -9,7 +9,12 @@ use crate::{ impl NcCell { /// New NcCell, expects a [char], [NcStyleMask] and [NcChannelPair]. #[inline] - pub const fn with_all(ch: char, width: u8, stylemask: NcStyleMask, channels: NcChannelPair) -> Self { + pub const fn with_all( + ch: char, + width: u8, + stylemask: NcStyleMask, + channels: NcChannelPair, + ) -> Self { NcCell { gcluster: ch as u32, gcluster_backstop: 0 as NcEgcBackstop, diff --git a/rust/src/dimension.rs b/rust/src/dimension.rs new file mode 100644 index 000000000..173674dac --- /dev/null +++ b/rust/src/dimension.rs @@ -0,0 +1,7 @@ +//! `NcDimension`, `NcOffset` + +/// A dimension in rows or columns. Can't be negative. +pub type NcDimension = u32; + +/// An offset in rows or columns. Can be negative. +pub type NcOffset = i32; diff --git a/rust/src/keycodes.rs b/rust/src/keycodes.rs index 143c1b487..c43ae68b3 100644 --- a/rust/src/keycodes.rs +++ b/rust/src/keycodes.rs @@ -2,12 +2,8 @@ use std::mem::transmute; -// NOTE: These defined macros can't be handled by bindgen yet, see: -// - https://github.com/rust-lang/rust-bindgen/issues/316 -// - https://github.com/jethrogb/rust-cexpr/pull/15 - -// Waiting for: https://github.com/rust-lang/rust/issues/53605 -//const fn suppuabize(w: u32) -> char { +// NOTE: Waiting for: https://github.com/rust-lang/rust/issues/53605 +// const fn suppuabize(w: u32) -> char { const fn suppuabize(w: u32) -> u32 { // unsafe { transmute(w + 0x100000) } w + 0x100000 @@ -134,3 +130,7 @@ pub const NCKEY_RELEASE: char = unsafe { transmute(suppuabize(212)) }; pub const NCKEY_SCROLL_UP: char = NCKEY_BUTTON4; pub const NCKEY_SCROLL_DOWN: char = NCKEY_BUTTON5; pub const NCKEY_RETURN: char = NCKEY_ENTER; + +// Aliases, from the 128 characters common to ASCII+UTF8 +pub const NCKEY_ESC: char = unsafe { transmute(0x1b) }; +pub const NCKEY_SPACE: char = unsafe { transmute(0x20) }; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 1fee3bd1c..421bd8379 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -114,6 +114,7 @@ pub use bindings::*; mod cells; mod channel; +mod dimension; mod direct; mod error; mod file; @@ -131,12 +132,13 @@ mod time; mod visual; mod widgets; +pub use crate::input::*; pub use cells::*; pub use channel::*; +pub use dimension::*; pub use direct::*; pub use error::*; pub use file::*; -pub use input::*; pub use key::*; pub use keycodes::*; pub use macros::*; diff --git a/rust/src/macros.rs b/rust/src/macros.rs index d863d1de4..63d27f0fa 100644 --- a/rust/src/macros.rs +++ b/rust/src/macros.rs @@ -14,16 +14,14 @@ macro_rules! sleep { /// milliseconds and returns the result of [notcurses_render]. #[macro_export] macro_rules! rsleep { - ($nc:expr, $ms:expr) => { - { - let mut res: NcResult = 0; - unsafe { - res = crate::notcurses_render($nc); - } - std::thread::sleep(std::time::Duration::from_millis($ms)); - res + ($nc:expr, $ms:expr) => {{ + let mut res: NcResult = 0; + unsafe { + res = crate::notcurses_render($nc); } - }; + std::thread::sleep(std::time::Duration::from_millis($ms)); + res + }}; } /// Converts `&str` to `*mut CString`, for when `*const c_char` is needed. diff --git a/rust/src/notcurses/methods.rs b/rust/src/notcurses/methods.rs index b24a10738..6030934ff 100644 --- a/rust/src/notcurses/methods.rs +++ b/rust/src/notcurses/methods.rs @@ -3,8 +3,8 @@ use core::ptr::{null, null_mut}; use crate::{ - notcurses_init, NcLogLevel, NcPlane, NcResult, Notcurses, NotcursesOptions, - NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, + notcurses_init, sigset_t, NcInput, NcLogLevel, NcPlane, NcResult, NcTime, Notcurses, + NotcursesOptions, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, }; /// # `NotcursesOptions` Constructors @@ -116,6 +116,26 @@ impl Notcurses { /// # `Notcurses` methods impl Notcurses { + /// + pub fn getc(&mut self, time: &NcTime, sigmask: &mut sigset_t, input: &mut NcInput) -> char { + unsafe { core::char::from_u32_unchecked(crate::notcurses_getc(self, time, sigmask, input)) } + } + + /// + pub fn getc_nblock(&mut self, input: &mut NcInput) -> char { + crate::notcurses_getc_nblock(self, input) + } + + /// + pub fn getc_nblocking(&mut self, input: &mut NcInput) -> char { + crate::notcurses_getc_nblocking(self, input) + } + + /// + pub fn render(&mut self) -> NcResult { + unsafe { crate::notcurses_render(self) } + } + /// Returns a mutable reference to the standard [NcPlane] for this terminal. /// /// The standard plane always exists, and its origin is always at the @@ -136,9 +156,4 @@ impl Notcurses { pub fn stop(&mut self) -> NcResult { unsafe { crate::notcurses_stop(self) } } - - /// - pub fn render(&mut self) -> NcResult { - unsafe { crate::notcurses_render(self) } - } } diff --git a/rust/src/notcurses/reimplemented.rs b/rust/src/notcurses/reimplemented.rs index b0c256d5a..71cb30602 100644 --- a/rust/src/notcurses/reimplemented.rs +++ b/rust/src/notcurses/reimplemented.rs @@ -10,7 +10,9 @@ use crate::{ notcurses_stdplane, notcurses_stdplane_const, NcAlign, + NcDimension, NcInput, + NcOffset, NcPlane, NcTime, Notcurses, @@ -18,9 +20,10 @@ use crate::{ NCALIGN_LEFT, }; -/// return the offset into 'availcols' at which 'cols' ought be output given the requirements of 'align' +/// Returns the offset into 'availcols' at which 'cols' ought be output given +/// the requirements of 'align'. #[inline] -pub fn notcurses_align(availcols: i32, align: NcAlign, cols: i32) -> i32 { +pub fn notcurses_align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcOffset { if align == NCALIGN_LEFT { return 0; } @@ -28,14 +31,13 @@ pub fn notcurses_align(availcols: i32, align: NcAlign, cols: i32) -> i32 { return 0; } if align == NCALIGN_CENTER { - return (availcols - cols) / 2; + return ((availcols - cols) / 2) as NcOffset; } - availcols - cols // NCALIGN_RIGHT + (availcols - cols) as NcOffset // NCALIGN_RIGHT } /// 'input' may be NULL if the caller is uninterested in event details. /// If no event is ready, returns 0. -// TODO: use pakr-signals #[inline] pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char { unsafe { @@ -63,10 +65,14 @@ pub fn notcurses_getc_nblocking(nc: &mut Notcurses, input: &mut NcInput) -> char /// notcurses_stdplane(), plus free bonus dimensions written to non-NULL y/x! #[inline] -pub fn notcurses_stddim_yx<'a>(nc: &mut Notcurses, y: &mut i32, x: &mut i32) -> &'a mut NcPlane { +pub fn notcurses_stddim_yx<'a>( + nc: &mut Notcurses, + y: &mut NcDimension, + x: &mut NcDimension, +) -> &'a mut NcPlane { unsafe { let s = notcurses_stdplane(nc); - ncplane_dim_yx(s, y, x); + ncplane_dim_yx(s, &mut (*y as i32), &mut (*x as i32)); &mut *s } } diff --git a/rust/src/plane/methods.rs b/rust/src/plane/methods.rs index 5ae7f1822..68c16457a 100644 --- a/rust/src/plane/methods.rs +++ b/rust/src/plane/methods.rs @@ -1,35 +1,60 @@ //! `NcPlane*` methods and associated functions. use core::ptr::{null, null_mut}; +use std::ffi::CStr; -use crate::{cstring, NcAlign, NcCell, NcPlane, NcPlaneOptions, NcResult, Notcurses}; +use crate::{ + cstring, NcAlign, NcCell, NcChannelPair, NcDimension, NcEgc, NcOffset, NcPlane, NcPlaneOptions, + NcResult, NcStyleMask, Notcurses, +}; /// # `NcPlaneOptions` Constructors impl NcPlaneOptions { /// New NcPlaneOptions using the horizontal x. - pub fn new(y: i32, x: i32, rows: u32, cols: u32) -> Self { + pub fn new(y: NcOffset, x: NcOffset, rows: NcDimension, cols: NcDimension) -> Self { Self::with_flags(y, x, rows, cols, 0) } /// New NcPlaneOptions with horizontal alignment. - pub fn new_halign(y: i32, align: NcAlign, rows: u32, cols: u32) -> Self { - Self::with_flags( - y, - align as i32, - rows, - cols, - crate::NCPLANE_OPTION_HORALIGNED, - ) + pub fn new_aligned(y: NcOffset, align: NcAlign, rows: NcDimension, cols: NcDimension) -> Self { + Self::with_flags_aligned(y, align, rows, cols, crate::NCPLANE_OPTION_HORALIGNED) } /// New NcPlaneOptions, with flags. + pub fn with_flags( + y: NcOffset, + x: NcOffset, + rows: NcDimension, + cols: NcDimension, + flags: u64, + ) -> Self { + NcPlaneOptions { + y: y as i32, + x: x as i32, + rows: rows as i32, + cols: cols as i32, + userptr: null_mut(), + name: null(), + resizecb: None, + flags, + } + } + + /// New NcPlaneOptions, with flags and horizontal alignment. /// - /// Note: If you use [NCPLANE_OPTION_HORALIGNED] flag, you must provide - /// the [NcAlign] value to the `x` parameter, casted to `i32`. - pub fn with_flags(y: i32, x: i32, rows: u32, cols: u32, flags: u64) -> Self { + /// Note: Already includes the + /// [NCPLANE_OPTION_HORALIGNED][crate::NCPLANE_OPTION_HORALIGNED] flag. + pub fn with_flags_aligned( + y: NcOffset, + align: NcAlign, + rows: NcDimension, + cols: NcDimension, + flags: u64, + ) -> Self { + let flags = crate::NCPLANE_OPTION_HORALIGNED | flags; NcPlaneOptions { - y, - x, + y: y as i32, + x: align as i32, rows: rows as i32, cols: cols as i32, userptr: null_mut(), @@ -40,12 +65,18 @@ impl NcPlaneOptions { } } -/// # `NcPlane` Constructors +/// # `NcPlane` constructors and destructors impl NcPlane { /// New NcPlane. /// /// The returned plane will be the top, bottom, and root of this new pile. - pub fn new<'a>(nc: &mut Notcurses, y: i32, x: i32, rows: u32, cols: u32) -> &'a mut NcPlane { + pub fn new<'a>( + nc: &mut Notcurses, + y: NcOffset, + x: NcOffset, + rows: NcDimension, + cols: NcDimension, + ) -> &'a mut NcPlane { let options = NcPlaneOptions::new(y, x, rows, cols); unsafe { &mut *crate::ncpile_create(nc, &options) } } @@ -60,10 +91,10 @@ impl NcPlane { /// New NcPlane, bound to another NcPlane. pub fn new_bound<'a>( bound_to: &mut NcPlane, - y: i32, - x: i32, - rows: u32, - cols: u32, + y: NcOffset, + x: NcOffset, + rows: NcDimension, + cols: NcDimension, ) -> &'a mut NcPlane { let options = NcPlaneOptions::new(y, x, rows, cols); unsafe { &mut *crate::ncplane_create(bound_to, &options) } @@ -72,8 +103,11 @@ impl NcPlane { /// New NcPlane, bound to another plane, expects an [NcPlaneOptions] struct. /// /// The returned plane will be the top, bottom, and root of this new pile. - pub fn with_options_bound<'a>(nc: &mut Notcurses, options: &NcPlaneOptions) -> &'a mut NcPlane { - unsafe { &mut *crate::ncpile_create(nc, options) } + pub fn with_options_bound<'a>( + bound_to: &mut NcPlane, + options: &NcPlaneOptions, + ) -> &'a mut NcPlane { + unsafe { &mut *crate::ncplane_create(bound_to, options) } } /// New NcPlane, with the same dimensions of the terminal. @@ -84,9 +118,19 @@ impl NcPlane { crate::notcurses_term_dim_yx(nc, &mut trows, &mut tcols); assert![(trows > 0) & (tcols > 0)]; unsafe { - &mut *crate::ncpile_create(nc, &NcPlaneOptions::new(0, 0, trows as u32, tcols as u32)) + &mut *crate::ncpile_create( + nc, + &NcPlaneOptions::new(0, 0, trows as NcDimension, tcols as NcDimension), + ) } } + + /// Destroys the NcPlane. + /// None of its contents will be visible after the next render call. + /// It is an error to attempt to destroy the standard plane. + pub fn destroy(&mut self) -> NcResult { + unsafe { crate::ncplane_destroy(self) } + } } /// # `NcPlane` Methods @@ -95,44 +139,92 @@ impl NcPlane { /// Returns the current position of the cursor within the [NcPlane]. /// - /// Unlike [ncplane_cursor_yx] which uses `i32`, this uses [u32]. - // // NOTE: y and/or x may be NULL. - // FIXME: CHECK for NULL and return Some() or None. - pub fn cursor_yx(&self) -> (i32, i32) { + // maybe check for null and return Some() or None? + pub fn cursor_yx(&self) -> (NcDimension, NcDimension) { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_cursor_yx(self, &mut y, &mut x) }; - (y, x) + (y as NcDimension, x as NcDimension) } /// Returns the current row of the cursor within the [NcPlane]. - pub fn cursor_y(&self) -> i32 { + pub fn cursor_y(&self) -> NcDimension { self.cursor_yx().0 } /// Returns the current column of the cursor within the [NcPlane]. - pub fn cursor_x(&self) -> i32 { + pub fn cursor_x(&self) -> NcDimension { self.cursor_yx().1 } + /// Moves the cursor to the specified position within the NcPlane. + /// + /// The cursor doesn't need to be visible. + /// + /// Parameters exceeding the plane's dimensions will result in an error, + /// and the cursor position will remain unchanged. + pub fn cursor_move_yx(&mut self, y: NcDimension, x: NcDimension) -> NcResult { + unsafe { crate::ncplane_cursor_move_yx(self, y as i32, x as i32) } + } + + /// Moves the cursor the number of rows specified (forward or backwards). + /// + /// It will error if the target row exceeds the plane dimensions. + pub fn cursor_move_rows(&mut self, rows: NcOffset) -> NcResult { + let (y, x) = self.cursor_yx(); + self.cursor_move_yx((y as NcOffset + rows) as NcDimension, x) + } + + /// Moves the cursor the number of columns specified (forward or backwards). + /// + /// It will error if the target column exceeds the plane dimensions. + // TODO: maybe in this case it can improve + pub fn cursor_move_cols(&mut self, cols: NcOffset) -> NcResult { + let (y, x) = self.cursor_yx(); + self.cursor_move_yx(y, (x as NcOffset + cols) as NcDimension) + } + + /// Moves the cursor to 0, 0. + pub fn cursor_home(&mut self) { + unsafe { + crate::ncplane_home(self); + } + } + // Size -------------------------------------------------------------------- + /// Returns the column at which 'cols' columns ought start in order to be aligned according to 'align' within ncplane 'n'. Returns INT_MAX on invalid 'align'. Undefined behavior on negative 'cols'. + pub fn align(&mut self, align: NcAlign, cols: NcDimension) -> NcResult { + crate::ncplane_align(self, align, cols) + } + /// Return the dimensions of this [NcPlane]. /// - /// Unlike [ncplane_dim_yx] which uses `i32`, this uses [u32]. - pub fn dim_yx(&self) -> (u32, u32) { + /// Unlike [ncplane_dim_yx][crate::ncplane_dim_yx] which uses `i32`, + /// this uses [u32]. + pub fn dim_yx(&self) -> (NcDimension, NcDimension) { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_dim_yx(self, &mut y, &mut x) }; - (y as u32, x as u32) + (y as NcDimension, x as NcDimension) } /// Return the rows of this [NcPlane]. - pub fn dim_y(&self) -> u32 { + pub fn dim_y(&self) -> NcDimension { self.dim_yx().0 } /// Return the columns of this [NcPlane]. - pub fn dim_x(&self) -> u32 { + pub fn dim_x(&self) -> NcDimension { + self.dim_yx().1 + } + + /// Return the rows of this [NcPlane]. + pub fn rows(&self) -> NcDimension { + self.dim_yx().0 + } + + /// Return the cols of this [NcPlane]. + pub fn cols(&self) -> NcDimension { self.dim_yx().1 } @@ -150,7 +242,160 @@ impl NcPlane { unsafe { crate::ncplane_set_scrolling(self, scroll) } } - // TODO: resize + /// Resizes the NcPlane. + /// + /// The four parameters 'keep_y', 'keep_x', 'keep_len_y', and 'keep_len_x' + /// defines a subset of the NcPlane to keep unchanged. This may be a section + /// of size 0. + /// + /// 'keep_x' and 'keep_y' are relative to the NcPlane. They must specify a + /// coordinate within the ncplane's totality. If either of 'keep_len_y' or + /// 'keep_len_x' is non-zero, both must be non-zero. + /// + /// 'y_off' and 'x_off' are relative to 'keep_y' and 'keep_x', and place the + /// upper-left corner of the resized NcPlane. + /// + /// 'y_len' and 'x_len' are the dimensions of the NcPlane after resizing. + /// 'y_len' must be greater than or equal to 'keep_len_y', + /// and 'x_len' must be greater than or equal to 'keeplenx'. + /// + /// It is an error to attempt to resize the standard plane. + pub fn resize( + &mut self, + keep_y: NcDimension, + keep_x: NcDimension, + keep_len_y: NcDimension, + keep_len_x: NcDimension, + y_off: NcOffset, + x_off: NcOffset, + y_len: NcDimension, + x_len: NcDimension, + ) -> NcResult { + unsafe { + crate::ncplane_resize( + self, + keep_y as i32, + keep_x as i32, + keep_len_y as i32, + keep_len_x as i32, + y_off as i32, + x_off as i32, + y_len as i32, + x_len as i32, + ) + } + } + + /// Realigns this NcPlane against its parent, using the alignment specified + /// at creation time. Suitable for use as a 'resizecb'. + pub fn resize_realign(&mut self) -> NcResult { + unsafe { crate::ncplane_resize_realign(self) } + } + + /// Resizes the NcPlane, retaining what data we can (everything, unless we're + /// shrinking in some dimension). Keeps the origin where it is. + pub fn resize_simple(&mut self, y_len: NcDimension, x_len: NcDimension) -> NcResult { + crate::ncplane_resize_simple(self, y_len as u32, x_len as u32) + } + + /// Returns the NcPlane's current resize callback. + pub fn resizecb(&self) -> Option NcResult> { + unsafe { crate::ncplane_resizecb(self) } + } + + // Read ------------------------------------------------------------------- + + /// Retrieves the current contents of the [NcCell] under the cursor, + /// returning the [NcEgc] and writing out the [NcStyleMask] and the [NcChannelPair]. + /// + /// This NcEgc must be freed by the caller. + pub fn at_cursor( + &mut self, + stylemask: &mut NcStyleMask, + channels: &mut NcChannelPair, + ) -> Option { + let egc = unsafe { crate::ncplane_at_cursor(self, stylemask, channels) }; + if egc.is_null() { + return None; + } + let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char"); + Some(egc) + } + + /// Retrieves the current contents of the [NcCell] under the cursor. + /// + /// This NcCell is invalidated if the associated NcPlane is destroyed. + pub fn at_cursor_cell(&mut self, cell: &mut NcCell) -> NcResult { + crate::ncplane_at_cursor_cell(self, cell) + } + + /// Retrieves the current contents of the specified [NcCell], returning the + /// [NcEgc] and writing out the [NcStyleMask] and the [NcChannelPair]. + /// + /// This NcEgc must be freed by the caller. + pub fn at_yx( + &mut self, + y: i32, + x: i32, + stylemask: &mut NcStyleMask, + channels: &mut NcChannelPair, + ) -> Option { + let egc = unsafe { crate::ncplane_at_yx(self, y, x, stylemask, channels) }; + if egc.is_null() { + return None; + } + let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char"); + Some(egc) + } + + /// Extracts this NcPlane's base [NcCell] into 'cell'. + /// + /// The reference is invalidated if the NcPlane is destroyed. + pub fn base(&mut self, cell: &mut NcCell) -> NcResult { + unsafe { crate::ncplane_base(self, cell) } + } + + /// Gets the current ChannelPair for this NcPlane. + pub fn channels(&self) -> NcChannelPair { + unsafe { crate::ncplane_channels(self) } + } + + /// Creates a flat string from the NcEgc's of the selected region of the + /// NcPlane. + /// + /// Starts at the plane's 'beg_y' * 'beg_x' coordinates (which must lie on + /// the plane), continuing for 'len_y' x 'len_x' cells. + /// + /// If either of 'through_y' or 'through_x' are true, then 'len_y' or 'len_x', + /// will ignored respectively, and will go through the boundary of the plane. + pub fn contents( + &self, + beg_y: NcDimension, + beg_x: NcDimension, + len_y: NcDimension, + len_x: NcDimension, + through_y: bool, + through_x: bool, + ) -> String { + let (mut len_y, mut len_x) = (len_y as i32, len_x as i32); + if through_y { + len_y = -1; + } + if through_x { + len_x = -1; + } + unsafe { + CStr::from_ptr(crate::ncplane_contents( + self, + beg_y as i32, + beg_x as i32, + len_y, + len_x, + )) + .to_string_lossy() + .into_owned() + } + } // Write ------------------------------------------------------------------- @@ -169,8 +414,8 @@ impl NcPlane { /// The new NcCell must already be associated with the Plane. /// On success, returns the number of columns the cursor was advanced. /// On failure, -1 is returned. - pub fn putc_yx(&mut self, y: i32, x: i32, cell: &NcCell) -> NcResult { - unsafe { crate::ncplane_putc_yx(self, y, x, cell) } + pub fn putc_yx(&mut self, y: NcDimension, x: NcDimension, cell: &NcCell) -> NcResult { + unsafe { crate::ncplane_putc_yx(self, y as i32, x as i32, cell) } } /// Replaces the NcCell at the current coordinates with the provided NcCell, @@ -178,20 +423,49 @@ impl NcPlane { /// /// The new NcCell must already be associated with the Plane. /// On success, returns the number of columns the cursor was advanced. - /// On failure, -1 is returned. pub fn putc(&mut self, cell: &NcCell) -> NcResult { crate::ncplane_putc(self, cell) } - /// Writes a series of [NcEgc]s to the current location, using the current style. + /// Calls ncplane_putchar_yx() at the current cursor location. + pub fn putchar(&mut self, ch: char) -> NcResult { + crate::ncplane_putchar(self, ch) + } + + // TODO: call put_egc + // /// Replaces the [NcEgc][crate::NcEgc] to the current location, but retain + // /// the styling. The current styling of the plane will not be changed. + // pub fn putchar_stained(&mut self, y: NcDimension, x: NcDimension, ch: char) -> NcResult { + // crate::ncplane_putchar_stained(self, ch) + // } + + /// Replaces the [NcEgc][crate::NcEgc], but retain the styling. + /// The current styling of the plane will not be changed. + pub fn putchar_yx(&mut self, y: NcDimension, x: NcDimension, ch: char) -> NcResult { + crate::ncplane_putchar_yx(self, y, x, ch) + } + + /// Writes a series of [NcEgc][crate::NcEgc]s to the current location, + /// using the current style. + /// + /// Advances the cursor by some positive number of columns (though not beyond + /// the end of the plane); this number is returned on success. + /// + /// On error, a non-positive number is returned, indicating the number of + /// columns which were written before the error. pub fn putstr(&mut self, string: &str) -> NcResult { crate::ncplane_putstr(self, string) } - // TODO: Stained Replace a string's worth of glyphs at the current cursor location, but retain the styling. The current styling of the plane will not be changed + /// Writes a series of [NcEgc][crate::NcEgc]s to the current location, but + /// retain the styling. + /// The current styling of the plane will not be changed. + pub fn putstr_stained(&mut self, string: &str) -> NcResult { + unsafe { crate::ncplane_putstr_stained(self, cstring![string]) } + } - /// Write a string, which is a series of [NcEgc]s, to the current location, - /// using the current style. + /// Write a string, which is a series of [NcEgc][crate::NcEgc]s, to the + /// current location, using the current style. /// /// They will be interpreted as a series of columns (according to the /// definition of `ncplane_putc()`). @@ -201,19 +475,108 @@ impl NcPlane { /// /// On error, a non-positive number is returned, indicating the number of /// columns which were written before the error. - pub fn putstr_yx(&mut self, y: i32, x: i32, string: &str) -> NcResult { - unsafe { crate::ncplane_putstr_yx(self, y, x, cstring![string]) } + pub fn putstr_yx(&mut self, y: NcDimension, x: NcDimension, string: &str) -> NcResult { + unsafe { crate::ncplane_putstr_yx(self, y as i32, x as i32, cstring![string]) } } // Pile -------------------------------------------------------------------- - /// Returns the bottommost [NcPlane] of the pile that contains this [NnPlane]. + // CHECK: + + /// Returns the bottommost [NcPlane] of the pile that contains this [NcPlane]. pub fn bottom<'a>(&mut self) -> &'a mut NcPlane { unsafe { &mut *crate::ncpile_bottom(self) } } - /// Returns the topmost [NcPlane] of the pile that contains this [NnPlane]. + /// Returns the topmost [NcPlane] of the pile that contains this [NcPlane]. pub fn top<'a>(&mut self) -> &'a mut NcPlane { unsafe { &mut *crate::ncpile_top(self) } } + + /// Makes the physical screen match the last rendered frame from the pile of + /// which this NcPlane is a part. + /// + /// This is a blocking call. Don't call this before the pile has been + /// rendered (doing so will likely result in a blank screen). + pub fn rasterize<'a>(&mut self) -> NcResult { + unsafe { crate::ncpile_rasterize(self) } + } + + /// Renders the pile of which this NcPlane is a part. + /// Rendering this pile again will blow away the render. + /// To actually write out the render, call ncpile_rasterize(). + pub fn render<'a>(&mut self) -> NcResult { + unsafe { crate::ncpile_render(self) } + } + + // Plane ------------------------------------------------------------------- + + // move_above + // move_below + // move_bottom + // move_top + + /// Duplicates this NcPlane. + /// The new plane will have the same geometry, will duplicate all content, + /// and will start with the same rendering state. + /// + /// The new plane will be immediately above the old one on the z axis, + /// and will be bound to the same parent. Bound planes are not duplicated; + /// the new plane is bound to the current parent, but has no bound planes. + // TODO: deal with the opaque field, currently giving a null_mut pointer. + pub fn dup<'a>(&'a mut self) -> &'a mut NcPlane { + unsafe { &mut *crate::ncplane_dup(self, null_mut()) } + } + /// Moves this NcPlane relative to the standard plane, or the plane to + /// which it is bound. + /// + /// It is an error to attempt to move the standard plane. + // CHECK: whether a negative offset is valid + pub fn move_yx(&mut self, y: NcOffset, x: NcOffset) -> NcResult { + unsafe { crate::ncplane_move_yx(self, y, x) } + } + + /// Returns the NcPlane above this one, or None if already at the top. + pub fn above<'a>(&'a mut self) -> Option<&'a mut NcPlane> { + let plane = unsafe { crate::ncplane_above(self) }; + if plane.is_null() { + return None; + } + Some(unsafe { &mut *plane }) + } + + /// Returns the NcPlane below this one, or None if already at the bottom. + pub fn below<'a>(&'a mut self) -> Option<&'a mut NcPlane> { + let plane = unsafe { crate::ncplane_below(self) }; + if plane.is_null() { + return None; + } + Some(unsafe { &mut *plane }) + } + + /// Gets the parent to which this NcPlane is bound, if any. + // TODO: CHECK: what happens when it's bound to itself. + // pub fn parent<'a>(&'a mut self) -> Option<&'a mut NcPlane> { + pub fn parent<'a>(&'a mut self) -> &'a mut NcPlane { + unsafe { &mut *crate::ncplane_parent(self) } + } + + /// Gets the parent to which this NcPlane is bound, if any. + // TODO: CHECK: what happens when it's bound to itself. + // pub fn parent<'a>(&'a mut self) -> Option<&'a mut NcPlane> { + pub fn parent_const<'a>(&'a self) -> &'a NcPlane { + unsafe { &*crate::ncplane_parent_const(self) } + } + + // Context ----------------------------------------------------------------- + + /// Gets a mutable reference to the [Notcurses] context of this NcPlane. + pub fn notcurses<'a>(&mut self) -> &'a mut Notcurses { + unsafe { &mut *crate::ncplane_notcurses(self) } + } + + /// Gets an immutable reference to the [Notcurses] context of this NcPlane. + pub fn notcurses_const<'a>(&mut self) -> &'a Notcurses { + unsafe { &*crate::ncplane_notcurses_const(self) } + } } diff --git a/rust/src/plane/mod.rs b/rust/src/plane/mod.rs index 02f95e6b6..1c2565cef 100644 --- a/rust/src/plane/mod.rs +++ b/rust/src/plane/mod.rs @@ -1,31 +1,32 @@ //! `NcPlane` // functions already exported by bindgen : 105 -// ------------------------------------------ -// (#) 13 / 92 unit tests -// (W) 1 wrapped as a method or function -// ------------------------------------------ -// ncpile_bottom -// # ncpile_create -// ncpile_rasterize -// ncpile_render -// ncpile_top -// ncplane_above -// ncplane_at_cursor -// ncplane_at_yx -// ncplane_base -// ncplane_below +// ------------------------------------------- +// (X) wont: 4 +// (#) test: 13 +// (W) wrap: 28 +// ------------------------------------------- +//W ncpile_bottom +//W# ncpile_create +//W ncpile_rasterize +//W ncpile_render +//W ncpile_top +//W ncplane_above +//W ncplane_at_cursor +//W ncplane_at_yx +//W ncplane_base +//W ncplane_below // ncplane_box // ncplane_center_abs -// # ncplane_channels -// ncplane_contents -// ncplane_create -// # ncplane_cursor_move_yx +//W# ncplane_channels +//W ncplane_contents +//W ncplane_create +//W# ncplane_cursor_move_yx //W# ncplane_cursor_yx -// ncplane_destroy +//W ncplane_destroy //W# ncplane_dim_yx -// ncplane_dup -// # ncplane_erase +//W ncplane_dup +//W# ncplane_erase // ncplane_fadein // ncplane_fadein_iteration // ncplane_fadeout @@ -36,41 +37,41 @@ // ncplane_highgradient // ncplane_highgradient_sized // ncplane_hline_interp -// # ncplane_home +//W# ncplane_home // ncplane_mergedown // ncplane_mergedown_simple // ncplane_move_above // ncplane_move_below // ncplane_move_bottom // ncplane_move_top -// ncplane_move_yx +//W ncplane_move_yx // ncplane_new -// # ncplane_notcurses -// # ncplane_notcurses_const +//W# ncplane_notcurses +//W# ncplane_notcurses_const // ncplane_off_styles // ncplane_on_styles -// ncplane_parent -// ncplane_parent_const +//W ncplane_parent +//W ncplane_parent_const // ncplane_polyfill_yx // ncplane_pulse // ncplane_putchar_stained // ncplane_putc_yx -// ncplane_putegc_stained -// ncplane_putegc_yx +// X ncplane_putegc_stained +// X ncplane_putegc_yx // ncplane_putnstr_aligned // ncplane_putnstr_yx // ncplane_putstr_aligned // ncplane_putstr_stained // ncplane_putstr_yx // ncplane_puttext -// ncplane_putwegc_stained -// ncplane_putwstr_stained +// X ncplane_putwegc_stained +// X ncplane_putwstr_stained // ncplane_qrcode // ncplane_reparent // ncplane_reparent_family -// # ncplane_resize -// ncplane_resizecb -// ncplane_resize_realign +//W# ncplane_resize +//W ncplane_resizecb +//W ncplane_resize_realign // ncplane_rgba // ncplane_rotate_ccw // ncplane_rotate_cw @@ -113,12 +114,13 @@ // // functions manually reimplemented: 42 // ------------------------------------------ -// (X) wont: 8 +// (X) wont: 9 // (+) done: 34 / 0 -// (#) test: 5 / 29 +// (W) wrap: 5 +// (#) test: 5 // ------------------------------------------ // + ncplane_align -// + ncplane_at_cursor_cell +//W+ ncplane_at_cursor_cell // + ncplane_at_yx_cell // + ncplane_bchannel // + ncplane_bg_alpha @@ -143,7 +145,7 @@ // + ncplane_putc // + ncplane_putchar // + ncplane_putchar_yx -// + ncplane_putegc +// X ncplane_putegc // + ncplane_putnstr //W+ ncplane_putstr // X ncplane_putwc // I don't think these will be needed from Rust. See: @@ -154,7 +156,7 @@ // X ncplane_putwstr // // X ncplane_putwstr_aligned // // X ncplane_putwstr_yx // -// # ncplane_resize_simple +//W# ncplane_resize_simple // + ncplane_rounded_box // + ncplane_rounded_box_sized // + ncplane_vline diff --git a/rust/src/plane/reimplemented.rs b/rust/src/plane/reimplemented.rs index 7fcec2f5e..469f1ea0e 100644 --- a/rust/src/plane/reimplemented.rs +++ b/rust/src/plane/reimplemented.rs @@ -9,10 +9,10 @@ use crate::{ channels_fg_alpha, channels_fg_default_p, channels_fg_rgb, channels_fg_rgb8, cstring, ffi::__va_list_tag, ncplane_at_cursor, ncplane_at_yx, ncplane_box, ncplane_channels, ncplane_cursor_move_yx, ncplane_cursor_yx, ncplane_dim_yx, ncplane_gradient, - ncplane_hline_interp, ncplane_putc_yx, ncplane_putegc_yx, ncplane_putnstr_yx, - ncplane_putstr_yx, ncplane_resize, ncplane_styles, ncplane_vline_interp, ncplane_vprintf_yx, - notcurses_align, NcAlign, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcPlane, - NcResult, NcStyleMask, NCRESULT_ERR, NCRESULT_OK, + ncplane_hline_interp, ncplane_putc_yx, ncplane_putnstr_yx, ncplane_putstr_yx, ncplane_resize, + ncplane_styles, ncplane_vline_interp, ncplane_vprintf_yx, notcurses_align, NcAlign, + NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcDimension, NcPlane, NcResult, NcRgb, + NcStyleMask, NCRESULT_ERR, NCRESULT_OK, }; // Alpha ----------------------------------------------------------------------- @@ -71,13 +71,13 @@ pub fn ncplane_bg_rgb8( /// Gets the foreground [NcRgb] from an [NcPlane], shifted to LSBs. #[inline] -pub fn ncplane_fg_rgb(plane: &NcPlane) -> NcChannel { +pub fn ncplane_fg_rgb(plane: &NcPlane) -> NcRgb { channels_fg_rgb(unsafe { ncplane_channels(plane) }) } /// Gets the background [NcRgb] from an [NcPlane], shifted to LSBs. #[inline] -pub fn ncplane_bg_rgb(plane: &NcPlane) -> NcChannel { +pub fn ncplane_bg_rgb(plane: &NcPlane) -> NcRgb { channels_bg_rgb(unsafe { ncplane_channels(plane) }) } @@ -105,32 +105,29 @@ pub fn ncplane_putc(plane: &mut NcPlane, cell: &NcCell) -> NcResult { /// Calls ncplane_putchar_yx() at the current cursor location. #[inline] -pub fn ncplane_putchar(plane: &mut NcPlane, c: char) -> NcResult { - ncplane_putchar_yx(plane, -1, -1, c) -} - -/// Replaces the [NcEgc] underneath us, but retain the styling. -/// The current styling of the plane will not be changed. -/// -/// Replace the [NcCell] at the specified coordinates with the provided 7-bit char. -/// -/// Advance the cursor by 1. On success, returns 1. On failure, returns -1. -/// This works whether the underlying char is signed or unsigned. -#[inline] -pub fn ncplane_putchar_yx(plane: &mut NcPlane, y: i32, x: i32, ch: char) -> NcResult { +pub fn ncplane_putchar(plane: &mut NcPlane, ch: char) -> NcResult { unsafe { let cell = NcCell::with_all(ch, 0, ncplane_styles(plane), ncplane_channels(plane)); - ncplane_putc_yx(plane, y, x, &cell) + ncplane_putc_yx(plane, -1, -1, &cell) } } -/// Calls `ncplane_putegc()` at the current cursor location. +/// Replaces the [NcCell] at the specified coordinates with the provided char. +/// Advances the cursor by 1. #[inline] -pub fn ncplane_putegc(plane: &mut NcPlane, gcluster: i8, sbytes: &mut i32) -> NcResult { - unsafe { ncplane_putegc_yx(plane, -1, -1, &gcluster, sbytes) } +pub fn ncplane_putchar_yx( + plane: &mut NcPlane, + y: NcDimension, + x: NcDimension, + ch: char, +) -> NcResult { + unsafe { + let cell = NcCell::with_all(ch, 0, ncplane_styles(plane), ncplane_channels(plane)); + ncplane_putc_yx(plane, y as i32, x as i32, &cell) + } } -/// +/// Writes a series of [NcEgc][crate::NcEgc]s to the current location, using the current style. #[inline] pub fn ncplane_putstr(plane: &mut NcPlane, string: &str) -> NcResult { unsafe { ncplane_putstr_yx(plane, -1, -1, cstring![string]) } @@ -171,8 +168,21 @@ pub fn ncplane_at_cursor_cell(plane: &mut NcPlane, cell: &mut NcCell) -> NcResul /// Retrieves the current contents of the specified cell into 'cell'. /// This cell is invalidated if the associated plane is destroyed. #[inline] -pub fn ncplane_at_yx_cell(plane: &mut NcPlane, y: i32, x: i32, cell: &mut NcCell) -> NcResult { - let mut egc = unsafe { ncplane_at_yx(plane, y, x, &mut cell.stylemask, &mut cell.channels) }; +pub fn ncplane_at_yx_cell( + plane: &mut NcPlane, + y: NcDimension, + x: NcDimension, + cell: &mut NcCell, +) -> NcResult { + let mut egc = unsafe { + ncplane_at_yx( + plane, + y as i32, + x as i32, + &mut cell.stylemask, + &mut cell.channels, + ) + }; if egc.is_null() { return NCRESULT_ERR; } @@ -189,74 +199,99 @@ pub fn ncplane_at_yx_cell(plane: &mut NcPlane, y: i32, x: i32, cell: &mut NcCell /// Gets the columns of the [NcPlane]. #[inline] -pub fn ncplane_dim_x(plane: &NcPlane) -> i32 { +pub fn ncplane_dim_x(plane: &NcPlane) -> NcDimension { unsafe { let mut x = 0; ncplane_dim_yx(plane, null_mut(), &mut x); - x + x as NcDimension } } /// Gets the rows of the [NcPlane]. #[inline] #[inline] -pub fn ncplane_dim_y(plane: &NcPlane) -> i32 { +pub fn ncplane_dim_y(plane: &NcPlane) -> NcDimension { unsafe { let mut y = 0; ncplane_dim_yx(plane, &mut y, null_mut()); - y + y as NcDimension } } /// Resizes the plane, retaining what data we can (everything, unless we're /// shrinking in some dimension). Keep the origin where it is. #[inline] -pub fn ncplane_resize_simple(plane: &mut NcPlane, ylen: i32, xlen: i32) -> NcResult { - let (mut oldy, mut oldx) = (0, 0); +pub fn ncplane_resize_simple( + plane: &mut NcPlane, + y_len: NcDimension, + x_len: NcDimension, +) -> NcResult { + let (mut old_y, mut old_x) = (0, 0); unsafe { - ncplane_dim_yx(plane, &mut oldy, &mut oldx); + ncplane_dim_yx(plane, &mut old_y, &mut old_x); } - let keepleny = { - if oldy > ylen { - ylen + let keep_len_y = { + if old_y > y_len as i32 { + y_len as i32 } else { - oldy + old_y } }; - let keeplenx = { - if oldx > xlen { - xlen + let keep_len_x = { + if old_x > x_len as i32 { + x_len as i32 } else { - oldx + old_x } }; - unsafe { ncplane_resize(plane, 0, 0, keepleny, keeplenx, 0, 0, ylen, xlen) } + unsafe { + ncplane_resize( + plane, + 0, + 0, + keep_len_y, + keep_len_x, + 0, + 0, + y_len as i32, + x_len as i32, + ) + } } /// Returns the column at which 'cols' columns ought start in order to be aligned /// according to 'align' within ncplane 'n'. Returns INT_MAX on invalid 'align'. -/// Undefined behavior on negative 'cols'. -// NOTE: Leave cols as i32. See: -// - > https://github.com/dankamongmen/notcurses/issues/920 -// - https://github.com/dankamongmen/notcurses/issues/904 #[inline] -pub fn ncplane_align(plane: &NcPlane, align: NcAlign, cols: i32) -> i32 { +pub fn ncplane_align(plane: &NcPlane, align: NcAlign, cols: NcDimension) -> NcResult { notcurses_align(ncplane_dim_x(plane), align, cols) } // line ------------------------------------------------------------------------ -/// On error, return the negative number of cells drawn. +/// Draws horizontal lines using the specified NcCell, starting at the current +/// cursor position. +/// +/// The cursor will end at the cell following the last cell output, +/// just as if ncplane_putc() was called at that spot. +/// +/// Returns the number of cells drawn on success. On error, returns the negative +/// number of cells drawn. #[inline] -pub fn ncplane_hline(plane: &mut NcPlane, cell: &NcCell, len: i32) -> i32 { - unsafe { ncplane_hline_interp(plane, cell, len, cell.channels, cell.channels) } +pub fn ncplane_hline(plane: &mut NcPlane, cell: &NcCell, len: NcDimension) -> NcResult { + unsafe { ncplane_hline_interp(plane, cell, len as i32, cell.channels, cell.channels) } } +/// Draws vertical lines using the specified NcCell, starting at the current +/// cursor position. /// -/// On error, return the negative number of cells drawn. +/// The cursor will end at the cell following the last cell output, +/// just as if ncplane_putc() was called at that spot. +/// +/// Returns the number of cells drawn on success. On error, returns the negative +/// number of cells drawn. #[inline] -pub fn ncplane_vline(plane: &mut NcPlane, cell: &NcCell, len: i32) -> i32 { - unsafe { ncplane_vline_interp(plane, cell, len, cell.channels, cell.channels) } +pub fn ncplane_vline(plane: &mut NcPlane, cell: &NcCell, len: NcDimension) -> NcResult { + unsafe { ncplane_vline_interp(plane, cell, len as i32, cell.channels, cell.channels) } } // perimeter ------------------------------------------------------------------- @@ -277,7 +312,18 @@ pub fn ncplane_perimeter( ncplane_cursor_move_yx(plane, 0, 0); let (mut dimy, mut dimx) = (0, 0); ncplane_dim_yx(plane, &mut dimy, &mut dimx); - ncplane_box_sized(plane, ul, ur, ll, lr, hline, vline, dimy, dimx, ctlword) + ncplane_box_sized( + plane, + ul, + ur, + ll, + lr, + hline, + vline, + dimy as NcDimension, + dimx as NcDimension, + ctlword, + ) } } @@ -318,7 +364,18 @@ pub fn ncplane_perimeter_double( { return NCRESULT_ERR; } - let ret = ncplane_box_sized(plane, &ul, &ur, &ll, &lr, &hl, &vl, dimy, dimx, ctlword); + let ret = ncplane_box_sized( + plane, + &ul, + &ur, + &ll, + &lr, + &hl, + &vl, + dimy as NcDimension, + dimx as NcDimension, + ctlword, + ); unsafe { cell_release(plane, &mut ul); cell_release(plane, &mut ur); @@ -367,7 +424,18 @@ pub fn ncplane_perimeter_rounded( { return NCRESULT_ERR; } - let ret = ncplane_box_sized(plane, &ul, &ur, &ll, &lr, &hl, &vl, dimy, dimx, ctlword); + let ret = ncplane_box_sized( + plane, + &ul, + &ur, + &ll, + &lr, + &hl, + &vl, + dimy as NcDimension, + dimx as NcDimension, + ctlword, + ); unsafe { cell_release(plane, &mut ul); cell_release(plane, &mut ur); @@ -381,8 +449,8 @@ pub fn ncplane_perimeter_rounded( // box ------------------------------------------------------------------------- -/// Draw a box with its upper-left corner at the current cursor position, having -/// dimensions 'ylen'x'xlen'. See ncplane_box() for more information. The +/// Draws a box with its upper-left corner at the current cursor position, +/// having dimensions 'y_len' * 'x_len'. See ncplane_box() for more information. The /// minimum box size is 2x2, and it cannot be drawn off-screen. #[inline] pub fn ncplane_box_sized( @@ -393,8 +461,8 @@ pub fn ncplane_box_sized( lr: &NcCell, hline: &NcCell, vline: &NcCell, - ylen: i32, - xlen: i32, + y_len: NcDimension, + x_len: NcDimension, ctlword: u32, ) -> NcResult { let (mut y, mut x) = (0, 0); @@ -408,8 +476,8 @@ pub fn ncplane_box_sized( lr, hline, vline, - y + ylen - 1, - x + xlen - 1, + y + y_len as i32 - 1, + x + x_len as i32 - 1, ctlword, ) } @@ -421,8 +489,8 @@ pub fn ncplane_double_box( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, - ystop: i32, - xstop: i32, + ystop: NcDimension, + xstop: NcDimension, ctlword: u32, ) -> NcResult { #[allow(unused_assignments)] @@ -448,7 +516,18 @@ pub fn ncplane_double_box( &mut vl, ); if ret == NCRESULT_OK { - ret = ncplane_box(plane, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword); + ret = ncplane_box( + plane, + &ul, + &ur, + &ll, + &lr, + &hl, + &vl, + ystop as i32, + xstop as i32, + ctlword, + ); } cell_release(plane, &mut ul); @@ -467,8 +546,8 @@ pub fn ncplane_double_box_sized( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, - ylen: i32, - xlen: i32, + y_len: NcDimension, + x_len: NcDimension, ctlword: u32, ) -> NcResult { let (mut y, mut x) = (0, 0); @@ -479,8 +558,8 @@ pub fn ncplane_double_box_sized( plane, stylemask, channels, - y + ylen - 1, - x + xlen - 1, + y as NcDimension + y_len - 1, + x as NcDimension + x_len - 1, ctlword, ) } @@ -491,8 +570,8 @@ pub fn ncplane_rounded_box( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, - ystop: i32, - xstop: i32, + ystop: NcDimension, + xstop: NcDimension, ctlword: u32, ) -> NcResult { #[allow(unused_assignments)] @@ -518,7 +597,18 @@ pub fn ncplane_rounded_box( &mut vl, ); if ret == NCRESULT_OK { - ret = ncplane_box(plane, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword); + ret = ncplane_box( + plane, + &ul, + &ur, + &ll, + &lr, + &hl, + &vl, + ystop as i32, + xstop as i32, + ctlword, + ); } cell_release(plane, &mut ul); cell_release(plane, &mut ur); @@ -536,8 +626,8 @@ pub fn ncplane_rounded_box_sized( plane: &mut NcPlane, stylemask: NcStyleMask, channels: NcChannelPair, - ylen: i32, - xlen: i32, + y_len: NcDimension, + x_len: NcDimension, ctlword: u32, ) -> NcResult { let (mut y, mut x) = (0, 0); @@ -548,8 +638,8 @@ pub fn ncplane_rounded_box_sized( plane, stylemask, channels, - y + ylen - 1, - x + xlen - 1, + y as NcDimension + y_len - 1, + x as NcDimension + x_len - 1, ctlword, ) } @@ -557,7 +647,7 @@ pub fn ncplane_rounded_box_sized( // gradient -------------------------------------------------------------------- /// Draw a gradient with its upper-left corner at the current cursor position, -/// having dimensions 'ylen'x'xlen'. See ncplane_gradient for more information. +/// having dimensions 'y_len' * 'x_len'. See ncplane_gradient for more information. /// static inline int // XXX receive cells as u32? See: // - https://github.com/dankamongmen/notcurses/issues/920 @@ -571,10 +661,10 @@ pub fn ncplane_gradient_sized( ur: u64, ll: u64, lr: u64, - ylen: i32, - xlen: i32, + y_len: NcDimension, + x_len: NcDimension, ) -> NcResult { - if ylen < 1 || xlen < 1 { + if y_len < 1 || x_len < 1 { return NCRESULT_ERR; } let (mut y, mut x) = (0, 0); @@ -588,8 +678,8 @@ pub fn ncplane_gradient_sized( ur, ll, lr, - y + ylen - 1, - x + xlen - 1, + y + y_len as i32 - 1, + x + x_len as i32 - 1, ) } } diff --git a/rust/src/time.rs b/rust/src/time.rs index c464b1708..66dc83e15 100644 --- a/rust/src/time.rs +++ b/rust/src/time.rs @@ -1,6 +1,6 @@ //! `NcTime` /// -// only used for now with [`notcurses_getc_nblock`], which can't use +// Expected by [`notcurses_getc`] & [`notcurses_getc_nblock`], that can't use // libc::timespec pub type NcTime = crate::bindings::ffi::timespec;