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 constexpr gfx::sRGBColor
sColorWhite(gfx::sRGBColor::OpaqueWhite());
24 static constexpr gfx::sRGBColor
sColorWhiteAlpha50(gfx::sRGBColor::White(0.5f
));
25 static constexpr gfx::sRGBColor
sColorWhiteAlpha80(gfx::sRGBColor::White(0.8f
));
26 static constexpr gfx::sRGBColor
sColorBlack(gfx::sRGBColor::OpaqueBlack());
28 static constexpr gfx::sRGBColor
sDefaultAccent(
29 gfx::sRGBColor::UnusualFromARGB(0xff0060df)); // Luminance: 13.69346%
30 static constexpr gfx::sRGBColor
sDefaultAccentForeground(sColorWhite
);
32 static constexpr gfx::sRGBColor
sColorGrey10(
33 gfx::sRGBColor::UnusualFromARGB(0xffe9e9ed));
34 static constexpr gfx::sRGBColor
sColorGrey10Alpha50(
35 gfx::sRGBColor::UnusualFromARGB(0x7fe9e9ed));
36 static constexpr gfx::sRGBColor
sColorGrey20(
37 gfx::sRGBColor::UnusualFromARGB(0xffd0d0d7));
38 static constexpr gfx::sRGBColor
sColorGrey30(
39 gfx::sRGBColor::UnusualFromARGB(0xffb1b1b9));
40 static constexpr gfx::sRGBColor
sColorGrey40(
41 gfx::sRGBColor::UnusualFromARGB(0xff8f8f9d));
42 static constexpr gfx::sRGBColor
sColorGrey40Alpha50(
43 gfx::sRGBColor::UnusualFromARGB(0x7f8f8f9d));
44 static constexpr gfx::sRGBColor
sColorGrey50(
45 gfx::sRGBColor::UnusualFromARGB(0xff676774));
46 static constexpr gfx::sRGBColor
sColorGrey50Alpha50(
47 gfx::sRGBColor::UnusualFromARGB(0x7f676774));
48 static constexpr gfx::sRGBColor
sColorGrey60(
49 gfx::sRGBColor::UnusualFromARGB(0xff484851));
50 static constexpr gfx::sRGBColor
sColorGrey60Alpha50(
51 gfx::sRGBColor::UnusualFromARGB(0x7f484851));
53 static constexpr gfx::sRGBColor
sColorMeterGreen10(
54 gfx::sRGBColor::UnusualFromARGB(0xff00ab60));
55 static constexpr gfx::sRGBColor
sColorMeterGreen20(
56 gfx::sRGBColor::UnusualFromARGB(0xff056139));
57 static constexpr gfx::sRGBColor
sColorMeterYellow10(
58 gfx::sRGBColor::UnusualFromARGB(0xffffbd4f));
59 static constexpr gfx::sRGBColor
sColorMeterYellow20(
60 gfx::sRGBColor::UnusualFromARGB(0xffd2811e));
61 static constexpr gfx::sRGBColor
sColorMeterRed10(
62 gfx::sRGBColor::UnusualFromARGB(0xffe22850));
63 static constexpr gfx::sRGBColor
sColorMeterRed20(
64 gfx::sRGBColor::UnusualFromARGB(0xff810220));
66 static constexpr gfx::sRGBColor
sScrollbarColor(
67 gfx::sRGBColor::UnusualFromARGB(0xfff0f0f0));
68 static constexpr gfx::sRGBColor
sScrollbarBorderColor(gfx::sRGBColor(1.0f
, 1.0f
,
70 static constexpr gfx::sRGBColor
sScrollbarThumbColor(
71 gfx::sRGBColor::UnusualFromARGB(0xffcdcdcd));
73 static const CSSCoord kMinimumColorPickerHeight
= 32.0f
;
74 static const CSSCoord kMinimumRangeThumbSize
= 20.0f
;
75 static const CSSCoord kMinimumDropdownArrowButtonWidth
= 18.0f
;
76 static const CSSCoord kMinimumSpinnerButtonWidth
= 18.0f
;
77 static const CSSCoord kMinimumSpinnerButtonHeight
= 9.0f
;
78 static const CSSCoord kButtonBorderWidth
= 1.0f
;
79 static const CSSCoord kMenulistBorderWidth
= 1.0f
;
80 static const CSSCoord kTextFieldBorderWidth
= 1.0f
;
81 static const CSSCoord kRangeHeight
= 6.0f
;
82 static const CSSCoord kProgressbarHeight
= 6.0f
;
83 static const CSSCoord kMeterHeight
= 12.0f
;
85 // nsCheckboxRadioFrame takes the bottom of the content box as the baseline.
86 // This border-width makes its baseline 2px under the bottom, which is nice.
87 static constexpr CSSCoord kCheckboxRadioBorderWidth
= 2.0f
;
90 } // namespace mozilla
92 class nsNativeBasicTheme
: protected nsNativeTheme
, public nsITheme
{
94 using sRGBColor
= mozilla::gfx::sRGBColor
;
95 using CSSCoord
= mozilla::CSSCoord
;
96 using CSSPoint
= mozilla::CSSPoint
;
97 using CSSIntCoord
= mozilla::CSSIntCoord
;
98 using ComputedStyle
= mozilla::ComputedStyle
;
99 using EventStates
= mozilla::EventStates
;
100 using DrawTarget
= mozilla::gfx::DrawTarget
;
101 using Path
= mozilla::gfx::Path
;
102 using Rect
= mozilla::gfx::Rect
;
103 using Point
= mozilla::gfx::Point
;
104 using RectCornerRadii
= mozilla::gfx::RectCornerRadii
;
105 using LayoutDeviceCoord
= mozilla::LayoutDeviceCoord
;
106 using LayoutDeviceRect
= mozilla::LayoutDeviceRect
;
111 static void Shutdown();
112 static void LookAndFeelChanged();
114 using DPIRatio
= mozilla::CSSToLayoutDeviceScale
;
116 NS_DECL_ISUPPORTS_INHERITED
118 // The nsITheme interface.
119 NS_IMETHOD
DrawWidgetBackground(gfxContext
* aContext
, nsIFrame
*,
120 StyleAppearance
, const nsRect
& aRect
,
121 const nsRect
& aDirtyRect
,
122 DrawOverflow
) override
;
124 struct WebRenderBackendData
{
125 mozilla::wr::DisplayListBuilder
& mBuilder
;
126 mozilla::wr::IpcResourceUpdateQueue
& mResources
;
127 const mozilla::layers::StackingContextHelper
& mSc
;
128 mozilla::layers::RenderRootStateManager
* mManager
;
131 bool CreateWebRenderCommandsForWidget(
132 mozilla::wr::DisplayListBuilder
& aBuilder
,
133 mozilla::wr::IpcResourceUpdateQueue
& aResources
,
134 const mozilla::layers::StackingContextHelper
& aSc
,
135 mozilla::layers::RenderRootStateManager
* aManager
, nsIFrame
*,
136 StyleAppearance
, const nsRect
& aRect
) override
;
138 // PaintBackendData will be either a DrawTarget, or a WebRenderBackendData.
140 // The return value represents whether the widget could be painted with the
142 template <typename PaintBackendData
>
143 bool DoDrawWidgetBackground(PaintBackendData
&, nsIFrame
*, StyleAppearance
,
144 const nsRect
&, DrawOverflow
);
146 [[nodiscard
]] LayoutDeviceIntMargin
GetWidgetBorder(nsDeviceContext
* aContext
,
148 StyleAppearance
) override
;
149 bool GetWidgetPadding(nsDeviceContext
* aContext
, nsIFrame
*, StyleAppearance
,
150 LayoutDeviceIntMargin
* aResult
) override
;
151 bool GetWidgetOverflow(nsDeviceContext
* aContext
, nsIFrame
*, StyleAppearance
,
152 nsRect
* aOverflowRect
) override
;
153 NS_IMETHOD
GetMinimumWidgetSize(nsPresContext
* aPresContext
, nsIFrame
*,
155 mozilla::LayoutDeviceIntSize
* aResult
,
156 bool* aIsOverridable
) override
;
157 Transparency
GetWidgetTransparency(nsIFrame
*, StyleAppearance
) override
;
158 NS_IMETHOD
WidgetStateChanged(nsIFrame
*, StyleAppearance
, nsAtom
* aAttribute
,
159 bool* aShouldRepaint
,
160 const nsAttrValue
* aOldValue
) override
;
161 NS_IMETHOD
ThemeChanged() override
;
162 bool WidgetAppearanceDependsOnWindowFocus(StyleAppearance
) override
;
163 /*bool NeedToClearBackgroundBehindWidget(
164 nsIFrame*, StyleAppearance) override;*/
165 ThemeGeometryType
ThemeGeometryTypeForWidget(nsIFrame
*,
166 StyleAppearance
) override
;
167 bool ThemeSupportsWidget(nsPresContext
*, nsIFrame
*, StyleAppearance
) override
;
168 bool WidgetIsContainer(StyleAppearance
) override
;
169 bool ThemeDrawsFocusForWidget(StyleAppearance
) override
;
170 bool ThemeNeedsComboboxDropmarker() override
;
171 ScrollbarSizes
GetScrollbarSizes(nsPresContext
*, StyleScrollbarWidth
,
173 static nscolor
AdjustUnthemedScrollbarThumbColor(nscolor
, EventStates
);
174 static nscolor
GetScrollbarButtonColor(nscolor aTrackColor
, EventStates
);
175 static mozilla::Maybe
<nscolor
> GetScrollbarArrowColor(nscolor aButtonColor
);
176 static nscolor
ComputeCustomAccentForeground(nscolor aAccent
);
178 nscoord
GetCheckboxRadioPrefSize() override
;
181 nsNativeBasicTheme() = default;
182 virtual ~nsNativeBasicTheme() = default;
184 static DPIRatio
GetDPIRatioForScrollbarPart(nsPresContext
*);
185 static DPIRatio
GetDPIRatio(nsPresContext
*, StyleAppearance
);
186 static DPIRatio
GetDPIRatio(nsIFrame
*, StyleAppearance
);
187 static bool IsDateTimeResetButton(nsIFrame
*);
188 static bool IsColorPickerButton(nsIFrame
*);
190 // Whether we should use system colors (for high contrast mode).
191 enum class UseSystemColors
: bool { No
, Yes
};
192 static UseSystemColors
ShouldUseSystemColors(const nsPresContext
&);
194 std::pair
<sRGBColor
, sRGBColor
> ComputeCheckboxColors(const EventStates
&,
198 sRGBColor
ComputeCheckmarkColor(const EventStates
&, const AccentColor
&,
200 sRGBColor
ComputeBorderColor(const EventStates
&, UseSystemColors
);
202 std::pair
<sRGBColor
, sRGBColor
> ComputeButtonColors(const EventStates
&,
204 nsIFrame
* = nullptr);
205 std::pair
<sRGBColor
, sRGBColor
> ComputeTextfieldColors(const EventStates
&,
207 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeProgressColors(const EventStates
&,
210 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeTrackColors(const EventStates
&,
212 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeThumbColors(const EventStates
&,
215 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressColors(const AccentColor
&,
217 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressTrackColors(UseSystemColors
);
218 std::pair
<sRGBColor
, sRGBColor
> ComputeMeterchunkColors(
219 const EventStates
& aMeterState
, UseSystemColors
);
220 std::array
<sRGBColor
, 3> ComputeFocusRectColors(const AccentColor
&,
223 static bool ShouldUseDarkScrollbar(nsIFrame
*, const ComputedStyle
&);
224 sRGBColor
ComputeScrollbarTrackColor(nsIFrame
*, const ComputedStyle
&,
225 const EventStates
& aDocumentState
,
227 sRGBColor
ComputeScrollbarThumbColor(nsIFrame
*, const ComputedStyle
&,
228 const EventStates
& aElementState
,
229 const EventStates
& aDocumentState
,
231 // Returned colors are button, arrow.
232 std::pair
<sRGBColor
, sRGBColor
> ComputeScrollbarButtonColors(
233 nsIFrame
*, StyleAppearance
, const ComputedStyle
&,
234 const EventStates
& aElementState
, const EventStates
& aDocumentState
,
237 template <typename PaintBackendData
>
238 void PaintRoundedFocusRect(PaintBackendData
&, const LayoutDeviceRect
&,
239 const AccentColor
&, UseSystemColors
, DPIRatio
,
240 CSSCoord aRadius
, CSSCoord aOffset
);
241 template <typename PaintBackendData
>
242 void PaintAutoStyleOutline(nsIFrame
*, PaintBackendData
&,
243 const LayoutDeviceRect
&, const AccentColor
&,
244 UseSystemColors
, DPIRatio
);
246 static void PaintRoundedRectWithRadius(DrawTarget
&,
247 const LayoutDeviceRect
& aRect
,
248 const LayoutDeviceRect
& aClipRect
,
249 const sRGBColor
& aBackgroundColor
,
250 const sRGBColor
& aBorderColor
,
251 CSSCoord aBorderWidth
,
252 CSSCoord aRadius
, DPIRatio
);
253 static void PaintRoundedRectWithRadius(WebRenderBackendData
&,
254 const LayoutDeviceRect
& aRect
,
255 const LayoutDeviceRect
& aClipRect
,
256 const sRGBColor
& aBackgroundColor
,
257 const sRGBColor
& aBorderColor
,
258 CSSCoord aBorderWidth
,
259 CSSCoord aRadius
, DPIRatio
);
260 template <typename PaintBackendData
>
261 static void PaintRoundedRectWithRadius(PaintBackendData
& aData
,
262 const LayoutDeviceRect
& aRect
,
263 const sRGBColor
& aBackgroundColor
,
264 const sRGBColor
& aBorderColor
,
265 CSSCoord aBorderWidth
,
266 CSSCoord aRadius
, DPIRatio aDpiRatio
) {
267 PaintRoundedRectWithRadius(aData
, aRect
, aRect
, aBackgroundColor
,
268 aBorderColor
, aBorderWidth
, aRadius
, aDpiRatio
);
271 static void FillRect(DrawTarget
&, const LayoutDeviceRect
&, const sRGBColor
&);
272 static void FillRect(WebRenderBackendData
&, const LayoutDeviceRect
&,
275 void PaintCheckboxControl(DrawTarget
& aDrawTarget
, const LayoutDeviceRect
&,
276 const EventStates
&, const AccentColor
&,
277 UseSystemColors
, DPIRatio
);
278 void PaintCheckMark(DrawTarget
&, const LayoutDeviceRect
&, const EventStates
&,
279 const AccentColor
&, UseSystemColors
);
280 void PaintIndeterminateMark(DrawTarget
&, const LayoutDeviceRect
&,
281 const EventStates
&, const AccentColor
&,
284 template <typename PaintBackendData
>
285 void PaintStrokedCircle(PaintBackendData
&, const LayoutDeviceRect
&,
286 const sRGBColor
& aBackgroundColor
,
287 const sRGBColor
& aBorderColor
,
288 const CSSCoord aBorderWidth
, DPIRatio
);
289 void PaintCircleShadow(DrawTarget
&, const LayoutDeviceRect
& aBoxRect
,
290 const LayoutDeviceRect
& aClipRect
, float aShadowAlpha
,
291 const CSSPoint
& aShadowOffset
,
292 CSSCoord aShadowBlurStdDev
, DPIRatio
);
293 void PaintCircleShadow(WebRenderBackendData
&,
294 const LayoutDeviceRect
& aBoxRect
,
295 const LayoutDeviceRect
& aClipRect
, float aShadowAlpha
,
296 const CSSPoint
& aShadowOffset
,
297 CSSCoord aShadowBlurStdDev
, DPIRatio
);
298 template <typename PaintBackendData
>
299 void PaintRadioControl(PaintBackendData
&, const LayoutDeviceRect
&,
300 const EventStates
&, const AccentColor
&,
301 UseSystemColors
, DPIRatio
);
302 template <typename PaintBackendData
>
303 void PaintRadioCheckmark(PaintBackendData
&, const LayoutDeviceRect
&,
304 const EventStates
&, DPIRatio
);
305 template <typename PaintBackendData
>
306 void PaintTextField(PaintBackendData
&, const LayoutDeviceRect
&,
307 const EventStates
&, const AccentColor
& aAccent
,
308 UseSystemColors
, DPIRatio
);
309 template <typename PaintBackendData
>
310 void PaintListbox(PaintBackendData
&, const LayoutDeviceRect
&,
311 const EventStates
&, const AccentColor
&, UseSystemColors
,
313 template <typename PaintBackendData
>
314 void PaintMenulist(PaintBackendData
&, const LayoutDeviceRect
&,
315 const EventStates
&, const AccentColor
&, UseSystemColors
,
317 void PaintArrow(DrawTarget
&, const LayoutDeviceRect
&,
318 const float aArrowPolygonX
[], const float aArrowPolygonY
[],
319 const float aArrowPolygonSize
, const int32_t aArrowNumPoints
,
320 const sRGBColor aFillColor
);
321 void PaintMenulistArrowButton(nsIFrame
*, DrawTarget
&, const LayoutDeviceRect
&,
322 const EventStates
&, UseSystemColors
);
323 void PaintSpinnerButton(nsIFrame
*, DrawTarget
&, const LayoutDeviceRect
&,
324 const EventStates
&, StyleAppearance
, UseSystemColors
,
326 template <typename PaintBackendData
>
327 void PaintRange(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
328 const EventStates
&, const AccentColor
&, UseSystemColors
,
329 DPIRatio
, bool aHorizontal
);
330 template <typename PaintBackendData
>
331 void PaintProgress(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
332 const EventStates
&, const AccentColor
&, UseSystemColors
,
333 DPIRatio
, bool aIsMeter
);
334 template <typename PaintBackendData
>
335 void PaintButton(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
336 const EventStates
&, const AccentColor
&, UseSystemColors
,
339 void PaintScrollbarButton(DrawTarget
&, StyleAppearance
,
340 const LayoutDeviceRect
&, nsIFrame
*,
341 const ComputedStyle
&,
342 const EventStates
& aElementState
,
343 const EventStates
& aDocumentState
, UseSystemColors
,
346 virtual bool PaintScrollbarThumb(DrawTarget
&, const LayoutDeviceRect
&,
347 bool aHorizontal
, nsIFrame
*,
348 const ComputedStyle
&,
349 const EventStates
& aElementState
,
350 const EventStates
& aDocumentState
,
351 UseSystemColors
, DPIRatio
);
352 virtual bool PaintScrollbarThumb(WebRenderBackendData
&,
353 const LayoutDeviceRect
&, bool aHorizontal
,
354 nsIFrame
*, const ComputedStyle
&,
355 const EventStates
& aElementState
,
356 const EventStates
& aDocumentState
,
357 UseSystemColors
, DPIRatio
);
358 template <typename PaintBackendData
>
359 bool DoPaintDefaultScrollbarThumb(PaintBackendData
&, const LayoutDeviceRect
&,
360 bool aHorizontal
, nsIFrame
*,
361 const ComputedStyle
&,
362 const EventStates
& aElementState
,
363 const EventStates
& aDocumentState
,
364 UseSystemColors aUseSystemColors
, DPIRatio
);
366 virtual bool PaintScrollbar(DrawTarget
&, const LayoutDeviceRect
&,
367 bool aHorizontal
, nsIFrame
*, const ComputedStyle
&,
368 const EventStates
& aElementState
,
369 const EventStates
& aDocumentState
,
370 UseSystemColors
, DPIRatio
);
371 virtual bool PaintScrollbar(WebRenderBackendData
&, const LayoutDeviceRect
&,
372 bool aHorizontal
, nsIFrame
*, const ComputedStyle
&,
373 const EventStates
& aElementState
,
374 const EventStates
& aDocumentState
,
375 UseSystemColors
, DPIRatio
);
376 template <typename PaintBackendData
>
377 bool DoPaintDefaultScrollbar(PaintBackendData
&, const LayoutDeviceRect
&,
378 bool aHorizontal
, nsIFrame
*,
379 const ComputedStyle
&,
380 const EventStates
& aElementState
,
381 const EventStates
& aDocumentState
,
382 UseSystemColors aUseSystemColors
, DPIRatio
);
384 virtual bool PaintScrollbarTrack(DrawTarget
&, const LayoutDeviceRect
&,
385 bool aHorizontal
, nsIFrame
*,
386 const ComputedStyle
&,
387 const EventStates
& aDocumentState
,
388 UseSystemColors
, DPIRatio
) {
389 // Draw nothing by default. Subclasses can override this.
392 virtual bool PaintScrollbarTrack(WebRenderBackendData
&,
393 const LayoutDeviceRect
&, bool aHorizontal
,
394 nsIFrame
*, const ComputedStyle
&,
395 const EventStates
& aDocumentState
,
396 UseSystemColors
, DPIRatio
) {
397 // Draw nothing by default. Subclasses can override this.
401 virtual bool PaintScrollCorner(DrawTarget
&, const LayoutDeviceRect
&,
402 nsIFrame
*, const ComputedStyle
&,
403 const EventStates
& aDocumentState
,
404 UseSystemColors
, DPIRatio
);
405 virtual bool PaintScrollCorner(WebRenderBackendData
&, const LayoutDeviceRect
&,
406 nsIFrame
*, const ComputedStyle
&,
407 const EventStates
& aDocumentState
,
408 UseSystemColors
, DPIRatio
);
409 template <typename PaintBackendData
>
410 bool DoPaintDefaultScrollCorner(PaintBackendData
&, const LayoutDeviceRect
&,
411 nsIFrame
*, const ComputedStyle
&,
412 const EventStates
& aDocumentState
,
413 UseSystemColors
, DPIRatio
);
415 static CSSIntCoord sHorizontalScrollbarHeight
;
416 static CSSIntCoord sVerticalScrollbarWidth
;
417 static bool sOverlayScrollbars
;
419 static void PrefChangedCallback(const char*, void*) { LookAndFeelChanged(); }
420 static void RecomputeAccentColors();
421 static void RecomputeScrollbarParams();