15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/color_chooser_dialog.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <commdlg.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/skia_utils_win.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/color_chooser/color_chooser_listener.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/win/hwnd_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COLORREF ColorChooserDialog::g_custom_colors[16];
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserDialog::ExecuteOpenParams::ExecuteOpenParams(SkColor color,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         RunState run_state,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         HWND owner)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : color(color),
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      run_state(run_state),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      owner(owner) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserDialog::ColorChooserDialog(views::ColorChooserListener* listener,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SkColor initial_color,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       gfx::NativeWindow owning_window)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : listener_(listener) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(listener_);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyCustomColors(g_custom_colors, custom_colors_);
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HWND owning_hwnd = views::HWNDForNativeWindow(owning_window);
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExecuteOpenParams execute_params(initial_color, BeginRun(owning_hwnd),
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   owning_hwnd);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  execute_params.run_state.dialog_thread->message_loop()->PostTask(FROM_HERE,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ColorChooserDialog::ExecuteOpen, this, execute_params));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserDialog::~ColorChooserDialog() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ColorChooserDialog::IsRunning(gfx::NativeWindow owning_window) const {
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return listener_ && IsRunningDialogForOwner(
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      views::HWNDForNativeWindow(owning_window));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserDialog::ListenerDestroyed() {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our associated listener has gone away, so we shouldn't call back to it if
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // our worker thread returns after the listener is dead.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_ = NULL;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserDialog::ExecuteOpen(const ExecuteOpenParams& params) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHOOSECOLOR cc;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cc.lStructSize = sizeof(CHOOSECOLOR);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cc.hwndOwner = params.owner;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cc.rgbResult = skia::SkColorToCOLORREF(params.color);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cc.lpCustColors = custom_colors_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = !!ChooseColor(&cc);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableOwner(cc.hwndOwner);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ColorChooserDialog::DidCloseDialog, this, success,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 skia::COLORREFToSkColor(cc.rgbResult), params.run_state));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserDialog::DidCloseDialog(bool chose_color,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        SkColor color,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        RunState run_state) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EndRun(run_state);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyCustomColors(custom_colors_, g_custom_colors);
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (listener_) {
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (chose_color)
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      listener_->OnColorChosen(color);
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    listener_->OnColorChooserDialogClosed();
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserDialog::CopyCustomColors(COLORREF* src, COLORREF* dst) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, src, sizeof(COLORREF) * arraysize(g_custom_colors));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86