mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-12 09:01:16 +00:00
Bug 875753 - Color input: Gtk widget. r=karlt
This commit is contained in:
parent
fd8eb7c308
commit
70bdf3b468
@ -91,10 +91,10 @@ static int ComponentValue(const PRUnichar* aColorSpec, int aLen, int color, int
|
||||
return component;
|
||||
}
|
||||
|
||||
NS_GFX_(bool) NS_HexToRGB(const nsString& aColorSpec,
|
||||
NS_GFX_(bool) NS_HexToRGB(const nsAString& aColorSpec,
|
||||
nscolor* aResult)
|
||||
{
|
||||
const PRUnichar* buffer = aColorSpec.get();
|
||||
const PRUnichar* buffer = aColorSpec.BeginReading();
|
||||
|
||||
int nameLen = aColorSpec.Length();
|
||||
if ((nameLen == 3) || (nameLen == 6)) {
|
||||
|
@ -48,7 +48,7 @@ typedef uint32_t nscolor;
|
||||
// Translate a hex string to a color. Return true if it parses ok,
|
||||
// otherwise return false.
|
||||
// This accepts only 3 or 6 digits
|
||||
NS_GFX_(bool) NS_HexToRGB(const nsString& aBuf, nscolor* aResult);
|
||||
NS_GFX_(bool) NS_HexToRGB(const nsAString& aBuf, nscolor* aResult);
|
||||
|
||||
// Compose one NS_RGB color onto another. The result is what
|
||||
// you get if you draw aFG on top of aBG with operator OVER.
|
||||
|
17
widget/gtk2/compat/gtk/gtkcolorselectiondialog.h
Normal file
17
widget/gtk2/compat/gtk/gtkcolorselectiondialog.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef GTKCOLORSELECTIONDIALOG_WRAPPER_H
|
||||
#define GTKCOLORSELECTIONDIALOG_WRAPPER_H
|
||||
|
||||
#include_next <gtk/gtkselection.h>
|
||||
#include <gtk/gtkversion.h>
|
||||
|
||||
#if !GTK_CHECK_VERSION(2, 14, 0)
|
||||
static inline GtkWidget*
|
||||
gtk_color_selection_dialog_get_color_selection(GtkColorSelectionDialog* colorseldialog)
|
||||
{
|
||||
GtkWidget* colorsel;
|
||||
g_object_get(colorseldialog, "color-selection", &colorsel, NULL);
|
||||
return colorsel;
|
||||
}
|
||||
#endif // GTK_CHECK_VERSION
|
||||
|
||||
#endif // GTKCOLORSELECTIONDIALOG_WRAPPER_H
|
@ -16,6 +16,7 @@ CPP_SOURCES += [
|
||||
'WidgetTraceEvent.cpp',
|
||||
'nsAppShell.cpp',
|
||||
'nsBidiKeyboard.cpp',
|
||||
'nsColorPicker.cpp',
|
||||
'nsFilePicker.cpp',
|
||||
'nsGtkIMModule.cpp',
|
||||
'nsGtkKeyUtils.cpp',
|
||||
|
161
widget/gtk2/nsColorPicker.cpp
Normal file
161
widget/gtk2/nsColorPicker.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsColorPicker.h"
|
||||
#include "nsGtkUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "WidgetUtils.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsColorPicker, nsIColorPicker)
|
||||
|
||||
int nsColorPicker::convertGdkColorComponent(guint16 color_component) {
|
||||
// GdkColor value is in range [0..65535]. We need something in range [0..255]
|
||||
return (int(color_component)*255 + 127)/65535;
|
||||
}
|
||||
|
||||
guint16 nsColorPicker::convertToGdkColorComponent(int color_component) {
|
||||
return color_component*65535/255;
|
||||
}
|
||||
|
||||
GdkColor nsColorPicker::convertToGdkColor(nscolor color) {
|
||||
GdkColor result = { 0 /* obsolete, unused 'pixel' value */,
|
||||
convertToGdkColorComponent(NS_GET_R(color)),
|
||||
convertToGdkColorComponent(NS_GET_G(color)),
|
||||
convertToGdkColorComponent(NS_GET_B(color)) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* void init (in nsIDOMWindow parent, in AString title, in short mode); */
|
||||
NS_IMETHODIMP nsColorPicker::Init(nsIDOMWindow *parent,
|
||||
const nsAString& title,
|
||||
const nsAString& initialColor)
|
||||
{
|
||||
// Input color string should be 7 length (i.e. a string representing a valid
|
||||
// simple color)
|
||||
if (initialColor.Length() != 7) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const nsAString& withoutHash = StringTail(initialColor, 6);
|
||||
nscolor color;
|
||||
if (!NS_HexToRGB(withoutHash, &color)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mDefaultColor = convertToGdkColor(color);
|
||||
|
||||
mParentWidget = mozilla::widget::WidgetUtils::DOMWindowToWidget(parent);
|
||||
mTitle.Assign(title);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void open (in nsIColorPickerShownCallback aColorPickerShownCallback); */
|
||||
NS_IMETHODIMP nsColorPicker::Open(nsIColorPickerShownCallback *aColorPickerShownCallback)
|
||||
{
|
||||
if (mCallback) {
|
||||
// It means Open has already been called: this is not allowed
|
||||
NS_WARNING("mCallback is already set. Open called twice?");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mCallback = aColorPickerShownCallback;
|
||||
|
||||
nsXPIDLCString title;
|
||||
title.Adopt(ToNewUTF8String(mTitle));
|
||||
GtkWidget *color_chooser = gtk_color_selection_dialog_new(title);
|
||||
|
||||
GtkWindow *parent_window = GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
|
||||
if (parent_window) {
|
||||
GtkWindow *window = GTK_WINDOW(color_chooser);
|
||||
gtk_window_set_transient_for(window, parent_window);
|
||||
gtk_window_set_destroy_with_parent(window, TRUE);
|
||||
}
|
||||
|
||||
gtk_color_selection_set_current_color(
|
||||
GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(
|
||||
GTK_COLOR_SELECTION_DIALOG(color_chooser))),
|
||||
&mDefaultColor);
|
||||
|
||||
NS_ADDREF_THIS();
|
||||
g_signal_connect(color_chooser, "response", G_CALLBACK(OnResponse), this);
|
||||
g_signal_connect(color_chooser, "destroy", G_CALLBACK(OnDestroy), this);
|
||||
gtk_widget_show(color_chooser);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsColorPicker::OnResponse(GtkWidget* color_chooser, gint response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
static_cast<nsColorPicker*>(user_data)->
|
||||
Done(color_chooser, response_id);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsColorPicker::OnDestroy(GtkWidget* color_chooser, gpointer user_data)
|
||||
{
|
||||
static_cast<nsColorPicker*>(user_data)->
|
||||
Done(color_chooser, GTK_RESPONSE_CANCEL);
|
||||
}
|
||||
|
||||
void
|
||||
nsColorPicker::Done(GtkWidget* color_chooser, gint response)
|
||||
{
|
||||
switch (response) {
|
||||
case GTK_RESPONSE_OK:
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
ReadValueFromColorChooser(color_chooser);
|
||||
break;
|
||||
case GTK_RESPONSE_CANCEL:
|
||||
case GTK_RESPONSE_CLOSE:
|
||||
case GTK_RESPONSE_DELETE_EVENT:
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Unexpected response");
|
||||
break;
|
||||
}
|
||||
|
||||
// A "response" signal won't be sent again but "destroy" will be.
|
||||
g_signal_handlers_disconnect_by_func(color_chooser,
|
||||
FuncToGpointer(OnDestroy), this);
|
||||
|
||||
gtk_widget_destroy(color_chooser);
|
||||
if (mCallback) {
|
||||
mCallback->Done(mColor);
|
||||
mCallback = nullptr;
|
||||
}
|
||||
|
||||
NS_RELEASE_THIS();
|
||||
}
|
||||
|
||||
nsString nsColorPicker::ToHexString(int n)
|
||||
{
|
||||
nsString result;
|
||||
if (n <= 0x0F) {
|
||||
result.Append('0');
|
||||
}
|
||||
result.AppendInt(n, 16);
|
||||
return result;
|
||||
}
|
||||
|
||||
void nsColorPicker::ReadValueFromColorChooser(GtkWidget* color_chooser)
|
||||
{
|
||||
GdkColor rgba;
|
||||
gtk_color_selection_get_current_color(
|
||||
GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(
|
||||
GTK_COLOR_SELECTION_DIALOG(color_chooser))),
|
||||
&rgba);
|
||||
|
||||
mColor.AssignLiteral("#");
|
||||
mColor += ToHexString(convertGdkColorComponent(rgba.red));
|
||||
mColor += ToHexString(convertGdkColorComponent(rgba.green));
|
||||
mColor += ToHexString(convertGdkColorComponent(rgba.blue));
|
||||
}
|
48
widget/gtk2/nsColorPicker.h
Normal file
48
widget/gtk2/nsColorPicker.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsColorPicker_h__
|
||||
#define nsColorPicker_h__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIColorPicker.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
class nsColorPicker : public nsIColorPicker
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICOLORPICKER
|
||||
|
||||
nsColorPicker() {};
|
||||
|
||||
private:
|
||||
~nsColorPicker() {};
|
||||
|
||||
static void OnResponse(GtkWidget* dialog, gint response_id,
|
||||
gpointer user_data);
|
||||
static void OnDestroy(GtkWidget* dialog, gpointer user_data);
|
||||
|
||||
// Conversion functions for color
|
||||
static int convertGdkColorComponent(guint16 color_component);
|
||||
static guint16 convertToGdkColorComponent(int color_component);
|
||||
static GdkColor convertToGdkColor(nscolor color);
|
||||
static nsString ToHexString(int n);
|
||||
|
||||
void Done(GtkWidget* dialog, gint response_id);
|
||||
void ReadValueFromColorChooser(GtkWidget* color_chooser);
|
||||
|
||||
nsCOMPtr<nsIWidget> mParentWidget;
|
||||
nsCOMPtr<nsIColorPickerShownCallback> mCallback;
|
||||
nsString mTitle;
|
||||
nsString mColor;
|
||||
GdkColor mDefaultColor;
|
||||
};
|
||||
|
||||
#endif // nsColorPicker_h__
|
@ -33,6 +33,7 @@
|
||||
#include "nsISelection.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsGtkUtils.h"
|
||||
|
||||
// This sets how opaque the drag image is
|
||||
#define DRAG_IMAGE_ALPHA_LEVEL 0.5
|
||||
@ -46,17 +47,6 @@ enum {
|
||||
MOZ_GTK_DRAG_RESULT_NO_TARGET
|
||||
};
|
||||
|
||||
// Some gobject functions expect functions for gpointer arguments.
|
||||
// gpointer is void* but C++ doesn't like casting functions to void*.
|
||||
template<class T> static inline gpointer
|
||||
FuncToGpointer(T aFunction)
|
||||
{
|
||||
return reinterpret_cast<gpointer>
|
||||
(reinterpret_cast<uintptr_t>
|
||||
// This cast just provides a warning if T is not a function.
|
||||
(reinterpret_cast<void (*)()>(aFunction)));
|
||||
}
|
||||
|
||||
static PRLogModuleInfo *sDragLm = NULL;
|
||||
|
||||
// data used for synthetic periodic motion events sent to the source widget
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "nsGtkUtils.h"
|
||||
#include "nsIFileURL.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWidget.h"
|
||||
@ -32,17 +33,6 @@ using namespace mozilla;
|
||||
|
||||
nsIFile *nsFilePicker::mPrevDisplayDirectory = nullptr;
|
||||
|
||||
// Some GObject functions expect functions for gpointer arguments.
|
||||
// gpointer is void* but C++ doesn't like casting functions to void*.
|
||||
template<class T> static inline gpointer
|
||||
FuncToGpointer(T aFunction)
|
||||
{
|
||||
return reinterpret_cast<gpointer>
|
||||
(reinterpret_cast<uintptr_t>
|
||||
// This cast just provides a warning if T is not a function.
|
||||
(reinterpret_cast<void (*)()>(aFunction)));
|
||||
}
|
||||
|
||||
void
|
||||
nsFilePicker::Shutdown()
|
||||
{
|
||||
|
24
widget/gtk2/nsGtkUtils.h
Normal file
24
widget/gtk2/nsGtkUtils.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsGtkUtils_h__
|
||||
#define nsGtkUtils_h__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
// Some gobject functions expect functions for gpointer arguments.
|
||||
// gpointer is void* but C++ doesn't like casting functions to void*.
|
||||
template<class T> static inline gpointer
|
||||
FuncToGpointer(T aFunction)
|
||||
{
|
||||
return reinterpret_cast<gpointer>
|
||||
(reinterpret_cast<uintptr_t>
|
||||
// This cast just provides a warning if T is not a function.
|
||||
(reinterpret_cast<void (*)()>(aFunction)));
|
||||
}
|
||||
|
||||
#endif // nsGtkUtils_h__
|
@ -19,6 +19,7 @@
|
||||
#include "nsClipboard.h"
|
||||
#include "nsDragService.h"
|
||||
#endif
|
||||
#include "nsColorPicker.h"
|
||||
#include "nsFilePicker.h"
|
||||
#include "nsSound.h"
|
||||
#include "nsBidiKeyboard.h"
|
||||
@ -152,6 +153,24 @@ nsFilePickerConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
return picker->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
nsColorPickerConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
if (aOuter != nullptr) {
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIColorPicker> picker = new nsColorPicker;
|
||||
|
||||
if (!picker) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return picker->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
nsNativeKeyBindingsConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult,
|
||||
@ -199,6 +218,7 @@ nsNativeKeyBindingsTextAreaConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
NS_DEFINE_NAMED_CID(NS_WINDOW_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CHILD_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SOUND_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID);
|
||||
@ -234,6 +254,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_WINDOW_CID, false, NULL, nsWindowConstructor },
|
||||
{ &kNS_CHILD_CID, false, NULL, nsChildWindowConstructor },
|
||||
{ &kNS_APPSHELL_CID, false, NULL, nsAppShellConstructor },
|
||||
{ &kNS_COLORPICKER_CID, false, NULL, nsColorPickerConstructor },
|
||||
{ &kNS_FILEPICKER_CID, false, NULL, nsFilePickerConstructor },
|
||||
{ &kNS_SOUND_CID, false, NULL, nsSoundConstructor },
|
||||
{ &kNS_TRANSFERABLE_CID, false, NULL, nsTransferableConstructor },
|
||||
@ -270,6 +291,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/widget/window/gtk;1", &kNS_WINDOW_CID },
|
||||
{ "@mozilla.org/widgets/child_window/gtk;1", &kNS_CHILD_CID },
|
||||
{ "@mozilla.org/widget/appshell/gtk;1", &kNS_APPSHELL_CID },
|
||||
{ "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID },
|
||||
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID },
|
||||
{ "@mozilla.org/sound;1", &kNS_SOUND_CID },
|
||||
{ "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID },
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsGtkUtils.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "nsIIdleServiceInternal.h"
|
||||
@ -283,17 +284,6 @@ static GtkWidget *gInvisibleContainer = NULL;
|
||||
// only the button state bits are used.
|
||||
static guint gButtonState;
|
||||
|
||||
// Some gobject functions expect functions for gpointer arguments.
|
||||
// gpointer is void* but C++ doesn't like casting functions to void*.
|
||||
template<class T> static inline gpointer
|
||||
FuncToGpointer(T aFunction)
|
||||
{
|
||||
return reinterpret_cast<gpointer>
|
||||
(reinterpret_cast<uintptr_t>
|
||||
// This cast just provides a warning if T is not a function.
|
||||
(reinterpret_cast<void (*)()>(aFunction)));
|
||||
}
|
||||
|
||||
// nsAutoRef<pixman_region32> uses nsSimpleRef<> to know how to automatically
|
||||
// destroy regions.
|
||||
template <>
|
||||
|
Loading…
Reference in New Issue
Block a user