1use repose_core::prelude::*;
7use repose_core::{Modifier, PaddingValues, View, WindowSizeClass};
8
9use crate::{Box, Column, Row, Text, ViewExt};
10
11#[derive(Clone, Copy, Debug)]
12pub struct PaneScaffoldDirective {
13 pub max_horizontal_partitions: u32,
14 pub horizontal_part_spacing: f32,
15 pub list_pane_width: f32,
16 pub content_padding: PaddingValues,
17}
18
19impl Default for PaneScaffoldDirective {
20 fn default() -> Self {
21 Self {
22 max_horizontal_partitions: 1,
23 horizontal_part_spacing: 0.0,
24 list_pane_width: 0.0,
25 content_padding: PaddingValues::default(),
26 }
27 }
28}
29
30impl PaneScaffoldDirective {
31 pub fn from_window_size_class(class: WindowSizeClass) -> Self {
32 if class.is_at_least_medium_width() {
33 Self {
34 max_horizontal_partitions: 2,
35 horizontal_part_spacing: 0.0,
36 list_pane_width: 360.0,
37 content_padding: PaddingValues::default(),
38 }
39 } else {
40 Self {
41 max_horizontal_partitions: 1,
42 horizontal_part_spacing: 0.0,
43 list_pane_width: 0.0,
44 content_padding: PaddingValues::default(),
45 }
46 }
47 }
48}
49
50#[derive(Clone, Copy, Debug, PartialEq, Eq)]
51pub enum ListDetailPaneValue {
52 List,
53 Detail,
54}
55
56pub fn ListDetailPaneScaffold<F1, F2>(
57 directive: PaneScaffoldDirective,
58 value: ListDetailPaneValue,
59 list: F1,
60 detail: F2,
61) -> View
62where
63 F1: Fn() -> View + 'static,
64 F2: Fn() -> View + 'static,
65{
66 if directive.max_horizontal_partitions >= 2 {
67 let spacing = directive.horizontal_part_spacing;
68 let list_mod = if directive.list_pane_width > 0.0 {
69 Modifier::new()
70 .width(directive.list_pane_width)
71 .fill_max_height()
72 } else {
73 Modifier::new().flex_grow(1.0).fill_max_height()
74 };
75 Row(Modifier::new().fill_max_size().gap(spacing)).child((
76 Box(list_mod).child(list()),
77 Box(Modifier::new().flex_grow(1.0).fill_max_height()).child(detail()),
78 ))
79 } else {
80 match value {
81 ListDetailPaneValue::List => list(),
82 ListDetailPaneValue::Detail => detail(),
83 }
84 }
85}
86
87pub fn ScaffoldPane(directive: &PaneScaffoldDirective, content: View) -> View {
88 Box(Modifier::new()
89 .fill_max_size()
90 .padding_values(directive.content_padding))
91 .child(content)
92}
93
94pub fn TwoPaneTopBar(title: &str, leading: Option<View>, trailing: Option<View>) -> View {
95 let th = theme();
96 let leading = leading.unwrap_or_else(|| Box(Modifier::new().width(0.0).height(0.0)));
97 let trailing = trailing.unwrap_or_else(|| Box(Modifier::new().width(0.0).height(0.0)));
98 Box(Modifier::new()
99 .fill_max_width()
100 .height(56.0)
101 .background(th.surface)
102 .padding_values(PaddingValues {
103 left: 16.0,
104 right: 16.0,
105 top: 0.0,
106 bottom: 0.0,
107 }))
108 .child((
109 leading,
110 Column(
111 Modifier::new()
112 .flex_grow(1.0)
113 .padding_values(PaddingValues {
114 left: 16.0,
115 right: 16.0,
116 top: 0.0,
117 bottom: 0.0,
118 }),
119 )
120 .child(Text(title)),
121 trailing,
122 ))
123}