Package org.carrot2.workbench.editors.impl.numeric

Source Code of org.carrot2.workbench.editors.impl.numeric.NumericRangeEditorBase

/*
* Carrot2 project.
*
* Copyright (C) 2002-2014, Dawid Weiss, Stanisław Osiński.
* All rights reserved.
*
* Refer to the full license file "carrot2.LICENSE"
* in the root folder of the repository checkout or at:
* http://www.carrot2.org/carrot2.LICENSE
*/

package org.carrot2.workbench.editors.impl.numeric;

import java.util.Map;

import org.carrot2.workbench.core.helpers.GUIFactory;
import org.carrot2.workbench.editors.*;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;

/**
* Common class for both floating point (with arbitrary precision of decimal digits) and
* integer, non-negative numeric ranges.
* <p>
* The widget is composed of a {@link Scale} and a {@link Spinner}, both of which can be
* used to modify the current value of the attribute.
*/
abstract class NumericRangeEditorBase extends AttributeEditorAdapter
{
    /** */
    private Scale scale;

    /** */
    private Spinner spinner;

    /**
     * A temporary flag used to avoid event looping.
     */
    private boolean duringSelection;

    /*
     * Numeric ranges.
     */

    private int min;
    private int max;
    private int precisionDigits;

    private int increment;
    private int pageIncrement;

    private boolean minBounded;
    private boolean maxBounded;

    /**
     * Value multiplier needed to convert between fixed precision floating point values
     * and integers.
     */
    private final double multiplier;

    /** Tooltip with allowed range. */
    private String tooltip;

    private int maxSpinnerWidth;

    /**
     * A copy of the current value of this editor. Added because it turns out
     * spinner widgets emit delayed events (and cause extra events to be fired because
     * they don't update their state immediately).
     */
    private int currentValue;

    /**
     * @param precisionDigits Number of digits after decimal separator.
     */
    public NumericRangeEditorBase(int precisionDigits)
    {
        this.precisionDigits = precisionDigits;
        this.multiplier = Math.pow(10, precisionDigits);
    }
   
    @Override
    protected AttributeEditorInfo init(Map<String,Object> defaultValues)
    {
        return new AttributeEditorInfo(2, false);
    }

    /**
     * Initialize numeric ranges, according to the descriptor's definition.
     */
    protected final void setRanges(int min, int max, int increment, int pageIncrement)
    {
        this.min = min;
        this.minBounded = (min != Integer.MIN_VALUE);

        this.max = max;
        this.maxBounded = (max != Integer.MAX_VALUE);

        this.increment = increment;
        this.pageIncrement = pageIncrement;

        if (!minBounded && !maxBounded)
        {
            this.tooltip = "Valid range: unbounded";
        }
        else
        {
            this.tooltip = "Valid range: [" + to_s(min) + "; " + to_s(max) + "]";
        }
    }

    /*
     * Return the current editor value.
     */
    @Override
    public Object getValue()
    {
        return currentValue;
    }

    /*
     *
     */
    @Override
    public void createEditor(Composite parent, int gridColumns)
    {
        final GridDataFactory factory = GUIFactory.editorGridData();

        final GridData spinnerLayoutData = factory.create();
        spinnerLayoutData.horizontalSpan = 1;
        spinnerLayoutData.grabExcessHorizontalSpace = false;
        spinnerLayoutData.verticalAlignment = SWT.CENTER;

        final GridData scaleLayoutData = factory.span(gridColumns - 1, 1).grab(true,
            false).create();

        if (minBounded && maxBounded)
        {
            createScale(parent);
            scale.setLayoutData(scaleLayoutData);
        }
        else
        {
            spinnerLayoutData.horizontalSpan = 2;
            spinnerLayoutData.grabExcessHorizontalSpace = true;
        }

        createSpinner(parent);

        spinner.setSelection(spinner.getMaximum());
        spinnerLayoutData.widthHint = maxSpinnerWidth;
        spinnerLayoutData.horizontalAlignment = SWT.FILL;

        spinner.setLayoutData(spinnerLayoutData);
    }

    /**
     * Create the scale control.
     */
    private void createScale(Composite holder)
    {
        scale = new Scale(holder, SWT.HORIZONTAL);
       
        scale.setMaximum(max);
        scale.setMinimum(min);
       
        scale.setIncrement(increment);
        scale.setPageIncrement(pageIncrement);
        scale.setToolTipText(tooltip);

        /*
         * Hook event listener to the scale component.
         */
        scale.addSelectionListener(new SelectionAdapter()
        {
            public void widgetSelected(SelectionEvent e)
            {
                if (scale.getSelection() != currentValue)
                    propagateNewValue(scale.getSelection());
            }
        });

        scale.addMouseWheelListener(new MouseWheelListener()
        {
            public void mouseScrolled(MouseEvent e)
            {
                if (scale.getSelection() != currentValue)
                    propagateNewValue(scale.getSelection());
            }
        });
    }

    /**
     * Create the spinner control.
     */
    private void createSpinner(Composite holder)
    {
        spinner = new Spinner(holder, SWT.BORDER);

        /*
         * Calculate maximum spinner width (consistently among all editors).
         */
        spinner.setMaximum(1000);
        spinner.setMinimum(0);
        spinner.setDigits(2);

        this.maxSpinnerWidth = spinner.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;

        /*
         * Now proceed with setting the actual values.
         */
       
        spinner.setMaximum(max);
        spinner.setMinimum(min);
        spinner.setSelection(min);
        spinner.setDigits(precisionDigits);
        spinner.setToolTipText(tooltip);

        if (minBounded && maxBounded)
        {
            spinner.setIncrement(increment);
            spinner.setPageIncrement(pageIncrement);
        }

        spinner.addSelectionListener(new SelectionAdapter()
        {
            public void widgetSelected(SelectionEvent e)
            {
                if (currentValue != spinner.getSelection())
                    propagateNewValue(spinner.getSelection());
            }
        });
    }

    /**
     * Propagates value change event to all listeners and updates
     * GUI widgets.
     */
    protected final void propagateNewValue(int value)
    {
        if (!this.duringSelection)
        {
            this.duringSelection = true;
            this.currentValue = value;

            if (spinner != null && spinner.getSelection() != value)
            {
                spinner.setSelection(value);
            }

            if (scale != null && scale.getSelection() != value)
            {
                scale.setSelection(value);
            }

            this.duringSelection = false;

            fireAttributeChanged(new AttributeEvent(this));
        }
    }

    /**
     * Convert between double values and integer values (taking into account precision
     * shift).
     */
    protected final int to_i(double v)
    {
        if (v == Double.MIN_VALUE)
        {
            return Integer.MIN_VALUE;
        }

        if (v == Double.MAX_VALUE)
        {
            return Integer.MAX_VALUE;
        }

        if (Double.isNaN(v))
        {
            return 0;
        }

        return (int) Math.round(v * multiplier);
    }

    /**
     * Convert between double values and integer values (taking into account precision
     * shift).
     */
    protected final double to_d(int i)
    {
        return i / multiplier;
    }

    /*
     * Converts the given argument to a human-readable string.
     */
    private String to_s(int v)
    {
        if (v == Integer.MIN_VALUE)
        {
            return "-\u221E";
        }
        else if (v == Integer.MAX_VALUE)
        {
            return "\u221E";
        }
        else
        {
            return String.format("%." + precisionDigits + "f", to_d(v));
        }
    }
}
TOP

Related Classes of org.carrot2.workbench.editors.impl.numeric.NumericRangeEditorBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.