config: add support for enum sets
This commit is contained in:
@@ -99,11 +99,9 @@ class ConfigInvocationHandler implements InvocationHandler
|
||||
}
|
||||
|
||||
// Convert value to return type
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
try
|
||||
{
|
||||
Object objectValue = ConfigManager.stringToObject(value, returnType);
|
||||
Object objectValue = manager.stringToObject(value, method.getGenericReturnType());
|
||||
cache.put(method, objectValue == null ? NULL : objectValue);
|
||||
return objectValue;
|
||||
}
|
||||
@@ -155,7 +153,7 @@ class ConfigInvocationHandler implements InvocationHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
String newValueStr = ConfigManager.objectToString(newValue);
|
||||
String newValueStr = manager.objectToString(newValue);
|
||||
manager.setConfiguration(group.value(), item.keyName(), newValueStr);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -24,13 +24,14 @@
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class ConfigItemDescriptor implements ConfigObject
|
||||
{
|
||||
private final ConfigItem item;
|
||||
private final Class<?> type;
|
||||
private final Type type;
|
||||
private final Range range;
|
||||
private final Alpha alpha;
|
||||
private final Units units;
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.hash.Hasher;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.gson.Gson;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
@@ -43,7 +44,9 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.AtomicMoveNotSupportedException;
|
||||
@@ -120,6 +123,7 @@ public class ConfigManager
|
||||
private final File settingsFileInput;
|
||||
private final EventBus eventBus;
|
||||
private final OkHttpClient okHttpClient;
|
||||
private final Gson gson;
|
||||
|
||||
private AccountSession session;
|
||||
private ConfigClient configClient;
|
||||
@@ -143,13 +147,15 @@ public class ConfigManager
|
||||
ScheduledExecutorService scheduledExecutorService,
|
||||
EventBus eventBus,
|
||||
OkHttpClient okHttpClient,
|
||||
@Nullable Client client)
|
||||
@Nullable Client client,
|
||||
Gson gson)
|
||||
{
|
||||
this.settingsFileInput = config;
|
||||
this.eventBus = eventBus;
|
||||
this.okHttpClient = okHttpClient;
|
||||
this.client = client;
|
||||
this.propertiesFile = getPropertiesFile();
|
||||
this.gson = gson;
|
||||
|
||||
scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
|
||||
}
|
||||
@@ -449,12 +455,12 @@ public class ConfigManager
|
||||
return properties.getProperty(getWholeKey(groupName, profile, key));
|
||||
}
|
||||
|
||||
public <T> T getConfiguration(String groupName, String key, Class<T> clazz)
|
||||
public <T> T getConfiguration(String groupName, String key, Type clazz)
|
||||
{
|
||||
return getConfiguration(groupName, null, key, clazz);
|
||||
}
|
||||
|
||||
public <T> T getRSProfileConfiguration(String groupName, String key, Class<T> clazz)
|
||||
public <T> T getRSProfileConfiguration(String groupName, String key, Type clazz)
|
||||
{
|
||||
String rsProfileKey = this.rsProfileKey;
|
||||
if (rsProfileKey == null)
|
||||
@@ -465,14 +471,14 @@ public class ConfigManager
|
||||
return getConfiguration(groupName, rsProfileKey, key, clazz);
|
||||
}
|
||||
|
||||
public <T> T getConfiguration(String groupName, String profile, String key, Class<T> clazz)
|
||||
public <T> T getConfiguration(String groupName, String profile, String key, Type type)
|
||||
{
|
||||
String value = getConfiguration(groupName, profile, key);
|
||||
if (!Strings.isNullOrEmpty(value))
|
||||
{
|
||||
try
|
||||
{
|
||||
return (T) stringToObject(value, clazz);
|
||||
return (T) stringToObject(value, type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -525,17 +531,17 @@ public class ConfigManager
|
||||
eventBus.post(configChanged);
|
||||
}
|
||||
|
||||
public void setConfiguration(String groupName, String profile, String key, Object value)
|
||||
public <T> void setConfiguration(String groupName, String profile, String key, T value)
|
||||
{
|
||||
setConfiguration(groupName, profile, key, objectToString(value));
|
||||
}
|
||||
|
||||
public void setConfiguration(String groupName, String key, Object value)
|
||||
public <T> void setConfiguration(String groupName, String key, T value)
|
||||
{
|
||||
setConfiguration(groupName, null, key, value);
|
||||
}
|
||||
|
||||
public void setRSProfileConfiguration(String groupName, String key, Object value)
|
||||
public <T> void setRSProfileConfiguration(String groupName, String key, T value)
|
||||
{
|
||||
String rsProfileKey = this.rsProfileKey;
|
||||
if (rsProfileKey == null)
|
||||
@@ -657,7 +663,7 @@ public class ConfigManager
|
||||
.filter(m -> m.getParameterCount() == 0 && m.isAnnotationPresent(ConfigItem.class))
|
||||
.map(m -> new ConfigItemDescriptor(
|
||||
m.getDeclaredAnnotation(ConfigItem.class),
|
||||
m.getReturnType(),
|
||||
m.getGenericReturnType(),
|
||||
m.getDeclaredAnnotation(Range.class),
|
||||
m.getDeclaredAnnotation(Alpha.class),
|
||||
m.getDeclaredAnnotation(Units.class)
|
||||
@@ -714,7 +720,7 @@ public class ConfigManager
|
||||
{
|
||||
// This checks if it is set and is also unmarshallable to the correct type; so
|
||||
// we will overwrite invalid config values with the default
|
||||
Object current = getConfiguration(group.value(), item.keyName(), method.getReturnType());
|
||||
Object current = getConfiguration(group.value(), item.keyName(), method.getGenericReturnType());
|
||||
if (current != null)
|
||||
{
|
||||
continue; // something else is already set
|
||||
@@ -748,7 +754,7 @@ public class ConfigManager
|
||||
}
|
||||
}
|
||||
|
||||
static Object stringToObject(String str, Class<?> type)
|
||||
Object stringToObject(String str, Type type)
|
||||
{
|
||||
if (type == boolean.class || type == Boolean.class)
|
||||
{
|
||||
@@ -789,7 +795,7 @@ public class ConfigManager
|
||||
int height = Integer.parseInt(splitStr[3]);
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
if (type.isEnum())
|
||||
if (type instanceof Class && ((Class<?>) type).isEnum())
|
||||
{
|
||||
return Enum.valueOf((Class<? extends Enum>) type, str);
|
||||
}
|
||||
@@ -824,11 +830,19 @@ public class ConfigManager
|
||||
{
|
||||
return Base64.getUrlDecoder().decode(str);
|
||||
}
|
||||
if (type instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
if (parameterizedType.getRawType() == Set.class)
|
||||
{
|
||||
return gson.fromJson(str, parameterizedType);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static String objectToString(Object object)
|
||||
String objectToString(Object object)
|
||||
{
|
||||
if (object instanceof Color)
|
||||
{
|
||||
@@ -875,6 +889,10 @@ public class ConfigManager
|
||||
{
|
||||
return Base64.getUrlEncoder().encodeToString((byte[]) object);
|
||||
}
|
||||
if (object instanceof Set)
|
||||
{
|
||||
return gson.toJson(object, Set.class);
|
||||
}
|
||||
return object == null ? null : object.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.config;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
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.BorderLayout;
|
||||
import java.awt.Color;
|
||||
@@ -37,8 +39,12 @@ import java.awt.event.ItemEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.BorderFactory;
|
||||
@@ -49,6 +55,7 @@ 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;
|
||||
@@ -56,6 +63,8 @@ import javax.swing.JPasswordField;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
@@ -97,6 +106,7 @@ import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@Slf4j
|
||||
class ConfigPanel extends PluginPanel
|
||||
@@ -111,27 +121,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 ColorPickerManager colorPickerManager;
|
||||
|
||||
private PluginConfigurationDescriptor pluginConfig = null;
|
||||
|
||||
static
|
||||
{
|
||||
final BufferedImage backIcon = ImageUtil.loadImageResource(ConfigPanel.class, "config_back_icon.png");
|
||||
@@ -147,10 +136,32 @@ 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 ConfigPanel(PluginListPanel pluginList, ConfigManager configManager, PluginManager pluginManager,
|
||||
ExternalPluginManager externalPluginManager, ColorPickerManager colorPickerManager)
|
||||
{
|
||||
super(false);
|
||||
|
||||
this.pluginList = pluginList;
|
||||
this.configManager = configManager;
|
||||
this.pluginManager = pluginManager;
|
||||
this.externalPluginManager = externalPluginManager;
|
||||
this.colorPickerManager = colorPickerManager;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
@@ -359,7 +370,7 @@ class ConfigPanel extends PluginPanel
|
||||
{
|
||||
item.add(createDimension(cd, cid), BorderLayout.EAST);
|
||||
}
|
||||
else if (cid.getType().isEnum())
|
||||
else if (cid.getType() instanceof Class && ((Class<?>) cid.getType()).isEnum())
|
||||
{
|
||||
item.add(createComboBox(cd, cid), BorderLayout.EAST);
|
||||
}
|
||||
@@ -367,6 +378,14 @@ class ConfigPanel extends PluginPanel
|
||||
{
|
||||
item.add(createKeybind(cd, cid), BorderLayout.EAST);
|
||||
}
|
||||
else if (cid.getType() instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType parameterizedType = (ParameterizedType) cid.getType();
|
||||
if (parameterizedType.getRawType() == Set.class)
|
||||
{
|
||||
item.add(createList(cd, cid), BorderLayout.EAST);
|
||||
}
|
||||
}
|
||||
|
||||
JPanel section = sectionWidgets.get(cid.getItem().section());
|
||||
if (section == null)
|
||||
@@ -581,7 +600,7 @@ class ConfigPanel extends PluginPanel
|
||||
// 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.setRenderer(listCellRenderer);
|
||||
box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25));
|
||||
box.setForeground(Color.WHITE);
|
||||
box.setFocusable(false);
|
||||
@@ -594,7 +613,7 @@ class ConfigPanel extends PluginPanel
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
log.debug("invalid seleced item", ex);
|
||||
log.debug("invalid selected item", ex);
|
||||
}
|
||||
box.addItemListener(e ->
|
||||
{
|
||||
@@ -628,6 +647,34 @@ class ConfigPanel extends PluginPanel
|
||||
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)
|
||||
{
|
||||
final ConfigItem configItem = cid.getItem();
|
||||
@@ -675,6 +722,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));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -59,9 +59,9 @@ public final class ComboBoxListRenderer<T> extends JLabel implements ListCellRen
|
||||
setBorder(new EmptyBorder(5, 5, 5, 0));
|
||||
|
||||
String text;
|
||||
if (o instanceof Enum)
|
||||
if (o instanceof Enum<?>)
|
||||
{
|
||||
text = Text.titleCase((Enum) o);
|
||||
text = Text.titleCase((Enum<?>) o);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user