Skip to content

Commit 602cc55

Browse files
Sirpixelalotclaude
andcommitted
Update to version 1.5 with dropdown menu positioning fix
- Fix theme toggle dropdown menu positioning in TopAppBar - Menu now correctly appears near the button instead of bottom-left corner - Moved dropdown menu logic to ThemeMenuButton composable with proper anchoring - Simplified MainActivity.kt by delegating menu handling to MainComposables.kt 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ebf1d37 commit 602cc55

File tree

4 files changed

+119
-16
lines changed

4 files changed

+119
-16
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ android {
2020
applicationId "com.renpytool"
2121
minSdk 33
2222
targetSdk 34
23-
versionCode 4
24-
versionName "1.4"
23+
versionCode 5
24+
versionName "1.5"
2525

2626
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2727

app/src/main/java/com/renpytool/MainActivity.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ import androidx.activity.compose.setContent
1515
import androidx.activity.result.ActivityResultLauncher
1616
import androidx.activity.result.contract.ActivityResultContracts
1717
import androidx.activity.viewModels
18+
import androidx.compose.foundation.isSystemInDarkTheme
1819
import androidx.compose.foundation.layout.fillMaxSize
1920
import androidx.compose.runtime.Composable
2021
import androidx.compose.runtime.collectAsState
2122
import androidx.compose.runtime.getValue
2223
import androidx.compose.ui.Modifier
23-
import androidx.compose.ui.platform.LocalView
2424
import androidx.core.app.ActivityCompat
2525
import androidx.core.content.ContextCompat
2626
import androidx.lifecycle.lifecycleScope
@@ -71,7 +71,14 @@ class MainActivity : ComponentActivity() {
7171

7272
// Set up Compose UI
7373
setContent {
74-
RenpytoolTheme {
74+
val themeMode by viewModel.themeMode.collectAsState()
75+
val darkTheme = when (themeMode) {
76+
MainViewModel.ThemeMode.LIGHT -> false
77+
MainViewModel.ThemeMode.DARK -> true
78+
MainViewModel.ThemeMode.SYSTEM -> isSystemInDarkTheme()
79+
}
80+
81+
RenpytoolTheme(darkTheme = darkTheme) {
7582
MainScreen()
7683
}
7784
}
@@ -91,6 +98,7 @@ class MainActivity : ComponentActivity() {
9198
val decompileStatus by viewModel.decompileStatus.collectAsState()
9299
val editStatus by viewModel.editStatus.collectAsState()
93100
val cardsEnabled by viewModel.cardsEnabled.collectAsState()
101+
val themeMode by viewModel.themeMode.collectAsState()
94102

95103
MainScreenContent(
96104
extractStatus = extractStatus,
@@ -102,15 +110,12 @@ class MainActivity : ComponentActivity() {
102110
onCreateClick = { startCreateFlow() },
103111
onDecompileClick = { startDecompileFlow() },
104112
onEditClick = { startEditRpyFlow() },
105-
onMenuClick = { showOptionsMenu() },
113+
themeMode = themeMode,
114+
onThemeModeChange = { mode -> viewModel.setThemeMode(mode) },
106115
modifier = Modifier.fillMaxSize()
107116
)
108117
}
109118

110-
private fun showOptionsMenu() {
111-
// Placeholder for options menu - can add GitHub link, about, etc.
112-
Toast.makeText(this, "Menu", Toast.LENGTH_SHORT).show()
113-
}
114119

115120
private fun checkPermissions() {
116121
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

app/src/main/java/com/renpytool/MainViewModel.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,22 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
4848
private val _cardsEnabled = MutableStateFlow(true)
4949
val cardsEnabled: StateFlow<Boolean> = _cardsEnabled.asStateFlow()
5050

51+
// Theme mode state
52+
enum class ThemeMode {
53+
SYSTEM, LIGHT, DARK;
54+
55+
companion object {
56+
fun fromString(value: String): ThemeMode {
57+
return values().find { it.name == value } ?: SYSTEM
58+
}
59+
}
60+
}
61+
62+
private val _themeMode = MutableStateFlow(
63+
ThemeMode.fromString(prefs.getString("theme_mode", ThemeMode.SYSTEM.name) ?: ThemeMode.SYSTEM.name)
64+
)
65+
val themeMode: StateFlow<ThemeMode> = _themeMode.asStateFlow()
66+
5167
init {
5268
// Load edit status from SharedPreferences
5369
updateEditStatus()
@@ -535,4 +551,12 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
535551
}
536552
file.delete()
537553
}
554+
555+
/**
556+
* Set the theme mode and save to preferences
557+
*/
558+
fun setThemeMode(mode: ThemeMode) {
559+
_themeMode.value = mode
560+
prefs.edit().putString("theme_mode", mode.name).apply()
561+
}
538562
}

app/src/main/java/com/renpytool/ui/MainComposables.kt

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ package com.renpytool.ui
33
import androidx.compose.foundation.layout.*
44
import androidx.compose.material3.*
55
import androidx.compose.runtime.Composable
6+
import androidx.compose.runtime.getValue
7+
import androidx.compose.runtime.mutableStateOf
8+
import androidx.compose.runtime.remember
9+
import androidx.compose.runtime.setValue
610
import androidx.compose.ui.Alignment
711
import androidx.compose.ui.Modifier
812
import androidx.compose.ui.graphics.Color
@@ -87,20 +91,19 @@ fun MainScreenContent(
8791
onCreateClick: () -> Unit,
8892
onDecompileClick: () -> Unit,
8993
onEditClick: () -> Unit,
90-
onMenuClick: () -> Unit,
94+
themeMode: com.renpytool.MainViewModel.ThemeMode,
95+
onThemeModeChange: (com.renpytool.MainViewModel.ThemeMode) -> Unit,
9196
modifier: Modifier = Modifier
9297
) {
9398
Scaffold(
9499
topBar = {
95100
TopAppBar(
96101
title = { Text("Rentool") },
97102
actions = {
98-
IconButton(onClick = onMenuClick) {
99-
Icon(
100-
painter = painterResource(id = android.R.drawable.ic_menu_more),
101-
contentDescription = "Menu"
102-
)
103-
}
103+
ThemeMenuButton(
104+
themeMode = themeMode,
105+
onThemeModeChange = onThemeModeChange
106+
)
104107
},
105108
colors = TopAppBarDefaults.topAppBarColors(
106109
containerColor = MaterialTheme.colorScheme.surfaceContainer,
@@ -156,3 +159,74 @@ fun MainScreenContent(
156159
}
157160
}
158161
}
162+
163+
/**
164+
* Theme menu button with dropdown
165+
*/
166+
@Composable
167+
fun ThemeMenuButton(
168+
themeMode: com.renpytool.MainViewModel.ThemeMode,
169+
onThemeModeChange: (com.renpytool.MainViewModel.ThemeMode) -> Unit
170+
) {
171+
var menuExpanded by remember { mutableStateOf(false) }
172+
173+
Box {
174+
IconButton(onClick = { menuExpanded = true }) {
175+
Icon(
176+
painter = painterResource(id = android.R.drawable.ic_menu_more),
177+
contentDescription = "Menu"
178+
)
179+
}
180+
181+
DropdownMenu(
182+
expanded = menuExpanded,
183+
onDismissRequest = { menuExpanded = false }
184+
) {
185+
DropdownMenuItem(
186+
text = { Text("System Default") },
187+
onClick = {
188+
onThemeModeChange(com.renpytool.MainViewModel.ThemeMode.SYSTEM)
189+
menuExpanded = false
190+
},
191+
trailingIcon = {
192+
if (themeMode == com.renpytool.MainViewModel.ThemeMode.SYSTEM) {
193+
Icon(
194+
painter = painterResource(id = android.R.drawable.checkbox_on_background),
195+
contentDescription = null
196+
)
197+
}
198+
}
199+
)
200+
DropdownMenuItem(
201+
text = { Text("Light Mode") },
202+
onClick = {
203+
onThemeModeChange(com.renpytool.MainViewModel.ThemeMode.LIGHT)
204+
menuExpanded = false
205+
},
206+
trailingIcon = {
207+
if (themeMode == com.renpytool.MainViewModel.ThemeMode.LIGHT) {
208+
Icon(
209+
painter = painterResource(id = android.R.drawable.checkbox_on_background),
210+
contentDescription = null
211+
)
212+
}
213+
}
214+
)
215+
DropdownMenuItem(
216+
text = { Text("Dark Mode") },
217+
onClick = {
218+
onThemeModeChange(com.renpytool.MainViewModel.ThemeMode.DARK)
219+
menuExpanded = false
220+
},
221+
trailingIcon = {
222+
if (themeMode == com.renpytool.MainViewModel.ThemeMode.DARK) {
223+
Icon(
224+
painter = painterResource(id = android.R.drawable.checkbox_on_background),
225+
contentDescription = null
226+
)
227+
}
228+
}
229+
)
230+
}
231+
}
232+
}

0 commit comments

Comments
 (0)