Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #import <Cocoa/Cocoa.h>
8 #include "nsColorPicker.h"
9 #include "nsCocoaUtils.h"
10 #include "nsThreadUtils.h"
12 using namespace mozilla;
14 static unsigned int
15 HexStrToInt(NSString* str)
16 {
17 unsigned int result = 0;
19 for (unsigned int i = 0; i < [str length]; ++i) {
20 char c = [str characterAtIndex:i];
21 result *= 16;
22 if (c >= '0' && c <= '9') {
23 result += c - '0';
24 } else if (c >= 'A' && c <= 'F') {
25 result += 10 + (c - 'A');
26 } else {
27 result += 10 + (c - 'a');
28 }
29 }
31 return result;
32 }
34 @interface NSColorPanelWrapper : NSObject <NSWindowDelegate>
35 {
36 NSColorPanel* mColorPanel;
37 nsColorPicker* mColorPicker;
38 }
39 - (id)initWithPicker:(nsColorPicker*)aPicker;
40 - (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle;
41 - (void)retarget:(nsColorPicker*)aPicker;
42 - (void)colorChanged:(NSColorPanel*)aPanel;
43 @end
45 @implementation NSColorPanelWrapper
46 - (id)initWithPicker:(nsColorPicker*)aPicker
47 {
48 mColorPicker = aPicker;
49 mColorPanel = [NSColorPanel sharedColorPanel];
51 self = [super init];
52 return self;
53 }
55 - (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle
56 {
57 [mColorPanel setTitle:aTitle];
58 [mColorPanel setColor:aInitialColor];
59 [mColorPanel setTarget:self];
60 [mColorPanel setAction:@selector(colorChanged:)];
61 [mColorPanel setDelegate:self];
62 [mColorPanel makeKeyAndOrderFront:nil];
63 }
65 - (void)colorChanged:(NSColorPanel*)aPanel
66 {
67 mColorPicker->Update([mColorPanel color]);
68 }
70 - (void)windowWillClose:(NSNotification*)aNotification
71 {
72 mColorPicker->Done();
73 }
75 - (void)retarget:(nsColorPicker*)aPicker
76 {
77 mColorPicker->DoneWithRetarget();
78 mColorPicker = aPicker;
79 }
81 - (void)dealloc
82 {
83 if ([mColorPanel delegate] == self) {
84 [mColorPanel setTarget:nil];
85 [mColorPanel setAction:nil];
86 [mColorPanel setDelegate:nil];
87 }
89 mColorPanel = nil;
90 mColorPicker = nullptr;
92 [super dealloc];
93 }
94 @end
96 NS_IMPL_ISUPPORTS(nsColorPicker, nsIColorPicker)
98 NSColorPanelWrapper* nsColorPicker::sColorPanelWrapper = nullptr;
100 NS_IMETHODIMP
101 nsColorPicker::Init(nsIDOMWindow* aParent, const nsAString& aTitle,
102 const nsAString& aInitialColor)
103 {
104 MOZ_ASSERT(NS_IsMainThread(),
105 "Color pickers can only be opened from main thread currently");
106 mTitle = aTitle;
107 mColor = aInitialColor;
109 if (sColorPanelWrapper) {
110 // Update current wrapper to target the new input instead
111 [sColorPanelWrapper retarget:this];
112 } else {
113 // Create a brand new color panel wrapper
114 sColorPanelWrapper = [[NSColorPanelWrapper alloc] initWithPicker:this];
115 }
116 return NS_OK;
117 }
119 /* static */ NSColor*
120 nsColorPicker::GetNSColorFromHexString(const nsAString& aColor)
121 {
122 NSString* str = nsCocoaUtils::ToNSString(aColor);
124 double red = HexStrToInt([str substringWithRange:NSMakeRange(1, 2)]) / 255.0;
125 double green = HexStrToInt([str substringWithRange:NSMakeRange(3, 2)]) / 255.0;
126 double blue = HexStrToInt([str substringWithRange:NSMakeRange(5, 2)]) / 255.0;
128 return [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1.0];
129 }
131 /* static */ void
132 nsColorPicker::GetHexStringFromNSColor(NSColor* aColor, nsAString& aResult)
133 {
134 CGFloat redFloat, greenFloat, blueFloat;
135 [aColor getRed: &redFloat green: &greenFloat blue: &blueFloat alpha: nil];
137 nsCocoaUtils::GetStringForNSString([NSString stringWithFormat:@"#%02x%02x%02x",
138 (int)(redFloat * 255),
139 (int)(greenFloat * 255),
140 (int)(blueFloat * 255)],
141 aResult);
142 }
144 NS_IMETHODIMP
145 nsColorPicker::Open(nsIColorPickerShownCallback* aCallback)
146 {
147 MOZ_ASSERT(aCallback);
148 mCallback = aCallback;
150 [sColorPanelWrapper open:GetNSColorFromHexString(mColor)
151 title:nsCocoaUtils::ToNSString(mTitle)];
153 NS_ADDREF_THIS();
155 return NS_OK;
156 }
158 void
159 nsColorPicker::Update(NSColor* aColor)
160 {
161 GetHexStringFromNSColor(aColor, mColor);
162 mCallback->Update(mColor);
163 }
165 void
166 nsColorPicker::DoneWithRetarget()
167 {
168 mCallback->Done(EmptyString());
169 mCallback = nullptr;
170 NS_RELEASE_THIS();
171 }
173 void
174 nsColorPicker::Done()
175 {
176 [sColorPanelWrapper release];
177 sColorPanelWrapper = nullptr;
178 DoneWithRetarget();
179 }