rust: more refactoring, channel methods, new macro.

- add NcChannel methods
- add the `NcChannelMethods` Trait to be able to use them,
  since you can't implement methods over a primitive otherwise, unlike over a struct like NcPlane. And NcChannel is a type alias of `u32`.
- create more channel functions, to set the r,g,b separately.
- made some functions const
- add new rsleep![] macro, for rendering before sleeping.
- improve doc comments.
- fix previous commits.
pull/1181/head
joseLuís 4 years ago
parent 5def609c73
commit 57d2eddbf5

@ -25,7 +25,7 @@ impl NcCell {
Self::with_all(ch, 0 as NcStyleMask, 0 as NcChannelPair)
}
/// New NcCell, expects an [NcPlane] and a utf-8 [char].
/// New NcCell, expects an [NcPlane] and a [char].
#[inline]
pub fn with_char(plane: &mut NcPlane, ch: char) -> Self {
let mut cell = Self::new();

@ -0,0 +1,131 @@
//! `NcChannel*` methods and associated functions.
use crate::{NcAlphaBits, NcChannel, NcChannelPair, NcColor, NcRgb};
/// Enables the methods of [NcChannel];
pub trait NcChannelMethods {
fn alpha(&self) -> NcAlphaBits;
fn set_alpha(&mut self, alpha: NcAlphaBits);
fn rgb8(&self) -> (NcColor, NcColor, NcColor);
fn set_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor);
fn r(&self) -> NcColor;
fn g(&self) -> NcColor;
fn b(&self) -> NcColor;
fn set_r(&mut self, r: NcColor) -> NcChannel;
fn set_g(&mut self, g: NcColor) -> NcChannel;
fn set_b(&mut self, b: NcColor) -> NcChannel;
fn rgb(&self) -> NcRgb;
fn set_rgb(&mut self, rgb: NcRgb);
//
}
/// Enables the methods of [NcChannelPair];
pub trait NcChannelPairMethods {
fn fg_alpha(&self) -> NcAlphaBits;
fn bg_alpha(&self) -> NcAlphaBits;
fn set_fg_alpha(&mut self, alpha: NcAlphaBits);
fn set_bg_alpha(&mut self, alpha: NcAlphaBits);
}
// NcChannel -------------------------------------------------------------------
/// # `NcChannel` Methods
impl NcChannelMethods for NcChannel {
// Alpha
/// Gets the [NcAlphaBits].
fn alpha(&self) -> NcAlphaBits {
crate::channel_alpha(*self)
}
/// Sets the [NcAlphaBits].
fn set_alpha(&mut self, alpha: NcAlphaBits) {
crate::channel_set_alpha(self, alpha)
}
// NcColor
/// Gets the three [NcColor]s.
fn rgb8(&self) -> (NcColor, NcColor, NcColor) {
let (mut r, mut g, mut b) = (0, 0, 0);
crate::channel_rgb8(*self, &mut r, &mut g, &mut b);
(r, g, b)
}
/// Sets the three [NcColor]s, and
/// marks the NcChannel as NOT using the default color.
fn set_rgb8(&mut self, r: NcColor, g: NcColor, b: NcColor) {
crate::channel_set_rgb8(self, r, g, b);
}
/// Gets the red [NcColor].
fn r(&self) -> NcColor {
crate::channel_r(*self)
}
/// Gets the green [NcColor].
fn g(&self) -> NcColor {
crate::channel_g(*self)
}
/// Gets the blue [NcColor].
fn b(&self) -> NcColor {
crate::channel_b(*self)
}
/// Sets the red [NcColor], and returns the new NcChannel.
fn set_r(&mut self, r: NcColor) -> NcChannel {
crate::channel_set_r(self, r)
}
/// Sets the green [NcColor], and returns the new NcChannel.
fn set_g(&mut self, g: NcColor) -> NcChannel {
crate::channel_set_g(self, g)
}
/// Sets the blue [NcColor], and returns the new NcChannel.
fn set_b(&mut self, b: NcColor) -> NcChannel {
crate::channel_set_b(self, b)
}
// NcRgb
/// Gets the [NcRgb].
fn rgb(&self) -> NcRgb {
crate::channel_rgb(*self)
}
/// Sets the [NcRgb] and marks it as NOT using the default color,
/// retaining the other bits unchanged.
fn set_rgb(&mut self, rgb: NcRgb) {
crate::channel_set(self, rgb);
}
}
// NcChannelPair ---------------------------------------------------------------
/// # `NcChannelPair` Methods
impl NcChannelPairMethods for NcChannelPair {
/// Gets the foreground [NcAlphaBits].
fn fg_alpha(&self) -> NcAlphaBits {
crate::channels_fg_alpha(*self)
}
/// Gets the background [NcAlphaBits].
fn bg_alpha(&self) -> NcAlphaBits {
crate::channels_bg_alpha(*self)
}
/// Sets the foreground [NcAlphaBits].
fn set_fg_alpha(&mut self, alpha: NcAlphaBits) {
crate::channels_set_fg_alpha(self, alpha)
}
/// Sets the background [NcAlphaBits].
fn set_bg_alpha(&mut self, alpha: NcAlphaBits) {
crate::channels_set_bg_alpha(self, alpha)
}
}

@ -16,44 +16,44 @@
// functions manually reimplemented: 39
// ------------------------------------------
// (X) wont: 3
// (W) wrap: 10 / 26
// (+) done: 34 / 2
// (W) wrap: 0 / 36
// (#) test: 19 / 17
// ------------------------------------------
// # channel_alpha
// # channel_b
//W# channel_alpha
//W# channel_b
// # channel_default_p
// # channel_g
//W# channel_g
// # channel_palindex_p
// # channel_r
// # channel_rgb8
//W# channel_r
//W# channel_rgb8
// + channel_set
// # channel_set_alpha
// # channel_set_default
//W# channel_set_rgb8
// X channel_set_rgb_clipped ---
// # channels_bchannel
// + channels_bg_alpha
//W+ channels_bg_alpha
// + channels_bg_default_p
// # channels_bg_palindex_p
// + channels_bg_rgb
// + channels_bg_rgb8
// # channels_combine
// + channel_set
// # channel_set_alpha
// # channel_set_default
// # channel_set_rgb8
// X channel_set_rgb_clipped
// # channels_fchannel
// + channels_fg_alpha
//W+ channels_fg_alpha
// + channels_fg_default_p
// # channels_fg_palindex_p
// + channels_fg_rgb
// + channels_fg_rgb8
// # channels_set_bchannel
// + channels_set_bg_alpha
//W+ channels_set_bg_alpha
// + channels_set_bg_default
// # channels_set_bg_palindex
// + channels_set_bg_rgb
// + channels_set_bg_rgb8
// X channels_set_bg_rgb8_clipped
// # channels_set_fchannel
// + channels_set_fg_alpha
//W+ channels_set_fg_alpha
// + channels_set_fg_default
// # channels_set_fg_palindex
// + channels_set_fg_rgb
@ -63,7 +63,9 @@
#[cfg(test)]
mod test;
mod methods;
mod reimplemented;
pub use methods::{NcChannelMethods, NcChannelPairMethods};
pub use reimplemented::*;
// NcChannel

@ -8,13 +8,13 @@ use crate::{
// Alpha -----------------------------------------------------------------------
/// Gets the [NcAlphaBits] 2-bit component from a 32-bit [NcChannel].
/// Gets the [NcAlphaBits] from an [NcChannel].
#[inline]
pub fn channel_alpha(channel: NcChannel) -> NcAlphaBits {
pub const fn channel_alpha(channel: NcChannel) -> NcAlphaBits {
channel & NCCHANNEL_ALPHA_MASK
}
/// Sets the [NcAlphaBits] 2-bit component of a 32-bit [NcChannel].
/// Sets the [NcAlphaBits] of an [NcChannel].
#[inline]
pub fn channel_set_alpha(channel: &mut NcChannel, alpha: NcAlphaBits) {
let alpha_clean = alpha & NCCHANNEL_ALPHA_MASK;
@ -28,13 +28,13 @@ pub fn channel_set_alpha(channel: &mut NcChannel, alpha: NcAlphaBits) {
/// Gets the foreground [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
#[inline]
pub fn channels_fg_alpha(channels: NcChannelPair) -> NcAlphaBits {
pub const fn channels_fg_alpha(channels: NcChannelPair) -> NcAlphaBits {
channel_alpha(channels_fchannel(channels))
}
/// Gets the background [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
#[inline]
pub fn channels_bg_alpha(channels: NcChannelPair) -> NcAlphaBits {
pub const fn channels_bg_alpha(channels: NcChannelPair) -> NcAlphaBits {
channel_alpha(channels_bchannel(channels))
}
@ -61,26 +61,26 @@ pub fn channels_set_bg_alpha(channels: &mut NcChannelPair, alpha: NcAlphaBits) {
// Channels --------------------------------------------------------------------
/// Extracts the 32-bit background [NcChannel] from a [NcChannelPair].
/// Extracts the background [NcChannel] from a [NcChannelPair].
#[inline]
pub fn channels_bchannel(channels: NcChannelPair) -> NcChannel {
pub const fn channels_bchannel(channels: NcChannelPair) -> NcChannel {
(channels & 0xffffffff_u64) as NcChannel
}
/// Extracts the 32-bit foreground [NcChannel] from an [NcChannelPair].
/// Extracts the foreground [NcChannel] from an [NcChannelPair].
#[inline]
pub fn channels_fchannel(channels: NcChannelPair) -> NcChannel {
pub const fn channels_fchannel(channels: NcChannelPair) -> NcChannel {
channels_bchannel(channels >> 32)
}
/// Sets the 32-bit background [NcChannel] of an [NcChannelPair].
/// Sets the background [NcChannel] of an [NcChannelPair].
#[inline]
pub fn channels_set_bchannel(channels: &mut NcChannelPair, bchannel: NcChannel) -> NcChannelPair {
*channels = (*channels & 0xffffffff00000000_u64) | bchannel as u64;
*channels
}
/// Sets the 32-bit foreground [NcChannel] of an [NcChannelPair].
/// Sets the foreground [NcChannel] of an [NcChannelPair].
#[inline]
pub fn channels_set_fchannel(channels: &mut NcChannelPair, fchannel: NcChannel) -> NcChannelPair {
*channels = (*channels & 0xffffffff_u64) | (fchannel as u64) << 32;
@ -98,25 +98,49 @@ pub fn channels_combine(fchannel: NcChannel, bchannel: NcChannel) -> NcChannelPa
// NcColor ---------------------------------------------------------------------
/// Gets the red [NcColor] 8-bit component from a 32-bit [NcChannel].
/// Gets the red [NcColor] from an [NcChannel].
#[inline]
pub const fn channel_r(channel: NcChannel) -> NcColor {
((channel & 0xff0000) >> 16) as NcColor
}
/// Gets the [NcColor] 8-bit component from a 32-bit [NcChannel].
/// Gets the green [NcColor] from an [NcChannel].
#[inline]
pub const fn channel_g(channel: NcChannel) -> NcColor {
((channel & 0x00ff00) >> 8) as NcColor
}
/// Gets the blue [NcColor] from an [NcChannel].
#[inline]
pub const fn channel_b(channel: NcChannel) -> NcColor {
(channel & 0x0000ff) as NcColor
}
/// Gets the green [NcColor] 8-bit component from a 32-bit [NcChannel].
/// Sets the red [NcColor] of an [NcChannel], and returns it.
// Not in the C API.
#[inline]
pub const fn channel_g(channel: NcChannel) -> NcColor {
((channel & 0x00ff00) >> 8) as NcColor
pub fn channel_set_r(channel: &mut NcChannel, r: NcColor) -> NcChannel {
*channel = (r as NcChannel) << 16 | (*channel & 0xff00) | (*channel & 0xff);
*channel
}
/// Sets the green [NcColor] of an [NcChannel], and returns it.
// Not in the C API.
#[inline]
pub fn channel_set_g(channel: &mut NcChannel, g: NcColor) -> NcChannel {
*channel = (*channel & 0xff0000) | (g as NcChannel) << 8 | (*channel & 0xff);
*channel
}
/// Sets the blue [NcColor] of an [NcChannel], and returns it.
// Not in the C API.
#[inline]
pub fn channel_set_b(channel: &mut NcChannel, b: NcColor) -> NcChannel {
*channel = (*channel & 0xff0000) | (*channel & 0xff00) | (b as NcChannel);
*channel
}
/// Gets the three [NcColor] 8-bit RGB components from a 32-bit [NcChannel].
/// Gets the three RGB [NcColor]s from an [NcChannel], and returns it.
#[inline]
pub fn channel_rgb8(
channel: NcChannel,
@ -130,17 +154,16 @@ pub fn channel_rgb8(
channel
}
/// Sets the three [NcColor] 8-bit components of a 32-bit [NcChannel], and marks
/// it as not using the "default color". Retain the other bits unchanged.
/// Sets the three RGB [NcColor]s an [NcChannel], and marks it as not using the
/// "default color", retaining the other bits unchanged.
#[inline]
pub fn channel_set_rgb8(channel: &mut NcChannel, r: NcColor, g: NcColor, b: NcColor) {
let rgb: NcRgb = (r as NcChannel) << 16 | (g as NcChannel) << 8 | (b as NcChannel);
*channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | rgb;
}
/// Gets the foreground [NcRgb] 24-bit value from an [NcChannelPair], and
/// saves it split into three [NcColor] 8-bit components. Also returns the
/// corresponding [NcChannel] (which can have some extra bits set).
/// Gets the three foreground RGB [NcColors] from an [NcChannelPair], and
/// returns the foreground [NcChannel] (which can have some extra bits set).
#[inline]
pub fn channels_fg_rgb8(
channels: NcChannelPair,
@ -151,9 +174,8 @@ pub fn channels_fg_rgb8(
channel_rgb8(channels_fchannel(channels), r, g, b)
}
/// Gets the background [NcRgb] 24-bit value from an [NcChannelPair], and
/// saves it split into three [NcColor] 8-bit components. Also returns the
/// corresponding [NcChannel] (which can have some extra bits set).
/// Gets the three background RGB [NcColors] from an [NcChannelPair], and
/// returns the background [NcChannel] (which can have some extra bits set).
#[inline]
pub fn channels_bg_rgb8(
channels: NcChannelPair,
@ -164,8 +186,8 @@ pub fn channels_bg_rgb8(
channel_rgb8(channels_bchannel(channels), r, g, b)
}
/// Sets the RGB [NcColor] components for the foreground [NcChannel] of an
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
/// Sets the three foreground RGB [NcColor]s of an [NcChannelPair], and
/// marks it as not using the "default color".
#[inline]
pub fn channels_set_fg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor) {
let mut channel = channels_fchannel(*channels);
@ -173,8 +195,8 @@ pub fn channels_set_fg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
}
/// Sets the RGB [NcColor] components for the background [NcChannel] of an
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
/// Sets the three background RGB [NcColor]s of an [NcChannelPair], and
/// marks it as not using the "default color".
#[inline]
pub fn channels_set_bg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor) {
let mut channel = channels_bchannel(*channels);
@ -184,29 +206,36 @@ pub fn channels_set_bg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor
// NcRgb -----------------------------------------------------------------------
/// Gets the foreground [NcRgb] 24-bit value from an [NcChannelPair],
/// shifted to LSBs.
/// Gets the foreground [NcRgb] from an [NcChannelPair], shifted to LSBs.
#[inline]
pub fn channels_fg_rgb(channels: NcChannelPair) -> NcChannel {
channels_fchannel(channels) & NCCELL_BG_RGB_MASK
}
/// Gets the background [NcRgb] 24-bit value from an [NcChannelPair],
/// shifted to LSBs.
/// Gets the background [NcRgb] from an [NcChannelPair], shifted to LSBs.
#[inline]
pub fn channels_bg_rgb(channels: NcChannelPair) -> NcChannel {
channels_bchannel(channels) & NCCELL_BG_RGB_MASK
}
/// Sets the [NcRgb] 24-bit RGB value of a 32-bit [NcChannel], and marks it as
/// not using the "default color". Retain the other bits unchanged.
/// Gets the [NcRgb] of an [NcChannel].
///
/// This function basically removes the 4th byte of the NcChannel.
// Not in the C API
#[inline]
pub const fn channel_rgb(channel: NcChannel) -> NcRgb {
channel & NCCELL_BG_RGB_MASK
}
/// Sets the [NcRgb] of an [NcChannel], and marks it
/// as not using the "default color", retaining the other bits unchanged.
#[inline]
pub fn channel_set(channel: &mut NcChannel, rgb: NcRgb) {
*channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | (rgb & 0x00ffffff);
}
/// Sets the foreground [NcRgb] 24-bit value of an [NcChannelPair],
/// and marks it as not using the "default color".
/// Sets the foreground [NcRgb] of an [NcChannelPair],
/// and marks it as not using the the "default color".
#[inline]
pub fn channels_set_fg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
let mut channel = channels_fchannel(*channels);
@ -214,8 +243,8 @@ pub fn channels_set_fg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
}
/// Sets the background [NcRgb] 24-bit value of an [NcChannelPair],
/// , and marks it as not using the "default color".
/// Sets the foreground [NcRgb] of an [NcChannelPair],
/// and marks it as not using the the "default color".
#[inline]
pub fn channels_set_bg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
let mut channel = channels_bchannel(*channels);
@ -227,7 +256,7 @@ pub fn channels_set_bg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
/// Is this [NcChannel] using the "default color" rather than RGB/palette-indexed?
#[inline]
pub fn channel_default_p(channel: NcChannel) -> bool {
pub const fn channel_default_p(channel: NcChannel) -> bool {
(channel & NCCELL_BGDEFAULT_MASK) == 0
}

@ -10,6 +10,17 @@ macro_rules! sleep {
};
}
/// Renders the [Notcurses] object sleeps for $ms milliseconds.
#[macro_export]
macro_rules! rsleep {
($nc: expr, $ms:expr) => {
unsafe {
crate::notcurses_render($nc);
}
std::thread::sleep(std::time::Duration::from_millis($ms));
};
}
/// Converts `&str` to `*mut CString`, for when `*const c_char` is needed.
#[macro_export]
macro_rules! cstring {

@ -136,33 +136,71 @@ impl NcPlane {
self.dim_yx().1
}
/// Erase every NcCell in the NcPlane, resetting all attributes to normal,
/// Sets the scrolling behaviour of the plane, and
/// returns true if scrolling was previously enabled, of false, if disabled.
///
/// All planes are created with scrolling disabled. Attempting to print past
/// the end of a line will stop at the plane boundary, and indicate an error.
///
/// On a plane 10 columns wide and two rows high, printing "0123456789"
/// at the origin should succeed, but printing "01234567890" will by default
/// fail at the eleventh character. In either case, the cursor will be left
/// at location 0x10; it must be moved before further printing can take place. I
pub fn set_scrolling(&mut self, scroll: bool) -> bool {
unsafe { crate::ncplane_set_scrolling(self, scroll) }
}
// TODO: resize
// Write -------------------------------------------------------------------
/// Erases every NcCell in the NcPlane, resetting all attributes to normal,
/// all colors to the default color, and all cells to undrawn.
///
/// All cells associated with this ncplane are invalidated, and must not be
/// All cells associated with this NcPlane are invalidated, and must not be
/// used after the call, excluding the base cell. The cursor is homed.
pub fn erase(&mut self) {
unsafe { crate::ncplane_erase(self) }
}
// Write -------------------------------------------------------------------
/// Replaces the NcCell at the specified coordinates with the provided NcCell,
/// advancing the cursor by its width (but not past the end of the plane).
///
/// 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) }
}
/// Replaces the NcCell at the current coordinates with the provided NcCell,
/// advancing the cursor by its width (but not past the end of the plane).
///
/// 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.
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
/// Write a string, which is a series of [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()`).
///
/// 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_yx(&mut self, y: i32, x: i32, string: &str) -> NcResult {
unsafe { crate::ncplane_putstr_yx(self, y, x, cstring![string]) }
}

@ -145,7 +145,7 @@
// + ncplane_putchar_yx
// + ncplane_putegc
// + ncplane_putnstr
// + ncplane_putstr
//W+ ncplane_putstr
// X ncplane_putwc // I don't think these will be needed from Rust. See:
// X ncplane_putwc_stained
// X ncplane_putwc_yx // https://locka99.gitbooks.io/a-guide-to-porting-c-to-rust/content/features_of_rust/strings.html

@ -7,7 +7,6 @@ pub type NcStats = crate::bindings::bindgen::ncstats;
/// # `NcStats` Methods.
impl NcStats {
/// Allocates an NcStats object.
pub fn new<'a>(nc: &'a Notcurses) -> &'a mut Self {
unsafe { &mut *crate::notcurses_stats_alloc(nc) }

@ -6,7 +6,6 @@ mod plot;
mod reader;
mod reel;
mod selector;
mod stats;
pub use menu::*;
pub use multiselector::*;
@ -14,4 +13,3 @@ pub use plot::*;
pub use reader::*;
pub use reel::*;
pub use selector::*;
pub use stats::*;

Loading…
Cancel
Save