зеркало из https://github.com/mozilla/gecko-dev.git
Bug 875754 - Implement <input type="color">: Windows widget/color picker. r=jimm
This commit is contained in:
Родитель
7ad2807a86
Коммит
244fc507ee
|
@ -41,6 +41,7 @@ CPP_SOURCES += [
|
|||
'nsAppShell.cpp',
|
||||
'nsBidiKeyboard.cpp',
|
||||
'nsClipboard.cpp',
|
||||
'nsColorPicker.cpp',
|
||||
'nsDataObj.cpp',
|
||||
'nsDataObjCollection.cpp',
|
||||
'nsDragService.cpp',
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/* -*- 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 "nsColorPicker.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include "nsIWidget.h"
|
||||
#include "WidgetUtils.h"
|
||||
|
||||
using namespace mozilla::widget;
|
||||
|
||||
namespace
|
||||
{
|
||||
// Manages NS_NATIVE_TMP_WINDOW child windows. NS_NATIVE_TMP_WINDOWs are
|
||||
// temporary child windows of mParentWidget created to address RTL issues
|
||||
// in picker dialogs. We are responsible for destroying these.
|
||||
class AutoDestroyTmpWindow
|
||||
{
|
||||
public:
|
||||
explicit AutoDestroyTmpWindow(HWND aTmpWnd) :
|
||||
mWnd(aTmpWnd) {
|
||||
}
|
||||
|
||||
~AutoDestroyTmpWindow() {
|
||||
if (mWnd)
|
||||
DestroyWindow(mWnd);
|
||||
}
|
||||
|
||||
inline HWND get() const { return mWnd; }
|
||||
private:
|
||||
HWND mWnd;
|
||||
};
|
||||
|
||||
static DWORD ColorStringToRGB(const nsAString& aColor)
|
||||
{
|
||||
DWORD result = 0;
|
||||
|
||||
for (uint32_t i = 1; i < aColor.Length(); ++i) {
|
||||
result *= 16;
|
||||
|
||||
PRUnichar c = aColor[i];
|
||||
if (c >= '0' && c <= '9') {
|
||||
result += c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
result += 10 + (c - 'a');
|
||||
} else {
|
||||
result += 10 + (c - 'A');
|
||||
}
|
||||
}
|
||||
|
||||
DWORD r = result & 0x00FF0000;
|
||||
DWORD g = result & 0x0000FF00;
|
||||
DWORD b = result & 0x000000FF;
|
||||
|
||||
r = r >> 16;
|
||||
b = b << 16;
|
||||
|
||||
result = r | g | b;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static nsString ToHexString(BYTE n)
|
||||
{
|
||||
nsString result;
|
||||
if (n <= 0x0F) {
|
||||
result.Append('0');
|
||||
}
|
||||
result.AppendInt(n, 16);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
BGRIntToRGBString(DWORD color, nsAString& aResult)
|
||||
{
|
||||
BYTE r = GetRValue(color);
|
||||
BYTE g = GetGValue(color);
|
||||
BYTE b = GetBValue(color);
|
||||
|
||||
aResult.AssignLiteral("#");
|
||||
aResult.Append(ToHexString(r));
|
||||
aResult.Append(ToHexString(g));
|
||||
aResult.Append(ToHexString(b));
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
AsyncColorChooser::AsyncColorChooser(DWORD aInitialColor, nsIWidget* aParentWidget, nsIColorPickerShownCallback* aCallback)
|
||||
: mInitialColor(aInitialColor)
|
||||
, mParentWidget(aParentWidget)
|
||||
, mCallback(aCallback)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncColorChooser::Run()
|
||||
{
|
||||
CHOOSECOLOR options;
|
||||
static COLORREF customColors[16] = {0} ;
|
||||
|
||||
AutoDestroyTmpWindow adtw((HWND) (mParentWidget.get() ?
|
||||
mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : NULL));
|
||||
|
||||
options.lStructSize = sizeof(options);
|
||||
options.hwndOwner = adtw.get();
|
||||
options.Flags = CC_RGBINIT | CC_FULLOPEN;
|
||||
options.rgbResult = mInitialColor;
|
||||
options.lpCustColors = customColors;
|
||||
|
||||
if (ChooseColor(&options)) {
|
||||
BGRIntToRGBString(options.rgbResult, mColor);
|
||||
}
|
||||
|
||||
if (mCallback) {
|
||||
mCallback->Done(mColor);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIColorPicker
|
||||
|
||||
nsColorPicker::nsColorPicker()
|
||||
{
|
||||
}
|
||||
|
||||
nsColorPicker::~nsColorPicker()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsColorPicker, nsIColorPicker)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsColorPicker::Init(nsIDOMWindow* parent, const nsAString& title, const nsAString& aInitialColor)
|
||||
{
|
||||
NS_PRECONDITION(parent,
|
||||
"Null parent passed to colorpicker, no color picker for you!");
|
||||
mParentWidget = WidgetUtils::DOMWindowToWidget(parent);
|
||||
mInitialColor = ColorStringToRGB(aInitialColor);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsColorPicker::Open(nsIColorPickerShownCallback* aCallback)
|
||||
{
|
||||
NS_ENSURE_ARG(aCallback);
|
||||
nsCOMPtr<nsIRunnable> event = new AsyncColorChooser(mInitialColor, mParentWidget, aCallback);
|
||||
return NS_DispatchToMainThread(event);
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- 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 <windows.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIColorPicker.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
class AsyncColorChooser :
|
||||
public nsRunnable
|
||||
{
|
||||
public:
|
||||
AsyncColorChooser(DWORD aInitialColor, nsIWidget* aParentWidget, nsIColorPickerShownCallback* aCallback);
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
DWORD mInitialColor;
|
||||
nsCOMPtr<nsIWidget> mParentWidget;
|
||||
nsCOMPtr<nsIColorPickerShownCallback> mCallback;
|
||||
nsString mColor;
|
||||
};
|
||||
|
||||
class nsColorPicker :
|
||||
public nsIColorPicker
|
||||
{
|
||||
public:
|
||||
nsColorPicker();
|
||||
virtual ~nsColorPicker();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init(nsIDOMWindow* parent, const nsAString& title, const nsAString& aInitialColor);
|
||||
NS_IMETHOD Open(nsIColorPickerShownCallback* aCallback);
|
||||
|
||||
protected:
|
||||
DWORD mInitialColor;
|
||||
nsCOMPtr<nsIWidget> mParentWidget;
|
||||
};
|
||||
|
||||
#endif // nsColorPicker_h__
|
|
@ -25,6 +25,7 @@
|
|||
#include "nsXULAppAPI.h"
|
||||
// Desktop
|
||||
#include "nsFilePicker.h" // needs to be included before other shobjidl.h includes
|
||||
#include "nsColorPicker.h"
|
||||
#include "nsNativeThemeWin.h"
|
||||
#include "nsWindow.h"
|
||||
// Content processes
|
||||
|
@ -125,6 +126,31 @@ FilePickerConstructor(nsISupports *aOuter, REFNSIID aIID,
|
|||
return picker->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ColorPickerConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
if (aOuter != nullptr) {
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
nsCOMPtr<nsIColorPicker> picker;
|
||||
|
||||
if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro) {
|
||||
#ifdef MOZ_METRO
|
||||
// TODO
|
||||
// picker = new nsMetroColorPicker;
|
||||
NS_ERROR("metro color picker isn't implemented currently");
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
#else
|
||||
NS_RUNTIMEABORT("build does not support metro.");
|
||||
#endif
|
||||
} else {
|
||||
picker = new nsColorPicker;
|
||||
}
|
||||
return picker->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerWin)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceWin, nsIdleServiceWin::GetInstance)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
|
||||
|
@ -160,6 +186,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init)
|
|||
NS_DEFINE_NAMED_CID(NS_WINDOW_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CHILD_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
|
||||
|
@ -193,6 +220,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
|||
{ &kNS_WINDOW_CID, false, NULL, WindowConstructor },
|
||||
{ &kNS_CHILD_CID, false, NULL, ChildWindowConstructor },
|
||||
{ &kNS_FILEPICKER_CID, false, NULL, FilePickerConstructor },
|
||||
{ &kNS_COLORPICKER_CID, false, NULL, ColorPickerConstructor },
|
||||
{ &kNS_APPSHELL_CID, false, NULL, nsAppShellConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerWinConstructor },
|
||||
{ &kNS_GFXINFO_CID, false, NULL, GfxInfoConstructor },
|
||||
|
@ -227,6 +255,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
|||
{ "@mozilla.org/widgets/window/win;1", &kNS_WINDOW_CID },
|
||||
{ "@mozilla.org/widgets/child_window/win;1", &kNS_CHILD_CID },
|
||||
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID },
|
||||
{ "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID },
|
||||
{ "@mozilla.org/widget/appshell/win;1", &kNS_APPSHELL_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
|
||||
{ "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
|
||||
|
|
Загрузка…
Ссылка в новой задаче