/* -*- 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<ScrollbarDrawing>&& 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 <
typename PaintBackendData>
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;
bool WidgetAttributeChangeRequiresRepaint(StyleAppearance,
nsAtom* aAttribute) 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;
LayoutDeviceIntCoord GetScrollbarSize(
const nsPresContext*,
StyleScrollbarWidth, Overlay) final;
CSSCoord GetCheckboxRadioPrefSize() override;
static UniquePtr<ScrollbarDrawing> ScrollbarStyle();
protected:
virtual ~Theme() =
default;
DPIRatio GetDPIRatio(nsIFrame*, StyleAppearance);
std::tuple<sRGBColor, sRGBColor, sRGBColor> ComputeCheckboxColors(
const ElementState&, StyleAppearance,
const Colors&);
enum class OutlineCoversBorder :
bool { No, Yes };
sRGBColor ComputeBorderColor(
const ElementState&,
const Colors&,
OutlineCoversBorder);
std::pair<sRGBColor, sRGBColor> ComputeButtonColors(
const ElementState&,
const Colors&);
std::pair<sRGBColor, sRGBColor> ComputeTextfieldColors(
const ElementState&,
const Colors&,
OutlineCoversBorder);
std::pair<sRGBColor, sRGBColor> ComputeRangeProgressColors(
const ElementState&,
const Colors&);
std::pair<sRGBColor, sRGBColor> ComputeRangeTrackColors(
const ElementState&,
const Colors&);
std::pair<sRGBColor, sRGBColor> ComputeRangeThumbColors(
const ElementState&,
const Colors&);
std::pair<sRGBColor, sRGBColor> ComputeProgressColors(
const Colors&);
std::pair<sRGBColor, sRGBColor> ComputeProgressTrackColors(
const Colors&);
std::pair<sRGBColor, sRGBColor> ComputeMeterchunkColors(
const ElementState& aMeterState,
const Colors&);
enum class InvertColors :
bool { No =
false, Yes };
template <
typename PaintBackendData>
void PaintAutoStyleOutline(PaintBackendData&,
const LayoutDeviceRect&,
const Colors&,
const RectCornerRadii& aInnerRadii,
LayoutDeviceCoord aOffset, InvertColors, DPIRatio);
template <
typename PaintBackendData>
void PaintAutoStyleOutline(PaintBackendData&,
const LayoutDeviceRect&,
const Colors&, CSSCoord aRadius, CSSCoord aOffset,
InvertColors, DPIRatio);
template <
typename PaintBackendData>
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 <
typename PaintBackendData>
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 <
typename PaintBackendData>
void PaintRadioControl(PaintBackendData&,
const LayoutDeviceRect&,
const ElementState&,
const Colors&, DPIRatio);
template <
typename PaintBackendData>
void PaintRadioCheckmark(PaintBackendData&,
const LayoutDeviceRect&,
const ElementState&, DPIRatio);
template <
typename PaintBackendData>
void PaintTextField(PaintBackendData&,
const LayoutDeviceRect&,
const ElementState&,
const Colors&, DPIRatio);
template <
typename PaintBackendData>
void PaintListbox(PaintBackendData&,
const LayoutDeviceRect&,
const ElementState&,
const Colors&, DPIRatio);
template <
typename PaintBackendData>
void PaintMenulist(PaintBackendData&,
const LayoutDeviceRect&,
const ElementState&,
const Colors&, DPIRatio);
void PaintMenulistArrow(nsIFrame*, DrawTarget&,
const LayoutDeviceRect&);
void PaintSpinnerButton(nsIFrame*, DrawTarget&,
const LayoutDeviceRect&,
const ElementState&, StyleAppearance,
const Colors&,
DPIRatio);
template <
typename PaintBackendData>
void PaintRange(nsIFrame*, PaintBackendData&,
const LayoutDeviceRect&,
const ElementState&,
const Colors&, DPIRatio,
bool aHorizontal);
template <
typename PaintBackendData>
void PaintProgress(nsIFrame*, PaintBackendData&,
const LayoutDeviceRect&,
const ElementState&,
const Colors&, DPIRatio,
bool aIsMeter);
template <
typename PaintBackendData>
void PaintButton(PaintBackendData&,
const LayoutDeviceRect&, StyleAppearance,
const ElementState&,
const Colors&, DPIRatio);
static void PrefChangedCallback(
const char*,
void*) {
LookAndFeel::NotifyChangedAllWindows(ThemeChangeKind::Layout);
}
void SetScrollbarDrawing(UniquePtr<ScrollbarDrawing>&& aScrollbarDrawing) {
mScrollbarDrawing = std::move(aScrollbarDrawing);
mScrollbarDrawing->RecomputeScrollbarParams();
}
ScrollbarDrawing& GetScrollbarDrawing()
const {
return *mScrollbarDrawing; }
UniquePtr<ScrollbarDrawing> mScrollbarDrawing;
bool ThemeSupportsScrollbarButtons() override;
};
}
// namespace widget
}
// namespace mozilla
#endif