├── .gitignore ├── KBButton.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── Kyle.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── Kyle.xcuserdatad │ └── xcschemes │ ├── KBButton.xcscheme │ └── xcschememanagement.plist ├── KBButton ├── KBAppDelegate.h ├── KBAppDelegate.m ├── KBButton-Info.plist ├── KBButton-Prefix.pch ├── KBButton │ ├── KBButton.h │ ├── KBButton.m │ ├── KBButtonCell.h │ ├── KBButtonCell.m │ ├── NSColor+ColorExtensions.h │ └── NSColor+ColorExtensions.m ├── en.lproj │ ├── Credits.rtf │ ├── InfoPlist.strings │ └── MainMenu.xib └── main.m ├── MIT-LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 / OS X Source projects 3 | # 4 | # NB: if you are storing "built" products, this WILL NOT WORK, 5 | # and you should use a different .gitignore (or none at all) 6 | # This file is for SOURCE projects, where there are many extra 7 | # files that we want to exclude 8 | # 9 | # For updates, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 10 | ######################### 11 | 12 | ##### 13 | # OS X temporary files that should never be committed 14 | 15 | .DS_Store 16 | *.swp 17 | *.lock 18 | profile 19 | 20 | 21 | #### 22 | # Xcode temporary files that should never be committed 23 | # 24 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... 25 | 26 | *~.nib 27 | 28 | 29 | #### 30 | # Xcode build files - 31 | # 32 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" 33 | 34 | DerivedData/ 35 | 36 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 37 | 38 | build/ 39 | 40 | 41 | ##### 42 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 43 | # 44 | # This is complicated: 45 | # 46 | # SOMETIMES you need to put this file in version control. 47 | # Apple designed it poorly - if you use "custom executables", they are 48 | # saved in this file. 49 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 50 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 51 | 52 | *.pbxuser 53 | *.mode1v3 54 | *.mode2v3 55 | *.perspectivev3 56 | # NB: also, whitelist the default ones, some projects need to use these 57 | !default.pbxuser 58 | !default.mode1v3 59 | !default.mode2v3 60 | !default.perspectivev3 61 | 62 | 63 | #### 64 | # Xcode 4 - semi-personal settings, often included in workspaces 65 | # 66 | # You can safely ignore the xcuserdata files - but do NOT ignore the files next to them 67 | # 68 | 69 | xcuserdata 70 | 71 | 72 | #### 73 | # XCode 4 workspaces - more detailed 74 | # 75 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 76 | # 77 | # Workspace layout is quite spammy. For reference: 78 | # 79 | # (root)/ 80 | # (project-name).xcodeproj/ 81 | # project.pbxproj 82 | # project.xcworkspace/ 83 | # contents.xcworkspacedata 84 | # xcuserdata/ 85 | # (your name)/xcuserdatad/ 86 | # xcuserdata/ 87 | # (your name)/xcuserdatad/ 88 | # 89 | # 90 | # 91 | # Xcode 4 workspaces - SHARED 92 | # 93 | # This is UNDOCUMENTED (google: "developer.apple.com xcshareddata" - 0 results 94 | # But if you're going to kill personal workspaces, at least keep the shared ones... 95 | # 96 | # 97 | !xcshareddata 98 | 99 | 100 | #### 101 | # Xcode 4 - Deprecated classes 102 | # 103 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 104 | # 105 | # We're using source-control, so this is a "feature" that we do not want! 106 | 107 | *.moved-aside 108 | 109 | 110 | #### 111 | # UNKNOWN: recommended by others, but I can't discover what these files are 112 | # 113 | # ...none. Everything is now explained. 114 | -------------------------------------------------------------------------------- /KBButton.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2769915E1644650D001C8375 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2769915D1644650D001C8375 /* Cocoa.framework */; }; 11 | 276991681644650D001C8375 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 276991661644650D001C8375 /* InfoPlist.strings */; }; 12 | 2769916A1644650D001C8375 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 276991691644650D001C8375 /* main.m */; }; 13 | 2769916E1644650D001C8375 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2769916C1644650D001C8375 /* Credits.rtf */; }; 14 | 276991711644650D001C8375 /* KBAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 276991701644650D001C8375 /* KBAppDelegate.m */; }; 15 | 276991741644650D001C8375 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 276991721644650D001C8375 /* MainMenu.xib */; }; 16 | 2769917C16446525001C8375 /* KBButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2769917B16446525001C8375 /* KBButtonCell.m */; }; 17 | FBF7C6D416456EB500D197E7 /* KBButton.m in Sources */ = {isa = PBXBuildFile; fileRef = FBF7C6D316456EB500D197E7 /* KBButton.m */; }; 18 | FBF7C6D81645AAF300D197E7 /* NSColor+ColorExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = FBF7C6D71645AAF300D197E7 /* NSColor+ColorExtensions.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 276991591644650D001C8375 /* KBButton.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KBButton.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 2769915D1644650D001C8375 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 24 | 276991601644650D001C8375 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 25 | 276991611644650D001C8375 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 26 | 276991621644650D001C8375 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 27 | 276991651644650D001C8375 /* KBButton-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "KBButton-Info.plist"; sourceTree = ""; }; 28 | 276991671644650D001C8375 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 29 | 276991691644650D001C8375 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | 2769916B1644650D001C8375 /* KBButton-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KBButton-Prefix.pch"; sourceTree = ""; }; 31 | 2769916D1644650D001C8375 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 32 | 2769916F1644650D001C8375 /* KBAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAppDelegate.h; sourceTree = ""; }; 33 | 276991701644650D001C8375 /* KBAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBAppDelegate.m; sourceTree = ""; }; 34 | 276991731644650D001C8375 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 35 | 2769917A16446525001C8375 /* KBButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KBButtonCell.h; path = KBButton/KBButtonCell.h; sourceTree = ""; }; 36 | 2769917B16446525001C8375 /* KBButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KBButtonCell.m; path = KBButton/KBButtonCell.m; sourceTree = ""; }; 37 | FBF7C6D216456EB500D197E7 /* KBButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KBButton.h; path = KBButton/KBButton.h; sourceTree = ""; }; 38 | FBF7C6D316456EB500D197E7 /* KBButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KBButton.m; path = KBButton/KBButton.m; sourceTree = ""; }; 39 | FBF7C6D61645AAF300D197E7 /* NSColor+ColorExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSColor+ColorExtensions.h"; path = "KBButton/NSColor+ColorExtensions.h"; sourceTree = ""; }; 40 | FBF7C6D71645AAF300D197E7 /* NSColor+ColorExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSColor+ColorExtensions.m"; path = "KBButton/NSColor+ColorExtensions.m"; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 276991561644650D001C8375 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 2769915E1644650D001C8375 /* Cocoa.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 2769914E1644650D001C8375 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 276991631644650D001C8375 /* KBButton */, 59 | 2769915C1644650D001C8375 /* Frameworks */, 60 | 2769915A1644650D001C8375 /* Products */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | 2769915A1644650D001C8375 /* Products */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 276991591644650D001C8375 /* KBButton.app */, 68 | ); 69 | name = Products; 70 | sourceTree = ""; 71 | }; 72 | 2769915C1644650D001C8375 /* Frameworks */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 2769915D1644650D001C8375 /* Cocoa.framework */, 76 | 2769915F1644650D001C8375 /* Other Frameworks */, 77 | ); 78 | name = Frameworks; 79 | sourceTree = ""; 80 | }; 81 | 2769915F1644650D001C8375 /* Other Frameworks */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 276991601644650D001C8375 /* AppKit.framework */, 85 | 276991611644650D001C8375 /* CoreData.framework */, 86 | 276991621644650D001C8375 /* Foundation.framework */, 87 | ); 88 | name = "Other Frameworks"; 89 | sourceTree = ""; 90 | }; 91 | 276991631644650D001C8375 /* KBButton */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 2769916F1644650D001C8375 /* KBAppDelegate.h */, 95 | 276991701644650D001C8375 /* KBAppDelegate.m */, 96 | 276991721644650D001C8375 /* MainMenu.xib */, 97 | 276991641644650D001C8375 /* Supporting Files */, 98 | 2769917D16446574001C8375 /* KBButton */, 99 | ); 100 | path = KBButton; 101 | sourceTree = ""; 102 | }; 103 | 276991641644650D001C8375 /* Supporting Files */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 276991651644650D001C8375 /* KBButton-Info.plist */, 107 | 276991661644650D001C8375 /* InfoPlist.strings */, 108 | 276991691644650D001C8375 /* main.m */, 109 | 2769916B1644650D001C8375 /* KBButton-Prefix.pch */, 110 | 2769916C1644650D001C8375 /* Credits.rtf */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | 2769917D16446574001C8375 /* KBButton */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 2769917A16446525001C8375 /* KBButtonCell.h */, 119 | 2769917B16446525001C8375 /* KBButtonCell.m */, 120 | FBF7C6D216456EB500D197E7 /* KBButton.h */, 121 | FBF7C6D316456EB500D197E7 /* KBButton.m */, 122 | FBF7C6D61645AAF300D197E7 /* NSColor+ColorExtensions.h */, 123 | FBF7C6D71645AAF300D197E7 /* NSColor+ColorExtensions.m */, 124 | ); 125 | name = KBButton; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | 276991581644650D001C8375 /* KBButton */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = 276991771644650D001C8375 /* Build configuration list for PBXNativeTarget "KBButton" */; 134 | buildPhases = ( 135 | 276991551644650D001C8375 /* Sources */, 136 | 276991561644650D001C8375 /* Frameworks */, 137 | 276991571644650D001C8375 /* Resources */, 138 | ); 139 | buildRules = ( 140 | ); 141 | dependencies = ( 142 | ); 143 | name = KBButton; 144 | productName = KBButton; 145 | productReference = 276991591644650D001C8375 /* KBButton.app */; 146 | productType = "com.apple.product-type.application"; 147 | }; 148 | /* End PBXNativeTarget section */ 149 | 150 | /* Begin PBXProject section */ 151 | 276991501644650D001C8375 /* Project object */ = { 152 | isa = PBXProject; 153 | attributes = { 154 | CLASSPREFIX = KB; 155 | LastUpgradeCheck = 0450; 156 | ORGANIZATIONNAME = "Kyle Bock"; 157 | }; 158 | buildConfigurationList = 276991531644650D001C8375 /* Build configuration list for PBXProject "KBButton" */; 159 | compatibilityVersion = "Xcode 3.2"; 160 | developmentRegion = English; 161 | hasScannedForEncodings = 0; 162 | knownRegions = ( 163 | en, 164 | ); 165 | mainGroup = 2769914E1644650D001C8375; 166 | productRefGroup = 2769915A1644650D001C8375 /* Products */; 167 | projectDirPath = ""; 168 | projectRoot = ""; 169 | targets = ( 170 | 276991581644650D001C8375 /* KBButton */, 171 | ); 172 | }; 173 | /* End PBXProject section */ 174 | 175 | /* Begin PBXResourcesBuildPhase section */ 176 | 276991571644650D001C8375 /* Resources */ = { 177 | isa = PBXResourcesBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | 276991681644650D001C8375 /* InfoPlist.strings in Resources */, 181 | 2769916E1644650D001C8375 /* Credits.rtf in Resources */, 182 | 276991741644650D001C8375 /* MainMenu.xib in Resources */, 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | }; 186 | /* End PBXResourcesBuildPhase section */ 187 | 188 | /* Begin PBXSourcesBuildPhase section */ 189 | 276991551644650D001C8375 /* Sources */ = { 190 | isa = PBXSourcesBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | 2769916A1644650D001C8375 /* main.m in Sources */, 194 | 276991711644650D001C8375 /* KBAppDelegate.m in Sources */, 195 | 2769917C16446525001C8375 /* KBButtonCell.m in Sources */, 196 | FBF7C6D416456EB500D197E7 /* KBButton.m in Sources */, 197 | FBF7C6D81645AAF300D197E7 /* NSColor+ColorExtensions.m in Sources */, 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | }; 201 | /* End PBXSourcesBuildPhase section */ 202 | 203 | /* Begin PBXVariantGroup section */ 204 | 276991661644650D001C8375 /* InfoPlist.strings */ = { 205 | isa = PBXVariantGroup; 206 | children = ( 207 | 276991671644650D001C8375 /* en */, 208 | ); 209 | name = InfoPlist.strings; 210 | sourceTree = ""; 211 | }; 212 | 2769916C1644650D001C8375 /* Credits.rtf */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | 2769916D1644650D001C8375 /* en */, 216 | ); 217 | name = Credits.rtf; 218 | sourceTree = ""; 219 | }; 220 | 276991721644650D001C8375 /* MainMenu.xib */ = { 221 | isa = PBXVariantGroup; 222 | children = ( 223 | 276991731644650D001C8375 /* en */, 224 | ); 225 | name = MainMenu.xib; 226 | sourceTree = ""; 227 | }; 228 | /* End PBXVariantGroup section */ 229 | 230 | /* Begin XCBuildConfiguration section */ 231 | 276991751644650D001C8375 /* Debug */ = { 232 | isa = XCBuildConfiguration; 233 | buildSettings = { 234 | ALWAYS_SEARCH_USER_PATHS = NO; 235 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 236 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 237 | CLANG_CXX_LIBRARY = "libc++"; 238 | CLANG_ENABLE_OBJC_ARC = YES; 239 | CLANG_WARN_EMPTY_BODY = YES; 240 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 241 | COPY_PHASE_STRIP = NO; 242 | GCC_C_LANGUAGE_STANDARD = gnu99; 243 | GCC_DYNAMIC_NO_PIC = NO; 244 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 245 | GCC_OPTIMIZATION_LEVEL = 0; 246 | GCC_PREPROCESSOR_DEFINITIONS = ( 247 | "DEBUG=1", 248 | "$(inherited)", 249 | ); 250 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 251 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 252 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 253 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 254 | GCC_WARN_UNUSED_VARIABLE = YES; 255 | MACOSX_DEPLOYMENT_TARGET = 10.7; 256 | ONLY_ACTIVE_ARCH = YES; 257 | SDKROOT = macosx; 258 | }; 259 | name = Debug; 260 | }; 261 | 276991761644650D001C8375 /* Release */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | ALWAYS_SEARCH_USER_PATHS = NO; 265 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 266 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 267 | CLANG_CXX_LIBRARY = "libc++"; 268 | CLANG_ENABLE_OBJC_ARC = YES; 269 | CLANG_WARN_EMPTY_BODY = YES; 270 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 271 | COPY_PHASE_STRIP = YES; 272 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 273 | GCC_C_LANGUAGE_STANDARD = gnu99; 274 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 275 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 276 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 277 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 278 | GCC_WARN_UNUSED_VARIABLE = YES; 279 | MACOSX_DEPLOYMENT_TARGET = 10.7; 280 | SDKROOT = macosx; 281 | }; 282 | name = Release; 283 | }; 284 | 276991781644650D001C8375 /* Debug */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | COMBINE_HIDPI_IMAGES = YES; 288 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 289 | GCC_PREFIX_HEADER = "KBButton/KBButton-Prefix.pch"; 290 | INFOPLIST_FILE = "KBButton/KBButton-Info.plist"; 291 | PRODUCT_NAME = "$(TARGET_NAME)"; 292 | WRAPPER_EXTENSION = app; 293 | }; 294 | name = Debug; 295 | }; 296 | 276991791644650D001C8375 /* Release */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | COMBINE_HIDPI_IMAGES = YES; 300 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 301 | GCC_PREFIX_HEADER = "KBButton/KBButton-Prefix.pch"; 302 | INFOPLIST_FILE = "KBButton/KBButton-Info.plist"; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | WRAPPER_EXTENSION = app; 305 | }; 306 | name = Release; 307 | }; 308 | /* End XCBuildConfiguration section */ 309 | 310 | /* Begin XCConfigurationList section */ 311 | 276991531644650D001C8375 /* Build configuration list for PBXProject "KBButton" */ = { 312 | isa = XCConfigurationList; 313 | buildConfigurations = ( 314 | 276991751644650D001C8375 /* Debug */, 315 | 276991761644650D001C8375 /* Release */, 316 | ); 317 | defaultConfigurationIsVisible = 0; 318 | defaultConfigurationName = Release; 319 | }; 320 | 276991771644650D001C8375 /* Build configuration list for PBXNativeTarget "KBButton" */ = { 321 | isa = XCConfigurationList; 322 | buildConfigurations = ( 323 | 276991781644650D001C8375 /* Debug */, 324 | 276991791644650D001C8375 /* Release */, 325 | ); 326 | defaultConfigurationIsVisible = 0; 327 | defaultConfigurationName = Release; 328 | }; 329 | /* End XCConfigurationList section */ 330 | }; 331 | rootObject = 276991501644650D001C8375 /* Project object */; 332 | } 333 | -------------------------------------------------------------------------------- /KBButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /KBButton.xcodeproj/project.xcworkspace/xcuserdata/Kyle.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwbock/KBButton/58a554d6e51629d27fd87dca953293fe7ea60183/KBButton.xcodeproj/project.xcworkspace/xcuserdata/Kyle.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /KBButton.xcodeproj/xcuserdata/Kyle.xcuserdatad/xcschemes/KBButton.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /KBButton.xcodeproj/xcuserdata/Kyle.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | KBButton.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 276991581644650D001C8375 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /KBButton/KBAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // KBAppDelegate.h 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/2/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "KBButton/KBButton.h" 11 | 12 | @interface KBAppDelegate : NSObject 13 | 14 | @property (assign) IBOutlet NSWindow *window; 15 | 16 | @property (assign) IBOutlet NSButton *defaultButton; 17 | @property (assign) IBOutlet NSButton *primaryButton; 18 | @property (assign) IBOutlet NSButton *infoButton; 19 | @property (assign) IBOutlet NSButton *successButton; 20 | @property (assign) IBOutlet NSButton *warningButton; 21 | @property (assign) IBOutlet NSButton *dangerButton; 22 | @property (assign) IBOutlet NSButton *inverseButton; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /KBButton/KBAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // KBAppDelegate.m 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/2/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import "KBAppDelegate.h" 10 | 11 | @implementation KBAppDelegate 12 | 13 | @synthesize defaultButton, primaryButton, infoButton, successButton, warningButton, dangerButton, inverseButton; 14 | 15 | - (void)awakeFromNib { 16 | [[defaultButton cell] setKBButtonType:BButtonTypeDefault]; 17 | [[primaryButton cell] setKBButtonType:BButtonTypePrimary]; 18 | [[infoButton cell] setKBButtonType:BButtonTypeInfo]; 19 | [[successButton cell] setKBButtonType:BButtonTypeSuccess]; 20 | [[warningButton cell] setKBButtonType:BButtonTypeWarning]; 21 | [[dangerButton cell] setKBButtonType:BButtonTypeDanger]; 22 | [[inverseButton cell] setKBButtonType:BButtonTypeInverse]; 23 | } 24 | 25 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 26 | { 27 | 28 | } 29 | 30 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication { 31 | return YES; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /KBButton/KBButton-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.kbock.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2012 Kyle Bock. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /KBButton/KBButton-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'KBButton' target in the 'KBButton' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /KBButton/KBButton/KBButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // KBButton.h 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/3/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "KBButtonCell.h" 12 | 13 | @interface KBButton : NSButton 14 | 15 | - (void) setKBButtonType:(BButtonType)type; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /KBButton/KBButton/KBButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // KBButton.m 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/3/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import "KBButton.h" 10 | #import "KBButtonCell.h" 11 | 12 | @implementation KBButton 13 | 14 | - (void) setKBButtonType:(BButtonType)type { 15 | [[self cell] setKBButtonType:type]; 16 | } 17 | 18 | - initWithCoder: (NSCoder *)origCoder 19 | { 20 | BOOL sub = YES; 21 | 22 | sub = sub && [origCoder isKindOfClass: [NSKeyedUnarchiver class]]; // no support for 10.1 nibs 23 | sub = sub && ![self isMemberOfClass: [NSControl class]]; // no raw NSControls 24 | sub = sub && [[self superclass] cellClass] != nil; // need to have something to substitute 25 | sub = sub && [[self superclass] cellClass] != [[self class] cellClass]; // pointless if same 26 | 27 | if( !sub ) 28 | { 29 | self = [super initWithCoder: origCoder]; 30 | } 31 | else 32 | { 33 | NSKeyedUnarchiver *coder = (id)origCoder; 34 | 35 | // gather info about the superclass's cell and save the archiver's old mapping 36 | Class superCell = [[self superclass] cellClass]; 37 | NSString *oldClassName = NSStringFromClass( superCell ); 38 | Class oldClass = [coder classForClassName: oldClassName]; 39 | if( !oldClass ) 40 | oldClass = superCell; 41 | 42 | // override what comes out of the unarchiver 43 | [coder setClass: [[self class] cellClass] forClassName: oldClassName]; 44 | 45 | // unarchive 46 | self = [super initWithCoder: coder]; 47 | 48 | // set it back 49 | [coder setClass: oldClass forClassName: oldClassName]; 50 | } 51 | 52 | return self; 53 | } 54 | 55 | + (Class)cellClass 56 | { 57 | return [KBButtonCell class]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /KBButton/KBButton/KBButtonCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // KBButtonCell.h 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/2/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum { 12 | BButtonTypeDefault = 0, 13 | BButtonTypePrimary, 14 | BButtonTypeInfo, 15 | BButtonTypeSuccess, 16 | BButtonTypeWarning, 17 | BButtonTypeDanger, 18 | BButtonTypeInverse, 19 | } BButtonType; 20 | 21 | @interface KBButtonCell : NSButtonCell { 22 | NSColor *_color; 23 | BButtonType kbButtonType; 24 | } 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /KBButton/KBButton/KBButtonCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // KBButtonCell.m 3 | // CustomButtons 4 | // 5 | // Created by Kyle Bock on 11/2/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import "KBButtonCell.h" 10 | #import "NSColor+ColorExtensions.h" 11 | 12 | @implementation KBButtonCell 13 | 14 | - (void)setKBButtonType:(BButtonType)type { 15 | [[NSGraphicsContext currentContext] saveGraphicsState]; 16 | kbButtonType = type; 17 | [[NSGraphicsContext currentContext] restoreGraphicsState]; 18 | } 19 | 20 | - (NSColor*)getColorForButtonType { 21 | switch (kbButtonType) { 22 | case BButtonTypeDefault: 23 | return [NSColor colorWithCalibratedRed:0.85f green:0.85f blue:0.85f alpha:1.00f]; 24 | break; 25 | case BButtonTypePrimary: 26 | return [NSColor colorWithCalibratedRed:0.00f green:0.33f blue:0.80f alpha:1.00f]; 27 | break; 28 | case BButtonTypeInfo: 29 | return [NSColor colorWithCalibratedRed:0.18f green:0.59f blue:0.71f alpha:1.00f]; 30 | break; 31 | case BButtonTypeSuccess: 32 | return [NSColor colorWithCalibratedRed:0.32f green:0.64f blue:0.32f alpha:1.00f]; 33 | break; 34 | case BButtonTypeWarning: 35 | return [NSColor colorWithCalibratedRed:0.97f green:0.58f blue:0.02f alpha:1.00f]; 36 | break; 37 | case BButtonTypeDanger: 38 | return [NSColor colorWithCalibratedRed:0.74f green:0.21f blue:0.18f alpha:1.00f]; 39 | break; 40 | case BButtonTypeInverse: 41 | return [NSColor colorWithCalibratedRed:0.13f green:0.13f blue:0.13f alpha:1.00f]; 42 | } 43 | } 44 | 45 | - (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView 46 | { 47 | NSGraphicsContext* ctx = [NSGraphicsContext currentContext]; 48 | 49 | // corner radius 50 | CGFloat roundedRadius = 3.0f; 51 | 52 | NSColor *color = [self getColorForButtonType]; 53 | 54 | // Draw darker overlay if button is pressed 55 | if([self isHighlighted]) { 56 | [ctx saveGraphicsState]; 57 | [[NSBezierPath bezierPathWithRoundedRect:frame 58 | xRadius:roundedRadius 59 | yRadius:roundedRadius] setClip]; 60 | [[color darkenColorByValue:0.12f] setFill]; 61 | NSRectFillUsingOperation(frame, NSCompositeSourceOver); 62 | [ctx restoreGraphicsState]; 63 | 64 | return; 65 | } 66 | 67 | // create background color 68 | [ctx saveGraphicsState]; 69 | [[NSBezierPath bezierPathWithRoundedRect:frame 70 | xRadius:roundedRadius 71 | yRadius:roundedRadius] setClip]; 72 | [[color darkenColorByValue:0.12f] setFill]; 73 | NSRectFillUsingOperation(frame, NSCompositeSourceOver); 74 | [ctx restoreGraphicsState]; 75 | 76 | 77 | //draw inner button area 78 | [ctx saveGraphicsState]; 79 | 80 | NSBezierPath* bgPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 1.0f, 1.0f) xRadius:roundedRadius yRadius:roundedRadius]; 81 | [bgPath setClip]; 82 | 83 | NSColor* topColor = [color lightenColorByValue:0.12f]; 84 | 85 | // gradient for inner portion of button 86 | NSGradient* bgGradient = [[NSGradient alloc] initWithColorsAndLocations: 87 | topColor, 0.0f, 88 | color, 1.0f, 89 | nil]; 90 | [bgGradient drawInRect:[bgPath bounds] angle:90.0f]; 91 | 92 | [ctx restoreGraphicsState]; 93 | } 94 | 95 | - (NSRect) drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView { 96 | NSGraphicsContext* ctx = [NSGraphicsContext currentContext]; 97 | 98 | [ctx saveGraphicsState]; 99 | NSMutableAttributedString *attrString = [title mutableCopy]; 100 | [attrString beginEditing]; 101 | NSColor *titleColor; 102 | if ([[self getColorForButtonType] isLightColor]) { 103 | titleColor = [NSColor blackColor]; 104 | } else { 105 | titleColor = [NSColor whiteColor]; 106 | } 107 | 108 | [attrString addAttribute:NSForegroundColorAttributeName value:titleColor range:NSMakeRange(0, [[self title] length])]; 109 | [attrString endEditing]; 110 | NSRect r = [super drawTitle:attrString withFrame:frame inView:controlView]; 111 | // 5) Restore the graphics state 112 | [ctx restoreGraphicsState]; 113 | 114 | return r; 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /KBButton/KBButton/NSColor+ColorExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+ColorExtensions.h 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/3/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSColor (ColorExtensions) 12 | 13 | - (NSColor *)lightenColorByValue:(float)value; 14 | - (NSColor *)darkenColorByValue:(float)value; 15 | - (BOOL)isLightColor; 16 | @end 17 | -------------------------------------------------------------------------------- /KBButton/KBButton/NSColor+ColorExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+ColorExtensions.m 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/3/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import "NSColor+ColorExtensions.h" 10 | 11 | @implementation NSColor (ColorExtensions) 12 | 13 | - (NSColor *)lightenColorByValue:(float)value { 14 | float red = [self redComponent]; 15 | red += value; 16 | 17 | float green = [self greenComponent]; 18 | green += value; 19 | 20 | float blue = [self blueComponent]; 21 | blue += value; 22 | 23 | return [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:1.0f]; 24 | } 25 | 26 | - (NSColor *)darkenColorByValue:(float)value { 27 | float red = [self redComponent]; 28 | red -= value; 29 | 30 | float green = [self greenComponent]; 31 | green -= value; 32 | 33 | float blue = [self blueComponent]; 34 | blue -= value; 35 | 36 | return [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:1.0f]; 37 | } 38 | 39 | - (BOOL)isLightColor { 40 | NSInteger totalComponents = [self numberOfComponents]; 41 | bool isGreyscale = totalComponents == 2 ? YES : NO; 42 | 43 | CGFloat sum; 44 | 45 | if (isGreyscale) { 46 | sum = [self redComponent]; 47 | } else { 48 | sum = ([self redComponent]+[self greenComponent]+[self blueComponent])/3.0; 49 | } 50 | 51 | return (sum > 0.8); 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /KBButton/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /KBButton/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /KBButton/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // KBButton 4 | // 5 | // Created by Kyle Bock on 11/2/12. 6 | // Copyright (c) 2012 Kyle Bock. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "KBButton/KBButtonCell.h" 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 Kyle Bock 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #KBButton 2 | 3 | KBButton is a subclass of NSButton. It was adapted from [http://github.com/mattlawer/BButton](http://github.com/mattlawer/BButton) to work under Cocoa on Mac OS X. 4 | 5 | 6 | 7 | Usage 8 | ----- 9 | Start by dragging the KBButton folder into your Xcode project. Make sure you use the following settings: 10 | - Destination: [x] Copy items into destination group's folder (if needed) 11 | - Folders: (*) Create groups for any added folders 12 | - Add to targets: [x] your-xcode-project 13 | 14 | 1. Create a NSButton instance in interface builder. 15 | 2. Set the class of the NSButton to KBButton 16 | 17 | ### Changing the Color programatically ### 18 | 19 | 1. Connect NSButton to IBOutlet through Interface Builder 20 | 2. call [[button cell] setKBButtonType:BButtonTypeDefault] in awakeFromNib. In the example this is done in KBAppDelegate.m 21 | 22 | License 23 | ------- 24 | This library is licensed under the [MIT license](https://github.com/kwbock/KBButton/blob/master/MIT-LICENSE). 25 | 26 | Contributing 27 | ------------ 28 | If you would like to contribute or could improve the code, please submit a pull request or issue. --------------------------------------------------------------------------------