mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-15 02:50:23 -07:00
supa fixa
This commit is contained in:
parent
9f5d6f59e3
commit
16546ef862
3 changed files with 206 additions and 165 deletions
BIN
plugin-playground/src/main/kotlin/KondoKit/.DS_Store
vendored
BIN
plugin-playground/src/main/kotlin/KondoKit/.DS_Store
vendored
Binary file not shown.
|
|
@ -176,9 +176,22 @@ class plugin : Plugin() {
|
|||
// Ensure Swing updates happen on the EDT to avoid flicker
|
||||
SwingUtilities.invokeLater {
|
||||
updateDisplaySettings()
|
||||
frame.remove(rightPanelWrapper)
|
||||
frame.layout = BorderLayout()
|
||||
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) }
|
||||
rightPanelWrapper?.let { wrapper ->
|
||||
wrapper.ignoreRepaint = true
|
||||
try {
|
||||
val parent = wrapper.parent
|
||||
val wrapperNeedsAttach = parent != frame
|
||||
if (wrapperNeedsAttach) {
|
||||
parent?.remove(wrapper)
|
||||
frame.layout = BorderLayout()
|
||||
frame.add(wrapper, BorderLayout.EAST)
|
||||
}
|
||||
wrapper.revalidate()
|
||||
wrapper.repaint()
|
||||
} finally {
|
||||
wrapper.ignoreRepaint = false
|
||||
}
|
||||
}
|
||||
frame.revalidate()
|
||||
frame.repaint()
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ object ReflectiveEditorView : View {
|
|||
// Search text for filtering plugins
|
||||
private var pluginSearchText: String = ""
|
||||
private var searchFieldWrapper: JPanel? = null
|
||||
private var pluginListContentPanel: JPanel? = null
|
||||
private var pluginListScrollablePanel: ScrollablePanel? = null
|
||||
|
||||
override val name: String = VIEW_NAME
|
||||
override val iconSpriteId: Int = WRENCH_ICON
|
||||
|
|
@ -166,160 +168,179 @@ object ReflectiveEditorView : View {
|
|||
panel.add(searchFieldWrapperPanel)
|
||||
panel.add(Box.createVerticalStrut(10))
|
||||
|
||||
try {
|
||||
// Get loaded plugins
|
||||
val loadedPluginsField = PluginRepository::class.java.getDeclaredField("loadedPlugins")
|
||||
loadedPluginsField.isAccessible = true
|
||||
val loadedPlugins = loadedPluginsField.get(null) as HashMap<*, *>
|
||||
|
||||
// Separate plugins with and without exposed attributes
|
||||
val pluginsWithExposed = mutableListOf<Pair<PluginInfo, Plugin>>()
|
||||
val pluginsWithoutExposed = mutableListOf<Pair<PluginInfo, Plugin>>()
|
||||
|
||||
for ((pluginInfo, plugin) in loadedPlugins) {
|
||||
val exposedFields = (plugin as Plugin).javaClass.declaredFields.filter { field ->
|
||||
field.annotations.any { annotation ->
|
||||
annotation.annotationClass.simpleName == "Exposed"
|
||||
}
|
||||
}
|
||||
|
||||
// Apply search filter
|
||||
val pluginName = plugin.javaClass.`package`.name
|
||||
if (pluginSearchText.isBlank() || pluginName.contains(pluginSearchText, ignoreCase = true)) {
|
||||
if (exposedFields.isNotEmpty()) {
|
||||
pluginsWithExposed.add(pluginInfo as PluginInfo to plugin)
|
||||
} else {
|
||||
pluginsWithoutExposed.add(pluginInfo as PluginInfo to plugin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginsWithExposed.sortWith(compareBy(
|
||||
{ if (isKondoKit(it.second.javaClass.`package`.name)) 0 else 1 },
|
||||
{ it.second.javaClass.`package`.name }
|
||||
))
|
||||
pluginsWithoutExposed.sortWith(compareBy(
|
||||
{ if (isKondoKit(it.second.javaClass.`package`.name)) 0 else 1 },
|
||||
{ it.second.javaClass.`package`.name }
|
||||
))
|
||||
|
||||
for ((pluginInfo, plugin) in pluginsWithExposed) {
|
||||
val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
|
||||
panel.add(pluginPanel)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
|
||||
if (pluginsWithExposed.isNotEmpty() && pluginsWithoutExposed.isNotEmpty()) {
|
||||
val separator = JPanel()
|
||||
separator.background = VIEW_BACKGROUND_COLOR
|
||||
separator.preferredSize = Dimension(Int.MAX_VALUE, 1)
|
||||
separator.maximumSize = Dimension(Int.MAX_VALUE, 1)
|
||||
panel.add(separator)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
|
||||
for ((pluginInfo, plugin) in pluginsWithoutExposed) {
|
||||
val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
|
||||
panel.add(pluginPanel)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
pluginListContentPanel = JPanel().apply {
|
||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||
background = VIEW_BACKGROUND_COLOR
|
||||
alignmentX = Component.CENTER_ALIGNMENT
|
||||
}
|
||||
panel.add(pluginListContentPanel)
|
||||
|
||||
val disabledDir = File(pluginsDirectory, "disabled")
|
||||
if (disabledDir.exists() && disabledDir.isDirectory) {
|
||||
val disabledPlugins = disabledDir.listFiles { file -> file.isDirectory } ?: arrayOf()
|
||||
|
||||
for (pluginDir in disabledPlugins.sortedBy { it.name }) {
|
||||
if (isKondoKit(pluginDir.name)) {
|
||||
continue
|
||||
}
|
||||
if (pluginSearchText.isBlank() || pluginDir.name.contains(pluginSearchText, ignoreCase = true)) {
|
||||
val pluginPanel = createDisabledPluginItemPanel(pluginDir.name)
|
||||
panel.add(pluginPanel)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginSearchText.isNotBlank()) {
|
||||
System.out.println("Filtering plugins for search term: '$pluginSearchText'")
|
||||
System.out.println("Total plugin statuses: ${pluginStatuses.size}")
|
||||
|
||||
val matchingPluginStatuses = pluginStatuses.filter { pluginStatus ->
|
||||
// Only show plugins that are not currently loaded and not KondoKit
|
||||
val shouldShow = !pluginStatus.isInstalled &&
|
||||
!isKondoKit(pluginStatus.name) &&
|
||||
(pluginStatus.name.contains(pluginSearchText, ignoreCase = true) ||
|
||||
(pluginStatus.description?.contains(pluginSearchText, ignoreCase = true) ?: false))
|
||||
|
||||
System.out.println("Plugin: ${pluginStatus.name}, isInstalled: ${pluginStatus.isInstalled}, shouldShow: $shouldShow")
|
||||
shouldShow
|
||||
}
|
||||
|
||||
System.out.println("Matching plugin statuses: ${matchingPluginStatuses.size}")
|
||||
|
||||
// Add a separator
|
||||
val separator = JPanel()
|
||||
separator.background = VIEW_BACKGROUND_COLOR
|
||||
separator.preferredSize = Dimension(Int.MAX_VALUE, 1)
|
||||
separator.maximumSize = Dimension(Int.MAX_VALUE, 1)
|
||||
panel.add(Box.createVerticalStrut(10))
|
||||
panel.add(separator)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
|
||||
val headerPanel = JPanel(FlowLayout(FlowLayout.LEFT))
|
||||
headerPanel.background = VIEW_BACKGROUND_COLOR
|
||||
val headerLabel = JLabel(if (matchingPluginStatuses.isNotEmpty()) "Available Plugins" else "")
|
||||
headerLabel.foreground = secondaryColor
|
||||
headerLabel.font = Font("RuneScape Small", Font.BOLD, 16)
|
||||
headerPanel.add(headerLabel)
|
||||
panel.add(headerPanel)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
|
||||
if (matchingPluginStatuses.isNotEmpty()) {
|
||||
if (matchingPluginStatuses.size > 1) {
|
||||
val downloadAllPanel = JPanel(FlowLayout(FlowLayout.LEFT))
|
||||
downloadAllPanel.background = VIEW_BACKGROUND_COLOR
|
||||
val downloadAllButton = JButton("Download All")
|
||||
downloadAllButton.background = TITLE_BAR_COLOR
|
||||
downloadAllButton.foreground = secondaryColor
|
||||
downloadAllButton.font = Font("RuneScape Small", Font.PLAIN, 14)
|
||||
downloadAllButton.addActionListener {
|
||||
startMultiplePluginDownloads(matchingPluginStatuses)
|
||||
}
|
||||
downloadAllPanel.add(downloadAllButton)
|
||||
panel.add(downloadAllPanel)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
|
||||
// Add matching plugin statuses
|
||||
for (pluginStatus in matchingPluginStatuses) {
|
||||
System.out.println("Adding plugin to UI: ${pluginStatus.name}")
|
||||
val pluginPanel = createPluginStatusItemPanel(pluginStatus)
|
||||
panel.add(pluginPanel)
|
||||
panel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap the panel in a ScrollablePanel for custom scrolling
|
||||
val scrollablePanel = ScrollablePanel(panel)
|
||||
|
||||
// Reset scroll position to top
|
||||
SwingUtilities.invokeLater {
|
||||
// For ScrollablePanel, we need to reset the internal offset
|
||||
resetScrollablePanel(scrollablePanel)
|
||||
}
|
||||
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 {
|
||||
// Get loaded plugins
|
||||
val loadedPluginsField = PluginRepository::class.java.getDeclaredField("loadedPlugins")
|
||||
loadedPluginsField.isAccessible = true
|
||||
val loadedPlugins = loadedPluginsField.get(null) as HashMap<*, *>
|
||||
|
||||
// Separate plugins with and without exposed attributes
|
||||
val pluginsWithExposed = mutableListOf<Pair<PluginInfo, Plugin>>()
|
||||
val pluginsWithoutExposed = mutableListOf<Pair<PluginInfo, Plugin>>()
|
||||
|
||||
for ((pluginInfo, plugin) in loadedPlugins) {
|
||||
val exposedFields = (plugin as Plugin).javaClass.declaredFields.filter { field ->
|
||||
field.annotations.any { annotation ->
|
||||
annotation.annotationClass.simpleName == "Exposed"
|
||||
}
|
||||
}
|
||||
|
||||
// Apply search filter
|
||||
val pluginName = plugin.javaClass.`package`.name
|
||||
if (pluginSearchText.isBlank() || pluginName.contains(pluginSearchText, ignoreCase = true)) {
|
||||
if (exposedFields.isNotEmpty()) {
|
||||
pluginsWithExposed.add(pluginInfo as PluginInfo to plugin)
|
||||
} else {
|
||||
pluginsWithoutExposed.add(pluginInfo as PluginInfo to plugin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginsWithExposed.sortWith(compareBy(
|
||||
{ if (isKondoKit(it.second.javaClass.`package`.name)) 0 else 1 },
|
||||
{ it.second.javaClass.`package`.name }
|
||||
))
|
||||
pluginsWithoutExposed.sortWith(compareBy(
|
||||
{ if (isKondoKit(it.second.javaClass.`package`.name)) 0 else 1 },
|
||||
{ it.second.javaClass.`package`.name }
|
||||
))
|
||||
|
||||
for ((pluginInfo, plugin) in pluginsWithExposed) {
|
||||
val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
|
||||
contentPanel.add(pluginPanel)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
|
||||
if (pluginsWithExposed.isNotEmpty() && pluginsWithoutExposed.isNotEmpty()) {
|
||||
val separator = JPanel()
|
||||
separator.background = VIEW_BACKGROUND_COLOR
|
||||
separator.preferredSize = Dimension(Int.MAX_VALUE, 1)
|
||||
separator.maximumSize = Dimension(Int.MAX_VALUE, 1)
|
||||
contentPanel.add(separator)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
|
||||
for ((pluginInfo, plugin) in pluginsWithoutExposed) {
|
||||
val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
|
||||
contentPanel.add(pluginPanel)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
val disabledDir = File(pluginsDirectory, "disabled")
|
||||
if (disabledDir.exists() && disabledDir.isDirectory) {
|
||||
val disabledPlugins = disabledDir.listFiles { file -> file.isDirectory } ?: arrayOf()
|
||||
|
||||
for (pluginDir in disabledPlugins.sortedBy { it.name }) {
|
||||
if (isKondoKit(pluginDir.name)) {
|
||||
continue
|
||||
}
|
||||
if (pluginSearchText.isBlank() || pluginDir.name.contains(pluginSearchText, ignoreCase = true)) {
|
||||
val pluginPanel = createDisabledPluginItemPanel(pluginDir.name)
|
||||
contentPanel.add(pluginPanel)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginSearchText.isNotBlank()) {
|
||||
System.out.println("Filtering plugins for search term: '$pluginSearchText'")
|
||||
System.out.println("Total plugin statuses: ${pluginStatuses.size}")
|
||||
|
||||
val matchingPluginStatuses = pluginStatuses.filter { pluginStatus ->
|
||||
// Only show plugins that are not currently loaded and not KondoKit
|
||||
val shouldShow = !pluginStatus.isInstalled &&
|
||||
!isKondoKit(pluginStatus.name) &&
|
||||
(pluginStatus.name.contains(pluginSearchText, ignoreCase = true) ||
|
||||
(pluginStatus.description?.contains(pluginSearchText, ignoreCase = true) ?: false))
|
||||
|
||||
System.out.println("Plugin: ${pluginStatus.name}, isInstalled: ${pluginStatus.isInstalled}, shouldShow: $shouldShow")
|
||||
shouldShow
|
||||
}
|
||||
|
||||
System.out.println("Matching plugin statuses: ${matchingPluginStatuses.size}")
|
||||
|
||||
// Add a separator
|
||||
val separator = JPanel()
|
||||
separator.background = VIEW_BACKGROUND_COLOR
|
||||
separator.preferredSize = Dimension(Int.MAX_VALUE, 1)
|
||||
separator.maximumSize = Dimension(Int.MAX_VALUE, 1)
|
||||
contentPanel.add(Box.createVerticalStrut(10))
|
||||
contentPanel.add(separator)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
|
||||
val headerPanel = JPanel(FlowLayout(FlowLayout.LEFT))
|
||||
headerPanel.background = VIEW_BACKGROUND_COLOR
|
||||
val headerLabel = JLabel(if (matchingPluginStatuses.isNotEmpty()) "Available Plugins" else "")
|
||||
headerLabel.foreground = secondaryColor
|
||||
headerLabel.font = Font("RuneScape Small", Font.BOLD, 16)
|
||||
headerPanel.add(headerLabel)
|
||||
contentPanel.add(headerPanel)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
|
||||
if (matchingPluginStatuses.isNotEmpty()) {
|
||||
if (matchingPluginStatuses.size > 1) {
|
||||
val downloadAllPanel = JPanel(FlowLayout(FlowLayout.LEFT))
|
||||
downloadAllPanel.background = VIEW_BACKGROUND_COLOR
|
||||
val downloadAllButton = JButton("Download All")
|
||||
downloadAllButton.background = TITLE_BAR_COLOR
|
||||
downloadAllButton.foreground = secondaryColor
|
||||
downloadAllButton.font = Font("RuneScape Small", Font.PLAIN, 14)
|
||||
downloadAllButton.addActionListener {
|
||||
startMultiplePluginDownloads(matchingPluginStatuses)
|
||||
}
|
||||
downloadAllPanel.add(downloadAllButton)
|
||||
contentPanel.add(downloadAllPanel)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
|
||||
// Add matching plugin statuses
|
||||
for (pluginStatus in matchingPluginStatuses) {
|
||||
System.out.println("Adding plugin to UI: ${pluginStatus.name}")
|
||||
val pluginPanel = createPluginStatusItemPanel(pluginStatus)
|
||||
contentPanel.add(pluginPanel)
|
||||
contentPanel.add(Box.createVerticalStrut(5))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentPanel.revalidate()
|
||||
contentPanel.repaint()
|
||||
}
|
||||
|
||||
private fun createPluginItemPanel(pluginInfo: PluginInfo, plugin: Plugin): JPanel {
|
||||
val panel = JPanel(BorderLayout())
|
||||
panel.background = WIDGET_COLOR
|
||||
|
|
@ -793,30 +814,37 @@ object ReflectiveEditorView : View {
|
|||
// Update plugin statuses to reflect current loaded plugins
|
||||
updatePluginStatuses()
|
||||
|
||||
// Batch updates to avoid intermediate repaints/flicker
|
||||
mainPanel.ignoreRepaint = true
|
||||
try {
|
||||
// Remove the existing plugin list view if present
|
||||
val contentPanel = pluginListContentPanel
|
||||
if (contentPanel == null) {
|
||||
// Fallback path: rebuild the list view if it was not initialized yet
|
||||
val existingListView = mainPanel.components.find { it.name == PLUGIN_LIST_VIEW }
|
||||
val pluginListView = createPluginListView()
|
||||
pluginListView.name = PLUGIN_LIST_VIEW
|
||||
if (existingListView != null) {
|
||||
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)
|
||||
|
||||
// Switch card after the new component is in place
|
||||
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
|
||||
|
||||
// Revalidate/repaint once at the end
|
||||
searchFieldWrapper?.isVisible = true
|
||||
mainPanel.revalidate()
|
||||
mainPanel.repaint()
|
||||
} finally {
|
||||
mainPanel.ignoreRepaint = false
|
||||
} else {
|
||||
contentPanel.isVisible = false
|
||||
try {
|
||||
populatePluginListContent()
|
||||
} finally {
|
||||
contentPanel.isVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
searchFieldWrapper?.isVisible = true
|
||||
|
||||
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
|
||||
|
||||
pluginListScrollablePanel?.let { scrollPanel ->
|
||||
SwingUtilities.invokeLater {
|
||||
resetScrollablePanel(scrollPanel)
|
||||
}
|
||||
}
|
||||
|
||||
mainPanel.revalidate()
|
||||
mainPanel.repaint()
|
||||
}
|
||||
|
||||
var customToolTipWindow: JWindow? = null
|
||||
|
|
@ -1338,4 +1366,4 @@ object ReflectiveEditorView : View {
|
|||
scrollablePanel.repaint()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue