Add option to color system bar icons automatically

This commit is contained in:
MM20 2022-10-21 17:20:09 +02:00
parent 62f4cb6e0e
commit 9db2372253
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
21 changed files with 99 additions and 75 deletions

View File

@ -37,7 +37,6 @@
<string name="weather_details_humidity">Vlhkost: %1$s</string>
<string name="preference_icon_pack_summary_empty">Nejsou nainstalovány žádné balíčky ikon</string>
<string name="weather_widget_set_location">Nastavit polohu</string>
<string name="preference_light_status_bar">Tmavé ikony na stavové liště</string>
<string name="missing_permission_calendar_widget_settings">Tento widget vyžaduje přístup ke kalendáři</string>
<string name="preference_summary_not_logged_in">Momentálně nejste přihlášeni</string>
<string name="preference_blur_wallpaper_unsupported">Není podporováno na tomto zařízení</string>
@ -310,7 +309,6 @@
<string name="preference_themed_icons_summary">Barevné ikony s barevným schématem aplikace</string>
<string name="preference_icon_pack">Balíček ikon</string>
<string name="preference_category_system_bars">Systémové lišty</string>
<string name="preference_light_nav_bar">Tmavé ikony na navigační liště</string>
<string name="preference_hide_status_bar">Skrýt stavovou lištu</string>
<string name="preference_hide_nav_bar">Skrýt navigační lištu</string>
<string name="preference_screen_services_summary">Spravovat připojené účty a služby</string>

View File

@ -110,8 +110,6 @@
<string name="widget_add_widget">Widget hinzufügen</string>
<string name="widget_add_external">Weitere</string>
<string name="preference_category_system_bars">Systemleisten</string>
<string name="preference_light_status_bar">Dunkle Statusleisten-Symbole</string>
<string name="preference_light_nav_bar">Dunkle Navigationsleisten-Symbole</string>
<string name="preference_hide_status_bar">Statusleiste ausblenden</string>
<string name="preference_hide_nav_bar">Navigationsleiste ausblenden</string>
<string name="widget_name_music">Musik</string>

View File

@ -145,8 +145,6 @@
<string name="widget_add_widget">Ajouter un widget</string>
<string name="widget_add_external">Plus</string>
<string name="preference_category_system_bars">Barres du système</string>
<string name="preference_light_status_bar">Icônes de la barre d\'état sombres</string>
<string name="preference_light_nav_bar">Icônes de la barre de navigation sombres</string>
<string name="widget_name_music">Musique</string>
<string name="menu_contacts_open_externally">Ouvrir dans l\'application de contacts</string>
<string name="menu_favorites_pin">Ajouter aux favoris</string>

View File

@ -30,7 +30,6 @@
<string name="preference_screen_buildinfo_summary">Maggiori informazioni sulla build di questa app</string>
<string name="preference_themed_icons_summary">Icone colorate con la combinazione di colori dell\'applicazione</string>
<string name="preference_search_bar_auto_focus_summary">Mostra automaticamente la tastiera all\'apertura della ricerca</string>
<string name="preference_light_nav_bar">Icone scure nella barra di navigazione</string>
<string name="connect_account">Connetti account</string>
<string name="preference_hide_status_bar">Nascondi barra di stato</string>
<string name="preference_summary_not_logged_in">Non hai eseguito l\'accesso</string>
@ -259,7 +258,6 @@
<string name="preference_themed_icons">Icone a tema</string>
<string name="preference_icon_pack_summary_empty">Nessun pacchetto icone installato</string>
<string name="preference_icon_pack">Pacchetto icone</string>
<string name="preference_light_status_bar">Icone scure nella barra di stato</string>
<string name="preference_category_system_bars">Barre di sistema</string>
<string name="preference_icon_shape_triangle">Triangolo di Reuleaux</string>
<string name="preference_hide_nav_bar">Nascondi barra di navigazione</string>

View File

@ -297,8 +297,6 @@
<string name="preference_force_themed_icons">Forceer iconen met een thema</string>
<string name="preference_icon_pack">Pictogrammenpakket</string>
<string name="preference_category_system_bars">Systeembalken</string>
<string name="preference_light_status_bar">Donkere statusbalkpictogrammen</string>
<string name="preference_light_nav_bar">Donkere navigatiebalkpictogrammen</string>
<string name="preference_hide_status_bar">Statusbalk verbergen</string>
<string name="preference_summary_not_logged_in">Je bent niet ingelogd</string>
<string name="preference_icon_shape_pentagon">Vijfhoek</string>

View File

@ -276,8 +276,6 @@
<string name="preference_icon_pack">Pacote de ícones</string>
<string name="preference_icon_pack_summary_empty">Não há pacotes de ícones instalados</string>
<string name="preference_category_system_bars">Barras do sistema</string>
<string name="preference_light_status_bar">Ícones da barra de status escuro</string>
<string name="preference_light_nav_bar">Ícones da barra de navegação escuro</string>
<string name="preference_hide_status_bar">Ocultar a barra de status</string>
<string name="preference_hide_nav_bar">Ocultar a barra de navegação</string>
<string name="preference_screen_services_summary">Gerenciar as contas e serviços conectados</string>

View File

@ -247,8 +247,6 @@
<string name="preference_icon_pack">Pachet de pictograme</string>
<string name="preference_icon_pack_summary_empty">Nu sunt instalate pachete de pictograme</string>
<string name="preference_category_system_bars">Bare de sistem</string>
<string name="preference_light_status_bar">Pictogramele barei de stare întunecate</string>
<string name="preference_light_nav_bar">Pictograme întunecate ale barei de navigare</string>
<string name="preference_hide_status_bar">Ascunde bara de stare</string>
<string name="preference_hide_nav_bar">Ascunde bara de navigare</string>
<string name="preference_category_services_google">Google</string>

View File

@ -284,8 +284,6 @@
<string name="preference_search_files_summary">Поиск локальных файлов и облачных файлов</string>
<string name="preference_search_websearch_summary">Показать ярлыки различных поисковых систем</string>
<string name="preference_category_services_google">Google</string>
<string name="preference_light_status_bar">Темные значки в строке состояния</string>
<string name="preference_light_nav_bar">Темные значки в панели навигации</string>
<string name="preference_hide_status_bar">Скрыть строку состояния</string>
<string name="preference_hide_nav_bar">Скрыть панель навигации</string>
<string name="preference_category_wallpaper">Обои</string>

View File

@ -230,8 +230,6 @@
<string name="preference_icon_pack">Ikonpaket</string>
<string name="preference_icon_pack_summary_empty">Inga ikonpaket installerade</string>
<string name="preference_category_system_bars">Systemfält</string>
<string name="preference_light_status_bar">Mörka statusfältikoner</string>
<string name="preference_light_nav_bar">Mörka navigationsfältikoner</string>
<string name="preference_hide_status_bar">Göm statusfält</string>
<string name="preference_hide_nav_bar">Göm navigationsfält</string>
<string name="preference_screen_services_summary">Hantera anslutna konton och tjänster</string>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="preference_light_nav_bar">深色的导航条图标</string>
<string name="preference_dim_wallpaper_summary">在深色主题中,使壁纸变暗</string>
<string name="preference_screen_badges_summary">配置图标角标</string>
<string name="preference_ms_signin_summary">登陆以查找OneDrive</string>
@ -252,7 +251,6 @@
<string name="preference_icon_pack">图标包</string>
<string name="preference_icon_pack_summary_empty">没有已安装的图标包</string>
<string name="preference_category_system_bars">系统栏</string>
<string name="preference_light_status_bar">深色的状态栏图标</string>
<string name="preference_hide_status_bar">隐藏状态栏</string>
<string name="preference_hide_nav_bar">隐藏导航条</string>
<string name="preference_screen_services_summary">管理已连接的账户和服务</string>

View File

@ -482,8 +482,11 @@
<string name="preference_icon_pack">Icon pack</string>
<string name="preference_icon_pack_summary_empty">No icon packs installed</string>
<string name="preference_category_system_bars">System bars</string>
<string name="preference_light_status_bar">Dark status bar icons</string>
<string name="preference_light_nav_bar">Dark navigation bar icons</string>
<string name="preference_status_bar_icons">Status bar icons</string>
<string name="preference_nav_bar_icons">Navigation bar icons</string>
<string name="preference_system_bar_icons_auto">Auto</string>
<string name="preference_system_bar_icons_light">Light</string>
<string name="preference_system_bar_icons_dark">Dark</string>
<string name="preference_hide_status_bar">Hide status bar</string>
<string name="preference_hide_nav_bar">Hide navigation bar</string>
<string name="preference_screen_services_summary">Manage connected accounts and services</string>

View File

@ -144,8 +144,8 @@ fun createFactorySettings(context: Context): Settings {
.setEasterEgg(false)
.setSystemBars(
Settings.SystemBarsSettings.newBuilder()
.setLightNavBar(false)
.setLightStatusBar(false)
.setNavBarColor(Settings.SystemBarsSettings.SystemBarColors.Light)
.setStatusBarColor(Settings.SystemBarsSettings.SystemBarColors.Light)
.setHideStatusBar(false)
.setHideNavBar(false)
)

View File

@ -238,8 +238,16 @@ message Settings {
bool easter_egg = 22;
message SystemBarsSettings {
bool lightStatusBar = 1;
bool lightNavBar = 2;
enum SystemBarColors {
// Light icons
Auto = 0;
// Dark icons
Dark = 1;
// Wallpaper based
Light = 2;
}
SystemBarColors statusBarColor = 1;
SystemBarColors navBarColor = 2;
bool hideStatusBar = 3;
bool hideNavBar = 4;
}

View File

@ -4,6 +4,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.SystemBarsSettings
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
@ -23,19 +24,8 @@ class LauncherActivityVM : ViewModel(), KoinComponent {
}
val dimBackground = dimBackgroundState.asLiveData()
val lightStatusBar = combine(
dimBackgroundState,
dataStore.data.map { it.systemBars.lightStatusBar }
) { dim, light ->
!dim && light
}.asLiveData()
val lightNavBar = combine(
dimBackgroundState,
dataStore.data.map { it.systemBars.lightNavBar }
) { dim, light ->
!dim && light
}.asLiveData()
val statusBarColor = dataStore.data.map { it.systemBars.statusBarColor }.asLiveData()
val navBarColor = dataStore.data.map { it.systemBars.statusBarColor }.asLiveData()
val hideNavBar = dataStore.data.map { it.systemBars.hideNavBar }.asLiveData()
val hideStatusBar = dataStore.data.map { it.systemBars.hideStatusBar }.asLiveData()

View File

@ -35,6 +35,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.SystemBarsSettings.SystemBarColors
import de.mm20.launcher2.ui.assistant.AssistantScaffold
import de.mm20.launcher2.ui.base.BaseActivity
import de.mm20.launcher2.ui.base.ProvideCurrentTime
@ -44,9 +45,12 @@ import de.mm20.launcher2.ui.ktx.animateTo
import de.mm20.launcher2.ui.launcher.transitions.HomeTransition
import de.mm20.launcher2.ui.launcher.transitions.HomeTransitionManager
import de.mm20.launcher2.ui.launcher.transitions.LocalHomeTransitionManager
import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
import de.mm20.launcher2.ui.locals.LocalWindowSize
import de.mm20.launcher2.ui.theme.LauncherTheme
import de.mm20.launcher2.ui.theme.wallpaperColorsAsState
import kotlin.math.pow
@ -73,19 +77,26 @@ abstract class SharedLauncherActivity(
setContent {
val snackbarHostState = remember { SnackbarHostState() }
val wallpaperColors by wallpaperColorsAsState()
val dimBackground by viewModel.dimBackground.observeAsState(false)
CompositionLocalProvider(
LocalHomeTransitionManager provides homeTransitionManager,
LocalWindowSize provides windowSize,
LocalSnackbarHostState provides snackbarHostState
LocalSnackbarHostState provides snackbarHostState,
LocalWallpaperColors provides wallpaperColors,
LocalPreferDarkContentOverWallpaper provides (!dimBackground && wallpaperColors.supportsDarkText),
) {
LauncherTheme {
ProvideCurrentTime {
ProvideSettings {
val lightStatus by viewModel.lightStatusBar.observeAsState(false)
val lightNav by viewModel.lightNavBar.observeAsState(false)
val statusBarColor by viewModel.statusBarColor.observeAsState(SystemBarColors.Auto)
val navBarColor by viewModel.navBarColor.observeAsState(SystemBarColors.Auto)
val lightStatus = !dimBackground && (statusBarColor == SystemBarColors.Dark || statusBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
val lightNav = !dimBackground && (navBarColor == SystemBarColors.Dark || navBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
val hideStatus by viewModel.hideStatusBar.observeAsState(false)
val hideNav by viewModel.hideNavBar.observeAsState(false)
val dimBackground by viewModel.dimBackground.observeAsState(false)
val layout by viewModel.layout.observeAsState(null)
val systemUiController = rememberSystemUiController()

View File

@ -4,10 +4,10 @@ import android.appwidget.AppWidgetHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.GridSettings
import de.mm20.launcher2.ui.theme.WallpaperColors
val LocalWindowSize = compositionLocalOf { Size(0f, 0f) }
@ -29,4 +29,8 @@ val LocalDarkTheme = compositionLocalOf { false }
* Workaround a bug in Jetpack Compose which incorrectly places popups
* that are nested inside other popups.
*/
val LocalWindowPosition = compositionLocalOf { 0f }
val LocalWindowPosition = compositionLocalOf { 0f }
val LocalWallpaperColors = compositionLocalOf { WallpaperColors() }
val LocalPreferDarkContentOverWallpaper = compositionLocalOf { false }

View File

@ -20,6 +20,7 @@ import de.mm20.launcher2.ui.theme.LauncherTheme
import de.mm20.launcher2.ui.base.BaseActivity
import de.mm20.launcher2.ui.locals.LocalCardStyle
import de.mm20.launcher2.ui.locals.LocalNavController
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
import de.mm20.launcher2.ui.settings.about.AboutSettingsScreen
import de.mm20.launcher2.ui.settings.accounts.AccountsSettingsScreen
import de.mm20.launcher2.ui.settings.appearance.AppearanceSettingsScreen
@ -47,6 +48,7 @@ import de.mm20.launcher2.ui.settings.weatherwidget.WeatherWidgetSettingsScreen
import de.mm20.launcher2.ui.settings.websearch.WebSearchSettingsScreen
import de.mm20.launcher2.ui.settings.widgets.WidgetsSettingsScreen
import de.mm20.launcher2.ui.settings.wikipedia.WikipediaSettingsScreen
import de.mm20.launcher2.ui.theme.wallpaperColorsAsState
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import org.koin.android.ext.android.inject
@ -72,9 +74,11 @@ class SettingsActivity : BaseActivity() {
}.collectAsState(
Settings.CardSettings.getDefaultInstance()
)
val wallpaperColors by wallpaperColorsAsState()
CompositionLocalProvider(
LocalNavController provides navController,
LocalCardStyle provides cardStyle
LocalCardStyle provides cardStyle,
LocalWallpaperColors provides wallpaperColors,
) {
LauncherTheme {
AnimatedNavHost(

View File

@ -33,6 +33,7 @@ import de.mm20.launcher2.ktx.isAtLeastApiLevel
import de.mm20.launcher2.preferences.Settings.*
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
import de.mm20.launcher2.preferences.Settings.SystemBarsSettings.SystemBarColors
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
import de.mm20.launcher2.ui.component.getShape
@ -251,20 +252,30 @@ fun AppearanceSettingsScreen() {
)
}
PreferenceCategory(stringResource(R.string.preference_category_system_bars)) {
val lightStatusBar by viewModel.lightStatusBar.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_light_status_bar),
value = lightStatusBar == true,
val lightStatusBar by viewModel.statusBarIcons.observeAsState()
ListPreference(
title = stringResource(R.string.preference_status_bar_icons),
value = lightStatusBar,
items = listOf(
stringResource(R.string.preference_system_bar_icons_auto) to SystemBarColors.Auto,
stringResource(R.string.preference_system_bar_icons_light) to SystemBarColors.Light,
stringResource(R.string.preference_system_bar_icons_dark) to SystemBarColors.Dark,
),
onValueChanged = {
viewModel.setLightStatusBar(it)
if (it != null) viewModel.setLightStatusBar(it)
}
)
val lightNavBar by viewModel.lightNavBar.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_light_nav_bar),
value = lightNavBar == true,
val lightNavBar by viewModel.navBarIcons.observeAsState()
ListPreference(
title = stringResource(R.string.preference_nav_bar_icons),
value = lightNavBar,
items = listOf(
stringResource(R.string.preference_system_bar_icons_auto) to SystemBarColors.Auto,
stringResource(R.string.preference_system_bar_icons_light) to SystemBarColors.Light,
stringResource(R.string.preference_system_bar_icons_dark) to SystemBarColors.Dark,
),
onValueChanged = {
viewModel.setLightNavBar(it)
if (it != null) viewModel.setLightNavBar(it)
}
)
val hideStatusBar by viewModel.hideStatusBar.observeAsState()

View File

@ -13,6 +13,7 @@ import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.*
import de.mm20.launcher2.preferences.Settings.SearchBarSettings
import de.mm20.launcher2.preferences.Settings.SystemBarsSettings
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
@ -217,28 +218,28 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
}
}
val lightStatusBar = dataStore.data.map { it.systemBars.lightStatusBar }.asLiveData()
fun setLightStatusBar(lightStatusBar: Boolean) {
val statusBarIcons = dataStore.data.map { it.systemBars.statusBarColor }.asLiveData()
fun setLightStatusBar(statusBarColor: SystemBarsSettings.SystemBarColors) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setSystemBars(
it.systemBars.toBuilder()
.setLightStatusBar(lightStatusBar)
.setStatusBarColor(statusBarColor)
)
.build()
}
}
}
val lightNavBar = dataStore.data.map { it.systemBars.lightNavBar }.asLiveData()
fun setLightNavBar(lightNavBar: Boolean) {
val navBarIcons = dataStore.data.map { it.systemBars.navBarColor }.asLiveData()
fun setLightNavBar(navBarColors: SystemBarsSettings.SystemBarColors) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setSystemBars(
it.systemBars.toBuilder()
.setLightNavBar(lightNavBar)
.setNavBarColor(navBarColors)
)
.build()
}

View File

@ -16,6 +16,7 @@ import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.AppearanceSettings
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
import de.mm20.launcher2.ui.locals.LocalDarkTheme
import de.mm20.launcher2.ui.locals.LocalWallpaperColors
import de.mm20.launcher2.ui.theme.colorscheme.*
import de.mm20.launcher2.ui.theme.typography.DefaultTypography
import de.mm20.launcher2.ui.theme.typography.getDeviceDefaultTypography
@ -124,11 +125,10 @@ fun colorSchemeAsState(
}
else -> {
if (Build.VERSION.SDK_INT >= 27 && (Build.VERSION.SDK_INT < 31 || colorScheme == AppearanceSettings.ColorScheme.DebugMaterialYouCompat)) {
val wallpaperColors by wallpaperColorsAsState()
val wallpaperColors = LocalWallpaperColors.current
val state = remember(wallpaperColors, darkTheme) {
mutableStateOf(
wallpaperColors?.let { MaterialYouCompatScheme(it, darkTheme) }
?: if (darkTheme) DarkDefaultColorScheme else LightDefaultColorScheme
MaterialYouCompatScheme(wallpaperColors, darkTheme)
)
}
return state

View File

@ -5,21 +5,35 @@ import android.os.Build
import android.os.Handler
import android.os.Looper
import androidx.annotation.RequiresApi
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
data class WallpaperColors(val primary: Color, val secondary: Color?, val tertiary: Color?) {
data class WallpaperColors(
val primary: Color = Color(0xFF3C6089),
val secondary: Color? = null,
val tertiary: Color? = null,
private val hints: Int = 0,
) {
val supportsDarkText: Boolean
get() = hints and android.app.WallpaperColors.HINT_SUPPORTS_DARK_TEXT != 0
companion object {
@RequiresApi(Build.VERSION_CODES.O_MR1)
fun fromPlatformType(colors: android.app.WallpaperColors): WallpaperColors {
return WallpaperColors(
Color(colors.primaryColor.toArgb()),
colors.secondaryColor?.toArgb()?.let { Color(it) },
colors.tertiaryColor?.toArgb()?.let { Color(it) }
colors.tertiaryColor?.toArgb()?.let { Color(it) },
colors.colorHints
)
}
}
@ -27,18 +41,18 @@ data class WallpaperColors(val primary: Color, val secondary: Color?, val tertia
@RequiresApi(Build.VERSION_CODES.O_MR1)
@Composable
fun wallpaperColorsAsState(): State<WallpaperColors?> {
fun wallpaperColorsAsState(): State<WallpaperColors> {
val scope = rememberCoroutineScope()
val context = LocalContext.current
val state = remember { mutableStateOf<WallpaperColors?>(null) }
val state = remember { mutableStateOf(WallpaperColors()) }
DisposableEffect(null) {
val wallpaperManager = WallpaperManager.getInstance(context)
val callback = callback@{ colors: android.app.WallpaperColors?, which: Int ->
if (which or WallpaperManager.FLAG_SYSTEM == 0) return@callback
if (which and WallpaperManager.FLAG_SYSTEM == 0) return@callback
if (colors != null) {
state.value = WallpaperColors.fromPlatformType(colors)
} else {
state.value = null
state.value = WallpaperColors()
}
}
wallpaperManager.addOnColorsChangedListener(
@ -57,6 +71,4 @@ fun wallpaperColorsAsState(): State<WallpaperColors?> {
}
}
return state
}
internal val DefaultWallpaperColors = WallpaperColors(Color.White, null, null)
}