use crate::core::{Pixels, px};
use crate::gpu::{TextAlign, TextTransform};
use crate::view::scale::scale_utilities;
use crate::view::style::{Align, Direction, Justify, Length, Overflow, ShadowPreset, Shadows, Style};
use crate::view::style_box::{
border_sides, border_widths, box_utilities, gradients, opacities, rounded_corners, rounded_sizes,
};
use crate::view::style_extra::{AUTO_ALL, AUTO_BOTTOM, AUTO_LEFT, AUTO_RIGHT, AUTO_TOP};
use crate::view::style_filter::{blurs, filter_utilities};
use crate::view::style_grid::{grid_numbers, grid_utilities};
use crate::view::style_layout::{layout_utilities, z_indexes};
use crate::view::style_macros::{fraction_steps, fractions, scale_methods, scale_steps, setters};
use crate::view::style_text::{line_clamps, text_utilities};
use crate::view::style_transform::{
numbered, percents, transform_utilities, translate_fraction_steps, translate_fractions,
};
use crate::view::theme::ColorSpec;
macro_rules! constant_setters {
($($name:ident => $field:ident = $value:expr;)*) => {
$(
fn $name(mut self) -> Self {
self.style().$field = Some($value);
self
}
)*
};
}
macro_rules! length_setters {
($($name:ident => $field:ident;)*) => {
$(
fn $name(mut self, value: Pixels) -> Self {
self.style().$field = Some(Length::Px(value));
self
}
)*
};
}
pub trait Styled: Sized {
fn style(&mut self) -> &mut Style;
scale_utilities!();
layout_utilities!();
text_utilities!();
box_utilities!();
grid_utilities!();
transform_utilities!();
filter_utilities!();
fn flex(self) -> Self {
self
}
constant_setters! {
flex_row => direction = Direction::Row;
flex_col => direction = Direction::Column;
flex_wrap => wrap = true;
flex_grow => flex_grow = 1.0;
flex_shrink_0 => flex_shrink = 0.0;
items_start => align_items = Align::Start;
items_center => align_items = Align::Center;
items_end => align_items = Align::End;
justify_start => justify_content = Justify::Start;
justify_center => justify_content = Justify::Center;
justify_end => justify_content = Justify::End;
justify_between => justify_content = Justify::SpaceBetween;
absolute => absolute = true;
hidden => hidden = true;
w_full => width = Length::Percent(1.0);
h_full => height = Length::Percent(1.0);
rounded_none => radius = Pixels::ZERO;
rounded_sm => radius = px(2.0);
rounded_md => radius = px(6.0);
rounded_lg => radius = px(8.0);
rounded_xl => radius = px(12.0);
rounded_full => radius = px(9999.0);
border_1 => border_width = px(1.0);
border_2 => border_width = px(2.0);
text_xs => font_size = px(12.0);
text_sm => font_size = px(13.0);
text_base => font_size = px(14.0);
text_lg => font_size = px(18.0);
overflow_y_scroll => overflow_y = Overflow::Scroll;
font_bold => font_bold = true;
italic => italic = true;
underline => underline = true;
whitespace_nowrap => text_wrap = false;
whitespace_normal => text_wrap = true;
text_2xl => font_size = px(24.0);
}
fn flex_1(mut self) -> Self {
let style = self.style();
style.flex_grow = Some(1.0);
style.flex_shrink = Some(1.0);
style.flex_basis = Some(Length::Px(Pixels::ZERO));
self
}
length_setters! {
w => width;
h => height;
min_w => min_width;
min_h => min_height;
max_w => max_width;
max_h => max_height;
}
fn aspect_ratio(mut self, ratio: f32) -> Self {
self.style().aspect_ratio = Some(ratio);
self
}
fn size(self, side: Pixels) -> Self {
self.w(side).h(side)
}
fn size_full(self) -> Self {
self.w_full().h_full()
}
fn px(mut self, value: Pixels) -> Self {
self.style().padding.set_horizontal(value);
self
}
fn py(mut self, value: Pixels) -> Self {
self.style().padding.set_vertical(value);
self
}
fn m(mut self, value: Pixels) -> Self {
self.style().margin.set_all(value);
self
}
fn pl(mut self, value: Pixels) -> Self {
self.style().padding.left = Some(value);
self
}
fn pr(mut self, value: Pixels) -> Self {
self.style().padding.right = Some(value);
self
}
fn pt(mut self, value: Pixels) -> Self {
self.style().padding.top = Some(value);
self
}
fn pb(mut self, value: Pixels) -> Self {
self.style().padding.bottom = Some(value);
self
}
fn mt(mut self, value: Pixels) -> Self {
self.style().margin.top = Some(value);
self
}
fn ml(mut self, value: Pixels) -> Self {
self.style().margin.left = Some(value);
self
}
fn gap(mut self, value: Pixels) -> Self {
let style = self.style();
style.gap_x = Some(value);
style.gap_y = Some(value);
self
}
fn top(mut self, value: Pixels) -> Self {
self.style().inset.top = Some(value);
self
}
fn right(mut self, value: Pixels) -> Self {
self.style().inset.right = Some(value);
self
}
fn bottom(mut self, value: Pixels) -> Self {
self.style().inset.bottom = Some(value);
self
}
fn left(mut self, value: Pixels) -> Self {
self.style().inset.left = Some(value);
self
}
fn shadow(mut self, shadow: impl Into<Shadows>) -> Self {
self.style().extra_mut().shadow = Some(shadow.into());
self
}
fn shadow_color(mut self, color: impl Into<ColorSpec>) -> Self {
let current = self.style().shadows().copied().unwrap_or(ShadowPreset::Md.shadows());
self.style().extra_mut().shadow = Some(current.tinted(color.into()));
self
}
fn glow(self, color: impl Into<ColorSpec>, blur: f32) -> Self {
self.shadow(crate::view::style::BoxShadow::new(0.0, 0.0, blur).color(color))
}
fn border_color(mut self, color: impl Into<ColorSpec>) -> Self {
self.style().border_color = Some(color.into());
self
}
fn bg_gradient(mut self, angle: f32, from: impl Into<ColorSpec>, to: impl Into<ColorSpec>) -> Self {
self.style().background = Some(from.into());
self.style().extra_mut().gradient = Some((angle, to.into()));
self
}
fn bg(mut self, color: impl Into<ColorSpec>) -> Self {
self.style().background = Some(color.into());
self
}
fn text_color(mut self, color: impl Into<ColorSpec>) -> Self {
self.style().text_color = Some(color.into());
self
}
fn text_size(mut self, size: Pixels) -> Self {
self.style().font_size = Some(size);
self
}
fn opacity(mut self, value: f32) -> Self {
self.style().opacity = Some(value);
self
}
fn overflow_hidden(mut self) -> Self {
let style = self.style();
style.overflow_x = Some(Overflow::Hidden);
style.overflow_y = Some(Overflow::Hidden);
self
}
}
impl Styled for Style {
fn style(&mut self) -> &mut Style {
self
}
}