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/. */
8 #include "mozilla/Util.h"
10 #include "nsColorPicker.h"
11 #include "nsGtkUtils.h"
12 #include "nsIWidget.h"
13 #include "WidgetUtils.h"
15 NS_IMPL_ISUPPORTS1(nsColorPicker
, nsIColorPicker
)
17 int nsColorPicker::convertGdkColorComponent(guint16 color_component
) {
18 // GdkColor value is in range [0..65535]. We need something in range [0..255]
19 return (int(color_component
)*255 + 127)/65535;
22 guint16
nsColorPicker::convertToGdkColorComponent(int color_component
) {
23 return color_component
*65535/255;
26 GdkColor
nsColorPicker::convertToGdkColor(nscolor color
) {
27 GdkColor result
= { 0 /* obsolete, unused 'pixel' value */,
28 convertToGdkColorComponent(NS_GET_R(color
)),
29 convertToGdkColorComponent(NS_GET_G(color
)),
30 convertToGdkColorComponent(NS_GET_B(color
)) };
35 /* void init (in nsIDOMWindow parent, in AString title, in short mode); */
36 NS_IMETHODIMP
nsColorPicker::Init(nsIDOMWindow
*parent
,
37 const nsAString
& title
,
38 const nsAString
& initialColor
)
40 // Input color string should be 7 length (i.e. a string representing a valid
42 if (initialColor
.Length() != 7) {
43 return NS_ERROR_INVALID_ARG
;
46 const nsAString
& withoutHash
= StringTail(initialColor
, 6);
48 if (!NS_HexToRGB(withoutHash
, &color
)) {
49 return NS_ERROR_INVALID_ARG
;
52 mDefaultColor
= convertToGdkColor(color
);
54 mParentWidget
= mozilla::widget::WidgetUtils::DOMWindowToWidget(parent
);
60 /* void open (in nsIColorPickerShownCallback aColorPickerShownCallback); */
61 NS_IMETHODIMP
nsColorPicker::Open(nsIColorPickerShownCallback
*aColorPickerShownCallback
)
64 // It means Open has already been called: this is not allowed
65 NS_WARNING("mCallback is already set. Open called twice?");
66 return NS_ERROR_FAILURE
;
68 mCallback
= aColorPickerShownCallback
;
71 title
.Adopt(ToNewUTF8String(mTitle
));
72 GtkWidget
*color_chooser
= gtk_color_selection_dialog_new(title
);
74 GtkWindow
*window
= GTK_WINDOW(color_chooser
);
75 gtk_window_set_modal(window
, TRUE
);
77 GtkWindow
*parent_window
= GTK_WINDOW(mParentWidget
->GetNativeData(NS_NATIVE_SHELLWIDGET
));
79 gtk_window_set_transient_for(window
, parent_window
);
80 gtk_window_set_destroy_with_parent(window
, TRUE
);
83 gtk_color_selection_set_current_color(
84 GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(
85 GTK_COLOR_SELECTION_DIALOG(color_chooser
))),
89 g_signal_connect(color_chooser
, "response", G_CALLBACK(OnResponse
), this);
90 g_signal_connect(color_chooser
, "destroy", G_CALLBACK(OnDestroy
), this);
91 gtk_widget_show(color_chooser
);
97 nsColorPicker::OnResponse(GtkWidget
* color_chooser
, gint response_id
,
100 static_cast<nsColorPicker
*>(user_data
)->
101 Done(color_chooser
, response_id
);
105 nsColorPicker::OnDestroy(GtkWidget
* color_chooser
, gpointer user_data
)
107 static_cast<nsColorPicker
*>(user_data
)->
108 Done(color_chooser
, GTK_RESPONSE_CANCEL
);
112 nsColorPicker::Done(GtkWidget
* color_chooser
, gint response
)
115 case GTK_RESPONSE_OK
:
116 case GTK_RESPONSE_ACCEPT
:
117 ReadValueFromColorChooser(color_chooser
);
119 case GTK_RESPONSE_CANCEL
:
120 case GTK_RESPONSE_CLOSE
:
121 case GTK_RESPONSE_DELETE_EVENT
:
124 NS_WARNING("Unexpected response");
128 // A "response" signal won't be sent again but "destroy" will be.
129 g_signal_handlers_disconnect_by_func(color_chooser
,
130 FuncToGpointer(OnDestroy
), this);
132 gtk_widget_destroy(color_chooser
);
134 mCallback
->Done(mColor
);
141 nsString
nsColorPicker::ToHexString(int n
)
147 result
.AppendInt(n
, 16);
151 void nsColorPicker::ReadValueFromColorChooser(GtkWidget
* color_chooser
)
154 gtk_color_selection_get_current_color(
155 GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(
156 GTK_COLOR_SELECTION_DIALOG(color_chooser
))),
159 mColor
.AssignLiteral("#");
160 mColor
+= ToHexString(convertGdkColorComponent(rgba
.red
));
161 mColor
+= ToHexString(convertGdkColorComponent(rgba
.green
));
162 mColor
+= ToHexString(convertGdkColorComponent(rgba
.blue
));