1#[allow(unused)] use super::Stretch; use crate::dir::Directional;
10use crate::geom::{Rect, Size};
11
12pub use crate::text::Align;
13
14#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
33pub struct AlignHints {
34 pub horiz: Option<Align>,
35 pub vert: Option<Align>,
36}
37
38impl AlignHints {
39 pub const NONE: AlignHints = AlignHints::new(None, None);
41
42 pub const TOP: AlignHints = AlignHints::new(None, Some(Align::TL));
44 pub const BOTTOM: AlignHints = AlignHints::new(None, Some(Align::BR));
46 pub const LEFT: AlignHints = AlignHints::new(Some(Align::TL), None);
48 pub const RIGHT: AlignHints = AlignHints::new(Some(Align::BR), None);
50
51 pub const TOP_LEFT: AlignHints = AlignHints::new(Some(Align::TL), Some(Align::TL));
53 pub const TOP_RIGHT: AlignHints = AlignHints::new(Some(Align::BR), Some(Align::TL));
55 pub const BOTTOM_LEFT: AlignHints = AlignHints::new(Some(Align::TL), Some(Align::BR));
57 pub const BOTTOM_RIGHT: AlignHints = AlignHints::new(Some(Align::BR), Some(Align::BR));
59
60 pub const CENTER: AlignHints = AlignHints::new(Some(Align::Center), Some(Align::Center));
62 pub const TOP_CENTER: AlignHints = AlignHints::new(Some(Align::Center), Some(Align::TL));
64 pub const BOTTOM_CENTER: AlignHints = AlignHints::new(Some(Align::Center), Some(Align::BR));
66 pub const CENTER_LEFT: AlignHints = AlignHints::new(Some(Align::TL), Some(Align::Center));
68 pub const CENTER_RIGHT: AlignHints = AlignHints::new(Some(Align::BR), Some(Align::Center));
70 pub const HORIZ_CENTER: AlignHints = AlignHints::new(Some(Align::Center), None);
72 pub const VERT_CENTER: AlignHints = AlignHints::new(None, Some(Align::Center));
74
75 pub const STRETCH: AlignHints = AlignHints::new(Some(Align::Stretch), Some(Align::Stretch));
77
78 pub const fn new(horiz: Option<Align>, vert: Option<Align>) -> Self {
80 Self { horiz, vert }
81 }
82
83 #[inline]
85 pub fn extract(self, dir: impl Directional) -> Option<Align> {
86 match dir.is_vertical() {
87 false => self.horiz,
88 true => self.vert,
89 }
90 }
91
92 #[inline]
94 pub fn set_component<D: Directional>(&mut self, dir: D, align: Option<Align>) {
95 match dir.is_vertical() {
96 false => self.horiz = align,
97 true => self.vert = align,
98 }
99 }
100
101 #[must_use = "method does not modify self but returns a new value"]
103 pub fn combine(self, rhs: AlignHints) -> Self {
104 Self {
105 horiz: self.horiz.or(rhs.horiz),
106 vert: self.vert.or(rhs.vert),
107 }
108 }
109
110 pub fn unwrap_or(self, horiz: Align, vert: Align) -> (Align, Align) {
112 (self.horiz.unwrap_or(horiz), self.vert.unwrap_or(vert))
113 }
114
115 pub fn complete(&self, horiz: Align, vert: Align) -> AlignPair {
117 AlignPair::new(self.horiz.unwrap_or(horiz), self.vert.unwrap_or(vert))
118 }
119
120 pub fn complete_default(&self) -> AlignPair {
122 self.complete(Align::Default, Align::Default)
123 }
124
125 pub fn complete_center(&self) -> AlignPair {
127 self.complete(Align::Center, Align::Center)
128 }
129}
130
131#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
135pub struct AlignPair {
136 pub horiz: Align,
137 pub vert: Align,
138}
139
140impl AlignPair {
141 pub const DEFAULT: AlignPair = AlignPair::new(Align::Default, Align::Default);
143
144 pub const CENTER: AlignPair = AlignPair::new(Align::Center, Align::Center);
146
147 pub const STRETCH: AlignPair = AlignPair::new(Align::Stretch, Align::Stretch);
149
150 pub const fn new(horiz: Align, vert: Align) -> Self {
152 Self { horiz, vert }
153 }
154
155 #[inline]
157 pub fn extract<D: Directional>(self, dir: D) -> Align {
158 match dir.is_vertical() {
159 false => self.horiz,
160 true => self.vert,
161 }
162 }
163
164 #[inline]
166 pub fn set_component<D: Directional>(&mut self, dir: D, align: Align) {
167 match dir.is_vertical() {
168 false => self.horiz = align,
169 true => self.vert = align,
170 }
171 }
172
173 pub fn aligned_rect(&self, ideal: Size, rect: Rect) -> Rect {
175 let mut pos = rect.pos;
176 let mut size = rect.size;
177 if ideal.0 < size.0 && self.horiz != Align::Stretch {
178 pos.0 += match self.horiz {
179 Align::Center => (size.0 - ideal.0) / 2,
180 Align::BR => size.0 - ideal.0,
181 Align::Default | Align::TL | Align::Stretch => 0,
182 };
183 size.0 = ideal.0;
184 }
185 if ideal.1 < size.1 && self.vert != Align::Stretch {
186 pos.1 += match self.vert {
187 Align::Center => (size.1 - ideal.1) / 2,
188 Align::BR => size.1 - ideal.1,
189 Align::Default | Align::TL | Align::Stretch => 0,
190 };
191 size.1 = ideal.1;
192 }
193 Rect { pos, size }
194 }
195}
196
197impl From<(Align, Align)> for AlignHints {
198 #[inline]
199 fn from((h, v): (Align, Align)) -> Self {
200 AlignHints::new(Some(h), Some(v))
201 }
202}
203
204impl From<(Align, Align)> for AlignPair {
205 #[inline]
206 fn from((h, v): (Align, Align)) -> Self {
207 AlignPair::new(h, v)
208 }
209}
210
211impl From<AlignPair> for (Align, Align) {
212 #[inline]
213 fn from(p: AlignPair) -> Self {
214 (p.horiz, p.vert)
215 }
216}