mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 935508 - Implement native theming of <input type=number>. r=roc
This commit is contained in:
parent
51ac041bbf
commit
37febbd150
@ -3314,6 +3314,8 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||||||
nsNumberControlFrame* numberControlFrame =
|
nsNumberControlFrame* numberControlFrame =
|
||||||
do_QueryFrame(GetPrimaryFrame());
|
do_QueryFrame(GetPrimaryFrame());
|
||||||
if (numberControlFrame) {
|
if (numberControlFrame) {
|
||||||
|
bool oldNumberControlSpinTimerSpinsUpValue =
|
||||||
|
mNumberControlSpinnerSpinsUp;
|
||||||
switch (numberControlFrame->GetSpinButtonForPointerEvent(
|
switch (numberControlFrame->GetSpinButtonForPointerEvent(
|
||||||
aVisitor.mEvent->AsMouseEvent())) {
|
aVisitor.mEvent->AsMouseEvent())) {
|
||||||
case nsNumberControlFrame::eSpinButtonUp:
|
case nsNumberControlFrame::eSpinButtonUp:
|
||||||
@ -3325,6 +3327,14 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||||||
stopSpin = false;
|
stopSpin = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (mNumberControlSpinnerSpinsUp !=
|
||||||
|
oldNumberControlSpinTimerSpinsUpValue) {
|
||||||
|
nsNumberControlFrame* numberControlFrame =
|
||||||
|
do_QueryFrame(GetPrimaryFrame());
|
||||||
|
if (numberControlFrame) {
|
||||||
|
numberControlFrame->SpinnerStateChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (stopSpin) {
|
if (stopSpin) {
|
||||||
StopNumberControlSpinnerSpin();
|
StopNumberControlSpinnerSpin();
|
||||||
@ -3346,6 +3356,15 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||||||
numberControlFrame->HandleFocusEvent(aVisitor.mEvent);
|
numberControlFrame->HandleFocusEvent(aVisitor.mEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (frame->IsThemed()) {
|
||||||
|
// Our frame's nested <input type=text> will be invalidated when it
|
||||||
|
// loses focus, but since we are also native themed we need to make
|
||||||
|
// sure that our entire area is repainted since any focus highlight
|
||||||
|
// from the theme should be removed from us (the repainting of the
|
||||||
|
// sub-area occupied by the anon text control is not enough to do
|
||||||
|
// that).
|
||||||
|
frame->InvalidateFrame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (aVisitor.mEvent->message == NS_KEY_UP) {
|
} else if (aVisitor.mEvent->message == NS_KEY_UP) {
|
||||||
WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent();
|
WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent();
|
||||||
@ -3497,6 +3516,12 @@ HTMLInputElement::StartNumberControlSpinnerSpin()
|
|||||||
// Capture the mouse so that we can tell if the pointer moves from one
|
// Capture the mouse so that we can tell if the pointer moves from one
|
||||||
// spin button to the other, or to some other element:
|
// spin button to the other, or to some other element:
|
||||||
nsIPresShell::SetCapturingContent(this, CAPTURE_IGNOREALLOWED);
|
nsIPresShell::SetCapturingContent(this, CAPTURE_IGNOREALLOWED);
|
||||||
|
|
||||||
|
nsNumberControlFrame* numberControlFrame =
|
||||||
|
do_QueryFrame(GetPrimaryFrame());
|
||||||
|
if (numberControlFrame) {
|
||||||
|
numberControlFrame->SpinnerStateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3512,6 +3537,12 @@ HTMLInputElement::StopNumberControlSpinnerSpin()
|
|||||||
mNumberControlSpinnerIsSpinning = false;
|
mNumberControlSpinnerIsSpinning = false;
|
||||||
|
|
||||||
FireChangeEventIfNeeded();
|
FireChangeEventIfNeeded();
|
||||||
|
|
||||||
|
nsNumberControlFrame* numberControlFrame =
|
||||||
|
do_QueryFrame(GetPrimaryFrame());
|
||||||
|
if (numberControlFrame) {
|
||||||
|
numberControlFrame->SpinnerStateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,6 +688,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void HandleNumberControlSpin(void* aData);
|
static void HandleNumberControlSpin(void* aData);
|
||||||
|
|
||||||
|
bool NumberSpinnerUpButtonIsDepressed() const
|
||||||
|
{
|
||||||
|
return mNumberControlSpinnerIsSpinning && mNumberControlSpinnerSpinsUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NumberSpinnerDownButtonIsDepressed() const
|
||||||
|
{
|
||||||
|
return mNumberControlSpinnerIsSpinning && !mNumberControlSpinnerSpinsUp;
|
||||||
|
}
|
||||||
|
|
||||||
bool MozIsTextField(bool aExcludePassword);
|
bool MozIsTextField(bool aExcludePassword);
|
||||||
|
|
||||||
nsIEditor* GetEditor();
|
nsIEditor* GetEditor();
|
||||||
|
@ -318,6 +318,49 @@ nsNumberControlFrame::GetAnonTextControl()
|
|||||||
return mTextField ? HTMLInputElement::FromContent(mTextField) : nullptr;
|
return mTextField ? HTMLInputElement::FromContent(mTextField) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsNumberControlFrame*
|
||||||
|
nsNumberControlFrame::GetNumberControlFrameForTextField(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
// If aFrame is the anon text field for an <input type=number> then we expect
|
||||||
|
// the frame of its mContent's grandparent to be that input's frame. We
|
||||||
|
// have to check for this via the content tree because we don't know whether
|
||||||
|
// extra frames will be wrapped around any of the elements between aFrame and
|
||||||
|
// the nsNumberControlFrame that we're looking for (e.g. flex wrappers).
|
||||||
|
nsIContent* content = aFrame->GetContent();
|
||||||
|
if (content->IsInNativeAnonymousSubtree() &&
|
||||||
|
content->GetParent() && content->GetParent()->GetParent()) {
|
||||||
|
nsIContent* grandparent = content->GetParent()->GetParent();
|
||||||
|
if (grandparent->IsHTML(nsGkAtoms::input) &&
|
||||||
|
grandparent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||||
|
nsGkAtoms::number, eCaseMatters)) {
|
||||||
|
return do_QueryFrame(grandparent->GetPrimaryFrame());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsNumberControlFrame*
|
||||||
|
nsNumberControlFrame::GetNumberControlFrameForSpinButton(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
// If aFrame is a spin button for an <input type=number> then we expect the
|
||||||
|
// frame of its mContent's great-grandparent to be that input's frame. We
|
||||||
|
// have to check for this via the content tree because we don't know whether
|
||||||
|
// extra frames will be wrapped around any of the elements between aFrame and
|
||||||
|
// the nsNumberControlFrame that we're looking for (e.g. flex wrappers).
|
||||||
|
nsIContent* content = aFrame->GetContent();
|
||||||
|
if (content->IsInNativeAnonymousSubtree() &&
|
||||||
|
content->GetParent() && content->GetParent()->GetParent() &&
|
||||||
|
content->GetParent()->GetParent()->GetParent()) {
|
||||||
|
nsIContent* greatgrandparent = content->GetParent()->GetParent()->GetParent();
|
||||||
|
if (greatgrandparent->IsHTML(nsGkAtoms::input) &&
|
||||||
|
greatgrandparent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||||
|
nsGkAtoms::number, eCaseMatters)) {
|
||||||
|
return do_QueryFrame(greatgrandparent->GetPrimaryFrame());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
nsNumberControlFrame::GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const
|
nsNumberControlFrame::GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const
|
||||||
{
|
{
|
||||||
@ -330,9 +373,64 @@ nsNumberControlFrame::GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const
|
|||||||
if (aEvent->originalTarget == mSpinDown) {
|
if (aEvent->originalTarget == mSpinDown) {
|
||||||
return eSpinButtonDown;
|
return eSpinButtonDown;
|
||||||
}
|
}
|
||||||
|
if (aEvent->originalTarget == mSpinBox) {
|
||||||
|
// In the case that the up/down buttons are hidden (display:none) we use
|
||||||
|
// just the spin box element, spinning up if the pointer is over the top
|
||||||
|
// half of the element, or down if it's over the bottom half. This is
|
||||||
|
// important to handle since this is the state things are in for the
|
||||||
|
// default UA style sheet. See the comment in forms.css for why.
|
||||||
|
LayoutDeviceIntPoint absPoint = aEvent->refPoint;
|
||||||
|
nsPoint point =
|
||||||
|
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
|
||||||
|
LayoutDeviceIntPoint::ToUntyped(absPoint),
|
||||||
|
mSpinBox->GetPrimaryFrame());
|
||||||
|
if (point != nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) {
|
||||||
|
if (point.y < mSpinBox->GetPrimaryFrame()->GetSize().height / 2) {
|
||||||
|
return eSpinButtonUp;
|
||||||
|
}
|
||||||
|
return eSpinButtonDown;
|
||||||
|
}
|
||||||
|
}
|
||||||
return eSpinButtonNone;
|
return eSpinButtonNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNumberControlFrame::SpinnerStateChanged() const
|
||||||
|
{
|
||||||
|
nsIFrame* spinUpFrame = mSpinUp->GetPrimaryFrame();
|
||||||
|
if (spinUpFrame && spinUpFrame->IsThemed()) {
|
||||||
|
spinUpFrame->InvalidateFrame();
|
||||||
|
}
|
||||||
|
nsIFrame* spinDownFrame = mSpinDown->GetPrimaryFrame();
|
||||||
|
if (spinDownFrame && spinDownFrame->IsThemed()) {
|
||||||
|
spinDownFrame->InvalidateFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsNumberControlFrame::SpinnerUpButtonIsDepressed() const
|
||||||
|
{
|
||||||
|
return HTMLInputElement::FromContent(mContent)->
|
||||||
|
NumberSpinnerUpButtonIsDepressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsNumberControlFrame::SpinnerDownButtonIsDepressed() const
|
||||||
|
{
|
||||||
|
return HTMLInputElement::FromContent(mContent)->
|
||||||
|
NumberSpinnerDownButtonIsDepressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsNumberControlFrame::IsFocused() const
|
||||||
|
{
|
||||||
|
// Normally this depends on the state of our anonymous text control (which
|
||||||
|
// takes focus for us), but in the case that it does not have a frame we will
|
||||||
|
// have focus ourself.
|
||||||
|
return mTextField->AsElement()->State().HasState(NS_EVENT_STATE_FOCUS) ||
|
||||||
|
mContent->AsElement()->State().HasState(NS_EVENT_STATE_FOCUS);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsNumberControlFrame::HandleFocusEvent(WidgetEvent* aEvent)
|
nsNumberControlFrame::HandleFocusEvent(WidgetEvent* aEvent)
|
||||||
{
|
{
|
||||||
@ -342,6 +440,27 @@ nsNumberControlFrame::HandleFocusEvent(WidgetEvent* aEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STYLES_DISABLING_NATIVE_THEMING \
|
||||||
|
NS_AUTHOR_SPECIFIED_BACKGROUND | \
|
||||||
|
NS_AUTHOR_SPECIFIED_PADDING | \
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsNumberControlFrame::ShouldUseNativeStyleForSpinner() const
|
||||||
|
{
|
||||||
|
nsIFrame* spinUpFrame = mSpinUp->GetPrimaryFrame();
|
||||||
|
nsIFrame* spinDownFrame = mSpinDown->GetPrimaryFrame();
|
||||||
|
|
||||||
|
return spinUpFrame &&
|
||||||
|
spinUpFrame->StyleDisplay()->mAppearance == NS_THEME_SPINNER_UP_BUTTON &&
|
||||||
|
!PresContext()->HasAuthorSpecifiedRules(spinUpFrame,
|
||||||
|
STYLES_DISABLING_NATIVE_THEMING) &&
|
||||||
|
spinDownFrame &&
|
||||||
|
spinDownFrame->StyleDisplay()->mAppearance == NS_THEME_SPINNER_DOWN_BUTTON &&
|
||||||
|
!PresContext()->HasAuthorSpecifiedRules(spinDownFrame,
|
||||||
|
STYLES_DISABLING_NATIVE_THEMING);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
|
nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
|
||||||
uint32_t aFilter)
|
uint32_t aFilter)
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
|
|
||||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
|
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
|
virtual bool IsLeaf() const MOZ_OVERRIDE { return false; }
|
||||||
|
|
||||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||||
nsHTMLReflowMetrics& aDesiredSize,
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
@ -91,6 +91,18 @@ public:
|
|||||||
|
|
||||||
HTMLInputElement* GetAnonTextControl();
|
HTMLInputElement* GetAnonTextControl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the frame is the frame for an nsNumberControlFrame's anonymous text
|
||||||
|
* field, returns the nsNumberControlFrame. Else returns nullptr.
|
||||||
|
*/
|
||||||
|
static nsNumberControlFrame* GetNumberControlFrameForTextField(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the frame is the frame for an nsNumberControlFrame's up or down spin
|
||||||
|
* button, returns the nsNumberControlFrame. Else returns nullptr.
|
||||||
|
*/
|
||||||
|
static nsNumberControlFrame* GetNumberControlFrameForSpinButton(nsIFrame* aFrame);
|
||||||
|
|
||||||
enum SpinButtonEnum {
|
enum SpinButtonEnum {
|
||||||
eSpinButtonNone,
|
eSpinButtonNone,
|
||||||
eSpinButtonUp,
|
eSpinButtonUp,
|
||||||
@ -104,10 +116,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
int32_t GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const;
|
int32_t GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const;
|
||||||
|
|
||||||
|
void SpinnerStateChanged() const;
|
||||||
|
|
||||||
|
bool SpinnerUpButtonIsDepressed() const;
|
||||||
|
bool SpinnerDownButtonIsDepressed() const;
|
||||||
|
|
||||||
|
bool IsFocused() const;
|
||||||
|
|
||||||
void HandleFocusEvent(WidgetEvent* aEvent);
|
void HandleFocusEvent(WidgetEvent* aEvent);
|
||||||
|
|
||||||
virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) MOZ_OVERRIDE;
|
virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
bool ShouldUseNativeStyleForSpinner() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
nsresult MakeAnonymousElement(Element** aResult,
|
nsresult MakeAnonymousElement(Element** aResult,
|
||||||
|
@ -897,9 +897,6 @@ input[type=number]::-moz-number-wrapper {
|
|||||||
display: flex;
|
display: flex;
|
||||||
float: none !important;
|
float: none !important;
|
||||||
position: static !important;
|
position: static !important;
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=number]::-moz-number-text {
|
input[type=number]::-moz-number-text {
|
||||||
@ -922,18 +919,23 @@ input[type=number]::-moz-number-text {
|
|||||||
input[type=number]::-moz-number-spin-box {
|
input[type=number]::-moz-number-spin-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 0 8px;
|
%ifdef XP_WIN
|
||||||
cursor: default;
|
/* The Window's Theme's spin buttons have a very narrow minimum width, so
|
||||||
padding: 1px;
|
* make it something reasonable:
|
||||||
|
*/
|
||||||
|
width: 16px;
|
||||||
|
%endif
|
||||||
|
height: 0;
|
||||||
|
align-self: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=number]::-moz-number-spin-up {
|
input[type=number]::-moz-number-spin-up {
|
||||||
/* We should be "display:block" so that we don't get wrapped in an anonymous
|
-moz-appearance: spinner-upbutton;
|
||||||
* flex item that will prevent the setting of the "flex" property below from
|
display: block; /* bug 926670 */
|
||||||
* working.
|
flex: none;
|
||||||
*/
|
cursor: default;
|
||||||
display: block;
|
/* Style for when native theming is off: */
|
||||||
flex: 1;
|
|
||||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,4 L3,0 5,4" fill="dimgrey"/></svg>');
|
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,4 L3,0 5,4" fill="dimgrey"/></svg>');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center bottom;
|
background-position: center bottom;
|
||||||
@ -944,12 +946,11 @@ input[type=number]::-moz-number-spin-up {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[type=number]::-moz-number-spin-down {
|
input[type=number]::-moz-number-spin-down {
|
||||||
/* We should be "display:block" so that we don't get wrapped in an anonymous
|
-moz-appearance: spinner-downbutton;
|
||||||
* flex item that will prevent the setting of the "flex" property below from
|
display: block; /* bug 926670 */
|
||||||
* working.
|
flex: none;
|
||||||
*/
|
cursor: default;
|
||||||
display: block;
|
/* Style for when native theming is off: */
|
||||||
flex: 1;
|
|
||||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,1 L3,5 5,1" fill="dimgrey"/></svg>');
|
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,1 L3,5 5,1" fill="dimgrey"/></svg>');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center top;
|
background-position: center top;
|
||||||
|
@ -104,6 +104,10 @@ protected:
|
|||||||
const HIRect& inBoxRect, ThemeDrawState inDrawState,
|
const HIRect& inBoxRect, ThemeDrawState inDrawState,
|
||||||
ThemeButtonAdornment inAdornment, nsEventStates inState,
|
ThemeButtonAdornment inAdornment, nsEventStates inState,
|
||||||
nsIFrame* aFrame);
|
nsIFrame* aFrame);
|
||||||
|
void DrawSpinButton(CGContextRef context, ThemeButtonKind inKind,
|
||||||
|
const HIRect& inBoxRect, ThemeDrawState inDrawState,
|
||||||
|
ThemeButtonAdornment inAdornment, nsEventStates inState,
|
||||||
|
nsIFrame* aFrame, uint8_t aWidgetType);
|
||||||
void DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inBoxRect,
|
void DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||||
NSWindow* aWindow);
|
NSWindow* aWindow);
|
||||||
void DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
|
void DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "nsNativeThemeCocoa.h"
|
#include "nsNativeThemeCocoa.h"
|
||||||
#include "nsObjCExceptions.h"
|
#include "nsObjCExceptions.h"
|
||||||
|
#include "nsNumberControlFrame.h"
|
||||||
#include "nsRangeFrame.h"
|
#include "nsRangeFrame.h"
|
||||||
#include "nsRenderingContext.h"
|
#include "nsRenderingContext.h"
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
@ -1210,6 +1211,26 @@ nsNativeThemeCocoa::DrawDropdown(CGContextRef cgContext, const HIRect& inBoxRect
|
|||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const CellRenderSettings spinnerSettings = {
|
||||||
|
{
|
||||||
|
NSMakeSize(11, 16), // mini (width trimmed by 2px to reduce blank border)
|
||||||
|
NSMakeSize(15, 22), // small
|
||||||
|
NSMakeSize(19, 27) // regular
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NSMakeSize(11, 16), // mini (width trimmed by 2px to reduce blank border)
|
||||||
|
NSMakeSize(15, 22), // small
|
||||||
|
NSMakeSize(19, 27) // regular
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ // Leopard
|
||||||
|
{0, 0, 0, 0}, // mini
|
||||||
|
{0, 0, 0, 0}, // small
|
||||||
|
{0, 0, 0, 0} // regular
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKind,
|
nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKind,
|
||||||
const HIRect& inBoxRect, ThemeDrawState inDrawState,
|
const HIRect& inBoxRect, ThemeDrawState inDrawState,
|
||||||
@ -1234,6 +1255,56 @@ nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKi
|
|||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNativeThemeCocoa::DrawSpinButton(CGContextRef cgContext,
|
||||||
|
ThemeButtonKind inKind,
|
||||||
|
const HIRect& inBoxRect,
|
||||||
|
ThemeDrawState inDrawState,
|
||||||
|
ThemeButtonAdornment inAdornment,
|
||||||
|
nsEventStates inState,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
uint8_t aWidgetType)
|
||||||
|
{
|
||||||
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||||
|
|
||||||
|
MOZ_ASSERT(aWidgetType == NS_THEME_SPINNER_UP_BUTTON ||
|
||||||
|
aWidgetType == NS_THEME_SPINNER_DOWN_BUTTON);
|
||||||
|
|
||||||
|
HIThemeButtonDrawInfo bdi;
|
||||||
|
bdi.version = 0;
|
||||||
|
bdi.kind = inKind;
|
||||||
|
bdi.value = kThemeButtonOff;
|
||||||
|
bdi.adornment = inAdornment;
|
||||||
|
|
||||||
|
if (IsDisabled(aFrame, inState))
|
||||||
|
bdi.state = kThemeStateUnavailable;
|
||||||
|
else
|
||||||
|
bdi.state = FrameIsInActiveWindow(aFrame) ? inDrawState : kThemeStateActive;
|
||||||
|
|
||||||
|
// Cocoa only allows kThemeIncDecButton to paint the up and down spin buttons
|
||||||
|
// together as a single unit (presumably because when one button is active,
|
||||||
|
// the appearance of both changes (in different ways)). Here we have to paint
|
||||||
|
// both buttons, using clip to hide the one we don't want to paint.
|
||||||
|
HIRect drawRect = inBoxRect;
|
||||||
|
drawRect.size.height *= 2;
|
||||||
|
if (aWidgetType == NS_THEME_SPINNER_DOWN_BUTTON) {
|
||||||
|
drawRect.origin.y -= inBoxRect.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift the drawing a little to the left, since cocoa paints with more
|
||||||
|
// blank space around the visual buttons than we'd like:
|
||||||
|
drawRect.origin.x -= 1;
|
||||||
|
|
||||||
|
CGContextSaveGState(cgContext);
|
||||||
|
CGContextClipToRect(cgContext, inBoxRect);
|
||||||
|
|
||||||
|
HIThemeDrawButton(&drawRect, &bdi, cgContext, HITHEME_ORIENTATION, NULL);
|
||||||
|
|
||||||
|
CGContextRestoreGState(cgContext);
|
||||||
|
|
||||||
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsNativeThemeCocoa::DrawFrame(CGContextRef cgContext, HIThemeFrameKind inKind,
|
nsNativeThemeCocoa::DrawFrame(CGContextRef cgContext, HIThemeFrameKind inKind,
|
||||||
const HIRect& inBoxRect, bool inDisabled,
|
const HIRect& inBoxRect, bool inDisabled,
|
||||||
@ -2135,8 +2206,14 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NS_THEME_SPINNER: {
|
case NS_THEME_SPINNER: {
|
||||||
ThemeDrawState state = kThemeStateActive;
|
|
||||||
nsIContent* content = aFrame->GetContent();
|
nsIContent* content = aFrame->GetContent();
|
||||||
|
if (content->IsHTML()) {
|
||||||
|
// In HTML the theming for the spin buttons is drawn individually into
|
||||||
|
// their own backgrounds instead of being drawn into the background of
|
||||||
|
// their spinner parent as it is for XUL.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ThemeDrawState state = kThemeStateActive;
|
||||||
if (content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::state,
|
if (content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::state,
|
||||||
NS_LITERAL_STRING("up"), eCaseMatters)) {
|
NS_LITERAL_STRING("up"), eCaseMatters)) {
|
||||||
state = kThemeStatePressedUp;
|
state = kThemeStatePressedUp;
|
||||||
@ -2151,6 +2228,23 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NS_THEME_SPINNER_UP_BUTTON:
|
||||||
|
case NS_THEME_SPINNER_DOWN_BUTTON: {
|
||||||
|
nsNumberControlFrame* numberControlFrame =
|
||||||
|
nsNumberControlFrame::GetNumberControlFrameForSpinButton(aFrame);
|
||||||
|
if (numberControlFrame) {
|
||||||
|
ThemeDrawState state = kThemeStateActive;
|
||||||
|
if (numberControlFrame->SpinnerUpButtonIsDepressed()) {
|
||||||
|
state = kThemeStatePressedUp;
|
||||||
|
} else if (numberControlFrame->SpinnerDownButtonIsDepressed()) {
|
||||||
|
state = kThemeStatePressedDown;
|
||||||
|
}
|
||||||
|
DrawSpinButton(cgContext, kThemeIncDecButtonMini, macRect, state,
|
||||||
|
kThemeAdornmentNone, eventState, aFrame, aWidgetType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case NS_THEME_TOOLBAR_BUTTON:
|
case NS_THEME_TOOLBAR_BUTTON:
|
||||||
DrawSegment(cgContext, macRect, eventState, aFrame, toolbarButtonRenderSettings);
|
DrawSegment(cgContext, macRect, eventState, aFrame, toolbarButtonRenderSettings);
|
||||||
break;
|
break;
|
||||||
@ -2747,12 +2841,25 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsRenderingContext* aContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case NS_THEME_SPINNER:
|
case NS_THEME_SPINNER:
|
||||||
|
case NS_THEME_SPINNER_UP_BUTTON:
|
||||||
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
||||||
{
|
{
|
||||||
SInt32 buttonHeight = 0, buttonWidth = 0;
|
SInt32 buttonHeight = 0, buttonWidth = 0;
|
||||||
|
if (aFrame->GetContent()->IsXUL()) {
|
||||||
::GetThemeMetric(kThemeMetricLittleArrowsWidth, &buttonWidth);
|
::GetThemeMetric(kThemeMetricLittleArrowsWidth, &buttonWidth);
|
||||||
::GetThemeMetric(kThemeMetricLittleArrowsHeight, &buttonHeight);
|
::GetThemeMetric(kThemeMetricLittleArrowsHeight, &buttonHeight);
|
||||||
|
} else {
|
||||||
|
NSSize size =
|
||||||
|
spinnerSettings.minimumSizes[EnumSizeForCocoaSize(NSMiniControlSize)];
|
||||||
|
buttonWidth = size.width;
|
||||||
|
buttonHeight = size.height;
|
||||||
|
if (aWidgetType != NS_THEME_SPINNER) {
|
||||||
|
// the buttons are half the height of the spinner
|
||||||
|
buttonHeight /= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
aResult->SizeTo(buttonWidth, buttonHeight);
|
aResult->SizeTo(buttonWidth, buttonHeight);
|
||||||
*aIsOverridable = false;
|
*aIsOverridable = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3100,6 +3207,8 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a
|
|||||||
case NS_THEME_BUTTON_BEVEL:
|
case NS_THEME_BUTTON_BEVEL:
|
||||||
case NS_THEME_TOOLBAR_BUTTON:
|
case NS_THEME_TOOLBAR_BUTTON:
|
||||||
case NS_THEME_SPINNER:
|
case NS_THEME_SPINNER:
|
||||||
|
case NS_THEME_SPINNER_UP_BUTTON:
|
||||||
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
||||||
case NS_THEME_TOOLBAR:
|
case NS_THEME_TOOLBAR:
|
||||||
case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
|
case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
|
||||||
case NS_THEME_STATUSBAR:
|
case NS_THEME_STATUSBAR:
|
||||||
@ -3224,6 +3333,8 @@ nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType)
|
|||||||
case NS_THEME_MENUSEPARATOR:
|
case NS_THEME_MENUSEPARATOR:
|
||||||
case NS_THEME_TOOLTIP:
|
case NS_THEME_TOOLTIP:
|
||||||
case NS_THEME_SPINNER:
|
case NS_THEME_SPINNER:
|
||||||
|
case NS_THEME_SPINNER_UP_BUTTON:
|
||||||
|
case NS_THEME_SPINNER_DOWN_BUTTON:
|
||||||
case NS_THEME_TOOLBAR_SEPARATOR:
|
case NS_THEME_TOOLBAR_SEPARATOR:
|
||||||
case NS_THEME_TOOLBOX:
|
case NS_THEME_TOOLBOX:
|
||||||
case NS_THEME_TEXTFIELD:
|
case NS_THEME_TEXTFIELD:
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
|
#include "nsNumberControlFrame.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsEventStateManager.h"
|
#include "nsEventStateManager.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
@ -74,6 +75,16 @@ nsNativeTheme::GetContentState(nsIFrame* aFrame, uint8_t aWidgetType)
|
|||||||
nsEventStates flags;
|
nsEventStates flags;
|
||||||
if (frameContent->IsElement()) {
|
if (frameContent->IsElement()) {
|
||||||
flags = frameContent->AsElement()->State();
|
flags = frameContent->AsElement()->State();
|
||||||
|
|
||||||
|
// <input type=number> needs special handling since its nested native
|
||||||
|
// anonymous <input type=text> takes focus for it.
|
||||||
|
if (aWidgetType == NS_THEME_TEXTFIELD &&
|
||||||
|
frameContent->IsHTML(nsGkAtoms::input)) {
|
||||||
|
nsNumberControlFrame *numberControlFrame = do_QueryFrame(aFrame);
|
||||||
|
if (numberControlFrame && numberControlFrame->IsFocused()) {
|
||||||
|
flags |= NS_EVENT_STATE_FOCUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isXULCheckboxRadio && aWidgetType == NS_THEME_RADIO) {
|
if (isXULCheckboxRadio && aWidgetType == NS_THEME_RADIO) {
|
||||||
@ -313,6 +324,15 @@ nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aWidgetType == NS_THEME_SPINNER_UP_BUTTON ||
|
||||||
|
aWidgetType == NS_THEME_SPINNER_DOWN_BUTTON) {
|
||||||
|
nsNumberControlFrame* numberControlFrame =
|
||||||
|
nsNumberControlFrame::GetNumberControlFrameForSpinButton(aFrame);
|
||||||
|
if (numberControlFrame) {
|
||||||
|
return !numberControlFrame->ShouldUseNativeStyleForSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (aWidgetType == NS_THEME_BUTTON ||
|
return (aWidgetType == NS_THEME_BUTTON ||
|
||||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
||||||
|
Loading…
Reference in New Issue
Block a user