File: layout_types.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (178 lines) | stat: -rw-r--r-- 7,024 bytes parent folder | download | duplicates (4)
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_VIEWS_LAYOUT_LAYOUT_TYPES_H_
#define UI_VIEWS_LAYOUT_LAYOUT_TYPES_H_

#include <algorithm>
#include <optional>
#include <ostream>
#include <string>
#include <tuple>
#include <utility>

#include "base/check.h"
#include "ui/base/metadata/base_type_conversion.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/views_export.h"

namespace views {

// Describes how elements should be aligned within a layout.  Baseline alignment
// only makes sense on the vertical axis and is unsupported by most layout
// managers.
enum class LayoutAlignment { kStart, kCenter, kEnd, kStretch, kBaseline };

// Whether a layout is oriented horizontally or vertically.
enum class LayoutOrientation {
  kHorizontal,
  kVertical,
};

// A value used to bound a View during layout.  May be a finite bound or
// "unbounded", which is treated as larger than any finite value.
class VIEWS_EXPORT SizeBound {
 public:
  // Method definitions below to avoid "complex constructor" warning.  Marked
  // explicitly inline because Clang currently doesn't realize that "constexpr"
  // explicitly means "inline" and thus should count as "intentionally inlined
  // and thus shouldn't be warned about".
  // TODO(crbug.com/40116092): Remove "inline" if Clang's isInlineSpecified()
  // learns about constexpr.
  // TODO(crbug.com/40116093): Put method bodies here if complex constructor
  // heuristic learns to peer into types to discover that e.g. Optional is not
  // complex.
  inline constexpr SizeBound();
  inline constexpr SizeBound(int bound);  // NOLINT
  inline constexpr SizeBound(const SizeBound&);
  inline constexpr SizeBound(SizeBound&&);
  SizeBound& operator=(const SizeBound&) = default;
  SizeBound& operator=(SizeBound&&) = default;
  ~SizeBound() = default;

  constexpr bool is_bounded() const { return bound_.has_value(); }
  // Must only be invoked when there is a bound, since otherwise the value to
  // return is unknown.
  constexpr int value() const {
    DCHECK(is_bounded());
    return *bound_;
  }

  constexpr int min_of(int value) const {
    return is_bounded() ? std::min(this->value(), value) : value;
  }

  constexpr int value_or(int defaule_value) const {
    return is_bounded() ? value() : defaule_value;
  }

  void operator+=(const SizeBound& rhs);
  void operator-=(const SizeBound& rhs);

  std::string ToString() const;

 private:
  friend constexpr bool operator==(const SizeBound&,
                                   const SizeBound&) = default;

  // nullopt represents "unbounded".
  std::optional<int> bound_;
};
constexpr SizeBound::SizeBound() = default;
constexpr SizeBound::SizeBound(int bound) : bound_(bound) {}
constexpr SizeBound::SizeBound(const SizeBound&) = default;
constexpr SizeBound::SizeBound(SizeBound&&) = default;
VIEWS_EXPORT SizeBound operator+(const SizeBound& lhs, const SizeBound& rhs);
VIEWS_EXPORT SizeBound operator-(const SizeBound& lhs, const SizeBound& rhs);
// Note: These comparisons treat unspecified values similar to infinity, that
// is, larger than any specified value and equal to any other unspecified value.
// While one can argue that two unspecified values can't be compared (and thus
// all comparisons should return false), this isn't what any callers want and
// breaks things in subtle ways, e.g. "a = b; DCHECK(a == b)" may fail.
constexpr bool operator<(const SizeBound& lhs, const SizeBound& rhs) {
  return lhs.is_bounded() && (!rhs.is_bounded() || (lhs.value() < rhs.value()));
}
constexpr bool operator>(const SizeBound& lhs, const SizeBound& rhs) {
  return rhs.is_bounded() && (!lhs.is_bounded() || (lhs.value() > rhs.value()));
}
constexpr bool operator<=(const SizeBound& lhs, const SizeBound& rhs) {
  return !(lhs > rhs);
}
constexpr bool operator>=(const SizeBound& lhs, const SizeBound& rhs) {
  return !(lhs < rhs);
}

// Stores an optional width and height upper bound. Used when calculating the
// preferred size of a layout pursuant to a maximum available size.
class VIEWS_EXPORT SizeBounds {
 public:
  // See comments in SizeBound re: "inline" with definitions below.
  inline constexpr SizeBounds();
  inline constexpr SizeBounds(SizeBound width, SizeBound height);
  inline constexpr explicit SizeBounds(const gfx::Size& size);
  inline constexpr SizeBounds(const SizeBounds&);
  inline constexpr SizeBounds(SizeBounds&&);
  SizeBounds& operator=(const SizeBounds&) = default;
  SizeBounds& operator=(SizeBounds&&) = default;
  ~SizeBounds() = default;

  constexpr const SizeBound& width() const { return width_; }
  constexpr SizeBound& width() { return width_; }
  void set_width(SizeBound width) { width_ = std::move(width); }

  constexpr const SizeBound& height() const { return height_; }
  constexpr SizeBound& height() { return height_; }
  void set_height(SizeBound height) { height_ = std::move(height); }

  constexpr bool is_fully_bounded() const {
    return width_.is_bounded() && height_.is_bounded();
  }

  // Enlarges (or shrinks, if negative) each upper bound that is present by the
  // specified amounts.
  void Enlarge(int width, int height);

  // Shrink the SizeBounds by the given `insets`.
  SizeBounds Inset(const gfx::Insets& inset) const;

  std::string ToString() const;

  friend constexpr bool operator==(const SizeBounds&,
                                   const SizeBounds&) = default;

 private:
  SizeBound width_;
  SizeBound height_;
};
constexpr SizeBounds::SizeBounds() = default;
constexpr SizeBounds::SizeBounds(SizeBound width, SizeBound height)
    : width_(std::move(width)), height_(std::move(height)) {}
constexpr SizeBounds::SizeBounds(const gfx::Size& size)
    : width_(size.width()), height_(size.height()) {}
constexpr SizeBounds::SizeBounds(const SizeBounds&) = default;
constexpr SizeBounds::SizeBounds(SizeBounds&&) = default;
constexpr bool operator<(const SizeBounds& lhs, const SizeBounds& rhs) {
  return std::tie(lhs.height(), lhs.width()) <
         std::tie(rhs.height(), rhs.width());
}

// Returns true if the specified |size| can fit in the specified |bounds|.
// Returns false if either the width or height of |bounds| is specified and is
// smaller than the corresponding element of |size|.
VIEWS_EXPORT bool CanFitInBounds(const gfx::Size& size,
                                 const SizeBounds& bounds);

// These are declared here for use in gtest-based unit tests but is defined in
// the views_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const SizeBounds& size_bounds, ::std::ostream* os);
void PrintTo(LayoutOrientation layout_orientation, ::std::ostream* os);

}  // namespace views

EXPORT_ENUM_CONVERTERS(views::LayoutAlignment, VIEWS_EXPORT)
EXPORT_ENUM_CONVERTERS(views::LayoutOrientation, VIEWS_EXPORT)

#endif  // UI_VIEWS_LAYOUT_LAYOUT_TYPES_H_