polyhorn_ui/styles/
view.rs

1use std::fmt::Debug;
2use strum_macros::EnumString;
3
4use super::{Align, FlexDirection, Inherited, Justify, Position, Transform};
5use crate::color::Color;
6use crate::geometry::{ByCorner, ByDirection, ByEdge, Dimension, Size};
7use crate::layout::LayoutDirection;
8
9/// Controls the style that is used to draw a border.
10#[derive(Copy, Clone, Debug, Eq, PartialEq, EnumString)]
11pub enum BorderStyle {
12    /// Draws a solid line.
13    #[strum(serialize = "solid")]
14    Solid,
15
16    /// Draws a dashed line. The gap and dash lengths, as well as the starting
17    /// position of the pattern are currently platform dependent and cannot be
18    /// customized.
19    #[strum(serialize = "dashed")]
20    Dashed,
21
22    /// Draws a dotted line. The starting position of the pattern is currently
23    /// platform dependent and cannot be customized.
24    #[strum(serialize = "dotted")]
25    Dotted,
26}
27
28/// Controls the appearance of a border shown around the dimensions of a view.
29#[derive(Copy, Clone, Debug, PartialEq)]
30pub struct Border {
31    /// Controls the thickness of a border rendered around a view. If the
32    /// dimension resolves to either undefined or auto, no border will be shown.
33    /// If the dimension is a percentage, it will be resolved relative to the
34    /// width of the view's bounding box. Note: even if this is a vertical
35    /// border, it will still be resolved relative to the width.
36    pub width: Dimension<f32>,
37
38    /// This is the style that is used to draw the border.
39    pub style: BorderStyle,
40
41    /// This is the color that is used to draw the border. If the color is
42    /// translucent (i.e. the alpha channel is not 1.0), the border color will
43    /// be composited over the background color of the view (if present) using
44    /// gamma-correct color blending. If the view itself is translucent or
45    /// transparent, the platform's own display compositor might use
46    /// non-gamma-correct color blending when compositing this view on top of
47    /// any underlying views.
48    pub color: Color,
49}
50
51impl Default for Border {
52    fn default() -> Self {
53        Border {
54            width: Dimension::Undefined,
55            style: BorderStyle::Solid,
56            color: Color::transparent(),
57        }
58    }
59}
60
61/// Controls the way dimensions of views are adjusted when their content
62/// overflows their original boundaries.
63#[derive(Copy, Clone, Debug, Eq, PartialEq, EnumString)]
64pub enum Overflow {
65    /// If overflow is visible, views are adjusted to accommodate the larger
66    /// content size.
67    #[strum(serialize = "visible")]
68    Visible,
69
70    /// If overflow is hidden, views are not adjusted.
71    #[strum(serialize = "hidden")]
72    Hidden,
73
74    /// If overflow is scroll, the view itself is not adjusted, but its
75    /// dimensions are increased internally in the layout algorithm to account
76    /// for the fact that it can be scrolled.
77    #[strum(serialize = "scroll")]
78    Scroll,
79}
80
81impl Default for Overflow {
82    fn default() -> Self {
83        Overflow::Visible
84    }
85}
86
87/// Controls the visibility of a view.
88#[derive(Copy, Clone, Debug, Eq, PartialEq, EnumString)]
89pub enum Visibility {
90    /// If visible, the view is both included in layout calculations and
91    /// rendered to the screen, even if its opacity is zero.
92    #[strum(serialize = "visible")]
93    Visible,
94
95    /// If hidden, the view is included in layout calculations, but is not
96    /// rendered to the screen, regardless of its opacity.
97    #[strum(serialize = "hidden")]
98    Hidden,
99}
100
101impl Default for Visibility {
102    fn default() -> Self {
103        Visibility::Visible
104    }
105}
106
107/// Controls the appearance of a View.
108#[derive(Copy, Clone, Debug, PartialEq)]
109pub struct ViewStyle {
110    /// This field determines whether this view should be included in
111    /// calculating the layout of descendant views of the ancestor of this view.
112    pub position: Position,
113
114    /// This field determines the direction in which descendant views are layed
115    /// out.
116    pub direction: Inherited<LayoutDirection>,
117
118    /// This is the size of this view.
119    pub size: Size<Dimension<f32>>,
120
121    /// This is the minimum size of this view. This must not be greater than the
122    /// `size` field if both fields are present and contain absolute values for
123    /// one of both dimensions.
124    pub min_size: Size<Dimension<f32>>,
125
126    /// This is the maximum size of this view. This must not be less than the
127    /// `size` field if both fields are present and contain absolute values for
128    /// one of both dimensions.
129    pub max_size: Size<Dimension<f32>>,
130
131    /// This is the main axis along which the flexbox algorithm operates.
132    pub flex_direction: FlexDirection,
133
134    /// This is the alignment of items along the main axis of the flexbox. The
135    /// default value for this property is `Align::Stretch` which will resize
136    /// descendant views along the cross axis to match the relevant dimension of
137    /// this view.
138    pub align_items: Align,
139
140    /// This property controls how the flexbox algorithm justifies content along
141    /// the cross axis of the flexbox. The default value for this property is
142    /// `Justify::FlexStart` which will stick the content to the start of the
143    /// main axis.
144    pub justify_content: Justify,
145
146    /// This property controls the margin that is used outside this view.
147    pub margin: ByEdge<Dimension<f32>>,
148
149    /// This property controls the border that is rendered around this view.
150    pub border: ByEdge<Border>,
151
152    /// This property controls the padding that is used inside this view.
153    pub padding: ByEdge<Dimension<f32>>,
154
155    /// This is the background color of this view. The default color is
156    /// transparent. This property does not affect the layout of this view, its
157    /// siblings or its descendants.
158    pub background_color: Color,
159
160    /// If not 0.0, this field controls the corner radius of this view. This
161    /// property does not affect the layout of this view, its siblings or its
162    /// descendants.
163    pub border_radius: ByCorner<ByDirection<Dimension<f32>>>,
164
165    /// If neither 1.0 nor 0.0, this property contains the weight of this layer
166    /// during composition. If 0.0, the layer is not composited at all, and if
167    /// 1.0, it is composited over any underlying layers. The default value is
168    /// 1.0.
169    pub opacity: f32,
170
171    /// Applies a transformation to the view during compositing. This property
172    /// does not affect the layout of this view, its siblings or descendants.
173    pub transform: [Transform<f32>; 8],
174
175    /// Controls the way dimensions of views are adjusted when their content
176    /// overflows their original boundaries.
177    pub overflow: Overflow,
178
179    /// Controls the visibility of this view. Invisible views are still included
180    /// in layout calculations, but are not actually rendered to the screen.
181    /// This can be used as a performance optimization. Generally, it is more
182    /// efficient to set a view's visibility to hidden than to set its opacity
183    /// to zero.
184    pub visibility: Visibility,
185}
186
187impl Default for ViewStyle {
188    fn default() -> Self {
189        ViewStyle {
190            position: Position::Relative(Default::default()),
191            direction: Inherited::Inherited,
192            min_size: Size::new(Dimension::Auto, Dimension::Auto),
193            max_size: Size::new(Dimension::Auto, Dimension::Auto),
194            flex_direction: FlexDirection::Column,
195            align_items: Align::Stretch,
196            justify_content: Justify::FlexStart,
197            size: Size::new(Dimension::Auto, Dimension::Auto),
198            background_color: Color::transparent(),
199            margin: Default::default(),
200            border: Default::default(),
201            border_radius: Default::default(),
202            padding: Default::default(),
203            opacity: 1.0,
204            transform: Default::default(),
205            overflow: Overflow::Visible,
206            visibility: Visibility::Visible,
207        }
208    }
209}