From ee7640a9c20394e5b7c6a6409642fc813eb9563d Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Mon, 4 Mar 2019 16:18:51 -0800 Subject: [PATCH 1/5] Add Yoga support to ASButtonNode --- Source/ASButtonNode.mm | 188 +++++++++++++++++++++++++++++++---------- 1 file changed, 143 insertions(+), 45 deletions(-) diff --git a/Source/ASButtonNode.mm b/Source/ASButtonNode.mm index 5ec1f2371..5466558c9 100644 --- a/Source/ASButtonNode.mm +++ b/Source/ASButtonNode.mm @@ -8,7 +8,10 @@ // #import +#import +#import #import +#import #import #import #import @@ -18,6 +21,22 @@ #import #import +static void ASButtonNodeResolveHorizontalAlignmentForStyle(unowned ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASHorizontalAlignment _horizontalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { + if (_direction == ASStackLayoutDirectionHorizontal) { + style.justifyContent = justifyContent(_horizontalAlignment, _justifyContent); + } else { + style.alignItems = alignment(_horizontalAlignment, _alignItems); + } +} + +static void ASButtonNodeResolveVerticalAlignmentForStyle(unowned ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASVerticalAlignment _verticalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { + if (_direction == ASStackLayoutDirectionHorizontal) { + style.alignItems = alignment(_verticalAlignment, _alignItems); + } else { + style.justifyContent = justifyContent(_verticalAlignment, _justifyContent); + } +} + @interface ASButtonNode () { NSAttributedString *_normalAttributedTitle; @@ -53,6 +72,8 @@ @implementation ASButtonNode @synthesize imageNode = _imageNode; @synthesize backgroundImageNode = _backgroundImageNode; +#pragma mark - Lifecycle + - (instancetype)init { if (self = [super init]) { @@ -65,6 +86,8 @@ - (instancetype)init _contentEdgeInsets = UIEdgeInsetsZero; _imageAlignment = ASButtonNodeImageAlignmentBeginning; self.accessibilityTraits = self.defaultAccessibilityTraits; + + [self updateYogaLayoutIfNeeded]; } return self; } @@ -84,6 +107,8 @@ - (ASTextNode *)titleNode return _titleNode; } +#pragma mark - Public Getter + - (ASImageNode *)imageNode { ASLockScopeSelf(); @@ -172,6 +197,7 @@ - (void)updateImage _imageNode.image = newImage; [self unlock]; + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; return; } @@ -202,6 +228,7 @@ - (void)updateTitle [self unlock]; self.accessibilityLabel = self.defaultAccessibilityLabel; + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; return; } @@ -229,7 +256,8 @@ - (void)updateBackgroundImage if ((_backgroundImageNode != nil || newImage != nil) && newImage != self.backgroundImageNode.image) { _backgroundImageNode.image = newImage; [self unlock]; - + + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; return; } @@ -246,6 +274,7 @@ - (CGFloat)contentSpacing - (void)setContentSpacing:(CGFloat)contentSpacing { if (ASLockedSelfCompareAssign(_contentSpacing, contentSpacing)) { + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; } } @@ -259,6 +288,7 @@ - (BOOL)laysOutHorizontally - (void)setLaysOutHorizontally:(BOOL)laysOutHorizontally { if (ASLockedSelfCompareAssign(_laysOutHorizontally, laysOutHorizontally)) { + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; } } @@ -496,50 +526,6 @@ - (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state [self updateBackgroundImage]; } -- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize -{ - UIEdgeInsets contentEdgeInsets; - ASButtonNodeImageAlignment imageAlignment; - ASLayoutSpec *spec; - ASStackLayoutSpec *stack = [[ASStackLayoutSpec alloc] init]; - { - ASLockScopeSelf(); - stack.direction = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; - stack.spacing = _contentSpacing; - stack.horizontalAlignment = _contentHorizontalAlignment; - stack.verticalAlignment = _contentVerticalAlignment; - - contentEdgeInsets = _contentEdgeInsets; - imageAlignment = _imageAlignment; - } - - NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; - if (_imageNode.image) { - [children addObject:_imageNode]; - } - - if (_titleNode.attributedText.length > 0) { - if (imageAlignment == ASButtonNodeImageAlignmentBeginning) { - [children addObject:_titleNode]; - } else { - [children insertObject:_titleNode atIndex:0]; - } - } - - stack.children = children; - - spec = stack; - - if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, contentEdgeInsets) == NO) { - spec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:contentEdgeInsets child:spec]; - } - - if (_backgroundImageNode.image) { - spec = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:spec background:_backgroundImageNode]; - } - - return spec; -} - (NSString *)defaultAccessibilityLabel { @@ -553,6 +539,118 @@ - (UIAccessibilityTraits)defaultAccessibilityTraits : (UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled); } +#pragma mark - Layout + +#if !YOGA +- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize +{ + UIEdgeInsets contentEdgeInsets; + ASButtonNodeImageAlignment imageAlignment; + ASLayoutSpec *spec; + ASStackLayoutSpec *stack = [[ASStackLayoutSpec alloc] init]; + { + ASLockScopeSelf(); + stack.direction = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; + stack.spacing = _contentSpacing; + stack.horizontalAlignment = _contentHorizontalAlignment; + stack.verticalAlignment = _contentVerticalAlignment; + + contentEdgeInsets = _contentEdgeInsets; + imageAlignment = _imageAlignment; + } + + NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; + if (_imageNode.image) { + [children addObject:_imageNode]; + } + + if (_titleNode.attributedText.length > 0) { + if (imageAlignment == ASButtonNodeImageAlignmentBeginning) { + [children addObject:_titleNode]; + } else { + [children insertObject:_titleNode atIndex:0]; + } + } + + stack.children = children; + + spec = stack; + + if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, contentEdgeInsets) == NO) { + spec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:contentEdgeInsets child:spec]; + } + + if (_backgroundImageNode.image) { + spec = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:spec background:_backgroundImageNode]; + } + + return spec; +} +#endif + +- (void)updateYogaLayoutIfNeeded +{ +#if YOGA + NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; + { + ASLockScopeSelf(); + + // Build up yoga children for button node again + unowned ASLayoutElementStyle *style = [self _locked_style]; + [style yogaNodeCreateIfNeeded]; + + // Setup stack layout values + style.flexDirection = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; + + // Resolve horizontal and vertical alignment + ASButtonNodeResolveHorizontalAlignmentForStyle(style, style.flexDirection, _contentHorizontalAlignment, style.justifyContent, style.alignItems); + ASButtonNodeResolveVerticalAlignmentForStyle(style, style.flexDirection, _contentVerticalAlignment, style.justifyContent, style.alignItems); + + // Setup new yoga children + if (_imageNode.image != nil) { + [_imageNode.style yogaNodeCreateIfNeeded]; + [children addObject:_imageNode]; + } + + if (_titleNode.attributedText.length > 0) { + [_titleNode.style yogaNodeCreateIfNeeded]; + if (_imageAlignment == ASButtonNodeImageAlignmentBeginning) { + [children addObject:_titleNode]; + } else { + [children insertObject:_titleNode atIndex:0]; + } + } + + // Add spacing between title and button + if (children.count == 2) { + unowned ASLayoutElementStyle *firstChildStyle = children.firstObject.style; + if (_laysOutHorizontally) { + firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, 0, _contentSpacing)); + } else { + firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, _contentSpacing, 0)); + } + } + + // Add padding to button + if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, _contentEdgeInsets) == NO) { + style.padding = ASEdgeInsetsMake(_contentEdgeInsets); + } + + // Add background node + if (_backgroundImageNode.image) { + [_backgroundImageNode.style yogaNodeCreateIfNeeded]; + [children insertObject:_backgroundImageNode atIndex:0]; + + _backgroundImageNode.style.positionType = YGPositionTypeAbsolute; + _backgroundImageNode.style.position = ASEdgeInsetsMake(UIEdgeInsetsZero); + } + } + + // Update new children + [self setYogaChildren:children]; +#endif +} + - (void)layout { [super layout]; From 17979974841b685f907947bf594cc60b4a441ef7 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 7 Mar 2019 09:14:48 -0800 Subject: [PATCH 2/5] Drop unowned ASLayoutElementStyle parameter --- Source/ASButtonNode.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/ASButtonNode.mm b/Source/ASButtonNode.mm index 5466558c9..114d2cdef 100644 --- a/Source/ASButtonNode.mm +++ b/Source/ASButtonNode.mm @@ -21,7 +21,7 @@ #import #import -static void ASButtonNodeResolveHorizontalAlignmentForStyle(unowned ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASHorizontalAlignment _horizontalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { +static void ASButtonNodeResolveHorizontalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASHorizontalAlignment _horizontalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { if (_direction == ASStackLayoutDirectionHorizontal) { style.justifyContent = justifyContent(_horizontalAlignment, _justifyContent); } else { @@ -29,7 +29,7 @@ static void ASButtonNodeResolveHorizontalAlignmentForStyle(unowned ASLayoutEleme } } -static void ASButtonNodeResolveVerticalAlignmentForStyle(unowned ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASVerticalAlignment _verticalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { +static void ASButtonNodeResolveVerticalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASVerticalAlignment _verticalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { if (_direction == ASStackLayoutDirectionHorizontal) { style.alignItems = alignment(_verticalAlignment, _alignItems); } else { From 05479b3dfdba583c6d90d1f94e268d6199a0ee43 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 7 Mar 2019 09:42:55 -0800 Subject: [PATCH 3/5] Fix access of Yoga properties --- Source/ASButtonNode.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/ASButtonNode.mm b/Source/ASButtonNode.mm index 114d2cdef..19159b08b 100644 --- a/Source/ASButtonNode.mm +++ b/Source/ASButtonNode.mm @@ -21,6 +21,7 @@ #import #import +#if YOGA static void ASButtonNodeResolveHorizontalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASHorizontalAlignment _horizontalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { if (_direction == ASStackLayoutDirectionHorizontal) { style.justifyContent = justifyContent(_horizontalAlignment, _justifyContent); @@ -36,6 +37,7 @@ static void ASButtonNodeResolveVerticalAlignmentForStyle(ASLayoutElementStyle *s style.justifyContent = justifyContent(_verticalAlignment, _justifyContent); } } +#endif @interface ASButtonNode () { From b7caff558f45fb07d1240f5502161cecbd3ee326 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 7 Mar 2019 12:36:35 -0800 Subject: [PATCH 4/5] Move ASButtonNode Yoga logic to Category --- AsyncDisplayKit.xcodeproj/project.pbxproj | 12 +++ Source/ASButtonNode+Private.h | 44 +++++++++ Source/ASButtonNode+Yoga.h | 20 ++++ Source/ASButtonNode+Yoga.mm | 106 ++++++++++++++++++++ Source/ASButtonNode.mm | 112 +--------------------- 5 files changed, 184 insertions(+), 110 deletions(-) create mode 100644 Source/ASButtonNode+Private.h create mode 100644 Source/ASButtonNode+Yoga.h create mode 100644 Source/ASButtonNode+Yoga.mm diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 84d4290de..c3617ea67 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -207,6 +207,9 @@ 9C8898BD1C738BB800D6B02E /* ASTextKitFontSizeAdjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = A32FEDD31C501B6A004F642A /* ASTextKitFontSizeAdjuster.h */; settings = {ATTRIBUTES = (Private, ); }; }; 9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.mm */; }; 9CDC18CD1B910E12004965E2 /* ASLayoutElementPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutElementPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D302F9B2231B07E005739C3 /* ASButtonNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D302F9A2231B07E005739C3 /* ASButtonNode+Private.h */; }; + 9D302F9E2231B373005739C3 /* ASButtonNode+Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D302F9C2231B373005739C3 /* ASButtonNode+Yoga.h */; }; + 9D302F9F2231B373005739C3 /* ASButtonNode+Yoga.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9D302F9D2231B373005739C3 /* ASButtonNode+Yoga.mm */; }; 9D9AA56921E23EE200172C09 /* ASDisplayNode+LayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AA56721E23EE200172C09 /* ASDisplayNode+LayoutSpec.mm */; }; 9D9AA56B21E254B800172C09 /* ASDisplayNode+Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9AA56A21E254B800172C09 /* ASDisplayNode+Yoga.h */; }; 9D9AA56D21E2568500172C09 /* ASDisplayNode+LayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9AA56C21E2568500172C09 /* ASDisplayNode+LayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -777,6 +780,9 @@ 9CDC18CB1B910E12004965E2 /* ASLayoutElementPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementPrivate.h; sourceTree = ""; }; 9CFFC6BF1CCAC73C006A6476 /* ASViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASViewController.mm; sourceTree = ""; }; 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTableNode.mm; sourceTree = ""; }; + 9D302F9A2231B07E005739C3 /* ASButtonNode+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASButtonNode+Private.h"; sourceTree = ""; }; + 9D302F9C2231B373005739C3 /* ASButtonNode+Yoga.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASButtonNode+Yoga.h"; sourceTree = ""; }; + 9D302F9D2231B373005739C3 /* ASButtonNode+Yoga.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASButtonNode+Yoga.mm"; sourceTree = ""; }; 9D9AA56721E23EE200172C09 /* ASDisplayNode+LayoutSpec.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASDisplayNode+LayoutSpec.mm"; sourceTree = ""; }; 9D9AA56A21E254B800172C09 /* ASDisplayNode+Yoga.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Yoga.h"; sourceTree = ""; }; 9D9AA56C21E2568500172C09 /* ASDisplayNode+LayoutSpec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+LayoutSpec.h"; sourceTree = ""; }; @@ -1282,6 +1288,9 @@ 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.mm */, CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */, CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.mm */, + 9D302F9A2231B07E005739C3 /* ASButtonNode+Private.h */, + 9D302F9C2231B373005739C3 /* ASButtonNode+Yoga.h */, + 9D302F9D2231B373005739C3 /* ASButtonNode+Yoga.mm */, ); path = Source; sourceTree = ""; @@ -1926,6 +1935,7 @@ CCA282B81E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.h in Headers */, B35062571B010F070018CF92 /* ASAssert.h in Headers */, CCBBBF5D1EB161760069AA91 /* ASRangeManagingNode.h in Headers */, + 9D302F9B2231B07E005739C3 /* ASButtonNode+Private.h in Headers */, B35062581B010F070018CF92 /* ASAvailability.h in Headers */, 9019FBBF1ED8061D00C45F72 /* ASYogaUtilities.h in Headers */, DE84918D1C8FFF2B003D89E9 /* ASRunLoopQueue.h in Headers */, @@ -1979,6 +1989,7 @@ 34EFC7691B701CE100AD841F /* ASLayoutElement.h in Headers */, 698DFF471E36B7E9002891F1 /* ASLayoutSpecUtilities.h in Headers */, 9C70F20D1CDBE9CB007D6C76 /* ASDefaultPlayButton.h in Headers */, + 9D302F9E2231B373005739C3 /* ASButtonNode+Yoga.h in Headers */, CCCCCCD51EC3EF060087FE10 /* ASTextDebugOption.h in Headers */, CC034A091E60BEB400626263 /* ASDisplayNode+Convenience.h in Headers */, 254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */, @@ -2433,6 +2444,7 @@ CCB1F95A1EFB60A5009C7475 /* ASLog.mm in Sources */, 767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.mm in Sources */, CCEDDDCB200C2AC300FFCD0A /* ASConfigurationInternal.mm in Sources */, + 9D302F9F2231B373005739C3 /* ASButtonNode+Yoga.mm in Sources */, CCCCCCD61EC3EF060087FE10 /* ASTextDebugOption.mm in Sources */, 34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */, B350624E1B010EFD0018CF92 /* ASDisplayNode+AsyncDisplay.mm in Sources */, diff --git a/Source/ASButtonNode+Private.h b/Source/ASButtonNode+Private.h new file mode 100644 index 000000000..aae5a19da --- /dev/null +++ b/Source/ASButtonNode+Private.h @@ -0,0 +1,44 @@ +// +// ASButtonNode+Private.h +// AsyncDisplayKit +// +// Created by Michael Schneider on 3/7/19. +// Copyright © 2019 Pinterest. All rights reserved. +// + +#import +#import +#import +#import + +@interface ASButtonNode() { + NSAttributedString *_normalAttributedTitle; + NSAttributedString *_highlightedAttributedTitle; + NSAttributedString *_selectedAttributedTitle; + NSAttributedString *_selectedHighlightedAttributedTitle; + NSAttributedString *_disabledAttributedTitle; + + UIImage *_normalImage; + UIImage *_highlightedImage; + UIImage *_selectedImage; + UIImage *_selectedHighlightedImage; + UIImage *_disabledImage; + + UIImage *_normalBackgroundImage; + UIImage *_highlightedBackgroundImage; + UIImage *_selectedBackgroundImage; + UIImage *_selectedHighlightedBackgroundImage; + UIImage *_disabledBackgroundImage; + + CGFloat _contentSpacing; + BOOL _laysOutHorizontally; + ASVerticalAlignment _contentVerticalAlignment; + ASHorizontalAlignment _contentHorizontalAlignment; + UIEdgeInsets _contentEdgeInsets; + ASButtonNodeImageAlignment _imageAlignment; + ASTextNode *_titleNode; + ASImageNode *_imageNode; + ASImageNode *_backgroundImageNode; +} + +@end diff --git a/Source/ASButtonNode+Yoga.h b/Source/ASButtonNode+Yoga.h new file mode 100644 index 000000000..1acf6ba64 --- /dev/null +++ b/Source/ASButtonNode+Yoga.h @@ -0,0 +1,20 @@ +// +// ASButtonNode+Yoga.h +// AsyncDisplayKit +// +// Created by Michael Schneider on 3/7/19. +// Copyright © 2019 Pinterest. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ASButtonNode (Yoga) + +- (void)updateYogaLayoutIfNeeded; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/ASButtonNode+Yoga.mm b/Source/ASButtonNode+Yoga.mm new file mode 100644 index 000000000..751a186b3 --- /dev/null +++ b/Source/ASButtonNode+Yoga.mm @@ -0,0 +1,106 @@ +// +// ASButtonNode+Yoga.m +// AsyncDisplayKit +// +// Created by Michael Schneider on 3/7/19. +// Copyright © 2019 Pinterest. All rights reserved. +// + +#import +#import "ASButtonNode+Yoga.h" +#import +#import +#import +#import + +#if YOGA +static void ASButtonNodeResolveHorizontalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASHorizontalAlignment _horizontalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { + if (_direction == ASStackLayoutDirectionHorizontal) { + style.justifyContent = justifyContent(_horizontalAlignment, _justifyContent); + } else { + style.alignItems = alignment(_horizontalAlignment, _alignItems); + } +} + +static void ASButtonNodeResolveVerticalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASVerticalAlignment _verticalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { + if (_direction == ASStackLayoutDirectionHorizontal) { + style.alignItems = alignment(_verticalAlignment, _alignItems); + } else { + style.justifyContent = justifyContent(_verticalAlignment, _justifyContent); + } +} + +@implementation ASButtonNode (Yoga) + +- (void)updateYogaLayoutIfNeeded +{ + NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; + { + ASLockScopeSelf(); + + // Build up yoga children for button node again + unowned ASLayoutElementStyle *style = [self _locked_style]; + [style yogaNodeCreateIfNeeded]; + + // Setup stack layout values + style.flexDirection = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; + + // Resolve horizontal and vertical alignment + ASButtonNodeResolveHorizontalAlignmentForStyle(style, style.flexDirection, _contentHorizontalAlignment, style.justifyContent, style.alignItems); + ASButtonNodeResolveVerticalAlignmentForStyle(style, style.flexDirection, _contentVerticalAlignment, style.justifyContent, style.alignItems); + + // Setup new yoga children + if (_imageNode.image != nil) { + [_imageNode.style yogaNodeCreateIfNeeded]; + [children addObject:_imageNode]; + } + + if (_titleNode.attributedText.length > 0) { + [_titleNode.style yogaNodeCreateIfNeeded]; + if (_imageAlignment == ASButtonNodeImageAlignmentBeginning) { + [children addObject:_titleNode]; + } else { + [children insertObject:_titleNode atIndex:0]; + } + } + + // Add spacing between title and button + if (children.count == 2) { + unowned ASLayoutElementStyle *firstChildStyle = children.firstObject.style; + if (_laysOutHorizontally) { + firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, 0, _contentSpacing)); + } else { + firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, _contentSpacing, 0)); + } + } + + // Add padding to button + if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, _contentEdgeInsets) == NO) { + style.padding = ASEdgeInsetsMake(_contentEdgeInsets); + } + + // Add background node + if (_backgroundImageNode.image) { + [_backgroundImageNode.style yogaNodeCreateIfNeeded]; + [children insertObject:_backgroundImageNode atIndex:0]; + + _backgroundImageNode.style.positionType = YGPositionTypeAbsolute; + _backgroundImageNode.style.position = ASEdgeInsetsMake(UIEdgeInsetsZero); + } + } + + // Update new children + [self setYogaChildren:children]; +} + +@end + +#else + +@implementation ASButtonNode (Yoga) + +- (void)updateYogaLayoutIfNeeded {} + +@end + +#endif diff --git a/Source/ASButtonNode.mm b/Source/ASButtonNode.mm index 19159b08b..f91b16c2b 100644 --- a/Source/ASButtonNode.mm +++ b/Source/ASButtonNode.mm @@ -7,61 +7,16 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import -#import -#import +#import +#import #import -#import #import #import #import #import #import -#import -#import #import -#if YOGA -static void ASButtonNodeResolveHorizontalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASHorizontalAlignment _horizontalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { - if (_direction == ASStackLayoutDirectionHorizontal) { - style.justifyContent = justifyContent(_horizontalAlignment, _justifyContent); - } else { - style.alignItems = alignment(_horizontalAlignment, _alignItems); - } -} - -static void ASButtonNodeResolveVerticalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASVerticalAlignment _verticalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { - if (_direction == ASStackLayoutDirectionHorizontal) { - style.alignItems = alignment(_verticalAlignment, _alignItems); - } else { - style.justifyContent = justifyContent(_verticalAlignment, _justifyContent); - } -} -#endif - -@interface ASButtonNode () -{ - NSAttributedString *_normalAttributedTitle; - NSAttributedString *_highlightedAttributedTitle; - NSAttributedString *_selectedAttributedTitle; - NSAttributedString *_selectedHighlightedAttributedTitle; - NSAttributedString *_disabledAttributedTitle; - - UIImage *_normalImage; - UIImage *_highlightedImage; - UIImage *_selectedImage; - UIImage *_selectedHighlightedImage; - UIImage *_disabledImage; - - UIImage *_normalBackgroundImage; - UIImage *_highlightedBackgroundImage; - UIImage *_selectedBackgroundImage; - UIImage *_selectedHighlightedBackgroundImage; - UIImage *_disabledBackgroundImage; -} - -@end - @implementation ASButtonNode @synthesize contentSpacing = _contentSpacing; @@ -590,69 +545,6 @@ - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize } #endif -- (void)updateYogaLayoutIfNeeded -{ -#if YOGA - NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; - { - ASLockScopeSelf(); - - // Build up yoga children for button node again - unowned ASLayoutElementStyle *style = [self _locked_style]; - [style yogaNodeCreateIfNeeded]; - - // Setup stack layout values - style.flexDirection = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; - - // Resolve horizontal and vertical alignment - ASButtonNodeResolveHorizontalAlignmentForStyle(style, style.flexDirection, _contentHorizontalAlignment, style.justifyContent, style.alignItems); - ASButtonNodeResolveVerticalAlignmentForStyle(style, style.flexDirection, _contentVerticalAlignment, style.justifyContent, style.alignItems); - - // Setup new yoga children - if (_imageNode.image != nil) { - [_imageNode.style yogaNodeCreateIfNeeded]; - [children addObject:_imageNode]; - } - - if (_titleNode.attributedText.length > 0) { - [_titleNode.style yogaNodeCreateIfNeeded]; - if (_imageAlignment == ASButtonNodeImageAlignmentBeginning) { - [children addObject:_titleNode]; - } else { - [children insertObject:_titleNode atIndex:0]; - } - } - - // Add spacing between title and button - if (children.count == 2) { - unowned ASLayoutElementStyle *firstChildStyle = children.firstObject.style; - if (_laysOutHorizontally) { - firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, 0, _contentSpacing)); - } else { - firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, _contentSpacing, 0)); - } - } - - // Add padding to button - if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, _contentEdgeInsets) == NO) { - style.padding = ASEdgeInsetsMake(_contentEdgeInsets); - } - - // Add background node - if (_backgroundImageNode.image) { - [_backgroundImageNode.style yogaNodeCreateIfNeeded]; - [children insertObject:_backgroundImageNode atIndex:0]; - - _backgroundImageNode.style.positionType = YGPositionTypeAbsolute; - _backgroundImageNode.style.position = ASEdgeInsetsMake(UIEdgeInsetsZero); - } - } - - // Update new children - [self setYogaChildren:children]; -#endif -} - - (void)layout { [super layout]; From c47cecaeac5166c97f441bbdefa3b0dd788ca85a Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Fri, 8 Mar 2019 07:26:11 -0800 Subject: [PATCH 5/5] Update header --- Source/ASButtonNode+Private.h | 6 +++--- Source/ASButtonNode+Yoga.h | 6 +++--- Source/ASButtonNode+Yoga.mm | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Source/ASButtonNode+Private.h b/Source/ASButtonNode+Private.h index aae5a19da..2ecc89446 100644 --- a/Source/ASButtonNode+Private.h +++ b/Source/ASButtonNode+Private.h @@ -1,9 +1,9 @@ // // ASButtonNode+Private.h -// AsyncDisplayKit +// Texture // -// Created by Michael Schneider on 3/7/19. -// Copyright © 2019 Pinterest. All rights reserved. +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // #import diff --git a/Source/ASButtonNode+Yoga.h b/Source/ASButtonNode+Yoga.h index 1acf6ba64..4fddc9df3 100644 --- a/Source/ASButtonNode+Yoga.h +++ b/Source/ASButtonNode+Yoga.h @@ -1,9 +1,9 @@ // // ASButtonNode+Yoga.h -// AsyncDisplayKit +// Texture // -// Created by Michael Schneider on 3/7/19. -// Copyright © 2019 Pinterest. All rights reserved. +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // #import diff --git a/Source/ASButtonNode+Yoga.mm b/Source/ASButtonNode+Yoga.mm index 751a186b3..466647556 100644 --- a/Source/ASButtonNode+Yoga.mm +++ b/Source/ASButtonNode+Yoga.mm @@ -1,9 +1,9 @@ // -// ASButtonNode+Yoga.m -// AsyncDisplayKit +// ASButtonNode+Yoga.mm +// Texture // -// Created by Michael Schneider on 3/7/19. -// Copyright © 2019 Pinterest. All rights reserved. +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // #import