tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 1082HTML 1014Markdown 12TOML 83222 Sutichaykuna

⎇ 0.3.x src/style_helpers.rs Rust · 549 siq'ikuna · 19.9 KB Ñawpa willay Pi imata llamkarqan ch'uya

evenly_sized_tracks - fix simple compile error (#643) ea2beedd0 · DavidM603 ·

1//! Helper functions which it make it easier to create instances of types in the `style` and `geometry` modules.
2use crate::{
3    geometry::{Line, Point, Rect, Size},
4    style::LengthPercentage,
5};
6
7#[cfg(feature = "grid")]
8use crate::{
9    geometry::MinMax,
10    style::{
11        GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction, NonRepeatedTrackSizingFunction,
12        TrackSizingFunction,
13    },
14    sys::Vec,
15};
16#[cfg(feature = "grid")]
17use core::fmt::Debug;
18
19/// Returns an auto-repeated track definition
20#[cfg(feature = "grid")]
21pub fn repeat<Input>(repetition_kind: Input, track_list: Vec<NonRepeatedTrackSizingFunction>) -> TrackSizingFunction
22where
23    Input: TryInto<GridTrackRepetition>,
24    <Input as TryInto<GridTrackRepetition>>::Error: Debug,
25{
26    TrackSizingFunction::Repeat(repetition_kind.try_into().unwrap(), track_list)
27}
28
29#[cfg(feature = "grid")]
30#[cfg(test)]
31mod repeat_fn_tests {
32    use super::repeat;
33    use crate::style::{GridTrackRepetition, NonRepeatedTrackSizingFunction, TrackSizingFunction};
34
35    const TEST_VEC: Vec<NonRepeatedTrackSizingFunction> = Vec::new();
36
37    #[test]
38    fn test_repeat_u16() {
39        assert_eq!(repeat(123, TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::Count(123), TEST_VEC));
40    }
41
42    #[test]
43    fn test_repeat_auto_fit_str() {
44        assert_eq!(repeat("auto-fit", TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::AutoFit, TEST_VEC));
45    }
46
47    #[test]
48    fn test_repeat_auto_fill_str() {
49        assert_eq!(repeat("auto-fill", TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::AutoFill, TEST_VEC));
50    }
51}
52
53#[cfg(feature = "grid")]
54/// Returns a grid template containing `count` evenly sized tracks
55pub fn evenly_sized_tracks(count: u16) -> Vec<TrackSizingFunction> {
56    use crate::sys::new_vec_with_capacity;
57    let mut repeated_tracks = new_vec_with_capacity(1);
58    repeated_tracks.push(flex(1.0f32));
59    let mut tracks = new_vec_with_capacity(1);
60    tracks.push(repeat(count, repeated_tracks));
61    tracks
62}
63
64/// Specifies a grid line to place a grid item between in CSS Grid Line coordinates:
65///  - Positive indicies count upwards from the start (top or left) of the explicit grid
66///  - Negative indicies count downwards from the end (bottom or right) of the explicit grid
67///  - ZERO IS INVALID index, and will be treated as a GridPlacement::Auto.
68pub fn line<T: TaffyGridLine>(index: i16) -> T {
69    T::from_line_index(index)
70}
71/// Trait to abstract over grid line values
72pub trait TaffyGridLine {
73    /// Converts an i16 into Self
74    fn from_line_index(index: i16) -> Self;
75}
76
77/// Returns a GridPlacement::Span
78pub fn span<T: TaffyGridSpan>(span: u16) -> T {
79    T::from_span(span)
80}
81/// Trait to abstract over grid span values
82pub trait TaffyGridSpan {
83    /// Converts an iu6 into Self
84    fn from_span(span: u16) -> Self;
85}
86
87/// Returns a MinMax with min value of min and max value of max
88#[cfg(feature = "grid")]
89pub fn minmax<Output>(min: MinTrackSizingFunction, max: MaxTrackSizingFunction) -> Output
90where
91    Output: From<MinMax<MinTrackSizingFunction, MaxTrackSizingFunction>>,
92{
93    MinMax { min, max }.into()
94}
95
96/// Shorthand for minmax(0, Nfr). Probably what you want if you want exactly evenly sized tracks.
97#[cfg(feature = "grid")]
98pub fn flex<Input, Output>(flex_fraction: Input) -> Output
99where
100    Input: Into<f32> + Copy,
101    Output: From<MinMax<MinTrackSizingFunction, MaxTrackSizingFunction>>,
102{
103    MinMax { min: zero(), max: fr(flex_fraction.into()) }.into()
104}
105
106/// Returns the zero value for that type
107pub const fn zero<T: TaffyZero>() -> T {
108    T::ZERO
109}
110
111/// Trait to abstract over zero values
112pub trait TaffyZero {
113    /// The zero value for type implementing TaffyZero
114    const ZERO: Self;
115}
116impl TaffyZero for f32 {
117    const ZERO: f32 = 0.0;
118}
119impl<T: TaffyZero> TaffyZero for Option<T> {
120    const ZERO: Option<T> = Some(T::ZERO);
121}
122impl<T: TaffyZero> TaffyZero for Point<T> {
123    const ZERO: Point<T> = Point { x: T::ZERO, y: T::ZERO };
124}
125impl<T: TaffyZero> Point<T> {
126    /// Returns a Point where both the x and y values are the zero value of the contained type
127    /// (e.g. 0.0, Some(0.0), or Dimension::Points(0.0))
128    pub const fn zero() -> Self {
129        zero::<Self>()
130    }
131}
132impl<T: TaffyZero> TaffyZero for Line<T> {
133    const ZERO: Line<T> = Line { start: T::ZERO, end: T::ZERO };
134}
135impl<T: TaffyZero> Line<T> {
136    /// Returns a Line where both the start and end values are the zero value of the contained type
137    /// (e.g. 0.0, Some(0.0), or Dimension::Points(0.0))
138    pub const fn zero() -> Self {
139        zero::<Self>()
140    }
141}
142impl<T: TaffyZero> TaffyZero for Size<T> {
143    const ZERO: Size<T> = Size { width: T::ZERO, height: T::ZERO };
144}
145impl<T: TaffyZero> Size<T> {
146    /// Returns a Size where both the width and height values are the zero value of the contained type
147    /// (e.g. 0.0, Some(0.0), or Dimension::Points(0.0))
148    pub const fn zero() -> Self {
149        zero::<Self>()
150    }
151}
152impl<T: TaffyZero> TaffyZero for Rect<T> {
153    const ZERO: Rect<T> = Rect { left: T::ZERO, right: T::ZERO, top: T::ZERO, bottom: T::ZERO };
154}
155impl<T: TaffyZero> Rect<T> {
156    /// Returns a Size where the left, right, top, and bottom values are all the zero value of the contained type
157    /// (e.g. 0.0, Some(0.0), or Dimension::Points(0.0))
158    pub const fn zero() -> Self {
159        zero::<Self>()
160    }
161}
162
163/// Returns the auto value for that type
164pub const fn auto<T: TaffyAuto>() -> T {
165    T::AUTO
166}
167
168/// Trait to abstract over auto values
169pub trait TaffyAuto {
170    /// The auto value for type implementing TaffyZero
171    const AUTO: Self;
172}
173impl<T: TaffyAuto> TaffyAuto for Option<T> {
174    const AUTO: Option<T> = Some(T::AUTO);
175}
176impl<T: TaffyAuto> TaffyAuto for Point<T> {
177    const AUTO: Point<T> = Point { x: T::AUTO, y: T::AUTO };
178}
179impl<T: TaffyAuto> Point<T> {
180    /// Returns a Point where both the x and y values are the auto value of the contained type
181    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
182    pub const fn auto() -> Self {
183        auto::<Self>()
184    }
185}
186impl<T: TaffyAuto> TaffyAuto for Line<T> {
187    const AUTO: Line<T> = Line { start: T::AUTO, end: T::AUTO };
188}
189impl<T: TaffyAuto> Line<T> {
190    /// Returns a Line where both the start and end values are the auto value of the contained type
191    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
192    pub const fn auto() -> Self {
193        auto::<Self>()
194    }
195}
196impl<T: TaffyAuto> TaffyAuto for Size<T> {
197    const AUTO: Size<T> = Size { width: T::AUTO, height: T::AUTO };
198}
199impl<T: TaffyAuto> Size<T> {
200    /// Returns a Size where both the width and height values are the auto value of the contained type
201    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
202    pub const fn auto() -> Self {
203        auto::<Self>()
204    }
205}
206impl<T: TaffyAuto> TaffyAuto for Rect<T> {
207    const AUTO: Rect<T> = Rect { left: T::AUTO, right: T::AUTO, top: T::AUTO, bottom: T::AUTO };
208}
209impl<T: TaffyAuto> Rect<T> {
210    /// Returns a Size where the left, right, top, and bottom values are all the auto value of the contained type
211    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
212    pub const fn auto() -> Self {
213        auto::<Self>()
214    }
215}
216
217/// Returns the auto value for that type
218pub const fn min_content<T: TaffyMinContent>() -> T {
219    T::MIN_CONTENT
220}
221
222/// Trait to abstract over min_content values
223pub trait TaffyMinContent {
224    /// The min_content value for type implementing TaffyZero
225    const MIN_CONTENT: Self;
226}
227impl<T: TaffyMinContent> TaffyMinContent for Option<T> {
228    const MIN_CONTENT: Option<T> = Some(T::MIN_CONTENT);
229}
230impl<T: TaffyMinContent> TaffyMinContent for Point<T> {
231    const MIN_CONTENT: Point<T> = Point { x: T::MIN_CONTENT, y: T::MIN_CONTENT };
232}
233impl<T: TaffyMinContent> Point<T> {
234    /// Returns a Point where both the x and y values are the min_content value of the contained type
235    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
236    pub const fn min_content() -> Self {
237        min_content::<Self>()
238    }
239}
240impl<T: TaffyMinContent> TaffyMinContent for Line<T> {
241    const MIN_CONTENT: Line<T> = Line { start: T::MIN_CONTENT, end: T::MIN_CONTENT };
242}
243impl<T: TaffyMinContent> Line<T> {
244    /// Returns a Line where both the start and end values are the min_content value of the contained type
245    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
246    pub const fn min_content() -> Self {
247        min_content::<Self>()
248    }
249}
250impl<T: TaffyMinContent> TaffyMinContent for Size<T> {
251    const MIN_CONTENT: Size<T> = Size { width: T::MIN_CONTENT, height: T::MIN_CONTENT };
252}
253impl<T: TaffyMinContent> Size<T> {
254    /// Returns a Size where both the width and height values are the min_content value of the contained type
255    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
256    pub const fn min_content() -> Self {
257        min_content::<Self>()
258    }
259}
260impl<T: TaffyMinContent> TaffyMinContent for Rect<T> {
261    const MIN_CONTENT: Rect<T> =
262        Rect { left: T::MIN_CONTENT, right: T::MIN_CONTENT, top: T::MIN_CONTENT, bottom: T::MIN_CONTENT };
263}
264impl<T: TaffyMinContent> Rect<T> {
265    /// Returns a Size where the left, right, top, and bottom values are all the min_content value of the contained type
266    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
267    pub const fn min_content() -> Self {
268        min_content::<Self>()
269    }
270}
271
272/// Returns the auto value for that type
273pub const fn max_content<T: TaffyMaxContent>() -> T {
274    T::MAX_CONTENT
275}
276
277/// Trait to abstract over max_content values
278pub trait TaffyMaxContent {
279    /// The max_content value for type implementing TaffyZero
280    const MAX_CONTENT: Self;
281}
282impl<T: TaffyMaxContent> TaffyMaxContent for Option<T> {
283    const MAX_CONTENT: Option<T> = Some(T::MAX_CONTENT);
284}
285impl<T: TaffyMaxContent> TaffyMaxContent for Point<T> {
286    const MAX_CONTENT: Point<T> = Point { x: T::MAX_CONTENT, y: T::MAX_CONTENT };
287}
288impl<T: TaffyMaxContent> Point<T> {
289    /// Returns a Point where both the x and y values are the max_content value of the contained type
290    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
291    pub const fn max_content() -> Self {
292        max_content::<Self>()
293    }
294}
295impl<T: TaffyMaxContent> TaffyMaxContent for Line<T> {
296    const MAX_CONTENT: Line<T> = Line { start: T::MAX_CONTENT, end: T::MAX_CONTENT };
297}
298impl<T: TaffyMaxContent> Line<T> {
299    /// Returns a Line where both the start and end values are the max_content value of the contained type
300    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
301    pub const fn max_content() -> Self {
302        max_content::<Self>()
303    }
304}
305impl<T: TaffyMaxContent> TaffyMaxContent for Size<T> {
306    const MAX_CONTENT: Size<T> = Size { width: T::MAX_CONTENT, height: T::MAX_CONTENT };
307}
308impl<T: TaffyMaxContent> Size<T> {
309    /// Returns a Size where both the width and height values are the max_content value of the contained type
310    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
311    pub const fn max_content() -> Self {
312        max_content::<Self>()
313    }
314}
315impl<T: TaffyMaxContent> TaffyMaxContent for Rect<T> {
316    const MAX_CONTENT: Rect<T> =
317        Rect { left: T::MAX_CONTENT, right: T::MAX_CONTENT, top: T::MAX_CONTENT, bottom: T::MAX_CONTENT };
318}
319impl<T: TaffyMaxContent> Rect<T> {
320    /// Returns a Size where the left, right, top, and bottom values are all the max_content value of the contained type
321    /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
322    pub const fn max_content() -> Self {
323        max_content::<Self>()
324    }
325}
326
327/// Returns a value of the inferred type which represent a constant of points
328pub fn fit_content<T: TaffyFitContent>(argument: LengthPercentage) -> T {
329    T::fit_content(argument)
330}
331
332/// Trait to create constant points values from plain numbers
333pub trait TaffyFitContent {
334    /// Converts into a LengthPercentage into Self
335    fn fit_content(argument: LengthPercentage) -> Self;
336}
337impl<T: TaffyFitContent> TaffyFitContent for Point<T> {
338    fn fit_content(argument: LengthPercentage) -> Self {
339        Point { x: T::fit_content(argument), y: T::fit_content(argument) }
340    }
341}
342impl<T: TaffyFitContent> Point<T> {
343    /// Returns a Point where both the x and y values are the constant points value of the contained type
344    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
345    pub fn fit_content(argument: LengthPercentage) -> Self {
346        fit_content(argument)
347    }
348}
349impl<T: TaffyFitContent> TaffyFitContent for Line<T> {
350    fn fit_content(argument: LengthPercentage) -> Self {
351        Line { start: T::fit_content(argument), end: T::fit_content(argument) }
352    }
353}
354impl<T: TaffyFitContent> Line<T> {
355    /// Returns a Line where both the start and end values are the constant points value of the contained type
356    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
357    pub fn fit_content(argument: LengthPercentage) -> Self {
358        fit_content(argument)
359    }
360}
361impl<T: TaffyFitContent> TaffyFitContent for Size<T> {
362    fn fit_content(argument: LengthPercentage) -> Self {
363        Size { width: T::fit_content(argument), height: T::fit_content(argument) }
364    }
365}
366impl<T: TaffyFitContent> Size<T> {
367    /// Returns a Size where both the width and height values are the constant fit_content value of the contained type
368    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
369    pub fn fit_content(argument: LengthPercentage) -> Self {
370        fit_content(argument)
371    }
372}
373impl<T: TaffyFitContent> TaffyFitContent for Rect<T> {
374    fn fit_content(argument: LengthPercentage) -> Self {
375        Rect {
376            left: T::fit_content(argument),
377            right: T::fit_content(argument),
378            top: T::fit_content(argument),
379            bottom: T::fit_content(argument),
380        }
381    }
382}
383impl<T: TaffyFitContent> Rect<T> {
384    /// Returns a Rect where the left, right, top and bottom values are all constant fit_content value of the contained type
385    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
386    pub fn fit_content(argument: LengthPercentage) -> Self {
387        fit_content(argument)
388    }
389}
390
391/// Returns a value of the inferred type which represent a constant of points
392pub fn points<Input: Into<f32> + Copy, T: FromPoints>(points: Input) -> T {
393    T::from_points(points)
394}
395
396/// Trait to create constant points values from plain numbers
397pub trait FromPoints {
398    /// Converts into an `Into<f32>` into Self
399    fn from_points<Input: Into<f32> + Copy>(points: Input) -> Self;
400}
401impl FromPoints for f32 {
402    fn from_points<Input: Into<f32> + Copy>(points: Input) -> Self {
403        points.into()
404    }
405}
406impl FromPoints for Option<f32> {
407    fn from_points<Input: Into<f32> + Copy>(points: Input) -> Self {
408        Some(points.into())
409    }
410}
411impl<T: FromPoints> FromPoints for Point<T> {
412    fn from_points<Input: Into<f32> + Copy>(points: Input) -> Self {
413        Point { x: T::from_points(points.into()), y: T::from_points(points.into()) }
414    }
415}
416impl<T: FromPoints> Point<T> {
417    /// Returns a Point where both the x and y values are the constant points value of the contained type
418    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
419    pub fn points<Input: Into<f32> + Copy>(points_value: Input) -> Self {
420        points::<Input, Self>(points_value)
421    }
422}
423impl<T: FromPoints> FromPoints for Line<T> {
424    fn from_points<Input: Into<f32> + Copy>(points: Input) -> Self {
425        Line { start: T::from_points(points.into()), end: T::from_points(points.into()) }
426    }
427}
428impl<T: FromPoints> Line<T> {
429    /// Returns a Line where both the start and end values are the constant points value of the contained type
430    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
431    pub fn points<Input: Into<f32> + Copy>(points_value: Input) -> Self {
432        points::<Input, Self>(points_value)
433    }
434}
435impl<T: FromPoints> FromPoints for Size<T> {
436    fn from_points<Input: Into<f32> + Copy>(points: Input) -> Self {
437        Size { width: T::from_points(points.into()), height: T::from_points(points.into()) }
438    }
439}
440impl<T: FromPoints> Size<T> {
441    /// Returns a Size where both the width and height values are the constant points value of the contained type
442    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
443    pub fn points<Input: Into<f32> + Copy>(points_value: Input) -> Self {
444        points::<Input, Self>(points_value)
445    }
446}
447impl<T: FromPoints> FromPoints for Rect<T> {
448    fn from_points<Input: Into<f32> + Copy>(points: Input) -> Self {
449        Rect {
450            left: T::from_points(points.into()),
451            right: T::from_points(points.into()),
452            top: T::from_points(points.into()),
453            bottom: T::from_points(points.into()),
454        }
455    }
456}
457impl<T: FromPoints> Rect<T> {
458    /// Returns a Rect where the left, right, top and bottom values are all constant points value of the contained type
459    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
460    pub fn points<Input: Into<f32> + Copy>(points_value: Input) -> Self {
461        points::<Input, Self>(points_value)
462    }
463}
464
465/// Returns a value of the inferred type which represent a constant of points
466pub fn percent<Input: Into<f32> + Copy, T: FromPercent>(percent: Input) -> T {
467    T::from_percent(percent)
468}
469
470/// Trait to create constant percent values from plain numbers
471pub trait FromPercent {
472    /// Converts into an `Into<f32>` into Self
473    fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self;
474}
475impl FromPercent for f32 {
476    fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
477        percent.into()
478    }
479}
480impl FromPercent for Option<f32> {
481    fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
482        Some(percent.into())
483    }
484}
485impl<T: FromPercent> FromPercent for Point<T> {
486    fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
487        Point { x: T::from_percent(percent.into()), y: T::from_percent(percent.into()) }
488    }
489}
490impl<T: FromPercent> Point<T> {
491    /// Returns a Point where both the x and y values are the constant percent value of the contained type
492    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
493    pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
494        percent::<Input, Self>(percent_value)
495    }
496}
497impl<T: FromPercent> FromPercent for Line<T> {
498    fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
499        Line { start: T::from_percent(percent.into()), end: T::from_percent(percent.into()) }
500    }
501}
502impl<T: FromPercent> Line<T> {
503    /// Returns a Line where both the start and end values are the constant percent value of the contained type
504    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
505    pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
506        percent::<Input, Self>(percent_value)
507    }
508}
509impl<T: FromPercent> FromPercent for Size<T> {
510    fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
511        Size { width: T::from_percent(percent.into()), height: T::from_percent(percent.into()) }
512    }
513}
514impl<T: FromPercent> Size<T> {
515    /// Returns a Size where both the width and height values are the constant percent value of the contained type
516    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
517    pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
518        percent::<Input, Self>(percent_value)
519    }
520}
521impl<T: FromPercent> FromPercent for Rect<T> {
522    fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
523        Rect {
524            left: T::from_percent(percent.into()),
525            right: T::from_percent(percent.into()),
526            top: T::from_percent(percent.into()),
527            bottom: T::from_percent(percent.into()),
528        }
529    }
530}
531impl<T: FromPercent> Rect<T> {
532    /// Returns a Rect where the left, right, top and bottom values are all constant percent value of the contained type
533    /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
534    pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
535        percent::<Input, Self>(percent_value)
536    }
537}
538
539/// Create a `Fraction` track sizing function (`fr` in CSS)
540#[cfg(feature = "grid")]
541pub fn fr<Input: Into<f32> + Copy, T: FromFlex>(flex: Input) -> T {
542    T::from_flex(flex)
543}
544
545/// Trait to create constant percent values from plain numbers
546pub trait FromFlex {
547    /// Converts into an `Into<f32>` into Self
548    fn from_flex<Input: Into<f32> + Copy>(flex: Input) -> Self;
549}