mod badge;
mod button;
mod choice;
mod progress;
mod skeleton;
mod switch;
pub use badge::{Badge, Keycap, Tone};
pub use button::{Button, IconPainter, Size, Variant};
pub use choice::{RadioGroup, Segmented};
pub use progress::{Progress, Spinner};
pub use skeleton::Skeleton;
pub use switch::Switch;
use std::hash::Hash;
use std::sync::Arc;
use egui::{Color32, CornerRadius, Galley, Painter, Pos2, Rect, Stroke, StrokeKind, Ui};
use crate::tokens::Tokens;
use crate::wake::{self, Reason};
pub(crate) const FOCUS_WIDTH: f32 = 1.5;
pub(crate) fn text_galley(ui: &Ui, key: impl Hash, text: &str, size: f32) -> Arc<Galley> {
let font = Tokens::font(size);
crate::cache::galley(ui, key, crate::cache::hash_of(&(text, size.to_bits())), || {
egui::text::LayoutJob::simple_singleline(text.to_owned(), font, Color32::PLACEHOLDER)
})
}
pub(crate) fn focus_ring(painter: &Painter, rect: Rect, radius: CornerRadius, t: &Tokens) {
painter.rect_stroke(rect.expand(2.0), radius, Stroke::new(FOCUS_WIDTH, t.focus), StrokeKind::Outside);
}
pub(crate) fn mix(a: Color32, b: Color32, t: f32) -> Color32 {
let t = if t.is_finite() { t.clamp(0.0, 1.0) } else { 0.0 };
let m = |x: u8, y: u8| (x as f32 + (y as f32 - x as f32) * t).round().clamp(0.0, 255.0) as u8;
Color32::from_rgba_unmultiplied(m(a.r(), b.r()), m(a.g(), b.g()), m(a.b(), b.b()), m(a.a(), b.a()))
}
pub(crate) fn dimmed(ui: &Ui, dim: bool) -> Painter {
let mut painter = ui.painter().clone();
if dim {
painter.multiply_opacity(ui.visuals().disabled_alpha());
}
painter
}
pub(crate) fn animate(ui: &Ui, rect: Rect) {
if ui.is_rect_visible(rect) {
wake::wake(ui.ctx(), Reason::ANIMATION);
}
}
pub(crate) fn arc_points(center: Pos2, radius: f32, start: f32, sweep: f32) -> Vec<Pos2> {
let sweep = if sweep.is_finite() { sweep.clamp(-std::f32::consts::TAU, std::f32::consts::TAU) } else { 0.0 };
let radius = if radius.is_finite() { radius.max(0.0) } else { 0.0 };
let n = ((sweep.abs() / std::f32::consts::TAU) * 90.0).ceil().clamp(1.0, 90.0) as usize;
(0..=n)
.map(|i| {
let a = start + sweep * (i as f32 / n as f32);
Pos2::new(center.x + radius * a.cos(), center.y + radius * a.sin())
})
.collect()
}
#[cfg(test)]
mod tests;