diff --git a/.swiftlint.yml b/.swiftlint.yml index ec780f8..b0fac38 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,3 +1,6 @@ +disabled_rules: + - trailing_comma + excluded: # paths to ignore during linting. Takes precedence over `included`. - Carthage - Pods @@ -6,5 +9,8 @@ line_length: - 150 # warning - 200 # error +type_body_length: + - 250 + cyclomatic_complexity: ignores_case_statements: true \ No newline at end of file diff --git a/Life Saver tvOS/AppDelegate.swift b/Life Saver tvOS/AppDelegate.swift deleted file mode 100644 index d6b23f9..0000000 --- a/Life Saver tvOS/AppDelegate.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// AppDelegate.swift -// Life Saver tvOS -// -// Created by Bradley Root on 5/19/19. -// Copyright © 2019 Brad Root. All rights reserved. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - window = UIWindow(frame: UIScreen.main.bounds) - window?.rootViewController = GameViewController() - window?.makeKeyAndVisible() - - application.isIdleTimerDisabled = true - - return true - } - - func applicationWillResignActive(_: UIApplication) {} - - func applicationDidEnterBackground(_: UIApplication) {} - - func applicationWillEnterForeground(_: UIApplication) {} - - func applicationDidBecomeActive(_: UIApplication) {} - - func applicationWillTerminate(_: UIApplication) {} -} diff --git a/Life Saver tvOS/GameViewController.swift b/Life Saver tvOS/GameViewController.swift deleted file mode 100644 index 446e631..0000000 --- a/Life Saver tvOS/GameViewController.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// GameViewController.swift -// Life Saver tvOS -// -// Created by Bradley Root on 5/19/19. -// Copyright © 2019 Brad Root. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -import GameplayKit -import SpriteKit -import UIKit - -class GameViewController: UIViewController { - var scene: LifeScene? - var skView: SKView? - - override func viewDidLoad() { - super.viewDidLoad() - - UIApplication.shared.isIdleTimerDisabled = true - view = SKView(frame: UIScreen.main.bounds) - scene = LifeScene(size: view.bounds.size) - - scene!.animationSpeed = .fast - scene!.squareSize = .superSmall - - if let preset = lifePresets.filter({ $0.title == "Braineater" }).first { - if let appearanceMode = preset.appearanceMode { - scene!.appearanceMode = appearanceMode - } - if let color1 = preset.color1, let color2 = preset.color2, let color3 = preset.color3 { - scene!.aliveColors = [color1, color2, color3] - } - } - - scene!.scaleMode = .aspectFill - skView = view as? SKView - skView?.ignoresSiblingOrder = true - skView?.showsFPS = true - skView?.showsDrawCount = true - skView?.showsNodeCount = true - skView!.presentScene(scene) - } -} diff --git a/Life Saver.xcodeproj/project.pbxproj b/Life Saver.xcodeproj/project.pbxproj index 7c2d464..8490ae0 100644 --- a/Life Saver.xcodeproj/project.pbxproj +++ b/Life Saver.xcodeproj/project.pbxproj @@ -14,37 +14,43 @@ 4415352022973A530061434F /* URLType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4437905F22961BA200AC3AFF /* URLType.swift */; }; 4415352222974E220061434F /* LifeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4415352122974E220061434F /* LifeNode.swift */; }; 4415352322974E220061434F /* LifeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4415352122974E220061434F /* LifeNode.swift */; }; - 4415352422974E220061434F /* LifeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4415352122974E220061434F /* LifeNode.swift */; }; 4437906022961BA200AC3AFF /* URLType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4437905F22961BA200AC3AFF /* URLType.swift */; }; - 4437906122961D3B00AC3AFF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4FD88B12290553600AE066A /* Assets.xcassets */; }; 4480C7092294B05200CC2EDC /* FileGrabber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7082294B05200CC2EDC /* FileGrabber.swift */; }; 4480C70A2294B05200CC2EDC /* FileGrabber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7082294B05200CC2EDC /* FileGrabber.swift */; }; - 4480C70B2294B05200CC2EDC /* FileGrabber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7082294B05200CC2EDC /* FileGrabber.swift */; }; - 4480C70E2294B4C800CC2EDC /* LifeDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C70D2294B4C800CC2EDC /* LifeDatabase.swift */; }; 4480C70F2294B4C800CC2EDC /* LifeDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C70D2294B4C800CC2EDC /* LifeDatabase.swift */; }; 4480C7162294B60800CC2EDC /* LifeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7152294B60800CC2EDC /* LifeManager.swift */; }; 4480C7172294B60800CC2EDC /* LifeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7152294B60800CC2EDC /* LifeManager.swift */; }; 4480C7412294CFB800CC2EDC /* ConfigureSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4480C7402294CFB800CC2EDC /* ConfigureSheet.xib */; }; 4480C7432294CFF400CC2EDC /* ConfigureSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7422294CFF400CC2EDC /* ConfigureSheetController.swift */; }; - 44A547AD22936C6A0020EC8E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4FD88B12290553600AE066A /* Assets.xcassets */; }; + 67E99765F2CC85D2357000E3 /* Pods_Life_Saver_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0F247DB6D6F78817A3F0E8F /* Pods_Life_Saver_tvOS.framework */; }; + B41C8C3F22C81D0200777A09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4FD88B12290553600AE066A /* Assets.xcassets */; }; + B41C8C4122C81D2400777A09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B41C8C4022C81D2400777A09 /* Assets.xcassets */; }; B45BF8BB22AC33E600D77162 /* ToroidalMatrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = B45BF8BA22AC33E600D77162 /* ToroidalMatrix.swift */; }; B45BF8BC22AC33E900D77162 /* ToroidalMatrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = B45BF8BA22AC33E600D77162 /* ToroidalMatrix.swift */; }; - B45BF8BD22AC33EA00D77162 /* ToroidalMatrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = B45BF8BA22AC33E600D77162 /* ToroidalMatrix.swift */; }; - B49221622291F59D00D5DEA4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49221612291F59D00D5DEA4 /* AppDelegate.swift */; }; - B492216A2291F59D00D5DEA4 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49221692291F59D00D5DEA4 /* GameViewController.swift */; }; - B49221742291F6AA00D5DEA4 /* LifeScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FD88BD229055FB00AE066A /* LifeScene.swift */; }; + B476201522C4612300B4834C /* MenuTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B476201422C4612300B4834C /* MenuTableViewController.swift */; }; B49221752294E5C500D5DEA4 /* ConfigureSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4480C7402294CFB800CC2EDC /* ConfigureSheet.xib */; }; B49221762294E71A00D5DEA4 /* ConfigureSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7422294CFF400CC2EDC /* ConfigureSheetController.swift */; }; - B49F59B8229881C700571F05 /* LifePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4415351D229733C20061434F /* LifePreset.swift */; }; - B4BF1F2222BEA478007E1095 /* LifeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7152294B60800CC2EDC /* LifeManager.swift */; }; + B49CB72822C3047500A53FB7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49CB72722C3047500A53FB7 /* AppDelegate.swift */; }; + B49CB73022C3047500A53FB7 /* LifeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49CB72F22C3047500A53FB7 /* LifeViewController.swift */; }; + B49CB73322C3047500A53FB7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B49CB73122C3047500A53FB7 /* Main.storyboard */; }; + B49CB73A22C304F500A53FB7 /* LifeScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FD88BD229055FB00AE066A /* LifeScene.swift */; }; + B49CB73B22C304F700A53FB7 /* LifeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4415352122974E220061434F /* LifeNode.swift */; }; + B49CB73C22C304FA00A53FB7 /* LifePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4415351D229733C20061434F /* LifePreset.swift */; }; + B49CB73D22C3050300A53FB7 /* FileGrabber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7082294B05200CC2EDC /* FileGrabber.swift */; }; + B49CB73F22C3050B00A53FB7 /* ToroidalMatrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = B45BF8BA22AC33E600D77162 /* ToroidalMatrix.swift */; }; + B49CB74122C30EFA00A53FB7 /* ColorPresetTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49CB74022C30EFA00A53FB7 /* ColorPresetTableViewCell.swift */; }; + B49CB74222C314C400A53FB7 /* LifeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4480C7152294B60800CC2EDC /* LifeManager.swift */; }; + B49CB74322C314CD00A53FB7 /* LifeDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40CD56622C0520600CC33DC /* LifeDatabase.swift */; }; + B4D49C0D22C7B5C2000F4E0C /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D49C0A22C7B5C2000F4E0C /* Extensions.swift */; }; + B4D49C0F22C7B976000F4E0C /* LifeDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40CD56622C0520600CC33DC /* LifeDatabase.swift */; }; + B4D49C1122C81C67000F4E0C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4FD88B12290553600AE066A /* Assets.xcassets */; }; + B4D49C1222C81C67000F4E0C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4FD88B12290553600AE066A /* Assets.xcassets */; }; B4FD88A82290553400AE066A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FD88A72290553400AE066A /* AppDelegate.swift */; }; B4FD88B02290553400AE066A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FD88AF2290553400AE066A /* ViewController.swift */; }; - B4FD88B22290553600AE066A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4FD88B12290553600AE066A /* Assets.xcassets */; }; B4FD88B52290553600AE066A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4FD88B32290553600AE066A /* Main.storyboard */; }; B4FD88BE229055FB00AE066A /* LifeScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FD88BD229055FB00AE066A /* LifeScene.swift */; }; B4FD88D02290BA2400AE066A /* LifeScreenSaverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FD88CF2290BA2400AE066A /* LifeScreenSaverView.swift */; }; B4FD88D32290BAB700AE066A /* LifeScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FD88BD229055FB00AE066A /* LifeScene.swift */; }; - BDD2445FD5A862ADAD380E48 /* Pods_Life_Saver_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0F247DB6D6F78817A3F0E8F /* Pods_Life_Saver_tvOS.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -61,11 +67,17 @@ 502A6BF15E385B76A6422725 /* Pods-Life Saver tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Life Saver tvOS.release.xcconfig"; path = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.release.xcconfig"; sourceTree = ""; }; 5EE01FF9B77AC381FC307FC3 /* Pods-Life Saver macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Life Saver macOS.release.xcconfig"; path = "Target Support Files/Pods-Life Saver macOS/Pods-Life Saver macOS.release.xcconfig"; sourceTree = ""; }; 6B6B746C076EE9C58D443E92 /* Pods-Life Saver macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Life Saver macOS.debug.xcconfig"; path = "Target Support Files/Pods-Life Saver macOS/Pods-Life Saver macOS.debug.xcconfig"; sourceTree = ""; }; + B40CD56622C0520600CC33DC /* LifeDatabase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LifeDatabase.swift; sourceTree = ""; }; + B41C8C4022C81D2400777A09 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B45BF8BA22AC33E600D77162 /* ToroidalMatrix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToroidalMatrix.swift; sourceTree = ""; }; - B492215F2291F59C00D5DEA4 /* Life Saver tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Life Saver tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - B49221612291F59D00D5DEA4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - B49221692291F59D00D5DEA4 /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; }; - B49221702291F5A000D5DEA4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B476201422C4612300B4834C /* MenuTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MenuTableViewController.swift; path = ../MenuTableViewController.swift; sourceTree = ""; }; + B49CB72522C3047500A53FB7 /* Life Saver tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Life Saver tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + B49CB72722C3047500A53FB7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B49CB72F22C3047500A53FB7 /* LifeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LifeViewController.swift; sourceTree = ""; }; + B49CB73222C3047500A53FB7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + B49CB73622C3047800A53FB7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B49CB74022C30EFA00A53FB7 /* ColorPresetTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ColorPresetTableViewCell.swift; path = ../ColorPresetTableViewCell.swift; sourceTree = ""; }; + B4D49C0A22C7B5C2000F4E0C /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; B4FD88A42290553400AE066A /* Life Saver macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Life Saver macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; B4FD88A72290553400AE066A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; B4FD88AF2290553400AE066A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -84,11 +96,11 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - B492215C2291F59C00D5DEA4 /* Frameworks */ = { + B49CB72222C3047500A53FB7 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BDD2445FD5A862ADAD380E48 /* Pods_Life_Saver_tvOS.framework in Frameworks */, + 67E99765F2CC85D2357000E3 /* Pods_Life_Saver_tvOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -127,6 +139,7 @@ 4480C7082294B05200CC2EDC /* FileGrabber.swift */, 4437905F22961BA200AC3AFF /* URLType.swift */, B45BF8BA22AC33E600D77162 /* ToroidalMatrix.swift */, + B4D49C0A22C7B5C2000F4E0C /* Extensions.swift */, ); path = Utilities; sourceTree = ""; @@ -140,7 +153,7 @@ path = Configuration; sourceTree = ""; }; - 4480C70C2294B1B300CC2EDC /* Life Saver macOS */ = { + 4480C70C2294B1B300CC2EDC /* macOS */ = { isa = PBXGroup; children = ( B4FD88B62290553600AE066A /* Info.plist */, @@ -149,7 +162,7 @@ B4FD88B72290553600AE066A /* Life_Saver.entitlements */, B4FD88B32290553600AE066A /* Main.storyboard */, ); - path = "Life Saver macOS"; + path = macOS; sourceTree = ""; }; 58C9C1C400ED8FD965B9FA76 /* Pods */ = { @@ -165,23 +178,35 @@ path = Pods; sourceTree = ""; }; - B49221602291F59D00D5DEA4 /* Life Saver tvOS */ = { + B49CB72622C3047500A53FB7 /* tvOS */ = { isa = PBXGroup; children = ( - B49221612291F59D00D5DEA4 /* AppDelegate.swift */, - B49221692291F59D00D5DEA4 /* GameViewController.swift */, - B49221702291F5A000D5DEA4 /* Info.plist */, + B4D49C0E22C7B93A000F4E0C /* Menus */, + B49CB72722C3047500A53FB7 /* AppDelegate.swift */, + B49CB72F22C3047500A53FB7 /* LifeViewController.swift */, + B49CB73122C3047500A53FB7 /* Main.storyboard */, + B49CB73622C3047800A53FB7 /* Info.plist */, + B41C8C4022C81D2400777A09 /* Assets.xcassets */, + ); + path = tvOS; + sourceTree = ""; + }; + B4D49C0E22C7B93A000F4E0C /* Menus */ = { + isa = PBXGroup; + children = ( + B476201422C4612300B4834C /* MenuTableViewController.swift */, + B49CB74022C30EFA00A53FB7 /* ColorPresetTableViewCell.swift */, ); - path = "Life Saver tvOS"; + path = Menus; sourceTree = ""; }; B4FD889B2290553400AE066A = { isa = PBXGroup; children = ( - B4FD88A62290553400AE066A /* Life Saver Shared */, - B4FD88C52290B9DB00AE066A /* Life Saver Screensaver */, - 4480C70C2294B1B300CC2EDC /* Life Saver macOS */, - B49221602291F59D00D5DEA4 /* Life Saver tvOS */, + B4FD88A62290553400AE066A /* Shared */, + B4FD88C52290B9DB00AE066A /* macOS Screensaver */, + 4480C70C2294B1B300CC2EDC /* macOS */, + B49CB72622C3047500A53FB7 /* tvOS */, B4FD88A52290553400AE066A /* Products */, 58C9C1C400ED8FD965B9FA76 /* Pods */, 0E788E8E9F042832DC359B27 /* Frameworks */, @@ -193,12 +218,12 @@ children = ( B4FD88A42290553400AE066A /* Life Saver macOS.app */, B4FD88C42290B9DB00AE066A /* Life Saver Screensaver.saver */, - B492215F2291F59C00D5DEA4 /* Life Saver tvOS.app */, + B49CB72522C3047500A53FB7 /* Life Saver tvOS.app */, ); name = Products; sourceTree = ""; }; - B4FD88A62290553400AE066A /* Life Saver Shared */ = { + B4FD88A62290553400AE066A /* Shared */ = { isa = PBXGroup; children = ( B4FD88B12290553600AE066A /* Assets.xcassets */, @@ -206,12 +231,13 @@ 4415352122974E220061434F /* LifeNode.swift */, 4415351D229733C20061434F /* LifePreset.swift */, 4480C7152294B60800CC2EDC /* LifeManager.swift */, + B40CD56622C0520600CC33DC /* LifeDatabase.swift */, 4415352522974E320061434F /* Utilities */, ); - path = "Life Saver Shared"; + path = Shared; sourceTree = ""; }; - B4FD88C52290B9DB00AE066A /* Life Saver Screensaver */ = { + B4FD88C52290B9DB00AE066A /* macOS Screensaver */ = { isa = PBXGroup; children = ( 4437905D2296036A00AC3AFF /* Configuration */, @@ -219,7 +245,7 @@ 4480C70D2294B4C800CC2EDC /* LifeDatabase.swift */, B4FD88CA2290B9DB00AE066A /* Info.plist */, ); - path = "Life Saver Screensaver"; + path = "macOS Screensaver"; sourceTree = ""; }; /* End PBXGroup section */ @@ -235,22 +261,23 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - B492215E2291F59C00D5DEA4 /* Life Saver tvOS */ = { + B49CB72422C3047500A53FB7 /* Life Saver tvOS */ = { isa = PBXNativeTarget; - buildConfigurationList = B49221732291F5A000D5DEA4 /* Build configuration list for PBXNativeTarget "Life Saver tvOS" */; + buildConfigurationList = B49CB73922C3047800A53FB7 /* Build configuration list for PBXNativeTarget "Life Saver tvOS" */; buildPhases = ( - 075C67AD20E5ECF4F6464D41 /* [CP] Check Pods Manifest.lock */, - B492215B2291F59C00D5DEA4 /* Sources */, - B492215C2291F59C00D5DEA4 /* Frameworks */, - B492215D2291F59C00D5DEA4 /* Resources */, + 3B9839752AE999D754E73906 /* [CP] Check Pods Manifest.lock */, + B49CB72122C3047500A53FB7 /* Sources */, + B49CB72222C3047500A53FB7 /* Frameworks */, + B49CB72322C3047500A53FB7 /* Resources */, + B4D49C0822C7B239000F4E0C /* SwiftLint */, ); buildRules = ( ); dependencies = ( ); name = "Life Saver tvOS"; - productName = "Life Saver tvOS"; - productReference = B492215F2291F59C00D5DEA4 /* Life Saver tvOS.app */; + productName = "Life Saver"; + productReference = B49CB72522C3047500A53FB7 /* Life Saver tvOS.app */; productType = "com.apple.product-type.application"; }; B4FD88A32290553400AE066A /* Life Saver macOS */ = { @@ -301,7 +328,7 @@ LastUpgradeCheck = 1020; ORGANIZATIONNAME = "Brad Root"; TargetAttributes = { - B492215E2291F59C00D5DEA4 = { + B49CB72422C3047500A53FB7 = { CreatedOnToolsVersion = 10.2.1; }; B4FD88A32290553400AE066A = { @@ -328,17 +355,19 @@ targets = ( B4FD88A32290553400AE066A /* Life Saver macOS */, B4FD88C32290B9DB00AE066A /* Life Saver Screensaver */, - B492215E2291F59C00D5DEA4 /* Life Saver tvOS */, + B49CB72422C3047500A53FB7 /* Life Saver tvOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - B492215D2291F59C00D5DEA4 /* Resources */ = { + B49CB72322C3047500A53FB7 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 44A547AD22936C6A0020EC8E /* Assets.xcassets in Resources */, + B41C8C3F22C81D0200777A09 /* Assets.xcassets in Resources */, + B41C8C4122C81D2400777A09 /* Assets.xcassets in Resources */, + B49CB73322C3047500A53FB7 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -346,8 +375,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - B4FD88B22290553600AE066A /* Assets.xcassets in Resources */, B4FD88B52290553600AE066A /* Main.storyboard in Resources */, + B4D49C1222C81C67000F4E0C /* Assets.xcassets in Resources */, B49221752294E5C500D5DEA4 /* ConfigureSheet.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -356,15 +385,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + B4D49C1122C81C67000F4E0C /* Assets.xcassets in Resources */, 4480C7412294CFB800CC2EDC /* ConfigureSheet.xib in Resources */, - 4437906122961D3B00AC3AFF /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 075C67AD20E5ECF4F6464D41 /* [CP] Check Pods Manifest.lock */ = { + 3B9839752AE999D754E73906 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -426,6 +455,24 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + B4D49C0822C7B239000F4E0C /* SwiftLint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = SwiftLint; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; + }; DBD9B1CE8DFAA8523A73363F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -451,18 +498,22 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - B492215B2291F59C00D5DEA4 /* Sources */ = { + B49CB72122C3047500A53FB7 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B49221742291F6AA00D5DEA4 /* LifeScene.swift in Sources */, - 4415352422974E220061434F /* LifeNode.swift in Sources */, - 4480C70B2294B05200CC2EDC /* FileGrabber.swift in Sources */, - B492216A2291F59D00D5DEA4 /* GameViewController.swift in Sources */, - B45BF8BD22AC33EA00D77162 /* ToroidalMatrix.swift in Sources */, - B49F59B8229881C700571F05 /* LifePreset.swift in Sources */, - B49221622291F59D00D5DEA4 /* AppDelegate.swift in Sources */, - B4BF1F2222BEA478007E1095 /* LifeManager.swift in Sources */, + B49CB73A22C304F500A53FB7 /* LifeScene.swift in Sources */, + B49CB73C22C304FA00A53FB7 /* LifePreset.swift in Sources */, + B476201522C4612300B4834C /* MenuTableViewController.swift in Sources */, + B49CB73022C3047500A53FB7 /* LifeViewController.swift in Sources */, + B49CB72822C3047500A53FB7 /* AppDelegate.swift in Sources */, + B49CB73F22C3050B00A53FB7 /* ToroidalMatrix.swift in Sources */, + B49CB73B22C304F700A53FB7 /* LifeNode.swift in Sources */, + B4D49C0D22C7B5C2000F4E0C /* Extensions.swift in Sources */, + B49CB74322C314CD00A53FB7 /* LifeDatabase.swift in Sources */, + B49CB74122C30EFA00A53FB7 /* ColorPresetTableViewCell.swift in Sources */, + B49CB73D22C3050300A53FB7 /* FileGrabber.swift in Sources */, + B49CB74222C314C400A53FB7 /* LifeManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -475,8 +526,8 @@ 4415352222974E220061434F /* LifeNode.swift in Sources */, 4480C7092294B05200CC2EDC /* FileGrabber.swift in Sources */, B4FD88B02290553400AE066A /* ViewController.swift in Sources */, - 4480C70E2294B4C800CC2EDC /* LifeDatabase.swift in Sources */, B45BF8BB22AC33E600D77162 /* ToroidalMatrix.swift in Sources */, + B4D49C0F22C7B976000F4E0C /* LifeDatabase.swift in Sources */, B4FD88A82290553400AE066A /* AppDelegate.swift in Sources */, 4415352022973A530061434F /* URLType.swift in Sources */, 4480C7162294B60800CC2EDC /* LifeManager.swift in Sources */, @@ -504,6 +555,14 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + B49CB73122C3047500A53FB7 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B49CB73222C3047500A53FB7 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; B4FD88B32290553600AE066A /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -515,16 +574,16 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - B49221712291F5A000D5DEA4 /* Debug */ = { + B49CB73722C3047800A53FB7 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = E829750ED1ADE3B20BC32D52 /* Pods-Life Saver tvOS.debug.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_APPICON_NAME = "Brand Assets"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 2Y9M69QJKZ; - INFOPLIST_FILE = "Life Saver tvOS/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -538,16 +597,16 @@ }; name = Debug; }; - B49221722291F5A000D5DEA4 /* Release */ = { + B49CB73822C3047800A53FB7 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 502A6BF15E385B76A6422725 /* Pods-Life Saver tvOS.release.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_APPICON_NAME = "Brand Assets"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 2Y9M69QJKZ; - INFOPLIST_FILE = "Life Saver tvOS/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -682,11 +741,11 @@ baseConfigurationReference = 6B6B746C076EE9C58D443E92 /* Pods-Life Saver macOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = "Life Saver macOS/Life_Saver.entitlements"; + CODE_SIGN_ENTITLEMENTS = macOS/Life_Saver.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = 2Y9M69QJKZ; - INFOPLIST_FILE = "$(SRCROOT)/Life Saver macOS/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/macOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", @@ -702,11 +761,11 @@ baseConfigurationReference = 5EE01FF9B77AC381FC307FC3 /* Pods-Life Saver macOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = "Life Saver macOS/Life_Saver.entitlements"; + CODE_SIGN_ENTITLEMENTS = macOS/Life_Saver.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = 2Y9M69QJKZ; - INFOPLIST_FILE = "$(SRCROOT)/Life Saver macOS/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/macOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", @@ -725,7 +784,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = 2Y9M69QJKZ; - INFOPLIST_FILE = "Life Saver Screensaver/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/macOS Screensaver/Info.plist"; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -748,7 +807,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = 2Y9M69QJKZ; - INFOPLIST_FILE = "Life Saver Screensaver/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/macOS Screensaver/Info.plist"; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -765,11 +824,11 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - B49221732291F5A000D5DEA4 /* Build configuration list for PBXNativeTarget "Life Saver tvOS" */ = { + B49CB73922C3047800A53FB7 /* Build configuration list for PBXNativeTarget "Life Saver tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - B49221712291F5A000D5DEA4 /* Debug */, - B49221722291F5A000D5DEA4 /* Release */, + B49CB73722C3047800A53FB7 /* Debug */, + B49CB73822C3047800A53FB7 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Life Saver.xcodeproj/xcshareddata/xcschemes/macOS Debug.xcscheme b/Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver macOS Debug.xcscheme similarity index 100% rename from Life Saver.xcodeproj/xcshareddata/xcschemes/macOS Debug.xcscheme rename to Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver macOS Debug.xcscheme diff --git a/Life Saver.xcodeproj/xcshareddata/xcschemes/tvOS Debug.xcscheme b/Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver tvOS Debug.xcscheme similarity index 92% rename from Life Saver.xcodeproj/xcshareddata/xcschemes/tvOS Debug.xcscheme rename to Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver tvOS Debug.xcscheme index 4cfa4de..9ef773f 100644 --- a/Life Saver.xcodeproj/xcshareddata/xcschemes/tvOS Debug.xcscheme +++ b/Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver tvOS Debug.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -32,7 +32,7 @@ @@ -55,7 +55,7 @@ runnableDebuggingMode = "0"> @@ -74,7 +74,7 @@ runnableDebuggingMode = "0"> diff --git a/Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver tvOS.xcscheme b/Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver tvOS.xcscheme new file mode 100644 index 0000000..5ca03db --- /dev/null +++ b/Life Saver.xcodeproj/xcshareddata/xcschemes/Life Saver tvOS.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Life Saver.xcodeproj/xcuserdata/bradroot.xcuserdatad/xcschemes/xcschememanagement.plist b/Life Saver.xcodeproj/xcuserdata/bradroot.xcuserdatad/xcschemes/xcschememanagement.plist index 617cf2d..4171070 100644 --- a/Life Saver.xcodeproj/xcuserdata/bradroot.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Life Saver.xcodeproj/xcuserdata/bradroot.xcuserdatad/xcschemes/xcschememanagement.plist @@ -9,20 +9,20 @@ orderHint 0 - macOS Debug.xcscheme_^#shared#^_ + Life Saver macOS Debug.xcscheme_^#shared#^_ orderHint 1 - tvOS Debug.xcscheme_^#shared#^_ + Life Saver tvOS Debug.xcscheme_^#shared#^_ orderHint - 3 + 7 - tvOS.xcscheme + Life Saver tvOS.xcscheme_^#shared#^_ orderHint - 2 + 6 SuppressBuildableAutocreation diff --git a/Podfile b/Podfile index d44c099..8545615 100644 --- a/Podfile +++ b/Podfile @@ -23,5 +23,5 @@ target 'Life Saver tvOS' do use_frameworks! # Pods for Life Saver tvOS - + pod 'SwiftLint' end diff --git a/Podfile.lock b/Podfile.lock index 0d01fa0..1ce9e53 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -11,6 +11,6 @@ SPEC REPOS: SPEC CHECKSUMS: SwiftLint: fed9c66336e41fc74dc48a73678380718f0c8b0e -PODFILE CHECKSUM: 05e9ba66064aab2784708b41bc20d5018f76cf98 +PODFILE CHECKSUM: 4e098b7aa804dffdefce9b1afb1a86d385d687ae COCOAPODS: 1.7.2 diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 0d01fa0..1ce9e53 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -11,6 +11,6 @@ SPEC REPOS: SPEC CHECKSUMS: SwiftLint: fed9c66336e41fc74dc48a73678380718f0c8b0e -PODFILE CHECKSUM: 05e9ba66064aab2784708b41bc20d5018f76cf98 +PODFILE CHECKSUM: 4e098b7aa804dffdefce9b1afb1a86d385d687ae COCOAPODS: 1.7.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 1519acd..f215607 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,40 +7,57 @@ objects = { /* Begin PBXAggregateTarget section */ - 52B60EC2A583F24ACBB69C113F5488B9 /* SwiftLint */ = { + 07B93100044EF37C3FEE234DF77D3C11 /* SwiftLint-tvOS */ = { isa = PBXAggregateTarget; - buildConfigurationList = AE7B4FB01588B9E6DF09CB79FC7CE7BD /* Build configuration list for PBXAggregateTarget "SwiftLint" */; + buildConfigurationList = 7A71D33AF5AD7FE987D9D4E2CC7353B9 /* Build configuration list for PBXAggregateTarget "SwiftLint-tvOS" */; buildPhases = ( ); dependencies = ( ); - name = SwiftLint; + name = "SwiftLint-tvOS"; + }; + 9F0E6E0C8BF75091EADD98FA13B1A847 /* SwiftLint-macOS */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 0D0981C130B08F416BEB2EAEC0323E63 /* Build configuration list for PBXAggregateTarget "SwiftLint-macOS" */; + buildPhases = ( + ); + dependencies = ( + ); + name = "SwiftLint-macOS"; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 3E34016F9F40A26CB5C891FA01414757 /* Pods-Life Saver Screensaver-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 227ACFDAB692458B3C5C2FE30904BE36 /* Pods-Life Saver Screensaver-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4E9740A4786B95001358F7CAB07A8497 /* Pods-Life Saver macOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 83EB07F1EB6533C9F17FD1ADD45D3CD3 /* Pods-Life Saver macOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5289DC2096DE80698C1E2C2CADF18669 /* Pods-Life Saver tvOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 98B93D8B468377FEE65C459E22FF4B31 /* Pods-Life Saver tvOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5FDFA3E0D04E135B480F79914577ECD2 /* Pods-Life Saver macOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 898FDD7F5B64CD51152E87B8FC309B5A /* Pods-Life Saver macOS-dummy.m */; }; - 890962F54A5674BED7C167D3FDDA5A1B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0CA16DCF871AB0B0369A82A37F75611 /* Cocoa.framework */; }; + 479012DCDA10524BDC2AA6DB52735E2A /* Pods-Life Saver tvOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 98B93D8B468377FEE65C459E22FF4B31 /* Pods-Life Saver tvOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A2A09E54DFC1C65853B0A099A3450A1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7947CB8D179191B73CEF516DDAB119C9 /* Foundation.framework */; }; + 6057F03864C080165DF6D8E1953E7D33 /* Pods-Life Saver tvOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FB040AC5B2C059764AC228131A981D3 /* Pods-Life Saver tvOS-dummy.m */; }; + 8559033339282510030B8DBE4526AD69 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0CA16DCF871AB0B0369A82A37F75611 /* Cocoa.framework */; }; 9B95B993F83537D7EF4EF496236EB3A0 /* Pods-Life Saver Screensaver-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = AE1D776CC277BC317038B893FFBC5D58 /* Pods-Life Saver Screensaver-dummy.m */; }; - 9C8E9CB8C8D50D9DD49DC7F1B358FF44 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7947CB8D179191B73CEF516DDAB119C9 /* Foundation.framework */; }; + B8921DE1D5A24135CCE02CF2D8E1BFB2 /* Pods-Life Saver macOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 83EB07F1EB6533C9F17FD1ADD45D3CD3 /* Pods-Life Saver macOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA6B684E17B9F34A6D38CD5880DB362D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0CA16DCF871AB0B0369A82A37F75611 /* Cocoa.framework */; }; - FE62AFB7DED7FE08A00B0058523130C3 /* Pods-Life Saver tvOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FB040AC5B2C059764AC228131A981D3 /* Pods-Life Saver tvOS-dummy.m */; }; + F9462148179E9C29F7EF2BEDBA20D9AF /* Pods-Life Saver macOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 898FDD7F5B64CD51152E87B8FC309B5A /* Pods-Life Saver macOS-dummy.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 426314B338FDDF07D7EE617E9FDDBAAA /* PBXContainerItemProxy */ = { + 82F5EABAD255E8A756512A194F8057BA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9F0E6E0C8BF75091EADD98FA13B1A847; + remoteInfo = "SwiftLint-macOS"; + }; + 92480934916F2CB00C469E261F7A909F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 52B60EC2A583F24ACBB69C113F5488B9; - remoteInfo = SwiftLint; + remoteGlobalIDString = 07B93100044EF37C3FEE234DF77D3C11; + remoteInfo = "SwiftLint-tvOS"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0A53E555BBC0E5F99EB5DFAF5415E209 /* SwiftLint-macOS.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "SwiftLint-macOS.xcconfig"; sourceTree = ""; }; 227ACFDAB692458B3C5C2FE30904BE36 /* Pods-Life Saver Screensaver-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Life Saver Screensaver-umbrella.h"; sourceTree = ""; }; 235BB1AC4868E4F8140CC5E8CD3F4BED /* Pods-Life Saver tvOS-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Life Saver tvOS-Info.plist"; sourceTree = ""; }; 398EDD7D103E403B828FB0A1206B755B /* Pods-Life Saver macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Life Saver macOS.release.xcconfig"; sourceTree = ""; }; @@ -52,7 +69,6 @@ 83EB07F1EB6533C9F17FD1ADD45D3CD3 /* Pods-Life Saver macOS-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Life Saver macOS-umbrella.h"; sourceTree = ""; }; 86531140D306D1BDAA17260C139A4019 /* Pods-Life Saver Screensaver-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Life Saver Screensaver-acknowledgements.markdown"; sourceTree = ""; }; 898FDD7F5B64CD51152E87B8FC309B5A /* Pods-Life Saver macOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Life Saver macOS-dummy.m"; sourceTree = ""; }; - 89F85ACF3D78B39506B75103B4694B36 /* SwiftLint.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftLint.xcconfig; sourceTree = ""; }; 8AE3097A9255C0EFABB9A4C7C6CD6218 /* Pods-Life Saver macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Life Saver macOS.debug.xcconfig"; sourceTree = ""; }; 97478B5053B11BFE402559A9B5AEAAE1 /* Pods-Life Saver Screensaver.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Life Saver Screensaver.debug.xcconfig"; sourceTree = ""; }; 98B93D8B468377FEE65C459E22FF4B31 /* Pods-Life Saver tvOS-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Life Saver tvOS-umbrella.h"; sourceTree = ""; }; @@ -63,6 +79,7 @@ A553AF1E60BD851057FF0E3B0ABCE7DF /* Pods-Life Saver tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Life Saver tvOS.release.xcconfig"; sourceTree = ""; }; AE1D776CC277BC317038B893FFBC5D58 /* Pods-Life Saver Screensaver-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Life Saver Screensaver-dummy.m"; sourceTree = ""; }; B4F8292AFEEA1E4AF5B2C831DA1304A5 /* Pods_Life_Saver_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Life_Saver_macOS.framework; path = "Pods-Life Saver macOS.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + C6D5BD4F15C003CE7FAC516B80DF28EC /* SwiftLint-tvOS.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "SwiftLint-tvOS.xcconfig"; path = "../SwiftLint-tvOS/SwiftLint-tvOS.xcconfig"; sourceTree = ""; }; C9821C04A095E85A88F88C5BD5B13943 /* Pods-Life Saver tvOS-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Life Saver tvOS-acknowledgements.markdown"; sourceTree = ""; }; CB7A5F87FF588BC87951CAEBE289AFE6 /* Pods-Life Saver tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Life Saver tvOS.debug.xcconfig"; sourceTree = ""; }; D6547326B99848B9BCE3433D35A35CBC /* Pods-Life Saver Screensaver.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Life Saver Screensaver.release.xcconfig"; sourceTree = ""; }; @@ -75,27 +92,27 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 3215B91004CD8DA0B4D5958FC25A0CC0 /* Frameworks */ = { + 3C4BF30F3AE2DD2FC7C35AAD4C05A820 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9C8E9CB8C8D50D9DD49DC7F1B358FF44 /* Foundation.framework in Frameworks */, + 8559033339282510030B8DBE4526AD69 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 32CCE717D1FE50D601173EE887D464EB /* Frameworks */ = { + 8EEC97E39519700486987F7D51D08B18 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 890962F54A5674BED7C167D3FDDA5A1B /* Cocoa.framework in Frameworks */, + DA6B684E17B9F34A6D38CD5880DB362D /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 8EEC97E39519700486987F7D51D08B18 /* Frameworks */ = { + AE64A8E5190358DD965580785090095A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DA6B684E17B9F34A6D38CD5880DB362D /* Cocoa.framework in Frameworks */, + 5A2A09E54DFC1C65853B0A099A3450A1 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -136,29 +153,30 @@ name = tvOS; sourceTree = ""; }; - 63A11A520583122BEB0D8B6FF70F7502 /* OS X */ = { + 2FE2FD9E17AD5BB915E0D23D476A19E0 /* Support Files */ = { isa = PBXGroup; children = ( - E0CA16DCF871AB0B0369A82A37F75611 /* Cocoa.framework */, + 0A53E555BBC0E5F99EB5DFAF5415E209 /* SwiftLint-macOS.xcconfig */, + C6D5BD4F15C003CE7FAC516B80DF28EC /* SwiftLint-tvOS.xcconfig */, ); - name = "OS X"; + name = "Support Files"; + path = "../Target Support Files/SwiftLint-macOS"; sourceTree = ""; }; - 965877409E01FB3D85D85E90E6B30185 /* Pods */ = { + 63A11A520583122BEB0D8B6FF70F7502 /* OS X */ = { isa = PBXGroup; children = ( - 9AED61B9A1CFA211C061344F741DBA07 /* SwiftLint */, + E0CA16DCF871AB0B0369A82A37F75611 /* Cocoa.framework */, ); - name = Pods; + name = "OS X"; sourceTree = ""; }; - 9AED61B9A1CFA211C061344F741DBA07 /* SwiftLint */ = { + 965877409E01FB3D85D85E90E6B30185 /* Pods */ = { isa = PBXGroup; children = ( - EEA599FE5C15138FF0981CCFB01E55AA /* Support Files */, + D2A28A9353B21FA4349A5E2D08ADA9B5 /* SwiftLint */, ); - name = SwiftLint; - path = SwiftLint; + name = Pods; sourceTree = ""; }; B8D787C369FB90AF9F92ECA9926A8A7E /* Pods-Life Saver Screensaver */ = { @@ -214,40 +232,40 @@ name = "Targets Support Files"; sourceTree = ""; }; - E3FDFE173C940A08CDAE8298694FAEAF /* Frameworks */ = { + D2A28A9353B21FA4349A5E2D08ADA9B5 /* SwiftLint */ = { isa = PBXGroup; children = ( - 63A11A520583122BEB0D8B6FF70F7502 /* OS X */, - 182E976C61BDBC8EB5AAE042D85583A1 /* tvOS */, + 2FE2FD9E17AD5BB915E0D23D476A19E0 /* Support Files */, ); - name = Frameworks; + name = SwiftLint; + path = SwiftLint; sourceTree = ""; }; - EEA599FE5C15138FF0981CCFB01E55AA /* Support Files */ = { + E3FDFE173C940A08CDAE8298694FAEAF /* Frameworks */ = { isa = PBXGroup; children = ( - 89F85ACF3D78B39506B75103B4694B36 /* SwiftLint.xcconfig */, + 63A11A520583122BEB0D8B6FF70F7502 /* OS X */, + 182E976C61BDBC8EB5AAE042D85583A1 /* tvOS */, ); - name = "Support Files"; - path = "../Target Support Files/SwiftLint"; + name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 3330F198284B2178EE8617E233201D6E /* Headers */ = { + 1F192A95124095FC0C8E7EB745EF6AA2 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4E9740A4786B95001358F7CAB07A8497 /* Pods-Life Saver macOS-umbrella.h in Headers */, + B8921DE1D5A24135CCE02CF2D8E1BFB2 /* Pods-Life Saver macOS-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - DB78795109526A9F67EBEF947B89D307 /* Headers */ = { + 8711CCF8D9F934E75792194C25EC16C4 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 5289DC2096DE80698C1E2C2CADF18669 /* Pods-Life Saver tvOS-umbrella.h in Headers */, + 479012DCDA10524BDC2AA6DB52735E2A /* Pods-Life Saver tvOS-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -282,17 +300,17 @@ }; 72CE050E7DC4DF0CBFBA9D524ED29015 /* Pods-Life Saver macOS */ = { isa = PBXNativeTarget; - buildConfigurationList = D404414FBAF42AB5BE1206C31466991F /* Build configuration list for PBXNativeTarget "Pods-Life Saver macOS" */; + buildConfigurationList = 4165F784B119B54F3B7B85D0DDEE0AE2 /* Build configuration list for PBXNativeTarget "Pods-Life Saver macOS" */; buildPhases = ( - 3330F198284B2178EE8617E233201D6E /* Headers */, - DBFDEF246E170F4FE68B81F35563200F /* Sources */, - 32CCE717D1FE50D601173EE887D464EB /* Frameworks */, - 6980AC8866922177AE6EF49CF3AE3746 /* Resources */, + 1F192A95124095FC0C8E7EB745EF6AA2 /* Headers */, + 4C42803CFB9352D2D6C9BFAD28B7745D /* Sources */, + 3C4BF30F3AE2DD2FC7C35AAD4C05A820 /* Frameworks */, + 4FE60DF1434F19C28BF2DB666E38CB63 /* Resources */, ); buildRules = ( ); dependencies = ( - F4A12D59F75D7061A67C055F20E49EAA /* PBXTargetDependency */, + B055CDE526E6BBEBBBCF1E8494F57A90 /* PBXTargetDependency */, ); name = "Pods-Life Saver macOS"; productName = "Pods-Life Saver macOS"; @@ -301,16 +319,17 @@ }; B780427177FAFADAFF435B6CA721B044 /* Pods-Life Saver tvOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 6ED0EE05B280C39AD0FB7946E4D35A7B /* Build configuration list for PBXNativeTarget "Pods-Life Saver tvOS" */; + buildConfigurationList = 1CE16184FA2A08A9B5022639761D6B78 /* Build configuration list for PBXNativeTarget "Pods-Life Saver tvOS" */; buildPhases = ( - DB78795109526A9F67EBEF947B89D307 /* Headers */, - ED814CC203B5F3236869AB5CD055F403 /* Sources */, - 3215B91004CD8DA0B4D5958FC25A0CC0 /* Frameworks */, - 9982B7233B751B67B5F0DA5D729311AD /* Resources */, + 8711CCF8D9F934E75792194C25EC16C4 /* Headers */, + CF1207F18A9D2135B3A961EBBE56E061 /* Sources */, + AE64A8E5190358DD965580785090095A /* Frameworks */, + AA285C0D7114BC9BCF85A2E2541146C8 /* Resources */, ); buildRules = ( ); dependencies = ( + 7493C32DC41AE2364B68B7EF65779F24 /* PBXTargetDependency */, ); name = "Pods-Life Saver tvOS"; productName = "Pods-Life Saver tvOS"; @@ -341,7 +360,8 @@ 72CE050E7DC4DF0CBFBA9D524ED29015 /* Pods-Life Saver macOS */, 0A3EFC96E07575A1DFB4D26A2839C4E7 /* Pods-Life Saver Screensaver */, B780427177FAFADAFF435B6CA721B044 /* Pods-Life Saver tvOS */, - 52B60EC2A583F24ACBB69C113F5488B9 /* SwiftLint */, + 9F0E6E0C8BF75091EADD98FA13B1A847 /* SwiftLint-macOS */, + 07B93100044EF37C3FEE234DF77D3C11 /* SwiftLint-tvOS */, ); }; /* End PBXProject section */ @@ -354,14 +374,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6980AC8866922177AE6EF49CF3AE3746 /* Resources */ = { + 4FE60DF1434F19C28BF2DB666E38CB63 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 9982B7233B751B67B5F0DA5D729311AD /* Resources */ = { + AA285C0D7114BC9BCF85A2E2541146C8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -371,42 +391,102 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 99E0E7FB3D92241E6411F0750A4D8D5E /* Sources */ = { + 4C42803CFB9352D2D6C9BFAD28B7745D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 9B95B993F83537D7EF4EF496236EB3A0 /* Pods-Life Saver Screensaver-dummy.m in Sources */, + F9462148179E9C29F7EF2BEDBA20D9AF /* Pods-Life Saver macOS-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DBFDEF246E170F4FE68B81F35563200F /* Sources */ = { + 99E0E7FB3D92241E6411F0750A4D8D5E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5FDFA3E0D04E135B480F79914577ECD2 /* Pods-Life Saver macOS-dummy.m in Sources */, + 9B95B993F83537D7EF4EF496236EB3A0 /* Pods-Life Saver Screensaver-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - ED814CC203B5F3236869AB5CD055F403 /* Sources */ = { + CF1207F18A9D2135B3A961EBBE56E061 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - FE62AFB7DED7FE08A00B0058523130C3 /* Pods-Life Saver tvOS-dummy.m in Sources */, + 6057F03864C080165DF6D8E1953E7D33 /* Pods-Life Saver tvOS-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - F4A12D59F75D7061A67C055F20E49EAA /* PBXTargetDependency */ = { + 7493C32DC41AE2364B68B7EF65779F24 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = SwiftLint; - target = 52B60EC2A583F24ACBB69C113F5488B9 /* SwiftLint */; - targetProxy = 426314B338FDDF07D7EE617E9FDDBAAA /* PBXContainerItemProxy */; + name = "SwiftLint-tvOS"; + target = 07B93100044EF37C3FEE234DF77D3C11 /* SwiftLint-tvOS */; + targetProxy = 92480934916F2CB00C469E261F7A909F /* PBXContainerItemProxy */; + }; + B055CDE526E6BBEBBBCF1E8494F57A90 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "SwiftLint-macOS"; + target = 9F0E6E0C8BF75091EADD98FA13B1A847 /* SwiftLint-macOS */; + targetProxy = 82F5EABAD255E8A756512A194F8057BA /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 0F0EEBB62A73C3B460BF619BD42D7FE7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CB7A5F87FF588BC87951CAEBE289AFE6 /* Pods-Life Saver tvOS.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 12.2; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 21D9652AD1A71BEDAAC8C44DD090D18D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C6D5BD4F15C003CE7FAC516B80DF28EC /* SwiftLint-tvOS.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; 3D5124080488C16600AF9BE4AFF1AE02 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -472,62 +552,6 @@ }; name = Debug; }; - 58190F6DFD39546710DD9A8C9DA71608 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A553AF1E60BD851057FF0E3B0ABCE7DF /* Pods-Life Saver tvOS.release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 12.2; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 8B2757D413B867ECEFDC200DDE84AFD2 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 89F85ACF3D78B39506B75103B4694B36 /* SwiftLint.xcconfig */; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.6; - SDKROOT = macosx; - }; - name = Release; - }; 8E9F8AB46A8BAEF6FC5EAFC8B6B873E1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -589,7 +613,23 @@ }; name = Release; }; - A597C6C170B9E89BC75C575EB65A41F0 /* Debug */ = { + A96F7C5AF4BDEF36E9A64F9AE7EDA95A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C6D5BD4F15C003CE7FAC516B80DF28EC /* SwiftLint-tvOS.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.0; + }; + name = Debug; + }; + B63FCC7629BD167A29B061D453BD67C6 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 8AE3097A9255C0EFABB9A4C7C6CD6218 /* Pods-Life Saver macOS.debug.xcconfig */; buildSettings = { @@ -629,41 +669,57 @@ }; name = Debug; }; - CB6172345BEA7ED682297FEF06A238DB /* Release */ = { + C4F9CB6BEA3B697DE48DB3B1C061EA31 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 398EDD7D103E403B828FB0A1206B755B /* Pods-Life Saver macOS.release.xcconfig */; + baseConfigurationReference = 0A53E555BBC0E5F99EB5DFAF5415E209 /* SwiftLint-macOS.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6; + SDKROOT = macosx; + }; + name = Release; + }; + CAB0E5854B1D27157D35548A82AE7835 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A553AF1E60BD851057FF0E3B0ABCE7DF /* Pods-Life Saver tvOS.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - INFOPLIST_FILE = "Target Support Files/Pods-Life Saver macOS/Pods-Life Saver macOS-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "@executable_path/../Frameworks", + "@executable_path/Frameworks", "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MODULEMAP_FILE = "Target Support Files/Pods-Life Saver macOS/Pods-Life Saver macOS.modulemap"; + MODULEMAP_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = macosx; + SDKROOT = appletvos; SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 12.2; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -749,64 +805,76 @@ }; name = Debug; }; - EBA0CC105C99CE8BFDA51C62E70EA605 /* Debug */ = { + EE64616D9AE4F273691BD9E00A83D137 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 89F85ACF3D78B39506B75103B4694B36 /* SwiftLint.xcconfig */; + baseConfigurationReference = 398EDD7D103E403B828FB0A1206B755B /* Pods-Life Saver macOS.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.6; - SDKROOT = macosx; - }; - name = Debug; - }; - FABD3A9EF636E2FCF5521BD65E4C01B1 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = CB7A5F87FF588BC87951CAEBE289AFE6 /* Pods-Life Saver tvOS.debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-Info.plist"; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = "Target Support Files/Pods-Life Saver macOS/Pods-Life Saver macOS-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "@executable_path/Frameworks", + "@executable_path/../Frameworks", "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.modulemap"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MODULEMAP_FILE = "Target Support Files/Pods-Life Saver macOS/Pods-Life Saver macOS.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = appletvos; + SDKROOT = macosx; SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 12.2; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; + name = Release; + }; + F065E9E7006E156BEA987FB995AFABBC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0A53E555BBC0E5F99EB5DFAF5415E209 /* SwiftLint-macOS.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6; + SDKROOT = macosx; + }; name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 0D0981C130B08F416BEB2EAEC0323E63 /* Build configuration list for PBXAggregateTarget "SwiftLint-macOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F065E9E7006E156BEA987FB995AFABBC /* Debug */, + C4F9CB6BEA3B697DE48DB3B1C061EA31 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 19D933694B837F87A8F2F7620DA185BD /* Build configuration list for PBXNativeTarget "Pods-Life Saver Screensaver" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -816,38 +884,38 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + 1CE16184FA2A08A9B5022639761D6B78 /* Build configuration list for PBXNativeTarget "Pods-Life Saver tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 3D5124080488C16600AF9BE4AFF1AE02 /* Debug */, - 8E9F8AB46A8BAEF6FC5EAFC8B6B873E1 /* Release */, + 0F0EEBB62A73C3B460BF619BD42D7FE7 /* Debug */, + CAB0E5854B1D27157D35548A82AE7835 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6ED0EE05B280C39AD0FB7946E4D35A7B /* Build configuration list for PBXNativeTarget "Pods-Life Saver tvOS" */ = { + 4165F784B119B54F3B7B85D0DDEE0AE2 /* Build configuration list for PBXNativeTarget "Pods-Life Saver macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - FABD3A9EF636E2FCF5521BD65E4C01B1 /* Debug */, - 58190F6DFD39546710DD9A8C9DA71608 /* Release */, + B63FCC7629BD167A29B061D453BD67C6 /* Debug */, + EE64616D9AE4F273691BD9E00A83D137 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - AE7B4FB01588B9E6DF09CB79FC7CE7BD /* Build configuration list for PBXAggregateTarget "SwiftLint" */ = { + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - EBA0CC105C99CE8BFDA51C62E70EA605 /* Debug */, - 8B2757D413B867ECEFDC200DDE84AFD2 /* Release */, + 3D5124080488C16600AF9BE4AFF1AE02 /* Debug */, + 8E9F8AB46A8BAEF6FC5EAFC8B6B873E1 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D404414FBAF42AB5BE1206C31466991F /* Build configuration list for PBXNativeTarget "Pods-Life Saver macOS" */ = { + 7A71D33AF5AD7FE987D9D4E2CC7353B9 /* Build configuration list for PBXAggregateTarget "SwiftLint-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - A597C6C170B9E89BC75C575EB65A41F0 /* Debug */, - CB6172345BEA7ED682297FEF06A238DB /* Release */, + A96F7C5AF4BDEF36E9A64F9AE7EDA95A /* Debug */, + 21D9652AD1A71BEDAAC8C44DD090D18D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.markdown b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.markdown index 102af75..d8c5fed 100644 --- a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.markdown @@ -1,3 +1,28 @@ # Acknowledgements This application makes use of the following third party libraries: + +## SwiftLint + +The MIT License (MIT) + +Copyright (c) 2015 Realm Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.plist b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.plist index 7acbad1..88fb231 100644 --- a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS-acknowledgements.plist @@ -12,6 +12,37 @@ Type PSGroupSpecifier + + FooterText + The MIT License (MIT) + +Copyright (c) 2015 Realm Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + SwiftLint + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.debug.xcconfig b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.debug.xcconfig index 521bc0e..566aa02 100644 --- a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.debug.xcconfig +++ b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.debug.xcconfig @@ -1,4 +1,5 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.release.xcconfig b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.release.xcconfig index 521bc0e..566aa02 100644 --- a/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.release.xcconfig +++ b/Pods/Target Support Files/Pods-Life Saver tvOS/Pods-Life Saver tvOS.release.xcconfig @@ -1,4 +1,5 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/SwiftLint/SwiftLint.xcconfig b/Pods/Target Support Files/SwiftLint-macOS/SwiftLint-macOS.xcconfig similarity index 97% rename from Pods/Target Support Files/SwiftLint/SwiftLint.xcconfig rename to Pods/Target Support Files/SwiftLint-macOS/SwiftLint-macOS.xcconfig index 707003c..2dee2c9 100644 --- a/Pods/Target Support Files/SwiftLint/SwiftLint.xcconfig +++ b/Pods/Target Support Files/SwiftLint-macOS/SwiftLint-macOS.xcconfig @@ -1,5 +1,5 @@ CODE_SIGN_IDENTITY = -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftLint +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftLint-macOS GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/SwiftLint-tvOS/SwiftLint-tvOS.xcconfig b/Pods/Target Support Files/SwiftLint-tvOS/SwiftLint-tvOS.xcconfig new file mode 100644 index 0000000..dfc3548 --- /dev/null +++ b/Pods/Target Support Files/SwiftLint-tvOS/SwiftLint-tvOS.xcconfig @@ -0,0 +1,8 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftLint-tvOS +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftLint +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Life Saver Shared/Assets.xcassets/AppIcon.appiconset/Contents.json b/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Life Saver Shared/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Shared/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Life Saver Shared/Assets.xcassets/Contents.json b/Shared/Assets.xcassets/Contents.json similarity index 100% rename from Life Saver Shared/Assets.xcassets/Contents.json rename to Shared/Assets.xcassets/Contents.json diff --git a/Life Saver Shared/Assets.xcassets/github.imageset/Contents.json b/Shared/Assets.xcassets/github.imageset/Contents.json similarity index 100% rename from Life Saver Shared/Assets.xcassets/github.imageset/Contents.json rename to Shared/Assets.xcassets/github.imageset/Contents.json diff --git a/Life Saver Shared/Assets.xcassets/github.imageset/github_dark-1.png b/Shared/Assets.xcassets/github.imageset/github_dark-1.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/github.imageset/github_dark-1.png rename to Shared/Assets.xcassets/github.imageset/github_dark-1.png diff --git a/Life Saver Shared/Assets.xcassets/github.imageset/github_dark.png b/Shared/Assets.xcassets/github.imageset/github_dark.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/github.imageset/github_dark.png rename to Shared/Assets.xcassets/github.imageset/github_dark.png diff --git a/Life Saver Shared/Assets.xcassets/github.imageset/github_light-1.png b/Shared/Assets.xcassets/github.imageset/github_light-1.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/github.imageset/github_light-1.png rename to Shared/Assets.xcassets/github.imageset/github_light-1.png diff --git a/Life Saver Shared/Assets.xcassets/github.imageset/github_light.png b/Shared/Assets.xcassets/github.imageset/github_light.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/github.imageset/github_light.png rename to Shared/Assets.xcassets/github.imageset/github_light.png diff --git a/Life Saver Shared/Assets.xcassets/square.imageset/Contents.json b/Shared/Assets.xcassets/square.imageset/Contents.json similarity index 100% rename from Life Saver Shared/Assets.xcassets/square.imageset/Contents.json rename to Shared/Assets.xcassets/square.imageset/Contents.json diff --git a/Life Saver Shared/Assets.xcassets/square.imageset/aeonSquare.pdf b/Shared/Assets.xcassets/square.imageset/aeonSquare.pdf similarity index 100% rename from Life Saver Shared/Assets.xcassets/square.imageset/aeonSquare.pdf rename to Shared/Assets.xcassets/square.imageset/aeonSquare.pdf diff --git a/Life Saver Shared/Assets.xcassets/thumbnail.imageset/Contents.json b/Shared/Assets.xcassets/thumbnail.imageset/Contents.json similarity index 100% rename from Life Saver Shared/Assets.xcassets/thumbnail.imageset/Contents.json rename to Shared/Assets.xcassets/thumbnail.imageset/Contents.json diff --git a/Life Saver Shared/Assets.xcassets/thumbnail.imageset/thumbnail.png b/Shared/Assets.xcassets/thumbnail.imageset/thumbnail.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/thumbnail.imageset/thumbnail.png rename to Shared/Assets.xcassets/thumbnail.imageset/thumbnail.png diff --git a/Life Saver Shared/Assets.xcassets/thumbnail.imageset/thumbnail@2x.png b/Shared/Assets.xcassets/thumbnail.imageset/thumbnail@2x.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/thumbnail.imageset/thumbnail@2x.png rename to Shared/Assets.xcassets/thumbnail.imageset/thumbnail@2x.png diff --git a/Life Saver Shared/Assets.xcassets/twitter.imageset/Contents.json b/Shared/Assets.xcassets/twitter.imageset/Contents.json similarity index 100% rename from Life Saver Shared/Assets.xcassets/twitter.imageset/Contents.json rename to Shared/Assets.xcassets/twitter.imageset/Contents.json diff --git a/Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_dark-1.png b/Shared/Assets.xcassets/twitter.imageset/twitter_dark-1.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_dark-1.png rename to Shared/Assets.xcassets/twitter.imageset/twitter_dark-1.png diff --git a/Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_dark.png b/Shared/Assets.xcassets/twitter.imageset/twitter_dark.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_dark.png rename to Shared/Assets.xcassets/twitter.imageset/twitter_dark.png diff --git a/Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_light-1.png b/Shared/Assets.xcassets/twitter.imageset/twitter_light-1.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_light-1.png rename to Shared/Assets.xcassets/twitter.imageset/twitter_light-1.png diff --git a/Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_light.png b/Shared/Assets.xcassets/twitter.imageset/twitter_light.png similarity index 100% rename from Life Saver Shared/Assets.xcassets/twitter.imageset/twitter_light.png rename to Shared/Assets.xcassets/twitter.imageset/twitter_light.png diff --git a/Shared/LifeDatabase.swift b/Shared/LifeDatabase.swift new file mode 100644 index 0000000..2033f61 --- /dev/null +++ b/Shared/LifeDatabase.swift @@ -0,0 +1,161 @@ +// +// LifeDatabase.swift +// Life Saver +// +// Created by Bradley Root on 6/23/19. +// Copyright © 2019 Brad Root. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import SpriteKit + +struct LifeDatabase { + fileprivate enum Key { + static let appearanceMode = "appearanceMode" + static let squareSize = "squareSize" + static let blurAmount = "blurAmount" + static let animationSpeed = "animationSpeed" + static let color1 = "color1" + static let color2 = "color2" + static let color3 = "color3" + static let randomColorPreset = "randomColorPreset" + static let selectedPresetTitle = "selectedPresetTitle" + static let deathFade = "deathFade" + static let shiftingColors = "shiftingColors" + static let hasPressedMenuButton = "hasPressedMenuButton" + } + + static var standard: UserDefaults { + let database = UserDefaults.standard + + database.register(defaults: + [Key.appearanceMode: Appearance.dark.rawValue, + Key.animationSpeed: AnimationSpeed.normal.rawValue, + Key.squareSize: SquareSize.medium.rawValue, + Key.color1: archiveData(SKColor.defaultColor1), + Key.color2: archiveData(SKColor.defaultColor2), + Key.color3: archiveData(SKColor.defaultColor3), + Key.randomColorPreset: false, + Key.deathFade: true, + Key.shiftingColors: false, + Key.selectedPresetTitle: "Santa Fe", + Key.hasPressedMenuButton: false]) + + return database + } +} + +extension UserDefaults { + var appearanceMode: Appearance { + return Appearance(rawValue: integer(forKey: LifeDatabase.Key.appearanceMode))! + } + + func set(appearanceMode: Appearance) { + set(appearanceMode.rawValue, for: LifeDatabase.Key.appearanceMode) + } + + var squareSize: SquareSize { + return SquareSize(rawValue: integer(forKey: LifeDatabase.Key.squareSize))! + } + + func set(squareSize: SquareSize) { + set(squareSize.rawValue, for: LifeDatabase.Key.squareSize) + } + + var animationSpeed: AnimationSpeed { + return AnimationSpeed(rawValue: integer(forKey: LifeDatabase.Key.animationSpeed))! + } + + func set(animationSpeed: AnimationSpeed) { + set(animationSpeed.rawValue, for: LifeDatabase.Key.animationSpeed) + } + + var randomColorPreset: Bool { + return bool(forKey: LifeDatabase.Key.randomColorPreset) + } + + func set(randomColorPreset: Bool) { + set(randomColorPreset, for: LifeDatabase.Key.randomColorPreset) + } + + var shiftingColors: Bool { + return bool(forKey: LifeDatabase.Key.shiftingColors) + } + + func set(shiftingColors: Bool) { + set(shiftingColors, for: LifeDatabase.Key.shiftingColors) + } + + var deathFade: Bool { + return bool(forKey: LifeDatabase.Key.deathFade) + } + + func set(deathFade: Bool) { + set(deathFade, for: LifeDatabase.Key.deathFade) + } + + var hasPressedMenuButton: Bool { + return bool(forKey: LifeDatabase.Key.hasPressedMenuButton) + } + + func set(hasPressedMenuButton: Bool) { + set(hasPressedMenuButton, for: LifeDatabase.Key.hasPressedMenuButton) + } + + var selectedPresetTitle: String { + return string(forKey: LifeDatabase.Key.selectedPresetTitle) ?? "" + } + + func set(selectedPresetTitle: String) { + set(selectedPresetTitle, for: LifeDatabase.Key.selectedPresetTitle) + } + + func getColor(_ color: Colors) -> SKColor { + switch color { + case .color1: + return unarchiveColor(data(forKey: LifeDatabase.Key.color1)!) + case .color2: + return unarchiveColor(data(forKey: LifeDatabase.Key.color2)!) + case .color3: + return unarchiveColor(data(forKey: LifeDatabase.Key.color3)!) + } + } + + func set(_ color: SKColor, for colors: Colors) { + switch colors { + case .color1: + set(archiveData(color), for: LifeDatabase.Key.color1) + case .color2: + set(archiveData(color), for: LifeDatabase.Key.color2) + case .color3: + set(archiveData(color), for: LifeDatabase.Key.color3) + } + } +} + +private extension UserDefaults { + func set(_ object: Any?, for key: String) { + set(object, forKey: key) + synchronize() + } +} + +private func archiveData(_ data: Any) -> Data { + do { + let data = try NSKeyedArchiver.archivedData(withRootObject: data, requiringSecureCoding: false) + return data + } catch { + fatalError("Failed to archive data") + } +} + +private func unarchiveColor(_ data: Data) -> SKColor { + do { + let color = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? SKColor + return color! + } catch { + fatalError("Failed to unarchive data") + } +} diff --git a/Life Saver Shared/LifeManager.swift b/Shared/LifeManager.swift similarity index 57% rename from Life Saver Shared/LifeManager.swift rename to Shared/LifeManager.swift index a06e1d8..e3245f2 100644 --- a/Life Saver Shared/LifeManager.swift +++ b/Shared/LifeManager.swift @@ -10,9 +10,12 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. import Foundation -import ScreenSaver import SpriteKit +protocol LifeManagerDelegate: AnyObject { + func updatedSettings() +} + final class LifeManager { private(set) var appearanceMode: Appearance private(set) var squareSize: SquareSize @@ -21,6 +24,15 @@ final class LifeManager { private(set) var color2: SKColor private(set) var color3: SKColor private(set) var randomColorPreset: Bool + private(set) var shiftingColors: Bool + private(set) var deathFade: Bool + private(set) var selectedPresetTitle: String + private(set) var hasPressedMenuButton: Bool + + private var usingPreset: Bool = false + + weak var delegate: LifeManagerDelegate? + weak var settingsDelegate: LifeManagerDelegate? init() { appearanceMode = LifeDatabase.standard.appearanceMode @@ -30,9 +42,15 @@ final class LifeManager { color2 = LifeDatabase.standard.getColor(.color2) color3 = LifeDatabase.standard.getColor(.color3) randomColorPreset = LifeDatabase.standard.randomColorPreset + deathFade = LifeDatabase.standard.deathFade + shiftingColors = LifeDatabase.standard.shiftingColors + selectedPresetTitle = LifeDatabase.standard.selectedPresetTitle + hasPressedMenuButton = LifeDatabase.standard.hasPressedMenuButton } func configure(with preset: LifePreset) { + usingPreset = true + if let appearanceMode = preset.appearanceMode { setAppearanceMode(appearanceMode) } @@ -45,6 +63,14 @@ final class LifeManager { setAnimationSpeed(animationSpeed) } + if let deathFade = preset.deathFade { + setDeathFade(deathFade) + } + + if let shiftingColors = preset.shiftingColors { + setShiftingColors(shiftingColors) + } + if let color1 = preset.color1 { setColor(color1, for: .color1) } @@ -56,26 +82,53 @@ final class LifeManager { if let color3 = preset.color3 { setColor(color3, for: .color3) } + + selectedPresetTitle = preset.title + LifeDatabase.standard.set(selectedPresetTitle: selectedPresetTitle) + + usingPreset = false + sendUpdateMessage() } func setRandomColorPreset(_ randomColorPreset: Bool) { self.randomColorPreset = randomColorPreset LifeDatabase.standard.set(randomColorPreset: randomColorPreset) + sendUpdateMessage() + } + + func setShiftingColors(_ shiftingColors: Bool) { + self.shiftingColors = shiftingColors + LifeDatabase.standard.set(shiftingColors: shiftingColors) + sendUpdateMessage() + } + + func setDeathFade(_ deathFade: Bool) { + self.deathFade = deathFade + LifeDatabase.standard.set(deathFade: deathFade) + sendUpdateMessage() + } + + func setHasPressedMenuButton(_ hasPressedMenuButton: Bool) { + self.hasPressedMenuButton = hasPressedMenuButton + LifeDatabase.standard.set(hasPressedMenuButton: hasPressedMenuButton) } func setAppearanceMode(_ appearanceMode: Appearance) { self.appearanceMode = appearanceMode LifeDatabase.standard.set(appearanceMode: appearanceMode) + sendUpdateMessage() } func setSquareSize(_ squareSize: SquareSize) { self.squareSize = squareSize LifeDatabase.standard.set(squareSize: squareSize) + sendUpdateMessage() } func setAnimationSpeed(_ animationSpeed: AnimationSpeed) { self.animationSpeed = animationSpeed LifeDatabase.standard.set(animationSpeed: animationSpeed) + sendUpdateMessage() } func setColor(_ color: SKColor, for colors: Colors) { @@ -88,5 +141,19 @@ final class LifeManager { color3 = color } LifeDatabase.standard.set(color, for: colors) + + if !usingPreset { + selectedPresetTitle = "" + LifeDatabase.standard.set(selectedPresetTitle: selectedPresetTitle) + } + + sendUpdateMessage() + } + + func sendUpdateMessage() { + if !usingPreset { + delegate?.updatedSettings() + settingsDelegate?.updatedSettings() + } } } diff --git a/Life Saver Shared/LifeNode.swift b/Shared/LifeNode.swift similarity index 61% rename from Life Saver Shared/LifeNode.swift rename to Shared/LifeNode.swift index 4487d59..23c9a72 100644 --- a/Life Saver Shared/LifeNode.swift +++ b/Shared/LifeNode.swift @@ -27,6 +27,7 @@ class LifeNode: SKSpriteNode { aliveColor = color deadColor = color super.init(texture: squareTexture, color: aliveColor, size: size) + isUserInteractionEnabled = false anchorPoint = CGPoint(x: 0, y: 0) colorBlendFactor = 1 zPosition = 0 @@ -44,22 +45,28 @@ class LifeNode: SKSpriteNode { return } - removeAllActions() timeInState = 0 alive = true - let fadeAction = SKAction.fadeAlpha(to: 1, duration: duration) - let colorAction = SKAction.colorize(with: aliveColor, colorBlendFactor: 1, duration: duration) - let actionGroup = SKAction.group([fadeAction, colorAction]) - actionGroup.timingMode = .easeInEaseOut - run(actionGroup) + if duration > 0 { + removeAllActions() + let fadeAction = SKAction.fadeAlpha(to: 1, duration: duration) + let colorAction = SKAction.colorize(with: aliveColor, colorBlendFactor: 1, duration: duration) + let actionGroup = SKAction.group([fadeAction, colorAction]) + actionGroup.timingMode = .easeInEaseOut + run(actionGroup) + } else { + alpha = 1 + color = aliveColor + } } - public func die(duration: TimeInterval) { + public func die(duration: TimeInterval, fade: Bool) { if !alive { timeInState += 1 - if timeInState == 30 { + // 30 for slow modes... 120 for fast? + if timeInState == 120, duration > 0, fade { removeAllActions() let fadeAction = SKAction.fadeAlpha(to: 0, duration: duration) let colorAction = SKAction.colorize(with: deadColor, colorBlendFactor: 1, duration: duration) @@ -71,12 +78,28 @@ class LifeNode: SKSpriteNode { return } + timeInState = 0 + alive = false + + if duration > 0, fade { + removeAllActions() + let fadeAction = SKAction.fadeAlpha(to: 0.2, duration: duration) + fadeAction.timingMode = .easeInEaseOut + run(fadeAction) + } else if fade { + alpha = 0.2 + } + } + + public func remove(duration: TimeInterval) { removeAllActions() timeInState = 0 alive = false - let fadeAction = SKAction.fadeAlpha(to: 0.2, duration: duration) + let fadeAction = SKAction.fadeAlpha(to: 0, duration: duration) fadeAction.timingMode = .easeInEaseOut - run(fadeAction) + run(fadeAction) { + self.removeFromParent() + } } } diff --git a/Life Saver Shared/LifePreset.swift b/Shared/LifePreset.swift similarity index 68% rename from Life Saver Shared/LifePreset.swift rename to Shared/LifePreset.swift index db032b4..3bf15c5 100644 --- a/Life Saver Shared/LifePreset.swift +++ b/Shared/LifePreset.swift @@ -16,6 +16,8 @@ struct LifePreset { let appearanceMode: Appearance? let squareSize: SquareSize? let animationSpeed: AnimationSpeed? + let deathFade: Bool? + let shiftingColors: Bool? let color1: SKColor? let color2: SKColor? let color3: SKColor? @@ -38,6 +40,7 @@ enum AnimationSpeed: Int { case fast = 0 case normal = 1 case slow = 2 + case off = 3 } enum Colors: Int { @@ -52,12 +55,72 @@ extension SKColor { static let defaultColor3 = SKColor(red: 174 / 255.0, green: 129 / 255.0, blue: 0 / 255.0, alpha: 1.00) } -let lifePresets = [ +let settingsPresets = [ + LifePreset( + title: "Defaults", + appearanceMode: .dark, + squareSize: .medium, + animationSpeed: .normal, + deathFade: true, + shiftingColors: false, + color1: SKColor.defaultColor1, + color2: SKColor.defaultColor2, + color3: SKColor.defaultColor3 + ), + LifePreset( + title: "Meditation", + appearanceMode: .light, + squareSize: .large, + animationSpeed: .normal, + deathFade: false, + shiftingColors: true, + color1: SKColor(red: 237 / 255.0, green: 200 / 255.0, blue: 195 / 255.0, alpha: 1.00), + color2: SKColor(red: 16 / 255.0, green: 103 / 255.0, blue: 110 / 255.0, alpha: 1.00), + color3: SKColor(red: 247 / 255.0, green: 172 / 255.0, blue: 153 / 255.0, alpha: 1.00) + ), + LifePreset( + title: "8-bit Fireplace", + appearanceMode: .dark, + squareSize: .medium, + animationSpeed: .fast, + deathFade: true, + shiftingColors: false, + color1: SKColor(red: 0.98, green: 0.75, blue: 0.00, alpha: 1.0), + color2: SKColor(red: 1.00, green: 0.46, blue: 0.00, alpha: 1.0), + color3: SKColor(red: 0.71, green: 0.13, blue: 0.01, alpha: 1.0) + ), + LifePreset( + title: "Technicolor Dream", + appearanceMode: .light, + squareSize: .verySmall, + animationSpeed: .off, + deathFade: false, + shiftingColors: true, + color1: SKColor(red: 252 / 255.0, green: 98 / 255.0, blue: 101 / 255.0, alpha: 1.00), + color2: SKColor(red: 88 / 255.0, green: 137 / 255.0, blue: 251 / 255.0, alpha: 1.00), + color3: SKColor(red: 38 / 255.0, green: 205 / 255.0, blue: 105 / 255.0, alpha: 1.00) + ), + LifePreset( + title: "Basic Life", + appearanceMode: .dark, + squareSize: .verySmall, + animationSpeed: .off, + deathFade: true, + shiftingColors: false, + color1: SKColor.white, + color2: SKColor.gray, + color3: SKColor.lightGray + ), +] + +let colorPresets = [ LifePreset( title: "Santa Fe", appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor.defaultColor1, color2: SKColor.defaultColor2, color3: SKColor.defaultColor3 @@ -67,6 +130,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 103 / 255.0, green: 22 / 255.0, blue: 169 / 255.0, alpha: 1.00), color2: SKColor(red: 13 / 255.0, green: 17 / 255.0, blue: 108 / 255.0, alpha: 1.00), color3: SKColor(red: 12 / 255.0, green: 67 / 255.0, blue: 108 / 255.0, alpha: 1.00) @@ -76,6 +141,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 113 / 255.0, green: 17 / 255.0, blue: 8 / 255.0, alpha: 1.00), color2: SKColor(red: 95 / 255.0, green: 7 / 255.0, blue: 0 / 255.0, alpha: 1.00), color3: SKColor(red: 55 / 255.0, green: 55 / 255.0, blue: 55 / 255.0, alpha: 1.00) @@ -85,6 +152,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 173 / 255.0, green: 255 / 255.0, blue: 14 / 255.0, alpha: 1.00), color2: SKColor(red: 174 / 255.0, green: 129 / 255.0, blue: 255 / 255.0, alpha: 1.00), color3: SKColor(red: 6 / 255.0, green: 66 / 255.0, blue: 110 / 255.0, alpha: 1.00) @@ -94,6 +163,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 190 / 255.0, green: 14 / 255.0, blue: 19 / 255.0, alpha: 1.00), color2: SKColor(red: 39 / 255.0, green: 65 / 255.0, blue: 110 / 255.0, alpha: 1.00), color3: SKColor(red: 212 / 255.0, green: 205 / 255.0, blue: 196 / 255.0, alpha: 1.00) @@ -103,6 +174,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 255 / 255.0, green: 255 / 255.0, blue: 255 / 255.0, alpha: 1.00), color2: SKColor(red: 255 / 255.0, green: 255 / 255.0, blue: 255 / 255.0, alpha: 1.00), color3: SKColor(red: 255 / 255.0, green: 255 / 255.0, blue: 255 / 255.0, alpha: 1.00) @@ -112,6 +185,8 @@ let lifePresets = [ appearanceMode: .light, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 252 / 255.0, green: 98 / 255.0, blue: 101 / 255.0, alpha: 1.00), color2: SKColor(red: 88 / 255.0, green: 137 / 255.0, blue: 251 / 255.0, alpha: 1.00), color3: SKColor(red: 38 / 255.0, green: 205 / 255.0, blue: 105 / 255.0, alpha: 1.00) @@ -121,6 +196,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 211 / 255.0, green: 208 / 255.0, blue: 203 / 255.0, alpha: 1.00), color2: SKColor(red: 88 / 255.0, green: 123 / 255.0, blue: 127 / 255.0, alpha: 1.00), color3: SKColor(red: 255 / 255.0, green: 173 / 255.0, blue: 105 / 255.0, alpha: 1.00) @@ -130,6 +207,8 @@ let lifePresets = [ appearanceMode: .light, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 229 / 255.0, green: 167 / 255.0, blue: 177 / 255.0, alpha: 1.00), color2: SKColor(red: 244 / 255.0, green: 243 / 255.0, blue: 216 / 255.0, alpha: 1.00), color3: SKColor(red: 175 / 255.0, green: 211 / 255.0, blue: 213 / 255.0, alpha: 1.00) @@ -139,6 +218,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 95 / 255.0, green: 67 / 255.0, blue: 107 / 255.0, alpha: 1.00), color2: SKColor(red: 205 / 255.0, green: 170 / 255.0, blue: 37 / 255.0, alpha: 1.00), color3: SKColor(red: 114 / 255.0, green: 100 / 255.0, blue: 87 / 255.0, alpha: 1.00) @@ -148,6 +229,8 @@ let lifePresets = [ appearanceMode: .light, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 1 / 255.0, green: 153 / 255.0, blue: 138 / 255.0, alpha: 1.00), color2: SKColor(red: 255 / 255.0, green: 203 / 255.0, blue: 213 / 255.0, alpha: 1.00), color3: SKColor(red: 191 / 255.0, green: 178 / 255.0, blue: 95 / 255.0, alpha: 1.00) @@ -157,15 +240,30 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 208 / 255.0, green: 117 / 255.0, blue: 126 / 255.0, alpha: 1.00), color2: SKColor(red: 44 / 255.0, green: 80 / 255.0, blue: 80 / 255.0, alpha: 1.00), color3: SKColor(red: 156 / 255.0, green: 154 / 255.0, blue: 23 / 255.0, alpha: 1.00) ), + LifePreset( + title: "Trial by Fire", + appearanceMode: .dark, + squareSize: nil, + animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, + color1: SKColor(red: 0.98, green: 0.75, blue: 0.00, alpha: 1.0), + color2: SKColor(red: 1.00, green: 0.46, blue: 0.00, alpha: 1.0), + color3: SKColor(red: 0.71, green: 0.13, blue: 0.01, alpha: 1.0) + ), LifePreset( title: "Georgia", appearanceMode: .light, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 237 / 255.0, green: 200 / 255.0, blue: 195 / 255.0, alpha: 1.00), color2: SKColor(red: 16 / 255.0, green: 103 / 255.0, blue: 110 / 255.0, alpha: 1.00), color3: SKColor(red: 247 / 255.0, green: 172 / 255.0, blue: 153 / 255.0, alpha: 1.00) @@ -175,6 +273,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 122 / 255.0, green: 55 / 255.0, blue: 100 / 255.0, alpha: 1.00), color2: SKColor(red: 56 / 255.0, green: 66 / 255.0, blue: 109 / 255.0, alpha: 1.00), color3: SKColor(red: 160 / 255.0, green: 121 / 255.0, blue: 72 / 255.0, alpha: 1.00) @@ -184,6 +284,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 59 / 255.0, green: 67 / 255.0, blue: 72 / 255.0, alpha: 1.00), color2: SKColor(red: 247 / 255.0, green: 201 / 255.0, blue: 177 / 255.0, alpha: 1.00), color3: SKColor(red: 176 / 255.0, green: 197 / 255.0, blue: 223 / 255.0, alpha: 1.00) @@ -193,6 +295,8 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 36 / 255.0, green: 55 / 255.0, blue: 13 / 255.0, alpha: 1.00), color2: SKColor(red: 55 / 255.0, green: 60 / 255.0, blue: 13 / 255.0, alpha: 1.00), color3: SKColor(red: 10 / 255.0, green: 44 / 255.0, blue: 24 / 255.0, alpha: 1.00) @@ -202,17 +306,32 @@ let lifePresets = [ appearanceMode: .dark, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: SKColor(red: 243 / 255.0, green: 136 / 255.0, blue: 103 / 255.0, alpha: 1.00), color2: SKColor(red: 241 / 255.0, green: 188 / 255.0, blue: 151 / 255.0, alpha: 1.00), color3: SKColor(red: 252 / 255.0, green: 53 / 255.0, blue: 113 / 255.0, alpha: 1.00) ), + LifePreset( + title: "Monochrome Red", + appearanceMode: .dark, + squareSize: nil, + animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, + color1: SKColor(red: 229 / 255, green: 0 / 255, blue: 0 / 255, alpha: 1.0), + color2: SKColor(red: 204 / 255, green: 0 / 255, blue: 0 / 255, alpha: 1.0), + color3: SKColor(red: 178 / 255, green: 0 / 255, blue: 0 / 255, alpha: 1.0) + ), LifePreset( title: "Custom", appearanceMode: nil, squareSize: nil, animationSpeed: nil, + deathFade: nil, + shiftingColors: nil, color1: nil, color2: nil, color3: nil - ) + ), ] diff --git a/Life Saver Shared/LifeScene.swift b/Shared/LifeScene.swift similarity index 72% rename from Life Saver Shared/LifeScene.swift rename to Shared/LifeScene.swift index 0033629..9607354 100644 --- a/Life Saver Shared/LifeScene.swift +++ b/Shared/LifeScene.swift @@ -12,13 +12,13 @@ import GameplayKit import SpriteKit -final class LifeScene: SKScene { +final class LifeScene: SKScene, LifeManagerDelegate { // MARK: - Settings var aliveColors: [SKColor] = [ SKColor.defaultColor1, SKColor.defaultColor2, - SKColor.defaultColor3 + SKColor.defaultColor3, ] var appearanceColor: SKColor = .black @@ -33,64 +33,84 @@ final class LifeScene: SKScene { } } + var deathFade: Bool = true + var shiftingColors: Bool = false + + private var animationTime: TimeInterval = 2 private var updateTime: TimeInterval = 2 var animationSpeed: AnimationSpeed = .normal { didSet { switch animationSpeed { case .fast: + animationTime = 0.6 updateTime = 0.6 case .normal: + animationTime = 2 updateTime = 2 case .slow: + animationTime = 5 updateTime = 5 + case .off: + animationTime = 0 + updateTime = 0.1 } } } var squareSize: SquareSize = .medium + // MARK: - Manager + + var manager: LifeManager? { + didSet { + manager?.delegate = self + } + } + + func updatedSettings() { + print("Updated Settings") + isUpdating = false + endLife() + perform(#selector(createField), with: nil, afterDelay: 0.5) + } + // MARK: - Scene Lifecycle override func sceneDidLoad() { size.width = frame.size.width * 2 size.height = frame.size.height * 2 + backgroundColor = .black } override func didMove(to _: SKView) { - backgroundColor = appearanceColor - scaleMode = .fill + backgroundNode = SKSpriteNode(texture: squareTexture, color: appearanceColor, size: frame.size) + backgroundNode.alpha = 0 + addChild(backgroundNode) + backgroundNode.position = CGPoint(x: frame.width / 2, y: frame.height / 2) + backgroundNode.zPosition = 0 - switch squareSize { - case .large: - lengthSquares = 7 - heightSquares = 4 - case .small: - lengthSquares = 32 - heightSquares = 18 - case .verySmall: - lengthSquares = 64 - heightSquares = 36 - case .superSmall: - lengthSquares = 128 - heightSquares = 74 - default: - break - } + let fadeIn = SKAction.fadeIn(withDuration: 0.5) + backgroundNode.run(fadeIn) - createLife() + createField() } private var lastUpdate: TimeInterval = 0 + private var isUpdating: Bool = true + override func update(_ currentTime: TimeInterval) { if lastUpdate == 0 || currentTime - lastUpdate >= updateTime { lastUpdate = currentTime - updateLife() + if isUpdating { + updateLife() + } } } - // MARK: - Life Logic + // MARK: - Life Parameters + private var backgroundNode: SKSpriteNode = SKSpriteNode() private var allNodes: [LifeNode] = [] private var aliveNodes: [LifeNode] = [] private var livingNodeHistory: [Int] = [] @@ -107,6 +127,48 @@ final class LifeScene: SKScene { ) ) + // MARK: - Life Creation + + @objc func createField() { + if let manager = manager { + appearanceMode = manager.appearanceMode + squareSize = manager.squareSize + animationSpeed = manager.animationSpeed + aliveColors = [manager.color1, manager.color2, manager.color3] + deathFade = manager.deathFade + shiftingColors = manager.shiftingColors + } + + if backgroundNode.color != appearanceColor { + let colorize = SKAction.colorize(with: appearanceColor, colorBlendFactor: 1.0, duration: 0.5) + backgroundNode.run(colorize) { + self.isUpdating = true + } + } + + scaleMode = .aspectFill + + switch squareSize { + case .large: + lengthSquares = 7 + heightSquares = 4 + case .medium: + lengthSquares = 16 + heightSquares = 9 + case .small: + lengthSquares = 32 + heightSquares = 18 + case .verySmall: + lengthSquares = 64 + heightSquares = 36 + case .superSmall: + lengthSquares = 128 + heightSquares = 74 + } + + createLife() + } + fileprivate func createLife() { matrix = ToroidalMatrix( rows: Int(lengthSquares), @@ -161,6 +223,7 @@ final class LifeScene: SKScene { ) addChild(newSquare) newSquare.position = actualPosition + newSquare.alpha = 0 if newSquare.alive { aliveNodes.append(newSquare) @@ -183,6 +246,21 @@ final class LifeScene: SKScene { node.neighbors = neighbors } + // MARK: - Life Ending + + fileprivate func destroyField() { + removeAllChildren() + } + + fileprivate func endLife() { + allNodes.forEach { $0.remove(duration: 0.5) } + allNodes.removeAll() + aliveNodes.removeAll() + livingNodeHistory.removeAll() + } + + // MARK: - Life Updates + fileprivate func updateLife() { var dyingNodes: [LifeNode] = [] var livingNodes: [LifeNode] = [] @@ -197,7 +275,13 @@ final class LifeScene: SKScene { livingNodes.append(node) } } else if livingNeighbors.count == 3 { - node.aliveColor = livingNeighbors.randomElement()!.color + var livingColor = livingNeighbors.randomElement()!.color + #if os(tvOS) + if shiftingColors { + livingColor = livingColor.modified(withAdditionalHue: 0.005, additionalSaturation: 0, additionalBrightness: 0) + } + #endif + node.aliveColor = livingColor livingNodes.append(node) } else { dyingNodes.append(node) @@ -210,7 +294,7 @@ final class LifeScene: SKScene { } // Static tank prevention - if livingNodeHistory.count >= 20 { + if livingNodeHistory.count >= 10 { livingNodeHistory.removeFirst() livingNodeHistory.append(livingNodes.count) if 1 ... 2 ~= Set(livingNodeHistory).count { @@ -223,11 +307,11 @@ final class LifeScene: SKScene { // Update nodes here dyingNodes.forEach { - $0.die(duration: updateTime * 5) + $0.die(duration: animationTime * 5, fade: deathFade) } livingNodes.forEach { - $0.live(duration: updateTime) + $0.live(duration: animationTime) } aliveNodes = livingNodes diff --git a/Shared/Utilities/Extensions.swift b/Shared/Utilities/Extensions.swift new file mode 100644 index 0000000..21860f5 --- /dev/null +++ b/Shared/Utilities/Extensions.swift @@ -0,0 +1,29 @@ +// +// Extensions.swift +// Life Saver +// +// Created by Bradley Root on 6/29/19. +// Copyright © 2019 Brad Root. All rights reserved. +// + +import SpriteKit + +extension SKColor { + func modified(withAdditionalHue hue: CGFloat, additionalSaturation: CGFloat, additionalBrightness: CGFloat) -> SKColor { + var currentHue: CGFloat = 0.0 + var currentSaturation: CGFloat = 0.0 + var currentBrigthness: CGFloat = 0.0 + var currentAlpha: CGFloat = 0.0 + + if getHue(¤tHue, saturation: ¤tSaturation, brightness: ¤tBrigthness, alpha: ¤tAlpha) { + return SKColor( + hue: currentHue + hue > 1 ? hue : currentHue + hue, + saturation: currentSaturation + additionalSaturation, + brightness: currentBrigthness + additionalBrightness, + alpha: currentAlpha + ) + } else { + return self + } + } +} diff --git a/Life Saver Shared/Utilities/FileGrabber.swift b/Shared/Utilities/FileGrabber.swift similarity index 100% rename from Life Saver Shared/Utilities/FileGrabber.swift rename to Shared/Utilities/FileGrabber.swift diff --git a/Life Saver Shared/Utilities/ToroidalMatrix.swift b/Shared/Utilities/ToroidalMatrix.swift similarity index 100% rename from Life Saver Shared/Utilities/ToroidalMatrix.swift rename to Shared/Utilities/ToroidalMatrix.swift diff --git a/Life Saver Shared/Utilities/URLType.swift b/Shared/Utilities/URLType.swift similarity index 100% rename from Life Saver Shared/Utilities/URLType.swift rename to Shared/Utilities/URLType.swift diff --git a/Life Saver Screensaver/Configuration/ConfigureSheet.xib b/macOS Screensaver/Configuration/ConfigureSheet.xib similarity index 100% rename from Life Saver Screensaver/Configuration/ConfigureSheet.xib rename to macOS Screensaver/Configuration/ConfigureSheet.xib diff --git a/Life Saver Screensaver/Configuration/ConfigureSheetController.swift b/macOS Screensaver/Configuration/ConfigureSheetController.swift similarity index 95% rename from Life Saver Screensaver/Configuration/ConfigureSheetController.swift rename to macOS Screensaver/Configuration/ConfigureSheetController.swift index a27ffbc..e9483f0 100644 --- a/Life Saver Screensaver/Configuration/ConfigureSheetController.swift +++ b/macOS Screensaver/Configuration/ConfigureSheetController.swift @@ -17,7 +17,7 @@ final class ConfigureSheetController: NSObject { // MARK: - Presets - fileprivate let presets: [LifePreset] = lifePresets + fileprivate let presets: [LifePreset] = colorPresets // MARK: - Config Actions and Outlets @@ -32,6 +32,8 @@ final class ConfigureSheetController: NSObject { appearanceMode: nil, squareSize: .small, animationSpeed: .fast, + deathFade: nil, + shiftingColors: nil, color1: nil, color2: nil, color3: nil @@ -43,6 +45,8 @@ final class ConfigureSheetController: NSObject { appearanceMode: nil, squareSize: .large, animationSpeed: .slow, + deathFade: nil, + shiftingColors: nil, color1: nil, color2: nil, color3: nil @@ -54,6 +58,8 @@ final class ConfigureSheetController: NSObject { appearanceMode: nil, squareSize: .medium, animationSpeed: .normal, + deathFade: nil, + shiftingColors: nil, color1: nil, color2: nil, color3: nil @@ -194,6 +200,8 @@ final class ConfigureSheetController: NSObject { animationSpeedControl.selectedSegment = 0 case .slow: animationSpeedControl.selectedSegment = 2 + case .off: + animationSpeedControl.selectedSegment = 1 } color1Well.color = manager.color1 diff --git a/Life Saver Screensaver/Info.plist b/macOS Screensaver/Info.plist similarity index 100% rename from Life Saver Screensaver/Info.plist rename to macOS Screensaver/Info.plist diff --git a/Life Saver Screensaver/LifeDatabase.swift b/macOS Screensaver/LifeDatabase.swift similarity index 74% rename from Life Saver Screensaver/LifeDatabase.swift rename to macOS Screensaver/LifeDatabase.swift index bc63766..5644755 100644 --- a/Life Saver Screensaver/LifeDatabase.swift +++ b/macOS Screensaver/LifeDatabase.swift @@ -22,6 +22,10 @@ struct LifeDatabase { static let color2 = "color2" static let color3 = "color3" static let randomColorPreset = "randomColorPreset" + static let selectedPresetTitle = "selectedPresetTitle" + static let deathFade = "deathFade" + static let shiftingColors = "shiftingColors" + static let hasPressedMenuButton = "hasPressedMenuButton" } static var standard: ScreenSaverDefaults { @@ -36,7 +40,11 @@ struct LifeDatabase { Key.color1: archiveData(SKColor.defaultColor1), Key.color2: archiveData(SKColor.defaultColor2), Key.color3: archiveData(SKColor.defaultColor3), - Key.randomColorPreset: false]) + Key.randomColorPreset: false, + Key.deathFade: true, + Key.shiftingColors: false, + Key.selectedPresetTitle: "Santa Fe", + Key.hasPressedMenuButton: false]) return database } @@ -75,6 +83,38 @@ extension ScreenSaverDefaults { set(randomColorPreset, for: LifeDatabase.Key.randomColorPreset) } + var shiftingColors: Bool { + return bool(forKey: LifeDatabase.Key.shiftingColors) + } + + func set(shiftingColors: Bool) { + set(shiftingColors, for: LifeDatabase.Key.shiftingColors) + } + + var deathFade: Bool { + return bool(forKey: LifeDatabase.Key.deathFade) + } + + func set(deathFade: Bool) { + set(deathFade, for: LifeDatabase.Key.deathFade) + } + + var hasPressedMenuButton: Bool { + return bool(forKey: LifeDatabase.Key.hasPressedMenuButton) + } + + func set(hasPressedMenuButton: Bool) { + set(hasPressedMenuButton, for: LifeDatabase.Key.hasPressedMenuButton) + } + + var selectedPresetTitle: String { + return string(forKey: LifeDatabase.Key.selectedPresetTitle) ?? "" + } + + func set(selectedPresetTitle: String) { + set(selectedPresetTitle, for: LifeDatabase.Key.selectedPresetTitle) + } + func getColor(_ color: Colors) -> SKColor { switch color { case .color1: diff --git a/Life Saver Screensaver/LifeScreenSaverView.swift b/macOS Screensaver/LifeScreenSaverView.swift similarity index 96% rename from Life Saver Screensaver/LifeScreenSaverView.swift rename to macOS Screensaver/LifeScreenSaverView.swift index 2186715..9a26bad 100644 --- a/Life Saver Screensaver/LifeScreenSaverView.swift +++ b/macOS Screensaver/LifeScreenSaverView.swift @@ -54,7 +54,7 @@ final class LifeScreenSaverView: ScreenSaverView { self.spriteView = spriteView addSubview(spriteView) - if manager.randomColorPreset, let preset = lifePresets.randomElement() { + if manager.randomColorPreset, let preset = colorPresets.randomElement() { manager.configure(with: preset) } diff --git a/Life Saver macOS/AppDelegate.swift b/macOS/AppDelegate.swift similarity index 100% rename from Life Saver macOS/AppDelegate.swift rename to macOS/AppDelegate.swift diff --git a/Life Saver macOS/Base.lproj/Main.storyboard b/macOS/Base.lproj/Main.storyboard similarity index 100% rename from Life Saver macOS/Base.lproj/Main.storyboard rename to macOS/Base.lproj/Main.storyboard diff --git a/Life Saver macOS/Info.plist b/macOS/Info.plist similarity index 100% rename from Life Saver macOS/Info.plist rename to macOS/Info.plist diff --git a/Life Saver macOS/Life_Saver.entitlements b/macOS/Life_Saver.entitlements similarity index 100% rename from Life Saver macOS/Life_Saver.entitlements rename to macOS/Life_Saver.entitlements diff --git a/Life Saver macOS/ViewController.swift b/macOS/ViewController.swift similarity index 94% rename from Life Saver macOS/ViewController.swift rename to macOS/ViewController.swift index 752f76f..b083c97 100644 --- a/Life Saver macOS/ViewController.swift +++ b/macOS/ViewController.swift @@ -24,7 +24,7 @@ class ViewController: NSViewController { scene.animationSpeed = .normal scene.squareSize = .medium - if let preset = lifePresets.filter({ $0.title == "Santa Fe" }).first { + if let preset = colorPresets.filter({ $0.title == "Santa Fe" }).first { if let appearanceMode = preset.appearanceMode { scene.appearanceMode = appearanceMode } diff --git a/tvOS/AppDelegate.swift b/tvOS/AppDelegate.swift new file mode 100644 index 0000000..d6c9972 --- /dev/null +++ b/tvOS/AppDelegate.swift @@ -0,0 +1,20 @@ +// +// AppDelegate.swift +// Life Saver +// +// Created by Bradley Root on 6/25/19. +// Copyright © 2019 Brad Root. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + application.isIdleTimerDisabled = true + return true + } +} diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..0e9ed94 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "tv", + "filename" : "TVA - Bottom Layer.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/TVA - Bottom Layer.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/TVA - Bottom Layer.png new file mode 100644 index 0000000..db4498c Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/TVA - Bottom Layer.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Contents.json new file mode 100644 index 0000000..d29f024 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "layers" : [ + { + "filename" : "Front.imagestacklayer" + }, + { + "filename" : "Middle.imagestacklayer" + }, + { + "filename" : "Back.imagestacklayer" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..894beda --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "tv", + "filename" : "TVA - Top Layer.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/TVA - Top Layer.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/TVA - Top Layer.png new file mode 100644 index 0000000..b7507c6 Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/TVA - Top Layer.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..86d699f --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "tv", + "filename" : "TVA - Middle Layer.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/TVA - Middle Layer.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/TVA - Middle Layer.png new file mode 100644 index 0000000..3fe4a35 Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/TVA - Middle Layer.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..ccd204c --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "idiom" : "tv", + "filename" : "TV - Bottom Layer.png", + "scale" : "1x" + }, + { + "idiom" : "tv", + "filename" : "TV - Bottom Layer@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/TV - Bottom Layer.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/TV - Bottom Layer.png new file mode 100644 index 0000000..a6efb9c Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/TV - Bottom Layer.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/TV - Bottom Layer@2x.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/TV - Bottom Layer@2x.png new file mode 100644 index 0000000..17470ae Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/TV - Bottom Layer@2x.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Contents.json new file mode 100644 index 0000000..d29f024 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "layers" : [ + { + "filename" : "Front.imagestacklayer" + }, + { + "filename" : "Middle.imagestacklayer" + }, + { + "filename" : "Back.imagestacklayer" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..2697093 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "idiom" : "tv", + "filename" : "TV - Top Layer.png", + "scale" : "1x" + }, + { + "idiom" : "tv", + "filename" : "TV - Top Layer@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/TV - Top Layer.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/TV - Top Layer.png new file mode 100644 index 0000000..783a6e1 Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/TV - Top Layer.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/TV - Top Layer@2x.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/TV - Top Layer@2x.png new file mode 100644 index 0000000..907b53d Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/TV - Top Layer@2x.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..8d21164 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "idiom" : "tv", + "filename" : "TV - Middle Layer.png", + "scale" : "1x" + }, + { + "idiom" : "tv", + "filename" : "TV - Middle Layer@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/TV - Middle Layer.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/TV - Middle Layer.png new file mode 100644 index 0000000..6cb1086 Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/TV - Middle Layer.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/TV - Middle Layer@2x.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/TV - Middle Layer@2x.png new file mode 100644 index 0000000..7c925b7 Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/TV - Middle Layer@2x.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/Contents.json new file mode 100644 index 0000000..db288f3 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/Contents.json @@ -0,0 +1,32 @@ +{ + "assets" : [ + { + "size" : "1280x768", + "idiom" : "tv", + "filename" : "App Icon - App Store.imagestack", + "role" : "primary-app-icon" + }, + { + "size" : "400x240", + "idiom" : "tv", + "filename" : "App Icon.imagestack", + "role" : "primary-app-icon" + }, + { + "size" : "2320x720", + "idiom" : "tv", + "filename" : "Top Shelf Image Wide.imageset", + "role" : "top-shelf-image-wide" + }, + { + "size" : "1920x720", + "idiom" : "tv", + "filename" : "Top Shelf Image.imageset", + "role" : "top-shelf-image" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Contents.json new file mode 100644 index 0000000..f971991 --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "idiom" : "tv", + "filename" : "Top Shelf.png", + "scale" : "1x" + }, + { + "idiom" : "tv", + "filename" : "Top Shelf@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Top Shelf.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Top Shelf.png new file mode 100644 index 0000000..db799c7 Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Top Shelf.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Top Shelf@2x.png b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Top Shelf@2x.png new file mode 100644 index 0000000..f2a5ba1 Binary files /dev/null and b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image Wide.imageset/Top Shelf@2x.png differ diff --git a/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image.imageset/Contents.json b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image.imageset/Contents.json new file mode 100644 index 0000000..16a370d --- /dev/null +++ b/tvOS/Assets.xcassets/Brand Assets.brandassets/Top Shelf Image.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "tv", + "scale" : "1x" + }, + { + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/Contents.json b/tvOS/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/tvOS/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json b/tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..54f1b6a --- /dev/null +++ b/tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "orientation" : "landscape", + "idiom" : "tv", + "filename" : "LaunchImage@2x.png", + "extent" : "full-screen", + "minimum-system-version" : "11.0", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "tv", + "filename" : "LaunchImage.png", + "extent" : "full-screen", + "minimum-system-version" : "9.0", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tvOS/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png b/tvOS/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png new file mode 100644 index 0000000..d0415dc Binary files /dev/null and b/tvOS/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png differ diff --git a/tvOS/Assets.xcassets/LaunchImage.launchimage/LaunchImage@2x.png b/tvOS/Assets.xcassets/LaunchImage.launchimage/LaunchImage@2x.png new file mode 100644 index 0000000..04c08f3 Binary files /dev/null and b/tvOS/Assets.xcassets/LaunchImage.launchimage/LaunchImage@2x.png differ diff --git a/tvOS/Base.lproj/Main.storyboard b/tvOS/Base.lproj/Main.storyboard new file mode 100644 index 0000000..bb2d080 --- /dev/null +++ b/tvOS/Base.lproj/Main.storyboard @@ -0,0 +1,502 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tvOS/ColorPresetTableViewCell.swift b/tvOS/ColorPresetTableViewCell.swift new file mode 100644 index 0000000..ac7f3e3 --- /dev/null +++ b/tvOS/ColorPresetTableViewCell.swift @@ -0,0 +1,24 @@ +// +// ColorPresetTableViewCell.swift +// Life Saver tvOS +// +// Created by Bradley Root on 6/25/19. +// Copyright © 2019 Brad Root. All rights reserved. +// + +import UIKit + +class ColorPresetTableViewCell: UITableViewCell { + @IBOutlet var titleLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } +} diff --git a/Life Saver tvOS/Info.plist b/tvOS/Info.plist similarity index 81% rename from Life Saver tvOS/Info.plist rename to tvOS/Info.plist index 82603da..8a085c3 100644 --- a/Life Saver tvOS/Info.plist +++ b/tvOS/Info.plist @@ -8,6 +8,10 @@ Life Saver CFBundleExecutable $(EXECUTABLE_NAME) + CFBundleIcons + + CFBundleIcons~ipad + CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion @@ -17,16 +21,18 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.1 + 1.0 CFBundleVersion - 1 + 3 LSRequiresIPhoneOS + UIMainStoryboardFile + Main UIRequiredDeviceCapabilities arm64 UIUserInterfaceStyle - Automatic + Dark diff --git a/tvOS/LifeViewController.swift b/tvOS/LifeViewController.swift new file mode 100644 index 0000000..c74d919 --- /dev/null +++ b/tvOS/LifeViewController.swift @@ -0,0 +1,378 @@ +// +// LifeViewController.swift +// Life Saver +// +// Created by Bradley Root on 6/25/19. +// Copyright © 2019 Brad Root. All rights reserved. +// + +import GameplayKit +import SpriteKit +import UIKit + +enum UIState { + case colorPresets + case mainMenu + case allClosed +} + +class LifeViewController: UIViewController, MenuTableDelegate { + var scene: LifeScene? + let manager = LifeManager() + var state: UIState = .allClosed + + @IBOutlet var colorPresetsTableView: UITableView! + @IBOutlet var colorPresetsView: UIVisualEffectView! + @IBOutlet var mainMenuView: UIVisualEffectView! + + @IBOutlet var mainMenuLeadingConstraint: NSLayoutConstraint! + @IBOutlet var colorMenuTrailingConstraint: NSLayoutConstraint! + + @IBOutlet var menuHintToast: UIVisualEffectView! + @IBOutlet var menuHintToastConstraint: NSLayoutConstraint! + var menuHintBounceAnimation: UIViewPropertyAnimator? + @IBOutlet var colorMenuCloseToast: UIVisualEffectView! + @IBOutlet var mainMenuCloseToast: UIVisualEffectView! + + @IBOutlet var kludgeButton: UIButton! + @IBOutlet var initialOverlayView: UIView! + + var menuTableViewController: MenuTableViewController? + var pressedMenuButton: UITapGestureRecognizer? + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .black + + setupView() + + setupPresetMenu() + + setupGestureRecognizers() + + if !manager.hasPressedMenuButton { + bounceOrHideMenuHintToast(reverse: false) + } else { + menuHintToast.alpha = 0 + } + + createScene() + + hideInitialOverlay() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + view.isUserInteractionEnabled = true + } + + override var preferredFocusEnvironments: [UIFocusEnvironment] { + if state == .colorPresets { + return [colorPresetsView] + } else { + return [mainMenuView] + } + } + + override func prepare(for segue: UIStoryboardSegue, sender _: Any?) { + if segue.identifier == "menuEmbedSegue" { + if let tableViewController = segue.destination as? MenuTableViewController { + menuTableViewController = tableViewController + menuTableViewController?.manager = manager + menuTableViewController?.delegate = self + manager.settingsDelegate = tableViewController + } + } + } + + // MARK: - UI Interactions + + fileprivate func setupGestureRecognizers() { + let swipeFromRight = UISwipeGestureRecognizer(target: self, action: #selector(didSwipeLeft)) + swipeFromRight.direction = .left + swipeFromRight.allowedTouchTypes = [NSNumber(value: UITouch.TouchType.indirect.rawValue)] + view.addGestureRecognizer(swipeFromRight) + + let swipeFromLeft = UISwipeGestureRecognizer(target: self, action: #selector(didSwipeRight)) + swipeFromLeft.direction = .right + swipeFromLeft.allowedTouchTypes = [NSNumber(value: UITouch.TouchType.indirect.rawValue)] + view.addGestureRecognizer(swipeFromLeft) + + pressedMenuButton = UITapGestureRecognizer(target: self, action: #selector(didPressMenuButton)) + pressedMenuButton!.allowedPressTypes = [NSNumber(value: UIPress.PressType.menu.rawValue)] + view.addGestureRecognizer(pressedMenuButton!) + } + + @objc func didPressMenuButton(gesture _: UIGestureRecognizer) { + print("Pressed Menu") + showMainMenu() + manager.setHasPressedMenuButton(true) + } + + @objc func didSwipeLeft(gesture _: UIGestureRecognizer) { + DispatchQueue.main.async { + var colorMenuToastAlpha: CGFloat = 0 + let mainMenuToastAlpha: CGFloat = 0 + + if self.state == .allClosed { + self.colorMenuTrailingConstraint.constant = 0 + colorMenuToastAlpha = 1 + self.state = .colorPresets + self.pressedMenuButton?.isEnabled = true + } + + if self.state == .mainMenu { + self.mainMenuLeadingConstraint.constant = -self.mainMenuView.frame.width + self.state = .allClosed + self.pressedMenuButton?.isEnabled = true + } + + let propertyAnimator = UIViewPropertyAnimator(duration: 1, dampingRatio: 1, animations: { + self.view.layoutIfNeeded() + self.colorMenuCloseToast.alpha = colorMenuToastAlpha + self.mainMenuCloseToast.alpha = mainMenuToastAlpha + }) + propertyAnimator.addCompletion { _ in + if self.state == .allClosed { + self.kludgeButton.alpha = 1 + } else { + self.kludgeButton.alpha = 0 + } + self.setNeedsFocusUpdate() + self.updateFocusIfNeeded() + } + propertyAnimator.startAnimation() + } + } + + @objc func didSwipeRight(gesture _: UIGestureRecognizer) { + DispatchQueue.main.async { + let colorMenuToastAlpha: CGFloat = 0 + var mainMenuToastAlpha: CGFloat = 0 + + if self.state == .allClosed { + self.mainMenuLeadingConstraint.constant = 0 + mainMenuToastAlpha = 1 + self.state = .mainMenu + self.pressedMenuButton?.isEnabled = false + } + + if self.state == .colorPresets { + self.colorMenuTrailingConstraint.constant = -self.colorPresetsView.frame.width + self.pressedMenuButton?.isEnabled = true + self.state = .allClosed + } + + let propertyAnimator = UIViewPropertyAnimator(duration: 1, dampingRatio: 1, animations: { + self.view.layoutIfNeeded() + self.colorMenuCloseToast.alpha = colorMenuToastAlpha + self.mainMenuCloseToast.alpha = mainMenuToastAlpha + }) + propertyAnimator.addCompletion { _ in + if self.state == .allClosed { + self.kludgeButton.alpha = 1 + } else { + self.kludgeButton.alpha = 0 + } + self.setNeedsFocusUpdate() + self.updateFocusIfNeeded() + } + propertyAnimator.startAnimation() + } + } + + func showColorPresets() { + DispatchQueue.main.async { + self.colorMenuTrailingConstraint.constant = 0 + self.mainMenuLeadingConstraint.constant = -self.mainMenuView.frame.width + self.state = .colorPresets + self.pressedMenuButton?.isEnabled = true + + let propertyAnimator = UIViewPropertyAnimator(duration: 1, dampingRatio: 1, animations: { + self.view.layoutIfNeeded() + self.colorMenuCloseToast.alpha = 1 + self.mainMenuCloseToast.alpha = 0 + }) + propertyAnimator.addCompletion { _ in + self.kludgeButton.alpha = 0 + self.setNeedsFocusUpdate() + self.updateFocusIfNeeded() + } + propertyAnimator.startAnimation() + } + } + + func showMainMenu() { + DispatchQueue.main.async { + self.colorMenuTrailingConstraint.constant = -self.colorPresetsView.frame.width + self.mainMenuLeadingConstraint.constant = 0 + self.state = .mainMenu + self.pressedMenuButton?.isEnabled = false + + let propertyAnimator = UIViewPropertyAnimator(duration: 1, dampingRatio: 1, animations: { + self.view.layoutIfNeeded() + self.colorMenuCloseToast.alpha = 0 + self.mainMenuCloseToast.alpha = 1 + }) + propertyAnimator.addCompletion { _ in + self.kludgeButton.alpha = 0 + self.setNeedsFocusUpdate() + self.updateFocusIfNeeded() + } + propertyAnimator.startAnimation() + } + } + + // MARK: - View Setup + + fileprivate func setupView() { + menuHintToast.layer.cornerRadius = menuHintToast.frame.height / 2 + menuHintToast.clipsToBounds = true + menuHintToast.alpha = 1 + + colorMenuCloseToast.layer.cornerRadius = colorMenuCloseToast.frame.height / 2 + colorMenuCloseToast.clipsToBounds = true + colorMenuCloseToast.alpha = 0 + colorMenuTrailingConstraint.constant = -colorPresetsView.frame.width + + mainMenuCloseToast.layer.cornerRadius = colorMenuCloseToast.frame.height / 2 + mainMenuCloseToast.clipsToBounds = true + mainMenuCloseToast.alpha = 0 + mainMenuLeadingConstraint.constant = -mainMenuView.frame.width + + updateViewConstraints() + + colorPresetsTableView.delegate = self + colorPresetsTableView.dataSource = self + } + + fileprivate func setupPresetMenu() { + let selectedPresetTitle = manager.selectedPresetTitle == "" ? "Default" : manager.selectedPresetTitle + var filteredPresets = colorPresets.filter { $0.title == selectedPresetTitle } + if filteredPresets.isEmpty { + filteredPresets = settingsPresets.filter { $0.title == selectedPresetTitle } + } + if let selectedPreset = filteredPresets.first { + var index = colorPresets.firstIndex(where: { $0.title == selectedPreset.title }) + var section = 1 + if index == nil { + section = 0 + index = settingsPresets.firstIndex(where: { $0.title == selectedPreset.title }) + } + colorPresetsTableView.selectRow( + at: IndexPath( + row: index ?? colorPresets.count - 1, + section: section + ), + animated: false, + scrollPosition: .top + ) + } + } + + fileprivate func hideInitialOverlay() { + let fadeAction = UIViewPropertyAnimator(duration: 2, curve: .easeInOut) { + self.initialOverlayView.alpha = 0 + } + fadeAction.addCompletion { state in + switch state { + case .end: + self.initialOverlayView.removeFromSuperview() + self.setNeedsFocusUpdate() + default: + return + } + } + fadeAction.startAnimation(afterDelay: 1) + } + + fileprivate func bounceOrHideMenuHintToast(reverse: Bool) { + if !manager.hasPressedMenuButton { + menuHintToastConstraint.constant = reverse ? 35 : 15 + menuHintBounceAnimation = UIViewPropertyAnimator(duration: 1.5, curve: .easeInOut, animations: nil) + menuHintBounceAnimation?.addAnimations { + self.view.layoutIfNeeded() + } + menuHintBounceAnimation?.addCompletion { _ in + self.bounceOrHideMenuHintToast(reverse: !reverse) + } + menuHintBounceAnimation?.startAnimation() + } else { + menuHintBounceAnimation?.stopAnimation(true) + menuHintToastConstraint.constant = 35 + menuHintBounceAnimation = UIViewPropertyAnimator(duration: 1, curve: .easeIn, animations: nil) + menuHintBounceAnimation?.addAnimations { + self.menuHintToast.alpha = 0 + self.view.layoutIfNeeded() + } + menuHintBounceAnimation?.addCompletion { state in + if state == .end { + self.bounceOrHideMenuHintToast(reverse: !reverse) + } + } + menuHintBounceAnimation?.startAnimation() + } + } + + fileprivate func createScene() { + if let view = self.view as? SKView { + scene = LifeScene(size: view.bounds.size) + scene!.scaleMode = .aspectFit + + scene!.manager = manager + + view.ignoresSiblingOrder = true + view.preferredFramesPerSecond = 60 + view.presentScene(scene) + } + } +} + +extension LifeViewController: UITableViewDelegate, UITableViewDataSource { + func numberOfSections(in _: UITableView) -> Int { + return 2 + } + + func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? { + if section == 1 { + return "Color Presets" + } else { + return "Presets" + } + } + + func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int { + if section == 1 { + return colorPresets.count - 1 + } else { + return settingsPresets.count + } + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if indexPath.section == 1, + let cell = tableView.dequeueReusableCell(withIdentifier: "presetCell", for: indexPath) as? ColorPresetTableViewCell { + let colorPreset = colorPresets[indexPath.row] + cell.titleLabel.text = colorPreset.title + return cell + } + + if indexPath.section == 0, + let cell = tableView.dequeueReusableCell(withIdentifier: "presetCell", for: indexPath) as? ColorPresetTableViewCell { + let settingPreset = settingsPresets[indexPath.row] + cell.titleLabel.text = settingPreset.title + return cell + } + return UITableViewCell() + } + + func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.section == 1 { + let colorPreset = colorPresets[indexPath.row] + manager.configure(with: colorPreset) + } else if indexPath.section == 0 { + let settingPreset = settingsPresets[indexPath.row] + manager.configure(with: settingPreset) + } + } +} diff --git a/tvOS/MenuTableViewController.swift b/tvOS/MenuTableViewController.swift new file mode 100644 index 0000000..a95f1bc --- /dev/null +++ b/tvOS/MenuTableViewController.swift @@ -0,0 +1,217 @@ +// +// MenuTableViewController.swift +// Life Saver tvOS +// +// Created by Bradley Root on 6/26/19. +// Copyright © 2019 Brad Root. All rights reserved. +// + +import UIKit + +protocol MenuTableDelegate: AnyObject { + func showColorPresets() +} + +class MenuTableViewController: UITableViewController, LifeManagerDelegate { + @IBOutlet var squareSizeCell: UITableViewCell! + @IBOutlet var speedCell: UITableViewCell! + @IBOutlet var deathFadeCell: UITableViewCell! + @IBOutlet var randomPresetColorCell: UITableViewCell! + @IBOutlet var showColorPresetsCell: UITableViewCell! + @IBOutlet var aboutCell: UITableViewCell! + + weak var manager: LifeManager? + weak var delegate: MenuTableDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + + updatedSettings() + } + + func updatedSettings() { + if let manager = manager { + switch manager.squareSize { + case .superSmall: + squareSizeCell.detailTextLabel?.text = "XX Small" + case .verySmall: + squareSizeCell.detailTextLabel?.text = "Tiny" + case .small: + squareSizeCell.detailTextLabel?.text = "Small" + case .medium: + squareSizeCell.detailTextLabel?.text = "Medium" + case .large: + squareSizeCell.detailTextLabel?.text = "Large" + } + + switch manager.animationSpeed { + case .normal: + speedCell.detailTextLabel?.text = "Normal" + case .fast: + speedCell.detailTextLabel?.text = "Fast" + case .slow: + speedCell.detailTextLabel?.text = "Slow" + case .off: + speedCell.detailTextLabel?.text = "Instant" + } + + let randomColorPresetTitle = manager.shiftingColors ? "On" : "Off" + randomPresetColorCell.detailTextLabel?.text = randomColorPresetTitle + + let deathFadeTitle = manager.deathFade ? "On" : "Off" + deathFadeCell.detailTextLabel?.text = deathFadeTitle + } + } + + override func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) { + print((indexPath.section, indexPath.row)) + switch (indexPath.section, indexPath.row) { + case (0, 0): + showSquareSizePicker() + case (0, 1): + showSpeedPicker() + case (0, 2): + showDeathFadePicker() + case (0, 3): + showColorShiftingPicker() + case (0, 4): + delegate?.showColorPresets() + case (1, 0): + showAboutPage() + default: + return + } + } + + fileprivate func showColorShiftingPicker() { + let alert = UIAlertController( + title: "Shifting Color", + message: "When this is enabled, the colors of newly born squares will be slightly mutated, leading to a color shift over time.", + preferredStyle: .actionSheet + ) + + let onAction = UIAlertAction(title: "On", style: .default) { _ in + self.manager?.setShiftingColors(true) + } + alert.addAction(onAction) + + let offAction = UIAlertAction(title: "Off", style: .default) { _ in + self.manager?.setShiftingColors(false) + } + alert.addAction(offAction) + + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + alert.addAction(cancelAction) + + present(alert, animated: true, completion: nil) + } + + fileprivate func showAboutPage() { + let alert = UIAlertController(title: "About Life Saver", message: """ + Life Saver is an artistic implementation of the Game of Life, a cellular automaton created by mathematician John Conway in 1972. + + Life Saver is open source software, which means you can see how it works and use it to make your own versions or modifications. + + For more information, visit https://amiantos.net/lifesaver + """, preferredStyle: .alert) + + let cancelAction = UIAlertAction(title: "Close", style: .cancel, handler: nil) + alert.addAction(cancelAction) + + present(alert, animated: true, completion: nil) + } + + fileprivate func showSpeedPicker() { + let alert = UIAlertController( + title: "Animation Speed", + message: """ + This governs how quickly change animations occur. \ + Slower speeds lead to more abstract, shifting colors. \ + Faster speeds make the simulation easier to observe. + """, + preferredStyle: .actionSheet + ) + + let defaultAction = UIAlertAction(title: "Normal", style: .default) { _ in + self.manager?.setAnimationSpeed(.normal) + } + alert.addAction(defaultAction) + + let fastAction = UIAlertAction(title: "Fast", style: .default) { _ in + self.manager?.setAnimationSpeed(.fast) + } + alert.addAction(fastAction) + + let offAction = UIAlertAction(title: "Instant", style: .default) { _ in + self.manager?.setAnimationSpeed(.off) + } + alert.addAction(offAction) + + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + alert.addAction(cancelAction) + present(alert, animated: true, completion: nil) + } + + fileprivate func showDeathFadePicker() { + let alert = UIAlertController( + title: "Death Fade", + message: """ + With death fade turned on, when a cell dies, it will fade into the background, \ + and eventually fade out completely. With death fade turned off, the cell color \ + will persist on the screen until it comes back to life as another color. + """, + preferredStyle: .actionSheet + ) + + let onAction = UIAlertAction(title: "On", style: .default) { _ in + self.manager?.setDeathFade(true) + } + alert.addAction(onAction) + + let offAction = UIAlertAction(title: "Off", style: .default) { _ in + self.manager?.setDeathFade(false) + } + alert.addAction(offAction) + + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + alert.addAction(cancelAction) + + present(alert, animated: true, completion: nil) + } + + fileprivate func showSquareSizePicker() { + // Square Size Picker + let alert = UIAlertController( + title: "Square Size", + message: """ + This governs the size of the squares on screen. \ + Larger squares are more abstract, while smaller squares allow you to see the simulation easier. + """, + preferredStyle: .actionSheet + ) + let xSmallAction = UIAlertAction(title: "Tiny", style: .default) { _ in + self.manager?.setSquareSize(.verySmall) + } + alert.addAction(xSmallAction) + + let smallAction = UIAlertAction(title: "Small", style: .default) { _ in + self.manager?.setSquareSize(.small) + } + alert.addAction(smallAction) + + let mediumAction = UIAlertAction(title: "Medium", style: .default) { _ in + self.manager?.setSquareSize(.medium) + } + alert.addAction(mediumAction) + + let largeAction = UIAlertAction(title: "Large", style: .default) { _ in + self.manager?.setSquareSize(.large) + } + alert.addAction(largeAction) + + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + alert.addAction(cancelAction) + + present(alert, animated: true, completion: nil) + } +}