From 6723fb3205e4a5a784be0c33a17c721ce4e12a99 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 26 Aug 2021 22:26:02 -0400 Subject: [PATCH] overlay: only layout widget overlays if the preferred location is set With the new steam client updates, the client tries to aggressively move around several of the widget overlay components, including xp tracker, and several hp bars. This tends to fight with the layouting we already do with the widgets. This changes the widgets to only be layouted if the overlay has a preferred location or position set. Otherwise, it will offset the snap corner bounds by where the client has positione the widget. It is still possible to get the client ui to fight the widget overlay by moving the overlays around manually, but it should no longer happen in the default positioning of the widgets. --- .../runelite/client/ui/overlay/Overlay.java | 5 +--- .../client/ui/overlay/OverlayManager.java | 5 +++- .../client/ui/overlay/OverlayRenderer.java | 24 ++++++++--------- .../client/ui/overlay/OverlayUtil.java | 26 +++++++++---------- .../client/ui/overlay/WidgetOverlay.java | 9 +++---- 5 files changed, 34 insertions(+), 35 deletions(-) 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 14197b90a1..c852f32b53 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 @@ -121,10 +121,7 @@ public abstract class Overlay implements LayoutableRenderableEntity return null; } - public void reset() + public void revalidate() { - 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 21cb834ca1..bea3f9d280 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,8 +289,11 @@ public class OverlayManager */ public synchronized void resetOverlay(final Overlay overlay) { - overlay.reset(); + overlay.setPreferredPosition(null); + overlay.setPreferredSize(null); + overlay.setPreferredLocation(null); saveOverlay(overlay); + overlay.revalidate(); } synchronized void rebuildOverlayLayers() diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index d70b043911..463e05725e 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -272,25 +272,18 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener final Dimension dimension = bounds.getSize(); final Point preferredLocation = overlay.getPreferredLocation(); Point location; + Rectangle snapCorner = null; // If the final position is not modified, layout it if (overlayPosition != OverlayPosition.DETACHED && (preferredLocation == null || overlay.getPreferredPosition() != null)) { - final Rectangle snapCorner = snapCorners.forPosition(overlayPosition); + snapCorner = snapCorners.forPosition(overlayPosition); final Point translation = OverlayUtil.transformPosition(overlayPosition, dimension); // offset from corner // Target x/y to draw the overlay - int destX = (int) snapCorner.getX() + translation.x; - int destY = (int) snapCorner.getY() + translation.y; + int destX = snapCorner.x + translation.x; + int destY = snapCorner.y + translation.y; // Clamp the target position to ensure it is on screen or within parent bounds location = clampOverlayLocation(destX, destY, dimension.width, dimension.height, overlay); - // Diff final position to target position in order to add it to the snap corner padding. The - // overlay effectively takes up the difference of (clamped location - target location) in - // addition to its normal dimensions. - int dX = location.x - destX; - int dY = location.y - destY; - final Point padding = OverlayUtil.padPosition(overlayPosition, dimension, PADDING); // overlay size + fixed padding - // translate corner for padding and any difference due to the position clamping - snapCorner.translate(padding.x + dX, padding.y + dY); } else { @@ -307,6 +300,12 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener safeRender(client, overlay, layer, graphics, location); + // Adjust snap corner based on where the overlay was drawn + if (snapCorner != null && bounds.width + bounds.height > 0) + { + OverlayUtil.shiftSnapCorner(overlayPosition, snapCorner, bounds, PADDING); + } + // Restore graphics2d properties prior to drawing bounds graphics.setTransform(transform); graphics.setStroke(stroke); @@ -665,7 +664,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener { OverlayPosition position = snapCorners.fromBounds(snapCorner); - if (position == currentManagedOverlay.getPosition()) + if (position == getCorrectedOverlayPosition(currentManagedOverlay)) { // overlay moves back to default position position = null; @@ -673,6 +672,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener currentManagedOverlay.setPreferredPosition(position); currentManagedOverlay.setPreferredLocation(null); // from dragging + currentManagedOverlay.revalidate(); break; } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java index 1caa3a7c01..26497ab43d 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java @@ -30,6 +30,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Polygon; +import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; @@ -201,33 +202,32 @@ public class OverlayUtil graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } - public static java.awt.Point padPosition(OverlayPosition position, Dimension dimension, final int padding) + static void shiftSnapCorner(OverlayPosition overlayPosition, Rectangle snapCorner, Rectangle bounds, int padding) { - final java.awt.Point result = new java.awt.Point(); - - switch (position) + // translate corner for padding and also based on where the overlay bounds are now + int sX = snapCorner.x, sY = snapCorner.y; + switch (overlayPosition) { - case DYNAMIC: - case TOOLTIP: - break; case BOTTOM_LEFT: - result.x += dimension.width + (dimension.width == 0 ? 0 : padding); + sX = bounds.x + bounds.width + padding; break; case BOTTOM_RIGHT: - result.x -= dimension.width + (dimension.width == 0 ? 0 : padding); + sX = bounds.x - padding; break; case TOP_LEFT: case TOP_CENTER: case CANVAS_TOP_RIGHT: case TOP_RIGHT: - result.y += dimension.height + (dimension.height == 0 ? 0 : padding); + sY = bounds.y + bounds.height + padding; break; case ABOVE_CHATBOX_RIGHT: - result.y -= dimension.height + (dimension.height == 0 ? 0 : padding); + sY = bounds.y - padding; break; + default: + throw new IllegalArgumentException(); } - - return result; + snapCorner.x = sX; + snapCorner.y = sY; } public static java.awt.Point transformPosition(OverlayPosition position, Dimension dimension) 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 67d20cf8bd..43a1faf32e 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 @@ -121,9 +121,9 @@ public class WidgetOverlay extends Overlay assert widget != null; final Rectangle bounds = getBounds(); - // 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) + // OverlayRenderer sets the overlay bounds to where it would like the overlay to render at prior to calling + // render(). If the overlay has a preferred location or position set we update the widget position to that. + if (getPreferredLocation() != null || getPreferredPosition() != null) { // The widget relative pos is relative to the parent widget.setRelativeX(bounds.x - parent.x); @@ -188,9 +188,8 @@ public class WidgetOverlay extends Overlay } @Override - public void reset() + public void revalidate() { - super.reset(); // Revalidate must be called on the client thread, so defer til next frame revalidate = true; }