use std::cell::RefCell;
use std::rc::Rc;
use teksilo_canvas::Rect;
use crate::build_context::BuildContext;
use crate::focus::FocusOrigin;
use crate::signal::Signal;
use crate::widget_id::WidgetId;
#[derive(Debug, Clone, Default)]
pub struct SegmentSlotGeometry {
pub frame: Rect,
pub segments: Vec<Rect>,
pub order: Vec<usize>,
pub overflow: Option<Rect>,
}
#[derive(Debug, Clone, Default)]
pub struct SegmentSlots(Rc<RefCell<SegmentSlotGeometry>>);
impl SegmentSlots {
pub fn new() -> Self {
Self::default()
}
pub fn publish(&self, geometry: SegmentSlotGeometry) {
*self.0.borrow_mut() = geometry;
}
pub fn with<R>(&self, f: impl FnOnce(&SegmentSlotGeometry) -> R) -> R {
f(&self.0.borrow())
}
pub fn slot_of(&self, segment: usize) -> Option<usize> {
self.0.borrow().order.iter().position(|&s| s == segment)
}
pub fn rect_of(&self, segment: usize) -> Option<Rect> {
let inner = self.0.borrow();
let slot = inner.order.iter().position(|&s| s == segment)?;
inner.segments.get(slot).copied()
}
pub fn len(&self) -> usize {
self.0.borrow().segments.len()
}
pub fn is_empty(&self) -> bool {
self.0.borrow().segments.is_empty()
}
}
#[derive(Clone, Debug)]
pub struct SegmentedControlStyleConfig {
pub slots: SegmentSlots,
pub selected: Signal<usize>,
pub hovered_segment: Signal<Option<usize>>,
pub focus_origin: Signal<Option<FocusOrigin>>,
pub is_enabled: Signal<bool>,
}
pub trait SegmentedControlStyle: 'static {
fn make_body(&self, cfg: &SegmentedControlStyleConfig, ctx: &mut BuildContext) -> WidgetId;
}
pub type SharedSegmentedControlStyle = Rc<dyn SegmentedControlStyle>;