Skip to content

Commit 62b111a

Browse files
committed
ColorSet files can now also be saved as XML (plist).
1 parent fbccc29 commit 62b111a

File tree

10 files changed

+395
-19
lines changed

10 files changed

+395
-19
lines changed

ColorSet.xcodeproj/project.pbxproj

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
05D11ECA20E13DFF00A621B5 /* ColorSet.AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05D11EC820E13DFF00A621B5 /* ColorSet.AboutWindowController.xib */; };
4949
05D11ECC20E13E0900A621B5 /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D11ECB20E13E0800A621B5 /* AboutWindowController.swift */; };
5050
05D11ECE20E165FB00A621B5 /* File.icns in Resources */ = {isa = PBXBuildFile; fileRef = 05D11ECD20E165FB00A621B5 /* File.icns */; };
51+
05DB415323846DCB0026C565 /* DictionaryRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05DB415223846DCB0026C565 /* DictionaryRepresentable.swift */; };
52+
05DB415723847CE80026C565 /* SaveAsOptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05DB415623847CE80026C565 /* SaveAsOptionsViewController.swift */; };
53+
05DB415A23847CF80026C565 /* ColorSet.SaveAsOptionsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05DB415823847CF80026C565 /* ColorSet.SaveAsOptionsViewController.xib */; };
5154
/* End PBXBuildFile section */
5255

5356
/* Begin PBXContainerItemProxy section */
@@ -171,6 +174,9 @@
171174
05D11EC920E13DFF00A621B5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ColorSet.AboutWindowController.xib; sourceTree = "<group>"; };
172175
05D11ECB20E13E0800A621B5 /* AboutWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = "<group>"; };
173176
05D11ECD20E165FB00A621B5 /* File.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = File.icns; sourceTree = "<group>"; };
177+
05DB415223846DCB0026C565 /* DictionaryRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryRepresentable.swift; sourceTree = "<group>"; };
178+
05DB415623847CE80026C565 /* SaveAsOptionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveAsOptionsViewController.swift; sourceTree = "<group>"; };
179+
05DB415923847CF80026C565 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ColorSet.SaveAsOptionsViewController.xib; sourceTree = "<group>"; };
174180
/* End PBXFileReference section */
175181

176182
/* Begin PBXFrameworksBuildPhase section */
@@ -330,6 +336,7 @@
330336
05A6D8C8234107B30079AF3B /* LightnessPair.swift */,
331337
0544CC0C2273466C004A2499 /* ColorSetStream.swift */,
332338
0544CBF52273199C004A2499 /* ColorSet.swift */,
339+
05DB415223846DCB0026C565 /* DictionaryRepresentable.swift */,
333340
);
334341
path = ColorSetKit;
335342
sourceTree = "<group>";
@@ -379,6 +386,7 @@
379386
0543AE8120DC382A00284E99 /* ColorItem.swift */,
380387
0530C42420E1305B00F5B259 /* ColorSet-Bridging-Header.h */,
381388
0543AE9D20E0FFD000284E99 /* ColorView.swift */,
389+
0556FA6C2342796C00EB91DB /* DrawingView.swift */,
382390
0530C42520E1305B00F5B259 /* Exception.h */,
383391
0530C42620E1305B00F5B259 /* Exception.m */,
384392
059F8C77233CDB3300C9B83F /* HColorComponent.swift */,
@@ -389,12 +397,12 @@
389397
05A6D896233F8A300079AF3B /* LightnessString.swift */,
390398
0543AE7C20DC345200284E99 /* MainWindowController.swift */,
391399
0530C42220E1213500F5B259 /* NSView.swift */,
392-
05D11EC020E1359C00A621B5 /* RGBColorComponent.swift */,
393-
059F8C78233CDB3300C9B83F /* SLColorComponent.swift */,
394-
0556FA66234275CF00EB91DB /* PaletteViewController.swift */,
395400
0556FA6D2342796C00EB91DB /* PaletteColorInfo.swift */,
396401
0556FA6B2342796C00EB91DB /* PaletteColorItem.swift */,
397-
0556FA6C2342796C00EB91DB /* DrawingView.swift */,
402+
0556FA66234275CF00EB91DB /* PaletteViewController.swift */,
403+
05D11EC020E1359C00A621B5 /* RGBColorComponent.swift */,
404+
05DB415623847CE80026C565 /* SaveAsOptionsViewController.swift */,
405+
059F8C78233CDB3300C9B83F /* SLColorComponent.swift */,
398406
);
399407
path = Classes;
400408
sourceTree = "<group>";
@@ -406,11 +414,12 @@
406414
05A6D8C32340EA880079AF3B /* ColorSet.LightnessPairCollectionViewItem.xib */,
407415
05A6D893233F805C0079AF3B /* ColorSet.LightnessPairWindowController.xib */,
408416
0543AE7E20DC35CC00284E99 /* ColorSet.MainWindowController.xib */,
409-
0556FA7123427DE500EB91DB /* PaletteColorItem.xib */,
410417
0556FA682342761000EB91DB /* ColorSet.PaletteViewController.xib */,
418+
05DB415823847CF80026C565 /* ColorSet.SaveAsOptionsViewController.xib */,
411419
05D11ECD20E165FB00A621B5 /* File.icns */,
412420
05D11EC620E13B9400A621B5 /* Icon.icns */,
413421
0543AE7720DC33DF00284E99 /* MainMenu.xib */,
422+
0556FA7123427DE500EB91DB /* PaletteColorItem.xib */,
414423
);
415424
path = Interface;
416425
sourceTree = "<group>";
@@ -575,6 +584,7 @@
575584
05D11EC720E13B9400A621B5 /* Icon.icns in Resources */,
576585
0556FA6A2342761000EB91DB /* ColorSet.PaletteViewController.xib in Resources */,
577586
0543AE8020DC35CC00284E99 /* ColorSet.MainWindowController.xib in Resources */,
587+
05DB415A23847CF80026C565 /* ColorSet.SaveAsOptionsViewController.xib in Resources */,
578588
0556FA7323427DE500EB91DB /* PaletteColorItem.xib in Resources */,
579589
05D11ECE20E165FB00A621B5 /* File.icns in Resources */,
580590
0543AE7B20DC33DF00284E99 /* MainMenu.xib in Resources */,
@@ -631,6 +641,7 @@
631641
0543AE8220DC382A00284E99 /* ColorItem.swift in Sources */,
632642
0556FA6F2342796C00EB91DB /* DrawingView.swift in Sources */,
633643
0556FA6E2342796C00EB91DB /* PaletteColorItem.swift in Sources */,
644+
05DB415723847CE80026C565 /* SaveAsOptionsViewController.swift in Sources */,
634645
05A6D897233F8A300079AF3B /* LightnessString.swift in Sources */,
635646
05A6D8C22340EA740079AF3B /* LightnessPairCollectionViewItem.swift in Sources */,
636647
0530C41F20E10FEA00F5B259 /* ArrayIsEmpty.swift in Sources */,
@@ -659,6 +670,7 @@
659670
files = (
660671
0544CBF62273199C004A2499 /* ColorSet.swift in Sources */,
661672
0544CBF422731990004A2499 /* ColorPair.swift in Sources */,
673+
05DB415323846DCB0026C565 /* DictionaryRepresentable.swift in Sources */,
662674
0544CC0D2273466C004A2499 /* ColorSetStream.swift in Sources */,
663675
05A6D8C9234107B30079AF3B /* LightnessPair.swift in Sources */,
664676
05A6D8C7234107A40079AF3B /* LightnessVariant.swift in Sources */,
@@ -738,6 +750,14 @@
738750
name = ColorSet.AboutWindowController.xib;
739751
sourceTree = "<group>";
740752
};
753+
05DB415823847CF80026C565 /* ColorSet.SaveAsOptionsViewController.xib */ = {
754+
isa = PBXVariantGroup;
755+
children = (
756+
05DB415923847CF80026C565 /* Base */,
757+
);
758+
name = ColorSet.SaveAsOptionsViewController.xib;
759+
sourceTree = "<group>";
760+
};
741761
/* End PBXVariantGroup section */
742762

743763
/* Begin XCBuildConfiguration section */

ColorSet/Classes/ApplicationDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class ApplicationDelegate: NSResponder, NSApplicationDelegate
145145
colors.append( item )
146146
}
147147

148-
let controller = MainWindowController( colors: colors )
148+
let controller = MainWindowController( colors: colors, format: set.format )
149149
controller.url = url
150150

151151
controller.window?.center()

ColorSet/Classes/MainWindowController.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,19 @@ class MainWindowController: NSWindowController, NSTableViewDelegate, NSTableView
3939
private var timer: Timer?
4040
private var lightnessPairWindowController: LightnessPairWindowController?
4141
private var paletteViewController: PaletteViewController?
42+
private var format: ColorSet.Format = .binary
4243

4344
@IBOutlet public var colorsArrayController: NSArrayController!
4445
@IBOutlet public var lightnessPairsArrayController: NSArrayController!
4546
@IBOutlet public var collectionView: NSCollectionView!
4647
@IBOutlet public var paletteViewContainer: NSView!
4748

48-
convenience init( colors: [ ColorItem ] )
49+
convenience init( colors: [ ColorItem ], format: ColorSet.Format )
4950
{
5051
self.init()
5152

5253
self.colors = colors
54+
self.format = format
5355
}
5456

5557
deinit
@@ -199,7 +201,7 @@ class MainWindowController: NSWindowController, NSTableViewDelegate, NSTableView
199201
return
200202
}
201203

202-
self.save( to: url )
204+
self.save( to: url, format: self.format )
203205
}
204206

205207
@IBAction public func saveDocumentAs( _ sender: Any? )
@@ -209,10 +211,12 @@ class MainWindowController: NSWindowController, NSTableViewDelegate, NSTableView
209211
return
210212
}
211213

212-
let panel = NSSavePanel()
214+
let panel = NSSavePanel()
215+
let options = SaveAsOptionsViewController()
213216

214217
panel.allowedFileTypes = [ "colorset" ]
215218
panel.canCreateDirectories = true
219+
panel.accessoryView = options.view
216220

217221
panel.beginSheetModal( for: window )
218222
{
@@ -228,20 +232,21 @@ class MainWindowController: NSWindowController, NSTableViewDelegate, NSTableView
228232
return
229233
}
230234

231-
self.save( to: url )
235+
self.save( to: url, format: options.format )
232236

237+
self.format = options.format
233238
self.url = url
234239
self.window?.title = ( self.url == nil ) ? "Untitled.colorset" : ( self.url!.path as NSString ).lastPathComponent
235240
}
236241
}
237242

238-
public func save( to url: URL )
243+
public func save( to url: URL, format: ColorSet.Format )
239244
{
240245
let set = self.generateColorSet()
241246

242247
do
243248
{
244-
try set.writeTo( url: url )
249+
try set.writeTo( url: url, format: format )
245250
}
246251
catch let error as NSError
247252
{
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*******************************************************************************
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2018 Jean-David Gadina - www.imazing.com
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
******************************************************************************/
24+
25+
import Cocoa
26+
import ColorSetKit
27+
28+
public class SaveAsOptionsViewController: NSViewController
29+
{
30+
@objc private dynamic var formatIndex: Int = 0
31+
32+
@objc public var format: ColorSet.Format
33+
{
34+
get
35+
{
36+
return self.formatIndex == 1 ? .xml : .binary
37+
}
38+
}
39+
40+
public override var nibName: NSNib.Name?
41+
{
42+
return NSNib.Name( NSStringFromClass( type( of: self ) ) )
43+
}
44+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
3+
<dependencies>
4+
<deployment identifier="macosx"/>
5+
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15505"/>
6+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7+
</dependencies>
8+
<objects>
9+
<customObject id="-2" userLabel="File's Owner" customClass="SaveAsOptionsViewController" customModule="ColorSet" customModuleProvider="target">
10+
<connections>
11+
<outlet property="view" destination="c22-O7-iKe" id="eaE-ym-wiA"/>
12+
</connections>
13+
</customObject>
14+
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
15+
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
16+
<customView id="c22-O7-iKe">
17+
<rect key="frame" x="0.0" y="0.0" width="480" height="61"/>
18+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
19+
<subviews>
20+
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="haU-aD-aZO">
21+
<rect key="frame" x="73" y="17" width="77" height="25"/>
22+
<popUpButtonCell key="cell" type="push" title="Binary" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="fjV-lK-Zy3" id="N27-4y-rlX">
23+
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
24+
<font key="font" metaFont="system"/>
25+
<menu key="menu" id="oip-mY-z2k">
26+
<items>
27+
<menuItem title="Binary" state="on" id="fjV-lK-Zy3"/>
28+
<menuItem title="XML" id="ExJ-CB-XR4"/>
29+
</items>
30+
</menu>
31+
</popUpButtonCell>
32+
<connections>
33+
<binding destination="-2" name="selectedIndex" keyPath="self.formatIndex" id="oNT-HJ-X6R"/>
34+
</connections>
35+
</popUpButton>
36+
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="h7d-ZQ-etW">
37+
<rect key="frame" x="18" y="23" width="51" height="16"/>
38+
<textFieldCell key="cell" lineBreakMode="clipping" title="Format:" id="mOe-Wb-EEP">
39+
<font key="font" usesAppearanceFont="YES"/>
40+
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
41+
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
42+
</textFieldCell>
43+
</textField>
44+
</subviews>
45+
<constraints>
46+
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="haU-aD-aZO" secondAttribute="trailing" constant="20" id="XWr-Hd-pRP"/>
47+
<constraint firstItem="haU-aD-aZO" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" constant="20" id="hAS-sr-kJo"/>
48+
<constraint firstItem="h7d-ZQ-etW" firstAttribute="centerY" secondItem="haU-aD-aZO" secondAttribute="centerY" id="hsN-80-0PL"/>
49+
<constraint firstAttribute="bottom" secondItem="haU-aD-aZO" secondAttribute="bottom" constant="20" id="ist-v8-kui"/>
50+
<constraint firstItem="h7d-ZQ-etW" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="20" id="k10-Hf-eq7"/>
51+
<constraint firstItem="haU-aD-aZO" firstAttribute="leading" secondItem="h7d-ZQ-etW" secondAttribute="trailing" constant="8" id="zYj-wi-hWU"/>
52+
</constraints>
53+
<point key="canvasLocation" x="139" y="154"/>
54+
</customView>
55+
</objects>
56+
</document>

ColorSetKit/ColorPair.swift

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import Cocoa
3535
*
3636
* - Seealso: `LightnessPair`
3737
*/
38-
@objc public class ColorPair: NSObject
38+
@objc public class ColorPair: NSObject, DictionaryRepresentable
3939
{
4040
/**
4141
* The main/primary color.
@@ -92,4 +92,82 @@ import Cocoa
9292
self.color = color
9393
self.variant = variant
9494
}
95+
96+
@objc public required init?( dictionary: [ String : Any ] )
97+
{
98+
super.init()
99+
100+
if let color = self.colorFromDictionary( dictionary[ "color" ] as? [ String : Any ] )
101+
{
102+
self.color = color
103+
}
104+
105+
if let variant = self.colorFromDictionary( dictionary[ "variant" ] as? [ String : Any ] )
106+
{
107+
self.variant = variant
108+
}
109+
110+
if let lightnesses = dictionary[ "lightnesses" ] as? [ [ String : Any ] ]
111+
{
112+
for l in lightnesses
113+
{
114+
if let lightness = LightnessPair( dictionary: l )
115+
{
116+
self.lightnesses.append( lightness )
117+
}
118+
}
119+
}
120+
}
121+
122+
@objc public func toDictionary() -> [ String : Any ]
123+
{
124+
var dict = [ String : Any ]()
125+
var lightnesses = [ [ String : Any ] ]()
126+
127+
dict[ "color" ] = self.colorToDictionary( self.color )
128+
dict[ "variant" ] = self.colorToDictionary( self.variant )
129+
130+
for l in self.lightnesses
131+
{
132+
lightnesses.append( l.toDictionary() )
133+
}
134+
135+
dict[ "lightnesses" ] = lightnesses
136+
137+
return dict
138+
}
139+
140+
private func colorToDictionary( _ color: NSColor? ) -> [ String : Any ]?
141+
{
142+
guard let color = color else
143+
{
144+
return nil
145+
}
146+
147+
guard let hsl = color.usingColorSpace( .sRGB )?.hsl() else
148+
{
149+
return nil
150+
}
151+
152+
return [ "h" : hsl.hue, "s" : hsl.saturation, "l" : hsl.lightness, "a" : hsl.alpha ]
153+
}
154+
155+
private func colorFromDictionary( _ dictionary: [ String : Any ]? ) -> NSColor?
156+
{
157+
guard let dictionary = dictionary else
158+
{
159+
return nil
160+
}
161+
162+
guard let h = dictionary[ "h" ] as? CGFloat,
163+
let s = dictionary[ "s" ] as? CGFloat,
164+
let l = dictionary[ "l" ] as? CGFloat,
165+
let a = dictionary[ "a" ] as? CGFloat
166+
else
167+
{
168+
return nil
169+
}
170+
171+
return NSColor( hue: h, saturation: s, lightness: l, alpha: a )
172+
}
95173
}

0 commit comments

Comments
 (0)