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
9pub 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 pub fn sidebar_width(mut self, width: f32) -> Self {
32 self.sidebar_width = width;
33 self
34 }
35
36 pub fn gap(mut self, gap: f32) -> Self {
38 self.gap = gap;
39 self
40 }
41
42 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 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);