Adds Save States action when previewing/long pressing games
This commit is contained in:
parent
3b9d169367
commit
f06fb72908
@ -32,6 +32,7 @@
|
||||
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E7F431B9A650B00AE44F8 /* SettingsViewController.swift */; };
|
||||
BF5E7F461B9A652600AE44F8 /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF5E7F451B9A652600AE44F8 /* Settings.storyboard */; };
|
||||
BF65E8631CEE5C6A00CD3247 /* Cheat.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF65E8621CEE5C6A00CD3247 /* Cheat.swift */; };
|
||||
BF696B801D9B2B02009639E0 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF696B7F1D9B2B02009639E0 /* Theme.swift */; };
|
||||
BF70798C1B6B464B0019077C /* ZipZap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF70798B1B6B464B0019077C /* ZipZap.framework */; };
|
||||
BF70798D1B6B464B0019077C /* ZipZap.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF70798B1B6B464B0019077C /* ZipZap.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
BF762EAB1BC1B076002C8866 /* NSManagedObject+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF762EAA1BC1B076002C8866 /* NSManagedObject+Conveniences.swift */; };
|
||||
@ -124,6 +125,7 @@
|
||||
BF5E7F451B9A652600AE44F8 /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = "<group>"; };
|
||||
BF63BDE91D389EEB00FCB040 /* GameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = "<group>"; };
|
||||
BF65E8621CEE5C6A00CD3247 /* Cheat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cheat.swift; sourceTree = "<group>"; };
|
||||
BF696B7F1D9B2B02009639E0 /* Theme.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Theme.swift; path = Theming/Theme.swift; sourceTree = "<group>"; };
|
||||
BF6BB2451BB73FE800CCF94A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
BF70798B1B6B464B0019077C /* ZipZap.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ZipZap.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BF762EAA1BC1B076002C8866 /* NSManagedObject+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Conveniences.swift"; sourceTree = "<group>"; };
|
||||
@ -257,6 +259,14 @@
|
||||
path = "Game Selection";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF696B7E1D9B2AE6009639E0 /* Theming */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF696B7F1D9B2B02009639E0 /* Theme.swift */,
|
||||
);
|
||||
name = Theming;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF762EA91BC1B044002C8866 /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -394,6 +404,7 @@
|
||||
BFFB709D1AF99ACA00DE56FE /* Emulation */,
|
||||
BF7AE7FA1C2E851F00B1B5BC /* Pause Menu */,
|
||||
BFAA1FEB1B8AA4E800495943 /* Settings */,
|
||||
BF696B7E1D9B2AE6009639E0 /* Theming */,
|
||||
BF090CEE1B490C1A00DCAB45 /* Extensions */,
|
||||
BFFA71DA1AAC406100EE9DD1 /* Supporting Files */,
|
||||
);
|
||||
@ -614,6 +625,7 @@
|
||||
BF5E7F441B9A650B00AE44F8 /* SettingsViewController.swift in Sources */,
|
||||
BF353FF21C5D7FB000C1184C /* PauseViewController.swift in Sources */,
|
||||
BFDB28451BC9DA7B001D0C83 /* GamePickerController.swift in Sources */,
|
||||
BF696B801D9B2B02009639E0 /* Theme.swift in Sources */,
|
||||
BF7AE8081C2E858400B1B5BC /* PauseMenuViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@ -21,7 +21,7 @@ class GameCollectionViewController: UICollectionViewController
|
||||
}
|
||||
}
|
||||
|
||||
var theme: GamesViewController.Theme = .light {
|
||||
var theme: Theme = .light {
|
||||
didSet {
|
||||
self.collectionView?.reloadData()
|
||||
}
|
||||
@ -197,11 +197,15 @@ private extension GameCollectionViewController
|
||||
{
|
||||
let cancelAction = Action(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, action: nil)
|
||||
|
||||
let saveStatesAction = Action(title: NSLocalizedString("Save States", comment: ""), style: .default, action: { [unowned self] action in
|
||||
self.viewSaveStates(for: game)
|
||||
})
|
||||
|
||||
let deleteAction = Action(title: NSLocalizedString("Delete", comment: ""), style: .destructive, action: { [unowned self] action in
|
||||
self.delete(game)
|
||||
})
|
||||
|
||||
return [cancelAction, deleteAction]
|
||||
return [cancelAction, saveStatesAction, deleteAction]
|
||||
}
|
||||
|
||||
func delete(_ game: Game)
|
||||
@ -222,6 +226,21 @@ private extension GameCollectionViewController
|
||||
self.present(confirmationAlertController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func viewSaveStates(for game: Game)
|
||||
{
|
||||
let storyboard = UIStoryboard(name: "PauseMenu", bundle: nil)
|
||||
|
||||
let saveStatesViewController = storyboard.instantiateViewController(withIdentifier: "saveStatesViewController") as! SaveStatesViewController
|
||||
saveStatesViewController.delegate = self
|
||||
saveStatesViewController.game = game
|
||||
saveStatesViewController.mode = .loading
|
||||
saveStatesViewController.theme = .light
|
||||
saveStatesViewController.showsDoneButton = true
|
||||
|
||||
let navigationController = UINavigationController(rootViewController: saveStatesViewController)
|
||||
self.present(navigationController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc func handleLongPressGesture(_ gestureRecognizer: UILongPressGestureRecognizer)
|
||||
{
|
||||
guard gestureRecognizer.state == .began else { return }
|
||||
@ -295,6 +314,27 @@ extension GameCollectionViewController: UIViewControllerPreviewingDelegate
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - SaveStatesViewControllerDelegate -
|
||||
/// SaveStatesViewControllerDelegate
|
||||
extension GameCollectionViewController: SaveStatesViewControllerDelegate
|
||||
{
|
||||
func saveStatesViewController(_ saveStatesViewController: SaveStatesViewController, updateSaveState saveState: SaveState)
|
||||
{
|
||||
}
|
||||
|
||||
func saveStatesViewController(_ saveStatesViewController: SaveStatesViewController, loadSaveState saveState: SaveStateProtocol)
|
||||
{
|
||||
self.activeSaveState = saveState
|
||||
|
||||
self.dismiss(animated: true) {
|
||||
let indexPath = self.dataSource.fetchedResultsController.indexPath(forObject: saveStatesViewController.game)!
|
||||
let cell = self.collectionView?.cellForItem(at: indexPath)
|
||||
|
||||
self.launchGame(withSender: cell, clearScreen: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - UICollectionViewDelegate -
|
||||
/// UICollectionViewDelegate
|
||||
extension GameCollectionViewController
|
||||
|
||||
@ -13,15 +13,6 @@ import DeltaCore
|
||||
|
||||
import Roxas
|
||||
|
||||
extension GamesViewController
|
||||
{
|
||||
enum Theme
|
||||
{
|
||||
case light
|
||||
case dark
|
||||
}
|
||||
}
|
||||
|
||||
class GamesViewController: UIViewController
|
||||
{
|
||||
var theme: Theme = .light {
|
||||
|
||||
@ -12,6 +12,21 @@ class SaveStatesCollectionHeaderView: UICollectionReusableView
|
||||
{
|
||||
let textLabel = UILabel()
|
||||
|
||||
fileprivate let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .dark)))
|
||||
|
||||
var isTextLabelVibrancyEnabled = true {
|
||||
didSet {
|
||||
if self.isTextLabelVibrancyEnabled
|
||||
{
|
||||
self.vibrancyView.contentView.addSubview(self.textLabel)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.addSubview(self.textLabel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override init(frame: CGRect)
|
||||
{
|
||||
super.init(frame: frame)
|
||||
@ -28,10 +43,9 @@ class SaveStatesCollectionHeaderView: UICollectionReusableView
|
||||
|
||||
private func initialize()
|
||||
{
|
||||
let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .dark)))
|
||||
vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
vibrancyView.frame = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
|
||||
self.addSubview(vibrancyView)
|
||||
self.vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
self.vibrancyView.frame = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
|
||||
self.addSubview(self.vibrancyView)
|
||||
|
||||
self.textLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.textLabel.textColor = UIColor.white
|
||||
@ -41,10 +55,12 @@ class SaveStatesCollectionHeaderView: UICollectionReusableView
|
||||
|
||||
self.textLabel.font = UIFont(descriptor: fontDescriptor, size: 0.0)
|
||||
self.textLabel.textAlignment = .center
|
||||
vibrancyView.contentView.addSubview(self.textLabel)
|
||||
self.vibrancyView.contentView.addSubview(self.textLabel)
|
||||
|
||||
// Auto Layout
|
||||
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[textLabel]-20-|", options: [], metrics: nil, views: ["textLabel": self.textLabel]))
|
||||
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-10-[textLabel]|", options: [], metrics: nil, views: ["textLabel": self.textLabel]))
|
||||
self.textLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20).isActive = true
|
||||
self.textLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
|
||||
self.textLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
|
||||
self.textLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,6 +49,18 @@ class SaveStatesViewController: UICollectionViewController
|
||||
|
||||
var mode = Mode.loading
|
||||
|
||||
var theme = Theme.dark {
|
||||
didSet {
|
||||
if self.isViewLoaded
|
||||
{
|
||||
self.updateTheme()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var showsDoneButton = false
|
||||
|
||||
fileprivate var vibrancyView: UIVisualEffectView!
|
||||
fileprivate var backgroundView: RSTBackgroundView!
|
||||
|
||||
fileprivate var prototypeCell = GridCollectionViewCell()
|
||||
@ -81,10 +93,10 @@ extension SaveStatesViewController
|
||||
{
|
||||
super.viewDidLoad()
|
||||
|
||||
let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .dark)))
|
||||
vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
vibrancyView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
|
||||
self.view.insertSubview(vibrancyView, at: 0)
|
||||
self.vibrancyView = UIVisualEffectView(effect: nil)
|
||||
self.vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
self.vibrancyView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
|
||||
self.view.insertSubview(self.vibrancyView, at: 0)
|
||||
|
||||
self.backgroundView = RSTBackgroundView(frame: CGRect(x: 0, y: 0, width: vibrancyView.bounds.width, height: vibrancyView.bounds.height))
|
||||
self.backgroundView.isHidden = true
|
||||
@ -92,7 +104,7 @@ extension SaveStatesViewController
|
||||
self.backgroundView.textLabel.text = NSLocalizedString("No Save States", comment: "")
|
||||
self.backgroundView.textLabel.textColor = UIColor.white
|
||||
self.backgroundView.detailTextLabel.textColor = UIColor.white
|
||||
vibrancyView.contentView.addSubview(self.backgroundView)
|
||||
self.vibrancyView.contentView.addSubview(self.backgroundView)
|
||||
|
||||
let collectionViewLayout = self.collectionViewLayout as! GridCollectionViewLayout
|
||||
let averageHorizontalInset = (collectionViewLayout.sectionInset.left + collectionViewLayout.sectionInset.right) / 2
|
||||
@ -114,6 +126,12 @@ extension SaveStatesViewController
|
||||
self.navigationItem.rightBarButtonItem = nil
|
||||
}
|
||||
|
||||
if self.showsDoneButton
|
||||
{
|
||||
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(SaveStatesViewController.handleDoneButton))
|
||||
self.navigationItem.rightBarButtonItem = doneButton
|
||||
}
|
||||
|
||||
// Manually update prototype cell properties
|
||||
self.prototypeCellWidthConstraint = self.prototypeCell.contentView.widthAnchor.constraint(equalToConstant: collectionViewLayout.itemWidth)
|
||||
self.prototypeCellWidthConstraint.isActive = true
|
||||
@ -126,6 +144,7 @@ extension SaveStatesViewController
|
||||
self.registerForPreviewing(with: self, sourceView: self.collectionView!)
|
||||
|
||||
self.updateBackgroundView()
|
||||
self.updateTheme()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool)
|
||||
@ -177,6 +196,41 @@ private extension SaveStatesViewController
|
||||
}
|
||||
}
|
||||
|
||||
func updateTheme()
|
||||
{
|
||||
switch self.theme
|
||||
{
|
||||
case .light:
|
||||
self.view.backgroundColor = UIColor.white
|
||||
|
||||
self.navigationController?.navigationBar.barStyle = .default
|
||||
self.navigationController?.toolbar.barStyle = .default
|
||||
|
||||
self.vibrancyView.effect = nil
|
||||
|
||||
self.backgroundView.textLabel.textColor = UIColor.gray
|
||||
self.backgroundView.detailTextLabel.textColor = UIColor.gray
|
||||
|
||||
case .dark:
|
||||
self.view.backgroundColor = nil
|
||||
|
||||
self.navigationController?.navigationBar.barStyle = .blackTranslucent
|
||||
self.navigationController?.toolbar.barStyle = .blackTranslucent
|
||||
|
||||
self.vibrancyView.effect = UIVibrancyEffect(blurEffect: UIBlurEffect(style: .dark))
|
||||
|
||||
self.backgroundView.textLabel.textColor = UIColor.white
|
||||
self.backgroundView.detailTextLabel.textColor = UIColor.white
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Navigation -
|
||||
|
||||
@objc func handleDoneButton()
|
||||
{
|
||||
self.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
//MARK: - Configure Views -
|
||||
|
||||
func configureCollectionViewCell(_ cell: GridCollectionViewCell, forIndexPath indexPath: IndexPath, ignoreExpensiveOperations ignoreOperations: Bool = false)
|
||||
@ -186,8 +240,20 @@ private extension SaveStatesViewController
|
||||
cell.imageView.backgroundColor = UIColor.white
|
||||
cell.imageView.image = UIImage(named: "DeltaPlaceholder")
|
||||
|
||||
cell.isTextLabelVibrancyEnabled = true
|
||||
cell.isImageViewVibrancyEnabled = true
|
||||
switch self.theme
|
||||
{
|
||||
case .light:
|
||||
cell.isTextLabelVibrancyEnabled = false
|
||||
cell.isImageViewVibrancyEnabled = false
|
||||
|
||||
cell.textLabel.textColor = UIColor.gray
|
||||
|
||||
case .dark:
|
||||
cell.isTextLabelVibrancyEnabled = true
|
||||
cell.isImageViewVibrancyEnabled = true
|
||||
|
||||
cell.textLabel.textColor = UIColor.white
|
||||
}
|
||||
|
||||
if !ignoreOperations
|
||||
{
|
||||
@ -218,7 +284,6 @@ private extension SaveStatesViewController
|
||||
let dimensions = deltaCore.emulatorConfiguration.videoBufferInfo.outputDimensions
|
||||
cell.maximumImageSize = CGSize(width: self.prototypeCellWidthConstraint.constant, height: (self.prototypeCellWidthConstraint.constant / dimensions.width) * dimensions.height)
|
||||
|
||||
cell.textLabel.textColor = UIColor.white
|
||||
cell.textLabel.font = UIFont.preferredFont(forTextStyle: .subheadline)
|
||||
|
||||
let name = saveState.name ?? self.dateFormatter.string(from: saveState.modifiedDate)
|
||||
@ -239,6 +304,17 @@ private extension SaveStatesViewController
|
||||
}
|
||||
|
||||
headerView.textLabel.text = title
|
||||
|
||||
switch self.theme
|
||||
{
|
||||
case .light:
|
||||
headerView.textLabel.textColor = UIColor.gray
|
||||
headerView.isTextLabelVibrancyEnabled = false
|
||||
|
||||
case .dark:
|
||||
headerView.textLabel.textColor = UIColor.white
|
||||
headerView.isTextLabelVibrancyEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Gestures -
|
||||
@ -549,10 +625,10 @@ extension SaveStatesViewController: UIViewControllerPreviewingDelegate
|
||||
{
|
||||
guard
|
||||
let indexPath = self.collectionView?.indexPathForItem(at: location),
|
||||
let layoutAttributes = self.collectionViewLayout.layoutAttributesForItem(at: indexPath),
|
||||
self.emulatorCoreSaveState != nil
|
||||
let layoutAttributes = self.collectionViewLayout.layoutAttributesForItem(at: indexPath)
|
||||
else { return nil }
|
||||
|
||||
guard self.emulatorCore == nil || (self.emulatorCore != nil && self.emulatorCoreSaveState != nil) else { return nil }
|
||||
|
||||
previewingContext.sourceRect = layoutAttributes.frame
|
||||
|
||||
|
||||
15
Delta/Theming/Theme.swift
Normal file
15
Delta/Theming/Theme.swift
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Theme.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 9/27/16.
|
||||
// Copyright © 2016 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum Theme
|
||||
{
|
||||
case light
|
||||
case dark
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user