diff --git a/lawnchair/res/drawable/work_apps_toggle_background_shape.xml b/lawnchair/res/drawable/work_apps_toggle_background_shape.xml new file mode 100644 index 0000000000..0e56b81e3f --- /dev/null +++ b/lawnchair/res/drawable/work_apps_toggle_background_shape.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/lawnchair/src/app/lawnchair/theme/ResourceToken.kt b/lawnchair/src/app/lawnchair/theme/ResourceToken.kt index 61ca36626a..8fc81d2aaa 100644 --- a/lawnchair/src/app/lawnchair/theme/ResourceToken.kt +++ b/lawnchair/src/app/lawnchair/theme/ResourceToken.kt @@ -1,8 +1,10 @@ package app.lawnchair.theme import android.content.Context +import app.lawnchair.theme.color.ColorToken import com.android.launcher3.R import com.android.launcher3.util.Themes +import dev.kdrag0n.colorkt.Color import dev.kdrag0n.monet.theme.ColorScheme interface ResourceToken { diff --git a/lawnchair/src/app/lawnchair/theme/color/ColorStateListToken.kt b/lawnchair/src/app/lawnchair/theme/color/ColorStateListToken.kt new file mode 100644 index 0000000000..eb043c8228 --- /dev/null +++ b/lawnchair/src/app/lawnchair/theme/color/ColorStateListToken.kt @@ -0,0 +1,32 @@ +package app.lawnchair.theme.color + +import android.content.Context +import android.content.res.ColorStateList +import app.lawnchair.theme.ResourceToken +import app.lawnchair.theme.UiColorMode +import dev.kdrag0n.monet.theme.ColorScheme + +interface ColorStateListToken : ResourceToken + +data class NewColorStateList( + private val factory: (context: Context, scheme: ColorScheme, uiColorMode: UiColorMode) -> ColorStateList +) : ColorStateListToken { + + override fun resolve(context: Context, scheme: ColorScheme, uiColorMode: UiColorMode): ColorStateList { + return factory(context, scheme, uiColorMode) + } +} + +class DayNightColorStateList( + private val lightToken: ColorStateListToken, + private val darkToken: ColorStateListToken +) : ColorStateListToken { + + override fun resolve(context: Context, scheme: ColorScheme, uiColorMode: UiColorMode): ColorStateList { + return if (uiColorMode.isDarkTheme) { + darkToken.resolve(context, scheme, uiColorMode) + } else { + lightToken.resolve(context, scheme, uiColorMode) + } + } +} diff --git a/lawnchair/src/app/lawnchair/theme/color/ColorStateListTokens.kt b/lawnchair/src/app/lawnchair/theme/color/ColorStateListTokens.kt new file mode 100644 index 0000000000..345bcffd8b --- /dev/null +++ b/lawnchair/src/app/lawnchair/theme/color/ColorStateListTokens.kt @@ -0,0 +1,33 @@ +package app.lawnchair.theme.color + +import android.content.res.ColorStateList + +@Suppress("MemberVisibilityCanBePrivate") +object ColorStateListTokens { + + val AllAppsTabTextLight = NewColorStateList { context, scheme, uiColorMode -> + val states = arrayOf( + intArrayOf(android.R.attr.state_selected), + intArrayOf() + ) + val colors = intArrayOf( + ColorTokens.TextColorPrimary.resolveColor(context, scheme, uiColorMode), + ColorTokens.TextColorSecondary.resolveColor(context, scheme, uiColorMode) + ) + ColorStateList(states, colors) + } + + val AllAppsTabTextDark = NewColorStateList { context, scheme, uiColorMode -> + val states = arrayOf( + intArrayOf(android.R.attr.state_selected), + intArrayOf() + ) + val colors = intArrayOf( + ColorTokens.TextColorPrimaryInverse.resolveColor(context, scheme, uiColorMode), + ColorTokens.TextColorSecondary.resolveColor(context, scheme, uiColorMode) + ) + ColorStateList(states, colors) + } + + @JvmField val AllAppsTabText = DayNightColorStateList(AllAppsTabTextLight, AllAppsTabTextDark) +} diff --git a/lawnchair/src/app/lawnchair/theme/color/ColorToken.kt b/lawnchair/src/app/lawnchair/theme/color/ColorToken.kt index 5849eaa08d..728ed2137d 100644 --- a/lawnchair/src/app/lawnchair/theme/color/ColorToken.kt +++ b/lawnchair/src/app/lawnchair/theme/color/ColorToken.kt @@ -3,6 +3,7 @@ package app.lawnchair.theme.color import android.content.Context import android.util.Log import androidx.core.graphics.ColorUtils +import androidx.core.graphics.toColorInt import app.lawnchair.theme.ResourceToken import app.lawnchair.theme.ThemeProvider import app.lawnchair.theme.UiColorMode @@ -62,8 +63,11 @@ data class DayNightColorToken( lightToken.resolve(context, scheme, uiColorMode) } } -} + fun inverse(): DayNightColorToken { + return DayNightColorToken(darkToken, lightToken) + } +} data class DarkTextColorToken( private val lightToken: ColorToken, @@ -79,6 +83,15 @@ data class DarkTextColorToken( } } +data class StaticColorToken( + private val color: Long +) : ColorToken { + + override fun resolve(context: Context, scheme: ColorScheme, uiColorMode: UiColorMode): Color { + return AndroidColor(color.toColorInt()) + } +} + data class SetAlphaColorToken( private val token: ColorToken, private val alpha: Float diff --git a/lawnchair/src/app/lawnchair/theme/color/ColorTokens.kt b/lawnchair/src/app/lawnchair/theme/color/ColorTokens.kt index 781bbb6270..1981c8eae8 100644 --- a/lawnchair/src/app/lawnchair/theme/color/ColorTokens.kt +++ b/lawnchair/src/app/lawnchair/theme/color/ColorTokens.kt @@ -13,6 +13,7 @@ object ColorTokens { val Neutral2_50 = SwatchColorToken(Swatch.Neutral2, Shade.S50) val Neutral2_100 = SwatchColorToken(Swatch.Neutral2, Shade.S100) + val Neutral2_200 = SwatchColorToken(Swatch.Neutral2, Shade.S200) val Neutral2_300 = SwatchColorToken(Swatch.Neutral2, Shade.S300) val Neutral2_500 = SwatchColorToken(Swatch.Neutral2, Shade.S500) val Neutral2_700 = SwatchColorToken(Swatch.Neutral2, Shade.S700) @@ -24,6 +25,7 @@ object ColorTokens { val Accent1_600 = SwatchColorToken(Swatch.Accent1, Shade.S600) val Accent2_50 = SwatchColorToken(Swatch.Accent2, Shade.S50) + val Accent2_100 = SwatchColorToken(Swatch.Accent2, Shade.S100) val Accent2_600 = SwatchColorToken(Swatch.Accent2, Shade.S600) val SurfaceLight = Neutral1_500.setLStar(98.0) @@ -35,9 +37,14 @@ object ColorTokens { @JvmField val ColorAccent = DayNightColorToken(Accent1_600, Accent1_100) @JvmField val ColorBackground = DayNightColorToken(Neutral1_50, Neutral1_900) + @JvmField val TextColorPrimary = DayNightColorToken(Neutral1_900, Neutral1_50) + @JvmField val TextColorPrimaryInverse = TextColorPrimary.inverse() + @JvmField val TextColorSecondary = DayNightColorToken(StaticColorToken(0xde000000), Neutral2_200) @JvmField val AllAppsHeaderProtectionColor = DayNightColorToken(Neutral1_100, Neutral1_700) @JvmField val AllAppsScrimColor = ColorBackground + @JvmField val AllAppsTabBackgroundSelected = DayNightColorToken(Accent1_100, Accent2_100) + @JvmField val FocusHighlight = DayNightColorToken(Neutral1_0, Neutral1_700) @JvmField val GroupHighlight = Surface @JvmField val OverviewScrim = DayNightColorToken(Neutral2_500.setLStar(87.0), Neutral1_800) diff --git a/lawnchair/src/app/lawnchair/theme/drawable/DrawableToken.kt b/lawnchair/src/app/lawnchair/theme/drawable/DrawableToken.kt index 67e9207766..a1e652df69 100644 --- a/lawnchair/src/app/lawnchair/theme/drawable/DrawableToken.kt +++ b/lawnchair/src/app/lawnchair/theme/drawable/DrawableToken.kt @@ -44,6 +44,15 @@ data class MutatedDrawableToken( } } +data class NewDrawable( + private val factory: (context: Context, scheme: ColorScheme, uiColorMode: UiColorMode) -> T +) : DrawableToken { + + override fun resolve(context: Context, scheme: ColorScheme, uiColorMode: UiColorMode): T { + return factory(context, scheme, uiColorMode) + } +} + fun DrawableToken.mutate( mutateBlock: T.(context: Context, scheme: ColorScheme, uiColorMode: UiColorMode) -> Unit ) = MutatedDrawableToken(this, mutateBlock) diff --git a/lawnchair/src/app/lawnchair/theme/drawable/DrawableTokens.kt b/lawnchair/src/app/lawnchair/theme/drawable/DrawableTokens.kt index d92d02abdb..607850a64c 100644 --- a/lawnchair/src/app/lawnchair/theme/drawable/DrawableTokens.kt +++ b/lawnchair/src/app/lawnchair/theme/drawable/DrawableTokens.kt @@ -2,16 +2,11 @@ package app.lawnchair.theme.drawable import android.content.res.ColorStateList import android.graphics.drawable.* +import androidx.appcompat.content.res.AppCompatResources import app.lawnchair.theme.color.ColorTokens import com.android.launcher3.R object DrawableTokens { - @JvmField - val SearchInputFg = ResourceDrawableToken(R.drawable.search_input_fg) - .mutate { context, scheme, darkTheme -> - val shape = getDrawable(0) as GradientDrawable - shape.setColor(ColorTokens.SearchboxHighlight.resolveColor(context, scheme, darkTheme)) - } @JvmField val BgCellLayout = ResourceDrawableToken(R.drawable.bg_celllayout) @@ -36,10 +31,6 @@ object DrawableTokens { val MiddleItemPrimary = ResourceDrawableToken(R.drawable.middle_item_primary) .setColor(ColorTokens.PopupColorPrimary) - @JvmField - val RoundRectFolder = ResourceDrawableToken(R.drawable.round_rect_folder) - .setColor(ColorTokens.FolderFillColor) - @JvmField val PopupItemBackgroundBorderless = AttributeDrawableToken(android.R.attr.selectableItemBackgroundBorderless) .mutate { context, scheme, uiColorMode -> @@ -49,6 +40,17 @@ object DrawableTokens { } } + @JvmField + val RoundRectFolder = ResourceDrawableToken(R.drawable.round_rect_folder) + .setColor(ColorTokens.FolderFillColor) + + @JvmField + val SearchInputFg = ResourceDrawableToken(R.drawable.search_input_fg) + .mutate { context, scheme, darkTheme -> + val shape = getDrawable(0) as GradientDrawable + shape.setColor(ColorTokens.SearchboxHighlight.resolveColor(context, scheme, darkTheme)) + } + @JvmField val SingleItemPrimary = ResourceDrawableToken(R.drawable.single_item_primary) .setColor(ColorTokens.PopupColorPrimary) @@ -60,4 +62,45 @@ object DrawableTokens { @JvmField val WidgetResizeFrame = ResourceDrawableToken(R.drawable.widget_resize_frame) .setStroke(2f, ColorTokens.WorkspaceAccentColor) + + @JvmField + val AllAppsTabsBackground = NewDrawable { context, scheme, uiColorMode -> + val list = StateListDrawable() + list.setEnterFadeDuration(100) + + val cornerRadius = context.resources + .getDimensionPixelSize(R.dimen.all_apps_header_pill_corner_radius).toFloat() + + val unselected = GradientDrawable() + unselected.shape = GradientDrawable.RECTANGLE + unselected.cornerRadius = cornerRadius + unselected.setColor(ColorTokens.Surface.resolveColor(context, scheme, uiColorMode)) + + val selected = GradientDrawable() + selected.shape = GradientDrawable.RECTANGLE + selected.cornerRadius = cornerRadius + selected.setColor(ColorTokens.AllAppsTabBackgroundSelected.resolveColor(context, scheme, uiColorMode)) + + list.addState(intArrayOf(-android.R.attr.state_selected), unselected) + list.addState(intArrayOf(android.R.attr.state_selected), selected) + + list + } + + @JvmField + val WorkAppsToggleBackground = NewDrawable { context, scheme, uiColorMode -> + val list = StateListDrawable() + + val disabled = AppCompatResources.getDrawable( + context, R.drawable.work_apps_toggle_background_shape) + + val enabled = AppCompatResources.getDrawable( + context, R.drawable.work_apps_toggle_background_shape) as GradientDrawable + enabled.setColor(ColorTokens.AllAppsTabBackgroundSelected.resolveColor(context, scheme, uiColorMode)) + + list.addState(intArrayOf(-android.R.attr.state_enabled), disabled) + list.addState(intArrayOf(), enabled) + + list + } } diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java index a800d34758..3b8fa7ed40 100644 --- a/src/com/android/launcher3/allapps/WorkModeSwitch.java +++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java @@ -19,6 +19,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.Insets; import android.graphics.Rect; import android.os.Build; @@ -40,6 +41,10 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.KeyboardInsetAnimationCallback; import com.android.launcher3.pm.UserCache; +import app.lawnchair.font.FontManager; +import app.lawnchair.theme.color.ColorStateListTokens; +import app.lawnchair.theme.drawable.DrawableTokens; + /** * Work profile toggle switch shown at the bottom of AllApps work tab */ @@ -62,6 +67,8 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); + + FontManager.INSTANCE.get(context).overrideFont(this, attrs); } @Override @@ -73,6 +80,11 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this); setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback); } + + setBackground(DrawableTokens.WorkAppsToggleBackground.resolve(getContext())); + ColorStateList textColor = ColorStateListTokens.AllAppsTabText.resolve(getContext()); + setTextColor(textColor); + setCompoundDrawableTintList(textColor); } @Override diff --git a/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java index 11185fb511..a9d07bc9f4 100644 --- a/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java +++ b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java @@ -16,6 +16,7 @@ package com.android.launcher3.workprofile; import android.content.Context; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.Button; import android.widget.LinearLayout; @@ -23,8 +24,13 @@ import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.R; import com.android.launcher3.pageindicators.PageIndicator; +import app.lawnchair.font.FontManager; +import app.lawnchair.theme.color.ColorStateListTokens; +import app.lawnchair.theme.drawable.DrawableTokens; + /** * Supports two indicator colors, dedicated for personal and work tabs. */ @@ -36,6 +42,20 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd super(context, attrs); } + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + FontManager fontManager = FontManager.INSTANCE.get(getContext()); + for (int i = 0; i < getChildCount(); i++) { + Button tab = (Button) getChildAt(i); + tab.setAllCaps(false); + tab.setBackground(DrawableTokens.AllAppsTabsBackground.resolve(getContext())); + tab.setTextColor(ColorStateListTokens.AllAppsTabText.resolve(getContext())); + fontManager.setCustomFont(tab, R.id.font_body_medium); + } + } + /** * Highlights tab with index pos */