use crate::{AtomKind, FontSelection, Id, SizedAtom, Ui};
use emath::{NumExt as _, Vec2};
use epaint::text::TextWrapMode;
#[derive(Clone, Debug)]
pub struct Atom<'a> {
pub size: Option<Vec2>,
pub max_size: Vec2,
pub grow: bool,
pub shrink: bool,
pub kind: AtomKind<'a>,
}
impl Default for Atom<'_> {
fn default() -> Self {
Atom {
size: None,
max_size: Vec2::INFINITY,
grow: false,
shrink: false,
kind: AtomKind::Empty,
}
}
}
impl<'a> Atom<'a> {
pub fn grow() -> Self {
Atom {
grow: true,
..Default::default()
}
}
pub fn custom(id: Id, size: impl Into<Vec2>) -> Self {
Atom {
size: Some(size.into()),
kind: AtomKind::Custom(id),
..Default::default()
}
}
pub fn into_sized(
self,
ui: &Ui,
mut available_size: Vec2,
mut wrap_mode: Option<TextWrapMode>,
fallback_font: FontSelection,
) -> SizedAtom<'a> {
if !self.shrink && self.max_size.x.is_infinite() {
wrap_mode = Some(TextWrapMode::Extend);
}
available_size = available_size.at_most(self.max_size);
if let Some(size) = self.size {
available_size = available_size.at_most(size);
}
if self.max_size.x.is_finite() {
wrap_mode = Some(TextWrapMode::Truncate);
}
let (intrinsic, kind) = self
.kind
.into_sized(ui, available_size, wrap_mode, fallback_font);
let size = self
.size
.map_or_else(|| kind.size(), |s| s.at_most(self.max_size));
SizedAtom {
size,
intrinsic_size: intrinsic.at_least(self.size.unwrap_or_default()),
grow: self.grow,
kind,
}
}
}
impl<'a, T> From<T> for Atom<'a>
where
T: Into<AtomKind<'a>>,
{
fn from(value: T) -> Self {
Atom {
kind: value.into(),
..Default::default()
}
}
}