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}