├── CalendarHero.acorn
├── CalendarHero
├── Assets.xcassets
│ ├── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── icon-128.png
│ │ ├── icon-16.png
│ │ ├── icon-256.png
│ │ ├── icon-32.png
│ │ ├── icon-512.png
│ │ ├── icon-16@2x.png
│ │ ├── icon-32@2x.png
│ │ ├── icon-128@2x.png
│ │ ├── icon-256@2x.png
│ │ ├── icon-512@2x.png
│ │ └── Contents.json
│ └── AccentColor.colorset
│ │ └── Contents.json
├── CalendarHero.entitlements
├── AppDelegate.swift
├── Info.plist
├── Window.swift
├── ViewController.swift
└── Base.lproj
│ └── Main.storyboard
├── Calendar Hero.xcodeproj
├── xcuserdata
│ └── thall.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── project.pbxproj
└── README.md
/CalendarHero.acorn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero.acorn
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-128.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-16.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-256.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-32.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-512.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tylerhall/CalendarHero/main/CalendarHero/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Calendar Hero.xcodeproj/xcuserdata/thall.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/Calendar Hero.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Calendar Hero.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CalendarHero/CalendarHero.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.personal-information.calendars
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Calendar Hero.xcodeproj/xcuserdata/thall.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Calendar Hero.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 | CalendarHero.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/CalendarHero/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CalendarHero
4 | //
5 | // Created by Tyler Hall on 2/17/21.
6 | //
7 |
8 | import Cocoa
9 |
10 | @main
11 | class AppDelegate: NSObject, NSApplicationDelegate {
12 |
13 | func applicationDidBecomeActive(_ notification: Notification) {
14 | for window in NSApp.windows {
15 | (window as? Window)?.updateStyle()
16 | }
17 | }
18 |
19 | func applicationDidResignActive(_ notification: Notification) {
20 | for window in NSApp.windows {
21 | (window as? Window)?.updateStyle()
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Calendar Hero
2 |
3 | [https://tyler.io/calendar-hero/](https://tyler.io/calendar-hero/)
4 |
5 | MIT License
6 |
7 | Copyright 2021 Tyler Hall
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14 |
--------------------------------------------------------------------------------
/CalendarHero/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 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSMainStoryboardFile
26 | Main
27 | NSPrincipalClass
28 | NSApplication
29 | NSCalendarsUsageDescription
30 | Dispaly your calendars.
31 | LSUIElement
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/CalendarHero/Window.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Window.swift
3 | // CalendarHero
4 | //
5 | // Created by Tyler Hall on 2/17/21.
6 | //
7 |
8 | import Cocoa
9 |
10 | class Window: NSWindow {
11 |
12 | func updateStyle() {
13 | standardWindowButton(.miniaturizeButton)?.isHidden = true
14 | standardWindowButton(.zoomButton)?.isHidden = true
15 | standardWindowButton(.closeButton)?.isHidden = true
16 |
17 | collectionBehavior = .stationary
18 |
19 | if NSApp.isActive {
20 | styleMask = [.resizable, .fullSizeContentView, .titled]
21 | ignoresMouseEvents = false
22 | level = .normal
23 | isOpaque = true
24 | backgroundColor = .windowBackgroundColor
25 | } else {
26 | styleMask = [.borderless, .fullSizeContentView]
27 | ignoresMouseEvents = true
28 | orderBack(nil)
29 | level = NSWindow.Level.init(Int(CGWindowLevelForKey(CGWindowLevelKey.desktopWindow)))
30 | isOpaque = false
31 | backgroundColor = .clear
32 | }
33 | }
34 |
35 | override var tabbingMode: NSWindow.TabbingMode {
36 | get {
37 | return .disallowed
38 | }
39 | set {
40 |
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/CalendarHero/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "icon-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "icon-16@2x.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "icon-32.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "icon-32@2x.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "icon-128.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "icon-128@2x.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "icon-256.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "icon-256@2x.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "icon-512.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "icon-512@2x.png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/CalendarHero/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CalendarHero
4 | //
5 | // Created by Tyler Hall on 2/17/21.
6 | //
7 |
8 | import Cocoa
9 | import EventKit
10 |
11 | class ViewController: NSViewController {
12 |
13 | @IBOutlet weak var nextEventCountdownTextField: NSTextField!
14 | @IBOutlet weak var weekStackView: NSStackView!
15 |
16 | let store = EKEventStore()
17 |
18 | let startHour = 0
19 | let endHour = 23
20 |
21 | // This is just a wrapper around the current date,
22 | // so I can test other dates during development.
23 | var theDate: Date {
24 | return Date() // Date(timeIntervalSinceNow: 3600 * 6)
25 | }
26 |
27 | var start: Date {
28 | return Calendar.current.date(from: Calendar.current.dateComponents([.yearForWeekOfYear, .weekOfYear], from: theDate))!
29 | }
30 |
31 | var end: Date {
32 | return Date(timeInterval: 86400 * 7, since: start)
33 | }
34 |
35 | var refreshTimer: Timer?
36 |
37 | override func viewDidLoad() {
38 | super.viewDidLoad()
39 |
40 | nextEventCountdownTextField.stringValue = ""
41 |
42 | setup()
43 |
44 | refreshTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true, block: { [weak self] (timer) in
45 | self?.loadCalendars()
46 | })
47 | }
48 |
49 | @objc func calendarDidChange(_ notification: Notification) {
50 | loadCalendars()
51 | }
52 |
53 | func setup() {
54 | for i in 0..<7 {
55 | let dayStackView = DayStackView(views: [])
56 | dayStackView.orientation = .vertical
57 | dayStackView.distribution = .fillEqually
58 | dayStackView.alignment = .leading
59 |
60 | weekStackView.insertArrangedSubview(dayStackView, at: i)
61 |
62 | var pos = 0
63 | for _ in startHour.. NSStackView? {
132 | guard !event.isAllDay else { return nil }
133 |
134 | var day = 0
135 | while event.startDate > Date(timeInterval: Double((day + 1) * 86400), since: start) {
136 | day += 1
137 | }
138 |
139 | guard (0 <= day) && (day <= 7) else { return nil }
140 |
141 | let hour = Calendar.current.component(.hour, from: event.startDate)
142 | guard (startHour <= hour) && (hour <= endHour) else { return nil }
143 |
144 | let dayStackView = weekStackView.arrangedSubviews[day] as! NSStackView
145 | let hourStackView = dayStackView.arrangedSubviews[hour] as! NSStackView
146 |
147 | return hourStackView
148 | }
149 |
150 | func calculateNextEvent() {
151 | let offsetStart = Date()
152 | let aDayFromNow = Date(timeIntervalSinceNow: 86400 * 3) // Just a random future date.
153 | let predicate = self.store.predicateForEvents(withStart: offsetStart, end: aDayFromNow, calendars: nil)
154 | let events = self.store.events(matching: predicate)
155 |
156 | // I couldn't find where it's guaranteed events come back sorted,
157 | // so let's do that just to be safe.
158 | let sortedEvents = events.sorted { (a, b) -> Bool in
159 | return a.startDate < b.startDate
160 | }
161 |
162 | if let nextEvent = sortedEvents.first(where: { (event) -> Bool in
163 | return !event.isAllDay && (offsetStart < event.startDate)
164 | }) {
165 | let df = RelativeDateTimeFormatter()
166 | nextEventCountdownTextField.stringValue = "Next event " + df.localizedString(fromTimeInterval: nextEvent.startDate.timeIntervalSinceNow)
167 | } else {
168 | nextEventCountdownTextField.stringValue = ""
169 | }
170 | }
171 | }
172 |
173 | class HourStackView: DayStackView {
174 |
175 | }
176 |
177 | class DayStackView: NSStackView {
178 |
179 | var backgroundColor: NSColor?
180 |
181 | override func draw(_ dirtyRect: NSRect) {
182 | if let backgroundColor = backgroundColor {
183 | let path = NSBezierPath(roundedRect: bounds, xRadius: 8, yRadius: 8)
184 | backgroundColor.setFill()
185 | path.fill()
186 | }
187 | super.draw(dirtyRect)
188 | }
189 | }
190 |
191 | class EventBubbleView: NSTextField {
192 |
193 | override var intrinsicContentSize: NSSize {
194 | let size = super.intrinsicContentSize
195 | return NSSize(width: size.width + 32, height: size.height + 16)
196 | }
197 |
198 | override func draw(_ dirtyRect: NSRect) {
199 | let path = NSBezierPath(roundedRect: bounds, xRadius: 8, yRadius: 8)
200 | backgroundColor?.setFill()
201 | path.fill()
202 | super.draw(dirtyRect)
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/Calendar Hero.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | C6C7634025DD79C600E466D7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C7633F25DD79C600E466D7 /* AppDelegate.swift */; };
11 | C6C7634225DD79C600E466D7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C7634125DD79C600E466D7 /* ViewController.swift */; };
12 | C6C7634425DD79C800E466D7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C6C7634325DD79C800E466D7 /* Assets.xcassets */; };
13 | C6C7634725DD79C800E466D7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C6C7634525DD79C800E466D7 /* Main.storyboard */; };
14 | C6C7635825DD8CE200E466D7 /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C7635725DD8CE200E466D7 /* Window.swift */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | C6C7633C25DD79C600E466D7 /* Calendar Hero.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Calendar Hero.app"; sourceTree = BUILT_PRODUCTS_DIR; };
19 | C6C7633F25DD79C600E466D7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
20 | C6C7634125DD79C600E466D7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
21 | C6C7634325DD79C800E466D7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
22 | C6C7634625DD79C800E466D7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
23 | C6C7634825DD79C800E466D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
24 | C6C7634925DD79C800E466D7 /* CalendarHero.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CalendarHero.entitlements; sourceTree = ""; };
25 | C6C7635725DD8CE200E466D7 /* Window.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Window.swift; sourceTree = ""; };
26 | /* End PBXFileReference section */
27 |
28 | /* Begin PBXFrameworksBuildPhase section */
29 | C6C7633925DD79C600E466D7 /* Frameworks */ = {
30 | isa = PBXFrameworksBuildPhase;
31 | buildActionMask = 2147483647;
32 | files = (
33 | );
34 | runOnlyForDeploymentPostprocessing = 0;
35 | };
36 | /* End PBXFrameworksBuildPhase section */
37 |
38 | /* Begin PBXGroup section */
39 | C6C7633325DD79C600E466D7 = {
40 | isa = PBXGroup;
41 | children = (
42 | C6C7633E25DD79C600E466D7 /* CalendarHero */,
43 | C6C7633D25DD79C600E466D7 /* Products */,
44 | );
45 | sourceTree = "";
46 | };
47 | C6C7633D25DD79C600E466D7 /* Products */ = {
48 | isa = PBXGroup;
49 | children = (
50 | C6C7633C25DD79C600E466D7 /* Calendar Hero.app */,
51 | );
52 | name = Products;
53 | sourceTree = "";
54 | };
55 | C6C7633E25DD79C600E466D7 /* CalendarHero */ = {
56 | isa = PBXGroup;
57 | children = (
58 | C6C7633F25DD79C600E466D7 /* AppDelegate.swift */,
59 | C6C7635725DD8CE200E466D7 /* Window.swift */,
60 | C6C7634125DD79C600E466D7 /* ViewController.swift */,
61 | C6C7634325DD79C800E466D7 /* Assets.xcassets */,
62 | C6C7634525DD79C800E466D7 /* Main.storyboard */,
63 | C6C7634825DD79C800E466D7 /* Info.plist */,
64 | C6C7634925DD79C800E466D7 /* CalendarHero.entitlements */,
65 | );
66 | path = CalendarHero;
67 | sourceTree = "";
68 | };
69 | /* End PBXGroup section */
70 |
71 | /* Begin PBXNativeTarget section */
72 | C6C7633B25DD79C600E466D7 /* Calendar Hero */ = {
73 | isa = PBXNativeTarget;
74 | buildConfigurationList = C6C7634C25DD79C800E466D7 /* Build configuration list for PBXNativeTarget "Calendar Hero" */;
75 | buildPhases = (
76 | C6C7633825DD79C600E466D7 /* Sources */,
77 | C6C7633925DD79C600E466D7 /* Frameworks */,
78 | C6C7633A25DD79C600E466D7 /* Resources */,
79 | );
80 | buildRules = (
81 | );
82 | dependencies = (
83 | );
84 | name = "Calendar Hero";
85 | productName = CalendarHero;
86 | productReference = C6C7633C25DD79C600E466D7 /* Calendar Hero.app */;
87 | productType = "com.apple.product-type.application";
88 | };
89 | /* End PBXNativeTarget section */
90 |
91 | /* Begin PBXProject section */
92 | C6C7633425DD79C600E466D7 /* Project object */ = {
93 | isa = PBXProject;
94 | attributes = {
95 | LastSwiftUpdateCheck = 1220;
96 | LastUpgradeCheck = 1220;
97 | TargetAttributes = {
98 | C6C7633B25DD79C600E466D7 = {
99 | CreatedOnToolsVersion = 12.2;
100 | };
101 | };
102 | };
103 | buildConfigurationList = C6C7633725DD79C600E466D7 /* Build configuration list for PBXProject "Calendar Hero" */;
104 | compatibilityVersion = "Xcode 9.3";
105 | developmentRegion = en;
106 | hasScannedForEncodings = 0;
107 | knownRegions = (
108 | en,
109 | Base,
110 | );
111 | mainGroup = C6C7633325DD79C600E466D7;
112 | productRefGroup = C6C7633D25DD79C600E466D7 /* Products */;
113 | projectDirPath = "";
114 | projectRoot = "";
115 | targets = (
116 | C6C7633B25DD79C600E466D7 /* Calendar Hero */,
117 | );
118 | };
119 | /* End PBXProject section */
120 |
121 | /* Begin PBXResourcesBuildPhase section */
122 | C6C7633A25DD79C600E466D7 /* Resources */ = {
123 | isa = PBXResourcesBuildPhase;
124 | buildActionMask = 2147483647;
125 | files = (
126 | C6C7634425DD79C800E466D7 /* Assets.xcassets in Resources */,
127 | C6C7634725DD79C800E466D7 /* Main.storyboard in Resources */,
128 | );
129 | runOnlyForDeploymentPostprocessing = 0;
130 | };
131 | /* End PBXResourcesBuildPhase section */
132 |
133 | /* Begin PBXSourcesBuildPhase section */
134 | C6C7633825DD79C600E466D7 /* Sources */ = {
135 | isa = PBXSourcesBuildPhase;
136 | buildActionMask = 2147483647;
137 | files = (
138 | C6C7634225DD79C600E466D7 /* ViewController.swift in Sources */,
139 | C6C7634025DD79C600E466D7 /* AppDelegate.swift in Sources */,
140 | C6C7635825DD8CE200E466D7 /* Window.swift in Sources */,
141 | );
142 | runOnlyForDeploymentPostprocessing = 0;
143 | };
144 | /* End PBXSourcesBuildPhase section */
145 |
146 | /* Begin PBXVariantGroup section */
147 | C6C7634525DD79C800E466D7 /* Main.storyboard */ = {
148 | isa = PBXVariantGroup;
149 | children = (
150 | C6C7634625DD79C800E466D7 /* Base */,
151 | );
152 | name = Main.storyboard;
153 | sourceTree = "";
154 | };
155 | /* End PBXVariantGroup section */
156 |
157 | /* Begin XCBuildConfiguration section */
158 | C6C7634A25DD79C800E466D7 /* Debug */ = {
159 | isa = XCBuildConfiguration;
160 | buildSettings = {
161 | ALWAYS_SEARCH_USER_PATHS = NO;
162 | CLANG_ANALYZER_NONNULL = YES;
163 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
164 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
165 | CLANG_CXX_LIBRARY = "libc++";
166 | CLANG_ENABLE_MODULES = YES;
167 | CLANG_ENABLE_OBJC_ARC = YES;
168 | CLANG_ENABLE_OBJC_WEAK = YES;
169 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
170 | CLANG_WARN_BOOL_CONVERSION = YES;
171 | CLANG_WARN_COMMA = YES;
172 | CLANG_WARN_CONSTANT_CONVERSION = YES;
173 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
174 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
175 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
176 | CLANG_WARN_EMPTY_BODY = YES;
177 | CLANG_WARN_ENUM_CONVERSION = YES;
178 | CLANG_WARN_INFINITE_RECURSION = YES;
179 | CLANG_WARN_INT_CONVERSION = YES;
180 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
181 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
182 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
183 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
184 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
185 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
186 | CLANG_WARN_STRICT_PROTOTYPES = YES;
187 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
188 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
189 | CLANG_WARN_UNREACHABLE_CODE = YES;
190 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
191 | COPY_PHASE_STRIP = NO;
192 | DEBUG_INFORMATION_FORMAT = dwarf;
193 | ENABLE_STRICT_OBJC_MSGSEND = YES;
194 | ENABLE_TESTABILITY = YES;
195 | GCC_C_LANGUAGE_STANDARD = gnu11;
196 | GCC_DYNAMIC_NO_PIC = NO;
197 | GCC_NO_COMMON_BLOCKS = YES;
198 | GCC_OPTIMIZATION_LEVEL = 0;
199 | GCC_PREPROCESSOR_DEFINITIONS = (
200 | "DEBUG=1",
201 | "$(inherited)",
202 | );
203 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
204 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
205 | GCC_WARN_UNDECLARED_SELECTOR = YES;
206 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
207 | GCC_WARN_UNUSED_FUNCTION = YES;
208 | GCC_WARN_UNUSED_VARIABLE = YES;
209 | MACOSX_DEPLOYMENT_TARGET = 10.15;
210 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
211 | MTL_FAST_MATH = YES;
212 | ONLY_ACTIVE_ARCH = YES;
213 | SDKROOT = macosx;
214 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
215 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
216 | };
217 | name = Debug;
218 | };
219 | C6C7634B25DD79C800E466D7 /* Release */ = {
220 | isa = XCBuildConfiguration;
221 | buildSettings = {
222 | ALWAYS_SEARCH_USER_PATHS = NO;
223 | CLANG_ANALYZER_NONNULL = YES;
224 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
225 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
226 | CLANG_CXX_LIBRARY = "libc++";
227 | CLANG_ENABLE_MODULES = YES;
228 | CLANG_ENABLE_OBJC_ARC = YES;
229 | CLANG_ENABLE_OBJC_WEAK = YES;
230 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
231 | CLANG_WARN_BOOL_CONVERSION = YES;
232 | CLANG_WARN_COMMA = YES;
233 | CLANG_WARN_CONSTANT_CONVERSION = YES;
234 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
235 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
236 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
237 | CLANG_WARN_EMPTY_BODY = YES;
238 | CLANG_WARN_ENUM_CONVERSION = YES;
239 | CLANG_WARN_INFINITE_RECURSION = YES;
240 | CLANG_WARN_INT_CONVERSION = YES;
241 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
242 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
243 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
244 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
245 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
246 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
247 | CLANG_WARN_STRICT_PROTOTYPES = YES;
248 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
249 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
250 | CLANG_WARN_UNREACHABLE_CODE = YES;
251 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
252 | COPY_PHASE_STRIP = NO;
253 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
254 | ENABLE_NS_ASSERTIONS = NO;
255 | ENABLE_STRICT_OBJC_MSGSEND = YES;
256 | GCC_C_LANGUAGE_STANDARD = gnu11;
257 | GCC_NO_COMMON_BLOCKS = YES;
258 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
259 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
260 | GCC_WARN_UNDECLARED_SELECTOR = YES;
261 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
262 | GCC_WARN_UNUSED_FUNCTION = YES;
263 | GCC_WARN_UNUSED_VARIABLE = YES;
264 | MACOSX_DEPLOYMENT_TARGET = 10.15;
265 | MTL_ENABLE_DEBUG_INFO = NO;
266 | MTL_FAST_MATH = YES;
267 | SDKROOT = macosx;
268 | SWIFT_COMPILATION_MODE = wholemodule;
269 | SWIFT_OPTIMIZATION_LEVEL = "-O";
270 | };
271 | name = Release;
272 | };
273 | C6C7634D25DD79C800E466D7 /* Debug */ = {
274 | isa = XCBuildConfiguration;
275 | buildSettings = {
276 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
277 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
278 | CODE_SIGN_ENTITLEMENTS = CalendarHero/CalendarHero.entitlements;
279 | CODE_SIGN_STYLE = Automatic;
280 | COMBINE_HIDPI_IMAGES = YES;
281 | DEVELOPMENT_TEAM = 3A6K89K388;
282 | ENABLE_HARDENED_RUNTIME = YES;
283 | INFOPLIST_FILE = CalendarHero/Info.plist;
284 | LD_RUNPATH_SEARCH_PATHS = (
285 | "$(inherited)",
286 | "@executable_path/../Frameworks",
287 | );
288 | PRODUCT_BUNDLE_IDENTIFIER = io.tyler.CalendarHero;
289 | PRODUCT_NAME = "$(TARGET_NAME)";
290 | SWIFT_VERSION = 5.0;
291 | };
292 | name = Debug;
293 | };
294 | C6C7634E25DD79C800E466D7 /* Release */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
298 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
299 | CODE_SIGN_ENTITLEMENTS = CalendarHero/CalendarHero.entitlements;
300 | CODE_SIGN_STYLE = Automatic;
301 | COMBINE_HIDPI_IMAGES = YES;
302 | DEVELOPMENT_TEAM = 3A6K89K388;
303 | ENABLE_HARDENED_RUNTIME = YES;
304 | INFOPLIST_FILE = CalendarHero/Info.plist;
305 | LD_RUNPATH_SEARCH_PATHS = (
306 | "$(inherited)",
307 | "@executable_path/../Frameworks",
308 | );
309 | PRODUCT_BUNDLE_IDENTIFIER = io.tyler.CalendarHero;
310 | PRODUCT_NAME = "$(TARGET_NAME)";
311 | SWIFT_VERSION = 5.0;
312 | };
313 | name = Release;
314 | };
315 | /* End XCBuildConfiguration section */
316 |
317 | /* Begin XCConfigurationList section */
318 | C6C7633725DD79C600E466D7 /* Build configuration list for PBXProject "Calendar Hero" */ = {
319 | isa = XCConfigurationList;
320 | buildConfigurations = (
321 | C6C7634A25DD79C800E466D7 /* Debug */,
322 | C6C7634B25DD79C800E466D7 /* Release */,
323 | );
324 | defaultConfigurationIsVisible = 0;
325 | defaultConfigurationName = Release;
326 | };
327 | C6C7634C25DD79C800E466D7 /* Build configuration list for PBXNativeTarget "Calendar Hero" */ = {
328 | isa = XCConfigurationList;
329 | buildConfigurations = (
330 | C6C7634D25DD79C800E466D7 /* Debug */,
331 | C6C7634E25DD79C800E466D7 /* Release */,
332 | );
333 | defaultConfigurationIsVisible = 0;
334 | defaultConfigurationName = Release;
335 | };
336 | /* End XCConfigurationList section */
337 | };
338 | rootObject = C6C7633425DD79C600E466D7 /* Project object */;
339 | }
340 |
--------------------------------------------------------------------------------
/CalendarHero/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
--------------------------------------------------------------------------------