/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.ui.hud.widgets;
import java.awt.FontMetrics;
import java.awt.geom.Rectangle2D;
import org.jagatoo.datatypes.Enableable;
import org.jagatoo.opengl.enums.TextureFormat;
import org.jagatoo.util.image.ImageUtility;
import org.openmali.types.twodee.Dim2f;
import org.openmali.types.twodee.Dim2i;
import org.openmali.types.twodee.Rect2i;
import org.openmali.vecmath2.Colorf;
import org.xith3d.scenegraph.Texture2D;
import org.xith3d.scenegraph.Texture2DCanvas;
import org.xith3d.ui.hud.HUD;
import org.xith3d.ui.hud.base.AutoSizable;
import org.xith3d.ui.hud.base.BackgroundSettableWidget;
import org.xith3d.ui.hud.base.PaddingSettable;
import org.xith3d.ui.hud.base.TextWidget;
import org.xith3d.ui.hud.base.Widget;
import org.xith3d.ui.hud.utils.DrawUtils;
import org.xith3d.ui.hud.utils.HUDFont;
import org.xith3d.ui.hud.utils.HUDTextureUtils;
import org.xith3d.ui.hud.utils.MultilineText;
import org.xith3d.ui.hud.utils.TileMode;
import org.xith3d.ui.text2d.TextAlignment;
/**
* A Label displays text content. The new implementation is very highly optimized
* for both static and dynamic text.
*
* @author Marvin Froehlich (aka Qudus)
*/
public class Label extends BackgroundSettableWidget implements TextWidget, PaddingSettable, Enableable, AutoSizable
{
/**
* This class is used to describe a (set of) Label Widget(s).
* You can pass it to the Label constructor.
* Modifications on the used instance after creating the Label Widget
* won't have any effect.
*
* @author Marvin Froehlich (aka Qudus)
*/
public static class Description extends Widget.DescriptionBase
{
private Colorf backgroundColor;
private Texture2D backgroundTexture;
private TextAlignment alignment;
private HUDFont font;
private HUDFont font_disabled;
private Colorf fontColor;
private Colorf fontColor_disabled;
/**
* @return the background texture of this label
*/
public final Texture2D getBackgroundTexture()
{
return ( backgroundTexture );
}
/**
* Sets the background texture of this label
*
* @param texture the texture to use
*/
public void setBackgroundTexture( Texture2D texture )
{
backgroundTexture = texture;
}
/**
* Sets the background color of this label
*
* @param color the color to use
*/
public void setBackgroundColor( Colorf color )
{
backgroundColor = color;
}
/**
* @return the background color of this label
*/
public Colorf getBackgroundColor()
{
return ( backgroundColor );
}
/**
* Sets the background texture of this label
*
* @param texture the texture resource to use
*/
public void setBackgroundTexture( String texture )
{
if ( texture != null )
setBackgroundTexture( HUDTextureUtils.getTexture( texture, true ) );
else
setBackgroundTexture( (Texture2D)null );
}
/**
* Sets the horizontal and vertical alignment of the text
*/
public void setAlignment( TextAlignment alignment )
{
this.alignment = alignment;
}
/**
* @return the horizontal and vertical alignment of the text
*/
public TextAlignment getAlignment()
{
return ( alignment );
}
/**
* Sets the new Font to be used
*
* @param font the new Font
* @param disabled
*/
public void setFont( HUDFont font, boolean disabled )
{
if ( disabled )
this.font_disabled = font;
else
this.font = font;
}
/**
* @return the used Font
*/
public HUDFont getFont( boolean disabled )
{
if ( disabled )
return ( font_disabled );
return ( font );
}
/**
* Sets the new color to be used
*
* @param color the new color
* @param disabled
*/
public void setFontColor( Colorf color, boolean disabled )
{
if ( disabled )
this.fontColor_disabled = color;
else
this.fontColor = color;
}
/**
* @return the used color
*/
public Colorf getFontColor( boolean disabled )
{
if ( disabled )
{
if ( fontColor_disabled == null )
this.fontColor_disabled = HUD.getTheme().getLabelDescription().getFontColor( true );
return ( fontColor_disabled );
}
return ( fontColor );
}
public static HUDFont deriveDisabledFont( HUDFont enabledFont )
{
return ( HUDFont.getFont( enabledFont.getName(), enabledFont.getStyle().makeItalic(), enabledFont.getSize() ) );
}
/**
* Clon-Constructor
*
* @param desc the original to clone
*/
public void set( Description desc )
{
this.backgroundTexture = desc.backgroundTexture;
this.backgroundColor = desc.backgroundColor;
this.alignment = desc.alignment;
this.font = desc.font;
this.font_disabled = desc.font_disabled;
this.fontColor = desc.fontColor;
this.fontColor_disabled = desc.fontColor_disabled;
}
/**
* @return a clone of this instance
*/
@Override
public Description clone()
{
return ( new Description( this ) );
}
/**
* Clon-Constructor
*
* @param desc the original to clone
*/
protected Description( Description desc )
{
this.set( desc );
}
/**
* Creates a new Label.Description.
*
* @param backgroundColor
* @param backgroundTexture the background texture
* @param font_enabled the Font to be used for the text
* @param font_disabled the Font to be used for the text
* @param color_enabled the color to be used
* @param color_disabled the color to be used
* @param alignment the horizontal and vertical alignment
*/
public Description( Colorf backgroundColor, Texture2D backgroundTexture, HUDFont font_enabled, HUDFont font_disabled, Colorf color_enabled, Colorf color_disabled, TextAlignment alignment )
{
this.backgroundColor = backgroundColor;
this.backgroundTexture = backgroundTexture;
if ( font_enabled == null )
this.font = HUD.getTheme().getFont( false );
else
this.font = font_enabled;
if ( font_disabled == null )
this.font_disabled = deriveDisabledFont( this.font );
else
this.font_disabled = font_disabled;
if ( color_enabled == null )
this.fontColor = HUD.getTheme().getFontColor( false );
else
this.fontColor = color_enabled;
this.fontColor_disabled = color_disabled;
if ( alignment == null )
this.alignment = TextAlignment.TOP_LEFT;
else
this.alignment = alignment;
}
/**
* Creates a new Label.Description.
*
* @param backgroundColor
* @param backgroundTexture the background texture
* @param font_enabled the Font to be used for the text
* @param font_disabled the Font to be used for the text
* @param color_enabled the color to be used
* @param color_disabled the color to be used
* @param alignment the horizontal and vertical alignment
*/
public Description( Colorf backgroundColor, String backgroundTexture, HUDFont font_enabled, HUDFont font_disabled, Colorf color_enabled, Colorf color_disabled, TextAlignment alignment )
{
this( backgroundColor, HUDTextureUtils.getTextureOrNull( backgroundTexture, true ), font_enabled, font_disabled, color_enabled, color_disabled, alignment );
}
}
protected static final boolean DEFAULT_HEAVYWEIGHT = false;
private boolean autoSize = false;
private int paddingBottom = 0;
private int paddingRight = 0;
private int paddingTop = 0;
private int paddingLeft = 0;
private int textOffsetX = 0;
private int textOffsetY = 0;
private TextAlignment alignment;
private String text;
private final MultilineText multiLineText = new MultilineText();
private HUDFont font;
private HUDFont font_disabled;
private Colorf fontColor;
private Colorf fontColor_disabled;
private Texture2D icon = null;
private int iconGap = 2;
private boolean enabled = true;
/**
* {@inheritDoc}
*/
public boolean setPadding( int paddingBottom, int paddingRight, int paddingTop, int paddingLeft )
{
if ( ( this.paddingBottom == paddingBottom ) &&
( this.paddingRight == paddingRight ) &&
( this.paddingTop == paddingTop ) &&
( this.paddingLeft == paddingLeft ) )
{
return ( false );
}
this.paddingBottom = paddingBottom;
this.paddingRight = paddingRight;
this.paddingTop = paddingTop;
this.paddingLeft = paddingLeft;
this.multiLineText.setPositionDirty();
updateSizeFactors();
setTextureDirty();
return ( true );
}
/**
* {@inheritDoc}
*/
public final boolean setPadding( int padding )
{
return ( setPadding( padding, padding, padding, padding ) );
}
/**
* {@inheritDoc}
*/
public final int getPaddingBottom()
{
return ( paddingBottom );
}
/**
* {@inheritDoc}
*/
public final int getPaddingRight()
{
return ( paddingRight );
}
/**
* {@inheritDoc}
*/
public final int getPaddingTop()
{
return ( paddingTop );
}
/**
* {@inheritDoc}
*/
public final int getPaddingLeft()
{
return ( paddingLeft );
}
/**
* Enables or disables auto-sizing.<br>
* If enabled, the Label's size will always be the minimal size to wrap
* the whole text content.
*
* @param enabled
*/
public void setAutoSizeEnabled( boolean enabled )
{
this.autoSize = enabled;
}
/**
* @return if auto-sizing is enabled.<br>
* If enabled, the Label's size will always be the minimal size to wrap
* the whole text content.
*/
public final boolean isAutoSizeEnabled()
{
return ( autoSize );
}
protected void updateText()
{
if ( autoSize && isInitialized() && ( getHUD() != null ) )
{
setMinimalSize();
}
setTextureDirty();
}
/**
* {@inheritDoc}
*/
public void setText( String text )
{
if ( text == null )
throw new NullPointerException( "text must not be null" );
if ( ( this.text == null ) || !this.text.equals( text ) )
{
this.text = text;
updateText();
this.multiLineText.setText( getDisplayedText() );
}
}
/**
* Sets the text from a float.
*
* @param prefix null for no prefix
* @param value the value
* @param decimalSep '\0' for no decimal places
* @param decPlaces
* @param postfix null for no postfix
*/
public void setText( String prefix, float value, char decimalSep, int decPlaces, String postfix )
{
String text;
if ( ( decimalSep == '\0' ) || ( decPlaces <= 0 ) )
{
text = String.valueOf( (int)value );
}
else if ( decimalSep == '.' )
{
float p = (float)Math.pow( 10, decPlaces );
text = String.valueOf( (int)( value * p ) / p );
}
else
{
float p = (float)Math.pow( 10, decPlaces );
text = String.valueOf( (int)value ) + decimalSep + String.valueOf( (int)( ( value - (int)value ) * p ) );
}
if ( ( prefix == null ) || ( prefix.length() == 0 ) )
{
if ( ( postfix == null ) || ( postfix.length() == 0 ) )
setText( text );
else
setText( text + postfix );
}
else if ( ( postfix == null ) || ( postfix.length() == 0 ) )
{
setText( prefix + text );
}
else
{
setText( prefix + text + postfix );
}
}
/**
* Sets the text from a float.<br>
* The value will be formatted with a dot ('.') as decimal separator and 2 decimal places.
*
* @param value the value
*/
public final void setText( float value )
{
setText( null, value, '.', 2, null );
}
/**
* {@inheritDoc}
*/
public String getText()
{
return ( text );
}
/**
* @return the text, that is actually displayed on the Label.
*/
protected String getDisplayedText()
{
return ( getText() );
}
/**
* Sets the horizontal and vertical alignment of the text
*/
public void setAlignment( TextAlignment alignment )
{
if ( this.alignment != alignment )
{
this.alignment = alignment;
this.multiLineText.setPositionDirty();
setTextureDirty();
}
}
/**
* @return the horizontal and vertical alignment of the text
*/
public TextAlignment getAlignment()
{
return ( alignment );
}
/**
* {@inheritDoc}
*/
public void setFont( HUDFont font )
{
this.font = font;
if ( isEnabled() )
{
this.multiLineText.setPositionDirty();
setTextureDirty();
}
}
/**
* {@inheritDoc}
*/
public final HUDFont getFont()
{
return ( font );
}
/**
* {@inheritDoc}
*/
public void setFontDisabled( HUDFont font )
{
this.font_disabled = font;
if ( !isEnabled() )
{
this.multiLineText.setPositionDirty();
setTextureDirty();
}
}
/**
* {@inheritDoc}
*/
public final HUDFont getFontDisabled()
{
return ( font_disabled );
}
protected HUDFont getFont( boolean disabled )
{
if ( disabled )
return ( getFontDisabled() );
return ( getFont() );
}
/**
* {@inheritDoc}
*/
public void setFontColor( Colorf color )
{
if ( !this.fontColor.equals( color ) )
{
this.fontColor = color;
if ( isEnabled() )
{
setTextureDirty();
}
}
}
/**
* {@inheritDoc}
*/
public final Colorf getFontColor()
{
return ( fontColor.getReadOnly() );
}
/**
* {@inheritDoc}
*/
public void setFontColorDisabled( Colorf color )
{
if ( !this.fontColor_disabled.equals( color ) )
{
this.fontColor_disabled = color;
if ( !isEnabled() )
{
setTextureDirty();
}
}
}
/**
* {@inheritDoc}
*/
public final Colorf getFontColorDisabled()
{
return ( fontColor_disabled.getReadOnly() );
}
protected Colorf getFontColor( boolean disabled )
{
if ( disabled )
return ( getFontColorDisabled() );
return ( getFontColor() );
}
/**
* Sets the icon for this Label.
*
* @param icon
*/
public void setIcon( Texture2D icon )
{
if ( this.icon == icon )
return;
this.icon = icon;
setTextureDirty();
}
/**
* Sets the icon for this Label.
*
* @param icon
*/
public final void setIcon( String icon )
{
setIcon( HUDTextureUtils.getTextureOrNull( icon, true ) );
}
/**
* Gets the icon of this Label.
*
* @return the icon of this Label.
*/
public final Texture2D getIcon()
{
return ( icon );
}
/**
* Sets the gap between the icon and the text.
*
* @param gap the gap in pixels
*/
public void setIconGap( int gap )
{
if ( this.iconGap == gap )
return;
this.iconGap = gap;
setTextureDirty();
}
/**
* Gets the gap between the icon and the text.
*
* @return gap the gap in pixels
*/
public final int getIconGap()
{
return ( iconGap );
}
/**
*
* @param enabled
*/
protected void setEnabledImpl( boolean enabled )
{
setTextureDirty();
}
/**
* {@inheritDoc}
*/
public final void setEnabled( boolean enabled )
{
if ( enabled == this.enabled )
return;
this.enabled = enabled;
setEnabledImpl( enabled );
}
/**
* {@inheritDoc}
*/
public final boolean isEnabled()
{
return ( enabled );
}
/**
* {@inheritDoc}
*/
@Override
protected void onSizeChanged( float oldWidth, float oldHeight, float newWidth, float newHeight )
{
super.onSizeChanged( oldWidth, oldHeight, newWidth, newHeight );
multiLineText.setPositionDirty();
if ( getHUD() != null )
{
updateTranslation();
}
}
@Override
protected void onAttachedToHUD( HUD hud )
{
super.onAttachedToHUD( hud );
}
/**
* Calculates the minimum Size needed to contain the whole caption.
*/
public <Dim2f_ extends Dim2f> Dim2f_ getMinimalSize( Dim2f_ buffer )
{
double totalWidth = 0.0;
double totalHeight = 0.0;
if ( ( multiLineText.getNumLines() > 1 ) || ( ( multiLineText.getNumLines() == 1 ) && ( multiLineText.getLine( 0 ).length() > 0 ) ) )
{
HUDFont fnt = isEnabled() ? font : font_disabled;
FontMetrics metrics = fnt.getFontMetrics( getHUD() );
for ( int i = 0; i < multiLineText.getNumLines(); i++ )
{
Rectangle2D bounds = metrics.getStringBounds( multiLineText.getLine( i ), null );
totalWidth = Math.max( totalWidth, bounds.getWidth() );
totalHeight += bounds.getHeight();
}
if ( getIcon() != null )
{
totalWidth += getIconGap();
}
}
if ( getIcon() != null )
{
totalWidth += HUDTextureUtils.getTextureWidth( getIcon() );
totalHeight = Math.max( totalHeight, (double)HUDTextureUtils.getTextureHeight( getIcon() ) );
}
totalWidth += getPaddingLeft() + getPaddingRight();
totalHeight += getPaddingTop() + getPaddingBottom();
if ( getBorder() != null )
{
totalWidth += getBorder().getLeftWidth() + getBorder().getRightWidth();
totalHeight += getBorder().getTopHeight() + getBorder().getBottomHeight();
}
if ( getHUD() != null )
getSizePixels2HUD_( (int)totalWidth, (int)totalHeight, buffer );
else
buffer.set( (int)totalWidth, (int)totalHeight );
return ( buffer );
}
/**
* Resizes this Label to the minimum Size needed to contain the whole caption.
*/
public final void setMinimalSize()
{
//if ( getHUD() == null )
// throw new IllegalStateException( "You cannot call this method, if the Widget is not added to the HUD." );
final Dim2f newSize = Dim2f.fromPool();
getMinimalSize( newSize );
setSize( newSize );
Dim2f.toPool( newSize );
}
/**
* Gets the Label's minimum width.
*
* @return the minimum width.
*/
public final float getMinimalWidth()
{
Dim2f buffer = Dim2f.fromPool();
getMinimalSize( buffer );
float minWidth = buffer.getWidth();
Dim2f.toPool( buffer );
return ( minWidth );
}
/**
* Gets the Label's minimum height.
*
* @return the minimum height.
*/
public final float getMinimalHeight()
{
Dim2f buffer = Dim2f.fromPool();
getMinimalSize( buffer );
float minHeight = buffer.getHeight();
Dim2f.toPool( buffer );
return ( minHeight );
}
public void setTextOffset( int textOffsetX, int textOffsetY )
{
if ( ( textOffsetX == this.textOffsetX ) && ( textOffsetY == this.textOffsetY ) )
return;
this.textOffsetX = textOffsetX;
this.textOffsetY = textOffsetY;
setTextureDirty();
}
public int getTextOffsetX()
{
return ( textOffsetX );
}
public int getTextOffsetY()
{
return ( textOffsetY );
}
private static Texture2D textImage = null;
private static Texture2DCanvas textGraphics = null;
private static Rect2i currClip = new Rect2i();
protected void prepareText( MultilineText multiLineText, Texture2DCanvas texCanvas, int width, int height )
{
if ( isEnabled() )
{
texCanvas.setColor( getFontColor() );
texCanvas.setFont( getFont().getAWTFont( getHUD() ) );
}
else
{
texCanvas.setColor( getFontColorDisabled() );
texCanvas.setFont( getFontDisabled().getAWTFont( getHUD() ) );
}
int padLeft = getContentLeftPX();
int padTop = getContentTopPX();
Dim2i tmp = Dim2i.fromPool();
getSizeHUD2Pixels_( getWidth(), getHeight(), tmp );
int padRight = tmp.getWidth() - getContentLeftPX() - getContentWidthPX();
int padBottom = tmp.getHeight() - getContentTopPX() - getContentHeightPX();
Dim2i.toPool( tmp );
multiLineText.update( texCanvas, width, height, padLeft, padRight, padTop, padBottom, getAlignment() );
}
protected void drawIcon( Texture2D icon, Texture2DCanvas texCanvas, int x, int y )
{
DrawUtils.drawImage( null, icon, null, texCanvas, x, y, HUDTextureUtils.getTextureWidth( icon ), HUDTextureUtils.getTextureHeight( icon ) );
}
/**
* Draws the text on the Label.
*
* @param multiLineText
* @param texCanvas
* @param offsetX
* @param offsetY
* @param width
* @param height
*/
protected void drawText( MultilineText multiLineText, Texture2DCanvas texCanvas, int offsetX, int offsetY, int width, int height )
{
offsetX += getTextOffsetX();
offsetY += getTextOffsetY();
int textX0 = multiLineText.getMinPosX();
int textY0 = multiLineText.getPosY( 0 ) + multiLineText.getLineOffsetY( 0 );
int textTotalWidth = multiLineText.getTotalWidth();
int textTotalHeight = multiLineText.getTotalHeight();
texCanvas.getClip( currClip );
/*
* TODO: remove the "if (false &&)"
*
* As long as DirectbufferedImage drawing is so slow, we can savely use the workaround always.
* The workaround will always be faster. But this should be fixed one day in DirectBufferedImage resp. in JDK.
*/
if ( false && currClip.covers( offsetX + textX0, offsetY + textY0, textTotalWidth, textTotalHeight ) )
{
texCanvas.setClip( (Rect2i)null );
for ( int i = 0; i < multiLineText.getNumLines(); i++ )
{
texCanvas.drawString( multiLineText.getLine( i ), offsetX + multiLineText.getPosX( i ), offsetY + multiLineText.getPosY( i ), multiLineText.getWidth( i ), multiLineText.getHeight( i ) );
}
texCanvas.setClip( currClip );
}
else
{
// Since clipping doesn't work without corrupting the text on a DirectBufferedImage
// doe to a bug in all JDKs (at least it looks like this),
// we have to use this ugly workaround.
//System.out.println( multiLineText.getLine( 0 ) + ", " + currClip + ", " + ( offsetX + textX0 ) + ", " + ( offsetY + textY0 ) + ", " + textTotalWidth + ", " + textTotalHeight );
if ( ( textImage == null ) || ( textImage.getWidth() < textX0 + textTotalWidth ) || ( textImage.getHeight() < textTotalHeight ) )
{
int w = ImageUtility.roundUpPower2( textX0 + textTotalWidth );
int h = ImageUtility.roundUpPower2( textTotalHeight );
textImage = Texture2D.createDrawTexture( TextureFormat.RGBA, w, h, false );
textGraphics = textImage.getTextureCanvas();
}
textGraphics.getImage().clear( Colorf.BLACK_TRANSPARENT );
textGraphics.setColor( texCanvas.getColor() );
textGraphics.setFont( texCanvas.getFont() );
for ( int i = 0; i < multiLineText.getNumLines(); i++ )
{
textGraphics.drawString( multiLineText.getLine( i ), multiLineText.getPosX( i ), multiLineText.getPosY( i ) - textY0 );
}
texCanvas.getImage().drawImage( textImage.getImage0(), 0, 0, textX0 + textTotalWidth, textTotalHeight, offsetX, offsetY + textY0 );
}
}
@Override
protected void drawWidget( Texture2DCanvas texCanvas, int offsetX, int offsetY, int width, int height, boolean drawsSelf )
{
prepareText( multiLineText, texCanvas, width, height );
Texture2D icon = getIcon();
if ( ( multiLineText.getNumLines() > 1 ) || ( ( multiLineText.getNumLines() == 1 ) && ( multiLineText.getLine( 0 ).length() > 0 ) ) )
{
int orgTextOffsetX = textOffsetX;
int orgTextOffsetY = textOffsetY;
if ( icon != null )
{
int iconWidth = HUDTextureUtils.getTextureWidth( icon );
int iconHeight = HUDTextureUtils.getTextureHeight( icon );
int gap = getIconGap();
if ( getAlignment().isLeftAligned() )
textOffsetX += iconWidth + gap;
else if ( getAlignment().isHCenterAligned() )
textOffsetX += ( iconWidth + gap ) / 2;
int textX0 = multiLineText.getMinPosX();
int textY0 = multiLineText.getPosY( 0 ) + multiLineText.getLineOffsetY( 0 );
int textTotalHeight = multiLineText.getTotalHeight();
if ( iconHeight > textTotalHeight )
{
if ( getAlignment().isTopAligned() )
textOffsetY += ( iconHeight - textTotalHeight ) / 2;
else if ( getAlignment().isBottomAligned() )
textOffsetY -= ( iconHeight - textTotalHeight ) / 2;
}
int y = offsetY + textOffsetY + textY0 + ( ( textTotalHeight - iconHeight ) / 2 );
switch ( getAlignment() )
{
case TOP_LEFT:
drawIcon( icon, texCanvas, offsetX, y );
break;
case TOP_CENTER:
drawIcon( icon, texCanvas, offsetX + textX0 - ( iconWidth + gap ) / 2, y );
break;
case TOP_RIGHT:
drawIcon( icon, texCanvas, offsetX + textX0 - ( iconWidth + gap ), y );
break;
case CENTER_LEFT:
drawIcon( icon, texCanvas, offsetX, y );
break;
case CENTER_CENTER:
drawIcon( icon, texCanvas, offsetX + textX0 - ( iconWidth + gap ) / 2, y );
break;
case CENTER_RIGHT:
drawIcon( icon, texCanvas, offsetX + textX0 - ( iconWidth + gap ), y );
break;
case BOTTOM_LEFT:
drawIcon( icon, texCanvas, offsetX, y );
break;
case BOTTOM_CENTER:
drawIcon( icon, texCanvas, offsetX + textX0 - ( iconWidth + gap ) / 2, y );
break;
case BOTTOM_RIGHT:
drawIcon( icon, texCanvas, offsetX + textX0 - ( iconWidth + gap ), y );
break;
}
}
drawText( multiLineText, texCanvas, offsetX, offsetY, width, height );
if ( icon != null )
{
textOffsetX = orgTextOffsetX;
textOffsetY = orgTextOffsetY;
}
}
else if ( icon != null )
{
int iconWidth = HUDTextureUtils.getTextureWidth( icon );
int iconHeight = HUDTextureUtils.getTextureHeight( icon );
switch ( getAlignment() )
{
case TOP_LEFT:
drawIcon( icon, texCanvas, offsetX, offsetY );
break;
case TOP_CENTER:
drawIcon( icon, texCanvas, offsetX + ( width - iconWidth ) / 2, offsetY );
break;
case TOP_RIGHT:
drawIcon( icon, texCanvas, offsetX + width - iconWidth, offsetY );
break;
case CENTER_LEFT:
drawIcon( icon, texCanvas, offsetX, offsetY + ( height - iconHeight ) / 2 );
break;
case CENTER_CENTER:
drawIcon( icon, texCanvas, offsetX + ( width - iconWidth ) / 2, offsetY + ( height - iconHeight ) / 2 );
break;
case CENTER_RIGHT:
drawIcon( icon, texCanvas, offsetX + width - iconWidth, offsetY + ( height - iconHeight ) / 2 );
break;
case BOTTOM_LEFT:
drawIcon( icon, texCanvas, offsetX, offsetY + height - iconHeight );
break;
case BOTTOM_CENTER:
drawIcon( icon, texCanvas, offsetX + ( width - iconWidth ) / 2, offsetY + height - iconHeight );
break;
case BOTTOM_RIGHT:
drawIcon( icon, texCanvas, offsetX + width - iconWidth, offsetY + height - iconHeight );
break;
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected void initSize()
{
if ( autoSize )
{
setMinimalSize();
}
}
/**
* {@inheritDoc}
*/
@Override
protected void init()
{
/*
if ( autoSize )
{
setMinimalSize();
}
*/
updateTranslation();
setTransparency( getTransparency() );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param isHeavyWeight
* @param hasWidgetAssembler
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font_enabled
* @param font_disabled
* @param fontColor_enabled
* @param fontColor_disabled
* @param alignment
* @param backgroundColor
* @param backgroundTexture
*/
protected Label( boolean isHeavyWeight, boolean hasWidgetAssembler, float width, float height, String text, HUDFont font_enabled, HUDFont font_disabled, Colorf fontColor_enabled, Colorf fontColor_disabled, TextAlignment alignment, Colorf backgroundColor, Texture2D backgroundTexture )
{
super( isHeavyWeight, hasWidgetAssembler, Math.max( 0f, width ), Math.max( 0f, height ), backgroundColor, backgroundTexture, TileMode.STRETCH );
if ( text == null )
throw new NullPointerException( "text must not be null" );
this.autoSize = ( ( width <= 0f ) || ( height <= 0f ) );
this.alignment = alignment;
if ( font_enabled == null )
this.font = HUD.getTheme().getFont( false );
else
this.font = font_enabled;
if ( font_disabled == null )
this.font_disabled = HUD.getTheme().getFont( true );
else
this.font_disabled = font_disabled;
if ( fontColor_enabled == null )
this.fontColor = HUD.getTheme().getFontColor( false );
else
this.fontColor = fontColor_enabled;
if ( fontColor_disabled == null )
this.fontColor_disabled = HUD.getTheme().getFontColor( true );
else
this.fontColor_disabled = fontColor_disabled;
this.setText( text );
this.setFocussable( false );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font_enabled
* @param font_disabled
* @param fontColor_enabled
* @param fontColor_disabled
* @param alignment
* @param backgroundColor
* @param backgroundTexture
*/
public Label( boolean isHeavyWeight, float width, float height, String text, HUDFont font_enabled, HUDFont font_disabled, Colorf fontColor_enabled, Colorf fontColor_disabled, TextAlignment alignment, Colorf backgroundColor, Texture2D backgroundTexture )
{
this( isHeavyWeight, false, width, height, text, font_enabled, font_disabled, fontColor_enabled, fontColor_disabled, alignment, backgroundColor, backgroundTexture );
}
private static final Description ld( Description desc )
{
if ( desc == null )
return ( HUD.getTheme().getLabelDescription() );
return ( desc );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param isHeavyWeight
* @param hasWidgetAssembler
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param labelDesc a LabelDescription instance holding information about font, color, alignment and background-texture
*/
protected Label( boolean isHeavyWeight, boolean hasWidgetAssembler, float width, float height, String text, Description labelDesc )
{
this( isHeavyWeight, hasWidgetAssembler, width, height, text,
ld( labelDesc ).getFont( false ), ld( labelDesc ).getFont( true ),
ld( labelDesc ).getFontColor( false ), ld( labelDesc ).getFontColor( true ),
ld( labelDesc ).getAlignment(),
ld( labelDesc ).getBackgroundColor(), ld( labelDesc ).getBackgroundTexture()
);
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param labelDesc a LabelDescription instance holding information about font, color, alignment and background-texture
*/
public Label( boolean isHeavyWeight, float width, float height, String text, Description labelDesc )
{
this( isHeavyWeight, width, height, text,
ld( labelDesc ).getFont( false ), ld( labelDesc ).getFont( true ),
ld( labelDesc ).getFontColor( false ), ld( labelDesc ).getFontColor( true ),
ld( labelDesc ).getAlignment(),
ld( labelDesc ).getBackgroundColor(), ld( labelDesc ).getBackgroundTexture()
);
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
* @param color the color to be used
* @param alignment the horizontal and vertical alignment
*/
public Label( boolean isHeavyWeight, float width, float height, String text, HUDFont font, Colorf color, TextAlignment alignment )
{
this( isHeavyWeight, width, height, text,
font, ( font == null ) ? Label.Description.deriveDisabledFont( HUD.getTheme().getFont( false ) ) : Label.Description.deriveDisabledFont( font ),
color, null,
alignment,
null, null
);
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param alignment the horizontal and vertical alignment
*/
public Label( boolean isHeavyWeight, float width, float height, String text, TextAlignment alignment )
{
this( isHeavyWeight, width, height, text, null, null, alignment );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param color the color to be used
* @param alignment the horizontal and vertical alignment
*/
public Label( boolean isHeavyWeight, float width, float height, String text, Colorf color, TextAlignment alignment )
{
this( isHeavyWeight, width, height, text, null, color, alignment );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
* @param color the color to be used
*/
public Label( boolean isHeavyWeight, float width, float height, String text, HUDFont font, Colorf color )
{
this( isHeavyWeight, width, height, text, font, color, TextAlignment.TOP_LEFT );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param color the color to be used
*/
public Label( boolean isHeavyWeight, float width, float height, String text, Colorf color )
{
this( isHeavyWeight, width, height, text, null, color, TextAlignment.TOP_LEFT );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
*/
public Label( boolean isHeavyWeight, float width, float height, String text, HUDFont font )
{
this( isHeavyWeight, width, height, text, font, null, TextAlignment.TOP_LEFT );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
* @param alignment the horizontal and vertical alignment
*/
public Label( boolean isHeavyWeight, float width, float height, String text, HUDFont font, TextAlignment alignment )
{
this( isHeavyWeight, width, height, text, font, null, alignment );
}
/**
* Creates a new Label with the given width and height and no text initially.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
*/
public Label( boolean isHeavyWeight, float width, float height )
{
this( isHeavyWeight, width, height, "", (HUDFont)null, (Colorf)null );
}
/**
* Creates a new Label with the given width and height and no text initially.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
*/
public Label( boolean isHeavyWeight, float width, float height, String text )
{
this( isHeavyWeight, width, height, text, (HUDFont)null, (Colorf)null );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param labelDesc a LabelDescription instance holding information about font, color, alignment and background-texture
*/
public Label( float width, float height, String text, Description labelDesc )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, labelDesc );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param alignment the horizontal and vertical alignment
*/
public Label( float width, float height, String text, TextAlignment alignment )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, alignment );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param color the color to be used
* @param alignment the horizontal and vertical alignment
*/
public Label( float width, float height, String text, Colorf color, TextAlignment alignment )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, color, alignment );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
* @param color the color to be used
* @param alignment the horizontal and vertical alignment
*/
public Label( float width, float height, String text, HUDFont font, Colorf color, TextAlignment alignment )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, font, color, alignment );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
* @param color the color to be used
*/
public Label( float width, float height, String text, HUDFont font, Colorf color )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, font, color );
}
/**
* Creates a new Label with the given width, height and z-index.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param color the color to be used
*/
public Label( float width, float height, String text, Colorf color )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, color );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
*/
public Label( float width, float height, String text, HUDFont font )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, font );
}
/**
* Creates a new Label with the given width and height and a z-index of 0.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
* @param font the Font to be used for the text
* @param alignment the horizontal and vertical alignment
*/
public Label( float width, float height, String text, HUDFont font, TextAlignment alignment )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text, font, alignment );
}
/**
* Creates a new Label with the given width and height and no text initially.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
*/
public Label( float width, float height )
{
this( DEFAULT_HEAVYWEIGHT, width, height );
}
/**
* Creates a new Label with the given width and height and no text initially.
*
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param text the text to display in this TextWidget
*/
public Label( float width, float height, String text )
{
this( DEFAULT_HEAVYWEIGHT, width, height, text );
}
}