451 lines
17 KiB
Objective-C
451 lines
17 KiB
Objective-C
#ifdef SHOULD_COMPILE_LOOKIN_SERVER
|
||
|
||
//
|
||
// LookinDisplayItem.m
|
||
// qmuidemo
|
||
//
|
||
// Created by Li Kai on 2018/11/15.
|
||
// Copyright © 2018 QMUI Team. All rights reserved.
|
||
//
|
||
|
||
#import "LookinDisplayItem.h"
|
||
#import "LookinAttributesGroup.h"
|
||
#import "LookinAttributesSection.h"
|
||
#import "LookinAttribute.h"
|
||
#import "LookinEventHandler.h"
|
||
#import "LookinIvarTrace.h"
|
||
#import "Color+Lookin.h"
|
||
#import "NSArray+Lookin.h"
|
||
#import "NSObject+Lookin.h"
|
||
#import "LookinDashboardBlueprint.h"
|
||
|
||
#if TARGET_OS_IPHONE
|
||
#import "UIColor+LookinServer.h"
|
||
#import "UIImage+LookinServer.h"
|
||
#elif TARGET_OS_MAC
|
||
#endif
|
||
|
||
@interface LookinDisplayItem ()
|
||
|
||
@property(nonatomic, assign, readwrite) CGRect frameToRoot;
|
||
@property(nonatomic, assign, readwrite) BOOL inNoPreviewHierarchy;
|
||
@property(nonatomic, assign) NSInteger indentLevel;
|
||
@property(nonatomic, assign, readwrite) BOOL isExpandable;
|
||
@property(nonatomic, assign, readwrite) BOOL inHiddenHierarchy;
|
||
@property(nonatomic, assign, readwrite) BOOL displayingInHierarchy;
|
||
|
||
@end
|
||
|
||
@implementation LookinDisplayItem
|
||
|
||
#pragma mark - <NSCopying>
|
||
|
||
- (id)copyWithZone:(NSZone *)zone {
|
||
LookinDisplayItem *newDisplayItem = [[LookinDisplayItem allocWithZone:zone] init];
|
||
newDisplayItem.subitems = [self.subitems lookin_map:^id(NSUInteger idx, LookinDisplayItem *value) {
|
||
return value.copy;
|
||
}];
|
||
newDisplayItem.customInfo = self.customInfo.copy;
|
||
newDisplayItem.isHidden = self.isHidden;
|
||
newDisplayItem.alpha = self.alpha;
|
||
newDisplayItem.frame = self.frame;
|
||
newDisplayItem.bounds = self.bounds;
|
||
newDisplayItem.soloScreenshot = self.soloScreenshot;
|
||
newDisplayItem.groupScreenshot = self.groupScreenshot;
|
||
newDisplayItem.viewObject = self.viewObject.copy;
|
||
newDisplayItem.layerObject = self.layerObject.copy;
|
||
newDisplayItem.hostViewControllerObject = self.hostViewControllerObject.copy;
|
||
newDisplayItem.attributesGroupList = [self.attributesGroupList lookin_map:^id(NSUInteger idx, LookinAttributesGroup *value) {
|
||
return value.copy;
|
||
}];
|
||
newDisplayItem.customAttrGroupList = [self.customAttrGroupList lookin_map:^id(NSUInteger idx, LookinAttributesGroup *value) {
|
||
return value.copy;
|
||
}];
|
||
newDisplayItem.eventHandlers = [self.eventHandlers lookin_map:^id(NSUInteger idx, LookinEventHandler *value) {
|
||
return value.copy;
|
||
}];
|
||
newDisplayItem.shouldCaptureImage = self.shouldCaptureImage;
|
||
newDisplayItem.representedAsKeyWindow = self.representedAsKeyWindow;
|
||
newDisplayItem.customDisplayTitle = self.customDisplayTitle;
|
||
newDisplayItem.danceuiSource = self.danceuiSource;
|
||
[newDisplayItem _updateDisplayingInHierarchyProperty];
|
||
return newDisplayItem;
|
||
}
|
||
#pragma mark - <NSCoding>
|
||
|
||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||
[aCoder encodeObject:self.customInfo forKey:@"customInfo"];
|
||
[aCoder encodeObject:self.subitems forKey:@"subitems"];
|
||
[aCoder encodeBool:self.isHidden forKey:@"hidden"];
|
||
[aCoder encodeFloat:self.alpha forKey:@"alpha"];
|
||
[aCoder encodeObject:self.viewObject forKey:@"viewObject"];
|
||
[aCoder encodeObject:self.layerObject forKey:@"layerObject"];
|
||
[aCoder encodeObject:self.hostViewControllerObject forKey:@"hostViewControllerObject"];
|
||
[aCoder encodeObject:self.attributesGroupList forKey:@"attributesGroupList"];
|
||
[aCoder encodeObject:self.customAttrGroupList forKey:@"customAttrGroupList"];
|
||
[aCoder encodeBool:self.representedAsKeyWindow forKey:@"representedAsKeyWindow"];
|
||
[aCoder encodeObject:self.eventHandlers forKey:@"eventHandlers"];
|
||
[aCoder encodeBool:self.shouldCaptureImage forKey:@"shouldCaptureImage"];
|
||
if (self.screenshotEncodeType == LookinDisplayItemImageEncodeTypeNSData) {
|
||
[aCoder encodeObject:[self.soloScreenshot lookin_encodedObjectWithType:LookinCodingValueTypeImage] forKey:@"soloScreenshot"];
|
||
[aCoder encodeObject:[self.groupScreenshot lookin_encodedObjectWithType:LookinCodingValueTypeImage] forKey:@"groupScreenshot"];
|
||
} else if (self.screenshotEncodeType == LookinDisplayItemImageEncodeTypeImage) {
|
||
[aCoder encodeObject:self.soloScreenshot forKey:@"soloScreenshot"];
|
||
[aCoder encodeObject:self.groupScreenshot forKey:@"groupScreenshot"];
|
||
}
|
||
[aCoder encodeObject:self.customDisplayTitle forKey:@"customDisplayTitle"];
|
||
[aCoder encodeObject:self.danceuiSource forKey:@"danceuiSource"];
|
||
#if TARGET_OS_IPHONE
|
||
[aCoder encodeCGRect:self.frame forKey:@"frame"];
|
||
[aCoder encodeCGRect:self.bounds forKey:@"bounds"];
|
||
[aCoder encodeObject:self.backgroundColor.lks_rgbaComponents forKey:@"backgroundColor"];
|
||
|
||
#elif TARGET_OS_MAC
|
||
[aCoder encodeRect:self.frame forKey:@"frame"];
|
||
[aCoder encodeRect:self.bounds forKey:@"bounds"];
|
||
[aCoder encodeObject:self.backgroundColor.lookin_rgbaComponents forKey:@"backgroundColor"];
|
||
#endif
|
||
}
|
||
|
||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||
if (self = [super init]) {
|
||
self.customInfo = [aDecoder decodeObjectForKey:@"customInfo"];
|
||
self.subitems = [aDecoder decodeObjectForKey:@"subitems"];
|
||
self.isHidden = [aDecoder decodeBoolForKey:@"hidden"];
|
||
self.alpha = [aDecoder decodeFloatForKey:@"alpha"];
|
||
self.viewObject = [aDecoder decodeObjectForKey:@"viewObject"];
|
||
self.layerObject = [aDecoder decodeObjectForKey:@"layerObject"];
|
||
self.hostViewControllerObject = [aDecoder decodeObjectForKey:@"hostViewControllerObject"];
|
||
self.attributesGroupList = [aDecoder decodeObjectForKey:@"attributesGroupList"];
|
||
self.customAttrGroupList = [aDecoder decodeObjectForKey:@"customAttrGroupList"];
|
||
self.representedAsKeyWindow = [aDecoder decodeBoolForKey:@"representedAsKeyWindow"];
|
||
|
||
id soloScreenshotObj = [aDecoder decodeObjectForKey:@"soloScreenshot"];
|
||
if (soloScreenshotObj) {
|
||
if ([soloScreenshotObj isKindOfClass:[NSData class]]) {
|
||
self.soloScreenshot = [soloScreenshotObj lookin_decodedObjectWithType:LookinCodingValueTypeImage];
|
||
} else if ([soloScreenshotObj isKindOfClass:[LookinImage class]]) {
|
||
self.soloScreenshot = soloScreenshotObj;
|
||
} else {
|
||
NSAssert(NO, @"");
|
||
}
|
||
}
|
||
|
||
id groupScreenshotObj = [aDecoder decodeObjectForKey:@"groupScreenshot"];
|
||
if (groupScreenshotObj) {
|
||
if ([groupScreenshotObj isKindOfClass:[NSData class]]) {
|
||
self.groupScreenshot = [groupScreenshotObj lookin_decodedObjectWithType:LookinCodingValueTypeImage];
|
||
} else if ([groupScreenshotObj isKindOfClass:[LookinImage class]]) {
|
||
self.groupScreenshot = groupScreenshotObj;
|
||
} else {
|
||
NSAssert(NO, @"");
|
||
}
|
||
}
|
||
|
||
self.eventHandlers = [aDecoder decodeObjectForKey:@"eventHandlers"];
|
||
/// this property was added in LookinServer 1.1.3
|
||
self.shouldCaptureImage = [aDecoder containsValueForKey:@"shouldCaptureImage"] ? [aDecoder decodeBoolForKey:@"shouldCaptureImage"] : YES;
|
||
self.customDisplayTitle = [aDecoder decodeObjectForKey:@"customDisplayTitle"];
|
||
self.danceuiSource = [aDecoder decodeObjectForKey:@"danceuiSource"];
|
||
#if TARGET_OS_IPHONE
|
||
self.frame = [aDecoder decodeCGRectForKey:@"frame"];
|
||
self.bounds = [aDecoder decodeCGRectForKey:@"bounds"];
|
||
self.backgroundColor = [UIColor lks_colorFromRGBAComponents:[aDecoder decodeObjectForKey:@"backgroundColor"]];
|
||
#elif TARGET_OS_MAC
|
||
self.frame = [aDecoder decodeRectForKey:@"frame"];
|
||
self.bounds = [aDecoder decodeRectForKey:@"bounds"];
|
||
self.backgroundColor = [NSColor lookin_colorFromRGBAComponents:[aDecoder decodeObjectForKey:@"backgroundColor"]];
|
||
|
||
#endif
|
||
[self _updateDisplayingInHierarchyProperty];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
+ (BOOL)supportsSecureCoding {
|
||
return YES;
|
||
}
|
||
|
||
- (instancetype)init {
|
||
if (self = [super init]) {
|
||
/// 在手机端,displayItem 被创建时会调用这个方法
|
||
[self _updateDisplayingInHierarchyProperty];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (LookinObject *)displayingObject {
|
||
return self.viewObject ? : self.layerObject;
|
||
}
|
||
|
||
- (void)setAttributesGroupList:(NSArray<LookinAttributesGroup *> *)attributesGroupList {
|
||
_attributesGroupList = attributesGroupList;
|
||
|
||
[_attributesGroupList enumerateObjectsUsingBlock:^(LookinAttributesGroup * _Nonnull group, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[group.attrSections enumerateObjectsUsingBlock:^(LookinAttributesSection * _Nonnull section, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[section.attributes enumerateObjectsUsingBlock:^(LookinAttribute * _Nonnull attr, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
attr.targetDisplayItem = self;
|
||
}];
|
||
}];
|
||
}];
|
||
}
|
||
|
||
- (void)setCustomAttrGroupList:(NSArray<LookinAttributesGroup *> *)customAttrGroupList {
|
||
_customAttrGroupList = customAttrGroupList;
|
||
// 传进来的时候就已经排好序了
|
||
[customAttrGroupList enumerateObjectsUsingBlock:^(LookinAttributesGroup * _Nonnull group, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[group.attrSections enumerateObjectsUsingBlock:^(LookinAttributesSection * _Nonnull section, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[section.attributes enumerateObjectsUsingBlock:^(LookinAttribute * _Nonnull attr, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
attr.targetDisplayItem = self;
|
||
}];
|
||
}];
|
||
}];
|
||
}
|
||
|
||
- (void)setSubitems:(NSArray<LookinDisplayItem *> *)subitems {
|
||
[_subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
obj.superItem = nil;
|
||
}];
|
||
|
||
_subitems = subitems;
|
||
|
||
self.isExpandable = (subitems.count > 0);
|
||
|
||
[subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
NSAssert(!obj.superItem, @"");
|
||
obj.superItem = self;
|
||
|
||
[obj _updateInHiddenHierarchyProperty];
|
||
[obj _updateDisplayingInHierarchyProperty];
|
||
}];
|
||
}
|
||
|
||
- (void)setIsExpandable:(BOOL)isExpandable {
|
||
if (_isExpandable == isExpandable) {
|
||
return;
|
||
}
|
||
_isExpandable = isExpandable;
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_IsExpandable];
|
||
}
|
||
|
||
- (void)setIsExpanded:(BOOL)isExpanded {
|
||
if (_isExpanded == isExpanded) {
|
||
return;
|
||
}
|
||
_isExpanded = isExpanded;
|
||
[self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[obj _updateDisplayingInHierarchyProperty];
|
||
}];
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_IsExpanded];
|
||
}
|
||
|
||
- (void)setSoloScreenshot:(LookinImage *)soloScreenshot {
|
||
if (_soloScreenshot == soloScreenshot) {
|
||
return;
|
||
}
|
||
_soloScreenshot = soloScreenshot;
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_SoloScreenshot];
|
||
}
|
||
|
||
- (void)notifySelectionChangeToDelegates {
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_IsSelected];
|
||
}
|
||
|
||
- (void)notifyHoverChangeToDelegates {
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_IsHovered];
|
||
}
|
||
|
||
- (void)setDoNotFetchScreenshotReason:(LookinDoNotFetchScreenshotReason)doNotFetchScreenshotReason {
|
||
if (_doNotFetchScreenshotReason == doNotFetchScreenshotReason) {
|
||
return;
|
||
}
|
||
_doNotFetchScreenshotReason = doNotFetchScreenshotReason;
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_AvoidSyncScreenshot];
|
||
}
|
||
|
||
- (void)setGroupScreenshot:(LookinImage *)groupScreenshot {
|
||
if (_groupScreenshot == groupScreenshot) {
|
||
return;
|
||
}
|
||
_groupScreenshot = groupScreenshot;
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_GroupScreenshot];
|
||
}
|
||
|
||
- (void)setDisplayingInHierarchy:(BOOL)displayingInHierarchy {
|
||
if (_displayingInHierarchy == displayingInHierarchy) {
|
||
return;
|
||
}
|
||
_displayingInHierarchy = displayingInHierarchy;
|
||
[self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[obj _updateDisplayingInHierarchyProperty];
|
||
}];
|
||
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_DisplayingInHierarchy];
|
||
}
|
||
|
||
- (void)_updateDisplayingInHierarchyProperty {
|
||
if (self.superItem && (!self.superItem.displayingInHierarchy || !self.superItem.isExpanded)) {
|
||
self.displayingInHierarchy = NO;
|
||
} else {
|
||
self.displayingInHierarchy = YES;
|
||
}
|
||
}
|
||
|
||
- (void)setIsHidden:(BOOL)isHidden {
|
||
_isHidden = isHidden;
|
||
[self _updateInHiddenHierarchyProperty];
|
||
}
|
||
|
||
- (void)setAlpha:(float)alpha {
|
||
_alpha = alpha;
|
||
[self _updateInHiddenHierarchyProperty];
|
||
}
|
||
|
||
- (void)setInHiddenHierarchy:(BOOL)inHiddenHierarchy {
|
||
if (_inHiddenHierarchy == inHiddenHierarchy) {
|
||
return;
|
||
}
|
||
_inHiddenHierarchy = inHiddenHierarchy;
|
||
[self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[obj _updateInHiddenHierarchyProperty];
|
||
}];
|
||
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_InHiddenHierarchy];
|
||
}
|
||
|
||
- (void)_updateInHiddenHierarchyProperty {
|
||
if (self.superItem.inHiddenHierarchy || self.isHidden || self.alpha <= 0) {
|
||
self.inHiddenHierarchy = YES;
|
||
} else {
|
||
self.inHiddenHierarchy = NO;
|
||
}
|
||
}
|
||
|
||
+ (NSArray<LookinDisplayItem *> *)flatItemsFromHierarchicalItems:(NSArray<LookinDisplayItem *> *)items {
|
||
NSMutableArray *resultArray = [NSMutableArray array];
|
||
|
||
[items enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
if (obj.superItem) {
|
||
obj.indentLevel = obj.superItem.indentLevel + 1;
|
||
}
|
||
[resultArray addObject:obj];
|
||
if (obj.subitems.count) {
|
||
[resultArray addObjectsFromArray:[self flatItemsFromHierarchicalItems:obj.subitems]];
|
||
}
|
||
}];
|
||
|
||
return resultArray;
|
||
}
|
||
|
||
- (NSString *)description {
|
||
if (self.viewObject) {
|
||
return self.viewObject.rawClassName;
|
||
} else if (self.layerObject) {
|
||
return self.layerObject.rawClassName;
|
||
} else {
|
||
return [super description];
|
||
}
|
||
}
|
||
|
||
- (void)setPreviewItemDelegate:(id<LookinDisplayItemDelegate>)previewItemDelegate {
|
||
_previewItemDelegate = previewItemDelegate;
|
||
|
||
if (![previewItemDelegate respondsToSelector:@selector(displayItem:propertyDidChange:)]) {
|
||
NSAssert(NO, @"");
|
||
_previewItemDelegate = nil;
|
||
return;
|
||
}
|
||
[self.previewItemDelegate displayItem:self propertyDidChange:LookinDisplayItemProperty_None];
|
||
}
|
||
|
||
- (void)setRowViewDelegate:(id<LookinDisplayItemDelegate>)rowViewDelegate {
|
||
if (_rowViewDelegate == rowViewDelegate) {
|
||
return;
|
||
}
|
||
_rowViewDelegate = rowViewDelegate;
|
||
|
||
if (![rowViewDelegate respondsToSelector:@selector(displayItem:propertyDidChange:)]) {
|
||
NSAssert(NO, @"");
|
||
_rowViewDelegate = nil;
|
||
return;
|
||
}
|
||
[self.rowViewDelegate displayItem:self propertyDidChange:LookinDisplayItemProperty_None];
|
||
}
|
||
|
||
- (void)setFrame:(CGRect)frame {
|
||
_frame = frame;
|
||
[self recursivelyNotifyFrameToRootMayChange];
|
||
}
|
||
|
||
- (void)recursivelyNotifyFrameToRootMayChange {
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_FrameToRoot];
|
||
|
||
[self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[obj recursivelyNotifyFrameToRootMayChange];
|
||
}];
|
||
}
|
||
|
||
- (void)setBounds:(CGRect)bounds {
|
||
_bounds = bounds;
|
||
[self recursivelyNotifyFrameToRootMayChange];
|
||
}
|
||
|
||
- (void)setInNoPreviewHierarchy:(BOOL)inNoPreviewHierarchy {
|
||
if (_inNoPreviewHierarchy == inNoPreviewHierarchy) {
|
||
return;
|
||
}
|
||
_inNoPreviewHierarchy = inNoPreviewHierarchy;
|
||
[self.subitems enumerateObjectsUsingBlock:^(LookinDisplayItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
[obj _updateInNoPreviewHierarchy];
|
||
}];
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_InNoPreviewHierarchy];
|
||
}
|
||
|
||
- (void)setNoPreview:(BOOL)noPreview {
|
||
_noPreview = noPreview;
|
||
[self _updateInNoPreviewHierarchy];
|
||
}
|
||
|
||
- (void)_updateInNoPreviewHierarchy {
|
||
if (self.superItem.inNoPreviewHierarchy || self.noPreview) {
|
||
self.inNoPreviewHierarchy = YES;
|
||
} else {
|
||
self.inNoPreviewHierarchy = NO;
|
||
}
|
||
}
|
||
|
||
- (void)_notifyDelegatesWith:(LookinDisplayItemProperty)property {
|
||
[self.previewItemDelegate displayItem:self propertyDidChange:property];
|
||
[self.rowViewDelegate displayItem:self propertyDidChange:property];
|
||
}
|
||
|
||
- (void)setIsInSearch:(BOOL)isInSearch {
|
||
_isInSearch = isInSearch;
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_IsInSearch];
|
||
}
|
||
|
||
- (void)setHighlightedSearchString:(NSString *)highlightedSearchString {
|
||
_highlightedSearchString = highlightedSearchString;
|
||
[self _notifyDelegatesWith:LookinDisplayItemProperty_HighlightedSearchString];
|
||
}
|
||
|
||
- (NSArray<LookinAttributesGroup *> *)queryAllAttrGroupList {
|
||
NSMutableArray *array = [NSMutableArray array];
|
||
if (self.attributesGroupList) {
|
||
[array addObjectsFromArray:self.attributesGroupList];
|
||
}
|
||
if (self.customAttrGroupList) {
|
||
[array addObjectsFromArray:self.customAttrGroupList];
|
||
}
|
||
return array;
|
||
}
|
||
|
||
//- (void)dealloc
|
||
//{
|
||
// NSLog(@"moss dealloc -%@", self);
|
||
//}
|
||
|
||
@end
|
||
|
||
#endif /* SHOULD_COMPILE_LOOKIN_SERVER */
|