Skip to content

Commit e0b65b8

Browse files
author
sentinelweb
committed
#489 system tray icon for player
1 parent 896d402 commit e0b65b8

File tree

6 files changed

+225
-2
lines changed

6 files changed

+225
-2
lines changed

hub/src/main/kotlin/uk/co/sentinelweb/cuer/hub/main/Main.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import uk.co.sentinelweb.cuer.core.wrapper.WifiStateProvider
88
import uk.co.sentinelweb.cuer.hub.di.Modules
99
import uk.co.sentinelweb.cuer.hub.ui.home.HomeUiCoordinator
1010
import uk.co.sentinelweb.cuer.hub.ui.home.home
11-
import uk.co.sentinelweb.cuer.hub.util.JarJnaCheck
1211
import uk.co.sentinelweb.cuer.hub.util.remote.KeyStoreManager
1312
import uk.co.sentinelweb.cuer.hub.util.remote.RemoteConfigFileInitialiseer
13+
import uk.co.sentinelweb.cuer.hub.util.system_tray.ComposePopup
14+
import uk.co.sentinelweb.cuer.hub.util.system_tray.createTrayIcon
15+
import uk.co.sentinelweb.cuer.hub.util.system_tray.createTrayIconSimple
16+
import java.awt.SystemTray
1417

1518
fun main() {
1619

@@ -22,6 +25,14 @@ fun main() {
2225

2326
koin.get<RemoteConfigFileInitialiseer>()
2427
.apply { initIfNecessary() }
28+
//println("SystemTray.isSupported() = ${SystemTray.isSupported()}")
29+
if (SystemTray.isSupported()) {
30+
// createTrayIconSimple()
31+
javax.swing.SwingUtilities.invokeLater {
32+
val composePopup = ComposePopup()
33+
createTrayIcon(composePopup)
34+
}
35+
}
2536

2637
val databaseInit = koin.get<DatabaseInitializer>()
2738
if (!databaseInit.isInitialized()) {

hub/src/main/kotlin/uk/co/sentinelweb/cuer/hub/ui/home/HomeUiCoordinator.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,9 @@ class HomeUiCoordinator(
132132
@JvmStatic
133133
val uiModule = module {
134134
single { HomeUiCoordinator(get()) }
135-
factory<PlayerLaunchHost> { get<HomeUiCoordinator>() } // injects to webserver
135+
factory<PlayerLaunchHost> { get<HomeUiCoordinator>() }
136136
scope(named<HomeUiCoordinator>()) {
137+
137138
}
138139
}
139140
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package uk.co.sentinelweb.cuer.hub.util.system_tray
2+
3+
import androidx.compose.ui.awt.ComposePanel
4+
import uk.co.sentinelweb.cuer.hub.util.system_tray.SystemTrayPopup.CustomPopupContent
5+
import java.awt.BorderLayout
6+
import java.awt.Dimension
7+
import java.awt.Toolkit
8+
import javax.swing.JFrame
9+
10+
class ComposePopup : JFrame() {
11+
12+
init {
13+
defaultCloseOperation = HIDE_ON_CLOSE
14+
isAlwaysOnTop = true
15+
setUndecorated(true)
16+
size = Dimension(260, 50)
17+
layout = BorderLayout()
18+
19+
// Create Compose Panel
20+
val composePanel = ComposePanel()
21+
22+
// Set Compose content
23+
composePanel.setContent {
24+
CustomPopupContent {
25+
// Close the popup when the close button is clicked
26+
hidePopup()
27+
}
28+
}
29+
30+
add(composePanel, BorderLayout.CENTER)
31+
positionAtTopRight()
32+
// Hide initially
33+
isVisible = false
34+
}
35+
36+
fun showPopup() {
37+
isVisible = true
38+
}
39+
40+
fun hidePopup() {
41+
isVisible = false
42+
}
43+
44+
private fun positionAtTopRight() {
45+
val screenSize = Toolkit.getDefaultToolkit().screenSize
46+
setLocation(screenSize.width - width - 20, 20)
47+
}
48+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package uk.co.sentinelweb.cuer.hub.util.system_tray
2+
3+
import androidx.compose.foundation.layout.Row
4+
import androidx.compose.material.Button
5+
import androidx.compose.material.Text
6+
import androidx.compose.runtime.Composable
7+
import org.koin.core.component.KoinComponent
8+
import uk.co.sentinelweb.cuer.app.ui.common.compose.CuerSharedTheme
9+
import java.awt.SystemTray
10+
11+
object SystemTrayPopup: KoinComponent {
12+
@Composable
13+
fun CustomPopupContent(onClose: () -> Unit) {
14+
CuerSharedTheme {
15+
Row {
16+
Button(onClick = { println("Play clicked") }) {
17+
Text("")
18+
}
19+
Button(onClick = { println("Pause clicked") }) {
20+
Text("️⏸")
21+
}
22+
Button(onClick = { println("Stop clicked") }) {
23+
Text("🛑")
24+
}
25+
Button(onClick = { onClose() }) {
26+
Text("")
27+
}
28+
}
29+
}
30+
}
31+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package uk.co.sentinelweb.cuer.hub.util.system_tray
2+
3+
import androidx.compose.ui.graphics.Color.Companion.White
4+
import loadSVG
5+
import java.awt.SystemTray
6+
import java.awt.Toolkit
7+
import java.awt.TrayIcon
8+
import java.awt.event.MouseEvent
9+
import java.awt.event.MouseListener
10+
import java.io.File
11+
import javax.imageio.ImageIO
12+
13+
fun createTrayIcon(popup: ComposePopup) {
14+
if (!SystemTray.isSupported()) {
15+
println("System tray is not supported")
16+
return
17+
}
18+
19+
try {
20+
// Load an image for the tray icon
21+
val trayIconImage = loadSVG("drawable/ic_launcher_yin_yang.svg", White, 24)
22+
23+
//val trayIconImage = ImageIO.read(File("path/to/icon.png"))
24+
val trayIcon = TrayIcon(trayIconImage, "Cuer")
25+
26+
// Set the auto-size option to true
27+
trayIcon.isImageAutoSize = true
28+
29+
trayIcon.addMouseListener(object : MouseListener {
30+
override fun mouseClicked(e: MouseEvent?) {
31+
println("mouseClicked: popup.isVisible= ${popup.isVisible}")
32+
if (popup.isVisible) {
33+
popup.hidePopup()
34+
} else {
35+
popup.showPopup()
36+
}
37+
}
38+
39+
override fun mousePressed(e: MouseEvent?) {
40+
println("mousePressed")
41+
}
42+
43+
override fun mouseReleased(e: MouseEvent?) {
44+
println("mouseReleased")
45+
}
46+
47+
override fun mouseEntered(e: MouseEvent?) {
48+
println("mouseEntered")
49+
}
50+
51+
override fun mouseExited(e: MouseEvent?) {
52+
println("mouseExited")
53+
}
54+
55+
})
56+
57+
// Get the system tray instance
58+
val systemTray = SystemTray.getSystemTray()
59+
60+
// Add the tray icon to the system tray
61+
systemTray.add(trayIcon)
62+
63+
} catch (e: Exception) {
64+
e.printStackTrace()
65+
}
66+
}
67+
68+
fun main() {
69+
javax.swing.SwingUtilities.invokeLater {
70+
val composePopup = ComposePopup()
71+
createTrayIcon(composePopup)
72+
}
73+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package uk.co.sentinelweb.cuer.hub.util.system_tray
2+
3+
import androidx.compose.ui.graphics.Color.Companion.White
4+
import loadSVG
5+
import java.awt.*
6+
7+
fun checkSystemTraySupport(): Boolean {
8+
return SystemTray.isSupported()
9+
}
10+
11+
fun createTrayIconSimple() {
12+
if (!SystemTray.isSupported()) {
13+
println("System tray is not supported")
14+
return
15+
}
16+
17+
try {
18+
// Load an image for the tray icon
19+
val trayIconImage = loadSVG("drawable/ic_launcher_yin_yang.svg", White, 24)
20+
21+
//val trayIconImage = ImageIO.read(File("path/to/icon.png"))
22+
val trayIcon = TrayIcon(trayIconImage, "Cuer")
23+
24+
// Set the auto-size option to true
25+
trayIcon.isImageAutoSize = true
26+
27+
// Create a popup menu
28+
val popup = PopupMenu()
29+
30+
// Create menu items
31+
val openItem = MenuItem("Open")
32+
val exitItem = MenuItem("Exit")
33+
34+
// Add action listeners to the menu items
35+
openItem.addActionListener {
36+
println("Open option selected")
37+
}
38+
39+
exitItem.addActionListener {
40+
System.exit(0)
41+
}
42+
43+
// Add items to the popup menu
44+
popup.add(openItem)
45+
popup.add(exitItem)
46+
47+
// Assign popup menu to the tray icon
48+
trayIcon.popupMenu = popup
49+
50+
// Get the system tray instance
51+
val systemTray = SystemTray.getSystemTray()
52+
53+
// Add the tray icon to the system tray
54+
systemTray.add(trayIcon)
55+
56+
} catch (e: Exception) {
57+
e.printStackTrace()
58+
}
59+
}

0 commit comments

Comments
 (0)