azul_layout/
geometry.rs

1#![allow(dead_code)]
2
3// MIT License
4//
5// Copyright (c) 2018 Visly Inc.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25use std::ops::Add;
26use azul_core::ui_solver::ResolvedOffsets;
27use crate::{
28    number::Number,
29    style::{FlexDirection, Dimension},
30};
31
32#[derive(Debug, Copy, Clone, PartialEq)]
33pub struct Rect {
34    pub origin: RectOrigin,
35    pub size: RectSize,
36    pub margin: ResolvedOffsets,
37    pub padding: ResolvedOffsets,
38    pub border_widths: ResolvedOffsets,
39}
40
41impl Rect {
42    pub const fn undefined() -> Self {
43        Self {
44            origin: RectOrigin::undefined(),
45            size: RectSize::undefined(),
46            margin: ResolvedOffsets::zero(),
47            padding: ResolvedOffsets::zero(),
48            border_widths: ResolvedOffsets::zero(),
49        }
50    }
51}
52
53#[derive(Debug, Copy, Clone, PartialEq)]
54pub struct RectOrigin {
55    pub x: Number,
56    pub y: Number,
57}
58
59impl RectOrigin {
60    pub const fn undefined() -> Self {
61        Self {
62            x: Number::Undefined,
63            y: Number::Undefined,
64        }
65    }
66}
67
68#[derive(Debug, Copy, Clone, PartialEq)]
69pub struct RectSize {
70    pub width: Number,
71    pub height: Number,
72}
73
74impl RectSize {
75    pub const fn undefined() -> Self {
76        Self {
77            width: Number::Undefined,
78            height: Number::Undefined,
79        }
80    }
81
82    pub(crate) fn main(self, direction: FlexDirection) -> Number {
83        match direction {
84            FlexDirection::Row | FlexDirection::RowReverse => self.width,
85            FlexDirection::Column | FlexDirection::ColumnReverse => self.height,
86        }
87    }
88
89    pub(crate) fn cross(self, direction: FlexDirection) -> Number {
90        match direction {
91            FlexDirection::Row | FlexDirection::RowReverse => self.height,
92            FlexDirection::Column | FlexDirection::ColumnReverse => self.width,
93        }
94    }
95}
96
97#[derive(Debug, Copy, Clone, PartialEq)]
98pub struct Offsets<T> {
99    pub top: T,
100    pub left: T,
101    pub bottom: T,
102    pub right: T,
103}
104
105pub(crate) const DEFAULT_OFFSETS: Offsets<Dimension> = Offsets {
106    top: Dimension::DEFAULT,
107    left: Dimension::DEFAULT,
108    bottom: Dimension::DEFAULT,
109    right: Dimension::DEFAULT,
110};
111
112impl<T> Offsets<T> {
113    pub(crate) fn map<R, F: Fn(T) -> R>(self, f: F) -> Offsets<R> {
114        Offsets { left: f(self.left), right: f(self.right), top: f(self.top), bottom: f(self.bottom) }
115    }
116}
117
118impl<T: Add<Output = T> + Copy + Clone> Offsets<T> {
119    pub(crate) fn horizontal(&self) -> T {
120        self.left + self.right
121    }
122
123    pub(crate) fn vertical(&self) -> T {
124        self.top + self.bottom
125    }
126
127    pub(crate) fn main(&self, direction: FlexDirection) -> T {
128        match direction {
129            FlexDirection::Row | FlexDirection::RowReverse => self.left + self.right,
130            FlexDirection::Column | FlexDirection::ColumnReverse => self.top + self.bottom,
131        }
132    }
133
134    pub(crate) fn cross(&self, direction: FlexDirection) -> T {
135        match direction {
136            FlexDirection::Row | FlexDirection::RowReverse => self.top + self.bottom,
137            FlexDirection::Column | FlexDirection::ColumnReverse => self.left + self.right,
138        }
139    }
140}
141
142impl Add<RectSize> for RectSize {
143    type Output = RectSize;
144
145    fn add(self, rhs: RectSize) -> RectSize {
146        RectSize {
147            width: self.width + rhs.width,
148            height: self.height + rhs.height,
149        }
150    }
151}
152
153impl<T: Add<Output = T>> Add<Offsets<T>> for Offsets<T> {
154    type Output = Offsets<T>;
155
156    fn add(self, rhs: Offsets<T>) -> Offsets<T> {
157        Offsets {
158            left: self.left + rhs.left,
159            right: self.right + rhs.right,
160            top: self.top + rhs.top,
161            bottom: self.bottom + rhs.bottom,
162        }
163    }
164}
165
166impl<T: Copy + Clone> Offsets<T> {
167    pub(crate) fn main_start(&self, direction: FlexDirection) -> T {
168        match direction {
169            FlexDirection::Row | FlexDirection::RowReverse => self.left,
170            FlexDirection::Column | FlexDirection::ColumnReverse => self.top,
171        }
172    }
173
174    pub(crate) fn main_end(&self, direction: FlexDirection) -> T {
175        match direction {
176            FlexDirection::Row | FlexDirection::RowReverse => self.right,
177            FlexDirection::Column | FlexDirection::ColumnReverse => self.bottom,
178        }
179    }
180
181    pub(crate) fn cross_start(&self, direction: FlexDirection) -> T {
182        match direction {
183            FlexDirection::Row | FlexDirection::RowReverse => self.top,
184            FlexDirection::Column | FlexDirection::ColumnReverse => self.left,
185        }
186    }
187
188    pub(crate) fn cross_end(&self, direction: FlexDirection) -> T {
189        match direction {
190            FlexDirection::Row | FlexDirection::RowReverse => self.bottom,
191            FlexDirection::Column | FlexDirection::ColumnReverse => self.right,
192        }
193    }
194}
195
196#[derive(Debug, Copy, Clone, PartialEq)]
197pub struct Size<T> {
198    pub width: T,
199    pub height: T,
200}
201
202pub(crate) const DEFAULT_SIZE: Size<Dimension> = Size {
203    width: Dimension::DEFAULT,
204    height: Dimension::DEFAULT,
205};
206
207impl<T> Size<T> {
208    pub(crate) fn map<R, F>(self, f: F) -> Size<R>
209    where
210        F: Fn(T) -> R,
211    {
212        Size { width: f(self.width), height: f(self.height) }
213    }
214
215    pub(crate) fn set_main(&mut self, direction: FlexDirection, value: T) {
216        match direction {
217            FlexDirection::Row | FlexDirection::RowReverse => self.width = value,
218            FlexDirection::Column | FlexDirection::ColumnReverse => self.height = value,
219        }
220    }
221
222    pub(crate) fn set_cross(&mut self, direction: FlexDirection, value: T) {
223        match direction {
224            FlexDirection::Row | FlexDirection::RowReverse => self.height = value,
225            FlexDirection::Column | FlexDirection::ColumnReverse => self.width = value,
226        }
227    }
228
229    pub(crate) fn main(self, direction: FlexDirection) -> T {
230        match direction {
231            FlexDirection::Row | FlexDirection::RowReverse => self.width,
232            FlexDirection::Column | FlexDirection::ColumnReverse => self.height,
233        }
234    }
235
236    pub(crate) fn cross(self, direction: FlexDirection) -> T {
237        match direction {
238            FlexDirection::Row | FlexDirection::RowReverse => self.height,
239            FlexDirection::Column | FlexDirection::ColumnReverse => self.width,
240        }
241    }
242}