mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
910bd6e0ed
Differential Revision: https://phabricator.services.mozilla.com/D222320
207 lines
9.3 KiB
C++
207 lines
9.3 KiB
C++
/* -*- 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&,
|
|
nsIFrame* = nullptr);
|
|
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&);
|
|
std::array<sRGBColor, 3> ComputeFocusRectColors(const Colors&);
|
|
|
|
template <typename PaintBackendData>
|
|
void PaintRoundedFocusRect(PaintBackendData&, const LayoutDeviceRect&,
|
|
const Colors&, DPIRatio, CSSCoord aRadius,
|
|
CSSCoord aOffset);
|
|
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(nsIFrame*, 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
|