Package guicomponents

Source Code of guicomponents.GWSlider

/*
*  Copyright notice
*  This file was created as part of the Processing library `gwoptics'
*  http://www.gwoptics.org/processing/gwoptics_p5lib/
*  Copyright (C) 2009 onwards Daniel Brown and Andreas Freise
*  It has been re-factored by Peter Lager to integrate it into the GUI
*  for Processing (G4P) library
*   http://www.lagers.org.uk/g4p/index.html
*  http://gui4processing.googlecode.com/svn/trunk/
*
*  Copyright (C) 2010 onwards Peter Lager
*  This library is free software; you can redistribute it and/or modify it under
*  the terms of the GNU Lesser General Public License version 2.1 as published
*  by the Free Software Foundation.
*  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
*  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU Lesser General Public License for more details.
*  You should have received a copy of the GNU Lesser General Public License along with
*  this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
*  Suite 330, Boston, MA 02111-1307 USA
*/

package guicomponents;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PImage;

/**
* <p>
* GWSlider is a wrapper class that extends the functionality of the gui4processing(g4p) slider. It adds a lot of
* functionality that is found in many other main stream sliders in other frameworks.
* </p>
*
* <p>
* The main change to the g4p slider was to introduce a more flexible and graphical interface to render the slider.
* The method used to render the slider is combining several images that relate to various segments of the slider
* in the form of a skin. The slider is broken down into 4 segments, each having a specific image file that relates
* to them:
* </p>
*
* <ul>
* <li>Left end cap of the slider(end_left.png)</li>
* <li>Right end cap of the slider(end_right.png)</li>
* <li>An extendible centre segment(centre.png)</li>
* <li>Draggable thumb (handle.png and handle_mouseover.png)</li>
* </ul>
*
* <p>
* The five images stated above define the skin that is applied to slider. A default skin is included in the library
* and applied when no other alternative is provided. To generate a skin all these images must be included into a
* folder in the sketches data directory, where the name of the folder is the name of the skin. When creating a new
* slider, there is a constructor available that allows you to specify the skin to use. Eg, if you have a folder name
* 'ShinyRedSkin' in your data directory that has the above images in, then pass a string with "ShinyRedSkin" to the
* constructor.
* </p>
*
* <p>
* The images need to related. The end_left, end_right and centre png's must all be the same height. The height can be
* whatever is required, though values round 20 is recommended. The end segments can both be different lengths and the
* length of the centre images must be 1 pixel. The centre image is stretched depending on the length of the slider to
* fill in the middle section. The thumb/handle can be any height and width but should be an odd number of pixels. An
* odd number allows a perfect centre to be found as fractional pixels are not possible. Alpha channel use is recommended
* to generate interesting skins.
* </p>
*
* <p>
* Also added to the slider is tick marks. The number of ticks shown is customisable and there is the option to stick the
* thumb to each tick. This only allows the thumb to take on certain values and positions. The ticks by default have only
* 2 labels, one showing the minimum and one the maximum. The other options are to have no tick labels or to specify a
* string array containing the labels.
* </p>
*
* <p>
* One of the more trickier features of the slider to understand is setting the type of the slider. By default the slider
* is set up to display and use integer values. On occasion it is useful to be able to specify a floating value range.
* When the slider is set to ValueType.Integer, any limits or values passed to the slider will be rounded to the nearest
* integer. If you later then switch to ValueType.Decimal or Exponential the limits and value will still be rounded.
* This can cause issues as the initial setting is ValueType.Integer, if you first set your floating limits and value then
* specify the type of the slider to be decimal, the decimal parts of the inputs will be lost. <b>Always specify the
* ValueType of the slider as soon as it is created</b>, this will save many headaches.
* </p>
*
* <p>
* Another confusing feature to the slider is the methods to retrieve the value of the slider. Initially the g4p slider
* only allowed an integer value. To get around this a new value member is defined as a float, where all the relevant
* methods are overridden to use this new value but to also update the old integer value. Unfortunately the getValue method
* is already predefined to return and integer, so a new getValuef() method is added to allow you to access the floating
* member. Either can be used but remember getValue() will always return a rounded value.
* </p>
*
* <p>
* The slider can also be controlled via the arrow keys on the keyboard for a finer adjustment. The slider must first
* have been given focus with the mouse before hand, before it will work.
* </p>
*
* <p>
* <b>NOTE: Handle/Thumb image should be an odd number of pixels wide so that it can correctly centre on tick marks.</b>
* </p>
*
* <p>
* History<br />
* Version 0.3.3 overhaul to how ticks are calculated and rendered, firstly calculating the difference in value
* between tick and then relating that into a distance in pixels, rather than dividing length of slider by tick
* number.
* </p>
*
* @author Daniel Brown 21/6/09
*
*/
public class GWSlider extends GSlider {

  // Unit of measurement e.g. amp, metre etc.
  public String unit;

  protected PImage _leftEnd;
  protected PImage _thumb;
  protected PImage _thumb_mouseover;
  protected PImage _rightEnd;
  protected PImage _centre;
  protected String _skin;
  protected int _numTicks;
  protected int _tickLength;
  protected int _tickOffset; 
  protected int _precision;
  protected boolean _renderMaxMinLabel;
  protected boolean _renderValueLabel;
  protected boolean _stickToTicks;
  protected String[] _tickLabels;
  protected boolean _isMouseOverThumb;
  protected boolean _mousePressedOverThumb;
  protected int[] _tickPositions;
  protected float[] _tickValues;
  protected int _tickColour; 
  protected int _fontColour; 

  // Mod made by Daniel 12/3/10
  protected int _currTickStuck; //Index of current index stuck to

  //setters
  /**
   * Sets the number of decimal places to print in the value labels
   */
  public void setPrecision(int acc){
    _precision = PApplet.constrain(acc, 0, 6);
  }

  /**
   * Sets the target value of the slider, if setInertia(x) has been used
   * to implement inertia then the actual slider value will gradually
   * change until it reaches the target value. The slider thumb is
   * always in the right position for the current slider value. <br>
   * <b>Note</b> that events will continue to be generated so if this
   * causes unexpected behaviour then use setValue(newValue, true)
   *
   * @param newValue the value we wish the slider to become
   */
  public void setValue(int newValue){
    value = PApplet.constrain(newValue, minValue, maxValue);
    thumbTargetPos = (int) PApplet.map(value, minValue, maxValue, thumbMin, thumbMax);
    if(_stickToTicks)
      _stickToTickByValue(value);
  }

  /**
   * Sets the target value of the slider, if setInertia(x) has been
   * to implement inertia then the actual slider value will gradually
   * change until it reaches the target value. The slider thumb is
   * always in the right position for the current slider value. <br>
   * <b>Note</b> that events will continue to be generated so if this
   * causes unexpected behaviour then use setValue(newValue, true)
   *
   * @param newValue the value we wish the slider to become
   */
  public void setValue(float newValue){
    value = PApplet.constrain(newValue, minValue, maxValue);
    thumbTargetPos = (int) PApplet.map(value, minValue, maxValue, thumbMin, thumbMax);
    if(_stickToTicks)
      _stickToTickByValue(value);
  }

  /**
   * Sets the target value of the slider according to the tick number.
   * If setInertia(x) has been to implement inertia then the actual
   * slider value will gradually change until it reaches the target
   * value. The slider thumb is always in the right position for the
   * current slider value. <br>
   * <b>Note</b> that events will continue to be generated so if this
   * causes unexpected behaviour then use setValue(newValue, true)
   *
   * @param tickNo >=0 and < number of ticks
   */
  public void setValueToTickNumber(int tickNo){
    if(_stickToTicks){
      tickNo = PApplet.constrain(tickNo, 0, _numTicks);
      float newValue = PApplet.map((float)tickNo, 0.0f, (float)_numTicks, minValue, maxValue);
      _stickToTickByValue(newValue);
    }   
  }

  /**
   * Sets the number of ticks shown on the slider. This will cancel any labels
   * previously set.
   */
  public void setTickCount(int nbrTicks){
    _numTicks = nbrTicks;
    _tickLabels = null;
    _calcTickPositions();
    // ***********************************************************
    if(_stickToTicks)
      _stickToTickByValue(value);
  }

  /**
   * Accepts an array of strings that then determines the number of ticks shown and the label
   * underneath each of them. This overrides any previous setting of the tick count and value
   * label rendering.
   * @param lbls
   */
  public void setTickLabels(String[] lbls){
    _tickLabels = lbls;
    _numTicks = lbls.length - 1;
    _calcTickPositions();
    // **********************************************************************
    if(_stickToTicks)
      _stickToTickByValue(value);
  }

  /**
   * Setting to true limits the thumb to only take values that each tick represents and no
   * value in between them
   */
  public void setStickToTicks(boolean stick){
    _stickToTicks = stick;
    if(stick){
      _stickToTickByValue(value);
    }
    _calcTickPositions();
  }

  /**
   * Adjusts the length of the ticks
   * @param l
   */
  public void setTickLength(int l){
    _tickLength = PApplet.constrain(l, 1, 10);
    _calcControlWidthHeight();
  }

  /**
   * set to false to not render the min/max labels for a more minamalistic look.
   */
  public void setRenderMaxMinLabel(boolean showMinMax){
    _renderMaxMinLabel = showMinMax;
    _calcControlWidthHeight();
  }

  /**
   * set to false to not render the value label for a more minamalistic look.
   */
  public void setRenderValueLabel(boolean showValue){
    _renderValueLabel = showValue;
  }

  /**
   * Set the colour of the ticks
   *
   * @param R red (0-255)
   * @param G green (0-255)
   * @param B blue (0-255)
   */
  public void setTickColour(int R,int G, int B){
    setTickColour(winApp.color(R,G,B));
  }

  /**
   * Set the colour of the ticks
   *
   * @param c the colour value as calculated by the PApplet color() method.
   */
  public void setTickColour(int c){
    _tickColour = c;
  }

  /**
   * Set the colour of the font
   *
   * @param R red (0-255)
   * @param G green (0-255)
   * @param B blue (0-255)
   */
  public void setFontColour(int R, int G, int B){
    setFontColour(winApp.color(R,G,B));
  }

  /**
   * Set the colour of the font
   *
   * @param c the colour value as calculated by the PApplet color() method.
   */
  public void setFontColour(int c){
    _fontColour = c;
  }

  /**
   * basic constructor that applies the default library skin to the slider. Accepts 
   * the x and y position of the slider, the PApplet theApplet where the slider is 
   * rendered and the length of the slider.
   *
   * @param theApplet
   * @param x
   * @param y
   * @param length
   */
  public GWSlider(PApplet theApplet, int x, int y, int length) {
    this(theApplet,"gwSlider",x,y,length);
  }

  /**
   * Alternative constructor that applies a given skin to the slider. Accepts the x and y
   * position of the slider, the PApplet theApplet where the slider is rendered and the length
   * of the slider. Throws GUIException if the necessary skin images are not present.
   *
   * @param theApplet
   * @param x
   * @param y
   * @param length
   */
  public GWSlider(PApplet theApplet, String skin, int x, int y, int length) {
    super(theApplet, x, y);
  //  super(theApplet, x, y, length, 1); //we reset the height later when we get the image heights

    this.width = length;
    this.height = 1;
    z = Z_SLIPPY;

//    if(length < 1){throw new RuntimeException("Length of slider must be greater than 0.");}

    //Here we set a bunch of default values for everything
    if(skin == null)
      _skin = "gwSlider";
    else
      _skin = skin;

    _numTicks = 5;
    _tickLength = 5;
    _tickOffset = 3;
    _renderMaxMinLabel = true;
    _renderValueLabel = true;
    _stickToTicks = false;
    _precision = 2;
    _valueType = INTEGER;
    _tickColour = winApp.color(0);
    _fontColour = winApp.color(0);

    unit = "";

    // Look for the skin images, if these don't exist the variable come out null
    // no exceptions are thrown
    _leftEnd = winApp.loadImage(_skin + "/end_left.png");
    _rightEnd = winApp.loadImage(_skin + "/end_right.png");
    _thumb = winApp.loadImage(_skin +"/handle.png");
    _thumb_mouseover = winApp.loadImage(_skin +"/handle_mouseover.png");
    //load the centre image up temporarily as we will generate the final stretched
    //image to use shortly
    PImage cTemp = winApp.loadImage(_skin + "/centre.png");

    String files = "";

    //generate a list of files that aren't there
    if(_leftEnd == null)
      files += "end_left.png\n";
    if(_rightEnd == null)
      files += "end_right.png\n";
    if(_thumb == null)
      files += "handle.png\n";
    if(_thumb_mouseover == null)
      files += "handle_mouseover.png\n";
    if(cTemp == null)
      files += "centre.png\n";

    // See if we have problems with the skin files
    if(files != ""){
      PApplet.println("The following files could not be found for the skin " + _skin + ": \n" + files
          + "\nCheck that these files are correctly placed in the data directory under a folder with"
          + " the same name as the skin used.\n");
    }
    if(cTemp.width != 1){
      PApplet.println("The supplied centre image for this skin is not of width 1px.");
    }
    if(cTemp.height != _leftEnd.height || cTemp.height != _rightEnd.height){
      PApplet.println("The image components of the slider are not all the same height.");
    }

    this.height = cTemp.height;
    int cWidth = length - _leftEnd.width - _rightEnd.width;
    if(cWidth < 0){cWidth = 1;}

    _centre = new PImage(cWidth,cTemp.height);

    //now copy over the data from cTemp to main centre image
    //the standard PImage stretch method is no good in this case
    //appears better to do it manually.
    cTemp.loadPixels();
    _centre.loadPixels();

    for (int i = 0; i < _centre.height; i++) {
      for (int j = 0; j < _centre.width; j++) {
        _centre.pixels[i*_centre.width +j] = cTemp.pixels[i];
      }
    }
    _centre.updatePixels();
    cTemp.updatePixels();
   
    //the thumb only moves along the centre section
    thumbMin = _leftEnd.width;
    thumbMax = _leftEnd.width + _centre.width;
    this.setLimits(50.0f, 0.0f, 100.0f);

    localFont = globalFont;

    _calcControlWidthHeight();
    _calcTickPositions();
    z = Z_SLIPPY;
   
    //signs up to the g4p events system
    createEventHandler(G4P.mainWinApp, "handleSliderEvents", new Class[]{ GSlider.class });
 
    registerAutos_DMPK(true, true, true, false);
  }

  /**
   * the width of the control and height, is determined by the length and also
   * the various images used in the skins. This function deals with that. It is
   * important as the width and height values define the bounding box around the
   * slider. This then helps determine if mouse clicks are relevant to this slider
   * or not.
   */
  protected void _calcControlWidthHeight(){
    //width is determined by image sizes
    width = _leftEnd.width + _centre.width + _rightEnd.width;
    height =  _centre.height + _tickLength + _tickOffset;

    if(_renderMaxMinLabel){height += localFont.getSize();}
  }

  /**
   * The tick positions are stored in an array and referenced on each draw call.
   * It is done this way to provide a more accurate way of lining up the ticks and
   * the thumb when stick to ticks is enabled
   */
  protected void _calcTickPositions(){
    Point p = new Point();
    calcAbsPosition(p);

    float sliderRange = maxValue - minValue;
    float dTick = sliderRange / _numTicks; //distance in terms of value

    _tickPositions = new int[_numTicks + 1];
    _tickValues = new float[_numTicks + 1];

    for(int i = 0; i <= _numTicks;i++){
      _tickPositions[i] = Math.round(PApplet.map(minValue + i * dTick, minValue, maxValue, thumbMin, thumbMax));
      _tickValues[i] = minValue + i * dTick;
    }
  }

  /**
   * This method takes a value that is to represented on the slider and determines which
   * tick it is closet to and sets the thumb at the relevant position
   * @param v
   */
  protected void _stickToTickByValue(float v){
    float sliderRange = maxValue - minValue;
    float dTick = sliderRange / _numTicks; //distance in terms of value

    int index = Math.round(PApplet.constrain(v - minValue, 0, sliderRange) / dTick);

    _currTickStuck = PApplet.constrain(index, 0,  _numTicks);
    thumbTargetPos = _tickPositions[_currTickStuck];

    value = minValue +_currTickStuck * dTick;
  }


  /**
   * This method accepts an input value that states a screen position(usually from a
   * mouse click) and determines the nearest tick marks to stick the thumb to
   * @param pos
   */
  protected void _stickToTickByPosition(float pos){
    Point p = new Point();
    calcAbsPosition(p);

    float sliderRange = maxValue - minValue;
    float dTick = sliderRange / _numTicks; //distance in terms of value
    float v = PApplet.map(pos, thumbMin, thumbMax, minValue, maxValue);

    int index = Math.round((v - minValue) / dTick);

    _currTickStuck = PApplet.constrain(index, 0, _tickPositions.length-1);
    thumbTargetPos = _tickPositions[_currTickStuck];
  }


  /**
   * handles all the mouse events that may effect the slider. depending on mouse position and action
   * the focus is set to the slider and the relevant function and members set.
   */
  @Override
  public void mouseEvent(MouseEvent event){
    if(!visible || !enabled) return;

    boolean isMouseOver = false;
    boolean isMouseOverThumb = false;
    // Is mouse over the slider?
    isMouseOver = this.isOver(event.getX(), event.getY());
    // If it is over slider then check to see if it is over thumb
    if(isMouseOver){
      isMouseOverThumb = isOverThumb(event.getX(), event.getY());
      if(isMouseOverThumb || focusIsWith == this)
        cursorIsOver = this;
      else if(cursorIsOver == this)
        cursorIsOver = null;
    }
    else {
      cursorIsOver = (cursorIsOver == this) ? null : cursorIsOver;
    }

    Point p = new Point();
    calcAbsPosition(p);

    switch (event.getID()) {
    case MouseEvent.MOUSE_PRESSED:
      if(focusIsWith != this && isMouseOver && z > focusObjectZ()) { // && isMouseOverThumb){
        this.takeFocus();
        _mousePressedOverThumb = isMouseOverThumb;
      }
      break;
    case MouseEvent.MOUSE_RELEASED: // OK as long as we have focus
      if(focusIsWith == this){  // && isMouseOverThumb || (_mousePressedOverThumb == true)){
        if(_stickToTicks){
          _stickToTickByPosition(winApp.mouseX - p.x);
        }
        else {
          thumbTargetPos  = PApplet.constrain(winApp.mouseX - p.x, thumbMin, thumbMax);
        }
        loseFocus(null);
        eventType = RELEASED;
        fireEvent();
      }
      _isMouseOverThumb = false;
      _mousePressedOverThumb = false;
      break;
    case MouseEvent.MOUSE_DRAGGED:
      if(focusIsWith == this && _mousePressedOverThumb){
        thumbTargetPos  = PApplet.constrain(winApp.mouseX - p.x , thumbMin, thumbMax);
        isValueChanging = true;
      }
      break;
    case MouseEvent.MOUSE_MOVED:
      if(isOverThumb(event.getX(), event.getY())){
        _isMouseOverThumb = true;
      }
      else
        _isMouseOverThumb = false;
      break;
    } // end of switch
  }

  /**
   * Registered key event of parent object, checks if arrow keys are being pressed and has focus
   * if so the thumb is moved one pixel.
   */
  public void keyEvent(KeyEvent e){
    if(e.getID() == KeyEvent.KEY_PRESSED && this.hasKeyFocus()){
      if(e.getKeyCode()== 37){ //left arrow
        if(_stickToTicks){     
          _currTickStuck = PApplet.constrain(_currTickStuck - 1, 0, _tickPositions.length-1);
          thumbTargetPos = _tickPositions[_currTickStuck];
        }else
          thumbTargetPos = PApplet.constrain(thumbTargetPos - 1,thumbMin,thumbMax);
      }else if(e.getKeyCode()== 39){ //right arrow
        if(_stickToTicks){
          _currTickStuck = PApplet.constrain(_currTickStuck + 1, 0, _tickPositions.length-1);
          thumbTargetPos = _tickPositions[_currTickStuck];
        }else
          thumbTargetPos = PApplet.constrain(thumbTargetPos + 1,thumbMin,thumbMax);     
      }
    }
  }


  /**
   * returns whether the positions supplied is over the mouse or not
   */
  @Override
  public boolean isOver(int ax, int ay){
    Point p = new Point(0,0);
    calcAbsPosition(p);
    float val = (float) (_centre.height * 0.5 - _thumb.height * 0.5); //takes into account if the thumbs height
    //is greater than the central bar image
    if(ax >= p.x && ax <= p.x + width && ay >= (p.y + val) && ay <= (p.y + height - val))
      return true;
    else
      return false;
  }

  /**
   * return whether input position is over the thumb, used to determine whether to show the
   * handle_mouseover image
   * @param ax
   * @param ay
   * @return true if the position ax,ay is over the thumb
   */
  public boolean isOverThumb(int ax, int ay){   
    Point p = new Point(0,0);
    calcAbsPosition(p);
    Rectangle r = new Rectangle((int)(p.x + thumbPos  - 0.5*_thumb.width - 1),
        (int)(p.y + 0.5*_centre.height -  0.5*_thumb.height -1),
        (int)(_thumb.width + 1),
        (int)(_thumb.height + 1));

    if(r.contains(ax, ay))
      return true;
    else
      return false;
  }

  /**
   * Sets font of labels
   */
  public void setFont(String fontname, int fontsize){
    localFont = GFont.getFont(winApp, fontname, fontsize);
  }

  @Override
  public void draw(){   
    if(!visible) return;
    String format = null;

    //depending on slider type we want to format the
    //labels as necessary
    switch(_valueType){
    case INTEGER:
      format = "%d%s";
      break;
    case DECIMAL:
      format = "%." + _precision + "f%s";
      break;
    case EXPONENT:
      format = "%." + _precision + "E%s";
      break;
    }

    winApp.pushStyle();

    //calculates the absolute position, this is
    //for when the slider is embedded in other panels and controls
    Point p = new Point();
    calcAbsPosition(p);
   
    //draw each of the slider skin images
    winApp.imageMode(CORNER);

    if(_leftEnd != null)
      winApp.image(_leftEnd, p.x, p.y);
    if(_centre != null)
      winApp.image(_centre, p.x + _leftEnd.width, p.y);
    if(_rightEnd != null)
      winApp.image(_rightEnd, p.x + _leftEnd.width + _centre.width, p.y);

    winApp.textFont(localFont);
    winApp.textAlign(PConstants.CENTER);

    //calc a few tick variables for drawing
    float tickDist =  (_centre.width )/(float)_numTicks;
    winApp.stroke(_tickColour);
    winApp.strokeWeight(1);
    winApp.fill(_fontColour);
    //draw ticks
    float tickYPos = p.y + _centre.height + _tickOffset + _tickLength + localFont.getSize();

    for(int i = 0;i < _tickPositions.length;i++){
      if(_tickLabels != null){
        Point pos = new Point(_tickPositions[i],(int) tickYPos);
        winApp.text(_tickLabels[i],p.x + pos.x,pos.y);
      }else if(i == 0 && _renderMaxMinLabel){
        //Draw in the min value
        Point pos = new Point(p.x + _leftEnd.width + Math.round(i * tickDist),p.y + _centre.height + _tickOffset + _tickLength + localFont.getSize()) ;
        if(_valueType == INTEGER)
          winApp.text(String.format(format,Math.round(minValue),unit),pos.x,pos.y);
        else
          winApp.text(String.format(format,minValue,unit),pos.x,pos.y);

      }else if(i == _numTicks && _renderMaxMinLabel){ 
        //Draw in the max value     
        Point pos = new Point(p.x + _leftEnd.width + Math.round(i * tickDist),p.y + _centre.height + _tickOffset + _tickLength + localFont.getSize()) ;
        if(_valueType == INTEGER)
          winApp.text(String.format(format,Math.round(maxValue),unit),pos.x,pos.y);
        else
          winApp.text(String.format(format,maxValue,unit),pos.x,pos.y);
      }

      winApp.beginShape(LINE);
      winApp.vertex(p.x + _tickPositions[i], p.y + _centre.height + _tickOffset);
      winApp.vertex(p.x + _tickPositions[i], p.y + _centre.height + _tickOffset + _tickLength);
      winApp.endShape();

      //draws a highlight line next to the black line, gives a more
      //3d feel to the control
      winApp.pushStyle();
      winApp.stroke(230);
      winApp.beginShape(LINE);
      winApp.vertex(p.x + _tickPositions[i] + 1, p.y + _centre.height + _tickOffset);
      winApp.vertex(p.x + _tickPositions[i] + 1, p.y + _centre.height + _tickOffset + _tickLength);
      winApp.endShape();
      winApp.popStyle();
      if(_thumb != null){
        if(!_isMouseOverThumb)
          winApp.image(_thumb, p.x + thumbPos - Math.round(_thumb.width*0.5) + 1, (float) (p.y + 0.5*_centre.height - 0.5*_thumb.height));
        else
          winApp.image(_thumb_mouseover, p.x + thumbPos - Math.round(_thumb_mouseover.width*0.5) + 1, (float) (p.y + 0.5*_centre.height - 0.5*_thumb_mouseover.height));
      }
      if(_renderValueLabel){
        if(_valueType == INTEGER)
          winApp.text(String.format(format,Math.round(value),unit),p.x + thumbPos, p.y - _thumb.height*0.5f + 0.5f*_centre.height - 4 );
        else
          winApp.text(String.format(format,value,unit),p.x + thumbPos, p.y - _thumb.height*0.5f + 0.5f*_centre.height - 4 );
      }
    }     
    winApp.popStyle();
  }

}
TOP

Related Classes of guicomponents.GWSlider

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.