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
sColorGrey10(
29 gfx::sRGBColor::UnusualFromARGB(0xffe9e9ed));
30 static constexpr gfx::sRGBColor
sColorGrey10Alpha50(
31 gfx::sRGBColor::UnusualFromARGB(0x7fe9e9ed));
32 static constexpr gfx::sRGBColor
sColorGrey20(
33 gfx::sRGBColor::UnusualFromARGB(0xffd0d0d7));
34 static constexpr gfx::sRGBColor
sColorGrey30(
35 gfx::sRGBColor::UnusualFromARGB(0xffb1b1b9));
36 static constexpr gfx::sRGBColor
sColorGrey40(
37 gfx::sRGBColor::UnusualFromARGB(0xff8f8f9d));
38 static constexpr gfx::sRGBColor
sColorGrey40Alpha50(
39 gfx::sRGBColor::UnusualFromARGB(0x7f8f8f9d));
40 static constexpr gfx::sRGBColor
sColorGrey50(
41 gfx::sRGBColor::UnusualFromARGB(0xff676774));
42 static constexpr gfx::sRGBColor
sColorGrey50Alpha50(
43 gfx::sRGBColor::UnusualFromARGB(0x7f676774));
44 static constexpr gfx::sRGBColor
sColorGrey60(
45 gfx::sRGBColor::UnusualFromARGB(0xff484851));
46 static constexpr gfx::sRGBColor
sColorGrey60Alpha50(
47 gfx::sRGBColor::UnusualFromARGB(0x7f484851));
49 static constexpr gfx::sRGBColor
sColorMeterGreen10(
50 gfx::sRGBColor::UnusualFromARGB(0xff00ab60));
51 static constexpr gfx::sRGBColor
sColorMeterGreen20(
52 gfx::sRGBColor::UnusualFromARGB(0xff056139));
53 static constexpr gfx::sRGBColor
sColorMeterYellow10(
54 gfx::sRGBColor::UnusualFromARGB(0xffffbd4f));
55 static constexpr gfx::sRGBColor
sColorMeterYellow20(
56 gfx::sRGBColor::UnusualFromARGB(0xffd2811e));
57 static constexpr gfx::sRGBColor
sColorMeterRed10(
58 gfx::sRGBColor::UnusualFromARGB(0xffe22850));
59 static constexpr gfx::sRGBColor
sColorMeterRed20(
60 gfx::sRGBColor::UnusualFromARGB(0xff810220));
62 static constexpr gfx::sRGBColor
sScrollbarColor(
63 gfx::sRGBColor::UnusualFromARGB(0xfff0f0f0));
64 static constexpr gfx::sRGBColor
sScrollbarBorderColor(gfx::sRGBColor(1.0f
, 1.0f
,
66 static constexpr gfx::sRGBColor
sScrollbarThumbColor(
67 gfx::sRGBColor::UnusualFromARGB(0xffcdcdcd));
69 static const CSSCoord kMinimumColorPickerHeight
= 32.0f
;
70 static const CSSCoord kMinimumRangeThumbSize
= 20.0f
;
71 static const CSSCoord kMinimumDropdownArrowButtonWidth
= 18.0f
;
72 static const CSSCoord kMinimumSpinnerButtonWidth
= 18.0f
;
73 static const CSSCoord kMinimumSpinnerButtonHeight
= 9.0f
;
74 static const CSSCoord kButtonBorderWidth
= 1.0f
;
75 static const CSSCoord kMenulistBorderWidth
= 1.0f
;
76 static const CSSCoord kTextFieldBorderWidth
= 1.0f
;
77 static const CSSCoord kRangeHeight
= 6.0f
;
78 static const CSSCoord kProgressbarHeight
= 6.0f
;
79 static const CSSCoord kMeterHeight
= 12.0f
;
81 // nsCheckboxRadioFrame takes the bottom of the content box as the baseline.
82 // This border-width makes its baseline 2px under the bottom, which is nice.
83 static constexpr CSSCoord kCheckboxRadioBorderWidth
= 2.0f
;
86 } // namespace mozilla
88 class nsNativeBasicTheme
: protected nsNativeTheme
, public nsITheme
{
90 using sRGBColor
= mozilla::gfx::sRGBColor
;
91 using CSSCoord
= mozilla::CSSCoord
;
92 using CSSPoint
= mozilla::CSSPoint
;
93 using CSSIntCoord
= mozilla::CSSIntCoord
;
94 using ComputedStyle
= mozilla::ComputedStyle
;
95 using EventStates
= mozilla::EventStates
;
96 using DrawTarget
= mozilla::gfx::DrawTarget
;
97 using Path
= mozilla::gfx::Path
;
98 using Rect
= mozilla::gfx::Rect
;
99 using Point
= mozilla::gfx::Point
;
100 using RectCornerRadii
= mozilla::gfx::RectCornerRadii
;
101 using LayoutDeviceCoord
= mozilla::LayoutDeviceCoord
;
102 using LayoutDeviceRect
= mozilla::LayoutDeviceRect
;
107 static void Shutdown();
108 static void LookAndFeelChanged();
110 using DPIRatio
= mozilla::CSSToLayoutDeviceScale
;
112 NS_DECL_ISUPPORTS_INHERITED
114 // The nsITheme interface.
115 NS_IMETHOD
DrawWidgetBackground(gfxContext
* aContext
, nsIFrame
*,
116 StyleAppearance
, const nsRect
& aRect
,
117 const nsRect
& aDirtyRect
,
118 DrawOverflow
) 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
&, DrawOverflow
);
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 mozilla::Maybe
<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
&,
193 sRGBColor
ComputeCheckmarkColor(const EventStates
&, const AccentColor
&,
195 sRGBColor
ComputeBorderColor(const EventStates
&, UseSystemColors
);
197 std::pair
<sRGBColor
, sRGBColor
> ComputeButtonColors(const EventStates
&,
199 nsIFrame
* = nullptr);
200 std::pair
<sRGBColor
, sRGBColor
> ComputeTextfieldColors(const EventStates
&,
202 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeProgressColors(const EventStates
&,
205 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeTrackColors(const EventStates
&,
207 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeThumbColors(const EventStates
&,
210 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressColors(const AccentColor
&,
212 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressTrackColors(UseSystemColors
);
213 std::pair
<sRGBColor
, sRGBColor
> ComputeMeterchunkColors(
214 const EventStates
& aMeterState
, UseSystemColors
);
215 std::array
<sRGBColor
, 3> ComputeFocusRectColors(const AccentColor
&,
218 static bool ShouldUseDarkScrollbar(nsIFrame
*, const ComputedStyle
&);
219 sRGBColor
ComputeScrollbarTrackColor(nsIFrame
*, const ComputedStyle
&,
220 const EventStates
& aDocumentState
,
222 sRGBColor
ComputeScrollbarThumbColor(nsIFrame
*, const ComputedStyle
&,
223 const EventStates
& aElementState
,
224 const EventStates
& aDocumentState
,
226 // Returned colors are button, arrow.
227 std::pair
<sRGBColor
, sRGBColor
> ComputeScrollbarButtonColors(
228 nsIFrame
*, StyleAppearance
, const ComputedStyle
&,
229 const EventStates
& aElementState
, const EventStates
& aDocumentState
,
232 template <typename PaintBackendData
>
233 void PaintRoundedFocusRect(PaintBackendData
&, const LayoutDeviceRect
&,
234 const AccentColor
&, UseSystemColors
, DPIRatio
,
235 CSSCoord aRadius
, CSSCoord aOffset
);
236 template <typename PaintBackendData
>
237 void PaintAutoStyleOutline(nsIFrame
*, PaintBackendData
&,
238 const LayoutDeviceRect
&, const AccentColor
&,
239 UseSystemColors
, DPIRatio
);
241 static void PaintRoundedRectWithRadius(DrawTarget
&,
242 const LayoutDeviceRect
& aRect
,
243 const LayoutDeviceRect
& aClipRect
,
244 const sRGBColor
& aBackgroundColor
,
245 const sRGBColor
& aBorderColor
,
246 CSSCoord aBorderWidth
,
247 CSSCoord aRadius
, DPIRatio
);
248 static void PaintRoundedRectWithRadius(WebRenderBackendData
&,
249 const LayoutDeviceRect
& aRect
,
250 const LayoutDeviceRect
& aClipRect
,
251 const sRGBColor
& aBackgroundColor
,
252 const sRGBColor
& aBorderColor
,
253 CSSCoord aBorderWidth
,
254 CSSCoord aRadius
, DPIRatio
);
255 template <typename PaintBackendData
>
256 static void PaintRoundedRectWithRadius(PaintBackendData
& aData
,
257 const LayoutDeviceRect
& aRect
,
258 const sRGBColor
& aBackgroundColor
,
259 const sRGBColor
& aBorderColor
,
260 CSSCoord aBorderWidth
,
261 CSSCoord aRadius
, DPIRatio aDpiRatio
) {
262 PaintRoundedRectWithRadius(aData
, aRect
, aRect
, aBackgroundColor
,
263 aBorderColor
, aBorderWidth
, aRadius
, aDpiRatio
);
266 static void FillRect(DrawTarget
&, const LayoutDeviceRect
&, const sRGBColor
&);
267 static void FillRect(WebRenderBackendData
&, const LayoutDeviceRect
&,
270 void PaintCheckboxControl(DrawTarget
& aDrawTarget
, const LayoutDeviceRect
&,
271 const EventStates
&, const AccentColor
&,
272 UseSystemColors
, DPIRatio
);
273 void PaintCheckMark(DrawTarget
&, const LayoutDeviceRect
&, const EventStates
&,
274 const AccentColor
&, UseSystemColors
);
275 void PaintIndeterminateMark(DrawTarget
&, const LayoutDeviceRect
&,
276 const EventStates
&, const AccentColor
&,
279 template <typename PaintBackendData
>
280 void PaintStrokedCircle(PaintBackendData
&, const LayoutDeviceRect
&,
281 const sRGBColor
& aBackgroundColor
,
282 const sRGBColor
& aBorderColor
,
283 const CSSCoord aBorderWidth
, DPIRatio
);
284 void PaintCircleShadow(DrawTarget
&, const LayoutDeviceRect
& aBoxRect
,
285 const LayoutDeviceRect
& aClipRect
, float aShadowAlpha
,
286 const CSSPoint
& aShadowOffset
,
287 CSSCoord aShadowBlurStdDev
, DPIRatio
);
288 void PaintCircleShadow(WebRenderBackendData
&,
289 const LayoutDeviceRect
& aBoxRect
,
290 const LayoutDeviceRect
& aClipRect
, float aShadowAlpha
,
291 const CSSPoint
& aShadowOffset
,
292 CSSCoord aShadowBlurStdDev
, DPIRatio
);
293 template <typename PaintBackendData
>
294 void PaintRadioControl(PaintBackendData
&, const LayoutDeviceRect
&,
295 const EventStates
&, const AccentColor
&,
296 UseSystemColors
, DPIRatio
);
297 template <typename PaintBackendData
>
298 void PaintRadioCheckmark(PaintBackendData
&, const LayoutDeviceRect
&,
299 const EventStates
&, DPIRatio
);
300 template <typename PaintBackendData
>
301 void PaintTextField(PaintBackendData
&, const LayoutDeviceRect
&,
302 const EventStates
&, const AccentColor
& aAccent
,
303 UseSystemColors
, DPIRatio
);
304 template <typename PaintBackendData
>
305 void PaintListbox(PaintBackendData
&, const LayoutDeviceRect
&,
306 const EventStates
&, const AccentColor
&, UseSystemColors
,
308 template <typename PaintBackendData
>
309 void PaintMenulist(PaintBackendData
&, const LayoutDeviceRect
&,
310 const EventStates
&, const AccentColor
&, UseSystemColors
,
312 void PaintArrow(DrawTarget
&, const LayoutDeviceRect
&,
313 const float aArrowPolygonX
[], const float aArrowPolygonY
[],
314 const float aArrowPolygonSize
, const int32_t aArrowNumPoints
,
315 const sRGBColor aFillColor
);
316 void PaintMenulistArrowButton(nsIFrame
*, DrawTarget
&, const LayoutDeviceRect
&,
317 const EventStates
&, UseSystemColors
);
318 void PaintSpinnerButton(nsIFrame
*, DrawTarget
&, const LayoutDeviceRect
&,
319 const EventStates
&, StyleAppearance
, UseSystemColors
,
321 template <typename PaintBackendData
>
322 void PaintRange(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
323 const EventStates
&, const AccentColor
&, UseSystemColors
,
324 DPIRatio
, bool aHorizontal
);
325 template <typename PaintBackendData
>
326 void PaintProgress(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
327 const EventStates
&, const AccentColor
&, UseSystemColors
,
328 DPIRatio
, bool aIsMeter
);
329 template <typename PaintBackendData
>
330 void PaintButton(nsIFrame
*, PaintBackendData
&, const LayoutDeviceRect
&,
331 const EventStates
&, const AccentColor
&, UseSystemColors
,
334 void PaintScrollbarButton(DrawTarget
&, StyleAppearance
,
335 const LayoutDeviceRect
&, nsIFrame
*,
336 const ComputedStyle
&,
337 const EventStates
& aElementState
,
338 const EventStates
& aDocumentState
, UseSystemColors
,
341 virtual bool PaintScrollbarThumb(DrawTarget
&, const LayoutDeviceRect
&,
342 bool aHorizontal
, nsIFrame
*,
343 const ComputedStyle
&,
344 const EventStates
& aElementState
,
345 const EventStates
& aDocumentState
,
346 UseSystemColors
, DPIRatio
);
347 virtual bool PaintScrollbarThumb(WebRenderBackendData
&,
348 const LayoutDeviceRect
&, bool aHorizontal
,
349 nsIFrame
*, const ComputedStyle
&,
350 const EventStates
& aElementState
,
351 const EventStates
& aDocumentState
,
352 UseSystemColors
, DPIRatio
);
353 template <typename PaintBackendData
>
354 bool DoPaintDefaultScrollbarThumb(PaintBackendData
&, const LayoutDeviceRect
&,
355 bool aHorizontal
, nsIFrame
*,
356 const ComputedStyle
&,
357 const EventStates
& aElementState
,
358 const EventStates
& aDocumentState
,
359 UseSystemColors aUseSystemColors
, DPIRatio
);
361 virtual bool PaintScrollbar(DrawTarget
&, const LayoutDeviceRect
&,
362 bool aHorizontal
, nsIFrame
*, const ComputedStyle
&,
363 const EventStates
& aElementState
,
364 const EventStates
& aDocumentState
,
365 UseSystemColors
, DPIRatio
);
366 virtual bool PaintScrollbar(WebRenderBackendData
&, const LayoutDeviceRect
&,
367 bool aHorizontal
, nsIFrame
*, const ComputedStyle
&,
368 const EventStates
& aElementState
,
369 const EventStates
& aDocumentState
,
370 UseSystemColors
, DPIRatio
);
371 template <typename PaintBackendData
>
372 bool DoPaintDefaultScrollbar(PaintBackendData
&, const LayoutDeviceRect
&,
373 bool aHorizontal
, nsIFrame
*,
374 const ComputedStyle
&,
375 const EventStates
& aElementState
,
376 const EventStates
& aDocumentState
,
377 UseSystemColors aUseSystemColors
, DPIRatio
);
379 virtual bool PaintScrollbarTrack(DrawTarget
&, const LayoutDeviceRect
&,
380 bool aHorizontal
, nsIFrame
*,
381 const ComputedStyle
&,
382 const EventStates
& aDocumentState
,
383 UseSystemColors
, DPIRatio
) {
384 // Draw nothing by default. Subclasses can override this.
387 virtual bool PaintScrollbarTrack(WebRenderBackendData
&,
388 const LayoutDeviceRect
&, bool aHorizontal
,
389 nsIFrame
*, const ComputedStyle
&,
390 const EventStates
& aDocumentState
,
391 UseSystemColors
, DPIRatio
) {
392 // Draw nothing by default. Subclasses can override this.
396 virtual bool PaintScrollCorner(DrawTarget
&, const LayoutDeviceRect
&,
397 nsIFrame
*, const ComputedStyle
&,
398 const EventStates
& aDocumentState
,
399 UseSystemColors
, DPIRatio
);
400 virtual bool PaintScrollCorner(WebRenderBackendData
&, const LayoutDeviceRect
&,
401 nsIFrame
*, const ComputedStyle
&,
402 const EventStates
& aDocumentState
,
403 UseSystemColors
, DPIRatio
);
404 template <typename PaintBackendData
>
405 bool DoPaintDefaultScrollCorner(PaintBackendData
&, const LayoutDeviceRect
&,
406 nsIFrame
*, const ComputedStyle
&,
407 const EventStates
& aDocumentState
,
408 UseSystemColors
, DPIRatio
);
410 static CSSIntCoord sHorizontalScrollbarHeight
;
411 static CSSIntCoord sVerticalScrollbarWidth
;
412 static bool sOverlayScrollbars
;
414 static void PrefChangedCallback(const char*, void*) { LookAndFeelChanged(); }
415 static void RecomputeAccentColors();
416 static void RecomputeScrollbarParams();