Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
4241982b6This file is pinned to the selected release. Download the original to open it in your design tool.
package controlP5;
/**
* controlP5 is a processing gui library.
*
* 2006-2012 by Andreas Schlegel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
* 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
*
* @author Andreas Schlegel (http://www.sojamo.de)
* @modified 07/30/2015
* @version 2.2.5
*
*/
import java.util.ArrayList;
import java.util.logging.Level;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PVector;
import controlP5.ControlP5.Invisible;
/**
* A range slider works just like a slider but can be adjusted on both ends.
*
* @see Slider
* @example controllers/ControlP5range
* @nosuperclasses Controller Controller
*/
public class Range extends Controller< Range > {
/* TODO if range value is int, value labels do initialize as floats. first click makes them
* display as ints without decimal point */
protected static final int HORIZONTAL = 0;
protected static final int VERTICAL = 1;
protected int _myDirection;
protected float _myValuePosition;
protected boolean isDragging;
protected boolean isDraggable = true;
protected boolean isFirstClick;
protected Label _myHighValueLabel;
protected float _myValueRange;
protected boolean isMinHandle;
protected boolean isMaxHandle;
protected boolean isMoveHandle;
protected float distanceHandle;
protected int handleSize = 10;
protected int minHandle = 0;
protected int maxHandle = 0;
protected int mr = 0;
protected final ArrayList< TickMark > _myTickMarks = new ArrayList< TickMark >( );
protected boolean isShowTickMarks;
protected boolean isSnapToTickMarks;
public static int autoWidth = 99;
public static int autoHeight = 9;
public static PVector autoSpacing = new PVector( 0 , 5 , 0 );
public int alignValueLabel = CENTER;
protected int _myColorTickMark = 0xffffffff;
private int mode = -1;
/**
* Convenience constructor to extend Range.
*
* @example use/ControlP5extendController
* @param theControlP5
* @param theName
*/
public Range( ControlP5 theControlP5 , String theName ) {
this( theControlP5 , theControlP5.getDefaultTab( ) , theName , 0 , 100 , 0 , 100 , 0 , 0 , 99 , 9 );
theControlP5.register( theControlP5.papplet , theName , this );
}
/**
*
* @param theControlP5 ControlP5
* @param theParent ControllerGroup
* @param theName String
* @param theMin float
* @param theMax float
* @param theDefaultValue float
* @param theX int
* @param theY int
* @param theWidth int
* @param theHeight int
*/
@ControlP5.Invisible public Range( ControlP5 theControlP5 , ControllerGroup< ? > theParent , String theName , float theMin , float theMax , float theDefaultMinValue , float theDefaultMaxValue , int theX , int theY , int theWidth , int theHeight ) {
super( theControlP5 , theParent , theName , theX , theY , theWidth , theHeight );
_myArrayValue = new float[] { theDefaultMinValue , theDefaultMaxValue };
_myMin = theMin;
_myMax = theMax;
_myValueRange = _myMax - _myMin;
minHandle = ( int ) PApplet.map( theDefaultMinValue , _myMin , _myMax , handleSize , getWidth( ) - handleSize );
maxHandle = ( int ) PApplet.map( theDefaultMaxValue , _myMin , _myMax , handleSize , getWidth( ) - handleSize );
mr = maxHandle - minHandle;
_myCaptionLabel = new Label( cp5 , theName ).setColor( color.getCaptionLabel( ) ).align( RIGHT_OUTSIDE , CENTER );
_myValueLabel = new Label( cp5 , "" + adjustValue( _myMin ) ).setColor( color.getValueLabel( ) ).set( "" + adjustValue( theDefaultMinValue ) ).align( LEFT , CENTER );
_myHighValueLabel = new Label( cp5 , adjustValue( _myMax ) ).setColor( color.getValueLabel( ) ).set( "" + adjustValue( theDefaultMaxValue ) ).align( RIGHT , CENTER );
_myValue = theDefaultMinValue;
_myDirection = HORIZONTAL;
update( );
}
@Override public Range setColorValueLabel( int theColor ) {
_myValueLabel.setColor( theColor );
_myHighValueLabel.setColor( theColor );
return this;
}
@Override public Range setColorCaptionLabel( int theColor ) {
_myCaptionLabel.setColor( theColor );
return this;
}
public Range setHighValueLabel( final String theLabel ) {
_myHighValueLabel.set( theLabel );
return this;
}
public Range setLowValueLabel( final String theLabel ) {
_myValueLabel.set( theLabel );
return this;
}
@ControlP5.Invisible public Range setSliderMode( int theMode ) {
return this;
}
public Range setHandleSize( int theSize ) {
handleSize = theSize;
setLowValue( _myArrayValue[ 0 ] , false );
setHighValue( _myArrayValue[ 1 ] , false );
mr = maxHandle - minHandle;
return this;
}
@ControlP5.Invisible public Range updateInternalEvents( PApplet theApplet ) {
if ( isVisible ) {
int c = _myControlWindow.mouseX - _myControlWindow.pmouseX;
if ( c == 0 ) {
return this;
}
if ( isMousePressed && !cp5.isAltDown( ) ) {
switch ( mode ) {
case ( LEFT ):
minHandle = PApplet.max( handleSize , PApplet.min( maxHandle , minHandle + c ) );
break;
case ( RIGHT ):
maxHandle = PApplet.max( minHandle , PApplet.min( getWidth( ) - handleSize , maxHandle + c ) );
break;
case ( CENTER ):
minHandle = PApplet.max( handleSize , PApplet.min( getWidth( ) - mr - handleSize , minHandle + c ) );
maxHandle = PApplet.max( minHandle , PApplet.min( getWidth( ) - handleSize , minHandle + mr ) );
break;
}
update( );
}
}
return this;
}
@Override @Invisible public void mousePressed( ) {
final float posX = x( _myParent.getAbsolutePosition( ) ) + x( position );
final float posY = y( _myParent.getAbsolutePosition( ) ) + y( position );
if ( _myControlWindow.mouseY < posY || _myControlWindow.mouseY > posY + getHeight( ) ) {
mode = -1;
isMinHandle = isMaxHandle = false;
return;
}
int x0 = ( int ) ( posX + minHandle );
int x1 = ( int ) ( posX + maxHandle );
if ( _myControlWindow.mouseX >= x0 - handleSize && _myControlWindow.mouseX < x0 ) {
mode = LEFT;
isMinHandle = true;
} else if ( _myControlWindow.mouseX >= x1 && _myControlWindow.mouseX < x1 + handleSize ) {
mode = RIGHT;
isMaxHandle = true;
} else if ( _myControlWindow.mouseX > x0 && _myControlWindow.mouseX < x1 && isDraggable ) {
mode = CENTER;
}
}
/**
* set the value of the range-slider. to set the low and high value, use setLowValue and
* setHighValue or setRangeValues
*
* @see #setLowValue(float)
* @see #setHighValue(float)
* @see #setRangeValues(float, float)
*
* @param theValue float
* @return Range
*/
@Override @ControlP5.Invisible public Range setValue( float theValue ) {
_myValue = theValue;
broadcast( ARRAY );
return this;
}
/**
* @exclude
*/
@Override @ControlP5.Invisible public Range update( ) {
_myArrayValue[ 0 ] = PApplet.map( minHandle , handleSize , getWidth( ) - handleSize , _myMin , _myMax );
_myArrayValue[ 1 ] = PApplet.map( maxHandle , handleSize , getWidth( ) - handleSize , _myMin , _myMax );
mr = maxHandle - minHandle;
_myHighValueLabel.set( adjustValue( _myArrayValue[ 1 ] ) );
_myValueLabel.set( adjustValue( _myArrayValue[ 0 ] ) );
return setValue( _myValue );
}
@ControlP5.Invisible public Range setDraggable( boolean theFlag ) {
isDraggable = theFlag;
isDragging = ( theFlag == false ) ? false : isDragging;
return this;
}
public float[] getArrayValue( ) {
return _myArrayValue;
}
@Override public Range setArrayValue( float[] theArray ) {
setLowValue( theArray[ 0 ] , false );
setHighValue( theArray[ 1 ] , false );
return update( );
}
@Override public Range setMin( float theValue ) {
_myMin = theValue;
_myValueRange = _myMax - _myMin;
return setLowValue( _myArrayValue[ 0 ] );
}
@Override public Range setMax( float theValue ) {
_myMax = theValue;
_myValueRange = _myMax - _myMin;
return setHighValue( _myArrayValue[ 1 ] );
}
public float getLowValue( ) {
return _myArrayValue[ 0 ];
}
public float getHighValue( ) {
return _myArrayValue[ 1 ];
}
@Override public Range setWidth( int theValue ) {
super.setWidth( theValue );
return this;
}
@Override public Range setHeight( int theValue ) {
super.setHeight( theValue );
return this;
}
@Override @ControlP5.Invisible public void mouseReleased( ) {
isDragging = isMinHandle = isMaxHandle = isMoveHandle = false;
mode = -1;
}
@Override @ControlP5.Invisible public void mouseReleasedOutside( ) {
mouseReleased( );
}
@Override @ControlP5.Invisible public void onLeave( ) {
isMinHandle = false;
isMaxHandle = false;
}
protected void setTickMarks( ) {
System.out.println( "Range Tickmarks not yet supported" );
}
public Range setColorTickMark( int theColor ) {
_myColorTickMark = theColor;
return this;
}
public Range showTickMarks( boolean theFlag ) {
isShowTickMarks = theFlag;
return this;
}
public Range snapToTickMarks( boolean theFlag ) {
isSnapToTickMarks = theFlag;
System.out.println( "Range Tickmarks not yet supported" );
return this;
}
@ControlP5.Invisible public TickMark getTickMark( ) {
System.out.println( "Range Tickmarks not yet supported" );
return null;
}
public ArrayList< TickMark > getTickMarks( ) {
return _myTickMarks;
}
public Range setNumberOfTickMarks( int theNumber ) {
System.out.println( "Range Tickmarks not yet supported" );
_myTickMarks.clear( );
if ( theNumber > 0 ) {
for ( int i = 0 ; i < theNumber ; i++ ) {
_myTickMarks.add( new TickMark( this ) );
}
showTickMarks( true );
snapToTickMarks( true );
} else {
showTickMarks( false );
snapToTickMarks( false );
}
_myUnit = ( _myMax - _myMin ) / ( ( getWidth( ) > getHeight( ) ) ? getWidth( ) - 1 : getHeight( ) - 1 );
setLowValue( _myArrayValue[ 0 ] , false );
setHighValue( _myArrayValue[ 1 ] , false );
return update( );
}
public Range setRange( float theMinValue , float theMaxValue ) {
setMin( theMinValue );
setMax( theMaxValue );
return this;
}
public Range setRangeValues( float theLowValue , float theHighValue ) {
return setArrayValue( new float[] { theLowValue , theHighValue } );
}
private Range setLowValue( float theValue , boolean isUpdate ) {
_myArrayValue[ 0 ] = PApplet.max( _myMin , snapValue( theValue ) );
minHandle = ( int ) PApplet.map( _myArrayValue[ 0 ] , _myMin , _myMax , handleSize , getWidth( ) - handleSize );
return ( isUpdate ) ? update( ) : this;
}
public Range setLowValue( float theValue ) {
return setLowValue( theValue , true );
}
private Range setHighValue( float theValue , boolean isUpdate ) {
_myArrayValue[ 1 ] = PApplet.min( _myMax , snapValue( theValue ) );
maxHandle = ( int ) PApplet.map( _myArrayValue[ 1 ] , _myMin , _myMax , handleSize , getWidth( ) - handleSize );
return ( isUpdate ) ? update( ) : this;
}
public Range setHighValue( float theValue ) {
return setHighValue( theValue , true );
}
protected float snapValue( float theValue ) {
if ( isMousePressed ) {
return theValue;
}
if ( isSnapToTickMarks ) {
_myValuePosition = ( ( theValue - _myMin ) / _myUnit );
float n = PApplet.round( PApplet.map( _myValuePosition , 0 , ( _myDirection == HORIZONTAL ) ? getWidth( ) : getHeight( ) , 0 , _myTickMarks.size( ) - 1 ) );
theValue = PApplet.map( n , 0 , _myTickMarks.size( ) - 1 , _myMin , _myMax );
}
return theValue;
}
@Override @ControlP5.Invisible public Range updateDisplayMode( int theMode ) {
_myDisplayMode = theMode;
switch ( theMode ) {
case ( DEFAULT ):
_myControllerView = new RangeView( );
break;
case ( SPRITE ):
_myControllerView = new RangeSpriteView( );
break;
case ( IMAGE ):
_myControllerView = new RangeImageView( );
break;
case ( CUSTOM ):
default:
break;
}
return this;
}
class RangeSpriteView implements ControllerView< Range > {
public void display( PGraphics theGraphics , Range theController ) {
ControlP5.logger( ).log( Level.INFO , "RangeSpriteDisplay not available." );
}
}
class RangeView implements ControllerView< Range > {
public void display( PGraphics theGraphics , Range theController ) {
int high = mode;
final float posX = x( _myParent.getAbsolutePosition( ) ) + x( position );
int x0 = ( int ) ( posX + minHandle );
int x1 = ( int ) ( posX + maxHandle );
if ( isInside( ) && high < 0 ) {
if ( _myControlWindow.mouseX >= x0 - handleSize && _myControlWindow.mouseX < x0 ) {
high = LEFT;
} else if ( _myControlWindow.mouseX >= x1 && _myControlWindow.mouseX < x1 + handleSize ) {
high = RIGHT;
} else if ( _myControlWindow.mouseX > x0 && _myControlWindow.mouseX < x1 && isDraggable ) {
high = CENTER;
}
}
theGraphics.pushMatrix( );
theGraphics.fill( color.getBackground( ) );
theGraphics.noStroke( );
theGraphics.rect( 0 , 0 , getWidth( ) , getHeight( ) );
theGraphics.fill( high == CENTER ? color.getActive( ) : color.getForeground( ) );
if ( isShowTickMarks ) {
int n = handleSize / 2;
theGraphics.rect( minHandle - n , 0 , mr + handleSize , getHeight( ) );
theGraphics.fill( ( isMinHandle || high == LEFT ) ? color.getActive( ) : color.getForeground( ) );
theGraphics.triangle( minHandle - handleSize , 0 , minHandle , 0 , minHandle - n , getHeight( ) );
theGraphics.fill( ( isMaxHandle || high == RIGHT ) ? color.getActive( ) : color.getForeground( ) );
theGraphics.triangle( maxHandle , 0 , maxHandle + handleSize , 0 , maxHandle + n , getHeight( ) );
} else {
theGraphics.rect( minHandle , 0 , mr , getHeight( ) );
theGraphics.fill( ( isMinHandle || high == LEFT ) ? color.getActive( ) : color.getForeground( ) );
theGraphics.rect( ( minHandle - handleSize ) , 0 , handleSize , getHeight( ) );
theGraphics.fill( ( isMaxHandle || high == RIGHT ) ? color.getActive( ) : color.getForeground( ) );
theGraphics.rect( maxHandle , 0 , handleSize , getHeight( ) );
}
if ( isLabelVisible ) {
_myCaptionLabel.draw( theGraphics , 0 , 0 , theController );
_myValueLabel.draw( theGraphics , 0 , 0 , theController );
_myHighValueLabel.draw( theGraphics , 0 , 0 , theController );
}
theGraphics.popMatrix( );
if ( isShowTickMarks ) {
theGraphics.pushMatrix( );
float x = ( getWidth( ) - handleSize ) / ( getTickMarks( ).size( ) - 1 );
theGraphics.translate( handleSize / 2 , getHeight( ) );
theGraphics.fill( _myColorTickMark );
for ( TickMark tm : getTickMarks( ) ) {
tm.draw( theGraphics );
theGraphics.translate( x , 0 );
}
theGraphics.popMatrix( );
}
}
}
class RangeImageView implements ControllerView< Range > {
public void display( PGraphics theGraphics , Range theController ) {
ControlP5.logger( ).log( Level.INFO , "RangeImageDisplay not implemented." );
}
}
@Override @ControlP5.Invisible public String toString( ) {
return "type:\tRange\n" + super.toString( );
}
@Deprecated public float lowValue( ) {
return getLowValue( );
}
@Deprecated public float highValue( ) {
return getHighValue( );
}
@Deprecated public float[] arrayValue( ) {
return _myArrayValue;
}
}