javauis/lcdui_qt/src/javax/microedition/lcdui/GaugeLayouter.java
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 02 Sep 2010 20:20:40 +0300
changeset 69 773449708c84
parent 61 bf7ee68962da
permissions -rw-r--r--
Revision: v2.2.11 Kit: 201035

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package javax.microedition.lcdui;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.internal.extension.Style;
import org.eclipse.ercp.swt.mobile.CaptionedControl;


/**
 * Class for layouting gauges.
 */
class GaugeLayouter extends ItemLayouter
{

    /**
     * Key name for selection listener.
     */
    private static final String SELECTION_LISTENER = "SelectionListener";
    private static final String MAX_LABEL_DATA = "MaxLabel";
    private static final String CURRENT_LABEL_DATA = "CurrentLabel";


    /**
     * Constructor.
     *
     * @param aFormLayouter FormLayouter used for layouting.
     */
    GaugeLayouter(FormLayouter aFormLayouter)
    {
        super(aFormLayouter);
    }

    /**
     * Creates the eSWT ProgressBar/Slider for this item.
     */
    Control eswtGetControl(Composite parent, Item item)
    {
        return eswtCreateControl(parent, item);
    }

    /**
     * Construts a gauge control surrounded with composite.
     */
    static Control eswtCreateControl(Composite parent, Item item)
    {
        Gauge gauge = (Gauge) item;
        // create an owning composite every time
        Composite comp = new Composite(parent, SWT.NONE);
		FormLayout layout = new FormLayout();
		comp.setLayout(layout);

        if(gauge.isInteractive())
        {
            //Current Value Label
            Label currentlabel = new Label(comp, SWT.WRAP);
            currentlabel.setText(Integer.toString(gauge.getValue()));
            currentlabel.setAlignment(SWT.LEAD);
			currentlabel.setData(CURRENT_LABEL_DATA, CURRENT_LABEL_DATA);
			//Current Value Label Data
            FormData currLabelData = new FormData();
            currLabelData.left = new FormAttachment(0);
            currentlabel.setLayoutData(currLabelData);
			//Slider
            Slider slider = new Slider(comp, SWT.HORIZONTAL);
            slider.setMinimum(0);
            slider.setMaximum(gauge.getMaxValue());
            slider.setSelection(gauge.getValue());
            slider.setIncrement(1);
            slider.setPageIncrement(1);
			//Slider Data
            FormData sliderLayoutData = new FormData();
            sliderLayoutData.right = new FormAttachment(100);
            sliderLayoutData.left = new FormAttachment(currentlabel);
            slider.setLayoutData(sliderLayoutData);
            //Min Value Label
            Label minlabel = new Label(comp, SWT.WRAP);
            minlabel.setText("0");
            minlabel.setAlignment(SWT.LEAD);
			//Min Value Label Data
            FormData minLabelData = new FormData();
            minLabelData.left = new FormAttachment(slider, 0, SWT.LEFT);
            minLabelData.top =  new FormAttachment(slider);
            minlabel.setLayoutData(minLabelData);
            //Max Value Label
            Label maxlabel = new Label(comp, SWT.WRAP);
            maxlabel.setText(Integer.toString(gauge.getMaxValue()));
            maxlabel.setAlignment(SWT.LEAD);
			maxlabel.setData(MAX_LABEL_DATA, MAX_LABEL_DATA);
			//Max Value Label Data
            FormData maxLabelData = new FormData();
            maxLabelData.right = new FormAttachment(slider, 0, SWT.RIGHT);
            maxLabelData.top =  new FormAttachment(slider);
            maxlabel.setLayoutData(maxLabelData);
        }
        else
        {
            ProgressBar progressBar = null;
            if(gauge.isIndefinite())
            {
                switch(gauge.getValue())
                {
                case Gauge.CONTINUOUS_IDLE:
                    // TODO: eSWT support required
                    // Gauge like busy-state indicator with no activity:
                    progressBar = new ProgressBar(comp,
                                                  SWT.HORIZONTAL | SWT.INDETERMINATE);
                    break;
                case Gauge.CONTINUOUS_RUNNING:
                    // Gauge like busy-state indicator with continuous activity:
                    progressBar = new ProgressBar(comp,
                                                  SWT.HORIZONTAL | SWT.INDETERMINATE);
                    break;
                case Gauge.INCREMENTAL_IDLE:
                    // TODO: eSWT support required
                    // Gauge like icremental updating, but no activity.
                    progressBar = new ProgressBar(comp,
                                                  SWT.HORIZONTAL | SWT.INDETERMINATE);
                    break;
                case Gauge.INCREMENTAL_UPDATING:
                    // TODO: eSWT support required
                    //Gauge like icremental updating, with indefinite activity.
                    progressBar = new ProgressBar(comp,
                                                  SWT.HORIZONTAL | SWT.INDETERMINATE);
                    break;
                default:
                    // This is invalid case and should never occur, as Gauge should take care of it.
                    Logger.warning("Unexpected gauge value: " + gauge.getValue());
                    break;
                }
            }
            else
            {
                progressBar = new ProgressBar(comp, SWT.HORIZONTAL);
                progressBar.setMaximum(gauge.getMaxValue());
                progressBar.setSelection(gauge.getValue());
            }

			if(progressBar != null)
			{
				FormData progressBarData = new FormData();
				progressBarData.left = new FormAttachment(0);
				progressBarData.right = new FormAttachment(100);
				progressBar.setLayoutData(progressBarData);
			}
        }
		parent.pack();
        return parent;
    }

    /**
     * returns the matching data Label of Gauge control.
     */
	Label eswtGetDataLabel(Control control, String data)
	{
        Control ret = null;
		
        if(control instanceof Label)
        {
			if(data.equals((String)control.getData(data)))
            ret = control;
        }
        else if(control instanceof Composite)
        {
            Control[] children = ((Composite) control).getChildren();
            for(int i = 0; i < children.length; i++)
            {
                Control result = eswtGetDataLabel(children[i], data);
                if(result != null)
                {
                    ret = result;
                    break;
                }
            }
        }
        return (Label)ret;
	}

    /**
     * Set the size of the layouted Control.
     */
    void eswtResizeControl(Item item, Control control, int width, int height)
    {
		if((control instanceof Slider) || (control instanceof ProgressBar))
		{
			Control comp = control.getParent();
			Control capt = comp.getParent();
			comp.pack();
			Point size = comp.computeSize(width, comp.getBounds().height);
			comp.setSize(size.x, size.y);
			Point loc = comp.getLocation();
			if((height-size.y) != 0)
			{
				comp.setLocation(loc.x, loc.y + (height - size.y)/2);
			}
		}
    }

    /**
     * Add listeners to Layouter specific control.
     */
    void eswtAddSpecificListeners(Item item, Control control)
    {
    	if(control instanceof Slider)
   		{
	        Slider slider = (Slider)control;
			SelectionListener listener = (SelectionListener)slider.getData(SELECTION_LISTENER);
	        if(listener == null)
	        {
		        super.eswtAddSpecificListeners(item, control);
				Gauge gauge = (Gauge)item;
		        listener = new GaugeSelectionListener(gauge);
				slider.addSelectionListener(listener);
				slider.setData(SELECTION_LISTENER, listener);
	        }
    	}
    }

    /**
     * Remove listeners from Layouter specific control.
     */
    void eswtRemoveSpecificListeners(Item item, Control control)
    {
    	if(control instanceof Slider)
   		{
	        Slider slider = (Slider)control;
			SelectionListener listener = (SelectionListener)slider.getData(SELECTION_LISTENER);
	        if(listener != null)
	        {
		        super.eswtRemoveSpecificListeners(item, control);
				slider.removeSelectionListener(listener);
                slider.setData(SELECTION_LISTENER, null);
	        }
    	}
    }

    /**
     * Returns if this eSWT control is Layouter specific.
     */
    boolean eswtIsSpecificControl(Item item, Control control)
    {
        return((control instanceof Slider) || (control instanceof ProgressBar));
    }

    /**
     * Updates the values of Gauge.
     */
    void eswtUpdateItem(Item item, Control control, int aReason, Object param)
    {
		if(!(control instanceof  CaptionedControl))
		{
			return;
		}
		
		Gauge gauge = (Gauge)item;
		int reason = aReason & Item.UPDATE_SIZE_MASK;
		
		switch(reason)
		{
		case Item.UPDATE_NONE:
			break;
		
		case Item.UPDATE_LABEL:
		{
			String label = gauge.getLabel();
			if(label == null)
			{
				label = "";
			}
		
			((CaptionedControl)control).setText(label);
			control.pack();
			break;
		}
		
		case Gauge.UPDATE_VALUE:
		{
			//Setting the value to the control irrespective of the reason,
			//as trade of for reason filtration.
			Control ctrl = eswtFindSpecificControl(gauge, control);
		
			if(ctrl instanceof Slider)
			{
				Slider slider = (Slider)ctrl;
				slider.setSelection(gauge.getValue());
			}
			else if(ctrl instanceof ProgressBar)
			{
				ProgressBar progressbar = (ProgressBar)ctrl;
				progressbar.setSelection(gauge.getValue());
			}

			Label currLabel = eswtGetDataLabel(control, CURRENT_LABEL_DATA);
			if(currLabel != null)
			{
				currLabel.setText(Integer.toString(gauge.getValue()));
				currLabel.getParent().layout();
			}
			break;
		}
		
		case Gauge.UPDATE_MAXVALUE:
		{
			Control ctrl = eswtFindSpecificControl(gauge, control);
		
			if(ctrl instanceof Slider)
			{
				Slider slider = (Slider)ctrl;
				slider.setMaximum(gauge.getMaxValue());
			}
			else if(ctrl instanceof ProgressBar)
			{
				ProgressBar progressbar = (ProgressBar)ctrl;
				progressbar.setMaximum(gauge.getMaxValue());
			}

			Label maxLabel = eswtGetDataLabel(control, MAX_LABEL_DATA);
			if(maxLabel != null)
			{
				maxLabel.setText(Integer.toString(gauge.getMaxValue()));			
				maxLabel.getParent().layout();
			}

			Label currLabel = eswtGetDataLabel(control, CURRENT_LABEL_DATA);
			if(currLabel != null)
			{
				currLabel.setText(Integer.toString(gauge.getValue()));
			}
			break;
		}
		
		default:
		{
			break;
		}
		}

    }

    /**
     * Returns true if that key was consumed by Gauge.
     */
    boolean eswtOfferKeyPressed(Item item, int key)
    {
        Gauge gauge = (Gauge) item;
        if(gauge.isInteractive())
        {
            if(key == SWT.ARROW_RIGHT)
            {
            	if(gauge.getValue() != gauge.getMaxValue())
				{
	                gauge.internalSetValue(gauge.getValue() + 1);
	                gauge.setLayout(gauge.internalGetLayout());
					return true;
            	}

            }
            else if(key == SWT.ARROW_LEFT)
            {
            	if(gauge.getValue() > 0)
            	{
	                gauge.internalSetValue(gauge.getValue() - 1);
	                gauge.setLayout(gauge.internalGetLayout());
					return true;
            	}
            }
        }
        return false;
    }

    /**
     * Returns the minimum area needed to display a Gauge.
     *
     * @param gauge Gauge object.
     * @return Minimum area needed to display Gauge.
     */
    static Point calculateMinimumBounds(final Gauge gauge)
    {
	    final Point minSize = new Point(0, 0);
        ESWTUIThreadRunner.syncExec(new Runnable()
        {
            public void run()
            {
		        CaptionedControl captioned = new CaptionedControl(eswtGetStaticShell(), SWT.VERTICAL);
		        if(gauge.hasLabel())
		        {
			        captioned.setText(MIN_TEXT);
				}
		        eswtCreateControl(captioned, gauge);
				int maxWidth = getMaximumItemWidth(gauge);
		        Point size = captioned.computeSize(maxWidth, SWT.DEFAULT);
		        captioned.dispose();
		        minSize.x = size.x;
		        minSize.y = size.y;
            }
        });
		return minSize;
    }

    /**
     * Returns the preferred area needed to display an Item.
     *
     * @param item Item.
     * @return Preferred area needed to display Item. x is width
     *      and y is height.
     */
    static Point calculatePreferredBounds(final Gauge gauge)
    {
	    final Point prefSize = new Point(0, 0);
	    ESWTUIThreadRunner.syncExec(new Runnable()
	    {
	        public void run()
	        {
		        CaptionedControl captioned = new CaptionedControl(eswtGetStaticShell(), SWT.VERTICAL);
		        if(gauge.hasLabel())
		        {
			        captioned.setText(gauge.getLabel());
				}
		        eswtCreateControl(captioned, gauge);
				int maxWidth = getMaximumItemWidth(gauge);
		        Point size = captioned.computeSize(maxWidth, SWT.DEFAULT);
		        captioned.dispose();
		        prefSize.x = size.x;
		        prefSize.y = size.y;
	        }
	    });
		return prefSize;
    }

    /**
     * Class that receives events from slider and updates gauge's value.
     */
    class GaugeSelectionListener implements SelectionListener
    {
        private Gauge gauge;

        /**
         * Constructor.
         * @param gauge Gauge to be updated.
         */
        public GaugeSelectionListener(Gauge gauge)
        {
            this.gauge = gauge;
        }

        public void widgetDefaultSelected(SelectionEvent e)
		{
			Logger.method(this, "widgetDefaultSelected");
		}

        /**
         * Called by eSWT when Slider's value is changed.
         * Updates Gauge's value.
         */
        public void widgetSelected(SelectionEvent e)
        {
        	//Implement for other Gauge types with Commands
            int newValue = ((Slider) e.getSource()).getSelection();

            // Actions needed only if value is adjusted:
            if(newValue != gauge.getValue())
            {
                // set Gauge value
                gauge.internalSetValue(newValue);
                gauge.setLayout(gauge.internalGetLayout());
            }
        }
    }
}