Merge pull request #3294 from deathbeam/infobox-smaller
Add support for configurable infobox sizes
This commit is contained in:
@@ -56,6 +56,7 @@ import net.runelite.client.ui.ClientUI;
|
|||||||
import net.runelite.client.ui.DrawManager;
|
import net.runelite.client.ui.DrawManager;
|
||||||
import net.runelite.client.ui.TitleToolbar;
|
import net.runelite.client.ui.TitleToolbar;
|
||||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||||
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.slf4j.MDC;
|
import org.slf4j.MDC;
|
||||||
|
|
||||||
@@ -120,6 +121,9 @@ public class RuneLite
|
|||||||
@Inject
|
@Inject
|
||||||
private ClanManager clanManager;
|
private ClanManager clanManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private InfoBoxManager infoBoxManager;
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception
|
public static void main(String[] args) throws Exception
|
||||||
@@ -214,6 +218,7 @@ public class RuneLite
|
|||||||
eventBus.register(commandManager);
|
eventBus.register(commandManager);
|
||||||
eventBus.register(pluginManager);
|
eventBus.register(pluginManager);
|
||||||
eventBus.register(clanManager);
|
eventBus.register(clanManager);
|
||||||
|
eventBus.register(infoBoxManager);
|
||||||
|
|
||||||
if (this.client != null)
|
if (this.client != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -221,4 +221,15 @@ public interface RuneLiteConfig extends Config
|
|||||||
{
|
{
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "infoBoxSize",
|
||||||
|
name = "Infobox size (px)",
|
||||||
|
description = "Configures the size of each infobox in pixels",
|
||||||
|
position = 34
|
||||||
|
)
|
||||||
|
default int infoBoxSize()
|
||||||
|
{
|
||||||
|
return 35;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,9 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.prayer;
|
package net.runelite.client.plugins.prayer;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||||
|
|
||||||
@@ -35,9 +33,6 @@ public class PrayerCounter extends Counter
|
|||||||
@Getter
|
@Getter
|
||||||
private final PrayerType prayerType;
|
private final PrayerType prayerType;
|
||||||
|
|
||||||
@Setter
|
|
||||||
private BufferedImage image;
|
|
||||||
|
|
||||||
PrayerCounter(Plugin plugin, PrayerType prayerType)
|
PrayerCounter(Plugin plugin, PrayerType prayerType)
|
||||||
{
|
{
|
||||||
super(null, plugin, "");
|
super(null, plugin, "");
|
||||||
@@ -55,10 +50,4 @@ public class PrayerCounter extends Counter
|
|||||||
{
|
{
|
||||||
return prayerType.getDescription();
|
return prayerType.getDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BufferedImage getImage()
|
|
||||||
{
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ package net.runelite.client.plugins.screenmarkers;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.Stroke;
|
import java.awt.Stroke;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -36,6 +37,10 @@ import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity;
|
|||||||
public class ScreenMarkerRenderable implements LayoutableRenderableEntity
|
public class ScreenMarkerRenderable implements LayoutableRenderableEntity
|
||||||
{
|
{
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
@Setter
|
||||||
|
private Point preferredLocation;
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
@Setter
|
||||||
private Dimension preferredSize;
|
private Dimension preferredSize;
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
@Setter(AccessLevel.PACKAGE)
|
@Setter(AccessLevel.PACKAGE)
|
||||||
@@ -69,10 +74,4 @@ public class ScreenMarkerRenderable implements LayoutableRenderableEntity
|
|||||||
graphics.drawRect(offset, offset, width - thickness, height - thickness);
|
graphics.drawRect(offset, offset, width - thickness, height - thickness);
|
||||||
return preferredSize;
|
return preferredSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPreferredSize(Dimension preferredSize)
|
|
||||||
{
|
|
||||||
this.preferredSize = preferredSize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ public class XpGlobesOverlay extends Overlay
|
|||||||
String skillCurrentXp = decimalFormat.format(mouseOverSkill.getCurrentXp());
|
String skillCurrentXp = decimalFormat.format(mouseOverSkill.getCurrentXp());
|
||||||
|
|
||||||
xpTooltip.getChildren().clear();
|
xpTooltip.getChildren().clear();
|
||||||
graphics.translate(x, y);
|
xpTooltip.setPreferredLocation(new java.awt.Point(x, y));
|
||||||
xpTooltip.setPreferredSize(new Dimension(TOOLTIP_RECT_SIZE_X, 0));
|
xpTooltip.setPreferredSize(new Dimension(TOOLTIP_RECT_SIZE_X, 0));
|
||||||
|
|
||||||
xpTooltip.getChildren().add(LineComponent.builder()
|
xpTooltip.getChildren().add(LineComponent.builder()
|
||||||
@@ -286,6 +286,5 @@ public class XpGlobesOverlay extends Overlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
xpTooltip.render(graphics);
|
xpTooltip.render(graphics);
|
||||||
graphics.translate(-x, -y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,17 @@ package net.runelite.client.ui.overlay.components;
|
|||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Setter
|
@Setter
|
||||||
public class ImageComponent implements LayoutableRenderableEntity
|
public class ImageComponent implements LayoutableRenderableEntity
|
||||||
{
|
{
|
||||||
private BufferedImage image;
|
private final BufferedImage image;
|
||||||
|
private Point preferredLocation = new Point();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
@@ -44,7 +46,7 @@ public class ImageComponent implements LayoutableRenderableEntity
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.drawImage(image, 0, -graphics.getFontMetrics().getHeight(), null);
|
graphics.drawImage(image, preferredLocation.x, preferredLocation.y, null);
|
||||||
return new Dimension(image.getWidth(), image.getHeight());
|
return new Dimension(image.getWidth(), image.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,49 +28,80 @@ import java.awt.Color;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.image.BufferedImage;
|
import lombok.Getter;
|
||||||
import java.util.Objects;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
import net.runelite.client.ui.FontManager;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
public class InfoBoxComponent implements RenderableEntity
|
public class InfoBoxComponent implements LayoutableRenderableEntity
|
||||||
{
|
{
|
||||||
private static final int BOX_SIZE = 35;
|
private static final int SEPARATOR = 3;
|
||||||
private static final int SEPARATOR = 2;
|
private static final int DEFAULT_SIZE = 32;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String tooltip;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Point preferredLocation = new Point();
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private Dimension preferredSize = new Dimension(DEFAULT_SIZE, DEFAULT_SIZE);
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
private Color color = Color.WHITE;
|
private Color color = Color.WHITE;
|
||||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||||
private Point position = new Point();
|
private Image image;
|
||||||
private BufferedImage image;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
|
if (image == null)
|
||||||
|
{
|
||||||
|
return new Dimension();
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.setFont(getSize() < DEFAULT_SIZE ? FontManager.getRunescapeSmallFont() : FontManager.getRunescapeFont());
|
||||||
|
graphics.translate(preferredLocation.x, preferredLocation.y);
|
||||||
|
|
||||||
|
// Calculate dimensions
|
||||||
final FontMetrics metrics = graphics.getFontMetrics();
|
final FontMetrics metrics = graphics.getFontMetrics();
|
||||||
final Rectangle bounds = new Rectangle(position.x, position.y, BOX_SIZE, BOX_SIZE);
|
final int size = getSize();
|
||||||
|
final Rectangle bounds = new Rectangle(size, size);
|
||||||
|
|
||||||
|
// Render background
|
||||||
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
||||||
backgroundComponent.setBackgroundColor(backgroundColor);
|
backgroundComponent.setBackgroundColor(backgroundColor);
|
||||||
backgroundComponent.setRectangle(bounds);
|
backgroundComponent.setRectangle(bounds);
|
||||||
backgroundComponent.render(graphics);
|
backgroundComponent.render(graphics);
|
||||||
|
|
||||||
if (Objects.nonNull(image))
|
// Render image
|
||||||
{
|
graphics.drawImage(
|
||||||
graphics.drawImage(image,
|
image,
|
||||||
position.x + (BOX_SIZE - image.getWidth()) / 2,
|
(size - image.getWidth(null)) / 2,
|
||||||
position.y + (BOX_SIZE - image.getHeight()) / 2, null);
|
(size - image.getHeight(null)) / 2,
|
||||||
}
|
null);
|
||||||
|
|
||||||
|
// Render caption
|
||||||
final TextComponent textComponent = new TextComponent();
|
final TextComponent textComponent = new TextComponent();
|
||||||
textComponent.setColor(color);
|
textComponent.setColor(color);
|
||||||
textComponent.setText(text);
|
textComponent.setText(text);
|
||||||
textComponent.setPosition(new Point(
|
textComponent.setPosition(new Point(((size - metrics.stringWidth(text)) / 2), size - SEPARATOR));
|
||||||
position.x + ((BOX_SIZE - metrics.stringWidth(text)) / 2),
|
|
||||||
position.y + BOX_SIZE - SEPARATOR));
|
|
||||||
textComponent.render(graphics);
|
textComponent.render(graphics);
|
||||||
return new Dimension(BOX_SIZE, BOX_SIZE);
|
|
||||||
|
graphics.translate(-preferredLocation.x, -preferredLocation.y);
|
||||||
|
return bounds.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dimension getPreferredSize()
|
||||||
|
{
|
||||||
|
return new Dimension(getSize(), getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSize()
|
||||||
|
{
|
||||||
|
return Math.max(preferredSize.width, preferredSize.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,11 @@
|
|||||||
package net.runelite.client.ui.overlay.components;
|
package net.runelite.client.ui.overlay.components;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Point;
|
||||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||||
|
|
||||||
public interface LayoutableRenderableEntity extends RenderableEntity
|
public interface LayoutableRenderableEntity extends RenderableEntity
|
||||||
{
|
{
|
||||||
|
void setPreferredLocation(Point position);
|
||||||
void setPreferredSize(Dimension dimension);
|
void setPreferredSize(Dimension dimension);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,19 +47,23 @@ public class LineComponent implements LayoutableRenderableEntity
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Color rightColor = Color.WHITE;
|
private Color rightColor = Color.WHITE;
|
||||||
|
|
||||||
|
@Builder.Default
|
||||||
|
private Point preferredLocation = new Point();
|
||||||
|
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0);
|
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
|
graphics.translate(preferredLocation.x, preferredLocation.y);
|
||||||
// Prevent NPEs
|
// Prevent NPEs
|
||||||
final String left = MoreObjects.firstNonNull(this.left, "");
|
final String left = MoreObjects.firstNonNull(this.left, "");
|
||||||
final String right = MoreObjects.firstNonNull(this.right, "");
|
final String right = MoreObjects.firstNonNull(this.right, "");
|
||||||
|
|
||||||
final FontMetrics metrics = graphics.getFontMetrics();
|
final FontMetrics metrics = graphics.getFontMetrics();
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = metrics.getHeight();
|
||||||
final int leftFullWidth = getLineWidth(left, metrics);
|
final int leftFullWidth = getLineWidth(left, metrics);
|
||||||
final int rightFullWidth = getLineWidth(right, metrics);
|
final int rightFullWidth = getLineWidth(right, metrics);
|
||||||
|
|
||||||
@@ -108,7 +112,8 @@ public class LineComponent implements LayoutableRenderableEntity
|
|||||||
y += metrics.getHeight();
|
y += metrics.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Dimension(preferredSize.width, y);
|
graphics.translate(-preferredLocation.x, -preferredLocation.y);
|
||||||
|
return new Dimension(preferredSize.width, y - metrics.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
final TextComponent leftLineComponent = new TextComponent();
|
final TextComponent leftLineComponent = new TextComponent();
|
||||||
@@ -124,7 +129,8 @@ public class LineComponent implements LayoutableRenderableEntity
|
|||||||
rightLineComponent.render(graphics);
|
rightLineComponent.render(graphics);
|
||||||
y += metrics.getHeight();
|
y += metrics.getHeight();
|
||||||
|
|
||||||
return new Dimension(preferredSize.width, y);
|
graphics.translate(-preferredLocation.x, -preferredLocation.y);
|
||||||
|
return new Dimension(preferredSize.width, y - metrics.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getLineWidth(final String line, final FontMetrics metrics)
|
private static int getLineWidth(final String line, final FontMetrics metrics)
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ package net.runelite.client.ui.overlay.components;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.FontMetrics;
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@@ -44,8 +44,12 @@ public class PanelComponent implements LayoutableRenderableEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
|
@Nullable
|
||||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private Point preferredLocation = new Point();
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0);
|
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0);
|
||||||
|
|
||||||
@@ -55,6 +59,9 @@ public class PanelComponent implements LayoutableRenderableEntity
|
|||||||
@Setter
|
@Setter
|
||||||
private Orientation orientation = Orientation.VERTICAL;
|
private Orientation orientation = Orientation.VERTICAL;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private int wrapping = -1;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private Rectangle border = new Rectangle(
|
private Rectangle border = new Rectangle(
|
||||||
ComponentConstants.STANDARD_BORDER,
|
ComponentConstants.STANDARD_BORDER,
|
||||||
@@ -75,21 +82,25 @@ public class PanelComponent implements LayoutableRenderableEntity
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final FontMetrics metrics = graphics.getFontMetrics();
|
graphics.translate(preferredLocation.x, preferredLocation.y);
|
||||||
|
|
||||||
// Render background
|
// Calculate panel dimension
|
||||||
final Dimension dimension = new Dimension(
|
final Dimension dimension = new Dimension(
|
||||||
border.x + childDimensions.width + border.width,
|
border.x + childDimensions.width + border.width,
|
||||||
border.y + childDimensions.height + border.height);
|
border.y + childDimensions.height + border.height);
|
||||||
|
|
||||||
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
// Render background
|
||||||
backgroundComponent.setRectangle(new Rectangle(dimension));
|
if (backgroundColor != null)
|
||||||
backgroundComponent.setBackgroundColor(backgroundColor);
|
{
|
||||||
backgroundComponent.render(graphics);
|
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
||||||
|
backgroundComponent.setRectangle(new Rectangle(dimension));
|
||||||
|
backgroundComponent.setBackgroundColor(backgroundColor);
|
||||||
|
backgroundComponent.render(graphics);
|
||||||
|
}
|
||||||
|
|
||||||
// Offset children
|
// Offset children
|
||||||
final int baseX = border.x;
|
final int baseX = border.x;
|
||||||
final int baseY = border.y + metrics.getHeight();
|
final int baseY = border.y;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
int x = baseX;
|
int x = baseX;
|
||||||
@@ -100,13 +111,17 @@ public class PanelComponent implements LayoutableRenderableEntity
|
|||||||
preferredSize.width - border.x - border.width,
|
preferredSize.width - border.x - border.width,
|
||||||
preferredSize.height - border.y - border.height);
|
preferredSize.height - border.y - border.height);
|
||||||
|
|
||||||
|
// Calculate max width/height for infoboxes
|
||||||
|
int totalHeight = 0;
|
||||||
|
int totalWidth = 0;
|
||||||
|
|
||||||
// Render all children
|
// Render all children
|
||||||
for (final LayoutableRenderableEntity child : children)
|
for (int i = 0; i < children.size(); i ++)
|
||||||
{
|
{
|
||||||
|
final LayoutableRenderableEntity child = children.get(i);
|
||||||
|
child.setPreferredLocation(new Point(x, y));
|
||||||
child.setPreferredSize(childPreferredSize);
|
child.setPreferredSize(childPreferredSize);
|
||||||
graphics.translate(x, y);
|
|
||||||
final Dimension childDimension = child.render(graphics);
|
final Dimension childDimension = child.render(graphics);
|
||||||
graphics.translate(-x, -y);
|
|
||||||
|
|
||||||
switch (orientation)
|
switch (orientation)
|
||||||
{
|
{
|
||||||
@@ -121,15 +136,45 @@ public class PanelComponent implements LayoutableRenderableEntity
|
|||||||
height = Math.max(height, childDimension.height);
|
height = Math.max(height, childDimension.height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate total size
|
||||||
|
totalWidth = Math.max(totalWidth, width);
|
||||||
|
totalHeight = Math.max(totalHeight, height);
|
||||||
|
|
||||||
|
if (wrapping > 0 && i < children.size() - 1 && (i + 1) % wrapping == 0)
|
||||||
|
{
|
||||||
|
switch (orientation)
|
||||||
|
{
|
||||||
|
case VERTICAL:
|
||||||
|
{
|
||||||
|
height = 0;
|
||||||
|
y = baseY;
|
||||||
|
int diff = childDimension.width + gap.x;
|
||||||
|
x += diff;
|
||||||
|
width += diff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HORIZONTAL:
|
||||||
|
{
|
||||||
|
width = 0;
|
||||||
|
x = baseX;
|
||||||
|
int diff = childDimension.height + gap.y;
|
||||||
|
y += diff;
|
||||||
|
height += diff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove last child gap
|
// Remove last child gap
|
||||||
width -= gap.x;
|
totalWidth -= gap.x;
|
||||||
height -= gap.y;
|
totalHeight -= gap.y;
|
||||||
|
|
||||||
// Cache children bounds
|
// Cache children bounds
|
||||||
childDimensions.setSize(width, height);
|
childDimensions.setSize(totalWidth, totalHeight);
|
||||||
|
|
||||||
|
graphics.translate(-preferredLocation.x, -preferredLocation.y);
|
||||||
return dimension;
|
return dimension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,15 +50,17 @@ public class ProgressBarComponent implements LayoutableRenderableEntity
|
|||||||
private Color foregroundColor = new Color(82, 161, 82);
|
private Color foregroundColor = new Color(82, 161, 82);
|
||||||
private Color backgroundColor = new Color(255, 255, 255, 127);
|
private Color backgroundColor = new Color(255, 255, 255, 127);
|
||||||
private Color fontColor = Color.WHITE;
|
private Color fontColor = Color.WHITE;
|
||||||
|
private Point preferredLocation = new Point();
|
||||||
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 16);
|
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 16);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
|
graphics.translate(preferredLocation.x, preferredLocation.y);
|
||||||
final FontMetrics metrics = graphics.getFontMetrics();
|
final FontMetrics metrics = graphics.getFontMetrics();
|
||||||
|
|
||||||
final int barX = 0;
|
final int barX = 0;
|
||||||
final int barY = -metrics.getHeight();
|
final int barY = 0;
|
||||||
|
|
||||||
final long span = maximum - minimum;
|
final long span = maximum - minimum;
|
||||||
final double currentValue = value - minimum;
|
final double currentValue = value - minimum;
|
||||||
@@ -92,6 +94,7 @@ public class ProgressBarComponent implements LayoutableRenderableEntity
|
|||||||
textComponent.setText(textToWrite);
|
textComponent.setText(textToWrite);
|
||||||
textComponent.render(graphics);
|
textComponent.render(graphics);
|
||||||
|
|
||||||
|
graphics.translate(-preferredLocation.x, -preferredLocation.y);
|
||||||
return new Dimension(width, height);
|
return new Dimension(width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,18 +41,23 @@ public class TitleComponent implements LayoutableRenderableEntity
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Color color = Color.WHITE;
|
private Color color = Color.WHITE;
|
||||||
|
|
||||||
|
@Builder.Default
|
||||||
|
private Point preferredLocation = new Point();
|
||||||
|
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0);
|
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
|
graphics.translate(preferredLocation.x, preferredLocation.y);
|
||||||
final FontMetrics metrics = graphics.getFontMetrics();
|
final FontMetrics metrics = graphics.getFontMetrics();
|
||||||
final TextComponent titleComponent = new TextComponent();
|
final TextComponent titleComponent = new TextComponent();
|
||||||
titleComponent.setText(text);
|
titleComponent.setText(text);
|
||||||
titleComponent.setColor(color);
|
titleComponent.setColor(color);
|
||||||
titleComponent.setPosition(new Point((preferredSize.width - metrics.stringWidth(text)) / 2, 0));
|
titleComponent.setPosition(new Point((preferredSize.width - metrics.stringWidth(text)) / 2, metrics.getHeight()));
|
||||||
final Dimension dimension = titleComponent.render(graphics);
|
final Dimension dimension = titleComponent.render(graphics);
|
||||||
|
graphics.translate(-preferredLocation.x, -preferredLocation.y);
|
||||||
return new Dimension(Math.min(preferredSize.width, dimension.width), dimension.height);
|
return new Dimension(Math.min(preferredSize.width, dimension.width), dimension.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,36 +25,39 @@
|
|||||||
package net.runelite.client.ui.overlay.infobox;
|
package net.runelite.client.ui.overlay.infobox;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.Image;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
|
||||||
public abstract class InfoBox
|
public abstract class InfoBox
|
||||||
{
|
{
|
||||||
private final BufferedImage image;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Image image;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Image scaledImage;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private InfoBoxPriority priority;
|
private InfoBoxPriority priority;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String tooltip;
|
private String tooltip;
|
||||||
|
|
||||||
public InfoBox(BufferedImage image, Plugin plugin)
|
public InfoBox(Image image, Plugin plugin)
|
||||||
{
|
{
|
||||||
this.image = image;
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
setImage(image);
|
||||||
setPriority(InfoBoxPriority.NONE);
|
setPriority(InfoBoxPriority.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferedImage getImage()
|
|
||||||
{
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String getText();
|
public abstract String getText();
|
||||||
|
|
||||||
public abstract Color getTextColor();
|
public abstract Color getTextColor();
|
||||||
@@ -68,14 +71,4 @@ public abstract class InfoBox
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTooltip()
|
|
||||||
{
|
|
||||||
return tooltip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTooltip(String tooltip)
|
|
||||||
{
|
|
||||||
this.tooltip = tooltip;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,20 @@ package net.runelite.client.ui.overlay.infobox;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ComparisonChain;
|
import com.google.common.collect.ComparisonChain;
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.events.ConfigChanged;
|
||||||
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -40,13 +47,30 @@ import net.runelite.client.plugins.PluginDescriptor;
|
|||||||
public class InfoBoxManager
|
public class InfoBoxManager
|
||||||
{
|
{
|
||||||
private final List<InfoBox> infoBoxes = new ArrayList<>();
|
private final List<InfoBox> infoBoxes = new ArrayList<>();
|
||||||
|
private final RuneLiteConfig runeLiteConfig;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private InfoBoxManager(final RuneLiteConfig runeLiteConfig)
|
||||||
|
{
|
||||||
|
this.runeLiteConfig = runeLiteConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onConfigChanged(ConfigChanged event)
|
||||||
|
{
|
||||||
|
if (event.getGroup().equals("runelite") && event.getKey().equals("infoBoxSize"))
|
||||||
|
{
|
||||||
|
infoBoxes.forEach(this::updateInfoBoxImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addInfoBox(InfoBox infoBox)
|
public void addInfoBox(InfoBox infoBox)
|
||||||
{
|
{
|
||||||
Preconditions.checkNotNull(infoBox);
|
Preconditions.checkNotNull(infoBox);
|
||||||
log.debug("Adding InfoBox {}", infoBox);
|
log.debug("Adding InfoBox {}", infoBox);
|
||||||
infoBoxes.add(infoBox);
|
|
||||||
|
|
||||||
|
updateInfoBoxImage(infoBox);
|
||||||
|
infoBoxes.add(infoBox);
|
||||||
refreshInfoBoxes();
|
refreshInfoBoxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +116,43 @@ public class InfoBoxManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateInfoBoxImage(final InfoBox infoBox)
|
||||||
|
{
|
||||||
|
if (infoBox.getImage() == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set scaled InfoBox image
|
||||||
|
final Image image = infoBox.getImage();
|
||||||
|
Image resultImage = image;
|
||||||
|
final double width = image.getWidth(null);
|
||||||
|
final double height = image.getHeight(null);
|
||||||
|
final double size = Math.max(2, runeLiteConfig.infoBoxSize()); // Limit size to 2 as that is minimum size not causing breakage
|
||||||
|
|
||||||
|
if (size < width || size < height)
|
||||||
|
{
|
||||||
|
final double scalex = size / width;
|
||||||
|
final double scaley = size / height;
|
||||||
|
|
||||||
|
if (scalex == 1 && scaley == 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final double scale = Math.min(scalex, scaley);
|
||||||
|
final int newWidth = (int) (width * scale);
|
||||||
|
final int newHeight = (int) (height * scale);
|
||||||
|
final BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
final Graphics g = scaledImage.createGraphics();
|
||||||
|
g.drawImage(image, 0, 0, newWidth, newHeight, null);
|
||||||
|
g.dispose();
|
||||||
|
resultImage = scaledImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoBox.setScaledImage(resultImage);
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshInfoBoxes()
|
private void refreshInfoBoxes()
|
||||||
{
|
{
|
||||||
Collections.sort(infoBoxes, (b1, b2) -> ComparisonChain
|
Collections.sort(infoBoxes, (b1, b2) -> ComparisonChain
|
||||||
|
|||||||
@@ -39,15 +39,14 @@ import net.runelite.client.ui.overlay.Overlay;
|
|||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||||
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
import net.runelite.client.ui.overlay.tooltip.Tooltip;
|
import net.runelite.client.ui.overlay.tooltip.Tooltip;
|
||||||
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||||
|
|
||||||
public class InfoBoxOverlay extends Overlay
|
public class InfoBoxOverlay extends Overlay
|
||||||
{
|
{
|
||||||
private static final int BOXSIZE = 35;
|
private final PanelComponent panelComponent = new PanelComponent();
|
||||||
private static final int SEPARATOR = 2;
|
|
||||||
private static final int TOTAL_BOXSIZE = BOXSIZE + SEPARATOR;
|
|
||||||
|
|
||||||
private final InfoBoxManager infoboxManager;
|
private final InfoBoxManager infoboxManager;
|
||||||
private final TooltipManager tooltipManager;
|
private final TooltipManager tooltipManager;
|
||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
@@ -65,108 +64,73 @@ public class InfoBoxOverlay extends Overlay
|
|||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
setPosition(OverlayPosition.TOP_LEFT);
|
setPosition(OverlayPosition.TOP_LEFT);
|
||||||
|
|
||||||
|
panelComponent.setBackgroundColor(null);
|
||||||
|
panelComponent.setBorder(new Rectangle());
|
||||||
|
panelComponent.setGap(new Point(1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
List<InfoBox> infoBoxes = infoboxManager.getInfoBoxes();
|
final List<InfoBox> infoBoxes = infoboxManager.getInfoBoxes();
|
||||||
|
|
||||||
if (infoBoxes.isEmpty())
|
if (infoBoxes.isEmpty())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wrap = config.infoBoxWrap();
|
panelComponent.getChildren().clear();
|
||||||
int infoBoxCount = infoBoxes.size();
|
panelComponent.setWrapping(config.infoBoxWrap());
|
||||||
boolean vertical = config.infoBoxVertical();
|
panelComponent.setOrientation(config.infoBoxVertical()
|
||||||
|
? PanelComponent.Orientation.VERTICAL
|
||||||
|
: PanelComponent.Orientation.HORIZONTAL);
|
||||||
|
panelComponent.setPreferredSize(new Dimension(config.infoBoxSize(), config.infoBoxSize()));
|
||||||
|
|
||||||
int width, height;
|
infoBoxes.forEach(box ->
|
||||||
if (!vertical)
|
|
||||||
{
|
{
|
||||||
width = getWidth(infoBoxCount, wrap);
|
|
||||||
height = getHeight(infoBoxCount, wrap);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
width = getHeight(infoBoxCount, wrap);
|
|
||||||
height = getWidth(infoBoxCount, wrap);
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
|
|
||||||
for (InfoBox box : infoBoxes)
|
|
||||||
{
|
|
||||||
if (!box.render())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
final InfoBoxComponent infoBoxComponent = new InfoBoxComponent();
|
final InfoBoxComponent infoBoxComponent = new InfoBoxComponent();
|
||||||
infoBoxComponent.setColor(box.getTextColor());
|
infoBoxComponent.setColor(box.getTextColor());
|
||||||
infoBoxComponent.setImage(box.getImage());
|
infoBoxComponent.setImage(box.getScaledImage());
|
||||||
infoBoxComponent.setText(box.getText());
|
infoBoxComponent.setText(box.getText());
|
||||||
infoBoxComponent.setPosition(new Point(x, y));
|
infoBoxComponent.setTooltip(box.getTooltip());
|
||||||
final Dimension infoBoxBounds = infoBoxComponent.render(graphics);
|
panelComponent.getChildren().add(infoBoxComponent);
|
||||||
|
});
|
||||||
|
|
||||||
if (!Strings.isNullOrEmpty(box.getTooltip()))
|
final Dimension dimension = panelComponent.render(graphics);
|
||||||
|
final Client client = clientProvider.get();
|
||||||
|
|
||||||
|
// Handle tooltips
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
final Point mouse = new Point(client.getMouseCanvasPosition().getX(), client.getMouseCanvasPosition().getY());
|
||||||
|
|
||||||
|
for (final LayoutableRenderableEntity child : panelComponent.getChildren())
|
||||||
{
|
{
|
||||||
final Rectangle intersectionRectangle = new Rectangle(infoBoxBounds);
|
if (child instanceof InfoBoxComponent)
|
||||||
intersectionRectangle.setLocation(getBounds().getLocation());
|
{
|
||||||
intersectionRectangle.translate(x, y);
|
final InfoBoxComponent component = (InfoBoxComponent) child;
|
||||||
final Point transformed = OverlayUtil.transformPosition(getPosition(), intersectionRectangle.getSize());
|
|
||||||
intersectionRectangle.translate(transformed.x, transformed.y);
|
|
||||||
|
|
||||||
final Client client = clientProvider.get();
|
if (!Strings.isNullOrEmpty(component.getTooltip()))
|
||||||
|
{
|
||||||
|
final Rectangle intersectionRectangle = new Rectangle(component.getPreferredLocation(), component.getPreferredSize());
|
||||||
|
|
||||||
if (client != null && intersectionRectangle.contains(new Point(client.getMouseCanvasPosition().getX(),
|
// Move the intersection based on overlay position
|
||||||
client.getMouseCanvasPosition().getY())))
|
intersectionRectangle.translate(getBounds().x, getBounds().y);
|
||||||
{
|
|
||||||
tooltipManager.add(new Tooltip(box.getTooltip()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine which axis to reset/increase
|
// Move the intersection based on overlay "orientation"
|
||||||
if (vertical)
|
final Point transformed = OverlayUtil.transformPosition(getPosition(), intersectionRectangle.getSize());
|
||||||
{
|
intersectionRectangle.translate(transformed.x, transformed.y);
|
||||||
// Reset y if newbox reaches height limit
|
|
||||||
if (y + TOTAL_BOXSIZE < height)
|
if (intersectionRectangle.contains(mouse))
|
||||||
{
|
{
|
||||||
y += TOTAL_BOXSIZE;
|
tooltipManager.add(new Tooltip(component.getTooltip()));
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
y = 0;
|
|
||||||
x += TOTAL_BOXSIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Reset x if newbox reaches width limit
|
|
||||||
if (x + TOTAL_BOXSIZE < width)
|
|
||||||
{
|
|
||||||
x += TOTAL_BOXSIZE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = 0;
|
|
||||||
y += TOTAL_BOXSIZE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Dimension(width, height);
|
return dimension;
|
||||||
}
|
|
||||||
|
|
||||||
private static int getHeight(int infoBoxCount, int maxRow)
|
|
||||||
{
|
|
||||||
return maxRow == 0 ? TOTAL_BOXSIZE : (int) Math.ceil((double)infoBoxCount / maxRow) * TOTAL_BOXSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getWidth(int infoBoxCount, int maxRow)
|
|
||||||
{
|
|
||||||
return maxRow == 0 ? infoBoxCount * TOTAL_BOXSIZE : (maxRow > infoBoxCount ? infoBoxCount : maxRow) * TOTAL_BOXSIZE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user