This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Doric/doric-iOS/Pod/Classes/Shader/DoricSuperNode.m
2021-11-12 16:46:49 +08:00

170 lines
5.3 KiB
Objective-C

/*
* Copyright [2019] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//
// Created by pengfei.zhou on 2019/11/15.
//
#import "DoricSuperNode.h"
#import "DoricExtensions.h"
@interface DoricSuperNode ()
@property(nonatomic, strong) NSMutableDictionary <NSString *, NSMutableDictionary *> *subNodes;
@end
@implementation DoricSuperNode
- (instancetype)initWithContext:(DoricContext *)doricContext {
if (self = [super initWithContext:doricContext]) {
_subNodes = [NSMutableDictionary new];
}
return self;
}
- (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop {
if ([@"subviews" isEqualToString:name]) {
NSArray *subviews = prop;
for (NSMutableDictionary *subModel in subviews) {
[self mixinSubNode:subModel];
[self blendSubNode:subModel];
}
self.view.doricLayout.resolved = NO;
} else {
[super blendView:view forPropName:name propValue:prop];
}
}
- (void)mixinSubNode:(NSMutableDictionary *)dictionary {
NSString *viewId = dictionary[@"id"];
NSMutableDictionary *oldModel = self.subNodes[viewId];
if (oldModel) {
[self mixin:dictionary to:oldModel];
} else {
self.subNodes[viewId] = dictionary;
}
}
- (void)mixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel {
NSDictionary *srcProp = srcModel[@"props"];
NSMutableDictionary *targetProp = [targetModel[@"props"] mutableCopy];
[srcProp enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
if (![@"subviews" isEqualToString:key]) {
targetProp[key] = obj;
}
}];
targetModel[@"props"] = targetProp;
}
- (void)recursiveMixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel {
NSDictionary *srcProp = srcModel[@"props"];
NSMutableDictionary *targetProp = [targetModel[@"props"] mutableCopy];
NSMutableArray *targetOri = targetProp[@"subviews"];
NSArray *srcSubviews = srcProp[@"subviews"];
if (srcSubviews && srcSubviews.count > 0) {
for (NSDictionary *subview in srcSubviews) {
NSString *viewId = subview[@"id"];
__block NSMutableDictionary *viewModel = nil;
[targetOri enumerateObjectsUsingBlock:^(NSMutableDictionary *obj, NSUInteger idx, BOOL *stop) {
if ([viewId isEqualToString:obj[@"id"]]) {
viewModel = obj;
*stop = YES;
}
}];
if (viewModel) {
[self recursiveMixin:subview to:viewModel];
}
}
}
[srcProp enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
if (![@"subviews" isEqualToString:key]) {
targetProp[key] = obj;
}
}];
targetModel[@"props"] = targetProp;
}
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutConfig {
[subNode blendLayoutConfig:layoutConfig];
}
- (void)blendSubNode:(NSDictionary *)subModel {
NSAssert(NO, @"Should override class:%@ ,method:%@.", NSStringFromClass([self class]),
NSStringFromSelector(_cmd));
}
- (DoricLayout *)generateDefaultLayoutParams {
DoricLayout *params = [[DoricLayout alloc] init];
return params;
}
- (NSDictionary *)subModelOf:(NSString *)viewId {
return self.subNodes[viewId];
}
- (void)setSubModel:(NSDictionary *)model in:(NSString *)viewId {
self.subNodes[viewId] = [model mutableCopy];
}
- (void)clearSubModel {
[self.subNodes removeAllObjects];
}
- (void)removeSubModel:(NSString *)viewId {
[self.subNodes removeObjectForKey:viewId];
}
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId {
NSAssert(NO, @"Should override class:%@ ,method:%@.", NSStringFromClass([self class]),
NSStringFromSelector(_cmd));
return nil;
}
- (NSArray *)getSubNodeViewIds {
NSMutableArray *discardedItems = [NSMutableArray array];
NSMutableArray *allKeys = [[NSMutableArray alloc] init];
allKeys = [NSMutableArray arrayWithArray:[self.subNodes allKeys]];
for (NSString *key in allKeys) {
if ([self subNodeWithViewId:key] == nil) {
[discardedItems addObject:key];
}
}
[allKeys removeObjectsInArray:discardedItems];
return allKeys;
}
- (void)reset {
[super reset];
for (NSString *viewId in self.subNodes.allKeys) {
[[self subNodeWithViewId:viewId] reset];
}
}
- (void)subNodeContentChanged:(DoricViewNode *)subNode {
if (self.superNode
&& (self.view.doricLayout.widthSpec == DoricLayoutFit
|| self.view.doricLayout.heightSpec == DoricLayoutFit)) {
[self.superNode subNodeContentChanged:self];
} else {
if (![self.type isEqualToString:@"Root"]) {
[self.view.doricLayout apply];
}
[self requestLayout];
}
}
@end