Skip to content

Commit

Permalink
runelite-client: use menu entries for focusing world map points
Browse files Browse the repository at this point in the history
The previous way had usability issues since it would cover up the close
button, consumed clicks for no reason on any icon, making it difficult
to pan around the map when zoomed out, and had no tooltips.

It previously also accessed widgets on the EDT, which is a threading
issue.
  • Loading branch information
abextm authored and Adam- committed Jun 18, 2021
1 parent 2ca169a commit 1d7172c
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static class WorldMap
{
static final int MAPVIEW = 7;
static final int OVERVIEW_MAP = 10;
static final int BOTTOM_BAR = 22;
static final int SEARCH = 25;
static final int SURFACE_SELECTOR = 33;
static final int TOOLTIP = 41;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public enum WidgetInfo

WORLD_MAP_VIEW(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.MAPVIEW),
WORLD_MAP_OVERVIEW_MAP(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.OVERVIEW_MAP),
WORLD_MAP_BOTTOM_BAR(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.BOTTOM_BAR),
WORLD_MAP_SEARCH(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.SEARCH),
WORLD_MAP_SURFACE_SELECTOR(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.SURFACE_SELECTOR),
WORLD_MAP_TOOLTIP(WidgetID.WORLD_MAP_GROUP_ID, WidgetID.WorldMap.TOOLTIP),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ public void start() throws Exception
// Add core overlays
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
overlayManager.add(worldMapOverlay.get());
eventBus.register(worldMapOverlay.get());
overlayManager.add(tooltipOverlay.get());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class ClueScrollWorldMapPoint extends WorldMapPoint
this.plugin = plugin;
this.setSnapToEdge(true);
this.setJumpOnClick(true);
this.setName("Clue Scroll");
this.setImage(clueScrollWorldImage);
this.setImagePoint(clueScrollWorldImagePoint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void drawRegionOverlay(Graphics2D graphics)
{
RenderOverview ro = client.getRenderOverview();
Widget map = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
Float pixelsPerTile = ro.getWorldMapZoom();
float pixelsPerTile = ro.getWorldMapZoom();

if (map == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class PartyWorldMapPoint extends WorldMapPoint
this.member = member;
this.setSnapToEdge(true);
this.setJumpOnClick(true);
this.setName(member.getName());
this.setImagePoint(new Point(
ARROW.getWidth() / 2,
ARROW.getHeight()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,43 @@
package net.runelite.client.ui.overlay.worldmap;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Point;
import net.runelite.api.RenderOverview;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.input.MouseManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.util.ColorUtil;

@Singleton
public class WorldMapOverlay extends Overlay
{
private static final String FOCUS_ON = "Focus on";

private static final int TOOLTIP_OFFSET_HEIGHT = 25;
private static final int TOOLTIP_OFFSET_WIDTH = 5;
private static final int TOOLTIP_PADDING_HEIGHT = 1;
Expand All @@ -63,20 +73,19 @@ public class WorldMapOverlay extends Overlay
private final WorldMapPointManager worldMapPointManager;
private final Client client;

private final List<MenuEntry> mapMenuEntries = new ArrayList<>();

@Inject
private WorldMapOverlay(
Client client,
WorldMapPointManager worldMapPointManager,
MouseManager mouseManager,
WorldMapOverlayMouseListener worldMapOverlayMouseListener)
WorldMapPointManager worldMapPointManager)
{
this.client = client;
this.worldMapPointManager = worldMapPointManager;
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.HIGHEST);
setLayer(OverlayLayer.MANUAL);
drawAfterInterface(WidgetID.WORLD_MAP_GROUP_ID);
mouseManager.registerMouseListener(worldMapOverlayMouseListener);
}

@Override
Expand All @@ -90,17 +99,44 @@ public Dimension render(Graphics2D graphics)
}

Widget widget = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
if (widget == null)
Widget bottomBar = client.getWidget(WidgetInfo.WORLD_MAP_BOTTOM_BAR);
if (widget == null || bottomBar == null)
{
return null;
}

bottomBar.setOnTimerListener((JavaScriptCallback) ev ->
{
if (client.isMenuOpen() || mapMenuEntries.isEmpty())
{
return;
}

MenuEntry[] entries = client.getMenuEntries();
int end = entries.length;
entries = Arrays.copyOf(entries, end + mapMenuEntries.size());
for (int i = 0; i < mapMenuEntries.size(); i++)
{
entries[end + i] = mapMenuEntries.get(i);
}
client.setMenuEntries(entries);
});
bottomBar.setHasListener(true);

final Rectangle worldMapRectangle = widget.getBounds();
final Area mapViewArea = getWorldMapClipArea(worldMapRectangle);
final Rectangle canvasBounds = new Rectangle(0, 0, client.getCanvasWidth(), client.getCanvasHeight());
final Area canvasViewArea = getWorldMapClipArea(canvasBounds);
Area currentClip = null;

Point mousePos = client.getMouseCanvasPosition();
if (!canvasViewArea.contains(mousePos.getX(), mousePos.getY()))
{
mousePos = null;
}

mapMenuEntries.clear();

WorldMapPoint tooltipPoint = null;

for (WorldMapPoint worldPoint : points)
Expand All @@ -111,10 +147,8 @@ public Dimension render(Graphics2D graphics)
if (image != null && point != null)
{
Point drawPoint = mapWorldPointToGraphicsPoint(point);

if (drawPoint == null)
{
worldPoint.setClickbox(null);
continue;
}

Expand Down Expand Up @@ -183,15 +217,40 @@ else if (!worldPoint.isSnapToEdge() && mapViewArea != currentClip)

graphics.drawImage(image, drawX, drawY, null);
Rectangle clickbox = new Rectangle(drawX, drawY, image.getWidth(), image.getHeight());
worldPoint.setClickbox(clickbox);

if (worldPoint.isTooltipVisible())
if (mousePos != null && clickbox.contains(mousePos.getX(), mousePos.getY()))
{
tooltipPoint = worldPoint;
if (!Strings.isNullOrEmpty(worldPoint.getTooltip()))
{
tooltipPoint = worldPoint;
}

if (worldPoint.isJumpOnClick())
{
assert worldPoint.getName() != null;

WorldPoint target = worldPoint.getTarget();
if (target == null)
{
target = worldPoint.getWorldPoint();
}

MenuEntry entry = new MenuEntry();
entry.setType(MenuAction.RUNELITE.getId());
entry.setOption(FOCUS_ON);
entry.setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET));
entry.setIdentifier(target.getPlane() << 28 | target.getX() << 14 | target.getY());
mapMenuEntries.add(entry);
}
}
}
}

final Widget rsTooltip = client.getWidget(WidgetInfo.WORLD_MAP_TOOLTIP);
if (rsTooltip != null)
{
rsTooltip.setHidden(tooltipPoint != null);
}

if (tooltipPoint != null)
{
drawTooltip(graphics, tooltipPoint);
Expand All @@ -200,8 +259,24 @@ else if (!worldPoint.isSnapToEdge() && mapViewArea != currentClip)
return null;
}

@Subscribe
private void onMenuOptionClicked(MenuOptionClicked ev)
{
if (ev.getMenuAction() == MenuAction.RUNELITE && FOCUS_ON.equals(ev.getMenuOption()))
{
int pxy = ev.getId();
WorldPoint wp = new WorldPoint(
pxy >> 14 & 0x3fff,
pxy & 0x3fff,
pxy >> 28);

client.getRenderOverview().setWorldMapPositionTarget(wp);
}
}

/**
* Get the screen coordinates for a WorldPoint on the world map
*
* @param worldPoint WorldPoint to get screen coordinates of
* @return Point of screen coordinates of the center of the world point
*/
Expand All @@ -214,7 +289,7 @@ public Point mapWorldPointToGraphicsPoint(WorldPoint worldPoint)
return null;
}

Float pixelsPerTile = ro.getWorldMapZoom();
float pixelsPerTile = ro.getWorldMapZoom();

Widget map = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
if (map != null)
Expand Down
Loading

0 comments on commit 1d7172c

Please sign in to comment.