Make RuneScape widgets layoutable
Instead of making RuneScape widgets detached, make them layoutable - Add new snap corner CANVAS_TOP_RIGHT that is basically minimap position - Make WidgetOverlay use standard overlay layouting - Adjust paddings in the OverlayRenderer to match game more closely Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
@@ -32,6 +32,7 @@ import lombok.Value;
|
||||
import static net.runelite.client.ui.overlay.OverlayPosition.ABOVE_CHATBOX_RIGHT;
|
||||
import static net.runelite.client.ui.overlay.OverlayPosition.BOTTOM_LEFT;
|
||||
import static net.runelite.client.ui.overlay.OverlayPosition.BOTTOM_RIGHT;
|
||||
import static net.runelite.client.ui.overlay.OverlayPosition.CANVAS_TOP_RIGHT;
|
||||
import static net.runelite.client.ui.overlay.OverlayPosition.TOP_LEFT;
|
||||
import static net.runelite.client.ui.overlay.OverlayPosition.TOP_RIGHT;
|
||||
|
||||
@@ -39,7 +40,7 @@ import static net.runelite.client.ui.overlay.OverlayPosition.TOP_RIGHT;
|
||||
@Value
|
||||
class OverlayBounds
|
||||
{
|
||||
private final Rectangle topLeft, topRight, bottomLeft, bottomRight, aboveChatboxRight;
|
||||
private final Rectangle topLeft, topRight, bottomLeft, bottomRight, aboveChatboxRight, canvasTopRight;
|
||||
|
||||
OverlayBounds(OverlayBounds other)
|
||||
{
|
||||
@@ -48,6 +49,7 @@ class OverlayBounds
|
||||
bottomLeft = new Rectangle(other.bottomLeft);
|
||||
bottomRight = new Rectangle(other.bottomRight);
|
||||
aboveChatboxRight = new Rectangle(other.aboveChatboxRight);
|
||||
canvasTopRight = new Rectangle(other.canvasTopRight);
|
||||
}
|
||||
|
||||
OverlayBounds translated(final int x, final int y)
|
||||
@@ -57,6 +59,7 @@ class OverlayBounds
|
||||
translated.getBottomLeft().translate(0, y);
|
||||
translated.getBottomRight().translate(x, y);
|
||||
translated.getAboveChatboxRight().translate(x, y);
|
||||
translated.getCanvasTopRight().translate(x, 0);
|
||||
return translated;
|
||||
}
|
||||
|
||||
@@ -74,6 +77,8 @@ class OverlayBounds
|
||||
return bottomRight;
|
||||
case ABOVE_CHATBOX_RIGHT:
|
||||
return aboveChatboxRight;
|
||||
case CANVAS_TOP_RIGHT:
|
||||
return canvasTopRight;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@@ -101,6 +106,10 @@ class OverlayBounds
|
||||
{
|
||||
return ABOVE_CHATBOX_RIGHT;
|
||||
}
|
||||
else if (bounds == canvasTopRight)
|
||||
{
|
||||
return CANVAS_TOP_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
@@ -109,6 +118,6 @@ class OverlayBounds
|
||||
|
||||
Collection<Rectangle> getBounds()
|
||||
{
|
||||
return Arrays.asList(topLeft, topRight, bottomLeft, bottomRight, aboveChatboxRight);
|
||||
return Arrays.asList(topLeft, topRight, bottomLeft, bottomRight, aboveChatboxRight, canvasTopRight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,27 +35,31 @@ public enum OverlayPosition
|
||||
*/
|
||||
DYNAMIC,
|
||||
/**
|
||||
* Place overlay in the top left most area possible
|
||||
* Place overlay in the top left viewport area
|
||||
*/
|
||||
TOP_LEFT,
|
||||
/**
|
||||
* Place overlay in the top right most area possible
|
||||
* Place overlay in the top right viewport area
|
||||
*/
|
||||
TOP_RIGHT,
|
||||
/**
|
||||
* Place overlay in the bottom left most area possible
|
||||
* Place overlay in the bottom left viewport area
|
||||
*/
|
||||
BOTTOM_LEFT,
|
||||
/**
|
||||
* Place overlay in the bottom right most area possible
|
||||
* Place overlay in the bottom right viewport area
|
||||
*/
|
||||
BOTTOM_RIGHT,
|
||||
/**
|
||||
* Place overlay directly above right most area of chatbox possible
|
||||
* Place overlay directly above right side of chatbox
|
||||
*/
|
||||
ABOVE_CHATBOX_RIGHT,
|
||||
/**
|
||||
* Place overlay in the top right most area possible
|
||||
*/
|
||||
CANVAS_TOP_RIGHT,
|
||||
/**
|
||||
* Tooltip overlay
|
||||
*/
|
||||
TOOLTIP;
|
||||
TOOLTIP
|
||||
}
|
||||
|
||||
@@ -52,13 +52,8 @@ import net.runelite.client.ui.FontManager;
|
||||
@Singleton
|
||||
public class OverlayRenderer extends MouseListener implements KeyListener
|
||||
{
|
||||
private static final int BORDER_LEFT_RESIZABLE = 5;
|
||||
private static final int BORDER_TOP_RESIZABLE = 20;
|
||||
private static final int FRAME_OFFSET = 4;
|
||||
private static final int BORDER_LEFT_FIXED = BORDER_LEFT_RESIZABLE + FRAME_OFFSET;
|
||||
private static final int BORDER_TOP_FIXED = BORDER_TOP_RESIZABLE + FRAME_OFFSET;
|
||||
private static final int BORDER_RIGHT = 2;
|
||||
private static final int BORDER_BOTTOM = 2;
|
||||
private static final int BORDER = 5;
|
||||
private static final int BORDER_TOP = BORDER + 15;
|
||||
private static final int PADDING = 2;
|
||||
private static final Dimension SNAP_CORNER_SIZE = new Dimension(80, 80);
|
||||
private static final Color SNAP_CORNER_COLOR = new Color(0, 255, 255, 50);
|
||||
@@ -78,6 +73,7 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
||||
// Overlay state validation
|
||||
private Rectangle viewportBounds;
|
||||
private Rectangle chatboxBounds;
|
||||
private int viewportOffset;
|
||||
private boolean chatboxHidden;
|
||||
private boolean isResizeable;
|
||||
private OverlayBounds snapCorners;
|
||||
@@ -155,12 +151,21 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
||||
overlayPosition = overlay.getPreferredPosition();
|
||||
}
|
||||
|
||||
if (overlayPosition == OverlayPosition.ABOVE_CHATBOX_RIGHT && !isResizeable)
|
||||
if (!isResizeable)
|
||||
{
|
||||
// On fixed mode, ABOVE_CHATBOX_RIGHT is in the same location as
|
||||
// BOTTOM_RIGHT. Just use BOTTOM_RIGHT to prevent overlays from
|
||||
// BOTTOM_RIGHT and CANVAST_TOP_RIGHT is same as TOP_RIGHT.
|
||||
// Just use BOTTOM_RIGHT and TOP_RIGHT to prevent overlays from
|
||||
// drawing over each other.
|
||||
overlayPosition = OverlayPosition.BOTTOM_RIGHT;
|
||||
switch (overlayPosition)
|
||||
{
|
||||
case CANVAS_TOP_RIGHT:
|
||||
overlayPosition = OverlayPosition.TOP_RIGHT;
|
||||
break;
|
||||
case ABOVE_CHATBOX_RIGHT:
|
||||
overlayPosition = OverlayPosition.BOTTOM_RIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (overlayPosition == OverlayPosition.DYNAMIC || overlayPosition == OverlayPosition.TOOLTIP)
|
||||
@@ -421,43 +426,55 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
||||
changed = true;
|
||||
}
|
||||
|
||||
final boolean viewportOffsetChanged = client.getViewportXOffset() != viewportOffset;
|
||||
|
||||
if (viewportOffsetChanged)
|
||||
{
|
||||
viewportOffset = client.getViewportXOffset();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private OverlayBounds buildSnapCorners()
|
||||
{
|
||||
final Point topLeftPoint = new Point(
|
||||
isResizeable ? BORDER_LEFT_RESIZABLE : BORDER_LEFT_FIXED,
|
||||
isResizeable ? BORDER_TOP_RESIZABLE : BORDER_TOP_FIXED);
|
||||
viewportOffset + BORDER,
|
||||
viewportOffset + BORDER_TOP);
|
||||
|
||||
final Point topRightPoint = new Point(
|
||||
viewportBounds.x + viewportBounds.width - BORDER_RIGHT,
|
||||
BORDER_TOP_FIXED);
|
||||
viewportOffset + viewportBounds.width - BORDER,
|
||||
viewportOffset + BORDER);
|
||||
|
||||
final Point bottomLeftPoint = new Point(
|
||||
isResizeable ? BORDER_LEFT_RESIZABLE : BORDER_LEFT_FIXED,
|
||||
viewportBounds.y + viewportBounds.height - BORDER_BOTTOM);
|
||||
|
||||
final Point bottomRightPoint = new Point(
|
||||
viewportBounds.x + viewportBounds.width - BORDER_RIGHT,
|
||||
viewportBounds.y + viewportBounds.height - BORDER_BOTTOM);
|
||||
|
||||
final Point rightChatboxPoint = new Point(
|
||||
viewportBounds.x + chatboxBounds.width - BORDER_RIGHT,
|
||||
viewportBounds.y + viewportBounds.height - BORDER_BOTTOM);
|
||||
topLeftPoint.x,
|
||||
viewportOffset + viewportBounds.height - BORDER);
|
||||
|
||||
// Check to see if chat box is minimized
|
||||
if (isResizeable && chatboxHidden)
|
||||
{
|
||||
rightChatboxPoint.y += chatboxBounds.height;
|
||||
bottomLeftPoint.y += chatboxBounds.height;
|
||||
}
|
||||
|
||||
final Point bottomRightPoint = new Point(
|
||||
topRightPoint.x,
|
||||
bottomLeftPoint.y);
|
||||
|
||||
final Point rightChatboxPoint = isResizeable ? new Point(
|
||||
viewportOffset + chatboxBounds.width - BORDER,
|
||||
bottomLeftPoint.y) : bottomRightPoint;
|
||||
|
||||
final Point canvasTopRightPoint = isResizeable ? new Point(
|
||||
client.getCanvas().getWidth(),
|
||||
0) : topRightPoint;
|
||||
|
||||
return new OverlayBounds(
|
||||
new Rectangle(topLeftPoint, SNAP_CORNER_SIZE),
|
||||
new Rectangle(topRightPoint, SNAP_CORNER_SIZE),
|
||||
new Rectangle(bottomLeftPoint, SNAP_CORNER_SIZE),
|
||||
new Rectangle(bottomRightPoint, SNAP_CORNER_SIZE),
|
||||
new Rectangle(rightChatboxPoint, SNAP_CORNER_SIZE));
|
||||
new Rectangle(rightChatboxPoint, SNAP_CORNER_SIZE),
|
||||
new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +204,7 @@ public class OverlayUtil
|
||||
case TOP_LEFT:
|
||||
result.y += dimension.height + (dimension.height == 0 ? 0 : padding);
|
||||
break;
|
||||
case CANVAS_TOP_RIGHT:
|
||||
case TOP_RIGHT:
|
||||
result.y += dimension.height + (dimension.height == 0 ? 0 : padding);
|
||||
break;
|
||||
@@ -232,6 +233,7 @@ public class OverlayUtil
|
||||
case ABOVE_CHATBOX_RIGHT:
|
||||
result.y = result.y - dimension.height;
|
||||
// FALLTHROUGH
|
||||
case CANVAS_TOP_RIGHT:
|
||||
case TOP_RIGHT:
|
||||
result.x = result.x - dimension.width;
|
||||
break;
|
||||
|
||||
@@ -24,10 +24,11 @@
|
||||
*/
|
||||
package net.runelite.client.ui.overlay;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -37,29 +38,29 @@ import net.runelite.api.widgets.WidgetInfo;
|
||||
|
||||
public class WidgetOverlay extends Overlay
|
||||
{
|
||||
private static final Set<WidgetInfo> WIDGETS = ImmutableSet.of(
|
||||
WidgetInfo.RESIZABLE_MINIMAP_WIDGET,
|
||||
WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET,
|
||||
WidgetInfo.EXPERIENCE_TRACKER_WIDGET,
|
||||
WidgetInfo.FOSSIL_ISLAND_OXYGENBAR
|
||||
);
|
||||
private static final Map<WidgetInfo, OverlayPosition> WIDGETS = ImmutableMap
|
||||
.<WidgetInfo, OverlayPosition>builder()
|
||||
.put(WidgetInfo.FOSSIL_ISLAND_OXYGENBAR, OverlayPosition.TOP_LEFT)
|
||||
.put(WidgetInfo.EXPERIENCE_TRACKER_WIDGET, OverlayPosition.TOP_RIGHT)
|
||||
.put(WidgetInfo.RESIZABLE_MINIMAP_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT)
|
||||
.put(WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT)
|
||||
.build();
|
||||
|
||||
public static Set<WidgetOverlay> createOverlays(final Client client)
|
||||
{
|
||||
return WIDGETS.stream().map(w -> new WidgetOverlay(client, w)).collect(Collectors.toSet());
|
||||
return WIDGETS.entrySet().stream().map(w -> new WidgetOverlay(client, w.getKey(), w.getValue())).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private final Client client;
|
||||
private final WidgetInfo widgetInfo;
|
||||
private Integer toRestoreX;
|
||||
private Integer toRestoreY;
|
||||
|
||||
private WidgetOverlay(final Client client, final WidgetInfo widgetInfo)
|
||||
private WidgetOverlay(final Client client, final WidgetInfo widgetInfo, final OverlayPosition overlayPosition)
|
||||
{
|
||||
this.client = client;
|
||||
this.widgetInfo = widgetInfo;
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
setPosition(OverlayPosition.DETACHED);
|
||||
setPosition(overlayPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,73 +69,39 @@ public class WidgetOverlay extends Overlay
|
||||
return Objects.toString(widgetInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getBounds()
|
||||
{
|
||||
final Widget widget = client.getWidget(widgetInfo);
|
||||
|
||||
if (widget != null && !widget.isHidden())
|
||||
{
|
||||
return new Rectangle(
|
||||
widget.getOriginalX() + widget.getRelativeX(),
|
||||
widget.getOriginalY() + widget.getRelativeY(),
|
||||
widget.getWidth(), widget.getHeight());
|
||||
}
|
||||
|
||||
return new Rectangle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final Widget widget = client.getWidget(widgetInfo);
|
||||
|
||||
if (widget == null || widget.isHidden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (getPreferredLocation() == null)
|
||||
{
|
||||
if (toRestoreX != null)
|
||||
{
|
||||
widget.setRelativeX(toRestoreX);
|
||||
toRestoreX = null;
|
||||
}
|
||||
|
||||
if (toRestoreY != null)
|
||||
{
|
||||
widget.setRelativeY(toRestoreY);
|
||||
toRestoreY = null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
final Rectangle bounds = getBounds();
|
||||
int x = getPreferredLocation().x - widget.getOriginalX();
|
||||
int y = getPreferredLocation().y - widget.getOriginalY();
|
||||
x = Math.max(0, x);
|
||||
y = Math.max(0, y);
|
||||
final Rectangle parent = getParentBounds(widget);
|
||||
int x = bounds.x;
|
||||
int y = bounds.y;
|
||||
x = Math.max(parent.x, x);
|
||||
y = Math.max(parent.y, y);
|
||||
x = Math.min((int)parent.getMaxX() - bounds.width, x);
|
||||
y = Math.min((int)parent.getMaxY() - bounds.height, y);
|
||||
bounds.setLocation(x, y);
|
||||
widget.setOriginalX(0);
|
||||
widget.setRelativeX(0);
|
||||
widget.setRelativeX(bounds.x - parent.x);
|
||||
widget.setRelativeY(bounds.y - parent.y);
|
||||
return new Dimension(widget.getWidth(), widget.getHeight());
|
||||
}
|
||||
|
||||
private Rectangle getParentBounds(final Widget widget)
|
||||
{
|
||||
final Widget parent = widget.getParent();
|
||||
final Dimension dimensions = parent == null ? client.getRealDimensions() : new Dimension(parent.getWidth(), parent.getHeight());
|
||||
x = Math.min(dimensions.width - bounds.width, x);
|
||||
y = Math.min(dimensions.height - bounds.height, y);
|
||||
|
||||
if (toRestoreX == null)
|
||||
if (parent == null)
|
||||
{
|
||||
toRestoreX = widget.getRelativeX();
|
||||
return new Rectangle(client.getRealDimensions());
|
||||
}
|
||||
|
||||
if (toRestoreY == null)
|
||||
{
|
||||
toRestoreY = widget.getRelativeY();
|
||||
}
|
||||
|
||||
widget.setRelativeX(x);
|
||||
widget.setRelativeY(y);
|
||||
|
||||
return null;
|
||||
return new Rectangle(parent.getCanvasLocation().getX(), parent.getCanvasLocation().getY(), parent.getWidth(), parent.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user