diff --git a/Common/Components/Action.swift b/Common/Components/Action.swift new file mode 100644 index 0000000..bc2167c --- /dev/null +++ b/Common/Components/Action.swift @@ -0,0 +1,84 @@ +// +// Action.swift +// Delta +// +// Created by Riley Testut on 5/18/16. +// Copyright © 2016 Riley Testut. All rights reserved. +// + +import UIKit + +extension Action +{ + enum Style + { + case Default + case Cancel + case Destructive + case Selected + } +} + +extension Action.Style +{ + var alertActionStyle: UIAlertActionStyle + { + switch self + { + case .Default, .Selected: return .Default + case .Cancel: return .Cancel + case .Destructive: return .Destructive + } + } + + var previewActionStyle: UIPreviewActionStyle + { + switch self + { + case .Default, .Cancel: return .Default + case .Destructive: return .Destructive + case .Selected: return .Selected + } + } +} + +struct Action +{ + let title: String + let style: Style + let action: (Action -> Void)? + + var alertAction: UIAlertAction + { + let alertAction = UIAlertAction(title: self.title, style: self.style.alertActionStyle) { (action) in + self.action?(self) + } + return alertAction + } + + var previewAction: UIPreviewAction + { + let previewAction = UIPreviewAction(title: self.title, style: self.style.previewActionStyle) { (action, viewController) in + self.action?(self) + } + return previewAction + } +} + +// There is no public designated initializer for UIAlertAction or UIPreviewAction, so we cannot add our own convenience init +// If only there were factory initializers... https://github.com/apple/swift-evolution/pull/247 +/* +extension UIAlertAction +{ + convenience init(action: Action) + { + } +} + +extension UIPreviewAction +{ + convenience init(action: Action) + { + } +} +*/ \ No newline at end of file diff --git a/Delta.xcodeproj/project.pbxproj b/Delta.xcodeproj/project.pbxproj index f510db9..db4ea79 100644 --- a/Delta.xcodeproj/project.pbxproj +++ b/Delta.xcodeproj/project.pbxproj @@ -65,6 +65,7 @@ BF8624AA1BB7464B00C12EEE /* DeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF9F4FCF1AAD7B87004C9500 /* DeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; }; BF9F4FD01AAD7B87004C9500 /* DeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + BFA2315C1CED10BE0011E35A /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA2315B1CED10BE0011E35A /* Action.swift */; }; BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FEC1B8AA4FA00495943 /* Settings.swift */; }; BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FF31B8AD7F900495943 /* ControllersSettingsViewController.swift */; }; BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */; }; @@ -161,6 +162,7 @@ BF7AE81A1C2E984300B1B5BC /* GridCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GridCollectionViewCell.swift; path = "Collection View/GridCollectionViewCell.swift"; sourceTree = ""; }; BF7AE81D1C2E984300B1B5BC /* GridCollectionViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GridCollectionViewLayout.swift; path = "Collection View/GridCollectionViewLayout.swift"; sourceTree = ""; }; BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BFA2315B1CED10BE0011E35A /* Action.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Action.swift; path = Components/Action.swift; sourceTree = ""; }; BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; BFAA1FF31B8AD7F900495943 /* ControllersSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControllersSettingsViewController.swift; sourceTree = ""; }; BFB141171BE46934004FBF46 /* GameCollectionViewDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameCollectionViewDataSource.swift; path = "Collection View/GameCollectionViewDataSource.swift"; sourceTree = ""; }; @@ -392,6 +394,7 @@ BFF1E55F1BE04BF6000E9EF6 /* Components */ = { isa = PBXGroup; children = ( + BFA2315B1CED10BE0011E35A /* Action.swift */, BFF1E5631BE04CAF000E9EF6 /* BoxArtImageView.swift */, BF0CDDAC1C8155D200640168 /* LoadImageOperation.swift */, ); @@ -703,6 +706,7 @@ BF7AE8241C2E984300B1B5BC /* GridCollectionViewLayout.swift in Sources */, BF1FB1861C5EE643007E2494 /* SaveState.swift in Sources */, BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */, + BFA2315C1CED10BE0011E35A /* Action.swift in Sources */, BFFB709F1AF99B1700DE56FE /* EmulationViewController.swift in Sources */, BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */, BF353FF91C5D870B00C1184C /* PauseItem.swift in Sources */, diff --git a/Delta/Pause Menu/Save States/SaveStatesViewController.swift b/Delta/Pause Menu/Save States/SaveStatesViewController.swift index 9895cd1..622056f 100644 --- a/Delta/Pause Menu/Save States/SaveStatesViewController.swift +++ b/Delta/Pause Menu/Save States/SaveStatesViewController.swift @@ -245,45 +245,11 @@ private extension SaveStatesViewController let saveState = self.fetchedResultsController.objectAtIndexPath(indexPath) as! SaveState let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet) - alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel, handler: nil)) - alertController.addAction(UIAlertAction(title: NSLocalizedString("Delete Save State", comment: ""), style: .Destructive, handler: { action in - self.deleteSaveState(saveState) - })) - alertController.addAction(UIAlertAction(title: NSLocalizedString("Rename Save State", comment: ""), style: .Default, handler: { action in - self.renameSaveState(saveState) - })) - if self.traitCollection.forceTouchCapability == .Available + let actions = self.actionsForSaveState(saveState).map { $0.alertAction } + for action in actions { - if !saveState.isPreview - { - alertController.addAction(UIAlertAction(title: NSLocalizedString("Set as Preview Save State", comment: ""), style: .Default, handler: { action in - self.updatePreviewSaveState(saveState) - })) - } - else - { - alertController.addAction(UIAlertAction(title: NSLocalizedString("Remove as Preview Save State", comment: ""), style: .Default, handler: { action in - self.updatePreviewSaveState(nil) - })) - } - } - - - let section = self.correctedSectionForSectionIndex(indexPath.section) - switch section - { - case .Auto: break - case .General: - alertController.addAction(UIAlertAction(title: NSLocalizedString("Lock Save State", comment: ""), style: .Default, handler: { action in - self.lockSaveState(saveState) - })) - - case .Locked: - alertController.addAction(UIAlertAction(title: NSLocalizedString("Unlock Save State", comment: ""), style: .Default, handler: { action in - self.unlockSaveState(saveState) - })) - + alertController.addAction(action) } self.presentViewController(alertController, animated: true, completion: nil) @@ -479,6 +445,60 @@ private extension SaveStatesViewController let section = Section(rawValue: sectionIndex)! return section } + + func actionsForSaveState(saveState: SaveState) -> [Action] + { + var actions = [Action]() + + let cancelAction = Action(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel, action: nil) + actions.append(cancelAction) + + let deleteAction = Action(title: NSLocalizedString("Delete Save State", comment: ""), style: .Destructive, action: { action in + self.deleteSaveState(saveState) + }) + actions.append(deleteAction) + + let renameAction = Action(title: NSLocalizedString("Rename Save State", comment: ""), style: .Default, action: { action in + self.renameSaveState(saveState) + }) + actions.append(renameAction) + + if self.traitCollection.forceTouchCapability == .Available + { + if !saveState.isPreview + { + let previewAction = Action(title: NSLocalizedString("Set as Preview Save State", comment: ""), style: .Default, action: { action in + self.updatePreviewSaveState(saveState) + }) + actions.append(previewAction) + } + else + { + let previewAction = Action(title: NSLocalizedString("Remove as Preview Save State", comment: ""), style: .Default, action: { action in + self.updatePreviewSaveState(nil) + }) + actions.append(previewAction) + } + } + + switch saveState.type + { + case .Auto: break + case .General: + let lockAction = Action(title: NSLocalizedString("Lock Save State", comment: ""), style: .Default, action: { action in + self.lockSaveState(saveState) + }) + actions.append(lockAction) + + case .Locked: + let unlockAction = Action(title: NSLocalizedString("Unlock Save State", comment: ""), style: .Default, action: { action in + self.unlockSaveState(saveState) + }) + actions.append(unlockAction) + } + + return actions + } } //MARK: - - @@ -493,9 +513,11 @@ extension SaveStatesViewController: UIViewControllerPreviewingDelegate let emulatorCore = self.delegate.saveStatesViewControllerActiveEmulatorCore(self) let storyboard = UIStoryboard(name: "Main", bundle: nil) + let saveState = self.fetchedResultsController.objectAtIndexPath(indexPath) as! SaveState + let emulationViewController = storyboard.instantiateViewControllerWithIdentifier("emulationViewController") as! EmulationViewController emulationViewController.game = emulatorCore.game as! Game - emulationViewController.overridePreviewActionItems = [] + emulationViewController.overridePreviewActionItems = self.actionsForSaveState(saveState).filter{ $0.style != .Cancel }.map{ $0.previewAction } emulationViewController.deferredPreparationHandler = { [unowned emulationViewController] in // Store reference to current game state before we stop emulation so we can resume it if user decides to not load a save state @@ -520,9 +542,6 @@ extension SaveStatesViewController: UIViewControllerPreviewingDelegate emulatorCore.stopEmulation() - - let saveState = self.fetchedResultsController.objectAtIndexPath(indexPath) as! SaveState - emulationViewController.emulatorCore.startEmulation() emulationViewController.emulatorCore.pauseEmulation() emulationViewController.emulatorCore.loadSaveState(saveState)