2013-08-16 04:09:39 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
|
|
|
|
#include "nsColorPicker.h"
|
|
|
|
#include "nsCocoaUtils.h"
|
2014-03-13 13:52:14 -07:00
|
|
|
#include "nsThreadUtils.h"
|
2013-08-16 04:09:39 -07:00
|
|
|
|
|
|
|
using namespace mozilla;
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
HexStrToInt(NSString* str)
|
|
|
|
{
|
|
|
|
unsigned int result = 0;
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < [str length]; ++i) {
|
|
|
|
char c = [str characterAtIndex:i];
|
|
|
|
result *= 16;
|
|
|
|
if (c >= '0' && c <= '9') {
|
|
|
|
result += c - '0';
|
|
|
|
} else if (c >= 'A' && c <= 'F') {
|
|
|
|
result += 10 + (c - 'A');
|
|
|
|
} else {
|
|
|
|
result += 10 + (c - 'a');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@interface NSColorPanelWrapper : NSObject <NSWindowDelegate>
|
|
|
|
{
|
|
|
|
NSColorPanel* mColorPanel;
|
|
|
|
nsColorPicker* mColorPicker;
|
|
|
|
}
|
|
|
|
- (id)initWithPicker:(nsColorPicker*)aPicker;
|
|
|
|
- (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle;
|
2014-03-13 13:52:14 -07:00
|
|
|
- (void)retarget:(nsColorPicker*)aPicker;
|
2013-08-16 04:09:39 -07:00
|
|
|
- (void)colorChanged:(NSColorPanel*)aPanel;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NSColorPanelWrapper
|
|
|
|
- (id)initWithPicker:(nsColorPicker*)aPicker
|
|
|
|
{
|
|
|
|
mColorPicker = aPicker;
|
|
|
|
mColorPanel = [NSColorPanel sharedColorPanel];
|
|
|
|
|
|
|
|
self = [super init];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)open:(NSColor*)aInitialColor title:(NSString*)aTitle
|
|
|
|
{
|
|
|
|
[mColorPanel setTitle:aTitle];
|
|
|
|
[mColorPanel setColor:aInitialColor];
|
|
|
|
[mColorPanel setTarget:self];
|
|
|
|
[mColorPanel setAction:@selector(colorChanged:)];
|
|
|
|
[mColorPanel setDelegate:self];
|
|
|
|
[mColorPanel makeKeyAndOrderFront:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)colorChanged:(NSColorPanel*)aPanel
|
|
|
|
{
|
|
|
|
mColorPicker->Update([mColorPanel color]);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)windowWillClose:(NSNotification*)aNotification
|
|
|
|
{
|
|
|
|
mColorPicker->Done();
|
|
|
|
}
|
|
|
|
|
2014-03-13 13:52:14 -07:00
|
|
|
- (void)retarget:(nsColorPicker*)aPicker
|
|
|
|
{
|
|
|
|
mColorPicker->DoneWithRetarget();
|
|
|
|
mColorPicker = aPicker;
|
|
|
|
}
|
|
|
|
|
2013-08-16 04:09:39 -07:00
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
if ([mColorPanel delegate] == self) {
|
|
|
|
[mColorPanel setTarget:nil];
|
|
|
|
[mColorPanel setAction:nil];
|
|
|
|
[mColorPanel setDelegate:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
mColorPanel = nil;
|
|
|
|
mColorPicker = nullptr;
|
|
|
|
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS1(nsColorPicker, nsIColorPicker)
|
|
|
|
|
2014-03-13 13:52:14 -07:00
|
|
|
NSColorPanelWrapper* nsColorPicker::sColorPanelWrapper = nullptr;
|
|
|
|
|
2013-08-16 04:09:39 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsColorPicker::Init(nsIDOMWindow* aParent, const nsAString& aTitle,
|
|
|
|
const nsAString& aInitialColor)
|
|
|
|
{
|
2014-03-13 13:52:14 -07:00
|
|
|
MOZ_ASSERT(NS_IsMainThread(),
|
|
|
|
"Color pickers can only be opened from main thread currently");
|
2013-08-16 04:09:39 -07:00
|
|
|
mTitle = aTitle;
|
|
|
|
mColor = aInitialColor;
|
|
|
|
|
2014-03-13 13:52:14 -07:00
|
|
|
if (sColorPanelWrapper) {
|
|
|
|
// Update current wrapper to target the new input instead
|
|
|
|
[sColorPanelWrapper retarget:this];
|
|
|
|
} else {
|
|
|
|
// Create a brand new color panel wrapper
|
|
|
|
sColorPanelWrapper = [[NSColorPanelWrapper alloc] initWithPicker:this];
|
|
|
|
}
|
2013-08-16 04:09:39 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ NSColor*
|
|
|
|
nsColorPicker::GetNSColorFromHexString(const nsAString& aColor)
|
|
|
|
{
|
|
|
|
NSString* str = nsCocoaUtils::ToNSString(aColor);
|
|
|
|
|
|
|
|
double red = HexStrToInt([str substringWithRange:NSMakeRange(1, 2)]) / 255.0;
|
|
|
|
double green = HexStrToInt([str substringWithRange:NSMakeRange(3, 2)]) / 255.0;
|
|
|
|
double blue = HexStrToInt([str substringWithRange:NSMakeRange(5, 2)]) / 255.0;
|
|
|
|
|
|
|
|
return [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1.0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ void
|
|
|
|
nsColorPicker::GetHexStringFromNSColor(NSColor* aColor, nsAString& aResult)
|
|
|
|
{
|
|
|
|
CGFloat redFloat, greenFloat, blueFloat;
|
|
|
|
[aColor getRed: &redFloat green: &greenFloat blue: &blueFloat alpha: nil];
|
|
|
|
|
|
|
|
nsCocoaUtils::GetStringForNSString([NSString stringWithFormat:@"#%02x%02x%02x",
|
|
|
|
(int)(redFloat * 255),
|
|
|
|
(int)(greenFloat * 255),
|
|
|
|
(int)(blueFloat * 255)],
|
|
|
|
aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsColorPicker::Open(nsIColorPickerShownCallback* aCallback)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aCallback);
|
|
|
|
mCallback = aCallback;
|
|
|
|
|
2014-03-13 13:52:14 -07:00
|
|
|
[sColorPanelWrapper open:GetNSColorFromHexString(mColor)
|
2013-08-16 04:09:39 -07:00
|
|
|
title:nsCocoaUtils::ToNSString(mTitle)];
|
|
|
|
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsColorPicker::Update(NSColor* aColor)
|
|
|
|
{
|
|
|
|
GetHexStringFromNSColor(aColor, mColor);
|
|
|
|
mCallback->Update(mColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-03-13 13:52:14 -07:00
|
|
|
nsColorPicker::DoneWithRetarget()
|
2013-08-16 04:09:39 -07:00
|
|
|
{
|
|
|
|
mCallback->Done(EmptyString());
|
|
|
|
mCallback = nullptr;
|
2014-03-13 11:48:04 -07:00
|
|
|
NS_RELEASE_THIS();
|
2014-03-13 08:04:57 -07:00
|
|
|
}
|
2014-03-13 13:52:14 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
nsColorPicker::Done()
|
|
|
|
{
|
|
|
|
[sColorPanelWrapper release];
|
|
|
|
sColorPanelWrapper = nullptr;
|
|
|
|
DoneWithRetarget();
|
|
|
|
}
|