diff --git a/Makefile b/Makefile index ce20f77..7a72b21 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,12 @@ -ARCHS = armv7 armv7s arm64 arm64e -TARGET = iphone:clang:11.2:5.0 +SIMULATOR ?= 0 + +ifeq ($(SIMULATOR), 1) +ARCHS = i386 x86_64 +TARGET = simulator:clang:12.1:9.0 +else +ARCHS = armv7 armv7s arm64 arm64e +TARGET = iphone:clang:12.1.2:9.0 +endif GO_EASY_ON_ME = 0 FINALPACKAGE = 1 @@ -15,6 +22,10 @@ $(LIBRARY_NAME)_FRAMEWORKS = UIKit CoreGraphics CoreFoundation $(LIBRARY_NAME)_PRIVATE_FRAMEWORKS = Preferences $(LIBRARY_NAME)_CFLAGS += -fobjc-arc -I$(INCLUDES) -IPrefix.pch +ifeq ($(SIMULATOR), 1) +$(LIBRARY_NAME)_CFLAGS += -D SIMULATOR=1 +endif + after-install:: install.exec "killall -9 Preferences" diff --git a/create_universal.sh b/create_universal.sh new file mode 100755 index 0000000..3c457ef --- /dev/null +++ b/create_universal.sh @@ -0,0 +1,8 @@ +set -e + +make + +make SIMULATOR=1 + +lipo ./.theos/obj/iphone_simulator/libCSColorPicker.dylib ./.theos/obj/libCSColorPicker.dylib -output ./libCSColorPicker.dylib -create +# Creates a dylib that can be properly linked from tweaks targetting both simulator and real devices diff --git a/install_simulator.sh b/install_simulator.sh new file mode 100755 index 0000000..3c0af49 --- /dev/null +++ b/install_simulator.sh @@ -0,0 +1,36 @@ +set -e + +make SIMULATOR=1 + +THEOS_OBJ_DIR=./.theos/obj/iphone_simulator + +#install libCSColorPicker into all additionally installed simulators + +for runtime in /Library/Developer/CoreSimulator/Profiles/Runtimes/* +do + if [ -d "$runtime" ]; then + echo "Installing libCSColorPicker to $runtime" + SIMULATOR_ROOT=$runtime/Contents/Resources/RuntimeRoot + SIMULATOR_LIB_PATH=$SIMULATOR_ROOT/usr/lib + + if [ -d "$SIMULATOR_LIB_PATH" ]; then + sudo rm -rf "$SIMULATOR_LIB_PATH/libCSColorPicker.dylib" ||: + sudo cp -rf "$THEOS_OBJ_DIR/libCSColorPicker.dylib" "$SIMULATOR_LIB_PATH" + fi + fi +done + +#install libCSColorPicker into the simulator that ships with Xcode + +for SIMULATOR_ROOT in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot +do + if [ -d "$SIMULATOR_ROOT" ]; then + echo "Installing libCSColorPicker to $SIMULATOR_ROOT" + SIMULATOR_LIB_PATH=$SIMULATOR_ROOT/usr/lib + + if [ -d "$SIMULATOR_LIB_PATH" ]; then + sudo rm -rf "$SIMULATOR_LIB_PATH/libCSColorPicker.dylib" ||: + sudo cp -rf "$THEOS_OBJ_DIR/libCSColorPicker.dylib" "$SIMULATOR_LIB_PATH" + fi + fi +done diff --git a/source/Cells/CSColorDisplayCell.m b/source/Cells/CSColorDisplayCell.m index ba3901d..590e3c3 100644 --- a/source/Cells/CSColorDisplayCell.m +++ b/source/Cells/CSColorDisplayCell.m @@ -5,6 +5,12 @@ #import +#import + +// get the associated view controller from a UIView +// credits https://stackoverflow.com/questions/1372977/given-a-view-how-do-i-get-its-viewcontroller/24590678 +#define UIViewParentController(__view) ({ UIResponder *__responder = __view; while ([__responder isKindOfClass:[UIView class]]) __responder = [__responder nextResponder]; (UIViewController *)__responder; }) + @implementation CSColorDisplayCell @synthesize cellColorDisplay; @@ -26,14 +32,13 @@ - (void)refreshCellContentsWithSpecifier:(PSSpecifier *)specifier { } - (void)refreshCellWithColor:(UIColor *)color { - + if (!color) { color = [self previewColor]; } else { - [self.specifier setProperty:color.cscp_hexStringWithAlpha forKey:@"hexValue"]; - [self.specifier setProperty:color forKey:@"color"]; - } - + [self.specifier setProperty:color.cscp_hexStringWithAlpha forKey:@"hexValue"]; + [self.specifier setProperty:color forKey:@"color"]; + } self.cellColorDisplay.backgroundColor = color; self.detailTextLabel.text = [NSString stringWithFormat:@"#%@", [color cscp_hexString]]; } @@ -99,9 +104,9 @@ - (UIColor *)previewColor { NSDictionary *prefsDict, *defaultsDict; UIColor *color; - userPrefsPath = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", [self.specifier propertyForKey:@"defaults"]]; - defaultsPlistPath = [[NSBundle bundleWithPath:[self.specifier propertyForKey:@"defaultsPath"]] pathForResource:@"defaults" ofType:@"plist"]; - motuumLSDefaultsPath = [[NSBundle bundleWithPath:@"/Library/PreferenceBundles/motuumLS.bundle"] pathForResource:@"com.creaturesurvive.motuumls_defaults" ofType:@"plist"]; + userPrefsPath = rPath([NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", [self.specifier propertyForKey:@"defaults"]]); + defaultsPlistPath = rPath([[NSBundle bundleWithPath:[self.specifier propertyForKey:@"defaultsPath"]] pathForResource:@"defaults" ofType:@"plist"]); + motuumLSDefaultsPath = rPath([[NSBundle bundleWithPath:@"/Library/PreferenceBundles/motuumLS.bundle"] pathForResource:@"com.creaturesurvive.motuumls_defaults" ofType:@"plist"]); if ((prefsDict = [NSDictionary dictionaryWithContentsOfFile:userPrefsPath])) { hex = prefsDict[[self.specifier propertyForKey:@"key"]]; @@ -119,7 +124,7 @@ - (UIColor *)previewColor { hex = [self.specifier propertyForKey:@"fallback"] ? : @"FF0000"; } - color = [UIColor cscp_colorFromHexString:hex]; + color = [UIColor cscp_colorFromHexString:hex]; [self.specifier setProperty:hex forKey:@"hexValue"]; [self.specifier setProperty:color forKey:@"color"]; diff --git a/source/Cells/CSGradientDisplayCell.m b/source/Cells/CSGradientDisplayCell.m index dd9d612..1dfd1f4 100644 --- a/source/Cells/CSGradientDisplayCell.m +++ b/source/Cells/CSGradientDisplayCell.m @@ -5,6 +5,10 @@ #import +// get the associated view controller from a UIView +// credits https://stackoverflow.com/questions/1372977/given-a-view-how-do-i-get-its-viewcontroller/24590678 +#define UIViewParentController(__view) ({ UIResponder *__responder = __view; while ([__responder isKindOfClass:[UIView class]]) __responder = [__responder nextResponder]; (UIViewController *)__responder; }) + @implementation CSGradientDisplayCell @synthesize cellColorDisplay, gradient; @@ -27,7 +31,7 @@ - (void)refreshCellContentsWithSpecifier:(PSSpecifier *)specifier { } - (void)refreshCellWithColors:(NSArray *)newColors { - + if (!newColors) { newColors = [self previewColors]; } else { @@ -35,7 +39,7 @@ - (void)refreshCellWithColors:(NSArray *)newColors { [self.specifier setProperty:newColors.lastObject forKey:@"color"]; [self.specifier setProperty:newColors forKey:@"colors"]; } - + self.detailTextLabel.text = nil; NSMutableArray *colors = [NSMutableArray new]; for (UIColor *color in newColors) { @@ -69,13 +73,13 @@ - (void)configureColorDisplay { self.cellColorDisplay.layer.cornerRadius = CGRectGetHeight(self.cellColorDisplay.frame) / 4; self.cellColorDisplay.layer.borderWidth = 2; self.cellColorDisplay.layer.borderColor = [UIColor lightGrayColor].CGColor; - + self.gradient = [CAGradientLayer layer]; self.gradient.frame = self.cellColorDisplay.bounds; self.gradient.cornerRadius = self.cellColorDisplay.layer.cornerRadius; self.gradient.startPoint = CGPointMake(0, 0.5); self.gradient.endPoint = CGPointMake(1, 0.5); - + [self.cellColorDisplay.layer addSublayer:self.gradient]; [self setAccessoryView:self.cellColorDisplay]; } diff --git a/source/Controllers/CSColorPickerViewController.m b/source/Controllers/CSColorPickerViewController.m index 1d7b35a..a65202d 100644 --- a/source/Controllers/CSColorPickerViewController.m +++ b/source/Controllers/CSColorPickerViewController.m @@ -5,6 +5,8 @@ #import +#import + #define SLIDER_HEIGHT 40.0 #define GRADIENT_HEIGHT 50.0 #define ALERT_TITLE @"Set Hex Color" @@ -201,9 +203,9 @@ - (void)setColor:(UIColor *)color animated:(BOOL)animated{ [self setColorInformationTextWithInformationFromColor:color]; }; - if (animated) + if (animated) [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ update(); } completion:nil]; - else + else update(); } @@ -211,7 +213,7 @@ - (void)setColorInformationTextWithInformationFromColor:(UIColor *)color { [self.colorInformationLable setText:[self informationStringForColor:color]]; UIColor *legibilityTint = (!color.cscp_light && color.cscp_alpha > 0.5) ? UIColor.whiteColor : UIColor.blackColor; UIColor *shadowColor = legibilityTint == UIColor.blackColor ? UIColor.whiteColor : UIColor.blackColor; - + [self.colorInformationLable setTextColor:legibilityTint]; [self.colorInformationLable.layer setShadowColor:[shadowColor CGColor]]; [self.colorInformationLable setFont:[UIFont boldSystemFontOfSize:[self isLandscape] ? 16 : 20]]; @@ -234,10 +236,11 @@ - (void)saveColor { NSString *key = [self.specifier propertyForKey:@"key"]; NSString *defaults = [self.specifier propertyForKey:@"defaults"]; - NSString *plistPath = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", defaults]; + NSString *plistPath = rPath([NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", defaults]); NSMutableDictionary *prefsDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath] ? : [NSMutableDictionary new]; + UITableViewCell *cell = [self.specifier propertyForKey:@"cellObject"]; - + // save via plist [prefsDict setObject:saveValue forKey:key]; [prefsDict writeToFile:plistPath atomically:NO]; @@ -248,19 +251,19 @@ - (void)saveColor { // save in domain for NSUserDefaults [[NSUserDefaults standardUserDefaults] setObject:saveValue forKey:key inDomain:defaults]; - + if (cell && [cell isKindOfClass:[CSColorDisplayCell class]]) [(CSColorDisplayCell *)cell refreshCellWithColor:[self colorForRGBSliders]]; else if (cell && [cell isKindOfClass:[CSGradientDisplayCell class]]) [(CSGradientDisplayCell *)cell refreshCellWithColors:self.colors]; - + if ([self.specifier propertyForKey:@"PostNotification"]) CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), (CFStringRef)[self.specifier propertyForKey:@"PostNotification"], (CFStringRef)[self.specifier propertyForKey:@"PostNotification"], NULL, YES); - + if ([self.specifier propertyForKey:@"callbackAction"]) { SEL callback = NSSelectorFromString([self.specifier propertyForKey:@"callbackAction"]); if ([self.specifier.target respondsToSelector:callback]) { diff --git a/source/simulator.h b/source/simulator.h new file mode 100644 index 0000000..8cbb074 --- /dev/null +++ b/source/simulator.h @@ -0,0 +1,14 @@ +#ifdef SIMULATOR + +@interface UIView () +@property(nonatomic, readonly) UIEdgeInsets safeAreaInsets; //9.2 sdk needed for simulator and this property was added in 11 +@end + +extern NSString* simulatorPath(NSString* path); +#define rPath(args ...) ({ simulatorPath(args); }) + +#else + +#define rPath(args ...) ({ args; }) + +#endif diff --git a/source/simulator.m b/source/simulator.m new file mode 100644 index 0000000..e409565 --- /dev/null +++ b/source/simulator.m @@ -0,0 +1,19 @@ +#ifdef SIMULATOR + +extern NSString *UISystemRootDirectory(); + +#define currentUser NSHomeDirectory().pathComponents[2] + +NSString* simulatorPath(NSString* path) +{ + if([path hasPrefix:@"/var/mobile/"] || [path hasPrefix:@"/User/"]) + { + NSString* simulatorID = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject].pathComponents[7]; + NSString* strippedPath = [path stringByReplacingOccurrencesOfString:@"/var/mobile/" withString:@""]; + strippedPath = [strippedPath stringByReplacingOccurrencesOfString:@"/User/" withString:@""]; + return [NSString stringWithFormat:@"/Users/%@/Library/Developer/CoreSimulator/Devices/%@/data/%@", currentUser, simulatorID, strippedPath]; + } + return [UISystemRootDirectory() stringByAppendingPathComponent:path]; +} + +#endif