Configs slight design tweak
- Updated the search bar to the new icon text field component. - Added new on/off icons based on the material design style. - Recoloured the background. - Recoloured the plugin name labels. - Replaced the config/toggle buttons for icon labels. - Hid config button if no config was found, instead of disabling it. - Left aligned the header title. - Added new ComboBoxListRenderer to prevent substance's ugly coloring. - Changed the panel title to "Configuration" - Used deathbeam's new layout manager DynamicGridLayout
This commit is contained in:
committed by
Tomas Slusny
parent
dcd241e3bf
commit
6ec0d60ec4
@@ -37,7 +37,6 @@ import java.awt.event.MouseAdapter;
|
|||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -61,6 +60,7 @@ import javax.swing.JTextField;
|
|||||||
import javax.swing.SpinnerModel;
|
import javax.swing.SpinnerModel;
|
||||||
import javax.swing.SpinnerNumberModel;
|
import javax.swing.SpinnerNumberModel;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
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.PluginDescriptor;
|
||||||
import net.runelite.client.plugins.PluginInstantiationException;
|
import net.runelite.client.plugins.PluginInstantiationException;
|
||||||
import net.runelite.client.plugins.PluginManager;
|
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.PluginPanel;
|
||||||
|
import net.runelite.client.ui.components.ComboBoxListRenderer;
|
||||||
|
import net.runelite.client.ui.components.IconTextField;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ConfigPanel extends PluginPanel
|
public class ConfigPanel extends PluginPanel
|
||||||
{
|
{
|
||||||
private static final int TEXT_FIELD_WIDTH = 7;
|
private static final int TEXT_FIELD_WIDTH = 7;
|
||||||
private static final int SPINNER_FIELD_WIDTH = 6;
|
private static final int SPINNER_FIELD_WIDTH = 6;
|
||||||
private static BufferedImage CONFIG_ICON;
|
|
||||||
private static BufferedImage UNCHECK_ICON;
|
private static final ImageIcon CONFIG_ICON;
|
||||||
private static BufferedImage CHECK_ICON;
|
private static final ImageIcon ON_SWITCHER;
|
||||||
|
private static final ImageIcon OFF_SWITCHER;
|
||||||
|
private static final ImageIcon SEARCH;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
@@ -92,14 +98,15 @@ public class ConfigPanel extends PluginPanel
|
|||||||
{
|
{
|
||||||
synchronized (ImageIO.class)
|
synchronized (ImageIO.class)
|
||||||
{
|
{
|
||||||
CONFIG_ICON = ImageIO.read(ConfigPanel.class.getResourceAsStream("config_icon.png"));
|
CONFIG_ICON = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("config_edit_icon.png")));
|
||||||
UNCHECK_ICON = ImageIO.read(ConfigPanel.class.getResourceAsStream("disabled.png"));
|
ON_SWITCHER = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("switchers/on.png")));
|
||||||
CHECK_ICON = ImageIO.read(ConfigPanel.class.getResourceAsStream("enabled.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)
|
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 ConfigManager configManager;
|
||||||
private final ScheduledExecutorService executorService;
|
private final ScheduledExecutorService executorService;
|
||||||
private final RuneLiteConfig runeLiteConfig;
|
private final RuneLiteConfig runeLiteConfig;
|
||||||
private final JTextField searchBar = new JTextField();
|
private final IconTextField searchBar = new IconTextField();
|
||||||
private Map<String, JPanel> children = new TreeMap<>();
|
private Map<String, JPanel> children = new TreeMap<>();
|
||||||
private int scrollBarPosition = 0;
|
private int scrollBarPosition = 0;
|
||||||
|
|
||||||
@@ -119,6 +126,10 @@ public class ConfigPanel extends PluginPanel
|
|||||||
this.executorService = executorService;
|
this.executorService = executorService;
|
||||||
this.runeLiteConfig = runeLiteConfig;
|
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()
|
searchBar.getDocument().addDocumentListener(new DocumentListener()
|
||||||
{
|
{
|
||||||
@Override
|
@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();
|
rebuildPluginList();
|
||||||
openConfigList();
|
openConfigList();
|
||||||
}
|
}
|
||||||
@@ -150,42 +165,54 @@ public class ConfigPanel extends PluginPanel
|
|||||||
Map<String, JPanel> newChildren = new TreeMap<>();
|
Map<String, JPanel> newChildren = new TreeMap<>();
|
||||||
|
|
||||||
pluginManager.getPlugins().stream()
|
pluginManager.getPlugins().stream()
|
||||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
|
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
|
||||||
.sorted(Comparator.comparing(left -> left.getClass().getAnnotation(PluginDescriptor.class).name()))
|
.sorted(Comparator.comparing(left -> left.getClass().getAnnotation(PluginDescriptor.class).name()))
|
||||||
.forEach(plugin ->
|
.forEach(plugin ->
|
||||||
{
|
{
|
||||||
final Config pluginConfigProxy = pluginManager.getPluginConfigProxy(plugin);
|
final Config pluginConfigProxy = pluginManager.getPluginConfigProxy(plugin);
|
||||||
final String pluginName = plugin.getClass().getAnnotation(PluginDescriptor.class).name();
|
final String pluginName = plugin.getClass().getAnnotation(PluginDescriptor.class).name();
|
||||||
|
|
||||||
final JPanel groupPanel = buildGroupPanel();
|
final JPanel groupPanel = buildGroupPanel();
|
||||||
groupPanel.add(new JLabel(pluginName), BorderLayout.CENTER);
|
|
||||||
|
|
||||||
final JPanel buttonPanel = new JPanel();
|
JLabel name = new JLabel(pluginName);
|
||||||
buttonPanel.setLayout(new GridLayout(1, 2, 3, 0));
|
name.setForeground(Color.WHITE);
|
||||||
groupPanel.add(buttonPanel, BorderLayout.LINE_END);
|
|
||||||
|
|
||||||
final JButton editConfigButton = buildConfigButton(pluginConfigProxy);
|
groupPanel.add(name, BorderLayout.CENTER);
|
||||||
buttonPanel.add(editConfigButton);
|
|
||||||
|
|
||||||
final JButton toggleButton = buildToggleButton(plugin);
|
final JPanel buttonPanel = new JPanel();
|
||||||
buttonPanel.add(toggleButton);
|
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();
|
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();
|
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);
|
groupPanel.add(buttonPanel, BorderLayout.LINE_END);
|
||||||
|
|
||||||
final JButton editConfigButton = buildConfigButton(runeLiteConfig);
|
final JLabel editConfigButton = buildConfigButton(runeLiteConfig);
|
||||||
buttonPanel.add(editConfigButton);
|
buttonPanel.add(editConfigButton);
|
||||||
|
|
||||||
final JButton toggleButton = buildToggleButton(null);
|
final JLabel toggleButton = buildToggleButton(null);
|
||||||
|
toggleButton.setVisible(false);
|
||||||
buttonPanel.add(toggleButton);
|
buttonPanel.add(toggleButton);
|
||||||
|
|
||||||
newChildren.put("RuneLite", groupPanel);
|
newChildren.put("RuneLite", groupPanel);
|
||||||
|
|
||||||
children = newChildren;
|
children = newChildren;
|
||||||
@@ -197,15 +224,17 @@ public class ConfigPanel extends PluginPanel
|
|||||||
// Create base panel for the config button and enabled/disabled button
|
// Create base panel for the config button and enabled/disabled button
|
||||||
final JPanel groupPanel = new JPanel();
|
final JPanel groupPanel = new JPanel();
|
||||||
groupPanel.setLayout(new BorderLayout(3, 0));
|
groupPanel.setLayout(new BorderLayout(3, 0));
|
||||||
|
groupPanel.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 20));
|
||||||
|
groupPanel.setOpaque(false);
|
||||||
return groupPanel;
|
return groupPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JButton buildConfigButton(Config config)
|
private JLabel buildConfigButton(Config config)
|
||||||
{
|
{
|
||||||
// Create edit config button and disable it by default
|
// Create edit config button and disable it by default
|
||||||
final JButton editConfigButton = new JButton(new ImageIcon(CONFIG_ICON));
|
final JLabel editConfigButton = new JLabel(CONFIG_ICON);
|
||||||
editConfigButton.setPreferredSize(new Dimension(32, 0));
|
editConfigButton.setPreferredSize(new Dimension(25, 0));
|
||||||
editConfigButton.setEnabled(false);
|
editConfigButton.setVisible(false);
|
||||||
|
|
||||||
// If we have configuration proxy enable the button and add edit config listener
|
// If we have configuration proxy enable the button and add edit config listener
|
||||||
if (config != null)
|
if (config != null)
|
||||||
@@ -215,8 +244,15 @@ public class ConfigPanel extends PluginPanel
|
|||||||
|
|
||||||
if (!configEmpty)
|
if (!configEmpty)
|
||||||
{
|
{
|
||||||
editConfigButton.addActionListener(ae -> openGroupConfigPanel(config, configDescriptor, configManager));
|
editConfigButton.addMouseListener(new MouseAdapter()
|
||||||
editConfigButton.setEnabled(true);
|
{
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent mouseEvent)
|
||||||
|
{
|
||||||
|
openGroupConfigPanel(config, configDescriptor, configManager);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editConfigButton.setVisible(true);
|
||||||
editConfigButton.setToolTipText("Edit plugin configuration");
|
editConfigButton.setToolTipText("Edit plugin configuration");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,11 +260,11 @@ public class ConfigPanel extends PluginPanel
|
|||||||
return editConfigButton;
|
return editConfigButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JButton buildToggleButton(Plugin plugin)
|
private JLabel buildToggleButton(Plugin plugin)
|
||||||
{
|
{
|
||||||
// Create enabling/disabling button
|
// Create enabling/disabling button
|
||||||
final JButton toggleButton = new JButton(new ImageIcon(CHECK_ICON));
|
final JLabel toggleButton = new JLabel(ON_SWITCHER);
|
||||||
toggleButton.setPreferredSize(new Dimension(32, 0));
|
toggleButton.setPreferredSize(new Dimension(25, 0));
|
||||||
|
|
||||||
if (plugin == null)
|
if (plugin == null)
|
||||||
{
|
{
|
||||||
@@ -238,36 +274,43 @@ public class ConfigPanel extends PluginPanel
|
|||||||
|
|
||||||
highlightButton(toggleButton, pluginManager.isPluginEnabled(plugin));
|
highlightButton(toggleButton, pluginManager.isPluginEnabled(plugin));
|
||||||
|
|
||||||
toggleButton.addActionListener(e -> executorService.submit(() ->
|
toggleButton.addMouseListener(new MouseAdapter()
|
||||||
{
|
{
|
||||||
final boolean enabled = pluginManager.isPluginEnabled(plugin);
|
@Override
|
||||||
pluginManager.setPluginEnabled(plugin, !enabled);
|
public void mousePressed(MouseEvent mouseEvent)
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (enabled)
|
executorService.submit(() ->
|
||||||
{
|
{
|
||||||
pluginManager.stopPlugin(plugin);
|
final boolean enabled = pluginManager.isPluginEnabled(plugin);
|
||||||
}
|
pluginManager.setPluginEnabled(plugin, !enabled);
|
||||||
else
|
|
||||||
{
|
|
||||||
pluginManager.startPlugin(plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (PluginInstantiationException ex)
|
|
||||||
{
|
|
||||||
log.warn("Error during starting/stopping plugin {}", plugin.getClass().getSimpleName(), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
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");
|
button.setToolTipText(enabled ? "Disable plugin" : "Enable plugin");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +344,11 @@ public class ConfigPanel extends PluginPanel
|
|||||||
private void openConfigList()
|
private void openConfigList()
|
||||||
{
|
{
|
||||||
removeAll();
|
removeAll();
|
||||||
add(new JLabel("Plugin Configuration", SwingConstants.CENTER));
|
|
||||||
|
JLabel title = new JLabel("Configuration", SwingConstants.LEFT);
|
||||||
|
title.setForeground(Color.WHITE);
|
||||||
|
|
||||||
|
add(title);
|
||||||
add(searchBar);
|
add(searchBar);
|
||||||
|
|
||||||
onSearchBarChanged();
|
onSearchBarChanged();
|
||||||
@@ -331,6 +378,7 @@ public class ConfigPanel extends PluginPanel
|
|||||||
if (component instanceof JCheckBox)
|
if (component instanceof JCheckBox)
|
||||||
{
|
{
|
||||||
JCheckBox checkbox = (JCheckBox) component;
|
JCheckBox checkbox = (JCheckBox) component;
|
||||||
|
checkbox.setOpaque(false);
|
||||||
configManager.setConfiguration(cd.getGroup().keyName(), cid.getItem().keyName(), "" + checkbox.isSelected());
|
configManager.setConfiguration(cd.getGroup().keyName(), cid.getItem().keyName(), "" + checkbox.isSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,6 +403,8 @@ public class ConfigPanel extends PluginPanel
|
|||||||
if (component instanceof JComboBox)
|
if (component instanceof JComboBox)
|
||||||
{
|
{
|
||||||
JComboBox jComboBox = (JComboBox) component;
|
JComboBox jComboBox = (JComboBox) component;
|
||||||
|
jComboBox.setRenderer(new ComboBoxListRenderer());
|
||||||
|
jComboBox.setForeground(Color.WHITE);
|
||||||
configManager.setConfiguration(cd.getGroup().keyName(), cid.getItem().keyName(), ((Enum) jComboBox.getSelectedItem()).name());
|
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();
|
JPanel item = new JPanel();
|
||||||
|
item.setOpaque(false);
|
||||||
item.setLayout(new BorderLayout());
|
item.setLayout(new BorderLayout());
|
||||||
name = cid.getItem().name();
|
name = cid.getItem().name();
|
||||||
JLabel configEntryName = new JLabel(name);
|
JLabel configEntryName = new JLabel(name);
|
||||||
@@ -385,6 +436,8 @@ public class ConfigPanel extends PluginPanel
|
|||||||
if (cid.getType() == boolean.class)
|
if (cid.getType() == boolean.class)
|
||||||
{
|
{
|
||||||
JCheckBox checkbox = new JCheckBox();
|
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.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().keyName(), cid.getItem().keyName())));
|
||||||
checkbox.addActionListener(ae -> changeConfiguration(config, checkbox, cd, cid));
|
checkbox.addActionListener(ae -> changeConfiguration(config, checkbox, cd, cid));
|
||||||
|
|
||||||
@@ -462,6 +515,7 @@ public class ConfigPanel extends PluginPanel
|
|||||||
if (cid.getType() == Dimension.class)
|
if (cid.getType() == Dimension.class)
|
||||||
{
|
{
|
||||||
JPanel dimensionPanel = new JPanel();
|
JPanel dimensionPanel = new JPanel();
|
||||||
|
dimensionPanel.setOpaque(false);
|
||||||
dimensionPanel.setLayout(new BorderLayout());
|
dimensionPanel.setLayout(new BorderLayout());
|
||||||
|
|
||||||
String str = configManager.getConfiguration(cd.getGroup().keyName(), cid.getItem().keyName());
|
String str = configManager.getConfiguration(cd.getGroup().keyName(), cid.getItem().keyName());
|
||||||
@@ -482,7 +536,7 @@ public class ConfigPanel extends PluginPanel
|
|||||||
heightSpinnerTextField.setColumns(4);
|
heightSpinnerTextField.setColumns(4);
|
||||||
|
|
||||||
ChangeListener listener = e ->
|
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);
|
widthSpinner.addChangeListener(listener);
|
||||||
heightSpinner.addChangeListener(listener);
|
heightSpinner.addChangeListener(listener);
|
||||||
@@ -498,6 +552,9 @@ public class ConfigPanel extends PluginPanel
|
|||||||
{
|
{
|
||||||
Class<? extends Enum> type = (Class<? extends Enum>) cid.getType();
|
Class<? extends Enum> type = (Class<? extends Enum>) cid.getType();
|
||||||
JComboBox box = new JComboBox(type.getEnumConstants());
|
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.setFocusable(false);
|
||||||
box.setPrototypeDisplayValue("XXXXXXXX"); //sorry but this is the way to keep the size of the combobox in check.
|
box.setPrototypeDisplayValue("XXXXXXXX"); //sorry but this is the way to keep the size of the combobox in check.
|
||||||
try
|
try
|
||||||
@@ -541,4 +598,4 @@ public class ConfigPanel extends PluginPanel
|
|||||||
revalidate();
|
revalidate();
|
||||||
getScrollPane().getVerticalScrollBar().setValue(0);
|
getScrollPane().getVerticalScrollBar().setValue(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* 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<Component, Dimension> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Psikoi <https://github.com/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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ import javax.swing.ImageIcon;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.text.Document;
|
||||||
import net.runelite.client.ui.ColorScheme;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,4 +161,9 @@ public class IconTextField extends JPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Document getDocument()
|
||||||
|
{
|
||||||
|
return textField.getDocument();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 335 B |
Binary file not shown.
|
Before Width: | Height: | Size: 417 B |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Reference in New Issue
Block a user