/*
* This file is part of the Illarion project.
*
* Copyright © 2015 - Illarion e.V.
*
* Illarion is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Illarion is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
package illarion.client.graphics;
import illarion.common.types.DisplayCoordinate;
import illarion.common.types.Rectangle;
import org.illarion.engine.GameContainer;
import org.illarion.engine.graphic.Color;
import org.illarion.engine.graphic.Font;
import org.illarion.engine.graphic.Graphics;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* This is the characterName tag that is in special displayed above avatars.
*
* @author Martin Karing <nitram@illarion.org>
*/
public final class AvatarTextTag {
/**
* The color of the background pane that is displayed behind the characterName.
*/
private static final Color BACK_COLOR = new Color(0.f, 0.f, 0.f, 0.58f);
/**
* The space in pixels between the lines.
*/
private static final int LINE_SPACE = 0;
/**
* The color implementation that is used to render the characterName.
*/
@Nullable
private Color charNameColor;
/**
* The color of the health state of the character.
*/
@Nullable
private Color healthStateColor;
/**
* The height of the avatar that is applied as offset.
*/
private int avatarHeight;
/**
* The coordinates where the tag is supposed to be displayed.
*/
@Nullable
private DisplayCoordinate displayCoordinate;
/**
* The text displayed to show the health state of the character.
*/
@Nullable
private String healthState;
/**
* The name of the character that is displayed in this text.
*/
private String charName;
/**
* This flag is set {@code true} in case the dimensions got changed.
*/
private boolean dimensionsDirty;
/**
* The width of this tag. This value is generated once the characterName is set.
*/
private int width;
/**
* The height of this tag. This value is generated once the characterName is set.
*/
private int height;
/**
* The font used to draw the text tag.
*/
@Nonnull
private final Font font;
/**
* Default constructor.
*/
public AvatarTextTag() {
font = FontLoader.getInstance().getFont(FontLoader.SMALL_FONT);
}
/**
* Get the height of the characterName tag.
*
* @return the height of the characterName tag
*/
public int getHeight() {
return height;
}
/**
* Get the width of the characterName tag.
*
* @return the width of the characterName tag
*/
public int getWidth() {
return width;
}
/**
* Set the location on the screen where the tag is supposed to be displayed.
*
* @param coordinate the coordinate of the location on the screen
*/
public void setDisplayLocation(@Nonnull DisplayCoordinate coordinate) {
displayCoordinate = coordinate;
}
/**
* Set the color that is used to render the text that shows the character name.
*
* @param newColor the color that is used to render the characterName tag.
*/
public void setCharNameColor(@Nullable Color newColor) {
if ((newColor == null) || newColor.equals(charNameColor)) {
return;
}
charNameColor = newColor;
}
/**
* Set the color that is used to render the text that shows the health state of the character.
*
* @param newColor the color that is used to render the characterName tag.
*/
public void setHealthStateColor(@Nullable Color newColor) {
if ((newColor == null) || newColor.equals(healthStateColor)) {
return;
}
healthStateColor = newColor;
}
/**
* Set the offset of this characterName tag.
*
* @param avaHeight set the height of the avatar this tag is displayed upon
*/
public void setAvatarHeight(int avaHeight) {
if (avatarHeight == avaHeight) {
return;
}
avatarHeight = avaHeight;
}
/**
* Set a new character that is shown from now on in the avatar tag.
*
* @param newText the new name of the character that is displayed from now on
*/
public void setCharacterName(@Nonnull String newText) {
if (newText.equals(charName)) {
return;
}
charName = newText;
dimensionsDirty = true;
}
/**
* Set the text that is supposed to be displayed as health state indicator.
*
* @param newText the new health state text
*/
public void setHealthState(@Nullable String newText) {
if ((newText == null) && (healthState == null)) {
return;
}
if ((newText != null) && newText.equals(healthState)) {
return;
}
healthState = newText;
dimensionsDirty = true;
}
private void calculateTextLocations() {
if (!dimensionsDirty) {
return;
}
int nameWidth;
int nameHeight;
if (charName == null) {
nameWidth = 0;
nameHeight = 0;
} else {
nameWidth = font.getWidth(charName);
nameHeight = font.getLineHeight();
}
int healthWidth;
int healthHeight;
if (healthState == null) {
healthWidth = 0;
healthHeight = 0;
} else {
healthWidth = font.getWidth(healthState);
healthHeight = font.getLineHeight();
}
width = Math.max(healthWidth, nameWidth);
height = nameHeight + healthHeight;
if ((nameHeight > 0) && (healthHeight > 0)) {
height += LINE_SPACE;
}
charNameOffsetX = (width - nameWidth) / 2;
charNameOffsetY = 0;
healthStateOffsetX = (width - healthWidth) / 2;
healthStateOffsetY = nameHeight;
displayRect.set(displayCoordinate.getX() - (getWidth() / 2),
displayCoordinate.getY() - avatarHeight - getHeight() - 5,
width, height);
}
private int charNameOffsetX;
private int charNameOffsetY;
private int healthStateOffsetX;
private int healthStateOffsetY;
public boolean render(@Nonnull Graphics g) {
if ((charName == null) && (healthState == null)) {
return true;
}
if (!Camera.getInstance().requiresUpdate(displayRect)) {
return true;
}
g.drawRectangle(displayRect, BACK_COLOR);
if ((charName != null) && (charNameColor != null)) {
g.drawText(font, charName, charNameColor, displayRect.getX() + charNameOffsetX,
displayRect.getY() + charNameOffsetY);
}
if ((healthState != null) && (healthStateColor != null)) {
g.drawText(font, healthState, healthStateColor, displayRect.getX() + healthStateOffsetX,
displayRect.getY() + healthStateOffsetY);
}
return true;
}
private final Rectangle displayRect = new Rectangle();
private final Rectangle oldDisplayRect = new Rectangle();
@Nonnull
public Rectangle getDisplayRect() {
return displayRect;
}
public void update(@Nonnull GameContainer container, int delta) {
calculateTextLocations();
}
}