supa fixa

This commit is contained in:
downthecrop 2025-10-22 21:48:05 -07:00
parent 9f5d6f59e3
commit 16546ef862
3 changed files with 206 additions and 165 deletions

View file

@ -176,9 +176,22 @@ class plugin : Plugin() {
// Ensure Swing updates happen on the EDT to avoid flicker // Ensure Swing updates happen on the EDT to avoid flicker
SwingUtilities.invokeLater { SwingUtilities.invokeLater {
updateDisplaySettings() updateDisplaySettings()
frame.remove(rightPanelWrapper) rightPanelWrapper?.let { wrapper ->
wrapper.ignoreRepaint = true
try {
val parent = wrapper.parent
val wrapperNeedsAttach = parent != frame
if (wrapperNeedsAttach) {
parent?.remove(wrapper)
frame.layout = BorderLayout() frame.layout = BorderLayout()
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) } frame.add(wrapper, BorderLayout.EAST)
}
wrapper.revalidate()
wrapper.repaint()
} finally {
wrapper.ignoreRepaint = false
}
}
frame.revalidate() frame.revalidate()
frame.repaint() frame.repaint()

View file

@ -83,6 +83,8 @@ object ReflectiveEditorView : View {
// Search text for filtering plugins // Search text for filtering plugins
private var pluginSearchText: String = "" private var pluginSearchText: String = ""
private var searchFieldWrapper: JPanel? = null private var searchFieldWrapper: JPanel? = null
private var pluginListContentPanel: JPanel? = null
private var pluginListScrollablePanel: ScrollablePanel? = null
override val name: String = VIEW_NAME override val name: String = VIEW_NAME
override val iconSpriteId: Int = WRENCH_ICON override val iconSpriteId: Int = WRENCH_ICON
@ -166,6 +168,36 @@ object ReflectiveEditorView : View {
panel.add(searchFieldWrapperPanel) panel.add(searchFieldWrapperPanel)
panel.add(Box.createVerticalStrut(10)) panel.add(Box.createVerticalStrut(10))
pluginListContentPanel = JPanel().apply {
layout = BoxLayout(this, BoxLayout.Y_AXIS)
background = VIEW_BACKGROUND_COLOR
alignmentX = Component.CENTER_ALIGNMENT
}
panel.add(pluginListContentPanel)
val scrollablePanel = ScrollablePanel(panel)
pluginListScrollablePanel = scrollablePanel
val container = JPanel(BorderLayout())
container.background = VIEW_BACKGROUND_COLOR
container.add(scrollablePanel, BorderLayout.CENTER)
populatePluginListContent()
SwingUtilities.invokeLater {
resetScrollablePanel(scrollablePanel)
}
return container
}
private fun populatePluginListContent() {
val contentPanel = pluginListContentPanel ?: return
val treeLock = contentPanel.treeLock
synchronized(treeLock) {
contentPanel.removeAll()
try { try {
// Get loaded plugins // Get loaded plugins
val loadedPluginsField = PluginRepository::class.java.getDeclaredField("loadedPlugins") val loadedPluginsField = PluginRepository::class.java.getDeclaredField("loadedPlugins")
@ -205,8 +237,8 @@ object ReflectiveEditorView : View {
for ((pluginInfo, plugin) in pluginsWithExposed) { for ((pluginInfo, plugin) in pluginsWithExposed) {
val pluginPanel = createPluginItemPanel(pluginInfo, plugin) val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
panel.add(pluginPanel) contentPanel.add(pluginPanel)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
} }
if (pluginsWithExposed.isNotEmpty() && pluginsWithoutExposed.isNotEmpty()) { if (pluginsWithExposed.isNotEmpty() && pluginsWithoutExposed.isNotEmpty()) {
@ -214,14 +246,14 @@ object ReflectiveEditorView : View {
separator.background = VIEW_BACKGROUND_COLOR separator.background = VIEW_BACKGROUND_COLOR
separator.preferredSize = Dimension(Int.MAX_VALUE, 1) separator.preferredSize = Dimension(Int.MAX_VALUE, 1)
separator.maximumSize = Dimension(Int.MAX_VALUE, 1) separator.maximumSize = Dimension(Int.MAX_VALUE, 1)
panel.add(separator) contentPanel.add(separator)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
} }
for ((pluginInfo, plugin) in pluginsWithoutExposed) { for ((pluginInfo, plugin) in pluginsWithoutExposed) {
val pluginPanel = createPluginItemPanel(pluginInfo, plugin) val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
panel.add(pluginPanel) contentPanel.add(pluginPanel)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
@ -237,8 +269,8 @@ object ReflectiveEditorView : View {
} }
if (pluginSearchText.isBlank() || pluginDir.name.contains(pluginSearchText, ignoreCase = true)) { if (pluginSearchText.isBlank() || pluginDir.name.contains(pluginSearchText, ignoreCase = true)) {
val pluginPanel = createDisabledPluginItemPanel(pluginDir.name) val pluginPanel = createDisabledPluginItemPanel(pluginDir.name)
panel.add(pluginPanel) contentPanel.add(pluginPanel)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
} }
} }
} }
@ -265,9 +297,9 @@ object ReflectiveEditorView : View {
separator.background = VIEW_BACKGROUND_COLOR separator.background = VIEW_BACKGROUND_COLOR
separator.preferredSize = Dimension(Int.MAX_VALUE, 1) separator.preferredSize = Dimension(Int.MAX_VALUE, 1)
separator.maximumSize = Dimension(Int.MAX_VALUE, 1) separator.maximumSize = Dimension(Int.MAX_VALUE, 1)
panel.add(Box.createVerticalStrut(10)) contentPanel.add(Box.createVerticalStrut(10))
panel.add(separator) contentPanel.add(separator)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
val headerPanel = JPanel(FlowLayout(FlowLayout.LEFT)) val headerPanel = JPanel(FlowLayout(FlowLayout.LEFT))
headerPanel.background = VIEW_BACKGROUND_COLOR headerPanel.background = VIEW_BACKGROUND_COLOR
@ -275,8 +307,8 @@ object ReflectiveEditorView : View {
headerLabel.foreground = secondaryColor headerLabel.foreground = secondaryColor
headerLabel.font = Font("RuneScape Small", Font.BOLD, 16) headerLabel.font = Font("RuneScape Small", Font.BOLD, 16)
headerPanel.add(headerLabel) headerPanel.add(headerLabel)
panel.add(headerPanel) contentPanel.add(headerPanel)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
if (matchingPluginStatuses.isNotEmpty()) { if (matchingPluginStatuses.isNotEmpty()) {
if (matchingPluginStatuses.size > 1) { if (matchingPluginStatuses.size > 1) {
@ -290,34 +322,23 @@ object ReflectiveEditorView : View {
startMultiplePluginDownloads(matchingPluginStatuses) startMultiplePluginDownloads(matchingPluginStatuses)
} }
downloadAllPanel.add(downloadAllButton) downloadAllPanel.add(downloadAllButton)
panel.add(downloadAllPanel) contentPanel.add(downloadAllPanel)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
} }
// Add matching plugin statuses // Add matching plugin statuses
for (pluginStatus in matchingPluginStatuses) { for (pluginStatus in matchingPluginStatuses) {
System.out.println("Adding plugin to UI: ${pluginStatus.name}") System.out.println("Adding plugin to UI: ${pluginStatus.name}")
val pluginPanel = createPluginStatusItemPanel(pluginStatus) val pluginPanel = createPluginStatusItemPanel(pluginStatus)
panel.add(pluginPanel) contentPanel.add(pluginPanel)
panel.add(Box.createVerticalStrut(5)) contentPanel.add(Box.createVerticalStrut(5))
}
} }
} }
} }
// Wrap the panel in a ScrollablePanel for custom scrolling contentPanel.revalidate()
val scrollablePanel = ScrollablePanel(panel) contentPanel.repaint()
// Reset scroll position to top
SwingUtilities.invokeLater {
// For ScrollablePanel, we need to reset the internal offset
resetScrollablePanel(scrollablePanel)
}
val container = JPanel(BorderLayout())
container.background = VIEW_BACKGROUND_COLOR
container.add(scrollablePanel, BorderLayout.CENTER)
return container
} }
private fun createPluginItemPanel(pluginInfo: PluginInfo, plugin: Plugin): JPanel { private fun createPluginItemPanel(pluginInfo: PluginInfo, plugin: Plugin): JPanel {
@ -793,30 +814,37 @@ object ReflectiveEditorView : View {
// Update plugin statuses to reflect current loaded plugins // Update plugin statuses to reflect current loaded plugins
updatePluginStatuses() updatePluginStatuses()
// Batch updates to avoid intermediate repaints/flicker val contentPanel = pluginListContentPanel
mainPanel.ignoreRepaint = true if (contentPanel == null) {
try { // Fallback path: rebuild the list view if it was not initialized yet
// Remove the existing plugin list view if present
val existingListView = mainPanel.components.find { it.name == PLUGIN_LIST_VIEW } val existingListView = mainPanel.components.find { it.name == PLUGIN_LIST_VIEW }
val pluginListView = createPluginListView()
pluginListView.name = PLUGIN_LIST_VIEW
if (existingListView != null) { if (existingListView != null) {
mainPanel.remove(existingListView) mainPanel.remove(existingListView)
} }
// Create a new plugin list view off-EDT (already on EDT here) and add it
val pluginListView = createPluginListView()
pluginListView.name = PLUGIN_LIST_VIEW
mainPanel.add(pluginListView, PLUGIN_LIST_VIEW) mainPanel.add(pluginListView, PLUGIN_LIST_VIEW)
} else {
contentPanel.isVisible = false
try {
populatePluginListContent()
} finally {
contentPanel.isVisible = true
}
}
searchFieldWrapper?.isVisible = true
// Switch card after the new component is in place
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW) cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
// Revalidate/repaint once at the end pluginListScrollablePanel?.let { scrollPanel ->
searchFieldWrapper?.isVisible = true SwingUtilities.invokeLater {
resetScrollablePanel(scrollPanel)
}
}
mainPanel.revalidate() mainPanel.revalidate()
mainPanel.repaint() mainPanel.repaint()
} finally {
mainPanel.ignoreRepaint = false
}
} }
var customToolTipWindow: JWindow? = null var customToolTipWindow: JWindow? = null