// // SettingsViewController.swift // Delta // // Created by Riley Testut on 9/4/15. // Copyright © 2015 Riley Testut. All rights reserved. // import UIKit import DeltaCore import Roxas private extension SettingsViewController { enum Section: Int { case controllers case controllerSkins case controllerOpacity case threeDTouch } enum Segue: String { case controllers = "controllersSegue" case controllerSkins = "controllerSkinsSegue" } enum ControllerSkinsRow: Int { case snes case gba case gbc } } class SettingsViewController: UITableViewController { @IBOutlet private var controllerOpacityLabel: UILabel! @IBOutlet private var controllerOpacitySlider: UISlider! @IBOutlet private var versionLabel: UILabel! private var selectionFeedbackGenerator: UISelectionFeedbackGenerator? private var previousSelectedRowIndexPath: IndexPath? required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) NotificationCenter.default.addObserver(self, selector: #selector(SettingsViewController.externalGameControllerDidConnect(_:)), name: .externalGameControllerDidConnect, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(SettingsViewController.externalGameControllerDidDisconnect(_:)), name: .externalGameControllerDidDisconnect, object: nil) } override func viewDidLoad() { super.viewDidLoad() self.controllerOpacitySlider.value = Float(Settings.translucentControllerSkinOpacity) self.updateControllerOpacityLabel() if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String { self.versionLabel.text = NSLocalizedString(String(format: "Delta %@", version), comment: "Delta Version") } else { self.versionLabel.text = NSLocalizedString("Delta", comment: "") } } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if let indexPath = self.previousSelectedRowIndexPath { if indexPath.section == Section.controllers.rawValue { // Update and temporarily re-select selected row. self.tableView.reloadSections(IndexSet(integer: Section.controllers.rawValue), with: .none) self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none) } self.tableView.deselectRow(at: indexPath, animated: true) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let identifier = segue.identifier, let segueType = Segue(rawValue: identifier), let cell = sender as? UITableViewCell, let indexPath = self.tableView.indexPath(for: cell) else { return } self.previousSelectedRowIndexPath = indexPath switch segueType { case Segue.controllers: let controllersSettingsViewController = segue.destination as! ControllersSettingsViewController controllersSettingsViewController.playerIndex = indexPath.row case Segue.controllerSkins: let systemControllerSkinsViewController = segue.destination as! SystemControllerSkinsViewController let row = ControllerSkinsRow(rawValue: indexPath.row)! switch row { case .snes: systemControllerSkinsViewController.system = .snes case .gba: systemControllerSkinsViewController.system = .gba case .gbc: systemControllerSkinsViewController.system = .gbc } } } } private extension SettingsViewController { func updateControllerOpacityLabel() { let percentage = String(format: "%.f", Settings.translucentControllerSkinOpacity * 100) + "%" self.controllerOpacityLabel.text = percentage } func isSectionHidden(_ section: Section) -> Bool { switch section { case .threeDTouch: return self.view.traitCollection.forceTouchCapability != .available default: return false } } } private extension SettingsViewController { @IBAction func beginChangingControllerOpacity(with sender: UISlider) { self.selectionFeedbackGenerator = UISelectionFeedbackGenerator() self.selectionFeedbackGenerator?.prepare() } @IBAction func changeControllerOpacity(with sender: UISlider) { let roundedValue = CGFloat((sender.value / 0.05).rounded() * 0.05) if roundedValue != Settings.translucentControllerSkinOpacity { self.selectionFeedbackGenerator?.selectionChanged() } Settings.translucentControllerSkinOpacity = CGFloat(roundedValue) self.updateControllerOpacityLabel() } @IBAction func didFinishChangingControllerOpacity(with sender: UISlider) { sender.value = Float(Settings.translucentControllerSkinOpacity) self.selectionFeedbackGenerator = nil } } private extension SettingsViewController { @objc func externalGameControllerDidConnect(_ notification: Notification) { self.tableView.reloadSections(IndexSet(integer: Section.controllers.rawValue), with: .none) } @objc func externalGameControllerDidDisconnect(_ notification: Notification) { self.tableView.reloadSections(IndexSet(integer: Section.controllers.rawValue), with: .none) } } extension SettingsViewController { override func tableView(_ tableView: UITableView, numberOfRowsInSection sectionIndex: Int) -> Int { let section = Section(rawValue: sectionIndex)! switch section { case .controllers: return 1 // Temporarily hide other controller indexes until controller logic is finalized case .controllerSkins: return System.supportedSystems.count default: if isSectionHidden(section) { return 0 } else { return super.tableView(tableView, numberOfRowsInSection: sectionIndex) } } } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = super.tableView(tableView, cellForRowAt: indexPath) let section = Section(rawValue: indexPath.section)! switch section { case .controllers: if indexPath.row == Settings.localControllerPlayerIndex { cell.detailTextLabel?.text = UIDevice.current.name } else if let index = ExternalGameControllerManager.shared.connectedControllers.index(where: { $0.playerIndex == indexPath.row }) { let controller = ExternalGameControllerManager.shared.connectedControllers[index] cell.detailTextLabel?.text = controller.name } else { cell.detailTextLabel?.text = nil } case .controllerSkins: cell.textLabel?.text = System.supportedSystems[indexPath.row].localizedName default: break } return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath) let section = Section(rawValue: indexPath.section)! switch section { case Section.controllers: self.performSegue(withIdentifier: Segue.controllers.rawValue, sender: cell) case Section.controllerSkins: self.performSegue(withIdentifier: Segue.controllerSkins.rawValue, sender: cell) case Section.controllerOpacity: break case Section.threeDTouch: break } } override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { let section = Section(rawValue: section)! if isSectionHidden(section) { return nil } else { return super.tableView(tableView, titleForHeaderInSection: section.rawValue) } } override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { let section = Section(rawValue: section)! if isSectionHidden(section) { return nil } else { return super.tableView(tableView, titleForFooterInSection: section.rawValue) } } override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { let section = Section(rawValue: section)! if isSectionHidden(section) { return 1 } else { return super.tableView(tableView, heightForHeaderInSection: section.rawValue) } } override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { let section = Section(rawValue: section)! if isSectionHidden(section) { return 1 } else { return super.tableView(tableView, heightForFooterInSection: section.rawValue) } } }