diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java index 859aa9f9d1..4ed53b575f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java @@ -197,7 +197,7 @@ public interface ChatCommandsConfig extends Config ) default Keybind clearSingleWord() { - return new Keybind(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK); + return new Keybind(KeyEvent.VK_BACK_SPACE, InputEvent.CTRL_DOWN_MASK); } @ConfigItem( @@ -208,6 +208,6 @@ public interface ChatCommandsConfig extends Config ) default Keybind clearChatBox() { - return new Keybind(KeyEvent.VK_BACK_SPACE, InputEvent.CTRL_DOWN_MASK); + return Keybind.NOT_SET; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index 792e648f63..ee0dfb7711 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -48,6 +48,7 @@ import net.runelite.api.VarbitComposition; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.CommandExecuted; import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.StatChanged; import net.runelite.api.events.VarbitChanged; import net.runelite.api.kit.KitType; @@ -492,4 +493,13 @@ public class DevToolsPlugin extends Plugin entry.setTarget(entry.getTarget() + " " + ColorUtil.prependColorTag("(" + info + ")", JagexColors.MENU_TARGET)); } } + + @Subscribe + public void onScriptCallbackEvent(ScriptCallbackEvent ev) + { + if ("devtoolsEnabled".equals(ev.getEventName())) + { + client.getIntStack()[client.getIntStackSize() - 1] = 1; + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java index 733440c6d0..25883f06d2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java @@ -308,6 +308,11 @@ enum ItemWithCharge ROW3(TELEPORT, RING_OF_WEALTH_3, 3), ROW4(TELEPORT, RING_OF_WEALTH_4, 4), ROW5(TELEPORT, RING_OF_WEALTH_5, 5), + ROWI1(TELEPORT, RING_OF_WEALTH_I1, 1), + ROWI2(TELEPORT, RING_OF_WEALTH_I2, 2), + ROWI3(TELEPORT, RING_OF_WEALTH_I3, 3), + ROWI4(TELEPORT, RING_OF_WEALTH_I4, 4), + ROWI5(TELEPORT, RING_OF_WEALTH_I5, 5), SACK_CABBAGES1(SACK, CABBAGES1, 1), SACK_CABBAGES2(SACK, CABBAGES2, 2), SACK_CABBAGES3(SACK, CABBAGES3, 3), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerCreationOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerCreationOverlay.java index 98b2c9a73b..81e25192ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerCreationOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerCreationOverlay.java @@ -42,9 +42,10 @@ class ScreenMarkerCreationOverlay extends Overlay private ScreenMarkerCreationOverlay(final ScreenMarkerPlugin plugin) { this.plugin = plugin; - setPosition(OverlayPosition.DETACHED); + setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_WIDGETS); setPriority(OverlayPriority.HIGH); + setMovable(true); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java index c991f58f2e..5341f75af8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java @@ -45,9 +45,10 @@ public class ScreenMarkerOverlay extends Overlay { this.marker = marker; this.screenMarkerRenderable = new ScreenMarkerRenderable(); - setPosition(OverlayPosition.DETACHED); + setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ALWAYS_ON_TOP); setPriority(OverlayPriority.HIGH); + setMovable(true); setResizable(true); setMinimumSize(16); setResettable(false); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerWidgetHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerWidgetHighlightOverlay.java index 718ea93903..9868b0f322 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerWidgetHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerWidgetHighlightOverlay.java @@ -51,9 +51,10 @@ class ScreenMarkerWidgetHighlightOverlay extends Overlay { this.plugin = plugin; this.client = client; - setPosition(OverlayPosition.DETACHED); + setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_WIDGETS); setPriority(OverlayPriority.HIGH); + setMovable(true); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java index d50a0b9c49..1fd875e7f7 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java @@ -64,12 +64,25 @@ public abstract class Overlay implements LayoutableRenderableEntity @Setter(AccessLevel.PROTECTED) private boolean dragTargetable; + /** + * Whether this overlay can be moved with alt + */ + @Setter(AccessLevel.PROTECTED) + private boolean movable = true; + + /** + * Whether this overlay can be moved to a snap corner + * and have its preferredPosition changed + */ + @Setter(AccessLevel.PROTECTED) + private boolean snappable = true; + protected Overlay() { plugin = null; } - protected Overlay(Plugin plugin) + protected Overlay(@Nullable Plugin plugin) { this.plugin = plugin; } @@ -169,4 +182,25 @@ public abstract class Overlay implements LayoutableRenderableEntity public void revalidate() { } + + public void setPosition(OverlayPosition position) + { + this.position = position; + + switch (position) + { + case TOOLTIP: + case DYNAMIC: + movable = false; + snappable = false; + break; + case DETACHED: + movable = true; + snappable = false; + break; + default: + movable = true; + snappable = true; + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java index 5811f98936..4ad59bf541 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java @@ -313,21 +313,29 @@ public class OverlayManager private void loadOverlay(final Overlay overlay) { final Point location = loadOverlayLocation(overlay); - overlay.setPreferredLocation(location); final Dimension size = loadOverlaySize(overlay); - overlay.setPreferredSize(size); final OverlayPosition position = loadOverlayPosition(overlay); - if (position != null) + + if (overlay.isMovable()) { - if (overlay.getPosition() != OverlayPosition.DYNAMIC && overlay.getPosition() != OverlayPosition.TOOLTIP) - { - overlay.setPreferredPosition(position); - } - else - { - log.info("Resetting preferred position of dynamic overlay {}", overlay.getClass().getSimpleName()); - saveOverlayPosition(overlay); - } + overlay.setPreferredLocation(location); + } + else + { + log.info("Resetting preferred location of non-movable overlay {} (class {})", overlay.getName(), overlay.getClass().getName()); + saveOverlayLocation(overlay); + } + + overlay.setPreferredSize(size); + + if (overlay.isSnappable()) + { + overlay.setPreferredPosition(position); + } + else + { + log.info("Resetting preferred position of non-snappable overlay {} (class {})", overlay.getName(), overlay.getClass().getName()); + saveOverlayPosition(overlay); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayPosition.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayPosition.java index 14edc0dd05..9464c87520 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayPosition.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayPosition.java @@ -28,7 +28,9 @@ public enum OverlayPosition { /** * Not attached anywhere, but still movable + * Deprecated. Use DYNAMIC and setMovable(true) */ + @Deprecated DETACHED, /** * Overlay places itself where it wants diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index c7055339c4..6ad7787f5f 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -25,7 +25,6 @@ package net.runelite.client.ui.overlay; import com.google.common.base.MoreObjects; -import com.google.common.collect.ImmutableList; import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Composite; @@ -41,7 +40,6 @@ import java.awt.event.MouseEvent; import java.awt.geom.AffineTransform; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; @@ -107,7 +105,8 @@ public class OverlayRenderer extends MouseAdapter private boolean inOverlayResizingMode; private boolean inOverlayDraggingMode; private boolean startedMovingOverlay; - private Overlay hoveredOverlay; // for building menu entries + private Overlay curHoveredOverlay; // for building menu entries + private Overlay lastHoveredOverlay; // for off-thread access // Overlay state validation private Rectangle viewportBounds; @@ -175,14 +174,16 @@ public class OverlayRenderer extends MouseAdapter resetOverlayManagementMode(); } - hoveredOverlay = null; + curHoveredOverlay = null; } } @Subscribe protected void onClientTick(ClientTick t) { - final Overlay overlay = hoveredOverlay; + lastHoveredOverlay = curHoveredOverlay; + + final Overlay overlay = curHoveredOverlay; if (overlay == null || client.isMenuOpen()) { return; @@ -216,7 +217,7 @@ public class OverlayRenderer extends MouseAdapter @Subscribe public void onBeforeRender(BeforeRender event) { - hoveredOverlay = null; + curHoveredOverlay = null; if (focusedOverlay == null && prevFocusedOverlay != null) { @@ -261,7 +262,7 @@ public class OverlayRenderer extends MouseAdapter overlayManager.setWidgetItems(Collections.emptyList()); } - private void renderOverlays(Graphics2D graphics, Collection overlays, OverlayLayer layer) + private void renderOverlays(final Graphics2D graphics, Collection overlays, final OverlayLayer layer) { if (overlays == null || overlays.isEmpty() @@ -273,7 +274,7 @@ public class OverlayRenderer extends MouseAdapter OverlayUtil.setGraphicProperties(graphics); // Draw snap corners - if (inOverlayDraggingMode && layer == OverlayLayer.UNDER_WIDGETS && currentManagedOverlay != null && currentManagedOverlay.getPosition() != OverlayPosition.DETACHED) + if (inOverlayDraggingMode && layer == OverlayLayer.UNDER_WIDGETS && currentManagedOverlay != null && currentManagedOverlay.isSnappable()) { final OverlayBounds translatedSnapCorners = snapCorners.translated( -SNAP_CORNER_SIZE.width, @@ -290,10 +291,6 @@ public class OverlayRenderer extends MouseAdapter graphics.setColor(previous); } - // Get mouse position - final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition(); - final Point mouse = new Point(mouseCanvasPosition.getX(), mouseCanvasPosition.getY()); - // Save graphics2d properties so we can restore them later final AffineTransform transform = graphics.getTransform(); final Stroke stroke = graphics.getStroke(); @@ -302,126 +299,97 @@ public class OverlayRenderer extends MouseAdapter final RenderingHints renderingHints = graphics.getRenderingHints(); final Color background = graphics.getBackground(); + final Rectangle clip = clipBounds(layer); + graphics.setClip(clip); + for (Overlay overlay : overlays) { final OverlayPosition overlayPosition = getCorrectedOverlayPosition(overlay); + final Rectangle bounds = overlay.getBounds(); + final Dimension dimension = bounds.getSize(); + final Point preferredLocation = overlay.getPreferredLocation(); + Point location; + Rectangle snapCorner = null; - if (overlayPosition == OverlayPosition.DYNAMIC || overlayPosition == OverlayPosition.TOOLTIP) + // If the final position is not modified, layout it + if (overlayPosition != OverlayPosition.DYNAMIC && overlayPosition != OverlayPosition.TOOLTIP + && overlayPosition != OverlayPosition.DETACHED && preferredLocation == null) { - safeRender(client, overlay, layer, graphics, new Point()); - - // Restore graphics2d properties - graphics.setTransform(transform); - graphics.setStroke(stroke); - graphics.setComposite(composite); - graphics.setPaint(paint); - graphics.setRenderingHints(renderingHints); - graphics.setBackground(background); + snapCorner = snapCorners.forPosition(overlayPosition); + final Point translation = OverlayUtil.transformPosition(overlayPosition, dimension); // offset from corner + // Target x/y to draw the overlay + int destX = snapCorner.x + translation.x; + int destY = snapCorner.y + translation.y; + // Clamp the target position to ensure it is on screen or within parent bounds + location = clampOverlayLocation(destX, destY, dimension.width, dimension.height, overlay); } else { - final Rectangle bounds = overlay.getBounds(); - final Dimension dimension = bounds.getSize(); - final Point preferredLocation = overlay.getPreferredLocation(); - Point location; - Rectangle snapCorner = null; + location = preferredLocation != null ? preferredLocation : bounds.getLocation(); - // If the final position is not modified, layout it - if (overlayPosition != OverlayPosition.DETACHED && (preferredLocation == null || overlay.getPreferredPosition() != null)) + // Clamp the overlay position to ensure it is on screen or within parent bounds + location = clampOverlayLocation(location.x, location.y, dimension.width, dimension.height, overlay); + } + + if (overlay.getPreferredSize() != null) + { + bounds.setSize(overlay.getPreferredSize()); + } + + safeRender(overlay, graphics, location); + + // Adjust snap corner based on where the overlay was drawn + if (snapCorner != null && bounds.width + bounds.height > 0) + { + OverlayUtil.shiftSnapCorner(overlayPosition, snapCorner, bounds, PADDING); + } + + // Restore graphics2d properties prior to drawing bounds + graphics.setTransform(transform); + graphics.setStroke(stroke); + graphics.setComposite(composite); + graphics.setPaint(paint); + graphics.setRenderingHints(renderingHints); + graphics.setBackground(background); + if (!graphics.getClip().equals(clip)) + { + graphics.setClip(clip); + } + + if (!bounds.isEmpty()) + { + if (inOverlayManagingMode) { - snapCorner = snapCorners.forPosition(overlayPosition); - final Point translation = OverlayUtil.transformPosition(overlayPosition, dimension); // offset from corner - // Target x/y to draw the overlay - int destX = snapCorner.x + translation.x; - int destY = snapCorner.y + translation.y; - // Clamp the target position to ensure it is on screen or within parent bounds - location = clampOverlayLocation(destX, destY, dimension.width, dimension.height, overlay); - } - else - { - location = preferredLocation != null ? preferredLocation : bounds.getLocation(); - - // Clamp the overlay position to ensure it is on screen or within parent bounds - location = clampOverlayLocation(location.x, location.y, dimension.width, dimension.height, overlay); - } - - if (overlay.getPreferredSize() != null) - { - bounds.setSize(overlay.getPreferredSize()); - } - - safeRender(client, overlay, layer, graphics, location); - - // Adjust snap corner based on where the overlay was drawn - if (snapCorner != null && bounds.width + bounds.height > 0) - { - OverlayUtil.shiftSnapCorner(overlayPosition, snapCorner, bounds, PADDING); - } - - // Restore graphics2d properties prior to drawing bounds - graphics.setTransform(transform); - graphics.setStroke(stroke); - graphics.setComposite(composite); - graphics.setPaint(paint); - graphics.setRenderingHints(renderingHints); - graphics.setBackground(background); - - if (!bounds.isEmpty()) - { - if (inOverlayManagingMode) + Color boundsColor; + if (inOverlayResizingMode && currentManagedOverlay == overlay) { - Color boundsColor; - if (inOverlayResizingMode && currentManagedOverlay == overlay) - { - boundsColor = MOVING_OVERLAY_RESIZING_COLOR; - } - else if (inOverlayDraggingMode && currentManagedOverlay == overlay) - { - boundsColor = MOVING_OVERLAY_ACTIVE_COLOR; - } - else if (inOverlayDraggingMode && overlay.isDragTargetable() && currentManagedOverlay.isDragTargetable() - && currentManagedOverlay.getBounds().intersects(bounds)) - { - boundsColor = MOVING_OVERLAY_TARGET_COLOR; - assert currentManagedOverlay != overlay; - dragTargetOverlay = overlay; - } - else - { - boundsColor = MOVING_OVERLAY_COLOR; - } - - graphics.setColor(boundsColor); - graphics.draw(bounds); - graphics.setPaint(paint); + boundsColor = MOVING_OVERLAY_RESIZING_COLOR; + } + else if (inOverlayDraggingMode && currentManagedOverlay == overlay) + { + boundsColor = MOVING_OVERLAY_ACTIVE_COLOR; + } + else if (inOverlayDraggingMode && overlay.isDragTargetable() && currentManagedOverlay.isDragTargetable() + && currentManagedOverlay.getBounds().intersects(bounds)) + { + boundsColor = MOVING_OVERLAY_TARGET_COLOR; + assert currentManagedOverlay != overlay; + dragTargetOverlay = overlay; + } + else + { + boundsColor = MOVING_OVERLAY_COLOR; } - if (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse)) - { - hoveredOverlay = overlay; + graphics.setColor(boundsColor); + graphics.draw(bounds); + graphics.setPaint(paint); + } - if (inOverlayManagingMode) - { - String tooltipText = overlay.getPlugin() == null ? overlay.getName() : overlay.getPlugin().getName(); - tooltipManager.add(new Tooltip(tooltipText)); - } - - if (focusedOverlay == null) - { - focusedOverlay = overlay; - if (focusedOverlay != prevFocusedOverlay) - { - if (prevFocusedOverlay != null) - { - prevFocusedOverlay.onMouseExit(); - } - - overlay.onMouseEnter(); - } - } - - overlay.onMouseOver(); - } + if (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mousePosition)) + { + curHoveredOverlay = overlay; + overlay.onMouseOver(); } } } @@ -430,17 +398,16 @@ public class OverlayRenderer extends MouseAdapter @Override public MouseEvent mousePressed(MouseEvent mouseEvent) { + final Point mousePoint = mouseEvent.getPoint(); + mousePosition.setLocation(mousePoint); + if (!inOverlayManagingMode) { return mouseEvent; } - final Point mousePoint = mouseEvent.getPoint(); - mousePosition.setLocation(mousePoint); - // See if we've clicked on an overlay - currentManagedOverlay = findMangedOverlay(mousePoint); - + currentManagedOverlay = lastHoveredOverlay; if (currentManagedOverlay == null) { return mouseEvent; @@ -476,17 +443,17 @@ public class OverlayRenderer extends MouseAdapter @Override public MouseEvent mouseMoved(MouseEvent mouseEvent) { + final Point mousePoint = mouseEvent.getPoint(); + mousePosition.setLocation(mousePoint); + if (!inOverlayManagingMode) { return mouseEvent; } - final Point mousePoint = mouseEvent.getPoint(); - mousePosition.setLocation(mousePoint); - if (!inOverlayResizingMode && !inOverlayDraggingMode) { - currentManagedOverlay = findMangedOverlay(mousePoint); + currentManagedOverlay = lastHoveredOverlay; } if (currentManagedOverlay == null || !currentManagedOverlay.isResizable()) @@ -533,47 +500,17 @@ public class OverlayRenderer extends MouseAdapter return mouseEvent; } - /** - * Find an overlay to manage which is under the given mouse point - * - * @param mousePoint - * @return - */ - private Overlay findMangedOverlay(Point mousePoint) - { - synchronized (overlayManager) - { - // render order is roughly: under -> manual -> above -> always on top - final List layerOrder = ImmutableList.of(OverlayLayer.UNDER_WIDGETS, OverlayLayer.MANUAL, OverlayLayer.ABOVE_WIDGETS, OverlayLayer.ALWAYS_ON_TOP); - return overlayManager.getOverlays() - .stream() - // ABOVE_SCENE overlays aren't managed - .filter(c -> layerOrder.contains(c.getLayer())) - // never allow moving dynamic or tooltip overlays - .filter(c -> c.getPosition() != OverlayPosition.DYNAMIC && c.getPosition() != OverlayPosition.TOOLTIP) - .sorted( - Comparator.comparingInt(c -> layerOrder.indexOf(c.getLayer())) - .thenComparing(OverlayManager.OVERLAY_COMPARATOR) - // pick order is reversed from render order - .reversed() - ) - .filter(o -> o.getBounds().contains(mousePoint)) - .findFirst() - .orElse(null); - } - } - @Override public MouseEvent mouseDragged(MouseEvent mouseEvent) { + final Point p = mouseEvent.getPoint(); + mousePosition.setLocation(p); + if (!inOverlayManagingMode) { return mouseEvent; } - final Point p = mouseEvent.getPoint(); - mousePosition.setLocation(p); - if (currentManagedOverlay == null) { return mouseEvent; @@ -708,13 +645,14 @@ public class OverlayRenderer extends MouseAdapter @Override public MouseEvent mouseReleased(MouseEvent mouseEvent) { + final Point mousePoint = mouseEvent.getPoint(); + mousePosition.setLocation(mousePoint); + if (!inOverlayManagingMode || currentManagedOverlay == null || (!inOverlayDraggingMode && !inOverlayResizingMode)) { return mouseEvent; } - mousePosition.setLocation(-1, -1); - if (dragTargetOverlay != null) { if (dragTargetOverlay.onDrag(currentManagedOverlay)) @@ -725,14 +663,14 @@ public class OverlayRenderer extends MouseAdapter } } - // Check if the overlay is over a snapcorner and move it if so, unless it is a detached overlay - if (currentManagedOverlay.getPosition() != OverlayPosition.DETACHED && inOverlayDraggingMode) + // Check if the overlay is over a snapcorner and snap it if so + if (currentManagedOverlay.isSnappable() && inOverlayDraggingMode) { final OverlayBounds snapCorners = this.emptySnapCorners.translated(-SNAP_CORNER_SIZE.width, -SNAP_CORNER_SIZE.height); for (Rectangle snapCorner : snapCorners.getBounds()) { - if (snapCorner.contains(mouseEvent.getPoint())) + if (snapCorner.contains(mousePoint)) { OverlayPosition position = snapCorners.fromBounds(snapCorner); @@ -756,20 +694,23 @@ public class OverlayRenderer extends MouseAdapter return mouseEvent; } - private void safeRender(Client client, Overlay overlay, OverlayLayer layer, Graphics2D graphics, Point point) + private Rectangle clipBounds(OverlayLayer layer) { if (!isResizeable && (layer == OverlayLayer.ABOVE_SCENE || layer == OverlayLayer.UNDER_WIDGETS)) { - graphics.setClip(client.getViewportXOffset(), + return new Rectangle(client.getViewportXOffset(), client.getViewportYOffset(), client.getViewportWidth(), client.getViewportHeight()); } else { - graphics.setClip(0, 0, client.getCanvasWidth(), client.getCanvasHeight()); + return new Rectangle(0, 0, client.getCanvasWidth(), client.getCanvasHeight()); } + } + private void safeRender(Overlay overlay, Graphics2D graphics, Point point) + { final OverlayPosition position = overlay.getPosition(); // Set font based on configuration diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java index 89d9e3c803..a9f68d6b92 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java @@ -213,19 +213,19 @@ public class OverlayUtil switch (overlayPosition) { case BOTTOM_LEFT: - sX = bounds.x + bounds.width + padding; + sX = Math.max(sX, bounds.x + bounds.width + padding); break; case BOTTOM_RIGHT: - sX = bounds.x - padding; + sX = Math.min(sX, bounds.x - padding); break; case TOP_LEFT: case TOP_CENTER: case CANVAS_TOP_RIGHT: case TOP_RIGHT: - sY = bounds.y + bounds.height + padding; + sY = Math.max(sY, bounds.y + bounds.height + padding); break; case ABOVE_CHATBOX_RIGHT: - sY = bounds.y - padding; + sY = Math.min(sY, bounds.y - padding); break; default: throw new IllegalArgumentException(); @@ -240,8 +240,6 @@ public class OverlayUtil switch (position) { - case DYNAMIC: - case TOOLTIP: case TOP_LEFT: break; case TOP_CENTER: @@ -258,6 +256,8 @@ public class OverlayUtil case TOP_RIGHT: result.x = -dimension.width; break; + default: + throw new IllegalArgumentException(); } return result; diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java index 77a00e59ec..5806234f65 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java @@ -42,16 +42,16 @@ public class WidgetOverlay extends Overlay public static Collection createOverlays(final OverlayManager overlayManager, final Client client) { return Arrays.asList( - // classic resizable - new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_CHATBOX_PARENT, OverlayPosition.DETACHED, OverlayPriority.HIGH), - new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_CHATBOX_PARENT, OverlayPosition.DETACHED, OverlayPriority.HIGH), - new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_PARENT, OverlayPosition.DETACHED), - new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_WIDGET, OverlayPosition.DETACHED, OverlayPriority.MED), + // classic resizable - these are in render order for managed overlay picking + new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_CHATBOX_PARENT, OverlayPosition.DYNAMIC), + new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_PARENT, OverlayPosition.DYNAMIC), + new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT), // modern resizable - new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_TABS1, OverlayPosition.DETACHED), - new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_TABS2, OverlayPosition.DETACHED), - new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_PARENT, OverlayPosition.DETACHED), - new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.DETACHED, OverlayPriority.MED), + new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_CHATBOX_PARENT, OverlayPosition.DYNAMIC), + new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT), + new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_TABS1, OverlayPosition.DYNAMIC), + new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_TABS2, OverlayPosition.DYNAMIC), + new WidgetOverlay(client, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_PARENT, OverlayPosition.DYNAMIC), // The client forces the oxygen bar below the xp tracker, so set its priority lower new WidgetOverlay(client, WidgetInfo.FOSSIL_ISLAND_OXYGENBAR, OverlayPosition.TOP_CENTER, OverlayPriority.HIGH), new XpTrackerWidgetOverlay(overlayManager, client, WidgetInfo.EXPERIENCE_TRACKER_WIDGET, OverlayPosition.TOP_RIGHT), @@ -84,7 +84,7 @@ public class WidgetOverlay extends Overlay new WidgetOverlay(client, WidgetInfo.TEMPOROSS_STATUS_INDICATOR, OverlayPosition.TOP_LEFT), new WidgetOverlay(client, WidgetInfo.BA_HEAL_TEAMMATES, OverlayPosition.BOTTOM_LEFT), new WidgetOverlay(client, WidgetInfo.BA_TEAM, OverlayPosition.TOP_RIGHT), - new WidgetOverlay(client, WidgetInfo.PVP_WILDERNESS_SKULL_CONTAINER, OverlayPosition.DETACHED) + new WidgetOverlay(client, WidgetInfo.PVP_WILDERNESS_SKULL_CONTAINER, OverlayPosition.DYNAMIC) ); } @@ -105,6 +105,8 @@ public class WidgetOverlay extends Overlay setPriority(overlayPriority); setLayer(OverlayLayer.UNDER_WIDGETS); setPosition(overlayPosition); + setMovable(true); + setSnappable(true); // It's almost possible to drawAfterInterface(widgetInfo.getGroupId()) here, but that fires // *after* the native components are drawn, which is too late. } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 16ca444f8a..d4241daa10 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -31,6 +31,7 @@ import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Rectangle; +import java.awt.Shape; import java.awt.geom.Area; import java.awt.image.BufferedImage; import java.util.List; @@ -119,10 +120,10 @@ public class WorldMapOverlay extends Overlay bottomBar.setHasListener(true); final Rectangle worldMapRectangle = widget.getBounds(); - final Area mapViewArea = getWorldMapClipArea(worldMapRectangle); + final Shape mapViewArea = getWorldMapClipArea(worldMapRectangle); final Rectangle canvasBounds = new Rectangle(0, 0, client.getCanvasWidth(), client.getCanvasHeight()); - final Area canvasViewArea = getWorldMapClipArea(canvasBounds); - Area currentClip = null; + final Shape canvasViewArea = getWorldMapClipArea(canvasBounds); + Shape currentClip = null; Point mousePos = client.getMouseCanvasPosition(); if (!mapViewArea.contains(mousePos.getX(), mousePos.getY())) @@ -297,24 +298,29 @@ public class WorldMapOverlay extends Overlay * @return An {@link Area} representing baseRectangle, with the area * of visible widgets overlaying the world map clipped from it. */ - private Area getWorldMapClipArea(Rectangle baseRectangle) + private Shape getWorldMapClipArea(Rectangle baseRectangle) { final Widget overview = client.getWidget(WidgetInfo.WORLD_MAP_OVERVIEW_MAP); final Widget surfaceSelector = client.getWidget(WidgetInfo.WORLD_MAP_SURFACE_SELECTOR); Area clipArea = new Area(baseRectangle); + boolean subtracted = false; if (overview != null && !overview.isHidden()) { clipArea.subtract(new Area(overview.getBounds())); + subtracted = true; } if (surfaceSelector != null && !surfaceSelector.isHidden()) { clipArea.subtract(new Area(surfaceSelector.getBounds())); + subtracted = true; } - return clipArea; + // The sun g2d implementation is much more efficient at applying clips which are subclasses of rectangle2d, + // so use that as the clip shape if possible + return subtracted ? clipArea : baseRectangle; } private void drawTooltip(Graphics2D graphics, WorldMapPoint worldPoint) @@ -336,7 +342,7 @@ public class WorldMapOverlay extends Overlay drawPoint = new Point(drawPoint.getX() + TOOLTIP_OFFSET_WIDTH, drawPoint.getY() + TOOLTIP_OFFSET_HEIGHT); final Rectangle bounds = new Rectangle(0, 0, client.getCanvasWidth(), client.getCanvasHeight()); - final Area mapArea = getWorldMapClipArea(bounds); + final Shape mapArea = getWorldMapClipArea(bounds); graphics.setClip(mapArea); graphics.setColor(JagexColors.TOOLTIP_BACKGROUND); graphics.setFont(FontManager.getRunescapeFont()); diff --git a/runelite-client/src/main/scripts/CommandScript.rs2asm b/runelite-client/src/main/scripts/CommandScript.rs2asm index 0cb44b4ee8..073d229c35 100644 --- a/runelite-client/src/main/scripts/CommandScript.rs2asm +++ b/runelite-client/src/main/scripts/CommandScript.rs2asm @@ -870,6 +870,9 @@ LABEL724: if_icmpgt LABEL728 jump LABEL791 LABEL728: + ; move chatout_add under if ($length2 > 2) to only add for :: commands + get_varc_string 335 + invoke 77 ; chatout_add get_varc_string 335 sconst "::toggleroof" iconst 0 @@ -962,8 +965,11 @@ LABEL798: iload 9 invoke 5517 LABEL804: + ; see comment above + jump AFTER_CHATOUT_ADD get_varc_string 335 invoke 77 +AFTER_CHATOUT_ADD: sconst "" set_varc_string 335 LABEL808: @@ -975,6 +981,8 @@ LABEL809: jump LABEL819 LABEL813: iload 3 + sconst "devtoolsEnabled" + runelite_callback iconst 1 if_icmpeq LABEL817 jump LABEL818 @@ -989,6 +997,8 @@ LABEL819: jump LABEL829 LABEL823: iload 3 + sconst "devtoolsEnabled" + runelite_callback iconst 1 if_icmpeq LABEL827 jump LABEL828