From 185826b835e7ccef8c896bb3e701affd36251284 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Mon, 22 Feb 2021 19:00:32 +0100 Subject: [PATCH] config: Reload button for external plugins in development mode --- .../client/plugins/config/PluginListItem.java | 67 +++++++++++++++++- .../plugins/config/PluginListPanel.java | 6 +- .../client/plugins/config/refresh.png | Bin 0 -> 211 bytes 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/config/refresh.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java index 767fddbc1a..6c3099fa36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java @@ -37,17 +37,23 @@ import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JMenuItem; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JToggleButton; import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; import javax.swing.border.EmptyBorder; import lombok.Getter; +import net.runelite.client.RuneLiteProperties; import net.runelite.client.externalplugins.ExternalPluginManifest; +import net.runelite.client.plugins.OPRSExternalPluginManager; +import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.util.ImageUtil; @@ -57,6 +63,8 @@ class PluginListItem extends JPanel implements SearchablePlugin { private static final ImageIcon CONFIG_ICON; private static final ImageIcon CONFIG_ICON_HOVER; + private static final ImageIcon REFRESH_ICON; + private static final ImageIcon REFRESH_ICON_HOVER; private static final ImageIcon ON_STAR; private static final ImageIcon OFF_STAR; @@ -74,10 +82,13 @@ class PluginListItem extends JPanel implements SearchablePlugin static { BufferedImage configIcon = ImageUtil.loadImageResource(ConfigPanel.class, "config_edit_icon.png"); + BufferedImage refreshIcon = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "refresh.png"); BufferedImage onStar = ImageUtil.loadImageResource(ConfigPanel.class, "star_on.png"); CONFIG_ICON = new ImageIcon(configIcon); + REFRESH_ICON = new ImageIcon(refreshIcon); ON_STAR = new ImageIcon(onStar); CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(configIcon, -100)); + REFRESH_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(refreshIcon, -100)); BufferedImage offStar = ImageUtil.luminanceScale( ImageUtil.grayscaleImage(onStar), @@ -86,7 +97,7 @@ class PluginListItem extends JPanel implements SearchablePlugin OFF_STAR = new ImageIcon(offStar); } - PluginListItem(PluginListPanel pluginListPanel, PluginConfigurationDescriptor pluginConfig) + PluginListItem(PluginListPanel pluginListPanel, PluginConfigurationDescriptor pluginConfig, OPRSExternalPluginManager oprsExternalPluginManager) { this.pluginListPanel = pluginListPanel; this.pluginConfig = pluginConfig; @@ -133,6 +144,60 @@ class PluginListItem extends JPanel implements SearchablePlugin buttonPanel.setLayout(new GridLayout(1, 2)); add(buttonPanel, BorderLayout.LINE_END); + Map> pluginsInfoMap = oprsExternalPluginManager.getPluginsInfoMap(); + + if ((OPRSExternalPluginManager.isDevelopmentMode() || RuneLiteProperties.getLauncherVersion() == null) && pluginConfig.getPlugin() != null && pluginsInfoMap.containsKey(pluginConfig.getPlugin().getClass().getSimpleName())) + { + JButton hotSwapButton = new JButton(REFRESH_ICON); + hotSwapButton.setRolloverIcon(REFRESH_ICON_HOVER); + SwingUtil.removeButtonDecorations(hotSwapButton); + hotSwapButton.setPreferredSize(new Dimension(25, 0)); + hotSwapButton.setVisible(false); + buttonPanel.add(hotSwapButton); + + hotSwapButton.addActionListener(e -> + { + Map pluginInfo = pluginsInfoMap.get(pluginConfig.getPlugin().getClass().getSimpleName()); + String pluginId = pluginInfo.get("id"); + + hotSwapButton.setIcon(REFRESH_ICON); + + new SwingWorker<>() + { + @Override + protected Boolean doInBackground() + { + return oprsExternalPluginManager.uninstall(pluginId); + } + + @Override + protected void done() + { + // In development mode our plugins will be loaded directly from sources, so we don't need to prompt + if (!OPRSExternalPluginManager.isDevelopmentMode()) + { + JOptionPane.showMessageDialog(ClientUI.getFrame(), + pluginId + " is unloaded, put the new jar file in the externalmanager folder and click `ok`", + "Hotswap " + pluginId, + JOptionPane.INFORMATION_MESSAGE); + } + + new SwingWorker<>() + { + @Override + protected Boolean doInBackground() + { + return oprsExternalPluginManager.reloadStart(pluginId); + } + }.execute(); + } + }.execute(); + }); + + hotSwapButton.setVisible(true); + hotSwapButton.setToolTipText("Hotswap plugin"); + } + JMenuItem configMenuItem = null; if (pluginConfig.hasConfigurables()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java index 286b534877..b4ce131eb7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java @@ -57,6 +57,7 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ExternalPluginsChanged; import net.runelite.client.events.PluginChanged; import net.runelite.client.externalplugins.ExternalPluginManager; +import net.runelite.client.plugins.OPRSExternalPluginManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginInstantiationException; @@ -93,6 +94,7 @@ class PluginListPanel extends PluginPanel @Getter private final ExternalPluginManager externalPluginManager; + private final OPRSExternalPluginManager oprsExternalPluginManager; @Getter private final MultiplexingPluginPanel muxer; @@ -107,6 +109,7 @@ class PluginListPanel extends PluginPanel ConfigManager configManager, PluginManager pluginManager, ExternalPluginManager externalPluginManager, + OPRSExternalPluginManager oprsExternalPluginManager, EventBus eventBus, Provider configPanelProvider, Provider pluginHubPanelProvider) @@ -116,6 +119,7 @@ class PluginListPanel extends PluginPanel this.configManager = configManager; this.pluginManager = pluginManager; this.externalPluginManager = externalPluginManager; + this.oprsExternalPluginManager = oprsExternalPluginManager; this.configPanelProvider = configPanelProvider; muxer = new MultiplexingPluginPanel(this) @@ -215,7 +219,7 @@ class PluginListPanel extends PluginPanel ) .map(desc -> { - PluginListItem listItem = new PluginListItem(this, desc); + PluginListItem listItem = new PluginListItem(this, desc, oprsExternalPluginManager); listItem.setPinned(pinnedPlugins.contains(desc.getName())); return listItem; }) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/refresh.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..cd26305f7a8c54a4c05a0b587352fde61e12f474 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mW_h|ehEy;fxv1*o!YJZ!vESWj z4cqeMxi*{GO&+e>y}<9tUB$n$58kz#8b5g~oAe)TSmDAoHa$9#W_(ESs zRlv@*TZBuhwyxIlaNp~F