mod interaction;
mod item;
mod layout;
mod multi;
mod render;
mod storage;
pub use item::{
MacSegmentEvent, MacSegmentItem, SegmentContent, SegmentEvent, SegmentIconFn,
SegmentIconPainter, SegmentItem, SegmentMenuTrigger,
};
use crate::controls::MacControlSize;
use crate::symbols::MacSymbol;
use crate::theme::MacTheme;
use egui::{Rect, Response, Ui};
use std::borrow::Cow;
use storage::{InlineBuf, INLINE_CAP};
pub struct MacSegmentedControl<'a> {
pub(crate) segments: InlineBuf<SegmentItem<'a>>,
pub(crate) selected_idx: usize,
pub(crate) enabled: bool,
pub(crate) theme: Option<&'a MacTheme>,
pub(crate) height: Option<f32>,
pub(crate) control_size: MacControlSize,
pub(crate) small_square: bool,
pub(crate) momentary: bool,
pub(crate) fixed_rect: Option<Rect>,
pub(crate) id_salt: Option<egui::Id>,
pub(crate) a11y_label: Option<Cow<'a, str>>,
}
impl<'a> MacSegmentedControl<'a> {
pub const INLINE_SEGMENT_CAPACITY: usize = INLINE_CAP;
pub fn new(options: &'a [&'a str], selected_idx: usize) -> Self {
Self::with_custom_segments(options.iter().map(|&opt| SegmentItem::new(opt)), selected_idx)
}
pub fn with_custom_segments(
segments: impl IntoIterator<Item = SegmentItem<'a>>,
selected_idx: usize,
) -> Self {
Self {
segments: segments.into_iter().collect(),
selected_idx,
enabled: true,
theme: None,
height: None,
control_size: MacControlSize::Regular,
small_square: false,
momentary: false,
fixed_rect: None,
id_salt: None,
a11y_label: None,
}
}
pub fn momentary(segments: impl IntoIterator<Item = SegmentItem<'a>>) -> Self {
let mut ctrl = Self::with_custom_segments(segments, 0);
ctrl.momentary = true;
ctrl
}
pub fn with_icons(symbols: &'a [MacSymbol], selected_idx: usize) -> Self {
Self::with_custom_segments(symbols.iter().map(|&sym| SegmentItem::from_symbol(sym)), selected_idx)
}
#[inline]
pub const fn is_inline_allocated(&self) -> bool {
self.segments.is_inline()
}
pub fn id_salt(mut self, salt: impl std::hash::Hash + std::fmt::Debug) -> Self {
self.id_salt = Some(egui::Id::NULL.with(salt));
self
}
pub fn accessibility_label(mut self, label: impl Into<Cow<'a, str>>) -> Self {
self.a11y_label = Some(label.into());
self
}
pub const fn enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}
pub const fn theme(mut self, theme: &'a MacTheme) -> Self {
self.theme = Some(theme);
self
}
pub const fn height(mut self, height: f32) -> Self {
self.height = Some(height);
self
}
pub const fn control_size(mut self, size: MacControlSize) -> Self {
self.control_size = size;
self
}
pub const fn small_square(mut self) -> Self {
self.small_square = true;
self
}
pub const fn fixed_rect(mut self, rect: Rect) -> Self {
self.fixed_rect = Some(rect);
self
}
pub fn show_multi(self, ui: &mut Ui, active: &mut [bool]) -> Option<usize> {
multi::render_multi(self, ui, active)
}
pub fn show(self, ui: &mut Ui, mut on_select: impl FnMut(usize)) -> Response {
self.show_with_events(ui, |ev| {
if !ev.opens_menu() {
on_select(ev.index);
}
})
}
pub fn show_with_events(self, ui: &mut Ui, on_event: impl FnMut(SegmentEvent)) -> Response {
render::render_segmented(self, ui, on_event)
}
pub fn show_momentary(mut self, ui: &mut Ui, mut on_action: impl FnMut(usize)) -> Response {
self.momentary = true;
self.show_with_events(ui, |ev| {
if !ev.opens_menu() {
on_action(ev.index);
}
})
}
pub fn show_momentary_with_events(
mut self,
ui: &mut Ui,
on_event: impl FnMut(SegmentEvent),
) -> Response {
self.momentary = true;
render::render_segmented(self, ui, on_event)
}
}