Home | History | Annotate | Download | only in gtk
      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 <gtk/gtk.h>
      6 
      7 #include "chrome/browser/ui/browser_dialogs.h"
      8 #include "content/public/browser/color_chooser.h"
      9 #include "content/public/browser/web_contents.h"
     10 #include "grit/generated_resources.h"
     11 #include "ui/base/gtk/gtk_signal.h"
     12 #include "ui/base/l10n/l10n_util.h"
     13 #include "ui/gfx/skia_utils_gtk.h"
     14 
     15 class ColorChooserGtk : public content::ColorChooser {
     16  public:
     17   static ColorChooserGtk* Open(content::WebContents* web_contents,
     18                                SkColor initial_color);
     19 
     20   ColorChooserGtk(content::WebContents* web_contents, SkColor initial_color);
     21   virtual ~ColorChooserGtk();
     22 
     23   virtual void End() OVERRIDE;
     24   virtual void SetSelectedColor(SkColor color) OVERRIDE;
     25 
     26  private:
     27   static ColorChooserGtk* current_color_chooser_;
     28 
     29   CHROMEGTK_CALLBACK_0(ColorChooserGtk, void, OnColorChooserOk);
     30   CHROMEGTK_CALLBACK_0(ColorChooserGtk, void, OnColorChooserCancel);
     31   CHROMEGTK_CALLBACK_0(ColorChooserGtk, void, OnColorChooserDestroy);
     32 
     33   // The web contents invoking the color chooser.  No ownership because it will
     34   // outlive this class.
     35   content::WebContents* web_contents_;
     36   GtkWidget* color_selection_dialog_;
     37 };
     38 
     39 ColorChooserGtk* ColorChooserGtk::current_color_chooser_ = NULL;
     40 
     41 ColorChooserGtk* ColorChooserGtk::Open(content::WebContents* web_contents,
     42                                        SkColor initial_color) {
     43   if (current_color_chooser_)
     44     current_color_chooser_->End();
     45   DCHECK(!current_color_chooser_);
     46   current_color_chooser_ = new ColorChooserGtk(web_contents, initial_color);
     47   return current_color_chooser_;
     48 }
     49 
     50 ColorChooserGtk::ColorChooserGtk(content::WebContents* web_contents,
     51                                  SkColor initial_color)
     52     : web_contents_(web_contents) {
     53   color_selection_dialog_ = gtk_color_selection_dialog_new(
     54       l10n_util::GetStringUTF8(IDS_SELECT_COLOR_DIALOG_TITLE).c_str());
     55   GtkWidget* cancel_button;
     56   GtkColorSelection* color_selection;
     57   GtkWidget* ok_button;
     58   g_object_get(color_selection_dialog_,
     59                "cancel-button", &cancel_button,
     60                "color-selection", &color_selection,
     61                "ok-button", &ok_button,
     62                NULL);
     63   gtk_color_selection_set_has_opacity_control(color_selection, FALSE);
     64   g_signal_connect(ok_button, "clicked",
     65                    G_CALLBACK(OnColorChooserOkThunk), this);
     66   g_signal_connect(cancel_button, "clicked",
     67                    G_CALLBACK(OnColorChooserCancelThunk), this);
     68   g_signal_connect(color_selection_dialog_, "destroy",
     69                    G_CALLBACK(OnColorChooserDestroyThunk), this);
     70   GdkColor gdk_color = gfx::SkColorToGdkColor(initial_color);
     71   gtk_color_selection_set_previous_color(color_selection, &gdk_color);
     72   gtk_color_selection_set_current_color(color_selection, &gdk_color);
     73   gtk_window_present(GTK_WINDOW(color_selection_dialog_));
     74   g_object_unref(cancel_button);
     75   g_object_unref(color_selection);
     76   g_object_unref(ok_button);
     77 }
     78 
     79 ColorChooserGtk::~ColorChooserGtk() {
     80   // Always call End() before destroying.
     81   DCHECK(!color_selection_dialog_);
     82 }
     83 
     84 void ColorChooserGtk::OnColorChooserOk(GtkWidget* widget) {
     85   GdkColor color;
     86   GtkColorSelection* color_selection;
     87   g_object_get(color_selection_dialog_,
     88                "color-selection", &color_selection, NULL);
     89   gtk_color_selection_get_current_color(color_selection, &color);
     90   if (web_contents_)
     91     web_contents_->DidChooseColorInColorChooser(gfx::GdkColorToSkColor(color));
     92   g_object_unref(color_selection);
     93   gtk_widget_destroy(color_selection_dialog_);
     94 }
     95 
     96 void ColorChooserGtk::OnColorChooserCancel(GtkWidget* widget) {
     97   gtk_widget_destroy(color_selection_dialog_);
     98 }
     99 
    100 void ColorChooserGtk::OnColorChooserDestroy(GtkWidget* widget) {
    101   color_selection_dialog_ = NULL;
    102   DCHECK(current_color_chooser_ == this);
    103   current_color_chooser_ = NULL;
    104   if (web_contents_)
    105     web_contents_->DidEndColorChooser();
    106 }
    107 
    108 void ColorChooserGtk::End() {
    109   if (!color_selection_dialog_)
    110     return;
    111 
    112   gtk_widget_destroy(color_selection_dialog_);
    113 }
    114 
    115 void ColorChooserGtk::SetSelectedColor(SkColor color) {
    116   if (!color_selection_dialog_)
    117     return;
    118 
    119   GdkColor gdk_color = gfx::SkColorToGdkColor(color);
    120   GtkColorSelection* color_selection;
    121   g_object_get(color_selection_dialog_,
    122                "color-selection", &color_selection, NULL);
    123   gtk_color_selection_set_previous_color(color_selection, &gdk_color);
    124   gtk_color_selection_set_current_color(color_selection, &gdk_color);
    125   g_object_unref(color_selection);
    126 }
    127 
    128 namespace chrome {
    129 
    130 content::ColorChooser* ShowColorChooser(content::WebContents* web_contents,
    131                                         SkColor initial_color) {
    132   return ColorChooserGtk::Open(web_contents, initial_color);
    133 }
    134 
    135 }  // namespace chrome
    136