BankTags: refactor to use ChatboxPanelManager

This commit is contained in:
Ron Young
2018-10-27 09:30:10 -05:00
committed by Tomas Slusny
parent fcb1029b0d
commit f8c94fb71c
3 changed files with 257 additions and 213 deletions

View File

@@ -38,6 +38,7 @@ import java.util.Collection;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.List;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.InventoryID;
@@ -46,7 +47,6 @@ import net.runelite.api.ItemComposition;
import net.runelite.api.ItemContainer;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.VarClientStr;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.DraggingWidgetChanged;
import net.runelite.api.events.FocusChanged;
@@ -60,10 +60,10 @@ import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.game.ChatboxInputManager;
import net.runelite.client.game.ItemManager;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.input.MouseManager;
import net.runelite.client.input.MouseWheelListener;
import net.runelite.client.plugins.Plugin;
@@ -85,7 +85,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis
public static final Joiner JOINER = Joiner.on(",").skipNulls();
public static final String CONFIG_GROUP = "banktags";
public static final String TAG_SEARCH = "tag:";
public static final String EDIT_TAGS_MENU_OPTION = "Edit-tags";
private static final String EDIT_TAGS_MENU_OPTION = "Edit-tags";
public static final String ICON_SEARCH = "icon_";
public static final String VAR_TAG_SUFFIX = "*";
@@ -106,7 +106,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis
private ClientThread clientThread;
@Inject
private ChatboxInputManager chatboxInputManager;
private ChatboxPanelManager chatboxPanelManager;
@Inject
private MouseManager mouseManager;
@@ -276,33 +276,31 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis
.map(i -> i + "*")
.forEach(tags::add);
// Create initial value string
String initialValue = JOINER.join(tags);
chatboxInputManager.openInputWindow(name + " tags:<br>(append " + VAR_TAG_SUFFIX + " for variation tag)", initialValue, (newValue) ->
{
if (!Objects.equals(newValue, client.getVar(VarClientStr.INPUT_TEXT)))
{
return;
}
chatboxPanelManager.openTextInput(name + " tags:<br>(append " + VAR_TAG_SUFFIX + " for variation tag)")
.value(initialValue)
.onDone((newTags) ->
clientThread.invoke(() ->
{
// Split inputted tags to vartags (ending with *) and regular tags
final Collection<String> newTags = new ArrayList<>(SPLITTER.splitToList(newValue.toLowerCase()));
final Collection<String> newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s ->
{
newTags.remove(s);
return s.substring(0, s.length() - VAR_TAG_SUFFIX.length());
}).collect(Collectors.toList());
// Split inputted tags to vartags (ending with *) and regular tags
final Collection<String> newTags = new ArrayList<>(SPLITTER.splitToList(newValue.toLowerCase()));
final Collection<String> newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s ->
{
newTags.remove(s);
return s.substring(0, s.length() - VAR_TAG_SUFFIX.length());
}).collect(Collectors.toList());
// And save them
tagManager.setTagString(itemId, JOINER.join(newTags), false);
tagManager.setTagString(itemId, JOINER.join(newVarTags), true);
// And save them
tagManager.setTagString(itemId, JOINER.join(newTags), false);
tagManager.setTagString(itemId, JOINER.join(newVarTags), true);
// Check both previous and current tags in case the tag got removed in new tags or in case
// the tag got added in new tags
tabInterface.updateTabIfActive(SPLITTER.splitToList(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), "")));
tabInterface.updateTabIfActive(SPLITTER.splitToList(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), "")));
});
// Check both previous and current tags in case the tag got removed in new tags or in case
// the tag got added in new tags
tabInterface.updateTabIfActive(SPLITTER.splitToList(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), "")));
tabInterface.updateTabIfActive(SPLITTER.splitToList(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), "")));
}))
.build();
}
else
{

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
* 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.banktags.tabs;
class MenuIndexes
{
static class NewTab
{
static final int NEW_TAB = 2;
static final int IMPORT_TAB = 3;
}
static class Tab
{
static final int OPEN_TAG = 2;
static final int CHANGE_ICON = 3;
static final int DELETE_TAB = 4;
static final int EXPORT_TAB = 5;
}
}

View File

@@ -27,6 +27,7 @@ package net.runelite.client.plugins.banktags.tabs;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Runnables;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Toolkit;
@@ -56,6 +57,7 @@ import net.runelite.api.ItemContainer;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Point;
import net.runelite.api.ScriptEvent;
import net.runelite.api.ScriptID;
import net.runelite.api.SoundEffectID;
import net.runelite.api.SpriteID;
@@ -67,14 +69,15 @@ import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.vars.InputType;
import net.runelite.api.widgets.ItemQuantityMode;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetConfig;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.Notifier;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.game.ChatboxInputManager;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.plugins.banktags.BankTagsConfig;
import net.runelite.client.plugins.banktags.BankTagsPlugin;
import static net.runelite.client.plugins.banktags.BankTagsPlugin.CONFIG_GROUP;
@@ -83,6 +86,8 @@ import static net.runelite.client.plugins.banktags.BankTagsPlugin.SPLITTER;
import static net.runelite.client.plugins.banktags.BankTagsPlugin.TAG_SEARCH;
import static net.runelite.client.plugins.banktags.BankTagsPlugin.VAR_TAG_SUFFIX;
import net.runelite.client.plugins.banktags.TagManager;
import static net.runelite.client.plugins.banktags.tabs.MenuIndexes.NewTab;
import static net.runelite.client.plugins.banktags.tabs.MenuIndexes.Tab;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.Text;
@@ -128,7 +133,7 @@ public class TabInterface
private final ConfigManager configManager;
private final TagManager tagManager;
private final TabManager tabManager;
private final ChatboxInputManager chatboxInputManager;
private final ChatboxPanelManager chatboxPanelManager;
private final BankTagsConfig config;
private final Notifier notifier;
private final Rectangle bounds = new Rectangle();
@@ -161,7 +166,7 @@ public class TabInterface
final ConfigManager configManager,
final TagManager tagManager,
final TabManager tabManager,
final ChatboxInputManager chatboxInputManager,
final ChatboxPanelManager chatboxPanelManager,
final BankTagsConfig config,
final Notifier notifier)
{
@@ -171,7 +176,7 @@ public class TabInterface
this.configManager = configManager;
this.tagManager = tagManager;
this.tabManager = tabManager;
this.chatboxInputManager = chatboxInputManager;
this.chatboxPanelManager = chatboxPanelManager;
this.config = config;
this.notifier = notifier;
}
@@ -201,16 +206,19 @@ public class TabInterface
int clickmask = upButton.getClickMask();
clickmask |= WidgetConfig.DRAG;
upButton.setClickMask(clickmask);
upButton.setOnOpListener((JavaScriptCallback) (event) -> scrollTab(-1));
downButton = createGraphic("", TabSprites.DOWN_ARROW.getSpriteId(), -1, TAB_WIDTH, BUTTON_HEIGHT, bounds.x, 0, true);
downButton.setAction(1, SCROLL_DOWN);
clickmask = downButton.getClickMask();
clickmask |= WidgetConfig.DRAG;
downButton.setClickMask(clickmask);
downButton.setOnOpListener((JavaScriptCallback) (event) -> scrollTab(1));
newTab = createGraphic("", TabSprites.NEW_TAB.getSpriteId(), -1, TAB_WIDTH, 39, bounds.x, 0, true);
newTab.setAction(1, NEW_TAB);
newTab.setAction(2, IMPORT_TAB);
newTab.setOnOpListener((JavaScriptCallback) this::handleNewTab);
tabManager.clear();
tabManager.getAllTabs().forEach(this::loadTab);
@@ -223,6 +231,167 @@ public class TabInterface
}
}
private void handleDeposit(MenuOptionClicked event, Boolean inventory)
{
ItemContainer container = client.getItemContainer(inventory ? InventoryID.INVENTORY : InventoryID.EQUIPMENT);
if (container == null)
{
return;
}
List<Integer> items = Arrays.stream(container.getItems())
.filter(Objects::nonNull)
.map(Item::getId)
.filter(id -> id != -1)
.collect(Collectors.toList());
if (!Strings.isNullOrEmpty(event.getMenuTarget()))
{
if (activeTab != null && Text.removeTags(event.getMenuTarget()).equals(activeTab.getTag()))
{
for (Integer item : items)
{
tagManager.addTag(item, activeTab.getTag(), false);
}
openTag(TAG_SEARCH + activeTab.getTag());
}
return;
}
chatboxPanelManager.openTextInput((inventory ? "Inventory " : "Equipment ") + " tags:")
.onDone((newTags) ->
clientThread.invoke(() ->
{
final List<String> tags = SPLITTER.splitToList(newTags.toLowerCase());
for (Integer item : items)
{
tagManager.addTags(item, tags, false);
}
updateTabIfActive(tags);
}))
.build();
}
private void handleNewTab(ScriptEvent event)
{
switch (event.getOp())
{
case NewTab.NEW_TAB:
chatboxPanelManager.openTextInput("Tag name")
.onDone((tagName) -> clientThread.invoke(() ->
{
if (!Strings.isNullOrEmpty(tagName))
{
loadTab(tagName);
tabManager.save();
scrollTab(0);
}
}))
.build();
break;
case NewTab.IMPORT_TAB:
try
{
final String dataString = Toolkit
.getDefaultToolkit()
.getSystemClipboard()
.getData(DataFlavor.stringFlavor)
.toString()
.trim();
final Iterator<String> dataIter = BankTagsPlugin.SPLITTER.split(dataString).iterator();
final String name = dataIter.next();
final String icon = dataIter.next();
configManager.setConfiguration(CONFIG_GROUP, ICON_SEARCH + name, icon);
while (dataIter.hasNext())
{
final int itemId = Integer.valueOf(dataIter.next());
tagManager.addTag(itemId, name, itemId < 0);
}
loadTab(name);
tabManager.save();
scrollTab(0);
if (activeTab != null && name.equals(activeTab.getTag()))
{
openTag(TAG_SEARCH + activeTab.getTag());
}
notifier.notify("Tag tab " + name + " has been imported from your clipboard!");
}
catch (UnsupportedFlavorException | NoSuchElementException | IOException | NumberFormatException ex)
{
notifier.notify("Failed to import tag tab from clipboard, invalid format.");
}
}
}
private void handleTagTab(ScriptEvent event)
{
switch (event.getOp())
{
case Tab.OPEN_TAG:
client.setVarbitValue(client.getVarps(), Varbits.CURRENT_BANK_TAB.getId(), 0);
Widget clicked = event.getSource();
TagTab tab = tabManager.find(Text.removeTags(clicked.getName()));
if (tab.equals(activeTab))
{
resetSearch();
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
}
else
{
openTag(TAG_SEARCH + Text.removeTags(clicked.getName()));
}
client.playSoundEffect(SoundEffectID.UI_BOOP);
break;
case Tab.CHANGE_ICON:
iconToSet = tabManager.find(Text.removeTags(event.getOpbase()));
break;
case Tab.DELETE_TAB:
String target = Text.standardize(event.getOpbase());
chatboxPanelManager.openTextMenuInput("Delete " + target)
.option("1. Tab and tag from all items", () ->
clientThread.invoke(() ->
{
tagManager.removeTag(target);
deleteTab(target);
})
)
.option("2. Only tab", () -> clientThread.invoke(() -> deleteTab(target)))
.option("3. Cancel", Runnables::doNothing)
.build();
break;
case Tab.EXPORT_TAB:
final List<String> data = new ArrayList<>();
final TagTab tagTab = tabManager.find(Text.removeTags(event.getOpbase()));
data.add(tagTab.getTag());
data.add(String.valueOf(tagTab.getIconItemId()));
for (Integer item : tagManager.getItemsForTag(tagTab.getTag()))
{
data.add(String.valueOf(item));
}
final StringSelection stringSelection = new StringSelection(BankTagsPlugin.JOINER.join(data));
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
notifier.notify("Tag tab " + tagTab.getTag() + " has been copied to your clipboard!");
break;
}
}
public void destroy()
{
activeTab = null;
@@ -433,186 +602,10 @@ public class TabInterface
doSearch(InputType.SEARCH, TAG_SEARCH + activeTab.getTag());
}
else if (event.getMenuAction() == MenuAction.RUNELITE
&& (event.getMenuOption().equals(TAG_INVENTORY) || event.getMenuOption().equals(TAG_GEAR)))
&& ((event.getWidgetId() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() && event.getMenuOption().equals(TAG_INVENTORY))
|| (event.getWidgetId() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() && event.getMenuOption().equals(TAG_GEAR))))
{
event.consume();
boolean inventory = event.getMenuOption().equals(TAG_INVENTORY);
ItemContainer container = client.getItemContainer(inventory ? InventoryID.INVENTORY : InventoryID.EQUIPMENT);
if (container == null)
{
return;
}
List<Integer> items = Arrays.stream(container.getItems())
.filter(Objects::nonNull)
.map(Item::getId)
.filter(id -> id != -1)
.collect(Collectors.toList());
if (!Strings.isNullOrEmpty(event.getMenuTarget()))
{
if (activeTab != null && Text.removeTags(event.getMenuTarget()).equals(activeTab.getTag()))
{
for (Integer item : items)
{
tagManager.addTag(item, activeTab.getTag(), false);
}
openTag(TAG_SEARCH + activeTab.getTag());
}
}
else
{
chatboxInputManager.openInputWindow((inventory ? "Inventory " : "Equipment ") + "tags:", "", (newTags) ->
{
if (!Objects.equals(newTags, client.getVar(VarClientStr.INPUT_TEXT)) || Strings.isNullOrEmpty(newTags))
{
return;
}
final List<String> tags = SPLITTER.splitToList(newTags.toLowerCase());
for (Integer item : items)
{
tagManager.addTags(item, tags, false);
}
updateTabIfActive(tags);
});
}
}
else
{
switch (event.getMenuOption())
{
case SCROLL_UP:
event.consume();
scrollTab(-1);
break;
case SCROLL_DOWN:
event.consume();
scrollTab(1);
break;
case CHANGE_ICON:
event.consume();
iconToSet = tabManager.find(Text.removeTags(event.getMenuTarget()));
break;
case VIEW_TAB:
event.consume();
client.setVarbitValue(client.getVarps(), Varbits.CURRENT_BANK_TAB.getId(), 0);
Widget[] children = parent.getDynamicChildren();
Widget clicked = children[event.getActionParam()];
TagTab tab = tabManager.find(Text.removeTags(clicked.getName()));
if (tab.equals(activeTab))
{
resetSearch();
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
}
else
{
openTag(TAG_SEARCH + Text.removeTags(clicked.getName()));
}
client.playSoundEffect(SoundEffectID.UI_BOOP);
break;
case NEW_TAB:
event.consume();
chatboxInputManager.openInputWindow("Tag Name", "", (tagName) ->
{
if (!Strings.isNullOrEmpty(tagName))
{
loadTab(tagName);
tabManager.save();
scrollTab(0);
}
});
break;
case REMOVE_TAB:
event.consume();
String target = Text.standardize(event.getMenuTarget());
// TODO: Replace this number input selection with actual in-game select input
chatboxInputManager.openInputWindow(
"1. Delete tab " + target + " and tag from all items<br>" +
"2. Delete tab " + target + "<br>" +
"3. Cancel", "", (response) ->
{
switch (response)
{
case "1":
tagManager.removeTag(target);
if (activeTab != null && activeTab.getTag().equals(target))
{
resetSearch();
}
case "2":
deleteTab(target);
break;
default:
break;
}
});
break;
case EXPORT_TAB:
event.consume();
final List<String> data = new ArrayList<>();
final TagTab tagTab = tabManager.find(Text.removeTags(event.getMenuTarget()));
data.add(tagTab.getTag());
data.add(String.valueOf(tagTab.getIconItemId()));
for (Integer item : tagManager.getItemsForTag(tagTab.getTag()))
{
data.add(String.valueOf(item));
}
final StringSelection stringSelection = new StringSelection(BankTagsPlugin.JOINER.join(data));
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
notifier.notify("Tag tab " + tagTab.getTag() + " has been copied to your clipboard!");
break;
case IMPORT_TAB:
event.consume();
try
{
final String dataString = Toolkit
.getDefaultToolkit()
.getSystemClipboard()
.getData(DataFlavor.stringFlavor)
.toString()
.trim();
final Iterator<String> dataIter = BankTagsPlugin.SPLITTER.split(dataString).iterator();
final String name = dataIter.next();
final String icon = dataIter.next();
configManager.setConfiguration(CONFIG_GROUP, ICON_SEARCH + name, icon);
while (dataIter.hasNext())
{
final int itemId = Integer.valueOf(dataIter.next());
tagManager.addTag(itemId, name, itemId < 0);
}
loadTab(name);
tabManager.save();
scrollTab(0);
if (activeTab != null && name.equals(activeTab.getTag()))
{
openTag(TAG_SEARCH + activeTab.getTag());
}
notifier.notify("Tag tab " + name + " has been imported from your clipboard!");
}
catch (UnsupportedFlavorException | NoSuchElementException | IOException | NumberFormatException ex)
{
notifier.notify("Failed to import tag tab from clipboard, invalid format.");
}
}
handleDeposit(event, event.getWidgetId() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId());
}
}
@@ -711,6 +704,7 @@ public class TabInterface
btn.setAction(2, CHANGE_ICON);
btn.setAction(3, REMOVE_TAB);
btn.setAction(4, EXPORT_TAB);
btn.setOnOpListener((JavaScriptCallback) this::handleTagTab);
tagTab.setBackground(btn);
}
@@ -932,7 +926,7 @@ public class TabInterface
t.revalidate();
}
private void doSearch(InputType inputType, String search)
public void doSearch(InputType inputType, String search, Boolean closeInput)
{
// In case the widget ids array is incorrect, do not proceed
if (widgetIds == null || widgetIds.length < 21)
@@ -940,11 +934,14 @@ public class TabInterface
return;
}
clientThread.invokeLater(() ->
clientThread.invoke(() ->
{
// This ensures that any chatbox input (e.g from search) will not remain visible when
// selecting/changing tab
client.runScript(ScriptID.RESET_CHATBOX_INPUT);
if (closeInput)
{
client.runScript(ScriptID.RESET_CHATBOX_INPUT);
}
client.setVar(VarClientInt.INPUT_TYPE, inputType.getType());
client.setVar(VarClientStr.INPUT_TEXT, search);
@@ -966,6 +963,12 @@ public class TabInterface
});
}
private void doSearch(InputType inputType, String search)
{
doSearch(inputType, search, true);
}
private ItemComposition getItem(int idx)
{
ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK);