blob: becc390de0a24f1a93ac9d3f6542b890da3fb7fe [file] [log] [blame]
// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef COBALT_LAYOUT_FLEX_ITEM_H_
#define COBALT_LAYOUT_FLEX_ITEM_H_
#include <vector>
#include "base/logging.h"
#include "base/optional.h"
#include "cobalt/layout/box.h"
#include "cobalt/layout/layout_unit.h"
namespace cobalt {
namespace layout {
// Base class for all Flex Items.
class FlexItem {
public:
// Disallow Copy and Assign.
explicit FlexItem(const FlexItem&) = delete;
FlexItem& operator=(const FlexItem&) = delete;
explicit FlexItem(FlexItem&& that) = delete;
virtual ~FlexItem() = default;
FlexItem(Box* box, bool main_direction_is_horizontal);
static std::unique_ptr<FlexItem> Create(Box* box,
bool main_direction_is_horizontal);
Box* box() const { return box_; }
const scoped_refptr<const cssom::CSSComputedStyleData>& computed_style()
const {
return box()->computed_style();
}
LayoutUnit flex_base_size() const { return flex_base_size_; }
LayoutUnit hypothetical_main_size() const { return hypothetical_main_size_; }
void set_target_main_size(LayoutUnit target_main_size) {
target_main_size_ = target_main_size;
}
LayoutUnit target_main_size() const { return target_main_size_; }
void set_flex_space(LayoutUnit flex_space) { flex_space_ = flex_space; }
LayoutUnit flex_space() const { return flex_space_; }
void set_scaled_flex_shrink_factor(LayoutUnit scaled_flex_shrink_factor) {
scaled_flex_shrink_factor_ = scaled_flex_shrink_factor;
}
LayoutUnit scaled_flex_shrink_factor() const {
return scaled_flex_shrink_factor_;
}
void set_flex_factor(float flex_factor) { flex_factor_ = flex_factor; }
void DetermineFlexFactor(bool flex_factor_is_grow);
float flex_factor() const { return flex_factor_; }
void set_max_violation(bool max_violation) { max_violation_ = max_violation; }
bool max_violation() const { return max_violation_; }
void set_min_violation(bool min_violation) { min_violation_ = min_violation; }
bool min_violation() const { return min_violation_; }
const scoped_refptr<cobalt::cssom::PropertyValue>&
GetUsedAlignSelfPropertyValue();
const scoped_refptr<cobalt::cssom::PropertyValue>&
GetUsedJustifyContentPropertyValue();
// Determine the flex base size.
// https://www.w3.org/TR/css-flexbox-1/#flex-base-size
void DetermineFlexBaseSize(const base::Optional<LayoutUnit>& main_space,
bool container_shrink_to_fit_width_forced);
// Determine the hypothetical main size.
// https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size
void DetermineHypotheticalMainSize(const SizeLayoutUnit& available_space);
base::Optional<LayoutUnit> GetContentBasedMinimumSize(
const SizeLayoutUnit& containing_block_size) const;
// Return the size difference between the content and margin box on the main
// axis.
virtual LayoutUnit GetContentToMarginMainAxis() const = 0;
// Return the size difference between the content and margin box on the cross
// axis.
virtual LayoutUnit GetContentToMarginCrossAxis() const = 0;
// Return the used style for the size in the main axis.
virtual base::Optional<LayoutUnit> GetUsedMainAxisSizeIfNotAuto(
const SizeLayoutUnit& containing_block_size) const = 0;
// Return the used style for the min size in the main axis.
virtual base::Optional<LayoutUnit> GetUsedMinMainAxisSizeIfNotAuto(
const SizeLayoutUnit& containing_block_size) const = 0;
// Return the used style for the min size in the cross axis.
virtual base::Optional<LayoutUnit> GetUsedMinCrossAxisSizeIfNotAuto(
const SizeLayoutUnit& containing_block_size) const = 0;
// Return the used style for the max size in the main axis.
virtual base::Optional<LayoutUnit> GetUsedMaxMainAxisSizeIfNotNone(
const SizeLayoutUnit& containing_block_size) const = 0;
// Return the used style for the max size in the cross axis.
virtual base::Optional<LayoutUnit> GetUsedMaxCrossAxisSizeIfNotNone(
const SizeLayoutUnit& containing_block_size) const = 0;
// Determine the hypothetical cross size.
// https://www.w3.org/TR/css-flexbox-1/#algo-cross-item
virtual void DetermineHypotheticalCrossSize(
const LayoutParams& layout_params) = 0;
virtual LayoutUnit GetContentBoxMainSize() const = 0;
virtual LayoutUnit GetMarginBoxMainSize() const = 0;
virtual LayoutUnit GetMarginBoxCrossSize() const = 0;
// Return true if the computed cross axis size is auto.
virtual bool CrossSizeIsAuto() const = 0;
// Return true if the margin at the main axis start is auto.
virtual bool MarginMainStartIsAuto() const = 0;
// Return true if the margin at the main axis end is auto.
virtual bool MarginMainEndIsAuto() const = 0;
// Return true if the margin at the cross axis start is auto.
virtual bool MarginCrossStartIsAuto() const = 0;
// Return true if the margin at the cross axis end is auto.
virtual bool MarginCrossEndIsAuto() const = 0;
virtual void SetCrossSize(LayoutUnit cross_size) = 0;
virtual void SetMainAxisStart(LayoutUnit position) = 0;
virtual void SetCrossAxisStart(LayoutUnit position) = 0;
private:
// Return true if the overflow is visible
bool OverflowIsVisible() const;
Box* const box_ = nullptr;
const bool main_direction_is_horizontal_;
LayoutUnit flex_base_size_ = LayoutUnit();
LayoutUnit hypothetical_main_size_ = LayoutUnit();
LayoutUnit target_main_size_ = LayoutUnit();
LayoutUnit flex_space_ = LayoutUnit();
LayoutUnit scaled_flex_shrink_factor_ = LayoutUnit();
float flex_factor_ = 0;
bool max_violation_ = false;
bool min_violation_ = false;
};
#ifdef COBALT_BOX_DUMP_ENABLED
inline std::ostream& operator<<(std::ostream& stream, const FlexItem& item) {
stream << "flex_base_size= " << item.flex_base_size()
<< " hypothetical_main_size = " << item.hypothetical_main_size()
<< " target_main_size = " << item.target_main_size()
<< " flex_space =" << item.flex_space() << " box " << *item.box()
<< " flex_factor = " << item.flex_factor();
return stream;
}
#endif // COBALT_BOX_DUMP_ENABLED
} // namespace layout
} // namespace cobalt
#endif // COBALT_LAYOUT_FLEX_ITEM_H_