From 0d942fbff56942ad060061ab5bc7cd37cbac4093 Mon Sep 17 00:00:00 2001 From: DrDisagree Date: Mon, 28 Oct 2024 20:24:59 +0600 Subject: [PATCH] Theme pixel launcher Add same-toned monochrome icon and search bar color Add option to make monochrome icons darker Add option to make monochrome icons and search bar semi-transparent Refactor and clean codes for better readability --- .../drdisagree/colorblendr/common/Const.kt | 11 +- .../ui/fragments/SettingsAdvancedFragment.kt | 27 +- .../colorblendr/utils/ColorMapUtil.kt | 62 +++ .../drdisagree/colorblendr/utils/ColorUtil.kt | 12 + .../colorblendr/utils/DynamicColors.kt | 14 - .../colorblendr/utils/FabricatedUtil.kt | 416 ++++++------------ .../colorblendr/utils/OverlayManager.kt | 224 +++++----- .../colorblendr/utils/PerPackageColors.kt | 217 +++++++++ app/src/main/res/drawable/ic_dark_icon.xml | 10 + .../main/res/drawable/ic_semi_transparent.xml | 12 + .../res/layout/fragment_settings_advanced.xml | 16 + app/src/main/res/layout/view_color_table.xml | 2 +- app/src/main/res/values-fr-rFR/strings.xml | 42 +- app/src/main/res/values/strings.xml | 4 + 14 files changed, 627 insertions(+), 442 deletions(-) create mode 100644 app/src/main/java/com/drdisagree/colorblendr/utils/ColorMapUtil.kt create mode 100644 app/src/main/java/com/drdisagree/colorblendr/utils/PerPackageColors.kt create mode 100644 app/src/main/res/drawable/ic_dark_icon.xml create mode 100644 app/src/main/res/drawable/ic_semi_transparent.xml diff --git a/app/src/main/java/com/drdisagree/colorblendr/common/Const.kt b/app/src/main/java/com/drdisagree/colorblendr/common/Const.kt index 7168c242..e446ff57 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/common/Const.kt +++ b/app/src/main/java/com/drdisagree/colorblendr/common/Const.kt @@ -11,16 +11,25 @@ object Const { // Preferences file const val SHARED_PREFS: String = BuildConfig.APPLICATION_ID + "_preferences" - // System packages + // Package names const val FRAMEWORK_PACKAGE: String = "android" const val SYSTEMUI_PACKAGE: String = "com.android.systemui" const val SHELL_PACKAGE: String = "com.android.shell" + const val SYSTEMUI_CLOCKS: String = "com.android.systemui.clocks." + const val GOOGLE_FEEDS: String = "com.google.android.googlequicksearchbox" + const val GOOGLE_NEWS: String = "com.google.android.apps.magazines" + const val PLAY_GAMES: String = "com.google.android.play.games" + const val SETTINGS: String = "com.android.settings" + const val SETTINGS_SEARCH: String = "com.google.android.settings.intelligence" + const val PIXEL_LAUNCHER: String = "com.google.android.apps.nexuslauncher" // General preferences const val FIRST_RUN: String = "firstRun" const val THEMING_ENABLED: String = "themingEnabled" const val MONET_STYLE: String = "customMonetStyle" const val MODE_SPECIFIC_THEMES: String = "modeSpecificThemes" + const val DARKER_LAUNCHER_ICONS: String = "darkerLauncherIcons" + const val SEMI_TRANSPARENT_LAUNCHER_ICONS: String = "semiTransparentLauncherIcons" private val modeSpecificThemes: Boolean get() = RPrefs.getBoolean(MODE_SPECIFIC_THEMES, false) val MONET_ACCENT_SATURATION: String diff --git a/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/SettingsAdvancedFragment.kt b/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/SettingsAdvancedFragment.kt index 48035e0f..f4bded20 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/SettingsAdvancedFragment.kt +++ b/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/SettingsAdvancedFragment.kt @@ -10,11 +10,14 @@ import android.widget.CompoundButton import androidx.fragment.app.Fragment import com.drdisagree.colorblendr.R import com.drdisagree.colorblendr.common.Const +import com.drdisagree.colorblendr.common.Const.DARKER_LAUNCHER_ICONS import com.drdisagree.colorblendr.common.Const.MODE_SPECIFIC_THEMES import com.drdisagree.colorblendr.common.Const.MONET_LAST_UPDATED import com.drdisagree.colorblendr.common.Const.MONET_SECONDARY_COLOR import com.drdisagree.colorblendr.common.Const.MONET_SEED_COLOR_ENABLED import com.drdisagree.colorblendr.common.Const.MONET_TERTIARY_COLOR +import com.drdisagree.colorblendr.common.Const.PIXEL_LAUNCHER +import com.drdisagree.colorblendr.common.Const.SEMI_TRANSPARENT_LAUNCHER_ICONS import com.drdisagree.colorblendr.common.Const.workingMethod import com.drdisagree.colorblendr.config.RPrefs.getBoolean import com.drdisagree.colorblendr.config.RPrefs.getInt @@ -24,6 +27,7 @@ import com.drdisagree.colorblendr.config.RPrefs.putLong import com.drdisagree.colorblendr.databinding.FragmentSettingsAdvancedBinding import com.drdisagree.colorblendr.utils.MiscUtil.setToolbarTitle import com.drdisagree.colorblendr.utils.OverlayManager.applyFabricatedColors +import com.drdisagree.colorblendr.utils.SystemUtil import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -36,6 +40,7 @@ class SettingsAdvancedFragment : Fragment() { private lateinit var binding: FragmentSettingsAdvancedBinding private val notShizukuMode: Boolean = workingMethod != Const.WorkMethod.SHIZUKU + private val hasPixelLauncher: Boolean = SystemUtil.isAppInstalled(PIXEL_LAUNCHER) override fun onCreateView( inflater: LayoutInflater, @@ -93,7 +98,7 @@ class SettingsAdvancedFragment : Fragment() { .show(getChildFragmentManager(), "tertiaryColorPicker") } - // Accurate shades + // Mode specific themes binding.modeSpecificThemes.setEnabled(notShizukuMode) binding.modeSpecificThemes.isSwitchChecked = getBoolean(MODE_SPECIFIC_THEMES, false) binding.modeSpecificThemes.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> @@ -101,6 +106,26 @@ class SettingsAdvancedFragment : Fragment() { applyFabricatedColors() } + // Darker launcher icons + binding.darkerLauncherIcons.setEnabled(notShizukuMode) + binding.darkerLauncherIcons.visibility = if (hasPixelLauncher) View.VISIBLE else View.GONE + binding.darkerLauncherIcons.isSwitchChecked = getBoolean(DARKER_LAUNCHER_ICONS, false) + binding.darkerLauncherIcons.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + putBoolean(DARKER_LAUNCHER_ICONS, isChecked) + applyFabricatedColors() + } + + // Semi-transparent launcher icons + binding.semitransparentLauncher.setEnabled(notShizukuMode) + binding.semitransparentLauncher.visibility = + if (hasPixelLauncher) View.VISIBLE else View.GONE + binding.semitransparentLauncher.isSwitchChecked = + getBoolean(SEMI_TRANSPARENT_LAUNCHER_ICONS, false) + binding.semitransparentLauncher.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + putBoolean(SEMI_TRANSPARENT_LAUNCHER_ICONS, isChecked) + applyFabricatedColors() + } + return binding.getRoot() } diff --git a/app/src/main/java/com/drdisagree/colorblendr/utils/ColorMapUtil.kt b/app/src/main/java/com/drdisagree/colorblendr/utils/ColorMapUtil.kt new file mode 100644 index 00000000..777f3e03 --- /dev/null +++ b/app/src/main/java/com/drdisagree/colorblendr/utils/ColorMapUtil.kt @@ -0,0 +1,62 @@ +package com.drdisagree.colorblendr.utils + +import androidx.core.util.Pair +import com.drdisagree.colorblendr.utils.ColorUtil.modifyBrightness + +data class ColorMapping( + val resourceName: String, + val tonalPalette: TonalPalette? = null, + val colorIndex: Int? = null, + val lightModeColorIndex: Int? = null, + val darkModeColorIndex: Int? = null, + val lightModeColorCode: Int? = null, + val colorCode: Int? = null, + val darkModeColorCode: Int? = null, + val lightnessAdjustment: Int? = null, + val lightModeLightnessAdjustment: Int? = null, + val darkModeLightnessAdjustment: Int? = null +) + +fun ColorMapping.extractResourceFromColorMap( + prefix: String = "", + suffix: String = "", + palette: ArrayList>, + isDark: Boolean = false +): Pair { + val resourceName = prefix + resourceName + suffix + + val colorValue: Int = if (tonalPalette != null) { + if (colorIndex != null) { + palette[tonalPalette.index][colorIndex] + } else { + if (isDark) { + palette[tonalPalette.index][darkModeColorIndex!!] + } else { + palette[tonalPalette.index][lightModeColorIndex!!] + } + } + } else { + colorCode ?: if (isDark) { + darkModeColorCode + } else { + lightModeColorCode + } + }!! + + return Pair(resourceName, colorValue) +} + +fun ColorMapping.adjustColorBrightnessIfRequired( + colorValue: Int, + isDark: Boolean +): Int { + return if (lightnessAdjustment != null) { + modifyBrightness(colorValue, lightnessAdjustment) + } else if (darkModeLightnessAdjustment != null && isDark) { + modifyBrightness(colorValue, darkModeLightnessAdjustment) + } else if (lightModeLightnessAdjustment != null && !isDark) { + modifyBrightness(colorValue, lightModeLightnessAdjustment) + } else { + colorValue + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/colorblendr/utils/ColorUtil.kt b/app/src/main/java/com/drdisagree/colorblendr/utils/ColorUtil.kt index 7c8832b9..ba60268d 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/utils/ColorUtil.kt +++ b/app/src/main/java/com/drdisagree/colorblendr/utils/ColorUtil.kt @@ -681,4 +681,16 @@ object ColorUtil { ) return colors } + + fun Int.applyAlphaToColor(percentage: Int): Int { + require(percentage in 0..100) { "Percentage must be between 0 and 100" } + + val alpha = (percentage * 255 / 100).coerceIn(0, 255) + + val red = (this shr 16) and 0xFF + val green = (this shr 8) and 0xFF + val blue = this and 0xFF + + return (alpha shl 24) or (red shl 16) or (green shl 8) or blue + } } diff --git a/app/src/main/java/com/drdisagree/colorblendr/utils/DynamicColors.kt b/app/src/main/java/com/drdisagree/colorblendr/utils/DynamicColors.kt index ca31a27b..30c1a29d 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/utils/DynamicColors.kt +++ b/app/src/main/java/com/drdisagree/colorblendr/utils/DynamicColors.kt @@ -3,20 +3,6 @@ package com.drdisagree.colorblendr.utils import android.graphics.Color import android.os.Build -data class ColorMapping( - val resourceName: String, - val tonalPalette: TonalPalette? = null, - val colorIndex: Int? = null, - val lightModeColorIndex: Int? = null, - val darkModeColorIndex: Int? = null, - val lightModeColorCode: Int? = null, - val colorCode: Int? = null, - val darkModeColorCode: Int? = null, - val lightnessAdjustment: Int? = null, - val lightModeLightnessAdjustment: Int? = null, - val darkModeLightnessAdjustment: Int? = null -) - enum class TonalPalette(val index: Int) { PRIMARY(0), SECONDARY(1), diff --git a/app/src/main/java/com/drdisagree/colorblendr/utils/FabricatedUtil.kt b/app/src/main/java/com/drdisagree/colorblendr/utils/FabricatedUtil.kt index 29301ff1..9b5ba58b 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/utils/FabricatedUtil.kt +++ b/app/src/main/java/com/drdisagree/colorblendr/utils/FabricatedUtil.kt @@ -5,7 +5,6 @@ import android.content.pm.PackageManager import android.graphics.Color import android.os.Build import androidx.annotation.ColorInt -import androidx.core.util.Pair import androidx.core.util.component1 import androidx.core.util.component2 import com.drdisagree.colorblendr.common.Const @@ -24,22 +23,12 @@ import com.drdisagree.colorblendr.utils.DynamicColors.M3_REF_PALETTE import com.drdisagree.colorblendr.utils.fabricated.FabricatedOverlayResource object FabricatedUtil { - private val colorNames: Array> = ColorUtil.colorNames - private val colorNamesM3var1: Array> = getColorNamesM3( - isDynamic = false, - prefixG = false - ) - private val colorNamesM3var2: Array> = getColorNamesM3( - isDynamic = true, - prefixG = false - ) - private val colorNamesM3var3: Array> = getColorNamesM3( - isDynamic = true, - prefixG = true - ) - private val colorNamesM3var4: Array> = getColorNamesM3( - isDynamic = false, - prefixG = true + + private val colorNamesM3Variants = listOf( + getColorNamesM3(isDynamic = false, prefixG = false), + getColorNamesM3(isDynamic = true, prefixG = false), + getColorNamesM3(isDynamic = true, prefixG = true), + getColorNamesM3(isDynamic = false, prefixG = true) ) fun FabricatedOverlayResource.createDynamicOverlay( @@ -72,20 +61,17 @@ object FabricatedUtil { suffix = tempSuffix, palette = palette, isDark = isDark - ) - - val adjustedColorValue = adjustColorForPitchBlackThemeIfRequired( - pitchBlackTheme = isPitchBlackTheme, - resourceName = resourceName, - colorValue = colorValue - ).let { value -> - colorMapping.adjustColorBrightnessIfRequired( - colorValue = value, - isDark = isDark + ).let { (name, value) -> + name to applyColorAdjustments( + colorMapping, + name, + value, + isDark, + isPitchBlackTheme ) } - setColor(resourceName, adjustedColorValue) + setColor(resourceName, colorValue) } } } @@ -106,40 +92,37 @@ object FabricatedUtil { fun FabricatedOverlayResource.assignPerAppColorsToOverlay( palette: ArrayList> ) { - val pitchBlackTheme = getBoolean(MONET_PITCH_BLACK_THEME, false) + val isPitchBlackTheme = getBoolean(MONET_PITCH_BLACK_THEME, false) + val tintTextColor = getBoolean(TINT_TEXT_COLOR, true) M3_REF_PALETTE.forEach { colorMapping -> val (resourceName, colorValue) = colorMapping.extractResourceFromColorMap( palette = palette - ) - - val adjustedColorValue = adjustColorForPitchBlackThemeIfRequired( - pitchBlackTheme = pitchBlackTheme, - resourceName = resourceName, - colorValue = colorValue - ).let { value -> - colorMapping.adjustColorBrightnessIfRequired( - colorValue = value, - isDark = false + ).let { (name, value) -> + name to applyColorAdjustments( + colorMapping, + name, + value, + isDark = false, + isPitchBlackTheme ) } - setColor(resourceName, adjustedColorValue) - setColor("g$resourceName", adjustedColorValue) + setColor(resourceName, colorValue) + setColor("g$resourceName", colorValue) } - for (i in 0..4) { - for (j in 0..12) { - setColor(colorNamesM3var1[i][j], palette[i][j]) - setColor(colorNamesM3var2[i][j], palette[i][j]) - setColor(colorNamesM3var3[i][j], palette[i][j]) - setColor(colorNamesM3var4[i][j], palette[i][j]) + colorNamesM3Variants.forEach { variant -> + variant.forEachIndexed { i, row -> + row.forEachIndexed { j, name -> + setColor(name, palette[i][j]) + } } } - replaceColorsPerPackageName(palette, pitchBlackTheme) + replaceColorsPerPackageName(palette, isPitchBlackTheme) - if (!getBoolean(TINT_TEXT_COLOR, true)) { + if (!tintTextColor) { addTintlessTextColors() } } @@ -151,23 +134,41 @@ object FabricatedUtil { val packageManager = context.packageManager val applications = packageManager.getInstalledApplications(PackageManager.GET_META_DATA) - val selectedApps = HashMap() - // selectedApps.put(BuildConfig.APPLICATION_ID, true); - for (appInfo in applications) { - val packageName = appInfo.packageName - val isSelected = OverlayManager.isOverlayEnabled( - String.format(FABRICATED_OVERLAY_NAME_APPS, packageName) - ) + val selectedApps = HashMap().apply { + applications.forEach { appInfo -> + val packageName = appInfo.packageName + val isSelected = OverlayManager.isOverlayEnabled( + String.format(FABRICATED_OVERLAY_NAME_APPS, packageName) + ) - if (isSelected) { - selectedApps[packageName] = true + if (isSelected) { + put(packageName, true) + } } } + // selectedApps.put(BuildConfig.APPLICATION_ID, true); + saveSelectedFabricatedApps(selectedApps) } + private fun applyColorAdjustments( + colorMapping: ColorMapping, + resourceName: String, + colorValue: Int, + isDark: Boolean, + pitchBlackTheme: Boolean + ): Int { + return adjustColorForPitchBlackThemeIfRequired( + pitchBlackTheme, + resourceName, + colorValue + ).let { adjustedValue -> + colorMapping.adjustColorBrightnessIfRequired(adjustedValue, isDark) + } + } + @ColorInt fun adjustColorForPitchBlackThemeIfRequired( pitchBlackTheme: Boolean, @@ -186,56 +187,35 @@ object FabricatedUtil { "m3_ref_palette_dynamic_neutral_variant12", "gm3_ref_palette_dynamic_neutral_variant12" -> { - modifyBrightness( - color = colorValue, - brightnessPercentage = -40 - ) + modifyBrightness(color = colorValue, brightnessPercentage = -40) } "m3_ref_palette_dynamic_neutral_variant17", "gm3_ref_palette_dynamic_neutral_variant17", "gm3_system_bar_color_night" -> { - modifyBrightness( - color = colorValue, - brightnessPercentage = -60 - ) + modifyBrightness(color = colorValue, brightnessPercentage = -60) } "system_surface_container_lowest_dark" -> { - modifyBrightness( - color = colorValue, - brightnessPercentage = -44 - ) + modifyBrightness(color = colorValue, brightnessPercentage = -44) } "system_surface_container_low_dark" -> { - modifyBrightness( - color = colorValue, - brightnessPercentage = -36 - ) + modifyBrightness(color = colorValue, brightnessPercentage = -36) } "system_surface_container_dark" -> { - modifyBrightness( - color = colorValue, - brightnessPercentage = -28 - ) + modifyBrightness(color = colorValue, brightnessPercentage = -28) } "system_surface_container_high_dark", "system_surface_dim_dark" -> { - modifyBrightness( - color = colorValue, - brightnessPercentage = -20 - ) + modifyBrightness(color = colorValue, brightnessPercentage = -20) } "system_surface_container_highest_dark", "system_surface_bright_dark" -> { - modifyBrightness( - color = colorValue, - brightnessPercentage = -12 - ) + modifyBrightness(color = colorValue, brightnessPercentage = -12) } else -> { @@ -245,222 +225,82 @@ object FabricatedUtil { } private fun FabricatedOverlayResource.addTintlessTextColors() { - val prefixes = arrayOf( - "m3_sys_color_", - "m3_sys_color_dynamic_" - ) - val variants = arrayOf( - "dark_", - "light_", - ) - val suffixes = arrayOf( - "on_surface", - "on_surface_variant", - "on_background" - ) + val prefixes = arrayOf("m3_sys_color_", "m3_sys_color_dynamic_") + val variants = arrayOf("dark_", "light_") + val suffixes = arrayOf("on_surface", "on_surface_variant", "on_background") - for (prefix in prefixes) { - for (variant in variants) { - for (suffix in suffixes) { - val resourceName = prefix + variant + suffix + prefixes.forEach { prefix -> + variants.forEach { variant -> + suffixes.forEach { suffix -> setColor( - resourceName, + "$prefix$variant$suffix", if (variant.contains("dark")) Color.WHITE else Color.BLACK ) } } } - // Dark mode - val resourcesDark = ArrayList>().apply { - add(Pair("m3_ref_palette_dynamic_neutral90", Color.WHITE)) - add(Pair("m3_ref_palette_dynamic_neutral95", Color.WHITE)) - add(Pair("m3_ref_palette_dynamic_neutral_variant70", -0x333334)) - add(Pair("m3_ref_palette_dynamic_neutral_variant80", Color.WHITE)) - add(Pair("text_color_primary_dark", Color.WHITE)) - add(Pair("text_color_secondary_dark", -0x4c000001)) - add(Pair("text_color_tertiary_dark", -0x7f000001)) - add(Pair("google_dark_default_color_on_background", Color.WHITE)) - add(Pair("gm_ref_palette_grey500", Color.WHITE)) - } - - // Light mode - val resourcesLight = ArrayList>().apply { - add(Pair("m3_ref_palette_dynamic_neutral10", Color.BLACK)) - add(Pair("m3_ref_palette_dynamic_neutral_variant30", -0x4d000000)) - add(Pair("text_color_primary_light", Color.BLACK)) - add(Pair("text_color_secondary_light", -0x4d000000)) - add(Pair("text_color_tertiary_light", -0x80000000)) - add(Pair("google_default_color_on_background", Color.BLACK)) - add(Pair("gm_ref_palette_grey700", Color.BLACK)) - } - - for (pair in resourcesDark) { - setColor(pair.first, pair.second) - setColor("g" + pair.first, pair.second) - } - - for (pair in resourcesLight) { - setColor(pair.first, pair.second) - setColor("g" + pair.first, pair.second) - } - - if (targetPackage == "com.android.settings") { - // For settings text color on android 14 - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - setColor( - "settingslib_text_color_primary_device_default", - Color.WHITE, - "night" - ) - setColor( - "settingslib_text_color_secondary_device_default", - -0x4c000001, - "night" - ) - } - - // For settings text color on android 15 - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - setColor( - "settingslib_materialColorOnSurface", - Color.WHITE, - "night" - ) - setColor( - "settingslib_materialColorOnSurfaceVariant", - -0x4c000001, - "night" - ) - } - } - } - - private fun FabricatedOverlayResource.replaceColorsPerPackageName( - palette: ArrayList>, - pitchBlackTheme: Boolean - ) { - if (targetPackage.startsWith("com.android.systemui.clocks.")) { // Android 14 clocks - for (i in 0..4) { - for (j in 0..12) { - setColor(colorNames[i][j], palette[i][j]) - } - } - } else if (targetPackage == "com.google.android.googlequicksearchbox") { // Google Feeds - if (pitchBlackTheme) { - setColor("gm3_ref_palette_dynamic_neutral_variant20", Color.BLACK) - } - } else if (targetPackage == "com.google.android.apps.magazines") { // Google News - setColor("cluster_divider_bg", Color.TRANSPARENT) - setColor("cluster_divider_border", Color.TRANSPARENT) - - setColor("appwidget_background_day", palette[3][2]) - setColor("home_background_day", palette[3][2]) - setColor("google_default_color_background", palette[3][2]) - setColor("gm3_system_bar_color_day", palette[4][3]) - setColor("google_default_color_on_background", palette[3][11]) - setColor("google_dark_default_color_on_background", palette[3][1]) - setColor("google_default_color_on_background", palette[3][11]) - setColor("gm3_system_bar_color_night", palette[4][10]) - - if (pitchBlackTheme) { - setColor("appwidget_background_night", Color.BLACK) - setColor("home_background_night", Color.BLACK) - setColor("google_dark_default_color_background", Color.BLACK) - } else { - setColor("appwidget_background_night", palette[3][11]) - setColor("home_background_night", palette[3][11]) - setColor("google_dark_default_color_background", palette[3][11]) - } - } else if (targetPackage == "com.google.android.play.games") { // Google Play Games - // Light mode - setColor("google_white", palette[3][2]) - setColor("gm_ref_palette_grey300", palette[4][4]) - setColor("gm_ref_palette_grey700", palette[3][11]) - setColor("replay__pal_games_light_600", palette[0][8]) - - // Dark mode - setColor( - "gm_ref_palette_grey900", - if (pitchBlackTheme) Color.BLACK else palette[3][11] + // Resources for dark and light modes + val resources = mapOf( + "dark" to listOf( + "m3_ref_palette_dynamic_neutral90" to Color.WHITE, + "m3_ref_palette_dynamic_neutral95" to Color.WHITE, + "m3_ref_palette_dynamic_neutral_variant70" to -0x333334, + "m3_ref_palette_dynamic_neutral_variant80" to Color.WHITE, + "text_color_primary_dark" to Color.WHITE, + "text_color_secondary_dark" to -0x4c000001, + "text_color_tertiary_dark" to -0x7f000001, + "google_dark_default_color_on_background" to Color.WHITE, + "gm_ref_palette_grey500" to Color.WHITE + ), + "light" to listOf( + "m3_ref_palette_dynamic_neutral10" to Color.BLACK, + "m3_ref_palette_dynamic_neutral_variant30" to -0x4d000000, + "text_color_primary_light" to Color.BLACK, + "text_color_secondary_light" to -0x4d000000, + "text_color_tertiary_light" to -0x80000000, + "google_default_color_on_background" to Color.BLACK, + "gm_ref_palette_grey700" to Color.BLACK ) - setColor("gm_ref_palette_grey600", palette[4][8]) - setColor("gm_ref_palette_grey500", palette[3][1]) - setColor("replay__pal_games_dark_300", palette[0][5]) - } else if (targetPackage == "com.android.settings") { // Settings app - if (Build.VERSION.SDK_INT >= 35 && pitchBlackTheme) { // Android 15 pitch black settings - setColor( - "settingslib_materialColorSurfaceContainer", - Color.BLACK - ) // inner page background - setColor("settingslib_materialColorSurfaceVariant", palette[3][11]) // app bar - setColor("settingslib_colorSurfaceHeader", palette[3][11]) // app bar + ) + + resources.forEach { (_, pairs) -> + pairs.forEach { (name, color) -> + setColor(name, color) + setColor("g$name", color) } - } else if (targetPackage == "com.google.android.settings.intelligence" && pitchBlackTheme) { // Settings search - setColor("m3_sys_color_dark_surface_container_lowest", Color.BLACK) - setColor("gm3_sys_color_dark_surface_container_lowest", Color.BLACK) - setColor("m3_sys_color_dynamic_dark_surface_container_lowest", Color.BLACK) - setColor("gm3_sys_color_dynamic_dark_surface_container_lowest", Color.BLACK) - setColor("m3_sys_color_dark_surface_container_low", Color.BLACK) - setColor("gm3_sys_color_dark_surface_container_low", Color.BLACK) - setColor("m3_sys_color_dynamic_dark_surface_container_low", Color.BLACK) - setColor("gm3_sys_color_dynamic_dark_surface_container_low", Color.BLACK) - setColor("m3_sys_color_dark_surface_container", Color.BLACK) - setColor("gm3_sys_color_dark_surface_container", Color.BLACK) - setColor("m3_sys_color_dynamic_dark_surface_container", Color.BLACK) - setColor("gm3_sys_color_dynamic_dark_surface_container", Color.BLACK) - setColor("m3_sys_color_dark_surface_container_high", Color.BLACK) - setColor("gm3_sys_color_dark_surface_container_high", Color.BLACK) - setColor("m3_sys_color_dynamic_dark_surface_container_high", Color.BLACK) - setColor("gm3_sys_color_dynamic_dark_surface_container_high", Color.BLACK) - setColor("m3_sys_color_dark_surface_container_highest", Color.BLACK) - setColor("gm3_sys_color_dark_surface_container_highest", Color.BLACK) - setColor("m3_sys_color_dynamic_dark_surface_container_highest", Color.BLACK) - setColor("gm3_sys_color_dynamic_dark_surface_container_highest", Color.BLACK) } - } - private fun ColorMapping.extractResourceFromColorMap( - prefix: String = "", - suffix: String = "", - palette: ArrayList>, - isDark: Boolean = false - ): Pair { - val resourceName = prefix + resourceName + suffix - - val colorValue: Int = if (tonalPalette != null) { - if (colorIndex != null) { - palette[tonalPalette.index][colorIndex] - } else { - if (isDark) { - palette[tonalPalette.index][darkModeColorIndex!!] - } else { - palette[tonalPalette.index][lightModeColorIndex!!] + when { + targetPackage == "com.android.settings" -> { + when { + Build.VERSION.SDK_INT <= Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> { + setColor( + "settingslib_text_color_primary_device_default", + Color.WHITE, + "night" + ) + setColor( + "settingslib_text_color_secondary_device_default", + -0x4c000001, + "night" + ) + } + + Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> { + setColor( + "settingslib_materialColorOnSurface", + Color.WHITE, + "night" + ) + setColor( + "settingslib_materialColorOnSurfaceVariant", + -0x4c000001, + "night" + ) + } } } - } else { - colorCode ?: if (isDark) { - darkModeColorCode - } else { - lightModeColorCode - } - }!! - - return Pair(resourceName, colorValue) - } - - private fun ColorMapping.adjustColorBrightnessIfRequired( - colorValue: Int, - isDark: Boolean - ): Int { - return if (lightnessAdjustment != null) { - modifyBrightness(colorValue, lightnessAdjustment) - } else if (darkModeLightnessAdjustment != null && isDark) { - modifyBrightness(colorValue, darkModeLightnessAdjustment) - } else if (lightModeLightnessAdjustment != null && !isDark) { - modifyBrightness(colorValue, lightModeLightnessAdjustment) - } else { - colorValue } } } diff --git a/app/src/main/java/com/drdisagree/colorblendr/utils/OverlayManager.kt b/app/src/main/java/com/drdisagree/colorblendr/utils/OverlayManager.kt index 5465bd2f..fa106efe 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/utils/OverlayManager.kt +++ b/app/src/main/java/com/drdisagree/colorblendr/utils/OverlayManager.kt @@ -9,6 +9,18 @@ import com.drdisagree.colorblendr.ColorBlendr.Companion.rootConnection import com.drdisagree.colorblendr.ColorBlendr.Companion.shizukuConnection import com.drdisagree.colorblendr.R import com.drdisagree.colorblendr.common.Const +import com.drdisagree.colorblendr.common.Const.FABRICATED_OVERLAY_NAME_APPS +import com.drdisagree.colorblendr.common.Const.FABRICATED_OVERLAY_NAME_SYSTEM +import com.drdisagree.colorblendr.common.Const.FABRICATED_OVERLAY_NAME_SYSTEMUI +import com.drdisagree.colorblendr.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.colorblendr.common.Const.MONET_ACCENT_SATURATION +import com.drdisagree.colorblendr.common.Const.MONET_ACCURATE_SHADES +import com.drdisagree.colorblendr.common.Const.MONET_BACKGROUND_LIGHTNESS +import com.drdisagree.colorblendr.common.Const.MONET_BACKGROUND_SATURATION +import com.drdisagree.colorblendr.common.Const.MONET_PITCH_BLACK_THEME +import com.drdisagree.colorblendr.common.Const.MONET_STYLE +import com.drdisagree.colorblendr.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.colorblendr.common.Const.selectedFabricatedApps import com.drdisagree.colorblendr.common.Const.workingMethod import com.drdisagree.colorblendr.config.RPrefs import com.drdisagree.colorblendr.config.RPrefs.getBoolean @@ -238,101 +250,88 @@ object OverlayManager { isDark = true ) - val fabricatedOverlays = ArrayList() - fabricatedOverlays.add( - FabricatedOverlayResource( - Const.FABRICATED_OVERLAY_NAME_SYSTEM, - Const.FRAMEWORK_PACKAGE + ArrayList().apply { + add( + FabricatedOverlayResource( + FABRICATED_OVERLAY_NAME_SYSTEM, + FRAMEWORK_PACKAGE + ).also { frameworkOverlay -> + val isDarkMode = SystemUtil.isDarkMode + + frameworkOverlay.apply { + for (i in colorNames.indices) { + for (j in colorNames[i].indices) { + setColor( + colorNames[i][j], + if (isDarkMode) paletteDark[i][j] else paletteLight[i][j] + ) + } + } + + createDynamicOverlay( + paletteLight, + paletteDark + ) + + // Temporary workaround for Android 15 QPR1 beta 3 background color issue in settings. + // Currently, we set the status bar color to match the background color + // to achieve a uniform appearance when the background lightness is reduced. + // TODO: Remove once the Settings background color issue is resolved. + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + // Light theme + setColor( + "primary_dark_device_default_settings_light", // status bar + getColor("system_surface_container_light") // background + ) + // Dark theme + setColor( + "primary_dark_device_default_settings", // status bar + getColor("system_surface_container_dark") // background + ) + } + + if (pitchBlackTheme) { + setColor("background_dark", Color.BLACK) + setColor("surface_header_dark_sysui", Color.BLACK) // QS top part color + setColor( + "system_surface_dim_dark", + Color.BLACK + ) // A14 notification scrim color + setColor(colorNames[3][11], Color.BLACK) + setColor(colorNames[4][11], Color.BLACK) + } + + if (!getBoolean(Const.TINT_TEXT_COLOR, true)) { + setColor("text_color_primary_device_default_dark", Color.WHITE) + setColor("text_color_secondary_device_default_dark", -0x4c000001) + setColor("text_color_primary_device_default_light", Color.BLACK) + setColor("text_color_secondary_device_default_light", -0x4d000000) + } + } + } ) - ) - - for (i in 0..4) { - for (j in 0..12) { - fabricatedOverlays[0].setColor( - colorNames[i][j], - paletteDark[i][j] - ) - } - } - fabricatedOverlays[0].createDynamicOverlay( - paletteLight, - paletteDark - ) - - // Temporary workaround for Android 15 QPR1 beta 3 background color issue in settings. - // Currently, we set the status bar color to match the background color - // to achieve a uniform appearance when the background lightness is reduced. - // TODO: Remove once the Settings background color issue is resolved. - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - // Light theme - fabricatedOverlays[0].setColor( - "primary_dark_device_default_settings_light", // status bar - fabricatedOverlays[0].getColor("system_surface_container_light") // background + add( + FabricatedOverlayResource( + FABRICATED_OVERLAY_NAME_SYSTEMUI, + SYSTEMUI_PACKAGE + ).also { systemuiOverlay -> + systemuiOverlay.setBoolean("flag_monet", false) + } ) - // Dark theme - fabricatedOverlays[0].setColor( - "primary_dark_device_default_settings", // status bar - fabricatedOverlays[0].getColor("system_surface_container_dark") // background - ) - } - val selectedApps = Const.selectedFabricatedApps - - for (packageName in selectedApps.keys) { - if (java.lang.Boolean.TRUE == selectedApps[packageName] && - SystemUtil.isAppInstalled(packageName) - ) { - val fabricatedOverlayPerApp = getFabricatedColorsPerApp( - context, - packageName, - if (SystemUtil.isDarkMode) paletteDark else paletteLight + selectedFabricatedApps.filter { (packageName, isSelected) -> + isSelected == java.lang.Boolean.TRUE && SystemUtil.isAppInstalled(packageName) + }.forEach { (packageName) -> + add( + getFabricatedColorsPerApp( + context, + packageName, + if (SystemUtil.isDarkMode) paletteDark else paletteLight + ) ) - - fabricatedOverlays.add(fabricatedOverlayPerApp) } - } - - if (pitchBlackTheme) { - fabricatedOverlays[0].setColor( - "background_dark", - Color.BLACK - ) - fabricatedOverlays[0].setColor( - "surface_header_dark_sysui", - Color.BLACK - ) // QS top part color - fabricatedOverlays[0].setColor( - "system_surface_dim_dark", - Color.BLACK - ) // A14 notification scrim color - fabricatedOverlays[0].setColor( - colorNames[3][11], Color.BLACK - ) - fabricatedOverlays[0].setColor( - colorNames[4][11], Color.BLACK - ) - } - - if (!getBoolean(Const.TINT_TEXT_COLOR, true)) { - fabricatedOverlays[0].setColor("text_color_primary_device_default_dark", Color.WHITE) - fabricatedOverlays[0].setColor("text_color_secondary_device_default_dark", -0x4c000001) - fabricatedOverlays[0].setColor("text_color_primary_device_default_light", Color.BLACK) - fabricatedOverlays[0].setColor("text_color_secondary_device_default_light", -0x4d000000) - } - - fabricatedOverlays.add( - FabricatedOverlayResource( - Const.FABRICATED_OVERLAY_NAME_SYSTEMUI, - Const.SYSTEMUI_PACKAGE - ) - ) - - fabricatedOverlays[fabricatedOverlays.size - 1].setBoolean("flag_monet", false) - - for (fabricatedOverlay in fabricatedOverlays) { - registerFabricatedOverlay(fabricatedOverlay) - } + }.forEach { registerFabricatedOverlay(it) } } fun applyFabricatedColorsPerApp( @@ -354,26 +353,21 @@ object OverlayManager { return } - val fabricatedOverlays = ArrayList() - val selectedApps = Const.selectedFabricatedApps - - for (packageName in selectedApps.keys) { - if (java.lang.Boolean.TRUE == selectedApps[packageName]) { - fabricatedOverlays.add( + ArrayList().apply { + selectedFabricatedApps.filter { (_, isSelected) -> + isSelected == java.lang.Boolean.TRUE + }.forEach { (packageName) -> + add( String.format( - Const.FABRICATED_OVERLAY_NAME_APPS, + FABRICATED_OVERLAY_NAME_APPS, packageName ) ) } - } - fabricatedOverlays.add(Const.FABRICATED_OVERLAY_NAME_SYSTEM) - fabricatedOverlays.add(Const.FABRICATED_OVERLAY_NAME_SYSTEMUI) - - for (packageName in fabricatedOverlays) { - unregisterFabricatedOverlay(packageName) - } + add(FABRICATED_OVERLAY_NAME_SYSTEM) + add(FABRICATED_OVERLAY_NAME_SYSTEMUI) + }.forEach { unregisterFabricatedOverlay(it) } } private fun getFabricatedColorsPerApp( @@ -388,27 +382,25 @@ object OverlayManager { ColorSchemeUtil.stringToEnumMonetStyle( context, RPrefs.getString( - Const.MONET_STYLE, + MONET_STYLE, context.getString(R.string.monet_tonalspot) )!! ), - getInt(Const.MONET_ACCENT_SATURATION, 100), - getInt(Const.MONET_BACKGROUND_SATURATION, 100), - getInt(Const.MONET_BACKGROUND_LIGHTNESS, 100), - getBoolean(Const.MONET_PITCH_BLACK_THEME, false), - getBoolean(Const.MONET_ACCURATE_SHADES, true), + getInt(MONET_ACCENT_SATURATION, 100), + getInt(MONET_BACKGROUND_SATURATION, 100), + getInt(MONET_BACKGROUND_LIGHTNESS, 100), + getBoolean(MONET_PITCH_BLACK_THEME, false), + getBoolean(MONET_ACCURATE_SHADES, true), modifyPitchBlack = false ) } - val fabricatedOverlay = FabricatedOverlayResource( - String.format(Const.FABRICATED_OVERLAY_NAME_APPS, packageName), + return FabricatedOverlayResource( + String.format(FABRICATED_OVERLAY_NAME_APPS, packageName), packageName - ) - - fabricatedOverlay.assignPerAppColorsToOverlay(paletteTemp) - - return fabricatedOverlay + ).also { overlay -> + overlay.assignPerAppColorsToOverlay(paletteTemp) + } } private fun applyFabricatedColorsNonRoot(context: Context): Boolean { diff --git a/app/src/main/java/com/drdisagree/colorblendr/utils/PerPackageColors.kt b/app/src/main/java/com/drdisagree/colorblendr/utils/PerPackageColors.kt new file mode 100644 index 00000000..0d966711 --- /dev/null +++ b/app/src/main/java/com/drdisagree/colorblendr/utils/PerPackageColors.kt @@ -0,0 +1,217 @@ +package com.drdisagree.colorblendr.utils + +import android.graphics.Color +import android.os.Build +import com.drdisagree.colorblendr.common.Const.DARKER_LAUNCHER_ICONS +import com.drdisagree.colorblendr.common.Const.GOOGLE_FEEDS +import com.drdisagree.colorblendr.common.Const.GOOGLE_NEWS +import com.drdisagree.colorblendr.common.Const.PIXEL_LAUNCHER +import com.drdisagree.colorblendr.common.Const.PLAY_GAMES +import com.drdisagree.colorblendr.common.Const.SEMI_TRANSPARENT_LAUNCHER_ICONS +import com.drdisagree.colorblendr.common.Const.SETTINGS +import com.drdisagree.colorblendr.common.Const.SETTINGS_SEARCH +import com.drdisagree.colorblendr.common.Const.SYSTEMUI_CLOCKS +import com.drdisagree.colorblendr.config.RPrefs.getBoolean +import com.drdisagree.colorblendr.utils.ColorUtil.applyAlphaToColor +import com.drdisagree.colorblendr.utils.ColorUtil.colorNames +import com.drdisagree.colorblendr.utils.SystemUtil.isDarkMode +import com.drdisagree.colorblendr.utils.fabricated.FabricatedOverlayResource + +fun FabricatedOverlayResource.replaceColorsPerPackageName( + palette: ArrayList>, + pitchBlackTheme: Boolean +) { + when { + targetPackage.startsWith(SYSTEMUI_CLOCKS) -> applyClockColors(palette) + else -> when (targetPackage) { + GOOGLE_FEEDS -> applyGoogleFeedsColors(pitchBlackTheme) + GOOGLE_NEWS -> applyGoogleNewsColors(palette, pitchBlackTheme) + PLAY_GAMES -> applyPlayGamesColors(palette, pitchBlackTheme) + SETTINGS -> applySettingsColors(palette, pitchBlackTheme) + SETTINGS_SEARCH -> applySettingsSearchColors(pitchBlackTheme) + PIXEL_LAUNCHER -> applyPixelLauncherColors(palette, pitchBlackTheme) + } + } +} + +private fun FabricatedOverlayResource.applyClockColors(palette: ArrayList>) { + for (i in colorNames.indices) { + for (j in colorNames[i].indices) { + setColor(colorNames[i][j], palette[i][j]) + } + } +} + +private fun FabricatedOverlayResource.applyGoogleFeedsColors(pitchBlackTheme: Boolean) { + if (!pitchBlackTheme || !isDarkMode) return + + setColor("gm3_ref_palette_dynamic_neutral_variant20", Color.BLACK) +} + +private fun FabricatedOverlayResource.applyGoogleNewsColors( + palette: ArrayList>, + pitchBlackTheme: Boolean +) { + // Divider colors + setColor("cluster_divider_bg", Color.TRANSPARENT) + setColor("cluster_divider_border", Color.TRANSPARENT) + + setColor("appwidget_background_day", palette[3][2]) + setColor("home_background_day", palette[3][2]) + setColor("google_default_color_background", palette[3][2]) + setColor("gm3_system_bar_color_day", palette[4][3]) + setColor("google_default_color_on_background", palette[3][11]) + setColor("google_dark_default_color_on_background", palette[3][1]) + setColor("google_default_color_on_background", palette[3][11]) + setColor("gm3_system_bar_color_night", palette[4][10]) + + if (pitchBlackTheme) { + setColor("appwidget_background_night", Color.BLACK) + setColor("home_background_night", Color.BLACK) + setColor("google_dark_default_color_background", Color.BLACK) + } else { + setColor("appwidget_background_night", palette[3][11]) + setColor("home_background_night", palette[3][11]) + setColor("google_dark_default_color_background", palette[3][11]) + } +} + +private fun FabricatedOverlayResource.applyPlayGamesColors( + palette: ArrayList>, + pitchBlackTheme: Boolean +) { + // Light mode + setColor("google_white", palette[3][2]) + setColor("gm_ref_palette_grey300", palette[4][4]) + setColor("gm_ref_palette_grey700", palette[3][11]) + setColor("replay__pal_games_light_600", palette[0][8]) + + // Dark mode + setColor("gm_ref_palette_grey900", if (pitchBlackTheme) Color.BLACK else palette[3][11]) + setColor("gm_ref_palette_grey600", palette[4][8]) + setColor("gm_ref_palette_grey500", palette[3][1]) + setColor("replay__pal_games_dark_300", palette[0][5]) +} + +private fun FabricatedOverlayResource.applySettingsColors( + palette: ArrayList>, + pitchBlackTheme: Boolean +) { + if (!pitchBlackTheme || !isDarkMode || Build.VERSION.SDK_INT < 35) return + + setColor("settingslib_materialColorSurfaceContainer", Color.BLACK) // inner page background + setColor("settingslib_materialColorSurfaceVariant", palette[3][11]) // app bar + setColor("settingslib_colorSurfaceHeader", palette[3][11]) // app bar +} + +private fun FabricatedOverlayResource.applySettingsSearchColors(pitchBlackTheme: Boolean) { + if (!pitchBlackTheme) return + + listOf( + "m3_sys_color_dark_surface_container_lowest", + "gm3_sys_color_dark_surface_container_lowest", + "m3_sys_color_dynamic_dark_surface_container_lowest", + "gm3_sys_color_dynamic_dark_surface_container_lowest", + "m3_sys_color_dark_surface_container_low", + "gm3_sys_color_dark_surface_container_low", + "m3_sys_color_dynamic_dark_surface_container_low", + "gm3_sys_color_dynamic_dark_surface_container_low", + "m3_sys_color_dark_surface_container", + "gm3_sys_color_dark_surface_container", + "m3_sys_color_dynamic_dark_surface_container", + "gm3_sys_color_dynamic_dark_surface_container", + "m3_sys_color_dark_surface_container_high", + "gm3_sys_color_dark_surface_container_high", + "m3_sys_color_dynamic_dark_surface_container_high", + "gm3_sys_color_dynamic_dark_surface_container_high", + "m3_sys_color_dark_surface_container_highest", + "gm3_sys_color_dark_surface_container_highest", + "m3_sys_color_dynamic_dark_surface_container_highest", + "gm3_sys_color_dynamic_dark_surface_container_highest" + ).forEach { setColor(it, Color.BLACK) } +} + +private fun FabricatedOverlayResource.applyPixelLauncherColors( + palette: ArrayList>, + pitchBlackTheme: Boolean +) { + /* + * qsb_icon_tint_quaternary_mono = monochrome icon color + * themed_icon_background_color = monochrome icon background + * material_color_surface_container_low = search bar color in homepage + * material_color_surface_bright = search bar color in app drawer + * material_color_surface_dim = app drawer background color + * folder_preview_xxx = folder preview background color + * folder_background_xxx = expanded folder background color + */ + + val isSemiTransparent = getBoolean(SEMI_TRANSPARENT_LAUNCHER_ICONS, false) + + if (isDarkMode) { + val darkerIcon = getBoolean(DARKER_LAUNCHER_ICONS, false) + + setColor("qsb_icon_tint_quaternary_mono", palette[0][5]) + + if (pitchBlackTheme) { + val iconBgColor = if (isSemiTransparent) { + Color.BLACK.applyAlphaToColor(60) + } else { + Color.BLACK + } + val folderColor = if (isSemiTransparent) { + Color.BLACK.applyAlphaToColor(60) + } else { + Color.BLACK + } + + setColor("themed_icon_background_color", iconBgColor) + setColor("material_color_surface_container_low", iconBgColor) + setColor("material_color_surface_bright", palette[3][11]) + setColor("material_color_surface_dim", Color.BLACK) + setColor("folder_preview_dark", folderColor) + setColor("folder_background_dark", folderColor) + } else { + val iconBgColor = if (isSemiTransparent) { + (if (darkerIcon) palette[1][11] else palette[1][10]).applyAlphaToColor(60) + } else { + (if (darkerIcon) palette[1][11] else palette[1][10]) + } + val folderColor = if (isSemiTransparent) { + palette[3][11].applyAlphaToColor(60) + } else { + palette[3][11] + } + + setColor("themed_icon_background_color", iconBgColor) + setColor("material_color_surface_container_low", iconBgColor) + setColor("material_color_surface_bright", palette[3][10]) + setColor("material_color_surface_dim", palette[3][11]) + setColor("folder_preview_dark", folderColor) + setColor("folder_background_dark", folderColor) + } + } else { + val iconBgColor = if (isSemiTransparent) { + palette[0][3].applyAlphaToColor(80) + } else { + palette[0][3] + } + val folderPreviewColor = if (isSemiTransparent) { + palette[1][4].applyAlphaToColor(80) + } else { + palette[1][4] + } + val folderBackgroundColor = if (isSemiTransparent) { + palette[3][1].applyAlphaToColor(80) + } else { + palette[3][1] + } + + setColor("qsb_icon_tint_quaternary_mono", palette[0][9]) + setColor("themed_icon_background_color", iconBgColor) + setColor("material_color_surface_container_low", iconBgColor) + setColor("material_color_surface_bright", palette[3][1]) + setColor("material_color_surface_dim", palette[4][2]) + setColor("folder_preview_light", folderPreviewColor) + setColor("folder_background_light", folderBackgroundColor) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_dark_icon.xml b/app/src/main/res/drawable/ic_dark_icon.xml new file mode 100644 index 00000000..78224d52 --- /dev/null +++ b/app/src/main/res/drawable/ic_dark_icon.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_semi_transparent.xml b/app/src/main/res/drawable/ic_semi_transparent.xml new file mode 100644 index 00000000..dc635d02 --- /dev/null +++ b/app/src/main/res/drawable/ic_semi_transparent.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/layout/fragment_settings_advanced.xml b/app/src/main/res/layout/fragment_settings_advanced.xml index f64677f1..a0d068cd 100644 --- a/app/src/main/res/layout/fragment_settings_advanced.xml +++ b/app/src/main/res/layout/fragment_settings_advanced.xml @@ -48,6 +48,22 @@ app:summaryText="@string/mode_specific_theme_desc" app:titleText="@string/mode_specific_theme_title" /> + + + + diff --git a/app/src/main/res/layout/view_color_table.xml b/app/src/main/res/layout/view_color_table.xml index 4e1511b2..b8af04af 100644 --- a/app/src/main/res/layout/view_color_table.xml +++ b/app/src/main/res/layout/view_color_table.xml @@ -1,7 +1,7 @@ Apprenti | Développeur | Designer Nouveautés Support - GitHub + Github Version Thème noir complet Fond noir en mode foncé @@ -89,8 +89,8 @@ Cette permission est nécessaire pour récupérer le fond d\'écran d\'accueil et de l\'écran de verrouillage. Accès à tous les fichiers Cette permission est nécessaire pour récupérer le fond d\'écran d\'accueil et de l\'écran de verrouillage. - Optimisation de la batterie - L\'optimisation non restreinte de la batterie est nécessaire pour permettre le fonctionnement en arrière-plan. + Battery Optimization + Unrestricted battery optimization is required to allow running in background. Démarrer Continuer Palette de couleurs vives et rafraîchissantes inspirée de l\'effervescence des boissons au spritz. @@ -114,7 +114,7 @@ Appliquer des couleurs personnalisées à des applications spécifiques qui ne suivent pas le système monet Précédent Permissions - Optimisation + Optimization Choisissez un mode Démarrage automatique Lancement du service au démarrage @@ -141,21 +141,21 @@ Utiliser l\'accès root pour changer les couleurs. Toutes les options de personnalisation seront disponibles. Shizuku Utiliser shizuku pour fonctionner sans root. Des options de personnalisation limitées seront disponibles. - Palette de couleurs - Explorez toutes les couleurs de votre palette material - Appuyez sur n\'importe quelle couleur de la palette pour personnaliser son apparence ; appuyez longuement pour rétablir la couleur par défaut. - Appuyez sur n\'importe quelle couleur de la palette pour copier son code couleur hexadécimal. - Sélectionner une catégorie d\'application - Applications système - Applications utilisateur - Applications exécutables - Toutes les applications - Il n\'est pas obligatoire mais recommandé de désactiver l\'optimisation de la batterie - Paramètres avancés - Couleur secondaire personnalisée - Sélectionnez la couleur blanche pure pour désactiver - Couleur tertiaire personnalisée - Sélectionnez la couleur blanche pure pour désactiver - Thème spécifique au mode - Appliquer une saturation et une luminosité différentes pour les modes clair et foncé + Color palette + Explore all the colors of your material palette + Tap on any color in the palette to customize its appearance; long press to reset to the default color. + Tap on any color in the palette to copy its hexadecimal color code. + Select app category + System apps + User apps + Launchable apps + All apps + It\'s not mandatory but recommended to disable the battery optimization + Advanced + Custom secondary color + Select pure white color to disable + Custom tertiary color + Select pure white color to disable + Mode-specific theme + Apply different saturation and lightness for light and dark modes diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca8bbad4..625d57a3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -170,4 +170,8 @@ Select pure white color to disable Mode-specific theme Apply different saturation and lightness for light and dark modes + Darker launcher icons + Apply a darker background to pixel launcher monochrome icons + Semi-transparent launcher + Apply a semi-transparent background to pixel launcher monochrome icons and search bar \ No newline at end of file