From 0a86fe35aff62d24942405490ac8b88b98bc9dcc Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 3 Aug 2021 19:13:52 -0400 Subject: [PATCH] widgetoverlay: support detached overlays This adds support for moving the wilderness icon layer, which is not in an area near a snap corner. With no preferred location set the overlay adjusts its bounds to the widget bounds and will not adjust the widget position. --- .../net/runelite/api/widgets/WidgetID.java | 1 + .../net/runelite/api/widgets/WidgetInfo.java | 1 + .../runelite/client/ui/overlay/Overlay.java | 7 +++ .../client/ui/overlay/OverlayManager.java | 4 +- .../client/ui/overlay/WidgetOverlay.java | 44 +++++++++++++++++-- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index c51e0ed1eb..097c456d14 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -774,6 +774,7 @@ public class WidgetID static class Pvp { static final int KILLDEATH_RATIO = 26; + static final int WILDERNESS_SKULL_CONTAINER = 44; static final int SKULL_CONTAINER = 45; static final int SAFE_ZONE = 47; static final int WILDERNESS_LEVEL = 50; // this can also be the Deadman Mode "Protection" text diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 98f66a8b83..52e5961559 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -501,6 +501,7 @@ public enum WidgetInfo SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT), SPELL_KOUREND_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.KOUREND_HOME_TELEPORT), + PVP_WILDERNESS_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.WILDERNESS_SKULL_CONTAINER), PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER), PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE), diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java index 41944b5cd7..14197b90a1 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java @@ -120,4 +120,11 @@ public abstract class Overlay implements LayoutableRenderableEntity { return null; } + + public void reset() + { + setPreferredPosition(null); + setPreferredSize(null); + setPreferredLocation(null); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java index 6e3c770b37..21cb834ca1 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java @@ -289,9 +289,7 @@ public class OverlayManager */ public synchronized void resetOverlay(final Overlay overlay) { - overlay.setPreferredPosition(null); - overlay.setPreferredSize(null); - overlay.setPreferredLocation(null); + overlay.reset(); saveOverlay(overlay); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java index d470bbb242..384acab9d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java @@ -30,11 +30,13 @@ import java.awt.Rectangle; import java.util.Arrays; import java.util.Collection; import java.util.Objects; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.Varbits; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +@Slf4j public class WidgetOverlay extends Overlay { public static Collection createOverlays(final Client client) @@ -71,13 +73,15 @@ public class WidgetOverlay extends Overlay new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_RESIZEABLE_CLASSIC, OverlayPosition.CANVAS_TOP_RIGHT), new WidgetOverlay(client, WidgetInfo.TEMPOROSS_STATUS_INDICATOR, OverlayPosition.TOP_LEFT), new WidgetOverlay(client, WidgetInfo.BA_HEAL_TEAMMATES, OverlayPosition.BOTTOM_LEFT), - new WidgetOverlay(client, WidgetInfo.BA_TEAM, OverlayPosition.TOP_RIGHT) + new WidgetOverlay(client, WidgetInfo.BA_TEAM, OverlayPosition.TOP_RIGHT), + new WidgetOverlay(client, WidgetInfo.PVP_WILDERNESS_SKULL_CONTAINER, OverlayPosition.DETACHED) ); } protected final Client client; private final WidgetInfo widgetInfo; private final Rectangle parentBounds = new Rectangle(); + private boolean revalidate; private WidgetOverlay(final Client client, final WidgetInfo widgetInfo, final OverlayPosition overlayPosition) { @@ -107,10 +111,34 @@ public class WidgetOverlay extends Overlay return null; } + assert widget != null; + final Rectangle bounds = getBounds(); - // The widget relative pos is relative to the parent - widget.setRelativeX(bounds.x - parent.x); - widget.setRelativeY(bounds.y - parent.y); + // OverlayRenderer sets the overlay bounds to the preferred location if one is set prior to calling render() + // for detached overlays. + if (getPosition() != OverlayPosition.DETACHED || getPreferredLocation() != null) + { + // The widget relative pos is relative to the parent + widget.setRelativeX(bounds.x - parent.x); + widget.setRelativeY(bounds.y - parent.y); + } + else + { + if (revalidate) + { + revalidate = false; + log.debug("Revalidating {}", widgetInfo); + // Revalidate the widget to reposition it back to its normal location after an overlay reset + widget.revalidate(); + } + + // Update the overlay bounds to the widget bounds so the drag overlay renders correctly. + // Note OverlayManager uses original bounds reference to render managing mode and for + // onMouseOver, so update the existing bounds vs. replacing the reference. + Rectangle widgetBounds = widget.getBounds(); + bounds.setBounds(widgetBounds.x, widgetBounds.y, widgetBounds.width, widgetBounds.height); + } + return new Dimension(widget.getWidth(), widget.getHeight()); } @@ -152,6 +180,14 @@ public class WidgetOverlay extends Overlay return getParentBounds(widget); } + @Override + public void reset() + { + super.reset(); + // Revalidate must be called on the client thread, so defer til next frame + revalidate = true; + } + private static class XpTrackerWidgetOverlay extends WidgetOverlay { private XpTrackerWidgetOverlay(Client client, WidgetInfo widgetInfo, OverlayPosition overlayPosition)