libnotcurses-sys 3.3.0

Low-level Rust bindings for the notcurses C library.
Documentation
//! NcPlaneBuilder

use crate::{
    Nc, NcAlign, NcError, NcPlane, NcPlaneOptions, NcPlaneOptionsBuilder,
    NcResizeCb, NcResult,
};

// use std::{
//     fmt,
//     ptr::{null, null_mut},
// };

/// Builder object for [`NcPlane`].
///
/// Can be constructed by calling [`NcPlaneOptions::builder()`].
///
/// By default it already has the [`MARGINALIZED`] flag set, alongside `(0, 0)`
/// margins, so that it automatically fills the parent plane.
///
/// [`NcPlaneOptions::builder()`]: NcPlaneOptions#method.builder
/// [`MARGINALIZED`]: NcPlaneOptions#associatedconstant.MARGINALIZED
#[derive(Debug, Default)]
pub struct NcPlaneBuilder<'nc, 'parent> {
    nc: Option<&'nc mut Nc>,
    parent: Option<&'parent mut NcPlane>,
    options: NcPlaneOptionsBuilder,
}

impl<'nc, 'parent> NcPlaneBuilder<'nc, 'parent> {
    /// Sets the options.
    pub fn options(mut self, options: &NcPlaneOptions) -> Self {
        self.options = options.into();
        self
    }

    /// Gets a copy of the options.
    pub fn get_options(&self) -> NcPlaneOptions {
        self.options.clone().into()
    }

    /// Sets the `parent` for the new `NcPlane`, and unsets the `nc` context.
    ///
    /// The new plane will be placed:
    /// - at the `y`×`x` offset coordinates relative to its parent.
    /// - with a size of `rows`×`cols`.
    /// - and at the top of the z-buffer.
    ///
    /// Default: *`None`*. (no parent plane)
    pub fn parent(mut self, plane: &'parent mut NcPlane) -> Self {
        self.parent = Some(plane);
        self.nc = None;
        self
    }

    /// Unsets the parent `NcPlane`.
    ///
    /// Default: *`None`* (no parent plane).
    ///
    /// [`CHILDPLANE`]: NcVisualOptions#associatedconstant.CHILDPLANE
    pub fn no_parent(mut self) -> Self {
        self.parent = None;
        self
    }

    /// Sets the `Nc` context, and unsets the `parent` plane.
    ///
    /// A new pile will be created.
    pub fn nc(mut self, nc: &'nc mut Nc) -> Self {
        self.nc = Some(nc);
        self.parent = None;
        self
    }

    // -------------------------------------------------------

    /// Sets the vertical placement relative to parent plane.
    ///
    /// Default: *`0`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.y][NcPlaneOptionsBuilder#method.y]*.
    pub fn y(mut self, y: i32) -> Self {
        self.options.y = y;
        self.options.flags &= !NcPlaneOptions::VERALIGNED;
        self
    }

    /// Sets the horizontal placement relative to parent plane.
    ///
    /// Default: *`0`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.x][NcPlaneOptionsBuilder#method.x]*.
    pub fn x(mut self, x: i32) -> Self {
        self.options.x = x;
        self.options.flags &= !NcPlaneOptions::HORALIGNED;
        self
    }

    /// Sets the vertical & horizontal placement relative to parent plane.
    ///
    /// Default: *`(0, 0)`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.yx][NcPlaneOptionsBuilder#method.yx]*.
    pub fn yx(mut self, y: i32, x: i32) -> Self {
        self.options.y = y;
        self.options.x = x;
        self.options.flags &= !NcPlaneOptions::VERALIGNED;
        self.options.flags &= !NcPlaneOptions::HORALIGNED;
        self
    }

    /// Sets the vertical alignment.
    ///
    /// Default: *[`NcAlign::TOP`]*.
    ///
    /// See: *[NcPlaneOptionsBuilder.valign][NcPlaneOptionsBuilder#method.valign]*.
    ///
    /// [`NcAlign::TOP`]: crate::NcAlign#associatedconstant.TOP
    pub fn valign(mut self, valign: impl Into<NcAlign>) -> Self {
        self.options.y = valign.into() as i32;
        self.options.flags |= NcPlaneOptions::VERALIGNED;
        self
    }

    /// Sets the horizontal alignment.
    ///
    /// Default: *[`NcAlign::LEFT`]*.
    ///
    /// See: *[NcPlaneOptionsBuilder.halign][NcPlaneOptionsBuilder#method.halign]*.
    ///
    /// [`NcAlign::LEFT`]: crate::NcAlign#associatedconstant.LEFT
    pub fn halign(mut self, halign: impl Into<NcAlign>) -> Self {
        self.options.y = halign.into() as i32;
        self.options.flags |= NcPlaneOptions::VERALIGNED;
        self
    }

    /// Sets the vertical & horizontal alignment.
    ///
    /// Default: *`(`[`NcAlign::TOP`], [`NcAlign::LEFT`]`)`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.align][NcPlaneOptionsBuilder#method.align]*.
    ///
    /// [`NcAlign::TOP`]: crate::NcAlign#associatedconstant.TOP
    /// [`NcAlign::LEFT`]: crate::NcAlign#associatedconstant.LEFT
    pub fn align(mut self, halign: impl Into<NcAlign>) -> Self {
        self.options.y = halign.into() as i32;
        self.options.flags |= NcPlaneOptions::VERALIGNED;
        self
    }

    /// Sets the number of rows for the plane.
    ///
    /// Default: *`0`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.rows][NcPlaneOptionsBuilder#method.rows]*.
    pub fn rows(mut self, rows: u32) -> Self {
        self.options.rows = rows;
        self.options.flags &= !NcPlaneOptions::MARGINALIZED;
        self
    }

    /// Sets the number of columns for the plane.
    ///
    /// Default: *`0`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.cols][NcPlaneOptionsBuilder#method.cols]*.
    pub fn cols(mut self, cols: u32) -> Self {
        self.options.cols = cols;
        self.options.flags &= !NcPlaneOptions::MARGINALIZED;
        self
    }

    /// Sets the number of rows & columns for the plane.
    ///
    /// Default: *`(0, 0)`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.rows_cols][NcPlaneOptionsBuilder#method.rows_cols]*.
    pub fn rows_cols(mut self, rows: u32, cols: u32) -> Self {
        self.options.rows = rows;
        self.options.cols = cols;
        self.options.flags &= !NcPlaneOptions::MARGINALIZED;
        self
    }

    /// Sets the bottom & right margins.
    ///
    /// Default: *`(0, 0)`*.
    ///
    /// See: *[NcPlaneOptionsBuilder.margins][NcPlaneOptionsBuilder#method.margins]*.
    pub fn margins(mut self, bottom: u32, right: u32) -> Self {
        self.options.margin_b = bottom;
        self.options.margin_r = right;
        self.options.flags &= !NcPlaneOptions::MARGINALIZED;
        self
    }

    /// If `true`, the plane will **not** scroll with the parent.
    ///
    /// Default: *false* (scrolls with the parent).
    ///
    /// See: *[NcPlaneOptionsBuilder.fixed][NcPlaneOptionsBuilder#method.fixed]*.
    pub fn fixed(mut self, fixed: bool) -> Self {
        if fixed {
            self.options.flags |= NcPlaneOptions::FIXED;
        } else {
            self.options.flags &= !NcPlaneOptions::FIXED;
        }
        self
    }

    /// (Un)Sets the resize callback.
    ///
    /// Default: *None*.
    ///
    /// See: *[NcPlaneOptionsBuilder.resizecb][NcPlaneOptionsBuilder#method.resizecb]*.
    pub fn resizecb(mut self, callback: Option<NcResizeCb>) -> Self {
        self.options.resizecb = callback;
        self
    }

    /// Finishes the building and returns [`NcPlane`].
    pub fn build(self) -> NcResult<&'parent mut NcPlane> {
        if let Some(plane) = self.parent {
            if self.nc.is_none() {
                NcPlane::new_child(plane, &self.options.into())
            } else {
                Err(NcError::new_msg(
                    "NcPlaneBuilder.build() error: Both `parent` and `nc` fields are set.",
                ))
            }
        } else if let Some(nc) = self.nc {
            NcPlane::new_pile(nc, &self.options.into())
        } else {
            Err(NcError::new_msg(
                "NcPlaneBuilder.build() error: Neither `parent` or `nc` fields are set.",
            ))
        }
    }
}