Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / cocoa / nsColorPicker.mm
blob36665577725918dbdd069598c55733d7c9eeb5ec
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 HexStrToInt(NSString* str) {
15   unsigned int result = 0;
17   for (unsigned int i = 0; i < [str length]; ++i) {
18     char c = [str characterAtIndex:i];
19     result *= 16;
20     if (c >= '0' && c <= '9') {
21       result += c - '0';
22     } else if (c >= 'A' && c <= 'F') {
23       result += 10 + (c - 'A');
24     } else {
25       result += 10 + (c - 'a');
26     }
27   }
29   return result;
32 @interface NSColorPanelWrapper : NSObject <NSWindowDelegate> {
33   NSColorPanel* mColorPanel;
34   nsColorPicker* mColorPicker;
36 - (id)initWithPicker:(nsColorPicker*)aPicker;
37 - (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle;
38 - (void)colorChanged:(NSColorPanel*)aPanel;
39 - (void)windowWillClose:(NSNotification*)aNotification;
40 - (void)close;
41 @end
43 @implementation NSColorPanelWrapper
44 - (id)initWithPicker:(nsColorPicker*)aPicker {
45   mColorPicker = aPicker;
46   mColorPanel = [NSColorPanel sharedColorPanel];
48   self = [super init];
49   return self;
52 - (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle {
53   [mColorPanel setTarget:self];
54   [mColorPanel setAction:@selector(colorChanged:)];
55   [mColorPanel setDelegate:self];
56   [mColorPanel setTitle:aTitle];
57   [mColorPanel setColor:aInitialColor];
58   [mColorPanel setFrameOrigin:[NSEvent mouseLocation]];
59   [mColorPanel makeKeyAndOrderFront:nil];
62 - (void)colorChanged:(NSColorPanel*)aPanel {
63   if (!mColorPicker) {
64     return;
65   }
66   mColorPicker->Update([mColorPanel color]);
69 - (void)windowWillClose:(NSNotification*)aNotification {
70   if (!mColorPicker) {
71     return;
72   }
73   mColorPicker->Done();
76 - (void)close {
77   [mColorPanel setTarget:nil];
78   [mColorPanel setAction:nil];
79   [mColorPanel setDelegate:nil];
81   mColorPanel = nil;
82   mColorPicker = nullptr;
84 @end
86 NS_IMPL_ISUPPORTS(nsColorPicker, nsIColorPicker)
88 nsColorPicker::~nsColorPicker() {
89   if (mColorPanelWrapper) {
90     [mColorPanelWrapper close];
91     [mColorPanelWrapper release];
92     mColorPanelWrapper = nullptr;
93   }
96 // TODO(bug 1805397): Implement default colors
97 NS_IMETHODIMP
98 nsColorPicker::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle,
99                     const nsAString& aInitialColor,
100                     const nsTArray<nsString>& aDefaultColors) {
101   MOZ_ASSERT(NS_IsMainThread(),
102              "Color pickers can only be opened from main thread currently");
103   mTitle = aTitle;
104   mColor = aInitialColor;
105   mColorPanelWrapper = [[NSColorPanelWrapper alloc] initWithPicker:this];
106   return NS_OK;
109 /* static */ NSColor* nsColorPicker::GetNSColorFromHexString(
110     const nsAString& aColor) {
111   NSString* str = nsCocoaUtils::ToNSString(aColor);
113   double red = HexStrToInt([str substringWithRange:NSMakeRange(1, 2)]) / 255.0;
114   double green =
115       HexStrToInt([str substringWithRange:NSMakeRange(3, 2)]) / 255.0;
116   double blue = HexStrToInt([str substringWithRange:NSMakeRange(5, 2)]) / 255.0;
118   return [NSColor colorWithDeviceRed:red green:green blue:blue alpha:1.0];
121 /* static */ void nsColorPicker::GetHexStringFromNSColor(NSColor* aColor,
122                                                          nsAString& aResult) {
123   CGFloat redFloat, greenFloat, blueFloat;
125   NSColor* color = aColor;
126   @try {
127     [color getRed:&redFloat green:&greenFloat blue:&blueFloat alpha:nil];
128   } @catch (NSException* e) {
129     color = [color colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]];
130     [color getRed:&redFloat green:&greenFloat blue:&blueFloat alpha:nil];
131   }
133   nsCocoaUtils::GetStringForNSString(
134       [NSString stringWithFormat:@"#%02x%02x%02x", (int)(redFloat * 255),
135                                  (int)(greenFloat * 255),
136                                  (int)(blueFloat * 255)],
137       aResult);
140 NS_IMETHODIMP
141 nsColorPicker::Open(nsIColorPickerShownCallback* aCallback) {
142   MOZ_ASSERT(aCallback);
143   mCallback = aCallback;
145   [mColorPanelWrapper open:GetNSColorFromHexString(mColor)
146                      title:nsCocoaUtils::ToNSString(mTitle)];
148   NS_ADDREF_THIS();
150   return NS_OK;
153 void nsColorPicker::Update(NSColor* aColor) {
154   GetHexStringFromNSColor(aColor, mColor);
155   mCallback->Update(mColor);
158 void nsColorPicker::Done() {
159   [mColorPanelWrapper close];
160   [mColorPanelWrapper release];
161   mColorPanelWrapper = nullptr;
162   mCallback->Done(u""_ns);
163   mCallback = nullptr;
164   NS_RELEASE_THIS();