| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/color/sys_color_mixer.h" |
| |
| #include "third_party/skia/include/core/SkColor.h" |
| #include "ui/color/color_id.h" |
| #include "ui/color/color_mixer.h" |
| #include "ui/color/color_provider.h" |
| #include "ui/color/color_provider_key.h" |
| #include "ui/color/color_recipe.h" |
| #include "ui/color/color_transform.h" |
| |
| namespace ui { |
| |
| namespace { |
| |
| // Sys token overrides for the non-baseline themed case. |
| void AddThemedSysColorOverrides(ColorMixer& mixer, |
| const ColorProviderKey& key) { |
| const bool dark_mode = key.color_mode == ColorProviderKey::ColorMode::kDark; |
| |
| // Surfaces. |
| mixer[kColorSysSurface] = {dark_mode ? kColorRefNeutral10 |
| : kColorRefNeutral99}; |
| mixer[kColorSysSurfaceNumberedForeground] = {kColorSysPrimary}; |
| |
| // General. |
| mixer[kColorSysOnSurfaceSecondary] = {dark_mode ? kColorRefSecondary80 |
| : kColorRefSecondary30}; |
| mixer[kColorSysTonalContainer] = {dark_mode ? kColorRefPrimary30 |
| : kColorRefPrimary90}; |
| mixer[kColorSysBaseTonalContainer] = {dark_mode ? kColorRefPrimary10 |
| : kColorRefPrimary90}; |
| mixer[kColorSysNeutralContainer] = {dark_mode ? kColorRefNeutralVariant15 |
| : kColorRefNeutral94}; |
| mixer[kColorSysDivider] = {dark_mode ? kColorRefSecondary35 |
| : kColorRefPrimary90}; |
| |
| // Chrome surfaces. |
| mixer[kColorSysBase] = {dark_mode ? kColorRefSecondary25 |
| : kColorRefNeutral98}; |
| mixer[kColorSysBaseContainer] = {dark_mode ? kColorRefSecondary15 |
| : kColorSysSurface4}; |
| mixer[kColorSysBaseContainerElevated] = {dark_mode ? kColorRefSecondary25 |
| : kColorRefNeutral98}; |
| |
| mixer[kColorSysHeader] = {dark_mode ? kColorRefSecondary12 |
| : kColorRefSecondary90}; |
| mixer[kColorSysHeaderContainer] = {dark_mode ? kColorRefSecondary25 |
| : kColorRefPrimary95}; |
| mixer[kColorSysHeaderContainerInactive] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefNeutral99}; |
| mixer[kColorSysOnHeaderDivider] = {dark_mode ? kColorRefSecondary25 |
| : kColorRefPrimary80}; |
| |
| // States. |
| mixer[kColorSysStateInactiveRing] = { |
| dark_mode ? SetAlpha({kColorRefPrimary70}, 0x8C) |
| : SetAlpha({kColorRefPrimary20}, 0x8C)}; |
| mixer[kColorSysStateOnHeaderHover] = {dark_mode ? kColorRefPrimary90 |
| : kColorRefPrimary20}; |
| mixer[kColorSysStateHeaderHover] = {dark_mode ? kColorRefPrimary30 |
| : kColorRefPrimary80}; |
| |
| // Experimentation. |
| mixer[kColorSysOmniboxContainer] = {dark_mode ? kColorRefSecondary15 |
| : kColorSysSurface4}; |
| } |
| |
| // Overrides for the grayscale baseline case. |
| // TODO(tluk): This can probably be migrated to the kMonochrome SchemeVariant |
| // when available. |
| void AddGrayscaleSysColorOverrides(ColorMixer& mixer, |
| const ColorProviderKey& key) { |
| const bool dark_mode = key.color_mode == ColorProviderKey::ColorMode::kDark; |
| |
| // General |
| mixer[kColorSysOnSurfacePrimary] = {dark_mode ? kColorRefNeutral90 |
| : kColorRefNeutral10}; |
| mixer[kColorSysDivider] = {dark_mode ? kColorRefNeutral40 |
| : kColorRefNeutral90}; |
| |
| // Chrome surfaces. |
| mixer[kColorSysHeader] = {dark_mode ? kColorRefNeutral12 |
| : kColorRefNeutral90}; |
| mixer[kColorSysHeaderInactive] = { |
| dark_mode ? AlphaBlend({kColorSysHeader}, {kColorRefNeutral25}, 0x99) |
| : AlphaBlend({kColorSysHeader}, {kColorRefNeutral98}, 0x48)}; |
| mixer[kColorSysHeaderContainer] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefNeutral95}; |
| mixer[kColorSysOnHeaderDivider] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefNeutral80}; |
| mixer[kColorSysOnHeaderPrimary] = {dark_mode ? kColorRefNeutral80 |
| : kColorRefNeutral40}; |
| |
| // States. |
| mixer[kColorSysStateInactiveRing] = { |
| dark_mode ? SetAlpha({kColorRefNeutral70}, 0x8C) |
| : SetAlpha({kColorRefNeutral20}, 0x8C)}; |
| mixer[kColorSysStateOnHeaderHover] = {dark_mode ? kColorRefNeutral90 |
| : kColorRefNeutral20}; |
| mixer[kColorSysStateHeaderHover] = {dark_mode ? kColorRefNeutral30 |
| : kColorRefNeutral80}; |
| |
| // Experimentation. |
| mixer[kColorSysOmniboxContainer] = {dark_mode ? kColorRefNeutral15 |
| : kColorRefNeutral94}; |
| } |
| |
| } // namespace |
| |
| void AddSysColorMixer(ColorProvider* provider, const ColorProviderKey& key) { |
| const bool dark_mode = key.color_mode == ColorProviderKey::ColorMode::kDark; |
| ColorMixer& mixer = provider->AddMixer(); |
| |
| // Primary. |
| mixer[kColorSysPrimary] = {dark_mode ? kColorRefPrimary80 |
| : kColorRefPrimary40}; |
| mixer[kColorSysOnPrimary] = {dark_mode ? kColorRefPrimary20 |
| : kColorRefPrimary100}; |
| mixer[kColorSysPrimaryContainer] = {dark_mode ? kColorRefPrimary30 |
| : kColorRefPrimary90}; |
| mixer[kColorSysOnPrimaryContainer] = {dark_mode ? kColorRefPrimary90 |
| : kColorRefPrimary10}; |
| |
| // Secondary. |
| mixer[kColorSysSecondary] = {dark_mode ? kColorRefSecondary80 |
| : kColorRefSecondary40}; |
| mixer[kColorSysOnSecondary] = {dark_mode ? kColorRefSecondary20 |
| : kColorRefSecondary100}; |
| mixer[kColorSysSecondaryContainer] = {dark_mode ? kColorRefSecondary30 |
| : kColorRefSecondary90}; |
| mixer[kColorSysOnSecondaryContainer] = {dark_mode ? kColorRefSecondary90 |
| : kColorRefSecondary10}; |
| // Tertiary. |
| mixer[kColorSysTertiary] = {dark_mode ? kColorRefTertiary80 |
| : kColorRefTertiary40}; |
| mixer[kColorSysOnTertiary] = {dark_mode ? kColorRefTertiary20 |
| : kColorRefTertiary100}; |
| mixer[kColorSysTertiaryContainer] = {dark_mode ? kColorRefTertiary30 |
| : kColorRefTertiary90}; |
| mixer[kColorSysOnTertiaryContainer] = {dark_mode ? kColorRefTertiary90 |
| : kColorRefTertiary10}; |
| |
| // Error. |
| mixer[kColorSysError] = {dark_mode ? kColorRefError80 : kColorRefError40}; |
| mixer[kColorSysOnError] = {dark_mode ? kColorRefError20 : kColorRefError100}; |
| mixer[kColorSysErrorContainer] = {dark_mode ? kColorRefError30 |
| : kColorRefError90}; |
| mixer[kColorSysOnErrorContainer] = {dark_mode ? kColorRefError90 |
| : kColorRefError10}; |
| // Neutral. |
| mixer[kColorSysOnSurface] = {dark_mode ? kColorRefNeutral90 |
| : kColorRefNeutral10}; |
| mixer[kColorSysOnSurfaceVariant] = {dark_mode ? kColorRefNeutralVariant80 |
| : kColorRefNeutralVariant30}; |
| mixer[kColorSysOutline] = {dark_mode ? kColorRefNeutralVariant60 |
| : kColorRefNeutralVariant50}; |
| mixer[kColorSysSurfaceVariant] = {dark_mode ? kColorRefNeutralVariant30 |
| : kColorRefNeutralVariant90}; |
| |
| // Constant. |
| mixer[kColorSysBlack] = {kColorRefNeutral0}; |
| mixer[kColorSysWhite] = {kColorRefNeutral100}; |
| |
| // Inverse. |
| mixer[kColorSysInversePrimary] = {dark_mode ? kColorRefPrimary40 |
| : kColorRefPrimary80}; |
| mixer[kColorSysInverseOnSurface] = {dark_mode ? kColorRefNeutral10 |
| : kColorRefNeutral95}; |
| mixer[kColorSysInverseSurface] = {dark_mode ? kColorRefNeutral90 |
| : kColorRefNeutral20}; |
| mixer[kColorSysInverseSurfacePrimary] = {dark_mode ? kColorRefPrimary95 |
| : kColorRefPrimary20}; |
| |
| // Surfaces. |
| mixer[kColorSysSurface] = {dark_mode ? kColorRefNeutral10 |
| : kColorRefNeutral100}; |
| mixer[kColorSysSurfaceNumberedForeground] = { |
| dark_mode ? SkColorSetRGB(0xD1, 0xE1, 0xFF) |
| : SkColorSetRGB(0x69, 0x91, 0xD6)}; |
| mixer[kColorSysSurface1] = AlphaBlend({kColorSysSurfaceNumberedForeground}, |
| {kColorSysSurface}, 0x0C); |
| mixer[kColorSysSurface2] = AlphaBlend({kColorSysSurfaceNumberedForeground}, |
| {kColorSysSurface}, 0x14); |
| mixer[kColorSysSurface3] = AlphaBlend({kColorSysSurfaceNumberedForeground}, |
| {kColorSysSurface}, 0x1C); |
| mixer[kColorSysSurface4] = AlphaBlend({kColorSysSurfaceNumberedForeground}, |
| {kColorSysSurface}, 0x1E); |
| mixer[kColorSysSurface5] = AlphaBlend({kColorSysSurfaceNumberedForeground}, |
| {kColorSysSurface}, 0x23); |
| |
| // General. |
| mixer[kColorSysOnSurfaceSecondary] = {dark_mode ? kColorRefNeutral80 |
| : kColorRefNeutral30}; |
| mixer[kColorSysOnSurfaceSubtle] = {dark_mode ? kColorRefNeutral80 |
| : kColorRefNeutral30}; |
| mixer[kColorSysOnSurfacePrimary] = {dark_mode ? kColorRefPrimary90 |
| : kColorRefPrimary10}; |
| mixer[kColorSysOnSurfacePrimaryInactive] = {dark_mode ? kColorRefNeutral90 |
| : kColorRefNeutral10}; |
| |
| mixer[kColorSysTonalContainer] = {dark_mode ? kColorRefSecondary30 |
| : kColorRefPrimary90}; |
| mixer[kColorSysOnTonalContainer] = {dark_mode ? kColorRefSecondary90 |
| : kColorRefPrimary10}; |
| mixer[kColorSysBaseTonalContainer] = {dark_mode ? kColorRefSecondary10 |
| : kColorRefPrimary90}; |
| mixer[kColorSysOnBaseTonalContainer] = {dark_mode ? kColorRefSecondary90 |
| : kColorRefPrimary10}; |
| mixer[kColorSysTonalOutline] = {dark_mode ? kColorRefSecondary50 |
| : kColorRefPrimary80}; |
| mixer[kColorSysNeutralOutline] = {dark_mode ? kColorRefNeutral50 |
| : kColorRefNeutral80}; |
| mixer[kColorSysNeutralContainer] = {dark_mode ? kColorRefNeutral15 |
| : kColorRefNeutral95}; |
| mixer[kColorSysDivider] = {dark_mode ? kColorRefNeutral40 |
| : kColorRefPrimary90}; |
| |
| // Chrome surfaces. |
| mixer[kColorSysBase] = {dark_mode ? kColorRefNeutral25 : kColorRefNeutral100}; |
| mixer[kColorSysBaseContainer] = {dark_mode ? kColorRefNeutral15 |
| : kColorSysSurface4}; |
| mixer[kColorSysBaseContainerElevated] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefNeutral100}; |
| |
| mixer[kColorSysHeader] = {dark_mode ? kColorRefNeutral12 |
| : kColorRefPrimary90}; |
| mixer[kColorSysHeaderInactive] = { |
| dark_mode |
| ? AlphaBlend({kColorSysHeader}, {kColorRefNeutral25}, 0x99) |
| : AlphaBlend({kColorSysHeader}, {kColorSysSurfaceVariant}, 0x48)}; |
| mixer[kColorSysHeaderContainer] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefPrimary95}; |
| mixer[kColorSysHeaderContainerInactive] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefNeutral100}; |
| mixer[kColorSysOnHeaderDivider] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefPrimary80}; |
| mixer[kColorSysOnHeaderDividerInactive] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefNeutral80}; |
| mixer[kColorSysOnHeaderPrimary] = {dark_mode ? kColorRefPrimary80 |
| : kColorRefPrimary40}; |
| mixer[kColorSysOnHeaderPrimaryInactive] = {dark_mode ? kColorRefNeutral80 |
| : kColorRefNeutral40}; |
| |
| // States. |
| mixer[kColorSysStateHoverOnProminent] = { |
| dark_mode ? SetAlpha({kColorRefNeutral10}, 0x0F) |
| : SetAlpha({kColorRefNeutral99}, 0x1A)}; |
| mixer[kColorSysStateHoverOnSubtle] = { |
| dark_mode ? SetAlpha({kColorRefNeutral99}, 0x1A) |
| : SetAlpha({kColorRefNeutral10}, 0x0F)}; |
| mixer[kColorSysStateRippleNeutralOnProminent] = { |
| dark_mode ? SetAlpha({kColorRefNeutral10}, 0x1F) |
| : SetAlpha({kColorRefNeutral99}, 0x29)}; |
| mixer[kColorSysStateRippleNeutralOnSubtle] = { |
| dark_mode ? SetAlpha({kColorRefNeutral99}, 0x29) |
| : SetAlpha({kColorRefNeutral10}, 0x14)}; |
| mixer[kColorSysStateRipplePrimary] = { |
| dark_mode ? SetAlpha({kColorRefPrimary60}, 0x52) |
| : SetAlpha({kColorRefPrimary70}, 0x52)}; |
| mixer[kColorSysStateFocusRing] = {dark_mode ? kColorRefPrimary80 |
| : kColorRefPrimary40}; |
| mixer[kColorSysStateFocusRingInverse] = {dark_mode ? kColorRefPrimary40 |
| : kColorRefPrimary80}; |
| mixer[kColorSysStateTextHighlight] = {dark_mode ? kColorRefPrimary80 |
| : kColorRefPrimary40}; |
| mixer[kColorSysStateOnTextHighlight] = {dark_mode ? kColorRefNeutral0 |
| : kColorRefNeutral100}; |
| mixer[kColorSysStateFocusHighlight] = { |
| dark_mode ? SetAlpha({kColorRefNeutral99}, 0x1A) |
| : SetAlpha({kColorRefNeutral10}, 0x0F)}; |
| mixer[kColorSysStateDisabled] = dark_mode |
| ? SetAlpha({kColorRefNeutral90}, 0x60) |
| : SetAlpha({kColorRefNeutral10}, 0x60); |
| mixer[kColorSysStateDisabledContainer] = |
| dark_mode ? SetAlpha({kColorRefNeutral90}, 0x1E) |
| : SetAlpha({kColorRefNeutral10}, 0x1E); |
| mixer[kColorSysStateHoverDimBlendProtection] = { |
| dark_mode ? SetAlpha({kColorRefNeutral99}, 0x1A) |
| : SetAlpha({kColorRefPrimary20}, 0x2E)}; |
| mixer[kColorSysStateHoverBrightBlendProtection] = { |
| dark_mode ? SetAlpha({kColorRefNeutral99}, 0x29) |
| : SetAlpha({kColorRefNeutral10}, 0x0F)}; |
| mixer[kColorSysStateInactiveRing] = { |
| dark_mode ? SetAlpha({kColorRefNeutral70}, 0x8C) |
| : SetAlpha({kColorRefPrimary20}, 0x8C)}; |
| mixer[kColorSysStateScrim] = {SetAlpha({kColorRefNeutral0}, 0x99)}; |
| mixer[kColorSysStateOnHeaderHover] = {dark_mode ? kColorRefSecondary90 |
| : kColorRefPrimary20}; |
| mixer[kColorSysStateHeaderHover] = {dark_mode ? kColorRefSecondary30 |
| : kColorRefPrimary80}; |
| mixer[kColorSysStateHeaderHoverInactive] = {kColorSysStateHoverOnSubtle}; |
| mixer[kColorSysStateHeaderSelect] = {SetAlpha({kColorSysBase}, 0x9A)}; |
| |
| // Effects. |
| mixer[kColorSysShadow] = {kColorRefNeutral0}; |
| mixer[kColorSysGradientPrimary] = {dark_mode ? kColorRefPrimary30 |
| : kColorRefPrimary90}; |
| mixer[kColorSysGradientTertiary] = {dark_mode ? kColorRefTertiary30 |
| : kColorRefTertiary95}; |
| |
| // Illustration. |
| mixer[kColorSysIlloPrimaryMin] = {dark_mode ? kColorRefPrimary30 |
| : kColorRefPrimary90}; |
| mixer[kColorSysIlloPrimaryLow] = {dark_mode ? kColorRefPrimary40 |
| : kColorRefPrimary80}; |
| mixer[kColorSysIlloPrimaryMid] = {dark_mode ? kColorRefPrimary50 |
| : kColorRefPrimary70}; |
| mixer[kColorSysIlloPrimaryHigh] = {dark_mode ? kColorRefPrimary70 |
| : kColorRefPrimary60}; |
| mixer[kColorSysIlloPrimaryMax] = {dark_mode ? kColorRefPrimary80 |
| : kColorRefPrimary40}; |
| mixer[kColorSysIlloSecondaryMin] = {dark_mode ? kColorRefSecondary30 |
| : kColorRefSecondary90}; |
| mixer[kColorSysIlloSecondaryLow] = {dark_mode ? kColorRefSecondary40 |
| : kColorRefSecondary80}; |
| mixer[kColorSysIlloSecondaryMid] = {dark_mode ? kColorRefSecondary50 |
| : kColorRefSecondary70}; |
| mixer[kColorSysIlloSecondaryHigh] = {dark_mode ? kColorRefSecondary70 |
| : kColorRefSecondary60}; |
| mixer[kColorSysIlloSecondaryMax] = {dark_mode ? kColorRefSecondary80 |
| : kColorRefSecondary40}; |
| mixer[kColorSysIlloTertiaryMin] = {dark_mode ? kColorRefTertiary30 |
| : kColorRefTertiary90}; |
| mixer[kColorSysIlloTertiaryLow] = {dark_mode ? kColorRefTertiary40 |
| : kColorRefTertiary80}; |
| mixer[kColorSysIlloTertiaryMid] = {dark_mode ? kColorRefTertiary50 |
| : kColorRefTertiary70}; |
| mixer[kColorSysIlloTertiaryHigh] = {dark_mode ? kColorRefTertiary70 |
| : kColorRefTertiary60}; |
| mixer[kColorSysIlloTertiaryMax] = {dark_mode ? kColorRefTertiary80 |
| : kColorRefTertiary40}; |
| mixer[kColorSysIlloNeutralMin] = {dark_mode ? kColorRefNeutral0 |
| : kColorRefNeutral100}; |
| mixer[kColorSysIlloNeutralLow] = {dark_mode ? kColorRefNeutral25 |
| : kColorRefNeutral90}; |
| mixer[kColorSysIlloNeutralMid] = {dark_mode ? kColorRefNeutral40 |
| : kColorRefNeutral80}; |
| mixer[kColorSysIlloNeutralHigh] = {dark_mode ? kColorRefNeutral60 |
| : kColorRefNeutral50}; |
| mixer[kColorSysIlloNeutralMax] = {dark_mode ? kColorRefNeutral100 |
| : kColorRefNeutral0}; |
| |
| // ActorUi |
| mixer[kColorSysActorUiBorder] = {ui::kColorRefPrimary50}; |
| mixer[kColorSysActorUiGradientStart] = {ui::kColorRefPrimary70}; |
| mixer[kColorSysActorUiGradientMiddle] = {ui::kColorRefPrimary40}; |
| mixer[kColorSysActorUiGradientEnd] = {ui::kColorRefPrimary60}; |
| |
| // Glic |
| mixer[kColorGlicTabUnderline1] = {ui::kColorRefPrimary50}; |
| mixer[kColorGlicTabUnderline2] = {ui::kColorRefPrimary60}; |
| mixer[kColorGlicTabUnderline3] = {ui::kColorRefPrimary70}; |
| |
| // AI. |
| mixer[kColorSysAiIllustrationShapeSurface1] = { |
| dark_mode ? ui::kColorRefPrimary40 : ui::kColorRefPrimary70}; |
| mixer[kColorSysAiIllustrationShapeSurface2] = { |
| dark_mode ? ui::kColorRefPrimary50 : ui::kColorRefPrimary95}; |
| mixer[kColorSysAiIllustrationShapeSurfaceGradientStart] = { |
| dark_mode ? ui::kColorRefPrimary30 : ui::kColorRefSecondary90}; |
| mixer[kColorSysAiIllustrationShapeSurfaceGradientEnd] = { |
| dark_mode ? ui::kColorRefPrimary40 : ui::kColorRefPrimary80}; |
| |
| // Experimentation. |
| mixer[kColorSysOmniboxContainer] = {dark_mode ? kColorRefNeutral15 |
| : kColorSysSurface4}; |
| |
| // Deprecated. |
| // TODO(crbug.com/350783235): Remove remaining uses of these deprecated sys |
| // tokens. |
| mixer[kColorSysStateHover] = dark_mode ? SetAlpha({kColorRefNeutral90}, 0x14) |
| : SetAlpha({kColorRefNeutral10}, 0x14); |
| mixer[kColorSysStateFocus] = dark_mode ? SetAlpha({kColorRefNeutral90}, 0x1E) |
| : SetAlpha({kColorRefNeutral10}, 0x1E); |
| mixer[kColorSysStatePressed] = dark_mode |
| ? SetAlpha({kColorRefNeutral90}, 0x1E) |
| : SetAlpha({kColorRefNeutral10}, 0x1E); |
| |
| // If grayscale is specified the design intention is to apply the grayscale |
| // overrides over the baseline palette. |
| if (key.user_color_source == ColorProviderKey::UserColorSource::kGrayscale) { |
| AddGrayscaleSysColorOverrides(mixer, key); |
| } else if (key.user_color_source == |
| ColorProviderKey::UserColorSource::kAccent && |
| key.user_color.has_value()) { |
| AddThemedSysColorOverrides(mixer, key); |
| } |
| } |
| |
| } // namespace ui |