Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: ui/views/layout/box_layout.h

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

Powered by Google App Engine
This is Rietveld 408576698