/**
* 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.vecmath2.Colorf;
import org.xith3d.scenegraph.Texture2D;
import org.xith3d.ui.hud.HUD;
import org.xith3d.ui.hud.listeners.ListSelectionListener;
import org.xith3d.ui.hud.utils.TileMode;
import org.xith3d.ui.text2d.TextAlignment;
/**
* This is the base implementation for a List Widget.
*
* @author Marvin Froehlich (aka Qudus)
*/
public abstract class AbstractList extends BackgroundSettableWidget implements PaddingSettable
{
protected static final boolean DEFAULT_HEAVYWEIGHT = false;
private ListModel model;
/**
* @param model
*/
protected void afterModelSetWidthItems( ListModel model )
{
}
/**
* Sets the underlying model.
*
* @param model
*/
public void setModel( ListModel model )
{
if ( model == null )
throw new IllegalArgumentException( "model must not be null" );
if ( model == this.model )
return;
if ( this.model != null )
{
for ( Widget widget : this.model.getUsedWidgets() )
{
getWidgetAssembler().removeWidget( widget );
}
this.model.setList( null );
}
this.model = model;
this.model.setList( this );
for ( Widget widget : model.getUsedWidgets() )
{
getWidgetAssembler().addUnmanagedWidget( widget );
}
if ( ( getHUD() != null ) && ( model.getItemsCount() > 0 ) )
{
afterModelSetWidthItems( model );
}
}
/**
* Gets the underlying model.
*
* @return the underlying model.
*/
public ListModel getModel()
{
return ( model );
}
/**
* {@inheritDoc}
*/
public final boolean setPadding( int padding )
{
return ( setPadding( padding, padding, padding, padding ) );
}
/**
* Sets the background-color of the hovered Item.
*
* @param color
*/
public abstract void setHoverBackgroundColor( Colorf color );
/**
* @return the background-color of the hovered Item.
*/
public abstract Colorf getHoverBackgroundColor();
/**
* Sets the background-color of the selected Item.
*
* @param color
*/
public abstract void setSelectionBackgroundColor( Colorf color );
/**
* @return the background-color of the selected Item.
*/
public abstract Colorf getSelectionBackgroundColor();
/**
* This alignment is used to render the items, if possible.
*
* @param alignment
*/
public abstract void setAlignment( TextAlignment alignment );
/**
* This alignment is used to render the items, if possible.
*
* @return the TextAlignment.
*/
public abstract TextAlignment getAlignment();
/**
* Adds a new ListSelectionListener.
*
* @param l the new listener
*/
public abstract void addSelectionListener( ListSelectionListener l );
/**
* Removes a ListSelectionListener.
*
* @param l the listener to be removed
*/
public abstract void removeSelectionListener( ListSelectionListener l );
/**
* Sets the currently selected Item.
*
* @param itemIndex
*/
public void setSelectedIndex( int itemIndex )
{
ListModel model = getModel();
model.setSelectedIndex( itemIndex );
model.markListDirty();
}
/**
* @return the selected Item's index or <i>null</i>
*/
public final int getSelectedIndex()
{
return ( getModel().getSelectedIndex() );
}
/**
* Returns the currently selected Item.
*
* @return the currently selected Item.
*/
public Object getSelectedItem()
{
return ( getModel().getSelectedItem() );
}
/**
* Finds the first item, which's equals() method returns true for the given value.
*
* @param item
*
* @return the found item's index (or -1)
*/
public int findItem( Object item )
{
ListModel model = getModel();
int n = model.getItemsCount();
for ( int i = 0; i < n; i++ )
{
if ( model.getItem( i ).equals( item ) )
return ( i );
}
return ( -1 );
}
/**
* Sets the selected item to the previous one of the currently selected item.
*
* @return the new selected index
*/
public final int selectPreviousItem()
{
int selIndex = getSelectedIndex();
if ( selIndex > 0 )
{
setSelectedIndex( --selIndex );
}
return ( selIndex );
}
/**
* Sets the selected item to the following one of the currently selected item.
*
* @return the new selected index
*/
public final int selectNextItem()
{
int selIndex = getSelectedIndex();
if ( selIndex < getItemsCount() - 1 )
{
setSelectedIndex( ++selIndex );
}
return ( selIndex );
}
/**
* If set to true, the addItem() method sets the selected item to the added one.
*
* @param b
*/
public abstract void setAddItemSetsSelectedItem( boolean b );
/**
* If set to true, the addItem() method sets the selected item to the added one.
*/
public abstract boolean addItemSetsSelectedItem();
/**
* Scrolls the list, so that the selected item is in the content area.
*/
public abstract void scrollSelectedItemIntoView();
protected void afterItemAddedToEnd()
{
}
protected void afterFirstItemAdded()
{
}
/**
* Adds the given Item to the List (at the given position).
*
* @param index the position to add the Item at
* @param item the new Item to add to the List
*/
public Object addItem( int index, Object item )
{
ListModel model = getModel();
model.addItem( index, item );
if ( addItemSetsSelectedItem() )
setSelectedIndex( index );
else if ( getSelectedIndex() >= index )
setSelectedIndex( getSelectedIndex() + 1 );
if ( index == model.getItemsCount() - 2 )
afterItemAddedToEnd();
model.markListDirty();
if ( ( getHUD() != null ) && ( model.getItemsCount() == 1 ) )
{
afterFirstItemAdded();
}
return ( item );
}
/**
* Adds the given Item to the List (at the end).
*
* @param item the new Item to add to the List
*
* @return the index, at which the item has been added.
*/
public final int addItem( Object item )
{
int index = getItemsCount();
addItem( index, item );
return ( index );
}
/**
* Adds all items from the given List to this List.
*
* @param items
*/
@SuppressWarnings( "unchecked" )
public void addItems( java.util.List items )
{
ListModel model = getModel();
int index = model.getItemsCount();
model.addItems( items );
if ( addItemSetsSelectedItem() )
setSelectedIndex( index );
//else if ( getSelectedIndex() >= index )
// setSelectedIndex( getSelectedIndex() + 1 );
//if ( index == model.getItemsCount() - 2 )
afterItemAddedToEnd();
model.markListDirty();
if ( ( getHUD() != null ) && ( model.getItemsCount() == items.size() ) )
{
afterFirstItemAdded();
}
}
/**
* Adds all items from the given array to this List.
*
* @param items
*/
public void addItems( Object[] items )
{
ListModel model = getModel();
int index = model.getItemsCount();
model.addItems( items );
if ( addItemSetsSelectedItem() )
setSelectedIndex( index );
//else if ( getSelectedIndex() >= index )
// setSelectedIndex( getSelectedIndex() + 1 );
//if ( index == model.getItemsCount() - 2 )
afterItemAddedToEnd();
model.markListDirty();
if ( ( getHUD() != null ) && ( model.getItemsCount() == items.length ) )
{
afterFirstItemAdded();
}
}
/**
* Removes the given Item from the List.
*
* @param index the position of the Item to be removed
*
* @return the removed Item or null, if there was no item at the given index.
*/
public Object removeItem( int index )
{
ListModel model = getModel();
Object item = model.removeItem( index );
model.markListDirty();
return ( item );
}
/**
* Removes all items from the List.
*/
public void clear()
{
ListModel model = getModel();
model.clear();
model.markListDirty();
}
/**
* @return the number of Items in this List
*/
public final int getItemsCount()
{
return ( getModel().getItemsCount() );
}
protected final Widget getWidget( float contentWidth, int itemIndex )
{
return ( getModel().getWidget( contentWidth, itemIndex ) );
}
/**
* Gets the item from the specified index.
*
* @param index the index to get the Item from
*
* @return the Item at the given index.
*/
public Object getItem( int index )
{
return ( getModel().getItem( index ) );
}
/**
* Scrolls the list, so that the given index is the top item's index (if possible).
*
* @param topIndex
*/
public abstract void setTopIndex( int topIndex );
/**
* The top-most item's index visible in the List (or -1, if the List is empty)
*
* @return the top index.
*/
public abstract int getTopIndex();
/**
* The bottom-most item's index visible in the List (or -1, if the List is empty)
*
* @return the bottom index.
*/
public abstract int getBottomIndex();
protected void updateSizesAndMarkDirty()
{
}
/**
* {@inheritDoc}
*/
@Override
protected void onAttachedToHUD( HUD hud )
{
super.onAttachedToHUD( hud );
updateSizesAndMarkDirty();
}
/**
* Creates a new AbstractList.
*
* @param isHeavyWeight
* @param backgroundColor
* @param backgroundTexture
* @param tileMode
* @param model the ListModel (null for auto-generation)
*/
protected AbstractList( boolean isHeavyWeight, Colorf backgroundColor, Texture2D backgroundTexture, TileMode tileMode, ListModel model )
{
super( isHeavyWeight, true, backgroundColor, backgroundTexture, tileMode );
if ( model == null )
throw new IllegalArgumentException( "model must not be null" );
setBackground( backgroundColor, backgroundTexture, tileMode );
setModel( model );
getWidgetAssembler().setPickDispatched( true );
}
/**
* Creates a new AbstractList with the given width and height.
*
* @param isHeavyWeight
* @param width the new width of this Widget
* @param height the new height of this Widget
* @param backgroundColor
* @param backgroundTexture
* @param tileMode
* @param model the ListModel (null for auto-generation)
*/
protected AbstractList( boolean isHeavyWeight, float width, float height, Colorf backgroundColor, Texture2D backgroundTexture, TileMode tileMode, ListModel model )
{
super( isHeavyWeight, true, width, height, backgroundColor, backgroundTexture, tileMode );
if ( model == null )
throw new IllegalArgumentException( "model must not be null" );
setBackground( backgroundColor, backgroundTexture, tileMode );
setModel( model );
getWidgetAssembler().setPickDispatched( true );
}
}