Bug 1715716 [wpt PR 29323] - Use unittest.mock instead of the mock package, a=testonly
[gecko.git] / widget / nsNativeBasicTheme.h
blob09d8c1e4939ef7842993453a201a64539d4f9585
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
10 #include "Units.h"
11 #include "mozilla/gfx/2D.h"
12 #include "mozilla/gfx/Rect.h"
13 #include "mozilla/gfx/Types.h"
14 #include "nsITheme.h"
15 #include "nsNativeTheme.h"
17 namespace mozilla {
19 enum class StyleSystemColor : uint8_t;
21 namespace widget {
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,
65 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;
85 } // namespace widget
86 } // namespace mozilla
88 class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
89 protected:
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;
103 class AccentColor;
105 public:
106 static void Init();
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
137 // given back-end.
138 template <typename PaintBackendData>
139 bool DoDrawWidgetBackground(PaintBackendData&, nsIFrame*, StyleAppearance,
140 const nsRect&, DrawOverflow);
142 [[nodiscard]] LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
143 nsIFrame*,
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*,
150 StyleAppearance,
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,
168 Overlay) override;
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;
175 protected:
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&,
190 StyleAppearance,
191 const AccentColor&,
192 UseSystemColors);
193 sRGBColor ComputeCheckmarkColor(const EventStates&, const AccentColor&,
194 UseSystemColors);
195 sRGBColor ComputeBorderColor(const EventStates&, UseSystemColors);
197 std::pair<sRGBColor, sRGBColor> ComputeButtonColors(const EventStates&,
198 UseSystemColors,
199 nsIFrame* = nullptr);
200 std::pair<sRGBColor, sRGBColor> ComputeTextfieldColors(const EventStates&,
201 UseSystemColors);
202 std::pair<sRGBColor, sRGBColor> ComputeRangeProgressColors(const EventStates&,
203 const AccentColor&,
204 UseSystemColors);
205 std::pair<sRGBColor, sRGBColor> ComputeRangeTrackColors(const EventStates&,
206 UseSystemColors);
207 std::pair<sRGBColor, sRGBColor> ComputeRangeThumbColors(const EventStates&,
208 const AccentColor&,
209 UseSystemColors);
210 std::pair<sRGBColor, sRGBColor> ComputeProgressColors(const AccentColor&,
211 UseSystemColors);
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&,
216 UseSystemColors);
218 static bool ShouldUseDarkScrollbar(nsIFrame*, const ComputedStyle&);
219 sRGBColor ComputeScrollbarTrackColor(nsIFrame*, const ComputedStyle&,
220 const EventStates& aDocumentState,
221 UseSystemColors);
222 sRGBColor ComputeScrollbarThumbColor(nsIFrame*, const ComputedStyle&,
223 const EventStates& aElementState,
224 const EventStates& aDocumentState,
225 UseSystemColors);
226 // Returned colors are button, arrow.
227 std::pair<sRGBColor, sRGBColor> ComputeScrollbarButtonColors(
228 nsIFrame*, StyleAppearance, const ComputedStyle&,
229 const EventStates& aElementState, const EventStates& aDocumentState,
230 UseSystemColors);
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&,
268 const sRGBColor&);
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&,
277 UseSystemColors);
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,
307 DPIRatio);
308 template <typename PaintBackendData>
309 void PaintMenulist(PaintBackendData&, const LayoutDeviceRect&,
310 const EventStates&, const AccentColor&, UseSystemColors,
311 DPIRatio);
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,
320 DPIRatio);
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,
332 DPIRatio);
334 void PaintScrollbarButton(DrawTarget&, StyleAppearance,
335 const LayoutDeviceRect&, nsIFrame*,
336 const ComputedStyle&,
337 const EventStates& aElementState,
338 const EventStates& aDocumentState, UseSystemColors,
339 DPIRatio);
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.
385 return true;
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.
393 return true;
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();
419 #endif