/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_widget_Theme_h #define mozilla_widget_Theme_h #include "Units.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Rect.h" #include "mozilla/gfx/Types.h" #include "nsITheme.h" #include "nsNativeTheme.h" #include "ScrollbarDrawing.h" namespace mozilla { enum class StyleSystemColor : uint8_t; namespace widget { class Theme : protected nsNativeTheme, public nsITheme { protected: using sRGBColor = gfx::sRGBColor; using DrawTarget = gfx::DrawTarget; using Path = gfx::Path; using Rect = gfx::Rect; using Point = gfx::Point; using RectCornerRadii = gfx::RectCornerRadii; using Colors = ThemeColors; using AccentColor = ThemeAccentColor; using ElementState = dom::ElementState; public: explicit Theme(UniquePtr&& aScrollbarDrawing) : mScrollbarDrawing(std::move(aScrollbarDrawing)) { mScrollbarDrawing->RecomputeScrollbarParams(); } static void Init(); static void Shutdown(); static void LookAndFeelChanged(); using DPIRatio = CSSToLayoutDeviceScale; NS_DECL_ISUPPORTS_INHERITED // The nsITheme interface. NS_IMETHOD DrawWidgetBackground(gfxContext* aContext, nsIFrame*, StyleAppearance, const nsRect& aRect, const nsRect& aDirtyRect, DrawOverflow) override; bool CreateWebRenderCommandsForWidget( wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources, const layers::StackingContextHelper& aSc, layers::RenderRootStateManager* aManager, nsIFrame*, StyleAppearance, const nsRect& aRect) override; // PaintBackendData will be either a DrawTarget, or a WebRenderBackendData. // // The return value represents whether the widget could be painted with the // given back-end. template bool DoDrawWidgetBackground(PaintBackendData&, nsIFrame*, StyleAppearance, const nsRect&, DrawOverflow); [[nodiscard]] LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext, nsIFrame*, StyleAppearance) override; bool GetWidgetPadding(nsDeviceContext* aContext, nsIFrame*, StyleAppearance, LayoutDeviceIntMargin* aResult) override; bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame*, StyleAppearance, nsRect* aOverflowRect) override; LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*, nsIFrame*, StyleAppearance) override; Transparency GetWidgetTransparency(nsIFrame*, StyleAppearance) override; NS_IMETHOD WidgetStateChanged(nsIFrame*, StyleAppearance, nsAtom* aAttribute, bool* aShouldRepaint, const nsAttrValue* aOldValue) override; NS_IMETHOD ThemeChanged() override; bool WidgetAppearanceDependsOnWindowFocus(StyleAppearance) override; /*bool NeedToClearBackgroundBehindWidget( nsIFrame*, StyleAppearance) override;*/ ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame*, StyleAppearance) override; bool ThemeSupportsWidget(nsPresContext*, nsIFrame*, StyleAppearance) override; bool WidgetIsContainer(StyleAppearance) override; bool ThemeDrawsFocusForWidget(nsIFrame*, StyleAppearance) override; bool ThemeNeedsComboboxDropmarker() override; ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth, Overlay) override; nscoord GetCheckboxRadioPrefSize() override; static UniquePtr ScrollbarStyle(); protected: virtual ~Theme() = default; static DPIRatio GetDPIRatio(nsPresContext*, StyleAppearance); static DPIRatio GetDPIRatio(nsIFrame*, StyleAppearance); std::tuple ComputeCheckboxColors( const ElementState&, StyleAppearance, const Colors&); enum class OutlineCoversBorder : bool { No, Yes }; sRGBColor ComputeBorderColor(const ElementState&, const Colors&, OutlineCoversBorder); std::pair ComputeButtonColors(const ElementState&, const Colors&, nsIFrame* = nullptr); std::pair ComputeTextfieldColors(const ElementState&, const Colors&, OutlineCoversBorder); std::pair ComputeRangeProgressColors( const ElementState&, const Colors&); std::pair ComputeRangeTrackColors(const ElementState&, const Colors&); std::pair ComputeRangeThumbColors(const ElementState&, const Colors&); std::pair ComputeProgressColors(const Colors&); std::pair ComputeProgressTrackColors(const Colors&); std::pair ComputeMeterchunkColors( const ElementState& aMeterState, const Colors&); std::array ComputeFocusRectColors(const Colors&); template void PaintRoundedFocusRect(PaintBackendData&, const LayoutDeviceRect&, const Colors&, DPIRatio, CSSCoord aRadius, CSSCoord aOffset); template void PaintAutoStyleOutline(nsIFrame*, PaintBackendData&, const LayoutDeviceRect&, const Colors&, DPIRatio); void PaintCheckboxControl(DrawTarget& aDrawTarget, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio); void PaintCheckMark(DrawTarget&, const LayoutDeviceRect&, const sRGBColor&); void PaintIndeterminateMark(DrawTarget&, const LayoutDeviceRect&, const sRGBColor&); template void PaintStrokedCircle(PaintBackendData&, const LayoutDeviceRect&, const sRGBColor& aBackgroundColor, const sRGBColor& aBorderColor, const CSSCoord aBorderWidth, DPIRatio); void PaintCircleShadow(DrawTarget&, const LayoutDeviceRect& aBoxRect, const LayoutDeviceRect& aClipRect, float aShadowAlpha, const CSSPoint& aShadowOffset, CSSCoord aShadowBlurStdDev, DPIRatio); void PaintCircleShadow(WebRenderBackendData&, const LayoutDeviceRect& aBoxRect, const LayoutDeviceRect& aClipRect, float aShadowAlpha, const CSSPoint& aShadowOffset, CSSCoord aShadowBlurStdDev, DPIRatio); template void PaintRadioControl(PaintBackendData&, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio); template void PaintRadioCheckmark(PaintBackendData&, const LayoutDeviceRect&, const ElementState&, DPIRatio); template void PaintTextField(PaintBackendData&, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio); template void PaintListbox(PaintBackendData&, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio); template void PaintMenulist(PaintBackendData&, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio); void PaintMenulistArrowButton(nsIFrame*, DrawTarget&, const LayoutDeviceRect&, const ElementState&); void PaintSpinnerButton(nsIFrame*, DrawTarget&, const LayoutDeviceRect&, const ElementState&, StyleAppearance, const Colors&, DPIRatio); template void PaintRange(nsIFrame*, PaintBackendData&, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio, bool aHorizontal); template void PaintProgress(nsIFrame*, PaintBackendData&, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio, bool aIsMeter); template void PaintButton(nsIFrame*, PaintBackendData&, const LayoutDeviceRect&, const ElementState&, const Colors&, DPIRatio); static void PrefChangedCallback(const char*, void*) { LookAndFeel::NotifyChangedAllWindows(ThemeChangeKind::Layout); } void SetScrollbarDrawing(UniquePtr&& aScrollbarDrawing) { mScrollbarDrawing = std::move(aScrollbarDrawing); mScrollbarDrawing->RecomputeScrollbarParams(); } ScrollbarDrawing& GetScrollbarDrawing() const { return *mScrollbarDrawing; } UniquePtr mScrollbarDrawing; bool ThemeSupportsScrollbarButtons() override; }; } // namespace widget } // namespace mozilla #endif