/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include "Bitfield.h" #include "CompactValue.h" #include "YGEnums.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" #include "Yoga.h" class YOGA_EXPORT YGStyle { template using Values = facebook::yoga::detail::Values()>; using CompactValue = facebook::yoga::detail::CompactValue; public: using Dimensions = Values; using Edges = Values; template struct Ref { YGStyle& style; operator T() const { return style.*Prop; } Ref& operator=(T value) { style.*Prop = value; return *this; } }; template YGStyle::*Prop> 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; IdxRef& operator=(const Values& values) { style.*Prop = values; return *this; } operator const Values&() const { return style.*Prop; } Ref operator[](Idx idx) { return {style, idx}; } CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; } }; YGStyle() = default; ~YGStyle() = default; private: 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}; 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::type; YGDirection direction() const { return flags_.at(); } Flags::Ref direction() { return flags_.at(); } YGFlexDirection flexDirection() const { return flags_.at(); } Flags::Ref flexDirection() { return flags_.at(); } YGJustify justifyContent() const { return flags_.at(); } Flags::Ref justifyContent() { return flags_.at(); } YGAlign alignContent() const { return flags_.at(); } Flags::Ref alignContent() { return flags_.at(); } YGAlign alignItems() const { return flags_.at(); } Flags::Ref alignItems() { return flags_.at(); } YGAlign alignSelf() const { return flags_.at(); } Flags::Ref alignSelf() { return flags_.at(); } YGPositionType positionType() const { return flags_.at(); } Flags::Ref positionType() { return flags_.at(); } YGWrap flexWrap() const { return flags_.at(); } Flags::Ref flexWrap() { return flags_.at(); } YGOverflow overflow() const { return flags_.at(); } Flags::Ref overflow() { return flags_.at(); } YGDisplay display() const { return flags_.at(); } Flags::Ref display() { return flags_.at(); } YGFloatOptional flex() const { return flex_; } Ref flex() { return {*this}; } YGFloatOptional flexGrow() const { return flexGrow_; } Ref flexGrow() { return {*this}; } YGFloatOptional flexShrink() const { return flexShrink_; } Ref flexShrink() { return {*this}; } CompactValue flexBasis() const { return flexBasis_; } Ref flexBasis() { return {*this}; } const Edges& margin() const { return margin_; } IdxRef margin() { return {*this}; } const Edges& position() const { return position_; } IdxRef position() { return {*this}; } const Edges& padding() const { return padding_; } IdxRef padding() { return {*this}; } const Edges& border() const { return border_; } IdxRef border() { return {*this}; } const Dimensions& dimensions() const { return dimensions_; } IdxRef dimensions() { return {*this}; } const Dimensions& minDimensions() const { return minDimensions_; } IdxRef minDimensions() { return {*this}; } const Dimensions& maxDimensions() const { return maxDimensions_; } IdxRef maxDimensions() { return {*this}; } // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio() const { return aspectRatio_; } Ref aspectRatio() { return {*this}; } }; YOGA_EXPORT bool operator==(const YGStyle& lhs, const YGStyle& rhs); YOGA_EXPORT inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) { return !(lhs == rhs); }