/* * 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 #ifdef __cplusplus #include #include #include #include #include "CompactValue.h" #include "YGEnums.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" #include "Yoga.h" #include "BitUtils.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 BitfieldRef { YGStyle& style; size_t offset; operator T() const { return facebook::yoga::detail::getEnumData(style.flags, offset); } BitfieldRef& operator=(T x) { facebook::yoga::detail::setEnumData(style.flags, offset, x); return *this; } }; 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() { alignContent() = YGAlignFlexStart; alignItems() = YGAlignStretch; } ~YGStyle() = default; private: static constexpr size_t directionOffset = 0; static constexpr size_t flexdirectionOffset = directionOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t justifyContentOffset = flexdirectionOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t alignContentOffset = justifyContentOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t alignItemsOffset = alignContentOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t alignSelfOffset = alignItemsOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t positionTypeOffset = alignSelfOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t flexWrapOffset = positionTypeOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t overflowOffset = flexWrapOffset + facebook::yoga::detail::bitWidthFn(); static constexpr size_t displayOffset = overflowOffset + facebook::yoga::detail::bitWidthFn(); uint32_t flags = 0; 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 facebook::yoga::detail::getEnumData( flags, directionOffset); } BitfieldRef direction() { return {*this, directionOffset}; } YGFlexDirection flexDirection() const { return facebook::yoga::detail::getEnumData( flags, flexdirectionOffset); } BitfieldRef flexDirection() { return {*this, flexdirectionOffset}; } YGJustify justifyContent() const { return facebook::yoga::detail::getEnumData( flags, justifyContentOffset); } BitfieldRef justifyContent() { return {*this, justifyContentOffset}; } YGAlign alignContent() const { return facebook::yoga::detail::getEnumData( flags, alignContentOffset); } BitfieldRef alignContent() { return {*this, alignContentOffset}; } YGAlign alignItems() const { return facebook::yoga::detail::getEnumData( flags, alignItemsOffset); } BitfieldRef alignItems() { return {*this, alignItemsOffset}; } YGAlign alignSelf() const { return facebook::yoga::detail::getEnumData(flags, alignSelfOffset); } BitfieldRef alignSelf() { return {*this, alignSelfOffset}; } YGPositionType positionType() const { return facebook::yoga::detail::getEnumData( flags, positionTypeOffset); } BitfieldRef positionType() { return {*this, positionTypeOffset}; } YGWrap flexWrap() const { return facebook::yoga::detail::getEnumData(flags, flexWrapOffset); } BitfieldRef flexWrap() { return {*this, flexWrapOffset}; } YGOverflow overflow() const { return facebook::yoga::detail::getEnumData( flags, overflowOffset); } BitfieldRef overflow() { return {*this, overflowOffset}; } YGDisplay display() const { return facebook::yoga::detail::getEnumData(flags, displayOffset); } BitfieldRef display() { return {*this, displayOffset}; } 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); } #endif