/*******************************************************************************
* Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
******************************************************************************/
package com.w4t.webgridlayoutkit;
import java.io.IOException;
import org.eclipse.rwt.Adaptable;
import org.eclipse.rwt.internal.lifecycle.HtmlResponseWriter;
import org.eclipse.rwt.internal.util.HTML;
import com.w4t.*;
import com.w4t.developer.AreaSelector;
import com.w4t.internal.adaptable.IRenderInfoAdapter;
import com.w4t.renderinfo.GridLayoutRenderInfo;
import com.w4t.weblayoutkit.LayoutRenderer;
/** <p>the superclass for all renderers that render org.eclipse.rap.WebGridLayout.</p>
*/
public abstract class WebGridLayoutRenderer extends LayoutRenderer {
private static final String BORDER_SIZE = "borderSize";
private static final String DESIGN_TIME = "designTime";
private static final String DESIGN_MATRIX = "designMatrix";
void setDesignMatrix( final WebContainer parent,
final AreaSelector[][] designMatrix )
{
IRenderInfoAdapter adapter = getRenderInfoAdapter( parent );
adapter.addRenderState( DESIGN_MATRIX, designMatrix );
}
AreaSelector[][] getDesignMatrix( final WebContainer parent ) {
IRenderInfoAdapter adapter = getRenderInfoAdapter( parent );
return ( AreaSelector[][] )adapter.getRenderState( DESIGN_MATRIX );
}
void setDesignTime( final WebContainer parent, final boolean designTime ) {
IRenderInfoAdapter adapter = getRenderInfoAdapter( parent );
adapter.addRenderState( DESIGN_TIME, Boolean.valueOf( designTime ) );
}
boolean isDesignTime( final WebContainer parent ) {
IRenderInfoAdapter adapter = getRenderInfoAdapter( parent );
Object renderState = adapter.getRenderState( DESIGN_TIME );
boolean result = false;
if( renderState != null ) {
result = ( ( Boolean )renderState ).booleanValue();
}
return result;
}
void setBorderSize( final WebContainer parent, final String borderSize ) {
IRenderInfoAdapter adapter = getRenderInfoAdapter( parent );
adapter.addRenderState( BORDER_SIZE, borderSize );
}
String getBorderSize( final WebContainer parent ) {
IRenderInfoAdapter adapter = getRenderInfoAdapter( parent );
return ( String )adapter.getRenderState( BORDER_SIZE );
}
public void render( final WebComponent component ) throws IOException {
WebContainer parent = ( WebContainer )component;
getRenderInfoAdapter( parent ).clearRenderState();
boolean[][] usedMatrix = null;
try {
setDesignTime( parent, parent.isDesignTime() );
checkBorderSizeInDesignTime( parent );
// put the WebComponents into the Table Cells
Position pos = null;
for( int i = 0; i < parent.getWebComponentCount(); i++ ) {
pos = ( Position )parent.getConstraint( i );
try {
WebTableCell tableCell
= ( WebTableCell )getLayout( parent ).getArea( pos );
tableCell.addContentElement( parent.get( i ) );
} catch( Exception e ) {
WebComponent wc = parent.get( i ) ;
parent.remove( wc );
}
}
/* initialize the TableCells and tests if the tablecells are used
* for row- or/and colspan. this test is realized with a matrix of
* boolean values */
usedMatrix = createUsedMatrix( parent );
setDesignMatrix( parent, null );
if( isDesignTime( parent ) ) {
setDesignMatrix( parent, createDesignMatrix( parent ) );
}
for( int i = 0; i < getLayout( parent ).getRowCount(); i++ ) {
WebTableCell[] row = getInfo( parent ).getTableCells( i );
for( int j = 0; j < getLayout( parent ).getColCount(); j++ ) {
WebTableCell tableCell = row[ j ];
initUsedMatrix( parent, tableCell, i, j, usedMatrix );
}
}
// build the html Table
HtmlResponseWriter out = getResponseWriter();
out.startElement( HTML.TABLE, null );
out.writeAttribute( HTML.ID, parent.getUniqueID(), null );
RenderUtil.writeUniversalAttributes( parent );
RenderUtil.writeTableAttributes( getLayout( parent ) );
out.closeElementIfStarted();
// loops over the matrix
for( int i = 0; i < getLayout( parent ).getRowCount(); i++ ) {
WebTableRow rowToRender = new WebTableRow();
WebTableCell[] row = getInfo( parent ).getTableCells( i );
for( int j = 0; j < getLayout( parent ).getColCount(); j++ ) {
if( usedMatrix[ i ][ j ] ) {
rowToRender.addCell( row[ j ] );
if( isDesignTime( parent ) ) {
WebTableCell cell = row[ j ];
getDesignMatrix( parent )[ i ][ j ].setRegion( cell );
cell.addContentElement( getDesignMatrix( parent )[ i ][ j ] );
parent.add( getDesignMatrix( parent )[ i ][ j ],
new Position( i, j ) );
}
}
}
rowToRender.render();
}
out.endElement( HTML.TABLE );
} finally {
removeComponents( parent, usedMatrix );
}
}
GridLayoutRenderInfo getInfo( final WebContainer parent ) {
IRenderInfoAdapter adapter = getRenderInfoAdapter( parent );
return ( GridLayoutRenderInfo )adapter.getInfo();
}
IRenderInfoAdapter getRenderInfoAdapter( final WebContainer parent ) {
Adaptable adaptable = getLayout( parent );
Class clazz = IRenderInfoAdapter.class;
return ( IRenderInfoAdapter )adaptable.getAdapter( clazz );
}
WebGridLayout getLayout( final WebContainer parent ) {
return ( WebGridLayout )parent.getWebLayout();
}
private void removeComponents( final WebContainer parent,
final boolean[][] used )
{
WebGridLayout layout = getLayout( parent );
for( int i = 0; i < layout.getRowCount(); i++ ) {
WebTableCell[] row = getInfo( parent ).getTableCells( i );
for( int j = 0; j < layout.getColCount(); j++ ) {
if( used[ i ][ j ] ) {
if( isDesignTime( parent ) ) {
AreaSelector areaSelector = getDesignMatrix( parent )[ i ][ j ];
row[ j ].removeContentElement( areaSelector );
parent.remove( areaSelector );
}
}
}
}
for( int i = 0; i < parent.getWebComponentCount(); i++ ) {
WebTableCell tableCell
= ( WebTableCell )layout.getArea( parent.getConstraint( i ) );
tableCell.removeContentElement( parent.get( i ) );
}
restoreBorderBuffer( parent );
}
private void checkBorderSizeInDesignTime( final WebContainer parent ) {
// buffer border size
setBorderSize( parent, getLayout( parent ).getBorder() );
boolean useBorderSize_1 = false;
if( isDesignTime( parent ) ) {
useBorderSize_1 = true;
try {
if( Integer.parseInt( getLayout( parent ).getBorder() ) > 1 ) {
useBorderSize_1 = false;
}
} catch( Exception e ) {
}
}
if( useBorderSize_1 ) {
getLayout( parent ).setBorder( "1" );
}
}
private void restoreBorderBuffer( final WebContainer parent ) {
getLayout( parent ).setBorder( getBorderSize( parent ) );
}
/** creates a matrix with Boolean objects, which contains the value true */
private boolean[][] createUsedMatrix( final WebContainer parent ) {
WebGridLayout layout = getLayout( parent );
int rowCount = layout.getRowCount();
int colCount = layout.getColCount();
boolean[][] result = new boolean[ rowCount ][ colCount ];
for( int i = 0; i < rowCount; i++ ) {
for( int j = 0; j < colCount; j++ ) {
result[ i ][ j ] = true;
}
}
return result;
}
/** creates a matrix with WebDesignButtons for design time */
private AreaSelector[][] createDesignMatrix( final WebContainer parent ) {
WebGridLayout layout = getLayout( parent );
AreaSelector[][] designMatrix =
new AreaSelector[ layout.getRowCount() ][ layout.getColCount() ];
for( int i = 0; i < layout.getRowCount(); i++ ) {
for( int j = 0; j < layout.getColCount(); j++ ) {
designMatrix[ i ][ j ] = new AreaSelector();
designMatrix[ i ][ j ].setConstraint( new Position( i + 1, j + 1 ) );
designMatrix[ i ][ j ].setContainer( parent );
}
}
return designMatrix;
}
/** initialises the usedMatrix which sets the cells of the table
* to unused, which belongs to a row- or a colspan
* of another cell */
private void initUsedMatrix( final WebContainer parent,
final WebTableCell tableCell,
final int row,
final int col,
final boolean[][] usedMatrix ) {
// read the row- and colspan out of the tableCell
if( usedMatrix[ row ][ col ] ) {
int rowspan = 1;
int colspan = 1;
try {
rowspan = Integer.parseInt( tableCell.getRowspan() );
if( row + rowspan > getLayout( parent ).getRowCount() ) {
rowspan = getLayout( parent ).getRowCount() - row;
}
} catch( Exception e ) {}
try {
colspan = Integer.parseInt( tableCell.getColspan() );
if( col + colspan > getLayout( parent ).getColCount() ) {
colspan = getLayout( parent ).getColCount() - col;
}
} catch( Exception e ) {}
rowspan = ( rowspan < 1 ) ? 1 : rowspan;
colspan = ( colspan < 1 ) ? 1 : colspan;
if( colspan > 1 ) {
tableCell.setColspan( String.valueOf( colspan ) );
}
if( rowspan > 1 ) {
tableCell.setRowspan( String.valueOf( rowspan ) );
}
// disable the usage of all cells which belong to the row- or colspan
for( int i = row; i < row + rowspan; i++ ) {
for( int j = col; j < col + colspan; j++ ) {
usedMatrix[ i ][ j ] = false;
}
}
// enable the usage of the current table cell
usedMatrix[ row ][ col ] = true;
}
}
}