Skip to main content

cotis_defaults/element_configs/
style.rs

1//! Style structs used by [`crate::element_configs::ElementConfig`].
2use crate::colors::{Color, ColorLayer};
3use cotis_utils::math::{Dimensions, Vector2};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7/// Core style helper types such as alignment, padding and clip settings.
8pub mod types;
9use types::*;
10
11/// Sizing enums used by layout integrations.
12pub mod sizing;
13use sizing::*;
14
15/// Fully transparent solid background (`Color::rgba(0, 0, 0, 0)`).
16///
17/// Wrapped as [`ColorLayer::Solid`] for use with [`CotisStyle::background_color`]
18/// and render-command fill fields when the `complex_color` feature is enabled.
19/// Matches the default background applied by [`CotisStyle::default`].
20#[cfg(feature = "complex_color")]
21pub const TRANSPARENT_BACKGROUND: ColorLayer = ColorLayer::Solid(Color::rgba(0.0, 0.0, 0.0, 0.0));
22#[cfg(not(feature = "complex_color"))]
23pub const TRANSPARENT_BACKGROUND: Color = Color::rgba(0.0, 0.0, 0.0, 0.0);
24
25/// Opaque black solid background (`Color::rgba(0, 0, 0, 255)`).
26///
27/// Wrapped as [`ColorLayer::Solid`] for use with [`CotisStyle::background_color`]
28/// and render-command fill fields when the `complex_color` feature is enabled.
29#[cfg(feature = "complex_color")]
30pub const BLACK_BACKGROUND: ColorLayer = ColorLayer::Solid(Color::rgba(0.0, 0.0, 0.0, 255.0));
31#[cfg(not(feature = "complex_color"))]
32pub const BLACK_BACKGROUND: Color = Color::rgba(0.0, 0.0, 0.0, 255.0);
33
34/// Full style payload attached to each configured element.
35#[derive(Debug, Clone)]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[cfg_attr(not(feature = "complex_color"), derive(Copy))]
38pub struct CotisStyle<Sizing> {
39    /// Element sizing behavior used by the layout engine.
40    pub sizing: Sizing,
41    /// Child layout settings (direction, gap, padding, alignment).
42    pub layout: LayoutStyle,
43    /// Element background color.
44    #[cfg(not(feature = "complex_color"))]
45    pub background_color: Color,
46    /// Element background paint (solid/gradient/layered).
47    #[cfg(feature = "complex_color")]
48    pub background_color: ColorLayer,
49    /// Per-corner radius for rounded corners.
50    pub corner_radius: CornerRadiiStyle,
51    /// Optional floating behavior relative to parent bounds.
52    pub floating: Option<FloatingElementStyle>,
53    /// Clip behavior for element content.
54    pub clip: ClipElementConfig,
55    /// Border styling.
56    pub border: BorderElementStyle,
57}
58
59impl Default for CotisStyle<Sizing> {
60    /// Default style for `Sizing` enum-based integrations.
61    fn default() -> Self {
62        Self {
63            sizing: Sizing::DoubleAxis(DoubleAxisSizing {
64                width: AxisSizing::Fit(0.0, f32::MAX),
65                height: AxisSizing::Fit(0.0, f32::MAX),
66            }),
67            layout: Default::default(),
68            #[cfg(not(feature = "complex_color"))]
69            background_color: Color::rgba(0.0, 0.0, 0.0, 0.0),
70            #[cfg(feature = "complex_color")]
71            background_color: ColorLayer::Solid(Color::rgba(0.0, 0.0, 0.0, 0.0)),
72            corner_radius: CornerRadiiStyle {
73                top_left: 0.0,
74                top_right: 0.0,
75                bottom_left: 0.0,
76                bottom_right: 0.0,
77            },
78            floating: None,
79            clip: ClipElementConfig {
80                horizontal: false,
81                vertical: false,
82                child_offset: Default::default(),
83            },
84            border: BorderElementStyle {
85                color: Color::rgba(0.0, 0.0, 0.0, 0.0),
86                width: BorderWidthStyle {
87                    left: 0.0,
88                    right: 0.0,
89                    top: 0.0,
90                    bottom: 0.0,
91                    between_children: 0.0,
92                },
93            },
94        }
95    }
96}
97
98impl Default for CotisStyle<DoubleAxisSizing> {
99    /// Default style for direct `DoubleAxisSizing` integrations.
100    fn default() -> Self {
101        Self {
102            sizing: DoubleAxisSizing {
103                width: AxisSizing::Fit(0.0, f32::MAX),
104                height: AxisSizing::Fit(0.0, f32::MAX),
105            },
106            layout: Default::default(),
107            #[cfg(not(feature = "complex_color"))]
108            background_color: Color::rgba(0.0, 0.0, 0.0, 0.0),
109            #[cfg(feature = "complex_color")]
110            background_color: ColorLayer::Solid(Color::rgba(0.0, 0.0, 0.0, 0.0)),
111            corner_radius: CornerRadiiStyle {
112                top_left: 0.0,
113                top_right: 0.0,
114                bottom_left: 0.0,
115                bottom_right: 0.0,
116            },
117            floating: None,
118            clip: ClipElementConfig {
119                horizontal: false,
120                vertical: false,
121                child_offset: Default::default(),
122            },
123            border: BorderElementStyle {
124                color: Color::rgba(0.0, 0.0, 0.0, 0.0),
125                width: BorderWidthStyle {
126                    left: 0.0,
127                    right: 0.0,
128                    top: 0.0,
129                    bottom: 0.0,
130                    between_children: 0.0,
131                },
132            },
133        }
134    }
135}
136
137/// Defines individual corner radii for an element.
138#[derive(Debug, Clone, Copy, PartialEq)]
139#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
140pub struct CornerRadiiStyle {
141    /// The radius for the top-left corner.
142    pub top_left: f32,
143    /// The radius for the top-right corner.
144    pub top_right: f32,
145    /// The radius for the bottom-left corner.
146    pub bottom_left: f32,
147    /// The radius for the bottom-right corner.
148    pub bottom_right: f32,
149}
150
151/// Border style payload.
152#[derive(Debug, Copy, Clone, PartialEq)]
153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
154pub struct BorderElementStyle {
155    /// Border color.
156    pub color: Color,
157    /// Per-side border widths.
158    pub width: BorderWidthStyle,
159}
160
161/// Border width values for each side.
162#[derive(Debug, Copy, Clone, PartialEq)]
163#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
164pub struct BorderWidthStyle {
165    /// Left border width.
166    pub left: f32,
167    /// Right border width.
168    pub right: f32,
169    /// Top border width.
170    pub top: f32,
171    /// Bottom border width.
172    pub bottom: f32,
173    /// Width used between sibling children.
174    pub between_children: f32,
175}
176
177/// Floating behavior for overlays/tooltips/popups.
178#[derive(Debug, Clone, Copy, PartialEq)]
179#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
180pub struct FloatingElementStyle {
181    /// Position offset relative to attachment point.
182    pub offset: Vector2,
183    /// Additional expansion of floating bounds.
184    pub expand: Dimensions,
185    /// Z-order offset used during rendering.
186    pub z_index: i16,
187    /// Anchor point on the parent.
188    pub attach_point: FloatingAttachPointType,
189    /// Pointer capture behavior.
190    pub pointer_capture_mode: PointerCaptureMode,
191}
192
193/// Layout styling for children.
194#[derive(Debug, Copy, Clone)]
195#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
196pub struct LayoutStyle {
197    /// Inner padding around child layout area.
198    pub padding: Padding,
199    /// Gap inserted between children.
200    pub child_gap: f32,
201    /// Child alignment along X and Y.
202    pub child_alignment: Alignment,
203    /// Primary direction used to place children.
204    pub layout_direction: LayoutDirection,
205    /// Experimental child-wrapping toggle.
206    ///
207    /// This field is feature-gated and currently not fully wired in all layout
208    /// integrations.
209    #[cfg(feature = "child_wrapping")]
210    pub child_wrapping: bool,
211}