1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/cocoa/nsColorPicker.mm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,179 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#import <Cocoa/Cocoa.h> 1.10 + 1.11 +#include "nsColorPicker.h" 1.12 +#include "nsCocoaUtils.h" 1.13 +#include "nsThreadUtils.h" 1.14 + 1.15 +using namespace mozilla; 1.16 + 1.17 +static unsigned int 1.18 +HexStrToInt(NSString* str) 1.19 +{ 1.20 + unsigned int result = 0; 1.21 + 1.22 + for (unsigned int i = 0; i < [str length]; ++i) { 1.23 + char c = [str characterAtIndex:i]; 1.24 + result *= 16; 1.25 + if (c >= '0' && c <= '9') { 1.26 + result += c - '0'; 1.27 + } else if (c >= 'A' && c <= 'F') { 1.28 + result += 10 + (c - 'A'); 1.29 + } else { 1.30 + result += 10 + (c - 'a'); 1.31 + } 1.32 + } 1.33 + 1.34 + return result; 1.35 +} 1.36 + 1.37 +@interface NSColorPanelWrapper : NSObject <NSWindowDelegate> 1.38 +{ 1.39 + NSColorPanel* mColorPanel; 1.40 + nsColorPicker* mColorPicker; 1.41 +} 1.42 +- (id)initWithPicker:(nsColorPicker*)aPicker; 1.43 +- (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle; 1.44 +- (void)retarget:(nsColorPicker*)aPicker; 1.45 +- (void)colorChanged:(NSColorPanel*)aPanel; 1.46 +@end 1.47 + 1.48 +@implementation NSColorPanelWrapper 1.49 +- (id)initWithPicker:(nsColorPicker*)aPicker 1.50 +{ 1.51 + mColorPicker = aPicker; 1.52 + mColorPanel = [NSColorPanel sharedColorPanel]; 1.53 + 1.54 + self = [super init]; 1.55 + return self; 1.56 +} 1.57 + 1.58 +- (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle 1.59 +{ 1.60 + [mColorPanel setTitle:aTitle]; 1.61 + [mColorPanel setColor:aInitialColor]; 1.62 + [mColorPanel setTarget:self]; 1.63 + [mColorPanel setAction:@selector(colorChanged:)]; 1.64 + [mColorPanel setDelegate:self]; 1.65 + [mColorPanel makeKeyAndOrderFront:nil]; 1.66 +} 1.67 + 1.68 +- (void)colorChanged:(NSColorPanel*)aPanel 1.69 +{ 1.70 + mColorPicker->Update([mColorPanel color]); 1.71 +} 1.72 + 1.73 +- (void)windowWillClose:(NSNotification*)aNotification 1.74 +{ 1.75 + mColorPicker->Done(); 1.76 +} 1.77 + 1.78 +- (void)retarget:(nsColorPicker*)aPicker 1.79 +{ 1.80 + mColorPicker->DoneWithRetarget(); 1.81 + mColorPicker = aPicker; 1.82 +} 1.83 + 1.84 +- (void)dealloc 1.85 +{ 1.86 + if ([mColorPanel delegate] == self) { 1.87 + [mColorPanel setTarget:nil]; 1.88 + [mColorPanel setAction:nil]; 1.89 + [mColorPanel setDelegate:nil]; 1.90 + } 1.91 + 1.92 + mColorPanel = nil; 1.93 + mColorPicker = nullptr; 1.94 + 1.95 + [super dealloc]; 1.96 +} 1.97 +@end 1.98 + 1.99 +NS_IMPL_ISUPPORTS(nsColorPicker, nsIColorPicker) 1.100 + 1.101 +NSColorPanelWrapper* nsColorPicker::sColorPanelWrapper = nullptr; 1.102 + 1.103 +NS_IMETHODIMP 1.104 +nsColorPicker::Init(nsIDOMWindow* aParent, const nsAString& aTitle, 1.105 + const nsAString& aInitialColor) 1.106 +{ 1.107 + MOZ_ASSERT(NS_IsMainThread(), 1.108 + "Color pickers can only be opened from main thread currently"); 1.109 + mTitle = aTitle; 1.110 + mColor = aInitialColor; 1.111 + 1.112 + if (sColorPanelWrapper) { 1.113 + // Update current wrapper to target the new input instead 1.114 + [sColorPanelWrapper retarget:this]; 1.115 + } else { 1.116 + // Create a brand new color panel wrapper 1.117 + sColorPanelWrapper = [[NSColorPanelWrapper alloc] initWithPicker:this]; 1.118 + } 1.119 + return NS_OK; 1.120 +} 1.121 + 1.122 +/* static */ NSColor* 1.123 +nsColorPicker::GetNSColorFromHexString(const nsAString& aColor) 1.124 +{ 1.125 + NSString* str = nsCocoaUtils::ToNSString(aColor); 1.126 + 1.127 + double red = HexStrToInt([str substringWithRange:NSMakeRange(1, 2)]) / 255.0; 1.128 + double green = HexStrToInt([str substringWithRange:NSMakeRange(3, 2)]) / 255.0; 1.129 + double blue = HexStrToInt([str substringWithRange:NSMakeRange(5, 2)]) / 255.0; 1.130 + 1.131 + return [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1.0]; 1.132 +} 1.133 + 1.134 +/* static */ void 1.135 +nsColorPicker::GetHexStringFromNSColor(NSColor* aColor, nsAString& aResult) 1.136 +{ 1.137 + CGFloat redFloat, greenFloat, blueFloat; 1.138 + [aColor getRed: &redFloat green: &greenFloat blue: &blueFloat alpha: nil]; 1.139 + 1.140 + nsCocoaUtils::GetStringForNSString([NSString stringWithFormat:@"#%02x%02x%02x", 1.141 + (int)(redFloat * 255), 1.142 + (int)(greenFloat * 255), 1.143 + (int)(blueFloat * 255)], 1.144 + aResult); 1.145 +} 1.146 + 1.147 +NS_IMETHODIMP 1.148 +nsColorPicker::Open(nsIColorPickerShownCallback* aCallback) 1.149 +{ 1.150 + MOZ_ASSERT(aCallback); 1.151 + mCallback = aCallback; 1.152 + 1.153 + [sColorPanelWrapper open:GetNSColorFromHexString(mColor) 1.154 + title:nsCocoaUtils::ToNSString(mTitle)]; 1.155 + 1.156 + NS_ADDREF_THIS(); 1.157 + 1.158 + return NS_OK; 1.159 +} 1.160 + 1.161 +void 1.162 +nsColorPicker::Update(NSColor* aColor) 1.163 +{ 1.164 + GetHexStringFromNSColor(aColor, mColor); 1.165 + mCallback->Update(mColor); 1.166 +} 1.167 + 1.168 +void 1.169 +nsColorPicker::DoneWithRetarget() 1.170 +{ 1.171 + mCallback->Done(EmptyString()); 1.172 + mCallback = nullptr; 1.173 + NS_RELEASE_THIS(); 1.174 +} 1.175 + 1.176 +void 1.177 +nsColorPicker::Done() 1.178 +{ 1.179 + [sColorPanelWrapper release]; 1.180 + sColorPanelWrapper = nullptr; 1.181 + DoneWithRetarget(); 1.182 +}