├── .gitignore ├── README.md ├── Swift-Color-Xcode-Plugin.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── houseshou.xcuserdatad │ └── xcschemes │ ├── Swift-Color-Xcode-Plugin Debug.xcscheme │ ├── Swift-Color-Xcode-Plugin.xcscheme │ └── xcschememanagement.plist ├── Swift-Color-Xcode-Plugin ├── Info.plist ├── SWCColorFrameView.swift ├── SWCMainController.swift ├── SWCPlainColorWell.swift └── Swift-Color-Xcode-Plugin-Bridging-Header.h └── ss1.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # https://github.com/github/gitignore/blob/master/Objective-C.gitignore 3 | # 4 | build/ 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | xcuserdata 14 | *.xccheckout 15 | *.moved-aside 16 | DerivedData 17 | *.hmap 18 | *.ipa 19 | *.xcuserstate 20 | *.DS_Store 21 | 22 | # CocoaPods 23 | # 24 | # We recommend against adding the Pods directory to your .gitignore. However 25 | # you should judge for yourself, the pros and cons are mentioned at: 26 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 27 | # 28 | Pods/ 29 | Podfile.lock 30 | *.xcworkspace 31 | 32 | # AppCode 33 | .idea/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swift Color Xcode Plugin 2 | 3 | ![demo](https://raw.githubusercontent.com/ShingoFukuyama/Swift-Color-Xcode-Plugin/master/ss1.gif) 4 | 5 | This work is based on the work of [Ole Zorn / omz](https://github.com/omz) 6 | Objective-C version [omz/ColorSense-for-Xcode](https://github.com/omz/ColorSense-for-Xcode) 7 | 8 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5E3A5AF51C959C8500D93440 /* SWCPlainColorWell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E3A5AF41C959C8500D93440 /* SWCPlainColorWell.swift */; }; 11 | 5E3F2C141C94736C001DD542 /* SWCMainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F2C131C94736C001DD542 /* SWCMainController.swift */; }; 12 | 5EFCCCB71C94877500935E68 /* SWCColorFrameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EFCCCB61C94877500935E68 /* SWCColorFrameView.swift */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXFileReference section */ 16 | 5E3A5AF41C959C8500D93440 /* SWCPlainColorWell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWCPlainColorWell.swift; sourceTree = ""; }; 17 | 5E3F2C091C946ECA001DD542 /* Swift-Color-Xcode-Plugin.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Swift-Color-Xcode-Plugin.xcplugin"; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | 5E3F2C0C1C946ECA001DD542 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 19 | 5E3F2C121C94736B001DD542 /* Swift-Color-Xcode-Plugin-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Swift-Color-Xcode-Plugin-Bridging-Header.h"; sourceTree = ""; }; 20 | 5E3F2C131C94736C001DD542 /* SWCMainController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWCMainController.swift; sourceTree = ""; }; 21 | 5EFCCCB61C94877500935E68 /* SWCColorFrameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWCColorFrameView.swift; sourceTree = ""; }; 22 | /* End PBXFileReference section */ 23 | 24 | /* Begin PBXFrameworksBuildPhase section */ 25 | 5E3F2C061C946ECA001DD542 /* Frameworks */ = { 26 | isa = PBXFrameworksBuildPhase; 27 | buildActionMask = 2147483647; 28 | files = ( 29 | ); 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXFrameworksBuildPhase section */ 33 | 34 | /* Begin PBXGroup section */ 35 | 5E3F2C001C946ECA001DD542 = { 36 | isa = PBXGroup; 37 | children = ( 38 | 5E3F2C0B1C946ECA001DD542 /* Swift-Color-Xcode-Plugin */, 39 | 5E3F2C0A1C946ECA001DD542 /* Products */, 40 | ); 41 | sourceTree = ""; 42 | }; 43 | 5E3F2C0A1C946ECA001DD542 /* Products */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 5E3F2C091C946ECA001DD542 /* Swift-Color-Xcode-Plugin.xcplugin */, 47 | ); 48 | name = Products; 49 | sourceTree = ""; 50 | }; 51 | 5E3F2C0B1C946ECA001DD542 /* Swift-Color-Xcode-Plugin */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 5E3F2C0C1C946ECA001DD542 /* Info.plist */, 55 | 5E3F2C131C94736C001DD542 /* SWCMainController.swift */, 56 | 5EFCCCB61C94877500935E68 /* SWCColorFrameView.swift */, 57 | 5E3A5AF41C959C8500D93440 /* SWCPlainColorWell.swift */, 58 | 5E3F2C121C94736B001DD542 /* Swift-Color-Xcode-Plugin-Bridging-Header.h */, 59 | ); 60 | path = "Swift-Color-Xcode-Plugin"; 61 | sourceTree = ""; 62 | }; 63 | /* End PBXGroup section */ 64 | 65 | /* Begin PBXNativeTarget section */ 66 | 5E3F2C081C946ECA001DD542 /* Swift-Color-Xcode-Plugin */ = { 67 | isa = PBXNativeTarget; 68 | buildConfigurationList = 5E3F2C0F1C946ECA001DD542 /* Build configuration list for PBXNativeTarget "Swift-Color-Xcode-Plugin" */; 69 | buildPhases = ( 70 | 5E3F2C051C946ECA001DD542 /* Sources */, 71 | 5E3F2C061C946ECA001DD542 /* Frameworks */, 72 | 5E3F2C071C946ECA001DD542 /* Resources */, 73 | ); 74 | buildRules = ( 75 | ); 76 | dependencies = ( 77 | ); 78 | name = "Swift-Color-Xcode-Plugin"; 79 | productName = "Swift-Color-Xcode-Plugin"; 80 | productReference = 5E3F2C091C946ECA001DD542 /* Swift-Color-Xcode-Plugin.xcplugin */; 81 | productType = "com.apple.product-type.bundle"; 82 | }; 83 | /* End PBXNativeTarget section */ 84 | 85 | /* Begin PBXProject section */ 86 | 5E3F2C011C946ECA001DD542 /* Project object */ = { 87 | isa = PBXProject; 88 | attributes = { 89 | LastUpgradeCheck = 0720; 90 | ORGANIZATIONNAME = "Shingo Fukuyama"; 91 | TargetAttributes = { 92 | 5E3F2C081C946ECA001DD542 = { 93 | CreatedOnToolsVersion = 7.2.1; 94 | }; 95 | }; 96 | }; 97 | buildConfigurationList = 5E3F2C041C946ECA001DD542 /* Build configuration list for PBXProject "Swift-Color-Xcode-Plugin" */; 98 | compatibilityVersion = "Xcode 3.2"; 99 | developmentRegion = English; 100 | hasScannedForEncodings = 0; 101 | knownRegions = ( 102 | en, 103 | ); 104 | mainGroup = 5E3F2C001C946ECA001DD542; 105 | productRefGroup = 5E3F2C0A1C946ECA001DD542 /* Products */; 106 | projectDirPath = ""; 107 | projectRoot = ""; 108 | targets = ( 109 | 5E3F2C081C946ECA001DD542 /* Swift-Color-Xcode-Plugin */, 110 | ); 111 | }; 112 | /* End PBXProject section */ 113 | 114 | /* Begin PBXResourcesBuildPhase section */ 115 | 5E3F2C071C946ECA001DD542 /* Resources */ = { 116 | isa = PBXResourcesBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | /* End PBXResourcesBuildPhase section */ 123 | 124 | /* Begin PBXSourcesBuildPhase section */ 125 | 5E3F2C051C946ECA001DD542 /* Sources */ = { 126 | isa = PBXSourcesBuildPhase; 127 | buildActionMask = 2147483647; 128 | files = ( 129 | 5E3F2C141C94736C001DD542 /* SWCMainController.swift in Sources */, 130 | 5EFCCCB71C94877500935E68 /* SWCColorFrameView.swift in Sources */, 131 | 5E3A5AF51C959C8500D93440 /* SWCPlainColorWell.swift in Sources */, 132 | ); 133 | runOnlyForDeploymentPostprocessing = 0; 134 | }; 135 | /* End PBXSourcesBuildPhase section */ 136 | 137 | /* Begin XCBuildConfiguration section */ 138 | 5E3F2C0D1C946ECA001DD542 /* Debug */ = { 139 | isa = XCBuildConfiguration; 140 | buildSettings = { 141 | ALWAYS_SEARCH_USER_PATHS = NO; 142 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 143 | CLANG_CXX_LIBRARY = "libc++"; 144 | CLANG_ENABLE_MODULES = YES; 145 | CLANG_ENABLE_OBJC_ARC = YES; 146 | CLANG_WARN_BOOL_CONVERSION = YES; 147 | CLANG_WARN_CONSTANT_CONVERSION = YES; 148 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 149 | CLANG_WARN_EMPTY_BODY = YES; 150 | CLANG_WARN_ENUM_CONVERSION = YES; 151 | CLANG_WARN_INT_CONVERSION = YES; 152 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 153 | CLANG_WARN_UNREACHABLE_CODE = YES; 154 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 155 | CODE_SIGN_IDENTITY = "-"; 156 | COPY_PHASE_STRIP = NO; 157 | DEBUG_INFORMATION_FORMAT = dwarf; 158 | ENABLE_STRICT_OBJC_MSGSEND = YES; 159 | ENABLE_TESTABILITY = YES; 160 | GCC_C_LANGUAGE_STANDARD = gnu99; 161 | GCC_DYNAMIC_NO_PIC = NO; 162 | GCC_NO_COMMON_BLOCKS = YES; 163 | GCC_OPTIMIZATION_LEVEL = 0; 164 | GCC_PREPROCESSOR_DEFINITIONS = ( 165 | "DEBUG=1", 166 | "$(inherited)", 167 | ); 168 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 169 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 170 | GCC_WARN_UNDECLARED_SELECTOR = YES; 171 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 172 | GCC_WARN_UNUSED_FUNCTION = YES; 173 | GCC_WARN_UNUSED_VARIABLE = YES; 174 | MACOSX_DEPLOYMENT_TARGET = 10.11; 175 | MTL_ENABLE_DEBUG_INFO = YES; 176 | ONLY_ACTIVE_ARCH = YES; 177 | SDKROOT = macosx; 178 | }; 179 | name = Debug; 180 | }; 181 | 5E3F2C0E1C946ECA001DD542 /* Release */ = { 182 | isa = XCBuildConfiguration; 183 | buildSettings = { 184 | ALWAYS_SEARCH_USER_PATHS = NO; 185 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 186 | CLANG_CXX_LIBRARY = "libc++"; 187 | CLANG_ENABLE_MODULES = YES; 188 | CLANG_ENABLE_OBJC_ARC = YES; 189 | CLANG_WARN_BOOL_CONVERSION = YES; 190 | CLANG_WARN_CONSTANT_CONVERSION = YES; 191 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 192 | CLANG_WARN_EMPTY_BODY = YES; 193 | CLANG_WARN_ENUM_CONVERSION = YES; 194 | CLANG_WARN_INT_CONVERSION = YES; 195 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 196 | CLANG_WARN_UNREACHABLE_CODE = YES; 197 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 198 | CODE_SIGN_IDENTITY = "-"; 199 | COPY_PHASE_STRIP = NO; 200 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 201 | ENABLE_NS_ASSERTIONS = NO; 202 | ENABLE_STRICT_OBJC_MSGSEND = YES; 203 | GCC_C_LANGUAGE_STANDARD = gnu99; 204 | GCC_NO_COMMON_BLOCKS = YES; 205 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 206 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 207 | GCC_WARN_UNDECLARED_SELECTOR = YES; 208 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 209 | GCC_WARN_UNUSED_FUNCTION = YES; 210 | GCC_WARN_UNUSED_VARIABLE = YES; 211 | MACOSX_DEPLOYMENT_TARGET = 10.11; 212 | MTL_ENABLE_DEBUG_INFO = NO; 213 | SDKROOT = macosx; 214 | }; 215 | name = Release; 216 | }; 217 | 5E3F2C101C946ECA001DD542 /* Debug */ = { 218 | isa = XCBuildConfiguration; 219 | buildSettings = { 220 | CLANG_ENABLE_MODULES = YES; 221 | COMBINE_HIDPI_IMAGES = YES; 222 | DEPLOYMENT_LOCATION = YES; 223 | DSTROOT = "$(HOME)"; 224 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 225 | INFOPLIST_FILE = "Swift-Color-Xcode-Plugin/Info.plist"; 226 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 227 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 228 | PRODUCT_BUNDLE_IDENTIFIER = "co.fukuyama.plugin.Swift-Color-Xcode-Plugin"; 229 | PRODUCT_NAME = "$(TARGET_NAME)"; 230 | SKIP_INSTALL = NO; 231 | SWIFT_OBJC_BRIDGING_HEADER = "Swift-Color-Xcode-Plugin/Swift-Color-Xcode-Plugin-Bridging-Header.h"; 232 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 233 | WRAPPER_EXTENSION = xcplugin; 234 | }; 235 | name = Debug; 236 | }; 237 | 5E3F2C111C946ECA001DD542 /* Release */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | CLANG_ENABLE_MODULES = YES; 241 | COMBINE_HIDPI_IMAGES = YES; 242 | DEPLOYMENT_LOCATION = YES; 243 | DSTROOT = "$(HOME)"; 244 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 245 | INFOPLIST_FILE = "Swift-Color-Xcode-Plugin/Info.plist"; 246 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 247 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 248 | PRODUCT_BUNDLE_IDENTIFIER = "co.fukuyama.plugin.Swift-Color-Xcode-Plugin"; 249 | PRODUCT_NAME = "$(TARGET_NAME)"; 250 | SKIP_INSTALL = NO; 251 | SWIFT_OBJC_BRIDGING_HEADER = "Swift-Color-Xcode-Plugin/Swift-Color-Xcode-Plugin-Bridging-Header.h"; 252 | WRAPPER_EXTENSION = xcplugin; 253 | }; 254 | name = Release; 255 | }; 256 | /* End XCBuildConfiguration section */ 257 | 258 | /* Begin XCConfigurationList section */ 259 | 5E3F2C041C946ECA001DD542 /* Build configuration list for PBXProject "Swift-Color-Xcode-Plugin" */ = { 260 | isa = XCConfigurationList; 261 | buildConfigurations = ( 262 | 5E3F2C0D1C946ECA001DD542 /* Debug */, 263 | 5E3F2C0E1C946ECA001DD542 /* Release */, 264 | ); 265 | defaultConfigurationIsVisible = 0; 266 | defaultConfigurationName = Release; 267 | }; 268 | 5E3F2C0F1C946ECA001DD542 /* Build configuration list for PBXNativeTarget "Swift-Color-Xcode-Plugin" */ = { 269 | isa = XCConfigurationList; 270 | buildConfigurations = ( 271 | 5E3F2C101C946ECA001DD542 /* Debug */, 272 | 5E3F2C111C946ECA001DD542 /* Release */, 273 | ); 274 | defaultConfigurationIsVisible = 0; 275 | defaultConfigurationName = Release; 276 | }; 277 | /* End XCConfigurationList section */ 278 | }; 279 | rootObject = 5E3F2C011C946ECA001DD542 /* Project object */; 280 | } 281 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin.xcodeproj/xcuserdata/houseshou.xcuserdatad/xcschemes/Swift-Color-Xcode-Plugin Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 46 | 50 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin.xcodeproj/xcuserdata/houseshou.xcuserdatad/xcschemes/Swift-Color-Xcode-Plugin.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin.xcodeproj/xcuserdata/houseshou.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Swift-Color-Xcode-Plugin Debug.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | Swift-Color-Xcode-Plugin.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 5E3F2C081C946ECA001DD542 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | XCGCReady 24 | 25 | XCPluginHasUI 26 | 27 | XC4Compatible 28 | 29 | XC5Compatible 30 | 31 | DVTPlugInCompatibilityUUIDs 32 | 33 | FEC992CC-CA4A-4CFD-8881-77300FCB848A 34 | C4A681B0-4A26-480E-93EC-1218098B9AA0 35 | A2E4D43F-41F4-4FB9-BB94-7177011C9AED 36 | AD68E85B-441B-4301-B564-A45E4919A6AD 37 | 63FC1C47-140D-42B0-BB4D-A10B2D225574 38 | 37B30044-3B14-46BA-ABAA-F01000C27B63 39 | 640F884E-CE55-4B40-87C0-8869546CAB7A 40 | 992275C1-432A-4CF7-B659-D84ED6D42D3F 41 | A16FF353-8441-459E-A50C-B071F53F51B7 42 | 9F75337B-21B4-4ADC-B558-F9CADF7073A7 43 | E969541F-E6F9-4D25-8158-72DC3545A6C6 44 | 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 45 | AABB7188-E14E-4433-AD3B-5CD791EAD9A3 46 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 47 | 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 48 | CC0D0F4F-05B3-431A-8F33-F84AFCB2C651 49 | 7265231C-39B4-402C-89E1-16167C4CC990 50 | 9AFF134A-08DC-4096-8CEE-62A4BB123046 51 | F41BD31E-2683-44B8-AE7F-5F09E919790E 52 | E71C2CFE-BFD8-4044-8F06-00AE685A406C 53 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C 54 | 55 | NSHumanReadableCopyright 56 | Copyright © 2016 Shingo Fukuyama. All rights reserved. 57 | NSPrincipalClass 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin/SWCColorFrameView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SWCColorFrameView.swift 3 | // Swift-Color-Xcode-Plugin 4 | // 5 | // Created by Shingo Fukuyama on 3/13/16. 6 | // Copyright © 2016 Shingo Fukuyama. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Cocoa 11 | 12 | 13 | class SWCColorFrameView : NSView { 14 | var color:NSColor? = NSColor.whiteColor() 15 | 16 | override func drawRect(dirtyRect: NSRect) { 17 | if let col = self.color { 18 | col.setStroke() 19 | NSBezierPath.strokeRect(NSInsetRect(self.bounds, 0.5, 0.5)) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin/SWCMainController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SWCMainController.swift 3 | // Swift-Color-Xcode-Plugin 4 | // 5 | // Created by Shingo Fukuyama on 3/13/16. 6 | // Copyright © 2016 Shingo Fukuyama. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Cocoa 11 | 12 | private struct SWC_KEY { 13 | static let HighlightingDisabled = "SWCColorHelperHighlightingDisabled" 14 | static let InsertionMode = "SWCColorHelperInsertionMode" 15 | } 16 | 17 | private struct SWC_RGBA { 18 | var r: CGFloat = 1.0 19 | var g: CGFloat = 1.0 20 | var b: CGFloat = 1.0 21 | var a: CGFloat = 1.0 22 | init(r: Double, g: Double, b: Double, a: Double) { 23 | self.r = CGFloat(r) 24 | self.g = CGFloat(g) 25 | self.b = CGFloat(b) 26 | self.a = CGFloat(a) 27 | } 28 | } 29 | 30 | enum SWCColorType : Int, Comparable { 31 | case None = 0 32 | // iOS 33 | case UIRGBA //UIColor(red:1.0, green:0.0, blue:0.0, alpha:1.0) 34 | case UIRGBAInit //UIColor.init(red:1.0, green:0.0, blue:0.0, alpha:1.0) 35 | case UIWhite //UIColor(white:0.5, alpha:1.0) 36 | case UIWhiteInit //UIColor.init(white:0.5, alpha:1.0) 37 | case UIConstant //UIColor.redColor() 38 | case UIRGBA_OBJC //[UIColor colorWithRed:250.0/255.0f green:0.0 blue:0.0 alpha:1.0f] 39 | case UIWhite_OBJC //[UIColor colorWithWhite:0.5 alpha:1.0] 40 | case UIConstant_OBJC //[UIColor redColor] 41 | // Mac OS X 42 | case NSRGBA //NSColor(red:1.0, green:0.0, blue:0.0, alpha:1.0) 43 | case NSRGBAInit //NSColor.init(red:1.0, green:0.0, blue:0.0, alpha:1.0) 44 | case NSRGBADevice //NSColor(deviceRed:1.0, green:0.0, blue:0.0, alpha:1.0) 45 | case NSRGBADeviceInit //NSColor.init(deviceRed:1.0, green:0.0, blue:0.0, alpha:1.0) 46 | case NSRGBACalibrated //NSColor(calibratedRed:1.0, green:0.0, blue:0.0, alpha:1.0) 47 | case NSRGBACalibratedInit //NSColor.init(calibratedRed:1.0, green:0.0, blue:0.0, alpha:1.0) 48 | case NSWhite //NSColor(white:0.5, alpha:1.0) 49 | case NSWhiteInit //NSColor.init(white:0.5, alpha:1.0) 50 | case NSWhiteDevice //NSColor(deviceWhite:0.5, alpha:1.0) 51 | case NSWhiteDeviceInit //NSColor.init(deviceWhite:0.5, alpha:1.0) 52 | case NSWhiteCalibrated //NSColor(calibratedWhite:0.5, alpha:1.0) 53 | case NSWhiteCalibratedInit //NSColor.init(calibratedWhite:0.5, alpha:1.0) 54 | case NSConstant //NSColor.redColor() 55 | case NSRGBA_OBJC //[NSColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0] 56 | case NSRGBADevice_OBJC //[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] 57 | case NSRGBACalibrated_OBJC //[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:1.0] 58 | case NSWhite_OBJC //[NSColor colorWithWhite:0.5 alpha:1.0] 59 | case NSWhiteDevice_OBJC //[NSColor colorWithDeviceWhite:0.5 alpha:1.0] 60 | case NSWhiteCalibrated_OBJC //[NSColor colorWithCalibratedWhite:0.5 alpha:1.0] 61 | case NSConstant_OBJC //[NSColor redColor] 62 | // ObjC 63 | static func isNSColor(colorType: SWCColorType) -> Bool { 64 | return colorType >= .NSRGBA 65 | } 66 | } 67 | func < (lhs:SWCColorType, rhs:SWCColorType) -> Bool { return lhs.rawValue < rhs.rawValue } 68 | 69 | 70 | class SWCMainController : NSObject { 71 | lazy var notificationCenter = NSNotificationCenter.defaultCenter() 72 | lazy var userDefault = NSUserDefaults.standardUserDefaults() 73 | let colorWell = SWCPlainColorWell.init(frame: NSMakeRect(0, 0, 50, 30)) 74 | var colorFrameView = SWCColorFrameView.init(frame: NSZeroRect) 75 | var textView: NSTextView? { 76 | if let fr = NSApp.keyWindow?.firstResponder as? NSTextView { 77 | return fr 78 | } 79 | return nil 80 | } 81 | var selectedColorType = SWCColorType.None 82 | var selectedColorRange = NSMakeRange(NSNotFound, 0) 83 | let constantColorsByName: [String:NSColor] 84 | = [ 85 | "black" : NSColor.blackColor(), 86 | "darkGray" : NSColor.darkGrayColor(), 87 | "gray" : NSColor.grayColor(), 88 | "lightGray" : NSColor.lightGrayColor(), 89 | "white" : NSColor.whiteColor(), 90 | "red" : NSColor.redColor(), 91 | "green" : NSColor.greenColor(), 92 | "blue" : NSColor.blueColor(), 93 | "cyan" : NSColor.cyanColor(), 94 | "yellow" : NSColor.yellowColor(), 95 | "magenta" : NSColor.magentaColor(), 96 | "orange" : NSColor.orangeColor(), 97 | "purple" : NSColor.purpleColor(), 98 | "brown" : NSColor.brownColor(), 99 | "clear" : NSColor.clearColor() 100 | ] 101 | 102 | // swift 103 | let rgbaUIColorRegex = try! NSRegularExpression.init(pattern: "UIColor(\\.init)?\\(\\s*red\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*green\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*blue\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*alpha\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\)", options: NSRegularExpressionOptions.init(rawValue: 0)) 104 | let whiteUIColorRegex = try! NSRegularExpression.init(pattern: "UIColor(\\.init)?\\(\\s*white\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*alpha\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\)", options: NSRegularExpressionOptions.init(rawValue: 0)) 105 | let rgbaNSColorRegex = try! NSRegularExpression.init(pattern: "NSColor(\\.init)?\\(\\s*(calibrated|device)?[rR]ed\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*green\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*blue\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*alpha\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\)", options: NSRegularExpressionOptions.init(rawValue: 0)) 106 | let whiteNSColorRegex = try! NSRegularExpression.init(pattern: "NSColor(\\.init)?\\(\\s*(calibrated|device)?[wW]hite\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\,\\s*alpha\\s*\\:\\s*([0-9]*\\.?[0-9]*)\\s*(\\/\\s*[0-9]*\\.?[0-9]*)?\\s*\\)", options: NSRegularExpressionOptions.init(rawValue: 0)) 107 | let constantColorRegex = try! NSRegularExpression.init(pattern: "(UI|NS)Color\\.(black|darkGray|lightGray|white|gray|red|green|blue|cyan|yellow|magenta|orange|purple|brown|clear)Color\\(\\s*\\)", options: NSRegularExpressionOptions.init(rawValue: 0)) 108 | // objc 109 | let objc_rgbaUIColorRegex = try! NSRegularExpression.init(pattern: "(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)Red:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+green:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+blue:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]", options: NSRegularExpressionOptions.init(rawValue: 0)) 110 | let objc_whiteUIColorRegex = try! NSRegularExpression.init(pattern: "(\\[\\s*UIColor\\s+colorWith|\\[\\s*\\[\\s*UIColor\\s+alloc\\]\\s*initWith)White:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]", options: NSRegularExpressionOptions.init(rawValue: 0)) 111 | let objc_rgbaNSColorRegex = try! NSRegularExpression.init(pattern: "\\[\\s*NSColor\\s+colorWith(Calibrated|Device)?Red:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+green:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+blue:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]", options: NSRegularExpressionOptions.init(rawValue: 0)) 112 | let objc_whiteNSColorRegex = try! NSRegularExpression.init(pattern: "\\[\\s*NSColor\\s+colorWith(Calibrated|Device)?White:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s+alpha:\\s*([0-9]*\\.?[0-9]*f?)\\s*(\\/\\s*[0-9]*\\.?[0-9]*f?)?\\s*\\]", options: NSRegularExpressionOptions.init(rawValue: 0)) 113 | let objc_constantColorRegex = try! NSRegularExpression.init(pattern: "\\[\\s*(UI|NS)Color\\s+(black|darkGray|lightGray|white|gray|red|green|blue|cyan|yellow|magenta|orange|purple|brown|clear)Color\\s*\\]", options: NSRegularExpressionOptions.init(rawValue: 0)) 114 | 115 | static let sharedInstance : SWCMainController = { 116 | let instance = SWCMainController.init() 117 | return instance 118 | }() 119 | 120 | private override init() { 121 | super.init() 122 | 123 | notificationCenter.addObserver(self, selector: #selector(applicationDidFinishLaunching(_:)), name: NSApplicationDidFinishLaunchingNotification, object: nil) 124 | 125 | self.colorWell.target = self 126 | self.colorWell.action = #selector(colorDidChange(_:)) 127 | 128 | } 129 | 130 | func createMenuItem() { 131 | if let item = NSApp.mainMenu?.itemWithTitle("Edit"), 132 | let submenu = item.submenu { 133 | submenu.addItem(NSMenuItem.separatorItem()) 134 | //let toggleColorHeighlightMenuItem = NSMenuItem.init(title: "Show Colors Under Caret", action: #selector(toggleColorHeighlightingEnabled), keyEquivalent: "") 135 | //toggleColorHeighlightMenuItem.target = self 136 | //submenu.addItem(toggleColorHeighlightMenuItem) 137 | let colorInsertionModeItem = NSMenuItem.init(title: "Color Insertion Mode", action: nil, keyEquivalent: "") 138 | let colorInsertionModeNSItem = NSMenuItem.init(title: "NSColor", action: #selector(selectNSColorInsertionMode(_:)), keyEquivalent: "") 139 | colorInsertionModeNSItem.target = self 140 | colorInsertionModeItem.target = self 141 | let colorInsertionModeUIItem = NSMenuItem.init(title: "UIColor", action: #selector(selectUIColorInsertionMode(_:)), keyEquivalent: "") 142 | colorInsertionModeUIItem.target = self 143 | 144 | let colorInsertionModeMenu = NSMenu.init(title: "Color Insertion Mode") 145 | colorInsertionModeItem.submenu = colorInsertionModeMenu 146 | colorInsertionModeItem.submenu!.addItem(colorInsertionModeUIItem) 147 | colorInsertionModeItem.submenu!.addItem(colorInsertionModeNSItem) 148 | submenu.addItem(colorInsertionModeItem) 149 | 150 | let insertColorMenuItem = NSMenuItem.init(title: "Insert Color...", action: #selector(insertColor(_:)), keyEquivalent: "") 151 | insertColorMenuItem.target = self 152 | submenu.addItem(insertColorMenuItem) 153 | } 154 | } 155 | 156 | class func pluginDidLoad(plugin: NSBundle) { 157 | self.sharedInstance 158 | } 159 | 160 | func applicationDidFinishLaunching(notification: NSNotification) { 161 | self.createMenuItem() 162 | 163 | let highlightingEnabled = !NSUserDefaults.standardUserDefaults().boolForKey(SWC_KEY.HighlightingDisabled) 164 | if highlightingEnabled { 165 | self.activateColorHighlighting() 166 | } 167 | } 168 | 169 | 170 | // MARK: Preferences 171 | override func validateMenuItem(menuItem: NSMenuItem) -> Bool { 172 | switch menuItem.action.description { 173 | case "insertColor:": 174 | return self.textView != nil 175 | case "toggleColorHighlightingEnabled:": 176 | let enabled = userDefault.boolForKey(SWC_KEY.HighlightingDisabled) 177 | menuItem.state = enabled ? NSOffState : NSOnState 178 | case "selectNSColorInsertionMode:": 179 | let state = userDefault.integerForKey(SWC_KEY.InsertionMode) 180 | menuItem.state = state == 1 ? NSOnState : NSOffState 181 | case "selectUIColorInsertionMode:": 182 | let state = userDefault.integerForKey(SWC_KEY.InsertionMode) 183 | menuItem.state = state == 0 ? NSOnState : NSOffState 184 | default: break 185 | } 186 | return true 187 | } 188 | 189 | func selectNSColorInsertionMode(sender: AnyObject) { 190 | userDefault.setInteger(1, forKey: SWC_KEY.InsertionMode) 191 | userDefault.synchronize() 192 | } 193 | 194 | func selectUIColorInsertionMode(sender: AnyObject) { 195 | userDefault.setInteger(0, forKey: SWC_KEY.InsertionMode) 196 | userDefault.synchronize() 197 | } 198 | 199 | func toggleColorHighlightingEnabled(sender: AnyObject) { 200 | let enabled = userDefault.boolForKey(SWC_KEY.HighlightingDisabled) 201 | userDefault.setBool(!enabled, forKey: SWC_KEY.HighlightingDisabled) 202 | userDefault.synchronize() 203 | if enabled { 204 | self.activateColorHighlighting() 205 | } 206 | else { 207 | self.deactivateColorHighlighting() 208 | } 209 | } 210 | 211 | func activateColorHighlighting() { 212 | notificationCenter.addObserver(self, selector: #selector(selectionDidChange(_:)), name: NSTextViewDidChangeSelectionNotification, object: nil) 213 | let notification = NSNotification.init(name: NSTextViewDidChangeSelectionNotification, object: nil) 214 | self.selectionDidChange(notification) 215 | } 216 | 217 | func deactivateColorHighlighting() { 218 | notificationCenter.removeObserver(self, name: NSTextViewDidChangeSelectionNotification, object: nil) 219 | self.dismissColorWell() 220 | } 221 | 222 | 223 | // MARK: Color Insertion 224 | func insertColor(sender: AnyObject) { 225 | guard let textView = self.textView else { 226 | return NSBeep() 227 | } 228 | if userDefault.boolForKey(SWC_KEY.HighlightingDisabled) { 229 | userDefault.setBool(false, forKey: SWC_KEY.HighlightingDisabled) 230 | userDefault.synchronize() 231 | self.activateColorHighlighting() 232 | } 233 | textView.undoManager?.beginUndoGrouping() 234 | let insertionMode = userDefault.integerForKey(SWC_KEY.InsertionMode) 235 | let range = textView.selectedRange 236 | if insertionMode == 0 { 237 | textView.insertText("UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)", replacementRange:range) 238 | } 239 | else { 240 | textView.insertText("NSColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)", replacementRange:range) 241 | } 242 | textView.undoManager?.endUndoGrouping() 243 | self.performSelector(#selector(activateColorWell), withObject: nil, afterDelay: 0.0) 244 | } 245 | 246 | func activateColorWell() { 247 | self.colorWell.activate(true) 248 | } 249 | 250 | 251 | // MARK: Text Selection Handling 252 | func selectionDidChange(notification: NSNotification) { 253 | if userDefault.boolForKey(SWC_KEY.HighlightingDisabled) { 254 | return 255 | } 256 | guard let textView = self.textView where textView.selectedRanges.count != 0, 257 | let textStorage = textView.textStorage 258 | else { 259 | self.dismissColorWell() 260 | return 261 | } 262 | 263 | let selectedRange = textView.selectedRanges.first!.rangeValue 264 | let text = NSString(string: textStorage.string) 265 | let lineRange = text.lineRangeForRange(selectedRange) 266 | let selectedRangeInLine = NSMakeRange(selectedRange.location - lineRange.location, selectedRange.length) 267 | let line = text.substringWithRange(lineRange) 268 | 269 | var colorRange = NSMakeRange(NSNotFound, 0) 270 | var colorType = SWCColorType.None 271 | let _matchedColor = self.color(text: line, selectedRange: selectedRangeInLine, type: &colorType, matchedRange: &colorRange) 272 | guard let matchedColor = _matchedColor else { 273 | self.dismissColorWell() 274 | return 275 | } 276 | let backgroundColor = textView.backgroundColor.colorUsingColorSpace(NSColorSpace.genericRGBColorSpace()) 277 | 278 | var c = SWC_RGBA(r: 1.0, g: 1.0, b: 1.0, a: 1.0) 279 | backgroundColor?.getRed(&c.r, green: &c.g, blue: &c.b, alpha: nil) 280 | let backgroundLuminance = (c.r + c.g + c.b) / 3.0 281 | 282 | let strokeColor = (backgroundLuminance > 0.5) ? NSColor.init(calibratedWhite: 0.2, alpha: 1.0) : NSColor.whiteColor() 283 | 284 | self.selectedColorType = colorType 285 | self.colorWell.color = matchedColor 286 | self.colorWell.strokeColor = strokeColor 287 | 288 | self.selectedColorRange = NSMakeRange(colorRange.location + lineRange.location, colorRange.length) 289 | let selectionRectOnScreen = textView.firstRectForCharacterRange(self.selectedColorRange, actualRange: nil) 290 | let selectionRectInWindow = textView.window!.convertRectFromScreen(selectionRectOnScreen) 291 | let selectionRectInView = textView.convertRect(selectionRectInWindow, fromView: nil) 292 | let colorWellRect = NSMakeRect(NSMaxX(selectionRectInView) - 49, 293 | NSMinY(selectionRectInView) - selectionRectInView.size.height - 2, 294 | 50, 295 | selectionRectInView.size.height + 2) 296 | 297 | textView.addSubview(self.colorWell) 298 | self.colorWell.frame = NSIntegralRect(colorWellRect) 299 | 300 | self.colorFrameView.frame = NSInsetRect(NSIntegralRect(selectionRectInView), -1, -1) 301 | self.colorFrameView.color = strokeColor 302 | textView.addSubview(colorFrameView) 303 | } 304 | 305 | func dismissColorWell() { 306 | if self.colorWell.active { 307 | self.colorWell.deactivate() 308 | NSColorPanel.sharedColorPanel().orderOut(nil) 309 | } 310 | self.colorWell.removeFromSuperview() 311 | self.colorFrameView.removeFromSuperview() 312 | self.selectedColorRange = NSMakeRange(NSNotFound, 0) 313 | self.selectedColorType = .None 314 | } 315 | 316 | func colorDidChange(sender: AnyObject) { 317 | guard self.selectedColorRange.location != NSNotFound else { 318 | return 319 | } 320 | guard let textView = self.textView else { 321 | return 322 | } 323 | if let colorString = self.colorStringForColor(self.colorWell.color, colorType: self.selectedColorType) { 324 | textView.undoManager?.beginUndoGrouping() 325 | textView.insertText(colorString, replacementRange: self.selectedColorRange) 326 | textView.undoManager?.endUndoGrouping() 327 | } 328 | } 329 | 330 | 331 | // MARK: Color String Parsing 332 | func colorCodeMatch(text: String, rx: NSRegularExpression, selectedRange: NSRange, handler: (result: NSTextCheckingResult, colorRange: NSRange, stop: UnsafeMutablePointer) -> ()) { 333 | let textRange = NSMakeRange(0, text.characters.count) 334 | let matchingOption = NSMatchingOptions.init(rawValue: 0) 335 | rx.enumerateMatchesInString(text, options: matchingOption, range: textRange) { (checkResult, flags, stop) in 336 | guard let result = checkResult else { 337 | stop.memory = true 338 | return 339 | } 340 | let colorRange = result.range 341 | guard colorRange.location != NSNotFound else { 342 | stop.memory = true 343 | return 344 | } 345 | if selectedRange.location >= colorRange.location 346 | && NSMaxRange(selectedRange) <= NSMaxRange(colorRange) { 347 | handler(result: result, colorRange: colorRange, stop: stop) 348 | } 349 | } 350 | } 351 | 352 | func color(text text: NSString, selectedRange: NSRange, inout type: SWCColorType, inout matchedRange: NSRange) -> NSColor? { 353 | var foundColor : NSColor? = nil 354 | var foundColorRange = NSMakeRange(NSNotFound, 0) 355 | var foundColorType = SWCColorType.None 356 | let string = String(text) 357 | self.colorCodeMatch(string, rx: self.rgbaUIColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) -> () in 358 | let hasInit = result.rangeAtIndex(1).location != NSNotFound 359 | var red = Double(text.substringWithRange(result.rangeAtIndex(2))) ?? 0.0 360 | red = self.dividedValue(red, divisorRange: result.rangeAtIndex(3), inString: text) 361 | var green = Double(text.substringWithRange(result.rangeAtIndex(4))) ?? 0.0 362 | green = self.dividedValue(green, divisorRange: result.rangeAtIndex(5), inString: text) 363 | var blue = Double(text.substringWithRange(result.rangeAtIndex(6))) ?? 0.0 364 | blue = self.dividedValue(blue, divisorRange: result.rangeAtIndex(7), inString: text) 365 | var alpha = Double(text.substringWithRange(result.rangeAtIndex(8))) ?? 0.0 366 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(9), inString: text) 367 | let c = SWC_RGBA.init(r: red, g: green, b: blue, a: alpha) 368 | foundColor = NSColor.init(calibratedRed: c.r, green: c.g, blue: c.b, alpha: c.a) 369 | if hasInit { 370 | foundColorType = .UIRGBAInit 371 | } 372 | else { 373 | foundColorType = .UIRGBA 374 | } 375 | foundColorRange = colorRange 376 | stop.memory = true 377 | } 378 | 379 | if foundColor == nil { 380 | self.colorCodeMatch(string, rx: self.whiteUIColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) -> () in 381 | let hasInit = result.rangeAtIndex(1).location != NSNotFound 382 | var white = Double(text.substringWithRange(result.rangeAtIndex(2))) ?? 0.0 383 | white = self.dividedValue(white, divisorRange: result.rangeAtIndex(3), inString: text) 384 | var alpha = Double(text.substringWithRange(result.rangeAtIndex(4))) ?? 0.0 385 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(5), inString: text) 386 | foundColor = NSColor(white: CGFloat(white), alpha: CGFloat(alpha)) 387 | foundColorType = hasInit ? .UIWhiteInit : .UIWhite 388 | foundColorRange = colorRange 389 | stop.memory = true 390 | } 391 | } 392 | 393 | if foundColor == nil { 394 | self.colorCodeMatch(string, rx: self.constantColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) -> () in 395 | let NS_UI = text.substringWithRange(result.rangeAtIndex(1)) 396 | let colorName = text.substringWithRange(result.rangeAtIndex(2)) 397 | foundColor = self.constantColorsByName[colorName] 398 | foundColorRange = colorRange 399 | foundColorType = NS_UI.hasPrefix("UI") ? .UIConstant : .NSConstant 400 | stop.memory = true 401 | } 402 | } 403 | 404 | if foundColor == nil { 405 | self.colorCodeMatch(string, rx: self.rgbaNSColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) -> () in 406 | let hasInit = result.rangeAtIndex(1).location != NSNotFound 407 | let foundPrefix = result.rangeAtIndex(2).location != NSNotFound 408 | var red = Double(text.substringWithRange(result.rangeAtIndex(3))) ?? 0.0 409 | red = self.dividedValue(red, divisorRange: result.rangeAtIndex(4), inString: text) 410 | var green = Double(text.substringWithRange(result.rangeAtIndex(5))) ?? 0.0 411 | green = self.dividedValue(green, divisorRange: result.rangeAtIndex(6), inString: text) 412 | var blue = Double(text.substringWithRange(result.rangeAtIndex(7))) ?? 0.0 413 | blue = self.dividedValue(blue, divisorRange: result.rangeAtIndex(8), inString: text) 414 | var alpha = Double(text.substringWithRange(result.rangeAtIndex(9))) ?? 0.0 415 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(10), inString: text) 416 | let c = SWC_RGBA.init(r: red, g: green, b: blue, a: alpha) 417 | if foundPrefix { 418 | let prefixString = text.substringWithRange(result.rangeAtIndex(2)) 419 | if prefixString.hasPrefix("calibrated") { 420 | foundColor = NSColor.init(calibratedRed: c.r, green: c.g, blue: c.b, alpha: c.a) 421 | foundColorType = hasInit ? .NSRGBACalibratedInit : .NSRGBACalibrated 422 | } 423 | else { 424 | foundColor = NSColor.init(deviceRed: c.r, green: c.g, blue: c.b, alpha: c.a) 425 | foundColorType = hasInit ? .NSRGBADeviceInit : .NSRGBADevice 426 | } 427 | } 428 | else { 429 | foundColor = NSColor.init(red: c.r, green: c.g, blue: c.b, alpha: c.a) 430 | foundColorType = hasInit ? .NSRGBAInit : .NSRGBA 431 | } 432 | foundColorRange = colorRange 433 | stop.memory = true 434 | } 435 | } 436 | 437 | if foundColor == nil { 438 | self.colorCodeMatch(string, rx: self.whiteNSColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) -> () in 439 | let hasInit = result.rangeAtIndex(1).location != NSNotFound 440 | let hasPrefix = result.rangeAtIndex(2).location != NSNotFound 441 | var white = Double(text.substringWithRange(result.rangeAtIndex(3))) ?? 0.0 442 | white = self.dividedValue(white, divisorRange: result.rangeAtIndex(4), inString: text) 443 | var alpha = Double(text.substringWithRange(result.rangeAtIndex(5))) ?? 0.0 444 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(6), inString: text) 445 | if hasPrefix { 446 | let prefixString = text.substringWithRange(result.rangeAtIndex(2)) 447 | if prefixString.hasPrefix("calibrated") { 448 | foundColor = NSColor(calibratedWhite: CGFloat(white), alpha: CGFloat(alpha)) 449 | foundColorType = hasInit ? .NSWhiteCalibratedInit : .NSWhiteCalibrated 450 | } 451 | else { 452 | foundColor = NSColor(deviceWhite: CGFloat(white), alpha: CGFloat(alpha)) 453 | foundColorType = hasInit ? .NSWhiteDeviceInit : .NSWhiteDevice 454 | } 455 | } 456 | else { 457 | foundColor = NSColor(white: CGFloat(white), alpha: CGFloat(alpha)) 458 | foundColorType = hasInit ? .NSWhiteInit : .NSWhite 459 | } 460 | foundColorRange = colorRange 461 | stop.memory = true 462 | } 463 | } 464 | 465 | if foundColor == nil { 466 | self.colorCodeMatch(string, rx: self.objc_rgbaUIColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) in 467 | var red = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(2))) 468 | red = self.dividedValue(red, divisorRange: result.rangeAtIndex(3), inString: text) 469 | var green = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(4))) 470 | green = self.dividedValue(green, divisorRange: result.rangeAtIndex(5), inString: text) 471 | var blue = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(6))) 472 | blue = self.dividedValue(blue, divisorRange: result.rangeAtIndex(7), inString: text) 473 | var alpha = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(8))) 474 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(9), inString: text) 475 | let c = SWC_RGBA.init(r: red, g: green, b: blue, a: alpha) 476 | foundColor = NSColor.init(red: c.r, green: c.g, blue: c.b, alpha: c.a) 477 | foundColorType = .UIRGBA_OBJC 478 | foundColorRange = colorRange 479 | stop.memory = true 480 | } 481 | } 482 | 483 | if foundColor == nil { 484 | self.colorCodeMatch(string, rx: self.objc_rgbaNSColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) in 485 | var red = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(2))) 486 | red = self.dividedValue(red, divisorRange: result.rangeAtIndex(3), inString: text) 487 | var green = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(4))) 488 | green = self.dividedValue(green, divisorRange: result.rangeAtIndex(5), inString: text) 489 | var blue = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(6))) 490 | blue = self.dividedValue(blue, divisorRange: result.rangeAtIndex(7), inString: text) 491 | var alpha = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(8))) 492 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(9), inString: text) 493 | let c = SWC_RGBA.init(r: red, g: green, b: blue, a: alpha) 494 | foundColor = NSColor.init(red: c.r, green: c.g, blue: c.b, alpha: c.a) 495 | let prefixRange = result.rangeAtIndex(1) 496 | if prefixRange.location == NSNotFound { 497 | foundColorType = .NSRGBA_OBJC 498 | } 499 | else { 500 | let prefixString = text.substringWithRange(result.rangeAtIndex(1)) 501 | if prefixString.hasPrefix("Calibrated") { 502 | foundColorType = .NSRGBACalibrated_OBJC 503 | } 504 | else if prefixString.hasPrefix("Device") { 505 | foundColorType = .NSRGBADevice_OBJC 506 | } 507 | } 508 | 509 | foundColorRange = colorRange 510 | stop.memory = true 511 | } 512 | } 513 | 514 | if foundColor == nil { 515 | self.colorCodeMatch(string, rx: self.objc_whiteUIColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) in 516 | var white = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(2))) 517 | white = self.dividedValue(white, divisorRange: result.rangeAtIndex(3), inString: text) 518 | var alpha = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(4))) 519 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(5), inString: text) 520 | foundColor = NSColor(white: CGFloat(white), alpha: CGFloat(alpha)) 521 | foundColorType = .UIWhite_OBJC 522 | foundColorRange = colorRange 523 | stop.memory = true 524 | } 525 | } 526 | 527 | if foundColor == nil { 528 | self.colorCodeMatch(string, rx: self.objc_whiteNSColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) in 529 | var white = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(2))) 530 | white = self.dividedValue(white, divisorRange: result.rangeAtIndex(3), inString: text) 531 | var alpha = self.convertMatchedStringToDouble(text.substringWithRange(result.rangeAtIndex(4))) 532 | alpha = self.dividedValue(alpha, divisorRange: result.rangeAtIndex(5), inString: text) 533 | foundColor = NSColor(white: CGFloat(white), alpha: CGFloat(alpha)) 534 | let prefixRange = result.rangeAtIndex(1) 535 | if prefixRange.location == NSNotFound { 536 | foundColorType = .NSWhite_OBJC 537 | } 538 | else { 539 | let prefixString = text.substringWithRange(result.rangeAtIndex(1)) 540 | if prefixString.hasPrefix("Calibrated") { 541 | foundColorType = .NSWhiteCalibrated_OBJC 542 | } 543 | else if prefixString.hasPrefix("Device") { 544 | foundColorType = .NSWhiteDevice_OBJC 545 | } 546 | } 547 | foundColorRange = colorRange 548 | stop.memory = true 549 | } 550 | } 551 | 552 | if foundColor == nil { 553 | self.colorCodeMatch(string, rx: self.objc_constantColorRegex, selectedRange: selectedRange) { [unowned self] (result, colorRange, stop) -> () in 554 | let NS_UI = text.substringWithRange(result.rangeAtIndex(1)) 555 | let colorName = text.substringWithRange(result.rangeAtIndex(2)) 556 | foundColor = self.constantColorsByName[colorName] 557 | foundColorRange = colorRange 558 | foundColorType = NS_UI.hasPrefix("UI") ? .UIConstant_OBJC : .NSConstant_OBJC 559 | stop.memory = true 560 | } 561 | } 562 | 563 | 564 | 565 | if foundColor != nil { 566 | matchedRange = foundColorRange 567 | type = foundColorType 568 | return foundColor 569 | } 570 | 571 | return nil 572 | } 573 | 574 | func convertMatchedStringToDouble(value: String?) -> Double { 575 | guard let string = value else { 576 | return 0 577 | } 578 | let trimmed = string.stringByTrimmingCharactersInSet(NSCharacterSet.init(charactersInString: "/ f")) 579 | return Double(trimmed) ?? 0 580 | } 581 | 582 | func dividedValue(value: Double, divisorRange: NSRange, inString text: NSString) -> Double { 583 | var val = value; 584 | if divisorRange.location != NSNotFound { 585 | let divisor = self.convertMatchedStringToDouble(text.substringWithRange(divisorRange)) 586 | if divisor != 0.0 { 587 | val /= divisor 588 | } 589 | } 590 | return val 591 | } 592 | 593 | func colorStringForColor(color: NSColor, colorType: SWCColorType) -> NSString? { 594 | var col = color; 595 | var colorString : NSString? = nil 596 | var c = SWC_RGBA(r: -1, g: -1, b: -1, a: -1) 597 | col = col.colorUsingColorSpace(NSColorSpace.genericRGBColorSpace())! 598 | col.getRed(&c.r, green: &c.g, blue: &c.b, alpha: &c.a) 599 | if c.r >= 0 { 600 | for (colorName, constantColor) in self.constantColorsByName { 601 | if constantColor == col { 602 | if SWCColorType.isNSColor(colorType) { 603 | colorString = NSString(format: "NSColor.%@Color()", colorName) 604 | } 605 | else { 606 | colorString = NSString(format: "UIColor.%@Color()", colorName) 607 | } 608 | break 609 | } 610 | } 611 | guard colorString == nil else { 612 | return colorString 613 | } 614 | if fabs(c.r - c.g) < 0.001 && fabs(c.g - c.b) < 0.001 { 615 | switch colorType { 616 | case .UIRGBA, .UIWhite, .UIConstant: 617 | colorString = NSString(format: 618 | "UIColor(white: %.3f, alpha: %.3f)", c.r, c.a) 619 | case .UIRGBAInit, .UIWhiteInit: 620 | colorString = NSString(format: 621 | "UIColor.init(white: %.3f, alpha: %.3f)", c.r, c.a) 622 | case .NSRGBA, .NSWhite: 623 | colorString = NSString(format: 624 | "NSColor(white: %.3f, alpha: %.3f)", c.r, c.a) 625 | case .NSRGBAInit, .NSWhiteInit: 626 | colorString = NSString(format: 627 | "NSColor.init(white: %.3f, alpha: %.3f)", c.r, c.a) 628 | case .NSRGBACalibrated, .NSWhiteCalibrated, .NSConstant: 629 | colorString = NSString(format: 630 | "NSColor(calibratedWhite: %.3f, alpha: %.3f)", c.r, c.a) 631 | case .NSRGBACalibratedInit, .NSWhiteCalibratedInit: 632 | colorString = NSString(format: 633 | "NSColor.init(calibratedWhite: %.3f, alpha: %.3f)", c.r, c.a) 634 | case .NSRGBADevice, .NSWhiteDevice: 635 | colorString = NSString(format: 636 | "NSColor(deviceWhite: %.3f, alpha: %.3f)", c.r, c.a) 637 | case .NSRGBADeviceInit, .NSWhiteDeviceInit: 638 | colorString = NSString(format: 639 | "NSColor.init(deviceWhite: %.3f, alpha: %.3f)", c.r, c.a) 640 | case .UIRGBA_OBJC, .UIWhite_OBJC, .UIConstant_OBJC: 641 | colorString = NSString(format: 642 | "[UIColor colorWithWhite:%.3f alpha:%.3f]", c.r, c.a) 643 | case .NSRGBA_OBJC, .NSWhite_OBJC: 644 | colorString = NSString(format: 645 | "[NSColor colorWithWhite:%.3f alpha:%.3f]", c.r, c.a) 646 | case .NSRGBACalibrated_OBJC, .NSWhiteCalibrated_OBJC, .NSConstant_OBJC: 647 | colorString = NSString(format: 648 | "[NSColor colorWithCalibratedWhite:%.3f alpha:%.3f]", c.r, c.a) 649 | case .NSRGBADevice_OBJC, .NSWhiteDevice_OBJC: 650 | colorString = NSString(format: 651 | "[NSColor colorWithDeviceWhite:%.3f alpha:%.3f]", c.r, c.a) 652 | default: break 653 | } 654 | } 655 | else { 656 | switch colorType { 657 | case .UIRGBA, .UIWhite, .UIConstant: 658 | colorString = NSString(format: 659 | "UIColor(red: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 660 | case .UIRGBAInit, .UIWhiteInit: 661 | colorString = NSString(format: 662 | "UIColor.init(red: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 663 | case .NSRGBA, .NSWhite: 664 | colorString = NSString(format: 665 | "NSColor(red: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 666 | case .NSRGBAInit, .NSWhiteInit: 667 | colorString = NSString(format: 668 | "NSColor.init(red: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 669 | case .NSRGBACalibrated, .NSWhiteCalibrated: 670 | colorString = NSString(format: 671 | "NSColor(calibratedRed: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 672 | case .NSRGBACalibratedInit, .NSWhiteCalibratedInit, .NSConstant: 673 | colorString = NSString(format: 674 | "NSColor.init(calibratedRed: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 675 | case .NSRGBADevice, .NSWhiteDevice: 676 | colorString = NSString(format: 677 | "NSColor(deviceRed: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 678 | case .NSRGBADeviceInit, .NSWhiteDeviceInit: 679 | colorString = NSString(format: 680 | "NSColor.init(deviceRed: %.3f, green: %.3f, blue: %.3f, alpha: %.3f)", c.r, c.g, c.b, c.a) 681 | case .UIRGBA_OBJC, .UIWhite_OBJC, .UIConstant_OBJC: 682 | colorString = NSString(format: 683 | "[UIColor colorWithRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", c.r, c.g, c.b, c.a) 684 | case .NSRGBA_OBJC, .NSWhite_OBJC: 685 | colorString = NSString(format: 686 | "[NSColor colorWithRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", c.r, c.g, c.b, c.a) 687 | case .NSRGBACalibrated_OBJC, .NSWhiteCalibrated_OBJC, .NSConstant_OBJC: 688 | colorString = NSString(format: 689 | "[NSColor colorWithCalibratedRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", c.r, c.g, c.b, c.a) 690 | case .NSRGBADevice_OBJC, .NSWhiteDevice_OBJC: 691 | colorString = NSString(format: 692 | "[NSColor colorWithDeviceRed:%.3f green:%.3f blue:%.3f alpha:%.3f]", c.r, c.g, c.b, c.a) 693 | default: break 694 | } 695 | } 696 | } 697 | return colorString 698 | } 699 | 700 | } 701 | 702 | 703 | 704 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin/SWCPlainColorWell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SWCPlainColorWell.swift 3 | // Swift-Color-Xcode-Plugin 4 | // 5 | // Created by Shingo Fukuyama on 3/13/16. 6 | // Copyright © 2016 Shingo Fukuyama. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Cocoa 11 | 12 | class SWCPlainColorWell : NSColorWell { 13 | var strokeColor : NSColor? = NSColor.whiteColor() 14 | 15 | override func deactivate() { 16 | super.deactivate() 17 | NSColorPanel.sharedColorPanel().orderOut(nil) 18 | } 19 | 20 | override func drawRect(dirtyRect: NSRect) { 21 | NSGraphicsContext.saveGraphicsState() 22 | let rectBody = NSMakeRect(0, -5, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + 5) 23 | let path = NSBezierPath.init(roundedRect: rectBody, xRadius: 5.0, yRadius: 5.0) 24 | path.addClip() 25 | self.drawWellInside(self.bounds) 26 | NSGraphicsContext.restoreGraphicsState() 27 | 28 | if let color = self.strokeColor { 29 | let strokePath = NSBezierPath.init(roundedRect: NSInsetRect(rectBody, 0.5, 0.5), xRadius: 5.0, yRadius: 5.0) 30 | color.setStroke() 31 | strokePath.stroke() 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Swift-Color-Xcode-Plugin/Swift-Color-Xcode-Plugin-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | 6 | #import -------------------------------------------------------------------------------- /ss1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShingoFukuyama/Swift-Color-Xcode-Plugin/616cf548d00c39e7a423743f62509d17a4485b89/ss1.gif --------------------------------------------------------------------------------