diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuOpened.java b/runelite-api/src/main/java/net/runelite/api/events/MenuOpened.java
new file mode 100644
index 0000000000..ff183dac50
--- /dev/null
+++ b/runelite-api/src/main/java/net/runelite/api/events/MenuOpened.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018, Kamiel
+ * 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.api.events;
+
+import lombok.Data;
+import net.runelite.api.MenuEntry;
+
+@Data
+public class MenuOpened
+{
+ private MenuEntry[] menuEntries;
+
+ public MenuEntry getFirstEntry()
+ {
+ if (menuEntries.length > 0)
+ {
+ return menuEntries[menuEntries.length - 1];
+ }
+
+ return null;
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
index a3dc7fbbc4..daaa7a76ce 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
@@ -27,7 +27,6 @@ package net.runelite.client.plugins.menuentryswapper;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides;
-import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Collections;
import javax.inject.Inject;
@@ -36,9 +35,12 @@ import lombok.Setter;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.ItemComposition;
+import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.MenuEntryAdded;
+import net.runelite.api.events.MenuOpened;
+import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.PostItemComposition;
import net.runelite.api.events.WidgetMenuOptionClicked;
import net.runelite.api.widgets.WidgetInfo;
@@ -46,13 +48,12 @@ import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.game.ItemManager;
import net.runelite.client.input.KeyManager;
-import net.runelite.client.input.MouseManager;
import net.runelite.client.menus.MenuManager;
import net.runelite.client.menus.WidgetMenuOption;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
-import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.util.Text;
+import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor(
name = "Menu Entry Swapper",
@@ -62,7 +63,8 @@ public class MenuEntrySwapperPlugin extends Plugin
{
private static final String CONFIGURE = "Configure";
private static final String SAVE = "Save";
- private static final String MENU_TARGET = "Shift-click";
+ private static final String RESET = "Reset";
+ private static final String MENU_TARGET = "
Shift-click";
private static final String CONFIG_GROUP = "shiftclick";
private static final String ITEM_KEY_PREFIX = "item_";
@@ -91,9 +93,6 @@ public class MenuEntrySwapperPlugin extends Plugin
@Inject
private MenuEntrySwapperConfig config;
- @Inject
- private ShiftClickConfigurationOverlay overlay;
-
@Inject
private ShiftClickInputListener inputListener;
@@ -103,9 +102,6 @@ public class MenuEntrySwapperPlugin extends Plugin
@Inject
private ItemManager itemManager;
- @Inject
- private MouseManager mouseManager;
-
@Inject
private KeyManager keyManager;
@@ -124,12 +120,6 @@ public class MenuEntrySwapperPlugin extends Plugin
return configManager.getConfig(MenuEntrySwapperConfig.class);
}
- @Override
- public Overlay getOverlay()
- {
- return overlay;
- }
-
@Override
public void startUp()
{
@@ -191,7 +181,6 @@ public class MenuEntrySwapperPlugin extends Plugin
private void disableCustomization()
{
keyManager.unregisterKeyListener(inputListener);
- mouseManager.unregisterMouseListener(inputListener);
removeShiftClickCustomizationMenus();
configuringShiftClick = false;
}
@@ -205,16 +194,127 @@ public class MenuEntrySwapperPlugin extends Plugin
{
configuringShiftClick = event.getMenuOption().equals(CONFIGURE);
refreshShiftClickCustomizationMenus();
+ }
+ }
- if (configuringShiftClick)
+ @Subscribe
+ public void onMenuOpened(MenuOpened event)
+ {
+ if (!configuringShiftClick)
+ {
+ return;
+ }
+
+ MenuEntry firstEntry = event.getFirstEntry();
+ if (firstEntry == null)
+ {
+ return;
+ }
+
+ int widgetId = firstEntry.getParam1();
+ if (widgetId != WidgetInfo.INVENTORY.getId())
+ {
+ return;
+ }
+
+ int itemId = firstEntry.getIdentifier();
+ if (itemId == -1)
+ {
+ return;
+ }
+
+ ItemComposition itemComposition = client.getItemDefinition(itemId);
+ String itemName = itemComposition.getName();
+ String option = "Use";
+ int shiftClickActionindex = itemComposition.getShiftClickActionIndex();
+ String[] inventoryActions = itemComposition.getInventoryActions();
+
+ if (shiftClickActionindex >= 0 && shiftClickActionindex < inventoryActions.length)
+ {
+ option = inventoryActions[shiftClickActionindex];
+ }
+
+ MenuEntry[] entries = event.getMenuEntries();
+
+ for (MenuEntry entry : entries)
+ {
+ if (itemName.equals(Text.removeTags(entry.getTarget())))
{
- mouseManager.registerMouseListener(inputListener);
+ entry.setType(MenuAction.RUNELITE.getId());
+
+ if (option.equals(entry.getOption()))
+ {
+ entry.setOption("* " + option);
+ }
}
- else
+ }
+
+ final MenuEntry resetShiftClickEntry = new MenuEntry();
+ resetShiftClickEntry.setOption(RESET);
+ resetShiftClickEntry.setTarget(MENU_TARGET);
+ resetShiftClickEntry.setIdentifier(itemId);
+ resetShiftClickEntry.setParam1(widgetId);
+ resetShiftClickEntry.setType(MenuAction.RUNELITE.getId());
+ client.setMenuEntries(ArrayUtils.addAll(entries, resetShiftClickEntry));
+ }
+
+ @Subscribe
+ public void onMenuOptionClicked(MenuOptionClicked event)
+ {
+ if (event.getMenuAction() != MenuAction.RUNELITE || event.getWidgetId() != WidgetInfo.INVENTORY.getId())
+ {
+ return;
+ }
+
+ int itemId = event.getId();
+
+ if (itemId == -1)
+ {
+ return;
+ }
+
+ String option = event.getMenuOption();
+ String target = event.getMenuTarget();
+ ItemComposition itemComposition = client.getItemDefinition(itemId);
+
+ if (option.equals(RESET) && target.equals(MENU_TARGET))
+ {
+ unsetSwapConfig(itemId);
+ itemComposition.resetShiftClickActionIndex();
+ return;
+ }
+
+ if (!itemComposition.getName().equals(Text.removeTags(target)))
+ {
+ return;
+ }
+
+ int index = -1;
+ boolean valid = false;
+
+ if (option.equals("Use")) //because "Use" is not in inventoryActions
+ {
+ valid = true;
+ }
+ else
+ {
+ String[] inventoryActions = itemComposition.getInventoryActions();
+
+ for (index = 0; index < inventoryActions.length; index++)
{
- mouseManager.unregisterMouseListener(inputListener);
+ if (option.equals(inventoryActions[index]))
+ {
+ valid = true;
+ break;
+ }
}
}
+
+ if (valid)
+ {
+ setSwapConfig(itemId, index);
+ itemComposition.setShiftClickActionIndex(index);
+ }
}
@Subscribe
@@ -380,51 +480,6 @@ public class MenuEntrySwapperPlugin extends Plugin
}
}
- public void cycleItemShiftClickAction(WidgetItem item, int mouseClick)
- {
- ItemComposition itemComposition = client.getItemDefinition(item.getId());
-
- if (mouseClick == MouseEvent.BUTTON1)
- {
- String[] actions = itemComposition.getInventoryActions();
- int shiftClickActionIndex = itemComposition.getShiftClickActionIndex();
- int nextActionIndex = getNextActionIndex(actions, shiftClickActionIndex);
- setSwapConfig(item.getId(), nextActionIndex);
- itemComposition.setShiftClickActionIndex(nextActionIndex);
- }
- else if (mouseClick == MouseEvent.BUTTON3)
- {
- unsetSwapConfig(item.getId());
- itemComposition.resetShiftClickActionIndex();
- }
- }
-
- private int getNextActionIndex(String[] actions, int currentIndex)
- {
- int size = actions.length;
- int index = currentIndex + 1;
-
- for (int i = index; i < index + size; i++)
- {
- if (i == size)
- {
- // -1 is used for "Use" which is not in actions
- return -1;
- }
-
- index = i % size;
-
- if (actions[index] == null)
- {
- continue;
- }
-
- break;
- }
-
- return index;
- }
-
private void removeShiftClickCustomizationMenus()
{
menuManager.removeManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/ShiftClickConfigurationOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/ShiftClickConfigurationOverlay.java
deleted file mode 100644
index ec9db0e938..0000000000
--- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/ShiftClickConfigurationOverlay.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2018, Kamiel
- * 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.plugins.menuentryswapper;
-
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import javax.inject.Inject;
-import net.runelite.api.Client;
-import net.runelite.api.ItemComposition;
-import net.runelite.api.widgets.WidgetInfo;
-import net.runelite.api.widgets.WidgetItem;
-import net.runelite.client.ui.FontManager;
-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.components.TextComponent;
-
-public class ShiftClickConfigurationOverlay extends Overlay
-{
- @Inject
- private Client client;
-
- @Inject
- private MenuEntrySwapperPlugin plugin;
-
- @Inject
- public ShiftClickConfigurationOverlay()
- {
- setPosition(OverlayPosition.DYNAMIC);
- setLayer(OverlayLayer.ABOVE_WIDGETS);
- }
-
- @Override
- public Dimension render(Graphics2D graphics)
- {
- if (!plugin.isConfiguringShiftClick() || client.isMenuOpen() || client.getWidget(WidgetInfo.INVENTORY).isHidden())
- {
- return null;
- }
-
- Font font = FontManager.getRunescapeSmallFont();
- graphics.setFont(font);
-
- net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
- Point mousePoint = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY());
-
- for (WidgetItem item : plugin.getInventoryItems())
- {
- final Rectangle bounds = item.getCanvasBounds();
-
- if (!bounds.contains(mousePoint))
- {
- continue;
- }
-
- ItemComposition itemComposition = client.getItemDefinition(item.getId());
- String[] actions = itemComposition.getInventoryActions();
- int index = itemComposition.getShiftClickActionIndex();
-
- if (index >= 0 && actions[index] == null)
- {
- continue;
- }
-
- String action = index == -1 ? "Use" : actions[index];
- int textWidth = graphics.getFontMetrics().stringWidth(action);
- int textLocationX = (int) (bounds.x + bounds.getWidth() / 2 - textWidth / 2);
- int textLocationY = bounds.y + 28;
- final TextComponent textComponent = new TextComponent();
- textComponent.setPosition(new Point(textLocationX, textLocationY));
- textComponent.setText(action);
- textComponent.render(graphics);
- }
-
- return null;
- }
-}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/ShiftClickInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/ShiftClickInputListener.java
index dddf78b696..f7dde77e00 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/ShiftClickInputListener.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/ShiftClickInputListener.java
@@ -24,19 +24,13 @@
*/
package net.runelite.client.plugins.menuentryswapper;
-import java.awt.Point;
import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
import javax.inject.Inject;
import net.runelite.api.Client;
-import net.runelite.api.widgets.Widget;
-import net.runelite.api.widgets.WidgetInfo;
-import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.input.KeyListener;
-import net.runelite.client.input.MouseListener;
-public class ShiftClickInputListener extends MouseListener implements KeyListener
+public class ShiftClickInputListener implements KeyListener
{
@Inject
private ClientThread clientThread;
@@ -47,60 +41,6 @@ public class ShiftClickInputListener extends MouseListener implements KeyListene
@Inject
private MenuEntrySwapperPlugin plugin;
- @Inject
- private MenuEntrySwapperConfig config;
-
- private WidgetItem getClickedItem(Point point)
- {
- for (WidgetItem item : plugin.getInventoryItems())
- {
- if (item.getCanvasBounds().contains(point))
- {
- return item;
- }
- }
-
- return null;
- }
-
- @Override
- public MouseEvent mouseClicked(MouseEvent event)
- {
- if (!config.shiftClickCustomization() || !isValidInventoryClick(event.getPoint()))
- {
- return event;
- }
-
- final WidgetItem item = getClickedItem(event.getPoint());
- final int button = event.getButton();
-
- if (item != null)
- {
- clientThread.invokeLater(() -> plugin.cycleItemShiftClickAction(item, button));
- event.consume();
- }
-
- return event;
- }
-
- @Override
- public MouseEvent mousePressed(MouseEvent event)
- {
- if (!config.shiftClickCustomization() || !isValidInventoryClick(event.getPoint()))
- {
- return event;
- }
-
- event.consume();
- return event;
- }
-
- private boolean isValidInventoryClick(Point point)
- {
- Widget widget = client.getWidget(WidgetInfo.INVENTORY).getParent();
- return !widget.isHidden() && !client.isMenuOpen() && widget.getBounds().contains(point);
- }
-
@Override
public void keyTyped(KeyEvent event)
{
diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java
index 0237aa6e54..a30822d80a 100644
--- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java
+++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java
@@ -62,6 +62,7 @@ import net.runelite.api.events.ExperienceChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GrandExchangeOfferChanged;
import net.runelite.api.events.MapRegionChanged;
+import net.runelite.api.events.MenuOpened;
import net.runelite.api.events.PlayerMenuOptionsChanged;
import net.runelite.api.events.ResizeableChanged;
import net.runelite.api.events.VarbitChanged;
@@ -661,4 +662,18 @@ public abstract class RSClientMixin implements RSClient
{
eventBus.post(new ClanChanged(client.getClanMemberManager() != null));
}
+
+ @FieldHook("isMenuOpen")
+ @Inject
+ public static void menuOpened(int opened)
+ {
+ if (!client.isMenuOpen())
+ {
+ return;
+ }
+
+ MenuOpened event = new MenuOpened();
+ event.setMenuEntries(client.getMenuEntries());
+ eventBus.post(event);
+ }
}