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.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<String, JPanel> 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<String, JPanel> 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<? extends Enum> type = (Class<? extends Enum>) 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.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();
|
||||
}
|
||||
|
||||
}
|
||||
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