egui_charts/ui_kit/toolbar/
button_group.rs1use egui::{Align, Layout, Ui};
6
7use crate::theme::ThemeExt;
8
9pub struct ButtonGroup {
24 separator_after: bool,
25 separator_before: bool,
26}
27
28impl Default for ButtonGroup {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl ButtonGroup {
35 pub fn new() -> Self {
37 Self {
38 separator_after: false,
39 separator_before: false,
40 }
41 }
42
43 #[must_use]
45 pub fn separator_after(mut self) -> Self {
46 self.separator_after = true;
47 self
48 }
49
50 #[must_use]
52 pub fn separator_before(mut self) -> Self {
53 self.separator_before = true;
54 self
55 }
56
57 pub fn show<R>(self, ui: &mut Ui, content: impl FnOnce(&mut Ui) -> R) -> R {
63 let gap = ui.active_theme().spacing.sm;
64 let stroke = ui.visuals().widgets.noninteractive.bg_stroke;
65 let slot = 2.0 * gap + stroke.width;
66 let horizontal = ui.layout().main_dir().is_horizontal();
67 let body = |ui: &mut Ui| {
68 if self.separator_before {
69 ui.add_space(slot);
70 }
71 let result = content(ui);
72 let group = ui.min_rect();
73 let offset = gap + stroke.width / 2.0;
75 if horizontal {
76 if self.separator_before {
77 ui.painter()
78 .vline(group.left() + offset, group.y_range(), stroke);
79 }
80 if self.separator_after {
81 ui.painter()
82 .vline(group.right() + offset, group.y_range(), stroke);
83 ui.expand_to_include_x(group.right() + slot);
84 }
85 } else {
86 if self.separator_before {
87 ui.painter()
88 .hline(group.x_range(), group.top() + offset, stroke);
89 }
90 if self.separator_after {
91 ui.painter()
92 .hline(group.x_range(), group.bottom() + offset, stroke);
93 ui.expand_to_include_y(group.bottom() + slot);
94 }
95 }
96 result
97 };
98 if horizontal {
99 ui.horizontal(body).inner
100 } else {
101 ui.vertical(body).inner
102 }
103 }
104}
105
106pub struct ToolbarLayout;
108
109impl ToolbarLayout {
110 pub fn left_right<L, R>(
131 ui: &mut Ui,
132 left_content: impl FnOnce(&mut Ui) -> L,
133 right_content: impl FnOnce(&mut Ui) -> R,
134 ) -> (L, R) {
135 let left = left_content(ui);
136
137 let right = ui
138 .with_layout(Layout::right_to_left(Align::Center), |ui| right_content(ui))
139 .inner;
140
141 (left, right)
142 }
143
144 pub fn centered<C, L, R>(
148 ui: &mut Ui,
149 left_content: impl FnOnce(&mut Ui) -> L,
150 center_content: impl FnOnce(&mut Ui) -> C,
151 right_content: impl FnOnce(&mut Ui) -> R,
152 ) -> (L, C, R) {
153 let left = left_content(ui);
154
155 let center = ui
156 .with_layout(
157 Layout::centered_and_justified(ui.layout().main_dir()),
158 |ui| center_content(ui),
159 )
160 .inner;
161
162 let right = ui
163 .with_layout(Layout::right_to_left(Align::Center), |ui| right_content(ui))
164 .inner;
165
166 (left, center, right)
167 }
168}