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 61b1e8b105..0a0b91256e 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 @@ -37,7 +37,6 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Comparator; import java.util.Map; @@ -61,6 +60,7 @@ import javax.swing.JTextField; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; import javax.swing.SwingConstants; +import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -75,16 +75,22 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginManager; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.DynamicGridLayout; import net.runelite.client.ui.PluginPanel; +import net.runelite.client.ui.components.ComboBoxListRenderer; +import net.runelite.client.ui.components.IconTextField; @Slf4j public class ConfigPanel extends PluginPanel { private static final int TEXT_FIELD_WIDTH = 7; private static final int SPINNER_FIELD_WIDTH = 6; - private static BufferedImage CONFIG_ICON; - private static BufferedImage UNCHECK_ICON; - private static BufferedImage CHECK_ICON; + + private static final ImageIcon CONFIG_ICON; + private static final ImageIcon ON_SWITCHER; + private static final ImageIcon OFF_SWITCHER; + private static final ImageIcon SEARCH; static { @@ -92,14 +98,15 @@ public class ConfigPanel extends PluginPanel { synchronized (ImageIO.class) { - CONFIG_ICON = ImageIO.read(ConfigPanel.class.getResourceAsStream("config_icon.png")); - UNCHECK_ICON = ImageIO.read(ConfigPanel.class.getResourceAsStream("disabled.png")); - CHECK_ICON = ImageIO.read(ConfigPanel.class.getResourceAsStream("enabled.png")); + CONFIG_ICON = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("config_edit_icon.png"))); + ON_SWITCHER = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("switchers/on.png"))); + OFF_SWITCHER = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("switchers/off.png"))); + SEARCH = new ImageIcon(ImageIO.read(IconTextField.class.getResourceAsStream("search.png"))); } } catch (IOException e) { - log.warn("Failed to read icon", e); + throw new RuntimeException(e); } } @@ -107,7 +114,7 @@ public class ConfigPanel extends PluginPanel private final ConfigManager configManager; private final ScheduledExecutorService executorService; private final RuneLiteConfig runeLiteConfig; - private final JTextField searchBar = new JTextField(); + private final IconTextField searchBar = new IconTextField(); private Map children = new TreeMap<>(); private int scrollBarPosition = 0; @@ -119,6 +126,10 @@ public class ConfigPanel extends PluginPanel this.executorService = executorService; this.runeLiteConfig = runeLiteConfig; + searchBar.setIcon(SEARCH); + searchBar.setPreferredSize(new Dimension(100, 30)); + searchBar.setBackground(ColorScheme.DARKER_GRAY_COLOR); + searchBar.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR); searchBar.getDocument().addDocumentListener(new DocumentListener() { @Override @@ -140,6 +151,10 @@ public class ConfigPanel extends PluginPanel } }); + setBorder(new EmptyBorder(10, 10, 10, 10)); + setLayout(new DynamicGridLayout(0, 1, 0, 5)); + setBackground(ColorScheme.DARK_GRAY_COLOR); + rebuildPluginList(); openConfigList(); } @@ -150,42 +165,54 @@ public class ConfigPanel extends PluginPanel Map newChildren = new TreeMap<>(); pluginManager.getPlugins().stream() - .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden()) - .sorted(Comparator.comparing(left -> left.getClass().getAnnotation(PluginDescriptor.class).name())) - .forEach(plugin -> - { - final Config pluginConfigProxy = pluginManager.getPluginConfigProxy(plugin); - final String pluginName = plugin.getClass().getAnnotation(PluginDescriptor.class).name(); + .filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden()) + .sorted(Comparator.comparing(left -> left.getClass().getAnnotation(PluginDescriptor.class).name())) + .forEach(plugin -> + { + final Config pluginConfigProxy = pluginManager.getPluginConfigProxy(plugin); + final String pluginName = plugin.getClass().getAnnotation(PluginDescriptor.class).name(); - final JPanel groupPanel = buildGroupPanel(); - groupPanel.add(new JLabel(pluginName), BorderLayout.CENTER); + final JPanel groupPanel = buildGroupPanel(); - final JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new GridLayout(1, 2, 3, 0)); - groupPanel.add(buttonPanel, BorderLayout.LINE_END); + JLabel name = new JLabel(pluginName); + name.setForeground(Color.WHITE); - final JButton editConfigButton = buildConfigButton(pluginConfigProxy); - buttonPanel.add(editConfigButton); + groupPanel.add(name, BorderLayout.CENTER); - final JButton toggleButton = buildToggleButton(plugin); - buttonPanel.add(toggleButton); + final JPanel buttonPanel = new JPanel(); + buttonPanel.setOpaque(false); + buttonPanel.setLayout(new GridLayout(1, 2)); + groupPanel.add(buttonPanel, BorderLayout.LINE_END); - newChildren.put(pluginName, groupPanel); - }); + final JLabel editConfigButton = buildConfigButton(pluginConfigProxy); + buttonPanel.add(editConfigButton); + final JLabel toggleButton = buildToggleButton(plugin); + toggleButton.setHorizontalAlignment(SwingConstants.RIGHT); + buttonPanel.add(toggleButton); + + newChildren.put(pluginName, groupPanel); + }); final JPanel groupPanel = buildGroupPanel(); - groupPanel.add(new JLabel("RuneLite"), BorderLayout.CENTER); + + JLabel name = new JLabel("RuneLite"); + name.setForeground(Color.WHITE); + + groupPanel.add(name, BorderLayout.CENTER); final JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new GridLayout(1, 2, 3, 0)); + buttonPanel.setOpaque(false); + buttonPanel.setLayout(new GridLayout(1, 2)); groupPanel.add(buttonPanel, BorderLayout.LINE_END); - final JButton editConfigButton = buildConfigButton(runeLiteConfig); + final JLabel editConfigButton = buildConfigButton(runeLiteConfig); buttonPanel.add(editConfigButton); - final JButton toggleButton = buildToggleButton(null); + final JLabel toggleButton = buildToggleButton(null); + toggleButton.setVisible(false); buttonPanel.add(toggleButton); + newChildren.put("RuneLite", groupPanel); children = newChildren; @@ -197,15 +224,17 @@ public class ConfigPanel extends PluginPanel // Create base panel for the config button and enabled/disabled button final JPanel groupPanel = new JPanel(); groupPanel.setLayout(new BorderLayout(3, 0)); + groupPanel.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 20)); + groupPanel.setOpaque(false); return groupPanel; } - private JButton buildConfigButton(Config config) + private JLabel buildConfigButton(Config config) { // Create edit config button and disable it by default - final JButton editConfigButton = new JButton(new ImageIcon(CONFIG_ICON)); - editConfigButton.setPreferredSize(new Dimension(32, 0)); - editConfigButton.setEnabled(false); + final JLabel editConfigButton = new JLabel(CONFIG_ICON); + editConfigButton.setPreferredSize(new Dimension(25, 0)); + editConfigButton.setVisible(false); // If we have configuration proxy enable the button and add edit config listener if (config != null) @@ -215,8 +244,15 @@ public class ConfigPanel extends PluginPanel if (!configEmpty) { - editConfigButton.addActionListener(ae -> openGroupConfigPanel(config, configDescriptor, configManager)); - editConfigButton.setEnabled(true); + editConfigButton.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + openGroupConfigPanel(config, configDescriptor, configManager); + } + }); + editConfigButton.setVisible(true); editConfigButton.setToolTipText("Edit plugin configuration"); } } @@ -224,11 +260,11 @@ public class ConfigPanel extends PluginPanel return editConfigButton; } - private JButton buildToggleButton(Plugin plugin) + private JLabel buildToggleButton(Plugin plugin) { // Create enabling/disabling button - final JButton toggleButton = new JButton(new ImageIcon(CHECK_ICON)); - toggleButton.setPreferredSize(new Dimension(32, 0)); + final JLabel toggleButton = new JLabel(ON_SWITCHER); + toggleButton.setPreferredSize(new Dimension(25, 0)); if (plugin == null) { @@ -238,36 +274,43 @@ public class ConfigPanel extends PluginPanel highlightButton(toggleButton, pluginManager.isPluginEnabled(plugin)); - toggleButton.addActionListener(e -> executorService.submit(() -> + toggleButton.addMouseListener(new MouseAdapter() { - final boolean enabled = pluginManager.isPluginEnabled(plugin); - pluginManager.setPluginEnabled(plugin, !enabled); - - try + @Override + public void mousePressed(MouseEvent mouseEvent) { - if (enabled) + executorService.submit(() -> { - pluginManager.stopPlugin(plugin); - } - else - { - pluginManager.startPlugin(plugin); - } - } - catch (PluginInstantiationException ex) - { - log.warn("Error during starting/stopping plugin {}", plugin.getClass().getSimpleName(), ex); - } + final boolean enabled = pluginManager.isPluginEnabled(plugin); + pluginManager.setPluginEnabled(plugin, !enabled); - highlightButton(toggleButton, !enabled); - })); + try + { + if (enabled) + { + pluginManager.stopPlugin(plugin); + } + else + { + pluginManager.startPlugin(plugin); + } + } + catch (PluginInstantiationException ex) + { + log.warn("Error during starting/stopping plugin {}", plugin.getClass().getSimpleName(), ex); + } + + highlightButton(toggleButton, !enabled); + }); + } + }); return toggleButton; } - private void highlightButton(JButton button, boolean enabled) + private void highlightButton(JLabel button, boolean enabled) { - button.setIcon(enabled ? new ImageIcon(CHECK_ICON) : new ImageIcon(UNCHECK_ICON)); + button.setIcon(enabled ? ON_SWITCHER : OFF_SWITCHER); button.setToolTipText(enabled ? "Disable plugin" : "Enable plugin"); } @@ -301,7 +344,11 @@ public class ConfigPanel extends PluginPanel private void openConfigList() { removeAll(); - add(new JLabel("Plugin Configuration", SwingConstants.CENTER)); + + JLabel title = new JLabel("Configuration", SwingConstants.LEFT); + title.setForeground(Color.WHITE); + + add(title); add(searchBar); onSearchBarChanged(); @@ -331,6 +378,7 @@ public class ConfigPanel extends PluginPanel if (component instanceof JCheckBox) { JCheckBox checkbox = (JCheckBox) component; + checkbox.setOpaque(false); configManager.setConfiguration(cd.getGroup().keyName(), cid.getItem().keyName(), "" + checkbox.isSelected()); } @@ -355,6 +403,8 @@ public class ConfigPanel extends PluginPanel if (component instanceof JComboBox) { JComboBox jComboBox = (JComboBox) component; + jComboBox.setRenderer(new ComboBoxListRenderer()); + jComboBox.setForeground(Color.WHITE); configManager.setConfiguration(cd.getGroup().keyName(), cid.getItem().keyName(), ((Enum) jComboBox.getSelectedItem()).name()); } } @@ -376,6 +426,7 @@ public class ConfigPanel extends PluginPanel } JPanel item = new JPanel(); + item.setOpaque(false); item.setLayout(new BorderLayout()); name = cid.getItem().name(); JLabel configEntryName = new JLabel(name); @@ -385,6 +436,8 @@ public class ConfigPanel extends PluginPanel if (cid.getType() == boolean.class) { JCheckBox checkbox = new JCheckBox(); + checkbox.setOpaque(false); + checkbox.setBackground(ColorScheme.LIGHT_GRAY_COLOR); checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().keyName(), cid.getItem().keyName()))); checkbox.addActionListener(ae -> changeConfiguration(config, checkbox, cd, cid)); @@ -462,6 +515,7 @@ public class ConfigPanel extends PluginPanel if (cid.getType() == Dimension.class) { JPanel dimensionPanel = new JPanel(); + dimensionPanel.setOpaque(false); dimensionPanel.setLayout(new BorderLayout()); String str = configManager.getConfiguration(cd.getGroup().keyName(), cid.getItem().keyName()); @@ -482,7 +536,7 @@ public class ConfigPanel extends PluginPanel heightSpinnerTextField.setColumns(4); ChangeListener listener = e -> - configManager.setConfiguration(cd.getGroup().keyName(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); + configManager.setConfiguration(cd.getGroup().keyName(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); widthSpinner.addChangeListener(listener); heightSpinner.addChangeListener(listener); @@ -498,6 +552,9 @@ public class ConfigPanel extends PluginPanel { Class type = (Class) cid.getType(); JComboBox box = new JComboBox(type.getEnumConstants()); + box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25)); + box.setRenderer(new ComboBoxListRenderer()); + box.setForeground(Color.WHITE); box.setFocusable(false); box.setPrototypeDisplayValue("XXXXXXXX"); //sorry but this is the way to keep the size of the combobox in check. try @@ -541,4 +598,4 @@ public class ConfigPanel extends PluginPanel revalidate(); getScrollPane().getVerticalScrollBar().setValue(0); } -} +} \ No newline at end of file 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 new file mode 100644 index 0000000000..8be06a706c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/DynamicGridLayout.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.ui; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Insets; +import java.util.function.Function; + +/** + * Grid layout implementation with support for cells with unequal size. + * + * See https://www.javaworld.com/article/2077486/core-java/java-tip-121--flex-your-grid-layout.html + */ +public class DynamicGridLayout extends GridLayout +{ + public DynamicGridLayout() + { + this(1, 0, 0, 0); + } + + public DynamicGridLayout(int rows, int cols) + { + this(rows, cols, 0, 0); + } + + public DynamicGridLayout(int rows, int cols, int hgap, int vgap) + { + super(rows, cols, hgap, vgap); + } + + @Override + public Dimension preferredLayoutSize(Container parent) + { + synchronized (parent.getTreeLock()) + { + return calculateSize(parent, Component::getPreferredSize); + } + } + + @Override + public Dimension minimumLayoutSize(Container parent) + { + synchronized (parent.getTreeLock()) + { + return calculateSize(parent, Component::getMinimumSize); + } + } + + @Override + public void layoutContainer(Container parent) + { + synchronized (parent.getTreeLock()) + { + final Insets insets = parent.getInsets(); + final int ncomponents = parent.getComponentCount(); + int nrows = getRows(); + int ncols = getColumns(); + + if (ncomponents == 0) + { + return; + } + + if (nrows > 0) + { + ncols = (ncomponents + nrows - 1) / nrows; + } + else + { + nrows = (ncomponents + ncols - 1) / ncols; + } + + final int hgap = getHgap(); + final int vgap = getVgap(); + + // scaling factors + final Dimension pd = preferredLayoutSize(parent); + final double sw = (1.0 * parent.getWidth()) / pd.width; + final double sh = (1.0 * parent.getHeight()) / pd.height; + + final int[] w = new int[ncols]; + final int[] h = new int[nrows]; + + // calculate dimensions for all components + apply scaling + for (int i = 0; i < ncomponents; i++) + { + final int r = i / ncols; + final int c = i % ncols; + final Component comp = parent.getComponent(i); + final Dimension d = comp.getPreferredSize(); + d.width = (int) (sw * d.width); + d.height = (int) (sh * d.height); + + if (w[c] < d.width) + { + w[c] = d.width; + } + + if (h[r] < d.height) + { + h[r] = d.height; + } + } + + // Apply new bounds to all child components + for (int c = 0, x = insets.left; c < ncols; c++) + { + for (int r = 0, y = insets.top; r < nrows; r++) + { + int i = r * ncols + c; + + if (i < ncomponents) + { + parent.getComponent(i).setBounds(x, y, w[c], h[r]); + } + + y += h[r] + vgap; + } + + x += w[c] + hgap; + } + } + } + + /** + * Calculate outer size of the layout based on it's children and sizer + * @param parent parent component + * @param sizer functioning returning dimension of the child component + * @return outer size + */ + private Dimension calculateSize(final Container parent, final Function sizer) + { + final int ncomponents = parent.getComponentCount(); + int nrows = getRows(); + int ncols = getColumns(); + + if (nrows > 0) + { + ncols = (ncomponents + nrows - 1) / nrows; + } + else + { + nrows = (ncomponents + ncols - 1) / ncols; + } + + final int[] w = new int[ncols]; + final int[] h = new int[nrows]; + + // Calculate dimensions for all components + for (int i = 0; i < ncomponents; i++) + { + final int r = i / ncols; + final int c = i % ncols; + final Component comp = parent.getComponent(i); + final Dimension d = sizer.apply(comp); + + if (w[c] < d.width) + { + w[c] = d.width; + } + + if (h[r] < d.height) + { + h[r] = d.height; + } + } + + // Calculate total width and height of the layout + int nw = 0; + + for (int j = 0; j < ncols; j++) + { + nw += w[j]; + } + + int nh = 0; + + for (int i = 0; i < nrows; i++) + { + nh += h[i]; + } + + final Insets insets = parent.getInsets(); + + // Apply insets and horizontal and vertical gap to layout + return new Dimension( + insets.left + insets.right + nw + (ncols - 1) * getHgap(), + insets.top + insets.bottom + nh + (nrows - 1) * getVgap()); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java new file mode 100644 index 0000000000..c97e128374 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017, Psikoi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.ui.components; + +import java.awt.Color; +import java.awt.Component; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import javax.swing.border.EmptyBorder; +import net.runelite.client.ui.ColorScheme; + +/** + * A custom list renderer to avoid substance's weird coloring. + * Substance was making selected items' foreground color black, this + * was very hard to see in the dark gray background, this makes the selected + * item white and adds some padding to the elements for more readable list. + */ +public final class ComboBoxListRenderer extends JLabel implements ListCellRenderer +{ + + @Override + public Component getListCellRendererComponent(JList list, Object o, int index, boolean isSelected, boolean cellHasFocus) + { + if (isSelected) + { + setBackground(ColorScheme.DARK_GRAY_COLOR); + setForeground(Color.WHITE); + } + else + { + setBackground(list.getBackground()); + setForeground(ColorScheme.LIGHT_GRAY_COLOR); + } + + setBorder(new EmptyBorder(5, 5, 5, 0)); + + String text = (String) o.toString(); + setText(text); + + return this; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java index e016215756..0734851fb0 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java @@ -37,6 +37,7 @@ import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; +import javax.swing.text.Document; import net.runelite.client.ui.ColorScheme; /** @@ -160,4 +161,9 @@ public class IconTextField extends JPanel } } + public Document getDocument() + { + return textField.getDocument(); + } + } \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/config_edit_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/config_edit_icon.png new file mode 100644 index 0000000000..d88ec51f71 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/config/config_edit_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/disabled.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/disabled.png deleted file mode 100644 index 160d431a95..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/config/disabled.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/enabled.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/enabled.png deleted file mode 100644 index a48cfcd5cc..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/config/enabled.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/off.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/off.png new file mode 100644 index 0000000000..ff25cc611a Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/off.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/on.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/on.png new file mode 100644 index 0000000000..43028e1716 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/on.png differ