/* -*- 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 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 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 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