зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1640195: Address UX feedback for non-native widget styling. r=geckoview-reviewers,emilio,agi
Differential Revision: https://phabricator.services.mozilla.com/D76509
This commit is contained in:
Родитель
515b4fb502
Коммит
597bb7d3e0
|
@ -16582,6 +16582,11 @@ void Document::AddPendingFrameStaticClone(nsFrameLoaderOwner* aElement,
|
|||
clone->mStaticCloneOf = aStaticCloneOf;
|
||||
}
|
||||
|
||||
bool Document::ShouldAvoidNativeTheme() const {
|
||||
return StaticPrefs::widget_disable_native_theme_for_content() &&
|
||||
(!IsInChromeDocShell() || XRE_IsContentProcess());
|
||||
}
|
||||
|
||||
bool Document::UseRegularPrincipal() const {
|
||||
return EffectiveStoragePrincipal() == NodePrincipal();
|
||||
}
|
||||
|
|
|
@ -3905,6 +3905,8 @@ class Document : public nsINode,
|
|||
void AddPendingFrameStaticClone(nsFrameLoaderOwner* aElement,
|
||||
nsFrameLoader* aStaticCloneOf);
|
||||
|
||||
bool ShouldAvoidNativeTheme() const;
|
||||
|
||||
protected:
|
||||
void DoUpdateSVGUseElementShadowTrees();
|
||||
|
||||
|
|
|
@ -10317,7 +10317,8 @@ already_AddRefed<nsFontMetrics> nsLayoutUtils::GetMetricsFor(
|
|||
/* static */
|
||||
void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
|
||||
LookAndFeel::FontID aFontID,
|
||||
const nsFont* aDefaultVariableFont) {
|
||||
const nsFont* aDefaultVariableFont,
|
||||
const Document* aDocument) {
|
||||
gfxFontStyle fontStyle;
|
||||
nsAutoString systemFontName;
|
||||
if (LookAndFeel::GetFont(aFontID, systemFontName, fontStyle)) {
|
||||
|
@ -10331,6 +10332,12 @@ void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
|
|||
aSystemFont->weight = fontStyle.weight;
|
||||
aSystemFont->stretch = fontStyle.stretch;
|
||||
aSystemFont->size = Length::FromPixels(fontStyle.size);
|
||||
|
||||
if (aDocument->ShouldAvoidNativeTheme()) {
|
||||
auto newSize =
|
||||
aDefaultVariableFont->size.ToCSSPixels() - CSSPixel::FromPoints(2.0f);
|
||||
aSystemFont->size = Length::FromPixels(std::max(float(newSize), 0.0f));
|
||||
}
|
||||
// aSystemFont->langGroup = fontStyle.langGroup;
|
||||
aSystemFont->sizeAdjust = fontStyle.sizeAdjust;
|
||||
|
||||
|
|
|
@ -3064,7 +3064,8 @@ class nsLayoutUtils {
|
|||
|
||||
static void ComputeSystemFont(nsFont* aSystemFont,
|
||||
mozilla::LookAndFeel::FontID aFontID,
|
||||
const nsFont* aDefaultVariableFont);
|
||||
const nsFont* aDefaultVariableFont,
|
||||
const mozilla::dom::Document* aDocument);
|
||||
|
||||
static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag);
|
||||
|
||||
|
|
|
@ -83,7 +83,6 @@
|
|||
#include "mozilla/GlobalStyleSheetCache.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "mozilla/StaticPrefs_zoom.h"
|
||||
#include "mozilla/StyleSheet.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
|
@ -1304,8 +1303,7 @@ void nsPresContext::RecordInteractionTime(InteractionType aType,
|
|||
|
||||
nsITheme* nsPresContext::EnsureTheme() {
|
||||
MOZ_ASSERT(!mTheme);
|
||||
if (StaticPrefs::widget_disable_native_theme_for_content() &&
|
||||
(!IsChrome() || XRE_IsContentProcess())) {
|
||||
if (Document()->ShouldAvoidNativeTheme()) {
|
||||
mTheme = do_GetBasicNativeThemeDoNotUseDirectly();
|
||||
} else {
|
||||
mTheme = do_GetNativeThemeDoNotUseDirectly();
|
||||
|
|
|
@ -708,6 +708,21 @@ bool nsComboboxControlFrame::HasDropDownButton() const {
|
|||
PresContext()->Theme()->ThemeNeedsComboboxDropmarker());
|
||||
}
|
||||
|
||||
nscoord nsComboboxControlFrame::DropDownButtonISize() {
|
||||
if (!HasDropDownButton()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LayoutDeviceIntSize dropdownButtonSize;
|
||||
bool canOverride = true;
|
||||
nsPresContext* presContext = PresContext();
|
||||
presContext->Theme()->GetMinimumWidgetSize(
|
||||
presContext, this, StyleAppearance::MozMenulistArrowButton,
|
||||
&dropdownButtonSize, &canOverride);
|
||||
|
||||
return presContext->DevPixelsToAppUnits(dropdownButtonSize.width);
|
||||
}
|
||||
|
||||
nscoord nsComboboxControlFrame::GetIntrinsicISize(
|
||||
gfxContext* aRenderingContext, nsLayoutUtils::IntrinsicISizeType aType) {
|
||||
// get the scrollbar width, we'll use this later
|
||||
|
@ -756,10 +771,8 @@ nscoord nsComboboxControlFrame::GetIntrinsicISize(
|
|||
displayISize = std::max(dropdownContentISize, displayISize);
|
||||
}
|
||||
|
||||
// add room for the dropmarker button if there is one
|
||||
if (HasDropDownButton()) {
|
||||
displayISize += scrollbarWidth;
|
||||
}
|
||||
// Add room for the dropmarker button if there is one.
|
||||
displayISize += DropDownButtonISize();
|
||||
|
||||
return displayISize;
|
||||
}
|
||||
|
@ -819,21 +832,12 @@ void nsComboboxControlFrame::Reflow(nsPresContext* aPresContext,
|
|||
Unused << resize.forget();
|
||||
}
|
||||
|
||||
// Get the width of the vertical scrollbar. That will be the inline
|
||||
// size of the dropdown button.
|
||||
WritingMode wm = aReflowInput.GetWritingMode();
|
||||
nscoord buttonISize;
|
||||
if (!HasDropDownButton()) {
|
||||
buttonISize = 0;
|
||||
} else {
|
||||
nsIScrollableFrame* scrollable = do_QueryFrame(mListControlFrame);
|
||||
NS_ASSERTION(scrollable, "List must be a scrollable frame");
|
||||
buttonISize = scrollable->GetNondisappearingScrollbarWidth(
|
||||
PresContext(), aReflowInput.mRenderingContext, wm);
|
||||
if (buttonISize > aReflowInput.ComputedISize()) {
|
||||
buttonISize = 0;
|
||||
}
|
||||
}
|
||||
nscoord buttonISize = 0;
|
||||
|
||||
// Check if the theme specifies a minimum size for the dropdown button
|
||||
// first.
|
||||
buttonISize += DropDownButtonISize();
|
||||
|
||||
mDisplayISize = aReflowInput.ComputedISize() - buttonISize;
|
||||
|
||||
|
|
|
@ -226,6 +226,7 @@ class nsComboboxControlFrame final : public nsBlockFrame,
|
|||
|
||||
// Return true if we should render a dropdown button.
|
||||
bool HasDropDownButton() const;
|
||||
nscoord DropDownButtonISize();
|
||||
|
||||
enum DropDownPositionState {
|
||||
// can't show the dropdown at its current position
|
||||
|
|
|
@ -1006,7 +1006,8 @@ void Gecko_nsFont_InitSystem(nsFont* aDest, int32_t aFontId,
|
|||
LookAndFeel::FontID fontID = static_cast<LookAndFeel::FontID>(aFontId);
|
||||
|
||||
AutoWriteLock guard(*sServoFFILock);
|
||||
nsLayoutUtils::ComputeSystemFont(aDest, fontID, defaultVariableFont);
|
||||
nsLayoutUtils::ComputeSystemFont(aDest, fontID, defaultVariableFont,
|
||||
aDocument);
|
||||
}
|
||||
|
||||
void Gecko_nsFont_Destroy(nsFont* aDest) { aDest->~nsFont(); }
|
||||
|
|
|
@ -9755,7 +9755,7 @@
|
|||
|
||||
# Global user preference for disabling native theme in content processes.
|
||||
- name: widget.disable-native-theme-for-content
|
||||
type: bool
|
||||
type: RelaxedAtomicBool
|
||||
value: @IS_ANDROID@
|
||||
mirror: always
|
||||
|
||||
|
|
|
@ -134,6 +134,7 @@ UNIFIED_SOURCES += [
|
|||
'nsClipboard.cpp',
|
||||
'nsDeviceContextAndroid.cpp',
|
||||
'nsLookAndFeel.cpp',
|
||||
'nsNativeBasicThemeAndroid.cpp',
|
||||
'nsPrintSettingsServiceAndroid.cpp',
|
||||
'nsUserIdleServiceAndroid.cpp',
|
||||
'nsWidgetFactory.cpp',
|
||||
|
@ -170,6 +171,7 @@ LOCAL_INCLUDES += [
|
|||
'/dom/system/android',
|
||||
'/gfx/2d',
|
||||
'/gfx/vr',
|
||||
'/layout/forms',
|
||||
'/layout/painting',
|
||||
'/netwerk/base',
|
||||
'/netwerk/cache',
|
||||
|
|
|
@ -0,0 +1,945 @@
|
|||
/* -*- Mode: C++; tab-width: 40; 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 "nsNativeBasicThemeAndroid.h"
|
||||
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsDateTimeControlFrame.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "PathHelpers.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
static const sRGBColor sBackgroundColor(sRGBColor(1.0f, 1.0f, 1.0f));
|
||||
static const sRGBColor sBackgroundActiveColor(sRGBColor(0.88f, 0.88f, 0.9f));
|
||||
static const sRGBColor sBackgroundActiveColorDisabled(sRGBColor(0.88f, 0.88f,
|
||||
0.9f, 0.4f));
|
||||
static const sRGBColor sBorderColor(sRGBColor(0.62f, 0.62f, 0.68f));
|
||||
static const sRGBColor sBorderColorDisabled(sRGBColor(0.44f, 0.44f, 0.44f,
|
||||
0.4f));
|
||||
static const sRGBColor sBorderHoverColor(sRGBColor(0.5f, 0.5f, 0.56f));
|
||||
static const sRGBColor sBorderHoverColorDisabled(sRGBColor(0.5f, 0.5f, 0.56f,
|
||||
0.4f));
|
||||
static const sRGBColor sBorderFocusColor(sRGBColor(0.04f, 0.52f, 1.0f));
|
||||
static const sRGBColor sCheckBackgroundColor(sRGBColor(0.18f, 0.39f, 0.89f));
|
||||
static const sRGBColor sCheckBackgroundColorDisabled(sRGBColor(0.18f, 0.39f,
|
||||
0.89f, 0.4f));
|
||||
static const sRGBColor sCheckBackgroundHoverColor(sRGBColor(0.02f, 0.24f,
|
||||
0.58f));
|
||||
static const sRGBColor sCheckBackgroundHoverColorDisabled(
|
||||
sRGBColor(0.02f, 0.24f, 0.58f, 0.4f));
|
||||
static const sRGBColor sCheckBackgroundActiveColor(sRGBColor(0.03f, 0.19f,
|
||||
0.45f));
|
||||
static const sRGBColor sCheckBackgroundActiveColorDisabled(
|
||||
sRGBColor(0.03f, 0.19f, 0.45f, 0.4f));
|
||||
static const sRGBColor sDisabledColor(sRGBColor(0.89f, 0.89f, 0.89f));
|
||||
static const sRGBColor sActiveColor(sRGBColor(0.47f, 0.47f, 0.48f));
|
||||
static const sRGBColor sInputHoverColor(sRGBColor(0.05f, 0.05f, 0.05f, 0.5f));
|
||||
static const sRGBColor sRangeInputBackgroundColor(sRGBColor(0.89f, 0.89f,
|
||||
0.89f));
|
||||
static const sRGBColor sScrollbarColor(sRGBColor(0.94f, 0.94f, 0.94f));
|
||||
static const sRGBColor sScrollbarBorderColor(sRGBColor(1.0f, 1.0f, 1.0f));
|
||||
static const sRGBColor sScrollbarThumbColor(sRGBColor(0.8f, 0.8f, 0.8f));
|
||||
static const sRGBColor sScrollbarThumbColorActive(sRGBColor(0.375f, 0.375f,
|
||||
0.375f));
|
||||
static const sRGBColor sScrollbarThumbColorHover(sRGBColor(0.65f, 0.65f,
|
||||
0.65f));
|
||||
static const sRGBColor sScrollbarArrowColor(sRGBColor(0.375f, 0.375f, 0.375f));
|
||||
static const sRGBColor sScrollbarArrowColorActive(sRGBColor(1.0f, 1.0f, 1.0f));
|
||||
static const sRGBColor sScrollbarArrowColorHover(sRGBColor(0.0f, 0.0f, 0.0f));
|
||||
static const sRGBColor sScrollbarButtonColor(sScrollbarColor);
|
||||
static const sRGBColor sScrollbarButtonActiveColor(sRGBColor(0.375f, 0.375f,
|
||||
0.375f));
|
||||
static const sRGBColor sScrollbarButtonHoverColor(sRGBColor(0.86f, 0.86f,
|
||||
0.86f));
|
||||
static const sRGBColor sButtonColor(sRGBColor(0.98f, 0.98f, 0.98f));
|
||||
static const sRGBColor sButtonHoverColor(sRGBColor(0.94f, 0.94f, 0.96f));
|
||||
static const sRGBColor sButtonActiveColor(sRGBColor(0.88f, 0.88f, 0.90f));
|
||||
static const sRGBColor sWhiteColor(sRGBColor(1.0f, 1.0f, 1.0f, 0.0f));
|
||||
|
||||
static const CSSIntCoord kMinimumWidgetSize = 17;
|
||||
static const CSSIntCoord kMinimumDropdownArrowButtonWidth = 18;
|
||||
static const CSSCoord kButtonBorderWidth = 1.0f;
|
||||
static const CSSCoord kMenulistBorderWidth = 1.0f;
|
||||
static const CSSCoord kTextFieldBorderWidth = 1.0f;
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsNativeBasicThemeAndroid, nsNativeTheme, nsITheme)
|
||||
|
||||
static uint32_t GetDPIRatio(nsIFrame* aFrame) {
|
||||
return AppUnitsPerCSSPixel() / aFrame->PresContext()
|
||||
->DeviceContext()
|
||||
->AppUnitsPerDevPixelAtUnitFullZoom();
|
||||
}
|
||||
|
||||
static bool IsDateTimeResetButton(nsIFrame* aFrame) {
|
||||
nsIFrame* parent = aFrame->GetParent();
|
||||
if (parent && (parent = parent->GetParent()) &&
|
||||
(parent = parent->GetParent())) {
|
||||
nsDateTimeControlFrame* dateTimeFrame = do_QueryFrame(parent);
|
||||
if (dateTimeFrame) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsDateTimeTextField(nsIFrame* aFrame) {
|
||||
nsDateTimeControlFrame* dateTimeFrame = do_QueryFrame(aFrame);
|
||||
return dateTimeFrame;
|
||||
}
|
||||
|
||||
static void ComputeCheckColors(const EventStates& aState,
|
||||
sRGBColor& aBackgroundColor,
|
||||
sRGBColor& aBorderColor) {
|
||||
bool isDisabled = aState.HasState(NS_EVENT_STATE_DISABLED);
|
||||
bool isPressed = !isDisabled && aState.HasAllStates(NS_EVENT_STATE_HOVER |
|
||||
NS_EVENT_STATE_ACTIVE);
|
||||
bool isHovered = !isDisabled && aState.HasState(NS_EVENT_STATE_HOVER);
|
||||
bool isFocused = aState.HasState(NS_EVENT_STATE_FOCUS);
|
||||
bool isChecked = aState.HasState(NS_EVENT_STATE_CHECKED);
|
||||
|
||||
sRGBColor fillColor = sBackgroundColor;
|
||||
sRGBColor borderColor = sBorderColor;
|
||||
if (isDisabled) {
|
||||
if (isChecked) {
|
||||
fillColor = borderColor = sCheckBackgroundColorDisabled;
|
||||
} else {
|
||||
fillColor = sBackgroundColor;
|
||||
borderColor = sBorderColorDisabled;
|
||||
}
|
||||
} else {
|
||||
if (isChecked) {
|
||||
if (isPressed) {
|
||||
fillColor = borderColor = sCheckBackgroundActiveColor;
|
||||
} else if (isHovered) {
|
||||
fillColor = borderColor = sCheckBackgroundHoverColor;
|
||||
} else {
|
||||
fillColor = borderColor = sCheckBackgroundColor;
|
||||
}
|
||||
} else if (isPressed) {
|
||||
fillColor = sBackgroundActiveColor;
|
||||
borderColor = sBorderHoverColor;
|
||||
} else if (isFocused) {
|
||||
fillColor = sBackgroundActiveColor;
|
||||
borderColor = sBorderFocusColor;
|
||||
} else if (isHovered) {
|
||||
fillColor = sBackgroundColor;
|
||||
borderColor = sBorderHoverColor;
|
||||
} else {
|
||||
fillColor = sBackgroundColor;
|
||||
borderColor = sBorderColor;
|
||||
}
|
||||
}
|
||||
|
||||
aBackgroundColor = fillColor;
|
||||
aBorderColor = borderColor;
|
||||
}
|
||||
|
||||
// Checkbox and radio need to preserve aspect-ratio for compat.
|
||||
static Rect FixAspectRatio(const Rect& aRect) {
|
||||
Rect rect(aRect);
|
||||
if (rect.width == rect.height) {
|
||||
return rect;
|
||||
}
|
||||
|
||||
if (rect.width > rect.height) {
|
||||
auto diff = rect.width - rect.height;
|
||||
rect.width = rect.height;
|
||||
rect.x += diff / 2;
|
||||
} else {
|
||||
auto diff = rect.height - rect.width;
|
||||
rect.height = rect.width;
|
||||
rect.y += diff / 2;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
// This pushes and pops a clip rect to the draw target.
|
||||
//
|
||||
// This is done to reduce fuzz in places where we may have antialiasing, because
|
||||
// skia is not clip-invariant: given different clips, it does not guarantee the
|
||||
// same result, even if the painted content doesn't intersect the clips.
|
||||
//
|
||||
// This is a bit sad, overall, but...
|
||||
struct MOZ_RAII AutoClipRect {
|
||||
AutoClipRect(DrawTarget& aDt, const Rect& aRect) : mDt(aDt) {
|
||||
mDt.PushClipRect(aRect);
|
||||
}
|
||||
|
||||
~AutoClipRect() { mDt.PopClip(); }
|
||||
|
||||
private:
|
||||
DrawTarget& mDt;
|
||||
};
|
||||
|
||||
static void PaintRoundedRectWithBorder(DrawTarget* aDrawTarget,
|
||||
const Rect& aRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
CSSCoord aBorderWidth, CSSCoord aRadius,
|
||||
uint32_t aDpi) {
|
||||
const LayoutDeviceCoord borderWidth(aBorderWidth * aDpi);
|
||||
const LayoutDeviceCoord radius(aRadius * aDpi);
|
||||
|
||||
Rect rect(aRect);
|
||||
// Deflate the rect by half the border width, so that the middle of the stroke
|
||||
// fills exactly the area we want to fill and not more.
|
||||
rect.Deflate(borderWidth * 0.5f);
|
||||
|
||||
RectCornerRadii radii(radius, radius, radius, radius);
|
||||
RefPtr<Path> roundedRect = MakePathForRoundedRect(*aDrawTarget, rect, radii);
|
||||
|
||||
aDrawTarget->Fill(roundedRect, ColorPattern(ToDeviceColor(aBackgroundColor)));
|
||||
aDrawTarget->Stroke(roundedRect, ColorPattern(ToDeviceColor(aBorderColor)),
|
||||
StrokeOptions(borderWidth));
|
||||
}
|
||||
|
||||
static void PaintCheckboxControl(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
const CSSCoord kBorderWidth = 2.0f;
|
||||
const CSSCoord kRadius = 4.0f;
|
||||
|
||||
sRGBColor backgroundColor;
|
||||
sRGBColor borderColor;
|
||||
ComputeCheckColors(aState, backgroundColor, borderColor);
|
||||
PaintRoundedRectWithBorder(aDrawTarget, aRect, backgroundColor, borderColor,
|
||||
kBorderWidth, kRadius, aDpi);
|
||||
}
|
||||
|
||||
static void PaintCheckMark(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
// Points come from the coordinates on a 7X7 unit box centered at 0,0
|
||||
const float checkPolygonX[] = {-2.5, -0.7, 2.5};
|
||||
const float checkPolygonY[] = {-0.3, 1.7, -1.5};
|
||||
const int32_t checkNumPoints = sizeof(checkPolygonX) / sizeof(float);
|
||||
const int32_t checkSize = 8;
|
||||
|
||||
auto center = aRect.Center();
|
||||
|
||||
// Scale the checkmark based on the smallest dimension
|
||||
nscoord paintScale = std::min(aRect.width, aRect.height) / checkSize;
|
||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
|
||||
Point p = center +
|
||||
Point(checkPolygonX[0] * paintScale, checkPolygonY[0] * paintScale);
|
||||
builder->MoveTo(p);
|
||||
for (int32_t polyIndex = 1; polyIndex < checkNumPoints; polyIndex++) {
|
||||
p = center + Point(checkPolygonX[polyIndex] * paintScale,
|
||||
checkPolygonY[polyIndex] * paintScale);
|
||||
builder->LineTo(p);
|
||||
}
|
||||
RefPtr<Path> path = builder->Finish();
|
||||
aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sBackgroundColor)),
|
||||
StrokeOptions(2.0f * aDpi));
|
||||
}
|
||||
|
||||
static void PaintIndeterminateMark(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState) {
|
||||
bool isDisabled = aState.HasState(NS_EVENT_STATE_DISABLED);
|
||||
|
||||
Rect rect(aRect);
|
||||
rect.y += (rect.height - rect.height / 4) / 2;
|
||||
rect.height /= 4;
|
||||
|
||||
aDrawTarget->FillRect(
|
||||
rect, ColorPattern(
|
||||
ToDeviceColor(isDisabled ? sDisabledColor : sBackgroundColor)));
|
||||
}
|
||||
|
||||
static void PaintStrokedEllipse(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
const CSSCoord aBorderWidth, uint32_t aDpi) {
|
||||
const LayoutDeviceCoord borderWidth(aBorderWidth * aDpi);
|
||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
|
||||
|
||||
// Deflate for the same reason as PaintRoundedRectWithBorder. Note that the
|
||||
// size is the diameter, so we just shrink by the border width once.
|
||||
Size size(aRect.Size() - Size(borderWidth, borderWidth));
|
||||
AppendEllipseToPath(builder, aRect.Center(), size);
|
||||
RefPtr<Path> ellipse = builder->Finish();
|
||||
|
||||
aDrawTarget->Fill(ellipse, ColorPattern(ToDeviceColor(aBackgroundColor)));
|
||||
aDrawTarget->Stroke(ellipse, ColorPattern(ToDeviceColor(aBorderColor)),
|
||||
StrokeOptions(borderWidth));
|
||||
}
|
||||
|
||||
static void PaintRadioControl(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
const CSSCoord kBorderWidth = 2.0f;
|
||||
|
||||
sRGBColor backgroundColor;
|
||||
sRGBColor borderColor;
|
||||
ComputeCheckColors(aState, backgroundColor, borderColor);
|
||||
|
||||
PaintStrokedEllipse(aDrawTarget, aRect, backgroundColor, borderColor,
|
||||
kBorderWidth, aDpi);
|
||||
}
|
||||
|
||||
static void PaintCheckedRadioButton(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
uint32_t aDpi) {
|
||||
Rect rect(aRect);
|
||||
rect.x += 4.5f * aDpi;
|
||||
rect.width -= 9.0f * aDpi;
|
||||
rect.y += 4.5f * aDpi;
|
||||
rect.height -= 9.0f * aDpi;
|
||||
|
||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
|
||||
AppendEllipseToPath(builder, rect.Center(), rect.Size());
|
||||
RefPtr<Path> ellipse = builder->Finish();
|
||||
aDrawTarget->Fill(ellipse, ColorPattern(ToDeviceColor(sBackgroundColor)));
|
||||
}
|
||||
|
||||
static sRGBColor ComputeBorderColor(const EventStates& aState) {
|
||||
bool isDisabled = aState.HasState(NS_EVENT_STATE_DISABLED);
|
||||
bool isHovered = !isDisabled && aState.HasState(NS_EVENT_STATE_HOVER);
|
||||
bool isFocused = aState.HasState(NS_EVENT_STATE_FOCUS);
|
||||
if (isFocused) {
|
||||
return sBorderFocusColor;
|
||||
}
|
||||
if (isHovered) {
|
||||
return sBorderHoverColor;
|
||||
}
|
||||
return sBorderColor;
|
||||
}
|
||||
|
||||
static void PaintTextField(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
bool isDisabled = aState.HasState(NS_EVENT_STATE_DISABLED);
|
||||
const sRGBColor& backgroundColor =
|
||||
isDisabled ? sDisabledColor : sBackgroundColor;
|
||||
const sRGBColor borderColor = ComputeBorderColor(aState);
|
||||
|
||||
const CSSCoord kRadius = 4.0f;
|
||||
|
||||
PaintRoundedRectWithBorder(aDrawTarget, aRect, backgroundColor, borderColor,
|
||||
kTextFieldBorderWidth, kRadius, aDpi);
|
||||
}
|
||||
|
||||
std::pair<sRGBColor, sRGBColor> ComputeButtonColors(
|
||||
const EventStates& aState, bool aIsDatetimeResetButton = false) {
|
||||
bool isActive =
|
||||
aState.HasAllStates(NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE);
|
||||
bool isDisabled = aState.HasState(NS_EVENT_STATE_DISABLED);
|
||||
bool isHovered = !isDisabled && aState.HasState(NS_EVENT_STATE_HOVER);
|
||||
|
||||
const sRGBColor& backgroundColor = [&] {
|
||||
if (isDisabled) {
|
||||
return sDisabledColor;
|
||||
}
|
||||
if (aIsDatetimeResetButton) {
|
||||
return sWhiteColor;
|
||||
}
|
||||
if (isActive) {
|
||||
return sButtonActiveColor;
|
||||
}
|
||||
if (isHovered) {
|
||||
return sButtonHoverColor;
|
||||
}
|
||||
return sButtonColor;
|
||||
}();
|
||||
|
||||
const sRGBColor borderColor = ComputeBorderColor(aState);
|
||||
|
||||
return std::make_pair(backgroundColor, borderColor);
|
||||
}
|
||||
|
||||
static void PaintMenulist(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
const CSSCoord kRadius = 4.0f;
|
||||
|
||||
sRGBColor backgroundColor, borderColor;
|
||||
std::tie(backgroundColor, borderColor) = ComputeButtonColors(aState);
|
||||
|
||||
PaintRoundedRectWithBorder(aDrawTarget, aRect, backgroundColor, borderColor,
|
||||
kMenulistBorderWidth, kRadius, aDpi);
|
||||
}
|
||||
|
||||
static void PaintArrow(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const int32_t aArrowPolygonX[],
|
||||
const int32_t aArrowPolygonY[],
|
||||
const int32_t aArrowNumPoints, const int32_t aArrowSize,
|
||||
const sRGBColor aFillColor, uint32_t aDpi) {
|
||||
nscoord paintScale = std::min(aRect.width, aRect.height) / aArrowSize;
|
||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
|
||||
Point p = aRect.Center() + Point(aArrowPolygonX[0] * paintScale,
|
||||
aArrowPolygonY[0] * paintScale);
|
||||
|
||||
builder->MoveTo(p);
|
||||
for (int32_t polyIndex = 1; polyIndex < aArrowNumPoints; polyIndex++) {
|
||||
p = aRect.Center() + Point(aArrowPolygonX[polyIndex] * paintScale,
|
||||
aArrowPolygonY[polyIndex] * paintScale);
|
||||
builder->LineTo(p);
|
||||
}
|
||||
RefPtr<Path> path = builder->Finish();
|
||||
|
||||
aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(aFillColor)),
|
||||
StrokeOptions(2.0f * aDpi));
|
||||
}
|
||||
|
||||
static void PaintMenulistArrowButton(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
bool isDisabled = aState.HasState(NS_EVENT_STATE_DISABLED);
|
||||
bool isPressed = !isDisabled && aState.HasAllStates(NS_EVENT_STATE_HOVER |
|
||||
NS_EVENT_STATE_ACTIVE);
|
||||
bool isHovered = !isDisabled && aState.HasState(NS_EVENT_STATE_HOVER);
|
||||
bool isHTML = nsNativeTheme::IsHTMLContent(aFrame);
|
||||
|
||||
if (!isHTML && nsNativeTheme::CheckBooleanAttr(aFrame, nsGkAtoms::open)) {
|
||||
isHovered = false;
|
||||
}
|
||||
|
||||
const int32_t arrowSize = 8;
|
||||
int32_t arrowPolygonX[] = {-4, -2, 0};
|
||||
int32_t arrowPolygonY[] = {-1, 1, -1};
|
||||
const int32_t arrowNumPoints = sizeof(arrowPolygonX) / sizeof(int32_t);
|
||||
|
||||
PaintArrow(
|
||||
aDrawTarget, aRect, arrowPolygonX, arrowPolygonY, arrowNumPoints,
|
||||
arrowSize,
|
||||
isPressed ? sActiveColor : isHovered ? sBorderHoverColor : sBorderColor,
|
||||
aDpi);
|
||||
}
|
||||
|
||||
static void PaintSpinnerButton(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState,
|
||||
StyleAppearance aAppearance, uint32_t aDpi) {
|
||||
bool isDisabled = aState.HasState(NS_EVENT_STATE_DISABLED);
|
||||
bool isPressed = !isDisabled && aState.HasAllStates(NS_EVENT_STATE_HOVER |
|
||||
NS_EVENT_STATE_ACTIVE);
|
||||
bool isHovered = !isDisabled && aState.HasState(NS_EVENT_STATE_HOVER);
|
||||
|
||||
const int32_t arrowSize = 8;
|
||||
int32_t arrowPolygonX[] = {0, 2, 4};
|
||||
int32_t arrowPolygonY[] = {-3, -1, -3};
|
||||
const int32_t arrowNumPoints = sizeof(arrowPolygonX) / sizeof(int32_t);
|
||||
|
||||
if (aAppearance == StyleAppearance::SpinnerUpbutton) {
|
||||
for (int32_t i = 0; i < arrowNumPoints; i++) {
|
||||
arrowPolygonY[i] *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
PaintArrow(
|
||||
aDrawTarget, aRect, arrowPolygonX, arrowPolygonY, arrowNumPoints,
|
||||
arrowSize,
|
||||
isPressed ? sActiveColor : isHovered ? sBorderHoverColor : sBorderColor,
|
||||
aDpi);
|
||||
}
|
||||
|
||||
static void PaintRangeInputBackground(DrawTarget* aDrawTarget,
|
||||
const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi,
|
||||
bool aHorizontal) {
|
||||
Rect rect(aRect);
|
||||
const LayoutDeviceCoord kVerticalSize = kMinimumWidgetSize * 0.25f * aDpi;
|
||||
|
||||
if (aHorizontal) {
|
||||
rect.y += (rect.height - kVerticalSize) / 2;
|
||||
rect.height = kVerticalSize;
|
||||
} else {
|
||||
rect.x += (rect.width - kVerticalSize) / 2;
|
||||
rect.width = kVerticalSize;
|
||||
}
|
||||
|
||||
aDrawTarget->FillRect(
|
||||
rect, ColorPattern(ToDeviceColor(sRangeInputBackgroundColor)));
|
||||
aDrawTarget->StrokeRect(rect,
|
||||
ColorPattern(ToDeviceColor(sButtonActiveColor)));
|
||||
}
|
||||
|
||||
static void PaintScrollbarthumbHorizontal(DrawTarget* aDrawTarget,
|
||||
const Rect& aRect,
|
||||
const EventStates& aState) {
|
||||
sRGBColor thumbColor = sScrollbarThumbColor;
|
||||
if (aState.HasAllStates(NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE)) {
|
||||
thumbColor = sScrollbarThumbColorActive;
|
||||
} else if (aState.HasState(NS_EVENT_STATE_HOVER)) {
|
||||
thumbColor = sScrollbarThumbColorHover;
|
||||
}
|
||||
aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(thumbColor)));
|
||||
}
|
||||
|
||||
static void PaintScrollbarthumbVertical(DrawTarget* aDrawTarget,
|
||||
const Rect& aRect,
|
||||
const EventStates& aState) {
|
||||
sRGBColor thumbColor = sScrollbarThumbColor;
|
||||
if (aState.HasAllStates(NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE)) {
|
||||
thumbColor = sScrollbarThumbColorActive;
|
||||
} else if (aState.HasState(NS_EVENT_STATE_HOVER)) {
|
||||
thumbColor = sScrollbarThumbColorHover;
|
||||
}
|
||||
aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(thumbColor)));
|
||||
}
|
||||
|
||||
static void PaintScrollbarHorizontal(DrawTarget* aDrawTarget,
|
||||
const Rect& aRect) {
|
||||
aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(sScrollbarColor)));
|
||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
|
||||
builder->MoveTo(Point(aRect.x, aRect.y));
|
||||
builder->LineTo(Point(aRect.x + aRect.width, aRect.y));
|
||||
RefPtr<Path> path = builder->Finish();
|
||||
aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sScrollbarBorderColor)));
|
||||
}
|
||||
|
||||
static void PaintScrollbarVerticalAndCorner(DrawTarget* aDrawTarget,
|
||||
const Rect& aRect, uint32_t aDpi) {
|
||||
aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(sScrollbarColor)));
|
||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
|
||||
builder->MoveTo(Point(aRect.x, aRect.y));
|
||||
builder->LineTo(Point(aRect.x, aRect.y + aRect.height));
|
||||
RefPtr<Path> path = builder->Finish();
|
||||
aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sScrollbarBorderColor)),
|
||||
StrokeOptions(1.0f * aDpi));
|
||||
}
|
||||
|
||||
static void PaintScrollbarbutton(DrawTarget* aDrawTarget,
|
||||
StyleAppearance aAppearance, const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
bool isActive =
|
||||
aState.HasAllStates(NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE);
|
||||
bool isHovered = aState.HasState(NS_EVENT_STATE_HOVER);
|
||||
|
||||
aDrawTarget->FillRect(
|
||||
aRect, ColorPattern(
|
||||
ToDeviceColor(isActive ? sScrollbarButtonActiveColor
|
||||
: isHovered ? sScrollbarButtonHoverColor
|
||||
: sScrollbarColor)));
|
||||
|
||||
// Start with Up arrow.
|
||||
int32_t arrowPolygonX[] = {3, 0, -3};
|
||||
int32_t arrowPolygonY[] = {2, -1, 2};
|
||||
const int32_t arrowNumPoints = sizeof(arrowPolygonX) / sizeof(int32_t);
|
||||
const int32_t arrowSize = 14;
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
break;
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
for (int32_t i = 0; i < arrowNumPoints; i++) {
|
||||
arrowPolygonY[i] *= -1;
|
||||
}
|
||||
break;
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
for (int32_t i = 0; i < arrowNumPoints; i++) {
|
||||
int32_t temp = arrowPolygonX[i];
|
||||
arrowPolygonX[i] = arrowPolygonY[i];
|
||||
arrowPolygonY[i] = temp;
|
||||
}
|
||||
break;
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
for (int32_t i = 0; i < arrowNumPoints; i++) {
|
||||
int32_t temp = arrowPolygonX[i];
|
||||
arrowPolygonX[i] = arrowPolygonY[i] * -1;
|
||||
arrowPolygonY[i] = temp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
PaintArrow(aDrawTarget, aRect, arrowPolygonX, arrowPolygonY, arrowNumPoints,
|
||||
arrowSize,
|
||||
isActive
|
||||
? sScrollbarArrowColorActive
|
||||
: isHovered ? sScrollbarArrowColorHover : sScrollbarArrowColor,
|
||||
aDpi);
|
||||
|
||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
|
||||
builder->MoveTo(Point(aRect.x, aRect.y));
|
||||
if (aAppearance == StyleAppearance::ScrollbarbuttonUp ||
|
||||
aAppearance == StyleAppearance::ScrollbarbuttonDown) {
|
||||
builder->LineTo(Point(aRect.x, aRect.y + aRect.height));
|
||||
} else {
|
||||
builder->LineTo(Point(aRect.x + aRect.width, aRect.y));
|
||||
}
|
||||
|
||||
RefPtr<Path> path = builder->Finish();
|
||||
aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sScrollbarBorderColor)),
|
||||
StrokeOptions(1.0f * aDpi));
|
||||
}
|
||||
|
||||
static void PaintButton(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
const Rect& aRect, const EventStates& aState,
|
||||
uint32_t aDpi) {
|
||||
const CSSCoord kRadius = 4.0f;
|
||||
|
||||
// FIXME: The DateTimeResetButton bit feels like a bit of a hack.
|
||||
sRGBColor backgroundColor, borderColor;
|
||||
std::tie(backgroundColor, borderColor) =
|
||||
ComputeButtonColors(aState, IsDateTimeResetButton(aFrame));
|
||||
|
||||
PaintRoundedRectWithBorder(aDrawTarget, aRect, backgroundColor, borderColor,
|
||||
kButtonBorderWidth, kRadius, aDpi);
|
||||
}
|
||||
|
||||
static void PaintRangeThumb(DrawTarget* aDrawTarget, const Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpi) {
|
||||
const CSSCoord kBorderWidth = 2.0f;
|
||||
|
||||
sRGBColor backgroundColor, borderColor;
|
||||
std::tie(backgroundColor, borderColor) = ComputeButtonColors(aState);
|
||||
|
||||
PaintStrokedEllipse(aDrawTarget, aRect, backgroundColor, borderColor,
|
||||
kBorderWidth, aDpi);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeAndroid::DrawWidgetBackground(
|
||||
gfxContext* aContext, nsIFrame* aFrame, StyleAppearance aAppearance,
|
||||
const nsRect& aRect, const nsRect& /* aDirtyRect */) {
|
||||
DrawTarget* dt = aContext->GetDrawTarget();
|
||||
const nscoord twipsPerPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
EventStates eventState = GetContentState(aFrame, aAppearance);
|
||||
|
||||
Rect devPxRect = NSRectToSnappedRect(aRect, twipsPerPixel, *dt);
|
||||
AutoClipRect clip(*dt, devPxRect);
|
||||
|
||||
if (aAppearance == StyleAppearance::MozMenulistArrowButton) {
|
||||
bool isHTML = IsHTMLContent(aFrame);
|
||||
nsIFrame* parentFrame = aFrame->GetParent();
|
||||
bool isMenulist = !isHTML && parentFrame->IsMenuFrame();
|
||||
// HTML select and XUL menulist dropdown buttons get state from the
|
||||
// parent.
|
||||
if (isHTML || isMenulist) {
|
||||
aFrame = parentFrame;
|
||||
eventState = GetContentState(parentFrame, aAppearance);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t dpi = GetDPIRatio(aFrame);
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Radio: {
|
||||
auto rect = FixAspectRatio(devPxRect);
|
||||
PaintRadioControl(dt, rect, eventState, dpi);
|
||||
if (IsSelected(aFrame)) {
|
||||
PaintCheckedRadioButton(dt, rect, dpi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case StyleAppearance::Checkbox: {
|
||||
auto rect = FixAspectRatio(devPxRect);
|
||||
PaintCheckboxControl(dt, rect, eventState, dpi);
|
||||
if (IsChecked(aFrame)) {
|
||||
PaintCheckMark(dt, rect, eventState, dpi);
|
||||
}
|
||||
if (GetIndeterminate(aFrame)) {
|
||||
PaintIndeterminateMark(dt, rect, eventState);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case StyleAppearance::Textarea:
|
||||
case StyleAppearance::Textfield:
|
||||
case StyleAppearance::NumberInput:
|
||||
PaintTextField(dt, devPxRect, eventState, dpi);
|
||||
break;
|
||||
case StyleAppearance::Listbox:
|
||||
case StyleAppearance::Menulist:
|
||||
case StyleAppearance::MenulistButton:
|
||||
PaintMenulist(dt, devPxRect, eventState, dpi);
|
||||
break;
|
||||
case StyleAppearance::MozMenulistArrowButton:
|
||||
PaintMenulistArrowButton(aFrame, dt, devPxRect, eventState, dpi);
|
||||
break;
|
||||
case StyleAppearance::SpinnerUpbutton:
|
||||
case StyleAppearance::SpinnerDownbutton:
|
||||
PaintSpinnerButton(dt, devPxRect, eventState, aAppearance, dpi);
|
||||
break;
|
||||
case StyleAppearance::Range:
|
||||
PaintRangeInputBackground(dt, devPxRect, eventState, dpi,
|
||||
IsRangeHorizontal(aFrame));
|
||||
break;
|
||||
case StyleAppearance::RangeThumb:
|
||||
// TODO(emilio): Do we want to enforce it being a circle using
|
||||
// FixAspectRatio here? For now let authors tweak, it's a custom pseudo so
|
||||
// it doesn't probably have much compat impact if at all.
|
||||
PaintRangeThumb(dt, devPxRect, eventState, dpi);
|
||||
break;
|
||||
case StyleAppearance::ScrollbarthumbHorizontal:
|
||||
PaintScrollbarthumbHorizontal(dt, devPxRect, eventState);
|
||||
break;
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
PaintScrollbarthumbVertical(dt, devPxRect, eventState);
|
||||
break;
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
PaintScrollbarHorizontal(dt, devPxRect);
|
||||
break;
|
||||
case StyleAppearance::ScrollbarVertical:
|
||||
case StyleAppearance::Scrollcorner:
|
||||
PaintScrollbarVerticalAndCorner(dt, devPxRect, dpi);
|
||||
break;
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
PaintScrollbarbutton(dt, aAppearance, devPxRect, eventState, dpi);
|
||||
break;
|
||||
case StyleAppearance::Button:
|
||||
PaintButton(aFrame, dt, devPxRect, eventState, dpi);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Should not get here with a widget type we don't support.");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*bool
|
||||
nsNativeBasicThemeAndroid::CreateWebRenderCommandsForWidget(mozilla::wr::DisplayListBuilder&
|
||||
aBuilder, mozilla::wr::IpcResourceUpdateQueue& aResources, const
|
||||
mozilla::layers::StackingContextHelper& aSc,
|
||||
mozilla::layers::RenderRootStateManager*
|
||||
aManager, nsIFrame* aFrame, StyleAppearance aAppearance, const nsRect& aRect) {
|
||||
}*/
|
||||
|
||||
LayoutDeviceIntMargin nsNativeBasicThemeAndroid::GetWidgetBorder(
|
||||
nsDeviceContext* aContext, nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
uint32_t dpi = GetDPIRatio(aFrame);
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Textfield:
|
||||
case StyleAppearance::Textarea:
|
||||
case StyleAppearance::NumberInput: {
|
||||
const LayoutDeviceIntCoord w = kTextFieldBorderWidth * dpi;
|
||||
return LayoutDeviceIntMargin(w, w, w, w);
|
||||
}
|
||||
case StyleAppearance::Listbox:
|
||||
case StyleAppearance::Menulist:
|
||||
case StyleAppearance::MenulistButton: {
|
||||
const LayoutDeviceIntCoord w = kMenulistBorderWidth * dpi;
|
||||
return LayoutDeviceIntMargin(w, w, w, w);
|
||||
}
|
||||
case StyleAppearance::Button: {
|
||||
const LayoutDeviceIntCoord w = kButtonBorderWidth * dpi;
|
||||
return LayoutDeviceIntMargin(w, w, w, w);
|
||||
}
|
||||
default:
|
||||
return LayoutDeviceIntMargin();
|
||||
}
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::GetWidgetPadding(
|
||||
nsDeviceContext* aContext, nsIFrame* aFrame, StyleAppearance aAppearance,
|
||||
LayoutDeviceIntMargin* aResult) {
|
||||
uint32_t dpiRatio = GetDPIRatio(aFrame);
|
||||
switch (aAppearance) {
|
||||
// Radios and checkboxes return a fixed size in GetMinimumWidgetSize
|
||||
// and have a meaningful baseline, so they can't have
|
||||
// author-specified padding.
|
||||
case StyleAppearance::Radio:
|
||||
case StyleAppearance::Checkbox:
|
||||
aResult->SizeTo(0, 0, 0, 0);
|
||||
return true;
|
||||
case StyleAppearance::MozMenulistArrowButton:
|
||||
aResult->SizeTo(1 * dpiRatio, 4 * dpiRatio, 1 * dpiRatio, 4 * dpiRatio);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Respect author padding.
|
||||
//
|
||||
// TODO(emilio): Consider just unconditionally returning false, so that the
|
||||
// default size of all elements matches other platforms and the UA stylesheet.
|
||||
if (aFrame->PresContext()->HasAuthorSpecifiedRules(
|
||||
aFrame, NS_AUTHOR_SPECIFIED_PADDING)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t dpi = GetDPIRatio(aFrame);
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Textarea:
|
||||
case StyleAppearance::Listbox:
|
||||
case StyleAppearance::Menulist:
|
||||
case StyleAppearance::MenulistButton:
|
||||
case StyleAppearance::NumberInput:
|
||||
aResult->SizeTo(6 * dpi, 7 * dpi, 6 * dpi, 7 * dpi);
|
||||
return true;
|
||||
case StyleAppearance::Button:
|
||||
aResult->SizeTo(6 * dpi, 21 * dpi, 6 * dpi, 21 * dpi);
|
||||
return true;
|
||||
case StyleAppearance::Textfield:
|
||||
if (IsDateTimeTextField(aFrame)) {
|
||||
aResult->SizeTo(7 * dpi, 7 * dpi, 5 * dpi, 7 * dpi);
|
||||
return true;
|
||||
}
|
||||
aResult->SizeTo(6 * dpi, 7 * dpi, 6 * dpi, 7 * dpi);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::GetWidgetOverflow(nsDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
nsRect* aOverflowRect) {
|
||||
// TODO(bug 1620360): This should return non-zero for
|
||||
// StyleAppearance::FocusOutline, if we implement outline-style: auto.
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeAndroid::GetMinimumWidgetSize(nsPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) {
|
||||
uint32_t dpiRatio = GetDPIRatio(aFrame);
|
||||
aResult->width = aResult->height =
|
||||
static_cast<uint32_t>(kMinimumWidgetSize) * dpiRatio;
|
||||
*aIsOverridable = true;
|
||||
if (aAppearance == StyleAppearance::MozMenulistArrowButton) {
|
||||
aResult->width =
|
||||
static_cast<uint32_t>(kMinimumDropdownArrowButtonWidth) * dpiRatio;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsITheme::Transparency nsNativeBasicThemeAndroid::GetWidgetTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
return eUnknownTransparency;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeAndroid::WidgetStateChanged(nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
nsAtom* aAttribute,
|
||||
bool* aShouldRepaint,
|
||||
const nsAttrValue* aOldValue) {
|
||||
if (!aAttribute) {
|
||||
// Hover/focus/active changed. Always repaint.
|
||||
*aShouldRepaint = true;
|
||||
} else {
|
||||
// Check the attribute to see if it's relevant.
|
||||
// disabled, checked, dlgtype, default, etc.
|
||||
*aShouldRepaint = false;
|
||||
if ((aAttribute == nsGkAtoms::disabled) ||
|
||||
(aAttribute == nsGkAtoms::checked) ||
|
||||
(aAttribute == nsGkAtoms::selected) ||
|
||||
(aAttribute == nsGkAtoms::visuallyselected) ||
|
||||
(aAttribute == nsGkAtoms::menuactive) ||
|
||||
(aAttribute == nsGkAtoms::sortDirection) ||
|
||||
(aAttribute == nsGkAtoms::focused) ||
|
||||
(aAttribute == nsGkAtoms::_default) ||
|
||||
(aAttribute == nsGkAtoms::open) || (aAttribute == nsGkAtoms::hover)) {
|
||||
*aShouldRepaint = true;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeAndroid::ThemeChanged() { return NS_OK; }
|
||||
|
||||
bool nsNativeBasicThemeAndroid::WidgetAppearanceDependsOnWindowFocus(
|
||||
StyleAppearance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsITheme::ThemeGeometryType
|
||||
nsNativeBasicThemeAndroid::ThemeGeometryTypeForWidget(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
return eThemeGeometryTypeUnknown;
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::ThemeSupportsWidget(
|
||||
nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) {
|
||||
if (IsWidgetScrollbarPart(aAppearance)) {
|
||||
const auto* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
// We don't currently handle custom scrollbars on nsNativeBasicThemeAndroid.
|
||||
// We could, potentially.
|
||||
if (style->StyleUI()->HasCustomScrollbars() ||
|
||||
style->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Radio:
|
||||
case StyleAppearance::Checkbox:
|
||||
case StyleAppearance::Textarea:
|
||||
case StyleAppearance::Textfield:
|
||||
case StyleAppearance::Range:
|
||||
case StyleAppearance::RangeThumb:
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
case StyleAppearance::ScrollbarthumbHorizontal:
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
case StyleAppearance::ScrollbarNonDisappearing:
|
||||
case StyleAppearance::ScrollbarVertical:
|
||||
case StyleAppearance::Scrollcorner:
|
||||
case StyleAppearance::Button:
|
||||
case StyleAppearance::Listbox:
|
||||
case StyleAppearance::Menulist:
|
||||
case StyleAppearance::MenulistButton:
|
||||
case StyleAppearance::NumberInput:
|
||||
case StyleAppearance::MozMenulistArrowButton:
|
||||
case StyleAppearance::SpinnerUpbutton:
|
||||
case StyleAppearance::SpinnerDownbutton:
|
||||
return !IsWidgetStyled(aPresContext, aFrame, aAppearance);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::WidgetIsContainer(StyleAppearance aAppearance) {
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::MozMenulistArrowButton:
|
||||
case StyleAppearance::Radio:
|
||||
case StyleAppearance::Checkbox:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::ThemeDrawsFocusForWidget(
|
||||
StyleAppearance aAppearance) {
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Range:
|
||||
// TODO(emilio): Checkbox / Radio don't have focus indicators when checked.
|
||||
// If they did, we could just return true here unconditionally.
|
||||
case StyleAppearance::Checkbox:
|
||||
case StyleAppearance::Radio:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::ThemeNeedsComboboxDropmarker() { return true; }
|
||||
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
static StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeAndroid();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
||||
|
||||
// On Android there's no native theme.
|
||||
already_AddRefed<nsITheme> do_GetNativeThemeDoNotUseDirectly() {
|
||||
return do_GetBasicNativeThemeDoNotUseDirectly();
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/* -*- 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 nsNativeBasicThemeAndroid_h
|
||||
#define nsNativeBasicThemeAndroid_h
|
||||
|
||||
#include "nsITheme.h"
|
||||
#include "nsNativeTheme.h"
|
||||
|
||||
class nsNativeBasicThemeAndroid : private nsNativeTheme, public nsITheme {
|
||||
public:
|
||||
nsNativeBasicThemeAndroid() = default;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// The nsITheme interface.
|
||||
NS_IMETHOD DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect) override;
|
||||
/*bool CreateWebRenderCommandsForWidget(mozilla::wr::DisplayListBuilder&
|
||||
aBuilder, mozilla::wr::IpcResourceUpdateQueue& aResources, const
|
||||
mozilla::layers::StackingContextHelper& aSc,
|
||||
mozilla::layers::RenderRootStateManager*
|
||||
aManager, nsIFrame* aFrame, StyleAppearance aAppearance, const nsRect&
|
||||
aRect) override;*/
|
||||
[[nodiscard]] LayoutDeviceIntMargin GetWidgetBorder(
|
||||
nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) override;
|
||||
bool GetWidgetPadding(nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
LayoutDeviceIntMargin* aResult) override;
|
||||
virtual bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
nsRect* aOverflowRect) override;
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) override;
|
||||
virtual Transparency GetWidgetTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) override;
|
||||
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, StyleAppearance aAppearance,
|
||||
nsAtom* aAttribute, bool* aShouldRepaint,
|
||||
const nsAttrValue* aOldValue) override;
|
||||
NS_IMETHOD ThemeChanged() override;
|
||||
virtual bool WidgetAppearanceDependsOnWindowFocus(
|
||||
StyleAppearance aAppearance) override;
|
||||
/*virtual bool NeedToClearBackgroundBehindWidget(nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance)
|
||||
override;*/
|
||||
virtual ThemeGeometryType ThemeGeometryTypeForWidget(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) override;
|
||||
bool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) override;
|
||||
bool WidgetIsContainer(StyleAppearance aAppearance) override;
|
||||
bool ThemeDrawsFocusForWidget(StyleAppearance aAppearance) override;
|
||||
bool ThemeNeedsComboboxDropmarker() override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeAndroid() = default;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -54,6 +54,7 @@ UNIFIED_SOURCES += [
|
|||
'nsMenuItemX.mm',
|
||||
'nsMenuUtilsX.mm',
|
||||
'nsMenuX.mm',
|
||||
'nsNativeBasicThemeCocoa.cpp',
|
||||
'nsPrintDialogX.mm',
|
||||
'nsPrintSettingsServiceX.mm',
|
||||
'nsPrintSettingsX.mm',
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* -*- Mode: C++; tab-width: 40; 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 "nsNativeBasicThemeCocoa.h"
|
||||
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
static StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeCocoa();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- 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 nsNativeBasicThemeCocoa_h
|
||||
#define nsNativeBasicThemeCocoa_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
class nsNativeBasicThemeCocoa : public nsNativeBasicTheme {
|
||||
public:
|
||||
nsNativeBasicThemeCocoa() = default;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeCocoa() = default;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -3756,8 +3756,7 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame*
|
|||
}
|
||||
|
||||
case StyleAppearance::Menulist:
|
||||
case StyleAppearance::MenulistButton:
|
||||
case StyleAppearance::MozMenulistArrowButton: {
|
||||
case StyleAppearance::MenulistButton: {
|
||||
SInt32 popupHeight = 0;
|
||||
::GetThemeMetric(kThemeMetricPopupButtonHeight, &popupHeight);
|
||||
aResult->SizeTo(0, popupHeight);
|
||||
|
@ -3875,6 +3874,7 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame*
|
|||
break;
|
||||
}
|
||||
|
||||
case StyleAppearance::MozMenulistArrowButton:
|
||||
case StyleAppearance::ScrollbarNonDisappearing: {
|
||||
int32_t themeMetric = kThemeMetricScrollBarWidth;
|
||||
SInt32 scrollbarWidth = 0;
|
||||
|
|
|
@ -41,6 +41,7 @@ UNIFIED_SOURCES += [
|
|||
'nsGtkKeyUtils.cpp',
|
||||
'nsImageToPixbuf.cpp',
|
||||
'nsLookAndFeel.cpp',
|
||||
'nsNativeBasicThemeGTK.cpp',
|
||||
'nsNativeThemeGTK.cpp',
|
||||
'nsSound.cpp',
|
||||
'nsToolkit.cpp',
|
||||
|
@ -134,6 +135,7 @@ FINAL_LIBRARY = 'xul'
|
|||
|
||||
LOCAL_INCLUDES += [
|
||||
'/layout/base',
|
||||
'/layout/forms',
|
||||
'/layout/generic',
|
||||
'/layout/xul',
|
||||
'/other-licenses/atk-1.0',
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* -*- Mode: C++; tab-width: 40; 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 "nsNativeBasicThemeGTK.h"
|
||||
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
static StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeGTK();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- 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 nsNativeBasicThemeGTK_h
|
||||
#define nsNativeBasicThemeGTK_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
class nsNativeBasicThemeGTK : public nsNativeBasicTheme {
|
||||
public:
|
||||
nsNativeBasicThemeGTK() = default;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeGTK() = default;
|
||||
};
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,13 +7,97 @@
|
|||
#ifndef nsNativeBasicTheme_h
|
||||
#define nsNativeBasicTheme_h
|
||||
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/HTMLMeterElement.h"
|
||||
#include "mozilla/dom/HTMLProgressElement.h"
|
||||
#include "nsColorControlFrame.h"
|
||||
#include "nsDateTimeControlFrame.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsMeterFrame.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "nsProgressFrame.h"
|
||||
#include "nsRangeFrame.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
static const sRGBColor sColorWhite(sRGBColor::OpaqueWhite());
|
||||
static const sRGBColor sColorWhiteAlpha50(sRGBColor::White(0.5f));
|
||||
static const sRGBColor sColorWhiteAlpha80(sRGBColor::White(0.8f));
|
||||
static const sRGBColor sColorBlack(sRGBColor::OpaqueBlack());
|
||||
|
||||
static const sRGBColor sColorGrey10(sRGBColor::UnusualFromARGB(0xffe9e9ed));
|
||||
static const sRGBColor sColorGrey10Alpha50(
|
||||
sRGBColor::UnusualFromARGB(0x7fe9e9ed));
|
||||
static const sRGBColor sColorGrey20(sRGBColor::UnusualFromARGB(0xffd0d0d7));
|
||||
static const sRGBColor sColorGrey30(sRGBColor::UnusualFromARGB(0xffb1b1b9));
|
||||
static const sRGBColor sColorGrey40(sRGBColor::UnusualFromARGB(0xff8f8f9d));
|
||||
static const sRGBColor sColorGrey40Alpha50(
|
||||
sRGBColor::UnusualFromARGB(0x7f8f8f9d));
|
||||
static const sRGBColor sColorGrey50(sRGBColor::UnusualFromARGB(0xff676774));
|
||||
static const sRGBColor sColorGrey50Alpha50(
|
||||
sRGBColor::UnusualFromARGB(0x7f676774));
|
||||
static const sRGBColor sColorGrey60(sRGBColor::UnusualFromARGB(0xff484851));
|
||||
static const sRGBColor sColorGrey60Alpha50(
|
||||
sRGBColor::UnusualFromARGB(0x7f484851));
|
||||
|
||||
static const sRGBColor sColorAccentLight(
|
||||
sRGBColor::UnusualFromARGB(0x4d008deb));
|
||||
static const sRGBColor sColorAccent(sRGBColor::UnusualFromARGB(0xff0060df));
|
||||
static const sRGBColor sColorAccentDark(sRGBColor::UnusualFromARGB(0xff0250bb));
|
||||
static const sRGBColor sColorAccentDarker(
|
||||
sRGBColor::UnusualFromARGB(0xff054096));
|
||||
|
||||
static const sRGBColor sColorMeterGreen10(
|
||||
sRGBColor::UnusualFromARGB(0xff00ab60));
|
||||
static const sRGBColor sColorMeterGreen20(
|
||||
sRGBColor::UnusualFromARGB(0xff056139));
|
||||
static const sRGBColor sColorMeterYellow10(
|
||||
sRGBColor::UnusualFromARGB(0xffffbd4f));
|
||||
static const sRGBColor sColorMeterYellow20(
|
||||
sRGBColor::UnusualFromARGB(0xffd2811e));
|
||||
static const sRGBColor sColorMeterRed10(sRGBColor::UnusualFromARGB(0xffe22850));
|
||||
static const sRGBColor sColorMeterRed20(sRGBColor::UnusualFromARGB(0xff810220));
|
||||
|
||||
static const sRGBColor sScrollbarColor(sRGBColor(0.94f, 0.94f, 0.94f));
|
||||
static const sRGBColor sScrollbarBorderColor(sRGBColor(1.0f, 1.0f, 1.0f));
|
||||
static const sRGBColor sScrollbarThumbColor(sRGBColor(0.8f, 0.8f, 0.8f));
|
||||
static const sRGBColor sScrollbarThumbColorActive(sRGBColor(0.375f, 0.375f,
|
||||
0.375f));
|
||||
static const sRGBColor sScrollbarThumbColorHover(sRGBColor(0.65f, 0.65f,
|
||||
0.65f));
|
||||
static const sRGBColor sScrollbarArrowColor(sRGBColor(0.375f, 0.375f, 0.375f));
|
||||
static const sRGBColor sScrollbarArrowColorActive(sRGBColor(1.0f, 1.0f, 1.0f));
|
||||
static const sRGBColor sScrollbarArrowColorHover(sRGBColor(0.0f, 0.0f, 0.0f));
|
||||
static const sRGBColor sScrollbarButtonColor(sScrollbarColor);
|
||||
static const sRGBColor sScrollbarButtonActiveColor(sRGBColor(0.375f, 0.375f,
|
||||
0.375f));
|
||||
static const sRGBColor sScrollbarButtonHoverColor(sRGBColor(0.86f, 0.86f,
|
||||
0.86f));
|
||||
|
||||
static const CSSIntCoord kMinimumWidgetSize = 14;
|
||||
static const CSSIntCoord kMinimumColorPickerHeight = 32;
|
||||
static const CSSIntCoord kMinimumRangeThumbSize = 20;
|
||||
static const CSSIntCoord kMinimumDropdownArrowButtonWidth = 18;
|
||||
static const CSSIntCoord kMinimumSpinnerButtonWidth = 31;
|
||||
static const CSSCoord kButtonBorderWidth = 1.0f;
|
||||
static const CSSCoord kMenulistBorderWidth = 1.0f;
|
||||
static const CSSCoord kTextFieldBorderWidth = 1.0f;
|
||||
static const CSSCoord kSpinnerBorderWidth = 1.0f;
|
||||
static const CSSCoord kRangeHeight = 6.0f;
|
||||
static const CSSCoord kProgressbarHeight = 6.0f;
|
||||
static const CSSCoord kMeterHeight = 12.0f;
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
class nsNativeBasicTheme : private nsNativeTheme, public nsITheme {
|
||||
public:
|
||||
nsNativeBasicTheme() = default;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// The nsITheme interface.
|
||||
|
@ -33,25 +117,24 @@ class nsNativeBasicTheme : private nsNativeTheme, public nsITheme {
|
|||
bool GetWidgetPadding(nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
LayoutDeviceIntMargin* aResult) override;
|
||||
virtual bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
nsRect* aOverflowRect) override;
|
||||
bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
nsRect* aOverflowRect) override;
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) override;
|
||||
virtual Transparency GetWidgetTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) override;
|
||||
Transparency GetWidgetTransparency(nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) override;
|
||||
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, StyleAppearance aAppearance,
|
||||
nsAtom* aAttribute, bool* aShouldRepaint,
|
||||
const nsAttrValue* aOldValue) override;
|
||||
NS_IMETHOD ThemeChanged() override;
|
||||
virtual bool WidgetAppearanceDependsOnWindowFocus(
|
||||
bool WidgetAppearanceDependsOnWindowFocus(
|
||||
StyleAppearance aAppearance) override;
|
||||
/*virtual bool NeedToClearBackgroundBehindWidget(nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance)
|
||||
override;*/
|
||||
virtual ThemeGeometryType ThemeGeometryTypeForWidget(
|
||||
/*bool NeedToClearBackgroundBehindWidget(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) override;*/
|
||||
ThemeGeometryType ThemeGeometryTypeForWidget(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) override;
|
||||
bool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) override;
|
||||
|
@ -60,7 +143,146 @@ class nsNativeBasicTheme : private nsNativeTheme, public nsITheme {
|
|||
bool ThemeNeedsComboboxDropmarker() override;
|
||||
|
||||
protected:
|
||||
nsNativeBasicTheme() = default;
|
||||
virtual ~nsNativeBasicTheme() = default;
|
||||
|
||||
static uint32_t GetDPIRatio(nsIFrame* aFrame);
|
||||
static bool IsDateTimeResetButton(nsIFrame* aFrame);
|
||||
static bool IsDateTimeTextField(nsIFrame* aFrame);
|
||||
static bool IsColorPickerButton(nsIFrame* aFrame);
|
||||
static std::pair<sRGBColor, sRGBColor> ComputeCheckColors(
|
||||
const EventStates& aState);
|
||||
static gfx::Rect FixAspectRatio(const gfx::Rect& aRect);
|
||||
|
||||
// This pushes and pops a clip rect to the draw target.
|
||||
//
|
||||
// This is done to reduce fuzz in places where we may have antialiasing,
|
||||
// because skia is not clip-invariant: given different clips, it does not
|
||||
// guarantee the same result, even if the painted content doesn't intersect
|
||||
// the clips.
|
||||
//
|
||||
// This is a bit sad, overall, but...
|
||||
struct MOZ_RAII AutoClipRect {
|
||||
AutoClipRect(DrawTarget& aDt, const gfx::Rect& aRect) : mDt(aDt) {
|
||||
mDt.PushClipRect(aRect);
|
||||
}
|
||||
|
||||
~AutoClipRect() { mDt.PopClip(); }
|
||||
|
||||
private:
|
||||
DrawTarget& mDt;
|
||||
};
|
||||
|
||||
static void GetFocusStrokeRect(DrawTarget* aDrawTarget, gfx::Rect& aFocusRect,
|
||||
CSSCoord aOffset, const CSSCoord aRadius,
|
||||
CSSCoord aFocusWidth, RefPtr<Path>& aOutRect);
|
||||
static void PaintRoundedFocusRect(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect, uint32_t aDpiRatio,
|
||||
CSSCoord aRadius, CSSCoord aOffset);
|
||||
static void PaintRoundedRect(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
CSSCoord aBorderWidth,
|
||||
RectCornerRadii aDpiAdjustedRadii,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintRoundedRectWithRadius(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
CSSCoord aBorderWidth,
|
||||
CSSCoord aRadius, uint32_t aDpiRatio);
|
||||
static void PaintCheckboxControl(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintCheckMark(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintIndeterminateMark(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintStrokedEllipse(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
const CSSCoord aBorderWidth,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintRadioControl(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintRadioCheckMark(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState,
|
||||
uint32_t aDpiRatio);
|
||||
static sRGBColor ComputeBorderColor(const EventStates& aState);
|
||||
static void PaintTextField(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static std::pair<sRGBColor, sRGBColor> ComputeButtonColors(
|
||||
const EventStates& aState, nsIFrame* aFrame = nullptr);
|
||||
static sRGBColor ComputeRangeProgressBorderColor(const EventStates& aState);
|
||||
static sRGBColor ComputeRangeTrackBorderColor(const EventStates& aState);
|
||||
static std::pair<sRGBColor, sRGBColor> ComputeRangeProgressColors(
|
||||
const EventStates& aState);
|
||||
static std::pair<sRGBColor, sRGBColor> ComputeRangeTrackColors(
|
||||
const EventStates& aState);
|
||||
static std::pair<sRGBColor, sRGBColor> ComputeRangeThumbColors(
|
||||
const EventStates& aState);
|
||||
static void PaintListbox(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintMenulist(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintArrow(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const int32_t aArrowPolygonX[],
|
||||
const int32_t aArrowPolygonY[],
|
||||
const int32_t aArrowNumPoints,
|
||||
const int32_t aArrowSize, const sRGBColor aFillColor,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintMenulistArrowButton(nsIFrame* aFrame,
|
||||
DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintSpinnerButton(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState,
|
||||
StyleAppearance aAppearance,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintRangeTrackBackground(nsIFrame* aFrame,
|
||||
DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState,
|
||||
uint32_t aDpiRatio, bool aHorizontal);
|
||||
static void PaintRangeThumb(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintProgressBar(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintProgresschunk(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintMeter(DrawTarget* aDrawTarget, const gfx::Rect& aRect,
|
||||
const EventStates& aState, uint32_t aDpiRatio);
|
||||
static void PaintMeterchunk(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect, const EventStates& aState,
|
||||
uint32_t aDpiRatio);
|
||||
static void PaintButton(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect, const EventStates& aState,
|
||||
uint32_t aDpiRatio);
|
||||
|
||||
virtual void PaintScrollbarthumbHorizontal(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState);
|
||||
virtual void PaintScrollbarthumbVertical(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState);
|
||||
virtual void PaintScrollbarHorizontal(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect);
|
||||
virtual void PaintScrollbarVerticalAndCorner(DrawTarget* aDrawTarget,
|
||||
const gfx::Rect& aRect,
|
||||
uint32_t aDpiRatio);
|
||||
virtual void PaintScrollbarbutton(DrawTarget* aDrawTarget,
|
||||
StyleAppearance aAppearance,
|
||||
const gfx::Rect& aRect,
|
||||
const EventStates& aState,
|
||||
uint32_t aDpiRatio);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,7 @@ UNIFIED_SOURCES += [
|
|||
'nsDataObjCollection.cpp',
|
||||
'nsDragService.cpp',
|
||||
'nsLookAndFeel.cpp',
|
||||
'nsNativeBasicThemeWin.cpp',
|
||||
'nsNativeDragSource.cpp',
|
||||
'nsNativeDragTarget.cpp',
|
||||
'nsNativeThemeWin.cpp',
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* -*- Mode: C++; tab-width: 40; 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 "nsNativeBasicThemeWin.h"
|
||||
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
static StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeWin();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- 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 nsNativeBasicThemeWin_h
|
||||
#define nsNativeBasicThemeWin_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
class nsNativeBasicThemeWin : public nsNativeBasicTheme {
|
||||
public:
|
||||
nsNativeBasicThemeWin() = default;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeWin() = default;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -2878,8 +2878,8 @@ nsresult nsNativeThemeWin::ClassicGetMinimumWidgetSize(
|
|||
// (*aResult).height = ::GetSystemMetrics(SM_CYVTHUMB) << 1;
|
||||
break;
|
||||
case StyleAppearance::ScrollbarNonDisappearing: {
|
||||
aResult->SizeTo(::GetSystemMetrics(SM_CXHSCROLL),
|
||||
::GetSystemMetrics(SM_CYVSCROLL));
|
||||
aResult->SizeTo(::GetSystemMetrics(SM_CXVSCROLL),
|
||||
::GetSystemMetrics(SM_CYHSCROLL));
|
||||
break;
|
||||
}
|
||||
case StyleAppearance::RangeThumb: {
|
||||
|
|
Загрузка…
Ссылка в новой задаче