Theme work mode tab and toggle

This commit is contained in:
Suphon Thanakornpakapong
2021-10-17 22:24:17 +07:00
parent 8d4ad0b289
commit a47aa62474
10 changed files with 191 additions and 11 deletions
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/work_fab_radius" />
<solid android:color="?android:attr/colorControlHighlight" />
<padding
android:left="@dimen/work_profile_footer_padding"
android:right="@dimen/work_profile_footer_padding" />
</shape>
@@ -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<T> {
@@ -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<ColorStateList>
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)
}
}
}
@@ -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)
}
@@ -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
@@ -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)
@@ -44,6 +44,15 @@ data class MutatedDrawableToken<T : Drawable>(
}
}
data class NewDrawable<T : Drawable>(
private val factory: (context: Context, scheme: ColorScheme, uiColorMode: UiColorMode) -> T
) : DrawableToken<T> {
override fun resolve(context: Context, scheme: ColorScheme, uiColorMode: UiColorMode): T {
return factory(context, scheme, uiColorMode)
}
}
fun <T : Drawable> DrawableToken<T>.mutate(
mutateBlock: T.(context: Context, scheme: ColorScheme, uiColorMode: UiColorMode) -> Unit
) = MutatedDrawableToken(this, mutateBlock)
@@ -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<LayerDrawable>(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<Drawable>(R.drawable.bg_celllayout)
@@ -36,10 +31,6 @@ object DrawableTokens {
val MiddleItemPrimary = ResourceDrawableToken<GradientDrawable>(R.drawable.middle_item_primary)
.setColor(ColorTokens.PopupColorPrimary)
@JvmField
val RoundRectFolder = ResourceDrawableToken<GradientDrawable>(R.drawable.round_rect_folder)
.setColor(ColorTokens.FolderFillColor)
@JvmField
val PopupItemBackgroundBorderless = AttributeDrawableToken<Drawable>(android.R.attr.selectableItemBackgroundBorderless)
.mutate { context, scheme, uiColorMode ->
@@ -49,6 +40,17 @@ object DrawableTokens {
}
}
@JvmField
val RoundRectFolder = ResourceDrawableToken<GradientDrawable>(R.drawable.round_rect_folder)
.setColor(ColorTokens.FolderFillColor)
@JvmField
val SearchInputFg = ResourceDrawableToken<LayerDrawable>(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<GradientDrawable>(R.drawable.single_item_primary)
.setColor(ColorTokens.PopupColorPrimary)
@@ -60,4 +62,45 @@ object DrawableTokens {
@JvmField
val WidgetResizeFrame = ResourceDrawableToken<GradientDrawable>(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
}
}
@@ -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
@@ -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
*/