Merge pull request #7089 from TheStonedTurtle/OverlayRightClickMenu

Add right click menu functionality to overlays
This commit is contained in:
Tomas Slusny
2019-01-14 09:18:54 +01:00
committed by GitHub
5 changed files with 130 additions and 3 deletions

View File

@@ -260,6 +260,10 @@ public enum MenuAction
* Menu action injected by runelite for its menu items. * Menu action injected by runelite for its menu items.
*/ */
RUNELITE(1500), RUNELITE(1500),
/**
* Menu action injected by runelite for overlay menu items.
*/
RUNELITE_OVERLAY(1501),
FOLLOW(2046), FOLLOW(2046),
TRADE(2047), TRADE(2047),

View File

@@ -229,11 +229,22 @@ public interface RuneLiteConfig extends Config
return FontType.REGULAR; return FontType.REGULAR;
} }
@ConfigItem(
keyName = "overlayRightClick",
name = "Require Shift for overlay menu options",
description = "Toggles whether the overlay right-click menu requires holding down the shift key",
position = 33
)
default boolean overlayRightClick()
{
return true;
}
@ConfigItem( @ConfigItem(
keyName = "infoBoxVertical", keyName = "infoBoxVertical",
name = "Display infoboxes vertically", name = "Display infoboxes vertically",
description = "Toggles the infoboxes to display vertically", description = "Toggles the infoboxes to display vertically",
position = 33 position = 34
) )
default boolean infoBoxVertical() default boolean infoBoxVertical()
{ {
@@ -244,7 +255,7 @@ public interface RuneLiteConfig extends Config
keyName = "infoBoxWrap", keyName = "infoBoxWrap",
name = "Infobox wrap count", name = "Infobox wrap count",
description = "Configures the amount of infoboxes shown before wrapping", description = "Configures the amount of infoboxes shown before wrapping",
position = 34 position = 35
) )
default int infoBoxWrap() default int infoBoxWrap()
{ {
@@ -255,7 +266,7 @@ public interface RuneLiteConfig extends Config
keyName = "infoBoxSize", keyName = "infoBoxSize",
name = "Infobox size (px)", name = "Infobox size (px)",
description = "Configures the size of each infobox in pixels", description = "Configures the size of each infobox in pixels",
position = 35 position = 36
) )
default int infoBoxSize() default int infoBoxSize()
{ {

View File

@@ -27,6 +27,7 @@ package net.runelite.client.ui.overlay;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.LinkedHashMap;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity; import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity;
@@ -42,6 +43,7 @@ public abstract class Overlay implements LayoutableRenderableEntity
private OverlayPosition position = OverlayPosition.TOP_LEFT; private OverlayPosition position = OverlayPosition.TOP_LEFT;
private OverlayPriority priority = OverlayPriority.NONE; private OverlayPriority priority = OverlayPriority.NONE;
private OverlayLayer layer = OverlayLayer.UNDER_WIDGETS; private OverlayLayer layer = OverlayLayer.UNDER_WIDGETS;
private final LinkedHashMap<String, Runnable> menuOptions = new LinkedHashMap<>();
/** /**
* Overlay name, used for saving the overlay, needs to be unique * Overlay name, used for saving the overlay, needs to be unique

View File

@@ -38,11 +38,14 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import net.runelite.api.MenuAction;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.PluginChanged; import net.runelite.client.events.PluginChanged;
import net.runelite.client.util.Text;
/** /**
* Manages state of all game overlays * Manages state of all game overlays
@@ -107,6 +110,39 @@ public class OverlayManager
rebuildOverlayLayers(); rebuildOverlayLayers();
} }
@Subscribe
public void onMenuOptionClicked(MenuOptionClicked event)
{
if (!MenuAction.RUNELITE_OVERLAY.equals(event.getMenuAction()))
{
return;
}
event.consume();
final String overlayName = Text.removeTags(event.getMenuTarget());
Overlay overlay = null;
for (Overlay o : overlays)
{
if (o.getName().equals(overlayName))
{
overlay = o;
break;
}
}
if (overlay == null)
{
return;
}
final Runnable r = overlay.getMenuOptions().get(event.getMenuOption());
if (r != null)
{
r.run();
}
}
/** /**
* Gets all of the overlays on a layer sorted by priority and position * Gets all of the overlays on a layer sorted by priority and position
* *

View File

@@ -34,11 +34,16 @@ import java.awt.Rectangle;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
@@ -48,10 +53,14 @@ import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager; import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseAdapter; import net.runelite.client.input.MouseAdapter;
import net.runelite.client.input.MouseManager; import net.runelite.client.input.MouseManager;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
import org.apache.commons.lang3.ArrayUtils;
@Singleton @Singleton
public class OverlayRenderer extends MouseAdapter implements KeyListener public class OverlayRenderer extends MouseAdapter implements KeyListener
{ {
private static final int OVERLAY_MENU_HOTKEY = KeyEvent.VK_SHIFT;
private static final int BORDER = 5; private static final int BORDER = 5;
private static final int BORDER_TOP = BORDER + 15; private static final int BORDER_TOP = BORDER + 15;
private static final int PADDING = 2; private static final int PADDING = 2;
@@ -69,6 +78,8 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
private final Point mousePosition = new Point(); private final Point mousePosition = new Point();
private Overlay movedOverlay; private Overlay movedOverlay;
private boolean inOverlayDraggingMode; private boolean inOverlayDraggingMode;
private boolean inOverlayMenuMode;
private MenuEntry[] menuEntries;
// Overlay state validation // Overlay state validation
private Rectangle viewportBounds; private Rectangle viewportBounds;
@@ -99,6 +110,30 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
if (!event.isFocused()) if (!event.isFocused())
{ {
inOverlayDraggingMode = false; inOverlayDraggingMode = false;
inOverlayMenuMode = false;
menuEntries = null;
}
}
@Subscribe
protected void onClientTick(ClientTick t)
{
if (menuEntries == null || client.isMenuOpen())
{
menuEntries = null;
return;
}
client.setMenuEntries(ArrayUtils.addAll(menuEntries, client.getMenuEntries()));
}
@Subscribe
public void onConfigChanged(ConfigChanged c)
{
if (c.getGroup().equals("runelite") && c.getKey().equals("overlayRightClick"))
{
inOverlayMenuMode = false;
menuEntries = null;
} }
} }
@@ -227,6 +262,13 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
graphics.draw(bounds); graphics.draw(bounds);
graphics.setColor(previous); graphics.setColor(previous);
} }
final boolean toggleCheck = inOverlayMenuMode || !runeLiteConfig.overlayRightClick();
final Point mouse = new Point(client.getMouseCanvasPosition().getX(), client.getMouseCanvasPosition().getY());
if (toggleCheck && bounds.contains(mouse) && !client.isMenuOpen())
{
menuEntries = createRightClickMenuEntries(overlay);
}
} }
} }
} }
@@ -356,6 +398,11 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
{ {
inOverlayDraggingMode = true; inOverlayDraggingMode = true;
} }
if (runeLiteConfig.overlayRightClick() && e.getKeyCode() == OVERLAY_MENU_HOTKEY)
{
inOverlayMenuMode = true;
}
} }
@Override @Override
@@ -365,6 +412,12 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
{ {
inOverlayDraggingMode = false; inOverlayDraggingMode = false;
} }
if (runeLiteConfig.overlayRightClick() && e.getKeyCode() == OVERLAY_MENU_HOTKEY)
{
inOverlayMenuMode = false;
menuEntries = null;
}
} }
private void safeRender(Client client, Overlay overlay, OverlayLayer layer, Graphics2D graphics, Point point) private void safeRender(Client client, Overlay overlay, OverlayLayer layer, Graphics2D graphics, Point point)
@@ -494,4 +547,25 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
new Rectangle(rightChatboxPoint, SNAP_CORNER_SIZE), new Rectangle(rightChatboxPoint, SNAP_CORNER_SIZE),
new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE)); new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE));
} }
private static MenuEntry[] createRightClickMenuEntries(Overlay overlay)
{
final Set<String> options = overlay.getMenuOptions().keySet();
final MenuEntry[] entries = new MenuEntry[options.size()];
// Add in reverse order so they display correctly in the right-click menu
int idx = options.size() - 1;
for (final String option : options)
{
final MenuEntry entry = new MenuEntry();
entry.setOption(option);
entry.setTarget(ColorUtil.wrapWithColorTag(overlay.getName(), JagexColors.MENU_TARGET));
entry.setIdentifier(-1);
entry.setType(MenuAction.RUNELITE_OVERLAY.getId());
entries[idx--] = entry;
}
return entries;
}
} }