widget/cocoa/nsColorPicker.mm

changeset 0
6474c204b198
     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 +}

mercurial