├── .gitignore ├── ThemePark-example-macOS ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── ThemePark_example_macOS.entitlements ├── AppDelegate.swift ├── Info.plist └── Base.lproj │ └── MainMenu.xib ├── Sources └── ThemePark │ ├── core │ ├── decode │ │ ├── ThemeFontKind.swift │ │ ├── ThemeFontColorKind.swift │ │ ├── ThemeColorKind.swift │ │ ├── ThemeDataKind.swift │ │ └── transformer │ │ │ └── DecodingTypes.swift │ ├── ThemeKind.swift │ ├── themeable │ │ ├── iOS │ │ │ ├── Themeable+UIStepper.swift │ │ │ ├── Themeable+UILabel.swift │ │ │ ├── Themeable+UISlider.swift │ │ │ ├── Themeable+UISegmentedControl.swift │ │ │ ├── Themeable+UIButton.swift │ │ │ ├── Themeable+UITableViewCell.swift │ │ │ ├── vc │ │ │ │ ├── Themeable+UIVC.swift │ │ │ │ ├── Themeable +UITVC.swift │ │ │ │ ├── Themeable +UITabBar.swift │ │ │ │ └── Themeable +UINavBar.swift │ │ │ ├── Themeable+UITextField.swift │ │ │ └── Themeable+UISwitch.swift │ │ ├── macOS │ │ │ └── Themeable+NSVC.swift │ │ └── Themeable.swift │ ├── util │ │ ├── ThemeUtil+Animation.swift │ │ └── ThemeUtil.swift │ └── Theme.swift │ └── common │ ├── Hybrid.swift │ ├── json │ ├── Data+Extension.swift │ ├── JSONUtil.swift │ └── DecodingHelpers.swift │ ├── View+Extension.swift │ ├── FileParser.swift │ ├── VC+Extension.swift │ ├── color │ ├── ColorUtil.swift │ ├── ColorTypes.swift │ └── Colors.swift │ └── FileWatcher.swift ├── ThemeTest.xcodeproj ├── xcuserdata │ ├── eon.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── andrejorgensen.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ ├── eon.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ └── andrejorgensen.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ └── ThemeTest.xcscheme └── project.pbxproj ├── .github └── workflows │ └── swift.yml ├── assets.bundle ├── dark.json └── light.json ├── Tests └── ThemeParkIOSTests │ ├── ThemeParkIOSTests.swift │ └── Info.plist ├── theme ├── ThemeFontColor.swift ├── ThemeFont.swift ├── ThemeData.swift ├── ThemeColor.swift ├── CustomTheme.swift └── deprecated │ └── Theme+Styles-DEPRECATED.swift ├── ThemeTest ├── vc │ ├── Settings.swift │ └── Main.swift ├── AppDelegate.swift ├── Info.plist ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard └── Assets.xcassets │ └── AppIcon.appiconset │ └── Contents.json ├── Package.swift ├── README.md └── .swiftlint.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | -------------------------------------------------------------------------------- /ThemePark-example-macOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Sources/ThemePark/core/decode/ThemeFontKind.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol ThemeFontKind { 4 | var system: Font { get } 5 | var systemBold: Font { get } 6 | } 7 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/ThemeKind.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | protocol ThemeKind { 4 | static var theme: ThemeDataKind { get set } 5 | static var currentType: String { get set } 6 | } 7 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/xcuserdata/eon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/decode/ThemeFontColorKind.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol ThemeFontColorKind { 4 | var highlight: Color { get } 5 | var disabled: Color { get } 6 | } 7 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/project.xcworkspace/xcuserdata/eon.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eonist/ThemePark/HEAD/ThemeTest.xcodeproj/project.xcworkspace/xcuserdata/eon.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UIStepper.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | 4 | extension UIStepper: Themeable { 5 | public func apply() { 6 | self.tintColor = Theme.theme.color.tint 7 | } 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UILabel.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | 4 | extension UILabel: Themeable { 5 | public func apply() { 6 | self.textColor = Theme.theme.color.font.highlight 7 | } 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UISlider.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | 3 | import UIKit 4 | 5 | extension UISlider: Themeable { 6 | public func apply() { 7 | self.tintColor = Theme.theme.color.tint 8 | } 9 | } 10 | #endif 11 | -------------------------------------------------------------------------------- /ThemePark-example-macOS/ThemePark_example_macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/project.xcworkspace/xcuserdata/andrejorgensen.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eonist/ThemePark/HEAD/ThemeTest.xcodeproj/project.xcworkspace/xcuserdata/andrejorgensen.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UISegmentedControl.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | 3 | import UIKit 4 | 5 | extension UISegmentedControl: Themeable { 6 | public func apply() { 7 | self.tintColor = Theme.theme.color.tint 8 | } 9 | } 10 | #endif 11 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/decode/ThemeColorKind.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol ThemeColorKind { 4 | var foreground: Color { get } 5 | var middleground: Color { get } 6 | var background: Color { get } 7 | var tint: Color { get } 8 | var font: ThemeFontColorKind { get } 9 | } 10 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UIButton.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | 4 | extension UIButton: Themeable { 5 | /** 6 | * - Note: there is also: backgroundColor 7 | */ 8 | public func apply() { 9 | setTitleColor(Theme.theme.color.font.highlight, for: .normal) 10 | } 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UITableViewCell.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | 3 | import UIKit 4 | 5 | extension UITableViewCell: Themeable { 6 | public func apply() { 7 | backgroundColor = Theme.theme.color.background 8 | textLabel?.textColor = Theme.theme.color.font.highlight 9 | } 10 | } 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/vc/Themeable+UIVC.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | /** 4 | * Fixme: ⚠️️ Store these theme extensions centrally? 5 | */ 6 | extension UIViewController: Themeable { 7 | @objc public func apply() { 8 | self.view.backgroundColor = Theme.theme.color.background 9 | } 10 | } 11 | #endif 12 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/macOS/Themeable+NSVC.swift: -------------------------------------------------------------------------------- 1 | #if os(macOS) 2 | import Cocoa 3 | /** 4 | * Fixme: ⚠️️ Store these theme extensions centrally? 5 | */ 6 | extension NSViewController: Themeable { 7 | public func apply() { 8 | self.view.layer?.backgroundColor = Theme.theme.color.background.cgColor 9 | } 10 | } 11 | #endif 12 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/Themeable.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol Themeable { 4 | /** 5 | * When classes extend Themeable they must implement this method with styling code 6 | * - Note: to deviate from default theme, create a SubClass and override with protocol method overriding 7 | */ 8 | func apply() 9 | } 10 | -------------------------------------------------------------------------------- /.github/workflows/swift.yml: -------------------------------------------------------------------------------- 1 | name: Swift 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: "0 11 * * 0-6" 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: macOS-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v1 17 | - name: Build 18 | run: swift build -v 19 | - name: Run tests 20 | run: swift test -v 21 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UITextField.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | 4 | extension UITextField: Themeable { 5 | public func apply() { 6 | textColor = Theme.theme.color.font.highlight 7 | backgroundColor = Theme.theme.color.background 8 | borderStyle = .roundedRect 9 | font = Theme.theme.font.system 10 | } 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/decode/ThemeDataKind.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * These are the minimal values a theme must have 4 | * - Note: if you want to Structure it differently, then you must provide getters so that UIKit can get its colors and fonts etc 5 | */ 6 | public protocol ThemeDataKind { 7 | var color: ThemeColorKind { get set } 8 | var font: ThemeFontKind { get set } 9 | } 10 | -------------------------------------------------------------------------------- /assets.bundle/dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "color":{ 3 | "foreground":"gray", 4 | "middleground":"gray", 5 | "background":"black", 6 | "tint":"yellow", 7 | "font":{ 8 | "highlight":"white", 9 | "disabled":"black" 10 | } 11 | }, 12 | "font":{ 13 | "system":{"name":"Helvetica","size":"18"}, 14 | "systemBold":{"name":"Helvetica-Bold","size":"18"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assets.bundle/light.json: -------------------------------------------------------------------------------- 1 | { 2 | "color":{ 3 | "foreground":"white", 4 | "middleground":"gray", 5 | "background":"white", 6 | "tint":"blue", 7 | "font":{ 8 | "highlight":"black", 9 | "disabled":"black" 10 | } 11 | }, 12 | "font":{ 13 | "system":{"name":"Helvetica","size":"18"}, 14 | "systemBold":{"name":"Helvetica-Bold","size":"18"} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Tests/ThemeParkIOSTests/ThemeParkIOSTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | class ThemeParkIOSTests: XCTestCase { 4 | override func setUp() { 5 | super.setUp() 6 | } 7 | override func tearDown() { 8 | super.tearDown() 9 | } 10 | func testExample() { 11 | XCTAssertEqual("Hello, World!", "Hello, World!") 12 | } 13 | func testPerformanceExample() { 14 | self.measure { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/Themeable+UISwitch.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | 3 | import UIKit 4 | extension UISwitch: Themeable { 5 | /** 6 | * Tint color doesn't animate very good on the switch if its used to switch theme, self.onTintColor = theme.color.tint 7 | */ 8 | public func apply() { 9 | self.layer.cornerRadius = 16.0 10 | self.backgroundColor = Theme.theme.color.background 11 | } 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/vc/Themeable +UITVC.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | /** 4 | * Fixme: ⚠️️ Store these theme extensions centrally? 5 | */ 6 | extension UITableViewController { 7 | override public func apply() { 8 | self.tableView.backgroundColor = Theme.theme.color.background 9 | tabBarController?.tabBar.apply() 10 | navigationController?.navigationBar.apply() 11 | } 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/vc/Themeable +UITabBar.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | 3 | import UIKit 4 | 5 | /*Tab Bar:*/ 6 | extension UITabBar: Themeable { 7 | public func apply() { 8 | self.barTintColor = Theme.theme.color.background 9 | self.tintColor = Theme.theme.color.tint 10 | //This line is a "Hot fix" see: https://forums.developer.apple.com/thread/60258 11 | self.layoutIfNeeded() 12 | } 13 | } 14 | #endif 15 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/Hybrid.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | public typealias View = UIView 4 | public typealias ViewController = UIViewController 5 | public typealias Color = UIColor 6 | public typealias Font = UIFont 7 | public typealias Application = UIApplication 8 | 9 | #elseif os(macOS) 10 | import Cocoa 11 | public typealias View = NSView 12 | public typealias ViewController = NSViewController 13 | public typealias Color = NSColor 14 | public typealias Font = NSFont 15 | public typealias Application = NSApplication 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/json/Data+Extension.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Global generic decode method for Decodable 4 | * Fixme: write example 5 | */ 6 | public func decode(data: Data) throws -> T { 7 | let decoder = JSONDecoder() 8 | return try decoder.decode(T.self, from: data) 9 | } 10 | 11 | /** 12 | * Encodable Extension 13 | * Fixme: write example 14 | */ 15 | extension Encodable { 16 | public func encode() throws -> Data { 17 | let encoder = JSONEncoder() 18 | encoder.outputFormatting = .prettyPrinted 19 | return try encoder.encode(self) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ThemePark-example-macOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | @NSApplicationMain 4 | class AppDelegate: NSObject, NSApplicationDelegate { 5 | @IBOutlet weak var window: NSWindow! 6 | func applicationDidFinishLaunching(_ aNotification: Notification) { 7 | CustomTheme.setTheme(themeType: CustomTheme.ThemeType.light.rawValue)//update the theme 8 | // Swift.print("Theme.theme.color.background: \(Theme.theme.color.background)") 9 | // Swift.print("Theme.theme.color.font.highlight: \(Theme.theme.color.font.highlight)") 10 | // Swift.print("Theme.theme.font.system: \(Theme.theme.font.system)") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/json/JSONUtil.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public class JSONUtil { 4 | /** 5 | * Converts json string to json object 6 | * "{\"title\":\"doctor\"}".json //Output: a JSON object 7 | */ 8 | public static func json(_ str: String) -> Any? { 9 | guard let data: Data = str.data(using: String.Encoding.utf8, allowLossyConversion: false) else { return nil } 10 | if let json: Any = try? JSONSerialization.jsonObject(with: data, options: []) { 11 | return json 12 | }else { 13 | fatalError("JSON is format wrongly: \(str)") 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /theme/ThemeFontColor.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct ThemeFontColor: Decodable, ThemeFontColorKind { 4 | enum CodingKeys: String, CodingKey { case highlight, disabled } // CodingKeys are required when you want to customize your json parsing 5 | public let highlight: Color 6 | public let disabled: Color 7 | public init(from decoder: Decoder) throws { 8 | // Swift.print("ThemeFontColor.init") 9 | let container = try decoder.container(keyedBy: CodingKeys.self) 10 | highlight = try container.decode(key: .highlight, transformer: ColorTransformer()) 11 | disabled = try container.decode(key: .disabled, transformer: ColorTransformer()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /theme/ThemeFont.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * UIFont 4 | */ 5 | public struct ThemeFont: Decodable, ThemeFontKind { 6 | /** 7 | * CodingKeys are required when you want to customize your json parsing 8 | */ 9 | enum CodingKeys: String, CodingKey { case system, systemBold } 10 | public let system: Font 11 | public let systemBold: Font 12 | public init(from decoder: Decoder) throws { 13 | let container = try decoder.container(keyedBy: CodingKeys.self) 14 | system = try container.decode(key: .system, transformer: UIFontTransformer()) 15 | systemBold = try container.decode(key: .systemBold, transformer: UIFontTransformer()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/util/ThemeUtil+Animation.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | /** 4 | * Animation 5 | */ 6 | extension ThemeUtil { 7 | /** 8 | * Collects all Themeable views, And initiates "from, to" animation 9 | */ 10 | public static func transition(_ view: UIView) { 11 | UIView.animate(withDuration: Theme.transitionDur, animations: { apply(view) }, completion: nil) 12 | } 13 | /** 14 | * For Controllers that are not a View it self 15 | */ 16 | public static func transition(_ viewController: UIViewController) { 17 | UIView.animate(withDuration: Theme.transitionDur, animations: { apply(viewController) }, completion: nil) 18 | } 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/View+Extension.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension View { 4 | /** 5 | * Traverses the entire UIView hirearchy and collects views that are of speccific PARAM: type 6 | * Fixme: ⚠️️ this can be written more elegantly with flatmap 7 | */ 8 | func descendants(type: T.Type? = nil) -> [T] { 9 | var subViewsOfType: [T] = [] 10 | self.subviews.forEach { 11 | if let subView: T = ($0 as? T) { 12 | subViewsOfType.append(subView) 13 | } 14 | if !$0.subviews.isEmpty { 15 | subViewsOfType += $0.descendants(type: type) 16 | } 17 | } 18 | return subViewsOfType 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ThemeTest/vc/Settings.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class SettingsController: UITableViewController { 4 | @IBAction private func onSwitchChange(_ sender: UISwitch) { 5 | CustomTheme.currentType = sender.isOn ? CustomTheme.ThemeType.dark.rawValue : CustomTheme.ThemeType.light.rawValue 6 | CustomTheme.theme = CustomTheme.getTheme(theme: CustomTheme.currentType) 7 | ThemeUtil.transition(self) 8 | } 9 | } 10 | /** 11 | * Core 12 | */ 13 | extension SettingsController { 14 | override func viewDidLayoutSubviews() { 15 | super.viewDidLayoutSubviews() 16 | // AppDelegate.curViewController = self 17 | ThemeUtil.apply(self) 18 | //Swift.print("topMostViewController(): \(UIApplication.shared.topMostViewController())") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ThemeTest/vc/Main.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | // - Fixme: ⚠️️ rename to MainView.swift 4 | class Main: UITableViewController { 5 | private var list: [String] = ["red", "blue", "green"] 6 | override func viewDidLayoutSubviews() { 7 | super.viewDidLayoutSubviews() 8 | ThemeUtil.apply(self) 9 | } 10 | } 11 | /** 12 | * Core 13 | */ 14 | extension Main { 15 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 16 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! 17 | cell.textLabel?.text = list[indexPath.row] 18 | return cell 19 | } 20 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 21 | return list.count 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/themeable/iOS/vc/Themeable +UINavBar.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | 3 | import UIKit 4 | 5 | /*navBar*/ 6 | extension UINavigationBar: Themeable { 7 | public func apply() { 8 | self.barTintColor = Theme.theme.color.background 9 | //Fixme: ⚠️️ this shuldnt be hardcode like this , try storing the actual style somehow? 10 | self.barStyle = (Theme.currentType == "dark" ? .black : .default) 11 | let navBarTitleColor: UIColor = Theme.theme.color.font.highlight 12 | self.titleTextAttributes = [NSAttributedString.Key.foregroundColor: navBarTitleColor] 13 | self.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: navBarTitleColor] 14 | //This line is a "Hot fix" see: https://forums.developer.apple.com/thread/60258 15 | self.layoutIfNeeded() 16 | } 17 | } 18 | #endif 19 | -------------------------------------------------------------------------------- /Tests/ThemeParkIOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /theme/ThemeData.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * ThemeData 4 | */ 5 | public struct ThemeData: Decodable, ThemeDataKind { 6 | enum CodingKeys: String, CodingKey { case color, font } // CodingKeys are required when you want to customize your json parsing 7 | public var font: ThemeFontKind 8 | public var color: ThemeColorKind 9 | /** 10 | * - Note: When you use Protocols as variable kind, the auto init doesnt work, so we have to decode it manually 11 | * - Note: Using "Variable kinds" makes Theme extensiable 12 | */ 13 | public init(from decoder: Decoder) throws { 14 | //Swift.print("ThemeData.init()") 15 | let container = try decoder.container(keyedBy: CodingKeys.self) 16 | font = try container.decode(ThemeFont.self, forKey: .font) 17 | color = try container.decode(ThemeColor.self, forKey: .color) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/util/ThemeUtil.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Utility methods (Apply theme to View and ViewController) 4 | */ 5 | public class ThemeUtil {// rename to Themer? ThemeApplier? 6 | /** 7 | * Applies a ThemeType to a UIView hierarchy (only affects UIViews that extends Themeable) 8 | */ 9 | public static func apply(_ view: View) { 10 | let themeables: [Themeable] = view.descendants() + (view is Themeable ? [view as! Themeable]: [])//add it view to the array if it is also themeable 11 | themeables.reversed().forEach { $0.apply() }/*We reverse so that higher up components can override their siblings*/ 12 | } 13 | /** 14 | * For Controllers that are not a View it self 15 | */ 16 | public static func apply(_ viewController: ViewController) { 17 | viewController.apply() 18 | apply(viewController.view) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/xcuserdata/andrejorgensen.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ThemePark-example-macOS.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 3 11 | 12 | ThemePark-macOS.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | ThemePark.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 0 21 | 22 | ThemeTest.xcscheme_^#shared#^_ 23 | 24 | orderHint 25 | 2 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/json/DecodingHelpers.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Makes the code more reusable/modular 4 | */ 5 | public protocol DecodingContainerTransformer { 6 | associatedtype DecodingInput 7 | associatedtype DecodingOutput 8 | func decode(input: DecodingInput) throws -> DecodingOutput 9 | } 10 | /** 11 | * Makes the code more reusable/modular 12 | */ 13 | extension KeyedDecodingContainer { 14 | public func decode(key: Key, transformer: Transformer) throws -> Transformer.DecodingOutput where Transformer.DecodingInput: Decodable { 15 | return try transformer.decode(input: try decode(Transformer.DecodingInput.self, forKey: key)) 16 | } 17 | /** 18 | * For optional? 19 | */ 20 | public func decodeIfPresent(key: Key, transformer: Transformer) throws -> Transformer.DecodingOutput? where Transformer.DecodingInput: Decodable { 21 | return try decodeIfPresent(Transformer.DecodingInput.self, forKey: key).map(transformer.decode) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /theme/ThemeColor.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * UIColor 4 | */ 5 | public struct ThemeColor: Decodable, ThemeColorKind { 6 | /** 7 | * CodingKeys are required when you want to customize your json parsing 8 | */ 9 | enum CodingKeys: String, CodingKey { case foreground, middleground, background, tint, font } 10 | public let foreground: Color 11 | public let middleground: Color 12 | public let background: Color 13 | public let tint: Color 14 | public let font: ThemeFontColorKind 15 | public init(from decoder: Decoder) throws { 16 | let container = try decoder.container(keyedBy: CodingKeys.self) 17 | foreground = try container.decode(key: .foreground, transformer: ColorTransformer()) 18 | middleground = try container.decode(key: .middleground, transformer: ColorTransformer()) 19 | background = try container.decode(key: .background, transformer: ColorTransformer()) 20 | tint = try container.decode(key: .tint, transformer: ColorTransformer()) 21 | font = try container.decode(ThemeFontColor.self, forKey: .font) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ThemeTest/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | var window: UIWindow? 6 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 7 | // Swift.print("\(Font.systemFont(ofSize: 20))") 8 | // Swift.print("\(Font.boldSystemFont(ofSize: 30))") 9 | /*Set the customTheme, before components ask Theme for styling*/ 10 | CustomTheme.setTheme(themeType: CustomTheme.ThemeType.light.rawValue)//set init theme 11 | /*Watches for changes, super useful for testing styling by just changing the json doc*/ 12 | FileWatcher(Bundle.main.resourcePath!+"/assets.bundle/dark.json") { 13 | Swift.print("the file was modified") 14 | if let controller = UIApplication.shared.topMostViewController() { 15 | CustomTheme.theme = CustomTheme.getTheme(theme: CustomTheme.currentType)//update the theme 16 | ThemeUtil.apply(controller) 17 | } 18 | }.start() 19 | return true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/xcuserdata/eon.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ThemePark-example-macOS.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | ThemeTest.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | ThemeTest.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | F114AE3A21A6E06500942A28 26 | 27 | primary 28 | 29 | 30 | F11ADDEB2235718B0024F9C7 31 | 32 | primary 33 | 34 | 35 | F12BA13F205D2BDA006C1D56 36 | 37 | primary 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ThemePark-example-macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2019 futurelab. All rights reserved. 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /theme/CustomTheme.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * - Fixme: ⚠️️ make something called DefaultTheme that you can extend, copying customTheme is a drag for testing 4 | */ 5 | public class CustomTheme: Theme { 6 | public enum ThemeType: String { case light, dark }// Fixme: ⚠️️ delete this 7 | override public class func getTheme(theme: String) -> ThemeDataKind { 8 | Swift.print("getTheme") 9 | let themeFileName: String = { 10 | switch theme { 11 | case ThemeType.light.rawValue: 12 | return "light.json" 13 | case ThemeType.dark.rawValue: 14 | return "dark.json" 15 | default: fatalError("theme not supported") 16 | } 17 | }() 18 | // ⭐ Entry point ⭐ 19 | do { 20 | guard let data: Data = FileParser.data(path: Bundle.main.resourcePath!+"/assets.bundle/" + themeFileName) else { fatalError("wrong file path") } 21 | let theme: ThemeData = try decode(data: data) 22 | return theme 23 | } 24 | catch { 25 | Swift.print("error: \(error)") 26 | fatalError("can't be converted json to Theme") 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ThemePark-example-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "ThemePark", 8 | platforms: [.iOS(.v12), .macOS(.v10_13)], 9 | products: [ 10 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 11 | .library( 12 | name: "ThemePark", 13 | targets: ["ThemePark"]) 14 | ], 15 | dependencies: [ 16 | // Dependencies declare other packages that this package depends on. 17 | // .package(url: /* package url */, from: "1.0.0"), 18 | // color sugar 19 | // JsonSugar 20 | // FileSugar 21 | ], 22 | targets: [ 23 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 24 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 25 | .target( 26 | name: "ThemePark", 27 | dependencies: []), 28 | .testTarget( 29 | name: "ThemeParkIOSTests", 30 | dependencies: ["ThemePark"]) 31 | ] 32 | ) 33 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/FileParser.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public class FileParser { 4 | /** 5 | * Returns string content from a file at file location "path" 6 | * - Param: path is the file path to the file in this format: (User/John/Desktop/test.txt) 7 | * - Important: ⚠️️ Remember to expand the path with the .tildePath call, if it's a tilde path 8 | * - Note: Supports syntax like this: /Users/John/Desktop/temp/../test.txt (the temp folder is excluded in this case) 9 | * ## Examples: 10 | * let path = "//Users//someFile.xml" 11 | * var err: NSError? 12 | * let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: &err) 13 | * FileParser.content("~/Desktop/temp.txt".tildePath)// 14 | */ 15 | public static func content(path: String) -> String? { 16 | do { 17 | let content = try String(contentsOfFile: path, encoding: .utf8) as String//encoding: NSUTF8StringEncoding 18 | return content 19 | } catch { 20 | return nil 21 | } 22 | } 23 | /** 24 | * New 25 | */ 26 | public static func data(path: String) -> Data? { 27 | guard let str: String = FileParser.content(path: path) else { return nil } 28 | return str.data(using: .utf8) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/decode/transformer/DecodingTypes.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import QuartzCore 3 | /** 4 | * The transformer that handles parsing the string value to UIColor 5 | * Fixme: ⚠️️ Add support for 0x00FF00FF (Aka hex with alpha value) 6 | * EXAMPLE: "color":"white" 7 | */ 8 | public struct ColorTransformer: DecodingContainerTransformer { 9 | // enum Error: Swift.Error { case cannotCreateColor(hex: String) } 10 | public func decode(input: String) throws -> Color { 11 | return try ColorUtil.color(input) 12 | } 13 | public init() {}//<- Strange that you have to have this, but SuperTypes won't compile if not 14 | } 15 | /** 16 | * The transformer that handles parsing the dictionary (Aka fontName and fontSize) value to UIColor 17 | * ## Examples: 18 | * "font":{"name":".SFUIText","size":"16"} 19 | */ 20 | public struct UIFontTransformer: DecodingContainerTransformer { 21 | enum Error: Swift.Error { case cannotCreateFont(name: [String:String]) } 22 | public func decode(input: [String: String]) throws -> Font { 23 | guard let name = input["name"], let fontSize = input["size"], 24 | let fontSizeAsDouble = Double(fontSize), 25 | let font = Font(name: name, size: CGFloat(fontSizeAsDouble)) else { 26 | throw Error.cannotCreateFont(name: input) 27 | } 28 | return font 29 | } 30 | public init() {} 31 | } 32 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/VC+Extension.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) 2 | import UIKit 3 | #elseif os(macOS) 4 | import Cocoa 5 | #endif 6 | /** 7 | * VC 8 | */ 9 | extension ViewController { 10 | #if os(iOS) 11 | func topMostViewController() -> ViewController { 12 | if let tab = self.presentedViewController as? UITabBarController { 13 | if let selectedTab = tab.selectedViewController { 14 | return selectedTab.topMostViewController() 15 | } 16 | return tab.topMostViewController() 17 | } 18 | if self.presentedViewController == nil { 19 | return self 20 | } 21 | return self.presentedViewController!.topMostViewController() 22 | } 23 | #endif 24 | } 25 | #if os(iOS) 26 | /** 27 | * App 28 | */ 29 | extension Application { 30 | public func topMostViewController() -> ViewController? { 31 | return self.keyWindow?.rootViewController?.topMostViewController() 32 | } 33 | } 34 | #endif 35 | #if os(macOS) 36 | /** 37 | * App 38 | */ 39 | extension Application { 40 | public func topMostViewController() -> ViewController? { 41 | return self.keyWindow?.contentViewController 42 | } 43 | } 44 | #endif 45 | // if let navigation = self.presentedViewController as? UINavigationController { 46 | // if let visibleController = navigation.visibleViewController { 47 | // return visibleController.topMostViewController() 48 | // } 49 | // } 50 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/color/ColorUtil.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import QuartzCore 3 | 4 | public class ColorUtil { 5 | enum Error: Swift.Error { case inCorrectColorType(hex: String) } 6 | /** 7 | * # Examples: 8 | * Swift.print("red: \(ColorUtils.color("red"))") 9 | * Swift.print("blue: \(ColorUtils.color("0x0000FF"))") // NSColor / UIColor 10 | */ 11 | public static func color(_ colorStr: String) throws -> Color { 12 | let color: UInt = try { 13 | if colorStr.hasPrefix("0x") { // do additional checking see regex pattern, but good enough for now 14 | return UInt(Float(colorStr)!) // CAUTION: ⚠️️ if you do "0xFF0000FF".uint it will give the wrong value, use UInt(Double("")!) instead for cases like that 15 | }else { 16 | guard let uint: UInt = ColorTypes.color(colorStr) else { throw Error.inCorrectColorType(hex: colorStr) } 17 | return uint 18 | } 19 | }() 20 | return ColorUtil.color(color) 21 | } 22 | /** 23 | * Returns NSColor for hex int 24 | * - Note: Convenience method 25 | * ## Examples: 26 | * nsColor(UInt(0x39D149)) 27 | */ 28 | private static func color(_ hexColor: UInt, alpha: CGFloat = 1.0) -> Color { 29 | let rgb: UInt = hexColor 30 | let r: UInt = rgb >> 16 31 | let g: UInt = (rgb ^ (r << 16)) >> 8 32 | let b: UInt = (rgb ^ (r << 16)) ^ (g << 8) 33 | return Color(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: CGFloat(alpha)) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ThemeTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ThemeTest/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sources/ThemePark/core/Theme.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Make this more extensiable for overriding, use string instead of enum 4 | * - Fixme: ⚠️️ needs refactoring, use didset etc. simplify, use singlton if needed, use extension methods 5 | */ 6 | open class Theme: ThemeKind { 7 | private static var _theme: ThemeDataKind? 8 | /** 9 | * Override this in subClass 10 | */ 11 | public static var theme: ThemeDataKind { 12 | get { 13 | if let _theme = _theme { 14 | return _theme 15 | } else { 16 | fatalError("No theme is assigned yet") 17 | } 18 | } set { 19 | _theme = newValue 20 | } 21 | } 22 | /** 23 | * Holdes the current theme type, not really needed, but nice to have 24 | */ 25 | private static var _currentType: String? 26 | /** 27 | * Fixme: ⚠️️ write doc 28 | */ 29 | public class var currentType: String { 30 | get { 31 | if let _currentType = _currentType { 32 | return _currentType 33 | } else { 34 | fatalError("No curThemeType is assigned yet") 35 | } 36 | } set { 37 | _currentType = newValue 38 | } 39 | }// = .light// <-- light is default 40 | /** 41 | * Time it takes to transition from one theme to another 42 | */ 43 | static var transitionDur = 0.5 44 | /** 45 | * Override this for custom themes 46 | */ 47 | open class func getTheme(theme: String) -> ThemeDataKind { // ⚠️️ this must be case string 48 | fatalError("must be ovveridien by subclass") 49 | } 50 | /** 51 | * Sets themeType 52 | */ 53 | public static func setTheme(themeType: String) { 54 | currentType = themeType 55 | theme = getTheme(theme: currentType) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ThemeTest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /theme/deprecated/Theme+Styles-DEPRECATED.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Light theme (If you want to use struct instead of json, not part of core, add to your own app) 4 | */ 5 | //struct LightTheme:ThemeProtocol{ 6 | // let color:ColorProtocol = Color() 7 | // struct Color:ColorProtocol{ 8 | // let foreground:UIColor = .white 9 | // let middleground:UIColor = .gray 10 | // let background:UIColor = .white 11 | // let tint:UIColor = .blue 12 | // let font:ColorFontProtocol = Font() 13 | // struct Font:ColorFontProtocol{ 14 | // let highlight:UIColor = .black 15 | // let disabled:UIColor = .black 16 | // } 17 | // } 18 | // let font:FontProtocol = DefaultFont() 19 | //} 20 | ///** 21 | // * Dark theme 22 | // */ 23 | //struct DarkTheme:ThemeProtocol{ 24 | // let color:ColorProtocol = Color() 25 | // struct Color:ColorProtocol{ 26 | // let foreground:UIColor = .gray 27 | // let middleground:UIColor = .gray 28 | // let background:UIColor = .black 29 | // let tint:UIColor = .yellow 30 | // let font:ColorFontProtocol = Font() 31 | // struct Font:ColorFontProtocol{ 32 | // let highlight:UIColor = .white 33 | // let disabled:UIColor = .black 34 | // } 35 | // } 36 | // let font:FontProtocol = DefaultFont() 37 | //} 38 | ///** 39 | // * Common trait for Dark and light theme 40 | // */ 41 | //struct DefaultFont:FontProtocol{ 42 | // let system:UIFont = .systemFont(ofSize:18) 43 | // let systemBold:UIFont = .boldSystemFont(ofSize:18) 44 | //} 45 | ///** 46 | // * Common theme protocols, required in order to be able to switch between themes 47 | // */ 48 | //protocol ThemeProtocol{ 49 | // var color:ColorProtocol {get} 50 | // var font:FontProtocol {get} 51 | //} 52 | //protocol FontProtocol{ 53 | // var system:UIFont {get} 54 | // var systemBold:UIFont {get} 55 | //} 56 | //protocol ColorProtocol{ 57 | // var foreground:UIColor {get} 58 | // var middleground:UIColor {get} 59 | // var background:UIColor {get} 60 | // var tint:UIColor {get} 61 | // var font:ColorFontProtocol {get} 62 | //} 63 | //protocol ColorFontProtocol{ 64 | // var highlight:UIColor {get} 65 | // var disabled:UIColor {get} 66 | //} 67 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/FileWatcher.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * EXAMPLE: 4 | * let filewatcher = FileWatcher(String(string: "~/Desktop/test.txt").expandingTildeInPath) 5 | * filewatcher.callback = { event in print("Something happened ")} 6 | * filewatcher.start() // start monitoring 7 | * EXAMPLE: 8 | * FileWatcher(String(string: "~/Desktop/test.txt").expandingTildeInPath) { Swift.print("file was modified") }.start() //shorthand 9 | * NOTE: Only works with a filepath to a file 10 | */ 11 | public class FileWatcher { 12 | public typealias CallBack = () -> Void 13 | let filePath: String 14 | var callback: CallBack 15 | var latency: TimeInterval /*in seconds*/ 16 | var timer: Timer? 17 | var prevModifiedDate: NSDate? 18 | public init(_ filePath: String, latency: Double = 0.3, callback:@escaping CallBack = {}) { 19 | self.filePath = filePath 20 | self.latency = latency 21 | self.callback = callback 22 | } 23 | /** 24 | * Start listening 25 | */ 26 | public func start() { 27 | prevModifiedDate = Utils.modificationDate(filePath)//set a modified date 28 | timer = Timer.scheduledTimer(timeInterval: latency, target: self, selector: #selector(update), userInfo: nil, repeats: true)//swift 3 upgrade 29 | } 30 | /** 31 | * Stop listening 32 | */ 33 | public func stop() { 34 | if timer != nil { timer!.invalidate() } 35 | } 36 | /** 37 | * This method must be in the public or scope 38 | */ 39 | @objc func update() { 40 | if let modifiedDate: NSDate = Utils.modificationDate(filePath), modifiedDate != prevModifiedDate {//this should be > prevDate, but works for now 41 | callback()//only call back if modification date changes 42 | prevModifiedDate = modifiedDate//set the new date 43 | } 44 | } 45 | } 46 | private class Utils { 47 | /** 48 | * NOTE: make sure the file exists with: FileAsserter.exists("some path here") 49 | * PARAM: can't be tildePath, must be absolute Users/John/... 50 | */ 51 | static func modificationDate(_ filePath: String) -> NSDate? { 52 | guard FileManager().fileExists(atPath: filePath) else { return nil } 53 | let fileURL: NSURL = .init(fileURLWithPath: filePath) 54 | let attributes = try! fileURL.resourceValues(forKeys: [URLResourceKey.contentModificationDateKey, URLResourceKey.nameKey]) 55 | let modificationDate = attributes[URLResourceKey.contentModificationDateKey] as! NSDate 56 | return modificationDate 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/color/ColorTypes.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | class ColorTypes { 4 | /** 5 | * Returns a color in hex 6 | * - Fixme: ⚠️️ Sort alphabetically 7 | * - Fixme: ⚠️️ you dont need the break in swift only on the default 8 | */ 9 | class func color(_ colorType: String) -> UInt? { 10 | var color: UInt 11 | switch colorType { 12 | case "blue": 13 | color = Colors.BLUE 14 | case "fuchsia": 15 | color = Colors.FUCHSIA 16 | case "black": 17 | color = Colors.BLACK 18 | case "white": 19 | color = Colors.WHITE 20 | case "gray": 21 | color = Colors.GRAY 22 | case "silver": 23 | color = Colors.SILVER 24 | case "maroon": 25 | color = Colors.MAROON 26 | case "red": 27 | color = Colors.RED 28 | case "orange": 29 | color = Colors.ORANGE 30 | case "yellow": 31 | color = Colors.YELLOW 32 | case "olive": 33 | color = Colors.OLIVE 34 | case "green": 35 | color = Colors.GREEN 36 | case "teal": 37 | color = Colors.TEAL 38 | case "lime": 39 | color = Colors.LIME 40 | case "aqua": 41 | color = Colors.AQUA 42 | case "navy": 43 | color = Colors.NAVY 44 | case "purple": 45 | color = Colors.PURPLE 46 | case "pink": 47 | color = Colors.PINK 48 | case "grey": 49 | color = Colors.GREY 50 | case "grey1": 51 | color = Colors.GREY_1 52 | case "grey2": 53 | color = Colors.GREY_2 54 | case "grey3": 55 | color = Colors.GREY_3 56 | case "grey4": 57 | color = Colors.GREY_4 58 | case "grey5": 59 | color = Colors.GREY_5 60 | case "grey6": 61 | color = Colors.GREY_6 62 | case "grey7": 63 | color = Colors.GREY_7 64 | case "grey8": 65 | color = Colors.GREY_8 66 | case "grey9": 67 | color = Colors.GREY_9 68 | case "white1": 69 | color = Colors.WHITE_1 70 | case "white2": 71 | color = Colors.WHITE_2 72 | case "white3": 73 | color = Colors.WHITE_3 74 | case "white4": 75 | color = Colors.WHITE_4 76 | case "white5": 77 | color = Colors.WHITE_5 78 | case "white6": 79 | color = Colors.WHITE_6 80 | case "white7": 81 | color = Colors.WHITE_7 82 | case "white8": 83 | color = Colors.WHITE_8 84 | case "white9": 85 | color = Colors.WHITE_9 86 | default: 87 | return nil 88 | } 89 | return color 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ThemePark 2 | ![mit](https://img.shields.io/badge/License-MIT-brightgreen.svg) 3 | ![platform](https://img.shields.io/badge/Platform-iOS/macOS-blue.svg) 4 | ![Lang](https://img.shields.io/badge/Language-Swift%205.0-orange.svg) 5 | [![SPM](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/apple/swift) 6 | [![SwiftLint Sindre](https://img.shields.io/badge/SwiftLint-Sindre-hotpink.svg)](https://github.com/sindresorhus/swiftlint-sindre) 7 | [![codebeat badge](https://codebeat.co/badges/947d25d2-2794-4a19-a25c-95f0d501e2e7)](https://codebeat.co/projects/github-com-eonist-themepark-master) 8 | ![Swift](https://github.com/eonist/ThemePark/workflows/Swift/badge.svg) 9 | 10 | img 11 | 12 | ### What is it 13 | Theme library for iOS & Mac 14 | 15 | ### How does it work 16 | - Watches for changes 💥 17 | - Live theme updates while the app is running 👌 18 | - Traverses the entire UIView hierarchy with one call 🤯 19 | - Animated transitions 🎬 20 | - Small foot-print 🗜 21 | - Store styles in json or struct 22 | 23 | ### How do I get it 24 | - SPM `"github.com/eonist/ThemePark"` branch: `"master"` 25 | - Manual Open `.xcodeproj` 26 | 27 | ### Topology: 28 | . 29 | ├── assets.bundle # .json theme files 30 | ├── theme # Customize your theme structure 31 | ├── ThemePark # iOS app code 32 | ├── ThemePark-example # macOS app code 33 | └── src # Core-src 34 | ├── common # Util-Extensions 35 | └── core # Core code 36 | ├── decode # Decode JSON to Color and Font 37 | ├── util # Apply theme to components 38 | └── themeable # Components that are themeable 39 | 40 | ### Examples: 41 | 42 | **Change theme live / dynamically in the app** 43 | ```swift 44 | @IBAction private func onSwitchChange(_ sender: UISwitch) { 45 | CustomTheme.currentType = sender.isOn ? CustomTheme.ThemeType.dark.rawValue : CustomTheme.ThemeType.light.rawValue 46 | CustomTheme.theme = CustomTheme.getTheme(theme: CustomTheme.currentType) 47 | ThemeUtil.transition(self) 48 | } 49 | } 50 | ``` 51 | 52 | **Add theme in controller** 53 | ```swift 54 | class Main: UITableViewController { 55 | override func viewDidLayoutSubviews() { 56 | super.viewDidLayoutSubviews() 57 | ThemeUtil.apply(self) 58 | } 59 | } 60 | ``` 61 | 62 | **Hot load theme / see your theme changes be applied live** 63 | ```swift 64 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 65 | // Set the customTheme, before components ask Theme for styling 66 | CustomTheme.setTheme(themeType: CustomTheme.ThemeType.light.rawValue) // set init theme 67 | // Watches for changes, super useful for testing styling by just changing the json doc 68 | FileWatcher(Bundle.main.resourcePath!+"/assets.bundle/dark.json") { 69 | Swift.print("the file was modified") 70 | if let controller = UIApplication.shared.topMostViewController() { 71 | CustomTheme.theme = CustomTheme.getTheme(theme: CustomTheme.currentType)//update the theme 72 | ThemeUtil.apply(controller) 73 | } 74 | }.start() 75 | return true 76 | } 77 | ``` 78 | 79 | ### Todo: 80 | - Clean up the code ✅ 81 | - Add OliverAtkinsons (from swift-lang) nifty JSON Transformer trick: [http://eon.codes/blog/2018/04/12/advance-json-parsing-pt1/](http://eon.codes/blog/2018/04/12/advance-json-parsing-pt1/) 👊 ✅ 82 | - Add json and file deps 83 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/xcshareddata/xcschemes/ThemeTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 64 | 70 | 71 | 72 | 73 | 79 | 81 | 87 | 88 | 89 | 90 | 92 | 93 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | whitelist_rules: 2 | - anyobject_protocol 3 | - array_init 4 | #- attributes 5 | - block_based_kvo 6 | - class_delegate_protocol 7 | - closing_brace 8 | - closure_end_indentation 9 | - closure_parameter_position 10 | - closure_spacing 11 | - collection_alignment 12 | - colon 13 | - comma 14 | - compiler_protocol_init 15 | # - conditional_returns_on_newline 16 | - contains_over_first_not_nil 17 | - control_statement 18 | - deployment_target 19 | - discarded_notification_center_observer 20 | - discouraged_direct_init 21 | - discouraged_object_literal 22 | - discouraged_optional_boolean 23 | # - discouraged_optional_collection 24 | - duplicate_imports 25 | - dynamic_inline 26 | - empty_count 27 | - empty_enum_arguments 28 | - empty_parameters 29 | - empty_parentheses_with_trailing_closure 30 | - empty_string 31 | - empty_xctest_method 32 | - explicit_init 33 | - fallthrough 34 | - fatal_error_message 35 | - first_where 36 | - for_where 37 | - generic_type_name 38 | - identical_operands 39 | - identifier_name 40 | - implicit_getter 41 | - implicit_return 42 | - inert_defer 43 | - is_disjoint 44 | - joined_default_parameter 45 | - last_where 46 | - leading_whitespace 47 | - legacy_cggeometry_functions 48 | - legacy_constant 49 | - legacy_constructor 50 | - legacy_hashing 51 | - legacy_nsgeometry_functions 52 | - legacy_random 53 | - literal_expression_end_indentation 54 | - lower_acl_than_parent 55 | - mark 56 | - modifier_order 57 | - multiline_arguments 58 | - multiline_function_chains 59 | - multiline_literal_brackets 60 | - multiline_parameters 61 | - multiline_parameters_brackets 62 | - multiple_closures_with_trailing_closure 63 | - nimble_operator 64 | - no_extension_access_modifier 65 | - no_fallthrough_only 66 | - notification_center_detachment 67 | - number_separator 68 | - object_literal 69 | - opening_brace 70 | - operator_usage_whitespace 71 | - operator_whitespace 72 | - overridden_super_call 73 | - pattern_matching_keywords 74 | - private_action 75 | # - private_outlet 76 | - private_unit_test 77 | - prohibited_super_call 78 | - protocol_property_accessors_order 79 | - redundant_discardable_let 80 | - redundant_nil_coalescing 81 | - redundant_objc_attribute 82 | - redundant_optional_initialization 83 | - redundant_set_access_control 84 | - redundant_string_enum_value 85 | - redundant_type_annotation 86 | - redundant_void_return 87 | - required_enum_case 88 | - return_arrow_whitespace 89 | - shorthand_operator 90 | - sorted_first_last 91 | # - statement_position 92 | - static_operator 93 | # - strong_iboutlet 94 | - superfluous_disable_command 95 | - switch_case_alignment 96 | # - switch_case_on_newline 97 | - syntactic_sugar 98 | - todo 99 | - toggle_bool 100 | - trailing_closure 101 | - trailing_comma 102 | - trailing_newline 103 | - trailing_semicolon 104 | - trailing_whitespace 105 | - type_name 106 | # - unavailable_function 107 | - unneeded_break_in_switch 108 | - unneeded_parentheses_in_closure_argument 109 | - untyped_error_in_catch 110 | - unused_closure_parameter 111 | - unused_control_flow_label 112 | - unused_enumerated 113 | - unused_optional_binding 114 | - unused_setter_value 115 | - valid_ibinspectable 116 | - vertical_parameter_alignment 117 | - vertical_parameter_alignment_on_call 118 | - vertical_whitespace_closing_braces 119 | - vertical_whitespace_opening_braces 120 | - void_return 121 | - weak_computed_property 122 | - weak_delegate 123 | - xct_specific_matcher 124 | - xctfail_message 125 | - yoda_condition 126 | analyzer_rules: 127 | - unused_import 128 | - unused_private_declaration 129 | force_cast: warning 130 | force_unwrapping: warning 131 | number_separator: 132 | minimum_length: 5 133 | object_literal: 134 | image_literal: false 135 | discouraged_object_literal: 136 | color_literal: false 137 | identifier_name: 138 | max_length: 139 | warning: 100 140 | error: 100 141 | min_length: 142 | warning: 1 143 | error: 1 144 | validates_start_with_lowercase: false 145 | allowed_symbols: 146 | - '_' 147 | excluded: 148 | - 'x' 149 | - 'y' 150 | - 'a' 151 | - 'b' 152 | - 'x1' 153 | - 'x2' 154 | - 'y1' 155 | - 'y2' 156 | macOS_deployment_target: '10.12' 157 | -------------------------------------------------------------------------------- /Sources/ThemePark/common/color/Colors.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Fixme: ⚠️️ WHITE1,WHITE2, BLACK2, BLACK3 etc 4 | * Fixme: ⚠️️ add CYAN,MAGENTA,KEY,YELLOW CMYK 5 | * Fixme: ⚠️️ make these consts lowercase 6 | */ 7 | class Colors { 8 | static var GREY_1: UInt = 0x111111/*near black*/ 9 | static var GREY_2: UInt = 0x222222 10 | static var GREY_3: UInt = 0x333333 11 | static var GREY_4: UInt = 0x444444 12 | static var GREY_5: UInt = 0x555555// : Fixme: rename to GREY5 13 | static var GREY_6: UInt = 0x666666 14 | static var GREY_7: UInt = 0x777777 15 | static var GREY_8: UInt = 0x888888 16 | static var GREY_9: UInt = 0x999999/*ligther grey*/ 17 | static var WHITE_1: UInt = 0xf9f9f9/*near white*/ 18 | static var WHITE_2: UInt = 0xf3f3f3 19 | static var WHITE_3: UInt = 0xfafafa 20 | static var WHITE_4: UInt = 0xf6f6f6 21 | static var WHITE_5: UInt = 0xe6e6e6 22 | static var WHITE_6: UInt = 0xeeeeee 23 | static var WHITE_7: UInt = 0xe8e8e8 24 | static var WHITE_8: UInt = 0xe2e2e2 25 | static var WHITE_9: UInt = 0xE4E4E4/*ligth grey*/ 26 | static var ALICEBLUE: UInt = 0xF0F8FF 27 | static var ANTIQUEWHITE: UInt = 0xFAEBD7 28 | static var AQUA: UInt = 0x00FFFF 29 | static var AQUAMARINE: UInt = 0x7FFFD4 30 | static var AZURE: UInt = 0xF0FFFF 31 | static var BEIGE: UInt = 0xF5F5DC 32 | static var BISQUE: UInt = 0xFFE4C4 33 | static var BLACK: UInt = 0x000000 34 | static var BLANCHEDALMOND: UInt = 0xFFEBCD 35 | static var BLUE: UInt = 0x0000FF 36 | static var BLUEVIOLET: UInt = 0x8A2BE2 37 | static var BROWN: UInt = 0xA52A2A 38 | static var BURLYWOOD: UInt = 0xDEB887 39 | static var CADETBLUE: UInt = 0x5F9EA0 40 | static var CHARTREUSE: UInt = 0x7FFF00 41 | static var CHOCOLATE: UInt = 0xD2691E 42 | static var CORAL: UInt = 0xFF7F50 43 | static var CORNFLOWERBLUE: UInt = 0x6495ED 44 | static var CORNSILK: UInt = 0xFFF8DC 45 | static var CRIMSON: UInt = 0xDC143C 46 | static var CYAN: UInt = 0x00FFFF 47 | static var DARKBLUE: UInt = 0x00008B 48 | static var DARKCYAN: UInt = 0x008B8B 49 | static var DARKGOLDENROD: UInt = 0xB8860B 50 | static var DARKGRAY: UInt = 0xA9A9A9 51 | static var DARKGREY: UInt = 0xA9A9A9 52 | static var DARKGREEN: UInt = 0x006400 53 | static var DARKKHAKI: UInt = 0xBDB76B 54 | static var DARKMAGENTA: UInt = 0x8B008B 55 | static var DARKOLIVEGREEN: UInt = 0x556B2F 56 | static var DARKORANGE: UInt = 0xFF8C00 57 | static var DARKORCHID: UInt = 0x9932CC 58 | static var DARKRED: UInt = 0x8B0000 59 | static var DARKSALMON: UInt = 0xE9967A 60 | static var DARKSEAGREEN: UInt = 0x8FBC8F 61 | static var DARKSLATEBLUE: UInt = 0x483D8B 62 | static var DARKSLATEGRAY: UInt = 0x2F4F4F 63 | static var DARKSLATEGREY: UInt = 0x2F4F4F 64 | static var DARKTURQUOISE: UInt = 0x00CED1 65 | static var DARKVIOLET: UInt = 0x9400D3 66 | static var DEEPPINK: UInt = 0xFF1493 67 | static var DEEPSKYBLUE: UInt = 0x00BFFF 68 | static var DIMGRAY: UInt = 0x696969 69 | static var DIMGREY: UInt = 0x696969 70 | static var DODGERBLUE: UInt = 0x1E90FF 71 | static var FIREBRICK: UInt = 0xB22222 72 | static var FLORALWHITE: UInt = 0xFFFAF0 73 | static var FORESTGREEN: UInt = 0x228B22 74 | static var FUCHSIA: UInt = 0xFF00FF 75 | static var GAINSBORO: UInt = 0xDCDCDC 76 | static var GHOSTWHITE: UInt = 0xF8F8FF 77 | static var GOLD: UInt = 0xFFD700 78 | static var GOLDENROD: UInt = 0xDAA520 79 | static var GRAY: UInt = 0x808080 80 | static var GREY: UInt = 0x808080 81 | static var GREEN: UInt = 0x008000 82 | static var GREENYELLOW: UInt = 0xADFF2F 83 | static var HONEYDEW: UInt = 0xF0FFF0 84 | static var HOTPINK: UInt = 0xFF69B4 85 | static var INDIANRED: UInt = 0xCD5C5C 86 | static var INDIGO: UInt = 0x4B0082 87 | static var IVORY: UInt = 0xFFFFF0 88 | static var KHAKI: UInt = 0xF0E68C 89 | static var LAVENDER: UInt = 0xE6E6FA 90 | static var LAVENDERBLUSH: UInt = 0xFFF0F5 91 | static var LAWNGREEN: UInt = 0x7CFC00 92 | static var LEMONCHIFFON: UInt = 0xFFFACD 93 | static var LIGHTBLUE: UInt = 0xADD8E6 94 | static var LIGHTCORAL: UInt = 0xF08080 95 | static var LIGHTCYAN: UInt = 0xE0FFFF 96 | static var LIGHTGOLDENRODYELLOW: UInt = 0xFAFAD2 97 | static var LIGHTGRAY: UInt = 0xD3D3D3 98 | static var LIGHTGREY: UInt = 0xD3D3D3 99 | static var LIGHTGREEN: UInt = 0x90EE90 100 | static var LIGHTPINK: UInt = 0xFFB6C1 101 | static var LIGHTSALMON: UInt = 0xFFA07A 102 | static var LIGHTSEAGREEN: UInt = 0x20B2AA 103 | static var LIGHTSKYBLUE: UInt = 0x87CEFA 104 | static var LIGHTSLATEGRAY: UInt = 0x778899 105 | static var LIGHTSLATEGREY: UInt = 0x778899 106 | static var LIGHTSTEELBLUE: UInt = 0xB0C4DE 107 | static var LIGHTYELLOW: UInt = 0xFFFFE0 108 | static var LIME: UInt = 0x00FF00 109 | static var LIMEGREEN: UInt = 0x32CD32 110 | static var LINEN: UInt = 0xFAF0E6 111 | static var MAGENTA: UInt = 0xFF00FF 112 | static var MAROON: UInt = 0x800000 113 | static var MEDIUMAQUAMARINE: UInt = 0x66CDAA 114 | static var MEDIUMBLUE: UInt = 0x0000CD 115 | static var MEDIUMORCHID: UInt = 0xBA55D3 116 | static var MEDIUMPURPLE: UInt = 0x9370D8 117 | static var MEDIUMSEAGREEN: UInt = 0x3CB371 118 | static var MEDIUMSLATEBLUE: UInt = 0x7B68EE 119 | static var MEDIUMSPRINGGREEN: UInt = 0x00FA9A 120 | static var MEDIUMTURQUOISE: UInt = 0x48D1CC 121 | static var MEDIUMVIOLETRED: UInt = 0xC71585 122 | static var MIDNIGHTBLUE: UInt = 0x191970 123 | static var MINTCREAM: UInt = 0xF5FFFA 124 | static var MISTYROSE: UInt = 0xFFE4E1 125 | static var MOCCASIN: UInt = 0xFFE4B5 126 | static var NAVAJOWHITE: UInt = 0xFFDEAD 127 | static var NAVY: UInt = 0x000080 128 | static var OLDLACE: UInt = 0xFDF5E6 129 | static var OLIVE: UInt = 0x808000 130 | static var OLIVEDRAB: UInt = 0x6B8E23 131 | static var ORANGE: UInt = 0xFFA500 132 | static var ORANGERED: UInt = 0xFF4500 133 | static var ORCHID: UInt = 0xDA70D6 134 | static var PALEGOLDENROD: UInt = 0xEEE8AA 135 | static var PALEGREEN: UInt = 0x98FB98 136 | static var PALETURQUOISE: UInt = 0xAFEEEE 137 | static var PALEVIOLETRED: UInt = 0xD87093 138 | static var PAPAYAWHIP: UInt = 0xFFEFD5 139 | static var PEACHPUFF: UInt = 0xFFDAB9 140 | static var PERU: UInt = 0xCD853F 141 | static var PINK: UInt = 0xFFC0CB 142 | static var PLUM: UInt = 0xDDA0DD 143 | static var POWDERBLUE: UInt = 0xB0E0E6 144 | static var PURPLE: UInt = 0x800080 145 | static var RED: UInt = 0xFF0000 146 | static var ROSYBROWN: UInt = 0xBC8F8F 147 | static var ROYALBLUE: UInt = 0x4169E1 148 | static var SADDLEBROWN: UInt = 0x8B4513 149 | static var SALMON: UInt = 0xFA8072 150 | static var SANDYBROWN: UInt = 0xF4A460 151 | static var SEAGREEN: UInt = 0x2E8B57 152 | static var SEASHELL: UInt = 0xFFF5EE 153 | static var SIENNA: UInt = 0xA0522D 154 | static var SILVER: UInt = 0xC0C0C0 155 | static var SKYBLUE: UInt = 0x87CEEB 156 | static var SLATEBLUE: UInt = 0x6A5ACD 157 | static var SLATEGRAY: UInt = 0x708090 158 | static var SLATEGREY: UInt = 0x708090 159 | static var SNOW: UInt = 0xFFFAFA 160 | static var SPRINGGREEN: UInt = 0x00FF7F 161 | static var STEELBLUE: UInt = 0x4682B4 162 | static var TAN: UInt = 0xD2B48C 163 | static var TEAL: UInt = 0x008080 164 | static var THISTLE: UInt = 0xD8BFD8 165 | static var TOMATO: UInt = 0xFF6347 166 | static var TURQUOISE: UInt = 0x40E0D0 167 | static var VIOLET: UInt = 0xEE82EE 168 | static var WHEAT: UInt = 0xF5DEB3 169 | static var WHITE: UInt = 0xFFFFFF 170 | static var WHITESMOKE: UInt = 0xF5F5F5 171 | static var YELLOW: UInt = 0xFFFF00 172 | static var YELLOWGREEN: UInt = 0x9ACD3 173 | /*Trivia*/ 174 | static var BAUHAUS_COLOR_1: UInt = 0x18346E 175 | static var BAUHAUS_COLOR_2: UInt = 0x191919 176 | static var BAUHAUS_COLOR_3: UInt = 0xCAA72A 177 | static var BAUHAUS_COLOR_4: UInt = 0x84251C 178 | static var BAUHAUS_COLOR_5: UInt = 0xE1E1E1 179 | static var BAUHAUS_COLOR_S: [UInt] = [BAUHAUS_COLOR_1, BAUHAUS_COLOR_2, BAUHAUS_COLOR_3, BAUHAUS_COLOR_4, BAUHAUS_COLOR_5] 180 | } 181 | /*FANCY IOS Colors - hex colors: */ 182 | extension Colors { 183 | static func red() -> UInt { return 0xFF3B30 } 184 | static func orange() -> UInt { return 0xFF9500 } 185 | static func yellow() -> UInt { return 0xFFCC00 } 186 | static func green() -> UInt { return 0x4CD964 } 187 | static func lightBlue() -> UInt { return 0x34AADC } 188 | static func darkBlue() -> UInt { return 0x007AFF } 189 | static func purple() -> UInt { return 0x5856D6 } 190 | static func pink() -> UInt { return 0xFF2D55 } 191 | static func darkGray() -> UInt { return 0x8E8E93 } 192 | static func lightGray() -> UInt { return 0xC7C7CC } 193 | /*iOS colors*/ 194 | static func paleBlue() -> UInt { return 0xD1EEFC } 195 | static func paleGreen() -> UInt { return 0xE0F8D8 } 196 | static func lightPink() -> UInt { return 0xFF4981 } 197 | static func palePink() -> UInt { return 0xFFD3E0 } 198 | static func paleGray() -> UInt { return 0xF7F7F7 } 199 | static func orangeRed() -> UInt { return 0xFF1300 } 200 | static func redOrange() -> UInt { return 0xFF3A2D } 201 | static func lightBlack() -> UInt { return 0x1F1F21 } 202 | static func gray() -> UInt { return 0xBDBEC2 } 203 | } 204 | /*FANCY IOS Colors - NSColor: */ 205 | //extension Colors { 206 | // static func red() -> NSColor { return NSColorParser.nsColor(Colors.red())} 207 | // static func orange() -> NSColor { return NSColorParser.nsColor(Colors.orange())} 208 | // static func yellow() -> NSColor { return NSColorParser.nsColor(Colors.yellow())} 209 | // static func green() -> NSColor { return NSColorParser.nsColor(Colors.green())} 210 | // static func lightBlue() -> NSColor { return NSColorParser.nsColor(Colors.lightBlue())} 211 | // static func darkBlue() -> NSColor { return NSColorParser.nsColor(Colors.darkBlue())} 212 | // static func purple() -> NSColor { return NSColorParser.nsColor(Colors.purple())} 213 | // static func pink() -> NSColor { return NSColorParser.nsColor(Colors.pink())} 214 | // static func darkGray() -> NSColor { return NSColorParser.nsColor(Colors.darkGray())} 215 | // static func lightGray() -> NSColor { return NSColorParser.nsColor(Colors.lightGray())} 216 | // 217 | // static func fancyColors() -> Array<(name: String,color: NSColor)> { return [("red",red()),("orange",orange()),("yellow",yellow()),("green",green()),("lightBlue",lightBlue()),("darkBlue",darkBlue()),("purple",purple()),("pink",pink()),("darkGray",darkGray()),("lightGray",lightGray())]}//,,, 218 | //} 219 | -------------------------------------------------------------------------------- /ThemeTest/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | -------------------------------------------------------------------------------- /ThemePark-example-macOS/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | Default 538 | 539 | 540 | 541 | 542 | 543 | 544 | Left to Right 545 | 546 | 547 | 548 | 549 | 550 | 551 | Right to Left 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | Default 563 | 564 | 565 | 566 | 567 | 568 | 569 | Left to Right 570 | 571 | 572 | 573 | 574 | 575 | 576 | Right to Left 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | -------------------------------------------------------------------------------- /ThemeTest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F11ADDF5223571B30024F9C7 /* CustomTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDE12235544B0024F9C7 /* CustomTheme.swift */; }; 11 | F11ADDF6223571B30024F9C7 /* ThemeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDCA22352D1D0024F9C7 /* ThemeData.swift */; }; 12 | F11ADDF7223571B30024F9C7 /* ThemeColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDCB22352D1D0024F9C7 /* ThemeColor.swift */; }; 13 | F11ADDF8223571B30024F9C7 /* ThemeFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDD222352D600024F9C7 /* ThemeFont.swift */; }; 14 | F11ADDF9223571B30024F9C7 /* ThemeFontColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDCC22352D1D0024F9C7 /* ThemeFontColor.swift */; }; 15 | F11ADDFA223571B30024F9C7 /* Theme+Styles-DEPRECATED.swift in Sources */ = {isa = PBXBuildFile; fileRef = F178DE1E205E8E2C001FD75E /* Theme+Styles-DEPRECATED.swift */; }; 16 | F11ADE23223672360024F9C7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADE22223672360024F9C7 /* AppDelegate.swift */; }; 17 | F11ADE252236723A0024F9C7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F11ADE242236723A0024F9C7 /* Assets.xcassets */; }; 18 | F11ADE282236723A0024F9C7 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F11ADE262236723A0024F9C7 /* MainMenu.xib */; }; 19 | F11ADE2E223672A50024F9C7 /* CustomTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDE12235544B0024F9C7 /* CustomTheme.swift */; }; 20 | F11ADE2F223672A50024F9C7 /* ThemeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDCA22352D1D0024F9C7 /* ThemeData.swift */; }; 21 | F11ADE30223672A50024F9C7 /* ThemeColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDCB22352D1D0024F9C7 /* ThemeColor.swift */; }; 22 | F11ADE31223672A50024F9C7 /* ThemeFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDD222352D600024F9C7 /* ThemeFont.swift */; }; 23 | F11ADE32223672A50024F9C7 /* ThemeFontColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDCC22352D1D0024F9C7 /* ThemeFontColor.swift */; }; 24 | F11ADE33223672AB0024F9C7 /* Theme+Styles-DEPRECATED.swift in Sources */ = {isa = PBXBuildFile; fileRef = F178DE1E205E8E2C001FD75E /* Theme+Styles-DEPRECATED.swift */; }; 25 | F11ADE37223675FB0024F9C7 /* assets.bundle in Resources */ = {isa = PBXBuildFile; fileRef = F11ADE342236733B0024F9C7 /* assets.bundle */; }; 26 | F11ADE38223676040024F9C7 /* assets.bundle in Resources */ = {isa = PBXBuildFile; fileRef = F11ADE342236733B0024F9C7 /* assets.bundle */; }; 27 | F12BA144205D2BDA006C1D56 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12BA143205D2BDA006C1D56 /* AppDelegate.swift */; }; 28 | F12BA149205D2BDA006C1D56 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F12BA147205D2BDA006C1D56 /* Main.storyboard */; }; 29 | F12BA14B205D2BDA006C1D56 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F12BA14A205D2BDA006C1D56 /* Assets.xcassets */; }; 30 | F12BA14E205D2BDA006C1D56 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F12BA14C205D2BDA006C1D56 /* LaunchScreen.storyboard */; }; 31 | F1354F4023AA55E9002BBF3C /* ThemeParkIOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1354F3F23AA55E9002BBF3C /* ThemeParkIOSTests.swift */; }; 32 | F178DE1D205E878B001FD75E /* Main.swift in Sources */ = {isa = PBXBuildFile; fileRef = F178DE1C205E878B001FD75E /* Main.swift */; }; 33 | F178DE21205EB232001FD75E /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F178DE20205EB232001FD75E /* Settings.swift */; }; 34 | F1E6455823940199008D2ABE /* ColorUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5AA206134690088CC57 /* ColorUtil.swift */; }; 35 | F1E6455923940199008D2ABE /* ColorTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5AD206136CD0088CC57 /* ColorTypes.swift */; }; 36 | F1E6455A23940199008D2ABE /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5AE206136CD0088CC57 /* Colors.swift */; }; 37 | F1E6455B23940199008D2ABE /* DecodingHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDC822352D1D0024F9C7 /* DecodingHelpers.swift */; }; 38 | F1E6455C23940199008D2ABE /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD4E223470800024F9C7 /* Data+Extension.swift */; }; 39 | F1E6455D23940199008D2ABE /* JSONUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5A6206122520088CC57 /* JSONUtil.swift */; }; 40 | F1E6455E23940199008D2ABE /* FileParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD502234709F0024F9C7 /* FileParser.swift */; }; 41 | F1E6455F23940199008D2ABE /* FileWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F114C2CE2062961D00C21A3D /* FileWatcher.swift */; }; 42 | F1E6456023940199008D2ABE /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD5C2235118E0024F9C7 /* View+Extension.swift */; }; 43 | F1E6456123940199008D2ABE /* VC+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD60223514380024F9C7 /* VC+Extension.swift */; }; 44 | F1E6456223940199008D2ABE /* Hybrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDD522353F290024F9C7 /* Hybrid.swift */; }; 45 | F1E6456323940199008D2ABE /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD5E2235128E0024F9C7 /* Theme.swift */; }; 46 | F1E6456423940199008D2ABE /* ThemeKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDE32235675C0024F9C7 /* ThemeKind.swift */; }; 47 | F1E6456523940199008D2ABE /* DecodingTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDC722352D1D0024F9C7 /* DecodingTypes.swift */; }; 48 | F1E6456623940199008D2ABE /* ThemeDataKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDD8223540C60024F9C7 /* ThemeDataKind.swift */; }; 49 | F1E6456723940199008D2ABE /* ThemeFontColorKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDDF223553740024F9C7 /* ThemeFontColorKind.swift */; }; 50 | F1E6456823940199008D2ABE /* ThemeColorKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDDA22354FE40024F9C7 /* ThemeColorKind.swift */; }; 51 | F1E6456923940199008D2ABE /* ThemeFontKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDDD2235530B0024F9C7 /* ThemeFontKind.swift */; }; 52 | F1E6456A23940199008D2ABE /* ThemeUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12BA158205D30A1006C1D56 /* ThemeUtil.swift */; }; 53 | F1E6456B23940199008D2ABE /* ThemeUtil+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDE522356ECE0024F9C7 /* ThemeUtil+Animation.swift */; }; 54 | F1E6456C23940199008D2ABE /* Themeable+NSVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADE5C2236B5500024F9C7 /* Themeable+NSVC.swift */; }; 55 | F1E6456D23940199008D2ABE /* Themeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD5A2235113B0024F9C7 /* Themeable.swift */; }; 56 | F1E6456E23940199008D2ABE /* Themeable +UITVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD7C223516870024F9C7 /* Themeable +UITVC.swift */; }; 57 | F1E6456F23940199008D2ABE /* Themeable+UIVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADE5F2236B71E0024F9C7 /* Themeable+UIVC.swift */; }; 58 | F1E6457023940199008D2ABE /* Themeable +UITabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD7F223518700024F9C7 /* Themeable +UITabBar.swift */; }; 59 | F1E6457123940199008D2ABE /* Themeable +UINavBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD812235189F0024F9C7 /* Themeable +UINavBar.swift */; }; 60 | F1E6457223940199008D2ABE /* Themeable+UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD6C223515A50024F9C7 /* Themeable+UIButton.swift */; }; 61 | F1E6457323940199008D2ABE /* Themeable+UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD6E223515C00024F9C7 /* Themeable+UILabel.swift */; }; 62 | F1E6457423940199008D2ABE /* Themeable+UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD70223515D20024F9C7 /* Themeable+UITableViewCell.swift */; }; 63 | F1E6457523940199008D2ABE /* Themeable+UISwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD72223515DD0024F9C7 /* Themeable+UISwitch.swift */; }; 64 | F1E6457623940199008D2ABE /* Themeable+UISegmentedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD74223515E90024F9C7 /* Themeable+UISegmentedControl.swift */; }; 65 | F1E6457723940199008D2ABE /* Themeable+UISlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD76223515FB0024F9C7 /* Themeable+UISlider.swift */; }; 66 | F1E6457823940199008D2ABE /* Themeable+UIStepper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD782235160F0024F9C7 /* Themeable+UIStepper.swift */; }; 67 | F1E6457923940199008D2ABE /* Themeable+UITextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD7A2235161B0024F9C7 /* Themeable+UITextField.swift */; }; 68 | F1E6457A2394019A008D2ABE /* ColorUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5AA206134690088CC57 /* ColorUtil.swift */; }; 69 | F1E6457B2394019A008D2ABE /* ColorTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5AD206136CD0088CC57 /* ColorTypes.swift */; }; 70 | F1E6457C2394019A008D2ABE /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5AE206136CD0088CC57 /* Colors.swift */; }; 71 | F1E6457D2394019A008D2ABE /* DecodingHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDC822352D1D0024F9C7 /* DecodingHelpers.swift */; }; 72 | F1E6457E2394019A008D2ABE /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD4E223470800024F9C7 /* Data+Extension.swift */; }; 73 | F1E6457F2394019A008D2ABE /* JSONUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120F5A6206122520088CC57 /* JSONUtil.swift */; }; 74 | F1E645802394019A008D2ABE /* FileParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD502234709F0024F9C7 /* FileParser.swift */; }; 75 | F1E645812394019A008D2ABE /* FileWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F114C2CE2062961D00C21A3D /* FileWatcher.swift */; }; 76 | F1E645822394019A008D2ABE /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD5C2235118E0024F9C7 /* View+Extension.swift */; }; 77 | F1E645832394019A008D2ABE /* VC+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD60223514380024F9C7 /* VC+Extension.swift */; }; 78 | F1E645842394019A008D2ABE /* Hybrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDD522353F290024F9C7 /* Hybrid.swift */; }; 79 | F1E645852394019A008D2ABE /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD5E2235128E0024F9C7 /* Theme.swift */; }; 80 | F1E645862394019A008D2ABE /* ThemeKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDE32235675C0024F9C7 /* ThemeKind.swift */; }; 81 | F1E645872394019A008D2ABE /* DecodingTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDC722352D1D0024F9C7 /* DecodingTypes.swift */; }; 82 | F1E645882394019A008D2ABE /* ThemeDataKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDD8223540C60024F9C7 /* ThemeDataKind.swift */; }; 83 | F1E645892394019A008D2ABE /* ThemeFontColorKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDDF223553740024F9C7 /* ThemeFontColorKind.swift */; }; 84 | F1E6458A2394019A008D2ABE /* ThemeColorKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDDA22354FE40024F9C7 /* ThemeColorKind.swift */; }; 85 | F1E6458B2394019A008D2ABE /* ThemeFontKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDDD2235530B0024F9C7 /* ThemeFontKind.swift */; }; 86 | F1E6458C2394019A008D2ABE /* ThemeUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12BA158205D30A1006C1D56 /* ThemeUtil.swift */; }; 87 | F1E6458D2394019A008D2ABE /* ThemeUtil+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADDE522356ECE0024F9C7 /* ThemeUtil+Animation.swift */; }; 88 | F1E6458E2394019A008D2ABE /* Themeable+NSVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADE5C2236B5500024F9C7 /* Themeable+NSVC.swift */; }; 89 | F1E6458F2394019A008D2ABE /* Themeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD5A2235113B0024F9C7 /* Themeable.swift */; }; 90 | F1E645902394019A008D2ABE /* Themeable +UITVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD7C223516870024F9C7 /* Themeable +UITVC.swift */; }; 91 | F1E645912394019A008D2ABE /* Themeable+UIVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADE5F2236B71E0024F9C7 /* Themeable+UIVC.swift */; }; 92 | F1E645922394019A008D2ABE /* Themeable +UITabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD7F223518700024F9C7 /* Themeable +UITabBar.swift */; }; 93 | F1E645932394019A008D2ABE /* Themeable +UINavBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD812235189F0024F9C7 /* Themeable +UINavBar.swift */; }; 94 | F1E645942394019A008D2ABE /* Themeable+UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD6C223515A50024F9C7 /* Themeable+UIButton.swift */; }; 95 | F1E645952394019A008D2ABE /* Themeable+UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD6E223515C00024F9C7 /* Themeable+UILabel.swift */; }; 96 | F1E645962394019A008D2ABE /* Themeable+UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD70223515D20024F9C7 /* Themeable+UITableViewCell.swift */; }; 97 | F1E645972394019A008D2ABE /* Themeable+UISwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD72223515DD0024F9C7 /* Themeable+UISwitch.swift */; }; 98 | F1E645982394019A008D2ABE /* Themeable+UISegmentedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD74223515E90024F9C7 /* Themeable+UISegmentedControl.swift */; }; 99 | F1E645992394019A008D2ABE /* Themeable+UISlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD76223515FB0024F9C7 /* Themeable+UISlider.swift */; }; 100 | F1E6459A2394019A008D2ABE /* Themeable+UIStepper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD782235160F0024F9C7 /* Themeable+UIStepper.swift */; }; 101 | F1E6459B2394019A008D2ABE /* Themeable+UITextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11ADD7A2235161B0024F9C7 /* Themeable+UITextField.swift */; }; 102 | /* End PBXBuildFile section */ 103 | 104 | /* Begin PBXContainerItemProxy section */ 105 | F1354F4223AA55E9002BBF3C /* PBXContainerItemProxy */ = { 106 | isa = PBXContainerItemProxy; 107 | containerPortal = F12BA138205D2BDA006C1D56 /* Project object */; 108 | proxyType = 1; 109 | remoteGlobalIDString = F12BA13F205D2BDA006C1D56; 110 | remoteInfo = ThemePark; 111 | }; 112 | /* End PBXContainerItemProxy section */ 113 | 114 | /* Begin PBXCopyFilesBuildPhase section */ 115 | F114AE4721A6E06500942A28 /* Embed Frameworks */ = { 116 | isa = PBXCopyFilesBuildPhase; 117 | buildActionMask = 2147483647; 118 | dstPath = ""; 119 | dstSubfolderSpec = 10; 120 | files = ( 121 | ); 122 | name = "Embed Frameworks"; 123 | runOnlyForDeploymentPostprocessing = 0; 124 | }; 125 | /* End PBXCopyFilesBuildPhase section */ 126 | 127 | /* Begin PBXFileReference section */ 128 | F114C2CE2062961D00C21A3D /* FileWatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileWatcher.swift; sourceTree = ""; }; 129 | F11ADD4E223470800024F9C7 /* Data+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Extension.swift"; sourceTree = ""; }; 130 | F11ADD502234709F0024F9C7 /* FileParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileParser.swift; sourceTree = ""; }; 131 | F11ADD5A2235113B0024F9C7 /* Themeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Themeable.swift; sourceTree = ""; }; 132 | F11ADD5C2235118E0024F9C7 /* View+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extension.swift"; sourceTree = ""; }; 133 | F11ADD5E2235128E0024F9C7 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; 134 | F11ADD60223514380024F9C7 /* VC+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VC+Extension.swift"; sourceTree = ""; }; 135 | F11ADD6C223515A50024F9C7 /* Themeable+UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UIButton.swift"; sourceTree = ""; }; 136 | F11ADD6E223515C00024F9C7 /* Themeable+UILabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UILabel.swift"; sourceTree = ""; }; 137 | F11ADD70223515D20024F9C7 /* Themeable+UITableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UITableViewCell.swift"; sourceTree = ""; }; 138 | F11ADD72223515DD0024F9C7 /* Themeable+UISwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UISwitch.swift"; sourceTree = ""; }; 139 | F11ADD74223515E90024F9C7 /* Themeable+UISegmentedControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UISegmentedControl.swift"; sourceTree = ""; }; 140 | F11ADD76223515FB0024F9C7 /* Themeable+UISlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UISlider.swift"; sourceTree = ""; }; 141 | F11ADD782235160F0024F9C7 /* Themeable+UIStepper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UIStepper.swift"; sourceTree = ""; }; 142 | F11ADD7A2235161B0024F9C7 /* Themeable+UITextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UITextField.swift"; sourceTree = ""; }; 143 | F11ADD7C223516870024F9C7 /* Themeable +UITVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable +UITVC.swift"; sourceTree = ""; }; 144 | F11ADD7F223518700024F9C7 /* Themeable +UITabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable +UITabBar.swift"; sourceTree = ""; }; 145 | F11ADD812235189F0024F9C7 /* Themeable +UINavBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable +UINavBar.swift"; sourceTree = ""; }; 146 | F11ADDC722352D1D0024F9C7 /* DecodingTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodingTypes.swift; sourceTree = ""; }; 147 | F11ADDC822352D1D0024F9C7 /* DecodingHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodingHelpers.swift; sourceTree = ""; }; 148 | F11ADDCA22352D1D0024F9C7 /* ThemeData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeData.swift; sourceTree = ""; }; 149 | F11ADDCB22352D1D0024F9C7 /* ThemeColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeColor.swift; sourceTree = ""; }; 150 | F11ADDCC22352D1D0024F9C7 /* ThemeFontColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeFontColor.swift; sourceTree = ""; }; 151 | F11ADDD222352D600024F9C7 /* ThemeFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeFont.swift; sourceTree = ""; }; 152 | F11ADDD522353F290024F9C7 /* Hybrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hybrid.swift; sourceTree = ""; }; 153 | F11ADDD8223540C60024F9C7 /* ThemeDataKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeDataKind.swift; sourceTree = ""; }; 154 | F11ADDDA22354FE40024F9C7 /* ThemeColorKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeColorKind.swift; sourceTree = ""; }; 155 | F11ADDDD2235530B0024F9C7 /* ThemeFontKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeFontKind.swift; sourceTree = ""; }; 156 | F11ADDDF223553740024F9C7 /* ThemeFontColorKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeFontColorKind.swift; sourceTree = ""; }; 157 | F11ADDE12235544B0024F9C7 /* CustomTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTheme.swift; sourceTree = ""; }; 158 | F11ADDE32235675C0024F9C7 /* ThemeKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeKind.swift; sourceTree = ""; }; 159 | F11ADDE522356ECE0024F9C7 /* ThemeUtil+Animation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ThemeUtil+Animation.swift"; sourceTree = ""; }; 160 | F11ADE20223672360024F9C7 /* ThemePark-example-macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ThemePark-example-macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 161 | F11ADE22223672360024F9C7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 162 | F11ADE242236723A0024F9C7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 163 | F11ADE272236723A0024F9C7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 164 | F11ADE292236723A0024F9C7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 165 | F11ADE2A2236723A0024F9C7 /* ThemePark_example_macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ThemePark_example_macOS.entitlements; sourceTree = ""; }; 166 | F11ADE342236733B0024F9C7 /* assets.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = assets.bundle; sourceTree = ""; }; 167 | F11ADE5C2236B5500024F9C7 /* Themeable+NSVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+NSVC.swift"; sourceTree = ""; }; 168 | F11ADE5F2236B71E0024F9C7 /* Themeable+UIVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themeable+UIVC.swift"; sourceTree = ""; }; 169 | F120F5A6206122520088CC57 /* JSONUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONUtil.swift; sourceTree = ""; }; 170 | F120F5AA206134690088CC57 /* ColorUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorUtil.swift; sourceTree = ""; }; 171 | F120F5AD206136CD0088CC57 /* ColorTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorTypes.swift; sourceTree = ""; }; 172 | F120F5AE206136CD0088CC57 /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; }; 173 | F12BA140205D2BDA006C1D56 /* ThemePark.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ThemePark.app; sourceTree = BUILT_PRODUCTS_DIR; }; 174 | F12BA143205D2BDA006C1D56 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 175 | F12BA148205D2BDA006C1D56 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 176 | F12BA14A205D2BDA006C1D56 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 177 | F12BA14D205D2BDA006C1D56 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 178 | F12BA14F205D2BDA006C1D56 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 179 | F12BA158205D30A1006C1D56 /* ThemeUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeUtil.swift; sourceTree = ""; }; 180 | F1354F3D23AA55E9002BBF3C /* ThemeParkIOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ThemeParkIOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 181 | F1354F3F23AA55E9002BBF3C /* ThemeParkIOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeParkIOSTests.swift; sourceTree = ""; }; 182 | F1354F4123AA55E9002BBF3C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 183 | F178DE1C205E878B001FD75E /* Main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Main.swift; sourceTree = ""; }; 184 | F178DE1E205E8E2C001FD75E /* Theme+Styles-DEPRECATED.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Theme+Styles-DEPRECATED.swift"; sourceTree = ""; }; 185 | F178DE20205EB232001FD75E /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; 186 | /* End PBXFileReference section */ 187 | 188 | /* Begin PBXFrameworksBuildPhase section */ 189 | F11ADE1D223672360024F9C7 /* Frameworks */ = { 190 | isa = PBXFrameworksBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | F12BA13D205D2BDA006C1D56 /* Frameworks */ = { 197 | isa = PBXFrameworksBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | F1354F3A23AA55E9002BBF3C /* Frameworks */ = { 204 | isa = PBXFrameworksBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXFrameworksBuildPhase section */ 211 | 212 | /* Begin PBXGroup section */ 213 | F11ADD4D223470430024F9C7 /* common */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | F120F5AC206136CD0088CC57 /* color */, 217 | F11ADDD422352F280024F9C7 /* json */, 218 | F11ADD502234709F0024F9C7 /* FileParser.swift */, 219 | F114C2CE2062961D00C21A3D /* FileWatcher.swift */, 220 | F11ADD5C2235118E0024F9C7 /* View+Extension.swift */, 221 | F11ADD60223514380024F9C7 /* VC+Extension.swift */, 222 | F11ADDD522353F290024F9C7 /* Hybrid.swift */, 223 | ); 224 | path = common; 225 | sourceTree = ""; 226 | }; 227 | F11ADD57223510E50024F9C7 /* util */ = { 228 | isa = PBXGroup; 229 | children = ( 230 | F12BA158205D30A1006C1D56 /* ThemeUtil.swift */, 231 | F11ADDE522356ECE0024F9C7 /* ThemeUtil+Animation.swift */, 232 | ); 233 | path = util; 234 | sourceTree = ""; 235 | }; 236 | F11ADD58223510F30024F9C7 /* theme */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | F11ADDE12235544B0024F9C7 /* CustomTheme.swift */, 240 | F11ADDCA22352D1D0024F9C7 /* ThemeData.swift */, 241 | F11ADDCB22352D1D0024F9C7 /* ThemeColor.swift */, 242 | F11ADDD222352D600024F9C7 /* ThemeFont.swift */, 243 | F11ADDCC22352D1D0024F9C7 /* ThemeFontColor.swift */, 244 | F11ADDDC22354FFA0024F9C7 /* deprecated */, 245 | ); 246 | path = theme; 247 | sourceTree = ""; 248 | }; 249 | F11ADD6B223515810024F9C7 /* themeable */ = { 250 | isa = PBXGroup; 251 | children = ( 252 | F11ADE5B2236B5330024F9C7 /* macOS */, 253 | F11ADD5A2235113B0024F9C7 /* Themeable.swift */, 254 | F11ADDD722353F640024F9C7 /* iOS */, 255 | ); 256 | path = themeable; 257 | sourceTree = ""; 258 | }; 259 | F11ADD7E223518590024F9C7 /* vc */ = { 260 | isa = PBXGroup; 261 | children = ( 262 | F11ADD7C223516870024F9C7 /* Themeable +UITVC.swift */, 263 | F11ADE5F2236B71E0024F9C7 /* Themeable+UIVC.swift */, 264 | F11ADD7F223518700024F9C7 /* Themeable +UITabBar.swift */, 265 | F11ADD812235189F0024F9C7 /* Themeable +UINavBar.swift */, 266 | ); 267 | path = vc; 268 | sourceTree = ""; 269 | }; 270 | F11ADDAF22351E310024F9C7 /* vc */ = { 271 | isa = PBXGroup; 272 | children = ( 273 | F178DE1C205E878B001FD75E /* Main.swift */, 274 | F178DE20205EB232001FD75E /* Settings.swift */, 275 | ); 276 | path = vc; 277 | sourceTree = ""; 278 | }; 279 | F11ADDC622352D1D0024F9C7 /* transformer */ = { 280 | isa = PBXGroup; 281 | children = ( 282 | F11ADDC722352D1D0024F9C7 /* DecodingTypes.swift */, 283 | ); 284 | path = transformer; 285 | sourceTree = ""; 286 | }; 287 | F11ADDC922352D1D0024F9C7 /* decode */ = { 288 | isa = PBXGroup; 289 | children = ( 290 | F11ADDC622352D1D0024F9C7 /* transformer */, 291 | F11ADDD8223540C60024F9C7 /* ThemeDataKind.swift */, 292 | F11ADDDF223553740024F9C7 /* ThemeFontColorKind.swift */, 293 | F11ADDDA22354FE40024F9C7 /* ThemeColorKind.swift */, 294 | F11ADDDD2235530B0024F9C7 /* ThemeFontKind.swift */, 295 | ); 296 | path = decode; 297 | sourceTree = ""; 298 | }; 299 | F11ADDD422352F280024F9C7 /* json */ = { 300 | isa = PBXGroup; 301 | children = ( 302 | F11ADDC822352D1D0024F9C7 /* DecodingHelpers.swift */, 303 | F11ADD4E223470800024F9C7 /* Data+Extension.swift */, 304 | F120F5A6206122520088CC57 /* JSONUtil.swift */, 305 | ); 306 | path = json; 307 | sourceTree = ""; 308 | }; 309 | F11ADDD722353F640024F9C7 /* iOS */ = { 310 | isa = PBXGroup; 311 | children = ( 312 | F11ADD7E223518590024F9C7 /* vc */, 313 | F11ADD6C223515A50024F9C7 /* Themeable+UIButton.swift */, 314 | F11ADD6E223515C00024F9C7 /* Themeable+UILabel.swift */, 315 | F11ADD70223515D20024F9C7 /* Themeable+UITableViewCell.swift */, 316 | F11ADD72223515DD0024F9C7 /* Themeable+UISwitch.swift */, 317 | F11ADD74223515E90024F9C7 /* Themeable+UISegmentedControl.swift */, 318 | F11ADD76223515FB0024F9C7 /* Themeable+UISlider.swift */, 319 | F11ADD782235160F0024F9C7 /* Themeable+UIStepper.swift */, 320 | F11ADD7A2235161B0024F9C7 /* Themeable+UITextField.swift */, 321 | ); 322 | path = iOS; 323 | sourceTree = ""; 324 | }; 325 | F11ADDDC22354FFA0024F9C7 /* deprecated */ = { 326 | isa = PBXGroup; 327 | children = ( 328 | F178DE1E205E8E2C001FD75E /* Theme+Styles-DEPRECATED.swift */, 329 | ); 330 | path = deprecated; 331 | sourceTree = ""; 332 | }; 333 | F11ADE21223672360024F9C7 /* ThemePark-example-macOS */ = { 334 | isa = PBXGroup; 335 | children = ( 336 | F11ADE22223672360024F9C7 /* AppDelegate.swift */, 337 | F11ADE242236723A0024F9C7 /* Assets.xcassets */, 338 | F11ADE262236723A0024F9C7 /* MainMenu.xib */, 339 | F11ADE292236723A0024F9C7 /* Info.plist */, 340 | F11ADE2A2236723A0024F9C7 /* ThemePark_example_macOS.entitlements */, 341 | ); 342 | path = "ThemePark-example-macOS"; 343 | sourceTree = ""; 344 | }; 345 | F11ADE5B2236B5330024F9C7 /* macOS */ = { 346 | isa = PBXGroup; 347 | children = ( 348 | F11ADE5C2236B5500024F9C7 /* Themeable+NSVC.swift */, 349 | ); 350 | path = macOS; 351 | sourceTree = ""; 352 | }; 353 | F120F5AC206136CD0088CC57 /* color */ = { 354 | isa = PBXGroup; 355 | children = ( 356 | F120F5AA206134690088CC57 /* ColorUtil.swift */, 357 | F120F5AD206136CD0088CC57 /* ColorTypes.swift */, 358 | F120F5AE206136CD0088CC57 /* Colors.swift */, 359 | ); 360 | path = color; 361 | sourceTree = ""; 362 | }; 363 | F12BA137205D2BDA006C1D56 = { 364 | isa = PBXGroup; 365 | children = ( 366 | F1354F4723AA55EF002BBF3C /* Tests */, 367 | F11ADE342236733B0024F9C7 /* assets.bundle */, 368 | F1E645532394013D008D2ABE /* Sources */, 369 | F11ADD58223510F30024F9C7 /* theme */, 370 | F12BA142205D2BDA006C1D56 /* ThemeTest */, 371 | F11ADE21223672360024F9C7 /* ThemePark-example-macOS */, 372 | F12BA141205D2BDA006C1D56 /* Products */, 373 | ); 374 | sourceTree = ""; 375 | }; 376 | F12BA141205D2BDA006C1D56 /* Products */ = { 377 | isa = PBXGroup; 378 | children = ( 379 | F12BA140205D2BDA006C1D56 /* ThemePark.app */, 380 | F11ADE20223672360024F9C7 /* ThemePark-example-macOS.app */, 381 | F1354F3D23AA55E9002BBF3C /* ThemeParkIOSTests.xctest */, 382 | ); 383 | name = Products; 384 | sourceTree = ""; 385 | }; 386 | F12BA142205D2BDA006C1D56 /* ThemeTest */ = { 387 | isa = PBXGroup; 388 | children = ( 389 | F12BA143205D2BDA006C1D56 /* AppDelegate.swift */, 390 | F11ADDAF22351E310024F9C7 /* vc */, 391 | F12BA147205D2BDA006C1D56 /* Main.storyboard */, 392 | F12BA14A205D2BDA006C1D56 /* Assets.xcassets */, 393 | F12BA14C205D2BDA006C1D56 /* LaunchScreen.storyboard */, 394 | F12BA14F205D2BDA006C1D56 /* Info.plist */, 395 | ); 396 | path = ThemeTest; 397 | sourceTree = ""; 398 | }; 399 | F12BA155205D3085006C1D56 /* core */ = { 400 | isa = PBXGroup; 401 | children = ( 402 | F11ADD5E2235128E0024F9C7 /* Theme.swift */, 403 | F11ADDE32235675C0024F9C7 /* ThemeKind.swift */, 404 | F11ADDC922352D1D0024F9C7 /* decode */, 405 | F11ADD57223510E50024F9C7 /* util */, 406 | F11ADD6B223515810024F9C7 /* themeable */, 407 | ); 408 | path = core; 409 | sourceTree = ""; 410 | }; 411 | F1354F3E23AA55E9002BBF3C /* ThemeParkIOSTests */ = { 412 | isa = PBXGroup; 413 | children = ( 414 | F1354F3F23AA55E9002BBF3C /* ThemeParkIOSTests.swift */, 415 | F1354F4123AA55E9002BBF3C /* Info.plist */, 416 | ); 417 | path = ThemeParkIOSTests; 418 | sourceTree = ""; 419 | }; 420 | F1354F4723AA55EF002BBF3C /* Tests */ = { 421 | isa = PBXGroup; 422 | children = ( 423 | F1354F3E23AA55E9002BBF3C /* ThemeParkIOSTests */, 424 | ); 425 | path = Tests; 426 | sourceTree = ""; 427 | }; 428 | F1E645532394013D008D2ABE /* Sources */ = { 429 | isa = PBXGroup; 430 | children = ( 431 | F1E645542394013D008D2ABE /* ThemePark */, 432 | ); 433 | path = Sources; 434 | sourceTree = SOURCE_ROOT; 435 | }; 436 | F1E645542394013D008D2ABE /* ThemePark */ = { 437 | isa = PBXGroup; 438 | children = ( 439 | F11ADD4D223470430024F9C7 /* common */, 440 | F12BA155205D3085006C1D56 /* core */, 441 | ); 442 | path = ThemePark; 443 | sourceTree = ""; 444 | }; 445 | /* End PBXGroup section */ 446 | 447 | /* Begin PBXNativeTarget section */ 448 | F11ADE1F223672360024F9C7 /* ThemePark-example-macOS */ = { 449 | isa = PBXNativeTarget; 450 | buildConfigurationList = F11ADE2B2236723A0024F9C7 /* Build configuration list for PBXNativeTarget "ThemePark-example-macOS" */; 451 | buildPhases = ( 452 | F11ADE1C223672360024F9C7 /* Sources */, 453 | F11ADE1D223672360024F9C7 /* Frameworks */, 454 | F11ADE1E223672360024F9C7 /* Resources */, 455 | F1CE26722281E6E600441836 /* ShellScript */, 456 | ); 457 | buildRules = ( 458 | ); 459 | dependencies = ( 460 | ); 461 | name = "ThemePark-example-macOS"; 462 | productName = "ThemePark-example-macOS"; 463 | productReference = F11ADE20223672360024F9C7 /* ThemePark-example-macOS.app */; 464 | productType = "com.apple.product-type.application"; 465 | }; 466 | F12BA13F205D2BDA006C1D56 /* ThemePark */ = { 467 | isa = PBXNativeTarget; 468 | buildConfigurationList = F12BA152205D2BDA006C1D56 /* Build configuration list for PBXNativeTarget "ThemePark" */; 469 | buildPhases = ( 470 | F12BA13C205D2BDA006C1D56 /* Sources */, 471 | F12BA13D205D2BDA006C1D56 /* Frameworks */, 472 | F12BA13E205D2BDA006C1D56 /* Resources */, 473 | F114AE4721A6E06500942A28 /* Embed Frameworks */, 474 | F1CE266F2281E6CD00441836 /* ShellScript */, 475 | ); 476 | buildRules = ( 477 | ); 478 | dependencies = ( 479 | ); 480 | name = ThemePark; 481 | productName = ThemeTest; 482 | productReference = F12BA140205D2BDA006C1D56 /* ThemePark.app */; 483 | productType = "com.apple.product-type.application"; 484 | }; 485 | F1354F3C23AA55E9002BBF3C /* ThemeParkIOSTests */ = { 486 | isa = PBXNativeTarget; 487 | buildConfigurationList = F1354F4423AA55E9002BBF3C /* Build configuration list for PBXNativeTarget "ThemeParkIOSTests" */; 488 | buildPhases = ( 489 | F1354F3923AA55E9002BBF3C /* Sources */, 490 | F1354F3A23AA55E9002BBF3C /* Frameworks */, 491 | F1354F3B23AA55E9002BBF3C /* Resources */, 492 | ); 493 | buildRules = ( 494 | ); 495 | dependencies = ( 496 | F1354F4323AA55E9002BBF3C /* PBXTargetDependency */, 497 | ); 498 | name = ThemeParkIOSTests; 499 | productName = ThemeParkIOSTests; 500 | productReference = F1354F3D23AA55E9002BBF3C /* ThemeParkIOSTests.xctest */; 501 | productType = "com.apple.product-type.bundle.unit-test"; 502 | }; 503 | /* End PBXNativeTarget section */ 504 | 505 | /* Begin PBXProject section */ 506 | F12BA138205D2BDA006C1D56 /* Project object */ = { 507 | isa = PBXProject; 508 | attributes = { 509 | LastSwiftUpdateCheck = 1120; 510 | LastUpgradeCheck = 1010; 511 | ORGANIZATIONNAME = futurelab; 512 | TargetAttributes = { 513 | F11ADE1F223672360024F9C7 = { 514 | CreatedOnToolsVersion = 10.1; 515 | ProvisioningStyle = Automatic; 516 | }; 517 | F12BA13F205D2BDA006C1D56 = { 518 | CreatedOnToolsVersion = 9.2; 519 | LastSwiftMigration = 1010; 520 | ProvisioningStyle = Automatic; 521 | }; 522 | F1354F3C23AA55E9002BBF3C = { 523 | CreatedOnToolsVersion = 11.2; 524 | ProvisioningStyle = Automatic; 525 | TestTargetID = F12BA13F205D2BDA006C1D56; 526 | }; 527 | }; 528 | }; 529 | buildConfigurationList = F12BA13B205D2BDA006C1D56 /* Build configuration list for PBXProject "ThemeTest" */; 530 | compatibilityVersion = "Xcode 8.0"; 531 | developmentRegion = en; 532 | hasScannedForEncodings = 0; 533 | knownRegions = ( 534 | en, 535 | Base, 536 | ); 537 | mainGroup = F12BA137205D2BDA006C1D56; 538 | productRefGroup = F12BA141205D2BDA006C1D56 /* Products */; 539 | projectDirPath = ""; 540 | projectRoot = ""; 541 | targets = ( 542 | F12BA13F205D2BDA006C1D56 /* ThemePark */, 543 | F11ADE1F223672360024F9C7 /* ThemePark-example-macOS */, 544 | F1354F3C23AA55E9002BBF3C /* ThemeParkIOSTests */, 545 | ); 546 | }; 547 | /* End PBXProject section */ 548 | 549 | /* Begin PBXResourcesBuildPhase section */ 550 | F11ADE1E223672360024F9C7 /* Resources */ = { 551 | isa = PBXResourcesBuildPhase; 552 | buildActionMask = 2147483647; 553 | files = ( 554 | F11ADE252236723A0024F9C7 /* Assets.xcassets in Resources */, 555 | F11ADE282236723A0024F9C7 /* MainMenu.xib in Resources */, 556 | F11ADE37223675FB0024F9C7 /* assets.bundle in Resources */, 557 | ); 558 | runOnlyForDeploymentPostprocessing = 0; 559 | }; 560 | F12BA13E205D2BDA006C1D56 /* Resources */ = { 561 | isa = PBXResourcesBuildPhase; 562 | buildActionMask = 2147483647; 563 | files = ( 564 | F12BA14E205D2BDA006C1D56 /* LaunchScreen.storyboard in Resources */, 565 | F12BA14B205D2BDA006C1D56 /* Assets.xcassets in Resources */, 566 | F12BA149205D2BDA006C1D56 /* Main.storyboard in Resources */, 567 | F11ADE38223676040024F9C7 /* assets.bundle in Resources */, 568 | ); 569 | runOnlyForDeploymentPostprocessing = 0; 570 | }; 571 | F1354F3B23AA55E9002BBF3C /* Resources */ = { 572 | isa = PBXResourcesBuildPhase; 573 | buildActionMask = 2147483647; 574 | files = ( 575 | ); 576 | runOnlyForDeploymentPostprocessing = 0; 577 | }; 578 | /* End PBXResourcesBuildPhase section */ 579 | 580 | /* Begin PBXShellScriptBuildPhase section */ 581 | F1CE266F2281E6CD00441836 /* ShellScript */ = { 582 | isa = PBXShellScriptBuildPhase; 583 | buildActionMask = 2147483647; 584 | files = ( 585 | ); 586 | inputFileListPaths = ( 587 | ); 588 | inputPaths = ( 589 | ); 590 | outputFileListPaths = ( 591 | ); 592 | outputPaths = ( 593 | ); 594 | runOnlyForDeploymentPostprocessing = 0; 595 | shellPath = /bin/sh; 596 | shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; 597 | }; 598 | F1CE26722281E6E600441836 /* ShellScript */ = { 599 | isa = PBXShellScriptBuildPhase; 600 | buildActionMask = 2147483647; 601 | files = ( 602 | ); 603 | inputFileListPaths = ( 604 | ); 605 | inputPaths = ( 606 | ); 607 | outputFileListPaths = ( 608 | ); 609 | outputPaths = ( 610 | ); 611 | runOnlyForDeploymentPostprocessing = 0; 612 | shellPath = /bin/sh; 613 | shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; 614 | }; 615 | /* End PBXShellScriptBuildPhase section */ 616 | 617 | /* Begin PBXSourcesBuildPhase section */ 618 | F11ADE1C223672360024F9C7 /* Sources */ = { 619 | isa = PBXSourcesBuildPhase; 620 | buildActionMask = 2147483647; 621 | files = ( 622 | F1E6455E23940199008D2ABE /* FileParser.swift in Sources */, 623 | F1E6455923940199008D2ABE /* ColorTypes.swift in Sources */, 624 | F1E6457623940199008D2ABE /* Themeable+UISegmentedControl.swift in Sources */, 625 | F1E6456B23940199008D2ABE /* ThemeUtil+Animation.swift in Sources */, 626 | F1E6456723940199008D2ABE /* ThemeFontColorKind.swift in Sources */, 627 | F1E6456E23940199008D2ABE /* Themeable +UITVC.swift in Sources */, 628 | F1E6456023940199008D2ABE /* View+Extension.swift in Sources */, 629 | F1E6457323940199008D2ABE /* Themeable+UILabel.swift in Sources */, 630 | F1E6455F23940199008D2ABE /* FileWatcher.swift in Sources */, 631 | F1E6456923940199008D2ABE /* ThemeFontKind.swift in Sources */, 632 | F1E6456523940199008D2ABE /* DecodingTypes.swift in Sources */, 633 | F1E6457723940199008D2ABE /* Themeable+UISlider.swift in Sources */, 634 | F1E6455A23940199008D2ABE /* Colors.swift in Sources */, 635 | F1E6457123940199008D2ABE /* Themeable +UINavBar.swift in Sources */, 636 | F11ADE2F223672A50024F9C7 /* ThemeData.swift in Sources */, 637 | F11ADE31223672A50024F9C7 /* ThemeFont.swift in Sources */, 638 | F11ADE30223672A50024F9C7 /* ThemeColor.swift in Sources */, 639 | F1E6455C23940199008D2ABE /* Data+Extension.swift in Sources */, 640 | F11ADE2E223672A50024F9C7 /* CustomTheme.swift in Sources */, 641 | F11ADE32223672A50024F9C7 /* ThemeFontColor.swift in Sources */, 642 | F1E6457023940199008D2ABE /* Themeable +UITabBar.swift in Sources */, 643 | F11ADE33223672AB0024F9C7 /* Theme+Styles-DEPRECATED.swift in Sources */, 644 | F1E6456D23940199008D2ABE /* Themeable.swift in Sources */, 645 | F1E6457823940199008D2ABE /* Themeable+UIStepper.swift in Sources */, 646 | F11ADE23223672360024F9C7 /* AppDelegate.swift in Sources */, 647 | F1E6456323940199008D2ABE /* Theme.swift in Sources */, 648 | F1E6456A23940199008D2ABE /* ThemeUtil.swift in Sources */, 649 | F1E6457523940199008D2ABE /* Themeable+UISwitch.swift in Sources */, 650 | F1E6456123940199008D2ABE /* VC+Extension.swift in Sources */, 651 | F1E6457423940199008D2ABE /* Themeable+UITableViewCell.swift in Sources */, 652 | F1E6457923940199008D2ABE /* Themeable+UITextField.swift in Sources */, 653 | F1E6456423940199008D2ABE /* ThemeKind.swift in Sources */, 654 | F1E6455D23940199008D2ABE /* JSONUtil.swift in Sources */, 655 | F1E6455823940199008D2ABE /* ColorUtil.swift in Sources */, 656 | F1E6456C23940199008D2ABE /* Themeable+NSVC.swift in Sources */, 657 | F1E6456F23940199008D2ABE /* Themeable+UIVC.swift in Sources */, 658 | F1E6456623940199008D2ABE /* ThemeDataKind.swift in Sources */, 659 | F1E6455B23940199008D2ABE /* DecodingHelpers.swift in Sources */, 660 | F1E6456223940199008D2ABE /* Hybrid.swift in Sources */, 661 | F1E6456823940199008D2ABE /* ThemeColorKind.swift in Sources */, 662 | F1E6457223940199008D2ABE /* Themeable+UIButton.swift in Sources */, 663 | ); 664 | runOnlyForDeploymentPostprocessing = 0; 665 | }; 666 | F12BA13C205D2BDA006C1D56 /* Sources */ = { 667 | isa = PBXSourcesBuildPhase; 668 | buildActionMask = 2147483647; 669 | files = ( 670 | F11ADDF9223571B30024F9C7 /* ThemeFontColor.swift in Sources */, 671 | F1E645882394019A008D2ABE /* ThemeDataKind.swift in Sources */, 672 | F1E645982394019A008D2ABE /* Themeable+UISegmentedControl.swift in Sources */, 673 | F1E6457E2394019A008D2ABE /* Data+Extension.swift in Sources */, 674 | F1E6457C2394019A008D2ABE /* Colors.swift in Sources */, 675 | F1E645872394019A008D2ABE /* DecodingTypes.swift in Sources */, 676 | F1E645832394019A008D2ABE /* VC+Extension.swift in Sources */, 677 | F1E645922394019A008D2ABE /* Themeable +UITabBar.swift in Sources */, 678 | F1E645972394019A008D2ABE /* Themeable+UISwitch.swift in Sources */, 679 | F1E6457D2394019A008D2ABE /* DecodingHelpers.swift in Sources */, 680 | F178DE1D205E878B001FD75E /* Main.swift in Sources */, 681 | F1E6458F2394019A008D2ABE /* Themeable.swift in Sources */, 682 | F1E645852394019A008D2ABE /* Theme.swift in Sources */, 683 | F11ADDFA223571B30024F9C7 /* Theme+Styles-DEPRECATED.swift in Sources */, 684 | F1E645892394019A008D2ABE /* ThemeFontColorKind.swift in Sources */, 685 | F1E6458C2394019A008D2ABE /* ThemeUtil.swift in Sources */, 686 | F1E645812394019A008D2ABE /* FileWatcher.swift in Sources */, 687 | F1E645912394019A008D2ABE /* Themeable+UIVC.swift in Sources */, 688 | F1E645902394019A008D2ABE /* Themeable +UITVC.swift in Sources */, 689 | F1E645862394019A008D2ABE /* ThemeKind.swift in Sources */, 690 | F1E6457A2394019A008D2ABE /* ColorUtil.swift in Sources */, 691 | F11ADDF6223571B30024F9C7 /* ThemeData.swift in Sources */, 692 | F1E645802394019A008D2ABE /* FileParser.swift in Sources */, 693 | F1E645932394019A008D2ABE /* Themeable +UINavBar.swift in Sources */, 694 | F1E6458D2394019A008D2ABE /* ThemeUtil+Animation.swift in Sources */, 695 | F1E645992394019A008D2ABE /* Themeable+UISlider.swift in Sources */, 696 | F1E6459B2394019A008D2ABE /* Themeable+UITextField.swift in Sources */, 697 | F178DE21205EB232001FD75E /* Settings.swift in Sources */, 698 | F1E6457B2394019A008D2ABE /* ColorTypes.swift in Sources */, 699 | F1E6458B2394019A008D2ABE /* ThemeFontKind.swift in Sources */, 700 | F1E645842394019A008D2ABE /* Hybrid.swift in Sources */, 701 | F1E6458A2394019A008D2ABE /* ThemeColorKind.swift in Sources */, 702 | F11ADDF8223571B30024F9C7 /* ThemeFont.swift in Sources */, 703 | F1E645962394019A008D2ABE /* Themeable+UITableViewCell.swift in Sources */, 704 | F11ADDF5223571B30024F9C7 /* CustomTheme.swift in Sources */, 705 | F1E6457F2394019A008D2ABE /* JSONUtil.swift in Sources */, 706 | F12BA144205D2BDA006C1D56 /* AppDelegate.swift in Sources */, 707 | F1E6458E2394019A008D2ABE /* Themeable+NSVC.swift in Sources */, 708 | F1E645822394019A008D2ABE /* View+Extension.swift in Sources */, 709 | F11ADDF7223571B30024F9C7 /* ThemeColor.swift in Sources */, 710 | F1E645942394019A008D2ABE /* Themeable+UIButton.swift in Sources */, 711 | F1E645952394019A008D2ABE /* Themeable+UILabel.swift in Sources */, 712 | F1E6459A2394019A008D2ABE /* Themeable+UIStepper.swift in Sources */, 713 | ); 714 | runOnlyForDeploymentPostprocessing = 0; 715 | }; 716 | F1354F3923AA55E9002BBF3C /* Sources */ = { 717 | isa = PBXSourcesBuildPhase; 718 | buildActionMask = 2147483647; 719 | files = ( 720 | F1354F4023AA55E9002BBF3C /* ThemeParkIOSTests.swift in Sources */, 721 | ); 722 | runOnlyForDeploymentPostprocessing = 0; 723 | }; 724 | /* End PBXSourcesBuildPhase section */ 725 | 726 | /* Begin PBXTargetDependency section */ 727 | F1354F4323AA55E9002BBF3C /* PBXTargetDependency */ = { 728 | isa = PBXTargetDependency; 729 | target = F12BA13F205D2BDA006C1D56 /* ThemePark */; 730 | targetProxy = F1354F4223AA55E9002BBF3C /* PBXContainerItemProxy */; 731 | }; 732 | /* End PBXTargetDependency section */ 733 | 734 | /* Begin PBXVariantGroup section */ 735 | F11ADE262236723A0024F9C7 /* MainMenu.xib */ = { 736 | isa = PBXVariantGroup; 737 | children = ( 738 | F11ADE272236723A0024F9C7 /* Base */, 739 | ); 740 | name = MainMenu.xib; 741 | sourceTree = ""; 742 | }; 743 | F12BA147205D2BDA006C1D56 /* Main.storyboard */ = { 744 | isa = PBXVariantGroup; 745 | children = ( 746 | F12BA148205D2BDA006C1D56 /* Base */, 747 | ); 748 | name = Main.storyboard; 749 | sourceTree = ""; 750 | }; 751 | F12BA14C205D2BDA006C1D56 /* LaunchScreen.storyboard */ = { 752 | isa = PBXVariantGroup; 753 | children = ( 754 | F12BA14D205D2BDA006C1D56 /* Base */, 755 | ); 756 | name = LaunchScreen.storyboard; 757 | sourceTree = ""; 758 | }; 759 | /* End PBXVariantGroup section */ 760 | 761 | /* Begin XCBuildConfiguration section */ 762 | F11ADE2C2236723A0024F9C7 /* Debug */ = { 763 | isa = XCBuildConfiguration; 764 | buildSettings = { 765 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 766 | CLANG_ENABLE_OBJC_WEAK = YES; 767 | CODE_SIGN_ENTITLEMENTS = "ThemePark-example-macOS/ThemePark_example_macOS.entitlements"; 768 | CODE_SIGN_IDENTITY = "-"; 769 | CODE_SIGN_STYLE = Automatic; 770 | COMBINE_HIDPI_IMAGES = YES; 771 | INFOPLIST_FILE = "ThemePark-example-macOS/Info.plist"; 772 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 773 | MACOSX_DEPLOYMENT_TARGET = 10.14; 774 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 775 | MTL_FAST_MATH = YES; 776 | PRODUCT_BUNDLE_IDENTIFIER = "io.github.futurelab.ThemePark-example-macOS"; 777 | PRODUCT_NAME = "$(TARGET_NAME)"; 778 | SDKROOT = macosx; 779 | SWIFT_VERSION = 5.0; 780 | }; 781 | name = Debug; 782 | }; 783 | F11ADE2D2236723A0024F9C7 /* Release */ = { 784 | isa = XCBuildConfiguration; 785 | buildSettings = { 786 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 787 | CLANG_ENABLE_OBJC_WEAK = YES; 788 | CODE_SIGN_ENTITLEMENTS = "ThemePark-example-macOS/ThemePark_example_macOS.entitlements"; 789 | CODE_SIGN_IDENTITY = "-"; 790 | CODE_SIGN_STYLE = Automatic; 791 | COMBINE_HIDPI_IMAGES = YES; 792 | INFOPLIST_FILE = "ThemePark-example-macOS/Info.plist"; 793 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 794 | MACOSX_DEPLOYMENT_TARGET = 10.14; 795 | MTL_FAST_MATH = YES; 796 | PRODUCT_BUNDLE_IDENTIFIER = "io.github.futurelab.ThemePark-example-macOS"; 797 | PRODUCT_NAME = "$(TARGET_NAME)"; 798 | SDKROOT = macosx; 799 | SWIFT_VERSION = 5.0; 800 | }; 801 | name = Release; 802 | }; 803 | F12BA150205D2BDA006C1D56 /* Debug */ = { 804 | isa = XCBuildConfiguration; 805 | buildSettings = { 806 | ALWAYS_SEARCH_USER_PATHS = NO; 807 | CLANG_ANALYZER_NONNULL = YES; 808 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 809 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 810 | CLANG_CXX_LIBRARY = "libc++"; 811 | CLANG_ENABLE_MODULES = YES; 812 | CLANG_ENABLE_OBJC_ARC = YES; 813 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 814 | CLANG_WARN_BOOL_CONVERSION = YES; 815 | CLANG_WARN_COMMA = YES; 816 | CLANG_WARN_CONSTANT_CONVERSION = YES; 817 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 818 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 819 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 820 | CLANG_WARN_EMPTY_BODY = YES; 821 | CLANG_WARN_ENUM_CONVERSION = YES; 822 | CLANG_WARN_INFINITE_RECURSION = YES; 823 | CLANG_WARN_INT_CONVERSION = YES; 824 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 825 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 826 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 827 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 828 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 829 | CLANG_WARN_STRICT_PROTOTYPES = YES; 830 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 831 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 832 | CLANG_WARN_UNREACHABLE_CODE = YES; 833 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 834 | CODE_SIGN_IDENTITY = "iPhone Developer"; 835 | COPY_PHASE_STRIP = NO; 836 | DEBUG_INFORMATION_FORMAT = dwarf; 837 | ENABLE_STRICT_OBJC_MSGSEND = YES; 838 | ENABLE_TESTABILITY = YES; 839 | GCC_C_LANGUAGE_STANDARD = gnu11; 840 | GCC_DYNAMIC_NO_PIC = NO; 841 | GCC_NO_COMMON_BLOCKS = YES; 842 | GCC_OPTIMIZATION_LEVEL = 0; 843 | GCC_PREPROCESSOR_DEFINITIONS = ( 844 | "DEBUG=1", 845 | "$(inherited)", 846 | ); 847 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 848 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 849 | GCC_WARN_UNDECLARED_SELECTOR = YES; 850 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 851 | GCC_WARN_UNUSED_FUNCTION = YES; 852 | GCC_WARN_UNUSED_VARIABLE = YES; 853 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 854 | MTL_ENABLE_DEBUG_INFO = YES; 855 | ONLY_ACTIVE_ARCH = YES; 856 | SDKROOT = iphoneos; 857 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 858 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 859 | }; 860 | name = Debug; 861 | }; 862 | F12BA151205D2BDA006C1D56 /* Release */ = { 863 | isa = XCBuildConfiguration; 864 | buildSettings = { 865 | ALWAYS_SEARCH_USER_PATHS = NO; 866 | CLANG_ANALYZER_NONNULL = YES; 867 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 868 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 869 | CLANG_CXX_LIBRARY = "libc++"; 870 | CLANG_ENABLE_MODULES = YES; 871 | CLANG_ENABLE_OBJC_ARC = YES; 872 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 873 | CLANG_WARN_BOOL_CONVERSION = YES; 874 | CLANG_WARN_COMMA = YES; 875 | CLANG_WARN_CONSTANT_CONVERSION = YES; 876 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 877 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 878 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 879 | CLANG_WARN_EMPTY_BODY = YES; 880 | CLANG_WARN_ENUM_CONVERSION = YES; 881 | CLANG_WARN_INFINITE_RECURSION = YES; 882 | CLANG_WARN_INT_CONVERSION = YES; 883 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 884 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 885 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 886 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 887 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 888 | CLANG_WARN_STRICT_PROTOTYPES = YES; 889 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 890 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 891 | CLANG_WARN_UNREACHABLE_CODE = YES; 892 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 893 | CODE_SIGN_IDENTITY = "iPhone Developer"; 894 | COPY_PHASE_STRIP = NO; 895 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 896 | ENABLE_NS_ASSERTIONS = NO; 897 | ENABLE_STRICT_OBJC_MSGSEND = YES; 898 | GCC_C_LANGUAGE_STANDARD = gnu11; 899 | GCC_NO_COMMON_BLOCKS = YES; 900 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 901 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 902 | GCC_WARN_UNDECLARED_SELECTOR = YES; 903 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 904 | GCC_WARN_UNUSED_FUNCTION = YES; 905 | GCC_WARN_UNUSED_VARIABLE = YES; 906 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 907 | MTL_ENABLE_DEBUG_INFO = NO; 908 | SDKROOT = iphoneos; 909 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 910 | VALIDATE_PRODUCT = YES; 911 | }; 912 | name = Release; 913 | }; 914 | F12BA153205D2BDA006C1D56 /* Debug */ = { 915 | isa = XCBuildConfiguration; 916 | buildSettings = { 917 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 918 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 919 | CODE_SIGN_STYLE = Automatic; 920 | INFOPLIST_FILE = ThemeTest/Info.plist; 921 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 922 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 923 | PRODUCT_BUNDLE_IDENTIFIER = io.futurelab.ThemeTest; 924 | PRODUCT_NAME = "$(TARGET_NAME)"; 925 | SWIFT_VERSION = 5.0; 926 | TARGETED_DEVICE_FAMILY = "1,2"; 927 | }; 928 | name = Debug; 929 | }; 930 | F12BA154205D2BDA006C1D56 /* Release */ = { 931 | isa = XCBuildConfiguration; 932 | buildSettings = { 933 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 934 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 935 | CODE_SIGN_STYLE = Automatic; 936 | INFOPLIST_FILE = ThemeTest/Info.plist; 937 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 938 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 939 | PRODUCT_BUNDLE_IDENTIFIER = io.futurelab.ThemeTest; 940 | PRODUCT_NAME = "$(TARGET_NAME)"; 941 | SWIFT_VERSION = 5.0; 942 | TARGETED_DEVICE_FAMILY = "1,2"; 943 | }; 944 | name = Release; 945 | }; 946 | F1354F4523AA55E9002BBF3C /* Debug */ = { 947 | isa = XCBuildConfiguration; 948 | buildSettings = { 949 | BUNDLE_LOADER = "$(TEST_HOST)"; 950 | CLANG_ENABLE_OBJC_WEAK = YES; 951 | CODE_SIGN_STYLE = Automatic; 952 | INFOPLIST_FILE = Tests/ThemeParkIOSTests/Info.plist; 953 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 954 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 955 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 956 | MTL_FAST_MATH = YES; 957 | PRODUCT_BUNDLE_IDENTIFIER = io.github.futurelab.ThemeParkIOSTests; 958 | PRODUCT_NAME = "$(TARGET_NAME)"; 959 | SWIFT_VERSION = 5.0; 960 | TARGETED_DEVICE_FAMILY = "1,2"; 961 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ThemePark.app/ThemePark"; 962 | }; 963 | name = Debug; 964 | }; 965 | F1354F4623AA55E9002BBF3C /* Release */ = { 966 | isa = XCBuildConfiguration; 967 | buildSettings = { 968 | BUNDLE_LOADER = "$(TEST_HOST)"; 969 | CLANG_ENABLE_OBJC_WEAK = YES; 970 | CODE_SIGN_STYLE = Automatic; 971 | INFOPLIST_FILE = Tests/ThemeParkIOSTests/Info.plist; 972 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 973 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 974 | MTL_FAST_MATH = YES; 975 | PRODUCT_BUNDLE_IDENTIFIER = io.github.futurelab.ThemeParkIOSTests; 976 | PRODUCT_NAME = "$(TARGET_NAME)"; 977 | SWIFT_VERSION = 5.0; 978 | TARGETED_DEVICE_FAMILY = "1,2"; 979 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ThemePark.app/ThemePark"; 980 | }; 981 | name = Release; 982 | }; 983 | /* End XCBuildConfiguration section */ 984 | 985 | /* Begin XCConfigurationList section */ 986 | F11ADE2B2236723A0024F9C7 /* Build configuration list for PBXNativeTarget "ThemePark-example-macOS" */ = { 987 | isa = XCConfigurationList; 988 | buildConfigurations = ( 989 | F11ADE2C2236723A0024F9C7 /* Debug */, 990 | F11ADE2D2236723A0024F9C7 /* Release */, 991 | ); 992 | defaultConfigurationIsVisible = 0; 993 | defaultConfigurationName = Release; 994 | }; 995 | F12BA13B205D2BDA006C1D56 /* Build configuration list for PBXProject "ThemeTest" */ = { 996 | isa = XCConfigurationList; 997 | buildConfigurations = ( 998 | F12BA150205D2BDA006C1D56 /* Debug */, 999 | F12BA151205D2BDA006C1D56 /* Release */, 1000 | ); 1001 | defaultConfigurationIsVisible = 0; 1002 | defaultConfigurationName = Release; 1003 | }; 1004 | F12BA152205D2BDA006C1D56 /* Build configuration list for PBXNativeTarget "ThemePark" */ = { 1005 | isa = XCConfigurationList; 1006 | buildConfigurations = ( 1007 | F12BA153205D2BDA006C1D56 /* Debug */, 1008 | F12BA154205D2BDA006C1D56 /* Release */, 1009 | ); 1010 | defaultConfigurationIsVisible = 0; 1011 | defaultConfigurationName = Release; 1012 | }; 1013 | F1354F4423AA55E9002BBF3C /* Build configuration list for PBXNativeTarget "ThemeParkIOSTests" */ = { 1014 | isa = XCConfigurationList; 1015 | buildConfigurations = ( 1016 | F1354F4523AA55E9002BBF3C /* Debug */, 1017 | F1354F4623AA55E9002BBF3C /* Release */, 1018 | ); 1019 | defaultConfigurationIsVisible = 0; 1020 | defaultConfigurationName = Release; 1021 | }; 1022 | /* End XCConfigurationList section */ 1023 | }; 1024 | rootObject = F12BA138205D2BDA006C1D56 /* Project object */; 1025 | } 1026 | --------------------------------------------------------------------------------