Merge branch 'master' of github.com:dankamongmen/notcurses

pull/1239/head
nick black 4 years ago
commit 1303e5e310
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -9,7 +9,12 @@ use crate::{
impl NcCell { impl NcCell {
/// New NcCell, expects a [char], [NcStyleMask] and [NcChannelPair]. /// New NcCell, expects a [char], [NcStyleMask] and [NcChannelPair].
#[inline] #[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 { NcCell {
gcluster: ch as u32, gcluster: ch as u32,
gcluster_backstop: 0 as NcEgcBackstop, gcluster_backstop: 0 as NcEgcBackstop,

@ -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;

@ -2,12 +2,8 @@
use std::mem::transmute; use std::mem::transmute;
// NOTE: These defined macros can't be handled by bindgen yet, see: // NOTE: Waiting for: https://github.com/rust-lang/rust/issues/53605
// - https://github.com/rust-lang/rust-bindgen/issues/316 // const fn suppuabize(w: u32) -> char {
// - https://github.com/jethrogb/rust-cexpr/pull/15
// Waiting for: https://github.com/rust-lang/rust/issues/53605
//const fn suppuabize(w: u32) -> char {
const fn suppuabize(w: u32) -> u32 { const fn suppuabize(w: u32) -> u32 {
// unsafe { transmute(w + 0x100000) } // unsafe { transmute(w + 0x100000) }
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_UP: char = NCKEY_BUTTON4;
pub const NCKEY_SCROLL_DOWN: char = NCKEY_BUTTON5; pub const NCKEY_SCROLL_DOWN: char = NCKEY_BUTTON5;
pub const NCKEY_RETURN: char = NCKEY_ENTER; 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) };

@ -114,6 +114,7 @@ pub use bindings::*;
mod cells; mod cells;
mod channel; mod channel;
mod dimension;
mod direct; mod direct;
mod error; mod error;
mod file; mod file;
@ -131,12 +132,13 @@ mod time;
mod visual; mod visual;
mod widgets; mod widgets;
pub use crate::input::*;
pub use cells::*; pub use cells::*;
pub use channel::*; pub use channel::*;
pub use dimension::*;
pub use direct::*; pub use direct::*;
pub use error::*; pub use error::*;
pub use file::*; pub use file::*;
pub use input::*;
pub use key::*; pub use key::*;
pub use keycodes::*; pub use keycodes::*;
pub use macros::*; pub use macros::*;

@ -14,16 +14,14 @@ macro_rules! sleep {
/// milliseconds and returns the result of [notcurses_render]. /// milliseconds and returns the result of [notcurses_render].
#[macro_export] #[macro_export]
macro_rules! rsleep { macro_rules! rsleep {
($nc:expr, $ms:expr) => { ($nc:expr, $ms:expr) => {{
{ let mut res: NcResult = 0;
let mut res: NcResult = 0; unsafe {
unsafe { res = crate::notcurses_render($nc);
res = crate::notcurses_render($nc);
}
std::thread::sleep(std::time::Duration::from_millis($ms));
res
} }
}; std::thread::sleep(std::time::Duration::from_millis($ms));
res
}};
} }
/// Converts `&str` to `*mut CString`, for when `*const c_char` is needed. /// Converts `&str` to `*mut CString`, for when `*const c_char` is needed.

@ -3,8 +3,8 @@
use core::ptr::{null, null_mut}; use core::ptr::{null, null_mut};
use crate::{ use crate::{
notcurses_init, NcLogLevel, NcPlane, NcResult, Notcurses, NotcursesOptions, notcurses_init, sigset_t, NcInput, NcLogLevel, NcPlane, NcResult, NcTime, Notcurses,
NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, NotcursesOptions, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS,
}; };
/// # `NotcursesOptions` Constructors /// # `NotcursesOptions` Constructors
@ -116,6 +116,26 @@ impl Notcurses {
/// # `Notcurses` methods /// # `Notcurses` methods
impl Notcurses { 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. /// Returns a mutable reference to the standard [NcPlane] for this terminal.
/// ///
/// The standard plane always exists, and its origin is always at the /// The standard plane always exists, and its origin is always at the
@ -136,9 +156,4 @@ impl Notcurses {
pub fn stop(&mut self) -> NcResult { pub fn stop(&mut self) -> NcResult {
unsafe { crate::notcurses_stop(self) } unsafe { crate::notcurses_stop(self) }
} }
///
pub fn render(&mut self) -> NcResult {
unsafe { crate::notcurses_render(self) }
}
} }

@ -10,7 +10,9 @@ use crate::{
notcurses_stdplane, notcurses_stdplane,
notcurses_stdplane_const, notcurses_stdplane_const,
NcAlign, NcAlign,
NcDimension,
NcInput, NcInput,
NcOffset,
NcPlane, NcPlane,
NcTime, NcTime,
Notcurses, Notcurses,
@ -18,9 +20,10 @@ use crate::{
NCALIGN_LEFT, 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] #[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 { if align == NCALIGN_LEFT {
return 0; return 0;
} }
@ -28,14 +31,13 @@ pub fn notcurses_align(availcols: i32, align: NcAlign, cols: i32) -> i32 {
return 0; return 0;
} }
if align == NCALIGN_CENTER { 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. /// 'input' may be NULL if the caller is uninterested in event details.
/// If no event is ready, returns 0. /// If no event is ready, returns 0.
// TODO: use pakr-signals
#[inline] #[inline]
pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char { pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char {
unsafe { 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! /// notcurses_stdplane(), plus free bonus dimensions written to non-NULL y/x!
#[inline] #[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 { unsafe {
let s = notcurses_stdplane(nc); 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 &mut *s
} }
} }

@ -1,35 +1,60 @@
//! `NcPlane*` methods and associated functions. //! `NcPlane*` methods and associated functions.
use core::ptr::{null, null_mut}; 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 /// # `NcPlaneOptions` Constructors
impl NcPlaneOptions { impl NcPlaneOptions {
/// New NcPlaneOptions using the horizontal x. /// 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) Self::with_flags(y, x, rows, cols, 0)
} }
/// New NcPlaneOptions with horizontal alignment. /// New NcPlaneOptions with horizontal alignment.
pub fn new_halign(y: i32, align: NcAlign, rows: u32, cols: u32) -> Self { pub fn new_aligned(y: NcOffset, align: NcAlign, rows: NcDimension, cols: NcDimension) -> Self {
Self::with_flags( Self::with_flags_aligned(y, align, rows, cols, crate::NCPLANE_OPTION_HORALIGNED)
y,
align as i32,
rows,
cols,
crate::NCPLANE_OPTION_HORALIGNED,
)
} }
/// New NcPlaneOptions, with flags. /// 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 /// Note: Already includes the
/// the [NcAlign] value to the `x` parameter, casted to `i32`. /// [NCPLANE_OPTION_HORALIGNED][crate::NCPLANE_OPTION_HORALIGNED] flag.
pub fn with_flags(y: i32, x: i32, rows: u32, cols: u32, flags: u64) -> Self { pub fn with_flags_aligned(
y: NcOffset,
align: NcAlign,
rows: NcDimension,
cols: NcDimension,
flags: u64,
) -> Self {
let flags = crate::NCPLANE_OPTION_HORALIGNED | flags;
NcPlaneOptions { NcPlaneOptions {
y, y: y as i32,
x, x: align as i32,
rows: rows as i32, rows: rows as i32,
cols: cols as i32, cols: cols as i32,
userptr: null_mut(), userptr: null_mut(),
@ -40,12 +65,18 @@ impl NcPlaneOptions {
} }
} }
/// # `NcPlane` Constructors /// # `NcPlane` constructors and destructors
impl NcPlane { impl NcPlane {
/// New NcPlane. /// New NcPlane.
/// ///
/// The returned plane will be the top, bottom, and root of this new pile. /// 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); let options = NcPlaneOptions::new(y, x, rows, cols);
unsafe { &mut *crate::ncpile_create(nc, &options) } unsafe { &mut *crate::ncpile_create(nc, &options) }
} }
@ -60,10 +91,10 @@ impl NcPlane {
/// New NcPlane, bound to another NcPlane. /// New NcPlane, bound to another NcPlane.
pub fn new_bound<'a>( pub fn new_bound<'a>(
bound_to: &mut NcPlane, bound_to: &mut NcPlane,
y: i32, y: NcOffset,
x: i32, x: NcOffset,
rows: u32, rows: NcDimension,
cols: u32, cols: NcDimension,
) -> &'a mut NcPlane { ) -> &'a mut NcPlane {
let options = NcPlaneOptions::new(y, x, rows, cols); let options = NcPlaneOptions::new(y, x, rows, cols);
unsafe { &mut *crate::ncplane_create(bound_to, &options) } unsafe { &mut *crate::ncplane_create(bound_to, &options) }
@ -72,8 +103,11 @@ impl NcPlane {
/// New NcPlane, bound to another plane, expects an [NcPlaneOptions] struct. /// New NcPlane, bound to another plane, expects an [NcPlaneOptions] struct.
/// ///
/// The returned plane will be the top, bottom, and root of this new pile. /// 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 { pub fn with_options_bound<'a>(
unsafe { &mut *crate::ncpile_create(nc, options) } 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. /// 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); crate::notcurses_term_dim_yx(nc, &mut trows, &mut tcols);
assert![(trows > 0) & (tcols > 0)]; assert![(trows > 0) & (tcols > 0)];
unsafe { 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 /// # `NcPlane` Methods
@ -95,44 +139,92 @@ impl NcPlane {
/// Returns the current position of the cursor within the [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. // NOTE: y and/or x may be NULL.
// FIXME: CHECK for NULL and return Some() or None. // maybe check for null and return Some() or None?
pub fn cursor_yx(&self) -> (i32, i32) { pub fn cursor_yx(&self) -> (NcDimension, NcDimension) {
let (mut y, mut x) = (0, 0); let (mut y, mut x) = (0, 0);
unsafe { crate::ncplane_cursor_yx(self, &mut y, &mut x) }; 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]. /// 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 self.cursor_yx().0
} }
/// Returns the current column of the cursor within the [NcPlane]. /// 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 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 -------------------------------------------------------------------- // 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]. /// Return the dimensions of this [NcPlane].
/// ///
/// Unlike [ncplane_dim_yx] which uses `i32`, this uses [u32]. /// Unlike [ncplane_dim_yx][crate::ncplane_dim_yx] which uses `i32`,
pub fn dim_yx(&self) -> (u32, u32) { /// this uses [u32].
pub fn dim_yx(&self) -> (NcDimension, NcDimension) {
let (mut y, mut x) = (0, 0); let (mut y, mut x) = (0, 0);
unsafe { crate::ncplane_dim_yx(self, &mut y, &mut x) }; 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]. /// Return the rows of this [NcPlane].
pub fn dim_y(&self) -> u32 { pub fn dim_y(&self) -> NcDimension {
self.dim_yx().0 self.dim_yx().0
} }
/// Return the columns of this [NcPlane]. /// 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 self.dim_yx().1
} }
@ -150,7 +242,160 @@ impl NcPlane {
unsafe { crate::ncplane_set_scrolling(self, scroll) } 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<unsafe extern "C" fn(*mut NcPlane) -> 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<NcEgc> {
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<NcEgc> {
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 ------------------------------------------------------------------- // Write -------------------------------------------------------------------
@ -169,8 +414,8 @@ impl NcPlane {
/// The new NcCell must already be associated with the Plane. /// The new NcCell must already be associated with the Plane.
/// On success, returns the number of columns the cursor was advanced. /// On success, returns the number of columns the cursor was advanced.
/// On failure, -1 is returned. /// On failure, -1 is returned.
pub fn putc_yx(&mut self, y: i32, x: i32, cell: &NcCell) -> NcResult { pub fn putc_yx(&mut self, y: NcDimension, x: NcDimension, cell: &NcCell) -> NcResult {
unsafe { crate::ncplane_putc_yx(self, y, x, cell) } unsafe { crate::ncplane_putc_yx(self, y as i32, x as i32, cell) }
} }
/// Replaces the NcCell at the current coordinates with the provided NcCell, /// 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. /// The new NcCell must already be associated with the Plane.
/// On success, returns the number of columns the cursor was advanced. /// On success, returns the number of columns the cursor was advanced.
/// On failure, -1 is returned.
pub fn putc(&mut self, cell: &NcCell) -> NcResult { pub fn putc(&mut self, cell: &NcCell) -> NcResult {
crate::ncplane_putc(self, cell) 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 { pub fn putstr(&mut self, string: &str) -> NcResult {
crate::ncplane_putstr(self, string) 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, /// Write a string, which is a series of [NcEgc][crate::NcEgc]s, to the
/// using the current style. /// current location, using the current style.
/// ///
/// They will be interpreted as a series of columns (according to the /// They will be interpreted as a series of columns (according to the
/// definition of `ncplane_putc()`). /// definition of `ncplane_putc()`).
@ -201,19 +475,108 @@ impl NcPlane {
/// ///
/// On error, a non-positive number is returned, indicating the number of /// On error, a non-positive number is returned, indicating the number of
/// columns which were written before the error. /// columns which were written before the error.
pub fn putstr_yx(&mut self, y: i32, x: i32, string: &str) -> NcResult { pub fn putstr_yx(&mut self, y: NcDimension, x: NcDimension, string: &str) -> NcResult {
unsafe { crate::ncplane_putstr_yx(self, y, x, cstring![string]) } unsafe { crate::ncplane_putstr_yx(self, y as i32, x as i32, cstring![string]) }
} }
// Pile -------------------------------------------------------------------- // 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 { pub fn bottom<'a>(&mut self) -> &'a mut NcPlane {
unsafe { &mut *crate::ncpile_bottom(self) } 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 { pub fn top<'a>(&mut self) -> &'a mut NcPlane {
unsafe { &mut *crate::ncpile_top(self) } 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) }
}
} }

@ -1,31 +1,32 @@
//! `NcPlane` //! `NcPlane`
// functions already exported by bindgen : 105 // functions already exported by bindgen : 105
// ------------------------------------------ // -------------------------------------------
// (#) 13 / 92 unit tests // (X) wont: 4
// (W) 1 wrapped as a method or function // (#) test: 13
// ------------------------------------------ // (W) wrap: 28
// ncpile_bottom // -------------------------------------------
// # ncpile_create //W ncpile_bottom
// ncpile_rasterize //W# ncpile_create
// ncpile_render //W ncpile_rasterize
// ncpile_top //W ncpile_render
// ncplane_above //W ncpile_top
// ncplane_at_cursor //W ncplane_above
// ncplane_at_yx //W ncplane_at_cursor
// ncplane_base //W ncplane_at_yx
// ncplane_below //W ncplane_base
//W ncplane_below
// ncplane_box // ncplane_box
// ncplane_center_abs // ncplane_center_abs
// # ncplane_channels //W# ncplane_channels
// ncplane_contents //W ncplane_contents
// ncplane_create //W ncplane_create
// # ncplane_cursor_move_yx //W# ncplane_cursor_move_yx
//W# ncplane_cursor_yx //W# ncplane_cursor_yx
// ncplane_destroy //W ncplane_destroy
//W# ncplane_dim_yx //W# ncplane_dim_yx
// ncplane_dup //W ncplane_dup
// # ncplane_erase //W# ncplane_erase
// ncplane_fadein // ncplane_fadein
// ncplane_fadein_iteration // ncplane_fadein_iteration
// ncplane_fadeout // ncplane_fadeout
@ -36,41 +37,41 @@
// ncplane_highgradient // ncplane_highgradient
// ncplane_highgradient_sized // ncplane_highgradient_sized
// ncplane_hline_interp // ncplane_hline_interp
// # ncplane_home //W# ncplane_home
// ncplane_mergedown // ncplane_mergedown
// ncplane_mergedown_simple // ncplane_mergedown_simple
// ncplane_move_above // ncplane_move_above
// ncplane_move_below // ncplane_move_below
// ncplane_move_bottom // ncplane_move_bottom
// ncplane_move_top // ncplane_move_top
// ncplane_move_yx //W ncplane_move_yx
// ncplane_new // ncplane_new
// # ncplane_notcurses //W# ncplane_notcurses
// # ncplane_notcurses_const //W# ncplane_notcurses_const
// ncplane_off_styles // ncplane_off_styles
// ncplane_on_styles // ncplane_on_styles
// ncplane_parent //W ncplane_parent
// ncplane_parent_const //W ncplane_parent_const
// ncplane_polyfill_yx // ncplane_polyfill_yx
// ncplane_pulse // ncplane_pulse
// ncplane_putchar_stained // ncplane_putchar_stained
// ncplane_putc_yx // ncplane_putc_yx
// ncplane_putegc_stained // X ncplane_putegc_stained
// ncplane_putegc_yx // X ncplane_putegc_yx
// ncplane_putnstr_aligned // ncplane_putnstr_aligned
// ncplane_putnstr_yx // ncplane_putnstr_yx
// ncplane_putstr_aligned // ncplane_putstr_aligned
// ncplane_putstr_stained // ncplane_putstr_stained
// ncplane_putstr_yx // ncplane_putstr_yx
// ncplane_puttext // ncplane_puttext
// ncplane_putwegc_stained // X ncplane_putwegc_stained
// ncplane_putwstr_stained // X ncplane_putwstr_stained
// ncplane_qrcode // ncplane_qrcode
// ncplane_reparent // ncplane_reparent
// ncplane_reparent_family // ncplane_reparent_family
// # ncplane_resize //W# ncplane_resize
// ncplane_resizecb //W ncplane_resizecb
// ncplane_resize_realign //W ncplane_resize_realign
// ncplane_rgba // ncplane_rgba
// ncplane_rotate_ccw // ncplane_rotate_ccw
// ncplane_rotate_cw // ncplane_rotate_cw
@ -113,12 +114,13 @@
// //
// functions manually reimplemented: 42 // functions manually reimplemented: 42
// ------------------------------------------ // ------------------------------------------
// (X) wont: 8 // (X) wont: 9
// (+) done: 34 / 0 // (+) done: 34 / 0
// (#) test: 5 / 29 // (W) wrap: 5
// (#) test: 5
// ------------------------------------------ // ------------------------------------------
// + ncplane_align // + ncplane_align
// + ncplane_at_cursor_cell //W+ ncplane_at_cursor_cell
// + ncplane_at_yx_cell // + ncplane_at_yx_cell
// + ncplane_bchannel // + ncplane_bchannel
// + ncplane_bg_alpha // + ncplane_bg_alpha
@ -143,7 +145,7 @@
// + ncplane_putc // + ncplane_putc
// + ncplane_putchar // + ncplane_putchar
// + ncplane_putchar_yx // + ncplane_putchar_yx
// + ncplane_putegc // X ncplane_putegc
// + ncplane_putnstr // + ncplane_putnstr
//W+ ncplane_putstr //W+ ncplane_putstr
// X ncplane_putwc // I don't think these will be needed from Rust. See: // X ncplane_putwc // I don't think these will be needed from Rust. See:
@ -154,7 +156,7 @@
// X ncplane_putwstr // // X ncplane_putwstr //
// X ncplane_putwstr_aligned // // X ncplane_putwstr_aligned //
// X ncplane_putwstr_yx // // X ncplane_putwstr_yx //
// # ncplane_resize_simple //W# ncplane_resize_simple
// + ncplane_rounded_box // + ncplane_rounded_box
// + ncplane_rounded_box_sized // + ncplane_rounded_box_sized
// + ncplane_vline // + ncplane_vline

@ -9,10 +9,10 @@ use crate::{
channels_fg_alpha, channels_fg_default_p, channels_fg_rgb, channels_fg_rgb8, cstring, 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, 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_cursor_move_yx, ncplane_cursor_yx, ncplane_dim_yx, ncplane_gradient,
ncplane_hline_interp, ncplane_putc_yx, ncplane_putegc_yx, ncplane_putnstr_yx, ncplane_hline_interp, ncplane_putc_yx, ncplane_putnstr_yx, ncplane_putstr_yx, ncplane_resize,
ncplane_putstr_yx, ncplane_resize, ncplane_styles, ncplane_vline_interp, ncplane_vprintf_yx, ncplane_styles, ncplane_vline_interp, ncplane_vprintf_yx, notcurses_align, NcAlign,
notcurses_align, NcAlign, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcPlane, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcDimension, NcPlane, NcResult, NcRgb,
NcResult, NcStyleMask, NCRESULT_ERR, NCRESULT_OK, NcStyleMask, NCRESULT_ERR, NCRESULT_OK,
}; };
// Alpha ----------------------------------------------------------------------- // Alpha -----------------------------------------------------------------------
@ -71,13 +71,13 @@ pub fn ncplane_bg_rgb8(
/// Gets the foreground [NcRgb] from an [NcPlane], shifted to LSBs. /// Gets the foreground [NcRgb] from an [NcPlane], shifted to LSBs.
#[inline] #[inline]
pub fn ncplane_fg_rgb(plane: &NcPlane) -> NcChannel { pub fn ncplane_fg_rgb(plane: &NcPlane) -> NcRgb {
channels_fg_rgb(unsafe { ncplane_channels(plane) }) channels_fg_rgb(unsafe { ncplane_channels(plane) })
} }
/// Gets the background [NcRgb] from an [NcPlane], shifted to LSBs. /// Gets the background [NcRgb] from an [NcPlane], shifted to LSBs.
#[inline] #[inline]
pub fn ncplane_bg_rgb(plane: &NcPlane) -> NcChannel { pub fn ncplane_bg_rgb(plane: &NcPlane) -> NcRgb {
channels_bg_rgb(unsafe { ncplane_channels(plane) }) 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. /// Calls ncplane_putchar_yx() at the current cursor location.
#[inline] #[inline]
pub fn ncplane_putchar(plane: &mut NcPlane, c: char) -> NcResult { pub fn ncplane_putchar(plane: &mut NcPlane, ch: 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 {
unsafe { unsafe {
let cell = NcCell::with_all(ch, 0, ncplane_styles(plane), ncplane_channels(plane)); 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] #[inline]
pub fn ncplane_putegc(plane: &mut NcPlane, gcluster: i8, sbytes: &mut i32) -> NcResult { pub fn ncplane_putchar_yx(
unsafe { ncplane_putegc_yx(plane, -1, -1, &gcluster, sbytes) } 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] #[inline]
pub fn ncplane_putstr(plane: &mut NcPlane, string: &str) -> NcResult { pub fn ncplane_putstr(plane: &mut NcPlane, string: &str) -> NcResult {
unsafe { ncplane_putstr_yx(plane, -1, -1, cstring![string]) } 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'. /// Retrieves the current contents of the specified cell into 'cell'.
/// This cell is invalidated if the associated plane is destroyed. /// This cell is invalidated if the associated plane is destroyed.
#[inline] #[inline]
pub fn ncplane_at_yx_cell(plane: &mut NcPlane, y: i32, x: i32, cell: &mut NcCell) -> NcResult { pub fn ncplane_at_yx_cell(
let mut egc = unsafe { ncplane_at_yx(plane, y, x, &mut cell.stylemask, &mut cell.channels) }; 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() { if egc.is_null() {
return NCRESULT_ERR; 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]. /// Gets the columns of the [NcPlane].
#[inline] #[inline]
pub fn ncplane_dim_x(plane: &NcPlane) -> i32 { pub fn ncplane_dim_x(plane: &NcPlane) -> NcDimension {
unsafe { unsafe {
let mut x = 0; let mut x = 0;
ncplane_dim_yx(plane, null_mut(), &mut x); ncplane_dim_yx(plane, null_mut(), &mut x);
x x as NcDimension
} }
} }
/// Gets the rows of the [NcPlane]. /// Gets the rows of the [NcPlane].
#[inline] #[inline]
#[inline] #[inline]
pub fn ncplane_dim_y(plane: &NcPlane) -> i32 { pub fn ncplane_dim_y(plane: &NcPlane) -> NcDimension {
unsafe { unsafe {
let mut y = 0; let mut y = 0;
ncplane_dim_yx(plane, &mut y, null_mut()); ncplane_dim_yx(plane, &mut y, null_mut());
y y as NcDimension
} }
} }
/// Resizes the plane, retaining what data we can (everything, unless we're /// Resizes the plane, retaining what data we can (everything, unless we're
/// shrinking in some dimension). Keep the origin where it is. /// shrinking in some dimension). Keep the origin where it is.
#[inline] #[inline]
pub fn ncplane_resize_simple(plane: &mut NcPlane, ylen: i32, xlen: i32) -> NcResult { pub fn ncplane_resize_simple(
let (mut oldy, mut oldx) = (0, 0); plane: &mut NcPlane,
y_len: NcDimension,
x_len: NcDimension,
) -> NcResult {
let (mut old_y, mut old_x) = (0, 0);
unsafe { unsafe {
ncplane_dim_yx(plane, &mut oldy, &mut oldx); ncplane_dim_yx(plane, &mut old_y, &mut old_x);
} }
let keepleny = { let keep_len_y = {
if oldy > ylen { if old_y > y_len as i32 {
ylen y_len as i32
} else { } else {
oldy old_y
} }
}; };
let keeplenx = { let keep_len_x = {
if oldx > xlen { if old_x > x_len as i32 {
xlen x_len as i32
} else { } 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 /// 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'. /// 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] #[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) notcurses_align(ncplane_dim_x(plane), align, cols)
} }
// line ------------------------------------------------------------------------ // 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] #[inline]
pub fn ncplane_hline(plane: &mut NcPlane, cell: &NcCell, len: i32) -> i32 { pub fn ncplane_hline(plane: &mut NcPlane, cell: &NcCell, len: NcDimension) -> NcResult {
unsafe { ncplane_hline_interp(plane, cell, len, cell.channels, cell.channels) } 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] #[inline]
pub fn ncplane_vline(plane: &mut NcPlane, cell: &NcCell, len: i32) -> i32 { pub fn ncplane_vline(plane: &mut NcPlane, cell: &NcCell, len: NcDimension) -> NcResult {
unsafe { ncplane_vline_interp(plane, cell, len, cell.channels, cell.channels) } unsafe { ncplane_vline_interp(plane, cell, len as i32, cell.channels, cell.channels) }
} }
// perimeter ------------------------------------------------------------------- // perimeter -------------------------------------------------------------------
@ -277,7 +312,18 @@ pub fn ncplane_perimeter(
ncplane_cursor_move_yx(plane, 0, 0); ncplane_cursor_move_yx(plane, 0, 0);
let (mut dimy, mut dimx) = (0, 0); let (mut dimy, mut dimx) = (0, 0);
ncplane_dim_yx(plane, &mut dimy, &mut dimx); 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; 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 { unsafe {
cell_release(plane, &mut ul); cell_release(plane, &mut ul);
cell_release(plane, &mut ur); cell_release(plane, &mut ur);
@ -367,7 +424,18 @@ pub fn ncplane_perimeter_rounded(
{ {
return NCRESULT_ERR; 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 { unsafe {
cell_release(plane, &mut ul); cell_release(plane, &mut ul);
cell_release(plane, &mut ur); cell_release(plane, &mut ur);
@ -381,8 +449,8 @@ pub fn ncplane_perimeter_rounded(
// box ------------------------------------------------------------------------- // box -------------------------------------------------------------------------
/// Draw a box with its upper-left corner at the current cursor position, having /// Draws a box with its upper-left corner at the current cursor position,
/// dimensions 'ylen'x'xlen'. See ncplane_box() for more information. The /// 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. /// minimum box size is 2x2, and it cannot be drawn off-screen.
#[inline] #[inline]
pub fn ncplane_box_sized( pub fn ncplane_box_sized(
@ -393,8 +461,8 @@ pub fn ncplane_box_sized(
lr: &NcCell, lr: &NcCell,
hline: &NcCell, hline: &NcCell,
vline: &NcCell, vline: &NcCell,
ylen: i32, y_len: NcDimension,
xlen: i32, x_len: NcDimension,
ctlword: u32, ctlword: u32,
) -> NcResult { ) -> NcResult {
let (mut y, mut x) = (0, 0); let (mut y, mut x) = (0, 0);
@ -408,8 +476,8 @@ pub fn ncplane_box_sized(
lr, lr,
hline, hline,
vline, vline,
y + ylen - 1, y + y_len as i32 - 1,
x + xlen - 1, x + x_len as i32 - 1,
ctlword, ctlword,
) )
} }
@ -421,8 +489,8 @@ pub fn ncplane_double_box(
plane: &mut NcPlane, plane: &mut NcPlane,
stylemask: NcStyleMask, stylemask: NcStyleMask,
channels: NcChannelPair, channels: NcChannelPair,
ystop: i32, ystop: NcDimension,
xstop: i32, xstop: NcDimension,
ctlword: u32, ctlword: u32,
) -> NcResult { ) -> NcResult {
#[allow(unused_assignments)] #[allow(unused_assignments)]
@ -448,7 +516,18 @@ pub fn ncplane_double_box(
&mut vl, &mut vl,
); );
if ret == NCRESULT_OK { 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 ul);
@ -467,8 +546,8 @@ pub fn ncplane_double_box_sized(
plane: &mut NcPlane, plane: &mut NcPlane,
stylemask: NcStyleMask, stylemask: NcStyleMask,
channels: NcChannelPair, channels: NcChannelPair,
ylen: i32, y_len: NcDimension,
xlen: i32, x_len: NcDimension,
ctlword: u32, ctlword: u32,
) -> NcResult { ) -> NcResult {
let (mut y, mut x) = (0, 0); let (mut y, mut x) = (0, 0);
@ -479,8 +558,8 @@ pub fn ncplane_double_box_sized(
plane, plane,
stylemask, stylemask,
channels, channels,
y + ylen - 1, y as NcDimension + y_len - 1,
x + xlen - 1, x as NcDimension + x_len - 1,
ctlword, ctlword,
) )
} }
@ -491,8 +570,8 @@ pub fn ncplane_rounded_box(
plane: &mut NcPlane, plane: &mut NcPlane,
stylemask: NcStyleMask, stylemask: NcStyleMask,
channels: NcChannelPair, channels: NcChannelPair,
ystop: i32, ystop: NcDimension,
xstop: i32, xstop: NcDimension,
ctlword: u32, ctlword: u32,
) -> NcResult { ) -> NcResult {
#[allow(unused_assignments)] #[allow(unused_assignments)]
@ -518,7 +597,18 @@ pub fn ncplane_rounded_box(
&mut vl, &mut vl,
); );
if ret == NCRESULT_OK { 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 ul);
cell_release(plane, &mut ur); cell_release(plane, &mut ur);
@ -536,8 +626,8 @@ pub fn ncplane_rounded_box_sized(
plane: &mut NcPlane, plane: &mut NcPlane,
stylemask: NcStyleMask, stylemask: NcStyleMask,
channels: NcChannelPair, channels: NcChannelPair,
ylen: i32, y_len: NcDimension,
xlen: i32, x_len: NcDimension,
ctlword: u32, ctlword: u32,
) -> NcResult { ) -> NcResult {
let (mut y, mut x) = (0, 0); let (mut y, mut x) = (0, 0);
@ -548,8 +638,8 @@ pub fn ncplane_rounded_box_sized(
plane, plane,
stylemask, stylemask,
channels, channels,
y + ylen - 1, y as NcDimension + y_len - 1,
x + xlen - 1, x as NcDimension + x_len - 1,
ctlword, ctlword,
) )
} }
@ -557,7 +647,7 @@ pub fn ncplane_rounded_box_sized(
// gradient -------------------------------------------------------------------- // gradient --------------------------------------------------------------------
/// Draw a gradient with its upper-left corner at the current cursor position, /// 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 /// static inline int
// XXX receive cells as u32? See: // XXX receive cells as u32? See:
// - https://github.com/dankamongmen/notcurses/issues/920 // - https://github.com/dankamongmen/notcurses/issues/920
@ -571,10 +661,10 @@ pub fn ncplane_gradient_sized(
ur: u64, ur: u64,
ll: u64, ll: u64,
lr: u64, lr: u64,
ylen: i32, y_len: NcDimension,
xlen: i32, x_len: NcDimension,
) -> NcResult { ) -> NcResult {
if ylen < 1 || xlen < 1 { if y_len < 1 || x_len < 1 {
return NCRESULT_ERR; return NCRESULT_ERR;
} }
let (mut y, mut x) = (0, 0); let (mut y, mut x) = (0, 0);
@ -588,8 +678,8 @@ pub fn ncplane_gradient_sized(
ur, ur,
ll, ll,
lr, lr,
y + ylen - 1, y + y_len as i32 - 1,
x + xlen - 1, x + x_len as i32 - 1,
) )
} }
} }

@ -1,6 +1,6 @@
//! `NcTime` //! `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 // libc::timespec
pub type NcTime = crate::bindings::ffi::timespec; pub type NcTime = crate::bindings::ffi::timespec;

Loading…
Cancel
Save