├── .DS_Store ├── Colours ├── .DS_Store ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ ├── icon_16x16.png │ │ ├── icon_32x32.png │ │ ├── icon_128x128.png │ │ ├── icon_256x256.png │ │ ├── icon_512x512.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512@2x.png │ │ └── Contents.json ├── Colours.entitlements ├── View \ Window Controllers │ ├── TouchbarOutletWindowController.swift │ ├── ViewController.swift │ └── ColourDetailViewController.swift ├── Others │ └── AppDelegate.swift ├── Info.plist ├── View (Controller) Extensions │ ├── ColourView + Mouse Input.swift │ ├── ColourView + Animations.swift │ └── ViewController + Actions.swift ├── Extensions │ └── Cocoa Extensions.swift └── Views │ └── ColourView.swift ├── Photos ├── iPad.png └── macOS.png ├── Colours (iOS) ├── Assets │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── icon-20.png │ │ │ ├── icon-29.png │ │ │ ├── icon-30.png │ │ │ ├── icon-40.png │ │ │ ├── icon-57.png │ │ │ ├── icon-76.png │ │ │ ├── icon-1024.png │ │ │ ├── icon-512.png │ │ │ ├── icon-20@2x-1.png │ │ │ ├── icon-20@2x.png │ │ │ ├── icon-20@3x.png │ │ │ ├── icon-29@2x-1.png │ │ │ ├── icon-29@2x.png │ │ │ ├── icon-29@3x.png │ │ │ ├── icon-40@2x-1.png │ │ │ ├── icon-40@2x.png │ │ │ ├── icon-40@3x.png │ │ │ ├── icon-57@2x.png │ │ │ ├── icon-60@2x.png │ │ │ ├── icon-60@3x.png │ │ │ ├── icon-76@2x.png │ │ │ ├── icon-83_5@2x.png │ │ │ └── Contents.json │ └── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard ├── Views │ ├── PaletteCellCollectionViewCell.swift │ └── ColourView.swift ├── View (Controller) Extensions │ ├── ViewController + Colour Picker Delegate.swift │ ├── ViewController + Colour Scheme Picker.swift │ ├── ViewController + Actions.swift │ ├── ColourView + Animations.swift │ ├── ColourView + Touch Events.swift │ ├── ColourDetailView + Actions.swift │ └── ColourView + Actions.swift ├── View Controllers │ ├── ColourDetailViewController.swift │ ├── ViewController.swift │ └── GeneratedPaletteCollectionViewController.swift ├── Delegates │ ├── AppDelegate.swift │ └── SceneDelegate.swift └── Info.plist ├── Colours.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── emily.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved ├── xcuserdata │ └── emily.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── Universal ├── Localizable.strings ├── CG Extensions.swift ├── Colour Name Info.swift └── Colour Extensions.swift ├── README.md └── LICENSE /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/.DS_Store -------------------------------------------------------------------------------- /Colours/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/.DS_Store -------------------------------------------------------------------------------- /Photos/iPad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Photos/iPad.png -------------------------------------------------------------------------------- /Photos/macOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Photos/macOS.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-30.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-57.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-76.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-1024.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-512.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20@2x-1.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29@2x-1.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40@2x-1.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-83_5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/icon-83_5@2x.png -------------------------------------------------------------------------------- /Colours.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Colours.xcodeproj/project.xcworkspace/xcuserdata/emily.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MissEmlizB/Colours/HEAD/Colours.xcodeproj/project.xcworkspace/xcuserdata/emily.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Colours.xcodeproj/xcuserdata/emily.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Colours.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Colours/Colours.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Colours (iOS)/Views/PaletteCellCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PaletteCellCollectionViewCell.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PaletteCellCollectionViewCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var colourView: ColourView! 14 | @IBOutlet weak var colourLabel: UILabel! 15 | } 16 | -------------------------------------------------------------------------------- /Universal/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | Colours 4 | 5 | Created by Emily Blackwell on 18/12/2019. 6 | Copyright © 2019 Emily Blackwell. All rights reserved. 7 | */ 8 | 9 | 10 | // error - title - colour scheme name 11 | "err-tCSN" = "This function replaces this string with its localised version."; 12 | 13 | // error - message - colour scheme name 14 | "err-mCSN" = "You have selected an invalid colour scheme!"; 15 | 16 | // error - colour name unavailable 17 | "err-cnu" = "Name identification is currently unavailable"; 18 | -------------------------------------------------------------------------------- /Colours.xcodeproj/xcuserdata/emily.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Colours (iOS).xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | Colours.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Colours 2 | A simple colour palette generator for macOS and iOS. 3 | 4 | ## macOS 5 | (Supported versions: OS X 10.11 or later) 6 | 7 | ![macOS](/Photos/macOS.png) 8 | 9 | ## iPad 10 | (Supported versions: iOS 9.0 or later) 11 | 12 | ![iPad/iOS](/Photos/iPad.png) 13 | 14 | # Credits 15 | 16 | ### The Color API (Colour Name Identification) 17 | https://thecolorapi.com 18 | 19 | ### FlexColorPicker (iOS) 20 | https://github.com/RastislavMirek/FlexColorPicker 21 | 22 | ### Hero Transitions (iOS) 23 | https://github.com/HeroTransitions/Hero 24 | 25 | # Help 26 | If you have any questions, feel free to contact me on Twitter (@MissEmlizB). 27 | -------------------------------------------------------------------------------- /Colours/View \ Window Controllers/TouchbarOutletWindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TouchbarOutletWindowController.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 24/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | class TouchbarOutletWindowController: NSWindowController { 13 | 14 | @IBOutlet weak var touchbarColourPicker: AnyObject! 15 | 16 | override func windowDidLoad() { 17 | 18 | super.windowDidLoad() 19 | 20 | // 21 | let viewController = self.contentViewController as! ViewController 22 | viewController.touchbarColourPicker = touchbarColourPicker 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Colours (iOS)/View (Controller) Extensions/ViewController + Colour Picker Delegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController + Colour Picker Delegate.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FlexColorPicker 11 | 12 | 13 | extension ViewController: ColorPickerDelegate { 14 | 15 | func colorPicker(_ colorPicker: ColorPickerController, confirmedColor: UIColor, usingControl: ColorControl) { 16 | 17 | } 18 | 19 | func colorPicker(_ colorPicker: ColorPickerController, selectedColor: UIColor, usingControl: ColorControl) { 20 | 21 | self.colourView.colour = selectedColor 22 | self.colourView.setNeedsDisplay() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Colours.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "FlexColorPicker", 6 | "repositoryURL": "https://github.com/RastislavMirek/FlexColorPicker", 7 | "state": { 8 | "branch": null, 9 | "revision": "1e96de1abbc00b5ab108c738b22e4df53a4222b2", 10 | "version": "1.3.1" 11 | } 12 | }, 13 | { 14 | "package": "Hero", 15 | "repositoryURL": "https://github.com/HeroTransitions/Hero", 16 | "state": { 17 | "branch": null, 18 | "revision": "ae951b89f23485de8a7b95aaa5cead7f78ab1df0", 19 | "version": "1.5.0" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /Colours/Others/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 16/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | @NSApplicationMain 13 | class AppDelegate: NSObject, NSApplicationDelegate { 14 | 15 | var session: URLSession! 16 | 17 | static func getURLSession() -> URLSession { 18 | 19 | let delegate = NSApp.delegate as! AppDelegate 20 | return delegate.session 21 | } 22 | 23 | func applicationDidFinishLaunching(_ aNotification: Notification) { 24 | 25 | // Insert code here to initialize your application 26 | session = URLSession(configuration: .ephemeral) 27 | } 28 | 29 | func applicationWillTerminate(_ aNotification: Notification) { 30 | // Insert code here to tear down your application 31 | } 32 | 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Colours (iOS)/View (Controller) Extensions/ViewController + Colour Scheme Picker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController + Colour Scheme Picker.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate { 13 | 14 | // MARK: Data Source 15 | 16 | func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 17 | 18 | return self.availableColourSchemes.count 19 | } 20 | 21 | 22 | func numberOfComponents(in pickerView: UIPickerView) -> Int { 23 | return 1 24 | } 25 | 26 | // MARK: Delegate 27 | 28 | func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 29 | 30 | return self.availableColourSchemes[row] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Universal/CG Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CG Extensions.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import CoreGraphics 10 | 11 | 12 | extension CGFloat { 13 | 14 | /// Returns the hexadecimal representation of this thing. (surprised pikachu) 15 | var hexadecimalRepresentation: String { 16 | get { 17 | 18 | // Does it need a zero prefix? 19 | let nz = self < 16 20 | let hexString = String(Int(self), radix: 16) 21 | 22 | return (nz ? "0" : "") + hexString 23 | } 24 | } 25 | 26 | /// Restrict this float's value range. 27 | /// - Parameter min: The lowest value this float can have. 28 | /// - Parameter max: The highest value this float can have. 29 | func withBoundaries(min: CGFloat, max: CGFloat) -> CGFloat { 30 | 31 | var float = self 32 | 33 | if float < min { 34 | float = min 35 | } 36 | 37 | if float > max { 38 | float = max 39 | } 40 | 41 | return float 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Colours (iOS)/View (Controller) Extensions/ViewController + Actions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController + Actions.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension ViewController { 13 | 14 | // MARK: Notification Centre 15 | 16 | @objc func openColourPicker(_ notification: NSNotification) { 17 | 18 | guard let object = notification.object as? ColourView, 19 | object.tag == 10 else { 20 | return 21 | } 22 | 23 | self.performSegue(withIdentifier: vColourPicker, sender: self) 24 | } 25 | 26 | // MARK: IB Actions 27 | 28 | @IBAction func closeColourPicker(sender: AnyObject) { 29 | 30 | let animated = !UIAccessibility.isReduceMotionEnabled 31 | self.colourPicker?.dismiss(animated: animated, completion: nil) 32 | } 33 | 34 | @IBAction func closePaletteView(sender: AnyObject) { 35 | 36 | let animated = !UIAccessibility.isReduceMotionEnabled 37 | self.paletteNavController?.dismiss(animated: animated, completion: nil) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Colours (iOS)/Views/ColourView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourView.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | let nColourViewTapped = NSNotification.Name(rawValue: "colourViewWasTappedNotification") 13 | 14 | /// Tihs determines a colour view's appearance 15 | @objc enum ColourViewShape: Int { 16 | case roundedRectangle = 0 17 | case circle = 1 18 | } 19 | 20 | @IBDesignable 21 | class ColourView: UIView { 22 | 23 | @IBInspectable var colour: UIColor! = .systemBlue { 24 | didSet { 25 | 26 | // for appearance-only colour views, 27 | // create their shape layer minus its touch recogniser 28 | 29 | if !wasSetUp { 30 | self.setupAppearance() 31 | self.wasSetUp = true 32 | } 33 | 34 | // update its appearance 35 | self.updateAppearance() 36 | } 37 | } 38 | 39 | @IBInspectable var tappable: Bool = true 40 | @IBInspectable var shape: ColourViewShape = .roundedRectangle 41 | var shapeLayer: CAShapeLayer! 42 | 43 | var wasSetUp = false 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Emily B 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Colours (iOS)/View (Controller) Extensions/ColourView + Animations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourView + Animations.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 23/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension ColourView { 13 | 14 | func animate(reversed: Bool) { 15 | 16 | // 17 | let a = CATransform3DMakeScale(0.925, 0.925, 0.925) 18 | let b = CATransform3DMakeScale(1.0, 1.0, 1.0) 19 | 20 | // make the view bounce whenever it gets tapped 21 | CATransaction.begin() 22 | 23 | // 24 | let bounce = CASpringAnimation(keyPath: #keyPath(CALayer.transform)) 25 | bounce.isRemovedOnCompletion = true 26 | 27 | if reversed { 28 | bounce.fromValue = a 29 | bounce.toValue = b 30 | 31 | self.layer.transform = b 32 | } 33 | 34 | else { 35 | bounce.fromValue = b 36 | bounce.toValue = a 37 | 38 | self.layer.transform = a 39 | } 40 | 41 | // 42 | bounce.run(forKey: "transform", 43 | object: self.layer, 44 | arguments: nil) 45 | 46 | // 47 | CATransaction.setAnimationDuration(bounce.settlingDuration) 48 | CATransaction.commit() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Colours (iOS)/View (Controller) Extensions/ColourView + Touch Events.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourView + Touch Events.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension ColourView { 13 | 14 | @objc func colourViewWasTapped(_ recogniser: UITapGestureRecognizer) { 15 | 16 | guard self.tappable else { 17 | return 18 | } 19 | 20 | if recogniser.state == .ended { 21 | 22 | NotificationCenter.default.post(name: nColourViewTapped, 23 | object: self, 24 | userInfo: nil) 25 | 26 | // 27 | self.animate(reversed: true) 28 | } 29 | } 30 | 31 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 32 | 33 | guard self.tappable else { 34 | return 35 | } 36 | 37 | super.touchesBegan(touches, with: event) 38 | self.animate(reversed: false) 39 | } 40 | 41 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 42 | 43 | guard self.tappable else { 44 | return 45 | } 46 | 47 | super.touchesEnded(touches, with: event) 48 | self.animate(reversed: true) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Colours/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSApplicationCategoryType 24 | public.app-category.productivity 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2019 Emily Blackwell. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | NSSupportsAutomaticTermination 34 | 35 | NSSupportsSuddenTermination 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Colours (iOS)/View Controllers/ColourDetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourDetailViewController.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 22/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Hero 11 | 12 | class ColourDetailViewController: UIViewController { 13 | 14 | @IBOutlet weak var colourView: ColourView! 15 | @IBOutlet weak var colourNameLabel: UILabel! 16 | @IBOutlet weak var rgbLabel: UILabel! 17 | @IBOutlet weak var hexLabel: UILabel! 18 | @IBOutlet weak var progressIndicator: UIActivityIndicatorView! 19 | 20 | weak var cell: PaletteCellCollectionViewCell? 21 | 22 | var dataTask: URLSessionDataTask? 23 | var colour: UIColor! 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | // Do any additional setup after loading the view. 29 | let rgbRepresentation = rgb(forColour: self.colour) 30 | let hexRepresentation = hex(forColour: self.colour) 31 | 32 | colourView.colour = self.colour 33 | colourView.setupAppearance() 34 | 35 | rgbLabel.text = rgbRepresentation 36 | hexLabel.text = hexRepresentation 37 | 38 | // 39 | let session = AppDelegate.getURLSession() 40 | 41 | self.dataTask = name(forColour: self.colour, usingSession: session) { name in 42 | 43 | DispatchQueue.main.async { 44 | self.setName(name: name) 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Colours/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Colours/View \ Window Controllers/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 16/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | class ViewController: NSViewController { 13 | 14 | @IBOutlet weak var colourStackView: NSStackView! 15 | @IBOutlet weak var colourWell: NSColorWell! 16 | @IBOutlet weak var colourScheme: NSComboBox! 17 | 18 | var colourViews: [ColourView] = [] 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | 23 | // 24 | NotificationCenter.default.addObserver(self, selector: #selector((openDetailPopover(_:))), name: nColourViewSelected, object: nil) 25 | } 26 | 27 | // MARK: Touchbar Colour Picker 28 | 29 | weak var touchbarColourPicker: AnyObject! { 30 | didSet { 31 | 32 | // touch bar colour picker 33 | if #available(macOS 10.12.2, *) { 34 | 35 | let picker = touchbarColourPicker as! NSColorPickerTouchBarItem 36 | 37 | // update our colour well if the user picks a colour from the touch bar 38 | picker.target = self 39 | picker.action = #selector((touchbarColourSelected(_:))) 40 | 41 | // colours picked from the colour well will update the touch bar, as well 42 | NotificationCenter.default.addObserver(self, selector: #selector(colourSelectedOnWell(_:)), name: NSColorPanel.colorDidChangeNotification, object: nil) 43 | } 44 | } 45 | } 46 | 47 | @available (macOS 10.12.2, *) 48 | var TouchbarColourPicker: NSColorPickerTouchBarItem { 49 | get { 50 | return touchbarColourPicker as! NSColorPickerTouchBarItem 51 | } 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Colours (iOS)/Delegates/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | 16 | // pre-iOS/iPadOS 13 storyboard window 17 | var window: UIWindow? 18 | var session: URLSession! 19 | 20 | static func getURLSession() -> URLSession { 21 | 22 | let delegate = UIApplication.shared.delegate as! AppDelegate 23 | return delegate.session 24 | } 25 | 26 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 27 | 28 | // Override point for customization after application launch. 29 | session = URLSession(configuration: .ephemeral) 30 | return true 31 | } 32 | 33 | // MARK: UISceneSession Lifecycle 34 | 35 | @available (iOS 13.0, *) 36 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 37 | // Called when a new scene session is being created. 38 | // Use this method to select a configuration to create the new scene with. 39 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 40 | } 41 | 42 | @available (iOS 13.0, *) 43 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 44 | // Called when the user discards a scene session. 45 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 46 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Colours/View (Controller) Extensions/ColourView + Mouse Input.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourView + Mouse Input.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 17/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | let nColourViewSelected = NSNotification.Name(rawValue: "colourViewWasSelected") 13 | let kColour = "colour" 14 | 15 | extension ColourView { 16 | 17 | // MARK: Tracking Area 18 | 19 | override func updateTrackingAreas() { 20 | 21 | let options: NSTrackingArea.Options = 22 | [.mouseEnteredAndExited, .mouseMoved, .activeInKeyWindow] 23 | 24 | let trackingArea = NSTrackingArea(rect: self.bounds, 25 | options: options, 26 | owner: self, 27 | userInfo: nil) 28 | 29 | self.addTrackingArea(trackingArea) 30 | } 31 | 32 | // MARK: Mouse Events 33 | 34 | override func mouseEntered(with event: NSEvent) { 35 | 36 | guard self.clickable else { 37 | return 38 | } 39 | 40 | // 41 | self.interactionAnimation(reversed: true) 42 | 43 | self.isHighlighted = true 44 | self.setNeedsDisplay(self.bounds) 45 | 46 | NSCursor.pointingHand.set() 47 | } 48 | 49 | override func mouseExited(with event: NSEvent) { 50 | 51 | guard self.clickable else { 52 | return 53 | } 54 | 55 | // 56 | self.interactionAnimation(reversed: false) 57 | 58 | self.isHighlighted = false 59 | self.setNeedsDisplay(self.bounds) 60 | 61 | NSCursor.arrow.set() 62 | } 63 | 64 | override func mouseDown(with event: NSEvent) { 65 | 66 | guard self.clickable else { 67 | return 68 | } 69 | 70 | self.interactionAnimation(reversed: true, a: 0.35, b: 0.5) 71 | } 72 | 73 | override func mouseUp(with event: NSEvent) { 74 | 75 | guard self.clickable else { 76 | return 77 | } 78 | 79 | self.interactionAnimation(reversed: false, a: 0.35, b: 0.5) 80 | 81 | NotificationCenter.default.post(name: nColourViewSelected, 82 | object: self, 83 | userInfo: [kColour: self.colour]) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Colours/View \ Window Controllers/ColourDetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourDetailViewController.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 17/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | let kDetailID = "Colour Detail" 13 | 14 | class ColourDetailViewController: NSViewController { 15 | 16 | @IBOutlet weak var colourView: ColourView! 17 | @IBOutlet weak var colourNameLabel: NSTextField! 18 | @IBOutlet weak var hexColourLabel: NSTextField! 19 | @IBOutlet weak var rgbColourLabel: NSTextField! 20 | @IBOutlet weak var processingIndicator: NSProgressIndicator! 21 | 22 | weak var dataTask: URLSessionDataTask? 23 | var colour: NSColor! 24 | 25 | override func viewDidLoad() { 26 | 27 | super.viewDidLoad() 28 | 29 | // 30 | colourView.colour = colour 31 | 32 | // colour information 33 | let hexRepresentation = hex(forColour: colour) 34 | let rgbRepresentation = rgb(forColour: colour) 35 | 36 | hexColourLabel.stringValue = hexRepresentation 37 | rgbColourLabel.stringValue = rgbRepresentation 38 | 39 | // 40 | self.setNameLabel(name: "") 41 | 42 | // Identify its name using 'The Color API' 43 | 44 | processingIndicator.isHidden = false 45 | processingIndicator.startAnimation(self) 46 | 47 | // 48 | let session = AppDelegate.getURLSession() 49 | 50 | self.dataTask = name(forColour: colour, usingSession: session) { name in 51 | 52 | DispatchQueue.main.async { 53 | self.setNameLabel(name: name ?? "err-cnu".l) 54 | } 55 | } 56 | } 57 | 58 | override func viewWillDisappear() { 59 | 60 | super.viewWillDisappear() 61 | 62 | // cancel any running tasks 63 | self.dataTask?.cancel() 64 | } 65 | 66 | // MARK: Name Label 67 | 68 | func setNameLabel(name: String?) { 69 | 70 | // 71 | processingIndicator.isHidden = true 72 | processingIndicator.stopAnimation(self) 73 | 74 | // 75 | colourNameLabel.isHidden = (name == nil) 76 | colourNameLabel.stringValue = name ?? "" 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Colours (iOS)/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 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Colours (iOS)/View (Controller) Extensions/ColourDetailView + Actions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourDetailView + Actions.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 22/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Hero 11 | 12 | 13 | extension ColourDetailViewController { 14 | 15 | func setName(name: String?) { 16 | 17 | // 18 | progressIndicator.stopAnimating() 19 | colourNameLabel.isHidden = false 20 | 21 | // 22 | guard let name = name else { 23 | 24 | let text = NSLocalizedString("err-cnu", comment: "") 25 | colourNameLabel.text = text 26 | 27 | return 28 | } 29 | 30 | // 31 | colourNameLabel.text = name 32 | } 33 | 34 | override func viewWillDisappear(_ animated: Bool) { 35 | 36 | super.viewWillDisappear(animated) 37 | self.dataTask?.cancel() 38 | } 39 | 40 | // MARK: IB Actions 41 | 42 | @IBAction func dismissVC(sender: AnyObject) { 43 | 44 | self.dismiss(animated: !UIAccessibility.isReduceMotionEnabled) { 45 | self.cell?.colourView.hero.id = "" 46 | self.cell?.colourLabel.hero.id = "" 47 | } 48 | } 49 | 50 | @IBAction func interactiveDismiss(sender: UIPanGestureRecognizer) { 51 | 52 | let translation = sender.translation(in: self.view) 53 | 54 | let yp = abs((translation.y) / (self.view.bounds.height / 2)) 55 | let xp = abs((translation.x) / (self.view.bounds.width / 2)) 56 | 57 | // 58 | switch sender.state { 59 | 60 | case .began: 61 | 62 | self.dismiss(animated: !UIAccessibility.isReduceMotionEnabled, 63 | completion: nil) 64 | 65 | case .changed: 66 | 67 | let translation = CGPoint(x: colourView.frame.origin.x - xp, 68 | y: colourView.frame.origin.y + translation.y) 69 | 70 | // allow the user to interact with the transition 71 | Hero.shared.update((xp + yp) / 2) 72 | Hero.shared.apply(modifiers: [.translate(translation)], to: colourView) 73 | 74 | case .ended: 75 | 76 | // depending on their progress, either finish or cancel the transition 77 | if yp > 0.25 || xp > 0.55 { 78 | 79 | Hero.shared.finish() 80 | self.cell?.colourView.hero.id = "" 81 | self.cell?.colourLabel.hero.id = "" 82 | } 83 | 84 | else { 85 | Hero.shared.cancel() 86 | } 87 | 88 | case .failed, .cancelled: 89 | Hero.shared.cancel() 90 | 91 | default: 92 | break 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Colours (iOS)/Delegates/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | @available (iOS 13.0, *) 13 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 21 | guard let _ = (scene as? UIWindowScene) else { return } 22 | } 23 | 24 | func sceneDidDisconnect(_ scene: UIScene) { 25 | // Called as the scene is being released by the system. 26 | // This occurs shortly after the scene enters the background, or when its session is discarded. 27 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 28 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 29 | } 30 | 31 | func sceneDidBecomeActive(_ scene: UIScene) { 32 | // Called when the scene has moved from an inactive state to an active state. 33 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 34 | } 35 | 36 | func sceneWillResignActive(_ scene: UIScene) { 37 | // Called when the scene will move from an active state to an inactive state. 38 | // This may occur due to temporary interruptions (ex. an incoming phone call). 39 | } 40 | 41 | func sceneWillEnterForeground(_ scene: UIScene) { 42 | // Called as the scene transitions from the background to the foreground. 43 | // Use this method to undo the changes made on entering the background. 44 | } 45 | 46 | func sceneDidEnterBackground(_ scene: UIScene) { 47 | // Called as the scene transitions from the foreground to the background. 48 | // Use this method to save data, release shared resources, and store enough scene-specific state information 49 | // to restore the scene back to its current state. 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Colours (iOS)/View (Controller) Extensions/ColourView + Actions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourView + Actions.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 24/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | extension ColourView { 13 | 14 | // MARK: Actions 15 | 16 | func setup() { 17 | 18 | guard !self.wasSetUp && self.tappable else { 19 | return 20 | } 21 | 22 | // detect taps in this view 23 | let recogniser = UITapGestureRecognizer(target: self, action: #selector((colourViewWasTapped(_:)))) 24 | 25 | self.addGestureRecognizer(recogniser) 26 | 27 | // 28 | self.setupAppearance() 29 | 30 | // 31 | self.wasSetUp = true 32 | self.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5) 33 | } 34 | 35 | // MARK: Appearance 36 | 37 | func setupAppearance() { 38 | 39 | var path: UIBezierPath! 40 | 41 | switch shape { 42 | 43 | case .roundedRectangle: 44 | path = UIBezierPath(roundedRect: self.bounds, 45 | byRoundingCorners: .allCorners, 46 | cornerRadii: CGSize(width: 32, height: 32)) 47 | 48 | case .circle: 49 | path = UIBezierPath(ovalIn: self.bounds) 50 | } 51 | 52 | self.shapeLayer = CAShapeLayer() 53 | 54 | self.shapeLayer.path = path.cgPath 55 | self.shapeLayer.lineWidth = 2.0 56 | 57 | self.updateAppearance() 58 | self.layer.addSublayer(self.shapeLayer) 59 | 60 | // respond appropriately to any changes to the user's accessibility settings 61 | NotificationCenter.default.addObserver(self, selector: #selector(accessibilityContrastChanged(_:)), name: UIAccessibility.darkerSystemColorsStatusDidChangeNotification, object: nil) 62 | } 63 | 64 | func updateOutline() { 65 | 66 | // add a subtle outline in high contrast mode 67 | if UIAccessibility.isDarkerSystemColorsEnabled { 68 | self.shapeLayer.strokeColor = self.colour.shadow(withLevel: 0.5)?.cgColor 69 | } 70 | 71 | else { 72 | self.shapeLayer.strokeColor = nil 73 | } 74 | } 75 | 76 | func updateAppearance() { 77 | 78 | CATransaction.begin() 79 | CATransaction.setAnimationDuration(0) 80 | 81 | self.shapeLayer.fillColor = self.colour.cgColor 82 | self.updateOutline() 83 | 84 | CATransaction.commit() 85 | } 86 | 87 | // MARK: Notification Centre 88 | 89 | @objc func accessibilityContrastChanged(_ notification: NSNotification) { 90 | 91 | self.updateOutline() 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Colours/Extensions/Cocoa Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cocoa Extensions.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 18/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | // MARK: Shortcuts 13 | 14 | let AlertDefaultButtons = ["Ok"] 15 | 16 | extension NSViewController { 17 | 18 | /// Show an alert modal to the user. 19 | /// - Parameter title: What is this alert about? 20 | /// - Parameter message: Add more details about the alert's subject here. 21 | /// - Parameter style: How crucial is this alert? 22 | /// - Parameter buttons: What options does the user have to deal with this alert? (optional) 23 | /// - Parameter completion: What happens when the user selects an action? (optional) 24 | 25 | func alert(title: String, message: String, style: NSAlert.Style, buttons: [String]? = nil, completion: ((NSApplication.ModalResponse) -> ())? = nil) { 26 | 27 | let alertModal = NSAlert() 28 | 29 | // 30 | alertModal.messageText = title 31 | alertModal.informativeText = message 32 | alertModal.alertStyle = style 33 | 34 | if let buttons = buttons { 35 | // add custom alert buttons 36 | for button in buttons { 37 | alertModal.addButton(withTitle: button) 38 | } 39 | } 40 | 41 | else { 42 | // use our default "Ok" if no custom titles were provided 43 | alertModal.addButton(withTitle: "Ok") 44 | } 45 | 46 | // 47 | let response = alertModal.runModal() 48 | completion?(response) 49 | } 50 | } 51 | 52 | // MARK: Localisation 53 | 54 | extension String { 55 | 56 | /// Localised version of this string 57 | var l: String { 58 | get { 59 | return NSLocalizedString(self, comment: "") 60 | } 61 | } 62 | } 63 | 64 | // MARK: Accessibility 65 | 66 | /// Checks if the user has 'reduced motion' disabled in their preferences 67 | func animationIsEnabled() -> Bool { 68 | 69 | if #available(macOS 10.12, *) { 70 | guard NSWorkspace.shared.accessibilityDisplayShouldReduceMotion else { 71 | return true 72 | } 73 | } 74 | 75 | return false 76 | } 77 | 78 | // MARK: Accessibility 79 | 80 | extension NSAccessibility { 81 | 82 | /// Checks if the user has 'increase contrast' enabled in their preferences 83 | static var highContrastMode: Bool { 84 | get { 85 | return NSWorkspace.shared.accessibilityDisplayShouldIncreaseContrast 86 | } 87 | } 88 | 89 | /// Checks if the user has 'reduce motion' disabled in their preferences 90 | static var animationsEnabled: Bool { 91 | get { 92 | 93 | if #available(macOS 10.12, *) { 94 | guard NSWorkspace.shared.accessibilityDisplayShouldReduceMotion else { 95 | return true 96 | } 97 | } 98 | 99 | return false 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Colours/Views/ColourView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourView.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 17/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | @IBDesignable 13 | class ColourView: NSView { 14 | 15 | @IBInspectable var clickable: Bool = true 16 | 17 | @IBInspectable var colour: NSColor = .black { 18 | didSet { 19 | self.toolTip = hex(forColour: self.colour) 20 | } 21 | } 22 | 23 | var isHighlighted: Bool = false 24 | 25 | override func draw(_ dirtyRect: NSRect) { 26 | super.draw(dirtyRect) 27 | 28 | // 29 | let highContrastEnabled = NSAccessibility.highContrastMode 30 | 31 | // Draw a simple filled rectangle with the given colour 32 | let path = NSBezierPath(roundedRect: self.bounds, 33 | xRadius: 8, yRadius: 8) 34 | 35 | self.colour.setFill() 36 | path.fill() 37 | 38 | // draw an outline in increased contrast mode 39 | if !self.isHighlighted && highContrastEnabled { 40 | 41 | path.lineWidth = 4.0 42 | 43 | self.colour.shadow(withLevel: 0.5)?.setStroke() 44 | path.stroke() 45 | } 46 | 47 | // draw a selection outline in reduced motion and/or increased contrast mode 48 | guard !NSAccessibility.animationsEnabled || highContrastEnabled else { 49 | return 50 | } 51 | 52 | // highlighting outline 53 | if self.isHighlighted { 54 | 55 | path.lineWidth = 8.0 56 | path.lineJoinStyle = .round 57 | path.lineCapStyle = .butt 58 | 59 | NSColor.controlColour.setStroke() 60 | path.stroke() 61 | } 62 | } 63 | 64 | func setup(delay: TimeInterval = 0.0) { 65 | 66 | self.wantsLayer = true 67 | 68 | self.layerContentsPlacement = .scaleAxesIndependently 69 | self.layerContentsRedrawPolicy = .onSetNeedsDisplay 70 | 71 | self.layer!.anchorPoint = CGPoint(x: 0.5, y: -0.5) 72 | 73 | // animation // 74 | 75 | guard animationIsEnabled() else { 76 | return 77 | } 78 | 79 | self.layer!.opacity = 0.0 80 | 81 | // delay our animation (if a delay was provided, ofc) 82 | Timer.scheduledTimer(timeInterval: delay, 83 | target: self, 84 | selector: #selector(appear(_:)), 85 | userInfo: nil, 86 | repeats: false) 87 | } 88 | 89 | /// Use this animation when you add the colour view to a superview. 90 | @objc func appear(_ sender: AnyObject) { 91 | 92 | self.animate(a: 0.0, b: 1.0, reversed: false, duration: 0.9) { 93 | 94 | DispatchQueue.main.async { 95 | self.setNeedsDisplay(self.bounds) 96 | } 97 | } 98 | } 99 | 100 | /// Use this to animate the removal of this colour view from its superview. 101 | func remove(completion: (() -> ())? = nil) { 102 | 103 | // stop any running animations before continuing 104 | self.layer!.removeAllAnimations() 105 | 106 | self.animate(a: 1.0, b: 0.0, reversed: true, duration: 0.65) { 107 | self.removeFromSuperview() 108 | completion?() 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Colours/View (Controller) Extensions/ColourView + Animations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColourView + Animations.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 23/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | extension ColourView { 13 | 14 | // MARK: Main Animation 15 | 16 | func animate(a: CGFloat, b: CGFloat, reversed: Bool, duration: CFTimeInterval, completion: (() -> ())? = nil) { 17 | 18 | // only play animations if the 'reduce motion' setting is disabled 19 | guard NSAccessibility.animationsEnabled else { 20 | 21 | completion?() 22 | return 23 | } 24 | 25 | CATransaction.begin() 26 | 27 | CATransaction.setCompletionBlock { 28 | completion?() 29 | } 30 | 31 | // transform animation // 32 | 33 | let animation = CASpringAnimation(keyPath: 34 | #keyPath(CALayer.transform)) 35 | 36 | // 37 | animation.isRemovedOnCompletion = true 38 | 39 | let from = CATransform3DMakeScale(a, a, a) 40 | let to = CATransform3DMakeScale(b, b, b) 41 | 42 | animation.fromValue = from 43 | animation.toValue = to 44 | 45 | // opacity animation // 46 | 47 | CATransaction.begin() 48 | CATransaction.setAnimationDuration(duration * 0.5) 49 | 50 | let opacity = CABasicAnimation(keyPath: 51 | #keyPath(CALayer.opacity)) 52 | 53 | // 54 | opacity.isRemovedOnCompletion = true 55 | 56 | if reversed { 57 | 58 | opacity.fromValue = 1.0 59 | opacity.toValue = 0.0 60 | 61 | self.layer!.opacity = 0.0 62 | } 63 | 64 | else { 65 | 66 | opacity.fromValue = 0.0 67 | opacity.toValue = 1.0 68 | 69 | self.layer!.opacity = 1.0 70 | } 71 | 72 | opacity.run(forKey: "opacity", 73 | object: self.layer!, 74 | arguments: [:]) 75 | 76 | CATransaction.commit() 77 | 78 | // 79 | self.layer!.transform = to 80 | 81 | animation.run(forKey: "transform", 82 | object: self.layer!, 83 | arguments: [:]) 84 | 85 | // 86 | CATransaction.setAnimationDuration(animation.settlingDuration) 87 | CATransaction.commit() 88 | } 89 | 90 | // MARK: Interaction Animation 91 | 92 | func interactionAnimation(reversed: Bool, a: Float = 0.5, b: Float = 1.0) { 93 | 94 | guard NSAccessibility.animationsEnabled else { 95 | return 96 | } 97 | 98 | CATransaction.begin() 99 | 100 | let hover = CABasicAnimation(keyPath: 101 | #keyPath(CALayer.opacity)) 102 | 103 | hover.isRemovedOnCompletion = true 104 | 105 | // 106 | 107 | if reversed { 108 | 109 | hover.fromValue = b 110 | hover.toValue = a 111 | 112 | self.layer!.opacity = a 113 | } 114 | 115 | else { 116 | 117 | hover.fromValue = a 118 | hover.toValue = b 119 | 120 | self.layer!.opacity = b 121 | } 122 | 123 | // 124 | hover.run(forKey: "transform", 125 | object: self.layer!, 126 | arguments: nil) 127 | 128 | CATransaction.setAnimationDuration(0.25) 129 | CATransaction.commit() 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /Universal/Colour Name Info.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Colour Name Info.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | #if os(macOS) 10 | 11 | import Cocoa 12 | 13 | #elseif os(iOS) 14 | 15 | import UIKit 16 | 17 | #endif 18 | 19 | 20 | // Colour identification by 'The Color API' 21 | // https://www.thecolorapi.com 22 | 23 | fileprivate let ColourAPIURL = "https://www.thecolorapi.com/id" 24 | 25 | 26 | /// Get the closest name for a colour (requires an active internet connection) 27 | /// - Parameter colour: Hmm, I wonder what this parameter could be... 28 | /// - Parameter session: The URL session to use for our data task. 29 | /// - Parameter completion: The block to call when the name becomes available (optional). 30 | func name(forColour colour: Colour, usingSession session: URLSession, completion: ((String?) -> ())? = nil) -> URLSessionDataTask? { 31 | 32 | guard let url = apiURL(forColour: colour) else { 33 | 34 | completion?(nil) 35 | return nil 36 | } 37 | 38 | // 39 | let request = URLRequest(url: url, 40 | cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, 41 | timeoutInterval: 30) 42 | 43 | // 44 | let task = session.dataTask(with: request) { data, _, error in 45 | 46 | guard let data = data, error == nil else { 47 | completion?(nil) 48 | return 49 | } 50 | 51 | // get the colour name from the response object 52 | let response = try? JSONSerialization 53 | .jsonObject(with: data, options: .allowFragments) as? [String: Any] 54 | 55 | let nameDict = response?["name"] as? [String: Any] 56 | let name = nameDict?["value"] as? String 57 | 58 | // 59 | completion?(name) 60 | } 61 | 62 | // 63 | task.resume() 64 | 65 | return task 66 | } 67 | 68 | /// Get a URL to use for a name identification request. 69 | /// - Parameter colour: The colour to use 70 | func apiURL(forColour colour: Colour) -> URL? { 71 | 72 | let hexRepresentation = hex(forColour: colour, withSymbol: false) 73 | 74 | // 75 | var components = URLComponents(string: ColourAPIURL) 76 | 77 | let hexParameter = URLQueryItem(name: "hex", value: hexRepresentation) 78 | components?.queryItems = [hexParameter] 79 | 80 | return components?.url 81 | } 82 | 83 | /// Get the hexadecimal value for a colour. (#rrggbb) 84 | /// - Parameter colour: The colour to 85 | func hex(forColour colour: Colour, withSymbol ws: Bool = true) -> String { 86 | 87 | // convert its components into their hexadecimal representations 88 | let rgb: String = colour.rgb 89 | .map { $0 * 255 } 90 | .map { $0.hexadecimalRepresentation } 91 | .joined() 92 | 93 | 94 | // 95 | return "\(ws ? "#" : "")\(rgb)" 96 | } 97 | 98 | /// Shows a colour in this format: rgb(r, g, b) 99 | /// - Parameter colour: The colour to use 100 | func rgb(forColour colour: Colour) -> String { 101 | 102 | let rgb = colour.rgb 103 | .map { String(Int($0 * 255)) } 104 | .joined(separator: ", ") 105 | 106 | return "rgb(\(rgb))" 107 | } 108 | -------------------------------------------------------------------------------- /Colours (iOS)/View Controllers/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FlexColorPicker 11 | import Hero 12 | 13 | 14 | let vColourPicker = "To Colour Picker" 15 | let vPalette = "To Generated Palette" 16 | 17 | class ViewController: UIViewController { 18 | 19 | @IBOutlet weak var colourView: ColourView! 20 | @IBOutlet weak var colourSchemePicker: UIPickerView! 21 | 22 | weak var colourPicker: DefaultColorPickerViewController? 23 | weak var paletteNavController: UINavigationController? 24 | 25 | let availableColourSchemes: [String] = [ 26 | "Monochromatic", 27 | "Complementary", 28 | "Split Complementary", 29 | "Triadic", 30 | "Tetradic", 31 | "Analogous" 32 | ] 33 | 34 | override func viewDidLoad() { 35 | 36 | super.viewDidLoad() 37 | 38 | // 39 | colourSchemePicker.dataSource = self 40 | colourSchemePicker.delegate = self 41 | 42 | // 43 | colourView.setup() 44 | 45 | // 46 | NotificationCenter.default.addObserver(self, selector: #selector(openColourPicker(_:)), name: nColourViewTapped, object: nil) 47 | } 48 | 49 | // MARK: Navigation 50 | 51 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 52 | 53 | if segue.identifier == vColourPicker { 54 | 55 | let colour = self.colourView.colour! 56 | let destination = segue.destination as! DefaultColorPickerViewController 57 | 58 | // 59 | destination.delegate = self 60 | destination.selectedColor = colour 61 | 62 | destination.hero.isEnabled = true 63 | 64 | // colour picker animation 65 | if UIAccessibility.isReduceMotionEnabled { 66 | 67 | destination.hero.modalAnimationType = .fade 68 | } 69 | 70 | else { 71 | 72 | destination.view.hero.modifiers = [.cascade] 73 | 74 | destination.colorPalette.hero.modifiers = 75 | [.fade, .scale(0.5)] 76 | 77 | destination.colorPreview.hero.modifiers = 78 | [.fade, .translate(x: 0.0, y: -50.0)] 79 | 80 | destination.brightnessSlider.hero.modifiers = 81 | [.fade, .translate(x: -100, y: 0.0)] 82 | } 83 | 84 | self.colourPicker = destination 85 | } 86 | 87 | else if segue.identifier == vPalette { 88 | 89 | // 90 | let destination = segue.destination as! UINavigationController 91 | let controller = destination.topViewController as! GeneratedPaletteCollectionViewController 92 | 93 | // 94 | let schemeRow = colourSchemePicker.selectedRow(inComponent: 0) 95 | let schemeName = self.availableColourSchemes[schemeRow] 96 | 97 | controller.title = "\(schemeName) Palette" 98 | 99 | // 100 | self.paletteNavController = destination 101 | 102 | // create and pass the selected palette to our destination 103 | let colourScheme = ColourScheme(rawValue: schemeName.lowercased())! 104 | 105 | let palette = colourView.colour! 106 | .colour(withColourSchemeName: colourScheme) 107 | 108 | // 109 | controller.colours = palette 110 | } 111 | } 112 | } 113 | 114 | -------------------------------------------------------------------------------- /Colours (iOS)/View Controllers/GeneratedPaletteCollectionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeneratedPaletteCollectionViewController.swift 3 | // Colours (iOS) 4 | // 5 | // Created by Emily Blackwell on 21/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Hero 11 | 12 | 13 | private let reuseIdentifier = "colourCell" 14 | let vDetail = "To Colour Detail" 15 | 16 | class GeneratedPaletteCollectionViewController: UICollectionViewController { 17 | 18 | var colours: [UIColor] = [] 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | } 23 | 24 | // MARK: Data Source 25 | 26 | override func numberOfSections(in collectionView: UICollectionView) -> Int { 27 | 28 | return 1 29 | } 30 | 31 | 32 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 33 | 34 | return self.colours.count 35 | } 36 | 37 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 38 | 39 | let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PaletteCellCollectionViewCell 40 | 41 | // Configure the cell 42 | let colour = self.colours[indexPath.item] 43 | 44 | cell.colourView.colour = colour 45 | cell.colourLabel.text = hex(forColour: colour) 46 | 47 | // cell animation 48 | if UIAccessibility.isReduceMotionEnabled { 49 | cell.hero.modifiers = [] 50 | } 51 | 52 | else { 53 | cell.hero.modifiers = [.fade, .scale(0.5)] 54 | } 55 | 56 | return cell 57 | } 58 | 59 | // MARK: Delegate 60 | 61 | override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 62 | 63 | let reducedMotionIsEnabled = UIAccessibility.isReduceMotionEnabled 64 | 65 | // 66 | let cell = collectionView.cellForItem(at: indexPath) as! PaletteCellCollectionViewCell 67 | 68 | cell.colourView.hero.id = "colourView" 69 | cell.colourLabel.hero.id = "hexLabel" 70 | 71 | // 72 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 73 | let detailVC = storyboard.instantiateViewController(withIdentifier: "Colour Detail") as! ColourDetailViewController 74 | 75 | // 76 | let colour = self.colours[indexPath.item] 77 | detailVC.colour = colour 78 | detailVC.cell = cell 79 | 80 | // transition animation 81 | 82 | if reducedMotionIsEnabled { 83 | detailVC.hero.isEnabled = false 84 | detailVC.hero.modalAnimationType = .fade 85 | } 86 | 87 | else { 88 | detailVC.hero.isEnabled = true 89 | detailVC.hero.modalAnimationType = .auto 90 | } 91 | 92 | // 93 | self.present(detailVC, animated: !reducedMotionIsEnabled) 94 | } 95 | } 96 | 97 | extension GeneratedPaletteCollectionViewController: UICollectionViewDelegateFlowLayout { 98 | 99 | // MARK: Layout 100 | // https://bit.ly/34Lmdag 101 | 102 | override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize { 103 | 104 | let aspectRatio: CGFloat = 268 / 265 105 | 106 | let width = self.view.frame.width / 4 107 | let height = width * aspectRatio 108 | 109 | print("\(width)x\(height)") 110 | 111 | return CGSize(width: width, height: height) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon-20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon-20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon-29.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon-29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "icon-29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon-40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "icon-40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "icon-57.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "icon-57@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "icon-60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "icon-60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "icon-20.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "icon-20@2x-1.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "icon-30.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "icon-29@2x-1.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "icon-40.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "icon-40@2x-1.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "76x76", 107 | "idiom" : "ipad", 108 | "filename" : "icon-76.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "76x76", 113 | "idiom" : "ipad", 114 | "filename" : "icon-76@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "83.5x83.5", 119 | "idiom" : "ipad", 120 | "filename" : "icon-83_5@2x.png", 121 | "scale" : "2x" 122 | }, 123 | { 124 | "size" : "1024x1024", 125 | "idiom" : "ios-marketing", 126 | "filename" : "icon-1024.png", 127 | "scale" : "1x" 128 | }, 129 | { 130 | "size" : "512x512", 131 | "idiom" : "mac", 132 | "filename" : "icon-512.png", 133 | "scale" : "1x" 134 | } 135 | ], 136 | "info" : { 137 | "version" : 1, 138 | "author" : "xcode" 139 | } 140 | } -------------------------------------------------------------------------------- /Colours/View (Controller) Extensions/ViewController + Actions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController + Actions.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 17/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | extension ViewController { 13 | 14 | // MARK: View Actions 15 | 16 | func readjustStackView() { 17 | 18 | // only animate our stack view if 'reduce motion' is disabled 19 | if #available(macOS 10.12, *), NSAccessibility.animationsEnabled { 20 | NSAnimationContext.runAnimationGroup { context in 21 | context.duration = 0.35 22 | context.allowsImplicitAnimation = true 23 | 24 | self.colourStackView.window?.layoutIfNeeded() 25 | } 26 | } 27 | 28 | else { 29 | self.colourStackView.window?.layoutIfNeeded() 30 | } 31 | } 32 | 33 | func removeColourViews() { 34 | 35 | for view in self.colourViews { 36 | view.remove() { 37 | self.readjustStackView() 38 | } 39 | } 40 | } 41 | 42 | func addColourViews(fromColours colours: [NSColor]) { 43 | 44 | // Remove old colour views from the stack view 45 | self.removeColourViews() 46 | 47 | // Create and insert new colour views into the stack view 48 | for (i, colour) in colours.enumerated() { 49 | 50 | let colourView = ColourView() 51 | colourView.colour = colour 52 | 53 | self.colourStackView.addArrangedSubview(colourView) 54 | self.colourViews.append(colourView) 55 | 56 | colourView.setup(delay: (TimeInterval(i) * 0.045)) 57 | } 58 | 59 | self.readjustStackView() 60 | } 61 | 62 | // MARK: IB Actions 63 | 64 | @IBAction func generateColourScheme(sender: AnyObject) { 65 | 66 | let colour = self.colourWell.color 67 | let schemeName = self.colourScheme.stringValue.lowercased() 68 | 69 | guard let scheme = ColourScheme(rawValue: schemeName) else { 70 | 71 | self.alert(title: "err-tCSN".l, 72 | message: "err-mCSN".l, 73 | style: .warning) 74 | 75 | return 76 | } 77 | 78 | let palette = colour.colour(withColourSchemeName: scheme) 79 | self.addColourViews(fromColours: palette) 80 | } 81 | 82 | @IBAction func switchColourScheme(sender: NSMenuItem) { 83 | 84 | colourScheme.selectItem(at: sender.tag) 85 | } 86 | 87 | @IBAction func changeColourScheme(sender: AnyObject) { 88 | 89 | let selectedRow = colourScheme.indexOfSelectedItem 90 | 91 | // 92 | switch sender.tag { 93 | 94 | // forward 95 | case 0: 96 | 97 | if selectedRow > 0 { 98 | colourScheme.selectItem(at: selectedRow - 1) 99 | } 100 | 101 | case 1: 102 | 103 | if selectedRow < 5 { 104 | colourScheme.selectItem(at: selectedRow + 1) 105 | } 106 | 107 | default: 108 | break 109 | } 110 | } 111 | 112 | // MARK: Notification Centre 113 | 114 | @available (macOS 10.12.2, *) 115 | @objc func touchbarColourSelected(_ notification: NSNotification) { 116 | 117 | self.colourWell.color = TouchbarColourPicker.color 118 | } 119 | 120 | @available (macOS 10.12.2, *) 121 | @objc func colourSelectedOnWell(_ notification: NSNotification) { 122 | 123 | TouchbarColourPicker.color = self.colourWell.color 124 | } 125 | 126 | @objc func openDetailPopover(_ notification: NSNotification) { 127 | 128 | // 129 | let colourView = notification.object as! ColourView 130 | let colour = notification.userInfo![kColour] as! NSColor 131 | 132 | // 133 | let storyboard = NSStoryboard(name: "Main", bundle: nil) 134 | 135 | let viewController = storyboard.instantiateController(withIdentifier: kDetailID) as! ColourDetailViewController 136 | 137 | viewController.colour = colour 138 | 139 | // open the detail popover below the selected colour view 140 | let popover = NSPopover() 141 | 142 | popover.contentViewController = viewController 143 | popover.behavior = .transient 144 | 145 | popover.show(relativeTo: colourView.bounds, 146 | of: colourView, 147 | preferredEdge: .minY) 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /Universal/Colour Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Colour Extensions.swift 3 | // Colours 4 | // 5 | // Created by Emily Blackwell on 17/12/2019. 6 | // Copyright © 2019 Emily Blackwell. All rights reserved. 7 | // 8 | 9 | #if os(macOS) 10 | 11 | import Cocoa 12 | typealias Colour = NSColor 13 | 14 | #elseif os(iOS) 15 | 16 | import UIKit 17 | typealias Colour = UIColor 18 | 19 | // apparently, UIKit doesn't have Cocoa's colour blending functions 20 | extension UIColor { 21 | 22 | /// Get this colour's red, green, and blue components 23 | var UIRGB: [CGFloat] { 24 | get { 25 | var red: CGFloat = 0.0 26 | var green: CGFloat = 0.0 27 | var blue: CGFloat = 0.0 28 | 29 | self.getRed(&red, 30 | green: &green, 31 | blue: &blue, 32 | alpha: nil) 33 | 34 | return [red, green, blue] 35 | } 36 | } 37 | 38 | /// Mix two colours together 39 | /// - Parameter a: The main colour 40 | /// - Parameter b: The colour to add 41 | /// - Parameter factor: How much of b should be added to a (0.0 - 1.0) 42 | func mix(a: UIColor, b: UIColor, factor: CGFloat) -> UIColor { 43 | 44 | let strengthB = factor.withBoundaries(min: 0.0, max: 1.0) 45 | let strengthA = 1.0 - strengthB 46 | 47 | let aRGB = a.UIRGB 48 | let bRGB = b.UIRGB 49 | 50 | // blend the colours together (factor determines B's strength) 51 | let frgb = zip(aRGB, bRGB) 52 | .map { ($0 * strengthA) + ($1 * strengthB) } 53 | 54 | // 55 | let mixedColour = UIColor(red: frgb[0], 56 | green: frgb[1], 57 | blue: frgb[2], 58 | alpha: 1.0) 59 | 60 | return mixedColour 61 | } 62 | 63 | /// Get a lighter variant of this colour 64 | /// - Parameter level: How much white should be added to this colour 65 | func highlight(withLevel level: CGFloat) -> UIColor! { 66 | 67 | return self.mix(a: self, b: .white, factor: level) 68 | } 69 | 70 | /// Get a darker variant of this colour 71 | /// - Parameter level: How much black should be added to this colour 72 | func shadow(withLevel level: CGFloat) -> UIColor! { 73 | 74 | return self.mix(a: self, b: .black, factor: level) 75 | } 76 | 77 | /// Get this colour's brightness value 78 | var brightnessComponent: CGFloat { 79 | get { 80 | var brightness: CGFloat = 0.0 81 | 82 | self.getHue(nil, 83 | saturation: nil, 84 | brightness: &brightness, 85 | alpha: nil) 86 | 87 | return brightness 88 | } 89 | } 90 | } 91 | 92 | #endif 93 | 94 | 95 | /// This decides how the generator picks colours for its palette 96 | enum ColourScheme: String { 97 | case monochromatic = "monochromatic" 98 | case complementary = "complementary" 99 | case splitComplementary = "split complementary" 100 | case triadic = "triadic" 101 | case tetradic = "tetradic" 102 | case analogous = "analogous" 103 | } 104 | 105 | 106 | extension Colour { 107 | 108 | // MARK: Colour Properties 109 | 110 | #if os(macOS) 111 | 112 | /// This property returns the user's selected accent colour in macOS Mojave or later; 113 | /// or the standard system blue colour in earlier versions. 114 | static var controlColour: NSColor { 115 | get { 116 | if #available(macOS 10.14, *) { 117 | return .controlAccentColor 118 | } else { 119 | return .systemBlue 120 | } 121 | } 122 | } 123 | 124 | #endif 125 | 126 | /// Get this colour's hue, saturation, lightness, and alpha properties. 127 | /// This returns four zeroes if colourspace conversation fails. 128 | var hsla: [CGFloat] { 129 | get { 130 | 131 | #if os(macOS) 132 | 133 | // Convert colour to the RGB colourspace in macOS. 134 | guard let colour = self.usingColorSpaceName(.deviceRGB) else { 135 | return [0.0, 0.0, 0.0, 0.0] 136 | } 137 | 138 | #else 139 | let colour = self 140 | #endif 141 | 142 | // 143 | var hue: CGFloat = 0.0 144 | var saturation: CGFloat = 0.0 145 | var lightness: CGFloat = 0.0 146 | var alpha: CGFloat = 0.0 147 | 148 | // 149 | colour.getHue(&hue, 150 | saturation: &saturation, 151 | brightness: &lightness, 152 | alpha: &alpha) 153 | 154 | // 155 | return [hue, saturation, lightness, alpha] 156 | } 157 | } 158 | 159 | /// Get this colour's red, green, blue components 160 | /// this returns three zeroes, if colourspace conversion fails 161 | var rgb: [CGFloat] { 162 | get { 163 | 164 | #if os(macOS) 165 | 166 | guard let colour = self.usingColorSpace(.deviceRGB) else { 167 | return [0, 0, 0] 168 | } 169 | 170 | // 171 | return [ 172 | colour.redComponent, 173 | colour.greenComponent, 174 | colour.blueComponent 175 | ] 176 | 177 | #elseif os(iOS) 178 | 179 | return self.UIRGB 180 | 181 | #endif 182 | } 183 | } 184 | 185 | /// This function creates a new HSL colour based on a given offset. 186 | /// - Parameter offset: Offset from the original hue 187 | func colour(withHueOffset offset: CGFloat) -> Colour { 188 | 189 | let hsla = self.hsla 190 | let angle = fmod(hsla[0] + offset, 1) 191 | 192 | return Colour(hue: angle, 193 | saturation: hsla[1], 194 | brightness: hsla[2], 195 | alpha: hsla[3]) 196 | } 197 | 198 | // MARK: Colour Schemes 199 | // https://bit.ly/34woUwF 200 | 201 | /// This generates a palette consisting of the various tones and shades of the same colour 202 | var monochromatic: [Colour] { 203 | get { 204 | var colours: [Colour] = [] 205 | 206 | for level in 1 ..< 7 { 207 | 208 | let level = CGFloat(level) / 7 209 | 210 | guard let colourA = self.highlight(withLevel: level), 211 | let colourB = self.shadow(withLevel: level) else { 212 | continue 213 | } 214 | 215 | colours.append(colourA) 216 | colours.append(colourB) 217 | } 218 | 219 | return colours.sorted { 220 | return $0.brightnessComponent < $1.brightnessComponent 221 | } 222 | } 223 | } 224 | 225 | /// This generates a two-colour palette consisting of opposite colours on the colour wheel 226 | var complementary: [Colour] { 227 | get { 228 | return [ 229 | self, 230 | colour(withHueOffset: 0.5) 231 | ] 232 | } 233 | } 234 | 235 | /// This generates a three-colour palette consisting of the base colour and two adjacent colours on the colour wheel. 236 | var splitComplementary: [Colour] { 237 | get { 238 | return [ 239 | self, 240 | colour(withHueOffset: 0.416), 241 | colour(withHueOffset: 0.583) 242 | ] 243 | } 244 | } 245 | 246 | /// This generates a three-colour palette using evenly-spaced colours on the colour wheel. 247 | var triadic: [Colour] { 248 | get { 249 | return [ 250 | self, 251 | colour(withHueOffset: 0.333), 252 | colour(withHueOffset: 0.666) 253 | ] 254 | } 255 | } 256 | 257 | /// This generates a four-colour palette using two complementary pairs. 258 | var tetradic: [Colour] { 259 | get { 260 | return [ 261 | self, 262 | colour(withHueOffset: 0.25), 263 | self.complementary[1], 264 | colour(withHueOffset: 0.75) 265 | ] 266 | } 267 | } 268 | 269 | /// This generates three-colour palette using colours that are next to one another on the colour wheel. 270 | var analogous: [Colour] { 271 | get { 272 | return [ 273 | self, 274 | colour(withHueOffset: -0.0833), 275 | colour(withHueOffset: 0.0833) 276 | ] 277 | } 278 | } 279 | 280 | /// This function returns an array of colours based on a given colour scheme name 281 | /// - Parameter name: complementary, tetradic, etc. 282 | func colour(withColourSchemeName scheme: ColourScheme) -> [Colour] { 283 | 284 | switch scheme { 285 | case .monochromatic: 286 | return self.monochromatic 287 | 288 | case .complementary: 289 | return self.complementary 290 | 291 | case .splitComplementary: 292 | return self.splitComplementary 293 | 294 | case .triadic: 295 | return self.triadic 296 | 297 | case .tetradic: 298 | return self.tetradic 299 | 300 | case .analogous: 301 | return self.analogous 302 | } 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /Colours.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A10E6B1A23A7FA6400719A6E /* ColourView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10E6B1923A7FA6400719A6E /* ColourView.swift */; }; 11 | A10E6B1C23A80EA700719A6E /* ViewController + Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10E6B1B23A80EA700719A6E /* ViewController + Actions.swift */; }; 12 | A1142FFB23A848F400F0D012 /* ColourView + Mouse Input.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1142FFA23A848F400F0D012 /* ColourView + Mouse Input.swift */; }; 13 | A1142FFF23A84F3E00F0D012 /* ColourDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1142FFE23A84F3D00F0D012 /* ColourDetailViewController.swift */; }; 14 | A118EDB223AE2B5F00BEF3A7 /* Colour Name Info.swift in Sources */ = {isa = PBXBuildFile; fileRef = A118EDB123AE2B5F00BEF3A7 /* Colour Name Info.swift */; }; 15 | A118EDB423AE2F9500BEF3A7 /* CG Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A118EDB323AE2F9400BEF3A7 /* CG Extensions.swift */; }; 16 | A17B14B123B1DD4100222DB7 /* ColourView + Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17B14B023B1DD4100222DB7 /* ColourView + Actions.swift */; }; 17 | A17B14B323B1F00100222DB7 /* TouchbarOutletWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17B14B223B1F00000222DB7 /* TouchbarOutletWindowController.swift */; }; 18 | A182A3A123B07F3400F96E8B /* ColourView + Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = A182A3A023B07F3400F96E8B /* ColourView + Animations.swift */; }; 19 | A18C994F23AE78EB008F142C /* Hero in Frameworks */ = {isa = PBXBuildFile; productRef = A18C994E23AE78EB008F142C /* Hero */; }; 20 | A18C995323AEA1C2008F142C /* ColourDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A18C995223AEA1C2008F142C /* ColourDetailViewController.swift */; }; 21 | A18C995523AEB116008F142C /* ColourDetailView + Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A18C995423AEB116008F142C /* ColourDetailView + Actions.swift */; }; 22 | A1AB94F523AA112D000346A6 /* Cocoa Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1AB94F423AA112D000346A6 /* Cocoa Extensions.swift */; }; 23 | A1AB94F823AA17A7000346A6 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1AB94F723AA17A7000346A6 /* Localizable.strings */; }; 24 | A1ADE29C23B0489B006E9BDF /* ColourView + Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1ADE29B23B0489B006E9BDF /* ColourView + Animations.swift */; }; 25 | A1BAAAC423A7DCAA001B670C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1BAAAC323A7DCAA001B670C /* AppDelegate.swift */; }; 26 | A1BAAAC623A7DCAA001B670C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1BAAAC523A7DCAA001B670C /* ViewController.swift */; }; 27 | A1BAAAC823A7DCBE001B670C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1BAAAC723A7DCBE001B670C /* Assets.xcassets */; }; 28 | A1BAAACB23A7DCBE001B670C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1BAAAC923A7DCBE001B670C /* Main.storyboard */; }; 29 | A1BAAAD423A7E24B001B670C /* Colour Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1BAAAD323A7E24B001B670C /* Colour Extensions.swift */; }; 30 | A1F5076023AE510D002387B6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5075F23AE510D002387B6 /* AppDelegate.swift */; }; 31 | A1F5076223AE510D002387B6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5076123AE510D002387B6 /* SceneDelegate.swift */; }; 32 | A1F5076423AE510D002387B6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5076323AE510D002387B6 /* ViewController.swift */; }; 33 | A1F5076723AE510D002387B6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1F5076523AE510D002387B6 /* Main.storyboard */; }; 34 | A1F5076923AE5120002387B6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1F5076823AE5120002387B6 /* Assets.xcassets */; }; 35 | A1F5076C23AE5120002387B6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1F5076A23AE5120002387B6 /* LaunchScreen.storyboard */; }; 36 | A1F5077223AE51A4002387B6 /* CG Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A118EDB323AE2F9400BEF3A7 /* CG Extensions.swift */; }; 37 | A1F5077323AE51A6002387B6 /* Colour Name Info.swift in Sources */ = {isa = PBXBuildFile; fileRef = A118EDB123AE2B5F00BEF3A7 /* Colour Name Info.swift */; }; 38 | A1F5077423AE51B4002387B6 /* Colour Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1BAAAD323A7E24B001B670C /* Colour Extensions.swift */; }; 39 | A1F5077B23AE5721002387B6 /* FlexColorPicker in Frameworks */ = {isa = PBXBuildFile; productRef = A1F5077A23AE5721002387B6 /* FlexColorPicker */; }; 40 | A1F5077D23AE5838002387B6 /* ColourView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5077C23AE5837002387B6 /* ColourView.swift */; }; 41 | A1F5077F23AE5A5D002387B6 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1AB94F723AA17A7000346A6 /* Localizable.strings */; }; 42 | A1F5078123AE5C97002387B6 /* ViewController + Colour Scheme Picker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5078023AE5C97002387B6 /* ViewController + Colour Scheme Picker.swift */; }; 43 | A1F5078323AE617E002387B6 /* ColourView + Touch Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5078223AE617E002387B6 /* ColourView + Touch Events.swift */; }; 44 | A1F5078623AE6623002387B6 /* ViewController + Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5078523AE6623002387B6 /* ViewController + Actions.swift */; }; 45 | A1F5078823AE6633002387B6 /* ViewController + Colour Picker Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5078723AE6633002387B6 /* ViewController + Colour Picker Delegate.swift */; }; 46 | A1F5078A23AE71DB002387B6 /* PaletteCellCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5078923AE71DB002387B6 /* PaletteCellCollectionViewCell.swift */; }; 47 | A1F5078C23AE7713002387B6 /* GeneratedPaletteCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F5078B23AE7712002387B6 /* GeneratedPaletteCollectionViewController.swift */; }; 48 | /* End PBXBuildFile section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | A10E6B1923A7FA6400719A6E /* ColourView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColourView.swift; sourceTree = ""; }; 52 | A10E6B1B23A80EA700719A6E /* ViewController + Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController + Actions.swift"; sourceTree = ""; }; 53 | A1142FFA23A848F400F0D012 /* ColourView + Mouse Input.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColourView + Mouse Input.swift"; sourceTree = ""; }; 54 | A1142FFE23A84F3D00F0D012 /* ColourDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColourDetailViewController.swift; sourceTree = ""; }; 55 | A118EDB123AE2B5F00BEF3A7 /* Colour Name Info.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Colour Name Info.swift"; sourceTree = ""; }; 56 | A118EDB323AE2F9400BEF3A7 /* CG Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CG Extensions.swift"; sourceTree = ""; }; 57 | A17B14B023B1DD4100222DB7 /* ColourView + Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColourView + Actions.swift"; sourceTree = ""; }; 58 | A17B14B223B1F00000222DB7 /* TouchbarOutletWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchbarOutletWindowController.swift; sourceTree = ""; }; 59 | A182A3A023B07F3400F96E8B /* ColourView + Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColourView + Animations.swift"; sourceTree = ""; }; 60 | A18C995223AEA1C2008F142C /* ColourDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColourDetailViewController.swift; sourceTree = ""; }; 61 | A18C995423AEB116008F142C /* ColourDetailView + Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColourDetailView + Actions.swift"; sourceTree = ""; }; 62 | A1AB94F423AA112D000346A6 /* Cocoa Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Cocoa Extensions.swift"; sourceTree = ""; }; 63 | A1AB94F723AA17A7000346A6 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; 64 | A1ADE29B23B0489B006E9BDF /* ColourView + Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColourView + Animations.swift"; sourceTree = ""; }; 65 | A1BAAAC023A7DCAA001B670C /* Colours.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Colours.app; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | A1BAAAC323A7DCAA001B670C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 67 | A1BAAAC523A7DCAA001B670C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 68 | A1BAAAC723A7DCBE001B670C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 69 | A1BAAACA23A7DCBE001B670C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 70 | A1BAAACC23A7DCBE001B670C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | A1BAAACD23A7DCBE001B670C /* Colours.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Colours.entitlements; sourceTree = ""; }; 72 | A1BAAAD323A7E24B001B670C /* Colour Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Colour Extensions.swift"; sourceTree = ""; }; 73 | A1F5075D23AE510D002387B6 /* Colours.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Colours.app; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | A1F5075F23AE510D002387B6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 75 | A1F5076123AE510D002387B6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 76 | A1F5076323AE510D002387B6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 77 | A1F5076623AE510D002387B6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 78 | A1F5076823AE5120002387B6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 79 | A1F5076B23AE5120002387B6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 80 | A1F5076D23AE5120002387B6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 81 | A1F5077C23AE5837002387B6 /* ColourView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColourView.swift; sourceTree = ""; }; 82 | A1F5078023AE5C97002387B6 /* ViewController + Colour Scheme Picker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController + Colour Scheme Picker.swift"; sourceTree = ""; }; 83 | A1F5078223AE617E002387B6 /* ColourView + Touch Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ColourView + Touch Events.swift"; sourceTree = ""; }; 84 | A1F5078523AE6623002387B6 /* ViewController + Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController + Actions.swift"; sourceTree = ""; }; 85 | A1F5078723AE6633002387B6 /* ViewController + Colour Picker Delegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController + Colour Picker Delegate.swift"; sourceTree = ""; }; 86 | A1F5078923AE71DB002387B6 /* PaletteCellCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaletteCellCollectionViewCell.swift; sourceTree = ""; }; 87 | A1F5078B23AE7712002387B6 /* GeneratedPaletteCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneratedPaletteCollectionViewController.swift; sourceTree = ""; }; 88 | /* End PBXFileReference section */ 89 | 90 | /* Begin PBXFrameworksBuildPhase section */ 91 | A1BAAABD23A7DCAA001B670C /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | A1F5075A23AE510C002387B6 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | A18C994F23AE78EB008F142C /* Hero in Frameworks */, 103 | A1F5077B23AE5721002387B6 /* FlexColorPicker in Frameworks */, 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | /* End PBXFrameworksBuildPhase section */ 108 | 109 | /* Begin PBXGroup section */ 110 | A1142FFC23A84F1200F0D012 /* View \ Window Controllers */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | A1BAAAC523A7DCAA001B670C /* ViewController.swift */, 114 | A1142FFE23A84F3D00F0D012 /* ColourDetailViewController.swift */, 115 | A17B14B223B1F00000222DB7 /* TouchbarOutletWindowController.swift */, 116 | ); 117 | path = "View \\ Window Controllers"; 118 | sourceTree = ""; 119 | }; 120 | A1142FFD23A84F1C00F0D012 /* Views */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | A10E6B1923A7FA6400719A6E /* ColourView.swift */, 124 | ); 125 | path = Views; 126 | sourceTree = ""; 127 | }; 128 | A118EDB523AE417B00BEF3A7 /* View (Controller) Extensions */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | A1142FFA23A848F400F0D012 /* ColourView + Mouse Input.swift */, 132 | A1ADE29B23B0489B006E9BDF /* ColourView + Animations.swift */, 133 | A10E6B1B23A80EA700719A6E /* ViewController + Actions.swift */, 134 | ); 135 | path = "View (Controller) Extensions"; 136 | sourceTree = ""; 137 | }; 138 | A1AB94F623AA113E000346A6 /* Extensions */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | A1AB94F423AA112D000346A6 /* Cocoa Extensions.swift */, 142 | ); 143 | path = Extensions; 144 | sourceTree = ""; 145 | }; 146 | A1AB94F923AA17B2000346A6 /* Assets */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | A1BAAACD23A7DCBE001B670C /* Colours.entitlements */, 150 | A1BAAACC23A7DCBE001B670C /* Info.plist */, 151 | A1BAAAC723A7DCBE001B670C /* Assets.xcassets */, 152 | A1BAAAC923A7DCBE001B670C /* Main.storyboard */, 153 | ); 154 | name = Assets; 155 | sourceTree = ""; 156 | }; 157 | A1AB94FA23AA1918000346A6 /* Others */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | A1BAAAC323A7DCAA001B670C /* AppDelegate.swift */, 161 | ); 162 | path = Others; 163 | sourceTree = ""; 164 | }; 165 | A1BAAAB723A7DCAA001B670C = { 166 | isa = PBXGroup; 167 | children = ( 168 | A1F5077123AE5150002387B6 /* Universal */, 169 | A1BAAAC223A7DCAA001B670C /* Colours */, 170 | A1F5075E23AE510D002387B6 /* Colours (iOS) */, 171 | A1BAAAC123A7DCAA001B670C /* Products */, 172 | ); 173 | sourceTree = ""; 174 | }; 175 | A1BAAAC123A7DCAA001B670C /* Products */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | A1BAAAC023A7DCAA001B670C /* Colours.app */, 179 | A1F5075D23AE510D002387B6 /* Colours.app */, 180 | ); 181 | name = Products; 182 | sourceTree = ""; 183 | }; 184 | A1BAAAC223A7DCAA001B670C /* Colours */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | A1AB94FA23AA1918000346A6 /* Others */, 188 | A1AB94F923AA17B2000346A6 /* Assets */, 189 | A1AB94F623AA113E000346A6 /* Extensions */, 190 | A1142FFC23A84F1200F0D012 /* View \ Window Controllers */, 191 | A118EDB523AE417B00BEF3A7 /* View (Controller) Extensions */, 192 | A1142FFD23A84F1C00F0D012 /* Views */, 193 | ); 194 | path = Colours; 195 | sourceTree = ""; 196 | }; 197 | A1F5075E23AE510D002387B6 /* Colours (iOS) */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | A1F5077823AE5675002387B6 /* Others */, 201 | A1F5077723AE5669002387B6 /* Assets */, 202 | A1F5077523AE564E002387B6 /* Delegates */, 203 | A1F5077623AE565C002387B6 /* View Controllers */, 204 | A1F5077E23AE5844002387B6 /* Views */, 205 | A1F5078423AE6183002387B6 /* View (Controller) Extensions */, 206 | ); 207 | path = "Colours (iOS)"; 208 | sourceTree = ""; 209 | }; 210 | A1F5077123AE5150002387B6 /* Universal */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | A118EDB323AE2F9400BEF3A7 /* CG Extensions.swift */, 214 | A118EDB123AE2B5F00BEF3A7 /* Colour Name Info.swift */, 215 | A1BAAAD323A7E24B001B670C /* Colour Extensions.swift */, 216 | A1AB94F723AA17A7000346A6 /* Localizable.strings */, 217 | ); 218 | path = Universal; 219 | sourceTree = ""; 220 | }; 221 | A1F5077523AE564E002387B6 /* Delegates */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | A1F5075F23AE510D002387B6 /* AppDelegate.swift */, 225 | A1F5076123AE510D002387B6 /* SceneDelegate.swift */, 226 | ); 227 | path = Delegates; 228 | sourceTree = ""; 229 | }; 230 | A1F5077623AE565C002387B6 /* View Controllers */ = { 231 | isa = PBXGroup; 232 | children = ( 233 | A1F5076323AE510D002387B6 /* ViewController.swift */, 234 | A1F5078B23AE7712002387B6 /* GeneratedPaletteCollectionViewController.swift */, 235 | A18C995223AEA1C2008F142C /* ColourDetailViewController.swift */, 236 | ); 237 | path = "View Controllers"; 238 | sourceTree = ""; 239 | }; 240 | A1F5077723AE5669002387B6 /* Assets */ = { 241 | isa = PBXGroup; 242 | children = ( 243 | A1F5076523AE510D002387B6 /* Main.storyboard */, 244 | A1F5076A23AE5120002387B6 /* LaunchScreen.storyboard */, 245 | A1F5076823AE5120002387B6 /* Assets.xcassets */, 246 | ); 247 | path = Assets; 248 | sourceTree = ""; 249 | }; 250 | A1F5077823AE5675002387B6 /* Others */ = { 251 | isa = PBXGroup; 252 | children = ( 253 | A1F5076D23AE5120002387B6 /* Info.plist */, 254 | ); 255 | name = Others; 256 | sourceTree = ""; 257 | }; 258 | A1F5077E23AE5844002387B6 /* Views */ = { 259 | isa = PBXGroup; 260 | children = ( 261 | A1F5078923AE71DB002387B6 /* PaletteCellCollectionViewCell.swift */, 262 | A1F5077C23AE5837002387B6 /* ColourView.swift */, 263 | ); 264 | path = Views; 265 | sourceTree = ""; 266 | }; 267 | A1F5078423AE6183002387B6 /* View (Controller) Extensions */ = { 268 | isa = PBXGroup; 269 | children = ( 270 | A17B14B023B1DD4100222DB7 /* ColourView + Actions.swift */, 271 | A1F5078223AE617E002387B6 /* ColourView + Touch Events.swift */, 272 | A182A3A023B07F3400F96E8B /* ColourView + Animations.swift */, 273 | A1F5078523AE6623002387B6 /* ViewController + Actions.swift */, 274 | A1F5078023AE5C97002387B6 /* ViewController + Colour Scheme Picker.swift */, 275 | A1F5078723AE6633002387B6 /* ViewController + Colour Picker Delegate.swift */, 276 | A18C995423AEB116008F142C /* ColourDetailView + Actions.swift */, 277 | ); 278 | path = "View (Controller) Extensions"; 279 | sourceTree = ""; 280 | }; 281 | /* End PBXGroup section */ 282 | 283 | /* Begin PBXNativeTarget section */ 284 | A1BAAABF23A7DCAA001B670C /* Colours */ = { 285 | isa = PBXNativeTarget; 286 | buildConfigurationList = A1BAAAD023A7DCBE001B670C /* Build configuration list for PBXNativeTarget "Colours" */; 287 | buildPhases = ( 288 | A1BAAABC23A7DCAA001B670C /* Sources */, 289 | A1BAAABD23A7DCAA001B670C /* Frameworks */, 290 | A1BAAABE23A7DCAA001B670C /* Resources */, 291 | ); 292 | buildRules = ( 293 | ); 294 | dependencies = ( 295 | ); 296 | name = Colours; 297 | productName = Colours; 298 | productReference = A1BAAAC023A7DCAA001B670C /* Colours.app */; 299 | productType = "com.apple.product-type.application"; 300 | }; 301 | A1F5075C23AE510C002387B6 /* Colours (iOS) */ = { 302 | isa = PBXNativeTarget; 303 | buildConfigurationList = A1F5077023AE5120002387B6 /* Build configuration list for PBXNativeTarget "Colours (iOS)" */; 304 | buildPhases = ( 305 | A1F5075923AE510C002387B6 /* Sources */, 306 | A1F5075A23AE510C002387B6 /* Frameworks */, 307 | A1F5075B23AE510C002387B6 /* Resources */, 308 | ); 309 | buildRules = ( 310 | ); 311 | dependencies = ( 312 | ); 313 | name = "Colours (iOS)"; 314 | packageProductDependencies = ( 315 | A1F5077A23AE5721002387B6 /* FlexColorPicker */, 316 | A18C994E23AE78EB008F142C /* Hero */, 317 | ); 318 | productName = "Colours (iOS)"; 319 | productReference = A1F5075D23AE510D002387B6 /* Colours.app */; 320 | productType = "com.apple.product-type.application"; 321 | }; 322 | /* End PBXNativeTarget section */ 323 | 324 | /* Begin PBXProject section */ 325 | A1BAAAB823A7DCAA001B670C /* Project object */ = { 326 | isa = PBXProject; 327 | attributes = { 328 | LastSwiftUpdateCheck = 1110; 329 | LastUpgradeCheck = 1110; 330 | ORGANIZATIONNAME = "Emily Blackwell"; 331 | TargetAttributes = { 332 | A1BAAABF23A7DCAA001B670C = { 333 | CreatedOnToolsVersion = 11.1; 334 | }; 335 | A1F5075C23AE510C002387B6 = { 336 | CreatedOnToolsVersion = 11.1; 337 | }; 338 | }; 339 | }; 340 | buildConfigurationList = A1BAAABB23A7DCAA001B670C /* Build configuration list for PBXProject "Colours" */; 341 | compatibilityVersion = "Xcode 9.3"; 342 | developmentRegion = en; 343 | hasScannedForEncodings = 0; 344 | knownRegions = ( 345 | en, 346 | Base, 347 | ); 348 | mainGroup = A1BAAAB723A7DCAA001B670C; 349 | packageReferences = ( 350 | A1F5077923AE5721002387B6 /* XCRemoteSwiftPackageReference "FlexColorPicker" */, 351 | A18C994D23AE78EB008F142C /* XCRemoteSwiftPackageReference "Hero" */, 352 | ); 353 | productRefGroup = A1BAAAC123A7DCAA001B670C /* Products */; 354 | projectDirPath = ""; 355 | projectRoot = ""; 356 | targets = ( 357 | A1BAAABF23A7DCAA001B670C /* Colours */, 358 | A1F5075C23AE510C002387B6 /* Colours (iOS) */, 359 | ); 360 | }; 361 | /* End PBXProject section */ 362 | 363 | /* Begin PBXResourcesBuildPhase section */ 364 | A1BAAABE23A7DCAA001B670C /* Resources */ = { 365 | isa = PBXResourcesBuildPhase; 366 | buildActionMask = 2147483647; 367 | files = ( 368 | A1BAAAC823A7DCBE001B670C /* Assets.xcassets in Resources */, 369 | A1AB94F823AA17A7000346A6 /* Localizable.strings in Resources */, 370 | A1BAAACB23A7DCBE001B670C /* Main.storyboard in Resources */, 371 | ); 372 | runOnlyForDeploymentPostprocessing = 0; 373 | }; 374 | A1F5075B23AE510C002387B6 /* Resources */ = { 375 | isa = PBXResourcesBuildPhase; 376 | buildActionMask = 2147483647; 377 | files = ( 378 | A1F5076C23AE5120002387B6 /* LaunchScreen.storyboard in Resources */, 379 | A1F5077F23AE5A5D002387B6 /* Localizable.strings in Resources */, 380 | A1F5076923AE5120002387B6 /* Assets.xcassets in Resources */, 381 | A1F5076723AE510D002387B6 /* Main.storyboard in Resources */, 382 | ); 383 | runOnlyForDeploymentPostprocessing = 0; 384 | }; 385 | /* End PBXResourcesBuildPhase section */ 386 | 387 | /* Begin PBXSourcesBuildPhase section */ 388 | A1BAAABC23A7DCAA001B670C /* Sources */ = { 389 | isa = PBXSourcesBuildPhase; 390 | buildActionMask = 2147483647; 391 | files = ( 392 | A1142FFB23A848F400F0D012 /* ColourView + Mouse Input.swift in Sources */, 393 | A10E6B1C23A80EA700719A6E /* ViewController + Actions.swift in Sources */, 394 | A1BAAAD423A7E24B001B670C /* Colour Extensions.swift in Sources */, 395 | A1BAAAC623A7DCAA001B670C /* ViewController.swift in Sources */, 396 | A17B14B323B1F00100222DB7 /* TouchbarOutletWindowController.swift in Sources */, 397 | A10E6B1A23A7FA6400719A6E /* ColourView.swift in Sources */, 398 | A1142FFF23A84F3E00F0D012 /* ColourDetailViewController.swift in Sources */, 399 | A1AB94F523AA112D000346A6 /* Cocoa Extensions.swift in Sources */, 400 | A1ADE29C23B0489B006E9BDF /* ColourView + Animations.swift in Sources */, 401 | A1BAAAC423A7DCAA001B670C /* AppDelegate.swift in Sources */, 402 | A118EDB223AE2B5F00BEF3A7 /* Colour Name Info.swift in Sources */, 403 | A118EDB423AE2F9500BEF3A7 /* CG Extensions.swift in Sources */, 404 | ); 405 | runOnlyForDeploymentPostprocessing = 0; 406 | }; 407 | A1F5075923AE510C002387B6 /* Sources */ = { 408 | isa = PBXSourcesBuildPhase; 409 | buildActionMask = 2147483647; 410 | files = ( 411 | A1F5078623AE6623002387B6 /* ViewController + Actions.swift in Sources */, 412 | A1F5077423AE51B4002387B6 /* Colour Extensions.swift in Sources */, 413 | A1F5076423AE510D002387B6 /* ViewController.swift in Sources */, 414 | A1F5078C23AE7713002387B6 /* GeneratedPaletteCollectionViewController.swift in Sources */, 415 | A1F5077323AE51A6002387B6 /* Colour Name Info.swift in Sources */, 416 | A182A3A123B07F3400F96E8B /* ColourView + Animations.swift in Sources */, 417 | A1F5078A23AE71DB002387B6 /* PaletteCellCollectionViewCell.swift in Sources */, 418 | A18C995523AEB116008F142C /* ColourDetailView + Actions.swift in Sources */, 419 | A1F5077D23AE5838002387B6 /* ColourView.swift in Sources */, 420 | A1F5078823AE6633002387B6 /* ViewController + Colour Picker Delegate.swift in Sources */, 421 | A1F5078323AE617E002387B6 /* ColourView + Touch Events.swift in Sources */, 422 | A1F5077223AE51A4002387B6 /* CG Extensions.swift in Sources */, 423 | A18C995323AEA1C2008F142C /* ColourDetailViewController.swift in Sources */, 424 | A1F5076023AE510D002387B6 /* AppDelegate.swift in Sources */, 425 | A1F5076223AE510D002387B6 /* SceneDelegate.swift in Sources */, 426 | A1F5078123AE5C97002387B6 /* ViewController + Colour Scheme Picker.swift in Sources */, 427 | A17B14B123B1DD4100222DB7 /* ColourView + Actions.swift in Sources */, 428 | ); 429 | runOnlyForDeploymentPostprocessing = 0; 430 | }; 431 | /* End PBXSourcesBuildPhase section */ 432 | 433 | /* Begin PBXVariantGroup section */ 434 | A1BAAAC923A7DCBE001B670C /* Main.storyboard */ = { 435 | isa = PBXVariantGroup; 436 | children = ( 437 | A1BAAACA23A7DCBE001B670C /* Base */, 438 | ); 439 | name = Main.storyboard; 440 | sourceTree = ""; 441 | }; 442 | A1F5076523AE510D002387B6 /* Main.storyboard */ = { 443 | isa = PBXVariantGroup; 444 | children = ( 445 | A1F5076623AE510D002387B6 /* Base */, 446 | ); 447 | name = Main.storyboard; 448 | sourceTree = ""; 449 | }; 450 | A1F5076A23AE5120002387B6 /* LaunchScreen.storyboard */ = { 451 | isa = PBXVariantGroup; 452 | children = ( 453 | A1F5076B23AE5120002387B6 /* Base */, 454 | ); 455 | name = LaunchScreen.storyboard; 456 | sourceTree = ""; 457 | }; 458 | /* End PBXVariantGroup section */ 459 | 460 | /* Begin XCBuildConfiguration section */ 461 | A1BAAACE23A7DCBE001B670C /* Debug */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | ALWAYS_SEARCH_USER_PATHS = NO; 465 | CLANG_ANALYZER_NONNULL = YES; 466 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 467 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 468 | CLANG_CXX_LIBRARY = "libc++"; 469 | CLANG_ENABLE_MODULES = YES; 470 | CLANG_ENABLE_OBJC_ARC = YES; 471 | CLANG_ENABLE_OBJC_WEAK = YES; 472 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 473 | CLANG_WARN_BOOL_CONVERSION = YES; 474 | CLANG_WARN_COMMA = YES; 475 | CLANG_WARN_CONSTANT_CONVERSION = YES; 476 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 477 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 478 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 479 | CLANG_WARN_EMPTY_BODY = YES; 480 | CLANG_WARN_ENUM_CONVERSION = YES; 481 | CLANG_WARN_INFINITE_RECURSION = YES; 482 | CLANG_WARN_INT_CONVERSION = YES; 483 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 484 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 485 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 486 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 487 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 488 | CLANG_WARN_STRICT_PROTOTYPES = YES; 489 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 490 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 491 | CLANG_WARN_UNREACHABLE_CODE = YES; 492 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 493 | COPY_PHASE_STRIP = NO; 494 | DEBUG_INFORMATION_FORMAT = dwarf; 495 | ENABLE_STRICT_OBJC_MSGSEND = YES; 496 | ENABLE_TESTABILITY = YES; 497 | GCC_C_LANGUAGE_STANDARD = gnu11; 498 | GCC_DYNAMIC_NO_PIC = NO; 499 | GCC_NO_COMMON_BLOCKS = YES; 500 | GCC_OPTIMIZATION_LEVEL = 0; 501 | GCC_PREPROCESSOR_DEFINITIONS = ( 502 | "DEBUG=1", 503 | "$(inherited)", 504 | ); 505 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 506 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 507 | GCC_WARN_UNDECLARED_SELECTOR = YES; 508 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 509 | GCC_WARN_UNUSED_FUNCTION = YES; 510 | GCC_WARN_UNUSED_VARIABLE = YES; 511 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 512 | MACOSX_DEPLOYMENT_TARGET = 10.11; 513 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 514 | MTL_FAST_MATH = YES; 515 | ONLY_ACTIVE_ARCH = YES; 516 | SDKROOT = macosx; 517 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 518 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 519 | }; 520 | name = Debug; 521 | }; 522 | A1BAAACF23A7DCBE001B670C /* Release */ = { 523 | isa = XCBuildConfiguration; 524 | buildSettings = { 525 | ALWAYS_SEARCH_USER_PATHS = NO; 526 | CLANG_ANALYZER_NONNULL = YES; 527 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 528 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 529 | CLANG_CXX_LIBRARY = "libc++"; 530 | CLANG_ENABLE_MODULES = YES; 531 | CLANG_ENABLE_OBJC_ARC = YES; 532 | CLANG_ENABLE_OBJC_WEAK = YES; 533 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 534 | CLANG_WARN_BOOL_CONVERSION = YES; 535 | CLANG_WARN_COMMA = YES; 536 | CLANG_WARN_CONSTANT_CONVERSION = YES; 537 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 538 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 539 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 540 | CLANG_WARN_EMPTY_BODY = YES; 541 | CLANG_WARN_ENUM_CONVERSION = YES; 542 | CLANG_WARN_INFINITE_RECURSION = YES; 543 | CLANG_WARN_INT_CONVERSION = YES; 544 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 545 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 546 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 547 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 548 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 549 | CLANG_WARN_STRICT_PROTOTYPES = YES; 550 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 551 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 552 | CLANG_WARN_UNREACHABLE_CODE = YES; 553 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 554 | COPY_PHASE_STRIP = NO; 555 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 556 | ENABLE_NS_ASSERTIONS = NO; 557 | ENABLE_STRICT_OBJC_MSGSEND = YES; 558 | GCC_C_LANGUAGE_STANDARD = gnu11; 559 | GCC_NO_COMMON_BLOCKS = YES; 560 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 561 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 562 | GCC_WARN_UNDECLARED_SELECTOR = YES; 563 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 564 | GCC_WARN_UNUSED_FUNCTION = YES; 565 | GCC_WARN_UNUSED_VARIABLE = YES; 566 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 567 | MACOSX_DEPLOYMENT_TARGET = 10.11; 568 | MTL_ENABLE_DEBUG_INFO = NO; 569 | MTL_FAST_MATH = YES; 570 | SDKROOT = macosx; 571 | SWIFT_COMPILATION_MODE = wholemodule; 572 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 573 | }; 574 | name = Release; 575 | }; 576 | A1BAAAD123A7DCBE001B670C /* Debug */ = { 577 | isa = XCBuildConfiguration; 578 | buildSettings = { 579 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 580 | CODE_SIGN_ENTITLEMENTS = Colours/Colours.entitlements; 581 | CODE_SIGN_STYLE = Automatic; 582 | COMBINE_HIDPI_IMAGES = YES; 583 | DEVELOPMENT_TEAM = 4VC3JB53HL; 584 | ENABLE_HARDENED_RUNTIME = YES; 585 | INFOPLIST_FILE = Colours/Info.plist; 586 | LD_RUNPATH_SEARCH_PATHS = ( 587 | "$(inherited)", 588 | "@executable_path/../Frameworks", 589 | ); 590 | PRODUCT_BUNDLE_IDENTIFIER = me.emilyblackwell.Colours; 591 | PRODUCT_NAME = "$(TARGET_NAME)"; 592 | SWIFT_VERSION = 5.0; 593 | }; 594 | name = Debug; 595 | }; 596 | A1BAAAD223A7DCBE001B670C /* Release */ = { 597 | isa = XCBuildConfiguration; 598 | buildSettings = { 599 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 600 | CODE_SIGN_ENTITLEMENTS = Colours/Colours.entitlements; 601 | CODE_SIGN_STYLE = Automatic; 602 | COMBINE_HIDPI_IMAGES = YES; 603 | DEVELOPMENT_TEAM = 4VC3JB53HL; 604 | ENABLE_HARDENED_RUNTIME = YES; 605 | INFOPLIST_FILE = Colours/Info.plist; 606 | LD_RUNPATH_SEARCH_PATHS = ( 607 | "$(inherited)", 608 | "@executable_path/../Frameworks", 609 | ); 610 | PRODUCT_BUNDLE_IDENTIFIER = me.emilyblackwell.Colours; 611 | PRODUCT_NAME = "$(TARGET_NAME)"; 612 | SWIFT_VERSION = 5.0; 613 | }; 614 | name = Release; 615 | }; 616 | A1F5076E23AE5120002387B6 /* Debug */ = { 617 | isa = XCBuildConfiguration; 618 | buildSettings = { 619 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 620 | CODE_SIGN_STYLE = Automatic; 621 | DEVELOPMENT_TEAM = 4VC3JB53HL; 622 | INFOPLIST_FILE = "Colours (iOS)/Info.plist"; 623 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 624 | LD_RUNPATH_SEARCH_PATHS = ( 625 | "$(inherited)", 626 | "@executable_path/Frameworks", 627 | ); 628 | PRODUCT_BUNDLE_IDENTIFIER = "me.emilyblackwell.Colours-iOS"; 629 | PRODUCT_NAME = Colours; 630 | SDKROOT = iphoneos; 631 | SWIFT_VERSION = 5.0; 632 | TARGETED_DEVICE_FAMILY = "1,2"; 633 | }; 634 | name = Debug; 635 | }; 636 | A1F5076F23AE5120002387B6 /* Release */ = { 637 | isa = XCBuildConfiguration; 638 | buildSettings = { 639 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 640 | CODE_SIGN_STYLE = Automatic; 641 | DEVELOPMENT_TEAM = 4VC3JB53HL; 642 | INFOPLIST_FILE = "Colours (iOS)/Info.plist"; 643 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 644 | LD_RUNPATH_SEARCH_PATHS = ( 645 | "$(inherited)", 646 | "@executable_path/Frameworks", 647 | ); 648 | PRODUCT_BUNDLE_IDENTIFIER = "me.emilyblackwell.Colours-iOS"; 649 | PRODUCT_NAME = Colours; 650 | SDKROOT = iphoneos; 651 | SWIFT_VERSION = 5.0; 652 | TARGETED_DEVICE_FAMILY = "1,2"; 653 | VALIDATE_PRODUCT = YES; 654 | }; 655 | name = Release; 656 | }; 657 | /* End XCBuildConfiguration section */ 658 | 659 | /* Begin XCConfigurationList section */ 660 | A1BAAABB23A7DCAA001B670C /* Build configuration list for PBXProject "Colours" */ = { 661 | isa = XCConfigurationList; 662 | buildConfigurations = ( 663 | A1BAAACE23A7DCBE001B670C /* Debug */, 664 | A1BAAACF23A7DCBE001B670C /* Release */, 665 | ); 666 | defaultConfigurationIsVisible = 0; 667 | defaultConfigurationName = Release; 668 | }; 669 | A1BAAAD023A7DCBE001B670C /* Build configuration list for PBXNativeTarget "Colours" */ = { 670 | isa = XCConfigurationList; 671 | buildConfigurations = ( 672 | A1BAAAD123A7DCBE001B670C /* Debug */, 673 | A1BAAAD223A7DCBE001B670C /* Release */, 674 | ); 675 | defaultConfigurationIsVisible = 0; 676 | defaultConfigurationName = Release; 677 | }; 678 | A1F5077023AE5120002387B6 /* Build configuration list for PBXNativeTarget "Colours (iOS)" */ = { 679 | isa = XCConfigurationList; 680 | buildConfigurations = ( 681 | A1F5076E23AE5120002387B6 /* Debug */, 682 | A1F5076F23AE5120002387B6 /* Release */, 683 | ); 684 | defaultConfigurationIsVisible = 0; 685 | defaultConfigurationName = Release; 686 | }; 687 | /* End XCConfigurationList section */ 688 | 689 | /* Begin XCRemoteSwiftPackageReference section */ 690 | A18C994D23AE78EB008F142C /* XCRemoteSwiftPackageReference "Hero" */ = { 691 | isa = XCRemoteSwiftPackageReference; 692 | repositoryURL = "https://github.com/HeroTransitions/Hero"; 693 | requirement = { 694 | kind = upToNextMajorVersion; 695 | minimumVersion = 1.5.0; 696 | }; 697 | }; 698 | A1F5077923AE5721002387B6 /* XCRemoteSwiftPackageReference "FlexColorPicker" */ = { 699 | isa = XCRemoteSwiftPackageReference; 700 | repositoryURL = "https://github.com/RastislavMirek/FlexColorPicker"; 701 | requirement = { 702 | kind = upToNextMajorVersion; 703 | minimumVersion = 1.3.1; 704 | }; 705 | }; 706 | /* End XCRemoteSwiftPackageReference section */ 707 | 708 | /* Begin XCSwiftPackageProductDependency section */ 709 | A18C994E23AE78EB008F142C /* Hero */ = { 710 | isa = XCSwiftPackageProductDependency; 711 | package = A18C994D23AE78EB008F142C /* XCRemoteSwiftPackageReference "Hero" */; 712 | productName = Hero; 713 | }; 714 | A1F5077A23AE5721002387B6 /* FlexColorPicker */ = { 715 | isa = XCSwiftPackageProductDependency; 716 | package = A1F5077923AE5721002387B6 /* XCRemoteSwiftPackageReference "FlexColorPicker" */; 717 | productName = FlexColorPicker; 718 | }; 719 | /* End XCSwiftPackageProductDependency section */ 720 | }; 721 | rootObject = A1BAAAB823A7DCAA001B670C /* Project object */; 722 | } 723 | -------------------------------------------------------------------------------- /Colours (iOS)/Assets/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 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 | 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 | 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 | 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 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 345 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 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 | 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 | --------------------------------------------------------------------------------