Chromium Code Reviews| 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" |
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |