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 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
;
106 static void Shutdown();
107 static void LookAndFeelChanged();
109 using DPIRatio
= mozilla::CSSToLayoutDeviceScale
;
111 NS_DECL_ISUPPORTS_INHERITED
113 // The nsITheme interface.
114 NS_IMETHOD
DrawWidgetBackground(gfxContext
* aContext
, nsIFrame
*,
115 StyleAppearance
, const nsRect
& aRect
,
116 const nsRect
& aDirtyRect
,
117 DrawOverflow
) override
;
119 struct WebRenderBackendData
{
120 mozilla::wr::DisplayListBuilder
& mBuilder
;
121 mozilla::wr::IpcResourceUpdateQueue
& mResources
;
122 const mozilla::layers::StackingContextHelper
& mSc
;
123 mozilla::layers::RenderRootStateManager
* mManager
;
126 bool CreateWebRenderCommandsForWidget(
127 mozilla::wr::DisplayListBuilder
& aBuilder
,
128 mozilla::wr::IpcResourceUpdateQueue
& aResources
,
129 const mozilla::layers::StackingContextHelper
& aSc
,
130 mozilla::layers::RenderRootStateManager
* aManager
, nsIFrame
*,
131 StyleAppearance
, const nsRect
& aRect
) override
;
133 // PaintBackendData will be either a DrawTarget, or a WebRenderBackendData.
135 // The return value represents whether the widget could be painted with the
137 template <typename PaintBackendData
>
138 bool DoDrawWidgetBackground(PaintBackendData
&, nsIFrame
*, StyleAppearance
,
139 const nsRect
&, DrawOverflow
);
141 [[nodiscard
]] LayoutDeviceIntMargin
GetWidgetBorder(nsDeviceContext
* aContext
,
143 StyleAppearance
) override
;
144 bool GetWidgetPadding(nsDeviceContext
* aContext
, nsIFrame
*, StyleAppearance
,
145 LayoutDeviceIntMargin
* aResult
) override
;
146 bool GetWidgetOverflow(nsDeviceContext
* aContext
, nsIFrame
*, StyleAppearance
,
147 nsRect
* aOverflowRect
) override
;
148 NS_IMETHOD
GetMinimumWidgetSize(nsPresContext
* aPresContext
, nsIFrame
*,
150 mozilla::LayoutDeviceIntSize
* aResult
,
151 bool* aIsOverridable
) override
;
152 Transparency
GetWidgetTransparency(nsIFrame
*, StyleAppearance
) override
;
153 NS_IMETHOD
WidgetStateChanged(nsIFrame
*, StyleAppearance
, nsAtom
* aAttribute
,
154 bool* aShouldRepaint
,
155 const nsAttrValue
* aOldValue
) override
;
156 NS_IMETHOD
ThemeChanged() override
;
157 bool WidgetAppearanceDependsOnWindowFocus(StyleAppearance
) override
;
158 /*bool NeedToClearBackgroundBehindWidget(
159 nsIFrame*, StyleAppearance) override;*/
160 ThemeGeometryType
ThemeGeometryTypeForWidget(nsIFrame
*,
161 StyleAppearance
) override
;
162 bool ThemeSupportsWidget(nsPresContext
*, nsIFrame
*, StyleAppearance
) override
;
163 bool WidgetIsContainer(StyleAppearance
) override
;
164 bool ThemeDrawsFocusForWidget(StyleAppearance
) override
;
165 bool ThemeNeedsComboboxDropmarker() override
;
166 ScrollbarSizes
GetScrollbarSizes(nsPresContext
*, StyleScrollbarWidth
,
168 static nscolor
AdjustUnthemedScrollbarThumbColor(nscolor
, EventStates
);
169 static nscolor
GetScrollbarButtonColor(nscolor aTrackColor
, EventStates
);
170 static mozilla::Maybe
<nscolor
> GetScrollbarArrowColor(nscolor aButtonColor
);
172 nscoord
GetCheckboxRadioPrefSize() override
;
175 nsNativeBasicTheme() = default;
176 virtual ~nsNativeBasicTheme() = default;
178 static DPIRatio
GetDPIRatioForScrollbarPart(nsPresContext
*);
179 static DPIRatio
GetDPIRatio(nsPresContext
*, StyleAppearance
);
180 static DPIRatio
GetDPIRatio(nsIFrame
*, StyleAppearance
);
181 static bool IsDateTimeResetButton(nsIFrame
*);
182 static bool IsColorPickerButton(nsIFrame
*);
184 // Whether we should use system colors (for high contrast mode).
185 enum class UseSystemColors
: bool { No
, Yes
};
186 static UseSystemColors
ShouldUseSystemColors(const mozilla::dom::Document
&);
188 std::pair
<sRGBColor
, sRGBColor
> ComputeCheckboxColors(const EventStates
&,
191 sRGBColor
ComputeCheckmarkColor(const EventStates
&, UseSystemColors
);
192 sRGBColor
ComputeBorderColor(const EventStates
&, UseSystemColors
);
194 std::pair
<sRGBColor
, sRGBColor
> ComputeButtonColors(const EventStates
&,
196 nsIFrame
* = nullptr);
197 std::pair
<sRGBColor
, sRGBColor
> ComputeTextfieldColors(const EventStates
&,
199 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeProgressColors(const EventStates
&,
201 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeTrackColors(const EventStates
&,
203 std::pair
<sRGBColor
, sRGBColor
> ComputeRangeThumbColors(const EventStates
&,
205 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressColors(UseSystemColors
);
206 std::pair
<sRGBColor
, sRGBColor
> ComputeProgressTrackColors(UseSystemColors
);
207 std::pair
<sRGBColor
, sRGBColor
> ComputeMeterchunkColors(
208 const EventStates
& aMeterState
, UseSystemColors
);
209 sRGBColor
ComputeMenulistArrowButtonColor(const EventStates
&,
211 std::array
<sRGBColor
, 3> ComputeFocusRectColors(UseSystemColors
);
213 static bool ShouldUseDarkScrollbar(nsIFrame
*, const ComputedStyle
&);
214 sRGBColor
ComputeScrollbarTrackColor(nsIFrame
*, const ComputedStyle
&,
215 const EventStates
& aDocumentState
,
217 sRGBColor
ComputeScrollbarThumbColor(nsIFrame
*, const ComputedStyle
&,
218 const EventStates
& aElementState
,
219 const EventStates
& aDocumentState
,
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
& aElementState
,
352 const EventStates
& aDocumentState
,
353 UseSystemColors
, DPIRatio
);
354 virtual bool PaintScrollbar(WebRenderBackendData
&, const LayoutDeviceRect
&,
355 bool aHorizontal
, nsIFrame
*, const ComputedStyle
&,
356 const EventStates
& aElementState
,
357 const EventStates
& aDocumentState
,
358 UseSystemColors
, DPIRatio
);
359 template <typename PaintBackendData
>
360 bool DoPaintDefaultScrollbar(PaintBackendData
&, const LayoutDeviceRect
&,
361 bool aHorizontal
, nsIFrame
*,
362 const ComputedStyle
&,
363 const EventStates
& aElementState
,
364 const EventStates
& aDocumentState
,
365 UseSystemColors aUseSystemColors
, DPIRatio
);
367 virtual bool PaintScrollbarTrack(DrawTarget
&, const LayoutDeviceRect
&,
368 bool aHorizontal
, nsIFrame
*,
369 const ComputedStyle
&,
370 const EventStates
& aDocumentState
,
371 UseSystemColors
, DPIRatio
) {
372 // Draw nothing by default. Subclasses can override this.
375 virtual bool PaintScrollbarTrack(WebRenderBackendData
&,
376 const LayoutDeviceRect
&, bool aHorizontal
,
377 nsIFrame
*, const ComputedStyle
&,
378 const EventStates
& aDocumentState
,
379 UseSystemColors
, DPIRatio
) {
380 // Draw nothing by default. Subclasses can override this.
384 virtual bool PaintScrollCorner(DrawTarget
&, const LayoutDeviceRect
&,
385 nsIFrame
*, const ComputedStyle
&,
386 const EventStates
& aDocumentState
,
387 UseSystemColors
, DPIRatio
);
388 virtual bool PaintScrollCorner(WebRenderBackendData
&, const LayoutDeviceRect
&,
389 nsIFrame
*, const ComputedStyle
&,
390 const EventStates
& aDocumentState
,
391 UseSystemColors
, DPIRatio
);
392 template <typename PaintBackendData
>
393 bool DoPaintDefaultScrollCorner(PaintBackendData
&, const LayoutDeviceRect
&,
394 nsIFrame
*, const ComputedStyle
&,
395 const EventStates
& aDocumentState
,
396 UseSystemColors
, DPIRatio
);
398 static sRGBColor sAccentColor
;
399 static sRGBColor sAccentColorForeground
;
401 // Note that depending on the exact accent color, lighter/darker might really
403 static sRGBColor sAccentColorLight
;
404 static sRGBColor sAccentColorDark
;
405 static sRGBColor sAccentColorDarker
;
406 static CSSIntCoord sHorizontalScrollbarHeight
;
407 static CSSIntCoord sVerticalScrollbarWidth
;
408 static bool sOverlayScrollbars
;
410 static void PrefChangedCallback(const char*, void*) { LookAndFeelChanged(); }
411 static void RecomputeAccentColors();
412 static void RecomputeScrollbarParams();