widget/gtk/nsColorPicker.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include <gtk/gtk.h>
     8 #include "nsColor.h"
     9 #include "nsColorPicker.h"
    10 #include "nsGtkUtils.h"
    11 #include "nsIWidget.h"
    12 #include "WidgetUtils.h"
    14 NS_IMPL_ISUPPORTS(nsColorPicker, nsIColorPicker)
    16 int nsColorPicker::convertGdkColorComponent(guint16 color_component) {
    17   // GdkColor value is in range [0..65535]. We need something in range [0..255]
    18   return (color_component * 255 + 127) / 65535;
    19 }
    21 guint16 nsColorPicker::convertToGdkColorComponent(int color_component) {
    22   return color_component * 65535 / 255;
    23 }
    25 GdkColor nsColorPicker::convertToGdkColor(nscolor color) {
    26   GdkColor result = { 0 /* obsolete, unused 'pixel' value */,
    27       convertToGdkColorComponent(NS_GET_R(color)),
    28       convertToGdkColorComponent(NS_GET_G(color)),
    29       convertToGdkColorComponent(NS_GET_B(color)) };
    31   return result;
    32 }
    34 GtkColorSelection* nsColorPicker::WidgetGetColorSelection(GtkWidget* widget)
    35 {
    36   return GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(
    37                              GTK_COLOR_SELECTION_DIALOG(widget)));
    38 }
    40 /* void init (in nsIDOMWindow parent, in AString title, in short mode); */
    41 NS_IMETHODIMP nsColorPicker::Init(nsIDOMWindow *parent,
    42                                   const nsAString& title,
    43                                   const nsAString& initialColor)
    44 {
    45   mParentWidget = mozilla::widget::WidgetUtils::DOMWindowToWidget(parent);
    46   mTitle = title;
    47   mInitialColor = initialColor;
    49   return NS_OK;
    50 }
    52 /* void open (in nsIColorPickerShownCallback aColorPickerShownCallback); */
    53 NS_IMETHODIMP nsColorPicker::Open(nsIColorPickerShownCallback *aColorPickerShownCallback)
    54 {
    56   // Input color string should be 7 length (i.e. a string representing a valid
    57   // simple color)
    58   if (mInitialColor.Length() != 7) {
    59     return NS_ERROR_FAILURE;
    60   }
    62   const nsAString& withoutHash  = StringTail(mInitialColor, 6);
    63   nscolor color;
    64   if (!NS_HexToRGB(withoutHash, &color)) {
    65     return NS_ERROR_FAILURE;
    66   }
    68   GdkColor color_gdk = convertToGdkColor(color);
    70   if (mCallback) {
    71     // It means Open has already been called: this is not allowed
    72     NS_WARNING("mCallback is already set. Open called twice?");
    73     return NS_ERROR_FAILURE;
    74   }
    75   mCallback = aColorPickerShownCallback;
    77   nsXPIDLCString title;
    78   title.Adopt(ToNewUTF8String(mTitle));
    79   GtkWidget *color_chooser = gtk_color_selection_dialog_new(title);
    81   GtkWindow *parent_window = GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
    82   if (parent_window) {
    83     GtkWindow *window = GTK_WINDOW(color_chooser);
    84     gtk_window_set_transient_for(window, parent_window);
    85     gtk_window_set_destroy_with_parent(window, TRUE);
    86   }
    88   gtk_color_selection_set_current_color(WidgetGetColorSelection(color_chooser),
    89                                         &color_gdk);
    91   NS_ADDREF_THIS();
    92   g_signal_connect(WidgetGetColorSelection(color_chooser), "color-changed",
    93                    G_CALLBACK(OnColorChanged), this);
    94   g_signal_connect(color_chooser, "response", G_CALLBACK(OnResponse), this);
    95   g_signal_connect(color_chooser, "destroy", G_CALLBACK(OnDestroy), this);
    96   gtk_widget_show(color_chooser);
    98   return NS_OK;
    99 }
   101 /* static */ void
   102 nsColorPicker::OnColorChanged(GtkColorSelection* colorselection,
   103                               gpointer user_data)
   104 {
   105   static_cast<nsColorPicker*>(user_data)->Update(colorselection);
   106 }
   108 /* static */ void
   109 nsColorPicker::OnResponse(GtkWidget* color_chooser, gint response_id,
   110                           gpointer user_data)
   111 {
   112   static_cast<nsColorPicker*>(user_data)->
   113     Done(color_chooser, response_id);
   114 }
   116 /* static */ void
   117 nsColorPicker::OnDestroy(GtkWidget* color_chooser, gpointer user_data)
   118 {
   119   static_cast<nsColorPicker*>(user_data)->
   120     Done(color_chooser, GTK_RESPONSE_CANCEL);
   121 }
   123 void
   124 nsColorPicker::Update(GtkColorSelection* colorselection)
   125 {
   126   ReadValueFromColorSelection(colorselection);
   127   if (mCallback) {
   128     mCallback->Update(mColor);
   129   }
   130 }
   132 void
   133 nsColorPicker::Done(GtkWidget* color_chooser, gint response)
   134 {
   135   switch (response) {
   136     case GTK_RESPONSE_OK:
   137     case GTK_RESPONSE_ACCEPT:
   138       ReadValueFromColorSelection(WidgetGetColorSelection(color_chooser));
   139       break;
   140     case GTK_RESPONSE_CANCEL:
   141     case GTK_RESPONSE_CLOSE:
   142     case GTK_RESPONSE_DELETE_EVENT:
   143       mColor = mInitialColor;
   144       break;
   145     default:
   146       NS_WARNING("Unexpected response");
   147       break;
   148   }
   150   // A "response" signal won't be sent again but "destroy" will be.
   151   g_signal_handlers_disconnect_by_func(color_chooser,
   152                                        FuncToGpointer(OnDestroy), this);
   154   gtk_widget_destroy(color_chooser);
   155   if (mCallback) {
   156     mCallback->Done(mColor);
   157     mCallback = nullptr;
   158   }
   160   NS_RELEASE_THIS();
   161 }
   163 nsString nsColorPicker::ToHexString(int n)
   164 {
   165   nsString result;
   166   if (n <= 0x0F) {
   167     result.Append('0');
   168   }
   169   result.AppendInt(n, 16);
   170   return result;
   171 }
   173 void nsColorPicker::ReadValueFromColorSelection(GtkColorSelection* colorselection)
   174 {
   175   GdkColor rgba;
   176   gtk_color_selection_get_current_color(colorselection, &rgba);
   178   mColor.AssignLiteral("#");
   179   mColor += ToHexString(convertGdkColorComponent(rgba.red));
   180   mColor += ToHexString(convertGdkColorComponent(rgba.green));
   181   mColor += ToHexString(convertGdkColorComponent(rgba.blue));
   182 }

mercurial