From a375b3541206299e0e9d489fa5f4abae25bea024 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 24 Feb 2021 19:47:35 +0100 Subject: [PATCH 1/2] config: Support for conusmers --- .../runelite/client/config/ConfigItem.java | 8 ++ .../runelite/client/config/ConfigManager.java | 112 ++++++++++++------ .../client/plugins/config/ConfigPanel.java | 15 +++ 3 files changed, 98 insertions(+), 37 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java index 05e5a2e103..7db9904d1c 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java @@ -65,6 +65,14 @@ public @interface ConfigItem String hideValue() default ""; + String enabledBy() default ""; + + String enabledByValue() default ""; + + String disabledBy() default ""; + + String disabledByValue() default ""; + /** * Use this to indicate the enum class that is going to be used in the multiple select config. * This implementation made debugging problems with multiple selects a lot easier diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index ac644c29d1..fb6c6b05d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -74,6 +74,7 @@ import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -97,6 +98,7 @@ import net.runelite.client.events.ClientShutdown; import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.RuneScapeProfileChanged; import net.runelite.client.plugins.OPRSExternalPluginManager; +import net.runelite.client.plugins.Plugin; import net.runelite.client.util.ColorUtil; import net.runelite.http.api.config.ConfigClient; import net.runelite.http.api.config.ConfigEntry; @@ -133,6 +135,7 @@ public class ConfigManager private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this); private final Map pendingChanges = new HashMap<>(); + private final Map> consumers = new HashMap<>(); private Properties properties = new Properties(); @@ -304,6 +307,8 @@ public class ConfigManager private synchronized void loadFromFile() { + consumers.clear(); + Properties newProperties = new Properties(); try (FileInputStream in = new FileInputStream(propertiesFile)) { @@ -484,6 +489,12 @@ public class ConfigManager public void setConfiguration(String groupName, String key, Object value) { + // do not save consumers for buttons, they cannot be changed anyway + if (value instanceof Consumer) + { + return; + } + setConfiguration(groupName, null, key, value); } @@ -671,55 +682,74 @@ public class ConfigManager continue; } - if (!method.isDefault()) + if (method.getReturnType().isAssignableFrom(Consumer.class)) { - if (override) + Object defaultValue; + try { - String current = getConfiguration(group.value(), item.keyName()); - // only unset if already set + defaultValue = ConfigInvocationHandler.callDefaultMethod(proxy, method, null); + } + catch (Throwable ex) + { + log.warn(null, ex); + continue; + } + + log.debug("Registered consumer: {}.{}", group.value(), item.keyName()); + consumers.put(group.value() + "." + item.keyName(), (Consumer) defaultValue); + } + else + { + if (!method.isDefault()) + { + if (override) + { + String current = getConfiguration(group.value(), item.keyName()); + // only unset if already set + if (current != null) + { + unsetConfiguration(group.value(), item.keyName()); + } + } + continue; + } + + if (!override) + { + // This checks if it is set and is also unmarshallable to the correct type; so + // we will overwrite invalid config values with the default + Object current = getConfiguration(group.value(), item.keyName(), method.getReturnType()); if (current != null) { - unsetConfiguration(group.value(), item.keyName()); + continue; // something else is already set } } - continue; - } - if (!override) - { - // This checks if it is set and is also unmarshallable to the correct type; so - // we will overwrite invalid config values with the default - Object current = getConfiguration(group.value(), item.keyName(), method.getReturnType()); - if (current != null) + Object defaultValue; + try { - continue; // something else is already set + defaultValue = ConfigInvocationHandler.callDefaultMethod(proxy, method, null); + } + catch (Throwable ex) + { + log.warn(null, ex); + continue; } - } - Object defaultValue; - try - { - defaultValue = ConfigInvocationHandler.callDefaultMethod(proxy, method, null); - } - catch (Throwable ex) - { - log.warn(null, ex); - continue; - } + String current = getConfiguration(group.value(), item.keyName()); + String valueString = objectToString(defaultValue); + // null and the empty string are treated identically in sendConfig and treated as an unset + // If a config value defaults to "" and the current value is null, it will cause an extra + // unset to be sent, so treat them as equal + if (Objects.equals(current, valueString) || (Strings.isNullOrEmpty(current) && Strings.isNullOrEmpty(valueString))) + { + continue; // already set to the default value + } - String current = getConfiguration(group.value(), item.keyName()); - String valueString = objectToString(defaultValue); - // null and the empty string are treated identically in sendConfig and treated as an unset - // If a config value defaults to "" and the current value is null, it will cause an extra - // unset to be sent, so treat them as equal - if (Objects.equals(current, valueString) || (Strings.isNullOrEmpty(current) && Strings.isNullOrEmpty(valueString))) - { - continue; // already set to the default value + log.debug("Setting default configuration value for {}.{} to {}", group.value(), item.keyName(), defaultValue); + + setConfiguration(group.value(), item.keyName(), valueString); } - - log.debug("Setting default configuration value for {}.{} to {}", group.value(), item.keyName(), defaultValue); - - setConfiguration(group.value(), item.keyName(), valueString); } } @@ -1286,4 +1316,12 @@ public class ConfigManager } setConfiguration("runelite", migrationKey, 1); } + + /** + * Retrieves a consumer from config group and key name + */ + public Consumer getConsumer(final String configGroup, final String keyName) + { + return consumers.getOrDefault(configGroup + "." + keyName, (p) -> log.error("Failed to retrieve consumer with name {}.{}", configGroup, keyName)); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 0bc3dd2cb1..ba5e653115 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -52,6 +52,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; +import java.util.function.Consumer; import javax.inject.Inject; import javax.swing.BorderFactory; import javax.swing.BoxLayout; @@ -485,6 +486,20 @@ class ConfigPanel extends PluginPanel item.add(checkbox, BorderLayout.EAST); } + if (cid.getType().isAssignableFrom(Consumer.class)) + { + item.remove(configEntryName); + + JButton button = new JButton(cid.getItem().name()); + button.addActionListener((e) -> + { + log.debug("Running consumer: {}.{}", cd.getGroup().value(), cid.getItem().keyName()); + configManager.getConsumer(cd.getGroup().value(), cid.getItem().keyName()).accept(pluginConfig.getPlugin()); + }); + + item.add(button, BorderLayout.CENTER); + } + if (cid.getType() == int.class) { int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); From 7bcb0c2d112371c960e67938f5a9f831b4a60c68 Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 24 Feb 2021 22:37:19 +0100 Subject: [PATCH 2/2] config: Fix issue with hide / unhide and reintroduce enabledBy and disabledBy --- .../client/plugins/config/ConfigPanel.java | 148 +++++++++++------- .../runelite/client/ui/DynamicGridLayout.java | 30 +--- 2 files changed, 99 insertions(+), 79 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index ba5e653115..50153c9f50 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -443,6 +443,11 @@ class ConfigPanel extends PluginPanel for (ConfigItemDescriptor cid : cd.getItems()) { + if (!hideUnhide(cid)) + { + continue; + } + JPanel item = new JPanel(); item.setLayout(new BorderLayout()); item.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); @@ -795,7 +800,7 @@ class ConfigPanel extends PluginPanel backButton.addActionListener(e -> pluginList.getMuxer().popState()); mainPanel.add(backButton); - hideUnhide(); + revalidate(); } private Boolean parse(ConfigItem item, String value) @@ -860,7 +865,7 @@ class ConfigPanel extends PluginPanel configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), finalEnumSet); - hideUnhide(); + rebuild(); } private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid) @@ -911,7 +916,8 @@ class ConfigPanel extends PluginPanel configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), hotkeyButton.getValue()); } - hideUnhide(); + enableDisable(component, cid); + rebuild(); } @Override @@ -961,78 +967,112 @@ class ConfigPanel extends PluginPanel return menuItem; } - private void hideUnhide() + private boolean hideUnhide(ConfigItemDescriptor cid) { ConfigDescriptor cd = pluginConfig.getConfigDescriptor(); - for (ConfigItemDescriptor cid : cd.getItems()) + boolean unhide = cid.getItem().hidden(); + boolean hide = !cid.getItem().hide().isEmpty(); + + if (unhide || hide) { - boolean unhide = cid.getItem().hidden(); - boolean hide = !cid.getItem().hide().isEmpty(); + boolean show = false; - if (unhide || hide) + List itemHide = Splitter + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(String.format("%s || %s", cid.getItem().unhide(), cid.getItem().hide())); + + for (ConfigItemDescriptor cid2 : cd.getItems()) { - boolean show = false; - - List itemHide = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(String.format("%s || %s", cid.getItem().unhide(), cid.getItem().hide())); - - for (ConfigItemDescriptor cid2 : cd.getItems()) + if (itemHide.contains(cid2.getItem().keyName())) { - if (itemHide.contains(cid2.getItem().keyName())) + if (cid2.getType() == boolean.class) { - if (cid2.getType() == boolean.class) + show = Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName())); + } + else if (cid2.getType().isEnum()) + { + Class type = (Class) cid2.getType(); + try { - show = Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName())); + Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName())); + if (!cid.getItem().unhideValue().equals("")) + { + List unhideValue = Splitter + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(cid.getItem().unhideValue()); + + show = unhideValue.contains(selectedItem.toString()); + } + else if (!cid.getItem().hideValue().equals("")) + { + List hideValue = Splitter + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(cid.getItem().hideValue()); + + show = !hideValue.contains(selectedItem.toString()); + } } - else if (cid2.getType().isEnum()) + catch (IllegalArgumentException ignored) { - Class type = (Class) cid2.getType(); - try - { - Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName())); - if (!cid.getItem().unhideValue().equals("")) - { - List unhideValue = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(cid.getItem().unhideValue()); - - show = unhideValue.contains(selectedItem.toString()); - } - else if (!cid.getItem().hideValue().equals("")) - { - List hideValue = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(cid.getItem().hideValue()); - - show = !hideValue.contains(selectedItem.toString()); - } - } - catch (IllegalArgumentException ignored) - { - } } } } + } - Component comp = findComponentByName(mainPanel, cid.getItem().keyName()); + return (!unhide || show) && (!hide || !show); + } - if (comp != null) + return true; + } + + private void enableDisable(Component component, ConfigItemDescriptor cid) + { + ConfigDescriptor cd = pluginConfig.getConfigDescriptor(); + + if (component instanceof JCheckBox) + { + JCheckBox checkbox = (JCheckBox) component; + + for (ConfigItemDescriptor cid2 : cd.getItems()) + { + if (checkbox.isSelected()) { - comp.setVisible((!unhide || show) && (!hide || !show)); + if (cid2.getItem().enabledBy().contains(cid.getItem().keyName())) + { + configManager.setConfiguration(cd.getGroup().value(), cid2.getItem().keyName(), "true"); + } + else if (cid2.getItem().disabledBy().contains(cid.getItem().keyName())) + { + configManager.setConfiguration(cd.getGroup().value(), cid2.getItem().keyName(), "false"); + } } } } + else if (component instanceof JComboBox) + { + JComboBox jComboBox = (JComboBox) component; - revalidate(); - repaint(); + for (ConfigItemDescriptor cid2 : cd.getItems()) + { + String changedVal = ((Enum) jComboBox.getSelectedItem()).name(); + + if (cid2.getItem().enabledBy().contains(cid.getItem().keyName()) && cid2.getItem().enabledByValue().equals(changedVal)) + { + configManager.setConfiguration(cd.getGroup().value(), cid2.getItem().keyName(), "true"); + } + else if (cid2.getItem().disabledBy().contains(cid.getItem().keyName()) && cid2.getItem().disabledByValue().equals(changedVal)) + { + configManager.setConfiguration(cd.getGroup().value(), cid2.getItem().keyName(), "false"); + } + } + } } private static String htmlLabel(String key, String value) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/DynamicGridLayout.java b/runelite-client/src/main/java/net/runelite/client/ui/DynamicGridLayout.java index b78d9019b3..120decaf13 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/DynamicGridLayout.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/DynamicGridLayout.java @@ -137,17 +137,12 @@ public class DynamicGridLayout extends GridLayout { int i = r * ncols + c; - Component component = parent.getComponent(i); - - if (component.isVisible()) + if (i < ncomponents) { - if (i < ncomponents) - { - component.setBounds(x, y, w[c], h[r]); - } - - y += h[r] + vgap; + parent.getComponent(i).setBounds(x, y, w[c], h[r]); } + + y += h[r] + vgap; } x += w[c] + hgap; @@ -163,7 +158,7 @@ public class DynamicGridLayout extends GridLayout */ private Dimension calculateSize(final Container parent, final Function sizer) { - final int ncomponents = getVisibleComponents(parent);; + final int ncomponents = parent.getComponentCount(); int nrows = getRows(); int ncols = getColumns(); @@ -220,19 +215,4 @@ public class DynamicGridLayout extends GridLayout insets.left + insets.right + nw + (ncols - 1) * getHgap(), insets.top + insets.bottom + nh + (nrows - 1) * getVgap()); } - - private int getVisibleComponents(Container parent) - { - int visible = 0; - - for (Component c : parent.getComponents()) - { - if (c.isVisible()) - { - visible++; - } - } - - return visible; - } } \ No newline at end of file