Skip to content

Commit 2663db5

Browse files
committed
Introduce TrayAppState for improved state management and enhance tray integration
- Added `TrayAppState` to manage tray window visibility, size, and state callbacks. - Updated `TrayApp` to use `TrayAppState` for better programmatic control. - Enhanced demo with visibility toggles, size adjustments, and improved UI alignment. - Refactored `TrayApp` overloads to streamline handling of tray state and content rendering.
1 parent 0f1739d commit 2663db5

4 files changed

Lines changed: 345 additions & 120 deletions

File tree

demo/src/jvmMain/kotlin/com/kdroid/composetray/demo/TrayAppDemo.kt

Lines changed: 168 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ import androidx.compose.ui.window.application
1818
import androidx.compose.ui.window.rememberWindowState
1919
import com.kdroid.composetray.tray.api.ExperimentalTrayAppApi
2020
import com.kdroid.composetray.tray.api.TrayApp
21+
import com.kdroid.composetray.tray.api.rememberTrayAppState
2122
import com.kdroid.composetray.utils.WindowRaise
2223
import com.kdroid.composetray.utils.allowComposeNativeTrayLogging
2324
import composenativetray.demo.generated.resources.Res
2425
import composenativetray.demo.generated.resources.icon
2526
import io.github.kdroidfilter.platformtools.darkmodedetector.isSystemInDarkMode
2627
import io.github.kdroidfilter.platformtools.darkmodedetector.mac.setMacOsAdaptiveTitleBar
2728
import io.github.kdroidfilter.platformtools.darkmodedetector.windows.setWindowsAdaptiveTitleBar
29+
import kotlinx.coroutines.launch
2830
import org.jetbrains.compose.resources.painterResource
2931

3032
@OptIn(ExperimentalTrayAppApi::class)
@@ -34,20 +36,55 @@ fun main() {
3436
application {
3537
var isWindowVisible by remember { mutableStateOf(true) }
3638
var textFieldValue by remember { mutableStateOf("") }
37-
var textFieldValue2 by remember { mutableStateOf("") }
39+
val coroutineScope = rememberCoroutineScope()
40+
41+
// Create TrayAppState with initial settings
42+
val trayAppState = rememberTrayAppState(
43+
initialWindowSize = DpSize(300.dp, 500.dp),
44+
initiallyVisible = true
45+
)
46+
47+
// Observe visibility changes
48+
val isTrayPopupVisible by trayAppState.isVisible.collectAsState()
49+
50+
// Set up visibility change callback
51+
LaunchedEffect(trayAppState) {
52+
trayAppState.onVisibilityChanged { visible ->
53+
println("Tray popup visibility changed to: $visible")
54+
}
55+
}
3856

3957
TrayApp(
58+
state = trayAppState,
4059
icon = Icons.Default.Window,
4160
tooltip = "TrayAppDemo",
42-
windowSize = DpSize(300.dp, 500.dp),
43-
visibleOnStart = true,
4461
menu = {
4562
Item(
4663
if (isWindowVisible) "Hide the app" else "Open the App",
4764
onClick = {
4865
isWindowVisible = !isWindowVisible
4966
}
5067
)
68+
Divider()
69+
Item(
70+
if (isTrayPopupVisible) "Hide popup" else "Show popup",
71+
onClick = {
72+
trayAppState.toggle()
73+
}
74+
)
75+
Item(
76+
"Resize popup to 400x600",
77+
onClick = {
78+
trayAppState.setWindowSize(400.dp, 600.dp)
79+
}
80+
)
81+
Item(
82+
"Resize popup to 250x350",
83+
onClick = {
84+
trayAppState.setWindowSize(DpSize(250.dp, 350.dp))
85+
}
86+
)
87+
Divider()
5188
Item("Exit", onClick = { exitApplication() })
5289
}
5390
) {
@@ -63,19 +100,47 @@ fun main() {
63100
.padding(16.dp),
64101
contentAlignment = Center,
65102
) {
66-
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
67-
Text("Your futur awesome compagnon App !", color = MaterialTheme.colorScheme.onBackground)
103+
Column(
104+
verticalArrangement = Arrangement.spacedBy(8.dp),
105+
horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally
106+
) {
107+
Text("Tray Companion App", color = MaterialTheme.colorScheme.onBackground)
108+
68109
TextField(
69-
value = textFieldValue2,
70-
onValueChange = { textFieldValue2 = it },
71-
placeholder = { Text("Enter some text") }
110+
value = textFieldValue,
111+
onValueChange = { textFieldValue = it },
112+
placeholder = { Text("Enter some text") },
113+
modifier = Modifier.fillMaxWidth()
114+
)
115+
116+
Text(
117+
"Status: ${if (isTrayPopupVisible) "Visible" else "Hidden"}",
118+
style = MaterialTheme.typography.bodySmall,
119+
color = MaterialTheme.colorScheme.onBackground
72120
)
121+
122+
Row(
123+
horizontalArrangement = Arrangement.spacedBy(8.dp)
124+
) {
125+
Button(
126+
onClick = { trayAppState.hide() },
127+
enabled = isTrayPopupVisible
128+
) {
129+
Text("Hide")
130+
}
131+
132+
Button(
133+
onClick = { trayAppState.show() },
134+
enabled = !isTrayPopupVisible
135+
) {
136+
Text("Show")
137+
}
138+
}
73139
}
74140
}
75141
}
76142
}
77143

78-
79144
if (isWindowVisible) {
80145
val state = rememberWindowState()
81146

@@ -85,7 +150,6 @@ fun main() {
85150
title = "Main App",
86151
icon = painterResource(Res.drawable.icon),
87152
) {
88-
// Use Windows adaptive title bar when available
89153
window.setWindowsAdaptiveTitleBar()
90154

91155
MaterialTheme(
@@ -94,11 +158,101 @@ fun main() {
94158
Box(
95159
modifier = Modifier
96160
.fillMaxSize()
97-
.background(MaterialTheme.colorScheme.background),
161+
.background(MaterialTheme.colorScheme.background)
162+
.padding(16.dp),
98163
contentAlignment = Center,
99164
) {
100-
Column {
101-
Text("Your futur awesome Main App !", color = MaterialTheme.colorScheme.onBackground)
165+
Column(
166+
verticalArrangement = Arrangement.spacedBy(16.dp),
167+
horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally
168+
) {
169+
Text(
170+
"Main Application Window",
171+
style = MaterialTheme.typography.headlineMedium,
172+
color = MaterialTheme.colorScheme.onBackground
173+
)
174+
175+
Text(
176+
"Tray popup is: ${if (isTrayPopupVisible) "Visible" else "Hidden"}",
177+
color = MaterialTheme.colorScheme.onBackground
178+
)
179+
180+
Row(
181+
horizontalArrangement = Arrangement.spacedBy(8.dp)
182+
) {
183+
Button(
184+
onClick = {
185+
coroutineScope.launch {
186+
trayAppState.show()
187+
}
188+
}
189+
) {
190+
Text("Show Tray Popup")
191+
}
192+
193+
Button(
194+
onClick = {
195+
coroutineScope.launch {
196+
trayAppState.hide()
197+
}
198+
}
199+
) {
200+
Text("Hide Tray Popup")
201+
}
202+
203+
Button(
204+
onClick = {
205+
coroutineScope.launch {
206+
trayAppState.toggle()
207+
}
208+
}
209+
) {
210+
Text("Toggle Tray Popup")
211+
}
212+
}
213+
214+
Divider(modifier = Modifier.padding(vertical = 8.dp))
215+
216+
Text(
217+
"Window Size Controls",
218+
style = MaterialTheme.typography.titleMedium,
219+
color = MaterialTheme.colorScheme.onBackground
220+
)
221+
222+
Row(
223+
horizontalArrangement = Arrangement.spacedBy(8.dp)
224+
) {
225+
Button(
226+
onClick = {
227+
trayAppState.setWindowSize(250.dp, 400.dp)
228+
}
229+
) {
230+
Text("Small")
231+
}
232+
233+
Button(
234+
onClick = {
235+
trayAppState.setWindowSize(350.dp, 500.dp)
236+
}
237+
) {
238+
Text("Medium")
239+
}
240+
241+
Button(
242+
onClick = {
243+
trayAppState.setWindowSize(450.dp, 600.dp)
244+
}
245+
) {
246+
Text("Large")
247+
}
248+
}
249+
250+
val windowSize by trayAppState.windowSize.collectAsState()
251+
Text(
252+
"Current popup size: ${windowSize.width.value.toInt()} x ${windowSize.height.value.toInt()} dp",
253+
style = MaterialTheme.typography.bodySmall,
254+
color = MaterialTheme.colorScheme.onBackground
255+
)
102256
}
103257
}
104258

@@ -112,4 +266,4 @@ fun main() {
112266
}
113267
}
114268
}
115-
}
269+
}

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
kermit = "2.0.8"
33
kotlin = "2.2.20"
44
kotlinx-coroutines = "1.10.2"
5-
compose = "1.8.0"
5+
compose = "1.9.0"
66
jna = "5.18.0"
77
platformtools = "0.6.2"
88

0 commit comments

Comments
 (0)