mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-05-16 16:01:00 +08:00
continued development
This commit is contained in:
@@ -44,19 +44,24 @@ static BOOL __shouldVisualizeLayoutSpecs = NO;
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
ASInsetLayoutSpec *insetSpec = [[ASInsetLayoutSpec alloc] init];
|
||||
ASInsetLayoutSpec *insetSpec = [[ASInsetLayoutSpec alloc] init]; // FIXME: need to auto pass properties to children
|
||||
insetSpec.neverShouldVisualize = YES;
|
||||
self.layoutSpec.neverShouldVisualize = YES;
|
||||
UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 10);
|
||||
|
||||
// propogate child's layoutSpec properties to the inset that we are adding
|
||||
insetSpec.flexGrow = _layoutSpec.flexGrow;
|
||||
insetSpec.flexShrink = _layoutSpec.flexShrink;
|
||||
insetSpec.alignSelf = _layoutSpec.alignSelf;
|
||||
|
||||
insetSpec.insets = insets;
|
||||
insetSpec.child = self.layoutSpec;
|
||||
return insetSpec;
|
||||
return self.layoutSpec;
|
||||
}
|
||||
|
||||
- (void)layoutMagicNodeTapped:(UIGestureRecognizer *)sender
|
||||
{
|
||||
NSLog(@"SELECTED: %@", self);
|
||||
[[ASLayoutableInspectorNode sharedInstance] setLayoutableToEdit:self];
|
||||
[[ASLayoutableInspectorNode sharedInstance] setLayoutableToEdit:self.layoutSpec];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,9 +8,17 @@
|
||||
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@interface ASLayoutableInspectorNode : ASDisplayNode
|
||||
@protocol ASLayoutableInspectorNodeDelegate <NSObject>
|
||||
|
||||
- (void)shouldShowMasterSplitViewController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface ASLayoutableInspectorNode : ASDisplayNode <UISplitViewControllerDelegate>
|
||||
|
||||
@property (nonatomic, strong) id<ASLayoutable> layoutableToEdit;
|
||||
@property (nonatomic, strong) id<ASLayoutableInspectorNodeDelegate> delegate;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
|
||||
@@ -8,17 +8,34 @@
|
||||
|
||||
#import "ASLayoutableInspectorNode.h"
|
||||
#import "ASDisplayNode+Beta.h"
|
||||
#import "ASLayoutSpec+Debug.h"
|
||||
|
||||
|
||||
@interface ASLayoutableInspectorNode ()
|
||||
@end
|
||||
|
||||
@implementation ASLayoutableInspectorNode
|
||||
{
|
||||
ASTextNode *_textNode;
|
||||
|
||||
// Navigate layout hierarchy
|
||||
ASButtonNode *_parentNodeNavBtn;
|
||||
ASButtonNode *_siblingNodeRightNavBtn;
|
||||
ASButtonNode *_siblingNodeLefttNavBtn;
|
||||
ASButtonNode *_childNodeNavBtn;
|
||||
|
||||
// Item properties
|
||||
ASTextNode *_itemPropertiesSectionTitle;
|
||||
ASTextNode *_itemDescription;
|
||||
ASButtonNode *_itemBackgroundColorBtn;
|
||||
|
||||
// <Layoutable> properites
|
||||
ASTextNode *_layoutablePropertiesSectionTitle;
|
||||
ASButtonNode *_flexGrowBtn;
|
||||
ASButtonNode *_flexShrinkBtn;
|
||||
ASButtonNode *_flexBasisBtn;
|
||||
ASButtonNode *_alignSelfBtn;
|
||||
ASButtonNode *_spacingBeforeBtn;
|
||||
ASButtonNode *_spacingAfterBtn;
|
||||
ASButtonNode *_alignItemsBtn;
|
||||
|
||||
ASTextNode *_flexGrowValue;
|
||||
ASTextNode *_flexShrinkValue;
|
||||
@@ -27,10 +44,13 @@
|
||||
ASTextNode *_spacingBeforeValue;
|
||||
ASTextNode *_spacingAfterValue;
|
||||
|
||||
// ASTextNode
|
||||
ASDisplayNode *_slider;
|
||||
|
||||
// LayoutSpec properties
|
||||
ASTextNode *_layoutSpecPropertiesSectionTitle;
|
||||
|
||||
|
||||
|
||||
// BOOL isPresented;
|
||||
// BOOL isAnimating;
|
||||
|
||||
}
|
||||
|
||||
@@ -54,126 +74,172 @@
|
||||
|
||||
self.usesImplicitHierarchyManagement = YES;
|
||||
|
||||
_textNode = [[ASTextNode alloc] init];
|
||||
// _tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStyleGrouped];
|
||||
// _tableNode.dataSource = self;
|
||||
|
||||
// self.backgroundColor = [UIColor colorWithRed:40/255.0 green:43/255.0 blue:53/255.0 alpha:1.0];
|
||||
|
||||
_itemDescription = [[ASTextNode alloc] init];
|
||||
_layoutablePropertiesSectionTitle = [[ASTextNode alloc] init];
|
||||
_layoutablePropertiesSectionTitle.attributedString = [self attributedStringFromString:@"<Layoutable> Properties"];
|
||||
_layoutSpecPropertiesSectionTitle = [[ASTextNode alloc] init];
|
||||
_layoutSpecPropertiesSectionTitle.attributedString = [self attributedStringFromString:@"<LayoutSpec> Properties"];
|
||||
|
||||
_flexGrowBtn = [self makeBtnNodeWithTitle:@"flexGrow"];
|
||||
[_flexGrowBtn addTarget:self action:@selector(setFlexGrowValue:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
_flexGrowValue = [[ASTextNode alloc] init];
|
||||
|
||||
_flexShrinkBtn = [self makeBtnNodeWithTitle:@"flexShrink"];
|
||||
// [_flexGrowBtn addTarget:self action:@selector(setFlexShrinkValue:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
[_flexShrinkBtn addTarget:self action:@selector(setFlexShrinkValue:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
_flexShrinkValue = [[ASTextNode alloc] init];
|
||||
|
||||
_flexBasisBtn = [self makeBtnNodeWithTitle:@"flexBasis"];
|
||||
_flexBasisValue = [[ASTextNode alloc] init];
|
||||
|
||||
_alignSelfBtn = [self makeBtnNodeWithTitle:@"alignSelf"];
|
||||
[_alignSelfBtn addTarget:self action:@selector(setAlignSelfValue:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
|
||||
_alignItemsBtn = [self makeBtnNodeWithTitle:@"alignItems"];
|
||||
[_alignItemsBtn addTarget:self action:@selector(setAlignItemsValue:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
|
||||
_itemBackgroundColorBtn = [self makeBtnNodeWithTitle:@"node color"];
|
||||
[_itemBackgroundColorBtn addTarget:self action:@selector(changeColor:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
|
||||
_parentNodeNavBtn = [self makeBtnNodeWithTitle:@"parent node"];
|
||||
_siblingNodeRightNavBtn = [self makeBtnNodeWithTitle:@"sibling node"];
|
||||
_siblingNodeLefttNavBtn = [self makeBtnNodeWithTitle:@"sibling node"];
|
||||
_childNodeNavBtn = [self makeBtnNodeWithTitle:@"child node"];
|
||||
|
||||
_slider = [[ASDisplayNode alloc] initWithViewBlock:^UIView * _Nonnull{
|
||||
UISlider *slider = [[UISlider alloc] init];
|
||||
return slider;
|
||||
}];
|
||||
|
||||
[self setUpInspectorForLayoutableType];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layout
|
||||
{
|
||||
[super layout];
|
||||
|
||||
// _tableNode.frame = self.bounds;
|
||||
}
|
||||
|
||||
- (ASButtonNode *)makeBtnNodeWithTitle:(NSString *)title
|
||||
{
|
||||
UIColor *orangeColor = [UIColor colorWithRed:255/255.0 green:181/255.0 blue:68/255.0 alpha:1];
|
||||
UIImage *orangeStretchBtnImg = [ASLayoutableInspectorNode imageForButtonWithBackgroundColor:orangeColor
|
||||
borderColor:[UIColor whiteColor]
|
||||
borderWidth:3];
|
||||
UIImage *greyStretchBtnImg = [ASLayoutableInspectorNode imageForButtonWithBackgroundColor:[UIColor grayColor]
|
||||
UIImage *greyStretchBtnImg = [ASLayoutableInspectorNode imageForButtonWithBackgroundColor:[UIColor lightGrayColor]
|
||||
borderColor:[UIColor whiteColor]
|
||||
borderWidth:3];
|
||||
UIImage *clearStretchBtnImg = [ASLayoutableInspectorNode imageForButtonWithBackgroundColor:[UIColor clearColor]
|
||||
borderColor:[UIColor whiteColor]
|
||||
borderWidth:3];
|
||||
ASButtonNode *btn = [[ASButtonNode alloc] init];
|
||||
btn.contentEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5);
|
||||
[btn setAttributedTitle:[self attributedStringFromString:title] forState:ASControlStateNormal];
|
||||
[btn setBackgroundImage:greyStretchBtnImg forState:ASControlStateNormal];
|
||||
[btn setBackgroundImage:clearStretchBtnImg forState:ASControlStateNormal];
|
||||
[btn setBackgroundImage:orangeStretchBtnImg forState:ASControlStateSelected];
|
||||
|
||||
[btn setBackgroundImage:greyStretchBtnImg forState:ASControlStateDisabled];
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
- (void)setLayoutableToEdit:(id<ASLayoutable>)layoutableToEdit
|
||||
{
|
||||
// show master split view controller
|
||||
// self.supernode.splitViewController.viewControllers[1]
|
||||
|
||||
[self.delegate shouldShowMasterSplitViewController];
|
||||
|
||||
if (_layoutableToEdit != layoutableToEdit) {
|
||||
_layoutableToEdit = layoutableToEdit;
|
||||
_textNode.attributedString = [self attributedStringFromLayoutable:_layoutableToEdit];
|
||||
self.backgroundColor = [UIColor colorWithRed:40/255.0 green:43/255.0 blue:53/255.0 alpha:1.0];
|
||||
_itemDescription.attributedString = [self attributedStringFromLayoutable:_layoutableToEdit];
|
||||
|
||||
[self updateInspectorViewWithLayoutable:layoutableToEdit];
|
||||
[self updateInspectorViewWithLayoutable];
|
||||
[self setUpInspectorForLayoutableType];
|
||||
|
||||
UIWindow *keyWindow = [[NSClassFromString(@"UIApplication") sharedApplication] keyWindow];
|
||||
CGSize windowSize = keyWindow.bounds.size;
|
||||
// UIWindow *keyWindow = [[NSClassFromString(@"UIApplication") sharedApplication] keyWindow];
|
||||
// CGSize windowSize = keyWindow.bounds.size;
|
||||
|
||||
if (layoutableToEdit) {
|
||||
|
||||
_textNode.attributedString = [self attributedStringFromLayoutable:_layoutableToEdit];
|
||||
|
||||
// present inspectorView
|
||||
self.frame = CGRectMake(0, windowSize.height, windowSize.width, windowSize.height / 3.0);
|
||||
[self measureWithSizeRange:ASSizeRangeMakeExactSize(self.bounds.size)];
|
||||
[keyWindow addSubnode:self];
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
CGRect rect = self.frame;
|
||||
rect.origin.y -= rect.size.height;
|
||||
self.frame = rect;
|
||||
}];
|
||||
|
||||
} else {
|
||||
|
||||
// hide inspector
|
||||
CGRect finalRect = CGRectMake(0, windowSize.height, windowSize.width, windowSize.height / 3.0);
|
||||
[keyWindow addSubnode:self];
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
self.frame = finalRect;
|
||||
} completion:^(BOOL finished) {
|
||||
[self removeFromSupernode];
|
||||
}];
|
||||
// _nodeDescription.attributedString = [self attributedStringFromLayoutable:_layoutableToEdit];
|
||||
//
|
||||
// // present inspectorView
|
||||
// self.frame = CGRectMake(0, windowSize.height, windowSize.width, windowSize.height / 3.0);
|
||||
// [self measureWithSizeRange:ASSizeRangeMakeExactSize(self.bounds.size)];
|
||||
// [keyWindow addSubnode:self];
|
||||
// [UIView animateWithDuration:0.2 animations:^{
|
||||
// CGRect rect = self.frame;
|
||||
// rect.origin.y -= rect.size.height;
|
||||
// self.frame = rect;
|
||||
// }];
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// // hide inspector
|
||||
// CGRect finalRect = CGRectMake(0, windowSize.height, windowSize.width, windowSize.height / 3.0);
|
||||
// [keyWindow addSubnode:self];
|
||||
// [UIView animateWithDuration:0.2 animations:^{
|
||||
// self.frame = finalRect;
|
||||
// } completion:^(BOOL finished) {
|
||||
// [self removeFromSupernode];
|
||||
// }];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateInspectorViewWithLayoutable:(id<ASLayoutable>)layoutableToEdit
|
||||
{
|
||||
_flexGrowBtn.selected = layoutableToEdit.flexGrow;
|
||||
_flexGrowValue.attributedString = [self attributedStringFromString: (_flexGrowBtn.selected) ? @"YES" : @"NO"];
|
||||
|
||||
_flexShrinkBtn.selected = layoutableToEdit.flexShrink;
|
||||
_flexShrinkValue.attributedString = [self attributedStringFromString: (_flexShrinkBtn.selected) ? @"YES" : @"NO"];
|
||||
|
||||
_flexBasisBtn.selected = layoutableToEdit.flexShrink;
|
||||
_flexBasisValue.attributedString = [self attributedStringFromString: (_flexBasisBtn.selected) ? @"YES" : @"NO"];
|
||||
|
||||
// _flexBasisBtn.selected = layoutableToEdit.flexBasis;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
// FIXME: way to manually disable on a sublayout tree
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
ASStackLayoutSpec *horizontalStackNav = [ASStackLayoutSpec horizontalStackLayoutSpec];
|
||||
horizontalStackNav.flexGrow = YES;
|
||||
horizontalStackNav.children = @[_siblingNodeLefttNavBtn, _siblingNodeRightNavBtn];
|
||||
|
||||
ASStackLayoutSpec *horizontalStack = [ASStackLayoutSpec horizontalStackLayoutSpec];
|
||||
horizontalStack.children = @[_flexGrowBtn, _flexGrowValue];
|
||||
_flexGrowValue.alignSelf = ASStackLayoutAlignSelfEnd; // FIXME: framework give a warning if you use ASAlignmentBottom!!!!!
|
||||
_flexGrowBtn.flexShrink = NO;
|
||||
horizontalStack.flexGrow = YES;
|
||||
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
|
||||
spacer.flexGrow = YES;
|
||||
horizontalStack.children = @[_flexGrowBtn, spacer, _flexGrowValue];
|
||||
_flexGrowValue.alignSelf = ASStackLayoutAlignSelfEnd; // FIXME: framework give a warning if you use ASAlignmentBottom!!!!!
|
||||
|
||||
ASStackLayoutSpec *horizontalStack2 = [ASStackLayoutSpec horizontalStackLayoutSpec];
|
||||
horizontalStack2.children = @[_flexShrinkBtn, _flexShrinkValue];
|
||||
horizontalStack2.flexGrow = YES;
|
||||
horizontalStack2.children = @[_flexShrinkBtn, spacer, _flexShrinkValue];
|
||||
_flexShrinkValue.alignSelf = ASStackLayoutAlignSelfEnd;
|
||||
|
||||
ASStackLayoutSpec *horizontalStack3 = [ASStackLayoutSpec horizontalStackLayoutSpec];
|
||||
horizontalStack3.children = @[_flexBasisBtn, _flexBasisValue];
|
||||
horizontalStack3.flexGrow = YES;
|
||||
horizontalStack3.children = @[_flexBasisBtn, spacer, _flexBasisValue];
|
||||
_flexBasisValue.alignSelf = ASStackLayoutAlignSelfEnd;
|
||||
|
||||
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
|
||||
verticalStack.children = @[horizontalStack, horizontalStack2, horizontalStack3];
|
||||
|
||||
ASLayoutSpec *insetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10) child:verticalStack];
|
||||
ASStackLayoutSpec *verticalLayoutableStack = [ASStackLayoutSpec verticalStackLayoutSpec];
|
||||
verticalLayoutableStack.flexGrow = YES;
|
||||
verticalLayoutableStack.spacing = 5;
|
||||
verticalLayoutableStack.children = @[_slider, _parentNodeNavBtn, horizontalStackNav, _childNodeNavBtn, _itemDescription, _itemBackgroundColorBtn, _layoutablePropertiesSectionTitle, horizontalStack, horizontalStack2, horizontalStack3, _alignSelfBtn, _alignItemsBtn, _layoutSpecPropertiesSectionTitle];
|
||||
verticalLayoutableStack.alignItems = ASStackLayoutAlignItemsStretch; // stretch headerStack to fill horizontal space
|
||||
|
||||
ASLayoutSpec *insetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(100, 10, 10, 10) child:verticalLayoutableStack];
|
||||
insetSpec.flexGrow = YES;
|
||||
return insetSpec;
|
||||
}
|
||||
|
||||
- (NSAttributedString *)attributedStringFromLayoutable:(id<ASLayoutable>)layoutable
|
||||
{
|
||||
if ([layoutable isKindOfClass:[ASLayoutSpec class]]) {
|
||||
return [self attributedStringFromString:[(ASLayoutSpec *)layoutable asciiArtString]];
|
||||
return [self attributedStringFromString:[(ASLayoutSpec *)layoutable description]];
|
||||
} else if ([layoutable isKindOfClass:[ASDisplayNode class]]) {
|
||||
return [self attributedStringFromString:[(ASControlNode *)layoutable asciiArtString]];
|
||||
return [self attributedStringFromString:[(ASControlNode *)layoutable description]];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
@@ -210,24 +276,144 @@
|
||||
return [btnImage stretchableImageWithLeftCapWidth:CORNER_RADIUS topCapHeight:CORNER_RADIUS];
|
||||
}
|
||||
|
||||
- (void)updateInspectorViewWithLayoutable
|
||||
{
|
||||
if ([self node]) {
|
||||
UIColor *nodeBackgroundColor = [[self node] backgroundColor];
|
||||
UIImage *colorBtnImg = [ASLayoutableInspectorNode imageForButtonWithBackgroundColor:nodeBackgroundColor
|
||||
borderColor:[UIColor whiteColor]
|
||||
borderWidth:3];
|
||||
[_itemBackgroundColorBtn setBackgroundImage:colorBtnImg forState:ASControlStateNormal];
|
||||
}
|
||||
|
||||
|
||||
// _alignSelfBtn.selected = YES;
|
||||
// NSUInteger alignSelfValue = [(ASDisplayNode *)self.layoutableToEdit alignSelf];
|
||||
// NSString *newTitle = [@"alignSelf:" stringByAppendingString:[self typeDisplayName:alignSelfValue]];
|
||||
// [_alignSelfBtn setAttributedTitle:[self attributedStringFromString:newTitle] forState:ASControlStateNormal];
|
||||
|
||||
_alignSelfBtn.selected = YES;
|
||||
NSUInteger alignSelfValue = [self.layoutableToEdit alignSelf];
|
||||
NSString *newTitle = [@"alignSelf:" stringByAppendingString:[self typeDisplayName:alignSelfValue]];
|
||||
[_alignSelfBtn setAttributedTitle:[self attributedStringFromString:newTitle] forState:ASControlStateNormal];
|
||||
|
||||
// _alignItemsBtn.selected = YES;
|
||||
// if ([[self layoutSpec] isKindOfClass:[ASStackLayoutSpec class]]) {
|
||||
// NSUInteger alignItemsValue = [(ASStackLayoutSpec *)[self layoutSpec] alignItems];
|
||||
// newTitle = [@"alignItems:" stringByAppendingString:[self typeDisplayNameItems:alignItemsValue]];
|
||||
// [_alignItemsBtn setAttributedTitle:[self attributedStringFromString:newTitle] forState:ASControlStateNormal];
|
||||
// }
|
||||
//
|
||||
// if ([layoutable isKindOfClass:[ASLayoutSpec class]]) {
|
||||
// return [self attributedStringFromString:[(ASLayoutSpec *)layoutable asciiArtString]];
|
||||
// } else if ([layoutable isKindOfClass:[ASDisplayNode class]]) {
|
||||
// return [self attributedStringFromString:[(ASControlNode *)layoutable asciiArtString]];
|
||||
// }
|
||||
|
||||
_flexGrowBtn.selected = [self.layoutableToEdit flexGrow];
|
||||
_flexGrowValue.attributedString = [self attributedStringFromString: (_flexGrowBtn.selected) ? @"YES" : @"NO"];
|
||||
|
||||
_flexShrinkBtn.selected = self.layoutableToEdit.flexShrink;
|
||||
_flexShrinkValue.attributedString = [self attributedStringFromString: (_flexShrinkBtn.selected) ? @"YES" : @"NO"];
|
||||
|
||||
// _flexBasisBtn.selected = self.layoutableToEdit.flexShrink;
|
||||
// _flexBasisValue.attributedString = [self attributedStringFromString: (_flexBasisBtn.selected) ? @"YES" : @"NO"];
|
||||
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)setFlexGrowValue:(ASButtonNode *)sender
|
||||
{
|
||||
[sender setSelected:!sender.isSelected]; // FIXME: fix ASControlNode documentation that this is automatic - unlike highlighted, it is up to the application to decide when a button should be selected or not. Selected is a more persistant thing and highlighted is for the moment, like as a user has a finger on it,
|
||||
|
||||
if ([self.layoutableToEdit isKindOfClass:[ASLayoutSpec class]]) {
|
||||
[(ASLayoutSpec *)self.layoutableToEdit setFlexGrow:!sender.isSelected];
|
||||
[(ASLayoutSpec *)self.layoutableToEdit setFlexGrow:sender.isSelected];
|
||||
|
||||
} else if ([self.layoutableToEdit isKindOfClass:[ASDisplayNode class]]) {
|
||||
[(ASControlNode *)self.layoutableToEdit setFlexGrow:!sender.isSelected];
|
||||
[(ASDisplayNode *)self.layoutableToEdit setFlexGrow:sender.isSelected];
|
||||
}
|
||||
[self updateInspectorViewWithLayoutable:self.layoutableToEdit];
|
||||
[self updateInspectorViewWithLayoutable];
|
||||
}
|
||||
|
||||
- (void)setFlexShrinkValue:(ASButtonNode *)sender
|
||||
{
|
||||
[sender setSelected:!sender.isSelected]; // FIXME: fix ASControlNode documentation that this is automatic - unlike highlighted, it is up to the application to decide when a button should be selected or not. Selected is a more persistant thing and highlighted is for the moment, like as a user has a finger on it,
|
||||
|
||||
[(ASDisplayNode *)self.layoutableToEdit setFlexShrink:sender.isSelected];
|
||||
|
||||
[self updateInspectorViewWithLayoutable];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)typeDisplayNames
|
||||
{
|
||||
return @{@(ASStackLayoutAlignSelfAuto) : @"Auto",
|
||||
@(ASStackLayoutAlignSelfStart) : @"Start",
|
||||
@(ASStackLayoutAlignSelfEnd) : @"End",
|
||||
@(ASStackLayoutAlignSelfCenter) : @"Center",
|
||||
@(ASStackLayoutAlignSelfStretch) : @"Stretch"};
|
||||
}
|
||||
|
||||
- (NSString *)typeDisplayName:(NSUInteger)type
|
||||
{
|
||||
return [[self class] typeDisplayNames][@(type)];
|
||||
}
|
||||
|
||||
- (void)setAlignSelfValue:(ASButtonNode *)sender
|
||||
{
|
||||
NSUInteger nodeAlignSelfValue = [(ASDisplayNode *)self.layoutableToEdit alignSelf];
|
||||
|
||||
NSUInteger nextAlignSelfValue = (nodeAlignSelfValue + 1 <= ASStackLayoutAlignSelfStretch) ? nodeAlignSelfValue + 1 : 0;
|
||||
|
||||
[(ASDisplayNode *)self.layoutableToEdit setAlignSelf:nextAlignSelfValue];
|
||||
[(ASDisplayNode *)self.layoutableToEdit setNeedsLayout];
|
||||
|
||||
[self updateInspectorViewWithLayoutable];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)typeDisplayNamesItems
|
||||
{
|
||||
return @{@(ASStackLayoutAlignItemsBaselineFirst) : @"BaselineFirst",
|
||||
@(ASStackLayoutAlignItemsBaselineLast) : @"BaselineLast",
|
||||
@(ASStackLayoutAlignItemsCenter) : @"Center",
|
||||
@(ASStackLayoutAlignItemsEnd) : @"End",
|
||||
@(ASStackLayoutAlignItemsStart) : @"Start",
|
||||
@(ASStackLayoutAlignItemsStretch) : @"Stretch"};
|
||||
}
|
||||
|
||||
- (NSString *)typeDisplayNameItems:(NSUInteger)type
|
||||
{
|
||||
return [[self class] typeDisplayNamesItems][@(type)];
|
||||
}
|
||||
|
||||
- (void)setAlignItemsValue:(ASButtonNode *)sender
|
||||
{
|
||||
NSUInteger alignItemsValue = [(ASStackLayoutSpec *)[(ASLayoutSpecVisualizerNode *)self.layoutableToEdit layoutSpec] alignItems];
|
||||
|
||||
NSUInteger nextAlignItemsValue = (alignItemsValue + 1 <= ASStackLayoutAlignItemsBaselineLast) ? alignItemsValue + 1 : 0;
|
||||
|
||||
[(ASStackLayoutSpec *)[(ASLayoutSpecVisualizerNode *)self.layoutableToEdit layoutSpec] setAlignItems:nextAlignItemsValue];
|
||||
[(ASLayoutSpecVisualizerNode *)self.layoutableToEdit setNeedsLayout];
|
||||
|
||||
[self updateInspectorViewWithLayoutable];
|
||||
}
|
||||
|
||||
- (void)changeColor:(ASButtonNode *)sender
|
||||
{
|
||||
NSArray *colorArray = @[[UIColor orangeColor],
|
||||
[UIColor redColor],
|
||||
[UIColor greenColor],
|
||||
[UIColor purpleColor]];
|
||||
|
||||
UIColor *nodeBackgroundColor = [(ASDisplayNode *)self.layoutableToEdit backgroundColor];
|
||||
|
||||
NSUInteger colorIndex = [colorArray indexOfObject:nodeBackgroundColor];
|
||||
colorIndex = (colorIndex + 1 < [colorArray count]) ? colorIndex + 1 : 0;
|
||||
|
||||
[(ASDisplayNode *)self.layoutableToEdit setBackgroundColor: [colorArray objectAtIndex:colorIndex]];
|
||||
|
||||
[self updateInspectorViewWithLayoutable];
|
||||
}
|
||||
|
||||
//- (void)setFlexShrinkValue:(ASButtonNode *)sender
|
||||
//{
|
||||
// [sender setSelected:!sender.isSelected]; // FIXME: fix ASControlNode documentation that this is automatic - unlike highlighted, it is up to the application to decide when a button should be selected or not. Selected is a more persistant thing and highlighted is for the moment, like as a user has a finger on it,
|
||||
//
|
||||
// [self.layoutableToEdit setFlexShrink:!sender.isSelected];
|
||||
//}
|
||||
//
|
||||
//- (void)setFlexBasisValue:(ASButtonNode *)sender
|
||||
//{
|
||||
@@ -236,4 +422,71 @@
|
||||
// // FIXME: finish
|
||||
//}
|
||||
|
||||
- (void)setUpInspectorForLayoutableType
|
||||
{
|
||||
[self.layoutableToEdit respondsToSelector:@selector(flexGrow)];
|
||||
|
||||
if (!self.layoutableToEdit) {
|
||||
|
||||
_itemBackgroundColorBtn.enabled = NO;
|
||||
_flexGrowBtn.enabled = NO;
|
||||
_flexShrinkBtn.enabled = NO;
|
||||
_flexBasisBtn.enabled = NO;
|
||||
_alignSelfBtn.enabled = NO;
|
||||
_spacingBeforeBtn.enabled = NO;
|
||||
_spacingAfterBtn.enabled = NO;
|
||||
_alignItemsBtn.enabled = NO;
|
||||
|
||||
} else if ([self layoutableIsASLayoutSpec]) { // maybe make an enum type?
|
||||
|
||||
_itemBackgroundColorBtn.enabled = YES;
|
||||
_flexGrowBtn.enabled = YES;
|
||||
_flexShrinkBtn.enabled = YES;
|
||||
_flexBasisBtn.enabled = YES;
|
||||
_alignSelfBtn.enabled = YES;
|
||||
_spacingBeforeBtn.enabled = YES;
|
||||
_spacingAfterBtn.enabled = YES;
|
||||
_alignItemsBtn.enabled = YES;
|
||||
|
||||
} else if ([self layoutableIsASDisplayNode]) {
|
||||
|
||||
_itemBackgroundColorBtn.enabled = YES;
|
||||
_flexGrowBtn.enabled = YES;
|
||||
_flexShrinkBtn.enabled = YES;
|
||||
_flexBasisBtn.enabled = YES;
|
||||
_alignSelfBtn.enabled = YES;
|
||||
_spacingBeforeBtn.enabled = YES;
|
||||
_spacingAfterBtn.enabled = YES;
|
||||
_alignItemsBtn.enabled = NO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (ASDisplayNode *)node
|
||||
{
|
||||
if ([self.layoutableToEdit isKindOfClass:[ASDisplayNode class]]) {
|
||||
return (ASDisplayNode *)self.layoutableToEdit;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (ASLayoutSpec *)layoutSpec
|
||||
{
|
||||
if ([self.layoutableToEdit isKindOfClass:[ASLayoutSpec class]]) {
|
||||
return (ASLayoutSpec *)self.layoutableToEdit;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)layoutableIsASLayoutSpec
|
||||
{
|
||||
return [self.layoutableToEdit isKindOfClass:[ASLayoutSpec class]];
|
||||
}
|
||||
|
||||
- (BOOL)layoutableIsASDisplayNode
|
||||
{
|
||||
return [self.layoutableToEdit isKindOfClass:[ASDisplayNode class]];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
76466F331C9DFFC4006C4D2D /* ColorNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 76466F2D1C9DFFC4006C4D2D /* ColorNode.m */; };
|
||||
76466F341C9DFFC4006C4D2D /* PlaygroundNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 76466F2F1C9DFFC4006C4D2D /* PlaygroundNode.m */; };
|
||||
76466F351C9DFFC4006C4D2D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 76466F311C9DFFC4006C4D2D /* ViewController.m */; };
|
||||
76B372ED1CA1041D003F866B /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 76B372EC1CA1041D003F866B /* MasterViewController.m */; };
|
||||
76F58D5C1C9E15C1004512CC /* PlaygroundContainerNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 76F58D5B1C9E15C1004512CC /* PlaygroundContainerNode.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -36,6 +37,8 @@
|
||||
76466F2F1C9DFFC4006C4D2D /* PlaygroundNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaygroundNode.m; sourceTree = "<group>"; };
|
||||
76466F301C9DFFC4006C4D2D /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
|
||||
76466F311C9DFFC4006C4D2D /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
|
||||
76B372EB1CA1041D003F866B /* MasterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = "<group>"; };
|
||||
76B372EC1CA1041D003F866B /* MasterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = "<group>"; };
|
||||
76F58D5A1C9E15C1004512CC /* PlaygroundContainerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaygroundContainerNode.h; sourceTree = "<group>"; };
|
||||
76F58D5B1C9E15C1004512CC /* PlaygroundContainerNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaygroundContainerNode.m; sourceTree = "<group>"; };
|
||||
C068F1D3F0CC317E895FCDAB /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
@@ -79,6 +82,8 @@
|
||||
children = (
|
||||
76466F2A1C9DFFC4006C4D2D /* AppDelegate.h */,
|
||||
76466F2B1C9DFFC4006C4D2D /* AppDelegate.m */,
|
||||
76B372EB1CA1041D003F866B /* MasterViewController.h */,
|
||||
76B372EC1CA1041D003F866B /* MasterViewController.m */,
|
||||
76466F301C9DFFC4006C4D2D /* ViewController.h */,
|
||||
76466F311C9DFFC4006C4D2D /* ViewController.m */,
|
||||
76F58D5A1C9E15C1004512CC /* PlaygroundContainerNode.h */,
|
||||
@@ -248,6 +253,7 @@
|
||||
76466F341C9DFFC4006C4D2D /* PlaygroundNode.m in Sources */,
|
||||
76F58D5C1C9E15C1004512CC /* PlaygroundContainerNode.m in Sources */,
|
||||
76466F351C9DFFC4006C4D2D /* ViewController.m in Sources */,
|
||||
76B372ED1CA1041D003F866B /* MasterViewController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "ViewController.h"
|
||||
#import "MasterViewController.h"
|
||||
#import "ASLayoutableInspectorNode.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@@ -18,12 +20,39 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window.backgroundColor = [UIColor colorWithRed:255/255.0 green:181/255.0 blue:68/255.0 alpha:1];
|
||||
|
||||
ViewController *vc = [[ViewController alloc] init];
|
||||
self.window.rootViewController = vc;
|
||||
// assign rootViewController
|
||||
UIViewController *rootViewController = nil;
|
||||
|
||||
// determine if app is running on an iPhone or iPad
|
||||
UIDevice *device = [UIDevice currentDevice];
|
||||
|
||||
if (device.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
|
||||
// cannot get to supernode - need a delegate protocol //
|
||||
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNode:[ASLayoutableInspectorNode sharedInstance]];
|
||||
masterViewController.view.backgroundColor = [UIColor colorWithRed:40/255.0 green:43/255.0 blue:53/255.0 alpha:1.0];
|
||||
UINavigationController *masterNav = [[UINavigationController alloc] initWithRootViewController:masterViewController];
|
||||
|
||||
ViewController *detailViewController = [[ViewController alloc] init];
|
||||
UINavigationController *detailNav = [[UINavigationController alloc] initWithRootViewController:detailViewController];
|
||||
|
||||
UISplitViewController *splitViewController = [[UISplitViewController alloc] init];
|
||||
splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
|
||||
splitViewController.viewControllers = [NSArray arrayWithObjects:masterNav, detailNav, nil];
|
||||
splitViewController.delegate = detailViewController;
|
||||
|
||||
detailViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;
|
||||
|
||||
rootViewController = splitViewController;
|
||||
|
||||
} else {
|
||||
NSAssert(YES, @"App optimized for iPad only.");
|
||||
}
|
||||
|
||||
[self.window setRootViewController:rootViewController];
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
|
||||
@@ -35,7 +35,11 @@
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
return CGSizeMake(50, 50);
|
||||
if (CGSizeEqualToSize(self.preferredFrameSize, CGSizeZero)) {
|
||||
return CGSizeMake(50, 50);
|
||||
} else {
|
||||
return self.preferredFrameSize;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)nodeWasTapped:(UIGestureRecognizer *)sender
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// MasterViewController.h
|
||||
// Sample
|
||||
//
|
||||
// Created by Hannah Troisi on 3/21/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@interface MasterViewController : ASViewController
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// MasterViewController.m
|
||||
// Sample
|
||||
//
|
||||
// Created by Hannah Troisi on 3/21/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MasterViewController.h"
|
||||
|
||||
@interface MasterViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation MasterViewController
|
||||
|
||||
|
||||
@end
|
||||
@@ -50,9 +50,12 @@
|
||||
[super layout];
|
||||
[self.view bringSubviewToFront:_resizeHandle.view];
|
||||
|
||||
CGSize playgroundSize = _playgroundNode.calculatedLayout.size; // this might be a bug with implicit heirarchy - frame isn't set yet
|
||||
CGSize playgroundSize = _playgroundNode.calculatedLayout.size; // FIXME:this might be a bug with implicit heirarchy - frame isn't set yet
|
||||
// _playgroundNode.frame = CGRectMake(300, 200, playgroundSize.width, playgroundSize.height);
|
||||
//
|
||||
|
||||
CGRect rect = CGRectZero;
|
||||
rect.size = CGSizeMake(RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE);
|
||||
rect.size = CGSizeMake(RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE); // FIXME: make this an overlay stack?
|
||||
rect.origin = CGPointMake(playgroundSize.width - rect.size.width, playgroundSize.height - rect.size.height);
|
||||
_resizeHandle.frame = rect;
|
||||
}
|
||||
@@ -67,11 +70,10 @@
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
ASStaticLayoutSpec *verticalStack = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[_playgroundNode]];
|
||||
// verticalStack.shouldVisualize = YES;
|
||||
// verticalStack.flexGrow = YES;
|
||||
UIEdgeInsets insets = UIEdgeInsetsMake(200, 100, 200, 100);
|
||||
ASInsetLayoutSpec *insetLayoutSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:_playgroundNode];
|
||||
|
||||
return verticalStack;
|
||||
return insetLayoutSpec;
|
||||
}
|
||||
|
||||
- (void)resizePlayground:(UIGestureRecognizer *)sender
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
#import "PlaygroundNode.h"
|
||||
#import "ColorNode.h"
|
||||
#import "AsyncDisplayKit+Debug.h"
|
||||
#import "ASLayoutableInspectorNode.h"
|
||||
|
||||
@implementation PlaygroundNode
|
||||
{
|
||||
NSArray *_colorNodes;
|
||||
ASDisplayNode *_individualColorNode;
|
||||
ASTextNode *_textNode;
|
||||
}
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
@@ -34,11 +36,22 @@
|
||||
_individualColorNode = [[ColorNode alloc] init];
|
||||
_individualColorNode.backgroundColor = [UIColor orangeColor];
|
||||
|
||||
// user interaction off by default
|
||||
_textNode = [[ASTextNode alloc] init];
|
||||
_textNode.attributedString = [[NSAttributedString alloc] initWithString:@"Hhhhhhhhhheeeeeeeeeelllllloooooooo"];
|
||||
_textNode.backgroundColor = [UIColor greenColor];
|
||||
_textNode.userInteractionEnabled = YES;
|
||||
[_textNode addTarget:self action:@selector(textTapped:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)textTapped:(UIGestureRecognizer *)sender
|
||||
{
|
||||
[ASLayoutableInspectorNode sharedInstance].layoutableToEdit = _textNode;
|
||||
}
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
NSMutableArray *children = [[NSMutableArray alloc] init];
|
||||
@@ -49,13 +62,21 @@
|
||||
insetSpec.flexGrow = YES;
|
||||
[children addObject:insetSpec];
|
||||
}
|
||||
|
||||
_textNode.flexShrink = YES;
|
||||
_textNode.flexGrow = YES;
|
||||
_textNode.alignSelf = ASStackLayoutAlignSelfStretch;
|
||||
[children addObject:_textNode];
|
||||
|
||||
ASStackLayoutSpec *innerStack = [ASStackLayoutSpec verticalStackLayoutSpec];
|
||||
innerStack.children = children;
|
||||
innerStack.flexGrow = YES;
|
||||
|
||||
_individualColorNode.preferredFrameSize = CGSizeMake(100, 600);
|
||||
ASStackLayoutSpec *outerStack = [ASStackLayoutSpec horizontalStackLayoutSpec];
|
||||
outerStack.flexGrow = YES;
|
||||
outerStack.children = @[innerStack, _individualColorNode];
|
||||
outerStack.alignItems = ASStackLayoutAlignItemsStretch;
|
||||
|
||||
return outerStack;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AsyncDisplayKit.h"
|
||||
#import "ASLayoutableInspectorNode.h"
|
||||
|
||||
|
||||
@interface ViewController : ASViewController <UISplitViewControllerDelegate, ASLayoutableInspectorNodeDelegate>
|
||||
|
||||
@interface ViewController : ASViewController
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
{
|
||||
self = [super initWithNode:[[PlaygroundContainerNode alloc] init]];
|
||||
if (self) {
|
||||
self.navigationItem.title = @"ASLayoutSpec Playground";
|
||||
[ASLayoutableInspectorNode sharedInstance].delegate = self;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -33,4 +35,12 @@
|
||||
[super viewDidLoad];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UISplitViewControllerDelegate
|
||||
|
||||
- (void)shouldShowMasterSplitViewController
|
||||
{
|
||||
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user