From 53d3d96a0647d0e276ec6e4aa9e7638ccacad114 Mon Sep 17 00:00:00 2001 From: hstyi Date: Sun, 6 Jul 2025 17:22:43 +0800 Subject: [PATCH] chore: dynamically modify icons --- .../ReconnectableTransportSupportLoader.kt | 5 ++ .../transfer/TransportSelectionPanel.kt | 2 +- .../transfer/TransportSupportLoader.kt | 5 ++ .../app/termora/transfer/TransportTabbed.kt | 9 ++-- .../app/termora/transfer/TransportViewer.kt | 49 ++++++++++++++++--- 5 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/app/termora/transfer/ReconnectableTransportSupportLoader.kt b/src/main/kotlin/app/termora/transfer/ReconnectableTransportSupportLoader.kt index c7f8e03..ff34065 100644 --- a/src/main/kotlin/app/termora/transfer/ReconnectableTransportSupportLoader.kt +++ b/src/main/kotlin/app/termora/transfer/ReconnectableTransportSupportLoader.kt @@ -68,6 +68,11 @@ internal class ReconnectableTransportSupportLoader(private val owner: Window, pr } } + override fun isOpening(): Boolean { + if (isOpened()) return false + return mutex.isLocked + } + private fun connect(): MyTransportSupport { val provider = TransferProtocolProvider.valueOf(host.protocol) if (provider == null) { diff --git a/src/main/kotlin/app/termora/transfer/TransportSelectionPanel.kt b/src/main/kotlin/app/termora/transfer/TransportSelectionPanel.kt index 3fb802d..616832d 100644 --- a/src/main/kotlin/app/termora/transfer/TransportSelectionPanel.kt +++ b/src/main/kotlin/app/termora/transfer/TransportSelectionPanel.kt @@ -111,7 +111,7 @@ internal class TransportSelectionPanel( }) swingCoroutineScope.launch { tabbed.remove(that) - tabbed.addTab(host.name, panel) + tabbed.addTab(host.name, TransportViewer.MyIcon.Success, panel) tabbed.selectedIndex = tabbed.tabCount - 1 } } diff --git a/src/main/kotlin/app/termora/transfer/TransportSupportLoader.kt b/src/main/kotlin/app/termora/transfer/TransportSupportLoader.kt index 8249dd1..0f00b19 100644 --- a/src/main/kotlin/app/termora/transfer/TransportSupportLoader.kt +++ b/src/main/kotlin/app/termora/transfer/TransportSupportLoader.kt @@ -23,4 +23,9 @@ internal interface TransportSupportLoader : Disposable { * 快速检查是否已经成功打开 */ fun isOpened(): Boolean = true + + /** + * 是否正在打开中,也有可能是加载中 + */ + fun isOpening(): Boolean = false } \ No newline at end of file diff --git a/src/main/kotlin/app/termora/transfer/TransportTabbed.kt b/src/main/kotlin/app/termora/transfer/TransportTabbed.kt index f5135a9..536798b 100644 --- a/src/main/kotlin/app/termora/transfer/TransportTabbed.kt +++ b/src/main/kotlin/app/termora/transfer/TransportTabbed.kt @@ -70,9 +70,8 @@ internal class TransportTabbed( showContextMenu(index, e) } else if (SwingUtilities.isLeftMouseButton(e) && e.clickCount % 2 == 0) { val tab = getTransportPanel(index) ?: return - if (tab.loader.isOpened().not()) { - tab.reload() - } + if (tab.loader.isOpening() || tab.loader.isOpened()) return + tab.reload() } } }) @@ -156,7 +155,7 @@ internal class TransportTabbed( return true } }) - addTab(I18n.getString("termora.transport.local"), panel) + addTab(I18n.getString("termora.transport.local"), TransportViewer.MyIcon.Success, panel) super.setTabClosable(0, false) } @@ -171,7 +170,7 @@ internal class TransportTabbed( val popupMenu = FlatPopupMenu() // 克隆 - val clone = popupMenu.add(I18n.getString("termora.tabbed.contextmenu.clone")) + val clone = popupMenu.add(I18n.getString("termora.copy")) clone.addActionListener(object : AnAction() { override fun actionPerformed(evt: AnActionEvent) { val c = addSelectionTab() diff --git a/src/main/kotlin/app/termora/transfer/TransportViewer.kt b/src/main/kotlin/app/termora/transfer/TransportViewer.kt index a219568..6fe6855 100644 --- a/src/main/kotlin/app/termora/transfer/TransportViewer.kt +++ b/src/main/kotlin/app/termora/transfer/TransportViewer.kt @@ -3,11 +3,10 @@ package app.termora.transfer import app.termora.Disposable import app.termora.Disposer import app.termora.DynamicColor -import app.termora.Icons import app.termora.actions.DataProvider import kotlinx.coroutines.* import kotlinx.coroutines.swing.Swing -import java.awt.BorderLayout +import java.awt.* import java.awt.event.ComponentAdapter import java.awt.event.ComponentEvent import java.nio.file.Path @@ -78,9 +77,9 @@ internal class TransportViewer : JPanel(BorderLayout()), DataProvider, Disposabl coroutineScope.launch(Dispatchers.Swing) { while (isActive) { - delay(250.milliseconds) checkDisconnected(leftTabbed) checkDisconnected(rightTabbed) + delay(250.milliseconds) } } @@ -93,11 +92,17 @@ internal class TransportViewer : JPanel(BorderLayout()), DataProvider, Disposabl val tab = tabbed.getTransportPanel(i) ?: continue val icon = tabbed.getIconAt(i) if (tab.loader.isOpened()) { - if (icon == null) continue - tabbed.setIconAt(i, null) + if (icon != MyIcon.Success) { + tabbed.setIconAt(i, MyIcon.Success) + } + } else if (tab.loader.isOpening()) { + if (icon != MyIcon.Warning) { + tabbed.setIconAt(i, MyIcon.Warning) + } } else { - if (icon == Icons.breakpoint) continue - tabbed.setIconAt(i, Icons.breakpoint) + if (icon != MyIcon.Error) { + tabbed.setIconAt(i, MyIcon.Error) + } } } } @@ -142,4 +147,34 @@ internal class TransportViewer : JPanel(BorderLayout()), DataProvider, Disposabl coroutineScope.cancel() } + internal class MyIcon(private val color: Color) : Icon { + private val size = 10 + + + // https://plugins.jetbrains.com/docs/intellij/icons-style.html#action-icons + companion object { + val Success = MyIcon(DynamicColor(Color(89, 168, 105), Color(73, 156, 84))) + val Error = MyIcon(DynamicColor(Color(219, 88, 96), Color(199, 84, 80))) + val Warning = MyIcon(DynamicColor(Color(237, 162, 0), Color(240, 167, 50))) + } + + override fun paintIcon(c: Component, g: Graphics, x: Int, y: Int) { + if (g is Graphics2D) { + g.color = color + val centerX = x + (iconWidth - size) / 2 + val centerY = y + (iconHeight - size) / 2 + g.fillRoundRect(centerX, centerY, size, size, size, size) + } + } + + override fun getIconWidth(): Int { + return 16 + } + + override fun getIconHeight(): Int { + return 16 + } + + } + } \ No newline at end of file