panes 0.19.0

Renderer-agnostic layout engine with declarative ergonomics
Documentation
use std::sync::Arc;

use crate::builder::LayoutBuilder;
use crate::error::PaneError;
use crate::layout::Layout;
use crate::preset::dwindle::build_recursive;
use crate::preset::{collect_kinds, validate_f32_param, validate_kinds, validate_share_param};

/// Builder for the spiral preset layout.
pub struct Spiral {
    kinds: Arc<[Arc<str>]>,
    ratio: f32,
    gap: f32,
}

impl Spiral {
    pub(crate) fn new(kinds: impl IntoIterator<Item = impl Into<Arc<str>>>) -> Self {
        Self {
            kinds: collect_kinds(kinds),
            ratio: 0.5,
            gap: 0.0,
        }
    }

    crate::macros::builder_setters!(
        /// Set the split ratio.
        ratio(ratio: f32);
        /// Set the gap between panels.
        gap(gap: f32)
    );

    /// Consume the builder and produce a [`Layout`].
    pub fn build(&self) -> Result<Layout, PaneError> {
        validate_kinds(&self.kinds)?;
        validate_share_param("ratio", self.ratio)?;
        validate_f32_param("gap", self.gap)?;

        let mut b = LayoutBuilder::new();
        let kinds = &self.kinds;
        let ratio = self.ratio;
        let gap_px = self.gap;

        b.row_gap(gap_px, |r| {
            build_recursive(r, kinds, 0, ratio, gap_px, true);
        })?;

        b.build()
    }
}

super::impl_preset!(
    Spiral,
    runtime(kinds, |this| crate::strategy::StrategyKind::BinarySplit {
        spiral: true,
        ratio: this.ratio,
        gap: this.gap,
    })
);