1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef UI_VIEWS_LAYOUT_NORMALIZED_GEOMETRY_H_
6 #define UI_VIEWS_LAYOUT_NORMALIZED_GEOMETRY_H_
7 
8 #include <string>
9 #include <utility>
10 
11 #include "base/optional.h"
12 #include "ui/views/layout/flex_layout_types.h"
13 #include "ui/views/views_export.h"
14 
15 namespace gfx {
16 class Insets;
17 class Point;
18 class Rect;
19 class Size;
20 }  // namespace gfx
21 
22 namespace views {
23 
24 class SizeBounds;
25 
26 // Represents a point in layout space - that is, a point on the main and cross
27 // axes of the layout (regardless of whether it is vertically or horizontally
28 // oriented.
29 class VIEWS_EXPORT NormalizedPoint {
30  public:
31   constexpr NormalizedPoint() = default;
NormalizedPoint(int main,int cross)32   constexpr NormalizedPoint(int main, int cross) : main_(main), cross_(cross) {}
33 
main()34   constexpr int main() const { return main_; }
set_main(int main)35   void set_main(int main) { main_ = main; }
36 
cross()37   constexpr int cross() const { return cross_; }
set_cross(int cross)38   void set_cross(int cross) { cross_ = cross; }
39 
40   void SetPoint(int main, int cross);
41   void Offset(int delta_main, int delta_cross);
42 
43   bool operator==(const NormalizedPoint& other) const;
44   bool operator!=(const NormalizedPoint& other) const;
45   bool operator<(const NormalizedPoint& other) const;
46 
47   std::string ToString() const;
48 
49  private:
50   int main_ = 0;
51   int cross_ = 0;
52 };
53 
54 // Represents a size in layout space - that is, a size on the main and cross
55 // axes of the layout (regardless of whether it is vertically or horizontally
56 // oriented.
57 class VIEWS_EXPORT NormalizedSize {
58  public:
59   constexpr NormalizedSize() = default;
NormalizedSize(int main,int cross)60   constexpr NormalizedSize(int main, int cross) : main_(main), cross_(cross) {}
61 
main()62   constexpr int main() const { return main_; }
set_main(int main)63   void set_main(int main) { main_ = main; }
64 
cross()65   constexpr int cross() const { return cross_; }
set_cross(int cross)66   void set_cross(int cross) { cross_ = cross; }
67 
68   void SetSize(int main, int cross);
69   void Enlarge(int delta_main, int delta_cross);
70   void SetToMax(int main, int cross);
71   void SetToMax(const NormalizedSize& other);
72   void SetToMin(int main, int cross);
73   void SetToMin(const NormalizedSize& other);
74 
is_empty()75   constexpr bool is_empty() const { return main_ == 0 || cross_ == 0; }
76 
77   bool operator==(const NormalizedSize& other) const;
78   bool operator!=(const NormalizedSize& other) const;
79   bool operator<(const NormalizedSize& other) const;
80 
81   std::string ToString() const;
82 
83  private:
84   int main_ = 0;
85   int cross_ = 0;
86 };
87 
88 // Represents insets in layout space - that is, insets on the main and cross
89 // axes of the layout (regardless of whether it is vertically or horizontally
90 // oriented.
91 class VIEWS_EXPORT NormalizedInsets {
92  public:
93   constexpr NormalizedInsets() = default;
NormalizedInsets(int all)94   constexpr explicit NormalizedInsets(int all) : main_(all), cross_(all) {}
NormalizedInsets(int main,int cross)95   constexpr NormalizedInsets(int main, int cross)
96       : main_(main), cross_(cross) {}
NormalizedInsets(const Inset1D & main,const Inset1D & cross)97   constexpr NormalizedInsets(const Inset1D& main, const Inset1D& cross)
98       : main_(main), cross_(cross) {}
NormalizedInsets(int main_leading,int cross_leading,int main_trailing,int cross_trailing)99   constexpr NormalizedInsets(int main_leading,
100                              int cross_leading,
101                              int main_trailing,
102                              int cross_trailing)
103       : main_(main_leading, main_trailing),
104         cross_(cross_leading, cross_trailing) {}
105 
main_leading()106   constexpr int main_leading() const { return main_.leading(); }
set_main_leading(int main_leading)107   void set_main_leading(int main_leading) { main_.set_leading(main_leading); }
108 
main_trailing()109   constexpr int main_trailing() const { return main_.trailing(); }
set_main_trailing(int main_trailing)110   void set_main_trailing(int main_trailing) {
111     main_.set_trailing(main_trailing);
112   }
113 
main_size()114   constexpr int main_size() const { return main_.size(); }
115 
cross_leading()116   constexpr int cross_leading() const { return cross_.leading(); }
set_cross_leading(int cross_leading)117   void set_cross_leading(int cross_leading) {
118     cross_.set_leading(cross_leading);
119   }
120 
cross_trailing()121   constexpr int cross_trailing() const { return cross_.trailing(); }
set_cross_trailing(int cross_trailing)122   void set_cross_trailing(int cross_trailing) {
123     cross_.set_trailing(cross_trailing);
124   }
125 
cross_size()126   constexpr int cross_size() const { return cross_.size(); }
127 
main()128   const Inset1D& main() const { return main_; }
set_main(const Inset1D & main)129   void set_main(const Inset1D& main) { main_ = main; }
130 
cross()131   const Inset1D& cross() const { return cross_; }
set_cross(const Inset1D & cross)132   void set_cross(const Inset1D& cross) { cross_ = cross; }
133 
134   bool operator==(const NormalizedInsets& other) const;
135   bool operator!=(const NormalizedInsets& other) const;
136   bool operator<(const NormalizedInsets& other) const;
137 
138   std::string ToString() const;
139 
140  private:
141   Inset1D main_;
142   Inset1D cross_;
143 };
144 
145 // Represents size bounds in layout space - that is, a set of size bounds using
146 // the main and cross axes of the layout (regardless of whether it is vertically
147 // or horizontally oriented).
148 class VIEWS_EXPORT NormalizedSizeBounds {
149  public:
150   NormalizedSizeBounds();
151   NormalizedSizeBounds(SizeBound main, SizeBound cross);
152   explicit NormalizedSizeBounds(const NormalizedSize& size);
153   NormalizedSizeBounds(const NormalizedSizeBounds& size_bounds);
154 
main()155   const SizeBound& main() const { return main_; }
set_main(SizeBound main)156   void set_main(SizeBound main) { main_ = std::move(main); }
157 
cross()158   const SizeBound& cross() const { return cross_; }
set_cross(SizeBound cross)159   void set_cross(SizeBound cross) { cross_ = std::move(cross); }
160 
161   void Expand(int main, int cross);
162   void Inset(const NormalizedInsets& insets);
163 
164   bool operator==(const NormalizedSizeBounds& other) const;
165   bool operator!=(const NormalizedSizeBounds& other) const;
166   bool operator<(const NormalizedSizeBounds& other) const;
167 
168   std::string ToString() const;
169 
170  private:
171   SizeBound main_;
172   SizeBound cross_;
173 };
174 
175 // Represents a rectangle in layout space - that is, a rectangle whose
176 // dimensions align with the main and cross axis of the layout (regardless of
177 // whether the layout is vertically or horizontally oriented).
178 class VIEWS_EXPORT NormalizedRect {
179  public:
180   constexpr NormalizedRect() = default;
NormalizedRect(const NormalizedPoint & origin,const NormalizedSize & size)181   constexpr NormalizedRect(const NormalizedPoint& origin,
182                            const NormalizedSize& size)
183       : origin_(origin), size_(size) {}
NormalizedRect(const Span & main,const Span & cross)184   constexpr NormalizedRect(const Span& main, const Span& cross)
185       : origin_(main.start(), cross.start()),
186         size_(main.length(), cross.length()) {}
NormalizedRect(int origin_main,int origin_cross,int size_main,int size_cross)187   constexpr NormalizedRect(int origin_main,
188                            int origin_cross,
189                            int size_main,
190                            int size_cross)
191       : origin_(origin_main, origin_cross), size_(size_main, size_cross) {}
192 
origin_main()193   constexpr int origin_main() const { return origin_.main(); }
set_origin_main(int main)194   void set_origin_main(int main) { origin_.set_main(main); }
195 
origin_cross()196   constexpr int origin_cross() const { return origin_.cross(); }
set_origin_cross(int cross)197   void set_origin_cross(int cross) { origin_.set_cross(cross); }
198 
origin()199   constexpr const NormalizedPoint& origin() const { return origin_; }
set_origin(const NormalizedPoint & origin)200   void set_origin(const NormalizedPoint& origin) { origin_ = origin; }
201 
size_main()202   constexpr int size_main() const { return size_.main(); }
set_size_main(int main)203   void set_size_main(int main) { size_.set_main(main); }
204 
size_cross()205   constexpr int size_cross() const { return size_.cross(); }
set_size_cross(int cross)206   void set_size_cross(int cross) { size_.set_cross(cross); }
207 
size()208   constexpr const NormalizedSize& size() const { return size_; }
set_size(const NormalizedSize & size)209   void set_size(const NormalizedSize& size) { size_ = size; }
210 
max_main()211   constexpr int max_main() const { return origin_.main() + size_.main(); }
max_cross()212   constexpr int max_cross() const { return origin_.cross() + size_.cross(); }
213 
214   Span GetMainSpan() const;
215   void SetMainSpan(const Span& span);
216   void AlignMain(const Span& container,
217                  LayoutAlignment alignment,
218                  const Inset1D& margins = Inset1D());
219 
220   Span GetCrossSpan() const;
221   void SetCrossSpan(const Span& span);
222   void AlignCross(const Span& container,
223                   LayoutAlignment alignment,
224                   const Inset1D& margins = Inset1D());
225 
226   void SetRect(int origin_main,
227                int origin_cross,
228                int size_main,
229                int size_cross);
230   void SetByBounds(int origin_main,
231                    int origin_cross,
232                    int max_main,
233                    int max_cross);
234   void Inset(const NormalizedInsets& insets);
235   void Inset(int main, int cross);
236   void Inset(int main_leading,
237              int cross_leading,
238              int main_trailing,
239              int cross_trailing);
240   void Offset(int main, int cross);
241 
is_empty()242   constexpr bool is_empty() const { return size_.is_empty(); }
243   bool operator==(const NormalizedRect& other) const;
244   bool operator!=(const NormalizedRect& other) const;
245   bool operator<(const NormalizedRect& other) const;
246 
247   std::string ToString() const;
248 
249  private:
250   NormalizedPoint origin_;
251   NormalizedSize size_;
252 };
253 
254 // Normalization and Denormalization -------------------------------------------
255 
256 NormalizedPoint VIEWS_EXPORT Normalize(LayoutOrientation orientation,
257                                        const gfx::Point& point);
258 gfx::Point VIEWS_EXPORT Denormalize(LayoutOrientation orientation,
259                                     const NormalizedPoint& point);
260 
261 NormalizedSize VIEWS_EXPORT Normalize(LayoutOrientation orientation,
262                                       const gfx::Size& size);
263 gfx::Size VIEWS_EXPORT Denormalize(LayoutOrientation orientation,
264                                    const NormalizedSize& size);
265 
266 NormalizedSizeBounds VIEWS_EXPORT Normalize(LayoutOrientation orientation,
267                                             const SizeBounds& bounds);
268 SizeBounds VIEWS_EXPORT Denormalize(LayoutOrientation orientation,
269                                     const NormalizedSizeBounds& bounds);
270 
271 NormalizedInsets VIEWS_EXPORT Normalize(LayoutOrientation orientation,
272                                         const gfx::Insets& insets);
273 gfx::Insets VIEWS_EXPORT Denormalize(LayoutOrientation orientation,
274                                      const NormalizedInsets& insets);
275 
276 NormalizedRect VIEWS_EXPORT Normalize(LayoutOrientation orientation,
277                                       const gfx::Rect& rect);
278 gfx::Rect VIEWS_EXPORT Denormalize(LayoutOrientation orientation,
279                                    const NormalizedRect& rect);
280 
281 // Convenience methods to get and set main and cross-axis elements of
282 // denormalized geometry elements.
283 int VIEWS_EXPORT GetMainAxis(LayoutOrientation orientation,
284                              const gfx::Size& size);
285 int VIEWS_EXPORT GetCrossAxis(LayoutOrientation orientation,
286                               const gfx::Size& size);
287 SizeBound VIEWS_EXPORT GetMainAxis(LayoutOrientation orientation,
288                                    const SizeBounds& size);
289 SizeBound VIEWS_EXPORT GetCrossAxis(LayoutOrientation orientation,
290                                     const SizeBounds& size);
291 void VIEWS_EXPORT SetMainAxis(gfx::Size* size,
292                               LayoutOrientation orientation,
293                               int main);
294 void VIEWS_EXPORT SetCrossAxis(gfx::Size* size,
295                                LayoutOrientation orientation,
296                                int cross);
297 void VIEWS_EXPORT SetMainAxis(SizeBounds* size,
298                               LayoutOrientation orientation,
299                               SizeBound main);
300 void VIEWS_EXPORT SetCrossAxis(SizeBounds* size,
301                                LayoutOrientation orientation,
302                                SizeBound cross);
303 
304 }  // namespace views
305 
306 #endif  // UI_VIEWS_LAYOUT_NORMALIZED_GEOMETRY_H_
307