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