├── Cartfile
├── Cartfile.resolved
├── Images
├── screen1.png
├── screen2.png
├── screen3.png
└── pencilcup.png
├── Example
├── PencilCup.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── PencilCup.xcscmblueprint
├── PencilCup.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── PencilCup-Example.xcscheme
│ └── project.pbxproj
└── PencilCup
│ ├── Drawable.swift
│ ├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── ColorViewController.swift
│ ├── AppDelegate.swift
│ ├── PencilCupView.swift
│ ├── DrawView.swift
│ ├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
│ ├── CoreGraphicsView.swift
│ └── InkWell.swift
├── .travis.yml
├── Sources
├── ContextRect.swift
├── ContextPoint.swift
├── ContextMisc.swift
├── ContextPath.swift
└── ContextRef.swift
├── .gitignore
├── XcodeSnippets
├── PencilCup_Dot.codesnippet
├── PencilCup_FillPath.codesnippet
├── PencilCup_StrokePath.codesnippet
├── PencilCup_MoveToPoint.codesnippet
├── PencilCup_AddLineToPoint.codesnippet
└── PencilCup_AddCurveToPoint.codesnippet
├── LICENSE
└── README.md
/Cartfile:
--------------------------------------------------------------------------------
1 | github "joalbright/Inlinit"
2 |
--------------------------------------------------------------------------------
/Cartfile.resolved:
--------------------------------------------------------------------------------
1 | github "joalbright/Inlinit" "0.1.3"
2 |
--------------------------------------------------------------------------------
/Images/screen1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joalbright/PencilCup/HEAD/Images/screen1.png
--------------------------------------------------------------------------------
/Images/screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joalbright/PencilCup/HEAD/Images/screen2.png
--------------------------------------------------------------------------------
/Images/screen3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joalbright/PencilCup/HEAD/Images/screen3.png
--------------------------------------------------------------------------------
/Images/pencilcup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joalbright/PencilCup/HEAD/Images/pencilcup.png
--------------------------------------------------------------------------------
/Example/PencilCup.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/PencilCup.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # references:
2 | # * http://www.objc.io/issue-6/travis-ci.html
3 | # * https://github.com/supermarin/xcpretty#usage
4 |
5 | language: objective-c
6 | # cache: cocoapods
7 | # podfile: Example/Podfile
8 | # before_install:
9 | # - gem install cocoapods # Since Travis is not always on latest version
10 | # - pod install --project-directory=Example
11 | script:
12 | - set -o pipefail && xcodebuild test -workspace Example/PencilCup.xcworkspace -scheme PencilCup-Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty
13 | - pod lib lint
14 |
--------------------------------------------------------------------------------
/Example/PencilCup/Drawable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Drawable.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/6/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public protocol Drawable {
12 |
13 | }
14 |
15 | extension Drawable {
16 |
17 | public func drawLines(_ context: CGContext?, lines: [CGLine]) {
18 |
19 | _ = context?.round()
20 |
21 | for line in lines {
22 |
23 | _ = line.drawPoints(context?.color(line.fill))?.fill()
24 | _ = line.drawPoints(context?.color(line.stroke))?.line(line.strokeWidth)?.stroke()
25 |
26 | }
27 |
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/Example/PencilCup/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Sources/ContextRect.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContextRect.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/4/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension CGRect {
12 |
13 | var center: CGPoint { return CGPoint(x: midX, y: midY) }
14 |
15 | /// Inset all four sides with d
16 | func inset(_ d: CGFloat) -> CGRect {
17 |
18 | return insetBy(dx: d, dy: d)
19 |
20 | }
21 |
22 | func pointOnCircleInRect(_ degree: CGFloat) -> CGPoint {
23 |
24 | return CGPoint {
25 |
26 | $0.x = (width) * cos(degree * CGFloat(M_PI / 180)) / 2 + center.x
27 | $0.y = (height) * sin(degree * CGFloat(M_PI / 180)) / 2 + center.y
28 |
29 | }
30 |
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | Carthage
26 | # We recommend against adding the Pods directory to your .gitignore. However
27 | # you should judge for yourself, the pros and cons are mentioned at:
28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
29 | #
30 | # Note: if you ignore the Pods directory, make sure to uncomment
31 | # `pod install` in .travis.yml
32 | #
33 | # Pods/
34 |
35 | .build/
36 | Packages/
37 |
38 | _Pods.xcodeproj
39 |
40 | PencilCup.podspec
41 |
--------------------------------------------------------------------------------
/XcodeSnippets/PencilCup_Dot.codesnippet:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDECodeSnippetCompletionPrefix
6 | dot
7 | IDECodeSnippetCompletionScopes
8 |
9 | CodeBlock
10 |
11 | IDECodeSnippetContents
12 | -•- <# Point #>
13 | IDECodeSnippetIdentifier
14 | 5A77FBC3-7A17-4E47-A204-AB9EA87A42F9
15 | IDECodeSnippetLanguage
16 | Xcode.SourceCodeLanguage.Swift
17 | IDECodeSnippetTitle
18 | CGContext Dot
19 | IDECodeSnippetUserSnippet
20 |
21 | IDECodeSnippetVersion
22 | 2
23 |
24 |
25 |
--------------------------------------------------------------------------------
/XcodeSnippets/PencilCup_FillPath.codesnippet:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDECodeSnippetCompletionPrefix
6 | fill
7 | IDECodeSnippetCompletionScopes
8 |
9 | All
10 |
11 | IDECodeSnippetContents
12 | -■ <# Next #>
13 | IDECodeSnippetIdentifier
14 | B285393C-2754-449F-9C7B-3CA7E97C99AC
15 | IDECodeSnippetLanguage
16 | Xcode.SourceCodeLanguage.Swift
17 | IDECodeSnippetTitle
18 | CGContext Fill Path
19 | IDECodeSnippetUserSnippet
20 |
21 | IDECodeSnippetVersion
22 | 2
23 |
24 |
25 |
--------------------------------------------------------------------------------
/XcodeSnippets/PencilCup_StrokePath.codesnippet:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDECodeSnippetCompletionPrefix
6 | stroke
7 | IDECodeSnippetCompletionScopes
8 |
9 | All
10 |
11 | IDECodeSnippetContents
12 | -□ <# Next #>
13 | IDECodeSnippetIdentifier
14 | 6B13E7EA-064D-42B8-9E95-32755C14433C
15 | IDECodeSnippetLanguage
16 | Xcode.SourceCodeLanguage.Swift
17 | IDECodeSnippetTitle
18 | CGContext Stroke Path
19 | IDECodeSnippetUserSnippet
20 |
21 | IDECodeSnippetVersion
22 | 2
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Sources/ContextPoint.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContexCGPoint.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/6/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension CGPoint: Inlinit { }
12 |
13 | public struct CGLine: Inlinit {
14 |
15 | public var points: [CGPoint] = []
16 | public var strokeWidth: CGFloat = 0
17 |
18 | public var fill: CGColor?
19 | public var stroke: CGColor?
20 |
21 | public init() { }
22 |
23 | public func drawPoints(_ context: CGContext?) -> CGContext? {
24 |
25 | for (p,point) in points.enumerated() {
26 |
27 | if point == .zero { continue }
28 | _ = p == 0 ? { context ->- point }() : { context -+- point }()
29 |
30 | }
31 |
32 | return context
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/XcodeSnippets/PencilCup_MoveToPoint.codesnippet:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDECodeSnippetCompletionPrefix
6 | move
7 | IDECodeSnippetCompletionScopes
8 |
9 | All
10 |
11 | IDECodeSnippetContents
12 | ->- <# Move to Point #>
13 | IDECodeSnippetIdentifier
14 | FE81D6E4-A12B-485E-869F-650D96FD9DA1
15 | IDECodeSnippetLanguage
16 | Xcode.SourceCodeLanguage.Swift
17 | IDECodeSnippetTitle
18 | CGContext Move to Point
19 | IDECodeSnippetUserSnippet
20 |
21 | IDECodeSnippetVersion
22 | 2
23 |
24 |
25 |
--------------------------------------------------------------------------------
/XcodeSnippets/PencilCup_AddLineToPoint.codesnippet:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDECodeSnippetCompletionPrefix
6 | add
7 | IDECodeSnippetCompletionScopes
8 |
9 | All
10 |
11 | IDECodeSnippetContents
12 | -+- <# Add Line to Point #>
13 | IDECodeSnippetIdentifier
14 | 7D6F57D2-BC92-4ECE-B768-C33E0DD73607
15 | IDECodeSnippetLanguage
16 | Xcode.SourceCodeLanguage.Swift
17 | IDECodeSnippetTitle
18 | CGContext Add Line to Point
19 | IDECodeSnippetUserSnippet
20 |
21 | IDECodeSnippetVersion
22 | 2
23 |
24 |
25 |
--------------------------------------------------------------------------------
/XcodeSnippets/PencilCup_AddCurveToPoint.codesnippet:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDECodeSnippetCompletionPrefix
6 | add
7 | IDECodeSnippetCompletionScopes
8 |
9 | All
10 |
11 | IDECodeSnippetContents
12 | -~- <# Add Curve to Point #>
13 | IDECodeSnippetIdentifier
14 | 168A4F19-B263-433B-B33D-F653800E8AA7
15 | IDECodeSnippetLanguage
16 | Xcode.SourceCodeLanguage.Swift
17 | IDECodeSnippetTitle
18 | CGContext Add Curve to Point
19 | IDECodeSnippetUserSnippet
20 |
21 | IDECodeSnippetVersion
22 | 2
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Jo Albright
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Example/PencilCup/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Example/PencilCup/ColorViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ColorViewController.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/8/16.
6 | // Copyright © 2016 CocoaPods. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ColorViewController: UIViewController {
12 |
13 | @IBOutlet weak var wheel: ColorWheel!
14 |
15 | @IBOutlet weak var hueBar: ColorBar!
16 |
17 | @IBOutlet weak var saturationBar: ColorBar!
18 |
19 | @IBOutlet weak var brightnessBar: ColorBar!
20 |
21 | @IBOutlet weak var alphaBar: ColorBar!
22 |
23 | override func viewDidLoad() {
24 | super.viewDidLoad()
25 |
26 | // Do any additional setup after loading the view.
27 | }
28 |
29 | @IBAction func hueChanged(_ bar: ColorBar) {
30 |
31 | print(bar.value)
32 |
33 | saturationBar.h = bar.value / 360
34 | brightnessBar.h = bar.value / 360
35 | alphaBar.h = bar.value / 360
36 |
37 | }
38 |
39 | @IBAction func brightnessChanged(_ bar: ColorBar) {
40 |
41 | saturationBar.b = bar.value
42 | alphaBar.b = bar.value
43 |
44 |
45 | }
46 |
47 | @IBAction func saturationChanged(_ bar: ColorBar) {
48 |
49 | brightnessBar.s = bar.value
50 | alphaBar.s = bar.value
51 |
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/Example/PencilCup.xcworkspace/xcshareddata/PencilCup.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "F423E37263D1CD1B20A383A95421A3124300B2D8",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 |
5 | },
6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7 | "F423E37263D1CD1B20A383A95421A3124300B2D8" : 9223372036854775807,
8 | "BC7D22AD9EBFA3958907C65E8D59AF07B67456E4" : 9223372036854775807
9 | },
10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "F90C44F9-36AD-4600-B650-8C2148F32A71",
11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12 | "F423E37263D1CD1B20A383A95421A3124300B2D8" : "PencilCup\/",
13 | "BC7D22AD9EBFA3958907C65E8D59AF07B67456E4" : "Relax\/"
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "PencilCup",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/PencilCup.xcworkspace",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/joalbright\/Relax.git",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BC7D22AD9EBFA3958907C65E8D59AF07B67456E4"
23 | },
24 | {
25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/joalbright\/PencilCup.git",
26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "F423E37263D1CD1B20A383A95421A3124300B2D8"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/Sources/ContextMisc.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContextMisc.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 10/28/15.
6 | // Copyright © 2015 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | typealias TPoint = (x: CGFloat, y: CGFloat)
12 | public typealias TCurve = (a1: CGPoint, a2: CGPoint, p: CGPoint)
13 | public typealias TSize = (width: CGFloat, height: CGFloat)
14 | public typealias TScale = (x: CGFloat, y: CGFloat)
15 | public typealias TDelta = (dx: CGFloat, dy: CGFloat)
16 |
17 | /// Update left CGPoint with offset of right CGPoint
18 | public func += (lhs: inout CGPoint, rhs: CGPoint) {
19 |
20 | lhs.x += rhs.x; lhs.y += rhs.y
21 |
22 | }
23 |
24 | /// Add right point to left point
25 | /// - returns: CGPoint
26 | public func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
27 |
28 | return CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
29 |
30 | }
31 |
32 | /// Subtract right point from left point
33 | /// - returns: CGPoint
34 | public func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
35 |
36 | return CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
37 |
38 | }
39 |
40 | /// Multiple right to left (x&&y)
41 | public func * (lhs: CGPoint, rhs: CGFloat) -> CGPoint {
42 |
43 | return CGPoint(x: lhs.x * rhs, y: lhs.y * rhs)
44 |
45 | }
46 |
47 | // MARK: - CGSize Operators
48 |
49 | /// Scale a CGSize by CGFloat value
50 | /// - returns: CGSize
51 | public func * (lhs: CGSize, rhs: CGFloat) -> CGSize {
52 |
53 | return CGSize(width: lhs.width * rhs, height: lhs.height * rhs)
54 |
55 | }
56 |
57 | /// Scale a CGSize by CGFloat value
58 | /// - returns: CGSize
59 | public func * (lhs: TSize, rhs: CGFloat) -> TSize {
60 |
61 | return (width: lhs.width * rhs, height: lhs.height * rhs)
62 |
63 | }
64 |
65 |
66 | extension CGFloat {
67 |
68 | init(_ n: CGFloat, min: CGFloat, max: CGFloat) {
69 |
70 | self = n
71 | if n < min { self = min }
72 | if n > max { self = max }
73 |
74 | }
75 |
76 | init(_ n: CGFloat, range: Range) {
77 |
78 | self = n
79 | if n < CGFloat(range.lowerBound) { self = CGFloat(range.lowerBound) }
80 | if n > CGFloat(range.upperBound) { self = CGFloat(range.upperBound) }
81 |
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/Example/PencilCup/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 01/05/2016.
6 | // Copyright (c) 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Sources/ContextPath.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContextPath.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/4/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | /// Move To Point Operator
13 | infix operator ->- : AdditionPrecedence
14 |
15 | /// CGContext Move To Point
16 | func ->- (lhs: CGContext?, rhs: CGPoint) -> CGContext? {
17 |
18 | lhs?.move(to: rhs); return lhs
19 |
20 | }
21 |
22 | func ->- (lhs: CGContext?, rhs: TPoint) -> CGContext? {
23 |
24 | lhs?.move(to: CGPoint(x: rhs.x, y: rhs.y)); return lhs
25 |
26 | }
27 |
28 |
29 | /// Add Line To Point Operator
30 | infix operator -+- : AdditionPrecedence
31 |
32 | /// CGContext Add Line To Point
33 | func -+- (lhs: CGContext?, rhs: CGPoint) -> CGContext? {
34 |
35 | lhs?.addLine(to: rhs); return lhs
36 |
37 | }
38 |
39 | func -+- (lhs: CGContext?, rhs: TPoint) -> CGContext? {
40 |
41 | lhs?.addLine(to: CGPoint(x: rhs.x, y: rhs.y)); return lhs
42 |
43 | }
44 |
45 |
46 | /// Add Curve To Point Operator
47 | infix operator -~- : AdditionPrecedence
48 |
49 | /// Add Curve To Point
50 | func -~- (lhs: CGContext?, rhs: (CGPoint,CGPoint,CGPoint)) -> CGContext? {
51 |
52 | lhs?.addCurve(to: rhs.2, control1: rhs.0, control2: rhs.1); return lhs
53 |
54 | }
55 |
56 | func -~- (lhs: CGContext?, rhs: (TPoint,TPoint,TPoint)) -> CGContext? {
57 |
58 | lhs?.addCurve(to: CGPoint(x: rhs.2.x, y: rhs.2.y), control1: CGPoint(x: rhs.0.x, y: rhs.0.y), control2: CGPoint(x: rhs.1.x, y: rhs.1.y)); return lhs
59 |
60 | }
61 |
62 | func -~- (lhs: CGContext?, rhs: (CGFloat,CGFloat,CGFloat,CGFloat,CGFloat,CGFloat)) -> CGContext? {
63 |
64 | lhs?.addCurve(to: CGPoint(x: rhs.4, y: rhs.5), control1: CGPoint(x: rhs.0, y: rhs.1), control2: CGPoint(x: rhs.2, y: rhs.3)); return lhs
65 |
66 | }
67 |
68 |
69 | /// Dot Operator
70 | /// - description : Line with start and end points that are equal with a stroke width and round cap.
71 | infix operator -•- : AdditionPrecedence
72 |
73 | /// CGContext Create Dot : Diameter = Stroke Width
74 | func -•- (lhs: CGContext?, rhs: CGPoint) -> CGContext? {
75 |
76 | return lhs ->- rhs -+- rhs -□ nil
77 |
78 | }
79 |
80 |
81 | /// Fill Path Operator
82 | infix operator -■ : AdditionPrecedence
83 |
84 | /// CGContext Fill Path
85 | /// - discussion : rhs gets set before fill
86 | func -■ (lhs: CGContext?, rhs: CGColor?) -> CGContext? {
87 |
88 | if let rhs = rhs { lhs?.setFillColor(rhs) }
89 | lhs?.fillPath(); return lhs
90 |
91 | }
92 |
93 |
94 | /// Stroke Path Operator
95 | infix operator -□ : AdditionPrecedence
96 |
97 | /// CGContext Stroke Path
98 | /// - discussion : rhs gets set before stroke
99 | func -□ (lhs: CGContext?, rhs: CGColor?) -> CGContext? {
100 |
101 | if let rhs = rhs { lhs?.setStrokeColor(rhs) }
102 | lhs?.strokePath(); return lhs
103 |
104 | }
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/Example/PencilCup/PencilCupView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PencilCupView.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/4/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @IBDesignable class PencilCupView: UIView {
12 |
13 | override func draw(_ rect: CGRect) {
14 |
15 | let (bgColor,cupColor) = (UIColor(white: 0.9, alpha: 1).cgColor, UIColor(white: 0.2, alpha: 1).cgColor)
16 |
17 | let context = UIGraphicsGetCurrentContext()?.round()?.color(bgColor)?.rect(rect)?.fill()
18 | _ = context?.color(cupColor)?.round()?.line(1)?.offset((rect.width - 188) / 2, (rect.height - 300) / 2)
19 |
20 | _ = context ->- (126.01,89.44) -~- (116.37,89.19,105.65,89.06,94.35,89.06) -~- (52.35,89.06,18.3,90.8,18.3,94.24)
21 | _ = context -~- (18.3,97.68,52.35,101.51,94.35,101.51) -~- (104.7,101.51,114.57,101.28,123.57,100.87) -+- (126.01,89.44) -■ nil
22 |
23 | _ = context ->- (140,99.75) -+- (150.28,49.72) -~- (150.5,48.64,151.56,47.94,152.64,48.17) -+- (162.37,50.18)
24 | _ = context -~- (163.46,50.4,164.15,51.46,163.93,52.54) -+- (154.43,98.52) -□ nil
25 |
26 | _ = context ->- (159.39,13.91) -~- (160.85,14.62,162.41,15.16,164.07,15.5) -~- (165.71,15.84,167.36,15.97,168.96,15.9)
27 | _ = context -~- (170.55,15.83,171.69,14.33,171.39,12.77) -+- (169.3,2.12) -~- (168.85,-0.16,165.88,-0.78,164.56,1.14)
28 | _ = context -+- (158.41,10.08) -~- (157.51,11.39,157.96,13.22,159.39,13.91) -■ nil
29 |
30 | _ = context ->- (159.39,13.91) -~- (160.85,14.62,162.41,15.16,164.07,15.5) -~- (165.71,15.84,167.36,15.97,168.96,15.9)
31 | _ = context -~- (170.55,15.83,171.69,14.33,171.39,12.77) -+- (169.3,2.12) -~- (168.85,-0.16,165.88,-0.78,164.56,1.14)
32 | _ = context -+- (158.41,10.08) -~- (157.51,11.39,157.96,13.22,159.39,13.91) -□ nil
33 |
34 | _ = context ->- (137.79,100.12) -+- (148.47,48.45) -~- (148.64,47.62,148.27,46.77,147.54,46.33) -+- (141.06,42.43)
35 | _ = context -~- (139.87,41.72,138.35,42.39,138.07,43.74) -+- (126.28,100.81) -□ nil
36 |
37 | _ = context ->- (158.41,10.08) -+- (140.27,38.9) ->- (176.92,46.09) -+- (171.39,12.77) -□ nil
38 |
39 | _ = context ->- (167.6,96.07) -+- (176.74,51.79) -~- (177.02,50.42,175.86,49.2,174.48,49.4) -+- (167.77,50.43)
40 | _ = context -~- (166.94,50.55,166.28,51.18,166.11,52) -+- (156.58,98.15) -□ nil
41 |
42 | _ = context ->- (30.06,218.44) -~- (30.06,221.19,27.83,223.42,25.08,223.42) -+- (24.83,223.42)
43 | _ = context -~- (22.08,223.42,19.84,221.19,19.84,218.44) -+- (19.84,138.67) -~- (19.84,135.92,22.08,133.69,24.83,133.69)
44 | _ = context -+- (25.08,133.69) -~- (27.83,133.69,30.06,135.92,30.06,138.67) -+- (30.06,218.44)
45 |
46 | _ = context ->- (174.9,100.03) -~- (161.84,103.04,137.31,106.55,94,106.55) -~- (50.69,106.55,26.17,103.04,13.1,100.03)
47 | _ = context -~- (6.38,98.48,-0.04,103.61,-0.04,110.51) -+- (-0.04,274.38) -~- (-0.04,281.03,4.04,286.99,10.23,289.4)
48 | _ = context -~- (22.22,294.07,46.74,300,94,300) -~- (141.26,300,165.78,294.07,177.77,289.4)
49 | _ = context -~- (183.96,286.99,188.04,281.03,188.04,274.38) -+- (188.04,110.51) -~- (188.04,103.61,181.62,98.48,174.9,100.03) -■ nil
50 |
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Example/PencilCup/DrawView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DrawView.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/6/16.
6 | // Copyright © 2016 CocoaPods. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DrawView: UIView, Drawable {
12 |
13 | var lines: [CGLine] = [] { didSet { setNeedsDisplay() } }
14 |
15 | override func draw(_ rect: CGRect) {
16 |
17 | drawLines(UIGraphicsGetCurrentContext(), lines: lines)
18 |
19 | }
20 |
21 | override func layoutSubviews() {
22 |
23 | /// Placeholder demo lines ... uncomment to test
24 | // lines = [CGLine] {
25 | //
26 | // for _ in 0...3 {
27 | //
28 | // $0.append(CGLine {
29 | //
30 | // $0.strokeWidth = CGFloat(drand48()) * 20
31 | //
32 | // for _ in 0...10 {
33 | //
34 | // $0.points.append(CGPoint {
35 | //
36 | // $0.x = CGFloat(drand48()) * UIScreen.mainScreen().bounds.width
37 | // $0.y = CGFloat(drand48()) * UIScreen.mainScreen().bounds.height
38 | //
39 | // })
40 | //
41 | // }
42 | //
43 | // print($0.points)
44 | //
45 | // })
46 | //
47 | // }
48 | //
49 | // }
50 |
51 | }
52 |
53 | override func prepareForInterfaceBuilder() {
54 |
55 | lines = [CGLine] {
56 |
57 | for _ in 0...3 {
58 |
59 | $0.append(CGLine {
60 |
61 | $0.strokeWidth = CGFloat(drand48()) * 20
62 |
63 | for _ in 0...10 {
64 |
65 | $0.points.append(CGPoint {
66 |
67 | $0.x = CGFloat(drand48()) * UIScreen.main.bounds.width
68 | $0.y = CGFloat(drand48()) * UIScreen.main.bounds.height
69 |
70 | })
71 |
72 | }
73 |
74 | })
75 |
76 | }
77 |
78 | }
79 |
80 | }
81 |
82 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
83 |
84 | guard let touch = touches.first else { return }
85 |
86 | lines.append(CGLine {
87 |
88 | $0.stroke = UIColor.darkGray.cgColor
89 | $0.fill = UIColor.clear.cgColor
90 | $0.strokeWidth = 1
91 | $0.points.append(touch.location(in: self))
92 |
93 | })
94 |
95 | }
96 |
97 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
98 |
99 | guard let touch = touches.first, lines.count > 0 else { return }
100 |
101 | lines[lines.count - 1].points.append(touch.location(in: self))
102 |
103 | }
104 |
105 | override func touchesEnded(_ touches: Set, with event: UIEvent?) {
106 |
107 | guard let touch = touches.first, lines.count > 0 else { return }
108 |
109 | lines[lines.count - 1].points.append(touch.location(in: self))
110 |
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/Example/PencilCup/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Example/PencilCup.xcodeproj/xcshareddata/xcschemes/PencilCup-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
78 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
99 |
105 |
106 |
107 |
108 |
110 |
111 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Sources/ContextRef.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContextRef.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/4/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | // MARK: - Context : Settings
13 |
14 | public extension CGContext {
15 |
16 | var boundingBox: CGRect { return boundingBoxOfPath }
17 | var currenCGPoint: CGPoint { return currentPointOfPath }
18 |
19 | /// Sets lineCap and lineJoin to .Round
20 | func round() -> CGContext? {
21 |
22 | setLineCap(.round); setLineJoin(.round); return self
23 |
24 | }
25 |
26 | /// Sets stroke and fill color
27 | func color(_ color: CGColor?) -> CGContext? {
28 |
29 | guard let color = color else { return self }
30 | setFillColor(color)
31 | setStrokeColor(color)
32 | return self
33 |
34 | }
35 |
36 | /// Sets lineWidth
37 | func line(_ width: CGFloat) -> CGContext? { setLineWidth(width); return self }
38 |
39 | /// Sets blendMode
40 | func blend(_ mode: CGBlendMode) -> CGContext? { setBlendMode(mode); return self }
41 |
42 | /// Sets alpha
43 | func alpha(_ alpha: CGFloat) -> CGContext? { setAlpha(alpha); return self }
44 |
45 | /// Sets flatness
46 | func flatness(_ flatness: CGFloat) -> CGContext? { setFlatness(flatness); return self }
47 |
48 | func containsPoint(_ x: CGFloat, _ y: CGFloat) -> Bool { return pathContains(CGPoint(x: x, y: y), mode: .fill) }
49 |
50 | func containsPoint(_ point: CGPoint) -> Bool { return pathContains(point, mode: .fill) }
51 |
52 | }
53 |
54 |
55 | // MARK: - Context : Scale, Rotate, & Offset
56 |
57 | public extension CGContext {
58 |
59 | /// Rotates by angle
60 | func rotate(_ angle: CGFloat) -> CGContext? { rotate(by: angle); return self }
61 |
62 | /// Translates origin by x,y
63 | func offset(_ x: CGFloat, _ y: CGFloat) -> CGContext? { translateBy(x: x, y: y); return self }
64 |
65 | /// Translates origin by point
66 | func offset(_ point: CGPoint) -> CGContext? { translateBy(x: point.x, y: point.y); return self }
67 |
68 | /// Scales both x & y by xy
69 | func scale(_ xy: CGFloat = 1) -> CGContext? { scaleBy(x: xy, y: xy); return self }
70 |
71 | /// Scales by x & y
72 | func scale(_ x: CGFloat, _ y: CGFloat) -> CGContext? { scaleBy(x: x, y: y); return self }
73 |
74 | /// Scales x & y by scale
75 | func scale(_ scale: TScale) -> CGContext? { scaleBy(x: scale.x, y: scale.y); return self }
76 |
77 | }
78 |
79 | // MARK: - Context : Fill, Stroke, & Clear
80 |
81 | public extension CGContext {
82 |
83 | /// Clears with rect
84 | func clear(_ rect: CGRect? = nil) -> CGContext? {
85 |
86 | clear(rect ?? CGRect(x: 0, y: 0, width: 2048, height: 2048)); return self
87 |
88 | }
89 |
90 | /// Strokes available path
91 | func stroke() -> CGContext? { strokePath(); return self }
92 |
93 | /// Fills available path
94 | func fill() -> CGContext? { fillPath(); return self }
95 |
96 | }
97 |
98 | // MARK: - Context : Add to Path
99 |
100 | public extension CGContext {
101 |
102 | /// Add rect(s) to path
103 | func rect(_ rects: CGRect...) -> CGContext? {
104 |
105 | for rect in rects { addRect(rect) }; return self
106 |
107 | }
108 |
109 | /// Add ellipse(s) in rect to path
110 | func ellipse(_ rects: CGRect...) -> CGContext? {
111 |
112 | for rect in rects { addEllipse(in: rect) }; return self
113 |
114 | }
115 |
116 | /// Add circle with center as c and radius of r to path
117 | func circle(_ c: CGPoint, r: CGFloat) -> CGContext? {
118 |
119 | addEllipse(in: CGRect(origin: c - CGPoint(x: r, y: r), size: CGSize(width: r, height: r) * 2)); return self
120 |
121 | }
122 |
123 | /// Move path to x,y
124 | func m(_ x: CGFloat, _ y: CGFloat) -> CGContext? {
125 |
126 | move(to: CGPoint(x: x, y: y)); return self
127 |
128 | }
129 |
130 | /// Move to point
131 | func m(_ point: CGPoint) -> CGContext? {
132 |
133 | move(to: point); return self
134 |
135 | }
136 |
137 | /// Add line to x,y
138 | func l(_ x: CGFloat, _ y: CGFloat) -> CGContext? {
139 |
140 | addLine(to: CGPoint(x: x, y: y)); return self
141 |
142 | }
143 |
144 | /// Add line(s) to point(s)
145 | func l(_ points: CGPoint...) -> CGContext? {
146 |
147 | for point in points { addLine(to: point) }; return self
148 |
149 | }
150 |
151 | /// Add curve to curve point with curve anchors
152 | func c(_ curve: (CGPoint,CGPoint,CGPoint)) -> CGContext? {
153 |
154 | addCurve(to: curve.2, control1: curve.0, control2: curve.1); return self
155 |
156 | }
157 |
158 | /// Dot with center of x,y and diameter of strokeWidth
159 | func d(_ x: CGFloat, _ y: CGFloat) -> CGContext? {
160 |
161 | return m(x,y)?.l(x,y)?.stroke()
162 |
163 | }
164 |
165 | /// Dot(s) with center of point(s) and diameter of strokeWidth
166 | func d(_ points: CGPoint...) -> CGContext? {
167 |
168 | for point in points { _ = m(point)?.l(point)?.stroke() }; return self
169 |
170 | }
171 |
172 | }
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/Example/PencilCup/CoreGraphicsView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoreGraphicsView.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/5/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @IBDesignable class CoreGraphicsView: UIView {
12 |
13 | override func draw(_ rect: CGRect) {
14 |
15 | let context = UIGraphicsGetCurrentContext()
16 |
17 | UIColor(white: 0.9, alpha: 1).set()
18 |
19 | context?.fill(rect)
20 |
21 | UIColor(white: 0.2, alpha: 1).set()
22 |
23 | context?.setLineCap(.round)
24 | context?.setLineJoin(.round)
25 | context?.setLineWidth(1)
26 | context?.translateBy(x: (rect.width - 188) / 2, y: (rect.height - 300) / 2)
27 |
28 | // context?.move(to: CGPoint(x: 126.01, y: 89.44))
29 | // context?.addCurve(to: CGPoint(x: 94.35, y: 89.06), control1: CGPoint(x: 116.37, y: 89.19), control2: CGPoint(x: 105.65, y: 89.06))
30 | // CGContextAddCurveToPoint(context,52.35,89.06,18.3,90.8,18.3,94.24)
31 | // CGContextAddCurveToPoint(context,18.3,97.68,52.35,101.51,94.35,101.51)
32 | // CGContextAddCurveToPoint(context,104.7,101.51,114.57,101.28,123.57,100.87)
33 | // context?.addLine(to: CGPoint(x: 126.01, y: 89.44))
34 | // context?.fillPath()
35 | //
36 | // context?.move(to: CGPoint(x: 140, y: 99.75))
37 | // context?.addLine(to: CGPoint(x: 150.28, y: 49.72))
38 | // CGContextAddCurveToPoint(context,150.5,48.64,151.56,47.94,152.64,48.17)
39 | // context?.addLine(to: CGPoint(x: 162.37, y: 50.18))
40 | // CGContextAddCurveToPoint(context,163.46,50.4,164.15,51.46,163.93,52.54)
41 | // context?.addLine(to: CGPoint(x: 154.43, y: 98.52))
42 | // context?.strokePath()
43 | //
44 | // context?.move(to: CGPoint(x: 159.39, y: 13.91))
45 | // CGContextAddCurveToPoint(context,160.85,14.62,162.41,15.16,164.07,15.5)
46 | // CGContextAddCurveToPoint(context,165.71,15.84,167.36,15.97,168.96,15.9)
47 | // CGContextAddCurveToPoint(context,170.55,15.83,171.69,14.33,171.39,12.77)
48 | // context?.addLine(to: CGPoint(x: 169.3, y: 2.12))
49 | // CGContextAddCurveToPoint(context,168.85,-0.16,165.88,-0.78,164.56,1.14)
50 | // context?.addLine(to: CGPoint(x: 158.41, y: 10.08))
51 | // CGContextAddCurveToPoint(context,157.51,11.39,157.96,13.22,159.39,13.91)
52 | // context?.fillPath()
53 | //
54 | // context?.move(to: CGPoint(x: 159.39, y: 13.91))
55 | // CGContextAddCurveToPoint(context,160.85,14.62,162.41,15.16,164.07,15.5)
56 | // CGContextAddCurveToPoint(context,165.71,15.84,167.36,15.97,168.96,15.9)
57 | // CGContextAddCurveToPoint(context,170.55,15.83,171.69,14.33,171.39,12.77)
58 | // context?.addLine(to: CGPoint(x: 169.3, y: 2.12))
59 | // CGContextAddCurveToPoint(context,168.85,-0.16,165.88,-0.78,164.56,1.14)
60 | // context?.addLine(to: CGPoint(x: 158.41, y: 10.08))
61 | // CGContextAddCurveToPoint(context,157.51,11.39,157.96,13.22,159.39,13.91)
62 | // context?.strokePath()
63 | //
64 | // context?.move(to: CGPoint(x: 137.79, y: 100.12))
65 | // context?.addLine(to: CGPoint(x: 148.47, y: 48.45))
66 | // CGContextAddCurveToPoint(context,148.64,47.62,148.27,46.77,147.54,46.33)
67 | // context?.addLine(to: CGPoint(x: 141.06, y: 42.43))
68 | // CGContextAddCurveToPoint(context,139.87,41.72,138.35,42.39,138.07,43.74)
69 | // context?.addLine(to: CGPoint(x: 126.28, y: 100.81))
70 | // context?.strokePath()
71 | //
72 | // context?.move(to: CGPoint(x: 158.41, y: 10.08))
73 | // context?.addLine(to: CGPoint(x: 140.27, y: 38.9))
74 | // context?.strokePath()
75 | //
76 | // context?.move(to: CGPoint(x: 176.92, y: 46.09))
77 | // context?.addLine(to: CGPoint(x: 171.39, y: 12.77))
78 | // context?.strokePath()
79 | //
80 | // context?.move(to: CGPoint(x: 167.6, y: 96.07))
81 | // context?.addLine(to: CGPoint(x: 176.74, y: 51.79))
82 | // CGContextAddCurveToPoint(context,177.02,50.42,175.86,49.2,174.48,49.4)
83 | // context?.addLine(to: CGPoint(x: 167.77, y: 50.43))
84 | // CGContextAddCurveToPoint(context,166.94,50.55,166.28,51.18,166.11,52)
85 | // context?.addLine(to: CGPoint(x: 156.58, y: 98.15))
86 | // context?.strokePath()
87 | //
88 | // context?.move(to: CGPoint(x: 30.06, y: 218.44))
89 | // CGContextAddCurveToPoint(context,30.06,221.19,27.83,223.42,25.08,223.42)
90 | // context?.addLine(to: CGPoint(x: 24.83, y: 223.42))
91 | // CGContextAddCurveToPoint(context,22.08,223.42,19.84,221.19,19.84,218.44)
92 | // context?.addLine(to: CGPoint(x: 19.84, y: 138.67))
93 | // CGContextAddCurveToPoint(context,19.84,135.92,22.08,133.69,24.83,133.69)
94 | // context?.addLine(to: CGPoint(x: 25.08, y: 133.69))
95 | // CGContextAddCurveToPoint(context,27.83,133.69,30.06,135.92,30.06,138.67)
96 | // context?.addLine(to: CGPoint(x: 30.06, y: 218.44))
97 | //
98 | // context?.move(to: CGPoint(x: 174.9, y: 100.03))
99 | // CGContextAddCurveToPoint(context,161.84,103.04,137.31,106.55,94,106.55)
100 | // CGContextAddCurveToPoint(context,50.69,106.55,26.17,103.04,13.1,100.03)
101 | // CGContextAddCurveToPoint(context,6.38,98.48,-0.04,103.61,-0.04,110.51)
102 | // context?.addLine(to: CGPoint(x: -0.04, y: 274.38))
103 | // CGContextAddCurveToPoint(context,-0.04,281.03,4.04,286.99,10.23,289.4)
104 | // CGContextAddCurveToPoint(context,22.22,294.07,46.74,300,94,300)
105 | // CGContextAddCurveToPoint(context,141.26,300,165.78,294.07,177.77,289.4)
106 | // CGContextAddCurveToPoint(context,183.96,286.99,188.04,281.03,188.04,274.38)
107 | // context?.addLine(to: CGPoint(x: 188.04, y: 110.51))
108 | // CGContextAddCurveToPoint(context,188.04,103.61,181.62,98.48,174.9,100.03)
109 | // context?.fillPath()
110 |
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PencilCup
2 | Tools built to help use CoreGraphics more Swiftly
3 |
4 |
5 |
6 | [](http://cocoapods.org/pods/PencilCup)
7 | [](http://cocoapods.org/pods/PencilCup)
8 | [](http://cocoapods.org/pods/PencilCup)
9 |
10 | 
11 |
12 | ## Usage
13 |
14 | To run the example project, clone the repo, and run `pod install` from the Example directory first.
15 |
16 | Add these [Code Snippets](./XcodeSnippets) into Xcode to help with using the new operators.
17 |
18 | Code Snippet Directory : **~/Library/Developer/Xcode/UserData/CodeSnippets/**
19 |
20 | ### Motivation
21 |
22 | > Core Graphics is an amazingly useful library that I work with in every app I build. But I also have spent a lot of time writing lines of code to draw things that are very simple.
23 |
24 | **Main Problems**
25 |
26 | - each point on a path uses a new line of code
27 | - you must pass "context" with every CGContext function
28 | - CGContext options set using functions instead of methods
29 |
30 | ```swift
31 | let context = UIGraphicsGetCurrentContext()
32 | UIColor(white: 0.9, alpha: 1).set()
33 | CGContextFillRect(context, rect)
34 | UIColor(white: 0.2, alpha: 1).set()
35 |
36 | CGContextSetLineCap(context, .Round)
37 | CGContextSetLineJoin(context, .Round)
38 | CGContextSetLineWidth(context, 1)
39 | CGContextTranslateCTM(context, (rect.width - 188) / 2, (rect.height - 300) / 2)
40 |
41 | CGContextMoveToPoint(context,126.01,89.44)
42 | CGContextAddCurveToPoint(context,116.37, 89.19, 105.65, 89.06, 94.35, 89.06)
43 | CGContextAddCurveToPoint(context, 52.35, 89.06, 18.3, 90.8, 18.3, 94.24)
44 | CGContextAddCurveToPoint(context, 18.3, 97.68, 52.35, 101.51, 94.35, 101.51)
45 | CGContextAddCurveToPoint(context, 104.7, 101.51, 114.57, 101.28, 123.57, 100.87)
46 | CGContextAddLineToPoint(context,126.01,89.44)
47 | CGContextFillPath(context)
48 |
49 | CGContextMoveToPoint(context,140, 99.75)
50 | CGContextAddLineToPoint(context, 150.28, 49.72)
51 | CGContextAddCurveToPoint(context, 150.5, 48.64, 151.56, 47.94, 152.64, 48.17)
52 | CGContextAddLineToPoint(context, 162.37, 50.18)
53 | CGContextAddCurveToPoint(context, 163.46, 50.4, 164.15, 51.46, 163.93, 52.54)
54 | CGContextAddLineToPoint(context, 154.43, 98.52)
55 | CGContextStrokePath(context)
56 | ```
57 | *22 lines of code*
58 |
59 | ---
60 |
61 | ### New Patterns
62 |
63 | > You now have the ability to set context options using extension methods. Infix operators open up the ability to build a multi point path on a single line of code.
64 |
65 | **New Features**
66 |
67 | - typealiases PCPoint, PCSize, PCScale, PCDelta
68 | - CGRect extended with inset methods and global initializer functions
69 | - CGContext extended with methods that simplify setup
70 | - infix operators for points and paths
71 |
72 | #### Operator Pattern
73 |
74 | ```swift
75 | let (bgColor,cupColor) = (UIColor(white: 0.9, alpha: 1).CGColor, UIColor(white: 0.2, alpha: 1).CGColor)
76 |
77 | let context = UIGraphicsGetCurrentContext()?.round()?.color(bgColor)?.rect(rect)?.fill()
78 | context?.color(cupColor)?.round()?.line(1)?.offset((rect.width - 188) / 2, (rect.height - 300) / 2)
79 |
80 | context ->- (126.01,89.44) -~- (116.37,89.19,105.65,89.06,94.35,89.06) -~- (52.35,89.06,18.3,90.8,18.3,94.24)
81 | context -~- (18.3,97.68,52.35,101.51,94.35,101.51) -~- (104.7,101.51,114.57,101.28,123.57,100.87) -+- (126.01,89.44) -■ nil
82 |
83 | context ->- (140,99.75) -+- (150.28,49.72) -~- (150.5,48.64,151.56,47.94,152.64,48.17) -+- (162.37,50.18)
84 | context -~- (163.46,50.4,164.15,51.46,163.93,52.54) -+- (154.43,98.52) -□ nil
85 | ```
86 | *7 lines of code*
87 |
88 | #### Function Pattern
89 |
90 | ```swift
91 | let (bgColor,cupColor) = (UIColor(white: 0.9, alpha: 1).CGColor, UIColor(white: 0.2, alpha: 1).CGColor)
92 |
93 | let context = UIGraphicsGetCurrentContext()?.round()?.color(bgColor)?.rect(rect)?.fill()
94 | context?.color(cupColor)?.round()?.line(1)?.offset((rect.width - 188) / 2, (rect.height - 300) / 2)
95 |
96 | context?.m(126.01,89.44)?.c(116.37,89.19,105.65,89.06,94.35,89.06)?.c(52.35,89.06,18.3,90.8,18.3,94.24)
97 | context?.c(18.3,97.68,52.35,101.51,94.35,101.51)?.c(104.7,101.51,114.57,101.28,123.57,100.87)?.l(126.01,89.44)?.fill()
98 |
99 | context?.m(140,99.75)?.l(150.28,49.72)?.c(150.5,48.64,151.56,47.94,152.64,48.17)?.l(162.37,50.18)
100 | context?.c(163.46,50.4,164.15,51.46,163.93,52.54)?.l(154.43,98.52)?.stroke()
101 | ```
102 | *7 lines of code*
103 |
104 | > I personally enjoy the operator pattern, because the visuals of the operators make it more readable for me. But both are great patterns.
105 |
106 |
107 |
108 | ---
109 |
110 | ### Screens
111 |
112 | - CoreGraphics Drawn PencilCup Logo
113 | - ColorWheel and ColorBar Classes in Example Project
114 | - gradient steps are changlable
115 | - bars have values to change hue, saturation, brightness, alpha
116 |
117 |
118 |
119 |   
120 |
121 |
122 | ## Installation
123 |
124 | PencilCup is available through [CocoaPods](http://cocoapods.org). To install
125 | it, simply add the following line to your Podfile:
126 |
127 | ```ruby
128 | pod "PencilCup"
129 | ```
130 |
131 | PencilCup is also available through [Swift Package Manager](https://swift.org/package-manager/). Please take a look at the link to learn more about how to use SwiftPM.
132 |
133 | ```swift
134 | import PackageDescription
135 |
136 | let package = Package(
137 | name: "YOUR_PACKAGE_NAME",
138 | dependencies: [
139 | .Package(url: "https://github.com/joalbright/PencilCup.git", majorVersion: 0)
140 | ]
141 | )
142 | ```
143 |
144 | ## Author
145 |
146 | [Jo Albright](http://github.com/joalbright)
147 |
148 | ## License
149 |
150 | PencilCup is available under the MIT license. See the LICENSE file for more info.
151 |
--------------------------------------------------------------------------------
/Example/PencilCup/InkWell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DrawableInkWell.swift
3 | // PencilCup
4 | //
5 | // Created by Jo Albright on 1/6/16.
6 | // Copyright © 2016 Jo Albright. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @IBDesignable class ColorBar: UIControl {
12 |
13 | @IBInspectable var steps: CGFloat = 360
14 | @IBInspectable var reverse: Bool = false
15 |
16 | enum BarType: String { case Hue, Saturation, Brightness, Alpha }
17 | var type: BarType = .Hue
18 | @IBInspectable var typeString: String = "Hue" { didSet { type = BarType(rawValue: typeString) ?? .Hue } }
19 |
20 | @IBInspectable var isHorizontal: Bool = false
21 |
22 | @IBInspectable var handleColor: UIColor = UIColor.black
23 |
24 | @IBInspectable var h: CGFloat = 0 { didSet { setNeedsDisplay() } }
25 | @IBInspectable var s: CGFloat = 1 { didSet { setNeedsDisplay() } }
26 | @IBInspectable var b: CGFloat = 1 { didSet { setNeedsDisplay() } }
27 | @IBInspectable var a: CGFloat = 1 { didSet { setNeedsDisplay() } }
28 |
29 | @IBInspectable var value: CGFloat = 0 { didSet { setNeedsDisplay() } }
30 | @IBInspectable var minValue: CGFloat = 0
31 | @IBInspectable var maxValue: CGFloat = 100
32 |
33 | var locked: Bool = true
34 |
35 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
36 |
37 | guard let touch = touches.first else { return }
38 | let location = touch.location(in: self)
39 |
40 | let wh = frame.width < frame.height ? frame.width : frame.height
41 |
42 | let percent = 1 - (value - minValue) / (maxValue - minValue)
43 |
44 | let x = isHorizontal ? frame.height / 2 + ((frame.width - frame.height) * percent) : frame.width / 2
45 | let y = isHorizontal ? frame.height / 2 : frame.width / 2 + ((frame.height - frame.width) * percent)
46 |
47 | locked = !(fabs(location.x - x) < wh / 2 && fabs(location.y - y) < wh / 2)
48 |
49 | }
50 |
51 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
52 |
53 | guard let touch = touches.first, !locked else { return }
54 | let location = touch.location(in: self)
55 |
56 | let percent = isHorizontal ? (location.x - frame.height / 2) / (frame.width - frame.height) : (location.y - frame.width / 2) / (frame.height - frame.width)
57 |
58 | let rP = reverse ? 1 - percent : percent
59 |
60 | value = rP * (maxValue - minValue) + minValue
61 |
62 | if value < minValue { value = minValue }
63 | if value > maxValue { value = maxValue }
64 |
65 | switch type {
66 |
67 | case .Hue: h = (value - minValue) / (maxValue - minValue)
68 | case .Saturation: s = (value - minValue) / (maxValue - minValue)
69 | case .Brightness: b = (value - minValue) / (maxValue - minValue)
70 | case .Alpha : a = (value - minValue) / (maxValue - minValue)
71 |
72 | }
73 |
74 | sendActions(for: .valueChanged)
75 |
76 | }
77 |
78 | override func draw(_ rect: CGRect) {
79 |
80 | steps = steps == 0 ? isHorizontal ? rect.width : rect.height : steps
81 |
82 | layer.cornerRadius = rect.width < rect.height ? rect.width / 2 : rect.height / 2
83 | layer.masksToBounds = true
84 |
85 | let sD: CGFloat = isHorizontal ? rect.width != steps ? 2 : 0 : rect.height != steps ? 2 : 0
86 |
87 | let context = UIGraphicsGetCurrentContext()
88 |
89 | var rW = reverse ? isHorizontal ? rect.width : 0 : 0
90 | var rH = reverse ? isHorizontal ? 0 : rect.height : 0
91 | let r: CGFloat = reverse ? 1 : -1
92 |
93 | let xM = isHorizontal ? rect.width / steps : 0
94 | let yM = isHorizontal ? 0 : rect.height / steps
95 |
96 | let width = isHorizontal ? rect.width / steps + sD : rect.width
97 | let height = isHorizontal ? rect.height : rect.height / steps + sD
98 |
99 | for i in 0...Int(steps) {
100 |
101 | switch type {
102 |
103 | case .Hue : UIColor(hue: CGFloat(i) / steps, saturation: 1, brightness: 1, alpha: 1).set()
104 | case .Saturation : UIColor(hue: h, saturation: CGFloat(i) / steps, brightness: b, alpha: 1).set()
105 | case .Brightness : UIColor(hue: h, saturation: s, brightness: CGFloat(i) / steps, alpha: 1).set()
106 | case .Alpha : UIColor(hue: h, saturation: s, brightness: b, alpha: CGFloat(i) / steps).set()
107 |
108 | }
109 |
110 | _ = context?.rect(CGRect(x: rW - (CGFloat(i) * xM * r), y: rH - (CGFloat(i) * yM * r), width: width, height: height))?.fill()
111 |
112 | }
113 |
114 | _ = context?.blend(.clear)?.line(6.5)
115 |
116 | rW = rW > 0 ? rW - rect.height : 0
117 | rH = rH > 0 ? rH - rect.width : 0
118 |
119 | let percent = (value - minValue) / (maxValue - minValue)
120 | let x = isHorizontal ? rW - (rect.width - rect.height) * percent * r : 0
121 | let y = isHorizontal ? 0 : rH - (rect.height - rect.width) * percent * r
122 |
123 | let handleWH = rect.width < rect.height ? rect.width : rect.height
124 | let handleRect = CGRect(x: x, y: y, width: handleWH, height: handleWH).inset(3)
125 |
126 | _ = context?.ellipse(handleRect)?.stroke()?.blend(.normal)?.color(handleColor.cgColor)?.line(1)
127 |
128 | if percent == 0 && type == .Alpha {
129 |
130 | let (l1,l2) = (handleRect.pointOnCircleInRect(-45),handleRect.pointOnCircleInRect(-225))
131 |
132 | _ = context?.line(2)?.color(UIColor.red.cgColor) ->- l1 -+- l2
133 |
134 | }
135 |
136 | _ = context?.ellipse(CGRect(x: x, y: y, width: handleWH, height: handleWH).inset(3))?.stroke()
137 |
138 | }
139 |
140 | }
141 |
142 | @IBDesignable class ColorWheel: UIControl {
143 |
144 | @IBInspectable var steps: CGFloat = 360
145 |
146 | @IBInspectable var hueStart: CGFloat = 0
147 | @IBInspectable var hueEnd: CGFloat = 360
148 |
149 | @IBInspectable var saturation: CGFloat = 1
150 | @IBInspectable var brightness: CGFloat = 1
151 |
152 | override func draw(_ rect: CGRect) {
153 |
154 | layer.cornerRadius = rect.width > rect.height ? rect.width / 2 : rect.width / 2
155 | layer.masksToBounds = true
156 |
157 | let context = UIGraphicsGetCurrentContext()
158 |
159 | let degrees: CGFloat = 360
160 |
161 | for d in 0...Int(steps) {
162 |
163 | let hueRange = hueEnd - hueStart
164 | let distance = degrees / steps
165 | let degree = CGFloat(d) * distance
166 | let percent = CGFloat(d) / steps
167 |
168 | var hue = percent * (hueRange / degrees) + hueStart / degrees
169 |
170 | if hue < 0 { hue += 1 } else if hue > 1 { hue -= 1 }
171 |
172 | UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1).set()
173 |
174 | let a1 = rect.inset(-100).pointOnCircleInRect(degree - distance / 2 - 0.25)
175 | let a2 = rect.inset(-100).pointOnCircleInRect(degree + distance / 2 + 0.25)
176 |
177 | _ = context ->- rect.center -+- a1 -+- a2 -■ nil
178 |
179 | }
180 |
181 | }
182 |
183 | // TODO: Add value functionality
184 |
185 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
186 |
187 |
188 |
189 | }
190 |
191 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
192 |
193 |
194 | sendActions(for: .valueChanged)
195 |
196 | }
197 |
198 | }
199 |
200 |
--------------------------------------------------------------------------------
/Example/PencilCup/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
--------------------------------------------------------------------------------
/Example/PencilCup.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
11 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
12 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
13 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
14 | A914C70E1E933C790027D1FB /* ContextMisc.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914C7091E933C790027D1FB /* ContextMisc.swift */; };
15 | A914C70F1E933C790027D1FB /* ContextPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914C70A1E933C790027D1FB /* ContextPath.swift */; };
16 | A914C7101E933C790027D1FB /* ContextPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914C70B1E933C790027D1FB /* ContextPoint.swift */; };
17 | A914C7111E933C790027D1FB /* ContextRect.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914C70C1E933C790027D1FB /* ContextRect.swift */; };
18 | A914C7121E933C790027D1FB /* ContextRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914C70D1E933C790027D1FB /* ContextRef.swift */; };
19 | A914C7151E933CF10027D1FB /* Inlinit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914C7141E933CF10027D1FB /* Inlinit.swift */; };
20 | A939C7151C3E007F001EC587 /* DrawView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A939C7141C3E007F001EC587 /* DrawView.swift */; };
21 | A945D6711C3F0B92006CDF25 /* InkWell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A945D6701C3F0B92006CDF25 /* InkWell.swift */; };
22 | A945D6731C3F0BAF006CDF25 /* Drawable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A945D6721C3F0BAF006CDF25 /* Drawable.swift */; };
23 | A945D67B1C40BC01006CDF25 /* ColorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A945D67A1C40BC01006CDF25 /* ColorViewController.swift */; };
24 | A9B091581C3CCC48004E26D0 /* PencilCupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B091561C3CCC48004E26D0 /* PencilCupView.swift */; };
25 | A9B091591C3CCC48004E26D0 /* CoreGraphicsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B091571C3CCC48004E26D0 /* CoreGraphicsView.swift */; };
26 | /* End PBXBuildFile section */
27 |
28 | /* Begin PBXFileReference section */
29 | 3A317D8797530C3299CF00DE /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../../README.md; sourceTree = ""; };
30 | 607FACD01AFB9204008FA782 /* PencilCup_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PencilCup_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
31 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
33 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
34 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
35 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
36 | 984567C7765F410F76D66991 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../../LICENSE; sourceTree = ""; };
37 | A914C7091E933C790027D1FB /* ContextMisc.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContextMisc.swift; path = ../../Sources/ContextMisc.swift; sourceTree = ""; };
38 | A914C70A1E933C790027D1FB /* ContextPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContextPath.swift; path = ../../Sources/ContextPath.swift; sourceTree = ""; };
39 | A914C70B1E933C790027D1FB /* ContextPoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContextPoint.swift; path = ../../Sources/ContextPoint.swift; sourceTree = ""; };
40 | A914C70C1E933C790027D1FB /* ContextRect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContextRect.swift; path = ../../Sources/ContextRect.swift; sourceTree = ""; };
41 | A914C70D1E933C790027D1FB /* ContextRef.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContextRef.swift; path = ../../Sources/ContextRef.swift; sourceTree = ""; };
42 | A914C7141E933CF10027D1FB /* Inlinit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Inlinit.swift; path = ../../Carthage/Checkouts/Inlinit/Sources/Inlinit.swift; sourceTree = ""; };
43 | A939C7141C3E007F001EC587 /* DrawView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DrawView.swift; sourceTree = ""; };
44 | A945D6701C3F0B92006CDF25 /* InkWell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InkWell.swift; path = /Users/RedLeader/_github/PencilCup/Example/PencilCup/InkWell.swift; sourceTree = ""; };
45 | A945D6721C3F0BAF006CDF25 /* Drawable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Drawable.swift; path = /Users/RedLeader/_github/PencilCup/Example/PencilCup/Drawable.swift; sourceTree = ""; };
46 | A945D67A1C40BC01006CDF25 /* ColorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorViewController.swift; sourceTree = ""; };
47 | A9B091561C3CCC48004E26D0 /* PencilCupView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PencilCupView.swift; sourceTree = ""; };
48 | A9B091571C3CCC48004E26D0 /* CoreGraphicsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreGraphicsView.swift; sourceTree = ""; };
49 | /* End PBXFileReference section */
50 |
51 | /* Begin PBXFrameworksBuildPhase section */
52 | 607FACCD1AFB9204008FA782 /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 2147483647;
55 | files = (
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | /* End PBXFrameworksBuildPhase section */
60 |
61 | /* Begin PBXGroup section */
62 | 607FACC71AFB9204008FA782 = {
63 | isa = PBXGroup;
64 | children = (
65 | 607FACD21AFB9204008FA782 /* Example for PencilCup */,
66 | 607FACD11AFB9204008FA782 /* Products */,
67 | );
68 | sourceTree = "";
69 | };
70 | 607FACD11AFB9204008FA782 /* Products */ = {
71 | isa = PBXGroup;
72 | children = (
73 | 607FACD01AFB9204008FA782 /* PencilCup_Example.app */,
74 | );
75 | name = Products;
76 | sourceTree = "";
77 | };
78 | 607FACD21AFB9204008FA782 /* Example for PencilCup */ = {
79 | isa = PBXGroup;
80 | children = (
81 | A914C7131E933CA60027D1FB /* Carthage */,
82 | A914C6FC1E933C2B0027D1FB /* PencilCup */,
83 | 607FACD91AFB9204008FA782 /* Main.storyboard */,
84 | A945D6771C40BBC7006CDF25 /* PencilCup Logo */,
85 | A945D6781C40BBE0006CDF25 /* DrawView */,
86 | A945D6791C40BBEA006CDF25 /* ColorPicker */,
87 | 607FACD31AFB9204008FA782 /* Supporting Files */,
88 | );
89 | name = "Example for PencilCup";
90 | path = PencilCup;
91 | sourceTree = "";
92 | };
93 | 607FACD31AFB9204008FA782 /* Supporting Files */ = {
94 | isa = PBXGroup;
95 | children = (
96 | 3A317D8797530C3299CF00DE /* README.md */,
97 | 984567C7765F410F76D66991 /* LICENSE */,
98 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */,
99 | 607FACDC1AFB9204008FA782 /* Images.xcassets */,
100 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */,
101 | 607FACD41AFB9204008FA782 /* Info.plist */,
102 | );
103 | name = "Supporting Files";
104 | sourceTree = "";
105 | };
106 | A914C6FC1E933C2B0027D1FB /* PencilCup */ = {
107 | isa = PBXGroup;
108 | children = (
109 | A914C7091E933C790027D1FB /* ContextMisc.swift */,
110 | A914C70A1E933C790027D1FB /* ContextPath.swift */,
111 | A914C70B1E933C790027D1FB /* ContextPoint.swift */,
112 | A914C70C1E933C790027D1FB /* ContextRect.swift */,
113 | A914C70D1E933C790027D1FB /* ContextRef.swift */,
114 | );
115 | name = PencilCup;
116 | sourceTree = "";
117 | };
118 | A914C7131E933CA60027D1FB /* Carthage */ = {
119 | isa = PBXGroup;
120 | children = (
121 | A914C7141E933CF10027D1FB /* Inlinit.swift */,
122 | );
123 | name = Carthage;
124 | sourceTree = "";
125 | };
126 | A945D6771C40BBC7006CDF25 /* PencilCup Logo */ = {
127 | isa = PBXGroup;
128 | children = (
129 | A9B091561C3CCC48004E26D0 /* PencilCupView.swift */,
130 | A9B091571C3CCC48004E26D0 /* CoreGraphicsView.swift */,
131 | );
132 | name = "PencilCup Logo";
133 | sourceTree = "";
134 | };
135 | A945D6781C40BBE0006CDF25 /* DrawView */ = {
136 | isa = PBXGroup;
137 | children = (
138 | A939C7141C3E007F001EC587 /* DrawView.swift */,
139 | A945D6721C3F0BAF006CDF25 /* Drawable.swift */,
140 | );
141 | name = DrawView;
142 | sourceTree = "";
143 | };
144 | A945D6791C40BBEA006CDF25 /* ColorPicker */ = {
145 | isa = PBXGroup;
146 | children = (
147 | A945D67A1C40BC01006CDF25 /* ColorViewController.swift */,
148 | A945D6701C3F0B92006CDF25 /* InkWell.swift */,
149 | );
150 | name = ColorPicker;
151 | sourceTree = "";
152 | };
153 | /* End PBXGroup section */
154 |
155 | /* Begin PBXNativeTarget section */
156 | 607FACCF1AFB9204008FA782 /* PencilCup_Example */ = {
157 | isa = PBXNativeTarget;
158 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "PencilCup_Example" */;
159 | buildPhases = (
160 | 607FACCC1AFB9204008FA782 /* Sources */,
161 | 607FACCD1AFB9204008FA782 /* Frameworks */,
162 | 607FACCE1AFB9204008FA782 /* Resources */,
163 | );
164 | buildRules = (
165 | );
166 | dependencies = (
167 | );
168 | name = PencilCup_Example;
169 | productName = PencilCup;
170 | productReference = 607FACD01AFB9204008FA782 /* PencilCup_Example.app */;
171 | productType = "com.apple.product-type.application";
172 | };
173 | /* End PBXNativeTarget section */
174 |
175 | /* Begin PBXProject section */
176 | 607FACC81AFB9204008FA782 /* Project object */ = {
177 | isa = PBXProject;
178 | attributes = {
179 | LastSwiftUpdateCheck = 0720;
180 | LastUpgradeCheck = 0720;
181 | ORGANIZATIONNAME = CocoaPods;
182 | TargetAttributes = {
183 | 607FACCF1AFB9204008FA782 = {
184 | CreatedOnToolsVersion = 6.3.1;
185 | LastSwiftMigration = 0820;
186 | };
187 | };
188 | };
189 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "PencilCup" */;
190 | compatibilityVersion = "Xcode 3.2";
191 | developmentRegion = English;
192 | hasScannedForEncodings = 0;
193 | knownRegions = (
194 | en,
195 | Base,
196 | );
197 | mainGroup = 607FACC71AFB9204008FA782;
198 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
199 | projectDirPath = "";
200 | projectRoot = "";
201 | targets = (
202 | 607FACCF1AFB9204008FA782 /* PencilCup_Example */,
203 | );
204 | };
205 | /* End PBXProject section */
206 |
207 | /* Begin PBXResourcesBuildPhase section */
208 | 607FACCE1AFB9204008FA782 /* Resources */ = {
209 | isa = PBXResourcesBuildPhase;
210 | buildActionMask = 2147483647;
211 | files = (
212 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
213 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
214 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */,
215 | );
216 | runOnlyForDeploymentPostprocessing = 0;
217 | };
218 | /* End PBXResourcesBuildPhase section */
219 |
220 | /* Begin PBXSourcesBuildPhase section */
221 | 607FACCC1AFB9204008FA782 /* Sources */ = {
222 | isa = PBXSourcesBuildPhase;
223 | buildActionMask = 2147483647;
224 | files = (
225 | A914C7101E933C790027D1FB /* ContextPoint.swift in Sources */,
226 | A914C7121E933C790027D1FB /* ContextRef.swift in Sources */,
227 | A9B091581C3CCC48004E26D0 /* PencilCupView.swift in Sources */,
228 | A914C7111E933C790027D1FB /* ContextRect.swift in Sources */,
229 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
230 | A939C7151C3E007F001EC587 /* DrawView.swift in Sources */,
231 | A945D6731C3F0BAF006CDF25 /* Drawable.swift in Sources */,
232 | A914C70F1E933C790027D1FB /* ContextPath.swift in Sources */,
233 | A945D67B1C40BC01006CDF25 /* ColorViewController.swift in Sources */,
234 | A914C70E1E933C790027D1FB /* ContextMisc.swift in Sources */,
235 | A9B091591C3CCC48004E26D0 /* CoreGraphicsView.swift in Sources */,
236 | A914C7151E933CF10027D1FB /* Inlinit.swift in Sources */,
237 | A945D6711C3F0B92006CDF25 /* InkWell.swift in Sources */,
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | };
241 | /* End PBXSourcesBuildPhase section */
242 |
243 | /* Begin PBXVariantGroup section */
244 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = {
245 | isa = PBXVariantGroup;
246 | children = (
247 | 607FACDA1AFB9204008FA782 /* Base */,
248 | );
249 | name = Main.storyboard;
250 | sourceTree = "";
251 | };
252 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = {
253 | isa = PBXVariantGroup;
254 | children = (
255 | 607FACDF1AFB9204008FA782 /* Base */,
256 | );
257 | name = LaunchScreen.xib;
258 | sourceTree = "";
259 | };
260 | /* End PBXVariantGroup section */
261 |
262 | /* Begin XCBuildConfiguration section */
263 | 607FACED1AFB9204008FA782 /* Debug */ = {
264 | isa = XCBuildConfiguration;
265 | buildSettings = {
266 | ALWAYS_SEARCH_USER_PATHS = NO;
267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
268 | CLANG_CXX_LIBRARY = "libc++";
269 | CLANG_ENABLE_MODULES = YES;
270 | CLANG_ENABLE_OBJC_ARC = YES;
271 | CLANG_WARN_BOOL_CONVERSION = YES;
272 | CLANG_WARN_CONSTANT_CONVERSION = YES;
273 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
274 | CLANG_WARN_EMPTY_BODY = YES;
275 | CLANG_WARN_ENUM_CONVERSION = YES;
276 | CLANG_WARN_INT_CONVERSION = YES;
277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
278 | CLANG_WARN_UNREACHABLE_CODE = YES;
279 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
280 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
281 | COPY_PHASE_STRIP = NO;
282 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
283 | ENABLE_STRICT_OBJC_MSGSEND = YES;
284 | ENABLE_TESTABILITY = YES;
285 | GCC_C_LANGUAGE_STANDARD = gnu99;
286 | GCC_DYNAMIC_NO_PIC = NO;
287 | GCC_NO_COMMON_BLOCKS = YES;
288 | GCC_OPTIMIZATION_LEVEL = 0;
289 | GCC_PREPROCESSOR_DEFINITIONS = (
290 | "DEBUG=1",
291 | "$(inherited)",
292 | );
293 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
296 | GCC_WARN_UNDECLARED_SELECTOR = YES;
297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
298 | GCC_WARN_UNUSED_FUNCTION = YES;
299 | GCC_WARN_UNUSED_VARIABLE = YES;
300 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
301 | MTL_ENABLE_DEBUG_INFO = YES;
302 | ONLY_ACTIVE_ARCH = YES;
303 | SDKROOT = iphoneos;
304 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
305 | };
306 | name = Debug;
307 | };
308 | 607FACEE1AFB9204008FA782 /* Release */ = {
309 | isa = XCBuildConfiguration;
310 | buildSettings = {
311 | ALWAYS_SEARCH_USER_PATHS = NO;
312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
313 | CLANG_CXX_LIBRARY = "libc++";
314 | CLANG_ENABLE_MODULES = YES;
315 | CLANG_ENABLE_OBJC_ARC = YES;
316 | CLANG_WARN_BOOL_CONVERSION = YES;
317 | CLANG_WARN_CONSTANT_CONVERSION = YES;
318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
319 | CLANG_WARN_EMPTY_BODY = YES;
320 | CLANG_WARN_ENUM_CONVERSION = YES;
321 | CLANG_WARN_INT_CONVERSION = YES;
322 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
323 | CLANG_WARN_UNREACHABLE_CODE = YES;
324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
326 | COPY_PHASE_STRIP = NO;
327 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
328 | ENABLE_NS_ASSERTIONS = NO;
329 | ENABLE_STRICT_OBJC_MSGSEND = YES;
330 | GCC_C_LANGUAGE_STANDARD = gnu99;
331 | GCC_NO_COMMON_BLOCKS = YES;
332 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
333 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
334 | GCC_WARN_UNDECLARED_SELECTOR = YES;
335 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
336 | GCC_WARN_UNUSED_FUNCTION = YES;
337 | GCC_WARN_UNUSED_VARIABLE = YES;
338 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
339 | MTL_ENABLE_DEBUG_INFO = NO;
340 | SDKROOT = iphoneos;
341 | VALIDATE_PRODUCT = YES;
342 | };
343 | name = Release;
344 | };
345 | 607FACF01AFB9204008FA782 /* Debug */ = {
346 | isa = XCBuildConfiguration;
347 | buildSettings = {
348 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
349 | INFOPLIST_FILE = PencilCup/Info.plist;
350 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
351 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
352 | MODULE_NAME = ExampleApp;
353 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
354 | PRODUCT_NAME = "$(TARGET_NAME)";
355 | SWIFT_VERSION = 3.0;
356 | };
357 | name = Debug;
358 | };
359 | 607FACF11AFB9204008FA782 /* Release */ = {
360 | isa = XCBuildConfiguration;
361 | buildSettings = {
362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
363 | INFOPLIST_FILE = PencilCup/Info.plist;
364 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
365 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
366 | MODULE_NAME = ExampleApp;
367 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
368 | PRODUCT_NAME = "$(TARGET_NAME)";
369 | SWIFT_VERSION = 3.0;
370 | };
371 | name = Release;
372 | };
373 | /* End XCBuildConfiguration section */
374 |
375 | /* Begin XCConfigurationList section */
376 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "PencilCup" */ = {
377 | isa = XCConfigurationList;
378 | buildConfigurations = (
379 | 607FACED1AFB9204008FA782 /* Debug */,
380 | 607FACEE1AFB9204008FA782 /* Release */,
381 | );
382 | defaultConfigurationIsVisible = 0;
383 | defaultConfigurationName = Release;
384 | };
385 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "PencilCup_Example" */ = {
386 | isa = XCConfigurationList;
387 | buildConfigurations = (
388 | 607FACF01AFB9204008FA782 /* Debug */,
389 | 607FACF11AFB9204008FA782 /* Release */,
390 | );
391 | defaultConfigurationIsVisible = 0;
392 | defaultConfigurationName = Release;
393 | };
394 | /* End XCConfigurationList section */
395 | };
396 | rootObject = 607FACC81AFB9204008FA782 /* Project object */;
397 | }
398 |
--------------------------------------------------------------------------------