/**
* Copyright (C) 2009-2014 Cars and Tracks Development Project (CTDP).
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package net.ctdp.rfdynhud.widgets.base.widget;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import net.ctdp.rfdynhud.gamedata.LiveGameData;
import net.ctdp.rfdynhud.gamedata.SessionType;
import net.ctdp.rfdynhud.gamedata.VehicleScoringInfo;
import net.ctdp.rfdynhud.input.InputAction;
import net.ctdp.rfdynhud.properties.BorderProperty;
import net.ctdp.rfdynhud.properties.ColorProperty;
import net.ctdp.rfdynhud.properties.FontProperty;
import net.ctdp.rfdynhud.properties.PropertyLoader;
import net.ctdp.rfdynhud.properties.PropertiesContainer;
import net.ctdp.rfdynhud.render.DrawnStringFactory;
import net.ctdp.rfdynhud.render.TextureImage2D;
import net.ctdp.rfdynhud.render.TransformableTexture;
import net.ctdp.rfdynhud.render.__RenderPrivilegedAccess;
import net.ctdp.rfdynhud.util.SubTextureCollector;
import net.ctdp.rfdynhud.util.WidgetZYXComparator;
import net.ctdp.rfdynhud.util.PropertyWriter;
import net.ctdp.rfdynhud.valuemanagers.Clock;
import net.ctdp.rfdynhud.widgets.WidgetsConfiguration;
/**
* An assembled {@link Widget} is a master {@link Widget} for other client {@link Widget}s.
* The client {@link Widget}s define its actual display.
*
* @author Marvin Froehlich
*/
public abstract class AbstractAssembledWidget extends StatefulWidget<Object, Object>
{
static class AssembledGeneralStore
{
@SuppressWarnings( "rawtypes" )
private final Map<StatefulWidget, Object> generalStores = new HashMap<StatefulWidget, Object>();
}
static class AssembledLocalStore
{
@SuppressWarnings( "rawtypes" )
private final Map<StatefulWidget, Object> localStores = new HashMap<StatefulWidget, Object>();
}
private boolean _initParts;
private Widget[] initialParts;
private Widget[] parts;
private void makeWidgetPart( Widget part, LiveGameData gameData )
{
part.setMasterWidget( this );
if ( getConfiguration() != null )
part.setConfiguration( getConfiguration(), gameData );
part.getBorderProperty().setBorder( null );
part.setPadding( 0, 0, 0, 0 );
//part.getBackgroundColorProperty().setColor( (String)null );
}
void sortParts()
{
Arrays.sort( parts, WidgetZYXComparator.INSTANCE );
}
/**
* Finds a free name starting with 'baseName'.
*
* @param baseName the name prefix
*
* @return the found free name.
*/
public String findFreePartName( String baseName )
{
for ( int i = 1; i < Integer.MAX_VALUE; i++ )
{
String name = baseName + i;
boolean isFree = true;
for ( int j = 0; j < parts.length; j++ )
{
if ( name.equals( parts[j].getName() ) )
{
isFree = false;
break;
}
}
if ( isFree )
return ( name );
}
// Theoretically unreachable code!
return ( null );
}
void addPart( Widget widget, LiveGameData gameData )
{
Widget[] tmp = new Widget[ parts.length + 1 ];
System.arraycopy( parts, 0, tmp, 0, parts.length );
parts = tmp;
parts[parts.length - 1] = widget;
makeWidgetPart( widget, gameData );
if ( getConfiguration() != null )
sortParts();
forceAndSetDirty( true );
}
void removePart( Widget widget, LiveGameData gameData )
{
if ( parts.length == 0 )
throw new IllegalArgumentException( "The passed Widget is not a part of this." );
if ( parts.length == 1 )
{
if ( parts[0] != widget )
throw new IllegalArgumentException( "The passed Widget is not a part of this." );
widget.setMasterWidget( null );
widget.setConfiguration( null, gameData );
parts = new Widget[ 0 ];
}
else
{
int index = -1;
for ( int i = 0; i < parts.length; i++ )
{
if ( parts[i] == widget )
{
index = i;
break;
}
}
if ( index == -1 )
throw new IllegalArgumentException( "The passed Widget is not a part of this." );
widget.setMasterWidget( null );
widget.setConfiguration( null, gameData );
Widget[] tmp = new Widget[ parts.length - 1 ];
if ( index == 0 )
{
System.arraycopy( parts, 1, tmp, 0, parts.length - 1 );
}
else if ( index == parts.length - 1 )
{
System.arraycopy( parts, 0, tmp, 0, parts.length - 1 );
}
else
{
System.arraycopy( parts, 0, tmp, 0, index );
System.arraycopy( parts, index + 1, tmp, index, parts.length - index - 1 );
}
parts = tmp;
}
forceAndSetDirty( true );
}
/**
* Gets the number of {@link Widget} parts in this {@link AbstractAssembledWidget}.
*
* @return the number of {@link Widget} parts in this {@link AbstractAssembledWidget}.
*/
public final int getNumParts()
{
return ( parts.length );
}
/**
* Gets the i-th {@link Widget}-part in this {@link AbstractAssembledWidget}.
*
* @param index the index
*
* @return the i-th {@link Widget}-part in this {@link AbstractAssembledWidget}.
*/
public final Widget getPart( int index )
{
return ( parts[index] );
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings( "rawtypes" )
boolean hasGeneralStore()
{
if ( super.hasGeneralStore() )
return ( true );
for ( int i = 0; i < parts.length; i++ )
{
Widget part = parts[i];
if ( ( part instanceof StatefulWidget ) && ( (StatefulWidget)part ).hasGeneralStore() )
return ( true );
}
return ( false );
}
/**
* {@inheritDoc}
*/
@Override
protected final AssembledGeneralStore createGeneralStore()
{
return ( new AssembledGeneralStore() );
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings( { "rawtypes", "unchecked" } )
void setGeneralStore( Object generalStore )
{
super.setGeneralStore( generalStore );
if ( generalStore != null )
{
AssembledGeneralStore ags = (AssembledGeneralStore)generalStore;
for ( int i = 0; i < parts.length; i++ )
{
Widget part = parts[i];
if ( part instanceof StatefulWidget )
{
StatefulWidget sw = (StatefulWidget)part;
sw.setGeneralStore( ags.generalStores.get( sw ) );
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings( "rawtypes" )
boolean hasLocalStore()
{
if ( super.hasLocalStore() )
return ( true );
for ( int i = 0; i < parts.length; i++ )
{
Widget part = parts[i];
if ( ( part instanceof StatefulWidget ) && ( (StatefulWidget)part ).hasLocalStore() )
return ( true );
}
return ( false );
}
/**
* {@inheritDoc}
*/
@Override
protected final AssembledLocalStore createLocalStore()
{
return ( new AssembledLocalStore() );
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings( { "rawtypes", "unchecked" } )
void setLocalStore( Object localStore )
{
super.setLocalStore( localStore );
if ( localStore != null )
{
AssembledLocalStore als = (AssembledLocalStore)localStore;
for ( int i = 0; i < parts.length; i++ )
{
Widget part = parts[i];
if ( part instanceof StatefulWidget )
{
StatefulWidget sw = (StatefulWidget)part;
sw.setLocalStore( als.localStores.get( sw ) );
}
}
}
}
/**
* This method is called when the configuration has been loaded.
*
* @param parts the parts to arrange
*/
protected void arrangeParts( Widget[] parts )
{
}
/**
* This method is called when the configuration has been loaded.
*
* @see #arrangeParts(Widget[])
*/
final void arrangeParts()
{
if ( _initParts )
arrangeParts( initialParts );
initialParts = null;
_initParts = false;
}
/**
* {@inheritDoc}
*/
@Override
public String getDefaultBorderValue( String name )
{
return ( BorderProperty.getDefaultBorderValue( name ) );
}
/**
* {@inheritDoc}
*/
@Override
public String getDefaultNamedColorValue( String name )
{
return ( ColorProperty.getDefaultNamedColorValue( name ) );
}
/**
* {@inheritDoc}
*/
@Override
public String getDefaultNamedFontValue( String name )
{
return ( FontProperty.getDefaultNamedFontValue( name ) );
}
@Override
final void setConfiguration( WidgetsConfiguration config, LiveGameData gameData )
{
super.setConfiguration( config, gameData );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].setConfiguration( config, gameData );
}
}
/**
* {@inheritDoc}
*/
@Override
protected void initSubTextures( LiveGameData gameData, boolean isEditorMode, int widgetInnerWidth, int widgetInnerHeight, SubTextureCollector collector )
{
for ( int i = 0; i < parts.length; i++ )
{
int baseIndex = collector.getNumberOf();
parts[i].initSubTextures( gameData, isEditorMode, parts[i].getInnerSize().getEffectiveWidth(), parts[i].getInnerSize().getEffectiveHeight(), collector );
for ( int j = baseIndex; j < collector.getNumberOf(); j++ )
{
TransformableTexture tt = collector.get( j );
if ( tt.getOwnerWidget() == null )
__RenderPrivilegedAccess.setOwnerWidget( parts[i], tt );
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void setDirtyFlag( boolean forwardCall )
{
super.setDirtyFlag( true );
}
/**
* {@inheritDoc}
*/
@Override
public void forceReinitialization( boolean forwardCall )
{
super.forceReinitialization( true );
if ( forwardCall && ( parts != null ) )
{
for ( int i = 0; i < parts.length; i++ )
{
parts[i].forceReinitialization( false );
}
}
}
/**
* {@inheritDoc}
*/
@Override
public int getMinWidth( LiveGameData gameData, boolean isEditorMode )
{
int mw = super.getMinWidth( gameData, isEditorMode );
/*
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
mw = Math.max( mw, part.getPosition().getEffectiveX() + part.getMinWidth( gameData, isEditorMode ) );
}
*/
return ( mw );
}
/**
* {@inheritDoc}
*/
@Override
public int getMinHeight( LiveGameData gameData, boolean isEditorMode )
{
int mh = super.getMinHeight( gameData, isEditorMode );
/*
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
mh = Math.max( mh, part.getPosition().getEffectiveY() + part.getMinHeight( gameData, isEditorMode ) );
}
*/
return ( mh );
}
/**
* {@inheritDoc}
*/
@Override
public int getMaxWidth( LiveGameData gameData, boolean isEditorMode )
{
//if ( parts.length == 0 )
return ( super.getMaxWidth( gameData, isEditorMode ) );
/*
int mw = 0;
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
mw = Math.max( mw, part.getPosition().getEffectiveX() + part.getMaxWidth( gameData, isEditorMode ) );
}
return ( mw );
*/
}
/**
* {@inheritDoc}
*/
@Override
public int getMaxHeight( LiveGameData gameData, boolean isEditorMode )
{
//if ( parts.length == 0 )
return ( super.getMaxHeight( gameData, isEditorMode ) );
/*
int mh = 0;
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
mh = Math.max( mh, part.getPosition().getEffectiveY() + part.getMaxHeight( gameData, isEditorMode ) );
}
return ( mh );
*/
}
/**
* {@inheritDoc}
*/
@Override
public void bake( boolean convertToPixels )
{
super.bake( convertToPixels );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].bake( convertToPixels );
}
}
/**
* {@inheritDoc}
*/
@Override
public void setAllPosAndSizeToPercents()
{
super.setAllPosAndSizeToPercents();
for ( int i = 0; i < parts.length; i++ )
{
parts[i].setAllPosAndSizeToPercents();
}
}
/**
* {@inheritDoc}
*/
@Override
public void setAllPosAndSizeToPixels()
{
super.setAllPosAndSizeToPixels();
for ( int i = 0; i < parts.length; i++ )
{
parts[i].setAllPosAndSizeToPixels();
}
}
/**
* {@inheritDoc}
*/
@Override
void forceCompleteRedraw_( boolean mergedBackgroundToo, boolean forwardCall )
{
super.forceCompleteRedraw_( mergedBackgroundToo, true );
if ( forwardCall && ( parts != null ) )
{
for ( int i = 0; i < parts.length; i++ )
{
parts[i].forceCompleteRedraw_( mergedBackgroundToo, false );
}
}
}
/**
* {@inheritDoc}
*/
@Override
public Boolean updateVisibility( LiveGameData gameData, boolean isEditorMode )
{
Boolean result = super.updateVisibility( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].updateVisibility( gameData, isEditorMode );
}
return ( result );
}
private int neededData = -1;
/**
* {@inheritDoc}
*/
@Override
public int getNeededData()
{
if ( neededData == -1 )
{
neededData = 0;
for ( int i = 0; i < parts.length; i++ )
{
neededData |= parts[i].getNeededData();
}
}
return ( neededData );
}
/**
* {@inheritDoc}
*/
@Override
public void afterConfigurationLoaded( WidgetsConfiguration widgetsConfig, LiveGameData gameData, boolean isEditorMode )
{
super.afterConfigurationLoaded( widgetsConfig, gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].afterConfigurationLoaded( widgetsConfig, gameData, isEditorMode );
}
arrangeParts();
}
/**
* {@inheritDoc}
*/
@Override
public void beforeConfigurationCleared( WidgetsConfiguration widgetsConfig, LiveGameData gameData, boolean isEditorMode )
{
super.beforeConfigurationCleared( widgetsConfig, gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].beforeConfigurationCleared( widgetsConfig, gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onTrackChanged( String trackname, LiveGameData gameData, boolean isEditorMode )
{
super.onTrackChanged( trackname, gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onTrackChanged( trackname, gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onSessionStarted( SessionType sessionType, LiveGameData gameData, boolean isEditorMode )
{
super.onSessionStarted( sessionType, gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onSessionStarted( sessionType, gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onCockpitEntered( LiveGameData gameData, boolean isEditorMode )
{
super.onCockpitEntered( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onCockpitEntered( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onScoringInfoUpdated( LiveGameData gameData, boolean isEditorMode )
{
super.onScoringInfoUpdated( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onScoringInfoUpdated( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onVehicleSetupUpdated( LiveGameData gameData, boolean isEditorMode )
{
super.onVehicleSetupUpdated( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onVehicleSetupUpdated( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onNeededDataComplete( LiveGameData gameData, boolean isEditorMode )
{
super.onNeededDataComplete( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onNeededDataComplete( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onPitsEntered( LiveGameData gameData, boolean isEditorMode )
{
super.onPitsEntered( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onPitsEntered( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onGarageEntered( LiveGameData gameData, boolean isEditorMode )
{
super.onGarageEntered( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onGarageEntered( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onGarageExited( LiveGameData gameData, boolean isEditorMode )
{
super.onGarageExited( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onGarageExited( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onPitsExited( LiveGameData gameData, boolean isEditorMode )
{
super.onPitsExited( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onPitsExited( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public void onCockpitExited( LiveGameData gameData, boolean isEditorMode )
{
super.onCockpitExited( gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onCockpitExited( gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
protected Boolean onVehicleControlChanged( VehicleScoringInfo viewedVSI, LiveGameData gameData, boolean isEditorMode )
{
Boolean result = super.onVehicleControlChanged( viewedVSI, gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
Boolean result2 = parts[i].onVehicleControlChanged( viewedVSI, gameData, isEditorMode );
if ( result2 != null )
result = result2;
}
return ( result );
}
/**
* {@inheritDoc}
*/
@Override
public void onLapStarted( VehicleScoringInfo vsi, LiveGameData gameData, boolean isEditorMode )
{
super.onLapStarted( vsi, gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
parts[i].onLapStarted( vsi, gameData, isEditorMode );
}
}
/**
* {@inheritDoc}
*/
@Override
public Boolean onBoundInputStateChanged( InputAction action, boolean state, int modifierMask, long when, LiveGameData gameData, boolean isEditorMode )
{
Boolean result = super.onBoundInputStateChanged( action, state, modifierMask, when, gameData, isEditorMode );
for ( int i = 0; i < parts.length; i++ )
{
Boolean result2 = parts[i].onBoundInputStateChanged( action, state, modifierMask, when, gameData, isEditorMode );
if ( result2 != null )
result = result2;
}
return ( result );
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasMasterCanvas( boolean isEditorMode )
{
return ( true );
}
/**
* {@inheritDoc}
*/
@Override
protected void initialize( LiveGameData gameData, boolean isEditorMode, DrawnStringFactory drawnStringFactory, TextureImage2D texture, int width, int height )
{
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
int width2 = part.getEffectiveWidth();
int height2 = part.getEffectiveHeight();
part.initialize( gameData, isEditorMode, drawnStringFactory, texture, width2, height2 );
}
}
/**
* {@inheritDoc}
*/
@Override
protected boolean checkForChanges( LiveGameData gameData, boolean isEditorMode, TextureImage2D texture, int width, int height )
{
boolean result = false;
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
int width2 = part.getEffectiveWidth();
int height2 = part.getEffectiveHeight();
result = part.checkForChanges( gameData, isEditorMode, texture, width2, height2 ) || result;
}
return ( result );
}
@Override
void _drawBackground( LiveGameData gameData, boolean isEditorMode, TextureImage2D texture, int offsetX, int offsetY, int width, int height, boolean isRoot )
{
super._drawBackground( gameData, isEditorMode, texture, offsetX, offsetY, width, height, isRoot );
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
int offsetX2 = offsetX + part.getPosition().getEffectiveX();
int offsetY2 = offsetY + part.getPosition().getEffectiveY();
int width2 = part.getEffectiveWidth();
int height2 = part.getEffectiveHeight();
part._drawBackground( gameData, isEditorMode, texture, offsetX2, offsetY2, width2, height2, false );
}
}
/**
* {@inheritDoc}
*/
@Override
protected void drawWidget( Clock clock, boolean needsCompleteRedraw, LiveGameData gameData, boolean isEditorMode, TextureImage2D texture, int offsetX, int offsetY, int width, int height )
{
Widget part;
for ( int i = 0; i < parts.length; i++ )
{
part = parts[i];
int offsetX2 = offsetX + part.getPosition().getEffectiveX()/* + part.getBorder().getInnerLeftWidth()*/;
int offsetY2 = offsetY + part.getPosition().getEffectiveY()/* + part.getBorder().getInnerTopHeight()*/;
//int width2 = part.getEffectiveInnerWidth();
//int height2 = part.getEffectiveInnerHeight();
int width2 = part.getEffectiveWidth();
int height2 = part.getEffectiveHeight();
if ( texture != null )
texture.getTextureCanvas().pushClip( offsetX2, offsetY2, width2, height2, true );
try
{
part.drawWidget( clock, needsCompleteRedraw, gameData, isEditorMode, texture, offsetX2, offsetY2, width2, height2 );
}
catch ( Throwable t )
{
log( t );
}
finally
{
if ( texture != null )
texture.getTextureCanvas().popClip();
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void saveProperties( PropertyWriter writer ) throws IOException
{
super.saveProperties( writer );
/*
for ( int i = 0; i < parts.length; i++ )
{
parts[i].saveProperties( writer );
}
*/
}
/**
* {@inheritDoc}
*/
@Override
public void loadProperty( PropertyLoader loader )
{
super.loadProperty( loader );
/*
for ( int i = 0; i < parts.length; i++ )
{
parts[i].loadProperty( loader );
}
*/
}
/**
* {@inheritDoc}
*/
@Override
public void getProperties( PropertiesContainer propsCont, boolean forceAll )
{
super.getProperties( propsCont, forceAll );
for ( int i = 0; i < parts.length; i++ )
{
propsCont.pushGroup( parts[i].getName(), true );
parts[i].getProperties( propsCont, forceAll );
propsCont.popGroup();
}
}
@Override
protected Widget getNewInstanceForClone()
{
AbstractAssembledWidget newWidget = WidgetFactory.createAssembledWidget( getClass().getName(), "CloneOf" + getName() );
for ( int i = 0; i < getNumParts(); i++ )
{
newWidget.addPart( getPart( i ).getNewInstanceForClone(), null );
}
return ( newWidget );
}
/**
* {@inheritDoc}
*/
@Override
protected boolean hasText()
{
return ( false );
}
/**
* {@inheritDoc}
*/
@Override
protected final boolean canHaveBackground()
{
return ( true );
}
protected abstract Widget[] initParts( float width, boolean widthPercent, float height, boolean heightPercent );
/**
* Creates a new Widget.
*
* @param widgetSet the {@link WidgetSet} this {@link Widget} belongs to
* @param widgetPackage the package in the editor
* @param width negative numbers for (screen_width - width)
* @param widthPercent width parameter treated as percents
* @param height negative numbers for (screen_height - height)
* @param heightPercent height parameter treated as percents
* @param initParts this parameter must exist in your contructor and has to be forwarded to this
*/
protected AbstractAssembledWidget( WidgetSet widgetSet, WidgetPackage widgetPackage, float width, boolean widthPercent, float height, boolean heightPercent, boolean initParts )
{
super( widgetSet, widgetPackage, width, widthPercent, height, heightPercent );
this._initParts = initParts;
if ( initParts )
this.parts = initParts( width, widthPercent, height, heightPercent );
else
this.parts = new Widget[ 0 ];
this.initialParts = new Widget[ parts.length ];
System.arraycopy( parts, 0, initialParts, 0, parts.length );
for ( int i = 0; i < parts.length; i++ )
{
makeWidgetPart( parts[i], null );
}
}
/**
* Creates a new Widget.
*
* @param widgetSet the {@link WidgetSet} this {@link Widget} belongs to
* @param widgetPackage the package in the editor
* @param width negative numbers for (screen_width - width)
* @param height negative numbers for (screen_height - height)
* @param initParts this parameter must exist in your contructor and has to be forwarded to this
*/
protected AbstractAssembledWidget( WidgetSet widgetSet, WidgetPackage widgetPackage, float width, float height, boolean initParts )
{
this( widgetSet, widgetPackage, width, true, height, true, initParts );
}
}