From 0c61ffd3b19a718d996cb544caa072c28035a87b Mon Sep 17 00:00:00 2001 From: Seth Date: Sun, 18 Mar 2018 17:27:13 -0500 Subject: [PATCH] ground items: add support for quickly hiding/highlighting items --- .../grounditems/GroundItemInputListener.java | 108 ++++++++++++++++++ .../grounditems/GroundItemsConfig.java | 14 +++ .../grounditems/GroundItemsOverlay.java | 91 ++++++++++++++- .../grounditems/GroundItemsPlugin.java | 68 ++++++++++- 4 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemInputListener.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemInputListener.java new file mode 100644 index 0000000000..4edb4f9168 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemInputListener.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018, Seth + * 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.plugins.grounditems; + +import java.awt.Rectangle; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.util.Map; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.client.input.KeyListener; +import net.runelite.client.input.MouseListener; + +public class GroundItemInputListener extends MouseListener implements KeyListener +{ + private static final int HOTKEY = KeyEvent.VK_ALT; + + @Inject + private Client client; + + @Inject + private GroundItemsPlugin plugin; + + @Override + public void keyTyped(KeyEvent e) + { + + } + + @Override + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == HOTKEY) + { + plugin.setHotKeyPressed(true); + } + } + + @Override + public void keyReleased(KeyEvent e) + { + if (e.getKeyCode() == HOTKEY) + { + plugin.setHotKeyPressed(false); + plugin.getHighlightBoxes().clear(); + plugin.getHiddenBoxes().clear(); + } + } + + @Override + public MouseEvent mousePressed(MouseEvent e) + { + if (plugin.isHotKeyPressed()) + { + // Check if left click + if (e.getButton() == MouseEvent.BUTTON1) + { + e.consume(); + + Point mousePos = client.getMouseCanvasPosition(); + + for (Map.Entry entry : plugin.getHiddenBoxes().entrySet()) + { + if (entry.getKey().contains(mousePos.getX(), mousePos.getY())) + { + plugin.updateList(entry.getValue(), true); + return e; + } + } + + for (Map.Entry entry : plugin.getHighlightBoxes().entrySet()) + { + if (entry.getKey().contains(mousePos.getX(), mousePos.getY())) + { + plugin.updateList(entry.getValue(), false); + return e; + } + } + } + } + + return e; + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java index e7cfa87ae8..796c51f3fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java @@ -137,6 +137,13 @@ public interface GroundItemsConfig extends Config return ""; } + @ConfigItem( + keyName = "highlightedItems", + name = "", + description = "" + ) + void setHighlightedItem(String key); + @ConfigItem( keyName = "hiddenItems", name = "Hidden Items", @@ -148,6 +155,13 @@ public interface GroundItemsConfig extends Config return ""; } + @ConfigItem( + keyName = "hiddenItems", + name = "", + description = "" + ) + void setHiddenItems(String key); + @ConfigItem( keyName = "defaultColor", name = "Default items color", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 312c087f9d..f0eaf076cd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -28,6 +28,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; +import java.awt.Rectangle; import static java.lang.Math.max; import static java.lang.Math.min; import java.util.ArrayList; @@ -81,6 +82,12 @@ public class GroundItemsOverlay extends Overlay // ItemID for coins private static final int COINS = ItemID.COINS_995; + // Size of the hidden/highlight boxes + private static final int RECTANGLE_SIZE = 8; + + private Rectangle itemHiddenBox; + private Rectangle itemHighlightBox; + private final Client client; private final GroundItemsPlugin plugin; private final GroundItemsConfig config; @@ -123,6 +130,13 @@ public class GroundItemsOverlay extends Overlay int upperX = min(from.getRegionX() + MAX_RANGE, REGION_SIZE - 1); int upperY = min(from.getRegionY() + MAX_RANGE, REGION_SIZE - 1); + // Clear boxes + if (plugin.isHotKeyPressed()) + { + plugin.getHiddenBoxes().clear(); + plugin.getHighlightBoxes().clear(); + } + for (int x = lowerX; x <= upperX; ++x) { for (int y = lowerY; y <= upperY; ++y) @@ -151,7 +165,7 @@ public class GroundItemsOverlay extends Overlay Integer currentQuantity = items.get(itemId); - if (config.showHighlightedOnly() ? plugin.isHighlighted(itemDefinition.getName()) : !plugin.isHidden(itemDefinition.getName())) + if ((config.showHighlightedOnly() ? plugin.isHighlighted(itemDefinition.getName()) : !plugin.isHidden(itemDefinition.getName())) || plugin.isHotKeyPressed()) { if (itemDefinition.getNote() != -1) { @@ -257,13 +271,47 @@ public class GroundItemsOverlay extends Overlay itemStringBuilder.setLength(0); int screenX = point.getX() + 2 - (fm.stringWidth(itemString) / 2); + int screenY = point.getY() - (STRING_GAP * i); // Drawing the shadow for the text, 1px on both x and y graphics.setColor(Color.BLACK); - graphics.drawString(itemString, screenX + 1, point.getY() - (STRING_GAP * i) + 1); + graphics.drawString(itemString, screenX + 1, screenY + 1); // Drawing the text itself graphics.setColor(textColor); - graphics.drawString(itemString, screenX, point.getY() - (STRING_GAP * i)); + graphics.drawString(itemString, screenX, screenY); + + if (plugin.isHotKeyPressed()) + { + // Hidden box + itemHiddenBox = new Rectangle + ( + screenX + fm.stringWidth(itemString), + screenY - (fm.getHeight() / 2) - fm.getDescent(), + RECTANGLE_SIZE, + fm.getHeight() / 2 + ); + plugin.getHiddenBoxes().put(itemHiddenBox, item.getName()); + + // Highlight box + itemHighlightBox = new Rectangle + ( + screenX + fm.stringWidth(itemString) + RECTANGLE_SIZE + 2, + screenY - (fm.getHeight() / 2) - fm.getDescent(), + RECTANGLE_SIZE, + fm.getHeight() / 2 + ); + plugin.getHighlightBoxes().put(itemHighlightBox, item.getName()); + + Point mousePos = client.getMouseCanvasPosition(); + boolean mouseInHiddenBox = itemHiddenBox.contains(mousePos.getX(), mousePos.getY()); + boolean mouseInHighlightBox = itemHighlightBox.contains(mousePos.getX(), mousePos.getY()); + + // Draw hidden box + drawRectangle(graphics, itemHiddenBox, mouseInHiddenBox ? Color.RED : textColor, plugin.isHidden(item.getName()), true); + + // Draw highlight box + drawRectangle(graphics, itemHighlightBox, mouseInHighlightBox ? Color.GREEN : textColor, plugin.isHighlighted(item.getName()), false); + } } } } @@ -296,4 +344,41 @@ public class GroundItemsOverlay extends Overlay } } + private void drawRectangle(Graphics2D graphics, Rectangle rect, Color color, boolean inList, boolean hiddenBox) + { + graphics.setColor(Color.BLACK); + graphics.drawRect(rect.x + 1, rect.y + 1, rect.width, rect.height); + + graphics.setColor(color); + graphics.draw(rect); + + if (inList) + { + graphics.fill(rect); + } + + graphics.setColor(Color.WHITE); + // Minus symbol + graphics.drawLine + ( + rect.x + 2, + rect.y + (RECTANGLE_SIZE / 2), + rect.x + RECTANGLE_SIZE - 2, + rect.y + (RECTANGLE_SIZE / 2) + ); + + if (!hiddenBox) + { + // Plus symbol + graphics.drawLine + ( + rect.x + (RECTANGLE_SIZE / 2), + rect.y + 2, + rect.x + (RECTANGLE_SIZE / 2), + rect.y + RECTANGLE_SIZE - 2 + ); + } + + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 9f78b6d623..1017c3cb68 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -24,17 +24,25 @@ */ package net.runelite.client.plugins.grounditems; +import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.cache.CacheBuilder; import com.google.common.cache.LoadingCache; import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.awt.Color; +import java.awt.Rectangle; import static java.lang.Boolean.TRUE; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; import net.runelite.api.Client; import net.runelite.api.Item; import net.runelite.api.ItemComposition; @@ -48,6 +56,8 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.config.ConfigManager; import net.runelite.client.game.ItemManager; +import net.runelite.client.input.KeyManager; +import net.runelite.client.input.MouseManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.Overlay; @@ -58,6 +68,28 @@ import net.runelite.http.api.item.ItemPrice; ) public class GroundItemsPlugin extends Plugin { + @Getter(AccessLevel.PACKAGE) + private final Map hiddenBoxes = new HashMap<>(); + + @Getter(AccessLevel.PACKAGE) + private final Map highlightBoxes = new HashMap<>(); + + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) + private boolean hotKeyPressed; + + private List hiddenItemList = new ArrayList<>(); + private List highlightedItemsList = new ArrayList<>(); + + @Inject + private GroundItemInputListener inputListener; + + @Inject + private MouseManager mouseManager; + + @Inject + private KeyManager keyManager; + @Inject private Client client; @@ -92,6 +124,16 @@ public class GroundItemsPlugin extends Plugin protected void startUp() { reset(); + + mouseManager.registerMouseListener(inputListener); + keyManager.registerKeyListener(inputListener); + } + + @Override + protected void shutDown() throws Exception + { + mouseManager.unregisterMouseListener(inputListener); + keyManager.unregisterKeyListener(inputListener); } @Subscribe @@ -108,10 +150,10 @@ public class GroundItemsPlugin extends Plugin Splitter COMMA_SPLITTER = Splitter.on(Pattern.compile("\\s*,\\s*")); // gets the hidden items from the text box in the config - List hiddenItemList = COMMA_SPLITTER.splitToList(config.getHiddenItems().trim()); + hiddenItemList = COMMA_SPLITTER.splitToList(config.getHiddenItems().trim()); // gets the highlighted items from the text box in the config - List highlightedItemsList = COMMA_SPLITTER.splitToList(config.getHighlightItems().trim()); + highlightedItemsList = COMMA_SPLITTER.splitToList(config.getHighlightItems().trim()); highlightedItems = CacheBuilder.newBuilder() .maximumSize(512L) @@ -213,6 +255,28 @@ public class GroundItemsPlugin extends Plugin } } + void updateList(String item, boolean hiddenList) + { + List items = new ArrayList<>((hiddenList) ? hiddenItemList : highlightedItemsList); + + items.removeIf(s -> s.isEmpty()); + if (!items.removeIf(s -> s.equalsIgnoreCase(item))) + { + items.add(item); + } + + String newList = Joiner.on(", ").join(items); + // This triggers the config update which updates the list + if (hiddenList) + { + config.setHiddenItems(newList); + } + else + { + config.setHighlightedItem(newList); + } + } + public boolean isHighlighted(String item) { return TRUE.equals(highlightedItems.getUnchecked(item));