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

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

Issue 2836313002: BoxLayout now suports per-view margins. (Closed)
Patch Set: Added margin collapsing and a BoxLayout example Created 3 years, 7 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"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "ui/gfx/geometry/insets.h" 12 #include "ui/gfx/geometry/insets.h"
13 #include "ui/views/layout/layout_manager.h" 13 #include "ui/views/layout/layout_manager.h"
14 14
15 namespace gfx { 15 namespace gfx {
16 class Rect; 16 class Rect;
17 class Size; 17 class Size;
18 } 18 }
19 19
20 namespace views { 20 namespace views {
21 21
22 class View; 22 class View;
23 23
24 // A Layout manager that arranges child views vertically or horizontally in a 24 // A Layout manager that arranges child views vertically or horizontally in a
25 // side-by-side fashion with spacing around and between the child views. The 25 // side-by-side fashion with spacing around and between the child views. The
26 // child views are always sized according to their preferred size. If the 26 // child views are always sized according to their preferred size. If the
27 // host's bounds provide insufficient space, child views will be clamped. 27 // host's bounds provide insufficient space, child views will be clamped.
28 // Excess space will not be distributed. 28 // Excess space will not be distributed.
29 class VIEWS_EXPORT BoxLayout : public LayoutManager { 29 class VIEWS_EXPORT BoxLayout : public LayoutManager {
sky 2017/05/09 19:26:03 You should make this class a ViewObserver on the v
30 public: 30 public:
31 enum Orientation { 31 enum Orientation {
32 kHorizontal, 32 kHorizontal,
33 kVertical, 33 kVertical,
34 }; 34 };
35 35
36 // This specifies where along the main axis the children should be laid out. 36 // This specifies where along the main axis the children should be laid out.
37 // e.g. a horizontal layout of MAIN_AXIS_ALIGNMENT_END will result in the 37 // e.g. a horizontal layout of MAIN_AXIS_ALIGNMENT_END will result in the
38 // child views being right-aligned. 38 // child views being right-aligned.
39 enum MainAxisAlignment { 39 enum MainAxisAlignment {
(...skipping 16 matching lines...) Expand all
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.
62 BoxLayout(Orientation orientation, 62 BoxLayout(Orientation orientation,
63 int inside_border_horizontal_spacing, 63 int inside_border_horizontal_spacing,
64 int inside_border_vertical_spacing, 64 int inside_border_vertical_spacing,
65 int between_child_spacing); 65 int between_child_spacing);
66 // As above but with added |collapse_margins_spacing| paramter which controls
67 // whether or not spacing adjacent to view margins are collapsed base on the
68 // max of the two values.
69 BoxLayout(Orientation orientation,
70 int inside_border_horizontal_spacing,
71 int inside_border_vertical_spacing,
72 int between_child_spacing,
73 bool collapse_margins_spacing);
sky 2017/05/09 19:26:03 Merge this with other constructor and make collaps
kylix_rd 2017/05/09 20:07:06 I'm wondering if the default should be "true". It
sky 2017/05/09 23:55:29 I think existing consumers should have to opt into
kylix_rd 2017/05/10 15:30:37 Done.
66 ~BoxLayout() override; 74 ~BoxLayout() override;
67 75
68 void set_main_axis_alignment(MainAxisAlignment main_axis_alignment) { 76 void set_main_axis_alignment(MainAxisAlignment main_axis_alignment) {
69 main_axis_alignment_ = main_axis_alignment; 77 main_axis_alignment_ = main_axis_alignment;
70 } 78 }
71 79
72 void set_cross_axis_alignment(CrossAxisAlignment cross_axis_alignment) { 80 void set_cross_axis_alignment(CrossAxisAlignment cross_axis_alignment) {
73 cross_axis_alignment_ = cross_axis_alignment; 81 cross_axis_alignment_ = cross_axis_alignment;
74 } 82 }
75 83
(...skipping 22 matching lines...) Expand all
98 void SetDefaultFlex(int default_flex); 106 void SetDefaultFlex(int default_flex);
99 107
100 // Overridden from views::LayoutManager: 108 // Overridden from views::LayoutManager:
101 void Installed(View* host) override; 109 void Installed(View* host) override;
102 void ViewRemoved(View* host, View* view) override; 110 void ViewRemoved(View* host, View* view) override;
103 void Layout(View* host) override; 111 void Layout(View* host) override;
104 gfx::Size GetPreferredSize(const View* host) const override; 112 gfx::Size GetPreferredSize(const View* host) const override;
105 int GetPreferredHeightForWidth(const View* host, int width) const override; 113 int GetPreferredHeightForWidth(const View* host, int width) const override;
106 114
107 private: 115 private:
116 // This struct is used internally to "wrap" a child view in order to obviate
sky 2017/05/09 19:26:03 Thanks for the detailed comments!
117 // the need for the main layout logic to be fully aware of the per-view
118 // margins when |collapse_margin_spacing_| is false. Since each view is a
119 // rectangle of a certain size, this wrapper, coupled with any margins set
120 // will increase the apparent size of the view. All necessary view size/
121 // position methods required for the layout logic add or subtract the margins
122 // where appropriate to ensure the actual visible size of the view doesn't
123 // include the margins.
124 // When |collapse_margin_spacing_| is true, this wrapper provides quick access
125 // to the view's margins for use by the layout to collapse adjacent spacing
126 // to the largest of the several values.
127 struct ViewWrapper {
sky 2017/05/09 19:26:03 Style guide says, "Use a struct only for passive o
kylix_rd 2017/05/09 20:07:06 Sure thing. This comes from my notion that "class
kylix_rd 2017/05/10 15:30:37 Done.
128 ViewWrapper();
129 ViewWrapper(const BoxLayout* layout, View* view);
130 ViewWrapper(const ViewWrapper& wrapper) = delete;
131 ~ViewWrapper();
132 int GetHeightForWidth(int width) const;
133 const gfx::Insets& margins() const { return margins_; }
134 gfx::Size GetPreferredSize() const;
135 void SetBoundsRect(const gfx::Rect& bounds);
136 View* view() const { return view_; }
137 bool visible() const;
138
139 private:
140 View* view_;
141 const BoxLayout* layout_;
142 gfx::Insets margins_;
143 };
144
145 using FlexMap = std::map<const View*, int>;
146
108 // Returns the flex for the specified |view|. 147 // Returns the flex for the specified |view|.
109 int GetFlexForView(const View* view) const; 148 int GetFlexForView(const View* view) const;
110 149
111 // Returns the size and position along the main axis of |rect|. 150 // Returns the size and position along the main axis of |rect|.
112 int MainAxisSize(const gfx::Rect& rect) const; 151 int MainAxisSize(const gfx::Rect& rect) const;
113 int MainAxisPosition(const gfx::Rect& rect) const; 152 int MainAxisPosition(const gfx::Rect& rect) const;
114 153
115 // Sets the size and position along the main axis of |rect|. 154 // Sets the size and position along the main axis of |rect|.
116 void SetMainAxisSize(int size, gfx::Rect* rect) const; 155 void SetMainAxisSize(int size, gfx::Rect* rect) const;
117 void SetMainAxisPosition(int position, gfx::Rect* rect) const; 156 void SetMainAxisPosition(int position, gfx::Rect* rect) const;
118 157
119 // Returns the size and position along the cross axis of |rect|. 158 // Returns the size and position along the cross axis of |rect|.
120 int CrossAxisSize(const gfx::Rect& rect) const; 159 int CrossAxisSize(const gfx::Rect& rect) const;
121 int CrossAxisPosition(const gfx::Rect& rect) const; 160 int CrossAxisPosition(const gfx::Rect& rect) const;
122 161
123 // Sets the size and position along the cross axis of |rect|. 162 // Sets the size and position along the cross axis of |rect|.
124 void SetCrossAxisSize(int size, gfx::Rect* rect) const; 163 void SetCrossAxisSize(int size, gfx::Rect* rect) const;
125 void SetCrossAxisPosition(int size, gfx::Rect* rect) const; 164 void SetCrossAxisPosition(int size, gfx::Rect* rect) const;
126 165
127 // Returns the main axis size for the given view. |child_area_width| is needed 166 // 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. 167 // to calculate the height of the view when the orientation is vertical.
129 int MainAxisSizeForView(const View* view, int child_area_width) const; 168 int MainAxisSizeForView(const ViewWrapper& view, int child_area_width) const;
169
170 // Returns the main axis margin spacing between the two views which is the max
171 // of the right margin from the |left| view, the left margin of the |right|
172 // view and |between_child_spacing_|.
173 int MainAxisMarginBetweenViews(const ViewWrapper& left,
174 const ViewWrapper& right) const;
175
176 // Adjusts the main axis for |rect| by optionally collapsing the
177 // left or top margin of the first view with corresponding side of
178 // |inside_border_insets_| and the right or bottom margin of the last view
179 // with the corresponding side of |inside_border_insets_|.
180 void AdjustMainAxisForMargin(gfx::Rect* rect) const;
181
182 // Adjust the cross axis of |rect| by optionally collapsing the closest margin
183 // of |control| with the corresponding side of |inside_border_insets_|
184 void AdjustCrossAxisForMargin(const ViewWrapper& child,
185 const gfx::Rect& client,
186 gfx::Rect* rect) const;
130 187
131 // Returns the cross axis size for the given view. 188 // Returns the cross axis size for the given view.
132 int CrossAxisSizeForView(const View* view) const; 189 int CrossAxisSizeForView(const ViewWrapper& view) const;
133 190
134 // The preferred size for the dialog given the width of the child area. 191 // The preferred size for the dialog given the width of the child area.
135 gfx::Size GetPreferredSizeForChildWidth(const View* host, 192 gfx::Size GetPreferredSizeForChildWidth(const View* host,
136 int child_area_width) const; 193 int child_area_width) const;
137 194
138 // The amount of space the layout requires in addition to any space for the 195 // The amount of space the layout requires in addition to any space for the
139 // child views. 196 // child views.
140 gfx::Size NonChildSize(const View* host) const; 197 gfx::Size NonChildSize(const View* host) const;
141 198
199 // The next visible view at > index. If no other views are visible, return
200 // nullptr.
201 View* NextVisibleView(View* host, int index) const;
202
203 // Return the first visible view in the host or nullptr if none are visible.
204 View* FirstVisibleView(View* host) const;
205
206 // Return the last visible view in the host or nullptr if none are visible.
207 View* LastVisibleView(View* host) const;
208
142 const Orientation orientation_; 209 const Orientation orientation_;
143 210
144 // Spacing between child views and host view border. 211 // Spacing between child views and host view border.
145 gfx::Insets inside_border_insets_; 212 gfx::Insets inside_border_insets_;
146 213
147 // Spacing to put in between child views. 214 // Spacing to put in between child views.
148 const int between_child_spacing_; 215 const int between_child_spacing_;
149 216
150 // The alignment of children in the main axis. This is 217 // The alignment of children in the main axis. This is
151 // MAIN_AXIS_ALIGNMENT_START by default. 218 // MAIN_AXIS_ALIGNMENT_START by default.
152 MainAxisAlignment main_axis_alignment_; 219 MainAxisAlignment main_axis_alignment_;
153 220
154 // The alignment of children in the cross axis. This is 221 // The alignment of children in the cross axis. This is
155 // CROSS_AXIS_ALIGNMENT_STRETCH by default. 222 // CROSS_AXIS_ALIGNMENT_STRETCH by default.
156 CrossAxisAlignment cross_axis_alignment_; 223 CrossAxisAlignment cross_axis_alignment_;
157 224
158 // A map of views to their flex weights. 225 // A map of views to their flex weights.
159 std::map<const View*, int> flex_map_; 226 FlexMap flex_map_;
160 227
161 // The flex weight for views if none is set. Defaults to 0. 228 // The flex weight for views if none is set. Defaults to 0.
162 int default_flex_; 229 int default_flex_;
163 230
164 // The minimum cross axis size for the layout. 231 // The minimum cross axis size for the layout.
165 int minimum_cross_axis_size_; 232 int minimum_cross_axis_size_;
166 233
234 // Adjacent view margins and spacing should be collapsed.
235 bool collapse_margins_spacing_;
sky 2017/05/09 19:26:03 const
kylix_rd 2017/05/10 15:30:37 Done.
236
167 // The view that this BoxLayout is managing the layout for. 237 // The view that this BoxLayout is managing the layout for.
168 views::View* host_; 238 views::View* host_;
169 239
170 DISALLOW_IMPLICIT_CONSTRUCTORS(BoxLayout); 240 DISALLOW_IMPLICIT_CONSTRUCTORS(BoxLayout);
171 }; 241 };
172 242
173 } // namespace views 243 } // namespace views
174 244
175 #endif // UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ 245 #endif // UI_VIEWS_LAYOUT_BOX_LAYOUT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698