mirror of
				https://github.com/SoPat712/YTLitePlus.git
				synced 2025-10-31 12:54:13 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			255 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
			
		
		
	
	
			255 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
| //
 | |
| //  FLEXShortcut.m
 | |
| //  FLEX
 | |
| //
 | |
| //  Created by Tanner Bennett on 12/10/19.
 | |
| //  Copyright © 2020 FLEX Team. All rights reserved.
 | |
| //
 | |
| 
 | |
| #import "FLEXShortcut.h"
 | |
| #import "FLEXProperty.h"
 | |
| #import "FLEXPropertyAttributes.h"
 | |
| #import "FLEXIvar.h"
 | |
| #import "FLEXMethod.h"
 | |
| #import "FLEXRuntime+UIKitHelpers.h"
 | |
| #import "FLEXObjectExplorerFactory.h"
 | |
| #import "FLEXFieldEditorViewController.h"
 | |
| #import "FLEXMethodCallingViewController.h"
 | |
| #import "FLEXMetadataSection.h"
 | |
| #import "FLEXTableView.h"
 | |
| 
 | |
| 
 | |
| #pragma mark - FLEXShortcut
 | |
| 
 | |
| @interface FLEXShortcut () {
 | |
|     id _item;
 | |
| }
 | |
| 
 | |
| @property (nonatomic, readonly) FLEXMetadataKind metadataKind;
 | |
| @property (nonatomic, readonly) FLEXProperty *property;
 | |
| @property (nonatomic, readonly) FLEXMethod *method;
 | |
| @property (nonatomic, readonly) FLEXIvar *ivar;
 | |
| @property (nonatomic, readonly) id<FLEXRuntimeMetadata> metadata;
 | |
| @end
 | |
| 
 | |
| @implementation FLEXShortcut
 | |
| @synthesize defaults = _defaults;
 | |
| 
 | |
| + (id<FLEXShortcut>)shortcutFor:(id)item {
 | |
|     if ([item conformsToProtocol:@protocol(FLEXShortcut)]) {
 | |
|         return item;
 | |
|     }
 | |
|     
 | |
|     FLEXShortcut *shortcut = [self new];
 | |
|     shortcut->_item = item;
 | |
| 
 | |
|     if ([item isKindOfClass:[FLEXProperty class]]) {
 | |
|         if (shortcut.property.isClassProperty) {
 | |
|             shortcut->_metadataKind =  FLEXMetadataKindClassProperties;
 | |
|         } else {
 | |
|             shortcut->_metadataKind =  FLEXMetadataKindProperties;
 | |
|         }
 | |
|     }
 | |
|     if ([item isKindOfClass:[FLEXIvar class]]) {
 | |
|         shortcut->_metadataKind = FLEXMetadataKindIvars;
 | |
|     }
 | |
|     if ([item isKindOfClass:[FLEXMethod class]]) {
 | |
|         // We don't care if it's a class method or not
 | |
|         shortcut->_metadataKind = FLEXMetadataKindMethods;
 | |
|     }
 | |
| 
 | |
|     return shortcut;
 | |
| }
 | |
| 
 | |
| - (id)propertyOrIvarValue:(id)object {
 | |
|     return [self.metadata currentValueWithTarget:object];
 | |
| }
 | |
| 
 | |
| - (NSString *)titleWith:(id)object {
 | |
|     switch (self.metadataKind) {
 | |
|         case FLEXMetadataKindClassProperties:
 | |
|         case FLEXMetadataKindProperties:
 | |
|             // Since we're outside of the "properties" section, prepend @property for clarity.
 | |
|             return [@"@property " stringByAppendingString:[_item description]];
 | |
| 
 | |
|         default:
 | |
|             return [_item description];
 | |
|     }
 | |
| 
 | |
|     NSAssert(
 | |
|         [_item isKindOfClass:[NSString class]],
 | |
|         @"Unexpected type: %@", [_item class]
 | |
|     );
 | |
| 
 | |
|     return _item;
 | |
| }
 | |
| 
 | |
| - (NSString *)subtitleWith:(id)object {
 | |
|     if (self.metadataKind) {
 | |
|         return [self.metadata previewWithTarget:object];
 | |
|     }
 | |
| 
 | |
|     // Item is probably a string; must return empty string since
 | |
|     // these will be gathered into an array. If the object is a
 | |
|     // just a string, it doesn't get a subtitle.
 | |
|     return @"";
 | |
| }
 | |
| 
 | |
| - (void (^)(UIViewController *))didSelectActionWith:(id)object { 
 | |
|     return nil;
 | |
| }
 | |
| 
 | |
| - (UIViewController *)viewerWith:(id)object {
 | |
|     NSAssert(self.metadataKind, @"Static titles cannot be viewed");
 | |
|     return [self.metadata viewerWithTarget:object];
 | |
| }
 | |
| 
 | |
| - (UIViewController *)editorWith:(id)object forSection:(FLEXTableViewSection *)section {
 | |
|     NSAssert(self.metadataKind, @"Static titles cannot be edited");
 | |
|     return [self.metadata editorWithTarget:object section:section];
 | |
| }
 | |
| 
 | |
| - (UITableViewCellAccessoryType)accessoryTypeWith:(id)object {
 | |
|     if (self.metadataKind) {
 | |
|         return [self.metadata suggestedAccessoryTypeWithTarget:object];
 | |
|     }
 | |
| 
 | |
|     return UITableViewCellAccessoryNone;
 | |
| }
 | |
| 
 | |
| - (NSString *)customReuseIdentifierWith:(id)object {
 | |
|     if (self.metadataKind) {
 | |
|         return kFLEXCodeFontCell;
 | |
|     }
 | |
| 
 | |
|     return kFLEXMultilineCell;
 | |
| }
 | |
| 
 | |
| #pragma mark FLEXObjectExplorerDefaults
 | |
| 
 | |
| - (void)setDefaults:(FLEXObjectExplorerDefaults *)defaults {
 | |
|     _defaults = defaults;
 | |
|     
 | |
|     if (_metadataKind) {
 | |
|         self.metadata.defaults = defaults;
 | |
|     }
 | |
| }
 | |
| 
 | |
| - (BOOL)isEditable {
 | |
|     if (_metadataKind) {
 | |
|         return self.metadata.isEditable;
 | |
|     }
 | |
|     
 | |
|     return NO;
 | |
| }
 | |
| 
 | |
| - (BOOL)isCallable {
 | |
|     if (_metadataKind) {
 | |
|         return self.metadata.isCallable;
 | |
|     }
 | |
|     
 | |
|     return NO;
 | |
| }
 | |
| 
 | |
| #pragma mark - Helpers
 | |
| 
 | |
| - (FLEXProperty *)property { return _item; }
 | |
| - (FLEXMethodBase *)method { return _item; }
 | |
| - (FLEXIvar *)ivar { return _item; }
 | |
| - (id<FLEXRuntimeMetadata>)metadata { return _item; }
 | |
| 
 | |
| @end
 | |
| 
 | |
| 
 | |
| #pragma mark - FLEXActionShortcut
 | |
| 
 | |
| @interface FLEXActionShortcut ()
 | |
| @property (nonatomic, readonly) NSString *title;
 | |
| @property (nonatomic, readonly) NSString *(^subtitleFuture)(id);
 | |
| @property (nonatomic, readonly) UIViewController *(^viewerFuture)(id);
 | |
| @property (nonatomic, readonly) void (^selectionHandler)(UIViewController *, id);
 | |
| @property (nonatomic, readonly) UITableViewCellAccessoryType (^accessoryTypeFuture)(id);
 | |
| @end
 | |
| 
 | |
| @implementation FLEXActionShortcut
 | |
| @synthesize defaults = _defaults;
 | |
| 
 | |
| + (instancetype)title:(NSString *)title
 | |
|              subtitle:(NSString *(^)(id))subtitle
 | |
|                viewer:(UIViewController *(^)(id))viewer
 | |
|         accessoryType:(UITableViewCellAccessoryType (^)(id))type {
 | |
|     return [[self alloc] initWithTitle:title subtitle:subtitle viewer:viewer selectionHandler:nil accessoryType:type];
 | |
| }
 | |
| 
 | |
| + (instancetype)title:(NSString *)title
 | |
|              subtitle:(NSString * (^)(id))subtitle
 | |
|      selectionHandler:(void (^)(UIViewController *, id))tapAction
 | |
|         accessoryType:(UITableViewCellAccessoryType (^)(id))type {
 | |
|     return [[self alloc] initWithTitle:title subtitle:subtitle viewer:nil selectionHandler:tapAction accessoryType:type];
 | |
| }
 | |
| 
 | |
| - (id)initWithTitle:(NSString *)title
 | |
|            subtitle:(id)subtitleFuture
 | |
|              viewer:(id)viewerFuture
 | |
|    selectionHandler:(id)tapAction
 | |
|       accessoryType:(id)accessoryTypeFuture {
 | |
|     NSParameterAssert(title.length);
 | |
| 
 | |
|     self = [super init];
 | |
|     if (self) {
 | |
|         id nilBlock = ^id (id obj) { return nil; };
 | |
|         
 | |
|         _title = title;
 | |
|         _subtitleFuture = subtitleFuture ?: nilBlock;
 | |
|         _viewerFuture = viewerFuture ?: nilBlock;
 | |
|         _selectionHandler = tapAction;
 | |
|         _accessoryTypeFuture = accessoryTypeFuture ?: nilBlock;
 | |
|     }
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| - (NSString *)titleWith:(id)object {
 | |
|     return self.title;
 | |
| }
 | |
| 
 | |
| - (NSString *)subtitleWith:(id)object {
 | |
|     if (self.defaults.wantsDynamicPreviews) {
 | |
|         return self.subtitleFuture(object);
 | |
|     }
 | |
|     
 | |
|     return nil;
 | |
| }
 | |
| 
 | |
| - (void (^)(UIViewController *))didSelectActionWith:(id)object {
 | |
|     if (self.selectionHandler) {
 | |
|         return ^(UIViewController *host) {
 | |
|             self.selectionHandler(host, object);
 | |
|         };
 | |
|     }
 | |
|     
 | |
|     return nil;
 | |
| }
 | |
| 
 | |
| - (UIViewController *)viewerWith:(id)object {
 | |
|     return self.viewerFuture(object);
 | |
| }
 | |
| 
 | |
| - (UITableViewCellAccessoryType)accessoryTypeWith:(id)object {
 | |
|     return self.accessoryTypeFuture(object);
 | |
| }
 | |
| 
 | |
| - (NSString *)customReuseIdentifierWith:(id)object {
 | |
|     if (!self.subtitleFuture(object)) {
 | |
|         // The text is more centered with this style if there is no subtitle
 | |
|         return kFLEXDefaultCell;
 | |
|     }
 | |
| 
 | |
|     return nil;
 | |
| }
 | |
| 
 | |
| - (BOOL)isEditable { return NO; }
 | |
| - (BOOL)isCallable { return NO; }
 | |
| 
 | |
| @end
 | 
