mirror of https://github.com/sojamo/controlp5
437 lines
11 KiB
Java
Executable File
437 lines
11 KiB
Java
Executable File
package controlP5;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import processing.core.PApplet;
|
|
import processing.core.PGraphics;
|
|
import processing.core.PVector;
|
|
|
|
/**
|
|
* A tooltip can be registered for individual controllers
|
|
* and is activated on rollover.
|
|
*
|
|
* @example controllers/ControlP5tooltip
|
|
*
|
|
*/
|
|
public class Tooltip {
|
|
|
|
private ControllerView< ? > _myView;
|
|
private PVector position = new PVector( );
|
|
private PVector currentPosition = new PVector( );
|
|
private PVector previousPosition = new PVector( );
|
|
private PVector offset = new PVector( );
|
|
private Controller< ? > _myController;
|
|
private long startTime = 0;
|
|
private long _myDelayInMillis = 500;
|
|
private int _myMode = ControlP5.INACTIVE;
|
|
private int _myHeight = 20;
|
|
private int _myBackgroundColor = 0xffffffb4;
|
|
private int _myMaxAlpha = 255;
|
|
private int _myAlpha = 0;
|
|
private Map< Controller< ? > , String > map;
|
|
private Label _myLabel;
|
|
private boolean enabled = true;
|
|
private int _myBorder;
|
|
private ControlP5 cp5;
|
|
private int _myAlignH = ControlP5.RIGHT;
|
|
private int _myColor = 0x00000000;
|
|
|
|
Tooltip( ControlP5 theControlP5 ) {
|
|
cp5 = theControlP5;
|
|
position = new PVector( -1000 , -1000 );
|
|
currentPosition = new PVector( );
|
|
previousPosition = new PVector( );
|
|
offset = new PVector( 0 , 24 , 0 );
|
|
map = new HashMap< Controller< ? > , String >( );
|
|
_myLabel = new Label( cp5 , "tooltip" );
|
|
_myLabel.setColor( _myColor );
|
|
_myLabel.setPadding( 0 , 0 );
|
|
setView( new TooltipView( ) );
|
|
setBorder( 4 );
|
|
}
|
|
|
|
/**
|
|
* sets the border of the tooltip, the default border is
|
|
* 4px.
|
|
*
|
|
* @param theValue
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setBorder( int theValue ) {
|
|
_myBorder = theValue;
|
|
_myLabel.getStyle( ).setMargin( _myBorder , _myBorder , _myBorder , _myBorder );
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* returns the value of the border
|
|
*
|
|
* @return
|
|
*/
|
|
public int getBorder( ) {
|
|
return _myBorder;
|
|
}
|
|
|
|
/**
|
|
* sets the transparency of the default background,
|
|
* default value is 200
|
|
*
|
|
* @param theValue
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setAlpha( int theValue ) {
|
|
_myMaxAlpha = theValue;
|
|
return this;
|
|
}
|
|
|
|
private void updateText( String theText ) {
|
|
int n = 1;
|
|
for ( char c : theText.toCharArray( ) ) {
|
|
if ( c == '\n' ) {
|
|
n++;
|
|
}
|
|
}
|
|
if ( _myLabel.getHeight( ) != _myLabel.getLineHeight( ) * n ) {
|
|
_myLabel.setHeight( _myLabel.getLineHeight( ) * n );
|
|
}
|
|
_myLabel.set( theText );
|
|
}
|
|
|
|
/**
|
|
* TODO see below
|
|
* @param theWindow
|
|
*/
|
|
void draw( ControlWindow theWindow ) {
|
|
/*
|
|
if ( enabled ) {
|
|
|
|
if ( _myMode >= ControlP5.WAIT ) {
|
|
|
|
previousPosition.set( currentPosition );
|
|
currentPosition.set( theWindow.mouseX , theWindow.mouseY , 0 );
|
|
|
|
if ( _myController != null ) {
|
|
if ( _myController.getControlWindow( ).equals( theWindow ) ) {
|
|
switch ( _myMode ) {
|
|
case ( ControlP5.WAIT ):
|
|
if ( moved( ) ) {
|
|
startTime = System.nanoTime( );
|
|
}
|
|
|
|
if ( System.nanoTime( ) > startTime + ( _myDelayInMillis * 1000000 ) ) {
|
|
|
|
position.set( currentPosition );
|
|
_myAlignH = ControlP5.RIGHT;
|
|
if ( position.x > ( _myController.getControlWindow( ).papplet( ).width - ( getWidth( ) + 20 ) ) ) {
|
|
position.sub( new PVector( getWidth( ) , 0 , 0 ) );
|
|
_myAlignH = ControlP5.LEFT;
|
|
}
|
|
_myMode = ControlP5.FADEIN;
|
|
startTime = System.nanoTime( );
|
|
_myAlpha = 0;
|
|
}
|
|
break;
|
|
case ( ControlP5.FADEIN ):
|
|
float t1 = System.nanoTime( ) - startTime;
|
|
_myAlpha = ( int ) PApplet.map( t1 , 0 , 200 * 1000000 , 0 , _myMaxAlpha );
|
|
if ( _myAlpha >= 250 ) {
|
|
_myMode = ControlP5.IDLE;
|
|
_myAlpha = 255;
|
|
}
|
|
break;
|
|
case ( ControlP5.IDLE ):
|
|
break;
|
|
case ( ControlP5.FADEOUT ):
|
|
float t2 = System.nanoTime( ) - startTime;
|
|
_myAlpha = ( int ) PApplet.map( t2 , 0 , 200 * 1000000 , _myMaxAlpha , 0 );
|
|
if ( _myAlpha <= 0 ) {
|
|
_myMode = ControlP5.DONE;
|
|
}
|
|
break;
|
|
case ( ControlP5.DONE ):
|
|
_myController = null;
|
|
_myMode = ControlP5.INACTIVE;
|
|
position.set( -1000 , -1000 , 0 );
|
|
}
|
|
|
|
_myAlpha = PApplet.max( 0 , PApplet.min( _myAlpha , _myMaxAlpha ) );
|
|
|
|
if ( _myMode >= ControlP5.WAIT ) {
|
|
_myAlpha = ( _myMode == ControlP5.WAIT ) ? 0 : _myAlpha;
|
|
theWindow.papplet( ).pushMatrix( );
|
|
theWindow.papplet( ).translate( position.x , position.y );
|
|
theWindow.papplet( ).translate( offset.x , offset.y );
|
|
// TODO should request the current PGraphics element, not only the PApplet context. What if we render into a PGraphics buffer?
|
|
_myView.display( theWindow.papplet( ).g , null );
|
|
theWindow.papplet( ).popMatrix( );
|
|
}
|
|
if ( _myMode < ControlP5.FADEOUT ) {
|
|
if ( moved( ) ) {
|
|
deactivate( 0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
private boolean moved( ) {
|
|
return PApplet.abs( PApplet.dist( previousPosition.x , previousPosition.y , currentPosition.x , currentPosition.y ) ) > 1;
|
|
}
|
|
|
|
/**
|
|
* A tooltip is activated when entered by the mouse,
|
|
* after a given delay time the Tooltip starts to fade
|
|
* in. Use setDelay(long) to adjust the default delay
|
|
* time of 1000 millis.
|
|
*
|
|
* @param theMillis
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setDelay( long theMillis ) {
|
|
_myDelayInMillis = theMillis;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* a Tooltip is activated when the mouse enters a
|
|
* controller.
|
|
*
|
|
* @param theController
|
|
*/
|
|
protected void activate( Controller< ? > theController ) {
|
|
if ( map.containsKey( theController ) ) {
|
|
startTime = System.nanoTime( );
|
|
_myController = theController;
|
|
currentPosition.set( theController.getControlWindow( ).mouseX , theController.getControlWindow( ).mouseY , 0 );
|
|
updateText( map.get( _myController ) );
|
|
_myMode = ControlP5.WAIT;
|
|
}
|
|
}
|
|
|
|
protected void deactivate( ) {
|
|
deactivate( 1 );
|
|
}
|
|
|
|
protected void deactivate( int theNum ) {
|
|
if ( theNum == 0 ) {
|
|
if ( _myMode >= ControlP5.IDLE ) {
|
|
if ( _myMode < ControlP5.FADEOUT )
|
|
startTime = System.nanoTime( );
|
|
_myMode = ControlP5.FADEOUT;
|
|
}
|
|
} else {
|
|
_myMode = ( _myMode >= ControlP5.IDLE ) ? ControlP5.FADEOUT : ControlP5.DONE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A custom view can be set for a Tooltip. The default
|
|
* view class can be found at the bottom of the Tooltip
|
|
* source.
|
|
*
|
|
* @see controlP5.ControllerView
|
|
* @param theDisplay
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setView( ControllerView< ? > theDisplay ) {
|
|
_myView = theDisplay;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* registers a controller with the Tooltip, when
|
|
* activating the tooltip for a particular controller,
|
|
* the registered text (second parameter) will be
|
|
* displayed.
|
|
*
|
|
* @param theController
|
|
* @param theText
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip register( Controller< ? > theController , String theText ) {
|
|
map.put( theController , theText );
|
|
theController.registerProperty( "setTooltipEnabled" , "isTooltipEnabled" );
|
|
return this;
|
|
}
|
|
|
|
public Tooltip register( String theControllerName , String theText ) {
|
|
Controller< ? > c = cp5.getController( theControllerName );
|
|
if ( c == null ) {
|
|
return this;
|
|
}
|
|
map.put( c , theText );
|
|
c.registerProperty( "setTooltipEnabled" , "isTooltipEnabled" );
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* removes a controller from the tooltip
|
|
*
|
|
* @param theController
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip unregister( Controller< ? > theController ) {
|
|
map.remove( theController );
|
|
theController.removeProperty( "setTooltipEnabled" , "isTooltipEnabled" );
|
|
return this;
|
|
}
|
|
|
|
public Tooltip unregister( String theControllerName ) {
|
|
Controller< ? > c = cp5.getController( theControllerName );
|
|
if ( c == null ) {
|
|
return this;
|
|
}
|
|
return unregister( c );
|
|
}
|
|
|
|
/**
|
|
* with the default display, the width of the tooltip is
|
|
* set automatically, therefore setWidth() does not have
|
|
* any effect without changing the default display to a
|
|
* custom ControllerView.
|
|
*
|
|
* @see controlP5.ControllerView
|
|
* @see controlP5.Tooltip#setDisplay(ControllerView)
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setWidth( int theWidth ) {
|
|
// TODO
|
|
// _myWidth = theWidth;
|
|
return this;
|
|
}
|
|
|
|
public int getWidth( ) {
|
|
return _myLabel.getWidth( );
|
|
}
|
|
|
|
/**
|
|
* @see controlP5.Tooltip#setWidth(int)
|
|
* @param theHeight
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setHeight( int theHeight ) {
|
|
ControlP5.logger( ).warning( "Tooltip.setHeight is disabled with this version" );
|
|
_myHeight = theHeight;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* adds an offset to the position of the controller
|
|
* relative to the mouse cursor's position. default
|
|
* offset is (10,20)
|
|
*
|
|
* @param theX
|
|
* @param theY
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setPositionOffset( float theX , float theY ) {
|
|
offset.x = theX;
|
|
offset.y = theY;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* disables the Tooltip on a global level, when
|
|
* disabled, tooltip will not respond to any registered
|
|
* controller. to disable a tooltip for aparticular
|
|
* controller, used unregister(Controller)
|
|
*
|
|
* @see controlP5.Tooltip#unregister(Controller)
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip disable( ) {
|
|
enabled = false;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* in case the tooltip is disabled, use enable() to turn
|
|
* the tooltip back on.
|
|
*
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip enable( ) {
|
|
enabled = true;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* check if the tooltip is enabled or disabled
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public boolean isEnabled( ) {
|
|
return enabled;
|
|
}
|
|
|
|
/**
|
|
* sets the Label to a custom label and replaces the
|
|
* default label.
|
|
*
|
|
* @param theLabel
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setLabel( Label theLabel ) {
|
|
_myLabel = theLabel;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* returns the current Label
|
|
*
|
|
* @return Label
|
|
*/
|
|
public Label getLabel( ) {
|
|
return _myLabel;
|
|
}
|
|
|
|
/**
|
|
* sets the background color of the tooltip, the default
|
|
* color is a dark grey
|
|
*
|
|
* @param theColor
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setColorBackground( int theColor ) {
|
|
_myBackgroundColor = theColor;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* sets the text color of the tooltip's label, the
|
|
* default color is a white
|
|
*
|
|
* @param theColor
|
|
* @return Tooltip
|
|
*/
|
|
public Tooltip setColorLabel( int theColor ) {
|
|
_myColor = theColor;
|
|
_myLabel.setColor( theColor );
|
|
return this;
|
|
}
|
|
|
|
class TooltipView implements ControllerView< Controller< ? >> {
|
|
|
|
public void display( PGraphics theGraphics , Controller< ? > theController ) {
|
|
_myHeight = _myLabel.getHeight( );
|
|
theGraphics.fill( _myBackgroundColor , _myAlpha );
|
|
theGraphics.rect( 0 , 0 , getWidth( ) + _myBorder * 2 , _myHeight + _myBorder * 2 );
|
|
theGraphics.pushMatrix( );
|
|
if ( _myAlignH == ControlP5.RIGHT ) {
|
|
theGraphics.translate( 6 , 0 );
|
|
} else {
|
|
theGraphics.translate( getWidth( ) - 6 , 0 );
|
|
}
|
|
theGraphics.triangle( 0 , 0 , 4 , -4 , 8 , 0 );
|
|
theGraphics.popMatrix( );
|
|
int a = ( int ) ( PApplet.map( _myAlpha , 0 , _myMaxAlpha , 0 , 255 ) );
|
|
_myLabel.setColor( a << 24 | ( _myColor >> 16 ) << 16 | ( _myColor >> 8 ) << 8 | ( _myColor >> 0 ) << 0 );
|
|
_myLabel.draw( theGraphics , 0 , 0 , theController );
|
|
}
|
|
}
|
|
}
|