widget/cocoa/nsColorPicker.mm

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

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 }

mercurial