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.
This commit is contained in:
Adam
2021-08-26 22:26:02 -04:00
parent ed5ae02bc3
commit 6723fb3205
5 changed files with 34 additions and 35 deletions

View File

@@ -121,10 +121,7 @@ public abstract class Overlay implements LayoutableRenderableEntity
return null;
}
public void reset()
public void revalidate()
{
setPreferredPosition(null);
setPreferredSize(null);
setPreferredLocation(null);
}
}

View File

@@ -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()

View File

@@ -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;
}
}

View File

@@ -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)

View File

@@ -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;
}