Fabric: Enabling clang-format for half of Fabric modules

Summary:
All code styles are terribly ugly. We have the only choise - choise something and embrace it.
This particular code style was borrowed from a neibour Fabric-friendly project because it follows established Facebook guides and respects client-side traditions.

Reviewed By: mdvacca

Differential Revision: D10218598

fbshipit-source-id: 8c4cf6713c07768566dadef479191661c79988f0
This commit is contained in:
Valentin Shergin 2018-10-05 11:01:08 -07:00 committed by Facebook Github Bot
parent 3d31bebbeb
commit 3ad5c9e016
100 changed files with 2589 additions and 1728 deletions

87
ReactCommon/.clang-format Normal file
View File

@ -0,0 +1,87 @@
---
AccessModifierOffset: -1
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: [ FOR_EACH_RANGE, FOR_EACH, ]
IncludeCategories:
- Regex: '^<.*\.h(pp)?>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@ -18,19 +18,12 @@ using Fragments = AttributedString::Fragments;
#pragma mark - Fragment
bool Fragment::operator==(const Fragment &rhs) const {
return
std::tie(
string,
textAttributes,
shadowNode,
parentShadowNode
) ==
std::tie(
rhs.string,
rhs.textAttributes,
rhs.shadowNode,
rhs.parentShadowNode
);
return std::tie(string, textAttributes, shadowNode, parentShadowNode) ==
std::tie(
rhs.string,
rhs.textAttributes,
rhs.shadowNode,
rhs.parentShadowNode);
}
bool Fragment::operator!=(const Fragment &rhs) const {
@ -49,14 +42,22 @@ void AttributedString::prependFragment(const Fragment &fragment) {
fragments_.insert(fragments_.begin(), fragment);
}
void AttributedString::appendAttributedString(const AttributedString &attributedString) {
void AttributedString::appendAttributedString(
const AttributedString &attributedString) {
ensureUnsealed();
fragments_.insert(fragments_.end(), attributedString.fragments_.begin(), attributedString.fragments_.end());
fragments_.insert(
fragments_.end(),
attributedString.fragments_.begin(),
attributedString.fragments_.end());
}
void AttributedString::prependAttributedString(const AttributedString &attributedString) {
void AttributedString::prependAttributedString(
const AttributedString &attributedString) {
ensureUnsealed();
fragments_.insert(fragments_.begin(), attributedString.fragments_.begin(), attributedString.fragments_.end());
fragments_.insert(
fragments_.begin(),
attributedString.fragments_.begin(),
attributedString.fragments_.end());
}
const std::vector<Fragment> &AttributedString::getFragments() const {
@ -64,7 +65,7 @@ const std::vector<Fragment> &AttributedString::getFragments() const {
}
std::string AttributedString::getString() const {
auto string = std::string {};
auto string = std::string{};
for (const auto &fragment : fragments_) {
string += fragment.string;
}
@ -83,23 +84,22 @@ bool AttributedString::operator!=(const AttributedString &rhs) const {
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList AttributedString::getDebugChildren() const {
auto list = SharedDebugStringConvertibleList {};
auto list = SharedDebugStringConvertibleList{};
for (auto &&fragment : fragments_) {
auto propsList = fragment.textAttributes.DebugStringConvertible::getDebugProps();
auto propsList =
fragment.textAttributes.DebugStringConvertible::getDebugProps();
if (fragment.shadowNode) {
propsList.push_back(std::make_shared<DebugStringConvertibleItem>("shadowNode", fragment.shadowNode->getDebugDescription()));
propsList.push_back(std::make_shared<DebugStringConvertibleItem>(
"shadowNode", fragment.shadowNode->getDebugDescription()));
}
list.push_back(
std::make_shared<DebugStringConvertibleItem>(
list.push_back(std::make_shared<DebugStringConvertibleItem>(
"Fragment",
fragment.string,
SharedDebugStringConvertibleList(),
propsList
)
);
propsList));
}
return list;

View File

@ -29,15 +29,10 @@ using SharedAttributedString = std::shared_ptr<const AttributedString>;
* `AttributedString` is basically a list of `Fragments` which have `string` and
* `textAttributes` + `shadowNode` associated with the `string`.
*/
class AttributedString:
public Sealable,
public DebugStringConvertible {
public:
class AttributedString : public Sealable, public DebugStringConvertible {
public:
class Fragment {
public:
public:
std::string string;
TextAttributes textAttributes;
SharedShadowNode shadowNode;
@ -81,8 +76,7 @@ public:
SharedDebugStringConvertibleList getDebugChildren() const override;
#endif
private:
private:
Fragments fragments_;
};
@ -90,27 +84,31 @@ private:
} // namespace facebook
namespace std {
template <>
struct hash<facebook::react::AttributedString::Fragment> {
size_t operator()(const facebook::react::AttributedString::Fragment &fragment) const {
return
std::hash<decltype(fragment.string)>{}(fragment.string) +
std::hash<decltype(fragment.textAttributes)>{}(fragment.textAttributes) +
template <>
struct hash<facebook::react::AttributedString::Fragment> {
size_t operator()(
const facebook::react::AttributedString::Fragment &fragment) const {
return std::hash<decltype(fragment.string)>{}(fragment.string) +
std::hash<decltype(fragment.textAttributes)>{}(
fragment.textAttributes) +
std::hash<decltype(fragment.shadowNode)>{}(fragment.shadowNode) +
std::hash<decltype(fragment.parentShadowNode)>{}(fragment.parentShadowNode);
std::hash<decltype(fragment.parentShadowNode)>{}(
fragment.parentShadowNode);
}
};
template <>
struct hash<facebook::react::AttributedString> {
size_t operator()(
const facebook::react::AttributedString &attributedString) const {
auto result = size_t{0};
for (const auto &fragment : attributedString.getFragments()) {
result +=
std::hash<facebook::react::AttributedString::Fragment>{}(fragment);
}
};
template <>
struct hash<facebook::react::AttributedString> {
size_t operator()(const facebook::react::AttributedString &attributedString) const {
auto result = size_t {0};
for (const auto &fragment : attributedString.getFragments()) {
result += std::hash<facebook::react::AttributedString::Fragment>{}(fragment);
}
return result;
}
};
return result;
}
};
} // namespace std

View File

@ -8,8 +8,8 @@
#include "ParagraphAttributes.h"
#include <fabric/attributedstring/conversions.h>
#include <fabric/graphics/conversions.h>
#include <fabric/debug/debugStringConvertibleUtils.h>
#include <fabric/graphics/conversions.h>
namespace facebook {
namespace react {
@ -19,12 +19,11 @@ namespace react {
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList ParagraphAttributes::getDebugProps() const {
return {
debugStringConvertibleItem("maximumNumberOfLines", maximumNumberOfLines),
debugStringConvertibleItem("ellipsizeMode", ellipsizeMode),
debugStringConvertibleItem("adjustsFontSizeToFit", adjustsFontSizeToFit),
debugStringConvertibleItem("minimumFontSize", minimumFontSize),
debugStringConvertibleItem("maximumFontSize", maximumFontSize)
};
debugStringConvertibleItem("maximumNumberOfLines", maximumNumberOfLines),
debugStringConvertibleItem("ellipsizeMode", ellipsizeMode),
debugStringConvertibleItem("adjustsFontSizeToFit", adjustsFontSizeToFit),
debugStringConvertibleItem("minimumFontSize", minimumFontSize),
debugStringConvertibleItem("maximumFontSize", maximumFontSize)};
}
#endif

View File

@ -25,36 +25,33 @@ using SharedParagraphAttributes = std::shared_ptr<const ParagraphAttributes>;
* Two data structures, ParagraphAttributes and AttributedText, should be
* enough to define visual representation of a piece of text on the screen.
*/
class ParagraphAttributes:
public DebugStringConvertible {
public:
class ParagraphAttributes : public DebugStringConvertible {
public:
#pragma mark - Fields
/*
* Maximum number of lines which paragraph can take.
* Zero value represents "no limit".
*/
int maximumNumberOfLines {};
int maximumNumberOfLines{};
/*
* In case if a text cannot fit given boundaries, defines a place where
* an ellipsize should be placed.
*/
EllipsizeMode ellipsizeMode {};
EllipsizeMode ellipsizeMode{};
/*
* Enables font size adjustment to fit constrained boundaries.
*/
bool adjustsFontSizeToFit {};
bool adjustsFontSizeToFit{};
/*
* In case of font size adjustment enabled, defines minimum and maximum
* font sizes.
*/
Float minimumFontSize {std::numeric_limits<Float>::quiet_NaN()};
Float maximumFontSize {std::numeric_limits<Float>::quiet_NaN()};
Float minimumFontSize{std::numeric_limits<Float>::quiet_NaN()};
Float maximumFontSize{std::numeric_limits<Float>::quiet_NaN()};
#pragma mark - DebugStringConvertible

View File

@ -18,95 +18,131 @@ namespace react {
void TextAttributes::apply(TextAttributes textAttributes) {
// Color
foregroundColor = textAttributes.foregroundColor ? textAttributes.foregroundColor : foregroundColor;
backgroundColor = textAttributes.backgroundColor ? textAttributes.backgroundColor : backgroundColor;
foregroundColor = textAttributes.foregroundColor
? textAttributes.foregroundColor
: foregroundColor;
backgroundColor = textAttributes.backgroundColor
? textAttributes.backgroundColor
: backgroundColor;
opacity = !isnan(textAttributes.opacity) ? textAttributes.opacity : opacity;
// Font
fontFamily = !textAttributes.fontFamily.empty() ? textAttributes.fontFamily : fontFamily;
fontSize = !isnan(textAttributes.fontSize) ? textAttributes.fontSize : fontSize;
fontSizeMultiplier = !isnan(textAttributes.fontSizeMultiplier) ? textAttributes.fontSizeMultiplier : fontSizeMultiplier;
fontWeight = textAttributes.fontWeight.hasValue() ? textAttributes.fontWeight : fontWeight;
fontStyle = textAttributes.fontStyle.hasValue() ? textAttributes.fontStyle : fontStyle;
fontVariant = textAttributes.fontVariant.hasValue() ? textAttributes.fontVariant : fontVariant;
allowFontScaling = textAttributes.allowFontScaling.hasValue() ? textAttributes.allowFontScaling : allowFontScaling;
letterSpacing = !isnan(textAttributes.letterSpacing) ? textAttributes.letterSpacing : letterSpacing;
fontFamily = !textAttributes.fontFamily.empty() ? textAttributes.fontFamily
: fontFamily;
fontSize =
!isnan(textAttributes.fontSize) ? textAttributes.fontSize : fontSize;
fontSizeMultiplier = !isnan(textAttributes.fontSizeMultiplier)
? textAttributes.fontSizeMultiplier
: fontSizeMultiplier;
fontWeight = textAttributes.fontWeight.hasValue() ? textAttributes.fontWeight
: fontWeight;
fontStyle = textAttributes.fontStyle.hasValue() ? textAttributes.fontStyle
: fontStyle;
fontVariant = textAttributes.fontVariant.hasValue()
? textAttributes.fontVariant
: fontVariant;
allowFontScaling = textAttributes.allowFontScaling.hasValue()
? textAttributes.allowFontScaling
: allowFontScaling;
letterSpacing = !isnan(textAttributes.letterSpacing)
? textAttributes.letterSpacing
: letterSpacing;
// Paragraph Styles
lineHeight = !isnan(textAttributes.lineHeight) ? textAttributes.lineHeight : lineHeight;
alignment = textAttributes.alignment.hasValue() ? textAttributes.alignment : alignment;
baseWritingDirection = textAttributes.baseWritingDirection.hasValue() ? textAttributes.baseWritingDirection : baseWritingDirection;
lineHeight = !isnan(textAttributes.lineHeight) ? textAttributes.lineHeight
: lineHeight;
alignment = textAttributes.alignment.hasValue() ? textAttributes.alignment
: alignment;
baseWritingDirection = textAttributes.baseWritingDirection.hasValue()
? textAttributes.baseWritingDirection
: baseWritingDirection;
// Decoration
textDecorationColor = textAttributes.textDecorationColor ? textAttributes.textDecorationColor : textDecorationColor;
textDecorationLineType = textAttributes.textDecorationLineType.hasValue() ? textAttributes.textDecorationLineType : textDecorationLineType;
textDecorationLineStyle = textAttributes.textDecorationLineStyle.hasValue() ? textAttributes.textDecorationLineStyle : textDecorationLineStyle;
textDecorationLinePattern = textAttributes.textDecorationLinePattern.hasValue() ? textAttributes.textDecorationLinePattern : textDecorationLinePattern;
textDecorationColor = textAttributes.textDecorationColor
? textAttributes.textDecorationColor
: textDecorationColor;
textDecorationLineType = textAttributes.textDecorationLineType.hasValue()
? textAttributes.textDecorationLineType
: textDecorationLineType;
textDecorationLineStyle = textAttributes.textDecorationLineStyle.hasValue()
? textAttributes.textDecorationLineStyle
: textDecorationLineStyle;
textDecorationLinePattern =
textAttributes.textDecorationLinePattern.hasValue()
? textAttributes.textDecorationLinePattern
: textDecorationLinePattern;
// Shadow
textShadowOffset = textAttributes.textShadowOffset.hasValue() ? textAttributes.textShadowOffset.value() : textShadowOffset;
textShadowRadius = !isnan(textAttributes.textShadowRadius) ? textAttributes.textShadowRadius : textShadowRadius;
textShadowColor = textAttributes.textShadowColor ? textAttributes.textShadowColor : textShadowColor;
textShadowOffset = textAttributes.textShadowOffset.hasValue()
? textAttributes.textShadowOffset.value()
: textShadowOffset;
textShadowRadius = !isnan(textAttributes.textShadowRadius)
? textAttributes.textShadowRadius
: textShadowRadius;
textShadowColor = textAttributes.textShadowColor
? textAttributes.textShadowColor
: textShadowColor;
// Special
isHighlighted = textAttributes.isHighlighted.hasValue() ? textAttributes.isHighlighted : isHighlighted;
layoutDirection = textAttributes.layoutDirection.hasValue() ? textAttributes.layoutDirection : layoutDirection;
isHighlighted = textAttributes.isHighlighted.hasValue()
? textAttributes.isHighlighted
: isHighlighted;
layoutDirection = textAttributes.layoutDirection.hasValue()
? textAttributes.layoutDirection
: layoutDirection;
}
#pragma mark - Operators
bool TextAttributes::operator==(const TextAttributes &rhs) const {
return
std::tie(
foregroundColor,
backgroundColor,
opacity,
fontFamily,
fontSize,
fontSizeMultiplier,
fontWeight,
fontStyle,
fontVariant,
allowFontScaling,
letterSpacing,
lineHeight,
alignment,
baseWritingDirection,
textDecorationColor,
textDecorationLineType,
textDecorationLineStyle,
textDecorationLinePattern,
textShadowOffset,
textShadowRadius,
textShadowColor,
isHighlighted,
layoutDirection
) ==
std::tie(
rhs.foregroundColor,
rhs.backgroundColor,
rhs.opacity,
rhs.fontFamily,
rhs.fontSize,
rhs.fontSizeMultiplier,
rhs.fontWeight,
rhs.fontStyle,
rhs.fontVariant,
rhs.allowFontScaling,
rhs.letterSpacing,
rhs.lineHeight,
rhs.alignment,
rhs.baseWritingDirection,
rhs.textDecorationColor,
rhs.textDecorationLineType,
rhs.textDecorationLineStyle,
rhs.textDecorationLinePattern,
rhs.textShadowOffset,
rhs.textShadowRadius,
rhs.textShadowColor,
rhs.isHighlighted,
rhs.layoutDirection
);
return std::tie(
foregroundColor,
backgroundColor,
opacity,
fontFamily,
fontSize,
fontSizeMultiplier,
fontWeight,
fontStyle,
fontVariant,
allowFontScaling,
letterSpacing,
lineHeight,
alignment,
baseWritingDirection,
textDecorationColor,
textDecorationLineType,
textDecorationLineStyle,
textDecorationLinePattern,
textShadowOffset,
textShadowRadius,
textShadowColor,
isHighlighted,
layoutDirection) ==
std::tie(
rhs.foregroundColor,
rhs.backgroundColor,
rhs.opacity,
rhs.fontFamily,
rhs.fontSize,
rhs.fontSizeMultiplier,
rhs.fontWeight,
rhs.fontStyle,
rhs.fontVariant,
rhs.allowFontScaling,
rhs.letterSpacing,
rhs.lineHeight,
rhs.alignment,
rhs.baseWritingDirection,
rhs.textDecorationColor,
rhs.textDecorationLineType,
rhs.textDecorationLineStyle,
rhs.textDecorationLinePattern,
rhs.textShadowOffset,
rhs.textShadowRadius,
rhs.textShadowColor,
rhs.isHighlighted,
rhs.layoutDirection);
}
bool TextAttributes::operator!=(const TextAttributes &rhs) const {
@ -118,40 +154,43 @@ bool TextAttributes::operator!=(const TextAttributes &rhs) const {
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
return {
// Color
debugStringConvertibleItem("backgroundColor", backgroundColor),
debugStringConvertibleItem("foregroundColor", foregroundColor),
debugStringConvertibleItem("opacity", opacity),
// Color
debugStringConvertibleItem("backgroundColor", backgroundColor),
debugStringConvertibleItem("foregroundColor", foregroundColor),
debugStringConvertibleItem("opacity", opacity),
// Font
debugStringConvertibleItem("fontFamily", fontFamily),
debugStringConvertibleItem("fontSize", fontSize),
debugStringConvertibleItem("fontSizeMultiplier", fontSizeMultiplier),
debugStringConvertibleItem("fontWeight", fontWeight),
debugStringConvertibleItem("fontStyle", fontStyle),
debugStringConvertibleItem("fontVariant", fontVariant),
debugStringConvertibleItem("allowFontScaling", allowFontScaling),
debugStringConvertibleItem("letterSpacing", letterSpacing),
// Font
debugStringConvertibleItem("fontFamily", fontFamily),
debugStringConvertibleItem("fontSize", fontSize),
debugStringConvertibleItem("fontSizeMultiplier", fontSizeMultiplier),
debugStringConvertibleItem("fontWeight", fontWeight),
debugStringConvertibleItem("fontStyle", fontStyle),
debugStringConvertibleItem("fontVariant", fontVariant),
debugStringConvertibleItem("allowFontScaling", allowFontScaling),
debugStringConvertibleItem("letterSpacing", letterSpacing),
// Paragraph Styles
debugStringConvertibleItem("lineHeight", lineHeight),
debugStringConvertibleItem("alignment", alignment),
debugStringConvertibleItem("baseWritingDirection", baseWritingDirection),
// Paragraph Styles
debugStringConvertibleItem("lineHeight", lineHeight),
debugStringConvertibleItem("alignment", alignment),
debugStringConvertibleItem("baseWritingDirection", baseWritingDirection),
// Decoration
debugStringConvertibleItem("textDecorationColor", textDecorationColor),
debugStringConvertibleItem("textDecorationLineType", textDecorationLineType),
debugStringConvertibleItem("textDecorationLineStyle", textDecorationLineStyle),
debugStringConvertibleItem("textDecorationLinePattern", textDecorationLinePattern),
// Decoration
debugStringConvertibleItem("textDecorationColor", textDecorationColor),
debugStringConvertibleItem(
"textDecorationLineType", textDecorationLineType),
debugStringConvertibleItem(
"textDecorationLineStyle", textDecorationLineStyle),
debugStringConvertibleItem(
"textDecorationLinePattern", textDecorationLinePattern),
// Shadow
debugStringConvertibleItem("textShadowOffset", textShadowOffset),
debugStringConvertibleItem("textShadowRadius", textShadowRadius),
debugStringConvertibleItem("textShadowColor", textShadowColor),
// Shadow
debugStringConvertibleItem("textShadowOffset", textShadowOffset),
debugStringConvertibleItem("textShadowRadius", textShadowRadius),
debugStringConvertibleItem("textShadowColor", textShadowColor),
// Special
debugStringConvertibleItem("isHighlighted", isHighlighted),
debugStringConvertibleItem("layoutDirection", layoutDirection),
// Special
debugStringConvertibleItem("isHighlighted", isHighlighted),
debugStringConvertibleItem("layoutDirection", layoutDirection),
};
}
#endif

View File

@ -25,47 +25,45 @@ class TextAttributes;
using SharedTextAttributes = std::shared_ptr<const TextAttributes>;
class TextAttributes:
public DebugStringConvertible {
public:
class TextAttributes : public DebugStringConvertible {
public:
#pragma mark - Fields
// Color
SharedColor foregroundColor {};
SharedColor backgroundColor {};
Float opacity {std::numeric_limits<Float>::quiet_NaN()};
SharedColor foregroundColor{};
SharedColor backgroundColor{};
Float opacity{std::numeric_limits<Float>::quiet_NaN()};
// Font
std::string fontFamily {""};
Float fontSize {std::numeric_limits<Float>::quiet_NaN()};
Float fontSizeMultiplier {std::numeric_limits<Float>::quiet_NaN()};
folly::Optional<FontWeight> fontWeight {};
folly::Optional<FontStyle> fontStyle {};
folly::Optional<FontVariant> fontVariant {};
folly::Optional<bool> allowFontScaling {};
Float letterSpacing {std::numeric_limits<Float>::quiet_NaN()};
std::string fontFamily{""};
Float fontSize{std::numeric_limits<Float>::quiet_NaN()};
Float fontSizeMultiplier{std::numeric_limits<Float>::quiet_NaN()};
folly::Optional<FontWeight> fontWeight{};
folly::Optional<FontStyle> fontStyle{};
folly::Optional<FontVariant> fontVariant{};
folly::Optional<bool> allowFontScaling{};
Float letterSpacing{std::numeric_limits<Float>::quiet_NaN()};
// Paragraph Styles
Float lineHeight {std::numeric_limits<Float>::quiet_NaN()};
folly::Optional<TextAlignment> alignment {};
folly::Optional<WritingDirection> baseWritingDirection {};
Float lineHeight{std::numeric_limits<Float>::quiet_NaN()};
folly::Optional<TextAlignment> alignment{};
folly::Optional<WritingDirection> baseWritingDirection{};
// Decoration
SharedColor textDecorationColor {};
folly::Optional<TextDecorationLineType> textDecorationLineType {};
folly::Optional<TextDecorationLineStyle> textDecorationLineStyle {};
folly::Optional<TextDecorationLinePattern> textDecorationLinePattern {};
SharedColor textDecorationColor{};
folly::Optional<TextDecorationLineType> textDecorationLineType{};
folly::Optional<TextDecorationLineStyle> textDecorationLineStyle{};
folly::Optional<TextDecorationLinePattern> textDecorationLinePattern{};
// Shadow
// TODO: Use `Point` type instead of `Size` for `textShadowOffset` attribute.
folly::Optional<Size> textShadowOffset {};
Float textShadowRadius {std::numeric_limits<Float>::quiet_NaN()};
SharedColor textShadowColor {};
folly::Optional<Size> textShadowOffset{};
Float textShadowRadius{std::numeric_limits<Float>::quiet_NaN()};
SharedColor textShadowColor{};
// Special
folly::Optional<bool> isHighlighted {};
folly::Optional<LayoutDirection> layoutDirection {};
folly::Optional<bool> isHighlighted{};
folly::Optional<LayoutDirection> layoutDirection{};
#pragma mark - Operations
@ -87,33 +85,55 @@ public:
} // namespace facebook
namespace std {
template <>
struct hash<facebook::react::TextAttributes> {
size_t operator()(const facebook::react::TextAttributes &textAttributes) const {
return
std::hash<decltype(textAttributes.foregroundColor)>{}(textAttributes.foregroundColor) +
std::hash<decltype(textAttributes.backgroundColor)>{}(textAttributes.backgroundColor) +
template <>
struct hash<facebook::react::TextAttributes> {
size_t operator()(
const facebook::react::TextAttributes &textAttributes) const {
return std::hash<decltype(textAttributes.foregroundColor)>{}(
textAttributes.foregroundColor) +
std::hash<decltype(textAttributes.backgroundColor)>{}(
textAttributes.backgroundColor) +
std::hash<decltype(textAttributes.opacity)>{}(textAttributes.opacity) +
std::hash<decltype(textAttributes.fontFamily)>{}(textAttributes.fontFamily) +
std::hash<decltype(textAttributes.fontSize)>{}(textAttributes.fontSize) +
std::hash<decltype(textAttributes.fontSizeMultiplier)>{}(textAttributes.fontSizeMultiplier) +
std::hash<decltype(textAttributes.fontWeight)>{}(textAttributes.fontWeight) +
std::hash<decltype(textAttributes.fontStyle)>{}(textAttributes.fontStyle) +
std::hash<decltype(textAttributes.fontVariant)>{}(textAttributes.fontVariant) +
std::hash<decltype(textAttributes.allowFontScaling)>{}(textAttributes.allowFontScaling) +
std::hash<decltype(textAttributes.letterSpacing)>{}(textAttributes.letterSpacing) +
std::hash<decltype(textAttributes.lineHeight)>{}(textAttributes.lineHeight) +
std::hash<decltype(textAttributes.alignment)>{}(textAttributes.alignment) +
std::hash<decltype(textAttributes.baseWritingDirection)>{}(textAttributes.baseWritingDirection) +
std::hash<decltype(textAttributes.textDecorationColor)>{}(textAttributes.textDecorationColor) +
std::hash<decltype(textAttributes.textDecorationLineType)>{}(textAttributes.textDecorationLineType) +
std::hash<decltype(textAttributes.textDecorationLineStyle)>{}(textAttributes.textDecorationLineStyle) +
std::hash<decltype(textAttributes.textDecorationLinePattern)>{}(textAttributes.textDecorationLinePattern) +
std::hash<decltype(textAttributes.textShadowOffset)>{}(textAttributes.textShadowOffset) +
std::hash<decltype(textAttributes.textShadowRadius)>{}(textAttributes.textShadowRadius) +
std::hash<decltype(textAttributes.textShadowColor)>{}(textAttributes.textShadowColor) +
std::hash<decltype(textAttributes.isHighlighted)>{}(textAttributes.isHighlighted) +
std::hash<decltype(textAttributes.layoutDirection)>{}(textAttributes.layoutDirection);
}
};
std::hash<decltype(textAttributes.fontFamily)>{}(
textAttributes.fontFamily) +
std::hash<decltype(textAttributes.fontSize)>{}(
textAttributes.fontSize) +
std::hash<decltype(textAttributes.fontSizeMultiplier)>{}(
textAttributes.fontSizeMultiplier) +
std::hash<decltype(textAttributes.fontWeight)>{}(
textAttributes.fontWeight) +
std::hash<decltype(textAttributes.fontStyle)>{}(
textAttributes.fontStyle) +
std::hash<decltype(textAttributes.fontVariant)>{}(
textAttributes.fontVariant) +
std::hash<decltype(textAttributes.allowFontScaling)>{}(
textAttributes.allowFontScaling) +
std::hash<decltype(textAttributes.letterSpacing)>{}(
textAttributes.letterSpacing) +
std::hash<decltype(textAttributes.lineHeight)>{}(
textAttributes.lineHeight) +
std::hash<decltype(textAttributes.alignment)>{}(
textAttributes.alignment) +
std::hash<decltype(textAttributes.baseWritingDirection)>{}(
textAttributes.baseWritingDirection) +
std::hash<decltype(textAttributes.textDecorationColor)>{}(
textAttributes.textDecorationColor) +
std::hash<decltype(textAttributes.textDecorationLineType)>{}(
textAttributes.textDecorationLineType) +
std::hash<decltype(textAttributes.textDecorationLineStyle)>{}(
textAttributes.textDecorationLineStyle) +
std::hash<decltype(textAttributes.textDecorationLinePattern)>{}(
textAttributes.textDecorationLinePattern) +
std::hash<decltype(textAttributes.textShadowOffset)>{}(
textAttributes.textShadowOffset) +
std::hash<decltype(textAttributes.textShadowRadius)>{}(
textAttributes.textShadowRadius) +
std::hash<decltype(textAttributes.textShadowColor)>{}(
textAttributes.textShadowColor) +
std::hash<decltype(textAttributes.isHighlighted)>{}(
textAttributes.isHighlighted) +
std::hash<decltype(textAttributes.layoutDirection)>{}(
textAttributes.layoutDirection);
}
};
} // namespace std

View File

@ -7,14 +7,14 @@
#pragma once
#include <fabric/attributedstring/conversions.h>
#include <fabric/attributedstring/primitives.h>
#include <fabric/attributedstring/AttributedString.h>
#include <fabric/attributedstring/ParagraphAttributes.h>
#include <fabric/attributedstring/TextAttributes.h>
#include <fabric/attributedstring/conversions.h>
#include <fabric/attributedstring/primitives.h>
#include <fabric/core/conversions.h>
#include <fabric/graphics/conversions.h>
#include <fabric/graphics/Geometry.h>
#include <fabric/graphics/conversions.h>
#include <folly/dynamic.h>
namespace facebook {
@ -22,36 +22,88 @@ namespace react {
inline std::string toString(const EllipsizeMode &ellipsisMode) {
switch (ellipsisMode) {
case EllipsizeMode::Clip: return "clip";
case EllipsizeMode::Head: return "head";
case EllipsizeMode::Tail: return "tail";
case EllipsizeMode::Middle: return "middle";
case EllipsizeMode::Clip:
return "clip";
case EllipsizeMode::Head:
return "head";
case EllipsizeMode::Tail:
return "tail";
case EllipsizeMode::Middle:
return "middle";
}
}
inline void fromDynamic(const folly::dynamic &value, EllipsizeMode &result) {
auto string = value.getString();
if (string == "clip") { result = EllipsizeMode::Clip; return; }
if (string == "head") { result = EllipsizeMode::Head; return; }
if (string == "tail") { result = EllipsizeMode::Tail; return; }
if (string == "middle") { result = EllipsizeMode::Middle; return; }
if (string == "clip") {
result = EllipsizeMode::Clip;
return;
}
if (string == "head") {
result = EllipsizeMode::Head;
return;
}
if (string == "tail") {
result = EllipsizeMode::Tail;
return;
}
if (string == "middle") {
result = EllipsizeMode::Middle;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, FontWeight &result) {
auto string = value.asString();
if (string == "normal") { result = FontWeight::Regular; return; }
if (string == "regular") { result = FontWeight::Regular; return; }
if (string == "bold") { result = FontWeight::Bold; return; }
if (string == "100") { result = FontWeight::Weight100; return; }
if (string == "200") { result = FontWeight::Weight200; return; }
if (string == "300") { result = FontWeight::Weight300; return; }
if (string == "400") { result = FontWeight::Weight400; return; }
if (string == "500") { result = FontWeight::Weight500; return; }
if (string == "600") { result = FontWeight::Weight600; return; }
if (string == "700") { result = FontWeight::Weight700; return; }
if (string == "800") { result = FontWeight::Weight800; return; }
if (string == "900") { result = FontWeight::Weight900; return; }
if (string == "normal") {
result = FontWeight::Regular;
return;
}
if (string == "regular") {
result = FontWeight::Regular;
return;
}
if (string == "bold") {
result = FontWeight::Bold;
return;
}
if (string == "100") {
result = FontWeight::Weight100;
return;
}
if (string == "200") {
result = FontWeight::Weight200;
return;
}
if (string == "300") {
result = FontWeight::Weight300;
return;
}
if (string == "400") {
result = FontWeight::Weight400;
return;
}
if (string == "500") {
result = FontWeight::Weight500;
return;
}
if (string == "600") {
result = FontWeight::Weight600;
return;
}
if (string == "700") {
result = FontWeight::Weight700;
return;
}
if (string == "800") {
result = FontWeight::Weight800;
return;
}
if (string == "900") {
result = FontWeight::Weight900;
return;
}
abort();
}
@ -61,17 +113,29 @@ inline std::string toString(const FontWeight &fontWeight) {
inline void fromDynamic(const folly::dynamic &value, FontStyle &result) {
auto string = value.asString();
if (string == "normal") { result = FontStyle::Normal; return; }
if (string == "italic") { result = FontStyle::Italic; return; }
if (string == "oblique") { result = FontStyle::Oblique; return; }
if (string == "normal") {
result = FontStyle::Normal;
return;
}
if (string == "italic") {
result = FontStyle::Italic;
return;
}
if (string == "oblique") {
result = FontStyle::Oblique;
return;
}
abort();
}
inline std::string toString(const FontStyle &fontStyle) {
switch (fontStyle) {
case FontStyle::Normal: return "normal";
case FontStyle::Italic: return "italic";
case FontStyle::Oblique: return "oblique";
case FontStyle::Normal:
return "normal";
case FontStyle::Italic:
return "italic";
case FontStyle::Oblique:
return "oblique";
}
}
@ -80,22 +144,47 @@ inline void fromDynamic(const folly::dynamic &value, FontVariant &result) {
result = FontVariant::Default;
for (auto &&item : value) {
auto string = item.asString();
if (string == "small-caps") { result = (FontVariant)((int)result | (int)FontVariant::SmallCaps); continue; }
if (string == "oldstyle-nums") { result = (FontVariant)((int)result | (int)FontVariant::OldstyleNums); continue; }
if (string == "lining-nums") { result = (FontVariant)((int)result | (int)FontVariant::LiningNums); continue; }
if (string == "tabular-nums") { result = (FontVariant)((int)result | (int)FontVariant::TabularNums); continue; }
if (string == "proportional-nums") { result = (FontVariant)((int)result | (int)FontVariant::ProportionalNums); continue; }
if (string == "small-caps") {
result = (FontVariant)((int)result | (int)FontVariant::SmallCaps);
continue;
}
if (string == "oldstyle-nums") {
result = (FontVariant)((int)result | (int)FontVariant::OldstyleNums);
continue;
}
if (string == "lining-nums") {
result = (FontVariant)((int)result | (int)FontVariant::LiningNums);
continue;
}
if (string == "tabular-nums") {
result = (FontVariant)((int)result | (int)FontVariant::TabularNums);
continue;
}
if (string == "proportional-nums") {
result = (FontVariant)((int)result | (int)FontVariant::ProportionalNums);
continue;
}
}
}
inline std::string toString(const FontVariant &fontVariant) {
auto result = std::string {};
auto separator = std::string {", "};
if ((int)fontVariant & (int)FontVariant::SmallCaps) { result += "small-caps" + separator; }
if ((int)fontVariant & (int)FontVariant::OldstyleNums) { result += "oldstyle-nums" + separator; }
if ((int)fontVariant & (int)FontVariant::LiningNums) { result += "lining-nums" + separator; }
if ((int)fontVariant & (int)FontVariant::TabularNums) { result += "tabular-nums" + separator; }
if ((int)fontVariant & (int)FontVariant::ProportionalNums) { result += "proportional-nums" + separator; }
auto result = std::string{};
auto separator = std::string{", "};
if ((int)fontVariant & (int)FontVariant::SmallCaps) {
result += "small-caps" + separator;
}
if ((int)fontVariant & (int)FontVariant::OldstyleNums) {
result += "oldstyle-nums" + separator;
}
if ((int)fontVariant & (int)FontVariant::LiningNums) {
result += "lining-nums" + separator;
}
if ((int)fontVariant & (int)FontVariant::TabularNums) {
result += "tabular-nums" + separator;
}
if ((int)fontVariant & (int)FontVariant::ProportionalNums) {
result += "proportional-nums" + separator;
}
if (!result.empty()) {
result.erase(result.length() - separator.length());
@ -106,95 +195,185 @@ inline std::string toString(const FontVariant &fontVariant) {
inline void fromDynamic(const folly::dynamic &value, TextAlignment &result) {
auto string = value.asString();
if (string == "natural") { result = TextAlignment::Natural; return; }
if (string == "left") { result = TextAlignment::Left; return; }
if (string == "center") { result = TextAlignment::Center; return; }
if (string == "right") { result = TextAlignment::Right; return; }
if (string == "justified") { result = TextAlignment::Justified; return; }
if (string == "natural") {
result = TextAlignment::Natural;
return;
}
if (string == "left") {
result = TextAlignment::Left;
return;
}
if (string == "center") {
result = TextAlignment::Center;
return;
}
if (string == "right") {
result = TextAlignment::Right;
return;
}
if (string == "justified") {
result = TextAlignment::Justified;
return;
}
abort();
}
inline std::string toString(const TextAlignment &textAlignment) {
switch (textAlignment) {
case TextAlignment::Natural: return "natural";
case TextAlignment::Left: return "left";
case TextAlignment::Center: return "center";
case TextAlignment::Right: return "right";
case TextAlignment::Justified: return "justified";
case TextAlignment::Natural:
return "natural";
case TextAlignment::Left:
return "left";
case TextAlignment::Center:
return "center";
case TextAlignment::Right:
return "right";
case TextAlignment::Justified:
return "justified";
}
}
inline void fromDynamic(const folly::dynamic &value, WritingDirection &result) {
auto string = value.asString();
if (string == "natural") { result = WritingDirection::Natural; return; }
if (string == "ltr") { result = WritingDirection::LeftToRight; return; }
if (string == "rtl") { result = WritingDirection::RightToLeft; return; }
if (string == "natural") {
result = WritingDirection::Natural;
return;
}
if (string == "ltr") {
result = WritingDirection::LeftToRight;
return;
}
if (string == "rtl") {
result = WritingDirection::RightToLeft;
return;
}
abort();
}
inline std::string toString(const WritingDirection &writingDirection) {
switch (writingDirection) {
case WritingDirection::Natural: return "natural";
case WritingDirection::LeftToRight: return "ltr";
case WritingDirection::RightToLeft: return "rtl";
case WritingDirection::Natural:
return "natural";
case WritingDirection::LeftToRight:
return "ltr";
case WritingDirection::RightToLeft:
return "rtl";
}
}
inline void fromDynamic(const folly::dynamic &value, TextDecorationLineType &result) {
inline void fromDynamic(
const folly::dynamic &value,
TextDecorationLineType &result) {
auto string = value.asString();
if (string == "none") { result = TextDecorationLineType::None; return; }
if (string == "underline") { result = TextDecorationLineType::Underline; return; }
if (string == "strikethrough") { result = TextDecorationLineType::Strikethrough; return; }
if (string == "underline-strikethrough") { result = TextDecorationLineType::UnderlineStrikethrough; return; }
if (string == "none") {
result = TextDecorationLineType::None;
return;
}
if (string == "underline") {
result = TextDecorationLineType::Underline;
return;
}
if (string == "strikethrough") {
result = TextDecorationLineType::Strikethrough;
return;
}
if (string == "underline-strikethrough") {
result = TextDecorationLineType::UnderlineStrikethrough;
return;
}
abort();
}
inline std::string toString(const TextDecorationLineType &textDecorationLineType) {
inline std::string toString(
const TextDecorationLineType &textDecorationLineType) {
switch (textDecorationLineType) {
case TextDecorationLineType::None: return "none";
case TextDecorationLineType::Underline: return "underline";
case TextDecorationLineType::Strikethrough: return "strikethrough";
case TextDecorationLineType::UnderlineStrikethrough: return "underline-strikethrough";
case TextDecorationLineType::None:
return "none";
case TextDecorationLineType::Underline:
return "underline";
case TextDecorationLineType::Strikethrough:
return "strikethrough";
case TextDecorationLineType::UnderlineStrikethrough:
return "underline-strikethrough";
}
}
inline void fromDynamic(const folly::dynamic &value, TextDecorationLineStyle &result) {
inline void fromDynamic(
const folly::dynamic &value,
TextDecorationLineStyle &result) {
auto string = value.asString();
if (string == "single") { result = TextDecorationLineStyle::Single; return; }
if (string == "thick") { result = TextDecorationLineStyle::Thick; return; }
if (string == "double") { result = TextDecorationLineStyle::Double; return; }
if (string == "single") {
result = TextDecorationLineStyle::Single;
return;
}
if (string == "thick") {
result = TextDecorationLineStyle::Thick;
return;
}
if (string == "double") {
result = TextDecorationLineStyle::Double;
return;
}
abort();
}
inline std::string toString(const TextDecorationLineStyle &textDecorationLineStyle) {
inline std::string toString(
const TextDecorationLineStyle &textDecorationLineStyle) {
switch (textDecorationLineStyle) {
case TextDecorationLineStyle::Single: return "single";
case TextDecorationLineStyle::Thick: return "thick";
case TextDecorationLineStyle::Double: return "double";
case TextDecorationLineStyle::Single:
return "single";
case TextDecorationLineStyle::Thick:
return "thick";
case TextDecorationLineStyle::Double:
return "double";
}
}
inline void fromDynamic(const folly::dynamic &value, TextDecorationLinePattern &result) {
inline void fromDynamic(
const folly::dynamic &value,
TextDecorationLinePattern &result) {
auto string = value.asString();
if (string == "solid") { result = TextDecorationLinePattern::Solid; return; }
if (string == "dot") { result = TextDecorationLinePattern::Dot; return; }
if (string == "dash") { result = TextDecorationLinePattern::Dash; return; }
if (string == "dash-dot") { result = TextDecorationLinePattern::DashDot; return; }
if (string == "dash-dot-dot") { result = TextDecorationLinePattern::DashDotDot; return; }
if (string == "solid") {
result = TextDecorationLinePattern::Solid;
return;
}
if (string == "dot") {
result = TextDecorationLinePattern::Dot;
return;
}
if (string == "dash") {
result = TextDecorationLinePattern::Dash;
return;
}
if (string == "dash-dot") {
result = TextDecorationLinePattern::DashDot;
return;
}
if (string == "dash-dot-dot") {
result = TextDecorationLinePattern::DashDotDot;
return;
}
abort();
}
inline std::string toString(const TextDecorationLinePattern &textDecorationLinePattern) {
inline std::string toString(
const TextDecorationLinePattern &textDecorationLinePattern) {
switch (textDecorationLinePattern) {
case TextDecorationLinePattern::Solid: return "solid";
case TextDecorationLinePattern::Dot: return "dot";
case TextDecorationLinePattern::Dash: return "dash";
case TextDecorationLinePattern::DashDot: return "dash-dot";
case TextDecorationLinePattern::DashDotDot: return "dash-dot-dot";
case TextDecorationLinePattern::Solid:
return "solid";
case TextDecorationLinePattern::Dot:
return "dot";
case TextDecorationLinePattern::Dash:
return "dash";
case TextDecorationLinePattern::DashDot:
return "dash-dot";
case TextDecorationLinePattern::DashDotDot:
return "dash-dot-dot";
}
}
inline folly::dynamic toDynamic(const ParagraphAttributes &paragraphAttributes) {
inline folly::dynamic toDynamic(
const ParagraphAttributes &paragraphAttributes) {
auto values = folly::dynamic::object();
values("maximumNumberOfLines", paragraphAttributes.maximumNumberOfLines);
values("ellipsizeMode", toString(paragraphAttributes.ellipsizeMode));
@ -208,7 +387,8 @@ inline folly::dynamic toDynamic(const TextAttributes &textAttributes) {
auto _textAttributes = folly::dynamic::object();
_textAttributes("foregroundColor", toDynamic(textAttributes.foregroundColor));
if (textAttributes.backgroundColor) {
_textAttributes("backgroundColor", toDynamic(textAttributes.backgroundColor));
_textAttributes(
"backgroundColor", toDynamic(textAttributes.backgroundColor));
}
if (!isnan(textAttributes.opacity)) {
_textAttributes("opacity", textAttributes.opacity);
@ -244,35 +424,46 @@ inline folly::dynamic toDynamic(const TextAttributes &textAttributes) {
_textAttributes("alignment", toString(*textAttributes.alignment));
}
if (textAttributes.baseWritingDirection.has_value()) {
_textAttributes("baseWritingDirection", toString(*textAttributes.baseWritingDirection));
_textAttributes(
"baseWritingDirection", toString(*textAttributes.baseWritingDirection));
}
// Decoration
if (textAttributes.textDecorationColor) {
_textAttributes("textDecorationColor", toDynamic(textAttributes.textDecorationColor));
_textAttributes(
"textDecorationColor", toDynamic(textAttributes.textDecorationColor));
}
if (textAttributes.textDecorationLineType.has_value()) {
_textAttributes("textDecorationLineType", toString(*textAttributes.textDecorationLineType));
_textAttributes(
"textDecorationLineType",
toString(*textAttributes.textDecorationLineType));
}
if (textAttributes.textDecorationLineStyle.has_value()) {
_textAttributes("textDecorationLineStyle", toString(*textAttributes.textDecorationLineStyle));
_textAttributes(
"textDecorationLineStyle",
toString(*textAttributes.textDecorationLineStyle));
}
if (textAttributes.textDecorationLinePattern.has_value()) {
_textAttributes("textDecorationLinePattern", toString(*textAttributes.textDecorationLinePattern));
_textAttributes(
"textDecorationLinePattern",
toString(*textAttributes.textDecorationLinePattern));
}
// Shadow
// textShadowOffset = textAttributes.textShadowOffset.has_value() ? textAttributes.textShadowOffset.value() : textShadowOffset;
// textShadowOffset = textAttributes.textShadowOffset.has_value() ?
// textAttributes.textShadowOffset.value() : textShadowOffset;
if (!isnan(textAttributes.textShadowRadius)) {
_textAttributes("textShadowRadius", textAttributes.textShadowRadius);
}
if (textAttributes.textShadowColor) {
_textAttributes("textShadowColor", toDynamic(textAttributes.textShadowColor));
_textAttributes(
"textShadowColor", toDynamic(textAttributes.textShadowColor));
}
// Special
if (textAttributes.isHighlighted.has_value()) {
_textAttributes("isHighlighted", *textAttributes.isHighlighted);
}
if (textAttributes.layoutDirection.has_value()) {
_textAttributes("layoutDirection", toString(*textAttributes.layoutDirection));
_textAttributes(
"layoutDirection", toString(*textAttributes.layoutDirection));
}
return _textAttributes;
}

View File

@ -7,20 +7,15 @@
#pragma once
#include <functional>
#include <limits>
namespace facebook {
namespace react {
enum class FontStyle {
Normal,
Italic,
Oblique
};
enum class FontStyle { Normal, Italic, Oblique };
enum class FontWeight: int {
enum class FontWeight : int {
Weight100 = 100,
UltraLight = 100,
Weight200 = 200,
@ -42,7 +37,7 @@ enum class FontWeight: int {
Black = 900
};
enum class FontVariant: int {
enum class FontVariant : int {
Default = 0,
SmallCaps = 1 << 1,
OldstyleNums = 1 << 2,
@ -52,24 +47,25 @@ enum class FontVariant: int {
};
enum class EllipsizeMode {
Clip, // Do not add ellipsize, simply clip.
Head, // Truncate at head of line: "...wxyz".
Tail, // Truncate at tail of line: "abcd...".
Clip, // Do not add ellipsize, simply clip.
Head, // Truncate at head of line: "...wxyz".
Tail, // Truncate at tail of line: "abcd...".
Middle // Truncate middle of line: "ab...yz".
};
enum class TextAlignment {
Natural, // Indicates the default alignment for script.
Left, // Visually left aligned.
Center, // Visually centered.
Right, // Visually right aligned.
Natural, // Indicates the default alignment for script.
Left, // Visually left aligned.
Center, // Visually centered.
Right, // Visually right aligned.
Justified // Fully-justified. The last line in a paragraph is natural-aligned.
};
enum class WritingDirection {
Natural, // Determines direction using the Unicode Bidi Algorithm rules P2 and P3.
Natural, // Determines direction using the Unicode Bidi Algorithm rules P2 and
// P3.
LeftToRight, // Left to right writing direction.
RightToLeft // Right to left writing direction.
RightToLeft // Right to left writing direction.
};
enum class TextDecorationLineType {
@ -79,12 +75,7 @@ enum class TextDecorationLineType {
UnderlineStrikethrough
};
enum class TextDecorationLineStyle {
Single,
Thick,
Double
};
enum class TextDecorationLineStyle { Single, Thick, Double };
enum class TextDecorationLinePattern {
Solid,
@ -94,90 +85,70 @@ enum class TextDecorationLinePattern {
DashDotDot,
};
} // namespace react
} // namespace facebook
namespace std
{
template <>
struct hash<facebook::react::FontVariant>
{
size_t operator()(const facebook::react::FontVariant& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
namespace std {
template <>
struct hash<facebook::react::FontVariant> {
size_t operator()(const facebook::react::FontVariant &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextAlignment>
{
size_t operator()(const facebook::react::TextAlignment& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextAlignment> {
size_t operator()(const facebook::react::TextAlignment &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::FontStyle>
{
size_t operator()(const facebook::react::FontStyle& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::FontStyle> {
size_t operator()(const facebook::react::FontStyle &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextDecorationLineType>
{
size_t operator()(const facebook::react::TextDecorationLineType& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextDecorationLineType> {
size_t operator()(const facebook::react::TextDecorationLineType &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::WritingDirection>
{
size_t operator()(const facebook::react::WritingDirection& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::WritingDirection> {
size_t operator()(const facebook::react::WritingDirection &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextDecorationLinePattern>
{
size_t operator()(const facebook::react::TextDecorationLinePattern& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextDecorationLinePattern> {
size_t operator()(const facebook::react::TextDecorationLinePattern &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextDecorationLineStyle>
{
size_t operator()(const facebook::react::TextDecorationLineStyle& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextDecorationLineStyle> {
size_t operator()(const facebook::react::TextDecorationLineStyle &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::FontWeight>
{
size_t operator()(const facebook::react::FontWeight& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::FontWeight> {
size_t operator()(const facebook::react::FontWeight &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::EllipsizeMode>
{
size_t operator()(const facebook::react::EllipsizeMode& v) const
{
return hash<int>()(static_cast<int>(v));
}
};
}
template <>
struct hash<facebook::react::EllipsizeMode> {
size_t operator()(const facebook::react::EllipsizeMode &v) const {
return hash<int>()(static_cast<int>(v));
}
};
} // namespace std

View File

@ -7,12 +7,12 @@
#include <memory>
#include <assert.h>
#include <fabric/attributedstring/TextAttributes.h>
#include <fabric/attributedstring/conversions.h>
#include <fabric/attributedstring/primitives.h>
#include <fabric/graphics/conversions.h>
#include <gtest/gtest.h>
#include <assert.h>
namespace facebook {
namespace react {
@ -23,7 +23,8 @@ TEST(AttributedStringTest, testSomething) {
fragment->string = "test";
auto text = new TextAttributes();
text->foregroundColor = {colorFromComponents({100/255.0, 153/255.0, 200/255.0, 1.0})};
text->foregroundColor = {
colorFromComponents({100 / 255.0, 153 / 255.0, 200 / 255.0, 1.0})};
text->opacity = 0.5;
text->fontStyle = FontStyle::Italic;
text->fontWeight = FontWeight::Thin;
@ -41,5 +42,5 @@ TEST(AttributedStringTest, testSomething) {
assert(textAttribute["fontWeight"] == toString(*text->fontWeight));
}
}
}
} // namespace react
} // namespace facebook

View File

@ -7,16 +7,15 @@
#include <memory>
#include <assert.h>
#include <fabric/attributedstring/ParagraphAttributes.h>
#include <fabric/attributedstring/conversions.h>
#include <fabric/attributedstring/primitives.h>
#include <gtest/gtest.h>
#include <assert.h>
namespace facebook {
namespace react {
TEST(ParagraphAttributesTest, testToDynamic) {
auto paragraphAttributes = ParagraphAttributes();
paragraphAttributes.maximumNumberOfLines = 2;
@ -26,12 +25,17 @@ TEST(ParagraphAttributesTest, testToDynamic) {
paragraphAttributes.maximumFontSize = 20;
auto result = toDynamic(paragraphAttributes);
assert(result["maximumNumberOfLines"] == paragraphAttributes.maximumNumberOfLines);
assert(result["adjustsFontSizeToFit"] == paragraphAttributes.adjustsFontSizeToFit);
assert(result["ellipsizeMode"] == toString(paragraphAttributes.ellipsizeMode));
assert(
result["maximumNumberOfLines"] ==
paragraphAttributes.maximumNumberOfLines);
assert(
result["adjustsFontSizeToFit"] ==
paragraphAttributes.adjustsFontSizeToFit);
assert(
result["ellipsizeMode"] == toString(paragraphAttributes.ellipsizeMode));
assert(result["minimumFontSize"] == paragraphAttributes.minimumFontSize);
assert(result["maximumFontSize"] == paragraphAttributes.maximumFontSize);
}
}
}
} // namespace react
} // namespace facebook

View File

@ -7,19 +7,20 @@
#include <memory>
#include <assert.h>
#include <fabric/attributedstring/TextAttributes.h>
#include <fabric/attributedstring/conversions.h>
#include <fabric/attributedstring/primitives.h>
#include <fabric/graphics/conversions.h>
#include <gtest/gtest.h>
#include <assert.h>
namespace facebook {
namespace react {
TEST(TextAttributesTest, testToDynamic) {
auto text = TextAttributes();
text.foregroundColor = {colorFromComponents({200/255.0, 153/255.0, 100/255.0, 1.0})};
text.foregroundColor = {
colorFromComponents({200 / 255.0, 153 / 255.0, 100 / 255.0, 1.0})};
text.opacity = 0.5;
text.fontStyle = FontStyle::Italic;
text.fontWeight = FontWeight::Thin;
@ -32,5 +33,5 @@ TEST(TextAttributesTest, testToDynamic) {
assert(result["fontWeight"] == toString(*text.fontWeight));
}
}
}
} // namespace react
} // namespace facebook

View File

@ -13,7 +13,8 @@
namespace facebook {
namespace react {
using ActivityIndicatorViewComponentDescriptor = ConcreteComponentDescriptor<ActivityIndicatorViewShadowNode>;
using ActivityIndicatorViewComponentDescriptor =
ConcreteComponentDescriptor<ActivityIndicatorViewShadowNode>;
} // namespace react
} // namespace facebook

View File

@ -12,12 +12,17 @@
namespace facebook {
namespace react {
ActivityIndicatorViewProps::ActivityIndicatorViewProps(const ActivityIndicatorViewProps &sourceProps, const RawProps &rawProps):
ViewProps(sourceProps, rawProps),
animating(convertRawProp(rawProps, "animating", sourceProps.animating)),
color(convertRawProp(rawProps, "color", sourceProps.color)),
hidesWhenStopped(convertRawProp(rawProps, "hidesWhenStopped", sourceProps.hidesWhenStopped)),
size(convertRawProp(rawProps, "size", sourceProps.size)) {}
ActivityIndicatorViewProps::ActivityIndicatorViewProps(
const ActivityIndicatorViewProps &sourceProps,
const RawProps &rawProps)
: ViewProps(sourceProps, rawProps),
animating(convertRawProp(rawProps, "animating", sourceProps.animating)),
color(convertRawProp(rawProps, "color", sourceProps.color)),
hidesWhenStopped(convertRawProp(
rawProps,
"hidesWhenStopped",
sourceProps.hidesWhenStopped)),
size(convertRawProp(rawProps, "size", sourceProps.size)) {}
} // namespace react
} // namespace facebook

View File

@ -13,19 +13,20 @@ namespace facebook {
namespace react {
// TODO (T28334063): Consider for codegen.
class ActivityIndicatorViewProps final:
public ViewProps {
public:
class ActivityIndicatorViewProps final : public ViewProps {
public:
ActivityIndicatorViewProps() = default;
ActivityIndicatorViewProps(const ActivityIndicatorViewProps &sourceProps, const RawProps &rawProps);
ActivityIndicatorViewProps(
const ActivityIndicatorViewProps &sourceProps,
const RawProps &rawProps);
#pragma mark - Props
const bool animating {true};
const SharedColor color {colorFromComponents({153/255.0, 153/255.0, 153/255.0, 1.0})}; // #999999
const bool hidesWhenStopped {true};
const ActivityIndicatorViewSize size {ActivityIndicatorViewSize::Small};
const bool animating{true};
const SharedColor color{colorFromComponents(
{153 / 255.0, 153 / 255.0, 153 / 255.0, 1.0})}; // #999999
const bool hidesWhenStopped{true};
const ActivityIndicatorViewSize size{ActivityIndicatorViewSize::Small};
};
} // namespace react

View File

@ -18,11 +18,9 @@ extern const char ActivityIndicatorViewComponentName[];
/*
* `ShadowNode` for <ActivityIndicatorView> component.
*/
using ActivityIndicatorViewShadowNode =
ConcreteViewShadowNode<
using ActivityIndicatorViewShadowNode = ConcreteViewShadowNode<
ActivityIndicatorViewComponentName,
ActivityIndicatorViewProps
>;
ActivityIndicatorViewProps>;
} // namespace react
} // namespace facebook

View File

@ -13,17 +13,27 @@
namespace facebook {
namespace react {
inline void fromDynamic(const folly::dynamic &value, ActivityIndicatorViewSize &result) {
inline void fromDynamic(
const folly::dynamic &value,
ActivityIndicatorViewSize &result) {
auto string = value.asString();
if (string == "large") { result = ActivityIndicatorViewSize::Large; return; }
if (string == "small") { result = ActivityIndicatorViewSize::Small; return; }
if (string == "large") {
result = ActivityIndicatorViewSize::Large;
return;
}
if (string == "small") {
result = ActivityIndicatorViewSize::Small;
return;
}
abort();
}
inline std::string toString(const ActivityIndicatorViewSize &value) {
switch (value) {
case ActivityIndicatorViewSize::Large: return "large";
case ActivityIndicatorViewSize::Small: return "small";
case ActivityIndicatorViewSize::Large:
return "large";
case ActivityIndicatorViewSize::Small:
return "small";
}
}

View File

@ -18,26 +18,31 @@ namespace react {
/*
* Descriptor for <Image> component.
*/
class ImageComponentDescriptor final:
public ConcreteComponentDescriptor<ImageShadowNode> {
public:
ImageComponentDescriptor(SharedEventDispatcher eventDispatcher, const SharedContextContainer &contextContainer):
ConcreteComponentDescriptor(eventDispatcher),
imageManager_(contextContainer ? contextContainer->getInstance<SharedImageManager>() : nullptr) {}
class ImageComponentDescriptor final
: public ConcreteComponentDescriptor<ImageShadowNode> {
public:
ImageComponentDescriptor(
SharedEventDispatcher eventDispatcher,
const SharedContextContainer &contextContainer)
: ConcreteComponentDescriptor(eventDispatcher),
imageManager_(
contextContainer
? contextContainer->getInstance<SharedImageManager>()
: nullptr) {}
void adopt(UnsharedShadowNode shadowNode) const override {
ConcreteComponentDescriptor::adopt(shadowNode);
assert(std::dynamic_pointer_cast<ImageShadowNode>(shadowNode));
auto imageShadowNode = std::static_pointer_cast<ImageShadowNode>(shadowNode);
auto imageShadowNode =
std::static_pointer_cast<ImageShadowNode>(shadowNode);
// `ImageShadowNode` uses `ImageManager` to initiate image loading and
// communicate the loading state and results to mounting layer.
imageShadowNode->setImageManager(imageManager_);
}
private:
private:
const SharedImageManager imageManager_;
};

View File

@ -11,10 +11,8 @@
namespace facebook {
namespace react {
class ImageEventEmitter:
public ViewEventEmitter {
public:
class ImageEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
void onLoadStart() const;

View File

@ -29,9 +29,7 @@ std::string ImageLocalData::getDebugName() const {
}
SharedDebugStringConvertibleList ImageLocalData::getDebugProps() const {
return {
debugStringConvertibleItem("imageSource", imageSource_)
};
return {debugStringConvertibleItem("imageSource", imageSource_)};
}
#endif

View File

@ -8,8 +8,8 @@
#pragma once
#include <fabric/core/LocalData.h>
#include <fabric/imagemanager/primitives.h>
#include <fabric/imagemanager/ImageRequest.h>
#include <fabric/imagemanager/primitives.h>
namespace facebook {
namespace react {
@ -22,14 +22,10 @@ using SharedImageLocalData = std::shared_ptr<const ImageLocalData>;
* LocalData for <Image> component.
* Represents the image request state and (possible) retrieved image bitmap.
*/
class ImageLocalData:
public LocalData {
public:
ImageLocalData(const ImageSource &imageSource, ImageRequest imageRequest):
imageSource_(imageSource),
imageRequest_(std::move(imageRequest)) {};
class ImageLocalData : public LocalData {
public:
ImageLocalData(const ImageSource &imageSource, ImageRequest imageRequest)
: imageSource_(imageSource), imageRequest_(std::move(imageRequest)){};
/*
* Returns stored ImageSource object.
@ -49,8 +45,7 @@ public:
SharedDebugStringConvertibleList getDebugProps() const override;
#endif
private:
private:
ImageSource imageSource_;
ImageRequest imageRequest_;
};

View File

@ -5,21 +5,29 @@
* LICENSE file in the root directory of this source tree.
*/
#include <fabric/components/image/conversions.h>
#include <fabric/components/image/ImageProps.h>
#include <fabric/components/image/conversions.h>
#include <fabric/core/propsConversions.h>
namespace facebook {
namespace react {
ImageProps::ImageProps(const ImageProps &sourceProps, const RawProps &rawProps):
ViewProps(sourceProps, rawProps),
sources(convertRawProp(rawProps, "source", sourceProps.sources)),
defaultSources(convertRawProp(rawProps, "defaultSource", sourceProps.defaultSources)),
resizeMode(convertRawProp(rawProps, "resizeMode", sourceProps.resizeMode, ImageResizeMode::Stretch)),
blurRadius(convertRawProp(rawProps, "blurRadius", sourceProps.blurRadius)),
capInsets(convertRawProp(rawProps, "capInsets", sourceProps.capInsets)),
tintColor(convertRawProp(rawProps, "tintColor", sourceProps.tintColor)) {}
ImageProps::ImageProps(const ImageProps &sourceProps, const RawProps &rawProps)
: ViewProps(sourceProps, rawProps),
sources(convertRawProp(rawProps, "source", sourceProps.sources)),
defaultSources(convertRawProp(
rawProps,
"defaultSource",
sourceProps.defaultSources)),
resizeMode(convertRawProp(
rawProps,
"resizeMode",
sourceProps.resizeMode,
ImageResizeMode::Stretch)),
blurRadius(
convertRawProp(rawProps, "blurRadius", sourceProps.blurRadius)),
capInsets(convertRawProp(rawProps, "capInsets", sourceProps.capInsets)),
tintColor(convertRawProp(rawProps, "tintColor", sourceProps.tintColor)) {}
} // namespace react
} // namespace facebook

View File

@ -13,21 +13,19 @@ namespace facebook {
namespace react {
// TODO (T28334063): Consider for codegen.
class ImageProps final:
public ViewProps {
public:
class ImageProps final : public ViewProps {
public:
ImageProps() = default;
ImageProps(const ImageProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const ImageSources sources {};
const ImageSources defaultSources {};
const ImageResizeMode resizeMode {ImageResizeMode::Stretch};
const Float blurRadius {};
const EdgeInsets capInsets {};
const SharedColor tintColor {};
const ImageSources sources{};
const ImageSources defaultSources{};
const ImageResizeMode resizeMode{ImageResizeMode::Stretch};
const Float blurRadius{};
const EdgeInsets capInsets{};
const SharedColor tintColor{};
};
} // namespace react

View File

@ -7,8 +7,8 @@
#include <cstdlib>
#include <fabric/components/image/ImageShadowNode.h>
#include <fabric/components/image/ImageLocalData.h>
#include <fabric/components/image/ImageShadowNode.h>
#include <fabric/core/LayoutContext.h>
namespace facebook {
@ -26,7 +26,8 @@ void ImageShadowNode::updateLocalData() {
const auto &currentLocalData = getLocalData();
if (currentLocalData) {
assert(std::dynamic_pointer_cast<const ImageLocalData>(currentLocalData));
auto currentImageLocalData = std::static_pointer_cast<const ImageLocalData>(currentLocalData);
auto currentImageLocalData =
std::static_pointer_cast<const ImageLocalData>(currentLocalData);
if (currentImageLocalData->getImageSource() == imageSource) {
// Same `imageSource` is already in `localData`,
// no need to (re)request an image resource.
@ -38,7 +39,8 @@ void ImageShadowNode::updateLocalData() {
ensureUnsealed();
auto imageRequest = imageManager_->requestImage(imageSource);
auto imageLocalData = std::make_shared<ImageLocalData>(imageSource, std::move(imageRequest));
auto imageLocalData =
std::make_shared<ImageLocalData>(imageSource, std::move(imageRequest));
setLocalData(imageLocalData);
}
@ -59,13 +61,13 @@ ImageSource ImageShadowNode::getImageSource() const {
auto targetImageArea = size.width * size.height * scale * scale;
auto bestFit = kFloatMax;
auto bestSource = ImageSource {};
auto bestSource = ImageSource{};
for (const auto &source : sources) {
auto sourceSize = source.size;
auto sourceScale = source.scale == 0 ? scale : source.scale;
auto sourceArea =
sourceSize.width * sourceSize.height * sourceScale * sourceScale;
sourceSize.width * sourceSize.height * sourceScale * sourceScale;
auto fit = std::abs(1 - (sourceArea / targetImageArea));

View File

@ -21,15 +21,11 @@ extern const char ImageComponentName[];
/*
* `ShadowNode` for <Image> component.
*/
class ImageShadowNode final:
public ConcreteViewShadowNode<
ImageComponentName,
ImageProps,
ImageEventEmitter
> {
public:
class ImageShadowNode final : public ConcreteViewShadowNode<
ImageComponentName,
ImageProps,
ImageEventEmitter> {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
/*
@ -41,8 +37,7 @@ public:
void layout(LayoutContext layoutContext) override;
private:
private:
/*
* (Re)Creates a `LocalData` object (with `ImageRequest`) if needed.
*/

View File

@ -7,8 +7,8 @@
#pragma once
#include <fabric/imagemanager/primitives.h>
#include <fabric/graphics/conversions.h>
#include <fabric/imagemanager/primitives.h>
#include <folly/dynamic.h>
namespace facebook {
@ -16,10 +16,7 @@ namespace react {
inline void fromDynamic(const folly::dynamic &value, ImageSource &result) {
if (value.isString()) {
result = {
.type = ImageSource::Type::Remote,
.uri = value.asString()
};
result = {.type = ImageSource::Type::Remote, .uri = value.asString()};
return;
}
@ -68,21 +65,41 @@ inline std::string toString(const ImageSource &value) {
inline void fromDynamic(const folly::dynamic &value, ImageResizeMode &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "cover") { result = ImageResizeMode::Cover; return; }
if (stringValue == "contain") { result = ImageResizeMode::Contain; return; }
if (stringValue == "stretch") { result = ImageResizeMode::Stretch; return; }
if (stringValue == "center") { result = ImageResizeMode::Center; return; }
if (stringValue == "repeat") { result = ImageResizeMode::Repeat; return; }
if (stringValue == "cover") {
result = ImageResizeMode::Cover;
return;
}
if (stringValue == "contain") {
result = ImageResizeMode::Contain;
return;
}
if (stringValue == "stretch") {
result = ImageResizeMode::Stretch;
return;
}
if (stringValue == "center") {
result = ImageResizeMode::Center;
return;
}
if (stringValue == "repeat") {
result = ImageResizeMode::Repeat;
return;
}
abort();
}
inline std::string toString(const ImageResizeMode &value) {
switch (value) {
case ImageResizeMode::Cover: return "cover";
case ImageResizeMode::Contain: return "contain";
case ImageResizeMode::Stretch: return "stretch";
case ImageResizeMode::Center: return "center";
case ImageResizeMode::Repeat: return "repeat";
case ImageResizeMode::Cover:
return "cover";
case ImageResizeMode::Contain:
return "contain";
case ImageResizeMode::Stretch:
return "stretch";
case ImageResizeMode::Center:
return "center";
case ImageResizeMode::Repeat:
return "repeat";
}
}

View File

@ -7,35 +7,35 @@
#include "RootProps.h"
#include <fabric/components/view/conversions.h>
#include <fabric/components/view/YogaLayoutableShadowNode.h>
#include <fabric/components/view/conversions.h>
namespace facebook {
namespace react {
static YGStyle yogaStyleFromLayoutConstraints(const LayoutConstraints &layoutConstraints) {
auto yogaStyle = YGStyle {};
static YGStyle yogaStyleFromLayoutConstraints(
const LayoutConstraints &layoutConstraints) {
auto yogaStyle = YGStyle{};
yogaStyle.minDimensions[YGDimensionWidth] =
yogaStyleValueFromFloat(layoutConstraints.minimumSize.width);
yogaStyleValueFromFloat(layoutConstraints.minimumSize.width);
yogaStyle.minDimensions[YGDimensionHeight] =
yogaStyleValueFromFloat(layoutConstraints.minimumSize.height);
yogaStyleValueFromFloat(layoutConstraints.minimumSize.height);
yogaStyle.maxDimensions[YGDimensionWidth] =
yogaStyleValueFromFloat(layoutConstraints.maximumSize.width);
yogaStyleValueFromFloat(layoutConstraints.maximumSize.width);
yogaStyle.maxDimensions[YGDimensionHeight] =
yogaStyleValueFromFloat(layoutConstraints.maximumSize.height);
yogaStyleValueFromFloat(layoutConstraints.maximumSize.height);
return yogaStyle;
}
RootProps::RootProps(
const RootProps &sourceProps,
const LayoutConstraints &layoutConstraints,
const LayoutContext &layoutContext
):
ViewProps(yogaStyleFromLayoutConstraints(layoutConstraints)),
layoutConstraints(layoutConstraints),
layoutContext(layoutContext) {};
const RootProps &sourceProps,
const LayoutConstraints &layoutConstraints,
const LayoutContext &layoutContext)
: ViewProps(yogaStyleFromLayoutConstraints(layoutConstraints)),
layoutConstraints(layoutConstraints),
layoutContext(layoutContext){};
} // namespace react
} // namespace facebook

View File

@ -20,21 +20,18 @@ class RootProps;
using SharedRootProps = std::shared_ptr<const RootProps>;
class RootProps final:
public ViewProps {
public:
class RootProps final : public ViewProps {
public:
RootProps() = default;
RootProps(
const RootProps &sourceProps,
const LayoutConstraints &layoutConstraints,
const LayoutContext &layoutContext
);
const RootProps &sourceProps,
const LayoutConstraints &layoutConstraints,
const LayoutContext &layoutContext);
#pragma mark - Props
const LayoutConstraints layoutConstraints {};
const LayoutContext layoutContext {};
const LayoutConstraints layoutConstraints{};
const LayoutContext layoutContext{};
};
} // namespace react

View File

@ -29,14 +29,9 @@ extern const char RootComponentName[];
* props which represent external layout constraints and context of the
* shadow tree.
*/
class RootShadowNode final:
public ConcreteViewShadowNode<
RootComponentName,
RootProps
> {
public:
class RootShadowNode final
: public ConcreteViewShadowNode<RootComponentName, RootProps> {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
/*
@ -44,8 +39,7 @@ public:
*/
void layout();
private:
private:
using YogaLayoutableShadowNode::layout;
};

View File

@ -13,7 +13,8 @@
namespace facebook {
namespace react {
using ScrollViewComponentDescriptor = ConcreteComponentDescriptor<ScrollViewShadowNode>;
using ScrollViewComponentDescriptor =
ConcreteComponentDescriptor<ScrollViewShadowNode>;
} // namespace react
} // namespace facebook

View File

@ -10,46 +10,54 @@
namespace facebook {
namespace react {
void ScrollViewEventEmitter::onScroll(const ScrollViewMetrics &scrollViewMetrics) const {
void ScrollViewEventEmitter::onScroll(
const ScrollViewMetrics &scrollViewMetrics) const {
dispatchScrollViewEvent("scroll", scrollViewMetrics);
}
void ScrollViewEventEmitter::onScrollBeginDrag(const ScrollViewMetrics &scrollViewMetrics) const {
void ScrollViewEventEmitter::onScrollBeginDrag(
const ScrollViewMetrics &scrollViewMetrics) const {
dispatchScrollViewEvent("scrollBeginDrag", scrollViewMetrics);
}
void ScrollViewEventEmitter::onScrollEndDrag(const ScrollViewMetrics &scrollViewMetrics) const {
void ScrollViewEventEmitter::onScrollEndDrag(
const ScrollViewMetrics &scrollViewMetrics) const {
dispatchScrollViewEvent("scrollEndDrag", scrollViewMetrics);
}
void ScrollViewEventEmitter::onMomentumScrollBegin(const ScrollViewMetrics &scrollViewMetrics) const {
void ScrollViewEventEmitter::onMomentumScrollBegin(
const ScrollViewMetrics &scrollViewMetrics) const {
dispatchScrollViewEvent("momentumScrollBegin", scrollViewMetrics);
}
void ScrollViewEventEmitter::onMomentumScrollEnd(const ScrollViewMetrics &scrollViewMetrics) const {
void ScrollViewEventEmitter::onMomentumScrollEnd(
const ScrollViewMetrics &scrollViewMetrics) const {
dispatchScrollViewEvent("momentumScrollEnd", scrollViewMetrics);
}
void ScrollViewEventEmitter::dispatchScrollViewEvent(const std::string &name, const ScrollViewMetrics &scrollViewMetrics, const folly::dynamic &payload) const {
void ScrollViewEventEmitter::dispatchScrollViewEvent(
const std::string &name,
const ScrollViewMetrics &scrollViewMetrics,
const folly::dynamic &payload) const {
folly::dynamic compoundPayload = folly::dynamic::object();
compoundPayload["contentOffset"] = folly::dynamic::object
("x", scrollViewMetrics.contentOffset.x)
("y", scrollViewMetrics.contentOffset.y);
compoundPayload["contentOffset"] =
folly::dynamic::object("x", scrollViewMetrics.contentOffset.x)(
"y", scrollViewMetrics.contentOffset.y);
compoundPayload["contentInset"] = folly::dynamic::object
("top", scrollViewMetrics.contentInset.top)
("left", scrollViewMetrics.contentInset.left)
("bottom", scrollViewMetrics.contentInset.bottom)
("right", scrollViewMetrics.contentInset.right);
compoundPayload["contentInset"] =
folly::dynamic::object("top", scrollViewMetrics.contentInset.top)(
"left", scrollViewMetrics.contentInset.left)(
"bottom", scrollViewMetrics.contentInset.bottom)(
"right", scrollViewMetrics.contentInset.right);
compoundPayload["contentSize"] = folly::dynamic::object
("width", scrollViewMetrics.contentSize.width)
("height", scrollViewMetrics.contentSize.height);
compoundPayload["contentSize"] =
folly::dynamic::object("width", scrollViewMetrics.contentSize.width)(
"height", scrollViewMetrics.contentSize.height);
compoundPayload["layoutMeasurement"] = folly::dynamic::object
("width", scrollViewMetrics.containerSize.width)
("height", scrollViewMetrics.containerSize.height);
compoundPayload["layoutMeasurement"] =
folly::dynamic::object("width", scrollViewMetrics.containerSize.width)(
"height", scrollViewMetrics.containerSize.height);
compoundPayload["zoomScale"] = scrollViewMetrics.zoomScale;

View File

@ -17,7 +17,7 @@ namespace facebook {
namespace react {
class ScrollViewMetrics {
public:
public:
Size contentSize;
Point contentOffset;
EdgeInsets contentInset;
@ -27,13 +27,11 @@ public:
class ScrollViewEventEmitter;
using SharedScrollViewEventEmitter = std::shared_ptr<const ScrollViewEventEmitter>;
class ScrollViewEventEmitter:
public ViewEventEmitter {
public:
using SharedScrollViewEventEmitter =
std::shared_ptr<const ScrollViewEventEmitter>;
class ScrollViewEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
void onScroll(const ScrollViewMetrics &scrollViewMetrics) const;
@ -42,9 +40,11 @@ public:
void onMomentumScrollBegin(const ScrollViewMetrics &scrollViewMetrics) const;
void onMomentumScrollEnd(const ScrollViewMetrics &scrollViewMetrics) const;
private:
void dispatchScrollViewEvent(const std::string &name, const ScrollViewMetrics &scrollViewMetrics, const folly::dynamic &payload = {}) const;
private:
void dispatchScrollViewEvent(
const std::string &name,
const ScrollViewMetrics &scrollViewMetrics,
const folly::dynamic &payload = {}) const;
};
} // namespace react

View File

@ -13,11 +13,11 @@
namespace facebook {
namespace react {
ScrollViewLocalData::ScrollViewLocalData(Rect contentBoundingRect):
contentBoundingRect(contentBoundingRect) {}
ScrollViewLocalData::ScrollViewLocalData(Rect contentBoundingRect)
: contentBoundingRect(contentBoundingRect) {}
Size ScrollViewLocalData::getContentSize() const {
return Size {contentBoundingRect.getMaxX(), contentBoundingRect.getMaxY()};
return Size{contentBoundingRect.getMaxX(), contentBoundingRect.getMaxY()};
}
#pragma mark - DebugStringConvertible
@ -29,8 +29,7 @@ std::string ScrollViewLocalData::getDebugName() const {
SharedDebugStringConvertibleList ScrollViewLocalData::getDebugProps() const {
return {
debugStringConvertibleItem("contentBoundingRect", contentBoundingRect)
};
debugStringConvertibleItem("contentBoundingRect", contentBoundingRect)};
}
#endif

View File

@ -20,10 +20,8 @@ using SharedScrollViewLocalData = std::shared_ptr<const ScrollViewLocalData>;
/*
* LocalData for <ScrollView> component.
*/
class ScrollViewLocalData:
public LocalData {
public:
class ScrollViewLocalData : public LocalData {
public:
ScrollViewLocalData(Rect contentBoundingRect);
/*

View File

@ -16,69 +16,217 @@
namespace facebook {
namespace react {
ScrollViewProps::ScrollViewProps(const ScrollViewProps &sourceProps, const RawProps &rawProps):
ViewProps(sourceProps, rawProps),
alwaysBounceHorizontal(convertRawProp(rawProps, "alwaysBounceHorizontal", sourceProps.alwaysBounceHorizontal, true)),
alwaysBounceVertical(convertRawProp(rawProps, "alwaysBounceVertical", sourceProps.alwaysBounceVertical, true)),
bounces(convertRawProp(rawProps, "bounces", sourceProps.bounces, true)),
bouncesZoom(convertRawProp(rawProps, "bouncesZoom", sourceProps.bouncesZoom, true)),
canCancelContentTouches(convertRawProp(rawProps, "canCancelContentTouches", sourceProps.canCancelContentTouches)),
centerContent(convertRawProp(rawProps, "centerContent", sourceProps.centerContent)),
automaticallyAdjustContentInsets(convertRawProp(rawProps, "automaticallyAdjustContentInsets", sourceProps.automaticallyAdjustContentInsets)),
decelerationRate(convertRawProp(rawProps, "decelerationRate", sourceProps.decelerationRate, (Float)0.998)),
directionalLockEnabled(convertRawProp(rawProps, "directionalLockEnabled", sourceProps.directionalLockEnabled)),
indicatorStyle(convertRawProp(rawProps, "indicatorStyle", sourceProps.indicatorStyle)),
keyboardDismissMode(convertRawProp(rawProps, "keyboardDismissMode", sourceProps.keyboardDismissMode)),
maximumZoomScale(convertRawProp(rawProps, "maximumZoomScale", sourceProps.maximumZoomScale, (Float)1.0)),
minimumZoomScale(convertRawProp(rawProps, "minimumZoomScale", sourceProps.minimumZoomScale, (Float)1.0)),
scrollEnabled(convertRawProp(rawProps, "scrollEnabled", sourceProps.scrollEnabled, true)),
pagingEnabled(convertRawProp(rawProps, "pagingEnabled", sourceProps.pagingEnabled)),
pinchGestureEnabled(convertRawProp(rawProps, "pinchGestureEnabled", sourceProps.pinchGestureEnabled, true)),
scrollsToTop(convertRawProp(rawProps, "scrollsToTop", sourceProps.scrollsToTop, true)),
showsHorizontalScrollIndicator(convertRawProp(rawProps, "showsHorizontalScrollIndicator", sourceProps.showsHorizontalScrollIndicator, true)),
showsVerticalScrollIndicator(convertRawProp(rawProps, "showsVerticalScrollIndicator", sourceProps.showsVerticalScrollIndicator, true)),
scrollEventThrottle(convertRawProp(rawProps, "scrollEventThrottle", sourceProps.scrollEventThrottle)),
zoomScale(convertRawProp(rawProps, "zoomScale", sourceProps.zoomScale, (Float)1.0)),
contentInset(convertRawProp(rawProps, "contentInset", sourceProps.contentInset)),
scrollIndicatorInsets(convertRawProp(rawProps, "scrollIndicatorInsets", sourceProps.scrollIndicatorInsets)),
snapToInterval(convertRawProp(rawProps, "snapToInterval", sourceProps.snapToInterval)),
snapToAlignment(convertRawProp(rawProps, "snapToAlignment", sourceProps.snapToAlignment)) {}
ScrollViewProps::ScrollViewProps(
const ScrollViewProps &sourceProps,
const RawProps &rawProps)
: ViewProps(sourceProps, rawProps),
alwaysBounceHorizontal(convertRawProp(
rawProps,
"alwaysBounceHorizontal",
sourceProps.alwaysBounceHorizontal,
true)),
alwaysBounceVertical(convertRawProp(
rawProps,
"alwaysBounceVertical",
sourceProps.alwaysBounceVertical,
true)),
bounces(convertRawProp(rawProps, "bounces", sourceProps.bounces, true)),
bouncesZoom(convertRawProp(
rawProps,
"bouncesZoom",
sourceProps.bouncesZoom,
true)),
canCancelContentTouches(convertRawProp(
rawProps,
"canCancelContentTouches",
sourceProps.canCancelContentTouches)),
centerContent(
convertRawProp(rawProps, "centerContent", sourceProps.centerContent)),
automaticallyAdjustContentInsets(convertRawProp(
rawProps,
"automaticallyAdjustContentInsets",
sourceProps.automaticallyAdjustContentInsets)),
decelerationRate(convertRawProp(
rawProps,
"decelerationRate",
sourceProps.decelerationRate,
(Float)0.998)),
directionalLockEnabled(convertRawProp(
rawProps,
"directionalLockEnabled",
sourceProps.directionalLockEnabled)),
indicatorStyle(convertRawProp(
rawProps,
"indicatorStyle",
sourceProps.indicatorStyle)),
keyboardDismissMode(convertRawProp(
rawProps,
"keyboardDismissMode",
sourceProps.keyboardDismissMode)),
maximumZoomScale(convertRawProp(
rawProps,
"maximumZoomScale",
sourceProps.maximumZoomScale,
(Float)1.0)),
minimumZoomScale(convertRawProp(
rawProps,
"minimumZoomScale",
sourceProps.minimumZoomScale,
(Float)1.0)),
scrollEnabled(convertRawProp(
rawProps,
"scrollEnabled",
sourceProps.scrollEnabled,
true)),
pagingEnabled(
convertRawProp(rawProps, "pagingEnabled", sourceProps.pagingEnabled)),
pinchGestureEnabled(convertRawProp(
rawProps,
"pinchGestureEnabled",
sourceProps.pinchGestureEnabled,
true)),
scrollsToTop(convertRawProp(
rawProps,
"scrollsToTop",
sourceProps.scrollsToTop,
true)),
showsHorizontalScrollIndicator(convertRawProp(
rawProps,
"showsHorizontalScrollIndicator",
sourceProps.showsHorizontalScrollIndicator,
true)),
showsVerticalScrollIndicator(convertRawProp(
rawProps,
"showsVerticalScrollIndicator",
sourceProps.showsVerticalScrollIndicator,
true)),
scrollEventThrottle(convertRawProp(
rawProps,
"scrollEventThrottle",
sourceProps.scrollEventThrottle)),
zoomScale(convertRawProp(
rawProps,
"zoomScale",
sourceProps.zoomScale,
(Float)1.0)),
contentInset(
convertRawProp(rawProps, "contentInset", sourceProps.contentInset)),
scrollIndicatorInsets(convertRawProp(
rawProps,
"scrollIndicatorInsets",
sourceProps.scrollIndicatorInsets)),
snapToInterval(convertRawProp(
rawProps,
"snapToInterval",
sourceProps.snapToInterval)),
snapToAlignment(convertRawProp(
rawProps,
"snapToAlignment",
sourceProps.snapToAlignment)) {}
#pragma mark - DebugStringConvertible
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList ScrollViewProps::getDebugProps() const {
auto defaultScrollViewProps = ScrollViewProps {};
auto defaultScrollViewProps = ScrollViewProps{};
return
ViewProps::getDebugProps() +
SharedDebugStringConvertibleList {
debugStringConvertibleItem("alwaysBounceHorizontal", alwaysBounceHorizontal, defaultScrollViewProps.alwaysBounceHorizontal),
debugStringConvertibleItem("alwaysBounceVertical", alwaysBounceVertical, defaultScrollViewProps.alwaysBounceVertical),
debugStringConvertibleItem("bounces", bounces, defaultScrollViewProps.bounces),
debugStringConvertibleItem("bouncesZoom", bouncesZoom, defaultScrollViewProps.bouncesZoom),
debugStringConvertibleItem("canCancelContentTouches", canCancelContentTouches, defaultScrollViewProps.canCancelContentTouches),
debugStringConvertibleItem("centerContent", centerContent, defaultScrollViewProps.centerContent),
debugStringConvertibleItem("automaticallyAdjustContentInsets", automaticallyAdjustContentInsets, defaultScrollViewProps.automaticallyAdjustContentInsets),
debugStringConvertibleItem("decelerationRate", decelerationRate, defaultScrollViewProps.decelerationRate),
debugStringConvertibleItem("directionalLockEnabled", directionalLockEnabled, defaultScrollViewProps.directionalLockEnabled),
debugStringConvertibleItem("indicatorStyle", indicatorStyle, defaultScrollViewProps.indicatorStyle),
debugStringConvertibleItem("keyboardDismissMode", keyboardDismissMode, defaultScrollViewProps.keyboardDismissMode),
debugStringConvertibleItem("maximumZoomScale", maximumZoomScale, defaultScrollViewProps.maximumZoomScale),
debugStringConvertibleItem("minimumZoomScale", minimumZoomScale, defaultScrollViewProps.minimumZoomScale),
debugStringConvertibleItem("scrollEnabled", scrollEnabled, defaultScrollViewProps.scrollEnabled),
debugStringConvertibleItem("pagingEnabled", pagingEnabled, defaultScrollViewProps.pagingEnabled),
debugStringConvertibleItem("pinchGestureEnabled", pinchGestureEnabled, defaultScrollViewProps.pinchGestureEnabled),
debugStringConvertibleItem("scrollsToTop", scrollsToTop, defaultScrollViewProps.scrollsToTop),
debugStringConvertibleItem("showsHorizontalScrollIndicator", showsHorizontalScrollIndicator, defaultScrollViewProps.showsHorizontalScrollIndicator),
debugStringConvertibleItem("showsVerticalScrollIndicator", showsVerticalScrollIndicator, defaultScrollViewProps.showsVerticalScrollIndicator),
debugStringConvertibleItem("scrollEventThrottle", scrollEventThrottle, defaultScrollViewProps.scrollEventThrottle),
debugStringConvertibleItem("zoomScale", zoomScale, defaultScrollViewProps.zoomScale),
debugStringConvertibleItem("contentInset", contentInset, defaultScrollViewProps.contentInset),
debugStringConvertibleItem("scrollIndicatorInsets", scrollIndicatorInsets, defaultScrollViewProps.scrollIndicatorInsets),
debugStringConvertibleItem("snapToInterval", snapToInterval, defaultScrollViewProps.snapToInterval),
debugStringConvertibleItem("snapToAlignment", snapToAlignment, defaultScrollViewProps.snapToAlignment),
};
return ViewProps::getDebugProps() +
SharedDebugStringConvertibleList{
debugStringConvertibleItem(
"alwaysBounceHorizontal",
alwaysBounceHorizontal,
defaultScrollViewProps.alwaysBounceHorizontal),
debugStringConvertibleItem(
"alwaysBounceVertical",
alwaysBounceVertical,
defaultScrollViewProps.alwaysBounceVertical),
debugStringConvertibleItem(
"bounces", bounces, defaultScrollViewProps.bounces),
debugStringConvertibleItem(
"bouncesZoom", bouncesZoom, defaultScrollViewProps.bouncesZoom),
debugStringConvertibleItem(
"canCancelContentTouches",
canCancelContentTouches,
defaultScrollViewProps.canCancelContentTouches),
debugStringConvertibleItem(
"centerContent",
centerContent,
defaultScrollViewProps.centerContent),
debugStringConvertibleItem(
"automaticallyAdjustContentInsets",
automaticallyAdjustContentInsets,
defaultScrollViewProps.automaticallyAdjustContentInsets),
debugStringConvertibleItem(
"decelerationRate",
decelerationRate,
defaultScrollViewProps.decelerationRate),
debugStringConvertibleItem(
"directionalLockEnabled",
directionalLockEnabled,
defaultScrollViewProps.directionalLockEnabled),
debugStringConvertibleItem(
"indicatorStyle",
indicatorStyle,
defaultScrollViewProps.indicatorStyle),
debugStringConvertibleItem(
"keyboardDismissMode",
keyboardDismissMode,
defaultScrollViewProps.keyboardDismissMode),
debugStringConvertibleItem(
"maximumZoomScale",
maximumZoomScale,
defaultScrollViewProps.maximumZoomScale),
debugStringConvertibleItem(
"minimumZoomScale",
minimumZoomScale,
defaultScrollViewProps.minimumZoomScale),
debugStringConvertibleItem(
"scrollEnabled",
scrollEnabled,
defaultScrollViewProps.scrollEnabled),
debugStringConvertibleItem(
"pagingEnabled",
pagingEnabled,
defaultScrollViewProps.pagingEnabled),
debugStringConvertibleItem(
"pinchGestureEnabled",
pinchGestureEnabled,
defaultScrollViewProps.pinchGestureEnabled),
debugStringConvertibleItem(
"scrollsToTop",
scrollsToTop,
defaultScrollViewProps.scrollsToTop),
debugStringConvertibleItem(
"showsHorizontalScrollIndicator",
showsHorizontalScrollIndicator,
defaultScrollViewProps.showsHorizontalScrollIndicator),
debugStringConvertibleItem(
"showsVerticalScrollIndicator",
showsVerticalScrollIndicator,
defaultScrollViewProps.showsVerticalScrollIndicator),
debugStringConvertibleItem(
"scrollEventThrottle",
scrollEventThrottle,
defaultScrollViewProps.scrollEventThrottle),
debugStringConvertibleItem(
"zoomScale", zoomScale, defaultScrollViewProps.zoomScale),
debugStringConvertibleItem(
"contentInset",
contentInset,
defaultScrollViewProps.contentInset),
debugStringConvertibleItem(
"scrollIndicatorInsets",
scrollIndicatorInsets,
defaultScrollViewProps.scrollIndicatorInsets),
debugStringConvertibleItem(
"snapToInterval",
snapToInterval,
defaultScrollViewProps.snapToInterval),
debugStringConvertibleItem(
"snapToAlignment",
snapToAlignment,
defaultScrollViewProps.snapToAlignment),
};
}
#endif

View File

@ -14,40 +14,38 @@ namespace facebook {
namespace react {
// TODO (T28334063): Consider for codegen.
class ScrollViewProps final:
public ViewProps {
public:
class ScrollViewProps final : public ViewProps {
public:
ScrollViewProps() = default;
ScrollViewProps(const ScrollViewProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const bool alwaysBounceHorizontal {true};
const bool alwaysBounceVertical {true};
const bool bounces {true};
const bool bouncesZoom {true};
const bool canCancelContentTouches {true};
const bool centerContent {};
const bool automaticallyAdjustContentInsets {};
const Float decelerationRate {0.998};
const bool directionalLockEnabled {};
const ScrollViewIndicatorStyle indicatorStyle {};
const ScrollViewKeyboardDismissMode keyboardDismissMode {};
const Float maximumZoomScale {1.0};
const Float minimumZoomScale {1.0};
const bool scrollEnabled {true};
const bool pagingEnabled {};
const bool pinchGestureEnabled {true};
const bool scrollsToTop {true};
const bool showsHorizontalScrollIndicator {true};
const bool showsVerticalScrollIndicator {true};
const Float scrollEventThrottle {};
const Float zoomScale {1.0};
const EdgeInsets contentInset {};
const EdgeInsets scrollIndicatorInsets {};
const int snapToInterval {};
const ScrollViewSnapToAlignment snapToAlignment {};
const bool alwaysBounceHorizontal{true};
const bool alwaysBounceVertical{true};
const bool bounces{true};
const bool bouncesZoom{true};
const bool canCancelContentTouches{true};
const bool centerContent{};
const bool automaticallyAdjustContentInsets{};
const Float decelerationRate{0.998};
const bool directionalLockEnabled{};
const ScrollViewIndicatorStyle indicatorStyle{};
const ScrollViewKeyboardDismissMode keyboardDismissMode{};
const Float maximumZoomScale{1.0};
const Float minimumZoomScale{1.0};
const bool scrollEnabled{true};
const bool pagingEnabled{};
const bool pinchGestureEnabled{true};
const bool scrollsToTop{true};
const bool showsHorizontalScrollIndicator{true};
const bool showsVerticalScrollIndicator{true};
const Float scrollEventThrottle{};
const Float zoomScale{1.0};
const EdgeInsets contentInset{};
const EdgeInsets scrollIndicatorInsets{};
const int snapToInterval{};
const ScrollViewSnapToAlignment snapToAlignment{};
#pragma mark - DebugStringConvertible
@ -58,4 +56,3 @@ public:
} // namespace react
} // namespace facebook

View File

@ -19,12 +19,13 @@ const char ScrollViewComponentName[] = "ScrollView";
void ScrollViewShadowNode::updateLocalData() {
ensureUnsealed();
auto contentBoundingRect = Rect {};
auto contentBoundingRect = Rect{};
for (const auto &childNode : getLayoutableChildNodes()) {
contentBoundingRect.unionInPlace(childNode->getLayoutMetrics().frame);
}
const auto &localData = std::make_shared<const ScrollViewLocalData>(contentBoundingRect);
const auto &localData =
std::make_shared<const ScrollViewLocalData>(contentBoundingRect);
setLocalData(localData);
}

View File

@ -20,23 +20,18 @@ extern const char ScrollViewComponentName[];
/*
* `ShadowNode` for <ScrollView> component.
*/
class ScrollViewShadowNode final:
public ConcreteViewShadowNode<
ScrollViewComponentName,
ScrollViewProps,
ScrollViewEventEmitter
> {
public:
class ScrollViewShadowNode final : public ConcreteViewShadowNode<
ScrollViewComponentName,
ScrollViewProps,
ScrollViewEventEmitter> {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
#pragma mark - LayoutableShadowNode
void layout(LayoutContext layoutContext) override;
private:
private:
void updateLocalData();
};

View File

@ -13,51 +13,93 @@
namespace facebook {
namespace react {
inline void fromDynamic(const folly::dynamic &value, ScrollViewSnapToAlignment &result) {
inline void fromDynamic(
const folly::dynamic &value,
ScrollViewSnapToAlignment &result) {
auto string = value.asString();
if (string == "start") { result = ScrollViewSnapToAlignment::Start; return; }
if (string == "center") { result = ScrollViewSnapToAlignment::Center; return; }
if (string == "end") { result = ScrollViewSnapToAlignment::End; return; }
if (string == "start") {
result = ScrollViewSnapToAlignment::Start;
return;
}
if (string == "center") {
result = ScrollViewSnapToAlignment::Center;
return;
}
if (string == "end") {
result = ScrollViewSnapToAlignment::End;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, ScrollViewIndicatorStyle &result) {
inline void fromDynamic(
const folly::dynamic &value,
ScrollViewIndicatorStyle &result) {
auto string = value.asString();
if (string == "default") { result = ScrollViewIndicatorStyle::Default; return; }
if (string == "black") { result = ScrollViewIndicatorStyle::Black; return; }
if (string == "white") { result = ScrollViewIndicatorStyle::White; return; }
if (string == "default") {
result = ScrollViewIndicatorStyle::Default;
return;
}
if (string == "black") {
result = ScrollViewIndicatorStyle::Black;
return;
}
if (string == "white") {
result = ScrollViewIndicatorStyle::White;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, ScrollViewKeyboardDismissMode &result) {
inline void fromDynamic(
const folly::dynamic &value,
ScrollViewKeyboardDismissMode &result) {
auto string = value.asString();
if (string == "none") { result = ScrollViewKeyboardDismissMode::None; return; }
if (string == "on-drag") { result = ScrollViewKeyboardDismissMode::OnDrag; return; }
if (string == "interactive") { result = ScrollViewKeyboardDismissMode::Interactive; return; }
if (string == "none") {
result = ScrollViewKeyboardDismissMode::None;
return;
}
if (string == "on-drag") {
result = ScrollViewKeyboardDismissMode::OnDrag;
return;
}
if (string == "interactive") {
result = ScrollViewKeyboardDismissMode::Interactive;
return;
}
abort();
}
inline std::string toString(const ScrollViewSnapToAlignment &value) {
switch (value) {
case ScrollViewSnapToAlignment::Start: return "start";
case ScrollViewSnapToAlignment::Center: return "center";
case ScrollViewSnapToAlignment::End: return "end";
case ScrollViewSnapToAlignment::Start:
return "start";
case ScrollViewSnapToAlignment::Center:
return "center";
case ScrollViewSnapToAlignment::End:
return "end";
}
}
inline std::string toString(const ScrollViewIndicatorStyle &value) {
switch (value) {
case ScrollViewIndicatorStyle::Default: return "default";
case ScrollViewIndicatorStyle::Black: return "black";
case ScrollViewIndicatorStyle::White: return "white";
case ScrollViewIndicatorStyle::Default:
return "default";
case ScrollViewIndicatorStyle::Black:
return "black";
case ScrollViewIndicatorStyle::White:
return "white";
}
}
inline std::string toString(const ScrollViewKeyboardDismissMode &value) {
switch (value) {
case ScrollViewKeyboardDismissMode::None: return "none";
case ScrollViewKeyboardDismissMode::OnDrag: return "on-drag";
case ScrollViewKeyboardDismissMode::Interactive: return "interactive";
case ScrollViewKeyboardDismissMode::None:
return "none";
case ScrollViewKeyboardDismissMode::OnDrag:
return "on-drag";
case ScrollViewKeyboardDismissMode::Interactive:
return "interactive";
}
}

View File

@ -10,23 +10,11 @@
namespace facebook {
namespace react {
enum class ScrollViewSnapToAlignment {
Start,
Center,
End
};
enum class ScrollViewSnapToAlignment { Start, Center, End };
enum class ScrollViewIndicatorStyle {
Default,
Black,
White
};
enum class ScrollViewIndicatorStyle { Default, Black, White };
enum class ScrollViewKeyboardDismissMode {
None,
OnDrag,
Interactive
};
enum class ScrollViewKeyboardDismissMode { None, OnDrag, Interactive };
} // namespace react
} // namespace facebook

View File

@ -11,11 +11,8 @@
namespace facebook {
namespace react {
class SwitchEventEmitter:
public ViewEventEmitter {
public:
class SwitchEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
void onChange(const bool &value) const;

View File

@ -11,13 +11,28 @@
namespace facebook {
namespace react {
SwitchProps::SwitchProps(const SwitchProps &sourceProps, const RawProps &rawProps):
ViewProps(sourceProps, rawProps),
value(convertRawProp(rawProps, "value", sourceProps.value, value)),
disabled(convertRawProp(rawProps, "disabled", sourceProps.disabled, disabled)),
tintColor(convertRawProp(rawProps, "tintColor", sourceProps.tintColor, tintColor)),
onTintColor(convertRawProp(rawProps, "onTintColor", sourceProps.onTintColor, onTintColor)),
thumbTintColor(convertRawProp(rawProps, "thumbTintColor", sourceProps.thumbTintColor, thumbTintColor)) {}
SwitchProps::SwitchProps(
const SwitchProps &sourceProps,
const RawProps &rawProps)
: ViewProps(sourceProps, rawProps),
value(convertRawProp(rawProps, "value", sourceProps.value, value)),
disabled(
convertRawProp(rawProps, "disabled", sourceProps.disabled, disabled)),
tintColor(convertRawProp(
rawProps,
"tintColor",
sourceProps.tintColor,
tintColor)),
onTintColor(convertRawProp(
rawProps,
"onTintColor",
sourceProps.onTintColor,
onTintColor)),
thumbTintColor(convertRawProp(
rawProps,
"thumbTintColor",
sourceProps.thumbTintColor,
thumbTintColor)) {}
} // namespace react
} // namespace facebook

View File

@ -12,20 +12,18 @@ namespace facebook {
namespace react {
// TODO (T28334063): Consider for codegen.
class SwitchProps final:
public ViewProps {
public:
class SwitchProps final : public ViewProps {
public:
SwitchProps() = default;
SwitchProps(const SwitchProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const bool value {false};
const bool disabled {false};
const SharedColor tintColor {};
const SharedColor onTintColor {};
const SharedColor thumbTintColor {};
const bool value{false};
const bool disabled{false};
const SharedColor tintColor{};
const SharedColor onTintColor{};
const SharedColor thumbTintColor{};
};
} // namespace react

View File

@ -19,12 +19,10 @@ extern const char SwitchComponentName[];
/*
* `ShadowNode` for <Switch> component.
*/
using SwitchShadowNode =
ConcreteViewShadowNode<
using SwitchShadowNode = ConcreteViewShadowNode<
SwitchComponentName,
SwitchProps,
SwitchEventEmitter
>;
SwitchEventEmitter>;
} // namespace react
} // namespace facebook

View File

@ -15,48 +15,84 @@
namespace facebook {
namespace react {
static TextAttributes convertRawProp(const RawProps &rawProps, const TextAttributes defaultTextAttributes) {
auto textAttributes = TextAttributes {};
static TextAttributes convertRawProp(
const RawProps &rawProps,
const TextAttributes defaultTextAttributes) {
auto textAttributes = TextAttributes{};
// Color
textAttributes.foregroundColor = convertRawProp(rawProps, "color", defaultTextAttributes.foregroundColor);
textAttributes.backgroundColor = convertRawProp(rawProps, "backgroundColor", defaultTextAttributes.backgroundColor);
textAttributes.opacity = convertRawProp(rawProps, "opacity", defaultTextAttributes.opacity);
textAttributes.foregroundColor =
convertRawProp(rawProps, "color", defaultTextAttributes.foregroundColor);
textAttributes.backgroundColor = convertRawProp(
rawProps, "backgroundColor", defaultTextAttributes.backgroundColor);
textAttributes.opacity =
convertRawProp(rawProps, "opacity", defaultTextAttributes.opacity);
// Font
textAttributes.fontFamily = convertRawProp(rawProps, "fontFamily", defaultTextAttributes.fontFamily);
textAttributes.fontSize = convertRawProp(rawProps, "fontSize", defaultTextAttributes.fontSize);
textAttributes.fontSizeMultiplier = convertRawProp(rawProps, "fontSizeMultiplier", defaultTextAttributes.fontSizeMultiplier);
textAttributes.fontWeight = convertRawProp(rawProps, "fontWeight", defaultTextAttributes.fontWeight);
textAttributes.fontStyle = convertRawProp(rawProps, "fontStyle", defaultTextAttributes.fontStyle);
textAttributes.fontVariant = convertRawProp(rawProps, "fontVariant", defaultTextAttributes.fontVariant);
textAttributes.allowFontScaling = convertRawProp(rawProps, "allowFontScaling", defaultTextAttributes.allowFontScaling);
textAttributes.letterSpacing = convertRawProp(rawProps, "letterSpacing", defaultTextAttributes.letterSpacing);
textAttributes.fontFamily =
convertRawProp(rawProps, "fontFamily", defaultTextAttributes.fontFamily);
textAttributes.fontSize =
convertRawProp(rawProps, "fontSize", defaultTextAttributes.fontSize);
textAttributes.fontSizeMultiplier = convertRawProp(
rawProps, "fontSizeMultiplier", defaultTextAttributes.fontSizeMultiplier);
textAttributes.fontWeight =
convertRawProp(rawProps, "fontWeight", defaultTextAttributes.fontWeight);
textAttributes.fontStyle =
convertRawProp(rawProps, "fontStyle", defaultTextAttributes.fontStyle);
textAttributes.fontVariant = convertRawProp(
rawProps, "fontVariant", defaultTextAttributes.fontVariant);
textAttributes.allowFontScaling = convertRawProp(
rawProps, "allowFontScaling", defaultTextAttributes.allowFontScaling);
textAttributes.letterSpacing = convertRawProp(
rawProps, "letterSpacing", defaultTextAttributes.letterSpacing);
// Paragraph
textAttributes.lineHeight = convertRawProp(rawProps, "lineHeight", defaultTextAttributes.lineHeight);
textAttributes.alignment = convertRawProp(rawProps, "alignment", defaultTextAttributes.alignment);
textAttributes.baseWritingDirection = convertRawProp(rawProps, "baseWritingDirection", defaultTextAttributes.baseWritingDirection);
textAttributes.lineHeight =
convertRawProp(rawProps, "lineHeight", defaultTextAttributes.lineHeight);
textAttributes.alignment =
convertRawProp(rawProps, "alignment", defaultTextAttributes.alignment);
textAttributes.baseWritingDirection = convertRawProp(
rawProps,
"baseWritingDirection",
defaultTextAttributes.baseWritingDirection);
// Decoration
textAttributes.textDecorationColor = convertRawProp(rawProps, "textDecorationColor", defaultTextAttributes.textDecorationColor);
textAttributes.textDecorationLineType = convertRawProp(rawProps, "textDecorationLineType", defaultTextAttributes.textDecorationLineType);
textAttributes.textDecorationLineStyle = convertRawProp(rawProps, "textDecorationLineStyle", defaultTextAttributes.textDecorationLineStyle);
textAttributes.textDecorationLinePattern = convertRawProp(rawProps, "textDecorationLinePattern", defaultTextAttributes.textDecorationLinePattern);
textAttributes.textDecorationColor = convertRawProp(
rawProps,
"textDecorationColor",
defaultTextAttributes.textDecorationColor);
textAttributes.textDecorationLineType = convertRawProp(
rawProps,
"textDecorationLineType",
defaultTextAttributes.textDecorationLineType);
textAttributes.textDecorationLineStyle = convertRawProp(
rawProps,
"textDecorationLineStyle",
defaultTextAttributes.textDecorationLineStyle);
textAttributes.textDecorationLinePattern = convertRawProp(
rawProps,
"textDecorationLinePattern",
defaultTextAttributes.textDecorationLinePattern);
// Shadow
textAttributes.textShadowOffset = convertRawProp(rawProps, "textShadowOffset", defaultTextAttributes.textShadowOffset);
textAttributes.textShadowRadius = convertRawProp(rawProps, "textShadowRadius", defaultTextAttributes.textShadowRadius);
textAttributes.textShadowColor = convertRawProp(rawProps, "textShadowColor", defaultTextAttributes.textShadowColor);
textAttributes.textShadowOffset = convertRawProp(
rawProps, "textShadowOffset", defaultTextAttributes.textShadowOffset);
textAttributes.textShadowRadius = convertRawProp(
rawProps, "textShadowRadius", defaultTextAttributes.textShadowRadius);
textAttributes.textShadowColor = convertRawProp(
rawProps, "textShadowColor", defaultTextAttributes.textShadowColor);
// Special
textAttributes.isHighlighted = convertRawProp(rawProps, "isHighlighted", defaultTextAttributes.isHighlighted);
textAttributes.isHighlighted = convertRawProp(
rawProps, "isHighlighted", defaultTextAttributes.isHighlighted);
return textAttributes;
}
BaseTextProps::BaseTextProps(const BaseTextProps &sourceProps, const RawProps &rawProps):
textAttributes(convertRawProp(rawProps, sourceProps.textAttributes)) {};
BaseTextProps::BaseTextProps(
const BaseTextProps &sourceProps,
const RawProps &rawProps)
: textAttributes(convertRawProp(rawProps, sourceProps.textAttributes)){};
#pragma mark - DebugStringConvertible

View File

@ -20,14 +20,13 @@ namespace react {
* that can have text attributes (such as Text and Paragraph).
*/
class BaseTextProps {
public:
public:
BaseTextProps() = default;
BaseTextProps(const BaseTextProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const TextAttributes textAttributes {};
const TextAttributes textAttributes{};
#pragma mark - DebugStringConvertible (partially)

View File

@ -7,26 +7,26 @@
#include "BaseTextShadowNode.h"
#include <fabric/components/text/RawTextShadowNode.h>
#include <fabric/components/text/RawTextProps.h>
#include <fabric/components/text/TextShadowNode.h>
#include <fabric/components/text/RawTextShadowNode.h>
#include <fabric/components/text/TextProps.h>
#include <fabric/components/text/TextShadowNode.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
namespace facebook {
namespace react {
AttributedString BaseTextShadowNode::getAttributedString(
const TextAttributes &textAttributes,
const SharedShadowNode &parentNode
) const {
auto attributedString = AttributedString {};
const TextAttributes &textAttributes,
const SharedShadowNode &parentNode) const {
auto attributedString = AttributedString{};
for (const auto &childNode : parentNode->getChildren()) {
// RawShadowNode
auto rawTextShadowNode = std::dynamic_pointer_cast<const RawTextShadowNode>(childNode);
auto rawTextShadowNode =
std::dynamic_pointer_cast<const RawTextShadowNode>(childNode);
if (rawTextShadowNode) {
auto fragment = AttributedString::Fragment {};
auto fragment = AttributedString::Fragment{};
fragment.string = rawTextShadowNode->getProps()->text;
fragment.textAttributes = textAttributes;
fragment.parentShadowNode = parentNode;
@ -35,16 +35,19 @@ AttributedString BaseTextShadowNode::getAttributedString(
}
// TextShadowNode
auto textShadowNode = std::dynamic_pointer_cast<const TextShadowNode>(childNode);
auto textShadowNode =
std::dynamic_pointer_cast<const TextShadowNode>(childNode);
if (textShadowNode) {
auto localTextAttributes = textAttributes;
localTextAttributes.apply(textShadowNode->getProps()->textAttributes);
attributedString.appendAttributedString(textShadowNode->getAttributedString(localTextAttributes, textShadowNode));
attributedString.appendAttributedString(
textShadowNode->getAttributedString(
localTextAttributes, textShadowNode));
continue;
}
// Any other kind of ShadowNode
auto fragment = AttributedString::Fragment {};
auto fragment = AttributedString::Fragment{};
fragment.shadowNode = childNode;
fragment.textAttributes = textAttributes;
attributedString.appendFragment(fragment);

View File

@ -18,15 +18,13 @@ namespace react {
* such as Text and Paragraph (but not RawText).
*/
class BaseTextShadowNode {
public:
public:
/*
* Returns a `AttributedString` which represents text content of the node.
*/
AttributedString getAttributedString(
const TextAttributes &baseTextAttributes,
const SharedShadowNode &parentNode
) const;
const TextAttributes &baseTextAttributes,
const SharedShadowNode &parentNode) const;
};
} // namespace react

View File

@ -18,13 +18,13 @@ namespace react {
/*
* Descriptor for <Paragraph> component.
*/
class ParagraphComponentDescriptor final:
public ConcreteComponentDescriptor<ParagraphShadowNode> {
public:
ParagraphComponentDescriptor(SharedEventDispatcher eventDispatcher, const SharedContextContainer &contextContainer):
ConcreteComponentDescriptor<ParagraphShadowNode>(eventDispatcher) {
class ParagraphComponentDescriptor final
: public ConcreteComponentDescriptor<ParagraphShadowNode> {
public:
ParagraphComponentDescriptor(
SharedEventDispatcher eventDispatcher,
const SharedContextContainer &contextContainer)
: ConcreteComponentDescriptor<ParagraphShadowNode>(eventDispatcher) {
// Every single `ParagraphShadowNode` will have a reference to
// a shared `TextLayoutManager`.
textLayoutManager_ = std::make_shared<TextLayoutManager>(contextContainer);
@ -34,7 +34,8 @@ public:
ConcreteComponentDescriptor::adopt(shadowNode);
assert(std::dynamic_pointer_cast<ParagraphShadowNode>(shadowNode));
auto paragraphShadowNode = std::static_pointer_cast<ParagraphShadowNode>(shadowNode);
auto paragraphShadowNode =
std::static_pointer_cast<ParagraphShadowNode>(shadowNode);
// `ParagraphShadowNode` uses `TextLayoutManager` to measure text content
// and communicate text rendering metrics to mounting layer.
@ -45,8 +46,7 @@ public:
paragraphShadowNode->enableMeasurement();
}
private:
private:
SharedTextLayoutManager textLayoutManager_;
};

View File

@ -17,7 +17,8 @@ AttributedString ParagraphLocalData::getAttributedString() const {
return attributedString_;
}
void ParagraphLocalData::setAttributedString(AttributedString attributedString) {
void ParagraphLocalData::setAttributedString(
AttributedString attributedString) {
ensureUnsealed();
attributedString_ = attributedString;
}
@ -26,7 +27,8 @@ SharedTextLayoutManager ParagraphLocalData::getTextLayoutManager() const {
return textLayoutManager_;
}
void ParagraphLocalData::setTextLayoutManager(SharedTextLayoutManager textLayoutManager) {
void ParagraphLocalData::setTextLayoutManager(
SharedTextLayoutManager textLayoutManager) {
ensureUnsealed();
textLayoutManager_ = textLayoutManager;
}
@ -44,8 +46,7 @@ std::string ParagraphLocalData::getDebugName() const {
SharedDebugStringConvertibleList ParagraphLocalData::getDebugProps() const {
return {
debugStringConvertibleItem("attributedString", attributedString_, "")
};
debugStringConvertibleItem("attributedString", attributedString_, "")};
}
#endif

View File

@ -22,11 +22,8 @@ using SharedParagraphLocalData = std::shared_ptr<const ParagraphLocalData>;
* LocalData for <Paragraph> component.
* Represents what to render and how to render.
*/
class ParagraphLocalData:
public LocalData {
public:
class ParagraphLocalData : public LocalData {
public:
/*
* All content of <Paragraph> component represented as an `AttributedString`.
*/
@ -50,8 +47,7 @@ public:
SharedDebugStringConvertibleList getDebugProps() const override;
#endif
private:
private:
AttributedString attributedString_;
SharedTextLayoutManager textLayoutManager_;
};

View File

@ -14,35 +14,53 @@
namespace facebook {
namespace react {
static ParagraphAttributes convertRawProp(const RawProps &rawProps, const ParagraphAttributes &defaultParagraphAttributes) {
auto paragraphAttributes = ParagraphAttributes {};
static ParagraphAttributes convertRawProp(
const RawProps &rawProps,
const ParagraphAttributes &defaultParagraphAttributes) {
auto paragraphAttributes = ParagraphAttributes{};
paragraphAttributes.maximumNumberOfLines = convertRawProp(rawProps, "numberOfLines", defaultParagraphAttributes.maximumNumberOfLines);
paragraphAttributes.ellipsizeMode = convertRawProp(rawProps, "ellipsizeMode", defaultParagraphAttributes.ellipsizeMode);
paragraphAttributes.adjustsFontSizeToFit = convertRawProp(rawProps, "adjustsFontSizeToFit", defaultParagraphAttributes.adjustsFontSizeToFit);
paragraphAttributes.minimumFontSize = convertRawProp(rawProps, "minimumFontSize", defaultParagraphAttributes.minimumFontSize, std::numeric_limits<Float>::quiet_NaN());
paragraphAttributes.maximumFontSize = convertRawProp(rawProps, "maximumFontSize", defaultParagraphAttributes.maximumFontSize, std::numeric_limits<Float>::quiet_NaN());
paragraphAttributes.maximumNumberOfLines = convertRawProp(
rawProps,
"numberOfLines",
defaultParagraphAttributes.maximumNumberOfLines);
paragraphAttributes.ellipsizeMode = convertRawProp(
rawProps, "ellipsizeMode", defaultParagraphAttributes.ellipsizeMode);
paragraphAttributes.adjustsFontSizeToFit = convertRawProp(
rawProps,
"adjustsFontSizeToFit",
defaultParagraphAttributes.adjustsFontSizeToFit);
paragraphAttributes.minimumFontSize = convertRawProp(
rawProps,
"minimumFontSize",
defaultParagraphAttributes.minimumFontSize,
std::numeric_limits<Float>::quiet_NaN());
paragraphAttributes.maximumFontSize = convertRawProp(
rawProps,
"maximumFontSize",
defaultParagraphAttributes.maximumFontSize,
std::numeric_limits<Float>::quiet_NaN());
return paragraphAttributes;
}
ParagraphProps::ParagraphProps(const ParagraphProps &sourceProps, const RawProps &rawProps):
ViewProps(sourceProps, rawProps),
BaseTextProps(sourceProps, rawProps),
paragraphAttributes(convertRawProp(rawProps, sourceProps.paragraphAttributes)),
isSelectable(convertRawProp(rawProps, "selectable", sourceProps.isSelectable)) {};
ParagraphProps::ParagraphProps(
const ParagraphProps &sourceProps,
const RawProps &rawProps)
: ViewProps(sourceProps, rawProps),
BaseTextProps(sourceProps, rawProps),
paragraphAttributes(
convertRawProp(rawProps, sourceProps.paragraphAttributes)),
isSelectable(
convertRawProp(rawProps, "selectable", sourceProps.isSelectable)){};
#pragma mark - DebugStringConvertible
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList ParagraphProps::getDebugProps() const {
return
ViewProps::getDebugProps() +
BaseTextProps::getDebugProps() +
paragraphAttributes.getDebugProps() +
SharedDebugStringConvertibleList {
debugStringConvertibleItem("isSelectable", isSelectable)
};
return ViewProps::getDebugProps() + BaseTextProps::getDebugProps() +
paragraphAttributes.getDebugProps() +
SharedDebugStringConvertibleList{
debugStringConvertibleItem("isSelectable", isSelectable)};
}
#endif

View File

@ -23,25 +23,23 @@ namespace react {
* Most of the props are directly stored in composed `ParagraphAttributes`
* object.
*/
class ParagraphProps:
public ViewProps,
public BaseTextProps {
public:
class ParagraphProps : public ViewProps, public BaseTextProps {
public:
ParagraphProps() = default;
ParagraphProps(const ParagraphProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
/*
* Contains all prop values that affect visual representation of the paragraph.
* Contains all prop values that affect visual representation of the
* paragraph.
*/
const ParagraphAttributes paragraphAttributes {};
const ParagraphAttributes paragraphAttributes{};
/*
* Defines can the text be selected (and copied) or not.
*/
const bool isSelectable {};
const bool isSelectable{};
#pragma mark - DebugStringConvertible

View File

@ -16,14 +16,15 @@ const char ParagraphComponentName[] = "Paragraph";
AttributedString ParagraphShadowNode::getAttributedString() const {
if (!cachedAttributedString_.has_value()) {
cachedAttributedString_ =
BaseTextShadowNode::getAttributedString(getProps()->textAttributes, shared_from_this());
cachedAttributedString_ = BaseTextShadowNode::getAttributedString(
getProps()->textAttributes, shared_from_this());
}
return cachedAttributedString_.value();
}
void ParagraphShadowNode::setTextLayoutManager(SharedTextLayoutManager textLayoutManager) {
void ParagraphShadowNode::setTextLayoutManager(
SharedTextLayoutManager textLayoutManager) {
ensureUnsealed();
textLayoutManager_ = textLayoutManager;
}
@ -41,11 +42,10 @@ void ParagraphShadowNode::updateLocalData() {
Size ParagraphShadowNode::measure(LayoutConstraints layoutConstraints) const {
return textLayoutManager_->measure(
getTag(),
getAttributedString(),
getProps()->paragraphAttributes,
layoutConstraints
);
getTag(),
getAttributedString(),
getProps()->paragraphAttributes,
layoutConstraints);
}
void ParagraphShadowNode::layout(LayoutContext layoutContext) {

View File

@ -11,8 +11,8 @@
#include <fabric/components/text/TextShadowNode.h>
#include <fabric/components/view/ConcreteViewShadowNode.h>
#include <fabric/core/ConcreteShadowNode.h>
#include <fabric/core/ShadowNode.h>
#include <fabric/core/LayoutContext.h>
#include <fabric/core/ShadowNode.h>
#include <fabric/textlayoutmanager/TextLayoutManager.h>
#include <folly/Optional.h>
@ -28,16 +28,12 @@ using ParagraphEventEmitter = ViewEventEmitter;
* containing and displaying text. Text content is represented as nested <Text>
* and <RawText> components.
*/
class ParagraphShadowNode:
public ConcreteViewShadowNode<
ParagraphComponentName,
ParagraphProps,
ParagraphEventEmitter
>,
public BaseTextShadowNode {
public:
class ParagraphShadowNode : public ConcreteViewShadowNode<
ParagraphComponentName,
ParagraphProps,
ParagraphEventEmitter>,
public BaseTextShadowNode {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
/*
@ -57,8 +53,7 @@ public:
void layout(LayoutContext layoutContext) override;
Size measure(LayoutConstraints layoutConstraints) const override;
private:
private:
/*
* Creates a `LocalData` object (with `AttributedText` and
* `TextLayoutManager`) if needed.
@ -71,7 +66,7 @@ private:
* Cached attributed string that represents the content of the subtree started
* from the node.
*/
mutable folly::Optional<AttributedString> cachedAttributedString_ {};
mutable folly::Optional<AttributedString> cachedAttributedString_{};
};
} // namespace react

View File

@ -8,9 +8,10 @@ namespace react {
inline folly::dynamic toDynamic(const ParagraphLocalData &paragraphLocalData) {
folly::dynamic newLocalData = folly::dynamic::object();
newLocalData["attributedString"] = toDynamic(paragraphLocalData.getAttributedString());
newLocalData["attributedString"] =
toDynamic(paragraphLocalData.getAttributedString());
return newLocalData;
}
}
}
} // namespace react
} // namespace facebook

View File

@ -13,7 +13,8 @@
namespace facebook {
namespace react {
using RawTextComponentDescriptor = ConcreteComponentDescriptor<RawTextShadowNode>;
using RawTextComponentDescriptor =
ConcreteComponentDescriptor<RawTextShadowNode>;
} // namespace react
} // namespace facebook

View File

@ -13,17 +13,17 @@
namespace facebook {
namespace react {
RawTextProps::RawTextProps(const RawTextProps &sourceProps, const RawProps &rawProps):
Props(sourceProps, rawProps),
text(convertRawProp(rawProps, "text", sourceProps.text)) {};
RawTextProps::RawTextProps(
const RawTextProps &sourceProps,
const RawProps &rawProps)
: Props(sourceProps, rawProps),
text(convertRawProp(rawProps, "text", sourceProps.text)){};
#pragma mark - DebugStringConvertible
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList RawTextProps::getDebugProps() const {
return {
debugStringConvertibleItem("text", text)
};
return {debugStringConvertibleItem("text", text)};
}
#endif

View File

@ -19,16 +19,14 @@ class RawTextProps;
using SharedRawTextProps = std::shared_ptr<const RawTextProps>;
class RawTextProps:
public Props {
public:
class RawTextProps : public Props {
public:
RawTextProps() = default;
RawTextProps(const RawTextProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const std::string text {};
const std::string text{};
#pragma mark - DebugStringConvertible

View File

@ -22,10 +22,7 @@ extern const char RawTextComponentName[];
* <RawText> component must not have any children.
*/
using RawTextShadowNode =
ConcreteShadowNode<
RawTextComponentName,
RawTextProps
>;
ConcreteShadowNode<RawTextComponentName, RawTextProps>;
} // namespace react
} // namespace facebook

View File

@ -5,15 +5,15 @@
* LICENSE file in the root directory of this source tree.
*/
#include <memory>
#include <memory>
#include <assert.h>
#include <fabric/attributedstring/AttributedString.h>
#include <fabric/attributedstring/TextAttributes.h>
#include <fabric/attributedstring/primitives.h>
#include <fabric/components/text/conversions.h>
#include <fabric/components/text/ParagraphLocalData.h>
#include <fabric/components/text/conversions.h>
#include <gtest/gtest.h>
#include <assert.h>
namespace facebook {
namespace react {
@ -24,7 +24,8 @@ TEST(ParagraphLocalDataTest, testSomething) {
fragment.string = "test";
auto text = TextAttributes();
text.foregroundColor = {colorFromComponents({100/255.0, 153/255.0, 253/255.0, 1.0})};
text.foregroundColor = {
colorFromComponents({100 / 255.0, 153 / 255.0, 253 / 255.0, 1.0})};
text.opacity = 0.5;
text.fontStyle = FontStyle::Italic;
text.fontWeight = FontWeight::Thin;
@ -45,5 +46,5 @@ TEST(ParagraphLocalDataTest, testSomething) {
assert(textAttribute["fontWeight"] == toString(*text.fontWeight));
}
}
}
} // namespace react
} // namespace facebook

View File

@ -10,8 +10,8 @@
namespace facebook {
namespace react {
TextProps::TextProps(const TextProps &sourceProps, const RawProps &rawProps):
BaseTextProps::BaseTextProps(sourceProps, rawProps) {};
TextProps::TextProps(const TextProps &sourceProps, const RawProps &rawProps)
: BaseTextProps::BaseTextProps(sourceProps, rawProps){};
#pragma mark - DebugStringConvertible

View File

@ -16,11 +16,8 @@
namespace facebook {
namespace react {
class TextProps:
public Props,
public BaseTextProps {
public:
class TextProps : public Props, public BaseTextProps {
public:
TextProps() = default;
TextProps(const TextProps &sourceProps, const RawProps &rawProps);

View File

@ -7,9 +7,9 @@
#pragma once
#include <fabric/components/view/ViewEventEmitter.h>
#include <fabric/components/text/BaseTextShadowNode.h>
#include <fabric/components/text/TextProps.h>
#include <fabric/components/view/ViewEventEmitter.h>
#include <fabric/core/ConcreteShadowNode.h>
namespace facebook {
@ -19,16 +19,10 @@ extern const char TextComponentName[];
using TextEventEmitter = TouchEventEmitter;
class TextShadowNode:
public ConcreteShadowNode<
TextComponentName,
TextProps,
TextEventEmitter
>,
public BaseTextShadowNode {
public:
class TextShadowNode
: public ConcreteShadowNode<TextComponentName, TextProps, TextEventEmitter>,
public BaseTextShadowNode {
public:
using ConcreteShadowNode::ConcreteShadowNode;
};

View File

@ -26,70 +26,61 @@ namespace react {
* For example: <Paragraph>, <Image>, but not <Text>, <RawText>.
*/
template <
const char *concreteComponentName,
typename ViewPropsT = ViewProps,
typename ViewEventEmitterT = ViewEventEmitter
>
class ConcreteViewShadowNode:
public ConcreteShadowNode<
concreteComponentName,
ViewPropsT,
ViewEventEmitterT
>,
public AccessibleShadowNode,
public YogaLayoutableShadowNode {
const char *concreteComponentName,
typename ViewPropsT = ViewProps,
typename ViewEventEmitterT = ViewEventEmitter>
class ConcreteViewShadowNode : public ConcreteShadowNode<
concreteComponentName,
ViewPropsT,
ViewEventEmitterT>,
public AccessibleShadowNode,
public YogaLayoutableShadowNode {
static_assert(
std::is_base_of<ViewProps, ViewPropsT>::value,
"ViewPropsT must be a descendant of ViewProps");
static_assert(
std::is_base_of<YogaStylableProps, ViewPropsT>::value,
"ViewPropsT must be a descendant of YogaStylableProps");
static_assert(
std::is_base_of<AccessibilityProps, ViewPropsT>::value,
"ViewPropsT must be a descendant of AccessibilityProps");
static_assert(std::is_base_of<ViewProps, ViewPropsT>::value, "ViewPropsT must be a descendant of ViewProps");
static_assert(std::is_base_of<YogaStylableProps, ViewPropsT>::value, "ViewPropsT must be a descendant of YogaStylableProps");
static_assert(std::is_base_of<AccessibilityProps, ViewPropsT>::value, "ViewPropsT must be a descendant of AccessibilityProps");
public:
using BaseShadowNode = ConcreteShadowNode<
concreteComponentName,
ViewPropsT,
ViewEventEmitterT
>;
public:
using BaseShadowNode =
ConcreteShadowNode<concreteComponentName, ViewPropsT, ViewEventEmitterT>;
using ConcreteViewProps = ViewPropsT;
ConcreteViewShadowNode(
const ShadowNodeFragment &fragment,
const ShadowNodeCloneFunction &cloneFunction
):
BaseShadowNode(
fragment,
cloneFunction
),
AccessibleShadowNode(
std::static_pointer_cast<const ConcreteViewProps>(fragment.props)
),
YogaLayoutableShadowNode() {
YogaLayoutableShadowNode::setProps(*std::static_pointer_cast<const ConcreteViewProps>(fragment.props));
YogaLayoutableShadowNode::setChildren(BaseShadowNode::template getChildrenSlice<YogaLayoutableShadowNode>());
const ShadowNodeFragment &fragment,
const ShadowNodeCloneFunction &cloneFunction)
: BaseShadowNode(fragment, cloneFunction),
AccessibleShadowNode(
std::static_pointer_cast<const ConcreteViewProps>(fragment.props)),
YogaLayoutableShadowNode() {
YogaLayoutableShadowNode::setProps(
*std::static_pointer_cast<const ConcreteViewProps>(fragment.props));
YogaLayoutableShadowNode::setChildren(
BaseShadowNode::template getChildrenSlice<YogaLayoutableShadowNode>());
};
ConcreteViewShadowNode(
const ShadowNode &sourceShadowNode,
const ShadowNodeFragment &fragment
):
BaseShadowNode(
sourceShadowNode,
fragment
),
AccessibleShadowNode(
static_cast<const ConcreteViewShadowNode &>(sourceShadowNode),
std::static_pointer_cast<const ConcreteViewProps>(fragment.props)
),
YogaLayoutableShadowNode(
static_cast<const ConcreteViewShadowNode &>(sourceShadowNode)
) {
const ShadowNode &sourceShadowNode,
const ShadowNodeFragment &fragment)
: BaseShadowNode(sourceShadowNode, fragment),
AccessibleShadowNode(
static_cast<const ConcreteViewShadowNode &>(sourceShadowNode),
std::static_pointer_cast<const ConcreteViewProps>(fragment.props)),
YogaLayoutableShadowNode(
static_cast<const ConcreteViewShadowNode &>(sourceShadowNode)) {
if (fragment.props) {
YogaLayoutableShadowNode::setProps(*std::static_pointer_cast<const ConcreteViewProps>(fragment.props));
YogaLayoutableShadowNode::setProps(
*std::static_pointer_cast<const ConcreteViewProps>(fragment.props));
}
if (fragment.children) {
YogaLayoutableShadowNode::setChildren(BaseShadowNode::template getChildrenSlice<YogaLayoutableShadowNode>());
YogaLayoutableShadowNode::setChildren(
BaseShadowNode::template getChildrenSlice<
YogaLayoutableShadowNode>());
}
};
@ -99,17 +90,25 @@ public:
ShadowNode::appendChild(child);
auto nonConstChild = const_cast<ShadowNode *>(child.get());
auto yogaLayoutableChild = dynamic_cast<YogaLayoutableShadowNode *>(nonConstChild);
auto yogaLayoutableChild =
dynamic_cast<YogaLayoutableShadowNode *>(nonConstChild);
if (yogaLayoutableChild) {
YogaLayoutableShadowNode::appendChild(yogaLayoutableChild);
}
}
LayoutableShadowNode *cloneAndReplaceChild(LayoutableShadowNode *child, int suggestedIndex = -1) override {
LayoutableShadowNode *cloneAndReplaceChild(
LayoutableShadowNode *child,
int suggestedIndex = -1) override {
ensureUnsealed();
auto childShadowNode = static_cast<const ConcreteViewShadowNode *>(child);
auto clonedChildShadowNode = std::static_pointer_cast<ConcreteViewShadowNode>(childShadowNode->clone({}));
ShadowNode::replaceChild(childShadowNode->shared_from_this(), clonedChildShadowNode, suggestedIndex);
auto clonedChildShadowNode =
std::static_pointer_cast<ConcreteViewShadowNode>(
childShadowNode->clone({}));
ShadowNode::replaceChild(
childShadowNode->shared_from_this(),
clonedChildShadowNode,
suggestedIndex);
return clonedChildShadowNode.get();
}
@ -117,12 +116,14 @@ public:
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList getDebugProps() const override {
auto list = SharedDebugStringConvertibleList {};
auto list = SharedDebugStringConvertibleList{};
auto basePropsList = ShadowNode::getDebugProps();
std::move(basePropsList.begin(), basePropsList.end(), std::back_inserter(list));
std::move(
basePropsList.begin(), basePropsList.end(), std::back_inserter(list));
list.push_back(std::make_shared<DebugStringConvertibleItem>("layout", "", LayoutableShadowNode::getDebugProps()));
list.push_back(std::make_shared<DebugStringConvertibleItem>(
"layout", "", LayoutableShadowNode::getDebugProps()));
return list;
}

View File

@ -9,9 +9,9 @@
namespace facebook {
namespace react {
#pragma mark - Touches
static folly::dynamic touchPayload(const Touch &touch) {
folly::dynamic object = folly::dynamic::object();
object["locationX"] = touch.offsetPoint.x;
@ -44,20 +44,28 @@ static folly::dynamic touchEventPayload(const TouchEvent &event) {
}
void TouchEventEmitter::onTouchStart(const TouchEvent &event) const {
dispatchEvent("touchStart", touchEventPayload(event), EventPriority::SynchronousUnbatched);
dispatchEvent(
"touchStart",
touchEventPayload(event),
EventPriority::SynchronousUnbatched);
}
void TouchEventEmitter::onTouchMove(const TouchEvent &event) const {
dispatchEvent("touchMove", touchEventPayload(event), EventPriority::SynchronousBatched);
dispatchEvent(
"touchMove", touchEventPayload(event), EventPriority::SynchronousBatched);
}
void TouchEventEmitter::onTouchEnd(const TouchEvent &event) const {
dispatchEvent("touchEnd", touchEventPayload(event), EventPriority::SynchronousBatched);
dispatchEvent(
"touchEnd", touchEventPayload(event), EventPriority::SynchronousBatched);
}
void TouchEventEmitter::onTouchCancel(const TouchEvent &event) const {
dispatchEvent("touchCancel", touchEventPayload(event), EventPriority::SynchronousBatched);
dispatchEvent(
"touchCancel",
touchEventPayload(event),
EventPriority::SynchronousBatched);
}
} // namespace react
} // namespace facebook

View File

@ -6,8 +6,8 @@
*/
#pragma once
#include <fabric/core/ReactPrimitives.h>
#include <fabric/core/LayoutMetrics.h>
#include <fabric/core/ReactPrimitives.h>
#include <fabric/events/EventEmitter.h>
namespace facebook {
@ -22,49 +22,50 @@ struct Touch {
* The coordinate of point relative to the root component in points.
*/
Point pagePoint;
/*
* The coordinate of point relative to the target component in points.
*/
Point offsetPoint;
/*
* The coordinate of point relative to the screen component in points.
*/
Point screenPoint;
/*
* An identification number for each touch point.
*/
int identifier;
/*
* The tag of a component on which the touch point started when it was first placed on the surface,
* even if the touch point has since moved outside the interactive area of that element.
* The tag of a component on which the touch point started when it was first
* placed on the surface, even if the touch point has since moved outside the
* interactive area of that element.
*/
Tag target;
/*
* The force of the touch.
*/
Float force;
/*
* The time in seconds when the touch occurred or when it was last mutated.
*/
Float timestamp;
/*
* The particular implementation of `Hasher` and (especially) `Comparator`
* make sense only when `Touch` object is used as a *key* in indexed collections.
* Because of that they are expressed as separate classes.
* make sense only when `Touch` object is used as a *key* in indexed
* collections. Because of that they are expressed as separate classes.
*/
struct Hasher {
size_t operator()(const Touch &touch) const {
return std::hash<decltype(touch.identifier)>()(touch.identifier);
}
};
struct Comparator {
bool operator()(const Touch &lhs, const Touch &rhs) const {
return lhs.identifier == rhs.identifier;
@ -75,19 +76,22 @@ struct Touch {
using Touches = std::unordered_set<Touch, Touch::Hasher, Touch::Comparator>;
/*
* Defines the `touchstart`, `touchend`, `touchmove`, and `touchcancel` event types.
* Defines the `touchstart`, `touchend`, `touchmove`, and `touchcancel` event
* types.
*/
struct TouchEvent {
/*
* A list of Touches for every point of contact currently touching the surface.
* A list of Touches for every point of contact currently touching the
* surface.
*/
Touches touches;
/*
* A list of Touches for every point of contact which contributed to the event.
* A list of Touches for every point of contact which contributed to the
* event.
*/
Touches changedTouches;
/*
* A list of Touches for every point of contact that is touching the surface
* and started on the element that is the target of the current event.
@ -98,10 +102,10 @@ struct TouchEvent {
class TouchEventEmitter;
using SharedTouchEventEmitter = std::shared_ptr<const TouchEventEmitter>;
class TouchEventEmitter: public EventEmitter {
public:
class TouchEventEmitter : public EventEmitter {
public:
using EventEmitter::EventEmitter;
void onTouchStart(const TouchEvent &event) const;
void onTouchMove(const TouchEvent &event) const;
void onTouchEnd(const TouchEvent &event) const;

View File

@ -29,11 +29,9 @@ void ViewEventEmitter::onAccessibilityMagicTap() const {
void ViewEventEmitter::onLayout(const LayoutMetrics &layoutMetrics) const {
folly::dynamic payload = folly::dynamic::object();
const auto &frame = layoutMetrics.frame;
payload["layout"] = folly::dynamic::object
("x", frame.origin.x)
("y", frame.origin.y)
("width", frame.size.width)
("height", frame.size.height);
payload["layout"] =
folly::dynamic::object("x", frame.origin.x)("y", frame.origin.y)(
"width", frame.size.width)("height", frame.size.height);
dispatchEvent("layout", payload);
}

View File

@ -19,9 +19,8 @@ class ViewEventEmitter;
using SharedViewEventEmitter = std::shared_ptr<const ViewEventEmitter>;
class ViewEventEmitter:
public TouchEventEmitter {
public:
class ViewEventEmitter : public TouchEventEmitter {
public:
using TouchEventEmitter::TouchEventEmitter;
#pragma mark - Accessibility

View File

@ -16,51 +16,78 @@
namespace facebook {
namespace react {
ViewProps::ViewProps(const YGStyle &yogaStyle):
YogaStylableProps(yogaStyle) {}
ViewProps::ViewProps(const YGStyle &yogaStyle) : YogaStylableProps(yogaStyle) {}
ViewProps::ViewProps(const ViewProps &sourceProps, const RawProps &rawProps):
Props(sourceProps, rawProps),
YogaStylableProps(sourceProps, rawProps),
opacity(convertRawProp(rawProps, "opacity", sourceProps.opacity, (Float)1.0)),
foregroundColor(convertRawProp(rawProps, "foregroundColor", sourceProps.foregroundColor)),
backgroundColor(convertRawProp(rawProps, "backgroundColor", sourceProps.backgroundColor)),
borderRadii(convertRawProp(rawProps, "border", "Radius", sourceProps.borderRadii)),
borderColors(convertRawProp(rawProps, "border", "Color", sourceProps.borderColors)),
borderStyles(convertRawProp(rawProps, "border", "Style", sourceProps.borderStyles)),
shadowColor(convertRawProp(rawProps, "shadowColor", sourceProps.shadowColor)),
shadowOffset(convertRawProp(rawProps, "shadowOffset", sourceProps.shadowOffset)),
shadowOpacity(convertRawProp(rawProps, "shadowOpacity", sourceProps.shadowOpacity)),
shadowRadius(convertRawProp(rawProps, "shadowRadius", sourceProps.shadowRadius)),
transform(convertRawProp(rawProps, "transform", sourceProps.transform)),
backfaceVisibility(convertRawProp(rawProps, "backfaceVisibility", sourceProps.backfaceVisibility)),
shouldRasterize(convertRawProp(rawProps, "shouldRasterize", sourceProps.shouldRasterize)),
zIndex(convertRawProp(rawProps, "zIndex", sourceProps.zIndex)),
pointerEvents(convertRawProp(rawProps, "pointerEvents", sourceProps.pointerEvents)),
hitSlop(convertRawProp(rawProps, "hitSlop", sourceProps.hitSlop)),
onLayout(convertRawProp(rawProps, "onLayout", sourceProps.onLayout)) {};
ViewProps::ViewProps(const ViewProps &sourceProps, const RawProps &rawProps)
: Props(sourceProps, rawProps),
YogaStylableProps(sourceProps, rawProps),
opacity(
convertRawProp(rawProps, "opacity", sourceProps.opacity, (Float)1.0)),
foregroundColor(convertRawProp(
rawProps,
"foregroundColor",
sourceProps.foregroundColor)),
backgroundColor(convertRawProp(
rawProps,
"backgroundColor",
sourceProps.backgroundColor)),
borderRadii(convertRawProp(
rawProps,
"border",
"Radius",
sourceProps.borderRadii)),
borderColors(convertRawProp(
rawProps,
"border",
"Color",
sourceProps.borderColors)),
borderStyles(convertRawProp(
rawProps,
"border",
"Style",
sourceProps.borderStyles)),
shadowColor(
convertRawProp(rawProps, "shadowColor", sourceProps.shadowColor)),
shadowOffset(
convertRawProp(rawProps, "shadowOffset", sourceProps.shadowOffset)),
shadowOpacity(
convertRawProp(rawProps, "shadowOpacity", sourceProps.shadowOpacity)),
shadowRadius(
convertRawProp(rawProps, "shadowRadius", sourceProps.shadowRadius)),
transform(convertRawProp(rawProps, "transform", sourceProps.transform)),
backfaceVisibility(convertRawProp(
rawProps,
"backfaceVisibility",
sourceProps.backfaceVisibility)),
shouldRasterize(convertRawProp(
rawProps,
"shouldRasterize",
sourceProps.shouldRasterize)),
zIndex(convertRawProp(rawProps, "zIndex", sourceProps.zIndex)),
pointerEvents(
convertRawProp(rawProps, "pointerEvents", sourceProps.pointerEvents)),
hitSlop(convertRawProp(rawProps, "hitSlop", sourceProps.hitSlop)),
onLayout(convertRawProp(rawProps, "onLayout", sourceProps.onLayout)){};
#pragma mark - Convenience Methods
BorderMetrics ViewProps::resolveBorderMetrics(bool isRTL) const {
auto borderWidths = CascadedBorderWidths {
.left = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeLeft]),
.top = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeTop]),
.right = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeRight]),
.bottom = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeBottom]),
.start = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeStart]),
.end = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeEnd]),
.horizontal = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeHorizontal]),
.vertical = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeVertical]),
.all = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeAll])
};
auto borderWidths = CascadedBorderWidths{
.left = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeLeft]),
.top = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeTop]),
.right = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeRight]),
.bottom = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeBottom]),
.start = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeStart]),
.end = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeEnd]),
.horizontal =
optionalFloatFromYogaValue(yogaStyle.border[YGEdgeHorizontal]),
.vertical = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeVertical]),
.all = optionalFloatFromYogaValue(yogaStyle.border[YGEdgeAll])};
return {
.borderColors = borderColors.resolve(isRTL, {}),
.borderWidths = borderWidths.resolve(isRTL, 0),
.borderRadii = borderRadii.resolve(isRTL, 0),
.borderStyles = borderStyles.resolve(isRTL, BorderStyle::Solid)
};
return {.borderColors = borderColors.resolve(isRTL, {}),
.borderWidths = borderWidths.resolve(isRTL, 0),
.borderRadii = borderRadii.resolve(isRTL, 0),
.borderStyles = borderStyles.resolve(isRTL, BorderStyle::Solid)};
}
#pragma mark - DebugStringConvertible
@ -69,15 +96,21 @@ BorderMetrics ViewProps::resolveBorderMetrics(bool isRTL) const {
SharedDebugStringConvertibleList ViewProps::getDebugProps() const {
const auto &defaultViewProps = ViewProps();
return
AccessibilityProps::getDebugProps() +
YogaStylableProps::getDebugProps() +
SharedDebugStringConvertibleList {
debugStringConvertibleItem("zIndex", zIndex, defaultViewProps.zIndex),
debugStringConvertibleItem("opacity", opacity, defaultViewProps.opacity),
debugStringConvertibleItem("foregroundColor", foregroundColor, defaultViewProps.foregroundColor),
debugStringConvertibleItem("backgroundColor", backgroundColor, defaultViewProps.backgroundColor),
};
return AccessibilityProps::getDebugProps() +
YogaStylableProps::getDebugProps() +
SharedDebugStringConvertibleList{
debugStringConvertibleItem("zIndex", zIndex, defaultViewProps.zIndex),
debugStringConvertibleItem(
"opacity", opacity, defaultViewProps.opacity),
debugStringConvertibleItem(
"foregroundColor",
foregroundColor,
defaultViewProps.foregroundColor),
debugStringConvertibleItem(
"backgroundColor",
backgroundColor,
defaultViewProps.backgroundColor),
};
}
#endif

View File

@ -8,11 +8,11 @@
#pragma once
#include <fabric/components/view/AccessibilityProps.h>
#include <fabric/components/view/primitives.h>
#include <fabric/components/view/YogaStylableProps.h>
#include <fabric/components/view/primitives.h>
#include <fabric/core/Props.h>
#include <fabric/graphics/Geometry.h>
#include <fabric/graphics/Color.h>
#include <fabric/graphics/Geometry.h>
namespace facebook {
namespace react {
@ -21,12 +21,10 @@ class ViewProps;
using SharedViewProps = std::shared_ptr<const ViewProps>;
class ViewProps:
public Props,
public YogaStylableProps,
public AccessibilityProps {
public:
class ViewProps : public Props,
public YogaStylableProps,
public AccessibilityProps {
public:
ViewProps() = default;
ViewProps(const YGStyle &yogaStyle);
ViewProps(const ViewProps &sourceProps, const RawProps &rawProps);
@ -34,31 +32,31 @@ public:
#pragma mark - Props
// Color
const Float opacity {1.0};
const SharedColor foregroundColor {};
const SharedColor backgroundColor {};
const Float opacity{1.0};
const SharedColor foregroundColor{};
const SharedColor backgroundColor{};
// Borders
const CascadedBorderRadii borderRadii {};
const CascadedBorderColors borderColors {};
const CascadedBorderStyles borderStyles {};
const CascadedBorderRadii borderRadii{};
const CascadedBorderColors borderColors{};
const CascadedBorderStyles borderStyles{};
// Shadow
const SharedColor shadowColor {};
const Size shadowOffset {};
const Float shadowOpacity {};
const Float shadowRadius {};
const SharedColor shadowColor{};
const Size shadowOffset{};
const Float shadowOpacity{};
const Float shadowRadius{};
// Transform
const Transform transform {};
const bool backfaceVisibility {};
const bool shouldRasterize {};
const int zIndex {};
const Transform transform{};
const bool backfaceVisibility{};
const bool shouldRasterize{};
const int zIndex{};
// Events
const PointerEventsMode pointerEvents {};
const EdgeInsets hitSlop {};
const bool onLayout {};
const PointerEventsMode pointerEvents{};
const EdgeInsets hitSlop{};
const bool onLayout{};
#pragma mark - Convenience Methods

View File

@ -20,22 +20,19 @@ bool ViewShadowNode::isLayoutOnly() const {
const auto &viewProps = *std::static_pointer_cast<const ViewProps>(props_);
return
// Event listeners
!viewProps.onLayout &&
// Generic Props
viewProps.nativeId.empty() &&
// Accessibility Props
!viewProps.accessible &&
// Style Props
viewProps.yogaStyle.overflow == YGOverflowVisible &&
viewProps.opacity == 1.0 &&
!viewProps.backgroundColor &&
!viewProps.foregroundColor &&
!viewProps.shadowColor &&
viewProps.transform == Transform {} &&
viewProps.zIndex == 0 &&
// Layout Metrics
getLayoutMetrics().borderWidth == EdgeInsets {};
// Event listeners
!viewProps.onLayout &&
// Generic Props
viewProps.nativeId.empty() &&
// Accessibility Props
!viewProps.accessible &&
// Style Props
viewProps.yogaStyle.overflow == YGOverflowVisible &&
viewProps.opacity == 1.0 && !viewProps.backgroundColor &&
!viewProps.foregroundColor && !viewProps.shadowColor &&
viewProps.transform == Transform{} && viewProps.zIndex == 0 &&
// Layout Metrics
getLayoutMetrics().borderWidth == EdgeInsets{};
#endif
}

View File

@ -7,8 +7,8 @@
#pragma once
#include <fabric/components/view/ViewProps.h>
#include <fabric/components/view/ConcreteViewShadowNode.h>
#include <fabric/components/view/ViewProps.h>
namespace facebook {
namespace react {
@ -18,14 +18,11 @@ extern const char ViewComponentName[];
/*
* `ShadowNode` for <View> component.
*/
class ViewShadowNode final:
public ConcreteViewShadowNode<
ViewComponentName,
ViewProps,
ViewEventEmitter
> {
public:
class ViewShadowNode final : public ConcreteViewShadowNode<
ViewComponentName,
ViewProps,
ViewEventEmitter> {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
bool isLayoutOnly() const;

View File

@ -12,7 +12,7 @@
namespace facebook {
namespace react {
enum class AccessibilityTraits: uint32_t {
enum class AccessibilityTraits : uint32_t {
None = 0,
Button = (1 << 0),
Link = (1 << 1),
@ -32,7 +32,9 @@ enum class AccessibilityTraits: uint32_t {
Header = (1 << 15),
};
constexpr enum AccessibilityTraits operator |(const enum AccessibilityTraits lhs, const enum AccessibilityTraits rhs) {
constexpr enum AccessibilityTraits operator|(
const enum AccessibilityTraits lhs,
const enum AccessibilityTraits rhs) {
return (enum AccessibilityTraits)((uint32_t)lhs | (uint32_t)rhs);
}

View File

@ -12,7 +12,9 @@
namespace facebook {
namespace react {
AccessibilityProps::AccessibilityProps(const AccessibilityProps &sourceProps, const RawProps &rawProps) {}
AccessibilityProps::AccessibilityProps(
const AccessibilityProps &sourceProps,
const RawProps &rawProps) {}
} // namespace react
} // namespace facebook

View File

@ -19,22 +19,21 @@ class AccessibilityProps;
typedef std::shared_ptr<const AccessibilityProps> SharedAccessibilityProps;
class AccessibilityProps:
public virtual DebugStringConvertible {
public:
class AccessibilityProps : public virtual DebugStringConvertible {
public:
AccessibilityProps() = default;
AccessibilityProps(const AccessibilityProps &sourceProps, const RawProps &rawProps);
AccessibilityProps(
const AccessibilityProps &sourceProps,
const RawProps &rawProps);
#pragma mark - Props
const bool accessible {false};
const std::vector<std::string> accessibilityActions {};
const std::string accessibilityLabel {""};
const AccessibilityTraits accessibilityTraits {AccessibilityTraits::None};
const bool accessibilityViewIsModal {false};
const bool accessibilityElementsHidden {false};
const bool accessible{false};
const std::vector<std::string> accessibilityActions{};
const std::string accessibilityLabel{""};
const AccessibilityTraits accessibilityTraits{AccessibilityTraits::None};
const bool accessibilityViewIsModal{false};
const bool accessibilityElementsHidden{false};
};
} // namespace react

View File

@ -13,16 +13,13 @@ namespace facebook {
namespace react {
AccessibleShadowNode::AccessibleShadowNode(
const SharedAccessibilityProps &props
) {
const SharedAccessibilityProps &props) {
assert(props);
}
AccessibleShadowNode::AccessibleShadowNode(
const AccessibleShadowNode &shadowNode,
const SharedAccessibilityProps &props
) {
}
const AccessibleShadowNode &shadowNode,
const SharedAccessibilityProps &props) {}
} // namespace react
} // namespace facebook

View File

@ -20,21 +20,16 @@ class AccessibleShadowNode;
using SharedAccessibleShadowNode = std::shared_ptr<const AccessibleShadowNode>;
class AccessibleShadowNode {
public:
public:
#pragma mark - Constructors
AccessibleShadowNode() = default;
AccessibleShadowNode(
const SharedAccessibilityProps &props
);
AccessibleShadowNode(const SharedAccessibilityProps &props);
AccessibleShadowNode(
const AccessibleShadowNode &shadowNode,
const SharedAccessibilityProps &props = nullptr
);
const AccessibleShadowNode &shadowNode,
const SharedAccessibilityProps &props = nullptr);
};
} // namespace react

View File

@ -12,7 +12,8 @@
namespace facebook {
namespace react {
AccessibilityTraits accessibilityTraitsFromDynamic(const folly::dynamic &value) {
AccessibilityTraits accessibilityTraitsFromDynamic(
const folly::dynamic &value) {
assert(value.isString());
// FIXME: Not clear yet.

View File

@ -10,10 +10,10 @@
#include <fabric/components/view/primitives.h>
#include <fabric/core/LayoutMetrics.h>
#include <fabric/graphics/Geometry.h>
#include <folly/dynamic.h>
#include <folly/Conv.h>
#include <yoga/Yoga.h>
#include <folly/dynamic.h>
#include <yoga/YGNode.h>
#include <yoga/Yoga.h>
namespace facebook {
namespace react {
@ -58,52 +58,57 @@ inline YGValue yogaStyleValueFromFloat(const Float &value) {
return {(float)value, YGUnitPoint};
}
inline folly::Optional<Float> optionalFloatFromYogaValue(const YGValue &value, folly::Optional<Float> base = {}) {
inline folly::Optional<Float> optionalFloatFromYogaValue(
const YGValue &value,
folly::Optional<Float> base = {}) {
switch (value.unit) {
case YGUnitUndefined:
return {};
case YGUnitPoint:
return floatFromYogaFloat(value.value);
case YGUnitPercent:
return base.has_value() ? folly::Optional<Float>(base.value() * floatFromYogaFloat(value.value)) : folly::Optional<Float>();
return base.has_value()
? folly::Optional<Float>(
base.value() * floatFromYogaFloat(value.value))
: folly::Optional<Float>();
case YGUnitAuto:
return {};
}
}
inline LayoutMetrics layoutMetricsFromYogaNode(YGNode &yogaNode) {
auto layoutMetrics = LayoutMetrics {};
auto layoutMetrics = LayoutMetrics{};
layoutMetrics.frame = Rect {
Point {
floatFromYogaFloat(YGNodeLayoutGetLeft(&yogaNode)),
floatFromYogaFloat(YGNodeLayoutGetTop(&yogaNode))
},
Size {
floatFromYogaFloat(YGNodeLayoutGetWidth(&yogaNode)),
floatFromYogaFloat(YGNodeLayoutGetHeight(&yogaNode))
}
};
layoutMetrics.frame =
Rect{Point{floatFromYogaFloat(YGNodeLayoutGetLeft(&yogaNode)),
floatFromYogaFloat(YGNodeLayoutGetTop(&yogaNode))},
Size{floatFromYogaFloat(YGNodeLayoutGetWidth(&yogaNode)),
floatFromYogaFloat(YGNodeLayoutGetHeight(&yogaNode))}};
layoutMetrics.borderWidth = EdgeInsets {
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeLeft)),
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeTop)),
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeRight)),
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeBottom))
};
layoutMetrics.borderWidth = EdgeInsets{
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeLeft)),
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeTop)),
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeRight)),
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeBottom))};
layoutMetrics.contentInsets = EdgeInsets {
layoutMetrics.borderWidth.left + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeLeft)),
layoutMetrics.borderWidth.top + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeTop)),
layoutMetrics.borderWidth.right + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeRight)),
layoutMetrics.borderWidth.bottom + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeBottom))
};
layoutMetrics.contentInsets = EdgeInsets{
layoutMetrics.borderWidth.left +
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeLeft)),
layoutMetrics.borderWidth.top +
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeTop)),
layoutMetrics.borderWidth.right +
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeRight)),
layoutMetrics.borderWidth.bottom +
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeBottom))};
layoutMetrics.displayType =
yogaNode.getStyle().display == YGDisplayNone ? DisplayType::None : DisplayType::Flex;
layoutMetrics.displayType = yogaNode.getStyle().display == YGDisplayNone
? DisplayType::None
: DisplayType::Flex;
layoutMetrics.layoutDirection =
YGNodeLayoutGetDirection(&yogaNode) == YGDirectionRTL ? LayoutDirection::RightToLeft : LayoutDirection::LeftToRight;
YGNodeLayoutGetDirection(&yogaNode) == YGDirectionRTL
? LayoutDirection::RightToLeft
: LayoutDirection::LeftToRight;
return layoutMetrics;
}
@ -111,79 +116,172 @@ inline LayoutMetrics layoutMetricsFromYogaNode(YGNode &yogaNode) {
inline void fromDynamic(const folly::dynamic &value, YGDirection &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "inherit") { result = YGDirectionInherit; return; }
if (stringValue == "ltr") { result = YGDirectionLTR; return; }
if (stringValue == "rtl") { result = YGDirectionRTL; return; }
if (stringValue == "inherit") {
result = YGDirectionInherit;
return;
}
if (stringValue == "ltr") {
result = YGDirectionLTR;
return;
}
if (stringValue == "rtl") {
result = YGDirectionRTL;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, YGFlexDirection &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "column") { result = YGFlexDirectionColumn; return; }
if (stringValue == "column-reverse") { result = YGFlexDirectionColumnReverse; return; }
if (stringValue == "row") { result = YGFlexDirectionRow; return; }
if (stringValue == "row-reverse") { result = YGFlexDirectionRowReverse; return; }
if (stringValue == "column") {
result = YGFlexDirectionColumn;
return;
}
if (stringValue == "column-reverse") {
result = YGFlexDirectionColumnReverse;
return;
}
if (stringValue == "row") {
result = YGFlexDirectionRow;
return;
}
if (stringValue == "row-reverse") {
result = YGFlexDirectionRowReverse;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, YGJustify &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "flex-start") { result = YGJustifyFlexStart; return; }
if (stringValue == "center") { result = YGJustifyCenter; return; }
if (stringValue == "flex-end") { result = YGJustifyFlexEnd; return; }
if (stringValue == "space-between") { result = YGJustifySpaceBetween; return; }
if (stringValue == "space-around") { result = YGJustifySpaceAround; return; }
if (stringValue == "space-evenly") { result = YGJustifySpaceEvenly; return; }
if (stringValue == "flex-start") {
result = YGJustifyFlexStart;
return;
}
if (stringValue == "center") {
result = YGJustifyCenter;
return;
}
if (stringValue == "flex-end") {
result = YGJustifyFlexEnd;
return;
}
if (stringValue == "space-between") {
result = YGJustifySpaceBetween;
return;
}
if (stringValue == "space-around") {
result = YGJustifySpaceAround;
return;
}
if (stringValue == "space-evenly") {
result = YGJustifySpaceEvenly;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, YGAlign &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "auto") { result = YGAlignAuto; return; }
if (stringValue == "flex-start") { result = YGAlignFlexStart; return; }
if (stringValue == "center") { result = YGAlignCenter; return; }
if (stringValue == "flex-end") { result = YGAlignFlexEnd; return; }
if (stringValue == "stretch") { result = YGAlignStretch; return; }
if (stringValue == "baseline") { result = YGAlignBaseline; return; }
if (stringValue == "between") { result = YGAlignSpaceBetween; return; }
if (stringValue == "space-around") { result = YGAlignSpaceAround; return; }
if (stringValue == "auto") {
result = YGAlignAuto;
return;
}
if (stringValue == "flex-start") {
result = YGAlignFlexStart;
return;
}
if (stringValue == "center") {
result = YGAlignCenter;
return;
}
if (stringValue == "flex-end") {
result = YGAlignFlexEnd;
return;
}
if (stringValue == "stretch") {
result = YGAlignStretch;
return;
}
if (stringValue == "baseline") {
result = YGAlignBaseline;
return;
}
if (stringValue == "between") {
result = YGAlignSpaceBetween;
return;
}
if (stringValue == "space-around") {
result = YGAlignSpaceAround;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, YGPositionType &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "relative") { result = YGPositionTypeRelative; return; }
if (stringValue == "absolute") { result = YGPositionTypeAbsolute; return; }
if (stringValue == "relative") {
result = YGPositionTypeRelative;
return;
}
if (stringValue == "absolute") {
result = YGPositionTypeAbsolute;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, YGWrap &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "no-wrap") { result = YGWrapNoWrap; return; }
if (stringValue == "wrap") { result = YGWrapWrap; return; }
if (stringValue == "wrap-reverse") { result = YGWrapWrapReverse; return; }
if (stringValue == "no-wrap") {
result = YGWrapNoWrap;
return;
}
if (stringValue == "wrap") {
result = YGWrapWrap;
return;
}
if (stringValue == "wrap-reverse") {
result = YGWrapWrapReverse;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, YGOverflow &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "visible") { result = YGOverflowVisible; return; }
if (stringValue == "hidden") { result = YGOverflowHidden; return; }
if (stringValue == "scroll") { result = YGOverflowScroll; return; }
if (stringValue == "visible") {
result = YGOverflowVisible;
return;
}
if (stringValue == "hidden") {
result = YGOverflowHidden;
return;
}
if (stringValue == "scroll") {
result = YGOverflowScroll;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, YGDisplay &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "flex") { result = YGDisplayFlex; return; }
if (stringValue == "none") { result = YGDisplayNone; return; }
if (stringValue == "flex") {
result = YGDisplayFlex;
return;
}
if (stringValue == "none") {
result = YGDisplayNone;
return;
}
abort();
}
@ -198,10 +296,12 @@ inline void fromDynamic(const folly::dynamic &value, YGValue &result) {
return;
} else {
if (stringValue.back() == '%') {
result = { folly::to<float>(stringValue.substr(0, stringValue.length() - 1)), YGUnitPercent };
result = {
folly::to<float>(stringValue.substr(0, stringValue.length() - 1)),
YGUnitPercent};
return;
} else {
result = { folly::to<float>(stringValue), YGUnitPoint };
result = {folly::to<float>(stringValue), YGUnitPoint};
return;
}
}
@ -225,7 +325,7 @@ inline void fromDynamic(const folly::dynamic &value, YGFloatOptional &result) {
inline void fromDynamic(const folly::dynamic &value, Transform &result) {
assert(value.isArray());
auto transformMatrix = Transform {};
auto transformMatrix = Transform{};
for (const auto &tranformConfiguration : value) {
assert(tranformConfiguration.isObject());
auto pair = *tranformConfiguration.items().begin();
@ -240,149 +340,226 @@ inline void fromDynamic(const folly::dynamic &value, Transform &result) {
transformMatrix.matrix[i++] = (Float)item.asDouble();
}
} else if (operation == "perspective") {
transformMatrix = transformMatrix * Transform::Perspective((Float)parameters.asDouble());
transformMatrix = transformMatrix *
Transform::Perspective((Float)parameters.asDouble());
} else if (operation == "rotateX") {
transformMatrix = transformMatrix * Transform::Rotate((Float)parameters.asDouble(), 0, 0);
transformMatrix = transformMatrix *
Transform::Rotate((Float)parameters.asDouble(), 0, 0);
} else if (operation == "rotateY") {
transformMatrix = transformMatrix * Transform::Rotate(0, (Float)parameters.asDouble(), 0);
transformMatrix = transformMatrix *
Transform::Rotate(0, (Float)parameters.asDouble(), 0);
} else if (operation == "rotateZ") {
transformMatrix = transformMatrix * Transform::Rotate(0, 0, (Float)parameters.asDouble());
transformMatrix = transformMatrix *
Transform::Rotate(0, 0, (Float)parameters.asDouble());
} else if (operation == "scale") {
transformMatrix = transformMatrix * Transform::Scale((Float)parameters.asDouble(), (Float)parameters.asDouble(), (Float)parameters.asDouble());
transformMatrix = transformMatrix *
Transform::Scale((Float)parameters.asDouble(),
(Float)parameters.asDouble(),
(Float)parameters.asDouble());
} else if (operation == "scaleX") {
transformMatrix = transformMatrix * Transform::Scale((Float)parameters.asDouble(), 0, 0);
transformMatrix = transformMatrix *
Transform::Scale((Float)parameters.asDouble(), 0, 0);
} else if (operation == "scaleY") {
transformMatrix = transformMatrix * Transform::Scale(0, (Float)parameters.asDouble(), 0);
transformMatrix = transformMatrix *
Transform::Scale(0, (Float)parameters.asDouble(), 0);
} else if (operation == "scaleZ") {
transformMatrix = transformMatrix * Transform::Scale(0, 0, (Float)parameters.asDouble());
transformMatrix = transformMatrix *
Transform::Scale(0, 0, (Float)parameters.asDouble());
} else if (operation == "translate") {
transformMatrix = transformMatrix * Transform::Translate(parameters[0].asDouble(), parameters[1].asDouble(), 0);
transformMatrix =
transformMatrix *
Transform::Translate(
parameters[0].asDouble(), parameters[1].asDouble(), 0);
} else if (operation == "translateX") {
transformMatrix = transformMatrix * Transform::Translate(parameters.asDouble(), 0, 0);
transformMatrix =
transformMatrix * Transform::Translate(parameters.asDouble(), 0, 0);
} else if (operation == "translateY") {
transformMatrix = transformMatrix * Transform::Translate(0, parameters.asDouble(), 0);
transformMatrix =
transformMatrix * Transform::Translate(0, parameters.asDouble(), 0);
} else if (operation == "skewX") {
transformMatrix = transformMatrix * Transform::Skew(parameters.asDouble(), 0);
transformMatrix =
transformMatrix * Transform::Skew(parameters.asDouble(), 0);
} else if (operation == "skewY") {
transformMatrix = transformMatrix * Transform::Skew(0, parameters.asDouble());
transformMatrix =
transformMatrix * Transform::Skew(0, parameters.asDouble());
}
}
result = transformMatrix;
}
inline void fromDynamic(const folly::dynamic &value, PointerEventsMode &result) {
inline void fromDynamic(
const folly::dynamic &value,
PointerEventsMode &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "auto") { result = PointerEventsMode::Auto; return; }
if (stringValue == "none") { result = PointerEventsMode::None; return; }
if (stringValue == "box-none") { result = PointerEventsMode::BoxNone; return; }
if (stringValue == "box-only") { result = PointerEventsMode::BoxOnly; return; }
if (stringValue == "auto") {
result = PointerEventsMode::Auto;
return;
}
if (stringValue == "none") {
result = PointerEventsMode::None;
return;
}
if (stringValue == "box-none") {
result = PointerEventsMode::BoxNone;
return;
}
if (stringValue == "box-only") {
result = PointerEventsMode::BoxOnly;
return;
}
abort();
}
inline void fromDynamic(const folly::dynamic &value, BorderStyle &result) {
assert(value.isString());
auto stringValue = value.asString();
if (stringValue == "solid") { result = BorderStyle::Solid; return; }
if (stringValue == "dotted") { result = BorderStyle::Dotted; return; }
if (stringValue == "dashed") { result = BorderStyle::Dashed; return; }
if (stringValue == "solid") {
result = BorderStyle::Solid;
return;
}
if (stringValue == "dotted") {
result = BorderStyle::Dotted;
return;
}
if (stringValue == "dashed") {
result = BorderStyle::Dashed;
return;
}
abort();
}
inline std::string toString(const std::array<float, YGDimensionCount> &dimensions) {
return "{" + folly::to<std::string>(dimensions[0]) + ", " + folly::to<std::string>(dimensions[1]) + "}";
inline std::string toString(
const std::array<float, YGDimensionCount> &dimensions) {
return "{" + folly::to<std::string>(dimensions[0]) + ", " +
folly::to<std::string>(dimensions[1]) + "}";
}
inline std::string toString(const std::array<float, 4> &position) {
return "{" + folly::to<std::string>(position[0]) + ", " + folly::to<std::string>(position[1]) + "}";
return "{" + folly::to<std::string>(position[0]) + ", " +
folly::to<std::string>(position[1]) + "}";
}
inline std::string toString(const std::array<float, YGEdgeCount> &edges) {
return "{" +
folly::to<std::string>(edges[0]) + ", " +
folly::to<std::string>(edges[1]) + ", " +
folly::to<std::string>(edges[2]) + ", " +
folly::to<std::string>(edges[3]) + "}";
return "{" + folly::to<std::string>(edges[0]) + ", " +
folly::to<std::string>(edges[1]) + ", " +
folly::to<std::string>(edges[2]) + ", " +
folly::to<std::string>(edges[3]) + "}";
}
inline std::string toString(const YGDirection &value) {
switch (value) {
case YGDirectionInherit: return "inherit";
case YGDirectionLTR: return "ltr";
case YGDirectionRTL: return "rtl";
case YGDirectionInherit:
return "inherit";
case YGDirectionLTR:
return "ltr";
case YGDirectionRTL:
return "rtl";
}
}
inline std::string toString(const YGFlexDirection &value) {
switch (value) {
case YGFlexDirectionColumn: return "column";
case YGFlexDirectionColumnReverse: return "column-reverse";
case YGFlexDirectionRow: return "row";
case YGFlexDirectionRowReverse: return "row-reverse";
case YGFlexDirectionColumn:
return "column";
case YGFlexDirectionColumnReverse:
return "column-reverse";
case YGFlexDirectionRow:
return "row";
case YGFlexDirectionRowReverse:
return "row-reverse";
}
}
inline std::string toString(const YGJustify &value) {
switch (value) {
case YGJustifyFlexStart: return "flex-start";
case YGJustifyCenter: return "center";
case YGJustifyFlexEnd: return "flex-end";
case YGJustifySpaceBetween: return "space-between";
case YGJustifySpaceAround: return "space-around";
case YGJustifySpaceEvenly: return "space-evenly";
case YGJustifyFlexStart:
return "flex-start";
case YGJustifyCenter:
return "center";
case YGJustifyFlexEnd:
return "flex-end";
case YGJustifySpaceBetween:
return "space-between";
case YGJustifySpaceAround:
return "space-around";
case YGJustifySpaceEvenly:
return "space-evenly";
}
}
inline std::string toString(const YGAlign &value) {
switch (value) {
case YGAlignAuto: return "auto";
case YGAlignFlexStart: return "flex-start";
case YGAlignCenter: return "center";
case YGAlignFlexEnd: return "flex-end";
case YGAlignStretch: return "stretch";
case YGAlignBaseline: return "baseline";
case YGAlignSpaceBetween: return "space-between";
case YGAlignSpaceAround: return "space-around";
case YGAlignAuto:
return "auto";
case YGAlignFlexStart:
return "flex-start";
case YGAlignCenter:
return "center";
case YGAlignFlexEnd:
return "flex-end";
case YGAlignStretch:
return "stretch";
case YGAlignBaseline:
return "baseline";
case YGAlignSpaceBetween:
return "space-between";
case YGAlignSpaceAround:
return "space-around";
}
}
inline std::string toString(const YGPositionType &value) {
switch (value) {
case YGPositionTypeRelative: return "relative";
case YGPositionTypeAbsolute: return "absolute";
case YGPositionTypeRelative:
return "relative";
case YGPositionTypeAbsolute:
return "absolute";
}
}
inline std::string toString(const YGWrap &value) {
switch (value) {
case YGWrapNoWrap: return "no-wrap";
case YGWrapWrap: return "wrap";
case YGWrapWrapReverse: return "wrap-reverse";
case YGWrapNoWrap:
return "no-wrap";
case YGWrapWrap:
return "wrap";
case YGWrapWrapReverse:
return "wrap-reverse";
}
}
inline std::string toString(const YGOverflow &value) {
switch (value) {
case YGOverflowVisible: return "visible";
case YGOverflowScroll: return "scroll";
case YGOverflowHidden: return "hidden";
case YGOverflowVisible:
return "visible";
case YGOverflowScroll:
return "scroll";
case YGOverflowHidden:
return "hidden";
}
}
inline std::string toString(const YGDisplay &value) {
switch (value) {
case YGDisplayFlex: return "flex";
case YGDisplayNone: return "none";
case YGDisplayFlex:
return "flex";
case YGDisplayNone:
return "none";
}
}
inline std::string toString(const YGValue &value) {
switch (value.unit) {
case YGUnitUndefined: return "undefined";
case YGUnitPoint: return folly::to<std::string>(value.value);
case YGUnitPercent: return folly::to<std::string>(value.value) + "%";
case YGUnitAuto: return "auto";
case YGUnitUndefined:
return "undefined";
case YGUnitPoint:
return folly::to<std::string>(value.value);
case YGUnitPercent:
return folly::to<std::string>(value.value) + "%";
case YGUnitAuto:
return "auto";
}
}
@ -394,19 +571,24 @@ inline std::string toString(const YGFloatOptional &value) {
return folly::to<std::string>(floatFromYogaFloat(value.getValue()));
}
inline std::string toString(const std::array<YGValue, YGDimensionCount> &value) {
return "{" +
toString(value[0]) + ", " +
toString(value[1]) + "}";
inline std::string toString(
const std::array<YGValue, YGDimensionCount> &value) {
return "{" + toString(value[0]) + ", " + toString(value[1]) + "}";
}
inline std::string toString(const std::array<YGValue, YGEdgeCount> &value) {
static std::array<std::string, YGEdgeCount> names = {
{"left", "top", "right", "bottom", "start", "end", "horizontal", "vertical", "all"}
};
static std::array<std::string, YGEdgeCount> names = {{"left",
"top",
"right",
"bottom",
"start",
"end",
"horizontal",
"vertical",
"all"}};
auto result = std::string {};
auto separator = std::string {", "};
auto result = std::string{};
auto separator = std::string{", "};
for (auto i = 0; i < YGEdgeCount; i++) {
if (value[i].unit == YGUnitUndefined) {

View File

@ -11,30 +11,29 @@
#include <fabric/graphics/Color.h>
#include <fabric/graphics/Geometry.h>
#include <folly/Optional.h>
#include <array>
#include <cmath>
namespace facebook {
namespace react {
struct Transform {
std::array<Float, 16> matrix {{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
}};
std::array<Float, 16> matrix{
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}};
static Transform Identity() {
return {};
}
static Transform Perspective(const Float &perspective) {
auto transform = Transform {};
auto transform = Transform{};
transform.matrix[11] = -1.0 / perspective;
return transform;
}
static Transform Scale(const Float &factorX, const Float &factorY, const Float &factorZ) {
auto transform = Transform {};
static Transform
Scale(const Float &factorX, const Float &factorY, const Float &factorZ) {
auto transform = Transform{};
transform.matrix[0] = factorX;
transform.matrix[5] = factorY;
transform.matrix[10] = factorZ;
@ -42,7 +41,7 @@ struct Transform {
}
static Transform Translate(const Float &x, const Float &y, const Float &z) {
auto transform = Transform {};
auto transform = Transform{};
transform.matrix[12] = x;
transform.matrix[13] = y;
transform.matrix[14] = z;
@ -50,14 +49,14 @@ struct Transform {
}
static Transform Skew(const Float &x, const Float &y) {
auto transform = Transform {};
auto transform = Transform{};
transform.matrix[4] = std::tan(x);
transform.matrix[1] = std::tan(y);
return transform;
}
static Transform RotateX(const Float &radians) {
auto transform = Transform {};
auto transform = Transform{};
transform.matrix[5] = std::cos(radians);
transform.matrix[6] = std::sin(radians);
transform.matrix[9] = -std::sin(radians);
@ -66,7 +65,7 @@ struct Transform {
}
static Transform RotateY(const Float &radians) {
auto transform = Transform {};
auto transform = Transform{};
transform.matrix[0] = std::cos(radians);
transform.matrix[2] = -std::sin(radians);
transform.matrix[8] = std::sin(radians);
@ -75,7 +74,7 @@ struct Transform {
}
static Transform RotateZ(const Float &radians) {
auto transform = Transform {};
auto transform = Transform{};
transform.matrix[0] = std::cos(radians);
transform.matrix[1] = std::sin(radians);
transform.matrix[4] = -std::sin(radians);
@ -84,14 +83,20 @@ struct Transform {
}
static Transform Rotate(const Float &x, const Float &y, const Float &z) {
auto transform = Transform {};
if (x != 0) { transform = transform * Transform::RotateX(x); }
if (y != 0) { transform = transform * Transform::RotateY(y); }
if (z != 0) { transform = transform * Transform::RotateZ(z); }
auto transform = Transform{};
if (x != 0) {
transform = transform * Transform::RotateX(x);
}
if (y != 0) {
transform = transform * Transform::RotateY(y);
}
if (z != 0) {
transform = transform * Transform::RotateZ(z);
}
return transform;
}
bool operator ==(const Transform& rhs) const {
bool operator==(const Transform &rhs) const {
for (auto i = 0; i < 16; i++) {
if (matrix[i] != rhs.matrix[i]) {
return false;
@ -100,97 +105,134 @@ struct Transform {
return true;
}
bool operator !=(const Transform& rhs) const {
bool operator!=(const Transform &rhs) const {
return !(*this == rhs);
}
Transform operator *(const Transform& rhs) const {
Transform operator*(const Transform &rhs) const {
if (*this == Transform::Identity()) {
return rhs;
}
const auto &lhs = *this;
auto result = Transform {};
auto result = Transform{};
auto lhs00 = lhs.matrix[0], lhs01 = lhs.matrix[1], lhs02 = lhs.matrix[2], lhs03 = lhs.matrix[3],
lhs10 = lhs.matrix[4], lhs11 = lhs.matrix[5], lhs12 = lhs.matrix[6], lhs13 = lhs.matrix[7],
lhs20 = lhs.matrix[8], lhs21 = lhs.matrix[9], lhs22 = lhs.matrix[10], lhs23 = lhs.matrix[11],
lhs30 = lhs.matrix[12], lhs31 = lhs.matrix[13], lhs32 = lhs.matrix[14], lhs33 = lhs.matrix[15];
auto lhs00 = lhs.matrix[0], lhs01 = lhs.matrix[1], lhs02 = lhs.matrix[2],
lhs03 = lhs.matrix[3], lhs10 = lhs.matrix[4], lhs11 = lhs.matrix[5],
lhs12 = lhs.matrix[6], lhs13 = lhs.matrix[7], lhs20 = lhs.matrix[8],
lhs21 = lhs.matrix[9], lhs22 = lhs.matrix[10], lhs23 = lhs.matrix[11],
lhs30 = lhs.matrix[12], lhs31 = lhs.matrix[13], lhs32 = lhs.matrix[14],
lhs33 = lhs.matrix[15];
auto rhs0 = rhs.matrix[0], rhs1 = rhs.matrix[1], rhs2 = rhs.matrix[2], rhs3 = rhs.matrix[3];
result.matrix[0] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[1] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[2] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[3] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
auto rhs0 = rhs.matrix[0], rhs1 = rhs.matrix[1], rhs2 = rhs.matrix[2],
rhs3 = rhs.matrix[3];
result.matrix[0] =
rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[1] =
rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[2] =
rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[3] =
rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
rhs0 = rhs.matrix[4]; rhs1 = rhs.matrix[5]; rhs2 = rhs.matrix[6]; rhs3 = rhs.matrix[7];
result.matrix[4] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[5] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[6] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[7] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
rhs0 = rhs.matrix[4];
rhs1 = rhs.matrix[5];
rhs2 = rhs.matrix[6];
rhs3 = rhs.matrix[7];
result.matrix[4] =
rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[5] =
rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[6] =
rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[7] =
rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
rhs0 = rhs.matrix[8]; rhs1 = rhs.matrix[9]; rhs2 = rhs.matrix[10]; rhs3 = rhs.matrix[11];
result.matrix[8] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[9] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[10] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[11] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
rhs0 = rhs.matrix[8];
rhs1 = rhs.matrix[9];
rhs2 = rhs.matrix[10];
rhs3 = rhs.matrix[11];
result.matrix[8] =
rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[9] =
rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[10] =
rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[11] =
rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
rhs0 = rhs.matrix[12]; rhs1 = rhs.matrix[13]; rhs2 = rhs.matrix[14]; rhs3 = rhs.matrix[15];
result.matrix[12] = rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[13] = rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[14] = rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[15] = rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
rhs0 = rhs.matrix[12];
rhs1 = rhs.matrix[13];
rhs2 = rhs.matrix[14];
rhs3 = rhs.matrix[15];
result.matrix[12] =
rhs0 * lhs00 + rhs1 * lhs10 + rhs2 * lhs20 + rhs3 * lhs30;
result.matrix[13] =
rhs0 * lhs01 + rhs1 * lhs11 + rhs2 * lhs21 + rhs3 * lhs31;
result.matrix[14] =
rhs0 * lhs02 + rhs1 * lhs12 + rhs2 * lhs22 + rhs3 * lhs32;
result.matrix[15] =
rhs0 * lhs03 + rhs1 * lhs13 + rhs2 * lhs23 + rhs3 * lhs33;
return result;
}
};
enum class PointerEventsMode {
Auto,
None,
BoxNone,
BoxOnly
};
enum class PointerEventsMode { Auto, None, BoxNone, BoxOnly };
enum class BorderStyle {
Solid,
Dotted,
Dashed
};
enum class BorderStyle { Solid, Dotted, Dashed };
template <typename T>
struct CascadedRectangleEdges {
using Counterpart = RectangleEdges<T>;
using OptionalT = folly::Optional<T>;
OptionalT left {};
OptionalT top {};
OptionalT right {};
OptionalT bottom {};
OptionalT start {};
OptionalT end {};
OptionalT horizontal {};
OptionalT vertical {};
OptionalT all {};
OptionalT left{};
OptionalT top{};
OptionalT right{};
OptionalT bottom{};
OptionalT start{};
OptionalT end{};
OptionalT horizontal{};
OptionalT vertical{};
OptionalT all{};
Counterpart resolve(bool isRTL, T defaults) const {
const auto leading = isRTL ? end : start;
const auto trailing = isRTL ? start : end;
const auto horizontalOrAllOrDefault = horizontal.value_or(all.value_or(defaults));
const auto verticalOrAllOrDefault = vertical.value_or(all.value_or(defaults));
const auto horizontalOrAllOrDefault =
horizontal.value_or(all.value_or(defaults));
const auto verticalOrAllOrDefault =
vertical.value_or(all.value_or(defaults));
return Counterpart {
.left = left.value_or(leading.value_or(horizontalOrAllOrDefault)),
.right = right.value_or(trailing.value_or(horizontalOrAllOrDefault)),
.top = top.value_or(verticalOrAllOrDefault),
.bottom = bottom.value_or(verticalOrAllOrDefault)
};
return Counterpart{
.left = left.value_or(leading.value_or(horizontalOrAllOrDefault)),
.right = right.value_or(trailing.value_or(horizontalOrAllOrDefault)),
.top = top.value_or(verticalOrAllOrDefault),
.bottom = bottom.value_or(verticalOrAllOrDefault)};
}
bool operator==(const CascadedRectangleEdges<T> &rhs) const {
return
std::tie(this->left, this->top, this->right, this->bottom, this->start, this->end, this->horizontal, this->vertical, this->all) ==
std::tie(rhs.left, rhs.top, rhs.right, rhs.bottom, rhs.start, rhs.end, rhs.horizontal, rhs.vertical, rhs.all);
return std::tie(
this->left,
this->top,
this->right,
this->bottom,
this->start,
this->end,
this->horizontal,
this->vertical,
this->all) ==
std::tie(
rhs.left,
rhs.top,
rhs.right,
rhs.bottom,
rhs.start,
rhs.end,
rhs.horizontal,
rhs.vertical,
rhs.all);
}
bool operator!=(const CascadedRectangleEdges<T> &rhs) const {
@ -203,15 +245,15 @@ struct CascadedRectangleCorners {
using Counterpart = RectangleCorners<T>;
using OptionalT = folly::Optional<T>;
OptionalT topLeft {};
OptionalT topRight {};
OptionalT bottomLeft {};
OptionalT bottomRight {};
OptionalT topStart {};
OptionalT topEnd {};
OptionalT bottomStart {};
OptionalT bottomEnd {};
OptionalT all {};
OptionalT topLeft{};
OptionalT topRight{};
OptionalT bottomLeft{};
OptionalT bottomRight{};
OptionalT topStart{};
OptionalT topEnd{};
OptionalT bottomStart{};
OptionalT bottomEnd{};
OptionalT all{};
Counterpart resolve(bool isRTL, T defaults) const {
const auto topLeading = isRTL ? topEnd : topStart;
@ -219,18 +261,38 @@ struct CascadedRectangleCorners {
const auto bottomLeading = isRTL ? bottomEnd : bottomStart;
const auto bottomTrailing = isRTL ? bottomStart : bottomEnd;
return Counterpart {
.topLeft = topLeft.value_or(topLeading.value_or(all.value_or(defaults))),
.topRight = topRight.value_or(topTrailing.value_or(all.value_or(defaults))),
.bottomLeft = bottomLeft.value_or(topLeading.value_or(all.value_or(defaults))),
.bottomRight = bottomRight.value_or(topTrailing.value_or(all.value_or(defaults)))
};
return Counterpart{
.topLeft =
topLeft.value_or(topLeading.value_or(all.value_or(defaults))),
.topRight =
topRight.value_or(topTrailing.value_or(all.value_or(defaults))),
.bottomLeft =
bottomLeft.value_or(topLeading.value_or(all.value_or(defaults))),
.bottomRight =
bottomRight.value_or(topTrailing.value_or(all.value_or(defaults)))};
}
bool operator==(const CascadedRectangleCorners<T> &rhs) const {
return
std::tie(this->topLeft, this->topRight, this->bottomLeft, this->bottomRight, this->topStart, this->topEnd, this->bottomStart, this->bottomEnd, this->all) ==
std::tie(rhs.topLeft, rhs.topRight, rhs.bottomLeft, rhs.bottomRight, rhs.topStart, rhs.topEnd, rhs.bottomStart, rhs.bottomEnd, rhs.all);
return std::tie(
this->topLeft,
this->topRight,
this->bottomLeft,
this->bottomRight,
this->topStart,
this->topEnd,
this->bottomStart,
this->bottomEnd,
this->all) ==
std::tie(
rhs.topLeft,
rhs.topRight,
rhs.bottomLeft,
rhs.bottomRight,
rhs.topStart,
rhs.topEnd,
rhs.bottomStart,
rhs.bottomEnd,
rhs.all);
}
bool operator!=(const CascadedRectangleCorners<T> &rhs) const {
@ -249,15 +311,22 @@ using CascadedBorderColors = CascadedRectangleEdges<SharedColor>;
using CascadedBorderRadii = CascadedRectangleCorners<Float>;
struct BorderMetrics {
BorderColors borderColors {};
BorderWidths borderWidths {};
BorderRadii borderRadii {};
BorderStyles borderStyles {};
BorderColors borderColors{};
BorderWidths borderWidths{};
BorderRadii borderRadii{};
BorderStyles borderStyles{};
bool operator==(const BorderMetrics &rhs) const {
return
std::tie(this->borderColors, this->borderWidths, this->borderRadii, this->borderStyles) ==
std::tie(rhs.borderColors, rhs.borderWidths, rhs.borderRadii, rhs.borderStyles);
return std::tie(
this->borderColors,
this->borderWidths,
this->borderRadii,
this->borderStyles) ==
std::tie(
rhs.borderColors,
rhs.borderWidths,
rhs.borderRadii,
rhs.borderStyles);
}
bool operator!=(const BorderMetrics &rhs) const {

View File

@ -11,18 +11,16 @@
#include <memory>
#include <fabric/components/view/conversions.h>
#include <fabric/core/LayoutContext.h>
#include <fabric/core/LayoutConstraints.h>
#include <fabric/core/LayoutContext.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
#include <yoga/Yoga.h>
namespace facebook {
namespace react {
YogaLayoutableShadowNode::YogaLayoutableShadowNode():
yogaNode_({}),
yogaConfig_(nullptr) {
YogaLayoutableShadowNode::YogaLayoutableShadowNode()
: yogaNode_({}), yogaConfig_(nullptr) {
initializeYogaConfig(yogaConfig_);
yogaNode_.setConfig(&yogaConfig_);
@ -31,11 +29,8 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode():
}
YogaLayoutableShadowNode::YogaLayoutableShadowNode(
const YogaLayoutableShadowNode &layoutableShadowNode
):
yogaNode_(layoutableShadowNode.yogaNode_),
yogaConfig_(nullptr) {
const YogaLayoutableShadowNode &layoutableShadowNode)
: yogaNode_(layoutableShadowNode.yogaNode_), yogaConfig_(nullptr) {
initializeYogaConfig(yogaConfig_);
yogaNode_.setConfig(&yogaConfig_);
@ -69,7 +64,8 @@ void YogaLayoutableShadowNode::setHasNewLayout(bool hasNewLayout) {
void YogaLayoutableShadowNode::enableMeasurement() {
ensureUnsealed();
yogaNode_.setMeasureFunc(YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector);
yogaNode_.setMeasureFunc(
YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector);
}
void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
@ -79,7 +75,8 @@ void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
auto childYogaNodeRawPtr = &child->yogaNode_;
if (childYogaNodeRawPtr->getOwner() != nullptr) {
child = static_cast<YogaLayoutableShadowNode *>(cloneAndReplaceChild(child, yogaNode_.getChildren().size()));
child = static_cast<YogaLayoutableShadowNode *>(
cloneAndReplaceChild(child, yogaNode_.getChildren().size()));
childYogaNodeRawPtr = &child->yogaNode_;
assert(childYogaNodeRawPtr->getOwner() == nullptr);
}
@ -87,10 +84,12 @@ void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
child->ensureUnsealed();
childYogaNodeRawPtr->setOwner(yogaNodeRawPtr);
yogaNodeRawPtr->insertChild(childYogaNodeRawPtr, yogaNodeRawPtr->getChildren().size());
yogaNodeRawPtr->insertChild(
childYogaNodeRawPtr, yogaNodeRawPtr->getChildren().size());
}
void YogaLayoutableShadowNode::setChildren(std::vector<YogaLayoutableShadowNode *> children) {
void YogaLayoutableShadowNode::setChildren(
std::vector<YogaLayoutableShadowNode *> children) {
yogaNode_.setChildren({});
for (const auto &child : children) {
appendChild(child);
@ -115,7 +114,8 @@ void YogaLayoutableShadowNode::layout(LayoutContext layoutContext) {
* (and this is by design).
*/
yogaConfig_.pointScaleFactor = layoutContext.pointScaleFactor;
YGNodeCalculateLayout(&yogaNode_, YGUndefined, YGUndefined, YGDirectionInherit);
YGNodeCalculateLayout(
&yogaNode_, YGUndefined, YGUndefined, YGDirectionInherit);
}
LayoutableShadowNode::layout(layoutContext);
@ -124,21 +124,23 @@ void YogaLayoutableShadowNode::layout(LayoutContext layoutContext) {
void YogaLayoutableShadowNode::layoutChildren(LayoutContext layoutContext) {
for (const auto &childYogaNode : yogaNode_.getChildren()) {
auto childNode =
static_cast<YogaLayoutableShadowNode *>(childYogaNode->getContext());
static_cast<YogaLayoutableShadowNode *>(childYogaNode->getContext());
LayoutMetrics childLayoutMetrics = layoutMetricsFromYogaNode(childNode->yogaNode_);
LayoutMetrics childLayoutMetrics =
layoutMetricsFromYogaNode(childNode->yogaNode_);
childLayoutMetrics.pointScaleFactor = layoutContext.pointScaleFactor;
childNode->setLayoutMetrics(childLayoutMetrics);
}
}
std::vector<LayoutableShadowNode *> YogaLayoutableShadowNode::getLayoutableChildNodes() const {
std::vector<LayoutableShadowNode *>
YogaLayoutableShadowNode::getLayoutableChildNodes() const {
std::vector<LayoutableShadowNode *> yogaLayoutableChildNodes;
yogaLayoutableChildNodes.reserve(yogaNode_.getChildren().size());
for (const auto &childYogaNode : yogaNode_.getChildren()) {
auto childNode =
static_cast<YogaLayoutableShadowNode *>(childYogaNode->getContext());
static_cast<YogaLayoutableShadowNode *>(childYogaNode->getContext());
yogaLayoutableChildNodes.push_back(childNode);
}
@ -147,22 +149,32 @@ std::vector<LayoutableShadowNode *> YogaLayoutableShadowNode::getLayoutableChild
#pragma mark - Yoga Connectors
YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(YGNode *oldYogaNode, YGNode *parentYogaNode, int childIndex) {
// At this point it is garanteed that all shadow nodes associated with yoga nodes are `YogaLayoutableShadowNode` subclasses.
YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(
YGNode *oldYogaNode,
YGNode *parentYogaNode,
int childIndex) {
// At this point it is garanteed that all shadow nodes associated with yoga
// nodes are `YogaLayoutableShadowNode` subclasses.
auto parentNode =
static_cast<YogaLayoutableShadowNode *>(parentYogaNode->getContext());
static_cast<YogaLayoutableShadowNode *>(parentYogaNode->getContext());
auto oldNode =
static_cast<YogaLayoutableShadowNode *>(oldYogaNode->getContext());
auto clonedNode =
static_cast<YogaLayoutableShadowNode *>(parentNode->cloneAndReplaceChild(oldNode, childIndex));
static_cast<YogaLayoutableShadowNode *>(oldYogaNode->getContext());
auto clonedNode = static_cast<YogaLayoutableShadowNode *>(
parentNode->cloneAndReplaceChild(oldNode, childIndex));
return &clonedNode->yogaNode_;
}
YGSize YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector(YGNode *yogaNode, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) {
auto shadowNodeRawPtr = static_cast<YogaLayoutableShadowNode *>(yogaNode->getContext());
YGSize YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector(
YGNode *yogaNode,
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode) {
auto shadowNodeRawPtr =
static_cast<YogaLayoutableShadowNode *>(yogaNode->getContext());
auto minimumSize = Size {0, 0};
auto maximumSize = Size {kFloatMax, kFloatMax};
auto minimumSize = Size{0, 0};
auto maximumSize = Size{kFloatMax, kFloatMax};
switch (widthMode) {
case YGMeasureModeUndefined:
@ -190,14 +202,13 @@ YGSize YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector(YGNode *yogaNo
auto size = shadowNodeRawPtr->measure({minimumSize, maximumSize});
return YGSize {
yogaFloatFromFloat(size.width),
yogaFloatFromFloat(size.height)
};
return YGSize{yogaFloatFromFloat(size.width),
yogaFloatFromFloat(size.height)};
}
void YogaLayoutableShadowNode::initializeYogaConfig(YGConfig &config) {
config.cloneNodeCallback = YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector;
config.cloneNodeCallback =
YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector;
}
} // namespace react

View File

@ -20,18 +20,16 @@
namespace facebook {
namespace react {
class YogaLayoutableShadowNode:
public LayoutableShadowNode,
public virtual DebugStringConvertible,
public virtual Sealable {
public:
class YogaLayoutableShadowNode : public LayoutableShadowNode,
public virtual DebugStringConvertible,
public virtual Sealable {
public:
#pragma mark - Constructors
YogaLayoutableShadowNode();
YogaLayoutableShadowNode(const YogaLayoutableShadowNode &layoutableShadowNode);
YogaLayoutableShadowNode(
const YogaLayoutableShadowNode &layoutableShadowNode);
#pragma mark - Mutating Methods
@ -43,13 +41,15 @@ public:
/*
* Appends `child`'s Yoga node to the own Yoga node.
* Complements `ShadowNode::appendChild(...)` functionality from Yoga perspective.
* Complements `ShadowNode::appendChild(...)` functionality from Yoga
* perspective.
*/
void appendChild(YogaLayoutableShadowNode *child);
/*
* Sets Yoga children based on collection of `YogaLayoutableShadowNode` instances.
* Complements `ShadowNode::setChildren(...)` functionality from Yoga perspective.
* Sets Yoga children based on collection of `YogaLayoutableShadowNode`
* instances. Complements `ShadowNode::setChildren(...)` functionality from
* Yoga perspective.
*/
void setChildren(std::vector<YogaLayoutableShadowNode *> children);
@ -72,12 +72,12 @@ public:
* See `LayoutableShadowNode` for more details.
*/
void layout(LayoutContext layoutContext) override;
void layoutChildren(LayoutContext layoutContext) override;
std::vector<LayoutableShadowNode *> getLayoutableChildNodes() const override;
protected:
protected:
/*
* All Yoga functions only accept non-const arguments, so we have to mark
* Yoga node as `mutable` here to avoid `static_cast`ing the pointer to this
@ -90,10 +90,18 @@ protected:
*/
YGConfig yogaConfig_;
private:
private:
static void initializeYogaConfig(YGConfig &config);
static YGNode *yogaNodeCloneCallbackConnector(YGNode *oldYogaNode, YGNode *parentYogaNode, int childIndex);
static YGSize yogaNodeMeasureCallbackConnector(YGNode *yogaNode, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode);
static YGNode *yogaNodeCloneCallbackConnector(
YGNode *oldYogaNode,
YGNode *parentYogaNode,
int childIndex);
static YGSize yogaNodeMeasureCallbackConnector(
YGNode *yogaNode,
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode);
};
} // namespace react

View File

@ -8,8 +8,8 @@
#include "YogaStylableProps.h"
#include <fabric/components/view/conversions.h>
#include <fabric/core/propsConversions.h>
#include <fabric/components/view/propsConversions.h>
#include <fabric/core/propsConversions.h>
#include <fabric/debug/debugStringConvertibleUtils.h>
#include <yoga/YGNode.h>
#include <yoga/Yoga.h>
@ -19,40 +19,75 @@
namespace facebook {
namespace react {
YogaStylableProps::YogaStylableProps(const YGStyle &yogaStyle):
yogaStyle(yogaStyle) {}
YogaStylableProps::YogaStylableProps(const YGStyle &yogaStyle)
: yogaStyle(yogaStyle) {}
YogaStylableProps::YogaStylableProps(const YogaStylableProps &sourceProps, const RawProps &rawProps):
yogaStyle(convertRawProp(rawProps, sourceProps.yogaStyle)) {};
YogaStylableProps::YogaStylableProps(
const YogaStylableProps &sourceProps,
const RawProps &rawProps)
: yogaStyle(convertRawProp(rawProps, sourceProps.yogaStyle)){};
#pragma mark - DebugStringConvertible
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const {
auto defaultYogaStyle = YGStyle {};
auto defaultYogaStyle = YGStyle{};
return {
debugStringConvertibleItem("direction", yogaStyle.direction, defaultYogaStyle.direction),
debugStringConvertibleItem("flexDirection", yogaStyle.flexDirection, defaultYogaStyle.flexDirection),
debugStringConvertibleItem("justifyContent", yogaStyle.justifyContent, defaultYogaStyle.justifyContent),
debugStringConvertibleItem("alignContent", yogaStyle.alignContent, defaultYogaStyle.alignContent),
debugStringConvertibleItem("alignItems", yogaStyle.alignItems, defaultYogaStyle.alignItems),
debugStringConvertibleItem("alignSelf", yogaStyle.alignSelf, defaultYogaStyle.alignSelf),
debugStringConvertibleItem("positionType", yogaStyle.positionType, defaultYogaStyle.positionType),
debugStringConvertibleItem("flexWrap", yogaStyle.flexWrap, defaultYogaStyle.flexWrap),
debugStringConvertibleItem("overflow", yogaStyle.overflow, defaultYogaStyle.overflow),
debugStringConvertibleItem("display", yogaStyle.display, defaultYogaStyle.display),
debugStringConvertibleItem("flex", yogaStyle.flex, defaultYogaStyle.flex),
debugStringConvertibleItem("flexGrow", yogaStyle.flexGrow, defaultYogaStyle.flexGrow),
debugStringConvertibleItem("flexShrink", yogaStyle.flexShrink, defaultYogaStyle.flexShrink),
debugStringConvertibleItem("flexBasis", yogaStyle.flexBasis, defaultYogaStyle.flexBasis),
debugStringConvertibleItem("margin", yogaStyle.margin, defaultYogaStyle.margin),
debugStringConvertibleItem("position", yogaStyle.position, defaultYogaStyle.position),
debugStringConvertibleItem("padding", yogaStyle.padding, defaultYogaStyle.padding),
debugStringConvertibleItem("border", yogaStyle.border, defaultYogaStyle.border),
debugStringConvertibleItem("dimensions", yogaStyle.dimensions, defaultYogaStyle.dimensions),
debugStringConvertibleItem("minDimensions", yogaStyle.minDimensions, defaultYogaStyle.minDimensions),
debugStringConvertibleItem("maxDimensions", yogaStyle.maxDimensions, defaultYogaStyle.maxDimensions),
debugStringConvertibleItem("aspectRatio", yogaStyle.aspectRatio, defaultYogaStyle.aspectRatio),
debugStringConvertibleItem(
"direction", yogaStyle.direction, defaultYogaStyle.direction),
debugStringConvertibleItem(
"flexDirection",
yogaStyle.flexDirection,
defaultYogaStyle.flexDirection),
debugStringConvertibleItem(
"justifyContent",
yogaStyle.justifyContent,
defaultYogaStyle.justifyContent),
debugStringConvertibleItem(
"alignContent",
yogaStyle.alignContent,
defaultYogaStyle.alignContent),
debugStringConvertibleItem(
"alignItems", yogaStyle.alignItems, defaultYogaStyle.alignItems),
debugStringConvertibleItem(
"alignSelf", yogaStyle.alignSelf, defaultYogaStyle.alignSelf),
debugStringConvertibleItem(
"positionType",
yogaStyle.positionType,
defaultYogaStyle.positionType),
debugStringConvertibleItem(
"flexWrap", yogaStyle.flexWrap, defaultYogaStyle.flexWrap),
debugStringConvertibleItem(
"overflow", yogaStyle.overflow, defaultYogaStyle.overflow),
debugStringConvertibleItem(
"display", yogaStyle.display, defaultYogaStyle.display),
debugStringConvertibleItem("flex", yogaStyle.flex, defaultYogaStyle.flex),
debugStringConvertibleItem(
"flexGrow", yogaStyle.flexGrow, defaultYogaStyle.flexGrow),
debugStringConvertibleItem(
"flexShrink", yogaStyle.flexShrink, defaultYogaStyle.flexShrink),
debugStringConvertibleItem(
"flexBasis", yogaStyle.flexBasis, defaultYogaStyle.flexBasis),
debugStringConvertibleItem(
"margin", yogaStyle.margin, defaultYogaStyle.margin),
debugStringConvertibleItem(
"position", yogaStyle.position, defaultYogaStyle.position),
debugStringConvertibleItem(
"padding", yogaStyle.padding, defaultYogaStyle.padding),
debugStringConvertibleItem(
"border", yogaStyle.border, defaultYogaStyle.border),
debugStringConvertibleItem(
"dimensions", yogaStyle.dimensions, defaultYogaStyle.dimensions),
debugStringConvertibleItem(
"minDimensions",
yogaStyle.minDimensions,
defaultYogaStyle.minDimensions),
debugStringConvertibleItem(
"maxDimensions",
yogaStyle.maxDimensions,
defaultYogaStyle.maxDimensions),
debugStringConvertibleItem(
"aspectRatio", yogaStyle.aspectRatio, defaultYogaStyle.aspectRatio),
};
}
#endif

View File

@ -20,16 +20,16 @@ class YogaStylableProps;
typedef std::shared_ptr<const YogaStylableProps> SharedYogaStylableProps;
class YogaStylableProps {
public:
public:
YogaStylableProps() = default;
YogaStylableProps(const YGStyle &yogaStyle);
YogaStylableProps(const YogaStylableProps &sourceProps, const RawProps &rawProps);
YogaStylableProps(
const YogaStylableProps &sourceProps,
const RawProps &rawProps);
#pragma mark - Props
const YGStyle yogaStyle {};
const YGStyle yogaStyle{};
#pragma mark - DebugStringConvertible (Partial)

View File

@ -11,10 +11,10 @@ namespace facebook {
namespace react {
struct ColorComponents {
float red {0};
float green {0};
float blue {0};
float alpha {0};
float red{0};
float green{0};
float blue{0};
float alpha{0};
};
} // namespace react

View File

@ -18,8 +18,8 @@ namespace react {
* Point
*/
struct Point {
Float x {0};
Float y {0};
Float x{0};
Float y{0};
Point &operator+=(const Point &point) {
x += point.x;
@ -38,9 +38,7 @@ struct Point {
}
bool operator==(const Point &rhs) const {
return
std::tie(this->x, this->y) ==
std::tie(rhs.x, rhs.y);
return std::tie(this->x, this->y) == std::tie(rhs.x, rhs.y);
}
bool operator!=(const Point &rhs) const {
@ -52,8 +50,8 @@ struct Point {
* Size
*/
struct Size {
Float width {0};
Float height {0};
Float width{0};
Float height{0};
Size &operator+=(const Point &point) {
width += point.x;
@ -68,9 +66,8 @@ struct Size {
}
bool operator==(const Size &rhs) const {
return
std::tie(this->width, this->height) ==
std::tie(rhs.width, rhs.height);
return std::tie(this->width, this->height) ==
std::tie(rhs.width, rhs.height);
}
bool operator!=(const Size &rhs) const {
@ -82,23 +79,29 @@ struct Size {
* Rect: Point and Size
*/
struct Rect {
Point origin {0, 0};
Size size {0, 0};
Point origin{0, 0};
Size size{0, 0};
bool operator==(const Rect &rhs) const {
return
std::tie(this->origin, this->size) ==
std::tie(rhs.origin, rhs.size);
return std::tie(this->origin, this->size) == std::tie(rhs.origin, rhs.size);
}
bool operator!=(const Rect &rhs) const {
return !(*this == rhs);
}
Float getMaxX() const { return size.width > 0 ? origin.x + size.width : origin.x; }
Float getMaxY() const { return size.height > 0 ? origin.y + size.height : origin.y; }
Float getMinX() const { return size.width >= 0 ? origin.x : origin.x + size.width; }
Float getMinY() const { return size.height >= 0 ? origin.y : origin.y + size.height; }
Float getMaxX() const {
return size.width > 0 ? origin.x + size.width : origin.x;
}
Float getMaxY() const {
return size.height > 0 ? origin.y + size.height : origin.y;
}
Float getMinX() const {
return size.width >= 0 ? origin.x : origin.x + size.width;
}
Float getMinY() const {
return size.height >= 0 ? origin.y : origin.y + size.height;
}
void unionInPlace(const Rect &rect) {
auto x1 = std::min(getMinX(), rect.getMinX());
@ -116,15 +119,14 @@ struct Rect {
*/
template <typename T>
struct RectangleEdges {
T left {};
T top {};
T right {};
T bottom {};
T left{};
T top{};
T right{};
T bottom{};
bool operator==(const RectangleEdges<T> &rhs) const {
return
std::tie(this->left, this->top, this->right, this->bottom) ==
std::tie(rhs.left, rhs.top, rhs.right, rhs.bottom);
return std::tie(this->left, this->top, this->right, this->bottom) ==
std::tie(rhs.left, rhs.top, rhs.right, rhs.bottom);
}
bool operator!=(const RectangleEdges<T> &rhs) const {
@ -132,9 +134,7 @@ struct RectangleEdges {
}
bool isUniform() const {
return left == top &&
left == right &&
left == bottom;
return left == top && left == right && left == bottom;
}
};
@ -144,15 +144,18 @@ struct RectangleEdges {
*/
template <typename T>
struct RectangleCorners {
T topLeft {};
T topRight {};
T bottomLeft {};
T bottomRight {};
T topLeft{};
T topRight{};
T bottomLeft{};
T bottomRight{};
bool operator==(const RectangleCorners<T> &rhs) const {
return
std::tie(this->topLeft, this->topRight, this->bottomLeft, this->bottomRight) ==
std::tie(rhs.topLeft, rhs.topRight, rhs.bottomLeft, rhs.bottomRight);
return std::tie(
this->topLeft,
this->topRight,
this->bottomLeft,
this->bottomRight) ==
std::tie(rhs.topLeft, rhs.topRight, rhs.bottomLeft, rhs.bottomRight);
}
bool operator!=(const RectangleCorners<T> &rhs) const {
@ -160,9 +163,8 @@ struct RectangleCorners {
}
bool isUniform() const {
return topLeft == topRight &&
topLeft == bottomLeft &&
topLeft == bottomRight;
return topLeft == topRight && topLeft == bottomLeft &&
topLeft == bottomRight;
}
};
@ -180,53 +182,48 @@ using CornerInsets = RectangleCorners<Float>;
} // namespace facebook
namespace std {
template <>
struct hash<facebook::react::Point> {
size_t operator()(const facebook::react::Point &point) const {
return
hash<decltype(point.x)>{}(point.x) +
template <>
struct hash<facebook::react::Point> {
size_t operator()(const facebook::react::Point &point) const {
return hash<decltype(point.x)>{}(point.x) +
hash<decltype(point.y)>{}(point.y);
}
};
}
};
template <>
struct hash<facebook::react::Size> {
size_t operator()(const facebook::react::Size &size) const {
return
hash<decltype(size.width)>{}(size.width) +
template <>
struct hash<facebook::react::Size> {
size_t operator()(const facebook::react::Size &size) const {
return hash<decltype(size.width)>{}(size.width) +
hash<decltype(size.height)>{}(size.height);
}
};
}
};
template <>
struct hash<facebook::react::Rect> {
size_t operator()(const facebook::react::Rect &rect) const {
return
hash<decltype(rect.origin)>{}(rect.origin) +
template <>
struct hash<facebook::react::Rect> {
size_t operator()(const facebook::react::Rect &rect) const {
return hash<decltype(rect.origin)>{}(rect.origin) +
hash<decltype(rect.size)>{}(rect.size);
}
};
}
};
template <typename T>
struct hash<facebook::react::RectangleEdges<T>> {
size_t operator()(const facebook::react::RectangleEdges<T> &edges) const {
return
hash<decltype(edges.left)>{}(edges.left) +
template <typename T>
struct hash<facebook::react::RectangleEdges<T>> {
size_t operator()(const facebook::react::RectangleEdges<T> &edges) const {
return hash<decltype(edges.left)>{}(edges.left) +
hash<decltype(edges.right)>{}(edges.right) +
hash<decltype(edges.top)>{}(edges.top) +
hash<decltype(edges.bottom)>{}(edges.bottom);
}
};
}
};
template <typename T>
struct hash<facebook::react::RectangleCorners<T>> {
size_t operator()(const facebook::react::RectangleCorners<T> &corners) const {
return
hash<decltype(corners.topLeft)>{}(corners.topLeft) +
template <typename T>
struct hash<facebook::react::RectangleCorners<T>> {
size_t operator()(const facebook::react::RectangleCorners<T> &corners) const {
return hash<decltype(corners.topLeft)>{}(corners.topLeft) +
hash<decltype(corners.bottomLeft)>{}(corners.bottomLeft) +
hash<decltype(corners.topRight)>{}(corners.topRight) +
hash<decltype(corners.bottomRight)>{}(corners.bottomRight);
}
};
}
};
} // namespace std

View File

@ -7,9 +7,9 @@
#pragma once
#include <folly/dynamic.h>
#include <fabric/graphics/Color.h>
#include <fabric/graphics/Geometry.h>
#include <folly/dynamic.h>
namespace facebook {
namespace react {
@ -46,32 +46,31 @@ inline void fromDynamic(const folly::dynamic &value, SharedColor &result) {
inline folly::dynamic toDynamic(const SharedColor &color) {
ColorComponents components = colorComponentsFromColor(color);
auto ratio = 256.f;
return
(((int)(components.alpha * ratio) & 0xff) << 24 |
((int)(components.red * ratio) & 0xff) << 16 |
((int)(components.green * ratio) & 0xff) << 8 |
((int)(components.blue * ratio) & 0xff));
return (
((int)(components.alpha * ratio) & 0xff) << 24 |
((int)(components.red * ratio) & 0xff) << 16 |
((int)(components.green * ratio) & 0xff) << 8 |
((int)(components.blue * ratio) & 0xff));
}
inline std::string toString(const SharedColor &value) {
ColorComponents components = colorComponentsFromColor(value);
auto ratio = 256.f;
return "rgba(" +
folly::to<std::string>(round(components.red * ratio)) + ", " +
folly::to<std::string>(round(components.green * ratio)) + ", " +
folly::to<std::string>(round(components.blue * ratio)) + ", " +
folly::to<std::string>(round(components.alpha * ratio)) + ")";
return "rgba(" + folly::to<std::string>(round(components.red * ratio)) +
", " + folly::to<std::string>(round(components.green * ratio)) + ", " +
folly::to<std::string>(round(components.blue * ratio)) + ", " +
folly::to<std::string>(round(components.alpha * ratio)) + ")";
}
#pragma mark - Geometry
inline void fromDynamic(const folly::dynamic &value, Point &result) {
if (value.isObject()) {
result = Point {(Float)value["x"].asDouble(), (Float)value["y"].asDouble()};
result = Point{(Float)value["x"].asDouble(), (Float)value["y"].asDouble()};
return;
}
if (value.isArray()) {
result = Point {(Float)value[0].asDouble(), (Float)value[1].asDouble()};
result = Point{(Float)value[0].asDouble(), (Float)value[1].asDouble()};
return;
}
abort();
@ -79,11 +78,12 @@ inline void fromDynamic(const folly::dynamic &value, Point &result) {
inline void fromDynamic(const folly::dynamic &value, Size &result) {
if (value.isObject()) {
result = Size {(Float)value["width"].asDouble(), (Float)value["height"].asDouble()};
result = Size{(Float)value["width"].asDouble(),
(Float)value["height"].asDouble()};
return;
}
if (value.isArray()) {
result = Size {(Float)value[0].asDouble(), (Float)value[1].asDouble()};
result = Size{(Float)value[0].asDouble(), (Float)value[1].asDouble()};
return;
}
abort();
@ -92,25 +92,21 @@ inline void fromDynamic(const folly::dynamic &value, Size &result) {
inline void fromDynamic(const folly::dynamic &value, EdgeInsets &result) {
if (value.isNumber()) {
const Float number = value.asDouble();
result = EdgeInsets {number, number, number, number};
result = EdgeInsets{number, number, number, number};
return;
}
if (value.isObject()) {
result = EdgeInsets {
(Float)value["top"].asDouble(),
(Float)value["left"].asDouble(),
(Float)value["bottom"].asDouble(),
(Float)value["right"].asDouble()
};
result = EdgeInsets{(Float)value["top"].asDouble(),
(Float)value["left"].asDouble(),
(Float)value["bottom"].asDouble(),
(Float)value["right"].asDouble()};
return;
}
if (value.isArray()) {
result = EdgeInsets {
(Float)value[0].asDouble(),
(Float)value[1].asDouble(),
(Float)value[2].asDouble(),
(Float)value[3].asDouble()
};
result = EdgeInsets{(Float)value[0].asDouble(),
(Float)value[1].asDouble(),
(Float)value[2].asDouble(),
(Float)value[3].asDouble()};
return;
}
abort();
@ -119,36 +115,34 @@ inline void fromDynamic(const folly::dynamic &value, EdgeInsets &result) {
inline void fromDynamic(const folly::dynamic &value, CornerInsets &result) {
if (value.isNumber()) {
const Float number = value.asDouble();
result = CornerInsets {number, number, number, number};
result = CornerInsets{number, number, number, number};
return;
}
if (value.isObject()) {
result = CornerInsets {
(Float)value["topLeft"].asDouble(),
(Float)value["topRight"].asDouble(),
(Float)value["bottomLeft"].asDouble(),
(Float)value["bottomRight"].asDouble()
};
result = CornerInsets{(Float)value["topLeft"].asDouble(),
(Float)value["topRight"].asDouble(),
(Float)value["bottomLeft"].asDouble(),
(Float)value["bottomRight"].asDouble()};
return;
}
if (value.isArray()) {
result = CornerInsets {
(Float)value[0].asDouble(),
(Float)value[1].asDouble(),
(Float)value[2].asDouble(),
(Float)value[3].asDouble()
};
result = CornerInsets{(Float)value[0].asDouble(),
(Float)value[1].asDouble(),
(Float)value[2].asDouble(),
(Float)value[3].asDouble()};
return;
}
abort();
}
inline std::string toString(const Point &point) {
return "{" + folly::to<std::string>(point.x) + ", " + folly::to<std::string>(point.y) + "}";
return "{" + folly::to<std::string>(point.x) + ", " +
folly::to<std::string>(point.y) + "}";
}
inline std::string toString(const Size &size) {
return "{" + folly::to<std::string>(size.width) + ", " + folly::to<std::string>(size.height) + "}";
return "{" + folly::to<std::string>(size.width) + ", " +
folly::to<std::string>(size.height) + "}";
}
inline std::string toString(const Rect &rect) {
@ -156,19 +150,17 @@ inline std::string toString(const Rect &rect) {
}
inline std::string toString(const EdgeInsets &edgeInsets) {
return "{" +
folly::to<std::string>(edgeInsets.left) + ", " +
folly::to<std::string>(edgeInsets.top) + ", " +
folly::to<std::string>(edgeInsets.right) + ", " +
folly::to<std::string>(edgeInsets.bottom) + "}";
return "{" + folly::to<std::string>(edgeInsets.left) + ", " +
folly::to<std::string>(edgeInsets.top) + ", " +
folly::to<std::string>(edgeInsets.right) + ", " +
folly::to<std::string>(edgeInsets.bottom) + "}";
}
inline std::string toString(const CornerInsets &cornerInsets) {
return "{" +
folly::to<std::string>(cornerInsets.topLeft) + ", " +
folly::to<std::string>(cornerInsets.topRight) + ", " +
folly::to<std::string>(cornerInsets.bottomLeft) + ", " +
folly::to<std::string>(cornerInsets.bottomRight) + "}";
return "{" + folly::to<std::string>(cornerInsets.topLeft) + ", " +
folly::to<std::string>(cornerInsets.topRight) + ", " +
folly::to<std::string>(cornerInsets.bottomLeft) + ", " +
folly::to<std::string>(cornerInsets.bottomRight) + "}";
}
} // namespace react

View File

@ -13,22 +13,19 @@ namespace react {
SharedColor colorFromComponents(ColorComponents components) {
float ratio = 255.9999;
return SharedColor(
((int)(components.alpha * ratio) & 0xff) << 24 |
((int)(components.red * ratio) & 0xff) << 16 |
((int)(components.green * ratio) & 0xff) << 8 |
((int)(components.blue * ratio) & 0xff)
);
((int)(components.alpha * ratio) & 0xff) << 24 |
((int)(components.red * ratio) & 0xff) << 16 |
((int)(components.green * ratio) & 0xff) << 8 |
((int)(components.blue * ratio) & 0xff));
}
ColorComponents colorComponentsFromColor(SharedColor sharedColor) {
float ratio = 256;
Color color = *sharedColor;
return ColorComponents {
(float)((color >> 16) & 0xff) / ratio,
(float)((color >> 8) & 0xff) / ratio,
(float)((color ) & 0xff) / ratio,
(float)((color >> 24) & 0xff) / ratio
};
return ColorComponents{(float)((color >> 16) & 0xff) / ratio,
(float)((color >> 8) & 0xff) / ratio,
(float)((color)&0xff) / ratio,
(float)((color >> 24) & 0xff) / ratio};
}
} // namespace react

View File

@ -18,24 +18,20 @@ namespace react {
using Color = int;
/*
* On Android, a color can be represented as 32 bits integer, so there is no need
* to instantiate complex color objects and then pass them as shared pointers.
* Hense instead of using shared_ptr, we use a simple wrapper class
* On Android, a color can be represented as 32 bits integer, so there is no
* need to instantiate complex color objects and then pass them as shared
* pointers. Hense instead of using shared_ptr, we use a simple wrapper class
* which provides a pointer-like interface.
*/
class SharedColor {
public:
public:
static const Color UndefinedColor = std::numeric_limits<Color>::max();
SharedColor():
color_(UndefinedColor) {}
SharedColor() : color_(UndefinedColor) {}
SharedColor(const SharedColor &sharedColor) :
color_(sharedColor.color_) {}
SharedColor(const SharedColor &sharedColor) : color_(sharedColor.color_) {}
SharedColor(Color color):
color_(color) {}
SharedColor(Color color) : color_(color) {}
SharedColor &operator=(const SharedColor &sharedColor) {
color_ = sharedColor.color_;
@ -50,7 +46,7 @@ public:
return color_ != UndefinedColor;
}
private:
private:
Color color_;
};
@ -60,14 +56,11 @@ ColorComponents colorComponentsFromColor(SharedColor color);
} // namespace react
} // namespace facebook
namespace std
{
template <>
struct hash<facebook::react::SharedColor>
{
size_t operator()(const facebook::react::SharedColor& sharedColor) const
{
return hash<decltype(*sharedColor)>{}(*sharedColor);
}
};
}
namespace std {
template <>
struct hash<facebook::react::SharedColor> {
size_t operator()(const facebook::react::SharedColor &sharedColor) const {
return hash<decltype(*sharedColor)>{}(*sharedColor);
}
};
} // namespace std

View File

@ -12,35 +12,27 @@ namespace react {
SharedColor colorFromComponents(ColorComponents components) {
const CGFloat componentsArray[] = {
components.red,
components.green,
components.blue,
components.alpha
};
components.red, components.green, components.blue, components.alpha};
auto color = CGColorCreate(
CGColorSpaceCreateDeviceRGB(),
componentsArray
);
auto color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), componentsArray);
return SharedColor(color, CFRelease);
}
ColorComponents colorComponentsFromColor(SharedColor color) {
if (!color) {
// Empty color object can be considered as `clear` (black, fully transparent) color.
return ColorComponents {0, 0, 0, 0};
// Empty color object can be considered as `clear` (black, fully
// transparent) color.
return ColorComponents{0, 0, 0, 0};
}
auto numberOfComponents = CGColorGetNumberOfComponents(color.get());
assert(numberOfComponents == 4);
const CGFloat *components = CGColorGetComponents(color.get());
return ColorComponents {
(float)components[0],
(float)components[1],
(float)components[2],
(float)components[3]
};
return ColorComponents{(float)components[0],
(float)components[1],
(float)components[2],
(float)components[3]};
}
} // namespace react

View File

@ -5,8 +5,8 @@
#pragma once
#include <limits>
#include <CoreGraphics/CoreGraphics.h>
#include <limits>
namespace facebook {
namespace react {

View File

@ -23,14 +23,13 @@ using SharedImageManager = std::shared_ptr<ImageManager>;
* Cross platform facade for iOS-specific RCTImageManager.
*/
class ImageManager {
public:
public:
ImageManager(void *platformSpecificCounterpart);
~ImageManager();
ImageRequest requestImage(const ImageSource &imageSource) const;
private:
private:
void *self_;
};

View File

@ -10,24 +10,25 @@
namespace facebook {
namespace react {
class ImageRequest::ImageNoLongerNeededException:
public std::logic_error {
public:
ImageNoLongerNeededException():
std::logic_error("Image no longer needed.") {}
class ImageRequest::ImageNoLongerNeededException : public std::logic_error {
public:
ImageNoLongerNeededException()
: std::logic_error("Image no longer needed.") {}
};
ImageRequest::ImageRequest() {}
ImageRequest::ImageRequest(const ImageSource &imageSource, folly::Future<ImageResponse> &&responseFuture):
imageSource_(imageSource),
responseFutureSplitter_(folly::splitFuture(std::move(responseFuture))) {}
ImageRequest::ImageRequest(
const ImageSource &imageSource,
folly::Future<ImageResponse> &&responseFuture)
: imageSource_(imageSource),
responseFutureSplitter_(folly::splitFuture(std::move(responseFuture))) {}
ImageRequest::ImageRequest(ImageRequest &&other) noexcept:
imageSource_(std::move(other.imageSource_)),
responseFutureSplitter_(std::move(other.responseFutureSplitter_)) {
other.moved_ = true;
};
ImageRequest::ImageRequest(ImageRequest &&other) noexcept
: imageSource_(std::move(other.imageSource_)),
responseFutureSplitter_(std::move(other.responseFutureSplitter_)) {
other.moved_ = true;
};
ImageRequest::~ImageRequest() {
if (!moved_) {

View File

@ -26,9 +26,7 @@ namespace react {
* Destroy to cancel the underlying request.
*/
class ImageRequest final {
public:
public:
/*
* The exception which is thrown when `ImageRequest` is being deallocated
* if the future is not ready yet.
@ -39,7 +37,9 @@ public:
* `ImageRequest` is constructed with `ImageSource` and
* `ImageResponse` future which must be moved in inside the object.
*/
ImageRequest(const ImageSource &imageSource, folly::Future<ImageResponse> &&responseFuture);
ImageRequest(
const ImageSource &imageSource,
folly::Future<ImageResponse> &&responseFuture);
ImageRequest();
@ -62,8 +62,7 @@ public:
*/
folly::Future<ImageResponse> getResponseFuture() const;
private:
private:
/*
* Mutext to protect an access to the future.
*/
@ -82,7 +81,7 @@ private:
/*
* Indicates that the object was moved and hence cannot be used anymore.
*/
bool moved_ {false};
bool moved_{false};
};
} // namespace react

View File

@ -10,8 +10,8 @@
namespace facebook {
namespace react {
ImageResponse::ImageResponse(const std::shared_ptr<void> &image):
image_(image) {}
ImageResponse::ImageResponse(const std::shared_ptr<void> &image)
: image_(image) {}
std::shared_ptr<void> ImageResponse::getImage() const {
return image_;

View File

@ -14,13 +14,12 @@ namespace react {
* Represents retrieved image bitmap and any assotiated platform-specific info.
*/
class ImageResponse final {
public:
public:
ImageResponse(const std::shared_ptr<void> &image);
std::shared_ptr<void> getImage() const;
private:
private:
std::shared_ptr<void> image_;
};

View File

@ -21,7 +21,8 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithImageLoader:(RCTImageLoader *)imageLoader;
- (facebook::react::ImageRequest)requestImage:(const facebook::react::ImageSource &)imageSource;
- (facebook::react::ImageRequest)requestImage:
(const facebook::react::ImageSource &)imageSource;
@end

View File

@ -7,28 +7,39 @@
#import <UIKit/UIKit.h>
#import <fabric/imagemanager/primitives.h>
#import <React/RCTImageLoader.h>
#import <fabric/imagemanager/primitives.h>
using namespace facebook::react;
inline static RCTResizeMode RCTResizeModeFromImageResizeMode(ImageResizeMode imageResizeMode) {
inline static RCTResizeMode RCTResizeModeFromImageResizeMode(
ImageResizeMode imageResizeMode) {
switch (imageResizeMode) {
case ImageResizeMode::Cover: return RCTResizeModeCover;
case ImageResizeMode::Contain: return RCTResizeModeContain;
case ImageResizeMode::Stretch: return RCTResizeModeStretch;
case ImageResizeMode::Center: return RCTResizeModeCenter;
case ImageResizeMode::Repeat: return RCTResizeModeRepeat;
case ImageResizeMode::Cover:
return RCTResizeModeCover;
case ImageResizeMode::Contain:
return RCTResizeModeContain;
case ImageResizeMode::Stretch:
return RCTResizeModeStretch;
case ImageResizeMode::Center:
return RCTResizeModeCenter;
case ImageResizeMode::Repeat:
return RCTResizeModeRepeat;
}
}
inline std::string toString(const ImageResizeMode &value) {
switch (value) {
case ImageResizeMode::Cover: return "cover";
case ImageResizeMode::Contain: return "contain";
case ImageResizeMode::Stretch: return "stretch";
case ImageResizeMode::Center: return "center";
case ImageResizeMode::Repeat: return "repeat";
case ImageResizeMode::Cover:
return "cover";
case ImageResizeMode::Contain:
return "contain";
case ImageResizeMode::Stretch:
return "stretch";
case ImageResizeMode::Center:
return "center";
case ImageResizeMode::Repeat:
return "repeat";
}
}
@ -41,7 +52,8 @@ inline static NSURL *NSURLFromImageSource(const ImageSource &imageSource) {
if (!imageSource.bundle.empty()) {
NSString *bundle = [NSString stringWithCString:imageSource.bundle.c_str()
encoding:NSASCIIStringEncoding];
urlString = [NSString stringWithFormat:@"%@.bundle/%@", bundle, urlString];
urlString =
[NSString stringWithFormat:@"%@.bundle/%@", bundle, urlString];
}
NSURL *url = [[NSURL alloc] initWithString:urlString];
@ -53,7 +65,8 @@ inline static NSURL *NSURLFromImageSource(const ImageSource &imageSource) {
if ([urlString rangeOfString:@":"].location != NSNotFound) {
// The URL has a scheme.
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
urlString = [urlString
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
url = [NSURL URLWithString:urlString];
return url;
}
@ -67,20 +80,21 @@ inline static NSURL *NSURLFromImageSource(const ImageSource &imageSource) {
} else {
if (![urlString isAbsolutePath]) {
// Assume it's a resource path.
urlString = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:urlString];
urlString = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:urlString];
}
}
url = [NSURL fileURLWithPath:urlString];
return url;
}
@catch (__unused NSException *exception) {
} @catch (__unused NSException *exception) {
return nil;
}
}
inline static NSURLRequest *NSURLRequestFromImageSource(const ImageSource &imageSource) {
inline static NSURLRequest *NSURLRequestFromImageSource(
const ImageSource &imageSource) {
NSURL *url = NSURLFromImageSource(imageSource);
if (!url) {

View File

@ -16,24 +16,17 @@ namespace facebook {
namespace react {
class ImageSource {
public:
enum class Type { Invalid, Remote, Local };
public:
enum class Type {
Invalid,
Remote,
Local
};
Type type {};
std::string uri {};
std::string bundle {};
Float scale {3};
Size size {0};
Type type{};
std::string uri{};
std::string bundle{};
Float scale{3};
Size size{0};
bool operator==(const ImageSource &rhs) const {
return
std::tie(this->type, this->uri) ==
std::tie(rhs.type, rhs.uri);
return std::tie(this->type, this->uri) == std::tie(rhs.type, rhs.uri);
}
bool operator!=(const ImageSource &rhs) const {