diff --git a/app/src/main/java/com/bnyro/translate/ext/HexToColor.kt b/app/src/main/java/com/bnyro/translate/ext/HexToColor.kt
new file mode 100644
index 000000000..6ab1c14ba
--- /dev/null
+++ b/app/src/main/java/com/bnyro/translate/ext/HexToColor.kt
@@ -0,0 +1,5 @@
+package com.bnyro.translate.ext
+
+import androidx.compose.ui.graphics.Color
+
+fun String.hexToColor() = Color(android.graphics.Color.parseColor("#$this"))
diff --git a/app/src/main/java/com/bnyro/translate/ui/MainActivity.kt b/app/src/main/java/com/bnyro/translate/ui/MainActivity.kt
index 203167768..c8902e020 100644
--- a/app/src/main/java/com/bnyro/translate/ui/MainActivity.kt
+++ b/app/src/main/java/com/bnyro/translate/ui/MainActivity.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.compose.rememberNavController
+import com.bnyro.translate.ext.hexToColor
import com.bnyro.translate.ext.parcelable
import com.bnyro.translate.ui.models.TranslationModel
import com.bnyro.translate.ui.nav.NavigationHost
@@ -27,6 +28,7 @@ class MainActivity : ComponentActivity() {
var themeMode by mutableStateOf(
Preferences.getThemeMode()
)
+ var accentColor by mutableStateOf(Preferences.getAccentColor())
override fun onCreate(savedInstanceState: Bundle?) {
LocaleHelper.updateLanguage(this)
@@ -36,7 +38,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
- TranslateYouTheme(themeMode) {
+ TranslateYouTheme(themeMode, accentColor?.hexToColor()) {
val navController = rememberNavController()
NavigationHost(navController, mainModel)
}
diff --git a/app/src/main/java/com/bnyro/translate/ui/components/BlockButton.kt b/app/src/main/java/com/bnyro/translate/ui/components/BlockButton.kt
index 7e41f1df2..733f55ff9 100644
--- a/app/src/main/java/com/bnyro/translate/ui/components/BlockButton.kt
+++ b/app/src/main/java/com/bnyro/translate/ui/components/BlockButton.kt
@@ -23,7 +23,7 @@ fun BlockButton(
text: String,
selected: Boolean = false,
containerColor: Color = MaterialTheme.colorScheme.surfaceVariant.copy(0.5f),
- selectedContainerColor: Color = MaterialTheme.colorScheme.primaryContainer,
+ selectedContainerColor: Color = MaterialTheme.colorScheme.primary,
contentColor: Color = MaterialTheme.colorScheme.inverseSurface,
selectedContentColor: Color = MaterialTheme.colorScheme.onSurface,
onClick: () -> Unit = {}
diff --git a/app/src/main/java/com/bnyro/translate/ui/components/TopBarMenu.kt b/app/src/main/java/com/bnyro/translate/ui/components/TopBarMenu.kt
index d07ac5a83..577040c93 100644
--- a/app/src/main/java/com/bnyro/translate/ui/components/TopBarMenu.kt
+++ b/app/src/main/java/com/bnyro/translate/ui/components/TopBarMenu.kt
@@ -1,7 +1,6 @@
package com.bnyro.translate.ui.components
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.DropdownMenu
@@ -10,8 +9,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
import com.bnyro.translate.obj.MenuItemData
@Composable
diff --git a/app/src/main/java/com/bnyro/translate/ui/components/prefs/AccentColorPref.kt b/app/src/main/java/com/bnyro/translate/ui/components/prefs/AccentColorPref.kt
new file mode 100644
index 000000000..2696ded43
--- /dev/null
+++ b/app/src/main/java/com/bnyro/translate/ui/components/prefs/AccentColorPref.kt
@@ -0,0 +1,143 @@
+package com.bnyro.translate.ui.components.prefs
+
+import android.os.Build
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.core.content.edit
+import com.bnyro.translate.R
+import com.bnyro.translate.ext.hexToColor
+import com.bnyro.translate.ui.MainActivity
+import com.bnyro.translate.ui.components.DialogButton
+import com.bnyro.translate.ui.theme.defaultAccentColor
+import com.bnyro.translate.util.Preferences
+import okhttp3.internal.toHexString
+
+@Composable
+fun AccentColorPrefDialog(
+ onDismissRequest: () -> Unit
+) {
+ val context = LocalContext.current
+ val supportsDynamicColors = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
+
+ var color by remember {
+ mutableStateOf(
+ Preferences.getAccentColor() ?: run {
+ if (supportsDynamicColors) null else defaultAccentColor
+ }
+ )
+ }
+
+ AlertDialog(
+ onDismissRequest = onDismissRequest,
+ confirmButton = {
+ DialogButton(text = stringResource(R.string.okay)) {
+ Preferences.prefs.edit(true) { putString(Preferences.accentColorKey, color) }
+ (context as MainActivity).accentColor = color
+ onDismissRequest.invoke()
+ }
+ },
+ dismissButton = {
+ DialogButton(text = stringResource(R.string.cancel)) {
+ onDismissRequest.invoke()
+ }
+ },
+ title = {
+ Text(stringResource(R.string.accent_color))
+ },
+ text = {
+ Column(
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ if (supportsDynamicColors) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ modifier = Modifier.weight(1f),
+ text = stringResource(R.string.dynamic_colors)
+ )
+ Switch(
+ checked = color == null,
+ onCheckedChange = { newValue ->
+ color = defaultAccentColor.takeIf { !newValue }
+ }
+ )
+ }
+ }
+ Row(
+ modifier = Modifier.height(250.dp)
+ ) {
+ AnimatedVisibility(
+ visible = color != null
+ ) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ listOf("R", "G", "B").forEachIndexed { index, c ->
+ val startIndex = index * 2
+ color?.let {
+ ColorSlider(
+ label = c,
+ value = it.substring(startIndex, startIndex + 2).toInt(16),
+ onChange = { colorInt ->
+ var newHex = colorInt.toHexString()
+ if (newHex.length == 1) newHex = "0$newHex"
+ color = StringBuilder(it).apply {
+ setCharAt(startIndex, newHex[0])
+ setCharAt(startIndex + 1, newHex[1])
+ }.toString()
+ }
+ )
+ }
+ }
+ Spacer(modifier = Modifier.height(20.dp))
+ color?.let {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Box(
+ Modifier.size(50.dp).background(
+ MaterialTheme.colorScheme.primary,
+ CircleShape
+ )
+ )
+ Text(text = " => ", fontSize = 27.sp)
+ Box(
+ modifier = Modifier.size(50.dp).background(
+ it.hexToColor(),
+ CircleShape
+ )
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+}
diff --git a/app/src/main/java/com/bnyro/translate/ui/components/prefs/ColorSlider.kt b/app/src/main/java/com/bnyro/translate/ui/components/prefs/ColorSlider.kt
new file mode 100644
index 000000000..ec741e7e3
--- /dev/null
+++ b/app/src/main/java/com/bnyro/translate/ui/components/prefs/ColorSlider.kt
@@ -0,0 +1,34 @@
+package com.bnyro.translate.ui.components.prefs
+
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Slider
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun ColorSlider(
+ label: String,
+ value: Int,
+ onChange: (Int) -> Unit
+) {
+ Row(
+ modifier = Modifier.padding(horizontal = 10.dp, vertical = 5.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(label)
+ Slider(
+ modifier = Modifier.padding(horizontal = 10.dp).weight(1f),
+ value = value.toFloat(),
+ valueRange = 0f..255f,
+ steps = 256,
+ onValueChange = {
+ onChange(it.toInt())
+ }
+ )
+ Text(value.toString())
+ }
+}
diff --git a/app/src/main/java/com/bnyro/translate/ui/screens/SettingsScreen.kt b/app/src/main/java/com/bnyro/translate/ui/screens/SettingsScreen.kt
index c84ce59fa..d65280381 100644
--- a/app/src/main/java/com/bnyro/translate/ui/screens/SettingsScreen.kt
+++ b/app/src/main/java/com/bnyro/translate/ui/screens/SettingsScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.DarkMode
+import androidx.compose.material.icons.filled.Palette
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
@@ -33,6 +34,7 @@ import com.bnyro.translate.R
import com.bnyro.translate.ui.MainActivity
import com.bnyro.translate.ui.components.StyledIconButton
import com.bnyro.translate.ui.components.ThemeModeDialog
+import com.bnyro.translate.ui.components.prefs.AccentColorPrefDialog
import com.bnyro.translate.ui.components.prefs.ListPreference
import com.bnyro.translate.ui.components.prefs.PreferenceItem
import com.bnyro.translate.ui.components.prefs.SettingsCategory
@@ -56,6 +58,10 @@ fun SettingsScreen(
mutableStateOf(false)
}
+ var showAccentColorDialog by remember {
+ mutableStateOf(false)
+ }
+
var enableSimultaneousTranslation by remember {
mutableStateOf(
Preferences.get(Preferences.simultaneousTranslationKey, false)
@@ -88,6 +94,11 @@ fun SettingsScreen(
}
},
actions = {
+ StyledIconButton(
+ imageVector = Icons.Default.Palette
+ ) {
+ showAccentColorDialog = true
+ }
StyledIconButton(
imageVector = Icons.Default.DarkMode
) {
@@ -268,4 +279,10 @@ fun SettingsScreen(
showTessSettings = false
}
}
+
+ if (showAccentColorDialog) {
+ AccentColorPrefDialog {
+ showAccentColorDialog = false
+ }
+ }
}
diff --git a/app/src/main/java/com/bnyro/translate/ui/theme/Color.kt b/app/src/main/java/com/bnyro/translate/ui/theme/Color.kt
deleted file mode 100644
index 87a91f864..000000000
--- a/app/src/main/java/com/bnyro/translate/ui/theme/Color.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.bnyro.translate.ui.theme
-
-import androidx.compose.ui.graphics.Color
-
-val Purple80 = Color(0xFFD0BCFF)
-val PurpleGrey80 = Color(0xFFCCC2DC)
-val Pink80 = Color(0xFFEFB8C8)
-
-val Purple40 = Color(0xFF6650a4)
-val PurpleGrey40 = Color(0xFF625b71)
-val Pink40 = Color(0xFF7D5260)
diff --git a/app/src/main/java/com/bnyro/translate/ui/theme/Theme.kt b/app/src/main/java/com/bnyro/translate/ui/theme/Theme.kt
index 3340ecd5e..c536dde7b 100644
--- a/app/src/main/java/com/bnyro/translate/ui/theme/Theme.kt
+++ b/app/src/main/java/com/bnyro/translate/ui/theme/Theme.kt
@@ -10,39 +10,21 @@ import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
+import androidx.core.graphics.ColorUtils
import androidx.core.view.WindowCompat
import com.bnyro.translate.const.ThemeMode
+import com.bnyro.translate.ext.hexToColor
-private val DarkColorScheme = darkColorScheme(
- primary = Purple80,
- secondary = PurpleGrey80,
- tertiary = Pink80
-)
-
-private val LightColorScheme = lightColorScheme(
- primary = Purple40,
- secondary = PurpleGrey40,
- tertiary = Pink40
-
- /* Other default colors to override
- background = Color(0xFFFFFBFE),
- surface = Color(0xFFFFFBFE),
- onPrimary = Color.White,
- onSecondary = Color.White,
- onTertiary = Color.White,
- onBackground = Color(0xFF1C1B1F),
- onSurface = Color(0xFF1C1B1F),
- */
-)
+const val defaultAccentColor = "d0bcff"
@Composable
fun TranslateYouTheme(
themeMode: Int = ThemeMode.AUTO,
- // Dynamic color is available on Android 12+
- dynamicColor: Boolean = true,
+ accentColor: Color? = null,
content: @Composable () -> Unit
) {
val darkTheme = when (themeMode) {
@@ -52,12 +34,20 @@ fun TranslateYouTheme(
}
val colorScheme = when {
- dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
+ accentColor == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
- darkTheme -> DarkColorScheme
- else -> LightColorScheme
+ else -> {
+ val accent = accentColor ?: defaultAccentColor.hexToColor()
+ val blendColor = if (darkTheme) android.graphics.Color.WHITE else android.graphics.Color.BLACK
+ val onPrimary = Color(ColorUtils.blendARGB(accent.toArgb(), blendColor, 0.3f))
+ if (darkTheme) darkColorScheme(accent, onPrimary, secondary = onPrimary) else lightColorScheme(
+ accent,
+ onPrimary,
+ secondary = onPrimary
+ )
+ }
}
val view = LocalView.current
diff --git a/app/src/main/java/com/bnyro/translate/util/Preferences.kt b/app/src/main/java/com/bnyro/translate/util/Preferences.kt
index 04c5ec61f..da28be03b 100644
--- a/app/src/main/java/com/bnyro/translate/util/Preferences.kt
+++ b/app/src/main/java/com/bnyro/translate/util/Preferences.kt
@@ -19,10 +19,11 @@ object Preferences {
const val tessLanguageKey = "tessLanguage"
const val themeModeKey = "themeMode"
+ const val accentColorKey = "accentColor"
const val sourceLanguage = "sourceLanguage"
const val targetLanguage = "targetLanguage"
- private lateinit var prefs: SharedPreferences
+ lateinit var prefs: SharedPreferences
fun initialize(context: Context) {
prefs = context.getSharedPreferences(
@@ -52,10 +53,7 @@ object Preferences {
}
}
- fun getThemeMode(): Int {
- return get(
- themeModeKey,
- ThemeMode.AUTO.toString()
- ).toInt()
- }
+ fun getThemeMode() = get(themeModeKey, ThemeMode.AUTO.toString()).toInt()
+
+ fun getAccentColor() = prefs.getString(accentColorKey, null)
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9732a5a78..ee6bd65eb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -55,6 +55,8 @@
System
Light
Dark
+ Accent color
+ Dynamic colors
Clear history
Open