From ed69c4f16a84dbdef3ef6e22867b925ff23bdcc0 Mon Sep 17 00:00:00 2001 From: Kyle Cui Date: Mon, 29 Mar 2021 16:11:32 -0700 Subject: [PATCH] add macOS descriptors for layout plugin Summary: Add macOS only descriptors. Currently does not support Yoga/YogaKit or accessibility features; will add those in a later diff. Reviewed By: priteshrnandgaonkar Differential Revision: D27332601 fbshipit-source-id: 35c93cf715f004dbf8dbf8753534f1d4f9801b4c --- .../FlipperKitLayoutPlugin.mm | 10 +- .../SKDescriptorMapper.mm | 35 +++ .../SKNSApplicationDescriptor.h | 17 ++ .../SKNSApplicationDescriptor.m | 61 +++++ .../SKNSButtonDescriptor.h | 18 ++ .../SKNSButtonDescriptor.mm | 75 ++++++ .../SKNSScrollViewDescriptor.h | 16 ++ .../SKNSScrollViewDescriptor.m | 88 +++++++ .../SKNSViewControllerDescriptor.h | 20 ++ .../SKNSViewControllerDescriptor.m | 45 ++++ .../SKNSViewDescriptor.h | 20 ++ .../SKNSViewDescriptor.mm | 221 ++++++++++++++++++ .../SKNSWindowDescriptor.h | 17 ++ .../SKNSWindowDescriptor.m | 58 +++++ 14 files changed, 700 insertions(+), 1 deletion(-) create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.h create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.m create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.h create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.mm create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.h create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.m create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.h create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.m create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.h create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.mm create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.h create mode 100644 iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.m diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm index 146c50573..74f205931 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm @@ -70,8 +70,12 @@ NSObject* flattenLayoutEditorMessage(NSObject* field); _connection = connection; if (!_rootNode) { - // TODO: T61384369 get rid off this if condition. +// TODO: T61384369 get rid off this if condition. +#if TARGET_OS_IPHONE _rootNode = [UIApplication sharedApplication]; +#elif TARGET_OS_OSX + _rootNode = [NSApplication sharedApplication]; +#endif } [SKInvalidation enableInvalidations]; @@ -366,7 +370,11 @@ NSObject* flattenLayoutEditorMessage(NSObject* field) { - (void)onCallSetSearchActive:(BOOL)active withConnection:(id)connection { if (active) { +#if TARGET_OS_IPHONE [_tapListener mountWithFrame:[[UIScreen mainScreen] bounds]]; +#elif TARGET_OS_OSX + [_tapListener mountWithFrame:NSRectToCGRect([NSScreen mainScreen].frame)]; +#endif __block id rootNode = _rootNode; [_tapListener listenForTapWithBlock:^(CGPoint touchPoint) { diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKDescriptorMapper.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKDescriptorMapper.mm index a22e1a17d..c003fcf0b 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKDescriptorMapper.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKDescriptorMapper.mm @@ -9,12 +9,25 @@ #import "SKDescriptorMapper.h" +#if TARGET_OS_IPHONE + #import #import #import #import #import +#elif TARGET_OS_OSX + +#import +#import +#import +#import +#import +#import + +#endif + @implementation SKDescriptorMapper { NSMutableDictionary* _descriptors; } @@ -23,6 +36,7 @@ if (self = [super init]) { _descriptors = [NSMutableDictionary new]; +#if TARGET_OS_IPHONE [self registerDescriptor:[[SKApplicationDescriptor alloc] initWithDescriptorMapper:self] forClass:[UIApplication class]]; @@ -38,6 +52,27 @@ [self registerDescriptor:[[SKViewDescriptor alloc] initWithDescriptorMapper:self] forClass:[UIView class]]; + +#elif TARGET_OS_OSX + [self registerDescriptor:[[SKNSApplicationDescriptor alloc] + initWithDescriptorMapper:self] + forClass:[NSApplication class]]; + [self registerDescriptor:[[SKNSViewControllerDescriptor alloc] + initWithDescriptorMapper:self] + forClass:[NSViewController class]]; + [self registerDescriptor:[[SKNSScrollViewDescriptor alloc] + initWithDescriptorMapper:self] + forClass:[NSScrollView class]]; + [self registerDescriptor:[[SKNSButtonDescriptor alloc] + initWithDescriptorMapper:self] + forClass:[NSButton class]]; + [self registerDescriptor:[[SKNSViewDescriptor alloc] + initWithDescriptorMapper:self] + forClass:[NSView class]]; + [self registerDescriptor:[[SKNSWindowDescriptor alloc] + initWithDescriptorMapper:self] + forClass:[NSWindow class]]; +#endif } return self; diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.h b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.h new file mode 100644 index 000000000..9238c70b7 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +#import + +@class SKDescriptorMapper; + +@interface SKNSApplicationDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.m b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.m new file mode 100644 index 000000000..95fc97a1b --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSApplicationDescriptor.m @@ -0,0 +1,61 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import "SKNSApplicationDescriptor.h" + +#import +#import + +@implementation SKNSApplicationDescriptor + +- (NSString*)identifierForNode:(NSApplication*)node { + return [NSString stringWithFormat:@"%p", node]; +} + +- (NSUInteger)childCountForNode:(NSApplication*)node { + return [[self visibleChildrenForNode:node] count]; +} + +- (id)childForNode:(NSApplication*)node atIndex:(NSUInteger)index { + return [self visibleChildrenForNode:node][index]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(NSApplication*)node { + SKNodeDescriptor* windowDescriptor = + [self descriptorForClass:[NSWindow class]]; + [windowDescriptor setHighlighted:highlighted forNode:[node keyWindow]]; +} + +- (void)hitTest:(SKTouch*)touch forNode:(NSApplication*)node { + bool finish = true; + for (NSInteger index = [self childCountForNode:node] - 1; index >= 0; + index--) { + NSWindow* child = [self childForNode:node atIndex:index]; + + if ([touch containedIn:child.frame]) { + [touch continueWithChildIndex:index withOffset:child.frame.origin]; + finish = false; + } + } + if (finish) { + [touch finish]; + } +} + +- (NSArray*)visibleChildrenForNode:(NSApplication*)node { + NSMutableArray* children = [NSMutableArray new]; + for (NSWindow* window in node.windows) { + [children addObject:window]; + } + return children; +} + +@end + +#endif diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.h b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.h new file mode 100644 index 000000000..6cea99411 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +#import + +@class NSButton; +@class SKDescriptorMapper; + +@interface SKNSButtonDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.mm b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.mm new file mode 100644 index 000000000..7988fcf97 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSButtonDescriptor.mm @@ -0,0 +1,75 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import "SKNSButtonDescriptor.h" + +#import +#import + +@implementation SKNSButtonDescriptor + +- (NSString*)identifierForNode:(NSButton*)node { + return [NSString stringWithFormat:@"%p", node]; +} + +- (NSUInteger)childCountForNode:(NSButton*)node { + return 0; +} + +- (id)childForNode:(NSButton*)node atIndex:(NSUInteger)index { + return nil; +} + +- (NSArray*>*)dataForNode:(NSButton*)node { + SKNodeDescriptor* viewDescriptor = [self descriptorForClass:[NSView class]]; + auto* viewData = [viewDescriptor dataForNode:node]; + + NSMutableArray* data = [NSMutableArray new]; + [data addObjectsFromArray:viewData]; + [data addObject:[SKNamed + newWithName:@"NSButton" + withValue:@{ + @"enabled" : SKMutableObject(@(node.enabled)), + @"highlighted" : SKMutableObject(@(node.highlighted)), + @"title" : SKMutableObject(node.title), + }]]; + return data; +} + +- (NSDictionary*)dataMutationsForNode: + (NSButton*)node { + NSDictionary* buttonMutations = @{}; + + SKNodeDescriptor* viewDescriptor = [self descriptorForClass:[NSView class]]; + NSDictionary* viewMutations = [viewDescriptor dataMutationsForNode:node]; + + NSMutableDictionary* mutations = [NSMutableDictionary new]; + [mutations addEntriesFromDictionary:buttonMutations]; + [mutations addEntriesFromDictionary:viewMutations]; + + return mutations; +} + +- (NSArray*>*)attributesForNode:(NSScrollView*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + return [descriptor attributesForNode:node]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(NSButton*)node { + SKNodeDescriptor* viewDescriptor = [self descriptorForClass:[NSView class]]; + [viewDescriptor setHighlighted:highlighted forNode:node]; +} + +- (void)hitTest:(SKTouch*)touch forNode:(NSButton*)node { + [touch finish]; +} + +@end + +#endif diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.h b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.h new file mode 100644 index 000000000..6a1f3ea86 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +#import + +@class SKDescriptorMapper; + +@interface SKNSScrollViewDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.m b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.m new file mode 100644 index 000000000..daed87e87 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSScrollViewDescriptor.m @@ -0,0 +1,88 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import "SKNSScrollViewDescriptor.h" + +@implementation SKNSScrollViewDescriptor + +- (NSString*)identifierForNode:(NSScrollView*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + return [descriptor identifierForNode:node]; +} + +- (NSUInteger)childCountForNode:(NSScrollView*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + return [descriptor childCountForNode:node]; +} + +- (id)childForNode:(NSScrollView*)node atIndex:(NSUInteger)index { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + return [descriptor childForNode:node atIndex:index]; +} + +- (id)dataForNode:(NSScrollView*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + return [descriptor dataForNode:node]; +} + +- (id)dataMutationsForNode:(NSScrollView*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + return [descriptor dataMutationsForNode:node]; +} + +- (NSArray*>*)attributesForNode:(NSScrollView*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + return [descriptor attributesForNode:node]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(NSScrollView*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + [descriptor setHighlighted:highlighted forNode:node]; +} + +- (void)hitTest:(SKTouch*)touch forNode:(NSScrollView*)node { + bool finish = true; + for (NSInteger index = [self childCountForNode:node] - 1; index >= 0; + index--) { + id childNode = [self childForNode:node atIndex:index]; + CGRect frame; + + if ([childNode isKindOfClass:[NSViewController class]]) { + NSViewController* child = (NSViewController*)childNode; + if (child.view.isHidden) { + continue; + } + + frame = child.view.frame; + } else { + NSView* child = (NSView*)childNode; + if (child.isHidden) { + continue; + } + + frame = child.frame; + } + + frame.origin.x -= node.documentVisibleRect.origin.x; + frame.origin.y -= node.documentVisibleRect.origin.y; + + if ([touch containedIn:frame]) { + [touch continueWithChildIndex:index withOffset:frame.origin]; + finish = false; + } + } + + if (finish) { + [touch finish]; + } +} + +@end + +#endif diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.h b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.h new file mode 100644 index 000000000..5ad53f1fc --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import + +#import + +@class SKDescriptorMapper; + +@interface SKNSViewControllerDescriptor : SKNodeDescriptor + +@end + +#endif diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.m b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.m new file mode 100644 index 000000000..d6ed18c61 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewControllerDescriptor.m @@ -0,0 +1,45 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import "SKNSViewControllerDescriptor.h" + +@implementation SKNSViewControllerDescriptor + +- (NSString*)identifierForNode:(NSViewController*)node { + return [NSString stringWithFormat:@"%p", node]; +} + +- (NSUInteger)childCountForNode:(NSViewController*)node { + return 1; +} + +- (id)childForNode:(NSViewController*)node atIndex:(NSUInteger)index { + return node.view; +} + +- (void)setHighlightedForNode:(NSViewController*)node { +} + +- (NSArray*>*)attributesForNode:(NSViewController*)node { + return @[ [SKNamed newWithName:@"addr" + withValue:[NSString stringWithFormat:@"%p", node]] ]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(NSViewController*)node { + SKNodeDescriptor* descriptor = [self descriptorForClass:[NSView class]]; + [descriptor setHighlighted:highlighted forNode:node.view]; +} + +- (void)hitTest:(SKTouch*)touch forNode:(NSViewController*)node { + [touch continueWithChildIndex:0 withOffset:(CGPoint){0, 0}]; +} + +@end + +#endif diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.h b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.h new file mode 100644 index 000000000..aea11a8e9 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import + +#import + +@class SKDescriptorMapper; + +@interface SKNSViewDescriptor : SKNodeDescriptor + +@end + +#endif diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.mm b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.mm new file mode 100644 index 000000000..f73d30c0b --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSViewDescriptor.mm @@ -0,0 +1,221 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import "SKNSViewDescriptor.h" + +#import +#import +#import +#import +#import +#import + +@implementation SKNSViewDescriptor + +- (instancetype)initWithDescriptorMapper: + (id)mapper { + if (self = [super initWithDescriptorMapper:mapper]) { + initEnumDictionaries(); + } + + return self; +} + +- (NSString*)identifierForNode:(NSView*)node { + return [NSString stringWithFormat:@"%p", node]; +} + +- (NSUInteger)childCountForNode:(NSView*)node { + return [[self validChildrenForNode:node] count]; +} + +- (id)childForNode:(NSView*)node atIndex:(NSUInteger)index { + return [[self validChildrenForNode:node] objectAtIndex:index]; +} + +- (NSArray*)validChildrenForNode:(NSView*)node { + NSMutableArray* validChildren = [NSMutableArray new]; + + // Use NSViewControllers for children which responds to a different + // viewController than their parent + for (NSView* child in node.subviews) { + BOOL responderIsNSViewController = + [child.nextResponder isKindOfClass:[NSViewController class]]; + + if (!child.isHidden) { + if (responderIsNSViewController && + child.nextResponder != node.nextResponder) { + [validChildren addObject:child.nextResponder]; + } else { + [validChildren addObject:child]; + } + } + } + + return validChildren; +} + +- (NSArray*>*)dataForNode:(NSView*)node { + return [NSArray + arrayWithObjects: + [SKNamed newWithName:@"NSView" + withValue:@{ + @"frame" : SKMutableObject(node.frame), + @"bounds" : SKObject(node.bounds), + @"alphaValue" : SKMutableObject(@(node.alphaValue)), + @"tag" : @(node.tag), + }], + [SKNamed + newWithName:@"CALayer" + withValue:@{ + @"shadowColor" : SKMutableObject( + node.layer.shadowColor + ? [NSColor colorWithCGColor:node.layer.shadowColor] + : nil), + @"shadowOpacity" : + SKMutableObject(@(node.layer.shadowOpacity)), + @"shadowRadius" : SKMutableObject(@(node.layer.shadowRadius)), + @"shadowOffset" : SKMutableObject(node.layer.shadowOffset), + @"backgroundColor" : SKMutableObject( + node.layer.backgroundColor + ? [NSColor + colorWithCGColor:node.layer.backgroundColor] + : nil), + @"borderColor" : SKMutableObject( + node.layer.borderColor + ? [NSColor colorWithCGColor:node.layer.borderColor] + : nil), + @"borderWidth" : SKMutableObject(@(node.layer.borderWidth)), + @"cornerRadius" : SKMutableObject(@(node.layer.cornerRadius)), + @"masksToBounds" : + SKMutableObject(@(node.layer.masksToBounds)), + }], + nil]; +} + +- (NSDictionary*)dataMutationsForNode: + (NSView*)node { + NSDictionary* dataMutations = @{ + // NSView + @"NSView.alphaValue" : ^(NSNumber* value){ + node.alphaValue = [value floatValue]; +} +, + @"NSView.frame.origin.y": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.origin.y = [value floatValue]; + node.frame = frame; + }, + @"NSView.frame.origin.x": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.origin.x = [value floatValue]; + node.frame = frame; + }, + @"NSView.frame.size.width": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.size.width = [value floatValue]; + node.frame = frame; + }, + @"NSView.frame.size.height": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.size.width = [value floatValue]; + node.frame = frame; + }, + // CALayer + @"CALayer.shadowColor": ^(NSNumber *value) { + node.layer.shadowColor = [NSColor fromSonarValue:value].CGColor; + }, + @"CALayer.shadowOpacity": ^(NSNumber *value) { + node.layer.shadowOpacity = [value floatValue]; + }, + @"CALayer.shadowRadius": ^(NSNumber *value) { + node.layer.shadowRadius = [value floatValue]; + }, + @"CALayer.shadowOffset.width": ^(NSNumber *value) { + CGSize offset = node.layer.shadowOffset; + offset.width = [value floatValue]; + node.layer.shadowOffset = offset; + }, + @"CALayer.shadowOffset.height": ^(NSNumber *value) { + CGSize offset = node.layer.shadowOffset; + offset.height = [value floatValue]; + node.layer.shadowOffset = offset; + }, + @"CALayer.backgroundColor": ^(NSNumber *value) { + node.layer.backgroundColor = [NSColor fromSonarValue:value].CGColor; + }, + @"CALayer.borderColor": ^(NSNumber *value) { + node.layer.borderColor = [NSColor fromSonarValue:value].CGColor; + }, + @"CALayer.borderWidth": ^(NSNumber *value) { + node.layer.borderWidth = [value floatValue]; + }, + @"CALayer.cornerRadius": ^(NSNumber *value) { + node.layer.cornerRadius = [value floatValue]; + }, + @"CALayer.masksToBounds": ^(NSNumber *value) { + node.layer.masksToBounds = [value boolValue]; + }, +} +; + +return dataMutations; +} + +- (NSArray*>*)attributesForNode:(NSView*)node { + return @[ [SKNamed newWithName:@"addr" + withValue:[NSString stringWithFormat:@"%p", node]] ]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(NSView*)node { + SKHighlightOverlay* overlay = [SKHighlightOverlay sharedInstance]; + if (highlighted == YES) { + [overlay mountInView:node withFrame:node.bounds]; + } else { + [overlay unmount]; + } +} + +- (void)hitTest:(SKTouch*)touch forNode:(NSView*)node { + bool finish = true; + for (NSInteger index = [self childCountForNode:node] - 1; index >= 0; + index--) { + id childNode = [self childForNode:node atIndex:index]; + NSView* viewForNode = nil; + + if ([childNode isKindOfClass:[NSViewController class]]) { + NSViewController* child = (NSViewController*)childNode; + viewForNode = child.view; + } else { + viewForNode = (NSView*)childNode; + } + + if (viewForNode.isHidden || viewForNode.alphaValue <= 0 || + [[viewForNode class] isEqual:[SKHiddenWindow class]]) { + /*SKHiddenWindow is the pink overlay which is added in window to capture + the gestures.*/ + continue; + } + + if ([touch containedIn:viewForNode.frame]) { + [touch continueWithChildIndex:index withOffset:viewForNode.frame.origin]; + finish = false; + } + } + + if (finish) { + [touch finish]; + } +} + +static void initEnumDictionaries() {} + +@end + +#endif diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.h b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.h new file mode 100644 index 000000000..0bdba1daa --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +#import + +@class SKDescriptorMapper; + +@interface SKNSWindowDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.m b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.m new file mode 100644 index 000000000..931ad87a8 --- /dev/null +++ b/iOS/Plugins/FlipperKitPluginUtils/FlipperKitLayoutMacOSDescriptors/FlipperKitLayoutMacOSDescriptors/SKNSWindowDescriptor.m @@ -0,0 +1,58 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if FB_SONARKIT_ENABLED + +#import "SKNSWindowDescriptor.h" + +#import +#import + +@implementation SKNSWindowDescriptor + +- (NSString*)identifierForNode:(NSWindow*)node { + return [NSString stringWithFormat:@"%p", node]; +} + +- (NSUInteger)childCountForNode:(NSWindow*)node { + return [[self visibleChildrenForNode:node] count]; +} + +- (id)childForNode:(NSWindow*)node atIndex:(NSUInteger)index { + return [self visibleChildrenForNode:node][index]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(NSWindow*)node { + SKNodeDescriptor* viewDescriptor = [self descriptorForClass:[NSView class]]; + [viewDescriptor setHighlighted:highlighted forNode:node.contentView]; +} + +- (void)hitTest:(SKTouch*)touch forNode:(NSWindow*)node { + bool finish = true; + for (NSInteger index = [self childCountForNode:node] - 1; index >= 0; + index--) { + NSView* child = [self childForNode:node atIndex:index]; + + if ([touch containedIn:child.frame]) { + [touch continueWithChildIndex:index withOffset:child.frame.origin]; + finish = false; + } + } + if (finish) { + [touch finish]; + } +} + +- (NSArray*)visibleChildrenForNode:(NSWindow*)node { + NSMutableArray* children = [NSMutableArray new]; + [children addObject:node.contentView]; + return children; +} + +@end + +#endif