Merge pull request #1231 from Kamielvf/shift-click-configuration
Change shift-click customization behaviour
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 = "<col=ff9040>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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user