| Index: ui/views/layout/box_layout.h
|
| diff --git a/ui/views/layout/box_layout.h b/ui/views/layout/box_layout.h
|
| index 9a87984d51f77cec0caa488860fa6dc1986f9e28..0b054fa879da4a732b1e1b66239883168bf69f33 100644
|
| --- a/ui/views/layout/box_layout.h
|
| +++ b/ui/views/layout/box_layout.h
|
| @@ -58,11 +58,57 @@ class VIEWS_EXPORT BoxLayout : public LayoutManager {
|
| // Use |inside_border_horizontal_spacing| and
|
| // |inside_border_vertical_spacing| to add additional space between the child
|
| // view area and the host view border. |between_child_spacing| controls the
|
| - // space in between child views.
|
| + // space in between child views. Use view->SetProperty(kMarginsKey,
|
| + // new gfx::Insets(xxx)) to add additional margins on a per-view basis. The
|
| + // |collapse_margins_spacing| parameter controls whether or not spacing
|
| + // adjacent to view margins are collapsed base on the max of the two values.
|
| + //
|
| + // Given the following views where V = view bounds, M = Margins property,
|
| + // B = between child spacing, S = inside border spacing and
|
| + // <space> = added margins for alignment
|
| + //
|
| + // MMMMM MMVVVVMM MMMM
|
| + // VVVVM MMMM
|
| + // VVVVM MMMM
|
| + // VVVVM VVVV
|
| + // MMMMM
|
| + //
|
| + // With collapse_margins_spacing = false, orientation = kHorizontal,
|
| + // inside_border_spacing_horizontal = 2, inside_border_spacing_vertical = 2
|
| + // and between_child_spacing = 1:
|
| + //
|
| + // -----------------------
|
| + // SSSSSSSSSSSSSSSSSSSSSSS
|
| + // SSSSSSSSSSSSSSSSSSSSSSS
|
| + // SS MBMM MMBMMMMSS
|
| + // SS MBMM MMBMMMMSS
|
| + // SSMMMMMBMM MMBMMMMSS
|
| + // SSVVVVMBMMVVVVMMBVVVVSS
|
| + // SSVVVVMBMMVVVVMMBVVVVSS
|
| + // SSVVVVMBMMVVVVMMBVVVVSS
|
| + // SSMMMMMBMMVVVVMMBVVVVSS
|
| + // SSSSSSSSSSSSSSSSSSSSSSS
|
| + // SSSSSSSSSSSSSSSSSSSSSSS
|
| + // -----------------------
|
| + //
|
| + // Same as above except, collapse_margins_spacing = true.
|
| + //
|
| + // --------------------
|
| + // SS MMMMMMSS
|
| + // SS MMMMMMSS
|
| + // SSMMMMMM MMMMMMSS
|
| + // SSVVVVMMVVVVMMVVVVSS
|
| + // SSVVVVMMVVVVMMVVVVSS
|
| + // SSVVVVMMVVVVMMVVVVSS
|
| + // SSSSSSSSSSSSSSSSSSSS
|
| + // SSSSSSSSSSSSSSSSSSSS
|
| + // --------------------
|
| + //
|
| BoxLayout(Orientation orientation,
|
| int inside_border_horizontal_spacing,
|
| int inside_border_vertical_spacing,
|
| - int between_child_spacing);
|
| + int between_child_spacing,
|
| + bool collapse_margins_spacing = false);
|
| ~BoxLayout() override;
|
|
|
| void set_main_axis_alignment(MainAxisAlignment main_axis_alignment) {
|
| @@ -105,6 +151,43 @@ class VIEWS_EXPORT BoxLayout : public LayoutManager {
|
| int GetPreferredHeightForWidth(const View* host, int width) const override;
|
|
|
| private:
|
| + // This struct is used internally to "wrap" a child view in order to obviate
|
| + // the need for the main layout logic to be fully aware of the per-view
|
| + // margins when |collapse_margin_spacing_| is false. Since each view is a
|
| + // rectangle of a certain size, this wrapper, coupled with any margins set
|
| + // will increase the apparent size of the view along the main axis. All
|
| + // necessary view size/position methods required for the layout logic add or
|
| + // subtract the margins where appropriate to ensure the actual visible size of
|
| + // the view doesn't include the margins. For the cross axis, the margins are
|
| + // NOT included in the size/position calculations. BoxLayout will adjust the
|
| + // bounding rectangle of the space used for layout using the maximum margin
|
| + // for all views along the appropriate edge.
|
| + // When |collapse_margin_spacing_| is true, this wrapper provides quick access
|
| + // to the view's margins for use by the layout to collapse adjacent spacing
|
| + // to the largest of the several values.
|
| + class ViewWrapper {
|
| + public:
|
| + ViewWrapper();
|
| + ViewWrapper(const BoxLayout* layout, View* view);
|
| + ~ViewWrapper();
|
| + int GetHeightForWidth(int width) const;
|
| + const gfx::Insets& margins() const { return margins_; }
|
| + gfx::Size GetPreferredSize() const;
|
| + void SetBoundsRect(const gfx::Rect& bounds);
|
| + View* view() const { return view_; }
|
| + bool visible() const;
|
| +
|
| + private:
|
| + View* view_;
|
| + const BoxLayout* layout_;
|
| + const Orientation orientation_;
|
| + gfx::Insets margins_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ViewWrapper);
|
| + };
|
| +
|
| + using FlexMap = std::map<const View*, int>;
|
| +
|
| // Returns the flex for the specified |view|.
|
| int GetFlexForView(const View* view) const;
|
|
|
| @@ -126,10 +209,36 @@ class VIEWS_EXPORT BoxLayout : public LayoutManager {
|
|
|
| // Returns the main axis size for the given view. |child_area_width| is needed
|
| // to calculate the height of the view when the orientation is vertical.
|
| - int MainAxisSizeForView(const View* view, int child_area_width) const;
|
| + int MainAxisSizeForView(const ViewWrapper& view, int child_area_width) const;
|
| +
|
| + // Returns the main axis margin spacing between the two views which is the max
|
| + // of the right margin from the |left| view, the left margin of the |right|
|
| + // view and |between_child_spacing_|.
|
| + int MainAxisMarginBetweenViews(const ViewWrapper& left,
|
| + const ViewWrapper& right) const;
|
| +
|
| + // Return the outer margin along the main axis as insets.
|
| + gfx::Insets MainAxisOuterMargin() const;
|
| +
|
| + // Return the maximum margin along the cross axis from all views as insets.
|
| + gfx::Insets CrossAxisMaxViewMargin() const;
|
| +
|
| + // Return the outer margin along the cross axis as insets.
|
| + gfx::Insets CrossAxisOuterMargin() const;
|
| +
|
| + // Adjusts the main axis for |rect| by collapsing the left or top margin of
|
| + // the first view with corresponding side of |inside_border_insets_| and the
|
| + // right or bottom margin of the last view with the corresponding side of
|
| + // |inside_border_insets_|.
|
| + void AdjustMainAxisForMargin(gfx::Rect* rect) const;
|
| +
|
| + // Adjust the cross axis of |rect| by collapsing the max of the cross axis
|
| + // margins of all children and the corresponding side of
|
| + // |inside_border_insets_|
|
| + void AdjustCrossAxisForMargin(gfx::Rect* rect) const;
|
|
|
| // Returns the cross axis size for the given view.
|
| - int CrossAxisSizeForView(const View* view) const;
|
| + int CrossAxisSizeForView(const ViewWrapper& view) const;
|
|
|
| // The preferred size for the dialog given the width of the child area.
|
| gfx::Size GetPreferredSizeForChildWidth(const View* host,
|
| @@ -139,6 +248,16 @@ class VIEWS_EXPORT BoxLayout : public LayoutManager {
|
| // child views.
|
| gfx::Size NonChildSize(const View* host) const;
|
|
|
| + // The next visible view at > index. If no other views are visible, return
|
| + // nullptr.
|
| + View* NextVisibleView(int index) const;
|
| +
|
| + // Return the first visible view in the host or nullptr if none are visible.
|
| + View* FirstVisibleView() const;
|
| +
|
| + // Return the last visible view in the host or nullptr if none are visible.
|
| + View* LastVisibleView() const;
|
| +
|
| const Orientation orientation_;
|
|
|
| // Spacing between child views and host view border.
|
| @@ -156,7 +275,7 @@ class VIEWS_EXPORT BoxLayout : public LayoutManager {
|
| CrossAxisAlignment cross_axis_alignment_;
|
|
|
| // A map of views to their flex weights.
|
| - std::map<const View*, int> flex_map_;
|
| + FlexMap flex_map_;
|
|
|
| // The flex weight for views if none is set. Defaults to 0.
|
| int default_flex_;
|
| @@ -164,6 +283,9 @@ class VIEWS_EXPORT BoxLayout : public LayoutManager {
|
| // The minimum cross axis size for the layout.
|
| int minimum_cross_axis_size_;
|
|
|
| + // Adjacent view margins and spacing should be collapsed.
|
| + const bool collapse_margins_spacing_;
|
| +
|
| // The view that this BoxLayout is managing the layout for.
|
| views::View* host_;
|
|
|
|
|