/** * 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.base; import org.openmali.types.twodee.Dim2f; import org.openmali.vecmath2.Colorf; import org.xith3d.scenegraph.Texture2D; import org.xith3d.scenegraph.Texture2DCanvas; 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.TileMode; import org.xith3d.ui.hud.widgets.Label; import org.xith3d.ui.text2d.TextAlignment; /** * This class serves as a base for all StateButtons with an Image and a Label. * * @author Marvin Froehlich (aka Qudus) */ public abstract class LabeledStateButton extends StateButton implements TextWidget, AutoSizable { protected static final boolean DEFAULT_HEAVYWEIGHT = false; /** * This class is used to describe a LabeledStateButton Widget. * You can pass it to the constructor. * Modifications on the used instance after creating the Widget * won't have any effect. * * @author Marvin Froehlich (aka Qudus) */ public static class Description extends Widget.DescriptionBase { private Texture2D texDeactivatedNormal; private Texture2D texDeactivatedHovered; private Texture2D texActivatedNormal; private Texture2D texActivatedHovered; private int space; private Label.Description labelDesc; public void setTexture( boolean state, boolean hovered, Texture2D texture ) { if ( state ) { if ( hovered ) this.texActivatedNormal = texture; else this.texActivatedHovered = texture; } else { if ( hovered ) this.texDeactivatedNormal = texture; else this.texDeactivatedHovered = texture; } } public void setTexture( boolean state, boolean hovered, String name ) { setTexture( state, hovered, HUDTextureUtils.getTextureOrNull( name, true ) ); } public final Texture2D getTexture( boolean state, boolean hovered ) { if ( state ) { if ( hovered ) return ( texActivatedHovered ); return ( texActivatedNormal ); } if ( hovered ) return ( texDeactivatedHovered ); return ( texDeactivatedNormal ); } public void setSpace( int space ) { this.space = space; } public final int getSpace() { return ( space ); } public void setLabelDescription( Label.Description labelDesc ) { this.labelDesc = labelDesc; } public final Label.Description getLabelDescription() { return ( labelDesc ); } /** * Clone-Constructor */ public void set( Description desc ) { this.texDeactivatedNormal = desc.texDeactivatedNormal; this.texDeactivatedHovered = desc.texDeactivatedHovered; this.texActivatedNormal = desc.texActivatedNormal; this.texActivatedHovered = desc.texActivatedHovered; this.space = desc.space; this.labelDesc = desc.labelDesc.clone(); } /** * Clones LabeledStateButton.Description */ @Override public Description clone() { return ( new Description( this ) ); } /** * Clone-Constructor */ public Description( Description desc ) { this.set( desc ); } /** * Create a new LabeledStateButton.Description * * @param texDeactivatedNormal Texture for DEACTIVATED_NORMAL state * @param texDeactivatedHovered Texture for DEACTIVATED_HOVERED state * @param texActivatedNormal Texture for ACTIVATED_NORMAL state * @param texActivatedHovered Texture for ACTIVATED_HOVERED state * @param imageSize size of the state images * @param space space between the Image and the Label * @param labelDesc description of the Label */ public Description( Texture2D texDeactivatedNormal, Texture2D texDeactivatedHovered, Texture2D texActivatedNormal, Texture2D texActivatedHovered, int space, Label.Description labelDesc ) { this.texDeactivatedNormal = texDeactivatedNormal; this.texDeactivatedHovered = texDeactivatedHovered; this.texActivatedNormal = texActivatedNormal; this.texActivatedHovered = texActivatedHovered; this.space = space; this.labelDesc = labelDesc; } /** * Create a new LabeledStateButton.Description * * @param texDeactivatedNormal Texture for DEACTIVATED_NORMAL state * @param texDeactivatedHovered Texture for DEACTIVATED_HOVERED state * @param texActivatedNormal Texture for ACTIVATED_NORMAL state * @param texActivatedHovered Texture for ACTIVATED_HOVERED state * @param imageSize size of the state images * @param space space between the Image and the Label * @param labelDesc description of the Label */ public Description( String texDeactivatedNormal, String texDeactivatedHovered, String texActivatedNormal, String texActivatedHovered, int space, Label.Description labelDesc ) { this( HUDTextureUtils.getTexture( texDeactivatedNormal, true ), HUDTextureUtils.getTexture( texDeactivatedHovered, true ), HUDTextureUtils.getTexture( texActivatedNormal, true ), HUDTextureUtils.getTexture( texActivatedHovered, true ), space, labelDesc ); } } private Description desc; private Texture2D buttonTex; private Label label; private boolean autoSize = false; /** * Sets the background color of the Widget. * * @param color the color to use */ public void setBackgroundColor( Colorf color ) { label.setBackgroundColor( color ); } /** * @return the background color of the Widget. */ public final Colorf getBackgroundColor() { return ( label.getBackgroundColor() ); } /** * Sets the background texture of the Widget. * * @param texture the texture resource to use */ public void setBackgroundTexture( Texture2D texture ) { label.setBackgroundTexture( texture ); } /** * Sets the background Texture of the Widget. * * @param texture the texture resource to use */ public void setBackgroundTexture( String texture ) { label.setBackgroundTexture( texture ); } /** * Sets background color and texture at once. * * @param color * @param texture * @param tileMode */ public final void setBackground( Colorf color, Texture2D texture, TileMode tileMode ) { label.setBackground( color, texture, tileMode ); } /** * Sets background color and texture at once. * * @param color * @param texture */ public final void setBackground( Colorf color, String texture ) { label.setBackground( color, texture ); } /** * Sets background color and texture to nothing at once. */ public final void setNoBackground() { label.setNoBackground(); } /** * @return the background Texture of the Widget. */ public final Texture2D getBackgroundTexture() { return ( label.getBackgroundTexture() ); } /** * Sets the background tile mode (null for no tiling) * * @param mode */ public void setBackgroundTileMode( TileMode mode ) { label.setBackgroundTileMode( mode ); } /** * @return the background tile mode (null for no tiling). */ public final TileMode getBackgroundTileMode() { return ( label.getBackgroundTileMode() ); } /** * {@inheritDoc} */ public void setText( String text ) { label.setText( text ); } /** * {@inheritDoc} */ public final String getText() { return ( label.getText() ); } /** * {@inheritDoc} */ public void setAlignment( TextAlignment alignment ) { label.setAlignment( alignment ); } /** * {@inheritDoc} */ public final TextAlignment getAlignment() { return ( label.getAlignment() ); } /** * {@inheritDoc} */ public void setFont( HUDFont font ) { label.setFont( font ); } /** * {@inheritDoc} */ public final HUDFont getFont() { return ( label.getFont() ); } /** * {@inheritDoc} */ public void setFontDisabled( HUDFont font ) { label.setFontDisabled( font ); } /** * {@inheritDoc} */ public final HUDFont getFontDisabled() { return ( label.getFontDisabled() ); } /** * {@inheritDoc} */ public void setFontColor( Colorf color ) { label.setFontColor( color ); } /** * {@inheritDoc} */ public final Colorf getFontColor() { return ( label.getFontColor() ); } /** * {@inheritDoc} */ public void setFontColorDisabled( Colorf color ) { label.setFontColorDisabled( color ); } /** * {@inheritDoc} */ public final Colorf getFontColorDisabled() { return ( label.getFontColorDisabled() ); } /** * {@inheritDoc} */ @Override protected void setEnabledImpl( boolean enabled ) { label.setEnabled( enabled ); } /** * {@inheritDoc} */ @Override protected void onExtendedStateChanged( boolean state, boolean hovered ) { this.buttonTex = desc.getTexture( state, hovered ); setTextureDirty(); } /** * {@inheritDoc} */ @Override protected void onSizeChanged( float oldWidth, float oldHeight, float newWidth, float newHeight ) { super.onSizeChanged( oldWidth, oldHeight, newWidth, newHeight ); label.setSize( newWidth, newHeight ); } /** * 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 ); } /** * {@inheritDoc} */ public final <Dim2f_ extends Dim2f> Dim2f_ getMinimalSize( Dim2f_ buffer ) { float minWidth = 0f; float minHeight = 0f; if ( buttonTex != null ) { getSizePixels2HUD_( HUDTextureUtils.getTextureWidth( buttonTex ), HUDTextureUtils.getTextureHeight( buttonTex ), buffer ); minWidth += buffer.getWidth(); minHeight = Math.max( minHeight, buffer.getHeight() ); if ( label != null ) { getSizePixels2HUD_( desc.getSpace(), 0, buffer ); minWidth += buffer.getWidth(); } } if ( label != null ) { label.getMinimalSize( buffer ); minWidth += buffer.getWidth(); minHeight = Math.max( minHeight, buffer.getHeight() ); } buffer.set( minWidth, minHeight ); return ( buffer ); } /** * Resizes this LabeledStateButton 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 state-button'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 state-button'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 ); } protected boolean isMouseOverStateImage( float mouseX, float mouseY ) { Dim2f buffer2 = Dim2f.fromPool(); getSizePixels2HUD_( HUDTextureUtils.getTextureWidth( buttonTex ), HUDTextureUtils.getTextureHeight( buttonTex ), buffer2 ); float iconWidth = buffer2.getWidth(); float iconHeight = buffer2.getHeight(); Dim2f.toPool( buffer2 ); float iconTop = ( getContentHeight() - iconHeight ) / 2f; if ( ( mouseX < 0f ) || ( 0f + iconWidth < mouseX ) ) return ( false ); if ( ( mouseY < iconTop ) || ( iconTop + iconHeight < mouseY ) ) return ( false ); return ( true ); } /** * {@inheritDoc} */ @Override protected void drawWidget( Texture2DCanvas texCanvas, int offsetX, int offsetY, int width, int height, boolean drawsSelf ) { } /** * {@inheritDoc} */ @Override protected void drawWidgetAfterWidgetAssembler( Texture2DCanvas texCanvas, int offsetX, int offsetY, int width, int height, boolean drawsSelf ) { super.drawWidgetAfterWidgetAssembler( texCanvas, offsetX, offsetY, width, height, drawsSelf ); int y = ( height - HUDTextureUtils.getTextureHeight( buttonTex ) ) / 2; DrawUtils.drawImage( null, buttonTex, null, texCanvas, offsetX, offsetY + y, width, height - y ); } /** * {@inheritDoc} */ @Override protected void initSize() { if ( autoSize ) { setMinimalSize(); } } /** * {@inheritDoc} */ @Override protected void init() { if ( label != null ) { //getWidgetAssembler().addWidget( label, 0f, 0f ); getWidgetAssembler().reposition( label, 0f, 0f ); } } /** * Creates a new LabeledStateButton * * @param isHeavyWeight * @param width the desired width * @param height the desired height * @param desc the Description object for this Widget * @param text the text to be displayed */ public LabeledStateButton( boolean isHeavyWeight, float width, float height, String text, Description desc ) { super( isHeavyWeight, true, Math.max( 0f, width ), Math.max( 0f, height ) ); this.autoSize = ( ( width <= 0f ) || ( height <= 0f ) ); this.desc = desc.clone(); this.buttonTex = desc.getTexture( getState(), isHovered() ); if ( ( desc.getLabelDescription() != null ) && ( text != null ) ) this.label = new Label( false, Math.max( 0.1f, width ), Math.max( 0.1f, height ), text, desc.getLabelDescription() ); else this.label = new Label( false, Math.max( 0.1f, width ), Math.max( 0.1f, height ), "" ); getWidgetAssembler().addWidget( label, 0f, 0f ); label.setTextOffset( HUDTextureUtils.getTextureWidth( desc.getTexture( false, false ) ) + desc.getSpace(), 0 ); } }