use crate::core::Pixels;
pub use crate::view::shadow::{BoxShadow, ShadowPreset, Shadows};
use crate::view::style_extra::StyleExtra;
use crate::view::theme::ColorSpec;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Length {
Px(Pixels),
Percent(f32),
Auto,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Direction {
Row,
Column,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Align {
Start,
Center,
End,
Stretch,
Baseline,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Justify {
Start,
Center,
End,
SpaceBetween,
SpaceAround,
SpaceEvenly,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Overflow {
Visible,
Hidden,
Scroll,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Sides {
pub top: Option<Pixels>,
pub right: Option<Pixels>,
pub bottom: Option<Pixels>,
pub left: Option<Pixels>,
}
impl Sides {
pub(crate) fn refine(&mut self, other: &Sides) {
self.top = other.top.or(self.top);
self.right = other.right.or(self.right);
self.bottom = other.bottom.or(self.bottom);
self.left = other.left.or(self.left);
}
pub fn set_all(&mut self, value: Pixels) {
*self = Sides { top: Some(value), right: Some(value), bottom: Some(value), left: Some(value) };
}
pub fn set_horizontal(&mut self, value: Pixels) {
self.left = Some(value);
self.right = Some(value);
}
pub fn set_vertical(&mut self, value: Pixels) {
self.top = Some(value);
self.bottom = Some(value);
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Style {
pub direction: Option<Direction>,
pub wrap: Option<bool>,
pub align_items: Option<Align>,
pub align_self: Option<Align>,
pub justify_content: Option<Justify>,
pub flex_grow: Option<f32>,
pub flex_shrink: Option<f32>,
pub flex_basis: Option<Length>,
pub width: Option<Length>,
pub height: Option<Length>,
pub min_width: Option<Length>,
pub min_height: Option<Length>,
pub max_width: Option<Length>,
pub max_height: Option<Length>,
pub aspect_ratio: Option<f32>,
pub padding: Sides,
pub margin: Sides,
pub inset: Sides,
pub gap_x: Option<Pixels>,
pub gap_y: Option<Pixels>,
pub absolute: Option<bool>,
pub hidden: Option<bool>,
pub overflow_x: Option<Overflow>,
pub overflow_y: Option<Overflow>,
pub background: Option<ColorSpec>,
pub border_color: Option<ColorSpec>,
pub border_width: Option<Pixels>,
pub radius: Option<Pixels>,
pub text_color: Option<ColorSpec>,
pub font_size: Option<Pixels>,
pub font_bold: Option<bool>,
pub italic: Option<bool>,
pub underline: Option<bool>,
pub text_wrap: Option<bool>,
pub opacity: Option<f32>,
pub extra: Option<Box<StyleExtra>>,
}
macro_rules! refine_options {
($self:ident, $other:ident, $($field:ident),* $(,)?) => {
$( $self.$field = $other.$field.or($self.$field); )*
};
}
pub(crate) use refine_options;
impl Style {
pub fn refine(&mut self, other: &Style) {
refine_options!(
self,
other,
direction,
wrap,
align_items,
align_self,
justify_content,
flex_grow,
flex_shrink,
flex_basis,
width,
height,
min_width,
min_height,
max_width,
max_height,
aspect_ratio,
gap_x,
gap_y,
absolute,
hidden,
overflow_x,
overflow_y,
background,
border_color,
border_width,
radius,
text_color,
font_size,
font_bold,
italic,
underline,
text_wrap,
opacity,
);
match (&mut self.extra, &other.extra) {
(_, None) => {}
(Some(own), Some(refinement)) => own.refine(refinement),
(own @ None, Some(refinement)) => *own = Some(refinement.clone()),
}
self.padding.refine(&other.padding);
self.margin.refine(&other.margin);
self.inset.refine(&other.inset);
}
pub fn extra_mut(&mut self) -> &mut StyleExtra {
self.extra.get_or_insert_with(Default::default)
}
pub fn shadows(&self) -> Option<&Shadows> {
self.extra.as_deref()?.shadow.as_ref()
}
pub fn gradient(&self) -> Option<(f32, ColorSpec)> {
self.extra.as_deref()?.gradient
}
pub fn is_scrollable_y(&self) -> bool {
self.overflow_y == Some(Overflow::Scroll)
}
}