2019-06-06 19:36:56 -07:00
|
|
|
/*
|
2018-11-29 11:35:34 -08:00
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
2018-02-20 05:41:48 -08:00
|
|
|
*
|
2018-11-29 11:35:34 -08:00
|
|
|
* This source code is licensed under the MIT license found in the LICENSE
|
|
|
|
* file in the root directory of this source tree.
|
2018-02-20 05:41:48 -08:00
|
|
|
*/
|
|
|
|
#pragma once
|
2018-12-14 09:20:27 -08:00
|
|
|
#include <algorithm>
|
|
|
|
#include <array>
|
2019-05-01 06:47:31 -07:00
|
|
|
#include <cstdint>
|
2019-04-29 09:18:57 -07:00
|
|
|
#include <type_traits>
|
2019-08-07 16:17:00 -07:00
|
|
|
#include "Bitfield.h"
|
2018-12-18 08:11:24 -08:00
|
|
|
#include "CompactValue.h"
|
2019-01-11 03:09:11 -08:00
|
|
|
#include "YGEnums.h"
|
2018-03-15 12:29:02 -07:00
|
|
|
#include "YGFloatOptional.h"
|
2018-02-20 05:41:48 -08:00
|
|
|
#include "Yoga-internal.h"
|
|
|
|
#include "Yoga.h"
|
|
|
|
|
2019-04-23 08:08:51 -07:00
|
|
|
class YGStyle {
|
2019-05-01 06:47:30 -07:00
|
|
|
template <typename Enum>
|
|
|
|
using Values =
|
|
|
|
facebook::yoga::detail::Values<facebook::yoga::enums::count<Enum>()>;
|
2018-12-18 08:11:24 -08:00
|
|
|
using CompactValue = facebook::yoga::detail::CompactValue;
|
|
|
|
|
2019-01-08 12:47:53 -08:00
|
|
|
public:
|
2019-05-01 06:47:30 -07:00
|
|
|
using Dimensions = Values<YGDimension>;
|
|
|
|
using Edges = Values<YGEdge>;
|
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
template <typename T, T YGStyle::*Prop>
|
2019-05-01 06:47:30 -07:00
|
|
|
struct Ref {
|
|
|
|
YGStyle& style;
|
|
|
|
operator T() const { return style.*Prop; }
|
2019-08-07 16:17:00 -07:00
|
|
|
Ref<T, Prop>& operator=(T value) {
|
2019-05-01 06:47:30 -07:00
|
|
|
style.*Prop = value;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
template <typename Idx, Values<Idx> YGStyle::*Prop>
|
2019-05-01 06:47:30 -07:00
|
|
|
struct IdxRef {
|
|
|
|
struct Ref {
|
|
|
|
YGStyle& style;
|
|
|
|
Idx idx;
|
|
|
|
operator CompactValue() const { return (style.*Prop)[idx]; }
|
|
|
|
operator YGValue() const { return (style.*Prop)[idx]; }
|
|
|
|
Ref& operator=(CompactValue value) {
|
|
|
|
(style.*Prop)[idx] = value;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
YGStyle& style;
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<Idx, Prop>& operator=(const Values<Idx>& values) {
|
2019-05-01 06:47:30 -07:00
|
|
|
style.*Prop = values;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
operator const Values<Idx>&() const { return style.*Prop; }
|
|
|
|
Ref operator[](Idx idx) { return {style, idx}; }
|
|
|
|
CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; }
|
|
|
|
};
|
2018-08-17 03:56:35 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGStyle() = default;
|
2019-04-23 08:08:51 -07:00
|
|
|
~YGStyle() = default;
|
|
|
|
|
2019-05-01 06:47:30 -07:00
|
|
|
private:
|
2019-08-07 16:17:00 -07:00
|
|
|
static constexpr size_t directionIdx = 0;
|
|
|
|
static constexpr size_t flexDirectionIdx = 1;
|
|
|
|
static constexpr size_t justifyContentIdx = 2;
|
|
|
|
static constexpr size_t alignContentIdx = 3;
|
|
|
|
static constexpr size_t alignItemsIdx = 4;
|
|
|
|
static constexpr size_t alignSelfIdx = 5;
|
|
|
|
static constexpr size_t positionTypeIdx = 6;
|
|
|
|
static constexpr size_t flexWrapIdx = 7;
|
|
|
|
static constexpr size_t overflowIdx = 8;
|
|
|
|
static constexpr size_t displayIdx = 9;
|
|
|
|
using Flags = facebook::yoga::Bitfield<
|
|
|
|
uint32_t,
|
|
|
|
YGDirection,
|
|
|
|
YGFlexDirection,
|
|
|
|
YGJustify,
|
|
|
|
YGAlign,
|
|
|
|
YGAlign,
|
|
|
|
YGAlign,
|
|
|
|
YGPositionType,
|
|
|
|
YGWrap,
|
|
|
|
YGOverflow,
|
|
|
|
YGDisplay>;
|
|
|
|
|
|
|
|
Flags flags_ = {YGDirectionInherit,
|
|
|
|
YGFlexDirectionColumn,
|
|
|
|
YGJustifyFlexStart,
|
|
|
|
YGAlignFlexStart,
|
|
|
|
YGAlignStretch,
|
|
|
|
YGAlignAuto,
|
|
|
|
YGPositionTypeRelative,
|
|
|
|
YGWrapNoWrap,
|
|
|
|
YGOverflowVisible,
|
|
|
|
YGDisplayFlex};
|
2019-05-01 06:47:30 -07:00
|
|
|
YGFloatOptional flex_ = {};
|
|
|
|
YGFloatOptional flexGrow_ = {};
|
|
|
|
YGFloatOptional flexShrink_ = {};
|
|
|
|
CompactValue flexBasis_ = CompactValue::ofAuto();
|
|
|
|
Edges margin_ = {};
|
|
|
|
Edges position_ = {};
|
|
|
|
Edges padding_ = {};
|
|
|
|
Edges border_ = {};
|
|
|
|
Dimensions dimensions_{CompactValue::ofAuto()};
|
|
|
|
Dimensions minDimensions_ = {};
|
|
|
|
Dimensions maxDimensions_ = {};
|
|
|
|
// Yoga specific properties, not compatible with flexbox specification
|
|
|
|
YGFloatOptional aspectRatio_ = {};
|
|
|
|
|
|
|
|
public:
|
|
|
|
// for library users needing a type
|
|
|
|
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
|
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGDirection direction() const { return flags_.at<directionIdx>(); }
|
|
|
|
Flags::Ref<directionIdx> direction() { return flags_.at<directionIdx>(); }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGFlexDirection flexDirection() const {
|
|
|
|
return flags_.at<flexDirectionIdx>();
|
|
|
|
}
|
|
|
|
Flags::Ref<flexDirectionIdx> flexDirection() {
|
|
|
|
return flags_.at<flexDirectionIdx>();
|
|
|
|
}
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGJustify justifyContent() const { return flags_.at<justifyContentIdx>(); }
|
|
|
|
Flags::Ref<justifyContentIdx> justifyContent() {
|
|
|
|
return flags_.at<justifyContentIdx>();
|
|
|
|
}
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGAlign alignContent() const { return flags_.at<alignContentIdx>(); }
|
|
|
|
Flags::Ref<alignContentIdx> alignContent() {
|
|
|
|
return flags_.at<alignContentIdx>();
|
|
|
|
}
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGAlign alignItems() const { return flags_.at<alignItemsIdx>(); }
|
|
|
|
Flags::Ref<alignItemsIdx> alignItems() { return flags_.at<alignItemsIdx>(); }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGAlign alignSelf() const { return flags_.at<alignSelfIdx>(); }
|
|
|
|
Flags::Ref<alignSelfIdx> alignSelf() { return flags_.at<alignSelfIdx>(); }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGPositionType positionType() const { return flags_.at<positionTypeIdx>(); }
|
|
|
|
Flags::Ref<positionTypeIdx> positionType() {
|
|
|
|
return flags_.at<positionTypeIdx>();
|
|
|
|
}
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGWrap flexWrap() const { return flags_.at<flexWrapIdx>(); }
|
|
|
|
Flags::Ref<flexWrapIdx> flexWrap() { return flags_.at<flexWrapIdx>(); }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGOverflow overflow() const { return flags_.at<overflowIdx>(); }
|
|
|
|
Flags::Ref<overflowIdx> overflow() { return flags_.at<overflowIdx>(); }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
YGDisplay display() const { return flags_.at<displayIdx>(); }
|
|
|
|
Flags::Ref<displayIdx> display() { return flags_.at<displayIdx>(); }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
YGFloatOptional flex() const { return flex_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
Ref<YGFloatOptional, &YGStyle::flex_> flex() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
YGFloatOptional flexGrow() const { return flexGrow_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
Ref<YGFloatOptional, &YGStyle::flexGrow_> flexGrow() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
YGFloatOptional flexShrink() const { return flexShrink_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
Ref<YGFloatOptional, &YGStyle::flexShrink_> flexShrink() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
CompactValue flexBasis() const { return flexBasis_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
Ref<CompactValue, &YGStyle::flexBasis_> flexBasis() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
const Edges& margin() const { return margin_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<YGEdge, &YGStyle::margin_> margin() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
const Edges& position() const { return position_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<YGEdge, &YGStyle::position_> position() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
const Edges& padding() const { return padding_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<YGEdge, &YGStyle::padding_> padding() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
const Edges& border() const { return border_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<YGEdge, &YGStyle::border_> border() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
const Dimensions& dimensions() const { return dimensions_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<YGDimension, &YGStyle::dimensions_> dimensions() { return {*this}; }
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
const Dimensions& minDimensions() const { return minDimensions_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<YGDimension, &YGStyle::minDimensions_> minDimensions() {
|
2019-05-01 06:47:30 -07:00
|
|
|
return {*this};
|
|
|
|
}
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
const Dimensions& maxDimensions() const { return maxDimensions_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
IdxRef<YGDimension, &YGStyle::maxDimensions_> maxDimensions() {
|
2019-05-01 06:47:30 -07:00
|
|
|
return {*this};
|
|
|
|
}
|
2019-04-23 08:08:51 -07:00
|
|
|
|
|
|
|
// Yoga specific properties, not compatible with flexbox specification
|
|
|
|
YGFloatOptional aspectRatio() const { return aspectRatio_; }
|
2019-08-07 16:17:00 -07:00
|
|
|
Ref<YGFloatOptional, &YGStyle::aspectRatio_> aspectRatio() { return {*this}; }
|
2018-02-20 05:41:48 -08:00
|
|
|
};
|
2019-02-04 10:21:37 -08:00
|
|
|
|
|
|
|
bool operator==(const YGStyle& lhs, const YGStyle& rhs);
|
|
|
|
inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|