1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
use super::*;
use AlignmentKey::*;
/// An argument key which describes a target alignment.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum AlignmentKey {
Align(Alignment),
Left,
Top,
Right,
Bottom,
}
impl AlignmentKey {
/// The generic axis this alignment key corresponds to in the given system
/// of layouting axes. `None` if the alignment is generic.
pub fn axis(self, axes: LayoutAxes) -> Option<GenericAxis> {
match self {
Left | Right => Some(Horizontal.to_generic(axes)),
Top | Bottom => Some(Vertical.to_generic(axes)),
Align(_) => None,
}
}
/// The generic version of this alignment in the given system of layouting
/// axes.
///
/// Returns an error if the alignment is invalid for the given axis.
pub fn to_generic(self, axes: LayoutAxes, axis: GenericAxis) -> LayoutResult<Alignment> {
let specific = axis.to_specific(axes);
let start = match axes.get(axis).is_positive() {
true => Origin,
false => End,
};
Ok(match (self, specific) {
(Align(alignment), _) => alignment,
(Left, Horizontal) | (Top, Vertical) => start,
(Right, Horizontal) | (Bottom, Vertical) => start.inv(),
_ => error!(
"invalid alignment `{}` for {} axis",
format!("{:?}", self).to_lowercase(),
format!("{:?}", axis).to_lowercase()
)
})
}
/// The specific version of this alignment in the given system of layouting
/// axes.
pub fn to_specific(self, axes: LayoutAxes, axis: SpecificAxis) -> AlignmentKey {
let direction = axes.get_specific(axis);
if let Align(alignment) = self {
match (direction, alignment) {
(LeftToRight, Origin) | (RightToLeft, End) => Left,
(LeftToRight, End) | (RightToLeft, Origin) => Right,
(TopToBottom, Origin) | (BottomToTop, End) => Top,
(TopToBottom, End) | (BottomToTop, Origin) => Bottom,
(_, Center) => self,
}
} else {
self
}
}
}
key!(AlignmentKey, "alignment",
"origin" => Align(Origin),
"center" => Align(Center),
"end" => Align(End),
"left" => Left,
"top" => Top,
"right" => Right,
"bottom" => Bottom,
);
|