From 210eecc6b6498a03d34a1b24dcdcf7559365ae6a Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Mon, 22 Feb 2021 21:13:31 +0100 Subject: [PATCH] config: Support for titles --- .../client/config/ConfigDescriptor.java | 4 +- .../runelite/client/config/ConfigItem.java | 2 + .../runelite/client/config/ConfigManager.java | 26 +++++++- .../runelite/client/config/ConfigTitle.java | 51 +++++++++++++++ .../client/config/ConfigTitleDescriptor.java | 52 ++++++++++++++++ .../client/plugins/config/ConfigPanel.java | 62 ++++++++++++++++++- 6 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/config/ConfigTitle.java create mode 100644 runelite-client/src/main/java/net/runelite/client/config/ConfigTitleDescriptor.java diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java index b234e756d6..19554fad18 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java @@ -32,12 +32,14 @@ public class ConfigDescriptor { private final ConfigGroup group; private final Collection sections; + private final Collection titles; private final Collection items; - public ConfigDescriptor(ConfigGroup group, Collection sections, Collection items) + public ConfigDescriptor(ConfigGroup group, Collection sections, Collection titles, Collection items) { this.group = group; this.sections = sections; + this.titles = titles; this.items = items; } } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java index a9a511cc08..80ff98d85c 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java @@ -48,4 +48,6 @@ public @interface ConfigItem boolean secret() default false; String section() default ""; + + String title() default ""; } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 42a6d4e965..4bba6fb2c5 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -647,6 +647,30 @@ public class ConfigManager .result()) .collect(Collectors.toList()); + final List titles = Arrays.stream(inter.getDeclaredFields()) + .filter(m -> m.isAnnotationPresent(ConfigTitle.class) && m.getType() == String.class) + .map(m -> + { + try + { + return new ConfigTitleDescriptor( + String.valueOf(m.get(inter)), + m.getDeclaredAnnotation(ConfigTitle.class) + ); + } + catch (IllegalAccessException e) + { + log.warn("Unable to load title {}::{}", inter.getSimpleName(), m.getName()); + return null; + } + }) + .filter(Objects::nonNull) + .sorted((a, b) -> ComparisonChain.start() + .compare(a.getTitle().position(), b.getTitle().position()) + .compare(a.getTitle().name(), b.getTitle().name()) + .result()) + .collect(Collectors.toList()); + final List items = Arrays.stream(inter.getMethods()) .filter(m -> m.getParameterCount() == 0 && m.isAnnotationPresent(ConfigItem.class)) .map(m -> new ConfigItemDescriptor( @@ -662,7 +686,7 @@ public class ConfigManager .result()) .collect(Collectors.toList()); - return new ConfigDescriptor(group, sections, items); + return new ConfigDescriptor(group, sections, titles, items); } /** diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigTitle.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitle.java new file mode 100644 index 0000000000..649beae4a0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitle.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Hydrox6 + * 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.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigTitle +{ + String name(); + + String description(); + + int position(); + + String title() default ""; + + /* + OpenOSRS Lazy Helpers tm + */ + String keyName() default ""; + String section() default ""; + boolean hidden() default false; + String unhide() default ""; +} diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigTitleDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitleDescriptor.java new file mode 100644 index 0000000000..17413d574d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitleDescriptor.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, Hydrox6 + * 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.config; + +import lombok.Value; + +@Value +public class ConfigTitleDescriptor implements ConfigObject +{ + private final String key; + private final ConfigTitle title; + + @Override + public String key() + { + return key; + } + + @Override + public String name() + { + return title.name(); + } + + @Override + public int position() + { + return title.position(); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index b176bf154b..a521711678 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -76,6 +76,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigObject; import net.runelite.client.config.ConfigSection; import net.runelite.client.config.ConfigSectionDescriptor; +import net.runelite.client.config.ConfigTitle; +import net.runelite.client.config.ConfigTitleDescriptor; import net.runelite.client.config.Keybind; import net.runelite.client.config.ModifierlessKeybind; import net.runelite.client.config.Range; @@ -256,6 +258,7 @@ class ConfigPanel extends PluginPanel ConfigDescriptor cd = pluginConfig.getConfigDescriptor(); final Map sectionWidgets = new HashMap<>(); + final Map titleWidgets = new HashMap<>(); final Map topLevelPanels = new TreeMap<>((a, b) -> ComparisonChain.start() .compare(a.position(), b.position()) @@ -323,6 +326,53 @@ class ConfigPanel extends PluginPanel topLevelPanels.put(csd, section); } + for (ConfigTitleDescriptor ctd : cd.getTitles()) + { + ConfigTitle ct = ctd.getTitle(); + final JPanel title = new JPanel(); + title.setLayout(new BoxLayout(title, BoxLayout.Y_AXIS)); + title.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + + final JPanel sectionHeader = new JPanel(); + sectionHeader.setLayout(new BorderLayout()); + sectionHeader.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + + title.add(sectionHeader, BorderLayout.NORTH); + + String name = ct.name(); + final JLabel sectionName = new JLabel(name); + sectionName.setForeground(ColorScheme.BRAND_ORANGE); + sectionName.setFont(FontManager.getRunescapeBoldFont()); + sectionName.setToolTipText("" + name + ":
" + ct.description() + ""); + sectionName.setBorder(new EmptyBorder(0, 0, 3, 1)); + sectionHeader.add(sectionName, BorderLayout.CENTER); + + final JPanel sectionContents = new JPanel(); + sectionContents.setLayout(new DynamicGridLayout(0, 1, 0, 5)); + sectionContents.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + sectionContents.setBorder(new EmptyBorder(0, 5, 0, 0)); + title.add(sectionContents, BorderLayout.SOUTH); + + titleWidgets.put(ctd.getKey(), sectionContents); + + // Allow for sub-sections + JPanel section = sectionWidgets.get(ct.section()); + JPanel titleSection = titleWidgets.get(ct.title()); + + if (section != null) + { + section.add(title); + } + else if (titleSection != null) + { + titleSection.add(title); + } + else + { + topLevelPanels.put(ctd, title); + } + } + for (ConfigItemDescriptor cid : cd.getItems()) { if (cid.getItem().hidden()) @@ -567,13 +617,19 @@ class ConfigPanel extends PluginPanel } JPanel section = sectionWidgets.get(cid.getItem().section()); - if (section == null) + JPanel title = titleWidgets.get(cid.getItem().title()); + + if (section != null) { - topLevelPanels.put(cid, item); + section.add(item); + } + else if (title != null) + { + title.add(item); } else { - section.add(item); + topLevelPanels.put(cid, item); } }