    001package org.vishia.gral.base;
    002
    003import org.vishia.gral.ifc.GralSetValue_ifc;
    004
    005/**This is a common base class for a ValueBar-widget.
    006 * It is designed as a container for the widget. The widget itself is derived from the graphical base class,
    007 * for example from org.eclipse.swt.widgets.Canvas if the SWT-graphic is used,
    008 * or from java.awt.canvas if Swing is used.
    009 * @author Hartmut Schorrig
    010 *
    011 */
    012public class GralValueBar extends GralWidget implements GralSetValue_ifc
    013{
    014
    015  /**Version, history and license.
    016   * <ul>
    017   * <li>2014-02-11 Hartmut new: new Widget concept
    018   * <li>2010-06-00 Hartmut created
    019   * </ul>
    020   *
    021   * <b>Copyright/Copyleft</b>:<br>
    022   * For this source the LGPL Lesser General Public License,
    023   * published by the Free Software Foundation is valid.
    024   * It means:
    025   * <ol>
    026   * <li> You can use this source without any restriction for any desired purpose.
    027   * <li> You can redistribute copies of this source to everybody.
    028   * <li> Every user of this source, also the user of redistribute copies
    029   *    with or without payment, must accept this license for further using.
    030   * <li> But the LPGL is not appropriate for a whole software product,
    031   *    if this source is only a part of them. It means, the user
    032   *    must publish this part of source,
    033   *    but doesn't need to publish the whole source of the own product.
    034   * <li> You can study and modify (improve) this source
    035   *    for own using or for redistribution, but you have to license the
    036   *    modified sources likewise under this LGPL Lesser General Public License.
    037   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
    038   * </ol>
    039   * If you intent to use this source without publishing its usage, you can get
    040   * a second license subscribing a special contract with the author.
    041   *
    042   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
    043   */
    044  public static final int version = 20140211;
    045
    046        protected float minRange = 0.0F, maxRange = 100.0F;
    047
    048        protected float[] fLevels;
    049
    050        protected String[] sColorLevels;
    051
    052
    053
    054        public GralValueBar(String name)
    055        { super(name, 'U');
    056        }
    057
    058
    059        @Override
    060        public void setMinMax(float minValue, float maxValue)
    061        {
    062                minRange = minValue;
    063          maxRange = maxValue;
    064        }
    065
    066        /**Associates values to level and color.
    067   * <ul>
    068   * <li>The first and the last String is the min and max values.
    069   * <li>All odd Strings (0, 2, ...) are values, the following String is the color.
    070   * <li>For example {"-100","red","0","green","100","orange", "200"}
    071   * </ul>
    072   * The example shows a value bar from -100 to 200. A value < 0 is shown red, >100 is shown organge.
    073   * This form of parameter allows a simple preparation from a simple String,
    074   * for example <pre>
    075   * String param = "-100,red,0,green,100,orange,200";
    076   * String[] sParam = param.tokenize(",");
    077   *
    078         * @param sParam Even number of Strings.
    079         *
    080         */
    081        public void setBorderAndColors(String[] sParam)
    082        {
    083                int zParam = sParam.length;
    084                //the first and the last value are the border:
    085                minRange = Float.parseFloat(sParam[0]);
    086                maxRange = Float.parseFloat(sParam[zParam-1]);
    087                fLevels = new float[zParam/2];
    088                sColorLevels = new String[zParam/2];
    089                int ixBorder = 0;
    090                for(int ix = 1; ix < zParam; ix +=2){
    091            sColorLevels[ixBorder] = sParam[ix];
    092            fLevels[ixBorder] = Float.parseFloat(sParam[ix+1]);
    093            ixBorder +=1;
    094                }
    095                if(_wdgImpl !=null){
    096                  ((GraphicImplAccess)_wdgImpl).setBorderAndColorsImpl(sColorLevels);
    097                }
    098        }
    099
    100
    101        /**Sets the bar and its color. A refresh of graphic is only done if the value change forces
    102         * a change of pixel positions of the value bar. Less changes of value does not force refresh.
    103         * @see org.vishia.gral.base.GralWidget#setValue(float)
    104         */
    105        @Override public void setValue(float value)
    106        {
    107                if(_wdgImpl !=null){
    108                  if(((GraphicImplAccess)_wdgImpl).setValue(value)) {
    109        this.repaint();
    110                  }
    111                }
    112        }
    113
    114
    115        public static class ColorValues
    116        {
    117                float[] border;
    118                int[] color;
    119        }
    120
    121
    122  public abstract class GraphicImplAccess extends GralWidget.ImplAccess
    123  implements GralWidgImpl_ifc
    124  {
    125
    126
    127    /**Values of the level borders */
    128    protected int[] pixLevel;
    129
    130    public boolean horizontal;
    131
    132    /**The values in Pixel between the colored bar is shown. */
    133    protected int pix0line, pixvalue = 50;
    134
    135    protected int ixColor;
    136
    137    protected GraphicImplAccess(GralMng mng)
    138    {
    139      super(GralValueBar.this, mng);
    140      if(GralValueBar.this.sColorLevels !=null){
    141        setBorderAndColorsImpl(GralValueBar.this.sColorLevels);
    142      }
    143    }
    144
    145
    146    /**Sets the pixel values
    147     * @param valueP
    148     * @return true if a pixel value is changed. Only then refresh is necessary.
    149     */
    150    protected boolean setValue(float valueP)
    151    {
    152      final boolean chg;
    153      int value1, value2;
    154      int pixMax = horizontal ? pixBounds.dx : pixBounds.dy;
    155      value1 = (int)(pixMax * ((0.0F - minRange)/ (maxRange - minRange)));  //the 0-value
    156      value2 = (int)(pixMax * ((valueP - minRange) / (maxRange - minRange)));
    157      if(value1 < 0){ value1 = 0;}
    158      if(value1 > pixMax){ value1 = pixMax; }
    159      if(value2 < 0){ value2 = 0;}
    160      if(value2 > pixMax){ value2 = pixMax; }
    161      chg = this.pix0line !=value1 || this.pixvalue !=value2;
    162      if(chg) {
    163        this.pix0line = value1;
    164        this.pixvalue = value2;
    165        float level1 = minRange;
    166        //check in which range the value is assigned, set ixColor
    167        if(fLevels !=null)
    168        for(ixColor = 0; ixColor < fLevels.length -1; ++ixColor){
    169          float level2 = fLevels[ixColor];
    170          if(  level1 < level2 && level1 <= valueP && valueP < level2
    171            || level1 > level2 && level2 <= valueP && valueP < level1
    172            )
    173          break; //found
    174          level1 = level2;
    175        }
    176      }
    177      return chg;
    178    }
    179
    180
    181    abstract public void setBorderAndColorsImpl(String[] sColorLevels);
    182
    183    protected boolean horizontal(){ return horizontal; }
    184
    185    protected int ixColor(){ return ixColor; }
    186
    187    protected int pix0line(){ return pix0line; }
    188
    189    protected int pixvalue(){ return pixvalue; }
    190
    191  }
    192
    193
    194}