| // 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. |
| |
| #include "chrome/browser/ui/views/color_chooser_dialog.h" |
| |
| #include <commdlg.h> |
| |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/stl_util.h" |
| #include "base/threading/thread.h" |
| #include "content/public/browser/browser_task_traits.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "skia/ext/skia_utils_win.h" |
| #include "ui/views/color_chooser/color_chooser_listener.h" |
| #include "ui/views/win/hwnd_util.h" |
| |
| // static |
| COLORREF ColorChooserDialog::g_custom_colors[16]; |
| |
| ColorChooserDialog::ColorChooserDialog(views::ColorChooserListener* listener) |
| : listener_(listener) { |
| DCHECK(listener_); |
| CopyCustomColors(g_custom_colors, custom_colors_); |
| } |
| |
| void ColorChooserDialog::Open(SkColor initial_color, |
| gfx::NativeWindow owning_window) { |
| HWND owning_hwnd = views::HWNDForNativeWindow(owning_window); |
| |
| std::unique_ptr<RunState> run_state = BeginRun(owning_hwnd); |
| |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
| run_state->dialog_task_runner; |
| task_runner->PostTask(FROM_HERE, |
| base::BindOnce(&ColorChooserDialog::ExecuteOpen, this, |
| initial_color, std::move(run_state))); |
| } |
| |
| bool ColorChooserDialog::IsRunning(gfx::NativeWindow owning_window) const { |
| return listener_ && IsRunningDialogForOwner( |
| views::HWNDForNativeWindow(owning_window)); |
| } |
| |
| void ColorChooserDialog::ListenerDestroyed() { |
| // Our associated listener has gone away, so we shouldn't call back to it if |
| // our worker thread returns after the listener is dead. |
| listener_ = nullptr; |
| } |
| |
| ColorChooserDialog::~ColorChooserDialog() { |
| } |
| |
| void ColorChooserDialog::ExecuteOpen(SkColor color, |
| std::unique_ptr<RunState> run_state) { |
| CHOOSECOLOR cc; |
| cc.lStructSize = sizeof(CHOOSECOLOR); |
| cc.hwndOwner = run_state->owner; |
| cc.rgbResult = skia::SkColorToCOLORREF(color); |
| cc.lpCustColors = custom_colors_; |
| cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT; |
| bool success = !!ChooseColor(&cc); |
| DisableOwner(cc.hwndOwner); |
| content::GetUIThreadTaskRunner({})->PostTask( |
| FROM_HERE, base::BindOnce(&ColorChooserDialog::DidCloseDialog, this, |
| success, skia::COLORREFToSkColor(cc.rgbResult), |
| std::move(run_state))); |
| } |
| |
| void ColorChooserDialog::DidCloseDialog(bool chose_color, |
| SkColor color, |
| std::unique_ptr<RunState> run_state) { |
| EndRun(std::move(run_state)); |
| CopyCustomColors(custom_colors_, g_custom_colors); |
| if (listener_) { |
| if (chose_color) |
| listener_->OnColorChosen(color); |
| listener_->OnColorChooserDialogClosed(); |
| } |
| } |
| |
| void ColorChooserDialog::CopyCustomColors(COLORREF* src, COLORREF* dst) { |
| memcpy(dst, src, sizeof(COLORREF) * base::size(g_custom_colors)); |
| } |