diff --git a/Mini vMac.xcodeproj/project.pbxproj b/Mini vMac.xcodeproj/project.pbxproj index 8021790..f4e29d7 100644 --- a/Mini vMac.xcodeproj/project.pbxproj +++ b/Mini vMac.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 28848B621CDE97D600B86C45 /* InsertDiskViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28848B611CDE97D600B86C45 /* InsertDiskViewController.m */; }; + 28848B651CDE97E900B86C45 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28848B641CDE97E900B86C45 /* SettingsViewController.m */; }; 28CE8EB51CD4C3B200FE25A8 /* GLOBGLUE.c in Sources */ = {isa = PBXBuildFile; fileRef = 28CE8E931CD4C3B200FE25A8 /* GLOBGLUE.c */; }; 28CE8EB61CD4C3B200FE25A8 /* IWMEMDEV.c in Sources */ = {isa = PBXBuildFile; fileRef = 28CE8E961CD4C3B200FE25A8 /* IWMEMDEV.c */; }; 28CE8EB71CD4C3B200FE25A8 /* KBRDEMDV.c in Sources */ = {isa = PBXBuildFile; fileRef = 28CE8E981CD4C3B200FE25A8 /* KBRDEMDV.c */; }; @@ -34,6 +36,10 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 28848B601CDE97D600B86C45 /* InsertDiskViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsertDiskViewController.h; sourceTree = ""; }; + 28848B611CDE97D600B86C45 /* InsertDiskViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InsertDiskViewController.m; sourceTree = ""; }; + 28848B631CDE97E900B86C45 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = ""; }; + 28848B641CDE97E900B86C45 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = ""; }; 28CE8E881CD4C33E00FE25A8 /* CNFGGLOB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNFGGLOB.h; sourceTree = ""; }; 28CE8E891CD4C33E00FE25A8 /* CNFGRAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNFGRAPI.h; sourceTree = ""; }; 28CE8E8A1CD4C33E00FE25A8 /* EMCONFIG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EMCONFIG.h; sourceTree = ""; }; @@ -186,6 +192,10 @@ 28D5A3FC1CD6868E001A33F6 /* TouchScreen.m */, 28F676C61CD15E0B00FC6FA6 /* ViewController.h */, 28F676C71CD15E0B00FC6FA6 /* ViewController.m */, + 28848B601CDE97D600B86C45 /* InsertDiskViewController.h */, + 28848B611CDE97D600B86C45 /* InsertDiskViewController.m */, + 28848B631CDE97E900B86C45 /* SettingsViewController.h */, + 28848B641CDE97E900B86C45 /* SettingsViewController.m */, 28F676C91CD15E0B00FC6FA6 /* Main.storyboard */, 28F676CC1CD15E0B00FC6FA6 /* Assets.xcassets */, 28F676CE1CD15E0B00FC6FA6 /* LaunchScreen.storyboard */, @@ -286,9 +296,11 @@ 28CE8EBA1CD4C3B200FE25A8 /* MOUSEMDV.c in Sources */, 28CE8EC31CD4C3B200FE25A8 /* VIAEMDEV.c in Sources */, 28CE8EB81CD4C3B200FE25A8 /* M68KITAB.c in Sources */, + 28848B651CDE97E900B86C45 /* SettingsViewController.m in Sources */, 28CE8EB71CD4C3B200FE25A8 /* KBRDEMDV.c in Sources */, 28CE8EBC1CD4C3B200FE25A8 /* ROMEMDEV.c in Sources */, 28CE8EBB1CD4C3B200FE25A8 /* PROGMAIN.c in Sources */, + 28848B621CDE97D600B86C45 /* InsertDiskViewController.m in Sources */, 28F676C81CD15E0B00FC6FA6 /* ViewController.m in Sources */, 28D5A3FD1CD6868F001A33F6 /* TouchScreen.m in Sources */, 28CE8EC21CD4C3B200FE25A8 /* SONYEMDV.c in Sources */, diff --git a/Mini vMac/AppDelegate.h b/Mini vMac/AppDelegate.h index cf19048..5c6ed93 100644 --- a/Mini vMac/AppDelegate.h +++ b/Mini vMac/AppDelegate.h @@ -8,18 +8,27 @@ #import +extern NSString * const MNVMDidInsertDiskNotification; +extern NSString * const MNVMDidEjectDiskNotification; + @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @property (assign, nonatomic, getter=isEmulatorRunning) BOOL emulatorRunning; @property (nonatomic, readonly) NSString *documentsPath; +@property (nonatomic, readonly) NSArray *diskImageExtensions; + (instancetype)sharedInstance; - (void)showAlertWithTitle:(NSString *)title message:(NSString *)message; +- (IBAction)showInsertDisk:(id)sender; +- (IBAction)showSettings:(id)sender; - (void)setMouseX:(NSInteger)x Y:(NSInteger)y; - (void)moveMouseX:(NSInteger)x Y:(NSInteger)y; - (void)setMouseButton:(BOOL)down; +- (BOOL)insertDisk:(NSString*)path; +- (BOOL)isDiskInserted:(NSString*)path; + @end diff --git a/Mini vMac/AppDelegate.m b/Mini vMac/AppDelegate.m index ef07ada..7829996 100644 --- a/Mini vMac/AppDelegate.m +++ b/Mini vMac/AppDelegate.m @@ -7,6 +7,8 @@ // #import "AppDelegate.h" +#import "SettingsViewController.h" +#import "InsertDiskViewController.h" #include "CNFGRAPI.h" #include "SYSDEPNS.h" #include "MYOSGLUE.h" @@ -17,8 +19,12 @@ IMPORTPROC SetSpeedStopped(blnr stopped); IMPORTPROC SetMouseButton(blnr down); IMPORTPROC SetMouseLoc(ui4r h, ui4r v); IMPORTPROC SetMouseDelta(ui4r dh, ui4r dv); +IMPORTFUNC blnr Sony_Insert1(NSString *filePath, blnr silentfail); +IMPORTFUNC blnr Sony_IsInserted(NSString *filePath); static AppDelegate *sharedAppDelegate = nil; +NSString * const MNVMDidInsertDiskNotification = @"MNVMDidInsertDisk"; +NSString * const MNVMDidEjectDiskNotification = @"MNVMDidEjectDisk"; @interface AppDelegate () @@ -57,8 +63,64 @@ static AppDelegate *sharedAppDelegate = nil; [controller presentViewController:alert animated:YES completion:nil]; } +- (void)showSettings:(id)sender { + [self showModalPanel:@"settings" sender:sender]; +} + +- (void)showInsertDisk:(id)sender { + [self showModalPanel:@"disk" sender:sender]; +} + +- (void)showModalPanel:(NSString*)name sender:(id)sender { + Class classToShow, otherClass; + if ([name isEqualToString:@"settings"]) { + classToShow = [SettingsViewController class]; + otherClass = [InsertDiskViewController class]; + } else { + classToShow = [InsertDiskViewController class]; + otherClass = [SettingsViewController class]; + } + + UIViewController *rootViewController = self.window.rootViewController; + UIViewController *presentedViewController = rootViewController.presentedViewController; + UIViewController *presentedTopViewController = [presentedViewController isKindOfClass:[UINavigationController class]] ? [(UINavigationController*)presentedViewController topViewController] : nil; + + if ([presentedTopViewController isKindOfClass:classToShow]) { + return; + } else if ([presentedTopViewController isKindOfClass:otherClass]) { + // flip + UIViewController *viewController = [rootViewController.storyboard instantiateViewControllerWithIdentifier:name]; + viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; + viewController.modalPresentationStyle = UIModalPresentationFormSheet; + UIView *windowSnapshotView = [self.window snapshotViewAfterScreenUpdates:NO]; + [self.window addSubview:windowSnapshotView]; + UIView *oldPanelSnapshotView = [presentedViewController.view snapshotViewAfterScreenUpdates:NO]; + [viewController.view addSubview:oldPanelSnapshotView]; + [rootViewController dismissViewControllerAnimated:NO completion:^{ + [rootViewController presentViewController:viewController animated:NO completion:^{ + UIView *emptyView = [[UIView alloc] initWithFrame:viewController.view.bounds]; + [windowSnapshotView removeFromSuperview]; + viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; + [UIView transitionFromView:oldPanelSnapshotView + toView:emptyView + duration:0.5 + options:UIViewAnimationOptionTransitionFlipFromRight + completion:^(BOOL finished) { + [emptyView removeFromSuperview]; + }]; + }]; + }]; + } else { + [self.window.rootViewController performSegueWithIdentifier:name sender:sender]; + } +} + #pragma mark - Files +- (NSArray *)diskImageExtensions { + return @[@"dsk", @"img", @"dc42", @"diskcopy42"]; +} + - (NSString *)documentsPath { static dispatch_once_t onceToken; static NSString *documentsPath; @@ -111,6 +173,8 @@ static AppDelegate *sharedAppDelegate = nil; SetSpeedStopped(emulatorRunning); } +#pragma mark - Mouse + - (void)setMouseX:(NSInteger)x Y:(NSInteger)y { SetMouseLoc(x, y); } @@ -123,4 +187,14 @@ static AppDelegate *sharedAppDelegate = nil; SetMouseButton(down); } +#pragma mark - Disk Drive + +- (BOOL)insertDisk:(NSString *)path { + return Sony_Insert1(path.stringByStandardizingPath, falseblnr); +} + +- (BOOL)isDiskInserted:(NSString *)path { + return Sony_IsInserted(path.stringByStandardizingPath); +} + @end diff --git a/Mini vMac/Assets.xcassets/Contents.json b/Mini vMac/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Mini vMac/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Mini vMac/Assets.xcassets/Settings.imageset/Contents.json b/Mini vMac/Assets.xcassets/Settings.imageset/Contents.json new file mode 100644 index 0000000..fad3ac1 --- /dev/null +++ b/Mini vMac/Assets.xcassets/Settings.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Settings.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Settings@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Settings@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Mini vMac/Assets.xcassets/Settings.imageset/Settings.png b/Mini vMac/Assets.xcassets/Settings.imageset/Settings.png new file mode 100644 index 0000000..c6ba6d8 Binary files /dev/null and b/Mini vMac/Assets.xcassets/Settings.imageset/Settings.png differ diff --git a/Mini vMac/Assets.xcassets/Settings.imageset/Settings@2x.png b/Mini vMac/Assets.xcassets/Settings.imageset/Settings@2x.png new file mode 100644 index 0000000..c51331d Binary files /dev/null and b/Mini vMac/Assets.xcassets/Settings.imageset/Settings@2x.png differ diff --git a/Mini vMac/Assets.xcassets/Settings.imageset/Settings@3x.png b/Mini vMac/Assets.xcassets/Settings.imageset/Settings@3x.png new file mode 100644 index 0000000..7f971d3 Binary files /dev/null and b/Mini vMac/Assets.xcassets/Settings.imageset/Settings@3x.png differ diff --git a/Mini vMac/Assets.xcassets/document.imageset/Contents.json b/Mini vMac/Assets.xcassets/document.imageset/Contents.json new file mode 100644 index 0000000..49cb64a --- /dev/null +++ b/Mini vMac/Assets.xcassets/document.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "document.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "document@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "document@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Mini vMac/Assets.xcassets/document.imageset/document.png b/Mini vMac/Assets.xcassets/document.imageset/document.png new file mode 100644 index 0000000..687da9f Binary files /dev/null and b/Mini vMac/Assets.xcassets/document.imageset/document.png differ diff --git a/Mini vMac/Assets.xcassets/document.imageset/document@2x.png b/Mini vMac/Assets.xcassets/document.imageset/document@2x.png new file mode 100644 index 0000000..03b6c1a Binary files /dev/null and b/Mini vMac/Assets.xcassets/document.imageset/document@2x.png differ diff --git a/Mini vMac/Assets.xcassets/document.imageset/document@3x.png b/Mini vMac/Assets.xcassets/document.imageset/document@3x.png new file mode 100644 index 0000000..d864e4f Binary files /dev/null and b/Mini vMac/Assets.xcassets/document.imageset/document@3x.png differ diff --git a/Mini vMac/Assets.xcassets/floppy.imageset/Contents.json b/Mini vMac/Assets.xcassets/floppy.imageset/Contents.json new file mode 100644 index 0000000..e1aee3e --- /dev/null +++ b/Mini vMac/Assets.xcassets/floppy.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "floppy.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "floppy@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "floppy@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Mini vMac/Assets.xcassets/floppy.imageset/floppy.png b/Mini vMac/Assets.xcassets/floppy.imageset/floppy.png new file mode 100644 index 0000000..88aea86 Binary files /dev/null and b/Mini vMac/Assets.xcassets/floppy.imageset/floppy.png differ diff --git a/Mini vMac/Assets.xcassets/floppy.imageset/floppy@2x.png b/Mini vMac/Assets.xcassets/floppy.imageset/floppy@2x.png new file mode 100644 index 0000000..9e9ca0b Binary files /dev/null and b/Mini vMac/Assets.xcassets/floppy.imageset/floppy@2x.png differ diff --git a/Mini vMac/Assets.xcassets/floppy.imageset/floppy@3x.png b/Mini vMac/Assets.xcassets/floppy.imageset/floppy@3x.png new file mode 100644 index 0000000..fef6174 Binary files /dev/null and b/Mini vMac/Assets.xcassets/floppy.imageset/floppy@3x.png differ diff --git a/Mini vMac/Assets.xcassets/floppy30.imageset/Contents.json b/Mini vMac/Assets.xcassets/floppy30.imageset/Contents.json new file mode 100644 index 0000000..1c58f23 --- /dev/null +++ b/Mini vMac/Assets.xcassets/floppy30.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "floppy30.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "floppy30@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "floppy30@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30.png b/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30.png new file mode 100644 index 0000000..754c771 Binary files /dev/null and b/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30.png differ diff --git a/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30@2x.png b/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30@2x.png new file mode 100644 index 0000000..e418936 Binary files /dev/null and b/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30@2x.png differ diff --git a/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30@3x.png b/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30@3x.png new file mode 100644 index 0000000..bc43613 Binary files /dev/null and b/Mini vMac/Assets.xcassets/floppy30.imageset/floppy30@3x.png differ diff --git a/Mini vMac/Assets.xcassets/folder.imageset/Contents.json b/Mini vMac/Assets.xcassets/folder.imageset/Contents.json new file mode 100644 index 0000000..07206c2 --- /dev/null +++ b/Mini vMac/Assets.xcassets/folder.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "folder.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "folder@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "folder@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Mini vMac/Assets.xcassets/folder.imageset/folder.png b/Mini vMac/Assets.xcassets/folder.imageset/folder.png new file mode 100644 index 0000000..bd058bd Binary files /dev/null and b/Mini vMac/Assets.xcassets/folder.imageset/folder.png differ diff --git a/Mini vMac/Assets.xcassets/folder.imageset/folder@2x.png b/Mini vMac/Assets.xcassets/folder.imageset/folder@2x.png new file mode 100644 index 0000000..e4d990e Binary files /dev/null and b/Mini vMac/Assets.xcassets/folder.imageset/folder@2x.png differ diff --git a/Mini vMac/Assets.xcassets/folder.imageset/folder@3x.png b/Mini vMac/Assets.xcassets/folder.imageset/folder@3x.png new file mode 100644 index 0000000..a8dea20 Binary files /dev/null and b/Mini vMac/Assets.xcassets/folder.imageset/folder@3x.png differ diff --git a/Mini vMac/Assets.xcassets/hardDisk.imageset/Contents.json b/Mini vMac/Assets.xcassets/hardDisk.imageset/Contents.json new file mode 100644 index 0000000..607b390 --- /dev/null +++ b/Mini vMac/Assets.xcassets/hardDisk.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "hardDisk.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "hardDisk@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "hardDisk@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk.png b/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk.png new file mode 100644 index 0000000..47fe4fb Binary files /dev/null and b/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk.png differ diff --git a/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk@2x.png b/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk@2x.png new file mode 100644 index 0000000..b2e8b65 Binary files /dev/null and b/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk@2x.png differ diff --git a/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk@3x.png b/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk@3x.png new file mode 100644 index 0000000..84a4b64 Binary files /dev/null and b/Mini vMac/Assets.xcassets/hardDisk.imageset/hardDisk@3x.png differ diff --git a/Mini vMac/Base.lproj/Main.storyboard b/Mini vMac/Base.lproj/Main.storyboard index 1cbeaad..b0ad48a 100644 --- a/Mini vMac/Base.lproj/Main.storyboard +++ b/Mini vMac/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -19,7 +19,7 @@ - + @@ -32,11 +32,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mini vMac/InsertDiskViewController.h b/Mini vMac/InsertDiskViewController.h new file mode 100644 index 0000000..4348838 --- /dev/null +++ b/Mini vMac/InsertDiskViewController.h @@ -0,0 +1,16 @@ +// +// InsertDiskViewController.h +// Mini vMac +// +// Created by Jesús A. Álvarez on 07/05/2016. +// Copyright © 2016 namedfork. All rights reserved. +// + +#import + +@interface InsertDiskViewController : UITableViewController + +- (IBAction)showSettings:(id)sender; +- (IBAction)dismiss:(id)sender; + +@end diff --git a/Mini vMac/InsertDiskViewController.m b/Mini vMac/InsertDiskViewController.m new file mode 100644 index 0000000..2cd0fb1 --- /dev/null +++ b/Mini vMac/InsertDiskViewController.m @@ -0,0 +1,448 @@ +// +// InsertDiskViewController.m +// Mini vMac +// +// Created by Jesús A. Álvarez on 07/05/2016. +// Copyright © 2016 namedfork. All rights reserved. +// + +#import "InsertDiskViewController.h" +#import "AppDelegate.h" + +@interface InsertDiskViewController () + +@end + +@interface FileTableViewCell : UITableViewCell + +@property (nonatomic, weak) InsertDiskViewController *controller; +@property (nonatomic, strong) NSString *filePath; +- (void)share:(id)sender; +- (void)rename:(id)sender; +- (void)delete:(id)sender; + +@end + +@implementation InsertDiskViewController +{ + NSString *basePath; + NSArray *diskImages, *otherFiles; + UIAlertController *createDiskImageController; + __block __weak UITextField *sizeTextField; + __block __weak UITextField *nameTextField; +} + ++ (void)initialize { + UIMenuController *menuController = [UIMenuController sharedMenuController]; + menuController.menuItems = @[[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Rename", @"Rename Context Menu Item") action:@selector(rename:)], + [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Share", @"Share Context Menu Item") action:@selector(share:)]]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + basePath = [AppDelegate sharedInstance].documentsPath; + [self loadDirectoryContents]; + self.navigationItem.rightBarButtonItem = self.editButtonItem; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(reloadData:) name:MNVMDidInsertDiskNotification object:nil]; + [nc addObserver:self selector:@selector(reloadData:) name:MNVMDidEjectDiskNotification object:nil]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc removeObserver:self name:MNVMDidInsertDiskNotification object:nil]; + [nc removeObserver:self name:MNVMDidEjectDiskNotification object:nil]; +} + +- (void)loadDirectoryContents { + NSArray *allFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:basePath error:NULL]; + diskImages = [allFiles pathsMatchingExtensions:[AppDelegate sharedInstance].diskImageExtensions]; + otherFiles = [allFiles filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString* _Nonnull name, NSDictionary * _Nullable bindings) { + BOOL isDiskImage = [diskImages containsObject:name]; + BOOL isDirectory; + BOOL isHidden = [name hasPrefix:@"."]; + [[NSFileManager defaultManager] fileExistsAtPath:[basePath stringByAppendingPathComponent:name] isDirectory:&isDirectory]; + return !(isDirectory || isDiskImage || isHidden); + }]]; +} + +- (void)reloadData:(id)sender { + [self loadDirectoryContents]; + [self.tableView reloadData]; +} + +- (void)showSettings:(id)sender { + [[AppDelegate sharedInstance] showSettings:sender]; +} + +- (void)dismiss:(id)sender { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return self.editing ? 2 : 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + switch (section) { + case 0: return diskImages.count + (self.editing ? 1 : 0); + case 1: return otherFiles.count; + default: return 0; + } +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + return section == 0 ? NSLocalizedString(@"Disk Images", nil) : NSLocalizedString(@"Other Files", nil); +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + return self.editing ? UITableViewAutomaticDimension : 0.0; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + [super setEditing:editing animated:animated]; + [self.tableView beginUpdates]; + [self loadDirectoryContents]; + self.tableView.tableHeaderView = nil; + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade]; + if (editing) { + [self.tableView insertSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade]; + } else { + [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade]; + } + [self.tableView endUpdates]; +} + +- (NSString *)fileAtIndexPath:(NSIndexPath *)indexPath { + NSArray *files = indexPath.section == 0 ? diskImages : otherFiles; + if (indexPath.row < files.count) { + NSString *fileName = files[indexPath.row]; + return [basePath stringByAppendingPathComponent:fileName]; + } else { + return nil; + } +} + +- (NSIndexPath *)indexPathForFile:(NSString *)filePath { + NSString *fileName = filePath.lastPathComponent; + if ([diskImages containsObject:fileName]) { + return [NSIndexPath indexPathForRow:[diskImages indexOfObject:fileName] inSection:0]; + } else if ([otherFiles containsObject:fileName]) { + return [NSIndexPath indexPathForRow:[otherFiles indexOfObject:fileName] inSection:1]; + } else { + return nil; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + FileTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; + NSString *filePath = [self fileAtIndexPath:indexPath]; + if (filePath) { + cell.filePath = filePath; + if ([[AppDelegate sharedInstance] isDiskInserted:filePath]) { + cell.userInteractionEnabled = NO; + cell.textLabel.enabled = NO; + cell.imageView.alpha = 0.5; + } + } else { + cell.textLabel.text = NSLocalizedString(@"Create Disk Image…", nil); + cell.detailTextLabel.text = nil; + } + cell.controller = self; + return cell; +} + +- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + if (self.editing == NO) { + return UITableViewCellEditingStyleNone; + } else if (indexPath.section == 0) { + if (indexPath.row == diskImages.count) { + return UITableViewCellEditingStyleInsert; + } + NSString *filePath = [self fileAtIndexPath:indexPath]; + BOOL isInserted = [[AppDelegate sharedInstance] isDiskInserted:filePath]; + return isInserted ? UITableViewCellEditingStyleNone : UITableViewCellEditingStyleDelete; + } else { + return UITableViewCellEditingStyleDelete; + } +} + +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + [self askDeleteFile:[self fileAtIndexPath:indexPath]]; + } else if (editingStyle == UITableViewCellEditingStyleInsert) { + [self createDiskImage]; + } +} + +- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { + return [self fileAtIndexPath:indexPath] != nil; +} + +- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { + return (action == @selector(share:) || action == @selector(rename:) || action == @selector(delete:)); +} + +- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { + // menu will not be shown if this method doesn't exist +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *filePath = [self fileAtIndexPath:indexPath]; + if (filePath && ![[AppDelegate sharedInstance] isDiskInserted:filePath]) { + [self dismissViewControllerAnimated:YES completion:^{ + [[AppDelegate sharedInstance] insertDisk:filePath]; + }]; + } +} + +#pragma mark - File Actions + +- (void)askDeleteFile:(NSString*)filePath { + NSString *fileName = filePath.lastPathComponent; + NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Are you sure you want to delete %@? This operation cannot be undone.", nil), fileName]; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Delete File", nil) message:message preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Delete", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + NSError *error = nil; + if ([[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]) { + NSIndexPath *indexPath = [self indexPathForFile:filePath]; + [self loadDirectoryContents]; + [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + } else { + [[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not delete file", nil) message:error.localizedDescription]; + } + }]]; + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:alertController animated:YES completion:nil]; +} + +- (void)askRenameFile:(NSString*)filePath { + NSString *fileName = filePath.lastPathComponent; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:fileName message:NSLocalizedString(@"Enter new name", nil) preferredStyle:UIAlertControllerStyleAlert]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + nameTextField = textField; + textField.delegate = self; + textField.placeholder = fileName; + textField.text = fileName; + }]; + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Rename", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + NSError *error = nil; + NSString *newName = alertController.textFields.firstObject.text; + NSString *newPath = [filePath.stringByDeletingLastPathComponent stringByAppendingPathComponent:newName]; + if ([[NSFileManager defaultManager] moveItemAtPath:filePath toPath:newPath error:&error]) { + NSIndexPath *oldIndexPath = [self indexPathForFile:filePath]; + [self loadDirectoryContents]; + NSIndexPath *newIndexPath = [self indexPathForFile:newPath]; + if (newIndexPath == nil) { + [self.tableView deleteRowsAtIndexPaths:@[oldIndexPath] withRowAnimation:UITableViewRowAnimationFade]; + } else { + [self.tableView moveRowAtIndexPath:oldIndexPath toIndexPath:newIndexPath]; + [self.tableView reloadRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone]; + } + } else { + [[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not rename file", nil) message:error.localizedDescription]; + } + }]]; + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:alertController animated:YES completion:nil]; +} + +#pragma mark - Disk Image Creation + +- (void)createDiskImage { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Create Disk Image", nil) message:nil preferredStyle:UIAlertControllerStyleAlert]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.placeholder = NSLocalizedString(@"name", nil); + [textField addTarget:self action:@selector(validateCreateDiskImageInput:) forControlEvents:UIControlEventAllEditingEvents]; + }]; + + [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.placeholder = NSLocalizedString(@"size", nil); + textField.keyboardType = UIKeyboardTypeDecimalPad; + UILabel *unitLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60.0, 32.0)]; + textField.rightViewMode = UITextFieldViewModeAlways; + textField.rightView = unitLabel; + unitLabel.textAlignment = NSTextAlignmentRight; + UISegmentedControl *unitsControl = [[UISegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 80.0, 16.0)]; + NSArray *units = @[NSLocalizedString(@"KB", nil), NSLocalizedString(@"MB", nil)]; + [units enumerateObjectsUsingBlock:^(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) { + [unitsControl insertSegmentWithTitle:title atIndex:idx animated:NO]; + }]; + unitsControl.selectedSegmentIndex = 0; + textField.rightView = unitsControl; + sizeTextField = textField; + textField.delegate = self; + [textField addTarget:self action:@selector(validateCreateDiskImageInput:) forControlEvents:UIControlEventAllEditingEvents]; + [unitsControl addTarget:self action:@selector(validateCreateDiskImageInput:) forControlEvents:UIControlEventValueChanged]; + unitLabel.text = [unitsControl titleForSegmentAtIndex:unitsControl.selectedSegmentIndex]; + }]; + + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]]; + UIAlertAction *createAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Create", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + NSString *name = [self _newDiskImageName]; + off_t size = [self _newDiskImageSize]; + createDiskImageController = nil; + [self createDiskImageWithName:name size:size]; + }]; + [alertController addAction:createAction]; + createAction.enabled = NO; + [self presentViewController:alertController animated:YES completion:nil]; + createDiskImageController = alertController; +} + +- (BOOL)validateCreateDiskImageInput:(id)sender { + BOOL valid = NO; + if (self.presentedViewController == createDiskImageController) { + NSString *name = [self _newDiskImageName]; + BOOL nameIsValid = (name.length > 0) && ![name hasPrefix:@"."] && ![name containsString:@"/"] && ![name containsString:@"*"]; + + off_t size = [self _newDiskImageSize]; + BOOL sizeIsValid = (size >= 400 * 1024) && (size <= 2LL * 1024 * 1024 * 1024); + + valid = nameIsValid && sizeIsValid; + UIAlertAction *createAction = createDiskImageController.actions[1]; + createAction.enabled = valid; + } + return valid; +} + +- (NSString*)_newDiskImageName { + return createDiskImageController ? createDiskImageController.textFields[0].text : nil; +} + +- (off_t)_newDiskImageSize { + if (createDiskImageController == nil) { + return 0; + } + UISegmentedControl *unitsControl = (UISegmentedControl*)createDiskImageController.textFields[1].rightView; + off_t unitsMultiplier = (unitsControl.selectedSegmentIndex == 0) ? 1024 : 1024 * 1024; + off_t size = createDiskImageController.textFields[1].text.floatValue * unitsMultiplier; + return size; +} + +- (void)createDiskImageWithName:(NSString*)name size:(off_t)size { + NSString *imageFileName = [[AppDelegate sharedInstance].diskImageExtensions containsObject:name.pathExtension.lowercaseString] ? name : [name stringByAppendingPathExtension:@"img"]; + NSString *imagePath = [basePath stringByAppendingPathComponent:imageFileName]; + + int fd = open(imagePath.fileSystemRepresentation, O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, 0666); + if (fd == -1) { + [[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not create disk image", nil) message:[[NSString alloc] initWithUTF8String:strerror(errno)]]; + return; + } + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Creating Disk Image", nil) message:@"\n\n\n" preferredStyle:UIAlertControllerStyleAlert]; + [self presentViewController:alertController animated:true completion:^{ + UIView *alertView = alertController.view; + UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + activityView.color = [UIColor blackColor]; + activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; + activityView.center = CGPointMake(alertView.bounds.size.width / 2.0, alertView.bounds.size.height / 2.0 + 32.0); + [alertView addSubview:activityView]; + [activityView startAnimating]; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + int error = 0; + if (ftruncate(fd, size)) { + error = errno; + } + close(fd); + dispatch_async(dispatch_get_main_queue(), ^{ + [activityView stopAnimating]; + [self dismissViewControllerAnimated:YES completion:^{ + if (error) { + [[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not create disk image", nil) message:[[NSString alloc] initWithUTF8String:strerror(error)]]; + } + }]; + [self.tableView beginUpdates]; + [self loadDirectoryContents]; + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade]; + [self.tableView endUpdates]; + }); + }); + }]; +} + +#pragma mark - Text Field Delegate + +- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { + if (textField == sizeTextField) { + UISegmentedControl *unitsControl = (UISegmentedControl*)textField.rightView; + NSArray *unitShortcuts = @[@"k", @"m"]; + if (string.length == 0) { + return YES; + } else if (string.length == 1 && [unitShortcuts indexOfObject:string.lowercaseString] != NSNotFound) { + unitsControl.selectedSegmentIndex = [unitShortcuts indexOfObject:string.lowercaseString]; + [unitsControl sendActionsForControlEvents:UIControlEventValueChanged]; + return NO; + } else { + NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string]; + NSScanner *scanner = [NSScanner scannerWithString:newString]; + double value; + return [scanner scanDouble:&value] && scanner.isAtEnd && value >= 0; + } + } else { + return YES; + } +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + if (textField == nameTextField && textField.text.pathExtension.length > 0) { + UITextPosition *beforeExtensionPosition = [textField positionFromPosition:textField.endOfDocument offset:-(textField.text.pathExtension.length + 1)]; + UITextRange *nameWithoutExtensionRange = [textField textRangeFromPosition:textField.beginningOfDocument toPosition:beforeExtensionPosition]; + [textField performSelector:@selector(setSelectedTextRange:) withObject:nameWithoutExtensionRange afterDelay:0.1]; + } +} + +@end + +@implementation FileTableViewCell + +- (void)prepareForReuse { + [super prepareForReuse]; + self.userInteractionEnabled = YES; + self.textLabel.text = nil; + self.textLabel.enabled = YES; + self.imageView.image = nil; + self.imageView.alpha = 1.0; + self.detailTextLabel.text = nil; +} + +- (void)setFilePath:(NSString *)filePath { + _filePath = filePath; + NSString *fileName = filePath.lastPathComponent; + self.textLabel.text = self.editing ? fileName : fileName.stringByDeletingPathExtension; + NSDictionary *attributes = [[NSURL fileURLWithPath:filePath] resourceValuesForKeys:@[NSURLTotalFileSizeKey] error:NULL]; + if (attributes && attributes[NSURLTotalFileSizeKey]) { + BOOL isDiskImage = [[AppDelegate sharedInstance].diskImageExtensions containsObject:fileName.pathExtension.lowercaseString]; + self.imageView.image = [UIImage imageNamed:isDiskImage ? @"floppy" : @"document"]; + NSString *sizeString = [NSByteCountFormatter stringFromByteCount:[attributes[NSURLTotalFileSizeKey] longLongValue] countStyle:NSByteCountFormatterCountStyleBinary]; + self.detailTextLabel.text = sizeString; + } else { + self.imageView.image = nil; + self.detailTextLabel.text = nil; + } +} + +- (void)share:(id)sender { + UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:@[[NSURL fileURLWithPath:self.filePath]] applicationActivities:nil]; + avc.modalPresentationStyle = UIModalPresentationPopover; + avc.popoverPresentationController.sourceView = self.imageView; + avc.popoverPresentationController.sourceRect = self.imageView.bounds; + [self.controller presentViewController:avc animated:YES completion:nil]; +} + +- (void)rename:(id)sender { + [self.controller askRenameFile:self.filePath]; +} + +- (void)delete:(id)sender { + [self.controller askDeleteFile:self.filePath]; +} + +@end diff --git a/Mini vMac/MYOSGLUE.m b/Mini vMac/MYOSGLUE.m index 2ab5f0d..78420f9 100644 --- a/Mini vMac/MYOSGLUE.m +++ b/Mini vMac/MYOSGLUE.m @@ -451,6 +451,10 @@ LOCALPROC MyUnlockFile(FILE *refnum) { LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit) { FILE *refnum = Drives[Drive_No]; + NSDictionary *userInfo = @{@"path": DriveNames[Drive_No], + @"drive": @(Drive_No), + @"delete": @(deleteit)}; + [[NSNotificationCenter defaultCenter] postNotificationName:MNVMDidEjectDiskNotification object:[AppDelegate sharedInstance] userInfo:userInfo]; DiskEjectedNotify(Drive_No); #if HaveAdvisoryLocks @@ -524,6 +528,10 @@ LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked, NSString *filePath) { MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage, falseblnr); } else { + NSDictionary *userInfo = @{@"path": filePath, + @"drive": @(Drive_No)}; + [[NSNotificationCenter defaultCenter] postNotificationName:MNVMDidInsertDiskNotification object:[AppDelegate sharedInstance] userInfo:userInfo]; + /* printf("Sony_Insert0 %d\n", (int)Drive_No); */ #if HaveAdvisoryLocks @@ -548,7 +556,18 @@ LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked, NSString *filePath) { return IsOk; } -LOCALFUNC blnr Sony_Insert1(NSString *filePath, blnr silentfail) { +GLOBALFUNC blnr Sony_IsInserted(NSString *filePath) { +#if IncludeSonyGetName + for (int i=0; i < NumDrives; i++) { + if (vSonyIsInserted(i) && [DriveNames[i] isEqualToString:filePath]) { + return trueblnr; + } + } +#endif + return falseblnr; +} + +GLOBALFUNC blnr Sony_Insert1(NSString *filePath, blnr silentfail) { /* const char *drivepath = [filePath UTF8String]; */ const char *drivepath = [filePath fileSystemRepresentation]; blnr locked = falseblnr; diff --git a/Mini vMac/SettingsViewController.h b/Mini vMac/SettingsViewController.h new file mode 100644 index 0000000..4ea0283 --- /dev/null +++ b/Mini vMac/SettingsViewController.h @@ -0,0 +1,16 @@ +// +// SettingsViewController.h +// Mini vMac +// +// Created by Jesús A. Álvarez on 07/05/2016. +// Copyright © 2016 namedfork. All rights reserved. +// + +#import + +@interface SettingsViewController : UITableViewController + +- (IBAction)showInsertDisk:(id)sender; +- (IBAction)dismiss:(id)sender; + +@end diff --git a/Mini vMac/SettingsViewController.m b/Mini vMac/SettingsViewController.m new file mode 100644 index 0000000..671ac02 --- /dev/null +++ b/Mini vMac/SettingsViewController.m @@ -0,0 +1,102 @@ +// +// SettingsViewController.m +// Mini vMac +// +// Created by Jesús A. Álvarez on 07/05/2016. +// Copyright © 2016 namedfork. All rights reserved. +// + +#import "SettingsViewController.h" +#import "AppDelegate.h" + +@interface SettingsViewController () + +@end + +@implementation SettingsViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + // Uncomment the following line to preserve selection between presentations. + // self.clearsSelectionOnViewWillAppear = NO; + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem; +} + +- (void)showInsertDisk:(id)sender { + [[AppDelegate sharedInstance] showInsertDisk:sender]; +} + +- (void)dismiss:(id)sender { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { +#warning Incomplete implementation, return the number of sections + return 0; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { +#warning Incomplete implementation, return the number of rows + return 0; +} + +/* +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath]; + + // Configure the cell... + + return cell; +} +*/ + +/* +// Override to support conditional editing of the table view. +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; +} +*/ + +/* +// Override to support editing the table view. +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + // Delete the row from the data source + [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + } else if (editingStyle == UITableViewCellEditingStyleInsert) { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } +} +*/ + +/* +// Override to support rearranging the table view. +- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { +} +*/ + +/* +// Override to support conditional rearranging of the table view. +- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; +} +*/ + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/Mini vMac/ViewController.m b/Mini vMac/ViewController.m index ec0c71c..741144a 100644 --- a/Mini vMac/ViewController.m +++ b/Mini vMac/ViewController.m @@ -8,6 +8,7 @@ #import "ViewController.h" #import "TouchScreen.h" +#import "AppDelegate.h" @interface ViewController () @@ -37,4 +38,10 @@ [self.view insertSubview:pointingDeviceView aboveSubview:self.screenView]; } +- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { + if (motion == UIEventSubtypeMotionShake) { + [[AppDelegate sharedInstance] showInsertDisk:self]; + } +} + @end