Change InfoBoxOverlay to use PanelComponent

Instead of doing layouting by itself, use PanelComponent and newly added
support for component wrapping and disabling of background.

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
Tomas Slusny
2018-05-13 13:26:35 +02:00
parent 3130e0f254
commit bd487d4bbf
2 changed files with 74 additions and 91 deletions

View File

@@ -32,26 +32,34 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.Objects;
import lombok.Getter;
import lombok.Setter;
import net.runelite.client.ui.overlay.RenderableEntity;
@Setter
public class InfoBoxComponent implements RenderableEntity
public class InfoBoxComponent implements LayoutableRenderableEntity
{
private static final int BOX_SIZE = 35;
private static final int SEPARATOR = 2;
@Getter
private String tooltip;
@Getter
private Point preferredLocation = new Point();
private String text;
private Color color = Color.WHITE;
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
private Point position = new Point();
private BufferedImage image;
@Override
public Dimension render(Graphics2D graphics)
{
graphics.translate(preferredLocation.x, preferredLocation.y);
final FontMetrics metrics = graphics.getFontMetrics();
final Rectangle bounds = new Rectangle(position.x, position.y, BOX_SIZE, BOX_SIZE);
final int w = BOX_SIZE;
final int h = BOX_SIZE;
final Rectangle bounds = new Rectangle(w, h);
final BackgroundComponent backgroundComponent = new BackgroundComponent();
backgroundComponent.setBackgroundColor(backgroundColor);
backgroundComponent.setRectangle(bounds);
@@ -59,18 +67,30 @@ public class InfoBoxComponent implements RenderableEntity
if (Objects.nonNull(image))
{
graphics.drawImage(image,
position.x + (BOX_SIZE - image.getWidth()) / 2,
position.y + (BOX_SIZE - image.getHeight()) / 2, null);
graphics.drawImage(
image,
(w - image.getWidth()) / 2,
(h - image.getHeight()) / 2,
null);
}
final TextComponent textComponent = new TextComponent();
textComponent.setColor(color);
textComponent.setText(text);
textComponent.setPosition(new Point(
position.x + ((BOX_SIZE - metrics.stringWidth(text)) / 2),
position.y + BOX_SIZE - SEPARATOR));
textComponent.setPosition(new Point(((w - metrics.stringWidth(text)) / 2), h - SEPARATOR));
textComponent.render(graphics);
graphics.translate(-preferredLocation.x, -preferredLocation.y);
return bounds.getSize();
}
public Dimension getPreferredSize()
{
return new Dimension(BOX_SIZE, BOX_SIZE);
}
@Override
public void setPreferredSize(Dimension dimension)
{
// Just use infobox dimensions for now
}
}

View File

@@ -39,15 +39,14 @@ import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
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.TooltipManager;
public class InfoBoxOverlay extends Overlay
{
private static final int BOXSIZE = 35;
private static final int SEPARATOR = 2;
private static final int TOTAL_BOXSIZE = BOXSIZE + SEPARATOR;
private final PanelComponent panelComponent = new PanelComponent();
private final InfoBoxManager infoboxManager;
private final TooltipManager tooltipManager;
private final Provider<Client> clientProvider;
@@ -65,108 +64,72 @@ public class InfoBoxOverlay extends Overlay
this.clientProvider = clientProvider;
this.config = config;
setPosition(OverlayPosition.TOP_LEFT);
panelComponent.setBackgroundColor(null);
panelComponent.setBorder(new Rectangle());
panelComponent.setGap(new Point(2, 2));
}
@Override
public Dimension render(Graphics2D graphics)
{
List<InfoBox> infoBoxes = infoboxManager.getInfoBoxes();
final List<InfoBox> infoBoxes = infoboxManager.getInfoBoxes();
if (infoBoxes.isEmpty())
{
return null;
}
int wrap = config.infoBoxWrap();
int infoBoxCount = infoBoxes.size();
boolean vertical = config.infoBoxVertical();
panelComponent.getChildren().clear();
panelComponent.setWrapping(config.infoBoxWrap());
panelComponent.setOrientation(config.infoBoxVertical()
? PanelComponent.Orientation.VERTICAL
: PanelComponent.Orientation.HORIZONTAL);
int width, height;
if (!vertical)
infoBoxes.forEach(box ->
{
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();
infoBoxComponent.setColor(box.getTextColor());
infoBoxComponent.setImage(box.getImage());
infoBoxComponent.setText(box.getText());
infoBoxComponent.setPosition(new Point(x, y));
final Dimension infoBoxBounds = infoBoxComponent.render(graphics);
infoBoxComponent.setTooltip(box.getTooltip());
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);
intersectionRectangle.setLocation(getBounds().getLocation());
intersectionRectangle.translate(x, y);
final Point transformed = OverlayUtil.transformPosition(getPosition(), intersectionRectangle.getSize());
intersectionRectangle.translate(transformed.x, transformed.y);
if (child instanceof InfoBoxComponent)
{
final InfoBoxComponent component = (InfoBoxComponent) child;
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(),
client.getMouseCanvasPosition().getY())))
{
tooltipManager.add(new Tooltip(box.getTooltip()));
}
}
// Move the intersection based on overlay position
intersectionRectangle.translate(getBounds().x, getBounds().y);
// Determine which axis to reset/increase
if (vertical)
{
// Reset y if newbox reaches height limit
if (y + TOTAL_BOXSIZE < height)
{
y += TOTAL_BOXSIZE;
}
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;
// Move the intersection based on overlay "orientation"
final Point transformed = OverlayUtil.transformPosition(getPosition(), intersectionRectangle.getSize());
intersectionRectangle.translate(transformed.x, transformed.y);
if (intersectionRectangle.contains(mouse))
{
tooltipManager.add(new Tooltip(component.getTooltip()));
}
}
}
}
}
return new Dimension(width, height);
}
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;
return dimension;
}
}