Home | History | Annotate | Download | only in views
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <windows.h>
      6 
      7 #include "chrome/browser/platform_util.h"
      8 #include "chrome/browser/ui/browser_dialogs.h"
      9 #include "chrome/browser/ui/host_desktop.h"
     10 #include "chrome/browser/ui/views/color_chooser_aura.h"
     11 #include "chrome/browser/ui/views/color_chooser_dialog.h"
     12 #include "content/public/browser/color_chooser.h"
     13 #include "content/public/browser/render_view_host.h"
     14 #include "content/public/browser/render_widget_host_view.h"
     15 #include "content/public/browser/web_contents.h"
     16 #include "ui/views/color_chooser/color_chooser_listener.h"
     17 
     18 class ColorChooserWin : public content::ColorChooser,
     19                         public views::ColorChooserListener {
     20  public:
     21   static ColorChooserWin* Open(content::WebContents* web_contents,
     22                                SkColor initial_color);
     23 
     24   ColorChooserWin(content::WebContents* web_contents,
     25                   SkColor initial_color);
     26   ~ColorChooserWin();
     27 
     28   // content::ColorChooser overrides:
     29   virtual void End() OVERRIDE;
     30   virtual void SetSelectedColor(SkColor color) OVERRIDE {}
     31 
     32   // views::ColorChooserListener overrides:
     33   virtual void OnColorChosen(SkColor color);
     34   virtual void OnColorChooserDialogClosed();
     35 
     36  private:
     37   static ColorChooserWin* current_color_chooser_;
     38 
     39   // The web contents invoking the color chooser.  No ownership. because it will
     40   // outlive this class.
     41   content::WebContents* web_contents_;
     42 
     43   // The color chooser dialog which maintains the native color chooser UI.
     44   scoped_refptr<ColorChooserDialog> color_chooser_dialog_;
     45 };
     46 
     47 ColorChooserWin* ColorChooserWin::current_color_chooser_ = NULL;
     48 
     49 ColorChooserWin* ColorChooserWin::Open(content::WebContents* web_contents,
     50                                        SkColor initial_color) {
     51   if (current_color_chooser_)
     52     return NULL;
     53   current_color_chooser_ = new ColorChooserWin(web_contents, initial_color);
     54   return current_color_chooser_;
     55 }
     56 
     57 ColorChooserWin::ColorChooserWin(content::WebContents* web_contents,
     58                                  SkColor initial_color)
     59     : web_contents_(web_contents) {
     60   gfx::NativeWindow owning_window = platform_util::GetTopLevel(
     61       web_contents->GetRenderViewHost()->GetView()->GetNativeView());
     62   color_chooser_dialog_ = new ColorChooserDialog(this,
     63                                                  initial_color,
     64                                                  owning_window);
     65 }
     66 
     67 ColorChooserWin::~ColorChooserWin() {
     68   // Always call End() before destroying.
     69   DCHECK(!color_chooser_dialog_);
     70 }
     71 
     72 void ColorChooserWin::End() {
     73   // The ColorChooserDialog's listener is going away.  Ideally we'd
     74   // programmatically close the dialog at this point.  Since that's impossible,
     75   // we instead tell the dialog its listener is going away, so that the dialog
     76   // doesn't try to communicate with a destroyed listener later.  (We also tell
     77   // the renderer the dialog is closed, since from the renderer's perspective
     78   // it effectively is.)
     79   OnColorChooserDialogClosed();
     80 }
     81 
     82 void ColorChooserWin::OnColorChosen(SkColor color) {
     83   if (web_contents_)
     84     web_contents_->DidChooseColorInColorChooser(color);
     85 }
     86 
     87 void ColorChooserWin::OnColorChooserDialogClosed() {
     88   if (color_chooser_dialog_.get()) {
     89     color_chooser_dialog_->ListenerDestroyed();
     90     color_chooser_dialog_ = NULL;
     91   }
     92   DCHECK(current_color_chooser_ == this);
     93   current_color_chooser_ = NULL;
     94   if (web_contents_)
     95     web_contents_->DidEndColorChooser();
     96 }
     97 
     98 namespace chrome {
     99 
    100 content::ColorChooser* ShowColorChooser(content::WebContents* web_contents,
    101                                         SkColor initial_color) {
    102   gfx::NativeView native_view = web_contents->GetNativeView();
    103   if (GetHostDesktopTypeForNativeView(native_view) == HOST_DESKTOP_TYPE_ASH)
    104     return ColorChooserAura::Open(web_contents, initial_color);
    105 
    106   return ColorChooserWin::Open(web_contents, initial_color);
    107 }
    108 
    109 }  // namespace chrome
    110