panes/preset/
master_stack.rs1use std::sync::Arc;
2
3use crate::builder::LayoutBuilder;
4use crate::error::PaneError;
5use crate::layout::Layout;
6use crate::panel::grow;
7use crate::preset::{collect_kinds, validate_f32_param, validate_kinds};
8
9pub struct MasterStack {
11 kinds: Arc<[Arc<str>]>,
12 master_ratio: f32,
13 gap: f32,
14}
15
16impl MasterStack {
17 pub(crate) fn new(kinds: impl IntoIterator<Item = impl Into<Arc<str>>>) -> Self {
18 Self {
19 kinds: collect_kinds(kinds),
20 master_ratio: 0.5,
21 gap: 0.0,
22 }
23 }
24
25 pub fn master_ratio(mut self, ratio: f32) -> Self {
27 self.master_ratio = ratio;
28 self
29 }
30
31 pub fn gap(mut self, gap: f32) -> Self {
33 self.gap = gap;
34 self
35 }
36
37 pub fn build(&self) -> Result<Layout, PaneError> {
39 validate_kinds(&self.kinds)?;
40 validate_f32_param("master_ratio", self.master_ratio)?;
41 match self.kinds.len() {
42 1 => super::build_single(Arc::clone(&self.kinds[0])),
43 _ => self.build_master_stack(),
44 }
45 }
46
47 fn build_master_stack(&self) -> Result<Layout, PaneError> {
48 let mut b = LayoutBuilder::new();
49 let ratio = self.master_ratio;
50 let master_kind = Arc::clone(&self.kinds[0]);
51 let stack_style = col_style(1.0 - ratio, self.gap);
52
53 b.row_gap(self.gap, |r| {
54 r.panel_with(master_kind, grow(ratio));
55 r.taffy_node(stack_style, |c| add_panels(c, &self.kinds[1..], grow(1.0)));
56 })?;
57
58 b.build()
59 }
60}
61
62pub(crate) fn col_style(flex_grow: f32, gap_px: f32) -> taffy::Style {
64 taffy::Style {
65 flex_direction: taffy::FlexDirection::Column,
66 flex_grow,
67 flex_basis: taffy::Dimension::length(0.0),
68 flex_shrink: 1.0,
69 gap: taffy::Size {
70 width: taffy::LengthPercentage::length(0.0),
71 height: taffy::LengthPercentage::length(gap_px),
72 },
73 ..Default::default()
74 }
75}
76
77pub(crate) fn row_style(flex_grow: f32, gap_px: f32) -> taffy::Style {
79 taffy::Style {
80 flex_direction: taffy::FlexDirection::Row,
81 flex_grow,
82 flex_basis: taffy::Dimension::length(0.0),
83 flex_shrink: 1.0,
84 gap: taffy::Size {
85 width: taffy::LengthPercentage::length(gap_px),
86 height: taffy::LengthPercentage::length(0.0),
87 },
88 ..Default::default()
89 }
90}
91
92pub(crate) fn add_panels(
93 ctx: &mut crate::ContainerCtx,
94 kinds: &[Arc<str>],
95 constraints: crate::Constraints,
96) {
97 for kind in kinds {
98 ctx.panel_with(Arc::clone(kind), constraints);
99 }
100}
101
102impl MasterStack {
103 pub fn into_runtime(self) -> Result<crate::runtime::LayoutRuntime, PaneError> {
105 let strategy = crate::strategy::StrategyKind::MasterStack {
106 master_ratio: self.master_ratio,
107 gap: self.gap,
108 };
109 crate::runtime::LayoutRuntime::from_strategy(strategy, &self.kinds)
110 }
111}
112
113super::impl_preset!(MasterStack);