use azul_core::dom::{Dom, IdOrClass, IdOrClass::Class, IdOrClassVec};
use azul_css::dynamic_selector::{CssPropertyWithConditions, CssPropertyWithConditionsVec};
use azul_css::{
props::{
basic::{color::ColorU, *},
layout::{LayoutAlignSelf, LayoutFlexGrow, LayoutWidth, LayoutHeight},
property::{CssProperty, *},
style::{LayoutBorderTopWidth, LayoutBorderBottomWidth, LayoutBorderLeftWidth, LayoutBorderRightWidth, StyleBorderTopStyle, BorderStyle, StyleBorderBottomStyle, StyleBorderLeftStyle, StyleBorderRightStyle, StyleBorderTopColor, StyleBorderBottomColor, StyleBorderLeftColor, StyleBorderRightColor, StyleBorderTopLeftRadius, StyleBorderTopRightRadius, StyleBorderBottomLeftRadius, StyleBorderBottomRightRadius},
},
AzString,
};
static SPINNER_CLASS: &[IdOrClass] = &[Class(AzString::from_const_str("__azul-native-spinner"))];
const DEFAULT_SIZE: isize = 24;
const DEFAULT_TRACK_COLOR: ColorU = ColorU { r: 208, g: 212, b: 217, a: 255 };
const DEFAULT_ACCENT_COLOR: ColorU = ColorU { r: 13, g: 110, b: 253, a: 255 };
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(C)]
pub struct Spinner {
pub size: isize,
pub color: ColorU,
pub track_color: ColorU,
pub spinner_style: CssPropertyWithConditionsVec,
}
fn build_spinner_style(size: isize, color: ColorU, track_color: ColorU) -> CssPropertyWithConditionsVec {
let border_width = (size / 8).max(2);
let radius = size / 2;
CssPropertyWithConditionsVec::from_vec(alloc::vec![
CssPropertyWithConditions::simple(CssProperty::align_self(LayoutAlignSelf::Start)),
CssPropertyWithConditions::simple(CssProperty::const_flex_grow(LayoutFlexGrow::const_new(
0,
))),
CssPropertyWithConditions::simple(CssProperty::const_width(LayoutWidth::const_px(size))),
CssPropertyWithConditions::simple(CssProperty::const_height(LayoutHeight::const_px(size))),
CssPropertyWithConditions::simple(CssProperty::const_border_top_width(
LayoutBorderTopWidth::const_px(border_width),
)),
CssPropertyWithConditions::simple(CssProperty::const_border_bottom_width(
LayoutBorderBottomWidth::const_px(border_width),
)),
CssPropertyWithConditions::simple(CssProperty::const_border_left_width(
LayoutBorderLeftWidth::const_px(border_width),
)),
CssPropertyWithConditions::simple(CssProperty::const_border_right_width(
LayoutBorderRightWidth::const_px(border_width),
)),
CssPropertyWithConditions::simple(CssProperty::const_border_top_style(StyleBorderTopStyle {
inner: BorderStyle::Solid,
})),
CssPropertyWithConditions::simple(CssProperty::const_border_bottom_style(
StyleBorderBottomStyle {
inner: BorderStyle::Solid,
},
)),
CssPropertyWithConditions::simple(CssProperty::const_border_left_style(StyleBorderLeftStyle {
inner: BorderStyle::Solid,
})),
CssPropertyWithConditions::simple(CssProperty::const_border_right_style(
StyleBorderRightStyle {
inner: BorderStyle::Solid,
},
)),
CssPropertyWithConditions::simple(CssProperty::const_border_top_color(StyleBorderTopColor {
inner: color,
})),
CssPropertyWithConditions::simple(CssProperty::const_border_bottom_color(
StyleBorderBottomColor { inner: track_color },
)),
CssPropertyWithConditions::simple(CssProperty::const_border_left_color(StyleBorderLeftColor {
inner: track_color,
})),
CssPropertyWithConditions::simple(CssProperty::const_border_right_color(
StyleBorderRightColor { inner: track_color },
)),
CssPropertyWithConditions::simple(CssProperty::const_border_top_left_radius(
StyleBorderTopLeftRadius::const_px(radius),
)),
CssPropertyWithConditions::simple(CssProperty::const_border_top_right_radius(
StyleBorderTopRightRadius::const_px(radius),
)),
CssPropertyWithConditions::simple(CssProperty::const_border_bottom_left_radius(
StyleBorderBottomLeftRadius::const_px(radius),
)),
CssPropertyWithConditions::simple(CssProperty::const_border_bottom_right_radius(
StyleBorderBottomRightRadius::const_px(radius),
)),
])
}
impl Spinner {
#[inline]
#[must_use] pub fn create() -> Self {
Self::with_size(DEFAULT_SIZE)
}
#[inline]
#[must_use] pub fn with_size(size: isize) -> Self {
Self {
size,
color: DEFAULT_ACCENT_COLOR,
track_color: DEFAULT_TRACK_COLOR,
spinner_style: build_spinner_style(size, DEFAULT_ACCENT_COLOR, DEFAULT_TRACK_COLOR),
}
}
#[inline]
pub fn set_size(&mut self, size: isize) {
self.size = size;
self.spinner_style = build_spinner_style(size, self.color, self.track_color);
}
#[inline]
#[must_use] pub fn with_spinner_size(mut self, size: isize) -> Self {
self.set_size(size);
self
}
#[inline]
pub fn set_color(&mut self, color: ColorU) {
self.color = color;
self.spinner_style = build_spinner_style(self.size, color, self.track_color);
}
#[inline]
#[must_use] pub fn with_color(mut self, color: ColorU) -> Self {
self.set_color(color);
self
}
#[inline]
pub fn set_track_color(&mut self, track_color: ColorU) {
self.track_color = track_color;
self.spinner_style = build_spinner_style(self.size, self.color, track_color);
}
#[inline]
#[must_use] pub fn with_track_color(mut self, track_color: ColorU) -> Self {
self.set_track_color(track_color);
self
}
#[inline]
#[must_use] pub fn swap_with_default(&mut self) -> Self {
let mut s = Self::create();
core::mem::swap(&mut s, self);
s
}
#[inline]
#[must_use] pub fn dom(self) -> Dom {
Dom::create_div()
.with_ids_and_classes(IdOrClassVec::from_const_slice(SPINNER_CLASS))
.with_css_props(self.spinner_style)
}
}
impl Default for Spinner {
fn default() -> Self {
Self::create()
}
}
impl From<Spinner> for Dom {
fn from(s: Spinner) -> Self {
s.dom()
}
}