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}