package org.atdl4j.ui.swt.impl;
import org.apache.log4j.Logger;
import org.atdl4j.fixatdl.layout.BorderT;
import org.atdl4j.fixatdl.layout.PanelOrientationT;
import org.atdl4j.fixatdl.layout.StrategyPanelT;
import org.atdl4j.ui.Atdl4jWidget;
import org.atdl4j.ui.StrategyPanelHelper;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.ExpandItem;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Layout;
/**
*
* Contains static SWT-specific methods to support building StrategyPanel
* container and related panel/composite redrawing.
*
* Creation date: (Mar 3, 2010 7:35:04 AM)
*
* @author Scott Atwell
* @version 1.0, Mar 3, 2010
*/
public class SWTStrategyPanelHelper
implements StrategyPanelHelper
{
private static final Logger logger = Logger.getLogger( SWTStrategyPanelHelper.class );
/**
* Invokes revalidateLayout() within Display.getCurrent().asyncExec(new
* Runnable() ... )
*
* @param aControl
*/
public static void revalidateLayoutAsync(ExpandBar anExpandBar)
{
SWTRelayoutExpandBarThread tempRevalidateLayoutThread = new SWTRelayoutExpandBarThread( anExpandBar );
tempRevalidateLayoutThread.start();
}
/**
* Helper method contributed on web:
* http://stackoverflow.com/questions/586414
* /why-does-an-swt-composite-sometimes
* -require-a-call-to-resize-to-layout-correctl
*
* @author http://stackoverflow.com/users/63293/peter-walser
* @param control
*/
// 3/13/2010 John Shields
// streamlined method to increase speed; previously was doing too much
// layout work which made the app very slow.
public static void relayoutExpandBar(ExpandBar expandBar)
{
relayoutExpandBar( expandBar, true );
}
public static void relayoutExpandBar(ExpandBar expandBar, boolean relayoutParents)
{
Composite c = expandBar;
int tempMaxControlX = 0;
logger.debug( "----- relayoutExpandBar (relayoutParents: " + relayoutParents + " expandBar: " + expandBar + " -----" );
do
{
logger.debug( "c: " + c.getClass() + " c.getParent(): " + c.getParent().getClass() );
if ( c instanceof ExpandBar )
{
ExpandBar eb = (ExpandBar) c;
logger.debug( "ExpandBar.getSize(): " + eb.getSize() );
for ( ExpandItem expandItem : eb.getItems() )
{
logger.debug( "expandItem: " + expandItem + " text: " + expandItem.getText() + " control: " + expandItem.getControl() + " controlLocation: " + expandItem.getControl().getLocation());
logger.debug( "before pack(): expandItem.getControl().getSize(): " + expandItem.getControl().getSize() );
expandItem.getControl().pack();
if ( expandItem.getControl().getSize().x > tempMaxControlX )
{
tempMaxControlX = expandItem.getControl().getSize().x;
}
logger.debug( "before: expandItem.getHeight(): " + expandItem.getHeight() + " expandItem.getControl().getSize(): " + expandItem.getControl().getSize() );
expandItem.setHeight( expandItem.getControl().computeSize( eb.getSize().x, SWT.DEFAULT, true ).y );
}
// -- Need to set ExpandBar's GridData.widthHint to the width of the widest control within it --
GridData tempGridData2 = (GridData) expandBar.getLayoutData();
tempGridData2.widthHint = tempMaxControlX;
// do not set height as ExpandBar handles this tempGridData2.heightHint = expandBar.getSize().y;
expandBar.setLayoutData( tempGridData2 );
if ( relayoutParents )
{
Control p = c.getParent();
if ( p instanceof ScrolledComposite )
{
ScrolledComposite scrolledComposite = (ScrolledComposite) p;
if ( scrolledComposite.getExpandHorizontal() || scrolledComposite.getExpandVertical() )
{
scrolledComposite.setMinSize( scrolledComposite.getContent().computeSize( SWT.DEFAULT, SWT.DEFAULT, true ) );
}
else
{
scrolledComposite.getContent().pack( true );
}
}
if ( p instanceof Composite )
{
Composite composite = (Composite) p;
composite.layout();
}
}
else
{
// -- this (or relayoutParents=true) is needed (otherwise ExampleStrategyPanelTests2.xml with 2 "columns" of StrategyPanels may not draw all of the ExpandBars initially) --
expandBar.getParent().layout();
}
}
c = c.getParent();
}
while ( c != null && c.getParent() != null && !( c instanceof ScrolledComposite ) );
// -- Needed to ensure that strategy panel is expanded vertically as panels go from collapsed to expanded
expandBar.getShell().layout();
expandBar.getShell().pack();
}
/**
* Builds the appropriate 'container' Composite for aStrategyPanel.
*
* Supports:
* - aStrategyPanel.isCollapsible() returning ExpandBar (collapsed state based upon aStrategyPanel.isCollapsed())
* - aStrategyPanel.getTitle() returning Group
* - aStrategyPanel.getBorder() of BorderT.LINE returning Group (without Text)
* - default returns Composite
*
* @param aStrategyPanel
* @param aParent
* @param aStyle
* @return
*/
public static Composite createStrategyPanelContainer(StrategyPanelT aStrategyPanel, Composite aParent, int aStyle)
{
Composite c;
// -- Check for Collapsible --
if ( aStrategyPanel.isCollapsible() )
{
ExpandBar tempExpandBar = new ExpandBar( aParent, SWT.NONE );
tempExpandBar.setSpacing( 1 );
//TODO if want to get rid of white background, likely want a border around whole thing...
//TODO tempExpandBar.setBackground( aParent.getBackground() );
if ( aParent.getLayout() instanceof GridLayout )
{
// mimics createStrategyPanelLayoutData() below
GridData tempGridData = new GridData( SWT.FILL, SWT.FILL, true, false );
tempGridData.horizontalSpan = 2; // same as createStrategyPanelLayoutData
tempGridData.horizontalAlignment = GridData.FILL; // occupy the full available horizontal width
tempExpandBar.setLayoutData( tempGridData );
}
Composite tempExpandBarComposite = new Composite( tempExpandBar, SWT.NONE );
// "c" is 'standard' composite containing StrategyPanel as Data
c = tempExpandBarComposite;
// -- since we're using GridLayout, need to force the aParent with that
// layout to resize via aParent.layout() when ExpandBar button is
// expanded/collapsed --
tempExpandBar.addExpandListener( new SWTExpandBarResizer( tempExpandBarComposite ) );
ExpandItem tempExpandItem = new ExpandItem( tempExpandBar, SWT.NONE, 0 );
if ( aStrategyPanel.getTitle() != null )
{
tempExpandItem.setText( aStrategyPanel.getTitle() );
}
tempExpandItem.setControl( tempExpandBarComposite );
// -- not very helpful in this context, we need revalidateLayout( c )
// executed _after_ the "c" component is loaded with Controls --
tempExpandItem.setHeight( tempExpandItem.getControl().computeSize( SWT.DEFAULT, SWT.DEFAULT ).y );
tempExpandItem.setExpanded( !aStrategyPanel.isCollapsed() );
}
// -- Check for titled border --
else if ( aStrategyPanel.getTitle() != null )
{
c = new Group( aParent, aStyle );
( (Group) c ).setText( aStrategyPanel.getTitle() );
}
// -- Check for Line border (no title) --
else if ( BorderT.LINE.equals( aStrategyPanel.getBorder() ) )
{
c = new Group( aParent, aStyle );
}
else
{
// -- normal, non-collapsible, non-bordered StrategyPanel --
c = new Composite( aParent, aStyle );
}
// -- Set the layout and layoutData for the SWT Composite containing the
// set of FIXatdl Controls --
c.setLayout( createStrategyPanelLayout( aStrategyPanel ) );
c.setLayoutData( createStrategyPanelLayoutData( c ) );
// -- Keep StrategyPanel in data object --
c.setData( aStrategyPanel );
return c;
}
/**
* Creates the layout for the SWT Composite containing the set of FIXatdl Controls
*
* @param c
* @return
*/
protected static Layout createStrategyPanelLayout(StrategyPanelT panel)
{
PanelOrientationT orientation = panel.getOrientation();
if ( orientation == PanelOrientationT.HORIZONTAL )
{
int parameterCount = panel.getControl() != null ? panel.getControl().size() : 0;
int panelCount = panel.getStrategyPanel() != null ? panel.getStrategyPanel().size() : 0;
// make 2 columns for each parameter and 1 column for each sub-panel
GridLayout l = new GridLayout( parameterCount * 2 + panelCount, false );
return l;
}
else if ( orientation == PanelOrientationT.VERTICAL )
{
// TODO ???? WHY TWO VS. ONE ????? GridLayout l = new GridLayout( 2, false );
// GridLayout l = new GridLayout( 1, false );
GridLayout l = new GridLayout( 2, false );
return l;
}
else
{
throw new IllegalStateException( "ERROR StrategyPanel (" + panel.getTitle() + ") is missing orientation attribute." );
}
}
/**
* Creates the layoutData for the SWT Composite containing the set of FIXatdl Controls
*
* @param c
* @return
*/
protected static Object createStrategyPanelLayoutData(Composite c)
{
// if parent is a strategy panel
if ( c.getParent().getData() instanceof StrategyPanelT )
{
GridData layoutData = new GridData( SWT.FILL, SWT.FILL, true, false );
c.setLayoutData( layoutData );
StrategyPanelT parentPanel = (StrategyPanelT) c.getParent().getData();
// if parent orientation is vertical, make this panel span 2 columns
if ( parentPanel.getOrientation() == PanelOrientationT.VERTICAL )
{
layoutData.horizontalSpan = 2;
}
return layoutData;
}
else if ( ( c.getParent() instanceof ExpandBar ) && ( c.getData() instanceof StrategyPanelT ) )
{
GridData layoutData = new GridData( SWT.FILL, SWT.FILL, true, false );
c.setLayoutData( layoutData );
StrategyPanelT parentPanel = (StrategyPanelT) c.getData();
// if parent orientation is vertical, make this panel span 2 columns
if ( parentPanel.getOrientation() == PanelOrientationT.VERTICAL )
{
layoutData.horizontalSpan = 2;
}
return layoutData;
}
return null;
}
/**
* Navigates through aWidget's getParent() looking for ExpandBar with ExpandItems not-yet-expanded and expands those
* @param aWidget
* @return boolean indicating whether any ExpandBar ExpandItems were adjusted
*/
public boolean expandAtdl4jWidgetParentStrategyPanel( Atdl4jWidget<?> aWidget )
{
boolean tempAdjustedFlag = false;
if ( ( aWidget.getParent() != null ) && ( aWidget.getParent() instanceof Composite ) )
{
Composite tempParent = (Composite) aWidget.getParent();
while ( tempParent != null )
{
// -- Expand if necessary --
if ( tempParent instanceof ExpandBar )
{
ExpandBar tempExpandBar = (ExpandBar) tempParent;
for ( ExpandItem tempExpandItem : tempExpandBar.getItems() )
{
if ( ! tempExpandItem.getExpanded() )
{
tempExpandItem.setExpanded( true );
// -- (relayoutParents=false) --
relayoutExpandBar( tempExpandBar, false );
tempAdjustedFlag = true;
}
}
}
// -- Iterate to next parent --
if ( ( tempParent.getParent() != null ) && ( ( tempParent.getParent() instanceof Composite ) ) )
{
tempParent = (Composite) tempParent.getParent();
}
else
{
break;
}
}
}
return tempAdjustedFlag;
}
}