SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 8ea5e8d74db335f5446e27ea05eed96adf4ef234 parent 6ddc3b0f0ab845158c8ad6e472af4cd4075b8133 Author: Lior Halphon <LIJI32@gmail.com> Date: Sat, 21 Jan 2023 22:51:30 +0200 More ROM management features Diffstat:
| M | Cocoa/GBCheatWindowController.m | 2 | +- |
| M | JoyKit/JOYElement.m | 2 | +- |
| M | JoyKit/JOYFullReportElement.m | 2 | +- |
| M | iOS/GBLoadROMTableViewController.m | 73 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
| M | iOS/GBROMManager.h | 2 | ++ |
| M | iOS/GBROMManager.m | 47 | +++++++++++++++++++++++++++++++++++++++++++++-- |
| M | iOS/GBViewController.h | 2 | +- |
7 files changed, 122 insertions(+), 8 deletions(-)
diff --git a/Cocoa/GBCheatWindowController.m b/Cocoa/GBCheatWindowController.m @@ -42,7 +42,7 @@ return nil; } -- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row +- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { size_t cheatCount; GB_gameboy_t *gb = self.document.gameboy; diff --git a/JoyKit/JOYElement.m b/JoyKit/JOYElement.m @@ -126,7 +126,7 @@ return self->_element == object; } -- (id)copyWithZone:(nullable NSZone *)zone; +- (id)copyWithZone:(NSZone *)zone; { return self; } diff --git a/JoyKit/JOYFullReportElement.m b/JoyKit/JOYFullReportElement.m @@ -67,7 +67,7 @@ return self.uniqueID == object.uniqueID; } -- (id)copyWithZone:(nullable NSZone *)zone; +- (id)copyWithZone:(NSZone *)zone; { return self; } diff --git a/iOS/GBLoadROMTableViewController.m b/iOS/GBLoadROMTableViewController.m @@ -6,6 +6,9 @@ @end @implementation GBLoadROMTableViewController +{ + NSIndexPath *_renamingPath; +} - (instancetype)init { @@ -75,7 +78,7 @@ - (UIModalPresentationStyle)modalPresentationStyle { - return UIModalPresentationFormSheet; + return UIModalPresentationOverFullScreen; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath @@ -87,7 +90,7 @@ preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive - handler:^(UIAlertAction * _Nonnull action) { + handler:^(UIAlertAction *action) { [[GBROMManager sharedManager] deleteROM:rom]; [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; if ([[GBROMManager sharedManager].currentROM isEqualToString:rom]) { @@ -101,4 +104,70 @@ [self presentViewController:alert animated:true completion:nil]; } +- (void)renameRow:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; + UITextField *field = [[UITextField alloc] initWithFrame:cell.textLabel.frame]; + field.font = cell.textLabel.font; + field.text = cell.textLabel.text; + cell.textLabel.text = @""; + [[cell.textLabel superview] addSubview:field]; + [field becomeFirstResponder]; + [field selectAll:nil]; + _renamingPath = indexPath; + [field addTarget:self action:@selector(doneRename:) forControlEvents:UIControlEventEditingDidEnd | UIControlEventEditingDidEndOnExit]; +} + +- (void)doneRename:(UITextField *)sender +{ + if (!_renamingPath) return; + NSString *newName = sender.text; + NSString *oldName = [GBROMManager sharedManager].allROMs[[_renamingPath indexAtPosition:1]]; + _renamingPath = nil; + if ([newName isEqualToString:oldName]) { + [self.tableView reloadData]; + return; + } + if ([newName containsString:@"/"]) { + [self.tableView reloadData]; + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"You can't use a name that contains “/”. Please choose another name." + message:nil + preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleCancel + handler:nil]]; + [self presentViewController:alert animated:true completion:nil]; + return; + } + [[GBROMManager sharedManager] renameROM:oldName toName:newName]; + [self.tableView reloadData]; + _renamingPath = nil; +} + +// Leave these ROM management to iOS 13.0 and up for now +- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView +contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath + point:(CGPoint)point API_AVAILABLE(ios(13.0)) +{ + return [UIContextMenuConfiguration configurationWithIdentifier:nil + previewProvider:nil + actionProvider:^UIMenu *(NSArray<UIMenuElement *> *suggestedActions) { + return [UIMenu menuWithTitle:nil children:@[ + [UIAction actionWithTitle:@"Rename" + image:[UIImage systemImageNamed:@"pencil"] + identifier:nil + handler:^(__kindof UIAction *action) { + [self renameRow:indexPath]; + }], + [UIAction actionWithTitle:@"Duplicate" + image:[UIImage systemImageNamed:@"plus.rectangle.on.rectangle"] + identifier:nil + handler:^(__kindof UIAction *action) { + [[GBROMManager sharedManager] duplicateROM:[GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]]]; + [self.tableView reloadData]; + }], + ]]; + }]; +} + @end diff --git a/iOS/GBROMManager.h b/iOS/GBROMManager.h @@ -16,5 +16,7 @@ - (NSString *)autosaveStateFileForROM:(NSString *)rom; - (NSString *)stateFile:(unsigned)index forROM:(NSString *)rom; - (NSString *)importROM:(NSString *)romFile keepOriginal:(bool)keep; +- (NSString *)renameROM:(NSString *)rom toName:(NSString *)newName; +- (NSString *)duplicateROM:(NSString *)rom; - (void)deleteROM:(NSString *)rom; @end diff --git a/iOS/GBROMManager.m b/iOS/GBROMManager.m @@ -113,7 +113,23 @@ [ret addObject:romDirectory]; } } - return ret; + return [ret sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; +} + +- (NSString *)makeNameUnique:(NSString *)name +{ + NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject; + if (![[NSFileManager defaultManager] fileExistsAtPath:[root stringByAppendingPathComponent:name]]) return name; + + unsigned i = 2; + while (true) { + NSString *attempt = [name stringByAppendingFormat:@" %u", i]; + if ([[NSFileManager defaultManager] fileExistsAtPath:[root stringByAppendingPathComponent:attempt]]) { + i++; + continue; + } + return attempt; + } } - (NSString *)importROM:(NSString *)romFile keepOriginal:(bool)keep @@ -136,7 +152,13 @@ break; } } - + + return [self importROM:romFile withName:friendlyName keepOriginal:keep]; +} + +- (NSString *)importROM:(NSString *)romFile withName:(NSString *)friendlyName keepOriginal:(bool)keep +{ + NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject; NSString *romFolder = [root stringByAppendingPathComponent:friendlyName]; [[NSFileManager defaultManager] createDirectoryAtPath:romFolder withIntermediateDirectories:false @@ -167,6 +189,27 @@ return friendlyName; } +- (NSString *)renameROM:(NSString *)rom toName:(NSString *)newName +{ + newName = [self makeNameUnique:newName]; + if ([rom isEqualToString:_currentROM]) { + _currentROM = newName; + } + NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject; + + [[NSFileManager defaultManager] moveItemAtPath:[root stringByAppendingPathComponent:rom] + toPath:[root stringByAppendingPathComponent:newName] error:nil]; + return newName; +} + +- (NSString *)duplicateROM:(NSString *)rom +{ + NSString *newName = [self makeNameUnique:rom]; + return [self importROM:[self romFileForROM:rom] + withName:newName + keepOriginal:true]; +} + - (void)deleteROM:(NSString *)rom { NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject; diff --git a/iOS/GBViewController.h b/iOS/GBViewController.h @@ -1,7 +1,7 @@ #import <UIKit/UIKit.h> @interface GBViewController : UIViewController <UIApplicationDelegate> -@property (nullable, nonatomic, strong) UIWindow *window; +@property (nonatomic, strong) UIWindow *window; - (void)reset; - (void)openLibrary; - (void)start;
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.