diff --git a/plugin-playground/src/main/kotlin/KondoKit/ReflectiveEditorView.kt b/plugin-playground/src/main/kotlin/KondoKit/ReflectiveEditorView.kt index 601b30d..61f7a24 100644 --- a/plugin-playground/src/main/kotlin/KondoKit/ReflectiveEditorView.kt +++ b/plugin-playground/src/main/kotlin/KondoKit/ReflectiveEditorView.kt @@ -2,22 +2,20 @@ package KondoKit import KondoKit.Helpers.convertValue import KondoKit.Helpers.showToast -import KondoKit.ScrollablePanel -import KondoKit.ToggleSwitch import KondoKit.plugin.Companion.TITLE_BAR_COLOR import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR import KondoKit.plugin.Companion.WIDGET_COLOR -import KondoKit.plugin.Companion.primaryColor import KondoKit.plugin.Companion.secondaryColor -import KondoKit.plugin.StateManager.focusedView import plugin.Plugin import plugin.PluginInfo import plugin.PluginRepository +import rt4.GlobalJsonConfig import java.awt.* import java.awt.event.MouseAdapter import java.awt.event.MouseEvent import java.awt.image.BufferedImage +import java.io.File import java.util.* import java.util.Timer import javax.imageio.ImageIO @@ -39,6 +37,7 @@ object ReflectiveEditorView { const val VIEW_NAME = "REFLECTIVE_EDITOR_VIEW" const val PLUGIN_LIST_VIEW = "PLUGIN_LIST" const val PLUGIN_DETAIL_VIEW = "PLUGIN_DETAIL" + val pluginsDirectory: File = File(GlobalJsonConfig.instance.pluginsFolder) // Store the cog icon to be reused private var cogIcon: Icon? = null @@ -150,6 +149,19 @@ object ReflectiveEditorView { e.printStackTrace() } + // Add disabled plugins to the list + val disabledDir = File(pluginsDirectory, "disabled") + if (disabledDir.exists() && disabledDir.isDirectory) { + val disabledPlugins = disabledDir.listFiles { file -> file.isDirectory } ?: arrayOf() + + // Add disabled plugins to the list without exposed attributes + for (pluginDir in disabledPlugins.sortedBy { it.name }) { + val pluginPanel = createDisabledPluginItemPanel(pluginDir.name) + panel.add(pluginPanel) + panel.add(Box.createVerticalStrut(5)) + } + } + // Wrap the panel in a ScrollablePanel for custom scrolling val scrollablePanel = ScrollablePanel(panel) @@ -227,29 +239,162 @@ object ReflectiveEditorView { return panel } + private fun createDisabledPluginItemPanel(pluginName: String): JPanel { + val panel = JPanel(BorderLayout()) + panel.background = WIDGET_COLOR + panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10) + panel.maximumSize = Dimension(220, 60) + + // Plugin name + val nameLabel = JLabel(pluginName) + nameLabel.foreground = secondaryColor + nameLabel.font = Font("RuneScape Small", Font.PLAIN, 16) + + // Plugin toggle switch (iOS style) - initially off for disabled plugins + val toggleSwitch = ToggleSwitch() + toggleSwitch.setActivated(false) + toggleSwitch.onToggleListener = { activated -> + if (activated) { + enablePlugin(pluginName) + } + // If trying to disable an already disabled plugin, reset the toggle + else { + toggleSwitch.setActivated(false) + } + } + + // Layout + val infoPanel = JPanel(BorderLayout()) + infoPanel.background = WIDGET_COLOR + infoPanel.add(nameLabel, BorderLayout.WEST) + + val controlsPanel = JPanel(FlowLayout(FlowLayout.RIGHT, 5, 0)) + controlsPanel.background = WIDGET_COLOR + controlsPanel.add(toggleSwitch) + + panel.add(infoPanel, BorderLayout.CENTER) + panel.add(controlsPanel, BorderLayout.EAST) + + return panel + } + + private fun enablePlugin(pluginName: String) { + try { + // Source and destination directories + val disabledDir = File(pluginsDirectory, "disabled") + val sourceDir = File(disabledDir, pluginName) + val destDir = File(pluginsDirectory, pluginName) + + // Check if source directory exists + if (!sourceDir.exists()) { + showToast(mainPanel, "Plugin directory not found: ${sourceDir.absolutePath}", JOptionPane.ERROR_MESSAGE) + return + } + + // Move the directory + if (sourceDir.renameTo(destDir)) { + showToast(mainPanel, "Plugin enabled") + + // Reload plugins to apply the change + PluginRepository.reloadPlugins() + + // Refresh the plugin list view + SwingUtilities.invokeLater { + addPlugins(reflectiveEditorView!!) + } + } else { + showToast(mainPanel, "Failed to enable plugin", JOptionPane.ERROR_MESSAGE) + } + } catch (e: Exception) { + e.printStackTrace() + showToast(mainPanel, "Error enabling plugin: ${e.message}", JOptionPane.ERROR_MESSAGE) + } + } + private fun createToggleSwitch(plugin: Plugin, pluginInfo: PluginInfo): ToggleSwitch { val toggleSwitch = ToggleSwitch() // Set initial state - toggleSwitch.setActivated(isPluginEnabled(pluginInfo)) + toggleSwitch.setActivated(isPluginEnabled(plugin, pluginInfo)) // Add toggle listener toggleSwitch.onToggleListener = { activated -> - togglePlugin(pluginInfo, plugin, toggleSwitch, activated) + togglePlugin(plugin, pluginInfo, toggleSwitch, activated) } return toggleSwitch } - private fun isPluginEnabled(pluginInfo: PluginInfo): Boolean { - // For now, we'll assume all loaded plugins are enabled - // In a more complete implementation, you might track enabled/disabled state - return true + private fun isPluginEnabled(plugin: Plugin, pluginInfo: PluginInfo): Boolean { + // Get the plugin directory name from the plugin's class package + val pluginDirName = getPluginDirName(plugin) + val pluginDir = File(pluginsDirectory, pluginDirName) + return pluginDir.exists() && pluginDir.isDirectory } - private fun togglePlugin(pluginInfo: PluginInfo, plugin: Plugin, toggleSwitch: ToggleSwitch, activated: Boolean) { - // In a full implementation, you would disable/enable the plugin here - showToast(mainPanel, if (activated) "Plugin enabled" else "Plugin disabled") + private fun getPluginDirName(plugin: Plugin): String { + // Extract the directory name from the plugin's package + // The package name is typically like "GroundItems.plugin" so we take the first part + val packageName = plugin.javaClass.`package`.name + return packageName.substringBefore(".") + } + + private fun togglePlugin(plugin: Plugin, pluginInfo: PluginInfo, toggleSwitch: ToggleSwitch, activated: Boolean) { + try { + // Get the plugin directory name from the plugin's class package + val pluginDirName = getPluginDirName(plugin) + + // Source and destination directories + val sourceDir = if (activated) { + // Moving from disabled to enabled + File(File(pluginsDirectory, "disabled"), pluginDirName) + } else { + // Moving from enabled to disabled + File(pluginsDirectory, pluginDirName) + } + + val destDir = if (activated) { + // Moving to main plugins directory + File(pluginsDirectory, pluginDirName) + } else { + // Moving to disabled directory + val disabledDir = File(pluginsDirectory, "disabled") + if (!disabledDir.exists()) { + disabledDir.mkdirs() + } + File(disabledDir, pluginDirName) + } + + // Check if source directory exists + if (!sourceDir.exists()) { + showToast(mainPanel, "Plugin directory not found: ${sourceDir.absolutePath}", JOptionPane.ERROR_MESSAGE) + // Reset toggle switch to previous state + toggleSwitch.setActivated(!activated) + return + } + + // Move the directory + if (sourceDir.renameTo(destDir)) { + showToast(mainPanel, if (activated) "Plugin enabled" else "Plugin disabled") + + // Reload plugins to apply the change + PluginRepository.reloadPlugins() + + // Refresh the plugin list view + SwingUtilities.invokeLater { + addPlugins(reflectiveEditorView!!) + } + } else { + showToast(mainPanel, "Failed to ${if (activated) "enable" else "disable"} plugin", JOptionPane.ERROR_MESSAGE) + // Reset toggle switch to previous state + toggleSwitch.setActivated(!activated) + } + } catch (e: Exception) { + e.printStackTrace() + showToast(mainPanel, "Error toggling plugin: ${e.message}", JOptionPane.ERROR_MESSAGE) + // Reset toggle switch to previous state + toggleSwitch.setActivated(!activated) + } } private fun showPluginDetails(pluginInfo: PluginInfo, plugin: Plugin) {