blob: bc9166c0a279aa6c93dd6dfbe0534e99778c6f42 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Cocoa/Cocoa.h>
#include "base/logging.h"
#import "base/mac/scoped_nsobject.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "content/public/browser/color_chooser.h"
#include "content/public/browser/web_contents.h"
#include "skia/ext/skia_utils_mac.h"
class ColorChooserMac;
// A Listener class to act as a event target for NSColorPanel and send
// the results to the C++ class, ColorChooserMac.
@interface ColorPanelCocoa : NSObject<NSWindowDelegate> {
@private
// We don't call DidChooseColor if the change wasn't caused by the user
// interacting with the panel.
BOOL nonUserChange_;
ColorChooserMac* chooser_; // weak, owns this
}
- (id)initWithChooser:(ColorChooserMac*)chooser;
// Called from NSColorPanel.
- (void)didChooseColor:(NSColorPanel*)panel;
// Sets color to the NSColorPanel as a non user change.
- (void)setColor:(NSColor*)color;
@end
class ColorChooserMac : public content::ColorChooser {
public:
static ColorChooserMac* Open(content::WebContents* web_contents,
SkColor initial_color);
ColorChooserMac(content::WebContents* tab, SkColor initial_color);
~ColorChooserMac() override;
// Called from ColorPanelCocoa.
void DidChooseColorInColorPanel(SkColor color);
void DidCloseColorPabel();
void End() override;
void SetSelectedColor(SkColor color) override;
private:
static ColorChooserMac* current_color_chooser_;
// The web contents invoking the color chooser. No ownership because it will
// outlive this class.
content::WebContents* web_contents_;
base::scoped_nsobject<ColorPanelCocoa> panel_;
};
ColorChooserMac* ColorChooserMac::current_color_chooser_ = NULL;
// static
ColorChooserMac* ColorChooserMac::Open(content::WebContents* web_contents,
SkColor initial_color) {
if (current_color_chooser_)
current_color_chooser_->End();
DCHECK(!current_color_chooser_);
current_color_chooser_ =
new ColorChooserMac(web_contents, initial_color);
return current_color_chooser_;
}
ColorChooserMac::ColorChooserMac(content::WebContents* web_contents,
SkColor initial_color)
: web_contents_(web_contents) {
panel_.reset([[ColorPanelCocoa alloc] initWithChooser:this]);
[panel_ setColor:gfx::SkColorToDeviceNSColor(initial_color)];
[[NSColorPanel sharedColorPanel] makeKeyAndOrderFront:nil];
}
ColorChooserMac::~ColorChooserMac() {
// Always call End() before destroying.
DCHECK(!panel_);
}
void ColorChooserMac::DidChooseColorInColorPanel(SkColor color) {
if (web_contents_)
web_contents_->DidChooseColorInColorChooser(color);
}
void ColorChooserMac::DidCloseColorPabel() {
End();
}
void ColorChooserMac::End() {
panel_.reset();
DCHECK(current_color_chooser_ == this);
current_color_chooser_ = NULL;
if (web_contents_)
web_contents_->DidEndColorChooser();
}
void ColorChooserMac::SetSelectedColor(SkColor color) {
[panel_ setColor:gfx::SkColorToDeviceNSColor(color)];
}
@implementation ColorPanelCocoa
- (id)initWithChooser:(ColorChooserMac*)chooser {
if ((self = [super init])) {
chooser_ = chooser;
NSColorPanel* panel = [NSColorPanel sharedColorPanel];
[panel setShowsAlpha:NO];
[panel setDelegate:self];
[panel setTarget:self];
[panel setAction:@selector(didChooseColor:)];
}
return self;
}
- (void)dealloc {
NSColorPanel* panel = [NSColorPanel sharedColorPanel];
if ([panel delegate] == self) {
[panel setDelegate:nil];
[panel setTarget:nil];
[panel setAction:nil];
}
[super dealloc];
}
- (void)windowWillClose:(NSNotification*)notification {
chooser_->DidCloseColorPabel();
nonUserChange_ = NO;
}
- (void)didChooseColor:(NSColorPanel*)panel {
if (nonUserChange_) {
nonUserChange_ = NO;
return;
}
chooser_->DidChooseColorInColorPanel(gfx::NSDeviceColorToSkColor(
[[panel color] colorUsingColorSpaceName:NSDeviceRGBColorSpace]));
nonUserChange_ = NO;
}
- (void)setColor:(NSColor*)color {
nonUserChange_ = YES;
[[NSColorPanel sharedColorPanel] setColor:color];
}
namespace chrome {
content::ColorChooser* ShowColorChooser(content::WebContents* web_contents,
SkColor initial_color) {
return ColorChooserMac::Open(web_contents, initial_color);
}
} // namepace chrome
@end