mirror of
https://github.com/SoPat712/YTLitePlus.git
synced 2025-08-24 11:28:52 -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
|