package org.atdl4j.ui.swt.widget;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import org.atdl4j.data.converter.DecimalConverter;
import org.atdl4j.data.converter.IntegerConverter;
import org.atdl4j.fixatdl.layout.DoubleSpinnerT;
import org.atdl4j.fixatdl.layout.SingleSpinnerT;
import org.atdl4j.ui.impl.ControlHelper;
import org.atdl4j.ui.swt.util.SWTNullableSpinner;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;
public class SWTSpinnerWidget
extends AbstractSWTWidget<BigDecimal>
{
private SWTNullableSpinner spinner;
private Label label;
private Button buttonUp;
private Button buttonDown;
/**
* SelectionListener that implements the dual spinner behavior.
*
*/
public class DoubleSpinnerSelection
implements SelectionListener
{
private SWTNullableSpinner spinner;
private BigDecimal increment;
public DoubleSpinnerSelection(SWTNullableSpinner spinner2, BigDecimal increment)
{
this.spinner = spinner2;
this.increment = increment;
}
public void widgetDefaultSelected(SelectionEvent event)
{
}
public void widgetSelected(SelectionEvent event)
{
spinner.increment( increment );
}
}
public Widget createWidget(Composite parent, int style)
{
String tooltip = getTooltip();
GridData controlGD = new GridData( SWT.FILL, SWT.FILL, false, false );
// label
if ( control.getLabel() != null ) {
label = new Label( parent, SWT.NONE );
label.setText( control.getLabel() );
if ( tooltip != null ) label.setToolTipText( tooltip );
controlGD.horizontalSpan = 1;
} else {
controlGD.horizontalSpan = 2;
}
if ( control instanceof SingleSpinnerT )
{
/*** 12/8/2010 Scott Atwell -- before border consumed space 'to the right' of the spinner box and buttons
// spinner
spinner = new SWTNullableSpinner( parent, style | SWT.BORDER );
spinner.setLayoutData( controlGD );
***/
Composite tempSpinnerComposite = new Composite( parent, SWT.NONE );
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
gridLayout.horizontalSpacing = 0;
gridLayout.verticalSpacing = 0;
tempSpinnerComposite.setLayout( gridLayout );
tempSpinnerComposite.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
// spinner
spinner = new SWTNullableSpinner( tempSpinnerComposite, SWT.BORDER );
spinner.setLayoutData( controlGD );
}
else if ( control instanceof DoubleSpinnerT )
{
// doubleSpinnerGrid
Composite c = new Composite( parent, SWT.NONE );
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
gridLayout.horizontalSpacing = 0;
gridLayout.verticalSpacing = 0;
c.setLayout( gridLayout );
c.setLayoutData( controlGD );
// doubleSpinner
spinner = new SWTNullableSpinner( c, style | SWT.BORDER );
GridData spinnerData = new GridData( SWT.FILL, SWT.CENTER, false, false );
spinnerData.verticalSpan = 2;
spinner.setLayoutData( spinnerData );
this.buttonUp = new Button( c, SWT.ARROW | SWT.UP );
this.buttonDown = new Button( c, SWT.ARROW | SWT.DOWN );
if ( tooltip != null ) {
buttonUp.setToolTipText( tooltip );
buttonDown.setToolTipText( tooltip );
}
}
// tooltip
if ( tooltip != null ) spinner.setToolTipText( tooltip );
// Set min/max/precision if a parameter is attached
if ( parameterConverter != null && parameterConverter instanceof DecimalConverter )
{
DecimalConverter tempDecimalConverter = (DecimalConverter) parameterConverter;
if ( tempDecimalConverter.getPrecision() != null )
{
spinner.setDigits( tempDecimalConverter.getPrecision().intValue() );
}
else
{
spinner.setDigits( ControlHelper.getDefaultDigitsForSpinnerControl( parameterConverter.getParameter(), getAtdl4jOptions() ) );
}
if ( tempDecimalConverter.getMinValue() != null )
{
// -- need to handle Percentage ("control value" representation) --
BigDecimal tempParameterMin = tempDecimalConverter.getMinValue();
BigDecimal tempControlMin = tempDecimalConverter.convertParameterValueToControlValue( tempParameterMin );
spinner.setMinimum( tempControlMin.setScale( spinner.getDigits(), RoundingMode.HALF_UP ) );
}
if ( tempDecimalConverter.getMaxValue() != null )
{
// -- need to handle Percentage ("control value" representation) --
BigDecimal tempParameterMax = tempDecimalConverter.getMaxValue();
BigDecimal tempControlMax = tempDecimalConverter.convertParameterValueToControlValue( tempParameterMax );
spinner.setMaximum( tempControlMax.setScale( spinner.getDigits(), RoundingMode.HALF_UP ) );
}
}
else if ( parameterConverter != null && parameterConverter instanceof IntegerConverter )
{
IntegerConverter tempIntegerConverter = (IntegerConverter) parameterConverter;
// -- Integer always has 0 digits --
spinner.setDigits( 0 );
if ( tempIntegerConverter.getMinValue() != null )
{
BigInteger tempParameterMin = tempIntegerConverter.getMinValue();
BigInteger tempControlMin = tempIntegerConverter.convertParameterValueToControlValue( tempParameterMin );
spinner.setMinimum( new BigDecimal( tempControlMin ) );
}
else
{
spinner.setMinimum( SWTNullableSpinner.MIN_INTEGER_VALUE_AS_BIG_DECIMAL );
}
if ( tempIntegerConverter.getMaxValue() != null )
{
BigInteger tempParameterMax = tempIntegerConverter.getMaxValue();
BigInteger tempControlMax = tempIntegerConverter.convertParameterValueToControlValue( tempParameterMax );
spinner.setMaximum( new BigDecimal( tempControlMax ) );
}
else
{
spinner.setMaximum( SWTNullableSpinner.MAX_INTEGER_VALUE_AS_BIG_DECIMAL );
}
}
if ( control instanceof DoubleSpinnerT )
{
BigDecimal tempInnerIncrement = ControlHelper.getInnerIncrementValue( control, getAtdl4jOptions(), spinner.getDigits() );
if ( tempInnerIncrement != null )
{
// -- Handle initValue="2.5" and ensure that we don't wind up using BigDecimal unscaled and end up with "25" --
spinner.setIncrement( tempInnerIncrement );
}
BigDecimal outerStepSize = new BigDecimal( "1" );
BigDecimal tempOuterIncrement = ControlHelper.getOuterIncrementValue( control, getAtdl4jOptions() );
if ( tempOuterIncrement != null )
{
outerStepSize = tempOuterIncrement;
}
buttonUp.addSelectionListener( new DoubleSpinnerSelection( spinner, outerStepSize ) );
buttonDown.addSelectionListener( new DoubleSpinnerSelection( spinner, outerStepSize.negate() ) );
}
else if ( control instanceof SingleSpinnerT )
{
BigDecimal tempIncrement = ControlHelper.getIncrementValue( control, getAtdl4jOptions(), spinner.getDigits() );
if ( tempIncrement != null )
{
// -- Handle initValue="2.5" and ensure that we don't wind up using BigDecimal unscaled and end up with "25" --
spinner.setIncrement( tempIncrement );
}
else // tempIncrement is null
{
if ( spinner.getDigits() != 0 )
{
// -- Set the increment to the precision associated with digits (eg ".01" when digits=2, ".001" when digits=3) --
spinner.setIncrement( new BigDecimal( Math.pow( 10, -spinner.getDigits() ) ).setScale( spinner.getDigits(), RoundingMode.HALF_UP ) );
}
else
{
spinner.setIncrement( new BigDecimal( "1" ) );
}
}
}
applyInitialValue();
return parent;
}
public BigDecimal getControlValueRaw()
{
try
{
return spinner.getValue();
}
catch (NumberFormatException e)
{
return null;
}
}
public void setValue(BigDecimal value)
{
spinner.setValue( value );
}
public List<Control> getControls()
{
List<Control> widgets = new ArrayList<Control>();
if (label != null) widgets.add( label );
widgets.add( spinner );
if ( control instanceof DoubleSpinnerT )
{
widgets.add( buttonUp );
widgets.add( buttonDown );
}
return widgets;
}
public List<Control> getControlsExcludingLabel()
{
List<Control> widgets = new ArrayList<Control>();
widgets.add( spinner );
if ( control instanceof DoubleSpinnerT )
{
widgets.add( buttonUp );
widgets.add( buttonDown );
}
return widgets;
}
public void addListener(Listener listener)
{
spinner.addListener( listener );
if ( control instanceof DoubleSpinnerT )
{
buttonUp.addListener( SWT.Selection, listener );
buttonDown.addListener( SWT.Selection, listener );
}
}
public void removeListener(Listener listener)
{
spinner.removeListener( listener );
if ( control instanceof DoubleSpinnerT )
{
buttonUp.removeListener( SWT.Selection, listener );
buttonDown.removeListener( SWT.Selection, listener );
}
}
/* (non-Javadoc)
* @see org.atdl4j.ui.Atdl4jWidget#reinit()
*/
@Override
public void processReinit( Object aControlInitValue )
{
if ( ( spinner != null ) && ( ! spinner.isDisposed() ) )
{
applyInitialValue();
}
}
/**
* Invokes spinner.setSelection() assigning
* - Control/@initValue if non-null
* - Parameter/@minValue if non-null
* - otherwise 0
*/
protected void applyInitialValue()
{
Double initValue = (Double) ControlHelper.getInitValue( control, getAtdl4jOptions() );
if ( initValue != null )
{
// -- Handle initValue="2.5" and ensure that we don't wind up using BigDecimal unscaled and end up with "25" --
setValue( new BigDecimal( initValue ) );
}
//TODO 12/15/2010 Scott Atwell added
else
{
setValue( null );
}
}
/*
*
*/
protected void processNullValueIndicatorChange(Boolean aOldNullValueInd, Boolean aNewNullValueInd)
{
// TODO ?? adjust the visual appearance of the control ??
}
}