Split OverlayRenderer logic to OverlayManager
- Split logic related to populating overlays to OverlayManager and OverlayRenderer. - Remove overlay-related logic from plugin, this is going to be handled via OverlayManager. - Inject core overlays to OverlayManager via new methods Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
@@ -27,9 +27,6 @@ package net.runelite.client.plugins;
|
|||||||
import com.google.inject.Binder;
|
import com.google.inject.Binder;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
|
|
||||||
public abstract class Plugin implements Module
|
public abstract class Plugin implements Module
|
||||||
{
|
{
|
||||||
@@ -52,15 +49,4 @@ public abstract class Plugin implements Module
|
|||||||
{
|
{
|
||||||
return injector;
|
return injector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Overlay getOverlay()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Overlay> getOverlays()
|
|
||||||
{
|
|
||||||
Overlay overlay = getOverlay();
|
|
||||||
return overlay != null ? Collections.singletonList(overlay) : Collections.EMPTY_LIST;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* 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.ui.overlay;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.client.config.ConfigGroup;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages state of all game overlays
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class OverlayManager
|
||||||
|
{
|
||||||
|
private static final String OVERLAY_CONFIG_PREFERRED_LOCATION = "_preferredLocation";
|
||||||
|
private static final String OVERLAY_CONFIG_PREFERRED_POSITION = "_preferredPosition";
|
||||||
|
private static final String OVERLAY_CONFIG_PREFERRED_SIZE = "_preferredSize";
|
||||||
|
private static final String RUNELITE_CONFIG_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).keyName();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final List<Overlay> overlays = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Map<OverlayLayer, List<Overlay>> overlayLayers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final ConfigManager configManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OverlayManager(final ConfigManager configManager)
|
||||||
|
{
|
||||||
|
this.configManager = configManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add overlay.
|
||||||
|
*
|
||||||
|
* @param overlay the overlay
|
||||||
|
* @return true if overlay was added
|
||||||
|
*/
|
||||||
|
public boolean add(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final boolean add = overlays.add(overlay);
|
||||||
|
|
||||||
|
if (add)
|
||||||
|
{
|
||||||
|
final Point location = loadOverlayLocation(overlay);
|
||||||
|
overlay.setPreferredLocation(location);
|
||||||
|
final Dimension size = loadOverlaySize(overlay);
|
||||||
|
overlay.setPreferredSize(size);
|
||||||
|
final OverlayPosition position = loadOverlayPosition(overlay);
|
||||||
|
overlay.setPreferredPosition(position);
|
||||||
|
sortOverlays(overlays);
|
||||||
|
rebuildOverlayLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
return add;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove overlay.
|
||||||
|
*
|
||||||
|
* @param overlay the overlay
|
||||||
|
* @return true if overlay was removed
|
||||||
|
*/
|
||||||
|
public boolean remove(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final boolean remove = overlays.remove(overlay);
|
||||||
|
|
||||||
|
if (remove)
|
||||||
|
{
|
||||||
|
sortOverlays(overlays);
|
||||||
|
rebuildOverlayLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
return remove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove if overlay matches filter
|
||||||
|
*
|
||||||
|
* @param filter the filter
|
||||||
|
* @return true if any overlay was removed
|
||||||
|
*/
|
||||||
|
public boolean removeIf(Predicate<Overlay> filter)
|
||||||
|
{
|
||||||
|
final boolean removeIf = overlays.removeIf(filter);
|
||||||
|
sortOverlays(overlays);
|
||||||
|
rebuildOverlayLayers();
|
||||||
|
return removeIf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all overlays
|
||||||
|
*/
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
overlays.clear();
|
||||||
|
sortOverlays(overlays);
|
||||||
|
rebuildOverlayLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force save overlay data
|
||||||
|
*
|
||||||
|
* @param overlay overlay to save
|
||||||
|
*/
|
||||||
|
public void saveOverlay(final Overlay overlay)
|
||||||
|
{
|
||||||
|
saveOverlayPosition(overlay);
|
||||||
|
saveOverlaySize(overlay);
|
||||||
|
saveOverlayLocation(overlay);
|
||||||
|
sortOverlays(overlays);
|
||||||
|
rebuildOverlayLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets stored overlay position data
|
||||||
|
*
|
||||||
|
* @param overlay overlay to reset
|
||||||
|
*/
|
||||||
|
public void resetOverlay(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
||||||
|
final String positionKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||||
|
final String sizeKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
||||||
|
configManager.unsetConfiguration(RUNELITE_CONFIG_GROUP_NAME, locationKey);
|
||||||
|
configManager.unsetConfiguration(RUNELITE_CONFIG_GROUP_NAME, positionKey);
|
||||||
|
configManager.unsetConfiguration(RUNELITE_CONFIG_GROUP_NAME, sizeKey);
|
||||||
|
sortOverlays(overlays);
|
||||||
|
rebuildOverlayLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rebuildOverlayLayers()
|
||||||
|
{
|
||||||
|
overlayLayers.clear();
|
||||||
|
|
||||||
|
for (final Overlay overlay : overlays)
|
||||||
|
{
|
||||||
|
OverlayLayer layer = overlay.getLayer();
|
||||||
|
|
||||||
|
if (overlay.getPreferredLocation() != null && overlay.getPreferredPosition() == null)
|
||||||
|
{
|
||||||
|
// When UNDER_WIDGET overlays are in preferred locations, move to
|
||||||
|
// ABOVE_WIDGETS so that it can draw over interfaces
|
||||||
|
if (layer == OverlayLayer.UNDER_WIDGETS)
|
||||||
|
{
|
||||||
|
layer = OverlayLayer.ABOVE_WIDGETS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overlayLayers.compute(layer, (key, value) ->
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
value = new CopyOnWriteArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
value.add(overlay);
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveOverlayLocation(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
||||||
|
if (overlay.getPreferredLocation() != null)
|
||||||
|
{
|
||||||
|
configManager.setConfiguration(
|
||||||
|
RUNELITE_CONFIG_GROUP_NAME,
|
||||||
|
key,
|
||||||
|
overlay.getPreferredLocation());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configManager.unsetConfiguration(
|
||||||
|
RUNELITE_CONFIG_GROUP_NAME,
|
||||||
|
key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveOverlaySize(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
||||||
|
if (overlay.getPreferredSize() != null)
|
||||||
|
{
|
||||||
|
configManager.setConfiguration(
|
||||||
|
RUNELITE_CONFIG_GROUP_NAME,
|
||||||
|
key,
|
||||||
|
overlay.getPreferredSize());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configManager.unsetConfiguration(
|
||||||
|
RUNELITE_CONFIG_GROUP_NAME,
|
||||||
|
key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveOverlayPosition(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||||
|
if (overlay.getPreferredPosition() != null)
|
||||||
|
{
|
||||||
|
configManager.setConfiguration(
|
||||||
|
RUNELITE_CONFIG_GROUP_NAME,
|
||||||
|
key,
|
||||||
|
overlay.getPreferredPosition());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configManager.unsetConfiguration(
|
||||||
|
RUNELITE_CONFIG_GROUP_NAME,
|
||||||
|
key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point loadOverlayLocation(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
||||||
|
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, key, Point.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dimension loadOverlaySize(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
||||||
|
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, key, Dimension.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OverlayPosition loadOverlayPosition(final Overlay overlay)
|
||||||
|
{
|
||||||
|
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||||
|
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, locationKey, OverlayPosition.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static void sortOverlays(List<Overlay> overlays)
|
||||||
|
{
|
||||||
|
overlays.sort((a, b) ->
|
||||||
|
{
|
||||||
|
if (a.getPosition() != b.getPosition())
|
||||||
|
{
|
||||||
|
// This is so non-dynamic overlays render after dynamic
|
||||||
|
// overlays, which are generally in the scene
|
||||||
|
return a.getPosition().compareTo(b.getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
// For dynamic overlays, higher priority means to
|
||||||
|
// draw *later* so it is on top.
|
||||||
|
// For non-dynamic overlays, higher priority means
|
||||||
|
// draw *first* so that they are closer to their
|
||||||
|
// defined position.
|
||||||
|
return a.getPosition() == OverlayPosition.DYNAMIC
|
||||||
|
? a.getPriority().compareTo(b.getPriority())
|
||||||
|
: b.getPriority().compareTo(a.getPriority());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,5 +29,6 @@ public enum OverlayPriority
|
|||||||
LOW,
|
LOW,
|
||||||
NONE,
|
NONE,
|
||||||
MED,
|
MED,
|
||||||
HIGH
|
HIGH,
|
||||||
|
HIGHEST
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,14 +33,7 @@ import java.awt.Point;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@@ -49,18 +42,13 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.events.FocusChanged;
|
import net.runelite.api.events.FocusChanged;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
import net.runelite.client.config.ConfigGroup;
|
|
||||||
import net.runelite.client.config.ConfigManager;
|
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
import net.runelite.client.events.PluginChanged;
|
|
||||||
import net.runelite.client.input.KeyListener;
|
import net.runelite.client.input.KeyListener;
|
||||||
import net.runelite.client.input.KeyManager;
|
import net.runelite.client.input.KeyManager;
|
||||||
import net.runelite.client.input.MouseListener;
|
import net.runelite.client.input.MouseListener;
|
||||||
import net.runelite.client.input.MouseManager;
|
import net.runelite.client.input.MouseManager;
|
||||||
import net.runelite.client.plugins.PluginManager;
|
|
||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
|
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
|
||||||
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
|
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
|
||||||
@@ -83,19 +71,9 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
private static final Color SNAP_CORNER_ACTIVE_COLOR = new Color(0, 255, 0, 100);
|
private static final Color SNAP_CORNER_ACTIVE_COLOR = new Color(0, 255, 0, 100);
|
||||||
private static final Color MOVING_OVERLAY_COLOR = new Color(255, 255, 0, 100);
|
private static final Color MOVING_OVERLAY_COLOR = new Color(255, 255, 0, 100);
|
||||||
private static final Color MOVING_OVERLAY_ACTIVE_COLOR = new Color(255, 255, 0, 200);
|
private static final Color MOVING_OVERLAY_ACTIVE_COLOR = new Color(255, 255, 0, 200);
|
||||||
private static final String OVERLAY_CONFIG_PREFERRED_LOCATION = "_preferredLocation";
|
|
||||||
private static final String OVERLAY_CONFIG_PREFERRED_POSITION = "_preferredPosition";
|
|
||||||
private static final String OVERLAY_CONFIG_PREFERRED_SIZE = "_preferredSize";
|
|
||||||
|
|
||||||
private final PluginManager pluginManager;
|
|
||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
private final InfoBoxOverlay infoBoxOverlay;
|
private final OverlayManager overlayManager;
|
||||||
private final ConfigManager configManager;
|
|
||||||
private final RuneLiteConfig runeLiteConfig;
|
private final RuneLiteConfig runeLiteConfig;
|
||||||
private final TooltipOverlay tooltipOverlay;
|
|
||||||
private final WorldMapOverlay worldMapOverlay;
|
|
||||||
private final List<Overlay> allOverlays = new CopyOnWriteArrayList<>();
|
|
||||||
private final String runeliteGroupName = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).keyName();
|
|
||||||
|
|
||||||
// Overlay movement variables
|
// Overlay movement variables
|
||||||
private final Point overlayOffset = new Point();
|
private final Point overlayOffset = new Point();
|
||||||
@@ -109,52 +87,28 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
private boolean chatboxHidden;
|
private boolean chatboxHidden;
|
||||||
private boolean isResizeable;
|
private boolean isResizeable;
|
||||||
private OverlayBounds snapCorners;
|
private OverlayBounds snapCorners;
|
||||||
private final Map<OverlayLayer, List<Overlay>> overlayLayerOverlayMap = Collections
|
|
||||||
.synchronizedMap(new HashMap<>());
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OverlayRenderer(
|
private OverlayRenderer(
|
||||||
final Provider<Client> clientProvider,
|
final Provider<Client> clientProvider,
|
||||||
final PluginManager pluginManager,
|
final OverlayManager overlayManager,
|
||||||
|
final RuneLiteConfig runeLiteConfig,
|
||||||
final MouseManager mouseManager,
|
final MouseManager mouseManager,
|
||||||
final KeyManager keyManager,
|
final KeyManager keyManager,
|
||||||
final TooltipOverlay tooltipOverlay,
|
|
||||||
final InfoBoxOverlay infoBoxOverlay,
|
final InfoBoxOverlay infoBoxOverlay,
|
||||||
final WorldMapOverlay worldMapOverlay,
|
final TooltipOverlay tooltipOverlay,
|
||||||
final ConfigManager configManager,
|
final WorldMapOverlay worldMapOverlay)
|
||||||
final RuneLiteConfig runeLiteConfig)
|
|
||||||
{
|
{
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.pluginManager = pluginManager;
|
this.overlayManager = overlayManager;
|
||||||
this.tooltipOverlay = tooltipOverlay;
|
|
||||||
this.infoBoxOverlay = infoBoxOverlay;
|
|
||||||
this.worldMapOverlay = worldMapOverlay;
|
|
||||||
this.configManager = configManager;
|
|
||||||
this.runeLiteConfig = runeLiteConfig;
|
this.runeLiteConfig = runeLiteConfig;
|
||||||
keyManager.registerKeyListener(this);
|
keyManager.registerKeyListener(this);
|
||||||
mouseManager.registerMouseListener(this);
|
mouseManager.registerMouseListener(this);
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
// Register core overlays
|
||||||
public void onGameStateChanged(GameStateChanged event)
|
overlayManager.add(infoBoxOverlay);
|
||||||
{
|
overlayManager.add(worldMapOverlay);
|
||||||
final Client client = clientProvider.get();
|
overlayManager.add(tooltipOverlay);
|
||||||
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getGameState().equals(GameState.LOGGED_IN))
|
|
||||||
{
|
|
||||||
rebuildOverlays();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onPluginChanged(PluginChanged event)
|
|
||||||
{
|
|
||||||
rebuildOverlays();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -166,129 +120,10 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Force save overlay data
|
|
||||||
* @param overlay overlay to save
|
|
||||||
*/
|
|
||||||
public void saveOverlay(final Overlay overlay)
|
|
||||||
{
|
|
||||||
saveOverlayPosition(overlay);
|
|
||||||
saveOverlaySize(overlay);
|
|
||||||
saveOverlayLocation(overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets stored overlay position data
|
|
||||||
* @param overlay overlay to reset
|
|
||||||
*/
|
|
||||||
public void resetOverlay(final Overlay overlay)
|
|
||||||
{
|
|
||||||
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
|
||||||
final String positionKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
|
||||||
final String sizeKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
|
||||||
configManager.unsetConfiguration(runeliteGroupName, locationKey);
|
|
||||||
configManager.unsetConfiguration(runeliteGroupName, positionKey);
|
|
||||||
configManager.unsetConfiguration(runeliteGroupName, sizeKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rebuild overlay cache for rendering
|
|
||||||
*/
|
|
||||||
public void rebuildOverlays()
|
|
||||||
{
|
|
||||||
final List<Overlay> overlays = Stream
|
|
||||||
.concat(
|
|
||||||
pluginManager.getPlugins()
|
|
||||||
.stream()
|
|
||||||
.filter(pluginManager::isPluginEnabled)
|
|
||||||
.flatMap(plugin -> plugin.getOverlays().stream()),
|
|
||||||
Stream.of(infoBoxOverlay, tooltipOverlay, worldMapOverlay))
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
sortOverlays(overlays);
|
|
||||||
allOverlays.clear();
|
|
||||||
allOverlays.addAll(overlays);
|
|
||||||
|
|
||||||
final Client client = clientProvider.get();
|
|
||||||
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Overlay overlay : overlays)
|
|
||||||
{
|
|
||||||
final Point location = loadOverlayLocation(overlay);
|
|
||||||
overlay.setPreferredLocation(location);
|
|
||||||
|
|
||||||
final Dimension size = loadOverlaySize(overlay);
|
|
||||||
overlay.setPreferredSize(size);
|
|
||||||
|
|
||||||
final OverlayPosition position = loadOverlayPosition(overlay);
|
|
||||||
overlay.setPreferredPosition(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuildOverlayLayers();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rebuildOverlayLayers()
|
|
||||||
{
|
|
||||||
overlayLayerOverlayMap.clear();
|
|
||||||
|
|
||||||
for (final Overlay overlay : allOverlays)
|
|
||||||
{
|
|
||||||
OverlayLayer layer = overlay.getLayer();
|
|
||||||
|
|
||||||
if (overlay.getPreferredLocation() != null && overlay.getPreferredPosition() == null)
|
|
||||||
{
|
|
||||||
// When UNDER_WIDGET overlays are in preferred locations, move to
|
|
||||||
// ABOVE_WIDGETS so that it can draw over interfaces
|
|
||||||
if (layer == OverlayLayer.UNDER_WIDGETS)
|
|
||||||
{
|
|
||||||
layer = OverlayLayer.ABOVE_WIDGETS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
overlayLayerOverlayMap.compute(layer, (key, value) ->
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
value = new CopyOnWriteArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
value.add(overlay);
|
|
||||||
return value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sortOverlays(List<Overlay> overlays)
|
|
||||||
{
|
|
||||||
overlays.sort((a, b) ->
|
|
||||||
{
|
|
||||||
if (a.getPosition() != b.getPosition())
|
|
||||||
{
|
|
||||||
// This is so non-dynamic overlays render after dynamic
|
|
||||||
// overlays, which are generally in the scene
|
|
||||||
return a.getPosition().compareTo(b.getPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
// For dynamic overlays, higher priority means to
|
|
||||||
// draw *later* so it is on top.
|
|
||||||
// For non-dynamic overlays, higher priority means
|
|
||||||
// draw *first* so that they are closer to their
|
|
||||||
// defined position.
|
|
||||||
return a.getPosition() == OverlayPosition.DYNAMIC
|
|
||||||
? a.getPriority().compareTo(b.getPriority())
|
|
||||||
: b.getPriority().compareTo(a.getPriority());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(Graphics2D graphics, final OverlayLayer layer)
|
public void render(Graphics2D graphics, final OverlayLayer layer)
|
||||||
{
|
{
|
||||||
final Client client = clientProvider.get();
|
final Client client = clientProvider.get();
|
||||||
final List<Overlay> overlays = overlayLayerOverlayMap.get(layer);
|
final List<Overlay> overlays = overlayManager.getOverlayLayers().get(layer);
|
||||||
|
|
||||||
if (client == null
|
if (client == null
|
||||||
|| overlays == null
|
|| overlays == null
|
||||||
@@ -410,7 +245,7 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
final Point mousePoint = mouseEvent.getPoint();
|
final Point mousePoint = mouseEvent.getPoint();
|
||||||
mousePosition.setLocation(mousePoint);
|
mousePosition.setLocation(mousePoint);
|
||||||
|
|
||||||
for (Overlay overlay : allOverlays)
|
for (Overlay overlay : overlayManager.getOverlays())
|
||||||
{
|
{
|
||||||
if (overlay.getBounds().contains(mousePoint))
|
if (overlay.getBounds().contains(mousePoint))
|
||||||
{
|
{
|
||||||
@@ -422,15 +257,20 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
overlay.setPreferredPosition(null);
|
overlay.setPreferredPosition(null);
|
||||||
overlay.setPreferredSize(null);
|
overlay.setPreferredSize(null);
|
||||||
overlay.setPreferredLocation(null);
|
overlay.setPreferredLocation(null);
|
||||||
saveOverlay(overlay);
|
overlayManager.resetOverlay(overlay);
|
||||||
rebuildOverlayLayers();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mousePoint.translate(-overlay.getBounds().x, -overlay.getBounds().y);
|
final Point offset = new Point(mousePoint.x, mousePoint.y);
|
||||||
overlayOffset.setLocation(mousePoint);
|
offset.translate(-overlay.getBounds().x, -overlay.getBounds().y);
|
||||||
|
overlayOffset.setLocation(offset);
|
||||||
|
|
||||||
|
mousePoint.translate(-offset.x, -offset.y);
|
||||||
movedOverlay = overlay;
|
movedOverlay = overlay;
|
||||||
|
movedOverlay.setPreferredPosition(null);
|
||||||
|
movedOverlay.setPreferredLocation(mousePoint);
|
||||||
|
overlayManager.saveOverlay(movedOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseEvent.consume();
|
mouseEvent.consume();
|
||||||
@@ -470,7 +310,6 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
mousePoint.translate(-overlayOffset.x, -overlayOffset.y);
|
mousePoint.translate(-overlayOffset.x, -overlayOffset.y);
|
||||||
movedOverlay.setPreferredPosition(null);
|
movedOverlay.setPreferredPosition(null);
|
||||||
movedOverlay.setPreferredLocation(mousePoint);
|
movedOverlay.setPreferredLocation(mousePoint);
|
||||||
rebuildOverlayLayers();
|
|
||||||
mouseEvent.consume();
|
mouseEvent.consume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,11 +333,13 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
if (snapCorner.contains(mouseEvent.getPoint()))
|
if (snapCorner.contains(mouseEvent.getPoint()))
|
||||||
{
|
{
|
||||||
OverlayPosition position = snapCorners.fromBounds(snapCorner);
|
OverlayPosition position = snapCorners.fromBounds(snapCorner);
|
||||||
|
|
||||||
if (position == movedOverlay.getPosition())
|
if (position == movedOverlay.getPosition())
|
||||||
{
|
{
|
||||||
// overlay moves back to default position
|
// overlay moves back to default position
|
||||||
position = null;
|
position = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
movedOverlay.setPreferredPosition(position);
|
movedOverlay.setPreferredPosition(position);
|
||||||
movedOverlay.setPreferredLocation(null); // from dragging
|
movedOverlay.setPreferredLocation(null); // from dragging
|
||||||
break;
|
break;
|
||||||
@@ -506,9 +347,7 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
saveOverlayPosition(movedOverlay);
|
overlayManager.saveOverlay(movedOverlay);
|
||||||
saveOverlayLocation(movedOverlay);
|
|
||||||
rebuildOverlayLayers();
|
|
||||||
movedOverlay = null;
|
movedOverlay = null;
|
||||||
mouseEvent.consume();
|
mouseEvent.consume();
|
||||||
}
|
}
|
||||||
@@ -650,76 +489,4 @@ public class OverlayRenderer extends MouseListener implements KeyListener
|
|||||||
new Rectangle(bottomRightPoint, SNAP_CORNER_SIZE),
|
new Rectangle(bottomRightPoint, SNAP_CORNER_SIZE),
|
||||||
new Rectangle(rightChatboxPoint, SNAP_CORNER_SIZE));
|
new Rectangle(rightChatboxPoint, SNAP_CORNER_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveOverlayLocation(final Overlay overlay)
|
|
||||||
{
|
|
||||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
|
||||||
if (overlay.getPreferredLocation() != null)
|
|
||||||
{
|
|
||||||
configManager.setConfiguration(
|
|
||||||
runeliteGroupName,
|
|
||||||
key,
|
|
||||||
overlay.getPreferredLocation());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
configManager.unsetConfiguration(
|
|
||||||
runeliteGroupName,
|
|
||||||
key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveOverlaySize(final Overlay overlay)
|
|
||||||
{
|
|
||||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
|
||||||
if (overlay.getPreferredSize() != null)
|
|
||||||
{
|
|
||||||
configManager.setConfiguration(
|
|
||||||
runeliteGroupName,
|
|
||||||
key,
|
|
||||||
overlay.getPreferredSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
configManager.unsetConfiguration(
|
|
||||||
runeliteGroupName,
|
|
||||||
key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveOverlayPosition(final Overlay overlay)
|
|
||||||
{
|
|
||||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
|
||||||
if (overlay.getPreferredPosition() != null)
|
|
||||||
{
|
|
||||||
configManager.setConfiguration(
|
|
||||||
runeliteGroupName,
|
|
||||||
key,
|
|
||||||
overlay.getPreferredPosition());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
configManager.unsetConfiguration(
|
|
||||||
runeliteGroupName,
|
|
||||||
key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point loadOverlayLocation(final Overlay overlay)
|
|
||||||
{
|
|
||||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
|
||||||
return configManager.getConfiguration(runeliteGroupName, key, Point.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dimension loadOverlaySize(final Overlay overlay)
|
|
||||||
{
|
|
||||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
|
||||||
return configManager.getConfiguration(runeliteGroupName, key, Dimension.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private OverlayPosition loadOverlayPosition(final Overlay overlay)
|
|
||||||
{
|
|
||||||
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
|
||||||
return configManager.getConfiguration(runeliteGroupName, locationKey, OverlayPosition.class);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,17 @@ public class InfoBoxOverlay extends Overlay
|
|||||||
private final RuneLiteConfig config;
|
private final RuneLiteConfig config;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public InfoBoxOverlay(InfoBoxManager infoboxManager, TooltipManager tooltipManager, Provider<Client> clientProvider, RuneLiteConfig config)
|
private InfoBoxOverlay(
|
||||||
|
InfoBoxManager infoboxManager,
|
||||||
|
TooltipManager tooltipManager,
|
||||||
|
Provider<Client> clientProvider,
|
||||||
|
RuneLiteConfig config)
|
||||||
{
|
{
|
||||||
setPosition(OverlayPosition.TOP_LEFT);
|
|
||||||
this.tooltipManager = tooltipManager;
|
this.tooltipManager = tooltipManager;
|
||||||
this.infoboxManager = infoboxManager;
|
this.infoboxManager = infoboxManager;
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
setPosition(OverlayPosition.TOP_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -50,12 +50,12 @@ public class TooltipOverlay extends Overlay
|
|||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TooltipOverlay(Provider<Client> clientProvider, TooltipManager tooltipManager)
|
private TooltipOverlay(Provider<Client> clientProvider, TooltipManager tooltipManager)
|
||||||
{
|
{
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.tooltipManager = tooltipManager;
|
this.tooltipManager = tooltipManager;
|
||||||
setPosition(OverlayPosition.TOOLTIP);
|
setPosition(OverlayPosition.TOOLTIP);
|
||||||
setPriority(OverlayPriority.HIGH);
|
setPriority(OverlayPriority.HIGHEST);
|
||||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,13 +63,16 @@ public class WorldMapOverlay extends Overlay
|
|||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private WorldMapOverlay(Provider<Client> clientProvider, WorldMapPointManager worldMapPointManager,
|
private WorldMapOverlay(
|
||||||
MouseManager mouseManager, WorldMapOverlayMouseListener worldMapOverlayMouseListener)
|
Provider<Client> clientProvider,
|
||||||
|
WorldMapPointManager worldMapPointManager,
|
||||||
|
MouseManager mouseManager,
|
||||||
|
WorldMapOverlayMouseListener worldMapOverlayMouseListener)
|
||||||
{
|
{
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.worldMapPointManager = worldMapPointManager;
|
this.worldMapPointManager = worldMapPointManager;
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
setPriority(OverlayPriority.HIGH);
|
setPriority(OverlayPriority.HIGHEST);
|
||||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||||
mouseManager.registerMouseListener(worldMapOverlayMouseListener);
|
mouseManager.registerMouseListener(worldMapOverlayMouseListener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,23 +31,23 @@ import java.util.List;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
class TestOverlay extends Overlay
|
public class OverlayManagerTest
|
||||||
{
|
{
|
||||||
public TestOverlay(OverlayPosition position, OverlayPriority priority)
|
class TestOverlay extends Overlay
|
||||||
{
|
{
|
||||||
setPosition(position);
|
TestOverlay(OverlayPosition position, OverlayPriority priority)
|
||||||
setPriority(priority);
|
{
|
||||||
|
setPosition(position);
|
||||||
|
setPriority(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OverlayRendererTest
|
|
||||||
{
|
|
||||||
@Test
|
@Test
|
||||||
public void testSort()
|
public void testSort()
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ public class OverlayRendererTest
|
|||||||
Overlay tlh = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.HIGH);
|
Overlay tlh = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.HIGH);
|
||||||
Overlay tll = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.LOW);
|
Overlay tll = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.LOW);
|
||||||
List<Overlay> overlays = Arrays.asList(tlh, tll);
|
List<Overlay> overlays = Arrays.asList(tlh, tll);
|
||||||
OverlayRenderer.sortOverlays(overlays);
|
OverlayManager.sortOverlays(overlays);
|
||||||
assertEquals(tlh, overlays.get(0));
|
assertEquals(tlh, overlays.get(0));
|
||||||
assertEquals(tll, overlays.get(1));
|
assertEquals(tll, overlays.get(1));
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ public class OverlayRendererTest
|
|||||||
Overlay tlh = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.HIGH);
|
Overlay tlh = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.HIGH);
|
||||||
Overlay dyn = new TestOverlay(OverlayPosition.DYNAMIC, OverlayPriority.HIGH);
|
Overlay dyn = new TestOverlay(OverlayPosition.DYNAMIC, OverlayPriority.HIGH);
|
||||||
List<Overlay> overlays = Arrays.asList(tlh, dyn);
|
List<Overlay> overlays = Arrays.asList(tlh, dyn);
|
||||||
OverlayRenderer.sortOverlays(overlays);
|
OverlayManager.sortOverlays(overlays);
|
||||||
assertEquals(dyn, overlays.get(0));
|
assertEquals(dyn, overlays.get(0));
|
||||||
assertEquals(tlh, overlays.get(1));
|
assertEquals(tlh, overlays.get(1));
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ public class OverlayRendererTest
|
|||||||
Overlay dyn = new TestOverlay(OverlayPosition.DYNAMIC, OverlayPriority.HIGH);
|
Overlay dyn = new TestOverlay(OverlayPosition.DYNAMIC, OverlayPriority.HIGH);
|
||||||
Overlay tlh = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.HIGH);
|
Overlay tlh = new TestOverlay(OverlayPosition.TOP_LEFT, OverlayPriority.HIGH);
|
||||||
List<Overlay> overlays = Arrays.asList(t, dyn, tlh);
|
List<Overlay> overlays = Arrays.asList(t, dyn, tlh);
|
||||||
OverlayRenderer.sortOverlays(overlays);
|
OverlayManager.sortOverlays(overlays);
|
||||||
assertEquals(dyn, overlays.get(0));
|
assertEquals(dyn, overlays.get(0));
|
||||||
assertEquals(tlh, overlays.get(1));
|
assertEquals(tlh, overlays.get(1));
|
||||||
assertEquals(t, overlays.get(2));
|
assertEquals(t, overlays.get(2));
|
||||||
Reference in New Issue
Block a user