1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsNativeBasicTheme_h
8 #define nsNativeBasicTheme_h
11 #include "mozilla/gfx/2D.h"
12 #include "mozilla/gfx/Rect.h"
13 #include "mozilla/gfx/Types.h"
15 #include "nsNativeTheme.h"
19 enum class StyleSystemColor
: uint8_t;
23 static const gfx::sRGBColor
sColorWhite(gfx::sRGBColor::OpaqueWhite());
24 static const gfx::sRGBColor
sColorWhiteAlpha50(gfx::sRGBColor::White(0.5f
));
25 static const gfx::sRGBColor
sColorWhiteAlpha80(gfx::sRGBColor::White(0.8f
));
26 static const gfx::sRGBColor
sColorBlack(gfx::sRGBColor::OpaqueBlack());
28 static const gfx::sRGBColor
sColorGrey10(
29 gfx::sRGBColor::UnusualFromARGB(0xffe9e9ed));
30 static const gfx::sRGBColor
sColorGrey10Alpha50(
31 gfx::sRGBColor::UnusualFromARGB(0x7fe9e9ed));
32 static const gfx::sRGBColor
sColorGrey20(
33 gfx::sRGBColor::UnusualFromARGB(0xffd0d0d7));
34 static const gfx::sRGBColor
sColorGrey30(
35 gfx::sRGBColor::UnusualFromARGB(0xffb1b1b9));
36 static const gfx::sRGBColor
sColorGrey40(
37 gfx::sRGBColor::UnusualFromARGB(0xff8f8f9d));
38 static const gfx::sRGBColor
sColorGrey40Alpha50(
39 gfx::sRGBColor::UnusualFromARGB(0x7f8f8f9d));
40 static const gfx::sRGBColor
sColorGrey50(
41 gfx::sRGBColor::UnusualFromARGB(0xff676774));
42 static const gfx::sRGBColor
sColorGrey50Alpha50(
43 gfx::sRGBColor::UnusualFromARGB(0x7f676774));
44 static const gfx::sRGBColor
sColorGrey60(
45 gfx::sRGBColor::UnusualFromARGB(0xff484851));
46 static const gfx::sRGBColor
sColorGrey60Alpha50(
47 gfx::sRGBColor::UnusualFromARGB(0x7f484851));
49 static const gfx::sRGBColor
sColorMeterGreen10(
50 gfx::sRGBColor::UnusualFromARGB(0xff00ab60));
51 static const gfx::sRGBColor
sColorMeterGreen20(
52 gfx::sRGBColor::UnusualFromARGB(0xff056139));
53 static const gfx::sRGBColor
sColorMeterYellow10(
54 gfx::sRGBColor::UnusualFromARGB(0xffffbd4f));
55 static const gfx::sRGBColor
sColorMeterYellow20(
56 gfx::sRGBColor::UnusualFromARGB(0xffd2811e));
57 static const gfx::sRGBColor
sColorMeterRed10(
58 gfx::sRGBColor::UnusualFromARGB(0xffe22850));
59 static const gfx::sRGBColor
sColorMeterRed20(
60 gfx::sRGBColor::UnusualFromARGB(0xff810220));
62 static const gfx::sRGBColor
sScrollbarColor(
63 gfx::sRGBColor::UnusualFromARGB(0xfff0f0f0));
64 static const gfx::sRGBColor
sScrollbarBorderColor(gfx::sRGBColor(1.0f
, 1.0f
,
66 static const gfx::sRGBColor
sScrollbarThumbColor(
67 gfx::sRGBColor::UnusualFromARGB(0xffcdcdcd));
69 static const CSSCoord kMinimumScrollbarSize
= 17.0f
;
70 static const CSSCoord kMinimumThinScrollbarSize
= 6.0f
;
71 static const CSSCoord kMinimumColorPickerHeight
= 32.0f
;
72 static const CSSCoord kMinimumRangeThumbSize
= 20.0f
;
73 static const CSSCoord kMinimumDropdownArrowButtonWidth
= 18.0f
;
74 static const CSSCoord kMinimumSpinnerButtonWidth
= 18.0f
;
75 static const CSSCoord kMinimumSpinnerButtonHeight
= 9.0f
;
76 static const CSSCoord kButtonBorderWidth
= 1.0f
;
77 static const CSSCoord kMenulistBorderWidth
= 1.0f
;
78 static const CSSCoord kTextFieldBorderWidth
= 1.0f
;
79 static const CSSCoord kRangeHeight
= 6.0f
;
80 static const CSSCoord kProgressbarHeight
= 6.0f
;
81 static const CSSCoord kMeterHeight
= 12.0f
;
83 // nsCheckboxRadioFrame takes the bottom of the content box as the baseline.
84 // This border-width makes its baseline 2px under the bottom, which is nice.
85 static constexpr CSSCoord kCheckboxRadioBorderWidth
= 2.0f
;
88 } // namespace mozilla
90 class nsNativeBasicTheme
: protected nsNativeTheme
, public nsITheme
{
92 using sRGBColor
= mozilla::gfx::sRGBColor
;
93 using CSSCoord
= mozilla::CSSCoord
;
94 using CSSPoint
= mozilla::CSSPoint
;
95 using CSSIntCoord
= mozilla::CSSIntCoord
;
96 using ComputedStyle
= mozilla::ComputedStyle
;
97 using EventStates
= mozilla::EventStates
;
98 using DrawTarget
= mozilla::gfx::DrawTarget
;
99 using Path
= mozilla::gfx::Path
;
100 using Rect
= mozilla::gfx::Rect
;
101 using Point
= mozilla::gfx::Point
;
102 using RectCornerRadii
= mozilla::gfx::RectCornerRadii
;
103 using LayoutDeviceCoord
= mozilla::LayoutDeviceCoord
;
104 using LayoutDeviceRect
= mozilla::LayoutDeviceRect
;
108 static void Shutdown();
109 static void LookAndFeelChanged();
111 using DPIRatio
= mozilla::CSSToLayoutDeviceScale
;
113 NS_DECL_ISUPPORTS_INHERITED
115 // The nsITheme interface.
116 NS_IMETHOD
DrawWidgetBackground(gfxContext
* aContext
, nsIFrame
*,
117 StyleAppearance
, const nsRect
& aRect
,
118 const nsRect
& aDirtyRect
) override
;
120 struct WebRenderBackendData
{
121 mozilla::wr::DisplayListBuilder
& mBuilder
;
122 mozilla::wr::IpcResourceUpdateQueue
& mResources
;
123 const mozilla::layers::StackingContextHelper
& mSc
;
124 mozilla::layers::RenderRootStateManager
* mManager
;
127 bool CreateWebRenderCommandsForWidget(
128 mozilla::wr::DisplayListBuilder
& aBuilder
,
129 mozilla::wr::IpcResourceUpdateQueue
& aResources
,
130 const mozilla::layers::StackingContextHelper
& aSc
,
131 mozilla::layers::RenderRootStateManager
* aManager
, nsIFrame
*,
132 StyleAppearance
, const nsRect
& aRect
) override
;
134 // PaintBackendData will be either a DrawTarget, or a WebRenderBackendData.
136 // The return value represents whether the widget could be painted with the
138 template <typename PaintBackendData
>
139 bool DoDrawWidgetBackground(PaintBackendData
&, nsIFrame
*, StyleAppearance
,
140 const nsRect
& aRect
);
142 [[nodiscard
]] LayoutDeviceIntMargin
GetWidgetBorder(nsDeviceContext
* aContext
,
144 StyleAppearance
) override
;
145 bool GetWidgetPadding(nsDeviceContext
* aContext
, nsIFrame
*, StyleAppearance
,
146 LayoutDeviceIntMargin
* aResult
) override
;
147 bool GetWidgetOverflow(nsDeviceContext
* aContext
, nsIFrame
*, StyleAppearance
,
148 nsRect
* aOverflowRect
) override
;
149 NS_IMETHOD
GetMinimumWidgetSize(nsPresContext
* aPresContext
, nsIFrame
*,
151 mozilla::LayoutDeviceIntSize
* aResult
,
152 bool* aIsOverridable
) override
;
153 Transparency
GetWidgetTransparency(nsIFrame
*, StyleAppearance
) override
;
154 NS_IMETHOD
WidgetStateChanged(nsIFrame
*, StyleAppearance
, nsAtom
* aAttribute
,
155 bool* aShouldRepaint
,
156 const nsAttrValue
* aOldValue
) override
;
157 NS_IMETHOD
ThemeChanged() override
;
158 bool WidgetAppearanceDependsOnWindowFocus(StyleAppearance
) override
;
159 /*bool NeedToClearBackgroundBehindWidget(
160 nsIFrame*, StyleAppearance) override;*/
161 ThemeGeometryType
ThemeGeometryTypeForWidget(nsIFrame
*,
162 StyleAppearance
) override
;
163 bool ThemeSupportsWidget(nsPresContext
*, nsIFrame
*, StyleAppearance
) override
;
164 bool WidgetIsContainer(StyleAppearance
) override
;
165 bool ThemeDrawsFocusForWidget(StyleAppearance
) override
;
166 bool ThemeNeedsComboboxDropmarker() override
;
167 ScrollbarSizes
GetScrollbarSizes(nsPresContext
*, StyleScrollbarWidth
,
169 static nscolor
AdjustUnthemedScrollbarThumbColor(nscolor
, EventStates
);
170 static nscolor
GetScrollbarButtonColor(nscolor aTrackColor
, EventStates
);
171 static nscolor
GetScrollbarArrowColor(nscolor aButtonColor
);
173 nscoord
GetCheckboxRadioPrefSize() override
;
176 nsNativeBasicTheme() = default;
177 virtual ~nsNativeBasicTheme() = default;
179 static DPIRatio
GetDPIRatioForScrollbarPart(nsPresContext
*);
180 static DPIRatio
GetDPIRatio(nsPresContext
*, StyleAppearance
);
181 static DPIRatio
GetDPIRatio(nsIFrame
*, StyleAppearance
);
182 static bool IsDateTimeResetButton(nsIFrame
*);
183 static bool IsColorPickerButton(nsIFrame
*);
185 // Whether we should use system colors (for high contrast mode).
186 enum class UseSystemColors
: bool { No
, Yes
};
187 static UseSystemColors
ShouldUseSystemColors(const mozilla::dom::Document
&);
189 std::pair
<sRGBColor
, sRGBColor
> ComputeCheckboxColors(const EventStates
&,
192 sRGBColor
ComputeCheckmarkColor(const EventStates
&, UseSystemColors
);
193 sRGBColor
ComputeBorderColor(const EventStates
&, UseSystemColors
);
195 std::pair
<sRGBColor
, sRGBColor
> ComputeButtonColors(const EventStates
&,
197 nsIFrame
* = nullptr);
198 std::pair
<sRGBColor
, sRGBColor
> ComputeTextfieldColors(const EventStates
&,
200 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeProgressColors(const EventStates
&,
202 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeTrackColors(const EventStates
&,
204 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeThumbColors(const EventStates
&,
206 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressColors(UseSystemColors
);
207 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressTrackColors(UseSystemColors
);
208 std::pair
<sRGBColor
, sRGBColor
> ComputeMeterchunkColors(
209 const EventStates
& aMeterState
, UseSystemColors
);
210 sRGBColor
ComputeMenulistArrowButtonColor(const EventStates
&,
212 std::array
<sRGBColor
, 3> ComputeFocusRectColors(UseSystemColors
);
214 static bool ShouldUseDarkScrollbar(nsIFrame
*, const ComputedStyle
&);
215 virtual sRGBColor
ComputeScrollbarColor(nsIFrame
*, const ComputedStyle
&,
216 const EventStates
& aDocumentState
,
218 virtual sRGBColor
ComputeScrollbarThumbColor(
219 nsIFrame
*, const ComputedStyle
&, const EventStates
& aElementState
,
220 const EventStates
& aDocumentState
, UseSystemColors
);
221 // Returned colors are button, arrow.
222 std::pair
<sRGBColor
, sRGBColor
> ComputeScrollbarButtonColors(
223 nsIFrame
*, StyleAppearance
, const ComputedStyle
&,
224 const EventStates
& aElementState
, const EventStates
& aDocumentState
,
227 template <typename PaintBackendData
>
228 void PaintRoundedFocusRect(PaintBackendData
&, const LayoutDeviceRect
&,
229 UseSystemColors
, DPIRatio
, CSSCoord aRadius
,
231 template <typename PaintBackendData
>
232 void PaintAutoStyleOutline(nsIFrame
*, PaintBackendData
&,
233 const LayoutDeviceRect
&, UseSystemColors
,
236 static void PaintRoundedRectWithRadius(DrawTarget
&,
237 const LayoutDeviceRect
& aRect
,
238 const LayoutDeviceRect
& aClipRect
,
239 const sRGBColor
& aBackgroundColor
,
240 const sRGBColor
& aBorderColor
,
241 CSSCoord aBorderWidth
,
242 CSSCoord aRadius
, DPIRatio
);
243 static void PaintRoundedRectWithRadius(WebRenderBackendData
&,
244 const LayoutDeviceRect
& aRect
,
245 const LayoutDeviceRect
& aClipRect
,
246 const sRGBColor
& aBackgroundColor
,
247 const sRGBColor
& aBorderColor
,
248 CSSCoord aBorderWidth
,
249 CSSCoord aRadius
, DPIRatio
);
250 template <typename PaintBackendData
>
251 static void PaintRoundedRectWithRadius(PaintBackendData
& aData
,
252 const LayoutDeviceRect
& aRect
,
253 const sRGBColor
& aBackgroundColor
,
254 const sRGBColor
& aBorderColor
,
255 CSSCoord aBorderWidth
,
256 CSSCoord aRadius
, DPIRatio aDpiRatio
) {
257 PaintRoundedRectWithRadius(aData
, aRect
, aRect
, aBackgroundColor
,
258 aBorderColor
, aBorderWidth
, aRadius
, aDpiRatio
);
261 static void FillRect(DrawTarget
&, const LayoutDeviceRect
&, const sRGBColor
&);
262 static void FillRect(WebRenderBackendData
&, const LayoutDeviceRect
&,
265 void PaintCheckboxControl(DrawTarget
& aDrawTarget
, const LayoutDeviceRect
&,
266 const EventStates
&, UseSystemColors
, DPIRatio
);
267 void PaintCheckMark(DrawTarget
&, const LayoutDeviceRect
&, const EventStates
&,
269 void PaintIndeterminateMark(DrawTarget
&, const LayoutDeviceRect
&,
270 const EventStates
&, UseSystemColors
);
272 template <typename PaintBackendData
>
273 void PaintStrokedCircle(PaintBackendData
&, const LayoutDeviceRect
&,
274 const sRGBColor
& aBackgroundColor
,
275 const sRGBColor
& aBorderColor
,
276 const CSSCoord aBorderWidth
, DPIRatio
);
277 void PaintCircleShadow(DrawTarget
&, const LayoutDeviceRect
& aBoxRect
,
278 const LayoutDeviceRect
& aClipRect
, float aShadowAlpha
,
279 const CSSPoint
& aShadowOffset
,
280 CSSCoord aShadowBlurStdDev
, DPIRatio
);
281 void PaintCircleShadow(WebRenderBackendData
&,
282 const LayoutDeviceRect
& aBoxRect
,
283 const LayoutDeviceRect
& aClipRect
, float aShadowAlpha
,
284 const CSSPoint
& aShadowOffset
,
285 CSSCoord aShadowBlurStdDev
, DPIRatio
);
286 template <typename PaintBackendData
>
287 void PaintRadioControl(PaintBackendData
&, const LayoutDeviceRect
&,
288 const EventStates
&, UseSystemColors
, DPIRatio
);
289 template <typename PaintBackendData
>
290 void PaintRadioCheckmark(PaintBackendData
&, const LayoutDeviceRect
&,
291 const EventStates
&, DPIRatio
);
292 template <typename PaintBackendData
>
293 void PaintTextField(PaintBackendData
&, const LayoutDeviceRect
&,
294 const EventStates
&, UseSystemColors
, DPIRatio
);
295 template <typename PaintBackendData
>
296 void PaintListbox(PaintBackendData
&, const LayoutDeviceRect
&,
297 const EventStates
&, UseSystemColors
, DPIRatio
);
298 template <typename PaintBackendData
>
299 void PaintMenulist(PaintBackendData
&, const LayoutDeviceRect
&,
300 const EventStates
&, UseSystemColors
, DPIRatio
);
301 void PaintArrow(DrawTarget
&, const LayoutDeviceRect
&,
302 const float aArrowPolygonX
[], const float aArrowPolygonY
[],
303 const float aArrowPolygonSize
, const int32_t aArrowNumPoints
,
304 const sRGBColor aFillColor
);
305 void PaintMenulistArrowButton(nsIFrame
*, DrawTarget
&, const LayoutDeviceRect
&,
306 const EventStates
&, UseSystemColors
);
307 void PaintSpinnerButton(nsIFrame
*, DrawTarget
&, const LayoutDeviceRect
&,
308 const EventStates
&, StyleAppearance
, UseSystemColors
,
310 template <typename PaintBackendData
>
311 void PaintRange(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
312 const EventStates
&, UseSystemColors
, DPIRatio
,
314 template <typename PaintBackendData
>
315 void PaintProgress(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
316 const EventStates
&, UseSystemColors
, DPIRatio
,
318 template <typename PaintBackendData
>
319 void PaintButton(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
320 const EventStates
&, UseSystemColors
, DPIRatio
);
322 void PaintScrollbarButton(DrawTarget
&, StyleAppearance
,
323 const LayoutDeviceRect
&, nsIFrame
*,
324 const ComputedStyle
&,
325 const EventStates
& aElementState
,
326 const EventStates
& aDocumentState
, UseSystemColors
,
329 virtual bool PaintScrollbarThumb(DrawTarget
&, const LayoutDeviceRect
&,
330 bool aHorizontal
, nsIFrame
*,
331 const ComputedStyle
&,
332 const EventStates
& aElementState
,
333 const EventStates
& aDocumentState
,
334 UseSystemColors
, DPIRatio
);
335 virtual bool PaintScrollbarThumb(WebRenderBackendData
&,
336 const LayoutDeviceRect
&, bool aHorizontal
,
337 nsIFrame
*, const ComputedStyle
&,
338 const EventStates
& aElementState
,
339 const EventStates
& aDocumentState
,
340 UseSystemColors
, DPIRatio
);
341 template <typename PaintBackendData
>
342 bool DoPaintDefaultScrollbarThumb(PaintBackendData
&, const LayoutDeviceRect
&,
343 bool aHorizontal
, nsIFrame
*,
344 const ComputedStyle
&,
345 const EventStates
& aElementState
,
346 const EventStates
& aDocumentState
,
347 UseSystemColors aUseSystemColors
, DPIRatio
);
349 virtual bool PaintScrollbar(DrawTarget
&, const LayoutDeviceRect
&,
350 bool aHorizontal
, nsIFrame
*, const ComputedStyle
&,
351 const EventStates
& aDocumentState
,
352 UseSystemColors
, DPIRatio
);
353 virtual bool PaintScrollbar(WebRenderBackendData
&, const LayoutDeviceRect
&,
354 bool aHorizontal
, nsIFrame
*, const ComputedStyle
&,
355 const EventStates
& aDocumentState
,
356 UseSystemColors
, DPIRatio
);
357 template <typename PaintBackendData
>
358 bool DoPaintDefaultScrollbar(PaintBackendData
&, const LayoutDeviceRect
&,
359 bool aHorizontal
, nsIFrame
*,
360 const ComputedStyle
&,
361 const EventStates
& aDocumentState
,
362 UseSystemColors aUseSystemColors
, DPIRatio
);
364 virtual bool PaintScrollbarTrack(DrawTarget
&, const LayoutDeviceRect
&,
365 bool aHorizontal
, nsIFrame
*,
366 const ComputedStyle
&,
367 const EventStates
& aDocumentState
,
368 UseSystemColors
, DPIRatio
) {
369 // Draw nothing by default. Subclasses can override this.
372 virtual bool PaintScrollbarTrack(WebRenderBackendData
&,
373 const LayoutDeviceRect
&, bool aHorizontal
,
374 nsIFrame
*, const ComputedStyle
&,
375 const EventStates
& aDocumentState
,
376 UseSystemColors
, DPIRatio
) {
377 // Draw nothing by default. Subclasses can override this.
381 virtual bool PaintScrollCorner(DrawTarget
&, const LayoutDeviceRect
&,
382 nsIFrame
*, const ComputedStyle
&,
383 const EventStates
& aDocumentState
,
384 UseSystemColors
, DPIRatio
);
385 virtual bool PaintScrollCorner(WebRenderBackendData
&, const LayoutDeviceRect
&,
386 nsIFrame
*, const ComputedStyle
&,
387 const EventStates
& aDocumentState
,
388 UseSystemColors
, DPIRatio
);
389 template <typename PaintBackendData
>
390 bool DoPaintDefaultScrollCorner(PaintBackendData
&, const LayoutDeviceRect
&,
391 nsIFrame
*, const ComputedStyle
&,
392 const EventStates
& aDocumentState
,
393 UseSystemColors
, DPIRatio
);
395 static sRGBColor sAccentColor
;
396 static sRGBColor sAccentColorForeground
;
398 // Note that depending on the exact accent color, lighter/darker might really
400 static sRGBColor sAccentColorLight
;
401 static sRGBColor sAccentColorDark
;
402 static sRGBColor sAccentColorDarker
;
404 static void PrefChangedCallback(const char*, void*) {
405 RecomputeAccentColors();
407 static void RecomputeAccentColors();