├── Calendar.xcodeproj └── project.pbxproj ├── Calendar ├── AppDelegate.swift ├── Base.lproj │ └── MainMenu.xib ├── CalendarCell.swift ├── CalendarView.swift ├── IconView.swift ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── NSDate+Extentions.swift └── Resources │ └── calendar@2x.png ├── CalendarTests ├── CalendarTests.swift └── Info.plist ├── README.md └── Screenshots └── Calendar-Mac.png /Calendar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 11E2E1C31AEB889000A13E0C /* NSDate+Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11E2E1C21AEB889000A13E0C /* NSDate+Extentions.swift */; }; 11 | 1C1AB3C49EFE258EFB92D1F0 /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C1AB2EAC6F3180CFC724AEA /* CalendarView.swift */; }; 12 | 1C1AB3FF340D256FF884EEF4 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1C1ABF898539E986322389C4 /* MainMenu.xib */; }; 13 | 1C1AB531E1C833EC887814C7 /* CalendarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C1AB8997D8870B64B99C012 /* CalendarTests.swift */; }; 14 | 1C1AB720D7F6FA18C6FFB72E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1C1AB9618F2AA30773C85DAB /* Images.xcassets */; }; 15 | 1C1AB8A8F59171916CBDEF1B /* calendar@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C1AB779655CB532F38C7732 /* calendar@2x.png */; }; 16 | 1C1AB91C5B6DB8C3D29FE9C4 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C1AB41B1C25907CD8A74B30 /* IconView.swift */; }; 17 | 1C1ABCEE27A2D5CED021019F /* CalendarCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C1AB826AECA293DE5EA1C19 /* CalendarCell.swift */; }; 18 | 1C1ABDD7B5ED77A1EB3584C0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C1ABBE1387B8EF8196753F4 /* AppDelegate.swift */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 1C1AB40046BC84CD16F77D28 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 1C1AB34A13C1E480F1BA6AF0 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 1C1AB6792C9426ACF121DA84; 27 | remoteInfo = Calendar; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 11E2E1C21AEB889000A13E0C /* NSDate+Extentions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSDate+Extentions.swift"; sourceTree = ""; }; 33 | 1C1AB0B93FDCDA2B641629EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 34 | 1C1AB2EAC6F3180CFC724AEA /* CalendarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = ""; }; 35 | 1C1AB3B3780ADBBEE4798120 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 36 | 1C1AB41B1C25907CD8A74B30 /* IconView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = ""; }; 37 | 1C1AB53E6339372ADADCB931 /* Calendar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Calendar.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 1C1AB779655CB532F38C7732 /* calendar@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar@2x.png"; sourceTree = ""; }; 39 | 1C1AB7B8D0739BBE518E09DB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 40 | 1C1AB826AECA293DE5EA1C19 /* CalendarCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarCell.swift; sourceTree = ""; }; 41 | 1C1AB8997D8870B64B99C012 /* CalendarTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarTests.swift; sourceTree = ""; }; 42 | 1C1AB9618F2AA30773C85DAB /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 43 | 1C1ABBE1387B8EF8196753F4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 44 | 1C1ABC01DE711EE86F328E6F /* CalendarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CalendarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 1C1AB64620ABB27421A9D3DB /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | 1C1ABDD88A911D00D2CA5EBD /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 1C1AB1FE631BBAE23C9B2195 = { 66 | isa = PBXGroup; 67 | children = ( 68 | 1C1AB886CDF6D1A75E8E6775 /* Products */, 69 | 1C1AB5F192718B690BB7574C /* Calendar */, 70 | 1C1ABA0C735C781A11CC5FBE /* CalendarTests */, 71 | ); 72 | sourceTree = ""; 73 | }; 74 | 1C1AB2154C3EB636E0215F88 /* Resources */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 1C1AB779655CB532F38C7732 /* calendar@2x.png */, 78 | ); 79 | path = Resources; 80 | sourceTree = ""; 81 | }; 82 | 1C1AB5F192718B690BB7574C /* Calendar */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 1C1ABFD9C90DAEBA3B600452 /* Supporting Files */, 86 | 1C1AB9618F2AA30773C85DAB /* Images.xcassets */, 87 | 1C1ABBE1387B8EF8196753F4 /* AppDelegate.swift */, 88 | 1C1ABF898539E986322389C4 /* MainMenu.xib */, 89 | 1C1AB2EAC6F3180CFC724AEA /* CalendarView.swift */, 90 | 1C1AB826AECA293DE5EA1C19 /* CalendarCell.swift */, 91 | 1C1AB41B1C25907CD8A74B30 /* IconView.swift */, 92 | 11E2E1C21AEB889000A13E0C /* NSDate+Extentions.swift */, 93 | 1C1AB2154C3EB636E0215F88 /* Resources */, 94 | ); 95 | path = Calendar; 96 | sourceTree = ""; 97 | }; 98 | 1C1AB886CDF6D1A75E8E6775 /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 1C1AB53E6339372ADADCB931 /* Calendar.app */, 102 | 1C1ABC01DE711EE86F328E6F /* CalendarTests.xctest */, 103 | ); 104 | name = Products; 105 | sourceTree = ""; 106 | }; 107 | 1C1AB96C62FF9EC962ED02AE /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 1C1AB0B93FDCDA2B641629EE /* Info.plist */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | 1C1ABA0C735C781A11CC5FBE /* CalendarTests */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 1C1AB96C62FF9EC962ED02AE /* Supporting Files */, 119 | 1C1AB8997D8870B64B99C012 /* CalendarTests.swift */, 120 | ); 121 | path = CalendarTests; 122 | sourceTree = ""; 123 | }; 124 | 1C1ABFD9C90DAEBA3B600452 /* Supporting Files */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 1C1AB3B3780ADBBEE4798120 /* Info.plist */, 128 | ); 129 | name = "Supporting Files"; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | 1C1AB6792C9426ACF121DA84 /* Calendar */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 1C1ABB35BA571F18456CD159 /* Build configuration list for PBXNativeTarget "Calendar" */; 138 | buildPhases = ( 139 | 1C1ABC38F3B25262CC3464E0 /* Sources */, 140 | 1C1AB64620ABB27421A9D3DB /* Frameworks */, 141 | 1C1ABB517A47F9FA9804990E /* Resources */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = Calendar; 148 | productName = Calendar; 149 | productReference = 1C1AB53E6339372ADADCB931 /* Calendar.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | 1C1ABFA27811C9F263B37DB5 /* CalendarTests */ = { 153 | isa = PBXNativeTarget; 154 | buildConfigurationList = 1C1ABBFCF0BDABCE979E659C /* Build configuration list for PBXNativeTarget "CalendarTests" */; 155 | buildPhases = ( 156 | 1C1AB2884EFF84929DC0DDCD /* Sources */, 157 | 1C1ABDD88A911D00D2CA5EBD /* Frameworks */, 158 | 1C1ABA0BCE8C5F10A9185858 /* Resources */, 159 | ); 160 | buildRules = ( 161 | ); 162 | dependencies = ( 163 | 1C1ABF96B7431D7348B7DEA8 /* PBXTargetDependency */, 164 | ); 165 | name = CalendarTests; 166 | productName = CalendarTests; 167 | productReference = 1C1ABC01DE711EE86F328E6F /* CalendarTests.xctest */; 168 | productType = "com.apple.product-type.bundle.unit-test"; 169 | }; 170 | /* End PBXNativeTarget section */ 171 | 172 | /* Begin PBXProject section */ 173 | 1C1AB34A13C1E480F1BA6AF0 /* Project object */ = { 174 | isa = PBXProject; 175 | attributes = { 176 | ORGANIZATIONNAME = "Age Of Mobile"; 177 | }; 178 | buildConfigurationList = 1C1ABD9FD5A272DCAC0CD3DF /* Build configuration list for PBXProject "Calendar" */; 179 | compatibilityVersion = "Xcode 3.2"; 180 | developmentRegion = English; 181 | hasScannedForEncodings = 0; 182 | knownRegions = ( 183 | en, 184 | ); 185 | mainGroup = 1C1AB1FE631BBAE23C9B2195; 186 | productRefGroup = 1C1AB886CDF6D1A75E8E6775 /* Products */; 187 | projectDirPath = ""; 188 | projectRoot = ""; 189 | targets = ( 190 | 1C1AB6792C9426ACF121DA84 /* Calendar */, 191 | 1C1ABFA27811C9F263B37DB5 /* CalendarTests */, 192 | ); 193 | }; 194 | /* End PBXProject section */ 195 | 196 | /* Begin PBXResourcesBuildPhase section */ 197 | 1C1ABA0BCE8C5F10A9185858 /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | 1C1ABB517A47F9FA9804990E /* Resources */ = { 205 | isa = PBXResourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | 1C1AB720D7F6FA18C6FFB72E /* Images.xcassets in Resources */, 209 | 1C1AB3FF340D256FF884EEF4 /* MainMenu.xib in Resources */, 210 | 1C1AB8A8F59171916CBDEF1B /* calendar@2x.png in Resources */, 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXResourcesBuildPhase section */ 215 | 216 | /* Begin PBXSourcesBuildPhase section */ 217 | 1C1AB2884EFF84929DC0DDCD /* Sources */ = { 218 | isa = PBXSourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | 1C1AB531E1C833EC887814C7 /* CalendarTests.swift in Sources */, 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | }; 225 | 1C1ABC38F3B25262CC3464E0 /* Sources */ = { 226 | isa = PBXSourcesBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | 11E2E1C31AEB889000A13E0C /* NSDate+Extentions.swift in Sources */, 230 | 1C1ABDD7B5ED77A1EB3584C0 /* AppDelegate.swift in Sources */, 231 | 1C1AB3C49EFE258EFB92D1F0 /* CalendarView.swift in Sources */, 232 | 1C1ABCEE27A2D5CED021019F /* CalendarCell.swift in Sources */, 233 | 1C1AB91C5B6DB8C3D29FE9C4 /* IconView.swift in Sources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXSourcesBuildPhase section */ 238 | 239 | /* Begin PBXTargetDependency section */ 240 | 1C1ABF96B7431D7348B7DEA8 /* PBXTargetDependency */ = { 241 | isa = PBXTargetDependency; 242 | target = 1C1AB6792C9426ACF121DA84 /* Calendar */; 243 | targetProxy = 1C1AB40046BC84CD16F77D28 /* PBXContainerItemProxy */; 244 | }; 245 | /* End PBXTargetDependency section */ 246 | 247 | /* Begin PBXVariantGroup section */ 248 | 1C1ABF898539E986322389C4 /* MainMenu.xib */ = { 249 | isa = PBXVariantGroup; 250 | children = ( 251 | 1C1AB7B8D0739BBE518E09DB /* Base */, 252 | ); 253 | name = MainMenu.xib; 254 | sourceTree = ""; 255 | }; 256 | /* End PBXVariantGroup section */ 257 | 258 | /* Begin XCBuildConfiguration section */ 259 | 1C1AB128A47E84721FD36231 /* Release */ = { 260 | isa = XCBuildConfiguration; 261 | buildSettings = { 262 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Calendar.app/Contents/MacOS/Calendar"; 263 | COMBINE_HIDPI_IMAGES = YES; 264 | FRAMEWORK_SEARCH_PATHS = ( 265 | "$(DEVELOPER_FRAMEWORKS_DIR)", 266 | "$(inherited)", 267 | ); 268 | INFOPLIST_FILE = CalendarTests/Info.plist; 269 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 270 | PRODUCT_NAME = "$(TARGET_NAME)"; 271 | TEST_HOST = "$(BUNDLE_LOADER)"; 272 | }; 273 | name = Release; 274 | }; 275 | 1C1AB24E97100CADF0B1372A /* Debug */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 279 | COMBINE_HIDPI_IMAGES = YES; 280 | INFOPLIST_FILE = Calendar/Info.plist; 281 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 282 | PRODUCT_NAME = "$(TARGET_NAME)"; 283 | }; 284 | name = Debug; 285 | }; 286 | 1C1AB421295EB0B08897EEFC /* Release */ = { 287 | isa = XCBuildConfiguration; 288 | buildSettings = { 289 | ALWAYS_SEARCH_USER_PATHS = NO; 290 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 291 | CLANG_CXX_LIBRARY = "libc++"; 292 | CLANG_ENABLE_MODULES = YES; 293 | CLANG_ENABLE_OBJC_ARC = YES; 294 | CLANG_WARN_BOOL_CONVERSION = YES; 295 | CLANG_WARN_CONSTANT_CONVERSION = YES; 296 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 297 | CLANG_WARN_EMPTY_BODY = YES; 298 | CLANG_WARN_ENUM_CONVERSION = YES; 299 | CLANG_WARN_INT_CONVERSION = YES; 300 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 301 | CLANG_WARN_UNREACHABLE_CODE = YES; 302 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 303 | CODE_SIGN_IDENTITY = "-"; 304 | COPY_PHASE_STRIP = NO; 305 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 306 | ENABLE_NS_ASSERTIONS = NO; 307 | ENABLE_STRICT_OBJC_MSGSEND = YES; 308 | GCC_C_LANGUAGE_STANDARD = gnu99; 309 | GCC_NO_COMMON_BLOCKS = YES; 310 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 311 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 312 | GCC_WARN_UNDECLARED_SELECTOR = YES; 313 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 314 | GCC_WARN_UNUSED_FUNCTION = YES; 315 | GCC_WARN_UNUSED_VARIABLE = YES; 316 | MACOSX_DEPLOYMENT_TARGET = 10.10; 317 | MTL_ENABLE_DEBUG_INFO = NO; 318 | SDKROOT = macosx; 319 | }; 320 | name = Release; 321 | }; 322 | 1C1AB613653E4E100902899B /* Debug */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Calendar.app/Contents/MacOS/Calendar"; 326 | COMBINE_HIDPI_IMAGES = YES; 327 | FRAMEWORK_SEARCH_PATHS = ( 328 | "$(DEVELOPER_FRAMEWORKS_DIR)", 329 | "$(inherited)", 330 | ); 331 | INFOPLIST_FILE = CalendarTests/Info.plist; 332 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 333 | PRODUCT_NAME = "$(TARGET_NAME)"; 334 | TEST_HOST = "$(BUNDLE_LOADER)"; 335 | }; 336 | name = Debug; 337 | }; 338 | 1C1ABC3F96BE3E3CFA4374A8 /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_MODULES = YES; 345 | CLANG_ENABLE_OBJC_ARC = YES; 346 | CLANG_WARN_BOOL_CONVERSION = YES; 347 | CLANG_WARN_CONSTANT_CONVERSION = YES; 348 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 349 | CLANG_WARN_EMPTY_BODY = YES; 350 | CLANG_WARN_ENUM_CONVERSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 353 | CLANG_WARN_UNREACHABLE_CODE = YES; 354 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 355 | CODE_SIGN_IDENTITY = "-"; 356 | COPY_PHASE_STRIP = NO; 357 | DEBUG_INFORMATION_FORMAT = dwarf; 358 | ENABLE_STRICT_OBJC_MSGSEND = YES; 359 | GCC_C_LANGUAGE_STANDARD = gnu99; 360 | GCC_DYNAMIC_NO_PIC = NO; 361 | GCC_NO_COMMON_BLOCKS = YES; 362 | GCC_OPTIMIZATION_LEVEL = 0; 363 | GCC_PREPROCESSOR_DEFINITIONS = ( 364 | "DEBUG=1", 365 | "$(inherited)", 366 | ); 367 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 368 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 369 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 370 | GCC_WARN_UNDECLARED_SELECTOR = YES; 371 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 372 | GCC_WARN_UNUSED_FUNCTION = YES; 373 | GCC_WARN_UNUSED_VARIABLE = YES; 374 | MACOSX_DEPLOYMENT_TARGET = 10.10; 375 | MTL_ENABLE_DEBUG_INFO = YES; 376 | ONLY_ACTIVE_ARCH = YES; 377 | SDKROOT = macosx; 378 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 379 | }; 380 | name = Debug; 381 | }; 382 | 1C1ABF3A631C478163AFC62A /* Release */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 386 | COMBINE_HIDPI_IMAGES = YES; 387 | INFOPLIST_FILE = Calendar/Info.plist; 388 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 389 | PRODUCT_NAME = "$(TARGET_NAME)"; 390 | }; 391 | name = Release; 392 | }; 393 | /* End XCBuildConfiguration section */ 394 | 395 | /* Begin XCConfigurationList section */ 396 | 1C1ABB35BA571F18456CD159 /* Build configuration list for PBXNativeTarget "Calendar" */ = { 397 | isa = XCConfigurationList; 398 | buildConfigurations = ( 399 | 1C1AB24E97100CADF0B1372A /* Debug */, 400 | 1C1ABF3A631C478163AFC62A /* Release */, 401 | ); 402 | defaultConfigurationIsVisible = 0; 403 | defaultConfigurationName = Release; 404 | }; 405 | 1C1ABBFCF0BDABCE979E659C /* Build configuration list for PBXNativeTarget "CalendarTests" */ = { 406 | isa = XCConfigurationList; 407 | buildConfigurations = ( 408 | 1C1AB613653E4E100902899B /* Debug */, 409 | 1C1AB128A47E84721FD36231 /* Release */, 410 | ); 411 | defaultConfigurationIsVisible = 0; 412 | defaultConfigurationName = Release; 413 | }; 414 | 1C1ABD9FD5A272DCAC0CD3DF /* Build configuration list for PBXProject "Calendar" */ = { 415 | isa = XCConfigurationList; 416 | buildConfigurations = ( 417 | 1C1ABC3F96BE3E3CFA4374A8 /* Debug */, 418 | 1C1AB421295EB0B08897EEFC /* Release */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | defaultConfigurationName = Release; 422 | }; 423 | /* End XCConfigurationList section */ 424 | }; 425 | rootObject = 1C1AB34A13C1E480F1BA6AF0 /* Project object */; 426 | } 427 | -------------------------------------------------------------------------------- /Calendar/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Calendar 4 | // 5 | // Created by Tri on 4/24/15. 6 | // Copyright (c) 2015 Age Of Mobile. All rights reserved. 7 | // 8 | 9 | 10 | import Cocoa 11 | 12 | 13 | @NSApplicationMain 14 | class AppDelegate: NSObject, NSApplicationDelegate { 15 | 16 | @IBOutlet weak var window: NSWindow! 17 | @IBOutlet weak var popover: NSPopover! 18 | 19 | private var popoverTransiencyMonitor : AnyObject! 20 | private let icon: IconView; 21 | 22 | override init() { 23 | let bar = NSStatusBar.systemStatusBar() 24 | 25 | let length: CGFloat = -1 //NSVariableStatusItemLength 26 | let item = bar.statusItemWithLength(length) 27 | 28 | self.icon = IconView(imageName: "calendar", item: item) 29 | item.view = icon 30 | 31 | super.init() 32 | } 33 | 34 | override func awakeFromNib() { 35 | self.popover?.appearance = NSAppearance(named: NSAppearanceNameAqua) 36 | let edge = NSMinYEdge 37 | let icon = self.icon 38 | let rect = icon.frame 39 | 40 | icon.onMouseDown = { 41 | if (icon.isSelected) { 42 | let calendarView : CalendarView = 43 | self.popover?.contentViewController?.view as! CalendarView; 44 | calendarView.updateViews() 45 | self.popover?.showRelativeToRect(rect, ofView: icon, preferredEdge: edge) 46 | if (self.popoverTransiencyMonitor == nil) { 47 | self.popoverTransiencyMonitor = NSEvent.addGlobalMonitorForEventsMatchingMask((.LeftMouseDownMask | .RightMouseDownMask | .KeyUpMask), 48 | handler: { (e: NSEvent!) -> Void in 49 | icon.isSelected = false 50 | NSEvent.removeMonitor(self.popoverTransiencyMonitor) 51 | self.popoverTransiencyMonitor = nil 52 | self.popover?.close() 53 | }) 54 | } 55 | return 56 | } 57 | self.popover?.close() 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Calendar/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Calendar/CalendarCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Tri on 4/24/15. 3 | // Copyright (c) 2015 Age Of Mobile. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | import Cocoa 8 | 9 | class CalendarCell : NSButton { 10 | var otherMonths : Bool = false 11 | var date : NSDate = NSDate() 12 | var currentMonthAttributes : [NSObject: AnyObject]! 13 | var otherMonthAttributes : [NSObject: AnyObject]! 14 | 15 | var titleFont : NSFont = NSFont(name: "HelveticaNeue", size: 15.0)! 16 | var otherMonthTitleFont : NSFont = NSFont(name: "HelveticaNeue-Light", size: 15.0)! 17 | 18 | var backgroundColor = NSColor.whiteColor() 19 | var borderColor = NSColor(red: 0.85, green: 0.85, blue: 0.85, alpha: 1.0) 20 | var todayBackgroundColor = NSColor(red: 0.85, green: 0.85, blue: 0.85, alpha: 1.0) 21 | var weekendBackgroundColor = NSColor.whiteColor() 22 | 23 | var textColor = NSColor.blackColor() 24 | var otherMonthTextColor = NSColor.lightGrayColor() 25 | var todayTextColor = NSColor.blackColor() 26 | var weekendTextColor = NSColor(red: 1.0, green: 0, blue: 0, alpha: 1.0) 27 | var otherMonthWeekendTextColor = NSColor.lightGrayColor() 28 | var otherMonthTodayTextColor = NSColor.lightGrayColor() 29 | 30 | override init(frame frameRect: NSRect) { 31 | super.init(frame: frameRect) 32 | commonInit() 33 | } 34 | 35 | required init?(coder: NSCoder) { 36 | super.init(coder: coder) 37 | commonInit() 38 | } 39 | 40 | func commonInit() { 41 | self.wantsLayer = true 42 | self.layer?.cornerRadius = self.frame.size.width / 2 43 | self.layer?.borderColor = borderColor.CGColor 44 | self.layer?.borderWidth = 1.0 45 | } 46 | 47 | func update() { 48 | var buttonCell = self.cell() as! NSButtonCell 49 | if (date.isToday()) { 50 | self.layer?.backgroundColor = todayBackgroundColor.CGColor 51 | } else if (date.isWeekend()) { 52 | self.layer?.backgroundColor = weekendBackgroundColor.CGColor; 53 | } else { 54 | self.layer?.backgroundColor = backgroundColor.CGColor 55 | } 56 | self.attributedTitle = NSAttributedString(string: "\(date.day)", attributes: titleAttributes()) 57 | } 58 | 59 | func titleAttributes() -> [NSObject: AnyObject]! { 60 | if (otherMonths) { 61 | if (otherMonthAttributes == nil) { 62 | otherMonthAttributes = commonTitleAttributes() 63 | } 64 | 65 | if (date.isToday()) { 66 | otherMonthAttributes[NSForegroundColorAttributeName] = otherMonthTodayTextColor 67 | } else if (date.isWeekend()) { 68 | otherMonthAttributes[NSForegroundColorAttributeName] = otherMonthWeekendTextColor 69 | } else { 70 | otherMonthAttributes[NSForegroundColorAttributeName] = otherMonthTextColor 71 | } 72 | otherMonthAttributes[NSFontAttributeName] = otherMonthTitleFont 73 | return otherMonthAttributes 74 | 75 | } else { 76 | if (currentMonthAttributes == nil) { 77 | currentMonthAttributes = commonTitleAttributes() 78 | } 79 | currentMonthAttributes[NSFontAttributeName] = titleFont 80 | 81 | if (date.isToday()) { 82 | currentMonthAttributes[NSForegroundColorAttributeName] = todayTextColor 83 | } else if (date.isWeekend()) { 84 | currentMonthAttributes[NSForegroundColorAttributeName] = weekendTextColor 85 | } else { 86 | currentMonthAttributes[NSForegroundColorAttributeName] = textColor; 87 | } 88 | return currentMonthAttributes 89 | } 90 | } 91 | 92 | func commonTitleAttributes() -> [NSObject: AnyObject] { 93 | var attributes : [NSObject: AnyObject] = [:] 94 | attributes[NSFontAttributeName] = titleFont 95 | var paragraphStyle = NSMutableParagraphStyle() 96 | paragraphStyle.alignment = .CenterTextAlignment 97 | attributes[NSParagraphStyleAttributeName] = paragraphStyle 98 | return attributes 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Calendar/CalendarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Tri on 4/24/15. 3 | // Copyright (c) 2015 Age Of Mobile. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | import Cocoa 8 | 9 | class CalendarView : NSView { 10 | let horizontalPadding: CGFloat = 5 11 | let verticalPadding: CGFloat = 5 12 | let cellWidth: CGFloat = 40 13 | let cellHeight: CGFloat = 40 14 | let font : NSFont! = NSFont(name: "HelveticaNeue-Light", size: 15.0) 15 | 16 | var titleBackgroundColor = NSColor.clearColor() 17 | var backgroundColor = NSColor.whiteColor() 18 | var dayOfWeekBackgroundColor = NSColor.clearColor() 19 | var previousMonthIcon = NSImage(named: "NSLeftFacingTriangleTemplate") 20 | var nextMonthIcon = NSImage(named: "NSRightFacingTriangleTemplate") 21 | 22 | var previousMonthView : NSButton! 23 | var nextMonthView : NSButton! 24 | var monthLabelView: NSTextField! 25 | var dayCells : [CalendarCell] = [] 26 | 27 | var date: NSDate = NSDate() 28 | var monthFormatter : NSDateFormatter = NSDateFormatter() 29 | let calendar = NSCalendar.currentCalendar() 30 | 31 | required init?(coder: NSCoder) { 32 | super.init(coder: coder) 33 | monthFormatter.dateFormat = "MMMM, yyyy" 34 | initViews() 35 | updateViews(); 36 | } 37 | 38 | func initViews() { 39 | let width = CGFloat(8.0 * horizontalPadding + 7.0 * cellWidth) 40 | let height = CGFloat(8.0 * verticalPadding + 8.0 * cellHeight) 41 | NSLayoutConstraint.activateConstraints([ 42 | NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal, 43 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: width), 44 | NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal, 45 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: height) 46 | ]) 47 | 48 | // layout title views 49 | previousMonthView = NSButton(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight)) 50 | previousMonthView.image = previousMonthIcon 51 | previousMonthView.translatesAutoresizingMaskIntoConstraints = false 52 | previousMonthView.bordered = false 53 | addSubview(previousMonthView) 54 | NSLayoutConstraint.activateConstraints([ 55 | NSLayoutConstraint(item: previousMonthView, attribute: .Left, relatedBy: .Equal, 56 | toItem: self, attribute: .Left, multiplier: 1.0, constant: horizontalPadding), 57 | NSLayoutConstraint(item: previousMonthView, attribute: .Width, relatedBy: .Equal, 58 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: cellWidth), 59 | NSLayoutConstraint(item: previousMonthView, attribute: .Height, relatedBy: .Equal, 60 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: cellHeight), 61 | NSLayoutConstraint(item: previousMonthView, attribute: .Top, relatedBy: .Equal, 62 | toItem: self, attribute: .Top, multiplier: 1.0, constant: verticalPadding) 63 | ]) 64 | previousMonthView.action = Selector("previousMonth") 65 | previousMonthView.target = self 66 | 67 | nextMonthView = NSButton(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight)) 68 | nextMonthView.image = nextMonthIcon 69 | nextMonthView.translatesAutoresizingMaskIntoConstraints = false 70 | nextMonthView.bordered = false 71 | addSubview(nextMonthView) 72 | NSLayoutConstraint.activateConstraints([ 73 | NSLayoutConstraint(item: nextMonthView, attribute: .Right, relatedBy: .Equal, 74 | toItem: self, attribute: .Right, multiplier: 1.0, constant: -horizontalPadding), 75 | NSLayoutConstraint(item: nextMonthView, attribute: .Width, relatedBy: .Equal, 76 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: cellWidth), 77 | NSLayoutConstraint(item: nextMonthView, attribute: .Height, relatedBy: .Equal, 78 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: cellHeight), 79 | NSLayoutConstraint(item: nextMonthView, attribute: .Top, relatedBy: .Equal, 80 | toItem: self, attribute: .Top, multiplier: 1.0, constant: verticalPadding) 81 | ]) 82 | nextMonthView.action = Selector("nextMonth") 83 | nextMonthView.target = self 84 | 85 | monthLabelView = NSTextField(frame: CGRect.zeroRect) 86 | monthLabelView.stringValue = monthTitle() 87 | monthLabelView.editable = false 88 | monthLabelView.font = font 89 | monthLabelView.backgroundColor = titleBackgroundColor 90 | monthLabelView.alignment = .CenterTextAlignment 91 | monthLabelView.translatesAutoresizingMaskIntoConstraints = false 92 | monthLabelView.bordered = false 93 | addSubview(monthLabelView) 94 | NSLayoutConstraint.activateConstraints([ 95 | NSLayoutConstraint(item: monthLabelView, attribute: .Left, relatedBy: .Equal, 96 | toItem: previousMonthView, attribute: .Right, multiplier: 1.0, constant: horizontalPadding), 97 | NSLayoutConstraint(item: monthLabelView, attribute: .CenterY, relatedBy: .Equal, 98 | toItem: previousMonthView, attribute: .CenterY, multiplier: 1.0, constant: 0), 99 | NSLayoutConstraint(item: monthLabelView, attribute: .Right, relatedBy: .Equal, 100 | toItem: nextMonthView, attribute: .Left, multiplier: 1.0, constant: -horizontalPadding), 101 | NSLayoutConstraint(item: nextMonthView, attribute: .Height, relatedBy: .Equal, 102 | toItem: previousMonthView, attribute: .Height, multiplier: 1.0, constant: 0) 103 | ]) 104 | 105 | // layout day label views 106 | var previousCell : NSView = self 107 | let widthMultiplier : CGFloat = 1.0 / 7.0 108 | for i in 0...6 { 109 | var dayLabel = NSTextField(frame: CGRect.zeroRect) 110 | dayLabel.stringValue = "\(calendar.shortWeekdaySymbols[i])" 111 | dayLabel.editable = false 112 | dayLabel.font = font 113 | dayLabel.backgroundColor = dayOfWeekBackgroundColor 114 | dayLabel.alignment = .CenterTextAlignment 115 | dayLabel.translatesAutoresizingMaskIntoConstraints = false 116 | dayLabel.bordered = false 117 | addSubview(dayLabel) 118 | NSLayoutConstraint.activateConstraints([ 119 | NSLayoutConstraint(item: dayLabel, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, 120 | toItem: previousCell, attribute: previousCell == self ? NSLayoutAttribute.Left : NSLayoutAttribute.Right, multiplier: 1.0, constant: 0), 121 | NSLayoutConstraint(item: dayLabel, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, 122 | toItem: self, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: CGFloat(verticalPadding + cellHeight)), 123 | NSLayoutConstraint(item: dayLabel, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, 124 | toItem: self, attribute: NSLayoutAttribute.Width, multiplier: widthMultiplier, constant: 0), 125 | NSLayoutConstraint(item: dayLabel, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, 126 | toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: cellHeight) 127 | ]) 128 | previousCell = dayLabel 129 | } 130 | 131 | // layout days of month views 132 | var index: Int = 0 133 | for row in 0...5 { 134 | previousCell = self 135 | for col in 0...6 { 136 | var dayCell = CalendarCell(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight)) 137 | dayCell.font = font 138 | dayCell.translatesAutoresizingMaskIntoConstraints = false 139 | dayCell.bordered = false 140 | addSubview(dayCell) 141 | let topConstraint : CGFloat = CGFloat(2 + row) * (cellHeight + verticalPadding) 142 | NSLayoutConstraint.activateConstraints([ 143 | NSLayoutConstraint(item: dayCell, attribute: .Left, relatedBy: .Equal, 144 | toItem: previousCell, attribute: previousCell == self ? .Left : .Right, multiplier: 1.0, constant: horizontalPadding), 145 | NSLayoutConstraint(item: dayCell, attribute: .Top, relatedBy: .Equal, 146 | toItem: self, attribute: .Top, multiplier: 1.0, constant: topConstraint), 147 | NSLayoutConstraint(item: dayCell, attribute: .Width, relatedBy: .Equal, 148 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: cellWidth), 149 | NSLayoutConstraint(item: dayCell, attribute: .Height, relatedBy: .Equal, 150 | toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: cellHeight) 151 | ]) 152 | previousCell = dayCell 153 | dayCells.append(dayCell) 154 | index++ 155 | } 156 | } 157 | } 158 | 159 | override func drawRect(dirtyRect: NSRect) { 160 | backgroundColor.setFill() 161 | NSRectFill(self.bounds) 162 | } 163 | 164 | func previousMonth() { 165 | date = date.dateByAddingMonths(-1) 166 | updateViews() 167 | } 168 | 169 | func nextMonth() { 170 | date = date.dateByAddingMonths(1) 171 | updateViews() 172 | } 173 | 174 | func monthTitle() -> String { 175 | return monthFormatter.stringFromDate(self.date); 176 | } 177 | 178 | func updateViews() { 179 | monthLabelView.stringValue = monthTitle() 180 | 181 | var beginOfMonthDate = date.beginOfMonth() 182 | var weekday = calendar.component(.CalendarUnitWeekday, fromDate: beginOfMonthDate) 183 | var firstDayOfMonthIndex = weekday - calendar.firstWeekday 184 | var lastDayIndex = firstDayOfMonthIndex + date.daysOfMonth() - 1 185 | var currentDate = beginOfMonthDate.dateByAddingDays(-firstDayOfMonthIndex) 186 | for index in 0.. lastDayIndex { 190 | cell.otherMonths = true 191 | } else { 192 | cell.otherMonths = false 193 | } 194 | cell.update() 195 | currentDate = currentDate.dateByAddingDays(1) 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Calendar/IconView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Tri on 4/24/15. 3 | // Copyright (c) 2015 Age Of Mobile. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | import Cocoa 8 | 9 | class IconView: NSView { 10 | private(set) var image: NSImage 11 | private let item: NSStatusItem 12 | 13 | var onMouseDown: () -> () 14 | 15 | var isSelected: Bool { 16 | didSet { 17 | //redraw if isSelected changes for bg highlight 18 | if (isSelected != oldValue) { 19 | self.needsDisplay = true 20 | } 21 | } 22 | } 23 | 24 | init(imageName: String, item: NSStatusItem) { 25 | self.image = NSImage(named: imageName)! 26 | self.item = item 27 | self.isSelected = false 28 | self.onMouseDown = { 29 | } 30 | 31 | let thickness = NSStatusBar.systemStatusBar().thickness 32 | let rect = CGRectMake(0, 0, thickness, thickness) 33 | 34 | super.init(frame: rect) 35 | } 36 | 37 | required init?(coder: NSCoder) { 38 | fatalError("init(coder:) has not been implemented") 39 | } 40 | 41 | 42 | override func drawRect(dirtyRect: NSRect) { 43 | self.item.drawStatusBarBackgroundInRect(dirtyRect, withHighlight: self.isSelected) 44 | 45 | let size = self.image.size 46 | let rect = CGRectMake(2, 2, size.width, size.height) 47 | 48 | self.image.drawInRect(rect) 49 | } 50 | 51 | override func mouseDown(theEvent: NSEvent) { 52 | self.isSelected = !self.isSelected; 53 | self.onMouseDown(); 54 | } 55 | 56 | override func mouseUp(theEvent: NSEvent) { 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Calendar/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Calendar/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleIdentifier 7 | com.ageofmobile.$(PRODUCT_NAME:rfc1034identifier) 8 | CFBundleInfoDictionaryVersion 9 | 6.0 10 | CFBundleSignature 11 | ???? 12 | 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | 16 | CFBundleName 17 | $(PRODUCT_NAME) 18 | 19 | CFBundleDevelopmentRegion 20 | en 21 | 22 | CFBundleShortVersionString 23 | 1.0 24 | CFBundleVersion 25 | 1 26 | 27 | CFBundlePackageType 28 | APPL 29 | 30 | CFBundleIconFile 31 | 32 | 33 | LSMinimumSystemVersion 34 | $(MACOSX_DEPLOYMENT_TARGET) 35 | 36 | NSMainNibFile 37 | MainMenu 38 | 39 | NSPrincipalClass 40 | NSApplication 41 | 42 | NSHumanReadableCopyright 43 | Copyright © 2015 Age Of Mobile. All rights reserved. 44 | LSUIElement 45 | 46 | 47 | -------------------------------------------------------------------------------- /Calendar/NSDate+Extentions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Extentions.swift 3 | // Calendar 4 | // 5 | // Created by Tri on 4/25/15. 6 | // Copyright (c) 2015 Age Of Mobile. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension NSDate { 12 | var day : Int { 13 | get { 14 | var calendar = NSCalendar.currentCalendar() 15 | var components = calendar.components(.CalendarUnitDay, fromDate: self) 16 | return components.day 17 | } 18 | } 19 | 20 | func isToday() -> Bool { 21 | var calendar = NSCalendar.currentCalendar() 22 | return calendar.isDateInToday(self) 23 | } 24 | 25 | func isWeekend() -> Bool { 26 | var calendar = NSCalendar.currentCalendar() 27 | return calendar.isDateInWeekend(self) 28 | } 29 | 30 | func dateByAddingDays(days: Int) -> NSDate { 31 | var calendar = NSCalendar.currentCalendar() 32 | return calendar.dateByAddingUnit(.CalendarUnitDay, value: days, toDate: self, options: nil)! 33 | } 34 | 35 | func dateByAddingMonths(months: Int) -> NSDate { 36 | var calendar = NSCalendar.currentCalendar() 37 | return calendar.dateByAddingUnit(.CalendarUnitMonth, value: months, toDate: self, options: nil)! 38 | } 39 | 40 | func beginOfMonth() -> NSDate { 41 | var calendar = NSCalendar.currentCalendar() 42 | var components = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: self) 43 | components.day = 1 44 | return calendar.dateFromComponents(components)! 45 | } 46 | 47 | func daysOfMonth() -> Int { 48 | var calendar = NSCalendar.currentCalendar() 49 | return calendar.rangeOfUnit(.CalendarUnitDay, inUnit: .CalendarUnitMonth, forDate: self).length 50 | } 51 | } -------------------------------------------------------------------------------- /Calendar/Resources/calendar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgeOfMobile/Calendar-Mac/a1f9509a417d129ae99040fcf98b97d93b31f7c3/Calendar/Resources/calendar@2x.png -------------------------------------------------------------------------------- /CalendarTests/CalendarTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarTests.swift 3 | // CalendarTests 4 | // 5 | // Created by Tri on 4/24/15. 6 | // Copyright (c) 2015 Age Of Mobile. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import XCTest 11 | 12 | class CalendarTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /CalendarTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleIdentifier 7 | com.ageofmobile.$(PRODUCT_NAME:rfc1034identifier) 8 | CFBundleInfoDictionaryVersion 9 | 6.0 10 | CFBundleSignature 11 | ???? 12 | 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | 16 | CFBundleName 17 | $(PRODUCT_NAME) 18 | 19 | CFBundleDevelopmentRegion 20 | en 21 | 22 | CFBundleShortVersionString 23 | 1.0 24 | CFBundleVersion 25 | 1 26 | 27 | CFBundlePackageType 28 | BNDL 29 | 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Calendar for Mac 2 | A small status bar app, which shows a month calendar when clicking on the status bar icon 3 | 4 | ![Simple Calendar for Mac](Screenshots/Calendar-Mac.png "Simple Calendar for Mac") 5 | -------------------------------------------------------------------------------- /Screenshots/Calendar-Mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgeOfMobile/Calendar-Mac/a1f9509a417d129ae99040fcf98b97d93b31f7c3/Screenshots/Calendar-Mac.png --------------------------------------------------------------------------------