diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java index e00114041d..ace5980b42 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.screenmarkers; +import java.awt.Rectangle; import java.awt.event.MouseEvent; import javax.swing.SwingUtilities; import net.runelite.client.input.MouseAdapter; @@ -59,7 +60,16 @@ public class ScreenMarkerMouseListener extends MouseAdapter if (SwingUtilities.isLeftMouseButton(event)) { - plugin.startCreation(event.getPoint()); + final Rectangle bounds = plugin.getSelectedWidgetBounds(); + + if (bounds != null) + { + plugin.startCreation(bounds.getLocation(), bounds.getSize()); + } + else + { + plugin.startCreation(event.getPoint()); + } } else if (plugin.isCreatingScreenMarker()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java index 9ca3c9c46d..6dc7558df2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java @@ -42,6 +42,7 @@ import java.util.stream.Stream; import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; +import lombok.Setter; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; @@ -91,6 +92,9 @@ public class ScreenMarkerPlugin extends Plugin @Inject private ColorPickerManager colorPickerManager; + @Inject + private ScreenMarkerWidgetHighlightOverlay widgetHighlight; + private ScreenMarkerMouseListener mouseListener; private ScreenMarkerPluginPanel pluginPanel; private NavigationButton navigationButton; @@ -99,13 +103,22 @@ public class ScreenMarkerPlugin extends Plugin private ScreenMarker currentMarker; @Getter + @Setter private boolean creatingScreenMarker = false; + + @Getter + private boolean drawingScreenMarker = false; + + @Getter + @Setter + private Rectangle selectedWidgetBounds = null; private Point startLocation = null; @Override protected void startUp() throws Exception { overlayManager.add(overlay); + overlayManager.add(widgetHighlight); loadConfig(configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY)).forEach(screenMarkers::add); screenMarkers.forEach(overlayManager::add); @@ -130,16 +143,19 @@ public class ScreenMarkerPlugin extends Plugin protected void shutDown() throws Exception { overlayManager.remove(overlay); + overlayManager.remove(widgetHighlight); overlayManager.removeIf(ScreenMarkerOverlay.class::isInstance); screenMarkers.clear(); clientToolbar.removeNavigation(navigationButton); setMouseListenerEnabled(false); creatingScreenMarker = false; + drawingScreenMarker = false; pluginPanel = null; currentMarker = null; mouseListener = null; navigationButton = null; + selectedWidgetBounds = null; } @Subscribe @@ -166,6 +182,17 @@ public class ScreenMarkerPlugin extends Plugin } public void startCreation(Point location) + { + startCreation(location, DEFAULT_SIZE); + + // Stop the highlighting so we don't get rectangles around widgets while trying to make normal screen markers + if (selectedWidgetBounds == null) + { + drawingScreenMarker = true; + } + } + + public void startCreation(Point location, Dimension size) { currentMarker = new ScreenMarker( Instant.now().toEpochMilli(), @@ -179,8 +206,7 @@ public class ScreenMarkerPlugin extends Plugin // Set overlay creator bounds to current position and default size startLocation = location; overlay.setPreferredLocation(location); - overlay.setPreferredSize(DEFAULT_SIZE); - creatingScreenMarker = true; + overlay.setPreferredSize(size); } public void finishCreation(boolean aborted) @@ -200,6 +226,8 @@ public class ScreenMarkerPlugin extends Plugin } creatingScreenMarker = false; + drawingScreenMarker = false; + selectedWidgetBounds = null; startLocation = null; currentMarker = null; setMouseListenerEnabled(false); @@ -207,7 +235,6 @@ public class ScreenMarkerPlugin extends Plugin pluginPanel.setCreation(false); } - /* The marker area has been drawn, inform the user and unlock the confirm button */ public void completeSelection() { pluginPanel.getCreationPanel().unlockConfirm(); @@ -224,6 +251,7 @@ public class ScreenMarkerPlugin extends Plugin void resizeMarker(Point point) { + drawingScreenMarker = true; Rectangle bounds = new Rectangle(startLocation); bounds.add(point); overlay.setPreferredLocation(bounds.getLocation()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerWidgetHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerWidgetHighlightOverlay.java new file mode 100644 index 0000000000..4dc590aefd --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerWidgetHighlightOverlay.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018, Jasper + * Copyright (c) 2020, melky + * 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.screenmarkers; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.MenuEntry; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetItem; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; + +class ScreenMarkerWidgetHighlightOverlay extends Overlay +{ + private final ScreenMarkerPlugin plugin; + private final Client client; + + @Inject + private ScreenMarkerWidgetHighlightOverlay(final ScreenMarkerPlugin plugin, final Client client) + { + this.plugin = plugin; + this.client = client; + setPosition(OverlayPosition.DETACHED); + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!plugin.isCreatingScreenMarker() || plugin.isDrawingScreenMarker()) + { + return null; + } + + if (client.isMenuOpen()) + { + plugin.setSelectedWidgetBounds(null); + return null; + } + + final MenuEntry[] menuEntries = client.getMenuEntries(); + + final int last = menuEntries.length - 1; + if (last < 0) + { + plugin.setSelectedWidgetBounds(null); + return null; + } + + final MenuEntry menuEntry = menuEntries[last]; + final int widgetId = menuEntry.getParam1(); + final int groupId = WidgetInfo.TO_GROUP(widgetId); + final int childId = WidgetInfo.TO_CHILD(widgetId); + + final Widget widget = client.getWidget(groupId, childId); + if (widget == null) + { + plugin.setSelectedWidgetBounds(null); + return null; + } + + final int param0 = menuEntry.getParam0(); + if (param0 > -1) + { + final WidgetItem widgetItem = widget.getWidgetItem(param0); + if (widgetItem != null) + { + drawHighlight(widgetItem.getCanvasBounds(), graphics); + } + else + { + drawHighlight(widget.getChild(param0).getBounds(), graphics); + } + } + else + { + drawHighlight(widget.getBounds(), graphics); + } + + return null; + } + + private void drawHighlight(Rectangle bounds, Graphics2D graphics) + { + graphics.setColor(Color.GREEN); + graphics.draw(bounds); + plugin.setSelectedWidgetBounds(bounds); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java index b0813cc8ef..d63a2af4d4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java @@ -204,6 +204,7 @@ public class ScreenMarkerPluginPanel extends PluginPanel { creationPanel.lockConfirm(); plugin.setMouseListenerEnabled(true); + plugin.setCreatingScreenMarker(true); } } }