diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index af4a16ea25..c861e50e6d 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -172,6 +172,7 @@ public class WidgetID { 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; diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 761b7fab6e..2227bb3c76 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -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), diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 42b57e6366..41c7fc8de3 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -326,6 +326,7 @@ public class RuneLite // Add core overlays WidgetOverlay.createOverlays(client).forEach(overlayManager::add); overlayManager.add(worldMapOverlay.get()); + eventBus.register(worldMapOverlay.get()); overlayManager.add(tooltipOverlay.get()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldMapPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldMapPoint.java index 45fa1f874c..11b2dfc559 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldMapPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldMapPoint.java @@ -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); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WorldMapRegionOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WorldMapRegionOverlay.java index 8bfbf54398..0ae5cbafb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WorldMapRegionOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WorldMapRegionOverlay.java @@ -79,7 +79,7 @@ class WorldMapRegionOverlay extends Overlay { RenderOverview ro = client.getRenderOverview(); Widget map = client.getWidget(WidgetInfo.WORLD_MAP_VIEW); - Float pixelsPerTile = ro.getWorldMapZoom(); + float pixelsPerTile = ro.getWorldMapZoom(); if (map == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java index f892560501..1c2bfd5b86 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java @@ -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())); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index d2e13ccad3..0c9a52b7e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -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; @@ -63,12 +73,12 @@ public class WorldMapOverlay extends Overlay private final WorldMapPointManager worldMapPointManager; private final Client client; + private final List mapMenuEntries = new ArrayList<>(); + @Inject private WorldMapOverlay( Client client, - WorldMapPointManager worldMapPointManager, - MouseManager mouseManager, - WorldMapOverlayMouseListener worldMapOverlayMouseListener) + WorldMapPointManager worldMapPointManager) { this.client = client; this.worldMapPointManager = worldMapPointManager; @@ -76,7 +86,6 @@ public class WorldMapOverlay extends Overlay setPriority(OverlayPriority.HIGHEST); setLayer(OverlayLayer.MANUAL); drawAfterInterface(WidgetID.WORLD_MAP_GROUP_ID); - mouseManager.registerMouseListener(worldMapOverlayMouseListener); } @Override @@ -90,17 +99,44 @@ public class WorldMapOverlay extends Overlay } 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) @@ -111,10 +147,8 @@ public class WorldMapOverlay extends Overlay if (image != null && point != null) { Point drawPoint = mapWorldPointToGraphicsPoint(point); - if (drawPoint == null) { - worldPoint.setClickbox(null); continue; } @@ -183,15 +217,40 @@ public class WorldMapOverlay extends Overlay 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); @@ -200,8 +259,24 @@ public class WorldMapOverlay extends Overlay 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 */ @@ -214,7 +289,7 @@ public class WorldMapOverlay extends Overlay return null; } - Float pixelsPerTile = ro.getWorldMapZoom(); + float pixelsPerTile = ro.getWorldMapZoom(); Widget map = client.getWidget(WidgetInfo.WORLD_MAP_VIEW); if (map != null) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlayMouseListener.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlayMouseListener.java deleted file mode 100644 index 71af9a55dc..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlayMouseListener.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2018, Morgan Lewis - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.ui.overlay.worldmap; - -import java.awt.Rectangle; -import java.awt.event.MouseEvent; -import java.util.List; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.swing.SwingUtilities; -import net.runelite.api.Client; -import net.runelite.api.Point; -import net.runelite.api.RenderOverview; -import net.runelite.api.coords.WorldPoint; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.input.MouseAdapter; - -@Singleton -public class WorldMapOverlayMouseListener extends MouseAdapter -{ - private final Client client; - private final WorldMapPointManager worldMapPointManager; - private WorldMapPoint tooltipPoint = null; - - @Inject - private WorldMapOverlayMouseListener(Client client, WorldMapPointManager worldMapPointManager) - { - this.client = client; - this.worldMapPointManager = worldMapPointManager; - } - - @Override - public MouseEvent mousePressed(MouseEvent e) - { - final List worldMapPoints = worldMapPointManager.getWorldMapPoints(); - - if (SwingUtilities.isLeftMouseButton(e) && !worldMapPoints.isEmpty()) - { - Point mousePos = client.getMouseCanvasPosition(); - final Widget view = client.getWidget(WidgetInfo.WORLD_MAP_VIEW); - - if (view == null) - { - return e; - } - - for (WorldMapPoint worldMapPoint : worldMapPoints) - { - Rectangle clickbox = worldMapPoint.getClickbox(); - if (clickbox != null && clickbox.contains(mousePos.getX(), mousePos.getY())) - { - if (worldMapPoint.isJumpOnClick()) - { - // jump map to target, or position of point - WorldPoint target = worldMapPoint.getTarget(); - if (target == null) - { - target = worldMapPoint.getWorldPoint(); - } - RenderOverview renderOverview = client.getRenderOverview(); - renderOverview.setWorldMapPositionTarget(target); - } - e.consume(); - return worldMapPoint.onClick(e); - } - } - } - return e; - } - - @Override - public MouseEvent mouseMoved(MouseEvent mouseEvent) - { - final List worldMapPoints = worldMapPointManager.getWorldMapPoints(); - - if (worldMapPoints.isEmpty()) - { - return mouseEvent; - } - - final Point mousePos = client.getMouseCanvasPosition(); - final Widget view = client.getWidget(WidgetInfo.WORLD_MAP_VIEW); - - if (view == null) - { - return mouseEvent; - } - - final Rectangle worldMapDisplay = view.getBounds(); - - if (worldMapDisplay == null || !worldMapDisplay.contains(mousePos.getX(), mousePos.getY())) - { - if (tooltipPoint != null) - { - tooltipPoint.setTooltipVisible(false); - tooltipPoint = null; - final Widget rsTooltip = client.getWidget(WidgetInfo.WORLD_MAP_TOOLTIP); - if (rsTooltip != null) - { - rsTooltip.setHidden(false); - } - } - return mouseEvent; - } - - if (tooltipPoint != null) - { - if (tooltipPoint.getClickbox() != null - && tooltipPoint.getClickbox().contains(mousePos.getX(), mousePos.getY())) - { - return mouseEvent; - } - else - { - tooltipPoint.setTooltipVisible(false); - tooltipPoint = null; - final Widget rsTooltip = client.getWidget(WidgetInfo.WORLD_MAP_TOOLTIP); - if (rsTooltip != null) - { - rsTooltip.setHidden(false); - } - } - } - - for (WorldMapPoint worldMapPoint : worldMapPointManager.getWorldMapPoints()) - { - if (worldMapPoint.getClickbox() != null - && worldMapPoint.getClickbox().contains(mousePos.getX(), mousePos.getY()) - && worldMapPoint.getTooltip() != null) - { - worldMapPoint.setTooltipVisible(true); - tooltipPoint = worldMapPoint; - final Widget rsTooltip = client.getWidget(WidgetInfo.WORLD_MAP_TOOLTIP); - if (rsTooltip != null) - { - rsTooltip.setHidden(true); - } - return mouseEvent; - } - } - return mouseEvent; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapPoint.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapPoint.java index 836bcd1ef5..f12fd10214 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapPoint.java @@ -24,8 +24,6 @@ */ package net.runelite.client.ui.overlay.worldmap; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import javax.annotation.Nullable; import lombok.Data; @@ -53,8 +51,6 @@ public class WorldMapPoint */ private Point imagePoint; - private Rectangle clickbox; - private boolean snapToEdge; private boolean currentlyEdgeSnapped; @@ -64,7 +60,10 @@ public class WorldMapPoint */ private boolean jumpOnClick; - private boolean tooltipVisible; + /** + * Name in menu option when {@link #jumpOnClick} is set + */ + private String name; private String tooltip; @@ -74,11 +73,6 @@ public class WorldMapPoint this.image = image; } - public MouseEvent onClick(MouseEvent e) - { - return e; - } - public void onEdgeSnap() { }