gecko-dev/widget/ThemeColors.h

118 lines
3.9 KiB
C++

/* -*- Mode: C++; tab-width: 40; 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_ThemeColors_h
#define mozilla_widget_ThemeColors_h
#include "mozilla/dom/Document.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/LookAndFeel.h"
#include "nsIFrame.h"
namespace mozilla::widget {
static constexpr gfx::sRGBColor sDefaultAccent(
gfx::sRGBColor::UnusualFromARGB(0xff0060df)); // Luminance: 13.69346%
static constexpr gfx::sRGBColor sDefaultAccentText(
gfx::sRGBColor::OpaqueWhite());
struct ColorPalette;
class ThemeAccentColor {
protected:
using sRGBColor = mozilla::gfx::sRGBColor;
using ComputedStyle = mozilla::ComputedStyle;
Maybe<nscolor> mAccentColor;
const ColorPalette* mDefaultPalette = nullptr;
public:
explicit ThemeAccentColor(const ComputedStyle&, ColorScheme);
virtual ~ThemeAccentColor() = default;
sRGBColor Get() const;
sRGBColor GetForeground() const;
sRGBColor GetLight() const;
sRGBColor GetDark() const;
sRGBColor GetDarker() const;
};
// Widget color information associated to a particular frame.
class ThemeColors {
protected:
using Document = mozilla::dom::Document;
using sRGBColor = mozilla::gfx::sRGBColor;
using LookAndFeel = mozilla::LookAndFeel;
using StyleSystemColor = mozilla::StyleSystemColor;
using AccentColor = ThemeAccentColor;
struct HighContrastInfo {
bool mHighContrast = false;
bool mMustUseLightSystemColors = false;
};
const Document& mDoc;
const HighContrastInfo mHighContrastInfo;
const ColorScheme mColorScheme;
const AccentColor mAccentColor;
public:
explicit ThemeColors(const nsIFrame* aFrame, StyleAppearance aAppearance)
: mDoc(*aFrame->PresContext()->Document()),
mHighContrastInfo(ShouldBeHighContrast(*aFrame->PresContext())),
mColorScheme(
ColorSchemeForWidget(aFrame, aAppearance, mHighContrastInfo)),
mAccentColor(*aFrame->Style(), mColorScheme) {}
virtual ~ThemeColors() = default;
[[nodiscard]] static float ScaleLuminanceBy(float aLuminance, float aFactor) {
return aLuminance >= 0.18f ? aLuminance * aFactor : aLuminance / aFactor;
}
const AccentColor& Accent() const { return mAccentColor; }
bool HighContrast() const { return mHighContrastInfo.mHighContrast; }
bool IsDark() const { return mColorScheme == ColorScheme::Dark; }
nscolor SystemNs(StyleSystemColor aColor) const {
return LookAndFeel::Color(aColor, mColorScheme,
LookAndFeel::ShouldUseStandins(mDoc, aColor));
}
sRGBColor System(StyleSystemColor aColor) const {
return sRGBColor::FromABGR(SystemNs(aColor));
}
template <typename Compute>
sRGBColor SystemOrElse(StyleSystemColor aColor, Compute aCompute) const {
if (auto color = LookAndFeel::GetColor(
aColor, mColorScheme,
LookAndFeel::ShouldUseStandins(mDoc, aColor))) {
return sRGBColor::FromABGR(*color);
}
return aCompute();
}
std::pair<sRGBColor, sRGBColor> SystemPair(StyleSystemColor aFirst,
StyleSystemColor aSecond) const {
return std::make_pair(System(aFirst), System(aSecond));
}
// Whether we should use system colors (for high contrast mode).
static HighContrastInfo ShouldBeHighContrast(const nsPresContext&);
static ColorScheme ColorSchemeForWidget(const nsIFrame*, StyleAppearance,
const HighContrastInfo&);
static void RecomputeAccentColors();
static nscolor ComputeCustomAccentForeground(nscolor aColor);
static nscolor AdjustUnthemedScrollbarThumbColor(nscolor aFaceColor,
dom::ElementState aStates);
};
} // namespace mozilla::widget
#endif