OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ | 5 #ifndef UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ |
6 #define UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ | 6 #define UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 enum CrossAxisAlignment { | 50 enum CrossAxisAlignment { |
51 // This causes the child view to stretch to fit the host in the cross axis. | 51 // This causes the child view to stretch to fit the host in the cross axis. |
52 CROSS_AXIS_ALIGNMENT_STRETCH, | 52 CROSS_AXIS_ALIGNMENT_STRETCH, |
53 CROSS_AXIS_ALIGNMENT_START, | 53 CROSS_AXIS_ALIGNMENT_START, |
54 CROSS_AXIS_ALIGNMENT_CENTER, | 54 CROSS_AXIS_ALIGNMENT_CENTER, |
55 CROSS_AXIS_ALIGNMENT_END, | 55 CROSS_AXIS_ALIGNMENT_END, |
56 }; | 56 }; |
57 | 57 |
58 // Use |inside_border_insets| to add additional space between the child | 58 // Use |inside_border_insets| to add additional space between the child |
59 // view area and the host view border. |between_child_spacing| controls the | 59 // view area and the host view border. |between_child_spacing| controls the |
60 // space in between child views. | 60 // space in between child views. Use view->SetProperty(kMarginsKey, |
| 61 // new gfx::Insets(xxx)) to add additional margins on a per-view basis. The |
| 62 // |collapse_margins_spacing| parameter controls whether or not adjacent |
| 63 // spacing/margins are collapsed based on the max of the two values. For the |
| 64 // cross axis, |collapse_margins_spacing| will collapse to the max of |
| 65 // inside_border_xxxxx_spacing and the corresponding margin edge from each |
| 66 // view. |
| 67 // |
| 68 // Given the following views where V = view bounds, M = Margins property, |
| 69 // B = between child spacing, S = inside border spacing and |
| 70 // <space> = added margins for alignment |
| 71 // |
| 72 // MMMMM MMVVVVMM MMMM |
| 73 // VVVVM MMMM |
| 74 // VVVVM MMMM |
| 75 // VVVVM VVVV |
| 76 // MMMMM |
| 77 // |
| 78 // With collapse_margins_spacing = false, orientation = kHorizontal, |
| 79 // inside_border_spacing_horizontal = 2, inside_border_spacing_vertical = 2 |
| 80 // and between_child_spacing = 1: |
| 81 // |
| 82 // ----------------------- |
| 83 // SSSSSSSSSSSSSSSSSSSSSSS |
| 84 // SSSSSSSSSSSSSSSSSSSSSSS |
| 85 // SS MBMM MMBMMMMSS |
| 86 // SS MBMM MMBMMMMSS |
| 87 // SSMMMMMBMM MMBMMMMSS |
| 88 // SSVVVVMBMMVVVVMMBVVVVSS |
| 89 // SSVVVVMBMMVVVVMMBVVVVSS |
| 90 // SSVVVVMBMMVVVVMMBVVVVSS |
| 91 // SSMMMMMBMMVVVVMMBVVVVSS |
| 92 // SSSSSSSSSSSSSSSSSSSSSSS |
| 93 // SSSSSSSSSSSSSSSSSSSSSSS |
| 94 // ----------------------- |
| 95 // |
| 96 // Same as above except, collapse_margins_spacing = true. |
| 97 // |
| 98 // -------------------- |
| 99 // SS MMMMMMSS |
| 100 // SS MMMMMMSS |
| 101 // SSMMMMMM MMMMMMSS |
| 102 // SSVVVVMMVVVVMMVVVVSS |
| 103 // SSVVVVMMVVVVMMVVVVSS |
| 104 // SSVVVVMMVVVVMMVVVVSS |
| 105 // SSSSSSSSSSSSSSSSSSSS |
| 106 // SSSSSSSSSSSSSSSSSSSS |
| 107 // -------------------- |
| 108 // |
61 BoxLayout(Orientation orientation, | 109 BoxLayout(Orientation orientation, |
62 const gfx::Insets& inside_border_insets = gfx::Insets(), | 110 const gfx::Insets& inside_border_insets = gfx::Insets(), |
63 int between_child_spacing = 0); | 111 int between_child_spacing = 0, |
| 112 bool collapse_margins_spacing = false); |
64 ~BoxLayout() override; | 113 ~BoxLayout() override; |
65 | 114 |
66 void set_main_axis_alignment(MainAxisAlignment main_axis_alignment) { | 115 void set_main_axis_alignment(MainAxisAlignment main_axis_alignment) { |
67 main_axis_alignment_ = main_axis_alignment; | 116 main_axis_alignment_ = main_axis_alignment; |
68 } | 117 } |
69 | 118 |
70 void set_cross_axis_alignment(CrossAxisAlignment cross_axis_alignment) { | 119 void set_cross_axis_alignment(CrossAxisAlignment cross_axis_alignment) { |
71 cross_axis_alignment_ = cross_axis_alignment; | 120 cross_axis_alignment_ = cross_axis_alignment; |
72 } | 121 } |
73 | 122 |
(...skipping 22 matching lines...) Expand all Loading... |
96 void SetDefaultFlex(int default_flex); | 145 void SetDefaultFlex(int default_flex); |
97 | 146 |
98 // Overridden from views::LayoutManager: | 147 // Overridden from views::LayoutManager: |
99 void Installed(View* host) override; | 148 void Installed(View* host) override; |
100 void ViewRemoved(View* host, View* view) override; | 149 void ViewRemoved(View* host, View* view) override; |
101 void Layout(View* host) override; | 150 void Layout(View* host) override; |
102 gfx::Size GetPreferredSize(const View* host) const override; | 151 gfx::Size GetPreferredSize(const View* host) const override; |
103 int GetPreferredHeightForWidth(const View* host, int width) const override; | 152 int GetPreferredHeightForWidth(const View* host, int width) const override; |
104 | 153 |
105 private: | 154 private: |
| 155 // This struct is used internally to "wrap" a child view in order to obviate |
| 156 // the need for the main layout logic to be fully aware of the per-view |
| 157 // margins when |collapse_margin_spacing_| is false. Since each view is a |
| 158 // rectangle of a certain size, this wrapper, coupled with any margins set |
| 159 // will increase the apparent size of the view along the main axis. All |
| 160 // necessary view size/position methods required for the layout logic add or |
| 161 // subtract the margins where appropriate to ensure the actual visible size of |
| 162 // the view doesn't include the margins. For the cross axis, the margins are |
| 163 // NOT included in the size/position calculations. BoxLayout will adjust the |
| 164 // bounding rectangle of the space used for layout using the maximum margin |
| 165 // for all views along the appropriate edge. |
| 166 // When |collapse_margin_spacing_| is true, this wrapper provides quick access |
| 167 // to the view's margins for use by the layout to collapse adjacent spacing |
| 168 // to the largest of the several values. |
| 169 class ViewWrapper { |
| 170 public: |
| 171 ViewWrapper(); |
| 172 ViewWrapper(const BoxLayout* layout, View* view); |
| 173 ~ViewWrapper(); |
| 174 |
| 175 int GetHeightForWidth(int width) const; |
| 176 const gfx::Insets& margins() const { return margins_; } |
| 177 gfx::Size GetPreferredSize() const; |
| 178 void SetBoundsRect(const gfx::Rect& bounds); |
| 179 View* view() const { return view_; } |
| 180 bool visible() const; |
| 181 |
| 182 private: |
| 183 View* view_; |
| 184 const BoxLayout* layout_; |
| 185 gfx::Insets margins_; |
| 186 |
| 187 DISALLOW_COPY_AND_ASSIGN(ViewWrapper); |
| 188 }; |
| 189 |
| 190 using FlexMap = std::map<const View*, int>; |
| 191 |
106 // Returns the flex for the specified |view|. | 192 // Returns the flex for the specified |view|. |
107 int GetFlexForView(const View* view) const; | 193 int GetFlexForView(const View* view) const; |
108 | 194 |
109 // Returns the size and position along the main axis of |rect|. | 195 // Returns the size and position along the main axis of |rect|. |
110 int MainAxisSize(const gfx::Rect& rect) const; | 196 int MainAxisSize(const gfx::Rect& rect) const; |
111 int MainAxisPosition(const gfx::Rect& rect) const; | 197 int MainAxisPosition(const gfx::Rect& rect) const; |
112 | 198 |
113 // Sets the size and position along the main axis of |rect|. | 199 // Sets the size and position along the main axis of |rect|. |
114 void SetMainAxisSize(int size, gfx::Rect* rect) const; | 200 void SetMainAxisSize(int size, gfx::Rect* rect) const; |
115 void SetMainAxisPosition(int position, gfx::Rect* rect) const; | 201 void SetMainAxisPosition(int position, gfx::Rect* rect) const; |
116 | 202 |
117 // Returns the size and position along the cross axis of |rect|. | 203 // Returns the size and position along the cross axis of |rect|. |
118 int CrossAxisSize(const gfx::Rect& rect) const; | 204 int CrossAxisSize(const gfx::Rect& rect) const; |
119 int CrossAxisPosition(const gfx::Rect& rect) const; | 205 int CrossAxisPosition(const gfx::Rect& rect) const; |
120 | 206 |
121 // Sets the size and position along the cross axis of |rect|. | 207 // Sets the size and position along the cross axis of |rect|. |
122 void SetCrossAxisSize(int size, gfx::Rect* rect) const; | 208 void SetCrossAxisSize(int size, gfx::Rect* rect) const; |
123 void SetCrossAxisPosition(int size, gfx::Rect* rect) const; | 209 void SetCrossAxisPosition(int size, gfx::Rect* rect) const; |
124 | 210 |
125 // Returns the main axis size for the given view. |child_area_width| is needed | 211 // Returns the main axis size for the given view. |child_area_width| is needed |
126 // to calculate the height of the view when the orientation is vertical. | 212 // to calculate the height of the view when the orientation is vertical. |
127 int MainAxisSizeForView(const View* view, int child_area_width) const; | 213 int MainAxisSizeForView(const ViewWrapper& view, int child_area_width) const; |
| 214 |
| 215 // Returns the |left| or |top| edge of the given inset based on the value of |
| 216 // |orientation_|. |
| 217 int MainAxisLeadingInset(const gfx::Insets& insets) const; |
| 218 |
| 219 // Returns the |right| or |bottom| edge of the given inset based on the value |
| 220 // of |orientation_|. |
| 221 int MainAxisTrailingInset(const gfx::Insets& insets) const; |
| 222 |
| 223 // Returns the left (|x|) or top (|y|) edge of the given rect based on the |
| 224 // value of |orientation_|. |
| 225 int CrossAxisLeadingEdge(const gfx::Rect& rect) const; |
| 226 |
| 227 // Returns the |left| or |top| edge of the given inset based on the value of |
| 228 // |orientation_|. |
| 229 int CrossAxisLeadingInset(const gfx::Insets& insets) const; |
| 230 |
| 231 // Returns the |right| or |bottom| edge of the given inset based on the value |
| 232 // of |orientation_|. |
| 233 int CrossAxisTrailingInset(const gfx::Insets& insets) const; |
| 234 |
| 235 // Returns the main axis margin spacing between the two views which is the max |
| 236 // of the right margin from the |left| view, the left margin of the |right| |
| 237 // view and |between_child_spacing_|. |
| 238 int MainAxisMarginBetweenViews(const ViewWrapper& left, |
| 239 const ViewWrapper& right) const; |
| 240 |
| 241 // Returns the outer margin along the main axis as insets. |
| 242 gfx::Insets MainAxisOuterMargin() const; |
| 243 |
| 244 // Returns the maximum margin along the cross axis from all views as insets. |
| 245 gfx::Insets CrossAxisMaxViewMargin() const; |
| 246 |
| 247 // Adjusts the main axis for |rect| by collapsing the left or top margin of |
| 248 // the first view with corresponding side of |inside_border_insets_| and the |
| 249 // right or bottom margin of the last view with the corresponding side of |
| 250 // |inside_border_insets_|. |
| 251 void AdjustMainAxisForMargin(gfx::Rect* rect) const; |
| 252 |
| 253 // Adjust the cross axis for |rect| using the appropriate sides of |
| 254 // |inside_border_insets_|. |
| 255 void AdjustCrossAxisForInsets(gfx::Rect* rect) const; |
128 | 256 |
129 // Returns the cross axis size for the given view. | 257 // Returns the cross axis size for the given view. |
130 int CrossAxisSizeForView(const View* view) const; | 258 int CrossAxisSizeForView(const ViewWrapper& view) const; |
| 259 |
| 260 // Returns the total margin width for the given view or 0 when |
| 261 // collapse_margins_spacing_ is true. |
| 262 int CrossAxisMarginSizeForView(const ViewWrapper& view) const; |
| 263 |
| 264 // Returns the Top or Left size of the margin for the given view or 0 when |
| 265 // collapse_margins_spacing_ is true. |
| 266 int CrossAxisLeadingMarginForView(const ViewWrapper& view) const; |
| 267 |
| 268 // Adjust the cross axis for |rect| using the given leading and trailing |
| 269 // values. |
| 270 void InsetCrossAxis(gfx::Rect* rect, int leading, int trailing) const; |
131 | 271 |
132 // The preferred size for the dialog given the width of the child area. | 272 // The preferred size for the dialog given the width of the child area. |
133 gfx::Size GetPreferredSizeForChildWidth(const View* host, | 273 gfx::Size GetPreferredSizeForChildWidth(const View* host, |
134 int child_area_width) const; | 274 int child_area_width) const; |
135 | 275 |
136 // The amount of space the layout requires in addition to any space for the | 276 // The amount of space the layout requires in addition to any space for the |
137 // child views. | 277 // child views. |
138 gfx::Size NonChildSize(const View* host) const; | 278 gfx::Size NonChildSize(const View* host) const; |
139 | 279 |
| 280 // The next visible view at > index. If no other views are visible, return |
| 281 // nullptr. |
| 282 View* NextVisibleView(int index) const; |
| 283 |
| 284 // Return the first visible view in the host or nullptr if none are visible. |
| 285 View* FirstVisibleView() const; |
| 286 |
| 287 // Return the last visible view in the host or nullptr if none are visible. |
| 288 View* LastVisibleView() const; |
| 289 |
140 const Orientation orientation_; | 290 const Orientation orientation_; |
141 | 291 |
142 // Spacing between child views and host view border. | 292 // Spacing between child views and host view border. |
143 gfx::Insets inside_border_insets_; | 293 gfx::Insets inside_border_insets_; |
144 | 294 |
145 // Spacing to put in between child views. | 295 // Spacing to put in between child views. |
146 const int between_child_spacing_; | 296 const int between_child_spacing_; |
147 | 297 |
148 // The alignment of children in the main axis. This is | 298 // The alignment of children in the main axis. This is |
149 // MAIN_AXIS_ALIGNMENT_START by default. | 299 // MAIN_AXIS_ALIGNMENT_START by default. |
150 MainAxisAlignment main_axis_alignment_; | 300 MainAxisAlignment main_axis_alignment_; |
151 | 301 |
152 // The alignment of children in the cross axis. This is | 302 // The alignment of children in the cross axis. This is |
153 // CROSS_AXIS_ALIGNMENT_STRETCH by default. | 303 // CROSS_AXIS_ALIGNMENT_STRETCH by default. |
154 CrossAxisAlignment cross_axis_alignment_; | 304 CrossAxisAlignment cross_axis_alignment_; |
155 | 305 |
156 // A map of views to their flex weights. | 306 // A map of views to their flex weights. |
157 std::map<const View*, int> flex_map_; | 307 FlexMap flex_map_; |
158 | 308 |
159 // The flex weight for views if none is set. Defaults to 0. | 309 // The flex weight for views if none is set. Defaults to 0. |
160 int default_flex_; | 310 int default_flex_; |
161 | 311 |
162 // The minimum cross axis size for the layout. | 312 // The minimum cross axis size for the layout. |
163 int minimum_cross_axis_size_; | 313 int minimum_cross_axis_size_; |
164 | 314 |
| 315 // Adjacent view margins and spacing should be collapsed. |
| 316 const bool collapse_margins_spacing_; |
| 317 |
165 // The view that this BoxLayout is managing the layout for. | 318 // The view that this BoxLayout is managing the layout for. |
166 views::View* host_; | 319 views::View* host_; |
167 | 320 |
168 DISALLOW_IMPLICIT_CONSTRUCTORS(BoxLayout); | 321 DISALLOW_IMPLICIT_CONSTRUCTORS(BoxLayout); |
169 }; | 322 }; |
170 | 323 |
171 } // namespace views | 324 } // namespace views |
172 | 325 |
173 #endif // UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ | 326 #endif // UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ |
OLD | NEW |