Merge ImagePanelComponent with PanelComponent
- Remove ImagePanelComponent - Add LayoutableRenderableEntity that is RenderableEntity with preferred size - Add support to PanelComponent for rendering list of LayoutableRenderableEntity - Add support for aligning PanelComponent horizontally or vertically - Add ImageComponent to be used in PanelComponent - Make other components support new design Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.components;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Setter
|
||||
public class ImageComponent implements LayoutableRenderableEntity
|
||||
{
|
||||
private BufferedImage image;
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (image == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
graphics.drawImage(image, 0, -graphics.getFontMetrics().getHeight(), null);
|
||||
return new Dimension(image.getWidth(), image.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreferredSize(Dimension dimension)
|
||||
{
|
||||
// Just use image dimensions for now
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.components;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
public class ImagePanelComponent implements RenderableEntity
|
||||
{
|
||||
private static final int TOP_BORDER = 4;
|
||||
private static final int SIDE_BORDER = 4;
|
||||
private static final int BOTTOM_BORDER = 4;
|
||||
private static final int SEPARATOR = 1;
|
||||
|
||||
@Setter
|
||||
@Nullable
|
||||
private String title;
|
||||
|
||||
@Setter
|
||||
private Color titleColor = Color.WHITE;
|
||||
|
||||
@Setter
|
||||
private Color backgroundColor = BackgroundComponent.DEFAULT_BACKGROUND_COLOR;
|
||||
|
||||
@Getter
|
||||
private final List<BufferedImage> images = new ArrayList<>();
|
||||
|
||||
@Setter
|
||||
private Point position = new Point();
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final Dimension dimension = new Dimension();
|
||||
final FontMetrics metrics = graphics.getFontMetrics();
|
||||
|
||||
//Determine max height and width of images
|
||||
int maxImageHeight = 0;
|
||||
int imageWidth = 0;
|
||||
for (final BufferedImage image : images)
|
||||
{
|
||||
if (image.getHeight() > maxImageHeight)
|
||||
{
|
||||
maxImageHeight = image.getHeight();
|
||||
}
|
||||
imageWidth += image.getWidth() + SEPARATOR;
|
||||
}
|
||||
|
||||
int height = TOP_BORDER + (Strings.isNullOrEmpty(title) ? 0 : metrics.getHeight() + SEPARATOR)
|
||||
+ maxImageHeight + BOTTOM_BORDER;
|
||||
int width = Math.max(Strings.isNullOrEmpty(title) ? 0 : metrics.stringWidth(title), imageWidth) + SIDE_BORDER * 2;
|
||||
dimension.setSize(width, height);
|
||||
|
||||
if (dimension.height == TOP_BORDER + BOTTOM_BORDER)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int y = position.y + TOP_BORDER;
|
||||
if (!Strings.isNullOrEmpty(title))
|
||||
{
|
||||
// Calculate panel dimensions
|
||||
y += metrics.getHeight();
|
||||
}
|
||||
|
||||
// Render background
|
||||
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
||||
backgroundComponent.setBackgroundColor(backgroundColor);
|
||||
backgroundComponent.setRectangle(new Rectangle(position.x, position.y, dimension.width, dimension.height));
|
||||
backgroundComponent.render(graphics);
|
||||
|
||||
// Render title
|
||||
if (!Strings.isNullOrEmpty(title))
|
||||
{
|
||||
final TextComponent titleComponent = new TextComponent();
|
||||
titleComponent.setText(title);
|
||||
titleComponent.setColor(titleColor);
|
||||
titleComponent.setPosition(new Point(position.x + (width - metrics.stringWidth(title)) / 2, y));
|
||||
titleComponent.render(graphics);
|
||||
y += SEPARATOR;
|
||||
}
|
||||
|
||||
// Render all images
|
||||
int imageOffsetX = ((width - imageWidth) / 2);
|
||||
for (final BufferedImage image : images)
|
||||
{
|
||||
graphics.drawImage(image, imageOffsetX + ((imageWidth / images.size()) - image.getWidth()) / 2, y, null);
|
||||
imageOffsetX += image.getWidth() + SEPARATOR;
|
||||
}
|
||||
|
||||
return dimension;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.components;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
public interface LayoutableRenderableEntity extends RenderableEntity
|
||||
{
|
||||
void setPreferredSize(Dimension dimension);
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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.components;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Strings;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import lombok.Builder;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Builder
|
||||
public class LineComponent implements LayoutableRenderableEntity
|
||||
{
|
||||
private static final int SEPARATOR = 1;
|
||||
|
||||
private String left;
|
||||
private String right;
|
||||
|
||||
@Builder.Default
|
||||
private Color leftColor = Color.WHITE;
|
||||
|
||||
@Builder.Default
|
||||
private Color rightColor = Color.WHITE;
|
||||
|
||||
@Builder.Default
|
||||
private Dimension preferredSize = new Dimension();
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Prevent NPEs
|
||||
final String left = MoreObjects.firstNonNull(this.left, "");
|
||||
final String right = MoreObjects.firstNonNull(this.right, "");
|
||||
|
||||
final FontMetrics metrics = graphics.getFontMetrics();
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
final int leftFullWidth = getLineWidth(left, metrics);
|
||||
final int rightFullWidth = getLineWidth(right, metrics);
|
||||
|
||||
if (preferredSize.width < leftFullWidth + rightFullWidth)
|
||||
{
|
||||
int leftSmallWidth = preferredSize.width;
|
||||
int rightSmallWidth = 0;
|
||||
|
||||
if (!Strings.isNullOrEmpty(right))
|
||||
{
|
||||
rightSmallWidth = (preferredSize.width / 3);
|
||||
leftSmallWidth -= rightSmallWidth;
|
||||
}
|
||||
|
||||
final String[] leftSplitLines = lineBreakText(left, leftSmallWidth, metrics);
|
||||
final String[] rightSplitLines = lineBreakText(right, rightSmallWidth, metrics);
|
||||
|
||||
int lineCount = Math.max(leftSplitLines.length, rightSplitLines.length);
|
||||
|
||||
for (int i = 0; i < lineCount; i++)
|
||||
{
|
||||
String leftText = "";
|
||||
String rightText = "";
|
||||
|
||||
if (i < leftSplitLines.length)
|
||||
{
|
||||
leftText = leftSplitLines[i];
|
||||
}
|
||||
|
||||
if (i < rightSplitLines.length)
|
||||
{
|
||||
rightText = rightSplitLines[i];
|
||||
}
|
||||
|
||||
final TextComponent leftLineComponent = new TextComponent();
|
||||
leftLineComponent.setPosition(new Point(x, y));
|
||||
leftLineComponent.setText(leftText);
|
||||
leftLineComponent.setColor(leftColor);
|
||||
leftLineComponent.render(graphics);
|
||||
|
||||
final TextComponent rightLineComponent = new TextComponent();
|
||||
rightLineComponent.setPosition(new Point(x + leftSmallWidth + rightFullWidth - getLineWidth(rightText, metrics), y));
|
||||
rightLineComponent.setText(rightText);
|
||||
rightLineComponent.setColor(rightColor);
|
||||
rightLineComponent.render(graphics);
|
||||
y += metrics.getHeight() + SEPARATOR;
|
||||
}
|
||||
|
||||
return new Dimension(preferredSize.width, y);
|
||||
}
|
||||
|
||||
final TextComponent leftLineComponent = new TextComponent();
|
||||
leftLineComponent.setPosition(new Point(x, y));
|
||||
leftLineComponent.setText(left);
|
||||
leftLineComponent.setColor(leftColor);
|
||||
leftLineComponent.render(graphics);
|
||||
|
||||
final TextComponent rightLineComponent = new TextComponent();
|
||||
rightLineComponent.setPosition(new Point(x + preferredSize.width - getLineWidth(right, metrics), y));
|
||||
rightLineComponent.setText(right);
|
||||
rightLineComponent.setColor(rightColor);
|
||||
rightLineComponent.render(graphics);
|
||||
y += metrics.getHeight() + SEPARATOR;
|
||||
|
||||
return new Dimension(preferredSize.width, y);
|
||||
}
|
||||
|
||||
private static int getLineWidth(final String line, final FontMetrics metrics)
|
||||
{
|
||||
return metrics.stringWidth(TextComponent.textWithoutColTags(line));
|
||||
}
|
||||
|
||||
private static String[] lineBreakText(String text, int maxWidth, FontMetrics metrics)
|
||||
{
|
||||
final String[] words = text.split(" ");
|
||||
|
||||
if (words.length == 0)
|
||||
{
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
final StringBuilder wrapped = new StringBuilder(words[0]);
|
||||
int spaceLeft = maxWidth - metrics.stringWidth(wrapped.toString());
|
||||
|
||||
for (int i = 1; i < words.length; i++)
|
||||
{
|
||||
final String word = words[i];
|
||||
final int wordLen = metrics.stringWidth(word);
|
||||
final int spaceWidth = metrics.stringWidth(" ");
|
||||
|
||||
if (wordLen + spaceWidth > spaceLeft)
|
||||
{
|
||||
wrapped.append("\n").append(word);
|
||||
spaceLeft = maxWidth - wordLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapped.append(" ").append(word);
|
||||
spaceLeft -= spaceWidth + wordLen;
|
||||
}
|
||||
}
|
||||
|
||||
return wrapped.toString().split("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,78 +33,23 @@ import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Objects;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
public class PanelComponent implements RenderableEntity
|
||||
public class PanelComponent implements LayoutableRenderableEntity
|
||||
{
|
||||
public enum Orientation
|
||||
{
|
||||
HORIZONTAL,
|
||||
VERTICAL;
|
||||
}
|
||||
|
||||
private static final int TOP_BORDER = 4;
|
||||
private static final int LEFT_BORDER = 4;
|
||||
private static final int RIGHT_BORDER = 4;
|
||||
private static final int BOTTOM_BORDER = 4;
|
||||
private static final int SEPARATOR = 1;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class Line
|
||||
{
|
||||
private boolean wrapWords;
|
||||
private String left;
|
||||
private Color leftColor = Color.WHITE;
|
||||
private String right = "";
|
||||
private Color rightColor = Color.WHITE;
|
||||
|
||||
public Line(String left)
|
||||
{
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public Line(boolean wrapWords, String left)
|
||||
{
|
||||
this.wrapWords = wrapWords;
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public Line(String left, Color leftColor)
|
||||
{
|
||||
this.left = left;
|
||||
this.leftColor = leftColor;
|
||||
}
|
||||
|
||||
public Line(boolean wrapWords, String left, Color leftColor)
|
||||
{
|
||||
this.wrapWords = wrapWords;
|
||||
this.left = left;
|
||||
this.leftColor = leftColor;
|
||||
}
|
||||
|
||||
public Line(String left, String right)
|
||||
{
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public Line(boolean wrapWords, String left, String right)
|
||||
{
|
||||
this.wrapWords = wrapWords;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public Line(String left, Color leftColor, String right, Color rightColor)
|
||||
{
|
||||
this.left = left;
|
||||
this.leftColor = leftColor;
|
||||
this.right = right;
|
||||
this.rightColor = rightColor;
|
||||
}
|
||||
}
|
||||
|
||||
@Setter
|
||||
private String title;
|
||||
|
||||
@@ -117,152 +62,92 @@ public class PanelComponent implements RenderableEntity
|
||||
@Setter
|
||||
private Point position = new Point();
|
||||
|
||||
@Setter
|
||||
private Dimension preferredSize = new Dimension(129, 0);
|
||||
|
||||
@Getter
|
||||
private List<Line> lines = new ArrayList<>();
|
||||
private List<LayoutableRenderableEntity> children = new ArrayList<>();
|
||||
|
||||
@Setter
|
||||
private ProgressBarComponent progressBar;
|
||||
private Orientation orientation = Orientation.VERTICAL;
|
||||
|
||||
@Setter
|
||||
private int width = 129;
|
||||
private final Dimension savedChildrenSize = new Dimension();
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final FontMetrics metrics = graphics.getFontMetrics();
|
||||
|
||||
// Do word wrapping
|
||||
ListIterator<Line> iterator = lines.listIterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Line line = iterator.next();
|
||||
|
||||
if (line.wrapWords)
|
||||
{
|
||||
iterator.remove();
|
||||
|
||||
int maxWidth = width;
|
||||
if (line.right.length() > 0)
|
||||
{
|
||||
maxWidth /= 2;
|
||||
}
|
||||
maxWidth -= LEFT_BORDER + RIGHT_BORDER;
|
||||
|
||||
List<String> leftSplitLines = lineBreakText(line.getLeft(), maxWidth, metrics);
|
||||
List<String> rightSplitLines = lineBreakText(line.getRight(), maxWidth, metrics);
|
||||
|
||||
int lineCount = Math.max(leftSplitLines.size(), rightSplitLines.size());
|
||||
|
||||
for (int i = 0; i < lineCount; i++)
|
||||
{
|
||||
String left = "";
|
||||
String right = "";
|
||||
|
||||
if (i < leftSplitLines.size())
|
||||
{
|
||||
left = leftSplitLines.get(i);
|
||||
}
|
||||
|
||||
if (i < rightSplitLines.size())
|
||||
{
|
||||
right = rightSplitLines.get(i);
|
||||
}
|
||||
|
||||
iterator.add(new Line(false, left, line.getLeftColor(), right, line.getRightColor()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Dimension dimension = new Dimension();
|
||||
final int elementNumber = (Strings.isNullOrEmpty(title) ? 0 : 1) + lines.size() + (Objects.isNull(progressBar) ? 0 : 1);
|
||||
int height = elementNumber == 0 ? 0 :
|
||||
TOP_BORDER + (graphics.getFontMetrics().getHeight() * elementNumber)
|
||||
+ SEPARATOR * elementNumber + (Objects.isNull(progressBar) ? 0 : progressBar.getHeight() / 2)
|
||||
+ BOTTOM_BORDER;
|
||||
dimension.setSize(width, height);
|
||||
|
||||
if (dimension.height == 0)
|
||||
if (Strings.isNullOrEmpty(title) && children.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final FontMetrics metrics = graphics.getFontMetrics();
|
||||
|
||||
// Calculate panel dimensions
|
||||
int y = position.y + TOP_BORDER + metrics.getHeight();
|
||||
int width = preferredSize.width;
|
||||
int height = preferredSize.height;
|
||||
int x = LEFT_BORDER;
|
||||
int y = TOP_BORDER + metrics.getHeight();
|
||||
|
||||
// Set graphics offset at correct position
|
||||
graphics.translate(position.x, position.y);
|
||||
|
||||
// Render background
|
||||
final Dimension dimension = new Dimension(
|
||||
savedChildrenSize.width + RIGHT_BORDER,
|
||||
savedChildrenSize.height + BOTTOM_BORDER);
|
||||
|
||||
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
||||
backgroundComponent.setRectangle(new Rectangle(dimension));
|
||||
backgroundComponent.setBackgroundColor(backgroundColor);
|
||||
backgroundComponent.setRectangle(new Rectangle(position.x, position.y, dimension.width, dimension.height));
|
||||
backgroundComponent.render(graphics);
|
||||
|
||||
// Render title
|
||||
if (!Strings.isNullOrEmpty(title))
|
||||
{
|
||||
// Render title
|
||||
final TextComponent titleComponent = new TextComponent();
|
||||
titleComponent.setText(title);
|
||||
titleComponent.setColor(titleColor);
|
||||
titleComponent.setPosition(new Point(position.x + (width - metrics.stringWidth(title)) / 2, y));
|
||||
titleComponent.setPosition(new Point((dimension.width - metrics.stringWidth(title)) / 2, y));
|
||||
titleComponent.render(graphics);
|
||||
y += metrics.getHeight() + SEPARATOR;
|
||||
|
||||
// Move children a bit
|
||||
height = y += metrics.getHeight() + SEPARATOR;
|
||||
}
|
||||
|
||||
// Render all lines
|
||||
for (final Line line : lines)
|
||||
// Render all children
|
||||
final Dimension childPreferredSize = new Dimension(
|
||||
preferredSize.width - RIGHT_BORDER,
|
||||
preferredSize.height - BOTTOM_BORDER);
|
||||
|
||||
for (final LayoutableRenderableEntity child : children)
|
||||
{
|
||||
final TextComponent leftLineComponent = new TextComponent();
|
||||
leftLineComponent.setPosition(new Point(position.x + LEFT_BORDER, y));
|
||||
leftLineComponent.setText(line.getLeft());
|
||||
leftLineComponent.setColor(line.getLeftColor());
|
||||
leftLineComponent.render(graphics);
|
||||
child.setPreferredSize(childPreferredSize);
|
||||
graphics.translate(x, y);
|
||||
final Dimension childDimension = child.render(graphics);
|
||||
graphics.translate(-x, -y);
|
||||
|
||||
final TextComponent rightLineComponent = new TextComponent();
|
||||
rightLineComponent.setPosition(new Point(position.x + width - RIGHT_BORDER - metrics.stringWidth(TextComponent.textWithoutColTags(line.getRight())), y));
|
||||
rightLineComponent.setText(line.getRight());
|
||||
rightLineComponent.setColor(line.getRightColor());
|
||||
rightLineComponent.render(graphics);
|
||||
y += metrics.getHeight() + SEPARATOR;
|
||||
switch (orientation)
|
||||
{
|
||||
case VERTICAL:
|
||||
height = y += childDimension.height + SEPARATOR;
|
||||
width = Math.max(width, x + childDimension.width);
|
||||
break;
|
||||
case HORIZONTAL:
|
||||
width = x += childDimension.width + SEPARATOR;
|
||||
height = Math.max(height, y + childDimension.height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Render progress bar
|
||||
if (!Objects.isNull(progressBar))
|
||||
{
|
||||
progressBar.setWidth(width - LEFT_BORDER - RIGHT_BORDER);
|
||||
progressBar.setPosition(new Point(position.x + LEFT_BORDER, y - (metrics.getHeight() / 2)));
|
||||
progressBar.render(graphics);
|
||||
}
|
||||
// Reset the padding
|
||||
height -= metrics.getHeight();
|
||||
|
||||
// Save children size
|
||||
savedChildrenSize.setSize(width, height);
|
||||
|
||||
// Reset graphics position
|
||||
graphics.translate(-position.x, -position.y);
|
||||
return dimension;
|
||||
}
|
||||
|
||||
private List<String> lineBreakText(String text, int maxWidth, FontMetrics metrics)
|
||||
{
|
||||
List<String> lines = new ArrayList<>();
|
||||
|
||||
int pos = 0;
|
||||
String[] words = text.split(" ");
|
||||
String line = "";
|
||||
|
||||
while (pos < words.length)
|
||||
{
|
||||
String newLine = pos > 0 && !line.isEmpty()
|
||||
? line + " " + words[pos]
|
||||
: words[pos];
|
||||
int width = metrics.stringWidth(newLine);
|
||||
|
||||
if (width >= maxWidth)
|
||||
{
|
||||
lines.add(line);
|
||||
line = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
line = newLine;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
lines.add(line);
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,9 @@ import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.text.DecimalFormat;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class ProgressBarComponent
|
||||
public class ProgressBarComponent implements LayoutableRenderableEntity
|
||||
{
|
||||
@Setter
|
||||
private String text;
|
||||
@@ -54,20 +53,16 @@ public class ProgressBarComponent
|
||||
@Setter
|
||||
private Color fontColor = Color.WHITE;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int width = 140;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int height = 16;
|
||||
private Dimension preferredSize = new Dimension(129, 16);
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
FontMetrics metrics = graphics.getFontMetrics();
|
||||
|
||||
int barX = position.x;
|
||||
int barY = position.y;
|
||||
int barY = position.y - metrics.getHeight();
|
||||
String textToWrite;
|
||||
|
||||
if (Strings.isNullOrEmpty(text))
|
||||
@@ -80,6 +75,9 @@ public class ProgressBarComponent
|
||||
textToWrite = text;
|
||||
}
|
||||
|
||||
int width = preferredSize.width;
|
||||
int height = Math.max(preferredSize.height, 16);
|
||||
|
||||
int progressTextX = barX + (width - metrics.stringWidth(textToWrite)) / 2;
|
||||
int progressTextY = barY + ((height - metrics.getHeight()) / 2) + metrics.getAscent();
|
||||
|
||||
|
||||
@@ -60,13 +60,13 @@ public class TextComponent implements RenderableEntity
|
||||
|
||||
if (COL_TAG_PATTERN.matcher(text).find())
|
||||
{
|
||||
String[] parts = COL_TAG_PATTERN_W_LOOKAHEAD.split(text);
|
||||
final String[] parts = COL_TAG_PATTERN_W_LOOKAHEAD.split(text);
|
||||
int x = position.x;
|
||||
for (int i = 0; i < parts.length; i++)
|
||||
|
||||
for (String textSplitOnCol : parts)
|
||||
{
|
||||
String textSplitOnCol = parts[i];
|
||||
String textWithoutCol = textWithoutColTags(textSplitOnCol);
|
||||
String colColor = textSplitOnCol.substring(textSplitOnCol.indexOf("=") + 1, textSplitOnCol.indexOf(">"));
|
||||
final String textWithoutCol = textWithoutColTags(textSplitOnCol);
|
||||
final String colColor = textSplitOnCol.substring(textSplitOnCol.indexOf("=") + 1, textSplitOnCol.indexOf(">"));
|
||||
|
||||
// shadow
|
||||
graphics.setColor(Color.BLACK);
|
||||
@@ -89,6 +89,7 @@ public class TextComponent implements RenderableEntity
|
||||
graphics.setColor(color);
|
||||
graphics.drawString(text, position.x, position.y);
|
||||
}
|
||||
|
||||
return new Dimension(fontMetrics.stringWidth(text), fontMetrics.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user