feat: 浅色主题适配,白字/金字自动切换为深色字/暗蓝字,覆盖全界面

This commit is contained in:
flykhan 2026-04-26 23:18:10 +08:00
parent 33dad2192a
commit 6bf797e2a9
14 changed files with 103 additions and 95 deletions

View File

@ -11,6 +11,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavBackStackEntry import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavType import androidx.navigation.NavType
@ -195,7 +196,9 @@ fun UnoApp() {
CompositionLocalProvider( CompositionLocalProvider(
LocalCardTheme provides cardTheme, LocalCardTheme provides cardTheme,
LocalTableBg provides tableBg, LocalTableBg provides tableBg,
LocalCardScale provides cardScale LocalCardScale provides cardScale,
LocalTextOnTable provides if (tableBg.isDark) Color.White else Color(0xFF222222),
LocalAccentOnTable provides if (tableBg.isDark) GoldAccent else Color(0xFF1A237E)
) { ) {
val enterAnim: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) = { val enterAnim: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) = {
fadeIn(animationSpec = tween(300)) + slideInHorizontally(animationSpec = tween(350)) { it / 4 } fadeIn(animationSpec = tween(300)) + slideInHorizontally(animationSpec = tween(350)) { it / 4 }

View File

@ -15,6 +15,7 @@ import androidx.compose.ui.unit.sp
import com.unogame.model.Card import com.unogame.model.Card
import com.unogame.model.CardColor import com.unogame.model.CardColor
import com.unogame.ui.theme.LocalCardScale import com.unogame.ui.theme.LocalCardScale
import com.unogame.ui.theme.LocalTextOnTable
@Composable @Composable
fun PlayerHand( fun PlayerHand(
@ -31,7 +32,7 @@ fun PlayerHand(
Column(modifier = modifier) { Column(modifier = modifier) {
Text( Text(
"你的手牌 (${cards.size})", "你的手牌 (${cards.size})",
color = Color.White.copy(alpha = 0.7f), color = LocalTextOnTable.current.copy(alpha = 0.7f),
fontSize = 14.sp, fontSize = 14.sp,
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = 8.dp)
) )

View File

@ -55,7 +55,7 @@ fun GameOverScreen(
text = if (isYouWinner) "恭喜你赢了!" else "游戏结束", text = if (isYouWinner) "恭喜你赢了!" else "游戏结束",
fontSize = 36.sp, fontSize = 36.sp,
fontWeight = FontWeight.Black, fontWeight = FontWeight.Black,
color = GoldAccent, color = LocalAccentOnTable.current,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
@ -64,7 +64,7 @@ fun GameOverScreen(
Text( Text(
text = if (isYouWinner) "你是UNO冠军" else "$winnerName 赢得了比赛", text = if (isYouWinner) "你是UNO冠军" else "$winnerName 赢得了比赛",
fontSize = 18.sp, fontSize = 18.sp,
color = Color.White.copy(alpha = 0.8f), color = LocalTextOnTable.current.copy(alpha = 0.8f),
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
@ -74,7 +74,7 @@ fun GameOverScreen(
text = "+$points", text = "+$points",
fontSize = 32.sp, fontSize = 32.sp,
fontWeight = FontWeight.Black, fontWeight = FontWeight.Black,
color = GoldAccent color = LocalAccentOnTable.current
) )
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
Row( Row(
@ -82,20 +82,20 @@ fun GameOverScreen(
horizontalArrangement = Arrangement.SpaceEvenly horizontalArrangement = Arrangement.SpaceEvenly
) { ) {
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("难度", color = Color.White.copy(alpha = 0.5f), fontSize = 12.sp) Text("难度", color = LocalTextOnTable.current.copy(alpha = 0.5f), fontSize = 12.sp)
Text(difficulty, color = Color.White, fontSize = 14.sp, fontWeight = FontWeight.Bold) Text(difficulty, color = LocalTextOnTable.current, fontSize = 14.sp, fontWeight = FontWeight.Bold)
} }
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("时长", color = Color.White.copy(alpha = 0.5f), fontSize = 12.sp) Text("时长", color = LocalTextOnTable.current.copy(alpha = 0.5f), fontSize = 12.sp)
Text(durationText, color = Color.White, fontSize = 14.sp, fontWeight = FontWeight.Bold) Text(durationText, color = LocalTextOnTable.current, fontSize = 14.sp, fontWeight = FontWeight.Bold)
} }
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("人数", color = Color.White.copy(alpha = 0.5f), fontSize = 12.sp) Text("人数", color = LocalTextOnTable.current.copy(alpha = 0.5f), fontSize = 12.sp)
Text("${playerCount}", color = Color.White, fontSize = 14.sp, fontWeight = FontWeight.Bold) Text("${playerCount}", color = LocalTextOnTable.current, fontSize = 14.sp, fontWeight = FontWeight.Bold)
} }
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("轮次", color = Color.White.copy(alpha = 0.5f), fontSize = 12.sp) Text("轮次", color = LocalTextOnTable.current.copy(alpha = 0.5f), fontSize = 12.sp)
Text("$turnNumber", color = Color.White, fontSize = 14.sp, fontWeight = FontWeight.Bold) Text("$turnNumber", color = LocalTextOnTable.current, fontSize = 14.sp, fontWeight = FontWeight.Bold)
} }
} }
} }

View File

@ -112,7 +112,7 @@ fun GameScreen(
) { ) {
Text( Text(
"方向: ${if (gameState.direction == 1) "→ 顺时" else "← 逆时"}", "方向: ${if (gameState.direction == 1) "→ 顺时" else "← 逆时"}",
color = Color.White.copy(alpha = 0.6f), color = LocalTextOnTable.current.copy(alpha = 0.6f),
fontSize = 14.sp fontSize = 14.sp
) )
if (flipped) { if (flipped) {
@ -125,7 +125,7 @@ fun GameScreen(
} }
Text( Text(
"牌堆: ${gameState.drawPileCount}", "牌堆: ${gameState.drawPileCount}",
color = Color.White.copy(alpha = 0.6f), color = LocalTextOnTable.current.copy(alpha = 0.6f),
fontSize = 14.sp fontSize = 14.sp
) )
} }
@ -200,7 +200,7 @@ fun GameScreen(
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
Text( Text(
"摸牌", "摸牌",
color = if (isMyTurn) GoldAccent else Color.Gray, color = if (isMyTurn) LocalAccentOnTable.current else LocalTextOnTable.current.copy(alpha = 0.5f),
fontSize = 12.sp fontSize = 12.sp
) )
} }
@ -208,7 +208,7 @@ fun GameScreen(
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text( Text(
text = "当前弃牌堆", text = "当前弃牌堆",
color = Color.White.copy(alpha = 0.5f), color = LocalTextOnTable.current.copy(alpha = 0.5f),
fontSize = 12.sp fontSize = 12.sp
) )
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
@ -242,7 +242,7 @@ fun GameScreen(
Text( Text(
if (isMyTurn) "⚠ 你必须摸 ${gameState.pendingDrawCount} 张牌" if (isMyTurn) "⚠ 你必须摸 ${gameState.pendingDrawCount} 张牌"
else "下家需摸 ${gameState.pendingDrawCount} 张牌", else "下家需摸 ${gameState.pendingDrawCount} 张牌",
color = if (isMyTurn) UnoRed else Color.White.copy(alpha = 0.6f), color = if (isMyTurn) UnoRed else LocalTextOnTable.current.copy(alpha = 0.6f),
fontSize = 14.sp, fontSize = 14.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
@ -253,7 +253,7 @@ fun GameScreen(
// Current turn indicator // Current turn indicator
Text( Text(
text = if (isMyTurn) "轮到你了!" else "等待: ${currentPlayer.name}", text = if (isMyTurn) "轮到你了!" else "等待: ${currentPlayer.name}",
color = if (isMyTurn) GoldAccent else Color.White.copy(alpha = 0.6f), color = if (isMyTurn) LocalAccentOnTable.current else LocalTextOnTable.current.copy(alpha = 0.6f),
fontSize = 18.sp, fontSize = 18.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,

View File

@ -33,9 +33,9 @@ fun LobbyMenuScreen(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White) Icon(Icons.Default.ArrowBack, "返回", tint = LocalTextOnTable.current)
} }
Text("联机模式", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White) Text("联机模式", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = LocalTextOnTable.current)
} }
Spacer(modifier = Modifier.height(40.dp)) Spacer(modifier = Modifier.height(40.dp))

View File

@ -58,17 +58,17 @@ fun LobbyScreen(
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White) Icon(Icons.Default.ArrowBack, "返回", tint = LocalTextOnTable.current)
} }
Text( Text(
text = if (isHost) "房间大厅" else "加入游戏", text = if (isHost) "房间大厅" else "加入游戏",
fontSize = 24.sp, fontSize = 24.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = Color.White color = LocalTextOnTable.current
) )
Text( Text(
text = if (isHost) "房主" else "玩家", text = if (isHost) "房主" else "玩家",
color = GoldAccent color = LocalAccentOnTable.current
) )
} }
@ -94,14 +94,14 @@ fun LobbyScreen(
// Host lobby // Host lobby
Text( Text(
text = "等待玩家加入... (${players.size}/10)", text = "等待玩家加入... (${players.size}/10)",
color = Color.White.copy(alpha = 0.7f), color = LocalTextOnTable.current.copy(alpha = 0.7f),
fontSize = 16.sp fontSize = 16.sp
) )
if (hostIp.isNotEmpty()) { if (hostIp.isNotEmpty()) {
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
Text( Text(
text = "你的IP: $hostIp告诉朋友用此IP连接", text = "你的IP: $hostIp告诉朋友用此IP连接",
color = GoldAccent.copy(alpha = 0.8f), color = LocalAccentOnTable.current.copy(alpha = 0.8f),
fontSize = 13.sp fontSize = 13.sp
) )
} }
@ -110,7 +110,7 @@ fun LobbyScreen(
if (players.isNotEmpty()) { if (players.isNotEmpty()) {
Text( Text(
"玩家列表", "玩家列表",
color = Color.White.copy(alpha = 0.6f), color = LocalTextOnTable.current.copy(alpha = 0.6f),
fontSize = 14.sp fontSize = 14.sp
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@ -134,7 +134,7 @@ fun LobbyScreen(
) { ) {
Text( Text(
"附近房间", "附近房间",
color = Color.White, color = LocalTextOnTable.current,
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
@ -157,7 +157,7 @@ fun LobbyScreen(
if (discoveredHosts.isEmpty() && !isDiscovering) { if (discoveredHosts.isEmpty() && !isDiscovering) {
Text( Text(
"没有发现房间请确保在同一WiFi下并点刷新", "没有发现房间请确保在同一WiFi下并点刷新",
color = Color.White.copy(alpha = 0.5f), color = LocalTextOnTable.current.copy(alpha = 0.5f),
fontSize = 14.sp fontSize = 14.sp
) )
} else { } else {
@ -212,7 +212,7 @@ fun LobbyScreen(
var manualIp by remember { mutableStateOf("") } var manualIp by remember { mutableStateOf("") }
Text( Text(
"手动连接输入房主IP", "手动连接输入房主IP",
color = Color.White.copy(alpha = 0.6f), color = LocalTextOnTable.current.copy(alpha = 0.6f),
fontSize = 13.sp fontSize = 13.sp
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@ -256,14 +256,14 @@ fun LobbyScreen(
// Connected to host, waiting for game start // Connected to host, waiting for game start
Text( Text(
"已连接到主机", "已连接到主机",
color = GoldAccent, color = LocalAccentOnTable.current,
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
"等待房主开始游戏...", "等待房主开始游戏...",
color = Color.White.copy(alpha = 0.7f), color = LocalTextOnTable.current.copy(alpha = 0.7f),
fontSize = 14.sp fontSize = 14.sp
) )
@ -272,7 +272,7 @@ fun LobbyScreen(
if (players.isNotEmpty()) { if (players.isNotEmpty()) {
Text( Text(
"玩家列表", "玩家列表",
color = Color.White.copy(alpha = 0.6f), color = LocalTextOnTable.current.copy(alpha = 0.6f),
fontSize = 14.sp fontSize = 14.sp
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@ -298,7 +298,7 @@ fun LobbyScreen(
) { ) {
CircularProgressIndicator(color = GoldAccent) CircularProgressIndicator(color = GoldAccent)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text("正在连接...", color = Color.White.copy(alpha = 0.7f), fontSize = 14.sp) Text("正在连接...", color = LocalTextOnTable.current.copy(alpha = 0.7f), fontSize = 14.sp)
} }
} }

View File

@ -68,20 +68,20 @@ fun LocalSetupScreen(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White) Icon(Icons.Default.ArrowBack, "返回", tint = LocalTextOnTable.current)
} }
Text( Text(
"本地模式 - $modeDisplayName", "本地模式 - $modeDisplayName",
fontSize = 24.sp, fontSize = 24.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = Color.White color = LocalTextOnTable.current
) )
} }
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
// Player name // Player name
Text("你的名字", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("你的名字", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField( OutlinedTextField(
value = name, value = name,
@ -89,11 +89,11 @@ fun LocalSetupScreen(
singleLine = true, singleLine = true,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White, focusedTextColor = LocalTextOnTable.current,
unfocusedTextColor = Color.White, unfocusedTextColor = LocalTextOnTable.current,
focusedBorderColor = GoldAccent, focusedBorderColor = LocalAccentOnTable.current,
unfocusedBorderColor = Color.Gray, unfocusedBorderColor = Color.Gray,
cursorColor = GoldAccent cursorColor = LocalAccentOnTable.current
) )
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@ -106,7 +106,7 @@ fun LocalSetupScreen(
value = "", value = "",
onValueChange = {}, onValueChange = {},
readOnly = true, readOnly = true,
placeholder = { Text("或选择预设名字", color = Color.White.copy(alpha = 0.4f)) }, placeholder = { Text("或选择预设名字", color = LocalTextOnTable.current.copy(alpha = 0.4f)) },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = nameDropdownExpanded) }, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = nameDropdownExpanded) },
modifier = Modifier.fillMaxWidth().menuAnchor(), modifier = Modifier.fillMaxWidth().menuAnchor(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
@ -136,7 +136,7 @@ fun LocalSetupScreen(
Spacer(modifier = Modifier.height(28.dp)) Spacer(modifier = Modifier.height(28.dp))
// Player count selector // Player count selector
Text("总玩家数", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("总玩家数", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
Row( Row(
modifier = Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()), modifier = Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()),
@ -171,7 +171,7 @@ fun LocalSetupScreen(
Spacer(modifier = Modifier.height(28.dp)) Spacer(modifier = Modifier.height(28.dp))
// AI difficulty // AI difficulty
Text("AI难度", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("AI难度", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -189,7 +189,8 @@ fun LocalSetupScreen(
com.unogame.game.AIDifficulty.NORMAL -> GoldAccent com.unogame.game.AIDifficulty.NORMAL -> GoldAccent
com.unogame.game.AIDifficulty.HARD -> UnoRed com.unogame.game.AIDifficulty.HARD -> UnoRed
}, },
selectedLabelColor = Color.Black selectedLabelColor = Color.Black,
labelColor = LocalTextOnTable.current
) )
) )
} }
@ -198,7 +199,7 @@ fun LocalSetupScreen(
Spacer(modifier = Modifier.height(28.dp)) Spacer(modifier = Modifier.height(28.dp))
// Hand size limit // Hand size limit
Text("手牌上限", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("手牌上限", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -218,7 +219,7 @@ fun LocalSetupScreen(
) )
Text( Text(
text = if (maxHandSize == 0) "无限制" else "${maxHandSize}", text = if (maxHandSize == 0) "无限制" else "${maxHandSize}",
color = GoldAccent, color = LocalAccentOnTable.current,
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
modifier = Modifier.width(56.dp) modifier = Modifier.width(56.dp)
@ -226,14 +227,14 @@ fun LocalSetupScreen(
} }
Text( Text(
"0 = 无限制默认各模式不限制无情模式默认10张上限", "0 = 无限制默认各模式不限制无情模式默认10张上限",
color = Color.White.copy(alpha = 0.35f), color = LocalTextOnTable.current.copy(alpha = 0.35f),
fontSize = 11.sp fontSize = 11.sp
) )
Spacer(modifier = Modifier.height(28.dp)) Spacer(modifier = Modifier.height(28.dp))
// Player list preview // Player list preview
Text("参与者预览", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("参与者预览", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
// You // You
@ -336,7 +337,7 @@ fun LocalSetupScreen(
) { ) {
Text( Text(
"• 1位真人 + ${totalPlayers - 1}个机器人\n• 支持2-8人局\n• 机器人会自动出牌,无需等待", "• 1位真人 + ${totalPlayers - 1}个机器人\n• 支持2-8人局\n• 机器人会自动出牌,无需等待",
color = Color.White.copy(alpha = 0.5f), color = LocalTextOnTable.current.copy(alpha = 0.5f),
fontSize = 12.sp, fontSize = 12.sp,
lineHeight = 20.sp, lineHeight = 20.sp,
modifier = Modifier.padding(16.dp) modifier = Modifier.padding(16.dp)

View File

@ -44,13 +44,13 @@ fun MainMenuScreen(
text = "UNO", text = "UNO",
fontSize = 72.sp, fontSize = 72.sp,
fontWeight = FontWeight.Black, fontWeight = FontWeight.Black,
color = GoldAccent, color = LocalAccentOnTable.current,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
Text( Text(
text = "卡牌游戏", text = "卡牌游戏",
fontSize = 18.sp, fontSize = 18.sp,
color = Color.White.copy(alpha = 0.6f), color = LocalTextOnTable.current.copy(alpha = 0.6f),
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )

View File

@ -36,13 +36,13 @@ fun ModeSelectScreen(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White) Icon(Icons.Default.ArrowBack, "返回", tint = LocalTextOnTable.current)
} }
Text("选择模式", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White) Text("选择模式", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = LocalTextOnTable.current)
} }
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text("玩家: $playerName", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("玩家: $playerName", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))

View File

@ -34,9 +34,9 @@ fun RulesHelpScreen(onBack: () -> Unit) {
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White) Icon(Icons.Default.ArrowBack, "返回", tint = LocalTextOnTable.current)
} }
Text("详细规则", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White) Text("详细规则", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = LocalTextOnTable.current)
} }
SpacerH(20) SpacerH(20)

View File

@ -102,12 +102,12 @@ fun ScoreboardScreen(onBack: () -> Unit) {
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White) Icon(Icons.Default.ArrowBack, "返回", tint = LocalTextOnTable.current)
} }
Text("积分排行榜", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White, modifier = Modifier.weight(1f)) Text("积分排行榜", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = LocalTextOnTable.current, modifier = Modifier.weight(1f))
Box { Box {
IconButton(onClick = { showMenu = true }) { IconButton(onClick = { showMenu = true }) {
Icon(Icons.Default.MoreVert, "菜单", tint = Color.White) Icon(Icons.Default.MoreVert, "菜单", tint = LocalTextOnTable.current)
} }
DropdownMenu( DropdownMenu(
expanded = showMenu, expanded = showMenu,

View File

@ -66,15 +66,15 @@ fun SettingsScreen(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White) Icon(Icons.Default.ArrowBack, "返回", tint = LocalTextOnTable.current)
} }
Text("游戏设置", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White) Text("游戏设置", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = LocalTextOnTable.current)
} }
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
// Nickname // Nickname
Text("你的昵称", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("你的昵称", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField( OutlinedTextField(
value = playerName, value = playerName,
@ -85,11 +85,11 @@ fun SettingsScreen(
singleLine = true, singleLine = true,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White, focusedTextColor = LocalTextOnTable.current,
unfocusedTextColor = Color.White, unfocusedTextColor = LocalTextOnTable.current,
focusedBorderColor = GoldAccent, focusedBorderColor = LocalAccentOnTable.current,
unfocusedBorderColor = Color.Gray, unfocusedBorderColor = Color.Gray,
cursorColor = GoldAccent cursorColor = LocalAccentOnTable.current
) )
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@ -102,15 +102,15 @@ fun SettingsScreen(
value = "", value = "",
onValueChange = {}, onValueChange = {},
readOnly = true, readOnly = true,
placeholder = { Text("或选择预设名字", color = Color.White.copy(alpha = 0.4f)) }, placeholder = { Text("或选择预设名字", color = LocalTextOnTable.current.copy(alpha = 0.4f)) },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = nameDropdownExpanded) }, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = nameDropdownExpanded) },
modifier = Modifier.fillMaxWidth().menuAnchor(), modifier = Modifier.fillMaxWidth().menuAnchor(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White, focusedTextColor = LocalTextOnTable.current,
unfocusedTextColor = Color.White, unfocusedTextColor = LocalTextOnTable.current,
focusedBorderColor = GoldAccent, focusedBorderColor = LocalAccentOnTable.current,
unfocusedBorderColor = Color.Gray, unfocusedBorderColor = Color.Gray,
cursorColor = GoldAccent cursorColor = LocalAccentOnTable.current
) )
) )
ExposedDropdownMenu( ExposedDropdownMenu(
@ -133,7 +133,7 @@ fun SettingsScreen(
Spacer(modifier = Modifier.height(28.dp)) Spacer(modifier = Modifier.height(28.dp))
// Appearance // Appearance
Text("外观设置", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("外观设置", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
// Card theme dropdown // Card theme dropdown
@ -149,13 +149,13 @@ fun SettingsScreen(
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = themeExpanded) }, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = themeExpanded) },
modifier = Modifier.fillMaxWidth().menuAnchor(), modifier = Modifier.fillMaxWidth().menuAnchor(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White, focusedTextColor = LocalTextOnTable.current,
unfocusedTextColor = Color.White, unfocusedTextColor = LocalTextOnTable.current,
focusedLabelColor = GoldAccent, focusedLabelColor = LocalAccentOnTable.current,
unfocusedLabelColor = Color.White.copy(alpha = 0.6f), unfocusedLabelColor = LocalTextOnTable.current.copy(alpha = 0.6f),
focusedBorderColor = GoldAccent, focusedBorderColor = LocalAccentOnTable.current,
unfocusedBorderColor = Color.Gray, unfocusedBorderColor = Color.Gray,
cursorColor = GoldAccent cursorColor = LocalAccentOnTable.current
) )
) )
ExposedDropdownMenu( ExposedDropdownMenu(
@ -195,13 +195,13 @@ fun SettingsScreen(
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = bgExpanded) }, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = bgExpanded) },
modifier = Modifier.fillMaxWidth().menuAnchor(), modifier = Modifier.fillMaxWidth().menuAnchor(),
colors = OutlinedTextFieldDefaults.colors( colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White, focusedTextColor = LocalTextOnTable.current,
unfocusedTextColor = Color.White, unfocusedTextColor = LocalTextOnTable.current,
focusedLabelColor = GoldAccent, focusedLabelColor = LocalAccentOnTable.current,
unfocusedLabelColor = Color.White.copy(alpha = 0.6f), unfocusedLabelColor = LocalTextOnTable.current.copy(alpha = 0.6f),
focusedBorderColor = GoldAccent, focusedBorderColor = LocalAccentOnTable.current,
unfocusedBorderColor = Color.Gray, unfocusedBorderColor = Color.Gray,
cursorColor = GoldAccent cursorColor = LocalAccentOnTable.current
) )
) )
ExposedDropdownMenu( ExposedDropdownMenu(
@ -273,7 +273,7 @@ fun SettingsScreen(
Spacer(modifier = Modifier.height(28.dp)) Spacer(modifier = Modifier.height(28.dp))
// About // About
Text("其他", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp) Text("其他", color = LocalTextOnTable.current.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
SettingsRow( SettingsRow(
icon = Icons.Default.Info, icon = Icons.Default.Info,

View File

@ -3,14 +3,14 @@ package com.unogame.ui.theme
import android.content.Context import android.content.Context
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
enum class TableBg(val displayName: String, val color: Color) { enum class TableBg(val displayName: String, val color: Color, val isDark: Boolean = true) {
DARK("暗黑", Color(0xFF121212)), DARK("暗黑", Color(0xFF121212), true),
GREEN("墨绿", Color(0xFF1A3C2A)), GREEN("墨绿", Color(0xFF1A3C2A), true),
BLUE("深蓝", Color(0xFF0D1B2A)), BLUE("深蓝", Color(0xFF0D1B2A), true),
PURPLE("暗紫", Color(0xFF1A1035)), WARM("暖米", Color(0xFFF5F0E8), false),
RED("酒红", Color(0xFF2D1111)), SKY("晴空", Color(0xFFE3F0F5), false),
TEAL("深青", Color(0xFF0D2B2A)), MINT("薄荷", Color(0xFFE8F5EC), false),
CHARCOAL("炭灰", Color(0xFF1E1E1E)); ROSE("浅玫", Color(0xFFF5ECF0), false);
companion object { companion object {
private const val KEY = "table_bg" private const val KEY = "table_bg"

View File

@ -2,10 +2,13 @@ package com.unogame.ui.theme
import android.content.Context import android.content.Context
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.graphics.Color
val LocalCardTheme = compositionLocalOf { CardTheme.ELEGANT } val LocalCardTheme = compositionLocalOf { CardTheme.ELEGANT }
val LocalTableBg = compositionLocalOf { TableBg.GREEN } val LocalTableBg = compositionLocalOf { TableBg.GREEN }
val LocalCardScale = compositionLocalOf { 1.0f } val LocalCardScale = compositionLocalOf { 1.0f }
val LocalTextOnTable = compositionLocalOf { Color.White }
val LocalAccentOnTable = compositionLocalOf { GoldAccent }
// 手牌缩放0.5 ~ 1.3,默认 1.0(原始大小) // 手牌缩放0.5 ~ 1.3,默认 1.0(原始大小)
fun loadCardScale(context: Context): Float { fun loadCardScale(context: Context): Float {