blob: 85940c1ab997279a944cbc1fe989d74693820e3e [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_TABS_OVERFLOW_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_OVERFLOW_VIEW_H_
#include <memory>
#include "ui/gfx/geometry/size.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/layout/layout_types.h"
#include "ui/views/view.h"
// Encloses a primary view and shows an overflow indicator (which is a second
// child view) if the overflow view is given less than the other view's minimum
// space.
//
// Provided because FlexLayout is not designed to show additional views as the
// parent view shrinks, but rather to shrink/hide them. It might still be
// possible to approximate this behavior with FlexLayout and creative use of
// FlexRules.
//
// Size of both views is by default interpolated between preferred and minimum
// size, with the indicator taking precedence if present. However you may set
// kFlexBehaviorKey on either or both views to provide different behavior.
//
// Note: currently only FlexSpecification::rule() will currently be respected as
// the other behaviors are implicit in how OverflowView functions. In the future
// we may add support for alignment() on the primary view as well as supporting
// kMarginsKey and kInternalPaddingKey. In the meantime you can simulate these
// by nesting views using the layout of your choice, or adding a border.
//
// TODO(dfried): If this turns out to be usable in multiple places, move to
// ui/views/layout.
class OverflowView : public views::View {
public:
OverflowView(std::unique_ptr<views::View> primary_view,
std::unique_ptr<views::View> indicator_view);
~OverflowView() override;
void SetOrientation(views::LayoutOrientation orientation);
views::LayoutOrientation orientation() const { return orientation_; }
void SetCrossAxisAlignment(views::LayoutAlignment cross_axis_alignment);
views::LayoutAlignment cross_axis_alignment() const {
return cross_axis_alignment_;
}
// View:
void Layout() override;
views::SizeBounds GetAvailableSize(const View* child) const override;
gfx::Size GetMinimumSize() const override;
gfx::Size CalculatePreferredSize() const override;
int GetHeightForWidth(int width) const override;
private:
// Whether the primary and overflow views are arranged horizontally or
// vertically. The overflow view is always placed in the trailing position.
views::LayoutOrientation orientation_ = views::LayoutOrientation::kHorizontal;
// By default stretch the main and overflow indicator views to the cross axis
// size of this view.
views::LayoutAlignment cross_axis_alignment_ =
views::LayoutAlignment::kStretch;
// The primary view to be displayed.
views::View* primary_view_ = nullptr;
// The overflow indicator view to be displayed if the primary view will
// receive less than its minimum size along the main axis.
views::View* indicator_view_ = nullptr;
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_OVERFLOW_VIEW_H_