diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java index 384ad0faf5..f3626d3d1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java @@ -34,5 +34,6 @@ class Spell private int widget; private int x; private int y; + private int size; private String name; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java index c7bcdcbb5a..1a47110f61 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java @@ -53,11 +53,22 @@ public interface SpellbookConfig extends Config return true; } + @ConfigItem( + keyName = "scroll", + name = "Scrollwheel resizing", + description = "Resize spells by scrolling your scrollwheel over them, reset with scrollwheel click", + position = 3 + ) + default boolean scroll() + { + return true; + } + @ConfigItem( keyName = "size", name = "Spell size", description = "Size (in px) of spells. Normal mobile size is 40px, use common sense for this setting please", - position = 3 + position = 4 ) default int size() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java index 6fa2c7fa90..b4416161b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java @@ -25,10 +25,12 @@ package net.runelite.client.plugins.spellbook; import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; import javax.swing.SwingUtilities; import net.runelite.client.input.MouseAdapter; +import net.runelite.client.input.MouseWheelListener; -public class SpellbookMouseListener extends MouseAdapter +public class SpellbookMouseListener extends MouseAdapter implements MouseWheelListener { private final SpellbookPlugin plugin; @@ -40,11 +42,16 @@ public class SpellbookMouseListener extends MouseAdapter @Override public MouseEvent mouseClicked(MouseEvent event) { - if (SwingUtilities.isMiddleMouseButton(event) || !plugin.isOnSpellWidget(event.getPoint())) + if (!plugin.isOnSpellWidget(event.getPoint())) { return event; } + if (SwingUtilities.isMiddleMouseButton(event)) + { + plugin.resetZoom(event.getPoint()); + } + event.consume(); return event; } @@ -76,4 +83,27 @@ public class SpellbookMouseListener extends MouseAdapter event.consume(); return event; } + + @Override + public MouseWheelEvent mouseWheelMoved(MouseWheelEvent event) + { + if (!plugin.isOnSpellWidget(event.getPoint())) + { + return event; + } + + int direction = event.getWheelRotation(); + + if (direction > 0) + { + plugin.increaseSize(event.getPoint()); + } + else + { + plugin.decreaseSize(event.getPoint()); + } + + event.consume(); + return event; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java index cadddb2df7..82181d6911 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java @@ -116,6 +116,7 @@ public class SpellbookPlugin extends Plugin private Point draggingLocation; private Map spells = new HashMap<>(); + private Map tmp = null; private List notFilteredSpells = new ArrayList<>(); private Spellbook spellbook; private SpellbookMouseListener mouseListener; @@ -142,6 +143,9 @@ public class SpellbookPlugin extends Plugin saveSpells(); config.canDrag(false); mouseManager.unregisterMouseListener(mouseListener); + + mouseManager.unregisterMouseWheelListener(mouseListener); + mouseListener = null; } @@ -173,7 +177,7 @@ public class SpellbookPlugin extends Plugin loadFilter(); } - runRebuild(); + clientThread.invokeLater(this::runRebuild); } @Subscribe @@ -206,6 +210,11 @@ public class SpellbookPlugin extends Plugin if ("startSpellRedraw".equals(event.getEventName())) { + if (config.canDrag()) + { + return; + } + spellbook = Spellbook.getByID(client.getVar(Varbits.SPELLBOOK)); loadSpells(); } @@ -221,6 +230,7 @@ public class SpellbookPlugin extends Plugin s.setWidget(widget); s.setX(-1); s.setY(-1); + s.setSize(0); s.setName(spell); spells.put(widget, s); @@ -255,6 +265,29 @@ public class SpellbookPlugin extends Plugin iStack[iStackSize - 1] = FULL_HEIGHT; iStack[iStackSize - 2] = FULL_WIDTH; } + else if ("resizeIndividualSpells".equals(event.getEventName())) + { + int widget = iStack[iStackSize - 1]; + int visCount = + (int) spells.values().stream() + .map(Spell::getName) + .filter(s -> notFilteredSpells + .stream() + .anyMatch(s::contains)) + .count(); + + + if (visCount > 20 || visCount == 0) + { + return; + } + + Spell spell = spells.get(widget); + int newSize = spell.getSize() * 5 + config.size(); + + iStack[iStackSize - 2] = newSize; + iStack[iStackSize - 3] = newSize; + } else if ("setSpellPosition".equals(event.getEventName())) { if (!config.dragSpells()) @@ -293,12 +326,21 @@ public class SpellbookPlugin extends Plugin config.canDrag(true); overlayManager.add(overlay); mouseManager.registerMouseListener(mouseListener); + tmp = new HashMap<>(); + + if (config.scroll()) + { + mouseManager.registerMouseWheelListener(mouseListener); + } } else if (event.getMenuOption().equals(LOCK)) { config.canDrag(false); overlayManager.remove(overlay); mouseManager.unregisterMouseListener(mouseListener); + mouseManager.unregisterMouseWheelListener(mouseListener); + saveSpells(); + tmp = null; } } @@ -360,6 +402,11 @@ public class SpellbookPlugin extends Plugin Collection gson = GSON.fromJson(cfg, new TypeToken>(){}.getType()); // CHECKSTYLE:ON gson.stream().filter(Objects::nonNull).forEach(s -> spells.put(s.getWidget(), s)); + + if (tmp != null) + { + tmp.forEach((k, v) -> spells.replace(k, v)); + } } private void saveSpells() @@ -369,6 +416,8 @@ public class SpellbookPlugin extends Plugin return; } + tmp.forEach((k, v) -> spells.replace(k, v)); + String key = spellbook.getConfigKey(); configManager.setConfiguration("spellbook", key, GSON.toJson(spells.values())); @@ -395,25 +444,10 @@ public class SpellbookPlugin extends Plugin return false; } - for (int id : spells.keySet()) - { - Widget w = client.getWidget(WidgetInfo.TO_GROUP(id), WidgetInfo.TO_CHILD(id)); // lol very useful - - if (w == null || notFilteredSpells.stream().noneMatch(spells.get(id).getName()::contains)) - { - continue; - } - - if (w.getBounds().contains(point)) - { - return true; - } - } - - return false; + return currentWidget(point) != null; } - void startDragging(java.awt.Point point) + private Widget currentWidget(java.awt.Point point) { for (int id : spells.keySet()) { @@ -424,8 +458,19 @@ public class SpellbookPlugin extends Plugin continue; } - draggingWidget = w; - break; + return w; + } + + return null; + } + + void startDragging(java.awt.Point point) + { + draggingWidget = currentWidget(point); + + if (draggingWidget == null) + { + return; } Point widgetPos = draggingWidget.getCanvasLocation(); @@ -471,11 +516,118 @@ public class SpellbookPlugin extends Plugin n.setX(x); n.setY(y); - spells.replace(draggedID, n); + tmp.put(draggedID, n); draggingWidget.setHidden(false); dragging = false; - saveSpells(); + runRebuild(); + } + + void resetZoom(java.awt.Point point) + { + Widget clickedWidget = currentWidget(point); + + if (clickedWidget == null || !config.scroll()) + { + return; + } + + int clickedWidgetId = clickedWidget.getId(); + + if (!spells.containsKey(clickedWidgetId)) + { + return; + } + + Spell clickedSpell = spells.get(clickedWidgetId); + + int oldSize = clickedSpell.getSize(); + int tmpSize = tmp.get(clickedWidgetId).getSize(); + + if (tmpSize == 0 && oldSize == 0) + { + return; + } + + clickedSpell.setSize(0); + + clickedSpell.setX(clickedSpell.getX() + oldSize * 5 / 2); + clickedSpell.setY(clickedSpell.getY() + oldSize * 5 / 2); + + tmp.put(clickedWidgetId, clickedSpell); + + runRebuild(); + } + + void decreaseSize(java.awt.Point point) + { + Widget scrolledWidget = currentWidget(point); + + if (scrolledWidget == null) + { + return; + } + + int scrolledWidgetId = scrolledWidget.getId(); + + if (!spells.containsKey(scrolledWidgetId)) + { + return; + } + + Spell scrolledSpell = spells.get(scrolledWidgetId); + + scrolledSpell.setSize(scrolledSpell.getSize() + 1); + + if (scrolledSpell.getSize() % 2 == 0) + { + scrolledSpell.setX(scrolledSpell.getX() - 3); + scrolledSpell.setY(scrolledSpell.getY() - 3); + } + else + { + scrolledSpell.setX(scrolledSpell.getX() - 2); + scrolledSpell.setY(scrolledSpell.getY() - 2); + } + + tmp.put(scrolledWidgetId, scrolledSpell); + + runRebuild(); + } + + void increaseSize(java.awt.Point point) + { + Widget scrolledWidget = currentWidget(point); + + if (scrolledWidget == null) + { + return; + } + + int scrolledWidgetId = scrolledWidget.getId(); + + if (!spells.containsKey(scrolledWidgetId)) + { + return; + } + + Spell scrolledSpell = spells.get(scrolledWidgetId); + scrolledSpell.setSize(scrolledSpell.getSize() - 1); + + if (scrolledSpell.getSize() % 2 == 0) + { + scrolledSpell.setX(scrolledSpell.getX() + 3); + scrolledSpell.setY(scrolledSpell.getY() + 3); + } + else + { + scrolledSpell.setX(scrolledSpell.getX() + 2); + scrolledSpell.setY(scrolledSpell.getY() + 2); + } + + tmp.put(scrolledWidgetId, scrolledSpell); + + runRebuild(); } } diff --git a/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm b/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm index 6e3e9afdd7..b51f3aa637 100644 --- a/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm +++ b/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm @@ -705,6 +705,10 @@ LABEL611: istore 25 iload 19 iload 19 + iload 25 + sconst "resizeIndividualSpells" + runelite_callback + pop_int iconst 0 iconst 0 iload 25