Skip to main content

panes/preset/
sidebar.rs

1use std::sync::Arc;
2
3use crate::builder::LayoutBuilder;
4use crate::error::PaneError;
5use crate::layout::Layout;
6use crate::panel::fixed;
7use crate::preset::validate_f32_param;
8
9/// Builder for the sidebar preset layout.
10pub struct Sidebar {
11    sidebar_kind: Arc<str>,
12    content_kind: Arc<str>,
13    sidebar_width: f32,
14    gap: f32,
15}
16
17impl Sidebar {
18    pub(crate) fn new(
19        sidebar_kind: impl Into<Arc<str>>,
20        content_kind: impl Into<Arc<str>>,
21    ) -> Self {
22        Self {
23            sidebar_kind: sidebar_kind.into(),
24            content_kind: content_kind.into(),
25            sidebar_width: 20.0,
26            gap: 0.0,
27        }
28    }
29
30    /// Set the sidebar width.
31    pub fn sidebar_width(mut self, width: f32) -> Self {
32        self.sidebar_width = width;
33        self
34    }
35
36    /// Set the gap between panels.
37    pub fn gap(mut self, gap: f32) -> Self {
38        self.gap = gap;
39        self
40    }
41
42    /// Consume the builder and produce a [`Layout`].
43    pub fn build(&self) -> Result<Layout, PaneError> {
44        validate_f32_param("sidebar_width", self.sidebar_width)?;
45
46        let mut b = LayoutBuilder::new();
47        let sidebar_kind = Arc::clone(&self.sidebar_kind);
48        let content_kind = Arc::clone(&self.content_kind);
49        let width = self.sidebar_width;
50
51        b.row_gap(self.gap, |r| {
52            r.panel_with(sidebar_kind, fixed(width));
53            r.panel(content_kind);
54        })?;
55
56        b.build()
57    }
58}
59
60impl Sidebar {
61    /// Consume the builder and produce a [`crate::runtime::LayoutRuntime`].
62    pub fn into_runtime(self) -> Result<crate::runtime::LayoutRuntime, PaneError> {
63        let slots: Arc<[crate::strategy::SlotDef]> = vec![
64            crate::strategy::SlotDef {
65                kind: Arc::clone(&self.sidebar_kind),
66                constraints: crate::panel::fixed(self.sidebar_width),
67            },
68            crate::strategy::SlotDef {
69                kind: Arc::clone(&self.content_kind),
70                constraints: crate::panel::grow(1.0),
71            },
72        ]
73        .into();
74        let strategy = crate::strategy::StrategyKind::Slotted {
75            slots,
76            gap: self.gap,
77            direction: crate::strategy::Direction::Horizontal,
78        };
79        let kinds = [
80            Arc::clone(&self.sidebar_kind),
81            Arc::clone(&self.content_kind),
82        ];
83        crate::runtime::LayoutRuntime::from_strategy(strategy, &kinds)
84    }
85}
86
87super::impl_preset!(Sidebar);