#include "ui/views/layout/flex_layout.h"
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "ui/base/class_property.h"
#include "ui/events/event_target.h"
#include "ui/events/event_target_iterator.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/tabbed_pane/tabbed_pane.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/layout/normalized_geometry.h"
#include "ui/views/layout/proposed_layout.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"
namespace views {
namespace {
struct FlexChildData { … };
template <typename T>
T GetViewProperty(const View* view,
const ui::PropertyHandler& defaults,
const ui::ClassProperty<T*>* property,
bool* is_default = nullptr) { … }
template <typename T>
T MaybeReverse(const T& list, FlexAllocationOrder order) { … }
}
constexpr LayoutAlignment FlexLayout::kDefaultMainAxisAlignment;
constexpr LayoutAlignment FlexLayout::kDefaultCrossAxisAlignment;
class FlexLayout::ChildViewSpacing { … };
FlexLayout::ChildViewSpacing::ChildViewSpacing(
GetViewSpacingCallback get_view_spacing)
: … { … }
bool FlexLayout::ChildViewSpacing::HasViewIndex(size_t view_index) const { … }
int FlexLayout::ChildViewSpacing::GetLeadingInset() const { … }
int FlexLayout::ChildViewSpacing::GetTrailingInset() const { … }
int FlexLayout::ChildViewSpacing::GetLeadingSpace(size_t view_index) const { … }
int FlexLayout::ChildViewSpacing::GetTotalSpace() const { … }
SizeBound FlexLayout::ChildViewSpacing::GetMaxSize(
size_t view_index,
int current_size,
const SizeBound& available_space) const { … }
int FlexLayout::ChildViewSpacing::GetTotalSizeChangeForNewSize(
size_t view_index,
int current_size,
int new_size) const { … }
void FlexLayout::ChildViewSpacing::AddViewIndex(size_t view_index,
int* new_leading,
int* new_trailing) { … }
std::optional<size_t> FlexLayout::ChildViewSpacing::GetPreviousViewIndex(
size_t view_index) const { … }
std::optional<size_t> FlexLayout::ChildViewSpacing::GetNextViewIndex(
size_t view_index) const { … }
int FlexLayout::ChildViewSpacing::GetAddDelta(size_t view_index) const { … }
struct FlexLayout::FlexLayoutData { … };
FlexLayout::PropertyHandler::PropertyHandler(FlexLayout* layout)
: … { … }
void FlexLayout::PropertyHandler::AfterPropertyChange(const void* key,
int64_t old_value) { … }
FlexLayout::FlexLayout() { … }
FlexLayout::~FlexLayout() = default;
FlexLayout& FlexLayout::SetOrientation(LayoutOrientation orientation) { … }
FlexLayout& FlexLayout::SetIncludeHostInsetsInLayout(
bool include_host_insets_in_layout) { … }
FlexLayout& FlexLayout::SetCollapseMargins(bool collapse_margins) { … }
FlexLayout& FlexLayout::SetMainAxisAlignment(
LayoutAlignment main_axis_alignment) { … }
FlexLayout& FlexLayout::SetCrossAxisAlignment(
LayoutAlignment cross_axis_alignment) { … }
FlexLayout& FlexLayout::SetInteriorMargin(const gfx::Insets& interior_margin) { … }
FlexLayout& FlexLayout::SetIgnoreDefaultMainAxisMargins(
bool ignore_default_main_axis_margins) { … }
FlexLayout& FlexLayout::SetMinimumCrossAxisSize(int size) { … }
FlexLayout& FlexLayout::SetFlexAllocationOrder(
FlexAllocationOrder flex_allocation_order) { … }
FlexRule FlexLayout::GetDefaultFlexRule() const { … }
ProposedLayout FlexLayout::CalculateProposedLayout(
const SizeBounds& size_bounds) const { … }
NormalizedSize FlexLayout::GetPreferredSizeForRule(
const FlexRule& rule,
const View* child,
const SizeBound& available_cross) const { … }
NormalizedSize FlexLayout::GetCurrentSizeForRule(
const FlexRule& rule,
const View* child,
const NormalizedSizeBounds& available) const { … }
void FlexLayout::InitializeChildData(
const NormalizedSizeBounds& bounds,
FlexLayoutData& data,
FlexOrderToViewIndexMap& flex_order_to_index) const { … }
void FlexLayout::CalculateChildBounds(const SizeBounds& size_bounds,
FlexLayoutData& data) const { … }
void FlexLayout::CalculateNonFlexAvailableSpace(
const SizeBound& available_space,
const FlexOrderToViewIndexMap& flex_views,
const ChildViewSpacing& child_spacing,
FlexLayoutData& data) const { … }
Inset1D FlexLayout::GetCrossAxisMargins(const FlexLayoutData& layout,
size_t child_index) const { … }
int FlexLayout::CalculateMargin(int margin1,
int margin2,
int internal_padding) const { … }
SizeBound FlexLayout::GetAvailableCrossAxisSize(
const FlexLayoutData& layout,
size_t child_index,
const NormalizedSizeBounds& bounds) const { … }
int FlexLayout::CalculateChildSpacing(
const FlexLayoutData& layout,
std::optional<size_t> child1_index,
std::optional<size_t> child2_index) const { … }
void FlexLayout::UpdateLayoutFromChildren(
const NormalizedSizeBounds& bounds,
FlexLayoutData& data,
ChildViewSpacing& child_spacing) const { … }
NormalizedSize FlexLayout::ClampSizeToMinAndMax(FlexLayoutData& data,
const size_t view_index,
SizeBound size) const { … }
void FlexLayout::AllocateFlexItem(const NormalizedSizeBounds& bounds,
const FlexOrderToViewIndexMap& order_to_index,
FlexLayoutData& data,
ChildViewSpacing& child_spacing,
bool skip_zero_preferred_size_view) const { … }
SizeBound FlexLayout::AllocateZeroWeightFlex(
const NormalizedSizeBounds& bounds,
ChildIndices& child_list,
FlexLayoutData& data,
ChildViewSpacing& child_spacing) const { … }
void FlexLayout::FilterZeroSizeChildreIfNeeded(
const NormalizedSizeBounds& bounds,
SizeBound& to_allocate,
ChildIndices& child_list,
FlexLayoutData& data,
ChildViewSpacing& child_spacing) const { … }
bool FlexLayout::ResolveFlexibleLengths(const NormalizedSizeBounds& bounds,
SizeBound& remaining_free_space,
ChildIndices& child_list,
FlexLayoutData& data,
ChildViewSpacing& child_spacing) const { … }
bool FlexLayout::FreezeViolations(ChildIndices& child_list,
SizeBound& remaining_free_space,
ChildIndices& freeze_child_list,
ChildViewSpacing& child_spacing,
FlexLayoutData& data) const { … }
void FlexLayout::AllocateRemainingSpaceIfNeeded(
const NormalizedSizeBounds& bounds,
const FlexOrderToViewIndexMap& order_to_index,
FlexLayoutData& data,
ChildViewSpacing& child_spacing) const { … }
void FlexLayout::CalculateFlexAvailableSpace(
const NormalizedSizeBounds& bounds,
const ChildIndices& child_indices,
const ChildViewSpacing& child_spacing,
FlexLayoutData& data) const { … }
int FlexLayout::CalculateFlexTotal(const FlexLayoutData& data,
const ChildIndices& child_indices) { … }
gfx::Size FlexLayout::DefaultFlexRuleImpl(const FlexLayout* flex_layout,
const View* view,
const SizeBounds& size_bounds) { … }
}