/* * SpectSlider.java * (FScape) * * Copyright (c) 2001-2016 Hanns Holger Rutz. All rights reserved. * * This software is published under the GNU General Public License v3+ * * * For further information, please contact Hanns Holger Rutz at * contact@sciss.de * * * Changelog: * 21-May-05 modernized */ package de.sciss.fscape.gui; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.StringTokenizer; /** * Used in chebychev waveshaper for adjusting the colour. */ public class SpectSlider extends JPanel implements ComponentListener, FocusListener, KeyListener, MouseListener, MouseMotionListener { // -------- private variables -------- private int bands = -1; private float[] value = null; private Color[] sliderColor = null; private Color[] borderColor = null; private Dimension currentSize; private Cursor lastCursor = null; private Cursor drawCursor; private int currentSlider; private boolean focused = false; private static final Color colrBorder = new Color( 128, 128, 128 ); private static final Color colrFocus = new Color( 100, 115, 162 ); // dieser Button wird nicht angezeigt, sondern dient nur als // Institution zum Verwalten der ActionListener und fuer // den Event-Dispatch! private Button actionComponent = new Button(); private static float[] clipboard = null; // -------- public methods -------- // public void setColor( Color c ); // public Color getColor(); public SpectSlider( float[] value, int width, int height ) { setBands( value ); drawCursor = new Cursor( Cursor.HAND_CURSOR ); Dimension preferredSize = new Dimension(width, height); setPreferredSize(preferredSize); setMinimumSize( new Dimension( width >> 1, height >> 1 )); currentSize = preferredSize; setForeground( Color.black ); // setBackground( Color.white ); addMouseListener( this ); addMouseMotionListener( this ); addComponentListener( this ); addKeyListener( this ); addFocusListener( this ); // Random rnd = new Random( System.currentTimeMillis() ); // for( int i = 0; i < bands; i++ ) { // value[ i ] = rnd.nextFloat(); // } } public SpectSlider( int bands, int width, int height ) { this( new float[ bands ], width, height ); } public SpectSlider( int bands ) { this( new float[ bands ], bands * 11 + 3, bands * 11 + 3 ); } public void setBand( int band, float value ) { this.value[ band ] = value; repaint(); } public float getBand( int band ) { return value[ band ]; } public void setBands( float[] value ) { int oldBands = bands; bands = value.length; if( (oldBands != bands) || (this.value == null) ) { this.value = new float[ value.length ]; } System.arraycopy( value, 0, this.value, 0, bands ); // ---- re-color ---- if( (oldBands != bands) || (sliderColor == null) ) { sliderColor = new Color[ bands ]; borderColor = new Color[ bands ]; } float hue, f; f = 0.75f / (bands-1); for( int i = 0; i< bands; i++ ) { hue = i * f; sliderColor[ i ] = new Color( Color.HSBtoRGB( hue, 0.5f, 1.0f )); borderColor[ i ] = new Color( Color.HSBtoRGB( hue, 0.5f, 0.5f )); } repaint(); } public float[] getBands() { final float[] b = new float[ value.length ]; System.arraycopy( value, 0, b, 0, value.length ); return b; } /** * Registriert einen ActionListener; * Action-Events kommen, wenn sich der Wert des PathFieldes aendert */ public void addActionListener( ActionListener list ) { actionComponent.addActionListener( list ); } /** * Entfernt einen ActionListener */ public void removeActionListener( ActionListener list ) { actionComponent.removeActionListener( list ); } public void paintComponent( Graphics g ) { super.paintComponent( g ); g.setColor( colrBorder ); g.draw3DRect( 0, 0, currentSize.width - 1, currentSize.height - 1, false ); if(focused) { g.setColor( colrFocus ); g.drawRect( 1, 1, currentSize.width - 3, currentSize.height - 3 ); } int i, x1, x2, y2, h; float f; f = (float) (currentSize.width - 3) / (float) bands; y2 = currentSize.height - 2; for( i = 0, x2 = 0; i < bands; i++ ) { h = (int) (value[ i ] * (currentSize.height - 4) + 0.5f); x1 = x2 + 2; x2 = (int) ((i + 1) * f + 0.5f); if( h <= 0 ) continue; g.setColor( sliderColor[ i ]); g.fillRect( x1, y2 - h, x2 - x1, h - 1 ); g.setColor( borderColor[ i ]); g.drawRect( x1, y2 - h, x2 - x1, h - 1 ); } } // public boolean isFocusTraversable() // { // return true; // } // -------- StringComm methods -------- public String toString() { StringBuffer sb = new StringBuffer(); for( int i = 0; i < bands; i++ ) { sb.append( value[i] ); sb.append( ',' ); } return( sb.toString() ); } public static float[] valueOf( String s ) { StringTokenizer st = new StringTokenizer( s, "," ); int bands = st.countTokens(); float[] value = new float[ bands ]; for( int i = 0; i < bands; i++ ) { value[ i ] = Float.valueOf( st.nextToken() ).floatValue(); } return value; } // -------- Component methods -------- public void componentResized( ComponentEvent e ) { currentSize = getSize(); repaint(); } public void componentMoved( ComponentEvent e ) {} public void componentHidden( ComponentEvent e ) {} public void componentShown( ComponentEvent e ) {} // -------- Focus Listener methods -------- public void focusGained( FocusEvent e ) { focused = true; repaint(); } public void focusLost( FocusEvent e ) { focused = false; repaint(); } // -------- Key Listener methods -------- public void keyTyped( KeyEvent e ) { switch( e.getKeyChar() ) { case 'c': synchronized( getClass() ) { clipboard = getBands(); } break; case 'v': synchronized( getClass() ) { setBands( clipboard ); } break; } } public void keyPressed( KeyEvent e ) {} public void keyReleased( KeyEvent e ) {} // -------- Mouse Listener methods -------- public void mousePressed( MouseEvent e ) { requestFocus(); lastCursor = getCursor(); setCursor( drawCursor ); processMouse( e.getX(), e.getY() ); } public void mouseReleased( MouseEvent e ) { if( currentSlider >= 0 ) { // Event mit SpectSlider als Source eintragen, damit wir vom // GUISupport gefunden werden ActionEvent parentE = new ActionEvent( this, ActionEvent.ACTION_PERFORMED, "" ); actionComponent.dispatchEvent( parentE ); } currentSlider = -1; setCursor( lastCursor ); } public void mouseClicked( MouseEvent e ) {} public void mouseEntered( MouseEvent e ) {} public void mouseExited( MouseEvent e ) {} // -------- MouseMotion Listener methods -------- public void mouseDragged( MouseEvent e ) { processMouse( e.getX(), e.getY() ); } public void mouseMoved( MouseEvent e ) {} // -------- private methods -------- private void processMouse( int x, int y ) { int slider; float f; f = (float) (currentSize.width - 3) / (float) bands; slider = (int) ((x - 2) / f); if( (slider < 0) || (slider >= bands) ) { if( currentSlider == -1 ) return; } else { currentSlider = slider; } f = (float) (currentSize.height - 2 - y) / (float) (currentSize.height - 4); value[ currentSlider ] = Math.max( 0f, Math.min( 1f, f )); repaint(); } }