client: add support for menu options on infoboxes
This commit is contained in:
@@ -277,6 +277,10 @@ public enum MenuAction
|
||||
* a player and have its identifier set to a player index.
|
||||
*/
|
||||
RUNELITE_PLAYER(1503),
|
||||
/**
|
||||
* Menu action for InfoBox menu entries
|
||||
*/
|
||||
RUNELITE_INFOBOX(1504),
|
||||
|
||||
/**
|
||||
* Menu action triggered when the id is not defined in this class.
|
||||
|
||||
@@ -361,6 +361,7 @@ public class RuneLite
|
||||
eventBus.register(lootManager.get());
|
||||
eventBus.register(chatboxPanelManager.get());
|
||||
eventBus.register(hooks.get());
|
||||
eventBus.register(infoBoxOverlay.get());
|
||||
|
||||
// Add core overlays
|
||||
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* 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.events;
|
||||
|
||||
import lombok.Value;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
|
||||
@Value
|
||||
public class InfoBoxMenuClicked
|
||||
{
|
||||
private OverlayMenuEntry entry;
|
||||
private InfoBox infoBox;
|
||||
}
|
||||
@@ -33,9 +33,11 @@ import javax.inject.Inject;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
@@ -166,7 +168,12 @@ class DevToolsPanel extends PluginPanel
|
||||
});
|
||||
|
||||
final JButton newInfoboxBtn = new JButton("Infobox");
|
||||
newInfoboxBtn.addActionListener(e -> infoBoxManager.addInfoBox(new Counter(ImageUtil.getResourceStreamFromClass(getClass(), "devtools_icon.png"), plugin, 42)));
|
||||
newInfoboxBtn.addActionListener(e ->
|
||||
{
|
||||
Counter counter = new Counter(ImageUtil.getResourceStreamFromClass(getClass(), "devtools_icon.png"), plugin, 42);
|
||||
counter.getMenuEntries().add(new OverlayMenuEntry(MenuAction.RUNELITE_INFOBOX, "Test", "DevTools"));
|
||||
infoBoxManager.addInfoBox(counter);
|
||||
});
|
||||
container.add(newInfoboxBtn);
|
||||
|
||||
final JButton clearInfoboxBtn = new JButton("Clear Infobox");
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -136,7 +135,8 @@ public class OverlayManager
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuAction() != MenuAction.RUNELITE_OVERLAY)
|
||||
MenuAction menuAction = event.getMenuAction();
|
||||
if (menuAction != MenuAction.RUNELITE_OVERLAY && menuAction != MenuAction.RUNELITE_OVERLAY_CONFIG)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -147,12 +147,13 @@ public class OverlayManager
|
||||
if (overlay != null)
|
||||
{
|
||||
List<OverlayMenuEntry> menuEntries = overlay.getMenuEntries();
|
||||
Optional<OverlayMenuEntry> optionalOverlayMenuEntry = menuEntries.stream()
|
||||
OverlayMenuEntry overlayMenuEntry = menuEntries.stream()
|
||||
.filter(me -> me.getOption().equals(event.getMenuOption()))
|
||||
.findAny();
|
||||
if (optionalOverlayMenuEntry.isPresent())
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
if (overlayMenuEntry != null)
|
||||
{
|
||||
eventBus.post(new OverlayMenuClicked(optionalOverlayMenuEntry.get(), overlay));
|
||||
eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ import javax.swing.SwingUtilities;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.events.BeforeRender;
|
||||
import net.runelite.api.events.ClientTick;
|
||||
@@ -807,7 +806,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
||||
final MenuEntry entry = new MenuEntry();
|
||||
entry.setOption(overlayMenuEntry.getOption());
|
||||
entry.setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET));
|
||||
entry.setType(MenuAction.RUNELITE_OVERLAY.getId());
|
||||
entry.setType(overlayMenuEntry.getMenuAction().getId());
|
||||
entry.setIdentifier(overlayManager.getOverlays().indexOf(overlay)); // overlay id
|
||||
|
||||
entries[i] = entry;
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.awt.image.BufferedImage;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
|
||||
@Setter
|
||||
public class InfoBoxComponent implements LayoutableRenderableEntity
|
||||
@@ -54,6 +55,8 @@ public class InfoBoxComponent implements LayoutableRenderableEntity
|
||||
private Color color = Color.WHITE;
|
||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||
private BufferedImage image;
|
||||
@Getter
|
||||
private InfoBox infoBox;
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
|
||||
@@ -26,11 +26,14 @@ package net.runelite.client.ui.overlay.infobox;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
|
||||
public abstract class InfoBox
|
||||
{
|
||||
@@ -54,6 +57,10 @@ public abstract class InfoBox
|
||||
@Setter
|
||||
private String tooltip;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private List<OverlayMenuEntry> menuEntries = new ArrayList<>();
|
||||
|
||||
public InfoBox(BufferedImage image, @Nonnull Plugin plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
|
||||
@@ -31,11 +31,18 @@ import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Collections;
|
||||
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.events.MenuOptionClicked;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.InfoBoxMenuClicked;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPanel;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
||||
@@ -54,18 +61,23 @@ public class InfoBoxOverlay extends OverlayPanel
|
||||
private final TooltipManager tooltipManager;
|
||||
private final Client client;
|
||||
private final RuneLiteConfig config;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private InfoBoxComponent hoveredComponent;
|
||||
|
||||
@Inject
|
||||
private InfoBoxOverlay(
|
||||
InfoBoxManager infoboxManager,
|
||||
TooltipManager tooltipManager,
|
||||
Client client,
|
||||
RuneLiteConfig config)
|
||||
RuneLiteConfig config,
|
||||
EventBus eventBus)
|
||||
{
|
||||
this.tooltipManager = tooltipManager;
|
||||
this.infoboxManager = infoboxManager;
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
this.eventBus = eventBus;
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
setClearChildren(false);
|
||||
|
||||
@@ -80,6 +92,12 @@ public class InfoBoxOverlay extends OverlayPanel
|
||||
{
|
||||
final List<InfoBox> infoBoxes = infoboxManager.getInfoBoxes();
|
||||
|
||||
final boolean menuOpen = client.isMenuOpen();
|
||||
if (!menuOpen)
|
||||
{
|
||||
hoveredComponent = null;
|
||||
}
|
||||
|
||||
if (infoBoxes.isEmpty())
|
||||
{
|
||||
return null;
|
||||
@@ -112,6 +130,7 @@ public class InfoBoxOverlay extends OverlayPanel
|
||||
infoBoxComponent.setTooltip(box.getTooltip());
|
||||
infoBoxComponent.setPreferredSize(new Dimension(config.infoBoxSize(), config.infoBoxSize()));
|
||||
infoBoxComponent.setBackgroundColor(config.overlayBackgroundColor());
|
||||
infoBoxComponent.setInfoBox(box);
|
||||
panelComponent.getChildren().add(infoBoxComponent);
|
||||
}
|
||||
|
||||
@@ -122,25 +141,55 @@ public class InfoBoxOverlay extends OverlayPanel
|
||||
|
||||
for (final LayoutableRenderableEntity child : panelComponent.getChildren())
|
||||
{
|
||||
if (child instanceof InfoBoxComponent)
|
||||
final InfoBoxComponent component = (InfoBoxComponent) child;
|
||||
|
||||
// Create intersection rectangle
|
||||
final Rectangle intersectionRectangle = new Rectangle(component.getBounds());
|
||||
intersectionRectangle.translate(getBounds().x, getBounds().y);
|
||||
|
||||
if (intersectionRectangle.contains(mouse))
|
||||
{
|
||||
final InfoBoxComponent component = (InfoBoxComponent) child;
|
||||
|
||||
if (!Strings.isNullOrEmpty(component.getTooltip()))
|
||||
final String tooltip = component.getTooltip();
|
||||
if (!Strings.isNullOrEmpty(tooltip))
|
||||
{
|
||||
// Create intersection rectangle
|
||||
final Rectangle intersectionRectangle = new Rectangle(component.getBounds());
|
||||
intersectionRectangle.translate(getBounds().x, getBounds().y);
|
||||
|
||||
if (intersectionRectangle.contains(mouse))
|
||||
{
|
||||
tooltipManager.add(new Tooltip(component.getTooltip()));
|
||||
}
|
||||
tooltipManager.add(new Tooltip(tooltip));
|
||||
}
|
||||
|
||||
if (!menuOpen)
|
||||
{
|
||||
hoveredComponent = component;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
return dimension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OverlayMenuEntry> getMenuEntries()
|
||||
{
|
||||
// we dynamically build the menu options based on which infobox is hovered
|
||||
return hoveredComponent == null ? Collections.emptyList() : hoveredComponent.getInfoBox().getMenuEntries();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked menuOptionClicked)
|
||||
{
|
||||
if (menuOptionClicked.getMenuAction() != MenuAction.RUNELITE_INFOBOX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfoBox infoBox = hoveredComponent.getInfoBox();
|
||||
OverlayMenuEntry overlayMenuEntry = infoBox.getMenuEntries().stream()
|
||||
.filter(me -> me.getOption().equals(menuOptionClicked.getMenuOption()))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
if (overlayMenuEntry != null)
|
||||
{
|
||||
eventBus.post(new InfoBoxMenuClicked(overlayMenuEntry, infoBox));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user