egui_macview/controls/segmented/
mod.rs1mod interaction;
7mod item;
8mod layout;
9mod multi;
10mod render;
11mod storage;
12
13pub use item::{
14 MacSegmentEvent, MacSegmentItem, SegmentContent, SegmentEvent, SegmentIconFn,
15 SegmentIconPainter, SegmentItem, SegmentMenuTrigger,
16};
17
18use crate::controls::MacControlSize;
19use crate::symbols::MacSymbol;
20use crate::theme::MacTheme;
21use egui::{Rect, Response, Ui};
22use std::borrow::Cow;
23use storage::{InlineBuf, INLINE_CAP};
24
25pub struct MacSegmentedControl<'a> {
47 pub(crate) segments: InlineBuf<SegmentItem<'a>>,
48 pub(crate) selected_idx: usize,
49 pub(crate) enabled: bool,
50 pub(crate) theme: Option<&'a MacTheme>,
51 pub(crate) height: Option<f32>,
52 pub(crate) control_size: MacControlSize,
53 pub(crate) small_square: bool,
54 pub(crate) momentary: bool,
55 pub(crate) fixed_rect: Option<Rect>,
56 pub(crate) id_salt: Option<egui::Id>,
57 pub(crate) a11y_label: Option<Cow<'a, str>>,
58}
59
60impl<'a> MacSegmentedControl<'a> {
61 pub const INLINE_SEGMENT_CAPACITY: usize = INLINE_CAP;
63
64 pub fn new(options: &'a [&'a str], selected_idx: usize) -> Self {
66 Self::with_custom_segments(options.iter().map(|&opt| SegmentItem::new(opt)), selected_idx)
67 }
68
69 pub fn with_custom_segments(
71 segments: impl IntoIterator<Item = SegmentItem<'a>>,
72 selected_idx: usize,
73 ) -> Self {
74 Self {
75 segments: segments.into_iter().collect(),
76 selected_idx,
77 enabled: true,
78 theme: None,
79 height: None,
80 control_size: MacControlSize::Regular,
81 small_square: false,
82 momentary: false,
83 fixed_rect: None,
84 id_salt: None,
85 a11y_label: None,
86 }
87 }
88
89 pub fn momentary(segments: impl IntoIterator<Item = SegmentItem<'a>>) -> Self {
91 let mut ctrl = Self::with_custom_segments(segments, 0);
92 ctrl.momentary = true;
93 ctrl
94 }
95
96 pub fn with_icons(symbols: &'a [MacSymbol], selected_idx: usize) -> Self {
98 Self::with_custom_segments(symbols.iter().map(|&sym| SegmentItem::from_symbol(sym)), selected_idx)
99 }
100
101 #[inline]
103 pub const fn is_inline_allocated(&self) -> bool {
104 self.segments.is_inline()
105 }
106
107 pub fn id_salt(mut self, salt: impl std::hash::Hash + std::fmt::Debug) -> Self {
109 self.id_salt = Some(egui::Id::NULL.with(salt));
110 self
111 }
112
113 pub fn accessibility_label(mut self, label: impl Into<Cow<'a, str>>) -> Self {
115 self.a11y_label = Some(label.into());
116 self
117 }
118
119 pub const fn enabled(mut self, enabled: bool) -> Self {
121 self.enabled = enabled;
122 self
123 }
124
125 pub const fn theme(mut self, theme: &'a MacTheme) -> Self {
127 self.theme = Some(theme);
128 self
129 }
130
131 pub const fn height(mut self, height: f32) -> Self {
133 self.height = Some(height);
134 self
135 }
136
137 pub const fn control_size(mut self, size: MacControlSize) -> Self {
139 self.control_size = size;
140 self
141 }
142
143 pub const fn small_square(mut self) -> Self {
145 self.small_square = true;
146 self
147 }
148
149 pub const fn fixed_rect(mut self, rect: Rect) -> Self {
151 self.fixed_rect = Some(rect);
152 self
153 }
154
155 pub fn show_multi(self, ui: &mut Ui, active: &mut [bool]) -> Option<usize> {
157 multi::render_multi(self, ui, active)
158 }
159
160 pub fn show(self, ui: &mut Ui, mut on_select: impl FnMut(usize)) -> Response {
162 self.show_with_events(ui, |ev| {
163 if !ev.opens_menu() {
164 on_select(ev.index);
165 }
166 })
167 }
168
169 pub fn show_with_events(self, ui: &mut Ui, on_event: impl FnMut(SegmentEvent)) -> Response {
171 render::render_segmented(self, ui, on_event)
172 }
173
174 pub fn show_momentary(mut self, ui: &mut Ui, mut on_action: impl FnMut(usize)) -> Response {
176 self.momentary = true;
177 self.show_with_events(ui, |ev| {
178 if !ev.opens_menu() {
179 on_action(ev.index);
180 }
181 })
182 }
183
184 pub fn show_momentary_with_events(
186 mut self,
187 ui: &mut Ui,
188 on_event: impl FnMut(SegmentEvent),
189 ) -> Response {
190 self.momentary = true;
191 render::render_segmented(self, ui, on_event)
192 }
193}