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
c3c4c07f0f
commit
8222abbd83
@ -3314,6 +3314,8 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
bool oldNumberControlSpinTimerSpinsUpValue =
|
||||
mNumberControlSpinnerSpinsUp;
|
||||
switch (numberControlFrame->GetSpinButtonForPointerEvent(
|
||||
aVisitor.mEvent->AsMouseEvent())) {
|
||||
case nsNumberControlFrame::eSpinButtonUp:
|
||||
@ -3325,6 +3327,14 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
stopSpin = false;
|
||||
break;
|
||||
}
|
||||
if (mNumberControlSpinnerSpinsUp !=
|
||||
oldNumberControlSpinTimerSpinsUpValue) {
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
numberControlFrame->SpinnerStateChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stopSpin) {
|
||||
StopNumberControlSpinnerSpin();
|
||||
@ -3346,6 +3356,15 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
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) {
|
||||
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
|
||||
// spin button to the other, or to some other element:
|
||||
nsIPresShell::SetCapturingContent(this, CAPTURE_IGNOREALLOWED);
|
||||
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
numberControlFrame->SpinnerStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -3512,6 +3537,12 @@ HTMLInputElement::StopNumberControlSpinnerSpin()
|
||||
mNumberControlSpinnerIsSpinning = false;
|
||||
|
||||
FireChangeEventIfNeeded();
|
||||
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
numberControlFrame->SpinnerStateChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -688,6 +688,16 @@ public:
|
||||
*/
|
||||
static void HandleNumberControlSpin(void* aData);
|
||||
|
||||
bool NumberSpinnerUpButtonIsDepressed() const
|
||||
{
|
||||
return mNumberControlSpinnerIsSpinning && mNumberControlSpinnerSpinsUp;
|
||||
}
|
||||
|
||||
bool NumberSpinnerDownButtonIsDepressed() const
|
||||
{
|
||||
return mNumberControlSpinnerIsSpinning && !mNumberControlSpinnerSpinsUp;
|
||||
}
|
||||
|
||||
bool MozIsTextField(bool aExcludePassword);
|
||||
|
||||
nsIEditor* GetEditor();
|
||||
|
@ -318,6 +318,49 @@ nsNumberControlFrame::GetAnonTextControl()
|
||||
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
|
||||
nsNumberControlFrame::GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const
|
||||
{
|
||||
@ -330,9 +373,64 @@ nsNumberControlFrame::GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const
|
||||
if (aEvent->originalTarget == mSpinDown) {
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
|
||||
uint32_t aFilter)
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
|
||||
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,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
@ -91,6 +91,18 @@ public:
|
||||
|
||||
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 {
|
||||
eSpinButtonNone,
|
||||
eSpinButtonUp,
|
||||
@ -104,10 +116,19 @@ public:
|
||||
*/
|
||||
int32_t GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const;
|
||||
|
||||
void SpinnerStateChanged() const;
|
||||
|
||||
bool SpinnerUpButtonIsDepressed() const;
|
||||
bool SpinnerDownButtonIsDepressed() const;
|
||||
|
||||
bool IsFocused() const;
|
||||
|
||||
void HandleFocusEvent(WidgetEvent* aEvent);
|
||||
|
||||
virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) MOZ_OVERRIDE;
|
||||
|
||||
bool ShouldUseNativeStyleForSpinner() const;
|
||||
|
||||
private:
|
||||
|
||||
nsresult MakeAnonymousElement(Element** aResult,
|
||||
|
@ -897,9 +897,6 @@ input[type=number]::-moz-number-wrapper {
|
||||
display: flex;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
-moz-box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-text {
|
||||
@ -922,18 +919,23 @@ input[type=number]::-moz-number-text {
|
||||
input[type=number]::-moz-number-spin-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 8px;
|
||||
cursor: default;
|
||||
padding: 1px;
|
||||
%ifdef XP_WIN
|
||||
/* The Window's Theme's spin buttons have a very narrow minimum width, so
|
||||
* make it something reasonable:
|
||||
*/
|
||||
width: 16px;
|
||||
%endif
|
||||
height: 0;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-spin-up {
|
||||
/* We should be "display:block" so that we don't get wrapped in an anonymous
|
||||
* flex item that will prevent the setting of the "flex" property below from
|
||||
* working.
|
||||
*/
|
||||
display: block;
|
||||
flex: 1;
|
||||
-moz-appearance: spinner-upbutton;
|
||||
display: block; /* bug 926670 */
|
||||
flex: none;
|
||||
cursor: default;
|
||||
/* Style for when native theming is off: */
|
||||
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-position: center bottom;
|
||||
@ -944,12 +946,11 @@ input[type=number]::-moz-number-spin-up {
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-spin-down {
|
||||
/* We should be "display:block" so that we don't get wrapped in an anonymous
|
||||
* flex item that will prevent the setting of the "flex" property below from
|
||||
* working.
|
||||
*/
|
||||
display: block;
|
||||
flex: 1;
|
||||
-moz-appearance: spinner-downbutton;
|
||||
display: block; /* bug 926670 */
|
||||
flex: none;
|
||||
cursor: default;
|
||||
/* Style for when native theming is off: */
|
||||
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-position: center top;
|
||||
|
@ -104,6 +104,10 @@ protected:
|
||||
const HIRect& inBoxRect, ThemeDrawState inDrawState,
|
||||
ThemeButtonAdornment inAdornment, nsEventStates inState,
|
||||
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,
|
||||
NSWindow* aWindow);
|
||||
void DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "nsNativeThemeCocoa.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsNumberControlFrame.h"
|
||||
#include "nsRangeFrame.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsRect.h"
|
||||
@ -1210,6 +1211,26 @@ nsNativeThemeCocoa::DrawDropdown(CGContextRef cgContext, const HIRect& inBoxRect
|
||||
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
|
||||
nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKind,
|
||||
const HIRect& inBoxRect, ThemeDrawState inDrawState,
|
||||
@ -1234,6 +1255,56 @@ nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKi
|
||||
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
|
||||
nsNativeThemeCocoa::DrawFrame(CGContextRef cgContext, HIThemeFrameKind inKind,
|
||||
const HIRect& inBoxRect, bool inDisabled,
|
||||
@ -2135,8 +2206,14 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
break;
|
||||
|
||||
case NS_THEME_SPINNER: {
|
||||
ThemeDrawState state = kThemeStateActive;
|
||||
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,
|
||||
NS_LITERAL_STRING("up"), eCaseMatters)) {
|
||||
state = kThemeStatePressedUp;
|
||||
@ -2151,6 +2228,23 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
}
|
||||
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:
|
||||
DrawSegment(cgContext, macRect, eventState, aFrame, toolbarButtonRenderSettings);
|
||||
break;
|
||||
@ -2747,12 +2841,25 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsRenderingContext* aContext,
|
||||
}
|
||||
|
||||
case NS_THEME_SPINNER:
|
||||
case NS_THEME_SPINNER_UP_BUTTON:
|
||||
case NS_THEME_SPINNER_DOWN_BUTTON:
|
||||
{
|
||||
SInt32 buttonHeight = 0, buttonWidth = 0;
|
||||
::GetThemeMetric(kThemeMetricLittleArrowsWidth, &buttonWidth);
|
||||
::GetThemeMetric(kThemeMetricLittleArrowsHeight, &buttonHeight);
|
||||
if (aFrame->GetContent()->IsXUL()) {
|
||||
::GetThemeMetric(kThemeMetricLittleArrowsWidth, &buttonWidth);
|
||||
::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);
|
||||
*aIsOverridable = false;
|
||||
*aIsOverridable = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3100,6 +3207,8 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a
|
||||
case NS_THEME_BUTTON_BEVEL:
|
||||
case NS_THEME_TOOLBAR_BUTTON:
|
||||
case NS_THEME_SPINNER:
|
||||
case NS_THEME_SPINNER_UP_BUTTON:
|
||||
case NS_THEME_SPINNER_DOWN_BUTTON:
|
||||
case NS_THEME_TOOLBAR:
|
||||
case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
|
||||
case NS_THEME_STATUSBAR:
|
||||
@ -3224,6 +3333,8 @@ nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType)
|
||||
case NS_THEME_MENUSEPARATOR:
|
||||
case NS_THEME_TOOLTIP:
|
||||
case NS_THEME_SPINNER:
|
||||
case NS_THEME_SPINNER_UP_BUTTON:
|
||||
case NS_THEME_SPINNER_DOWN_BUTTON:
|
||||
case NS_THEME_TOOLBAR_SEPARATOR:
|
||||
case NS_THEME_TOOLBOX:
|
||||
case NS_THEME_TEXTFIELD:
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "nsIContent.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsNumberControlFrame.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsEventStateManager.h"
|
||||
#include "nsString.h"
|
||||
@ -74,6 +75,16 @@ nsNativeTheme::GetContentState(nsIFrame* aFrame, uint8_t aWidgetType)
|
||||
nsEventStates flags;
|
||||
if (frameContent->IsElement()) {
|
||||
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) {
|
||||
@ -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 ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
||||
|
Loading…
Reference in New Issue
Block a user