diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 40bfba4e..07836e95 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -8,13 +8,18 @@ /* Begin PBXBuildFile section */ BFD2476E2284B9A500981D42 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2476D2284B9A500981D42 /* AppDelegate.swift */; }; - BFD247702284B9A500981D42 /* FirstViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2476F2284B9A500981D42 /* FirstViewController.swift */; }; + BFD247702284B9A500981D42 /* AppsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2476F2284B9A500981D42 /* AppsViewController.swift */; }; BFD247722284B9A500981D42 /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD247712284B9A500981D42 /* SecondViewController.swift */; }; BFD247752284B9A500981D42 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFD247732284B9A500981D42 /* Main.storyboard */; }; BFD247772284B9A700981D42 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BFD247762284B9A700981D42 /* Assets.xcassets */; }; BFD2477A2284B9A700981D42 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFD247782284B9A700981D42 /* LaunchScreen.storyboard */; }; BFD247872284BB4200981D42 /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFD247862284BB3B00981D42 /* Roxas.framework */; }; BFD247882284BB4200981D42 /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFD247862284BB3B00981D42 /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + BFD2478C2284C4C300981D42 /* AppIconImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2478B2284C4C300981D42 /* AppIconImageView.swift */; }; + BFD2478F2284C8F900981D42 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2478E2284C8F900981D42 /* Button.swift */; }; + BFD247932284D4B700981D42 /* AppTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD247922284D4B700981D42 /* AppTableViewCell.swift */; }; + BFD247952284D7BD00981D42 /* Apps.plist in Resources */ = {isa = PBXBuildFile; fileRef = BFD247942284D7BD00981D42 /* Apps.plist */; }; + BFD2479A2284D80900981D42 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD247992284D80900981D42 /* App.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -34,13 +39,18 @@ /* Begin PBXFileReference section */ BFD2476A2284B9A500981D42 /* AltStore.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AltStore.app; sourceTree = BUILT_PRODUCTS_DIR; }; BFD2476D2284B9A500981D42 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - BFD2476F2284B9A500981D42 /* FirstViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstViewController.swift; sourceTree = ""; }; + BFD2476F2284B9A500981D42 /* AppsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppsViewController.swift; sourceTree = ""; }; BFD247712284B9A500981D42 /* SecondViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondViewController.swift; sourceTree = ""; }; BFD247742284B9A500981D42 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; BFD247762284B9A700981D42 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; BFD247792284B9A700981D42 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; BFD2477B2284B9A700981D42 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; BFD247862284BB3B00981D42 /* Roxas.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BFD2478B2284C4C300981D42 /* AppIconImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconImageView.swift; sourceTree = ""; }; + BFD2478E2284C8F900981D42 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; + BFD247922284D4B700981D42 /* AppTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTableViewCell.swift; sourceTree = ""; }; + BFD247942284D7BD00981D42 /* Apps.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Apps.plist; sourceTree = ""; }; + BFD247992284D80900981D42 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -76,12 +86,13 @@ isa = PBXGroup; children = ( BFD2476D2284B9A500981D42 /* AppDelegate.swift */, - BFD2476F2284B9A500981D42 /* FirstViewController.swift */, - BFD247712284B9A500981D42 /* SecondViewController.swift */, BFD247732284B9A500981D42 /* Main.storyboard */, - BFD247762284B9A700981D42 /* Assets.xcassets */, - BFD247782284B9A700981D42 /* LaunchScreen.storyboard */, - BFD2477B2284B9A700981D42 /* Info.plist */, + BFD2478A2284C49000981D42 /* Apps */, + BFD247982284D7FC00981D42 /* Model */, + BFD2478D2284C4C700981D42 /* Components */, + BFD247712284B9A500981D42 /* SecondViewController.swift */, + BFD247962284D7C100981D42 /* Resources */, + BFD247972284D7D800981D42 /* Supporting Files */, ); path = AltStore; sourceTree = ""; @@ -94,6 +105,50 @@ name = Frameworks; sourceTree = ""; }; + BFD2478A2284C49000981D42 /* Apps */ = { + isa = PBXGroup; + children = ( + BFD2476F2284B9A500981D42 /* AppsViewController.swift */, + BFD247922284D4B700981D42 /* AppTableViewCell.swift */, + ); + path = Apps; + sourceTree = ""; + }; + BFD2478D2284C4C700981D42 /* Components */ = { + isa = PBXGroup; + children = ( + BFD2478B2284C4C300981D42 /* AppIconImageView.swift */, + BFD2478E2284C8F900981D42 /* Button.swift */, + ); + path = Components; + sourceTree = ""; + }; + BFD247962284D7C100981D42 /* Resources */ = { + isa = PBXGroup; + children = ( + BFD247762284B9A700981D42 /* Assets.xcassets */, + BFD247942284D7BD00981D42 /* Apps.plist */, + ); + path = Resources; + sourceTree = ""; + }; + BFD247972284D7D800981D42 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + BFD247782284B9A700981D42 /* LaunchScreen.storyboard */, + BFD2477B2284B9A700981D42 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + BFD247982284D7FC00981D42 /* Model */ = { + isa = PBXGroup; + children = ( + BFD247992284D80900981D42 /* App.swift */, + ); + path = Model; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -153,6 +208,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + BFD247952284D7BD00981D42 /* Apps.plist in Resources */, BFD2477A2284B9A700981D42 /* LaunchScreen.storyboard in Resources */, BFD247772284B9A700981D42 /* Assets.xcassets in Resources */, BFD247752284B9A500981D42 /* Main.storyboard in Resources */, @@ -166,9 +222,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + BFD2478F2284C8F900981D42 /* Button.swift in Sources */, BFD247722284B9A500981D42 /* SecondViewController.swift in Sources */, + BFD2478C2284C4C300981D42 /* AppIconImageView.swift in Sources */, BFD2476E2284B9A500981D42 /* AppDelegate.swift in Sources */, - BFD247702284B9A500981D42 /* FirstViewController.swift in Sources */, + BFD247702284B9A500981D42 /* AppsViewController.swift in Sources */, + BFD2479A2284D80900981D42 /* App.swift in Sources */, + BFD247932284D4B700981D42 /* AppTableViewCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/AltStore/Apps/AppTableViewCell.swift b/AltStore/Apps/AppTableViewCell.swift new file mode 100644 index 00000000..733056d9 --- /dev/null +++ b/AltStore/Apps/AppTableViewCell.swift @@ -0,0 +1,53 @@ +// +// AppTableViewCell.swift +// AltStore +// +// Created by Riley Testut on 5/9/19. +// Copyright © 2019 Riley Testut. All rights reserved. +// + +import UIKit + +@objc class AppTableViewCell: UITableViewCell +{ + @IBOutlet var nameLabel: UILabel! + @IBOutlet var subtitleLabel: UILabel! + @IBOutlet var appIconImageView: UIImageView! + @IBOutlet var button: UIButton! + + override func awakeFromNib() + { + super.awakeFromNib() + + self.selectionStyle = .none + } + + override func setHighlighted(_ highlighted: Bool, animated: Bool) + { + super.setHighlighted(highlighted, animated: animated) + + self.update() + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + + self.update() + } +} + +private extension AppTableViewCell +{ + func update() + { + if self.isHighlighted || self.isSelected + { + self.contentView.backgroundColor = UIColor(white: 0.9, alpha: 1.0) + } + else + { + self.contentView.backgroundColor = .white + } + } +} diff --git a/AltStore/Apps/AppsViewController.swift b/AltStore/Apps/AppsViewController.swift new file mode 100644 index 00000000..8b54ef5d --- /dev/null +++ b/AltStore/Apps/AppsViewController.swift @@ -0,0 +1,52 @@ +// +// AppsViewController.swift +// AltStore +// +// Created by Riley Testut on 5/9/19. +// Copyright © 2019 Riley Testut. All rights reserved. +// + +import UIKit +import Roxas + +class AppsViewController: UITableViewController +{ + private lazy var dataSource = self.makeDataSource() + + override func viewDidLoad() + { + super.viewDidLoad() + + self.tableView.dataSource = self.dataSource + + // Hide trailing row separators. + self.tableView.tableFooterView = UIView() + } +} + +private extension AppsViewController +{ + func makeDataSource() -> RSTArrayTableViewDataSource + { + let appsFileURL = Bundle.main.url(forResource: "Apps", withExtension: "plist")! + + do + { + let data = try Data(contentsOf: appsFileURL) + let apps = try PropertyListDecoder().decode([App].self, from: data) + + let dataSource = RSTArrayTableViewDataSource(items: apps) + dataSource.cellConfigurationHandler = { (cell, app, indexPath) in + let cell = cell as! AppTableViewCell + cell.nameLabel.text = app.name + cell.subtitleLabel.text = app.subtitle + cell.appIconImageView.image = UIImage(named: app.iconName) + } + return dataSource + } + catch + { + fatalError("Failed to load apps. \(error)") + } + } +} diff --git a/AltStore/Base.lproj/Main.storyboard b/AltStore/Base.lproj/Main.storyboard index 816ce834..c2daeb3a 100644 --- a/AltStore/Base.lproj/Main.storyboard +++ b/AltStore/Base.lproj/Main.storyboard @@ -1,61 +1,32 @@ - + + + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AltStore/Components/AppIconImageView.swift b/AltStore/Components/AppIconImageView.swift new file mode 100644 index 00000000..092b3d18 --- /dev/null +++ b/AltStore/Components/AppIconImageView.swift @@ -0,0 +1,38 @@ +// +// AppIconImageView.swift +// AltStore +// +// Created by Riley Testut on 5/9/19. +// Copyright © 2019 Riley Testut. All rights reserved. +// + +import UIKit + +class AppIconImageView: UIImageView +{ + override func awakeFromNib() + { + super.awakeFromNib() + + self.contentMode = .scaleAspectFill + self.clipsToBounds = true + + self.layer.borderWidth = 0.5 + self.layer.borderColor = UIColor.lightGray.cgColor + + // Allows us to match system look for app icons. + if self.layer.responds(to: Selector(("continuousCorners"))) + { + self.layer.setValue(true, forKey: "continuousCorners") + } + } + + override func layoutSubviews() + { + super.layoutSubviews() + + // Based off of 60pt icon having 12pt radius. + let radius = self.bounds.height / 5 + self.layer.cornerRadius = radius + } +} diff --git a/AltStore/Components/Button.swift b/AltStore/Components/Button.swift new file mode 100644 index 00000000..f3c2aebb --- /dev/null +++ b/AltStore/Components/Button.swift @@ -0,0 +1,51 @@ +// +// Button.swift +// AltStore +// +// Created by Riley Testut on 5/9/19. +// Copyright © 2019 Riley Testut. All rights reserved. +// + +import UIKit + +class Button: UIButton +{ + override var intrinsicContentSize: CGSize { + var size = super.intrinsicContentSize + size.width += 20 + return size + } + + override func awakeFromNib() + { + super.awakeFromNib() + + self.setTitleColor(.white, for: .normal) + + self.layer.masksToBounds = true + self.layer.cornerRadius = 8 + + self.update() + } + + override func tintColorDidChange() + { + super.tintColorDidChange() + + self.update() + } + + override var isHighlighted: Bool { + didSet { + self.update() + } + } +} + +private extension Button +{ + func update() + { + self.backgroundColor = self.tintColor + } +} diff --git a/AltStore/FirstViewController.swift b/AltStore/FirstViewController.swift deleted file mode 100644 index 0b36b45a..00000000 --- a/AltStore/FirstViewController.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// FirstViewController.swift -// AltStore -// -// Created by Riley Testut on 5/9/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -import UIKit - -class FirstViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/AltStore/Model/App.swift b/AltStore/Model/App.swift new file mode 100644 index 00000000..20f50bfc --- /dev/null +++ b/AltStore/Model/App.swift @@ -0,0 +1,17 @@ +// +// App.swift +// AltStore +// +// Created by Riley Testut on 5/9/19. +// Copyright © 2019 Riley Testut. All rights reserved. +// + +import Foundation + +class App: NSObject, Codable +{ + var name: String + var subtitle: String + + var iconName: String +} diff --git a/AltStore/Resources/Apps.plist b/AltStore/Resources/Apps.plist new file mode 100644 index 00000000..11f1262f --- /dev/null +++ b/AltStore/Resources/Apps.plist @@ -0,0 +1,22 @@ + + + + + + name + Delta + subtitle + All-in-one Nintendo emulator + iconName + DeltaIcon + + + name + Clipboard Manager + subtitle + Simple but powerful clipboard manager + iconName + ClipboardIcon + + + diff --git a/AltStore/Resources/Assets.xcassets/App Icons/ClipboardIcon.imageset/ClipboardIcon.png b/AltStore/Resources/Assets.xcassets/App Icons/ClipboardIcon.imageset/ClipboardIcon.png new file mode 100644 index 00000000..ad42ca2b Binary files /dev/null and b/AltStore/Resources/Assets.xcassets/App Icons/ClipboardIcon.imageset/ClipboardIcon.png differ diff --git a/AltStore/Resources/Assets.xcassets/App Icons/ClipboardIcon.imageset/Contents.json b/AltStore/Resources/Assets.xcassets/App Icons/ClipboardIcon.imageset/Contents.json new file mode 100644 index 00000000..20147059 --- /dev/null +++ b/AltStore/Resources/Assets.xcassets/App Icons/ClipboardIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ClipboardIcon.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/AltStore/Assets.xcassets/Contents.json b/AltStore/Resources/Assets.xcassets/App Icons/Contents.json similarity index 100% rename from AltStore/Assets.xcassets/Contents.json rename to AltStore/Resources/Assets.xcassets/App Icons/Contents.json diff --git a/AltStore/Resources/Assets.xcassets/App Icons/DeltaIcon.imageset/Contents.json b/AltStore/Resources/Assets.xcassets/App Icons/DeltaIcon.imageset/Contents.json new file mode 100644 index 00000000..80b74036 --- /dev/null +++ b/AltStore/Resources/Assets.xcassets/App Icons/DeltaIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "DeltaIcon.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/AltStore/Resources/Assets.xcassets/App Icons/DeltaIcon.imageset/DeltaIcon.png b/AltStore/Resources/Assets.xcassets/App Icons/DeltaIcon.imageset/DeltaIcon.png new file mode 100644 index 00000000..40f46a9a Binary files /dev/null and b/AltStore/Resources/Assets.xcassets/App Icons/DeltaIcon.imageset/DeltaIcon.png differ diff --git a/AltStore/Assets.xcassets/AppIcon.appiconset/Contents.json b/AltStore/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from AltStore/Assets.xcassets/AppIcon.appiconset/Contents.json rename to AltStore/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/AltStore/Resources/Assets.xcassets/Contents.json b/AltStore/Resources/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/AltStore/Resources/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/AltStore/Assets.xcassets/first.imageset/Contents.json b/AltStore/Resources/Assets.xcassets/first.imageset/Contents.json similarity index 100% rename from AltStore/Assets.xcassets/first.imageset/Contents.json rename to AltStore/Resources/Assets.xcassets/first.imageset/Contents.json diff --git a/AltStore/Assets.xcassets/first.imageset/first.pdf b/AltStore/Resources/Assets.xcassets/first.imageset/first.pdf similarity index 100% rename from AltStore/Assets.xcassets/first.imageset/first.pdf rename to AltStore/Resources/Assets.xcassets/first.imageset/first.pdf diff --git a/AltStore/Assets.xcassets/second.imageset/Contents.json b/AltStore/Resources/Assets.xcassets/second.imageset/Contents.json similarity index 100% rename from AltStore/Assets.xcassets/second.imageset/Contents.json rename to AltStore/Resources/Assets.xcassets/second.imageset/Contents.json diff --git a/AltStore/Assets.xcassets/second.imageset/second.pdf b/AltStore/Resources/Assets.xcassets/second.imageset/second.pdf similarity index 100% rename from AltStore/Assets.xcassets/second.imageset/second.pdf rename to AltStore/Resources/Assets.xcassets/second.imageset/second.pdf