mirror of
https://github.com/danbulant/cushy
synced 2026-05-24 12:28:23 +00:00
133 lines
6.2 KiB
Rust
133 lines
6.2 KiB
Rust
//! All style components supported by the built-in widgets.
|
|
|
|
use kludgine::figures::units::Lp;
|
|
use kludgine::Color;
|
|
|
|
use crate::animation::easings::{EaseInOutQuadradic, EaseInQuadradic, EaseOutQuadradic};
|
|
use crate::animation::EasingFunction;
|
|
use crate::styles::{Dimension, FocusableWidgets, VisualOrder};
|
|
|
|
/// Defines a set of style components for Gooey.
|
|
///
|
|
/// These macros implement [`NamedComponent`](crate::styles::NamedComponent) and
|
|
/// [`ComponentDefinition`](crate::styles::ComponentDefinition) for each entry
|
|
/// defined. The syntax is:
|
|
///
|
|
/// ```rust
|
|
/// use gooey::define_components;
|
|
/// use gooey::styles::Dimension;
|
|
/// use gooey::styles::components::{SurfaceColor, TextColor};
|
|
/// use gooey::kludgine::Color;
|
|
///
|
|
/// define_components! {
|
|
/// GroupName {
|
|
/// /// This is the documentation for example component. It has a default value of `Dimension::ZERO`.
|
|
/// ExampleComponent(Dimension, "example_component", Dimension::ZERO)
|
|
/// /// This component whose default value is a color from the current theme.
|
|
/// ThemedComponent(Color, "themed_component", .primary.color)
|
|
/// /// This component is a color whose default value is the currently defined `TextColor`.
|
|
/// DependentComponent(Color, "dependent_component", @TextColor)
|
|
/// /// This component defaults to picking a contrasting color between `TextColor` and `SurfaceColor`
|
|
/// ContrastingColor(Color, "contrasting_color", contrasting!(ThemedComponent, TextColor, SurfaceColor))
|
|
/// /// This component shows how to use a closure for nearly infinite flexibility in computing the default value.
|
|
/// ClosureDefaultComponent(Color, "closure_component", |context| context.get(&TextColor))
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! define_components {
|
|
($($widget:ident { $($(#$doc:tt)* $component:ident($type:ty, $name:expr, $($default:tt)*))* })*) => {$($(
|
|
$(#$doc)*
|
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
|
pub struct $component;
|
|
|
|
const _: () = {
|
|
use $crate::styles::{ComponentDefinition, ComponentName, NamedComponent};
|
|
use $crate::context::WidgetContext;
|
|
use $crate::Lazy;
|
|
use ::std::borrow::Cow;
|
|
|
|
impl NamedComponent for $component {
|
|
fn name(&self) -> Cow<'_, ComponentName> {
|
|
static NAME: Lazy<ComponentName> = Lazy::new(|| ComponentName::new(stringify!($widget), $name));
|
|
Cow::Borrowed(&*NAME)
|
|
}
|
|
}
|
|
|
|
impl ComponentDefinition for $component {
|
|
type ComponentType = $type;
|
|
|
|
define_components!($type, $($default)*);
|
|
}
|
|
};
|
|
|
|
)*)*};
|
|
($type:ty, . $($path:tt)*) => {
|
|
define_components!($type, |context| context.theme().$($path)*);
|
|
};
|
|
($type:ty, |$context:ident| $($expr:tt)*) => {
|
|
fn default_value(&self, $context: &WidgetContext<'_, '_>) -> $type {
|
|
$($expr)*
|
|
}
|
|
};
|
|
($type:ty, @$path:path) => {
|
|
define_components!($type, |context| context.get(&$path));
|
|
};
|
|
($type:ty, contrasting!($bg:ident, $($fg:ident),+ $(,)?)) => {
|
|
define_components!($type, |context| {
|
|
use $crate::styles::ColorExt;
|
|
context.get(&$bg).most_contrasting(&[
|
|
$(context.get(&$fg)),+
|
|
])
|
|
});
|
|
};
|
|
($type:ty, $($expr:tt)*) => {
|
|
define_components!($type, |_context| $($expr)*);
|
|
};
|
|
}
|
|
|
|
define_components! {
|
|
Global {
|
|
/// The [`Dimension`] to use as the size to render text.
|
|
TextSize(Dimension, "text_size", Dimension::Lp(Lp::points(12)))
|
|
/// The [`Dimension`] to use to space multiple lines of text.
|
|
LineHeight(Dimension,"line_height",Dimension::Lp(Lp::points(14)))
|
|
/// The [`Color`] of the surface for the user interface to draw upon.
|
|
SurfaceColor(Color, "surface_color", .surface.color)
|
|
/// The [`Color`] to use when rendering text.
|
|
TextColor(Color, "text_color", .surface.on_color)
|
|
/// A [`Color`] to be used as a highlight color.
|
|
HighlightColor(Color,"highlight_color",.primary.color.with_alpha(128))
|
|
/// Intrinsic, uniform padding for a widget.
|
|
///
|
|
/// This component is opt-in and does not automatically work for all widgets.
|
|
IntrinsicPadding(Dimension, "padding", Dimension::Lp(Lp::points(5)))
|
|
/// The [`EasingFunction`] to apply to animations that have no inherent
|
|
/// directionality.
|
|
Easing(EasingFunction, "Easing", EasingFunction::from(EaseInOutQuadradic))
|
|
/// The [`EasingFunction`] to apply to animations that transition a value from
|
|
/// "nothing" to "something". For example, if an widget is animating a color's
|
|
/// alpha channel towards opaqueness, it would query for this style component.
|
|
/// Otherwise, it would use [`EasingOut`].
|
|
EasingIn(EasingFunction, "easing_out", EasingFunction::from(EaseInQuadradic))
|
|
/// The [`EasingFunction`] to apply to animations that transition a value from
|
|
/// "something" to "nothing". For example, if an widget is animating a color's
|
|
/// alpha channel towards transparency, it would query for this style component.
|
|
/// Otherwise, it would use [`EasingIn`].
|
|
EasingOut(EasingFunction, "easing_out", EasingFunction::from(EaseOutQuadradic))
|
|
/// The [`VisualOrder`] strategy to use when laying out content.
|
|
LayoutOrder(VisualOrder, "visual_order", VisualOrder::left_to_right())
|
|
/// The set of controls to allow focusing via tab key and initial focus
|
|
/// selection.
|
|
AutoFocusableControls(FocusableWidgets, "focus", FocusableWidgets::default())
|
|
/// A [`Color`] to be used as the background color of a widget.
|
|
WidgetBackground(Color, "widget_backgrond_color", Color::CLEAR_WHITE)
|
|
/// A [`Color`] to be used as an outline color.
|
|
OutlineColor(Color, "outline_color", .surface.outline)
|
|
/// A [`Color`] to be used as an outline color.
|
|
DisabledOutlineColor(Color, "disabled_outline_color", .surface.outline_variant)
|
|
/// A [`Color`] to be used as a background color for widgets that render an
|
|
/// opaque background.
|
|
OpaqueWidgetColor(Color, "opaque_color", .surface.opaque_widget)
|
|
}
|
|
}
|