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::TL), Some(Align::BR));
55 pub const BOTTOM_LEFT: AlignHints = AlignHints::new(Some(Align::BR), Some(Align::TL));
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
71 pub const STRETCH: AlignHints = AlignHints::new(Some(Align::Stretch), Some(Align::Stretch));
73
74 pub const fn new(horiz: Option<Align>, vert: Option<Align>) -> Self {
76 Self { horiz, vert }
77 }
78
79 #[inline]
81 pub fn extract(self, dir: impl Directional) -> Option<Align> {
82 match dir.is_vertical() {
83 false => self.horiz,
84 true => self.vert,
85 }
86 }
87
88 #[inline]
90 pub fn set_component<D: Directional>(&mut self, dir: D, align: Option<Align>) {
91 match dir.is_vertical() {
92 false => self.horiz = align,
93 true => self.vert = align,
94 }
95 }
96
97 #[must_use = "method does not modify self but returns a new value"]
99 pub fn combine(self, rhs: AlignHints) -> Self {
100 Self {
101 horiz: self.horiz.or(rhs.horiz),
102 vert: self.vert.or(rhs.vert),
103 }
104 }
105
106 pub fn unwrap_or(self, horiz: Align, vert: Align) -> (Align, Align) {
108 (self.horiz.unwrap_or(horiz), self.vert.unwrap_or(vert))
109 }
110
111 pub fn complete(&self, horiz: Align, vert: Align) -> AlignPair {
113 AlignPair::new(self.horiz.unwrap_or(horiz), self.vert.unwrap_or(vert))
114 }
115
116 pub fn complete_default(&self) -> AlignPair {
118 self.complete(Align::Default, Align::Default)
119 }
120
121 pub fn complete_center(&self) -> AlignPair {
123 self.complete(Align::Center, Align::Center)
124 }
125}
126
127#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
131pub struct AlignPair {
132 pub horiz: Align,
133 pub vert: Align,
134}
135
136impl AlignPair {
137 pub const DEFAULT: AlignPair = AlignPair::new(Align::Default, Align::Default);
139
140 pub const CENTER: AlignPair = AlignPair::new(Align::Center, Align::Center);
142
143 pub const STRETCH: AlignPair = AlignPair::new(Align::Stretch, Align::Stretch);
145
146 pub const fn new(horiz: Align, vert: Align) -> Self {
148 Self { horiz, vert }
149 }
150
151 #[inline]
153 pub fn extract<D: Directional>(self, dir: D) -> Align {
154 match dir.is_vertical() {
155 false => self.horiz,
156 true => self.vert,
157 }
158 }
159
160 #[inline]
162 pub fn set_component<D: Directional>(&mut self, dir: D, align: Align) {
163 match dir.is_vertical() {
164 false => self.horiz = align,
165 true => self.vert = align,
166 }
167 }
168
169 pub fn aligned_rect(&self, ideal: Size, rect: Rect) -> Rect {
171 let mut pos = rect.pos;
172 let mut size = rect.size;
173 if ideal.0 < size.0 && self.horiz != Align::Stretch {
174 pos.0 += match self.horiz {
175 Align::Center => (size.0 - ideal.0) / 2,
176 Align::BR => size.0 - ideal.0,
177 Align::Default | Align::TL | Align::Stretch => 0,
178 };
179 size.0 = ideal.0;
180 }
181 if ideal.1 < size.1 && self.vert != Align::Stretch {
182 pos.1 += match self.vert {
183 Align::Center => (size.1 - ideal.1) / 2,
184 Align::BR => size.1 - ideal.1,
185 Align::Default | Align::TL | Align::Stretch => 0,
186 };
187 size.1 = ideal.1;
188 }
189 Rect { pos, size }
190 }
191}
192
193impl From<(Align, Align)> for AlignHints {
194 #[inline]
195 fn from((h, v): (Align, Align)) -> Self {
196 AlignHints::new(Some(h), Some(v))
197 }
198}
199
200impl From<(Align, Align)> for AlignPair {
201 #[inline]
202 fn from((h, v): (Align, Align)) -> Self {
203 AlignPair::new(h, v)
204 }
205}
206
207impl From<AlignPair> for (Align, Align) {
208 #[inline]
209 fn from(p: AlignPair) -> Self {
210 (p.horiz, p.vert)
211 }
212}