diff --git a/iOS/Assets.car b/iOS/Assets.car index 6237eca..08c543a 100644 Binary files a/iOS/Assets.car and b/iOS/Assets.car differ diff --git a/iOS/Cartridge.png b/iOS/Cartridge.png index 61e83bf..b637d79 100644 Binary files a/iOS/Cartridge.png and b/iOS/Cartridge.png differ diff --git a/iOS/Cartridge64.png b/iOS/Cartridge64.png new file mode 100644 index 0000000..add728c Binary files /dev/null and b/iOS/Cartridge64.png differ diff --git a/iOS/ColorCartridge.png b/iOS/ColorCartridge.png index 349e780..96447dd 100644 Binary files a/iOS/ColorCartridge.png and b/iOS/ColorCartridge.png differ diff --git a/iOS/ColorCartridge64.png b/iOS/ColorCartridge64.png new file mode 100644 index 0000000..9342cf3 Binary files /dev/null and b/iOS/ColorCartridge64.png differ diff --git a/iOS/GBCheatsController.m b/iOS/GBCheatsController.m index 290ef77..4d20186 100644 --- a/iOS/GBCheatsController.m +++ b/iOS/GBCheatsController.m @@ -119,9 +119,17 @@ [button sizeToFit]; CGRect frame = button.frame; frame.size.width = ceil(frame.size.width + (label? 4 : 0)); + if (@available(iOS 19.0, *)) { + if (label) { + frame.size.width += 12; + } + } frame.size.height = 28; button.frame = frame; - return [[UIBarButtonItem alloc] initWithCustomView:button]; + UIView *wrapper = [[UIView alloc] initWithFrame:button.bounds]; + [wrapper addSubview:button]; + UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:wrapper]; + return item; } return [[UIBarButtonItem alloc] initWithTitle:label style:UIBarButtonItemStylePlain target:target action:action]; } @@ -178,28 +186,37 @@ hasSFSymbols = true; } - self.toolbarItems = @[ - hasSFSymbols? - [self.class buttonWithLabel:nil - imageWithName:@"square.and.arrow.up" - target:self - action:@selector(exportCheats)] : - [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction - target:self - action:@selector(exportCheats)], - [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace - target:nil - action:NULL], - [self.class buttonWithLabel:@"Import" - imageWithName:@"square.and.arrow.down" + UIBarButtonItem *export = hasSFSymbols? + [self.class buttonWithLabel:nil + imageWithName:@"square.and.arrow.up" target:self - action:@selector(importCheats)], - [self.class buttonWithLabel:@"Add" - imageWithName:@"plus" - target:self - action:@selector(addCheat)], - - ]; + action:@selector(exportCheats)] : + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction + target:self + action:@selector(exportCheats)]; + + UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:NULL]; + UIBarButtonItem *import = [self.class buttonWithLabel:@"Import" + imageWithName:@"square.and.arrow.down" + target:self + action:@selector(importCheats)]; + + UIBarButtonItem *add = [self.class buttonWithLabel:@"Add" + imageWithName:@"plus" + target:self + action:@selector(addCheat)]; + + if (@available(iOS 19.0, *)) { + self.toolbarItems = @[export, + flexItem, + import, [UIBarButtonItem fixedSpaceItemOfWidth:0], add]; + } else { + self.toolbarItems = @[export, + flexItem, + import, add]; + } _gb = gb; return self; diff --git a/iOS/GBMenuViewController.m b/iOS/GBMenuViewController.m index ca7679d..ef92296 100644 --- a/iOS/GBMenuViewController.m +++ b/iOS/GBMenuViewController.m @@ -283,7 +283,12 @@ static NSString *const tips[] = { button.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.3]; button.layer.borderWidth = 2.0; button.layer.borderColor = [UIColor systemBlueColor].CGColor; - button.layer.cornerRadius = 8.0; + if (@available(iOS 19.0, *)) { + button.layer.cornerRadius = 32.0; + } + else { + button.layer.cornerRadius = 8.0; + } } else { button.backgroundColor = [UIColor clearColor]; diff --git a/iOS/GBROMViewController.m b/iOS/GBROMViewController.m index 692f845..f2c416d 100644 --- a/iOS/GBROMViewController.m +++ b/iOS/GBROMViewController.m @@ -247,8 +247,8 @@ if ([newName containsString:@"/"]) { [self.tableView reloadData]; - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"You can't use a name that contains “/”. Please choose another name." - message:nil + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Invalid Name" + message:@"You can't use a name that contains “/”. Please choose another name." preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel diff --git a/iOS/GBSettingsViewController.m b/iOS/GBSettingsViewController.m index 7841a0a..9a4e204 100644 --- a/iOS/GBSettingsViewController.m +++ b/iOS/GBSettingsViewController.m @@ -22,6 +22,7 @@ static NSString const *typeLightTemp = @"typeLightTemp"; NSArray *_structure; UINavigationController *_detailsNavigation; NSArray *> *_themes; // For prewarming + bool _iPadRoot; } + (UIImage *)settingsImageNamed:(NSString *)name @@ -187,7 +188,7 @@ static NSString const *typeLightTemp = @"typeLightTemp"; @{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"HQ2x", @"value": @"HQ2x"}, @{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"OmniScale", @"value": @"OmniScale"}, @{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"OmniScale Legacy", @"value": @"OmniScaleLegacy"}, - @{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"AA OmniScale Legacy", @"value": @"AAOmniScaleLegacy"}, + @{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"Anti-aliased OmniScale Legacy", @"value": @"AAOmniScaleLegacy"}, ] }, ] @@ -434,12 +435,20 @@ static NSString const *typeLightTemp = @"typeLightTemp"; return controller; } - UISplitViewController *split = [[UISplitViewController alloc] init]; + UISplitViewController *split = nil; + if (@available(iOS 14.5, *)) { + split = [[UISplitViewController alloc] initWithStyle:UISplitViewControllerStyleDoubleColumn]; + split.displayModeButtonVisibility = UISplitViewControllerDisplayModeButtonVisibilityNever; + } + else { + split = [[UISplitViewController alloc] init]; + } UIViewController *blank = [[UIViewController alloc] init]; blank.view.backgroundColor = root.view.backgroundColor; root->_detailsNavigation = [[UINavigationController alloc] initWithRootViewController:blank]; split.viewControllers = @[controller, root->_detailsNavigation]; split.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; + root->_iPadRoot = true; return split; } @@ -729,7 +738,6 @@ static id ValueForItem(NSDictionary *item) - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSDictionary *item = [self itemForIndexPath:indexPath]; - UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; cell.textLabel.text = item[@"title"]; @@ -833,6 +841,13 @@ static id ValueForItem(NSDictionary *item) cell.separatorInset = UIEdgeInsetsZero; } cell.imageView.image = item[@"image"]; + if (@available(iOS 19.0, *)) { + if (_iPadRoot) { + cell.textLabel.textColor = [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) { + return cell.isSelected? [UIColor whiteColor] : [UIColor labelColor]; + }]; + } + } return cell; } diff --git a/iOS/GBSlider.m b/iOS/GBSlider.m index add80bc..736cbbe 100644 --- a/iOS/GBSlider.m +++ b/iOS/GBSlider.m @@ -21,11 +21,15 @@ static inline void temperature_tint(double temperature, double *r, double *g, do } @implementation GBSlider +{ + GBSliderStyle _style; +} - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; [self addTarget:self action:@selector(valueChanged) forControlEvents:UIControlEventValueChanged]; + self.style = GBSliderStyleTemperature; return self; } @@ -97,6 +101,10 @@ static inline void temperature_tint(double temperature, double *r, double *g, do - (void)drawRect:(CGRect)rect { + bool solarium = false; + if (@available(iOS 19.0, *)) { + solarium = true; + } CGSize size = self.bounds.size; UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(2, round(size.height / 2 - 1.5), size.width - 4, 3) cornerRadius:4]; if (_style != GBSliderStyleHue) { @@ -107,7 +115,7 @@ static inline void temperature_tint(double temperature, double *r, double *g, do [path appendPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(size.width - 3, 12, 3, size.height - 24) cornerRadius:4]]; } if (_style == GBSliderStyleHue) { - UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(3, round(size.height / 2 - 1.5) + 1, size.width - 6, 1) cornerRadius:4]; + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(3, round(size.height / 2 - 1.5) + 1 - solarium, size.width - 6, solarium? 2 : 1) cornerRadius:8]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); [path addClip]; @@ -124,11 +132,12 @@ static inline void temperature_tint(double temperature, double *r, double *g, do }; CFArrayRef colorsArray = CFArrayCreate(NULL, (const void **)colors, 7, &kCFTypeArrayCallBacks); CGGradientRef gradient = CGGradientCreateWithColors(colorspace, colorsArray, NULL); + unsigned spacing = solarium? 16 : 3; CGContextDrawLinearGradient(context, gradient, - (CGPoint){3, 0}, - (CGPoint){size.width - 3, 0}, - 0); + (CGPoint){spacing, 0}, + (CGPoint){size.width - spacing, 0}, + kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); CFRelease(gradient); CFRelease(colorsArray); CFRelease(colorspace); @@ -139,11 +148,44 @@ static inline void temperature_tint(double temperature, double *r, double *g, do green:120 / 255.0 blue:130 / 255.0 alpha:70 / 255.0] set]; - [path fill]; + if (!solarium) { + [path fill]; + } [super drawRect:rect]; } +- (void)setStyle:(GBSliderStyle)style +{ + _style = style; + if (@available(iOS 26.0, *)) { + switch (_style) { + case GBSliderStyleTemperature: + case GBSliderStyleTicks: { + UISliderTrackConfiguration *conf = [UISliderTrackConfiguration configurationWithNumberOfTicks:3]; + conf.allowsTickValuesOnly = false; + conf.neutralValue = 0.5; + self.trackConfiguration = conf; + self.maximumTrackTintColor = nil; + self.minimumTrackTintColor = nil; + break; + } + case GBSliderStyleHue: { + UISliderTrackConfiguration *conf = [UISliderTrackConfiguration configurationWithNumberOfTicks:0]; + conf.allowsTickValuesOnly = false; + self.trackConfiguration = conf; + self.minimumTrackTintColor = [UIColor clearColor]; + break; + } + } + } +} + +- (GBSliderStyle)style +{ + return _style; +} + - (void)setFrame:(CGRect)frame { [super setFrame:frame]; diff --git a/iOS/GBStatesViewController.m b/iOS/GBStatesViewController.m index e8eb741..a6d8efa 100644 --- a/iOS/GBStatesViewController.m +++ b/iOS/GBStatesViewController.m @@ -39,8 +39,8 @@ - (void)viewDidLoad { [super viewDidLoad]; - self.view.bounds = CGRectMake(0, 0, 0x300, 0x300); - UIView *root = self.view; + UIView *root = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0x300, 0x300)]; + [self.view addSubview:root]; for (unsigned i = 0; i < 9; i++) { unsigned x = i % 3; unsigned y = i / 3; @@ -114,6 +114,12 @@ [self presentViewController:controller animated:true completion:nil]; } +- (void)viewWillLayoutSubviews +{ + [super viewWillLayoutSubviews]; + self.view.subviews.firstObject.frame = [self.view.safeAreaLayoutGuide layoutFrame]; +} + - (NSString *)title { return @"Save States"; diff --git a/iOS/GBThemePreviewController.m b/iOS/GBThemePreviewController.m index 1260994..efde9e6 100644 --- a/iOS/GBThemePreviewController.m +++ b/iOS/GBThemePreviewController.m @@ -65,8 +65,8 @@ - (void)showPopup { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Apply “%@” as the current theme?", _verticalLayout.theme.name] - message:nil + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Apply Theme" + message:[NSString stringWithFormat:@"Apply “%@” as the current theme?", _verticalLayout.theme.name] preferredStyle:[UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad? UIAlertControllerStyleAlert : UIAlertControllerStyleActionSheet]; if (false) { diff --git a/iOS/GBViewController.m b/iOS/GBViewController.m index 9a3134b..6d63e5b 100644 --- a/iOS/GBViewController.m +++ b/iOS/GBViewController.m @@ -1814,8 +1814,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response { UIAlertControllerStyle style = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad? UIAlertControllerStyleAlert : UIAlertControllerStyleActionSheet; - GBCheckableAlertController *menu = [GBCheckableAlertController alertControllerWithTitle:@"Connect which accessory?" - message:nil + GBCheckableAlertController *menu = [GBCheckableAlertController alertControllerWithTitle:@"Connect Accessory" + message:@"Choose an accessory to connect." preferredStyle:style]; [menu addAction:[UIAlertAction actionWithTitle:@"None" style:UIAlertActionStyleDefault diff --git a/iOS/Info.plist b/iOS/Info.plist index a1694d7..ad7bbf7 100644 --- a/iOS/Info.plist +++ b/iOS/Info.plist @@ -63,6 +63,7 @@ CFBundleTypeIconFiles + Cartridge64.png Cartridge.png CFBundleTypeExtensions @@ -81,6 +82,7 @@ CFBundleTypeIconFiles + ColorCartridge64.png ColorCartridge.png CFBundleTypeExtensions @@ -99,6 +101,7 @@ CFBundleTypeIconFiles + ColorCartridge64.png ColorCartridge.png CFBundleTypeExtensions @@ -157,6 +160,12 @@ gb + UTTypeIconFiles + + Cartridge64 + Cartridge + + UTTypeConformsTo @@ -174,6 +183,11 @@ gbc + UTTypeIconFiles + + ColorCartridge64 + ColorCartridge + UTTypeConformsTo @@ -191,6 +205,11 @@ isx + UTTypeIconFiles + + ColorCartridge64 + ColorCartridge + UTTypeConformsTo diff --git a/iOS/button2Pressed-tint@2x.png b/iOS/button2Pressed-tint@2x.png index 38084ca..81e336a 100644 Binary files a/iOS/button2Pressed-tint@2x.png and b/iOS/button2Pressed-tint@2x.png differ diff --git a/iOS/button2Pressed-tint@3x.png b/iOS/button2Pressed-tint@3x.png index 4bb86a7..893b50e 100644 Binary files a/iOS/button2Pressed-tint@3x.png and b/iOS/button2Pressed-tint@3x.png differ diff --git a/iOS/button@2x.png b/iOS/button@2x.png index 5737256..16a9c28 100644 Binary files a/iOS/button@2x.png and b/iOS/button@2x.png differ diff --git a/iOS/button@3x.png b/iOS/button@3x.png index 3d1c6ca..1a63ce3 100644 Binary files a/iOS/button@3x.png and b/iOS/button@3x.png differ diff --git a/iOS/buttonPressed@2x.png b/iOS/buttonPressed@2x.png index 5802cda..b36d64b 100644 Binary files a/iOS/buttonPressed@2x.png and b/iOS/buttonPressed@2x.png differ diff --git a/iOS/buttonPressed@3x.png b/iOS/buttonPressed@3x.png index 7ae742b..2ce934f 100644 Binary files a/iOS/buttonPressed@3x.png and b/iOS/buttonPressed@3x.png differ diff --git a/iOS/dpad-tint@2x.png b/iOS/dpad-tint@2x.png index f4b5fac..125b0b9 100644 Binary files a/iOS/dpad-tint@2x.png and b/iOS/dpad-tint@2x.png differ diff --git a/iOS/dpad-tint@3x.png b/iOS/dpad-tint@3x.png index 512a89e..c434b01 100644 Binary files a/iOS/dpad-tint@3x.png and b/iOS/dpad-tint@3x.png differ diff --git a/iOS/dpadShadowDiagonal@3x.png b/iOS/dpadShadowDiagonal@3x.png index b4cab27..6fe0c1c 100644 Binary files a/iOS/dpadShadowDiagonal@3x.png and b/iOS/dpadShadowDiagonal@3x.png differ diff --git a/iOS/logo@2x.png b/iOS/logo@2x.png index 1a47ce7..60b7e74 100644 Binary files a/iOS/logo@2x.png and b/iOS/logo@2x.png differ diff --git a/iOS/logo@3x.png b/iOS/logo@3x.png index 0f9f0b5..a3f354c 100644 Binary files a/iOS/logo@3x.png and b/iOS/logo@3x.png differ diff --git a/iOS/main.m b/iOS/main.m index 7f5c8bd..17321ed 100644 --- a/iOS/main.m +++ b/iOS/main.m @@ -146,6 +146,9 @@ int main(int argc, char * argv[]) @"Manual": @NO, }, }, + + // Forces iOS to use Solarium even when linking against older SDKs + @"com.apple.SwiftUI.IgnoreSolariumLinkedOnCheck": @YES, }]; if (![[defaults stringForKey:@"GBThemesVersion"] isEqualToString:@(GB_VERSION)]) { diff --git a/iOS/swipepad-tint@2x.png b/iOS/swipepad-tint@2x.png index 62a9d99..08df0ea 100644 Binary files a/iOS/swipepad-tint@2x.png and b/iOS/swipepad-tint@2x.png differ diff --git a/iOS/swipepad-tint@3x.png b/iOS/swipepad-tint@3x.png index 2017aca..e011c00 100644 Binary files a/iOS/swipepad-tint@3x.png and b/iOS/swipepad-tint@3x.png differ diff --git a/iOS/swipepad@2x.png b/iOS/swipepad@2x.png index 79c41b8..7ebeda3 100644 Binary files a/iOS/swipepad@2x.png and b/iOS/swipepad@2x.png differ diff --git a/iOS/swipepad@3x.png b/iOS/swipepad@3x.png index 0f727d4..65d3b46 100644 Binary files a/iOS/swipepad@3x.png and b/iOS/swipepad@3x.png differ