overlay: better handle picking up overlapping overlays

findManagedOverlay needs to iterate in roughly the reverse drawing
order. Also adjust the moveable tli layers to be by priority in render
oder.
This commit is contained in:
Adam
2022-05-13 11:16:17 -04:00
parent 3fcf4c4217
commit 570907ea11
3 changed files with 26 additions and 22 deletions

View File

@@ -24,7 +24,6 @@
*/
package net.runelite.client.ui.overlay;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ArrayListMultimap;
import java.awt.Dimension;
@@ -64,7 +63,6 @@ public class OverlayManager
private static final String OVERLAY_CONFIG_PREFERRED_SIZE = "_preferredSize";
private static final String RUNELITE_CONFIG_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).value();
@VisibleForTesting
static final Comparator<Overlay> OVERLAY_COMPARATOR = (a, b) ->
{
final OverlayPosition aPos = MoreObjects.firstNonNull(a.getPreferredPosition(), a.getPosition());
@@ -82,7 +80,7 @@ public class OverlayManager
// For non-dynamic overlays, higher priority means
// draw *earlier* so that they are closer to their
// defined position.
return aPos == OverlayPosition.DYNAMIC
return aPos == OverlayPosition.DYNAMIC || aPos == OverlayPosition.DETACHED
? a.getPriority().compareTo(b.getPriority())
: b.getPriority().compareTo(a.getPriority());
};

View File

@@ -25,6 +25,7 @@
package net.runelite.client.ui.overlay;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
import java.awt.Color;
import java.awt.Composite;
@@ -40,6 +41,7 @@ import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -502,22 +504,24 @@ public class OverlayRenderer extends MouseAdapter
{
synchronized (overlayManager)
{
for (Overlay overlay : overlayManager.getOverlays())
{
if (overlay.getPosition() == OverlayPosition.DYNAMIC || overlay.getPosition() == OverlayPosition.TOOLTIP)
{
// render order is roughly: under -> manual -> above -> always on top
final List<OverlayLayer> layerOrder = ImmutableList.of(OverlayLayer.UNDER_WIDGETS, OverlayLayer.MANUAL, OverlayLayer.ABOVE_WIDGETS, OverlayLayer.ALWAYS_ON_TOP);
return overlayManager.getOverlays()
.stream()
// ABOVE_SCENE overlays aren't managed
.filter(c -> layerOrder.contains(c.getLayer()))
// never allow moving dynamic or tooltip overlays
continue;
.filter(c -> c.getPosition() != OverlayPosition.DYNAMIC && c.getPosition() != OverlayPosition.TOOLTIP)
.sorted(
Comparator.<Overlay>comparingInt(c -> layerOrder.indexOf(c.getLayer()))
.thenComparing(OverlayManager.OVERLAY_COMPARATOR)
// pick order is reversed from render order
.reversed()
)
.filter(o -> o.getBounds().contains(mousePoint))
.findFirst()
.orElse(null);
}
final Rectangle bounds = overlay.getBounds();
if (bounds.contains(mousePoint))
{
return overlay;
}
}
}
return null;
}
@Override

View File

@@ -42,14 +42,16 @@ public class WidgetOverlay extends Overlay
public static Collection<WidgetOverlay> createOverlays(final OverlayManager overlayManager, final Client client)
{
return Arrays.asList(
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_CHATBOX_PARENT, OverlayPosition.DETACHED),
// classic resizable
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_CHATBOX_PARENT, OverlayPosition.DETACHED, OverlayPriority.HIGH),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_CHATBOX_PARENT, OverlayPosition.DETACHED, OverlayPriority.HIGH),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_PARENT, OverlayPosition.DETACHED),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_CHATBOX_PARENT, OverlayPosition.DETACHED),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_WIDGET, OverlayPosition.DETACHED, OverlayPriority.MED),
// modern resizable
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_TABS1, OverlayPosition.DETACHED),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_TABS2, OverlayPosition.DETACHED),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_PARENT, OverlayPosition.DETACHED),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT),
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.DETACHED, OverlayPriority.MED),
// The client forces the oxygen bar below the xp tracker, so set its priority lower
new WidgetOverlay(client, WidgetInfo.FOSSIL_ISLAND_OXYGENBAR, OverlayPosition.TOP_CENTER, OverlayPriority.HIGH),
new XpTrackerWidgetOverlay(overlayManager, client, WidgetInfo.EXPERIENCE_TRACKER_WIDGET, OverlayPosition.TOP_RIGHT),