|
|
|
|
@@ -24,10 +24,13 @@
|
|
|
|
|
*/
|
|
|
|
|
package net.runelite.client.plugins.config;
|
|
|
|
|
|
|
|
|
|
import com.google.common.base.MoreObjects;
|
|
|
|
|
import com.google.common.base.Splitter;
|
|
|
|
|
import com.google.common.base.Strings;
|
|
|
|
|
import com.google.common.collect.ComparisonChain;
|
|
|
|
|
import com.google.common.collect.Sets;
|
|
|
|
|
import com.google.common.primitives.Ints;
|
|
|
|
|
|
|
|
|
|
import java.awt.BasicStroke;
|
|
|
|
|
import java.awt.BorderLayout;
|
|
|
|
|
import java.awt.Color;
|
|
|
|
|
@@ -44,15 +47,14 @@ import java.awt.event.ItemEvent;
|
|
|
|
|
import java.awt.event.MouseAdapter;
|
|
|
|
|
import java.awt.event.MouseEvent;
|
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.lang.reflect.ParameterizedType;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.EnumSet;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.TreeMap;
|
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
import javax.inject.Inject;
|
|
|
|
|
import javax.swing.BorderFactory;
|
|
|
|
|
import javax.swing.BoxLayout;
|
|
|
|
|
@@ -62,30 +64,27 @@ import javax.swing.JCheckBox;
|
|
|
|
|
import javax.swing.JComboBox;
|
|
|
|
|
import javax.swing.JFormattedTextField;
|
|
|
|
|
import javax.swing.JLabel;
|
|
|
|
|
import javax.swing.JList;
|
|
|
|
|
import javax.swing.JMenuItem;
|
|
|
|
|
import javax.swing.JOptionPane;
|
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
|
import javax.swing.JPasswordField;
|
|
|
|
|
import javax.swing.JScrollPane;
|
|
|
|
|
import javax.swing.JSeparator;
|
|
|
|
|
import javax.swing.JSlider;
|
|
|
|
|
import javax.swing.JSpinner;
|
|
|
|
|
import javax.swing.JTextArea;
|
|
|
|
|
import javax.swing.JTextField;
|
|
|
|
|
import javax.swing.ListCellRenderer;
|
|
|
|
|
import javax.swing.ListSelectionModel;
|
|
|
|
|
import javax.swing.ScrollPaneConstants;
|
|
|
|
|
import javax.swing.SpinnerModel;
|
|
|
|
|
import javax.swing.SpinnerNumberModel;
|
|
|
|
|
import javax.swing.SwingConstants;
|
|
|
|
|
import javax.swing.SwingUtilities;
|
|
|
|
|
import javax.swing.border.CompoundBorder;
|
|
|
|
|
import javax.swing.border.EmptyBorder;
|
|
|
|
|
import javax.swing.border.MatteBorder;
|
|
|
|
|
import javax.swing.event.ChangeListener;
|
|
|
|
|
import javax.swing.plaf.basic.BasicSpinnerUI;
|
|
|
|
|
import javax.swing.text.JTextComponent;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import net.runelite.api.events.ConfigButtonClicked;
|
|
|
|
|
import net.runelite.client.config.Button;
|
|
|
|
|
import net.runelite.client.config.ConfigDescriptor;
|
|
|
|
|
import net.runelite.client.config.ConfigGroup;
|
|
|
|
|
import net.runelite.client.config.ConfigItem;
|
|
|
|
|
@@ -100,7 +99,6 @@ import net.runelite.client.config.Keybind;
|
|
|
|
|
import net.runelite.client.config.ModifierlessKeybind;
|
|
|
|
|
import net.runelite.client.config.Range;
|
|
|
|
|
import net.runelite.client.config.Units;
|
|
|
|
|
import net.runelite.client.eventbus.EventBus;
|
|
|
|
|
import net.runelite.client.eventbus.Subscribe;
|
|
|
|
|
import net.runelite.client.events.ExternalPluginsChanged;
|
|
|
|
|
import net.runelite.client.events.PluginChanged;
|
|
|
|
|
@@ -119,11 +117,11 @@ import net.runelite.client.ui.components.ToggleButton;
|
|
|
|
|
import net.runelite.client.ui.components.colorpicker.ColorPickerManager;
|
|
|
|
|
import net.runelite.client.ui.components.colorpicker.RuneliteColorPicker;
|
|
|
|
|
import net.runelite.client.util.ColorUtil;
|
|
|
|
|
import net.runelite.client.util.DeferredDocumentChangedListener;
|
|
|
|
|
import net.runelite.client.util.ImageUtil;
|
|
|
|
|
import net.runelite.client.util.LinkBrowser;
|
|
|
|
|
import net.runelite.client.util.SwingUtil;
|
|
|
|
|
import net.runelite.client.util.Text;
|
|
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
class ConfigPanel extends PluginPanel
|
|
|
|
|
@@ -138,33 +136,6 @@ class ConfigPanel extends PluginPanel
|
|
|
|
|
|
|
|
|
|
private static final Map<ConfigSectionDescriptor, Boolean> sectionExpandStates = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
private final FixedWidthPanel mainPanel;
|
|
|
|
|
private final JLabel title;
|
|
|
|
|
private final PluginToggleButton pluginToggle;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private PluginListPanel pluginList;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private ConfigManager configManager;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private PluginManager pluginManager;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private ExternalPluginManager externalPluginManager;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private OPRSExternalPluginManager oprsExternalPluginManager;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private ColorPickerManager colorPickerManager;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private EventBus eventBus;
|
|
|
|
|
|
|
|
|
|
private PluginConfigurationDescriptor pluginConfig = null;
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
{
|
|
|
|
|
final BufferedImage backIcon = ImageUtil.loadImageResource(ConfigPanel.class, "config_back_icon.png");
|
|
|
|
|
@@ -180,10 +151,36 @@ class ConfigPanel extends PluginPanel
|
|
|
|
|
SECTION_RETRACT_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(sectionExpandIcon, -100));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ConfigPanel()
|
|
|
|
|
private final PluginListPanel pluginList;
|
|
|
|
|
private final ConfigManager configManager;
|
|
|
|
|
private final PluginManager pluginManager;
|
|
|
|
|
private final ExternalPluginManager externalPluginManager;
|
|
|
|
|
private final ColorPickerManager colorPickerManager;
|
|
|
|
|
|
|
|
|
|
private final ListCellRenderer<Enum<?>> listCellRenderer = new ComboBoxListRenderer<>();
|
|
|
|
|
|
|
|
|
|
private final FixedWidthPanel mainPanel;
|
|
|
|
|
private final JLabel title;
|
|
|
|
|
private final PluginToggleButton pluginToggle;
|
|
|
|
|
|
|
|
|
|
private PluginConfigurationDescriptor pluginConfig = null;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private OPRSExternalPluginManager oprsExternalPluginManager;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private ConfigPanel(PluginListPanel pluginList, ConfigManager configManager, PluginManager pluginManager,
|
|
|
|
|
ExternalPluginManager externalPluginManager, ColorPickerManager colorPickerManager, OPRSExternalPluginManager oprsExternalPluginManager)
|
|
|
|
|
{
|
|
|
|
|
super(false);
|
|
|
|
|
|
|
|
|
|
this.pluginList = pluginList;
|
|
|
|
|
this.configManager = configManager;
|
|
|
|
|
this.pluginManager = pluginManager;
|
|
|
|
|
this.externalPluginManager = externalPluginManager;
|
|
|
|
|
this.colorPickerManager = colorPickerManager;
|
|
|
|
|
this.oprsExternalPluginManager = oprsExternalPluginManager;
|
|
|
|
|
|
|
|
|
|
setLayout(new BorderLayout());
|
|
|
|
|
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
|
|
|
|
|
|
|
|
|
@@ -462,436 +459,63 @@ class ConfigPanel extends PluginPanel
|
|
|
|
|
configEntryName.setToolTipText("<html>" + name + ":<br>" + cid.getItem().description() + "</html>");
|
|
|
|
|
PluginListItem.addLabelPopupMenu(configEntryName, createResetMenuItem(pluginConfig, cid));
|
|
|
|
|
item.add(configEntryName, BorderLayout.CENTER);
|
|
|
|
|
item.setName(cid.getItem().keyName());
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == Button.class)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ConfigItem cidItem = cid.getItem();
|
|
|
|
|
JButton button = new JButton(cidItem.name());
|
|
|
|
|
button.addActionListener((e) ->
|
|
|
|
|
{
|
|
|
|
|
ConfigButtonClicked event = new ConfigButtonClicked();
|
|
|
|
|
event.setGroup(cd.getGroup().value());
|
|
|
|
|
event.setKey(cid.getItem().keyName());
|
|
|
|
|
eventBus.post(event);
|
|
|
|
|
});
|
|
|
|
|
item.add(button);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
log.error("Adding action listener failed: {}", ex.getMessage());
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == boolean.class)
|
|
|
|
|
{
|
|
|
|
|
JCheckBox checkbox = new ToggleButton();
|
|
|
|
|
checkbox.setPreferredSize(new Dimension(26, 25));
|
|
|
|
|
checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())));
|
|
|
|
|
checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid));
|
|
|
|
|
|
|
|
|
|
item.add(checkbox, BorderLayout.EAST);
|
|
|
|
|
item.add(createCheckbox(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType().isAssignableFrom(Consumer.class))
|
|
|
|
|
else if (cid.getType() == int.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);
|
|
|
|
|
item.add(createIntSpinner(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == int.class)
|
|
|
|
|
{
|
|
|
|
|
int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
|
|
|
|
|
|
|
|
|
Units units = cid.getUnits();
|
|
|
|
|
Range range = cid.getRange();
|
|
|
|
|
int min = 0, max = Integer.MAX_VALUE;
|
|
|
|
|
if (range != null)
|
|
|
|
|
{
|
|
|
|
|
min = range.min();
|
|
|
|
|
max = range.max();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Config may previously have been out of range
|
|
|
|
|
value = Ints.constrainToRange(value, min, max);
|
|
|
|
|
|
|
|
|
|
if (max < Integer.MAX_VALUE)
|
|
|
|
|
{
|
|
|
|
|
JLabel sliderValueLabel = new JLabel();
|
|
|
|
|
JSlider slider = new JSlider(min, max, value);
|
|
|
|
|
slider.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
|
|
|
|
if (units != null)
|
|
|
|
|
{
|
|
|
|
|
sliderValueLabel.setText(slider.getValue() + units.value());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sliderValueLabel.setText(String.valueOf(slider.getValue()));
|
|
|
|
|
}
|
|
|
|
|
slider.setPreferredSize(new Dimension(80, 25));
|
|
|
|
|
slider.addChangeListener((l) ->
|
|
|
|
|
{
|
|
|
|
|
if (units != null)
|
|
|
|
|
{
|
|
|
|
|
sliderValueLabel.setText(slider.getValue() + units.value());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sliderValueLabel.setText(String.valueOf(slider.getValue()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!slider.getValueIsAdjusting())
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(slider, cd, cid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
SpinnerModel model = new SpinnerNumberModel(value, min, max, 1);
|
|
|
|
|
JSpinner spinner = new JSpinner(model);
|
|
|
|
|
Component editor = spinner.getEditor();
|
|
|
|
|
JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField();
|
|
|
|
|
spinnerTextField.setColumns(SPINNER_FIELD_WIDTH);
|
|
|
|
|
spinner.setUI(new BasicSpinnerUI()
|
|
|
|
|
{
|
|
|
|
|
protected Component createNextButton()
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected Component createPreviousButton()
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
JPanel subPanel = new JPanel();
|
|
|
|
|
subPanel.setPreferredSize(new Dimension(110, 25));
|
|
|
|
|
subPanel.setLayout(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
spinner.addChangeListener((ce) ->
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(spinner, cd, cid);
|
|
|
|
|
|
|
|
|
|
if (units != null)
|
|
|
|
|
{
|
|
|
|
|
sliderValueLabel.setText(spinner.getValue() + units.value());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sliderValueLabel.setText(String.valueOf(spinner.getValue()));
|
|
|
|
|
}
|
|
|
|
|
slider.setValue((Integer) spinner.getValue());
|
|
|
|
|
|
|
|
|
|
subPanel.add(sliderValueLabel, BorderLayout.WEST);
|
|
|
|
|
subPanel.add(slider, BorderLayout.EAST);
|
|
|
|
|
subPanel.remove(spinner);
|
|
|
|
|
|
|
|
|
|
validate();
|
|
|
|
|
repaint();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
sliderValueLabel.addMouseListener(new MouseAdapter()
|
|
|
|
|
{
|
|
|
|
|
public void mouseClicked(MouseEvent e)
|
|
|
|
|
{
|
|
|
|
|
spinner.setValue(slider.getValue());
|
|
|
|
|
|
|
|
|
|
subPanel.remove(sliderValueLabel);
|
|
|
|
|
subPanel.remove(slider);
|
|
|
|
|
subPanel.add(spinner, BorderLayout.EAST);
|
|
|
|
|
|
|
|
|
|
validate();
|
|
|
|
|
repaint();
|
|
|
|
|
|
|
|
|
|
final JTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
|
|
|
|
|
tf.requestFocusInWindow();
|
|
|
|
|
SwingUtilities.invokeLater(tf::selectAll);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
subPanel.add(sliderValueLabel, BorderLayout.WEST);
|
|
|
|
|
subPanel.add(slider, BorderLayout.EAST);
|
|
|
|
|
|
|
|
|
|
item.add(subPanel, BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SpinnerModel model = new SpinnerNumberModel(value, min, max, 1);
|
|
|
|
|
JSpinner spinner = new JSpinner(model);
|
|
|
|
|
Component editor = spinner.getEditor();
|
|
|
|
|
JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField();
|
|
|
|
|
spinnerTextField.setColumns(SPINNER_FIELD_WIDTH);
|
|
|
|
|
spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid));
|
|
|
|
|
|
|
|
|
|
if (units != null)
|
|
|
|
|
{
|
|
|
|
|
spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item.add(spinner, BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (cid.getType() == double.class)
|
|
|
|
|
{
|
|
|
|
|
double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class);
|
|
|
|
|
|
|
|
|
|
SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1);
|
|
|
|
|
JSpinner spinner = new JSpinner(model);
|
|
|
|
|
Component editor = spinner.getEditor();
|
|
|
|
|
JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField();
|
|
|
|
|
spinnerTextField.setColumns(SPINNER_FIELD_WIDTH);
|
|
|
|
|
spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid));
|
|
|
|
|
|
|
|
|
|
item.add(spinner, BorderLayout.EAST);
|
|
|
|
|
item.add(createDoubleSpinner(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == String.class)
|
|
|
|
|
else if (cid.getType() == String.class)
|
|
|
|
|
{
|
|
|
|
|
JTextComponent textField;
|
|
|
|
|
|
|
|
|
|
if (cid.getItem().secret())
|
|
|
|
|
{
|
|
|
|
|
textField = new JPasswordField();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
final JTextArea textArea = new JTextArea();
|
|
|
|
|
textArea.setLineWrap(true);
|
|
|
|
|
textArea.setWrapStyleWord(true);
|
|
|
|
|
textField = textArea;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
|
|
|
|
textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
|
|
|
|
|
|
|
|
|
textField.addFocusListener(new FocusAdapter()
|
|
|
|
|
{
|
|
|
|
|
@Override
|
|
|
|
|
public void focusLost(FocusEvent e)
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(textField, cd, cid);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (cid.getItem().parse())
|
|
|
|
|
{
|
|
|
|
|
JLabel parsingLabel = new JLabel();
|
|
|
|
|
parsingLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
|
|
|
|
parsingLabel.setPreferredSize(new Dimension(PANEL_WIDTH, 15));
|
|
|
|
|
|
|
|
|
|
DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener();
|
|
|
|
|
listener.addChangeListener(e ->
|
|
|
|
|
{
|
|
|
|
|
if (cid.getItem().parse())
|
|
|
|
|
{
|
|
|
|
|
parseLabel(cid.getItem(), parsingLabel, textField.getText());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
textField.getDocument().addDocumentListener(listener);
|
|
|
|
|
|
|
|
|
|
item.add(configEntryName, BorderLayout.NORTH);
|
|
|
|
|
item.add(textField, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parseLabel(cid.getItem(), parsingLabel, textField.getText());
|
|
|
|
|
item.add(parsingLabel, BorderLayout.SOUTH);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
item.add(textField, BorderLayout.SOUTH);
|
|
|
|
|
}
|
|
|
|
|
item.add(createTextField(cd, cid), BorderLayout.SOUTH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == Color.class)
|
|
|
|
|
else if (cid.getType() == Color.class)
|
|
|
|
|
{
|
|
|
|
|
Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class);
|
|
|
|
|
|
|
|
|
|
ColorJButton colorPickerBtn;
|
|
|
|
|
|
|
|
|
|
boolean alphaHidden = cid.getAlpha() == null;
|
|
|
|
|
|
|
|
|
|
if (existing == null)
|
|
|
|
|
{
|
|
|
|
|
colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase();
|
|
|
|
|
colorPickerBtn = new ColorJButton(colorHex, existing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
colorPickerBtn.setFocusable(false);
|
|
|
|
|
colorPickerBtn.addMouseListener(new MouseAdapter()
|
|
|
|
|
{
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseClicked(MouseEvent e)
|
|
|
|
|
{
|
|
|
|
|
RuneliteColorPicker colorPicker = colorPickerManager.create(
|
|
|
|
|
SwingUtilities.windowForComponent(ConfigPanel.this),
|
|
|
|
|
colorPickerBtn.getColor(),
|
|
|
|
|
cid.getItem().name(),
|
|
|
|
|
alphaHidden);
|
|
|
|
|
colorPicker.setLocation(getLocationOnScreen());
|
|
|
|
|
colorPicker.setOnColorChange(c ->
|
|
|
|
|
{
|
|
|
|
|
colorPickerBtn.setColor(c);
|
|
|
|
|
colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase());
|
|
|
|
|
});
|
|
|
|
|
colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid));
|
|
|
|
|
colorPicker.setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
item.add(colorPickerBtn, BorderLayout.EAST);
|
|
|
|
|
item.add(createColorPicker(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == Dimension.class)
|
|
|
|
|
else if (cid.getType() == Dimension.class)
|
|
|
|
|
{
|
|
|
|
|
JPanel dimensionPanel = new JPanel();
|
|
|
|
|
dimensionPanel.setLayout(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName());
|
|
|
|
|
String[] splitStr = str.split("x");
|
|
|
|
|
int width = Integer.parseInt(splitStr[0]);
|
|
|
|
|
int height = Integer.parseInt(splitStr[1]);
|
|
|
|
|
|
|
|
|
|
SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1);
|
|
|
|
|
JSpinner widthSpinner = new JSpinner(widthModel);
|
|
|
|
|
Component widthEditor = widthSpinner.getEditor();
|
|
|
|
|
JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField();
|
|
|
|
|
widthSpinnerTextField.setColumns(4);
|
|
|
|
|
|
|
|
|
|
SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1);
|
|
|
|
|
JSpinner heightSpinner = new JSpinner(heightModel);
|
|
|
|
|
Component heightEditor = heightSpinner.getEditor();
|
|
|
|
|
JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField();
|
|
|
|
|
heightSpinnerTextField.setColumns(4);
|
|
|
|
|
|
|
|
|
|
ChangeListener listener = e ->
|
|
|
|
|
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue());
|
|
|
|
|
|
|
|
|
|
widthSpinner.addChangeListener(listener);
|
|
|
|
|
heightSpinner.addChangeListener(listener);
|
|
|
|
|
|
|
|
|
|
dimensionPanel.add(widthSpinner, BorderLayout.WEST);
|
|
|
|
|
dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER);
|
|
|
|
|
dimensionPanel.add(heightSpinner, BorderLayout.EAST);
|
|
|
|
|
|
|
|
|
|
item.add(dimensionPanel, BorderLayout.EAST);
|
|
|
|
|
item.add(createDimension(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType().isEnum())
|
|
|
|
|
else if (cid.getType() instanceof Class && ((Class<?>) cid.getType()).isEnum())
|
|
|
|
|
{
|
|
|
|
|
Class<? extends Enum> type = (Class<? extends Enum>) cid.getType();
|
|
|
|
|
|
|
|
|
|
JComboBox<Enum<?>> box = new JComboBox<Enum<?>>(type.getEnumConstants()); // NOPMD: UseDiamondOperator
|
|
|
|
|
// set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer
|
|
|
|
|
// to build components for each combobox element in order to compute the display size of the
|
|
|
|
|
// combobox
|
|
|
|
|
box.setRenderer(new ComboBoxListRenderer<>());
|
|
|
|
|
box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25));
|
|
|
|
|
box.setForeground(Color.WHITE);
|
|
|
|
|
box.setFocusable(false);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Enum<?> selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
|
|
|
|
box.setSelectedItem(selectedItem);
|
|
|
|
|
box.setToolTipText(Text.titleCase(selectedItem));
|
|
|
|
|
}
|
|
|
|
|
catch (IllegalArgumentException ex)
|
|
|
|
|
{
|
|
|
|
|
log.debug("invalid seleced item", ex);
|
|
|
|
|
}
|
|
|
|
|
box.addItemListener(e ->
|
|
|
|
|
{
|
|
|
|
|
if (e.getStateChange() == ItemEvent.SELECTED)
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(box, cd, cid);
|
|
|
|
|
box.setToolTipText(Text.titleCase((Enum<?>) box.getSelectedItem()));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
item.add(box, BorderLayout.EAST);
|
|
|
|
|
item.add(createComboBox(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class)
|
|
|
|
|
else if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class)
|
|
|
|
|
{
|
|
|
|
|
Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(),
|
|
|
|
|
cid.getItem().keyName(),
|
|
|
|
|
(Class<? extends Keybind>) cid.getType());
|
|
|
|
|
|
|
|
|
|
HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class);
|
|
|
|
|
|
|
|
|
|
button.addFocusListener(new FocusAdapter()
|
|
|
|
|
{
|
|
|
|
|
@Override
|
|
|
|
|
public void focusLost(FocusEvent e)
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(button, cd, cid);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
item.add(button, BorderLayout.EAST);
|
|
|
|
|
item.add(createKeybind(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cid.getType() == EnumSet.class)
|
|
|
|
|
else if (cid.getType() instanceof ParameterizedType)
|
|
|
|
|
{
|
|
|
|
|
Class enumType = cid.getItem().enumClass();
|
|
|
|
|
|
|
|
|
|
EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(),
|
|
|
|
|
cid.getItem().keyName(), EnumSet.class);
|
|
|
|
|
if (enumSet == null || enumSet.contains(null))
|
|
|
|
|
ParameterizedType parameterizedType = (ParameterizedType) cid.getType();
|
|
|
|
|
if (parameterizedType.getRawType() == Set.class)
|
|
|
|
|
{
|
|
|
|
|
enumSet = EnumSet.noneOf(enumType);
|
|
|
|
|
item.add(createList(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (cid.getType() instanceof EnumSet)
|
|
|
|
|
{
|
|
|
|
|
ParameterizedType parameterizedType = (ParameterizedType) cid.getType();
|
|
|
|
|
if (parameterizedType.getRawType() == EnumSet.class)
|
|
|
|
|
{
|
|
|
|
|
item.add(createList(cd, cid), BorderLayout.EAST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JPanel enumsetLayout = new JPanel(new GridLayout(0, 2));
|
|
|
|
|
List<JCheckBox> jcheckboxes = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
for (Object obj : enumType.getEnumConstants())
|
|
|
|
|
{
|
|
|
|
|
String option = String.valueOf(obj).toLowerCase().replace("_", " ");
|
|
|
|
|
|
|
|
|
|
JCheckBox checkbox = new ToggleButton(option);
|
|
|
|
|
checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
|
|
|
|
checkbox.setSelected(enumSet.contains(obj));
|
|
|
|
|
jcheckboxes.add(checkbox);
|
|
|
|
|
|
|
|
|
|
enumsetLayout.add(checkbox);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid)));
|
|
|
|
|
|
|
|
|
|
item.add(enumsetLayout, BorderLayout.SOUTH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JPanel section = sectionWidgets.get(cid.getItem().section());
|
|
|
|
|
JPanel title = titleWidgets.get(cid.getItem().title());
|
|
|
|
|
|
|
|
|
|
if (section != null)
|
|
|
|
|
if (section == null)
|
|
|
|
|
{
|
|
|
|
|
section.add(item);
|
|
|
|
|
}
|
|
|
|
|
else if (title != null)
|
|
|
|
|
{
|
|
|
|
|
title.add(item);
|
|
|
|
|
topLevelPanels.put(cid, item);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
topLevelPanels.put(cid, item);
|
|
|
|
|
section.add(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -927,69 +551,249 @@ class ConfigPanel extends PluginPanel
|
|
|
|
|
revalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Boolean parse(ConfigItem item, String value)
|
|
|
|
|
private JCheckBox createCheckbox(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Method parse = item.clazz().getMethod(item.method(), String.class);
|
|
|
|
|
|
|
|
|
|
return (boolean) parse.invoke(null, value);
|
|
|
|
|
}
|
|
|
|
|
catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex)
|
|
|
|
|
{
|
|
|
|
|
log.error("Parsing failed: {}", ex.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
JCheckBox checkbox = new ToggleButton();
|
|
|
|
|
checkbox.setPreferredSize(new Dimension(26, 25));
|
|
|
|
|
checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())));
|
|
|
|
|
checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid));
|
|
|
|
|
return checkbox;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void parseLabel(ConfigItem item, JLabel label, String value)
|
|
|
|
|
private JSpinner createIntSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
Boolean result = parse(item, value);
|
|
|
|
|
int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
|
|
|
|
|
|
|
|
|
if (result == null)
|
|
|
|
|
Range range = cid.getRange();
|
|
|
|
|
int min = 0, max = Integer.MAX_VALUE;
|
|
|
|
|
if (range != null)
|
|
|
|
|
{
|
|
|
|
|
label.setForeground(Color.RED);
|
|
|
|
|
label.setText("Parsing failed");
|
|
|
|
|
min = range.min();
|
|
|
|
|
max = range.max();
|
|
|
|
|
}
|
|
|
|
|
else if (result)
|
|
|
|
|
|
|
|
|
|
// Config may previously have been out of range
|
|
|
|
|
value = Ints.constrainToRange(value, min, max);
|
|
|
|
|
|
|
|
|
|
SpinnerModel model = new SpinnerNumberModel(value, min, max, 1);
|
|
|
|
|
JSpinner spinner = new JSpinner(model);
|
|
|
|
|
Component editor = spinner.getEditor();
|
|
|
|
|
JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField();
|
|
|
|
|
spinnerTextField.setColumns(SPINNER_FIELD_WIDTH);
|
|
|
|
|
spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid));
|
|
|
|
|
|
|
|
|
|
Units units = cid.getUnits();
|
|
|
|
|
if (units != null)
|
|
|
|
|
{
|
|
|
|
|
label.setForeground(Color.GREEN);
|
|
|
|
|
label.setText("Valid input");
|
|
|
|
|
spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return spinner;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JSpinner createDoubleSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class);
|
|
|
|
|
|
|
|
|
|
SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1);
|
|
|
|
|
JSpinner spinner = new JSpinner(model);
|
|
|
|
|
Component editor = spinner.getEditor();
|
|
|
|
|
JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField();
|
|
|
|
|
spinnerTextField.setColumns(SPINNER_FIELD_WIDTH);
|
|
|
|
|
spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid));
|
|
|
|
|
return spinner;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JTextComponent createTextField(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
JTextComponent textField;
|
|
|
|
|
|
|
|
|
|
if (cid.getItem().secret())
|
|
|
|
|
{
|
|
|
|
|
textField = new JPasswordField();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
label.setForeground(Color.RED);
|
|
|
|
|
label.setText("Invalid input");
|
|
|
|
|
final JTextArea textArea = new JTextArea();
|
|
|
|
|
textArea.setLineWrap(true);
|
|
|
|
|
textArea.setWrapStyleWord(true);
|
|
|
|
|
textField = textArea;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void changeConfiguration(List<JCheckBox> components, ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
Class<? extends Enum> enumType = cid.getItem().enumClass();
|
|
|
|
|
EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(),
|
|
|
|
|
cid.getItem().keyName(), EnumSet.class);
|
|
|
|
|
if (enumSet == null)
|
|
|
|
|
textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
|
|
|
|
textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
|
|
|
|
|
|
|
|
|
textField.addFocusListener(new FocusAdapter()
|
|
|
|
|
{
|
|
|
|
|
//noinspection unchecked
|
|
|
|
|
enumSet = EnumSet.noneOf(enumType);
|
|
|
|
|
}
|
|
|
|
|
enumSet.clear();
|
|
|
|
|
|
|
|
|
|
EnumSet finalEnumSet = enumSet;
|
|
|
|
|
|
|
|
|
|
//noinspection unchecked
|
|
|
|
|
components.forEach(value ->
|
|
|
|
|
{
|
|
|
|
|
if (value.isSelected())
|
|
|
|
|
@Override
|
|
|
|
|
public void focusLost(FocusEvent e)
|
|
|
|
|
{
|
|
|
|
|
finalEnumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_")));
|
|
|
|
|
changeConfiguration(textField, cd, cid);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), finalEnumSet);
|
|
|
|
|
return textField;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rebuild();
|
|
|
|
|
private ColorJButton createColorPicker(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class);
|
|
|
|
|
|
|
|
|
|
ColorJButton colorPickerBtn;
|
|
|
|
|
|
|
|
|
|
boolean alphaHidden = cid.getAlpha() == null;
|
|
|
|
|
|
|
|
|
|
if (existing == null)
|
|
|
|
|
{
|
|
|
|
|
colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase();
|
|
|
|
|
colorPickerBtn = new ColorJButton(colorHex, existing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
colorPickerBtn.setFocusable(false);
|
|
|
|
|
colorPickerBtn.addMouseListener(new MouseAdapter()
|
|
|
|
|
{
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseClicked(MouseEvent e)
|
|
|
|
|
{
|
|
|
|
|
RuneliteColorPicker colorPicker = colorPickerManager.create(
|
|
|
|
|
SwingUtilities.windowForComponent(ConfigPanel.this),
|
|
|
|
|
colorPickerBtn.getColor(),
|
|
|
|
|
cid.getItem().name(),
|
|
|
|
|
alphaHidden);
|
|
|
|
|
colorPicker.setLocation(getLocationOnScreen());
|
|
|
|
|
colorPicker.setOnColorChange(c ->
|
|
|
|
|
{
|
|
|
|
|
colorPickerBtn.setColor(c);
|
|
|
|
|
colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase());
|
|
|
|
|
});
|
|
|
|
|
colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid));
|
|
|
|
|
colorPicker.setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return colorPickerBtn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JPanel createDimension(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
JPanel dimensionPanel = new JPanel();
|
|
|
|
|
dimensionPanel.setLayout(new BorderLayout());
|
|
|
|
|
|
|
|
|
|
String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName());
|
|
|
|
|
String[] splitStr = str.split("x");
|
|
|
|
|
int width = Integer.parseInt(splitStr[0]);
|
|
|
|
|
int height = Integer.parseInt(splitStr[1]);
|
|
|
|
|
|
|
|
|
|
SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1);
|
|
|
|
|
JSpinner widthSpinner = new JSpinner(widthModel);
|
|
|
|
|
Component widthEditor = widthSpinner.getEditor();
|
|
|
|
|
JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField();
|
|
|
|
|
widthSpinnerTextField.setColumns(4);
|
|
|
|
|
|
|
|
|
|
SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1);
|
|
|
|
|
JSpinner heightSpinner = new JSpinner(heightModel);
|
|
|
|
|
Component heightEditor = heightSpinner.getEditor();
|
|
|
|
|
JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField();
|
|
|
|
|
heightSpinnerTextField.setColumns(4);
|
|
|
|
|
|
|
|
|
|
ChangeListener listener = e ->
|
|
|
|
|
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue());
|
|
|
|
|
|
|
|
|
|
widthSpinner.addChangeListener(listener);
|
|
|
|
|
heightSpinner.addChangeListener(listener);
|
|
|
|
|
|
|
|
|
|
dimensionPanel.add(widthSpinner, BorderLayout.WEST);
|
|
|
|
|
dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER);
|
|
|
|
|
dimensionPanel.add(heightSpinner, BorderLayout.EAST);
|
|
|
|
|
|
|
|
|
|
return dimensionPanel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JComboBox<Enum<?>> createComboBox(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
Class<? extends Enum> type = (Class<? extends Enum>) cid.getType();
|
|
|
|
|
|
|
|
|
|
JComboBox<Enum<?>> box = new JComboBox<Enum<?>>(type.getEnumConstants()); // NOPMD: UseDiamondOperator
|
|
|
|
|
// set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer
|
|
|
|
|
// to build components for each combobox element in order to compute the display size of the
|
|
|
|
|
// combobox
|
|
|
|
|
box.setRenderer(listCellRenderer);
|
|
|
|
|
box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25));
|
|
|
|
|
box.setForeground(Color.WHITE);
|
|
|
|
|
box.setFocusable(false);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Enum<?> selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
|
|
|
|
box.setSelectedItem(selectedItem);
|
|
|
|
|
box.setToolTipText(Text.titleCase(selectedItem));
|
|
|
|
|
}
|
|
|
|
|
catch (IllegalArgumentException ex)
|
|
|
|
|
{
|
|
|
|
|
log.debug("invalid selected item", ex);
|
|
|
|
|
}
|
|
|
|
|
box.addItemListener(e ->
|
|
|
|
|
{
|
|
|
|
|
if (e.getStateChange() == ItemEvent.SELECTED)
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(box, cd, cid);
|
|
|
|
|
box.setToolTipText(Text.titleCase((Enum<?>) box.getSelectedItem()));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private HotkeyButton createKeybind(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(),
|
|
|
|
|
cid.getItem().keyName(),
|
|
|
|
|
(Class<? extends Keybind>) cid.getType());
|
|
|
|
|
|
|
|
|
|
HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class);
|
|
|
|
|
|
|
|
|
|
button.addFocusListener(new FocusAdapter()
|
|
|
|
|
{
|
|
|
|
|
@Override
|
|
|
|
|
public void focusLost(FocusEvent e)
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(button, cd, cid);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return button;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JList<Enum<?>> createList(ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
{
|
|
|
|
|
ParameterizedType parameterizedType = (ParameterizedType) cid.getType();
|
|
|
|
|
Class<? extends Enum> type = (Class<? extends Enum>) parameterizedType.getActualTypeArguments()[0];
|
|
|
|
|
Set<? extends Enum> set = configManager.getConfiguration(cd.getGroup().value(), null,
|
|
|
|
|
cid.getItem().keyName(), parameterizedType);
|
|
|
|
|
|
|
|
|
|
JList<Enum<?>> list = new JList<Enum<?>>(type.getEnumConstants()); // NOPMD: UseDiamondOperator
|
|
|
|
|
list.setCellRenderer(listCellRenderer);
|
|
|
|
|
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
|
|
|
|
list.setLayoutOrientation(JList.VERTICAL);
|
|
|
|
|
list.setSelectedIndices(
|
|
|
|
|
MoreObjects.firstNonNull(set, Collections.emptySet())
|
|
|
|
|
.stream()
|
|
|
|
|
.mapToInt(e -> ArrayUtils.indexOf(type.getEnumConstants(), e))
|
|
|
|
|
.toArray());
|
|
|
|
|
list.addFocusListener(new FocusAdapter()
|
|
|
|
|
{
|
|
|
|
|
@Override
|
|
|
|
|
public void focusLost(FocusEvent e)
|
|
|
|
|
{
|
|
|
|
|
changeConfiguration(list, cd, cid);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid)
|
|
|
|
|
@@ -1019,11 +823,6 @@ class ConfigPanel extends PluginPanel
|
|
|
|
|
JSpinner spinner = (JSpinner) component;
|
|
|
|
|
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), "" + spinner.getValue());
|
|
|
|
|
}
|
|
|
|
|
else if (component instanceof JSlider)
|
|
|
|
|
{
|
|
|
|
|
JSlider slider = (JSlider) component;
|
|
|
|
|
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), slider.getValue());
|
|
|
|
|
}
|
|
|
|
|
else if (component instanceof JTextComponent)
|
|
|
|
|
{
|
|
|
|
|
JTextComponent textField = (JTextComponent) component;
|
|
|
|
|
@@ -1044,6 +843,13 @@ class ConfigPanel extends PluginPanel
|
|
|
|
|
HotkeyButton hotkeyButton = (HotkeyButton) component;
|
|
|
|
|
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), hotkeyButton.getValue());
|
|
|
|
|
}
|
|
|
|
|
else if (component instanceof JList)
|
|
|
|
|
{
|
|
|
|
|
JList<?> list = (JList<?>) component;
|
|
|
|
|
List<?> selectedValues = list.getSelectedValuesList();
|
|
|
|
|
|
|
|
|
|
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Sets.newHashSet(selectedValues));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enableDisable(component, cid);
|
|
|
|
|
rebuild();
|
|
|
|
|
@@ -1121,7 +927,7 @@ class ConfigPanel extends PluginPanel
|
|
|
|
|
{
|
|
|
|
|
show = Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName()));
|
|
|
|
|
}
|
|
|
|
|
else if (cid2.getType().isEnum())
|
|
|
|
|
else if (cid2.getType() instanceof Class && ((Class<?>) cid2.getType()).isEnum())
|
|
|
|
|
{
|
|
|
|
|
Class<? extends Enum> type = (Class<? extends Enum>) cid2.getType();
|
|
|
|
|
try
|
|
|
|
|
|