package org.roussev.hiena.gui;
/*
* Copyright 2009 Hiena Mp3 Player http://code.google.com/p/hiena-mp3-player/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;
import java.awt.Dimension;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.Rectangle;
import java.util.Vector;
import java.util.Enumeration;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.net.URL;
/**
* <pre>
* <b>AtaProgressSlider</b> is a custom Slider with mouse, key and focus support.
* </pre>
*
* @author
*
*/
public final class XSlider extends java.awt.Panel /*javax.swing.JPanel*/ {
//private final static Color FOCUS_COLOR = new Color(0x9999CC);
private Color progressColor = new Color(0xAEAEFF);
private boolean showProgress = true;
private Rectangle progressRectangle = new Rectangle(0, 2);
private int DOT_WIDTH ;
private int DOT_HEIGHT ;
private int CANVAS_WIDTH ;
private int CANVAS_HEIGHT ;
//private int percent = 0;
private int eX, eY;
private int eXprevios/*, eYprevios*/;
private int dotX = progressRectangle.x, dotY = progressRectangle.y;
private boolean mouseEnter = false;
private boolean mouseUp = true;
private boolean keyPressed = false;
private boolean draggable = false;
//private boolean hasFocus;
private boolean focusable = true;
//----------
// Event Source Management
private final Vector actionListeners;
private String label;
//-----------
private Image imgOff;
private Image dot;
private Image dot_;
private Image bgSlider;
private Graphics gOff;
//-------------------------------------------------------
public XSlider(String label, String[] url) {
this.label = label;
initComponents();
// Initialize Event Source Management
actionListeners = new Vector();
if(url.length < 3) {
throw new ArrayIndexOutOfBoundsException(
"\n ------------------------------" +
"\n -- Error loading images. " +
"\n -- 3 images are needed for XSlider." +
"\n -- Usage:" +
"\n -- \t String[] url = {" +
"\n -- \t\t \"/img_arrow.gif\"" +
"\n -- \t\t \"/img_arrow_OVER.gif\"" +
"\n -- \t\t \"/img_slider_BACKGROUND.gif\"" +
"\n -- \t }" +
"\n ------------------------------"
);
}
setImages( url[0], url[1], url[2]);
}
//-------------------------------------------------------
public XSlider(String label, String[] url, Rectangle progressRectangle) {
this( label, url);
this.progressRectangle = progressRectangle;
final double medium = progressRectangle.y + (double)progressRectangle.height/2.0;
dotY = (int)(medium - (double)DOT_HEIGHT/2.0);
dotX = progressRectangle.x;
}
//-------------------------------------------------------
public XSlider(String label, URL[] url) {
this.label = label;
initComponents();
// Initialize Event Source Management
actionListeners = new Vector();
if(url.length < 3) {
throw new ArrayIndexOutOfBoundsException(
"\n ------------------------------" +
"\n -- Error loading images. " +
"\n -- 3 images are needed for XSlider." +
"\n -- Usage:" +
"\n -- \t URL[] url = {" +
"\n -- \t\t url_img_arrow" +
"\n -- \t\t url_img_arrow_OVER" +
"\n -- \t\t url_img_slider_BACKGROUND" +
"\n -- \t }" +
"\n ------------------------------"
);
}
setImages( url[0], url[1], url[2]);
}
//-------------------------------------------------------
public XSlider(String label, URL[] url, Rectangle progressRectangle) {
this( label, url);
this.progressRectangle = progressRectangle;
final double medium = progressRectangle.y + (double)progressRectangle.height/2.0;
dotY = (int)(medium - (double)DOT_HEIGHT/2.0);
dotX = progressRectangle.x;
}
//-----------------------------------------------
private final void setImages(URL urlDot, URL urlDot_, URL urlBg) {
final MediaTracker md = new MediaTracker(this);
final Toolkit toolkit = getToolkit();
dot = toolkit.createImage( urlDot );
dot_ = toolkit.createImage( urlDot_ );
bgSlider = toolkit.createImage( urlBg );
md.addImage(dot, 0);
md.addImage(dot_, 1);
md.addImage(bgSlider, 2);
try {
md.waitForAll();
if (md.isErrorAny()) { System.out.println("Error loading image "); }
} catch (Exception ex) { ex.printStackTrace(); }
CANVAS_WIDTH = bgSlider.getWidth(this);
CANVAS_HEIGHT = bgSlider.getHeight(this);
DOT_WIDTH = dot.getWidth(this);
DOT_HEIGHT = dot.getHeight(this);
setSize( getPreferredSize());
}
//-----------------------------------------------
private final void setImages(String urlDot, String urlDot_, String urlBg) {
setImages(
getClass().getResource(urlDot),
getClass().getResource(urlDot_),
getClass().getResource(urlBg)
);
}
//-------------------------------------------------------
private final void initComponents() {
this.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
doMouseEntered();
}
public void mouseExited(java.awt.event.MouseEvent evt) {
doMouseExited();
}
public void mousePressed(java.awt.event.MouseEvent evt) {
doMousePressed(evt);
}
public void mouseReleased(java.awt.event.MouseEvent evt) {
doMouseReleased();
}
});
this.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseMoved(java.awt.event.MouseEvent evt) {
doMouseMoved(evt);
}
public void mouseDragged(java.awt.event.MouseEvent evt) {
doMouseDragged(evt);
}
});
this.addFocusListener( new java.awt.event.FocusAdapter(){
public void focusGained(java.awt.event.FocusEvent evt) {
doFocusGained();
}
public void focusLost(java.awt.event.FocusEvent evt) {
doFocusLost();
}
});
this.addKeyListener( new java.awt.event.KeyAdapter(){
public void keyPressed(java.awt.event.KeyEvent evt) {
doKeyPressed(evt);
}
public void keyReleased(java.awt.event.KeyEvent evt) {
doKeyReleased();
}
});
}
//-------------------------------------------------------
public final void updateSlider(){
if(mouseEnter){
update( getGraphics() );
}
}
//-------------------------------------------------------
public final void update(Graphics g) {
gOff = null;
imgOff = null;
// create the offscreen buffer and associated Graphics
imgOff = createImage( this.CANVAS_WIDTH, this.CANVAS_HEIGHT );
gOff = imgOff.getGraphics();
// clear the exposed area
gOff.setColor(getBackground());
gOff.fillRect(0,0, this.CANVAS_WIDTH, this.CANVAS_HEIGHT);
gOff.setColor(getForeground());
// do normal redraw
paint(gOff);
// transfer offscreen to window
g.drawImage(imgOff, 0, 0, this);
imgOff.flush();
}
//-------------------------------------------------------
public final void paint(Graphics g){
g.drawImage( bgSlider, 0, 0, this);
drawProgress(g);
drawDot(g);
// Focus Management
/*if ( hasFocus && focusable ) {
g.setColor(FOCUS_COLOR);
g.drawRect( 0, 0, CANVAS_WIDTH - BORDER, CANVAS_HEIGHT - BORDER );
}*/
g.dispose();
}
//-------------------------------------------------------
private final void drawProgress(Graphics g ){
if(showProgress){
g.setColor( progressColor );
final int posX = (dotX - progressRectangle.x);
g.fillRect( progressRectangle.x, progressRectangle.y, posX, progressRectangle.height );
}
}
//-------------------------------------------------------
private final void drawDot(Graphics g ){
if( insideDot(eX,eY) || draggable ) {
g.drawImage( dot_, dotX, dotY, this);
}
else {
g.drawImage( dot, dotX, dotY, this);
}
if(!mouseEnter)
g.drawImage( dot, dotX, dotY, this);
if( keyPressed) {
g.drawImage( dot_, dotX, dotY, this);
}
}
//-------------------------------------------------------
public final int getPercent(){
final int slider_length = CANVAS_WIDTH - 2*progressRectangle.x - DOT_WIDTH;
final int slider_pos = dotX - progressRectangle.x;
int x = (int)Math.round( slider_pos*100/slider_length);
if(x >= 0 && x <= 100) {
return x;
}
else {
x = ( x < 0 )? 0 : x;
x = ( x > 100 )? 100 : x;
return x;
}
}
//-------------------------------------------------------
public final void setProgressColor(Color c) {
this.progressColor = c;
}
//-------------------------------------------------------
// Set the progress line to be visible
public final void setShowProgress( boolean showProgress) {
this.showProgress = showProgress;
}
//-------------------------------------------------------
public final void setPercent(int percent){
dotX = (percent*(CANVAS_WIDTH - progressRectangle.x ))/100 - DOT_WIDTH;
repaint();
}
//-------------------------------------------------------
final void doKeyPressed(java.awt.event.KeyEvent evt) {
keyPressed = true;
// Key Model Management
if (evt.getKeyCode() == KeyEvent.VK_RIGHT || evt.getKeyCode() == KeyEvent.VK_UP ) {
fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, label));
if( dotX < CANVAS_WIDTH - DOT_WIDTH - progressRectangle.x ){
eX ++;
dotX ++;
repaint();
}
}
else if (evt.getKeyCode() == KeyEvent.VK_LEFT || evt.getKeyCode() == KeyEvent.VK_DOWN ) {
fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, label));
if( dotX > progressRectangle.x ){
eX --;
dotX --;
repaint();
}
}
}
//-----------------------------------
final void doKeyReleased() {
keyPressed = false;
repaint();
}
//-------------------------------------------------------
final void doFocusGained() {
//hasFocus = true;
keyPressed = true;
repaint();
}
//-----------------------------------
final void doFocusLost() {
//hasFocus = false;
keyPressed = false;
repaint();
}
//-------------------------------------------------------
final void doMouseEntered() {
mouseEnter = true;
}
//-----------------------------------
final void doMouseExited() {
mouseEnter = false;
keyPressed = false;
repaint();
}
//-----------------------------------
final void doMouseReleased() {
mouseUp = true;
setDraggable( eX, eY );
}
//-----------------------------------
final void doMousePressed(java.awt.event.MouseEvent evt) {
mouseUp = false;
eX = evt.getX();
eY = evt.getY();
setDraggable( eX, eY );
if( insideDraggCanvas(eX) ){
dotX = eX - (int)Math.round(DOT_WIDTH/2);
if( dotX > CANVAS_WIDTH - DOT_WIDTH - progressRectangle.x )
dotX = CANVAS_WIDTH - DOT_WIDTH - progressRectangle.x ;
else if(dotX < progressRectangle.x)
dotX = progressRectangle.x ;
fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, label));
repaint();
}
}
//-----------------------------------
final void doMouseMoved(java.awt.event.MouseEvent evt) {
eX = evt.getX() ;
eY = evt.getY() ;
eXprevios = eX;
setDraggable( eX, eY );
repaint();
}
//-----------------------------------
final void doMouseDragged(java.awt.event.MouseEvent evt) {
eX = evt.getX();
eY = evt.getY();
int currentDotX = dotX + eX-eXprevios ;
if( currentDotX >= progressRectangle.x && currentDotX <= ( CANVAS_WIDTH - DOT_WIDTH - progressRectangle.x ) )
dotX += eX-eXprevios ;
else if ( currentDotX < progressRectangle.x )
dotX = progressRectangle.x ;
else
dotX = CANVAS_WIDTH - DOT_WIDTH - progressRectangle.x ;
eXprevios = eX;
fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, label));
repaint();
}
//-------------------------------------------------------
private final void setDraggable(int x, int y){
if( insideDot( x, y) && mouseEnter ){
draggable = true;
}
else
draggable = false;
}
//-------------------------------------------------------
private final boolean insideDot(int x, int y){
return ( x >= dotX && x <= (dotX + DOT_WIDTH) &&
y > dotY && y <= (dotY + DOT_HEIGHT)
);
}
//-------------------------------------------------------
/*private final boolean insideCanvas(int x, int y){
return (
x >= 0 && x <= CANVAS_WIDTH &&
y >= 0 && y <= CANVAS_HEIGHT
);
}
//-------------------------------------------------------
private final boolean insideDraggCanvas(int x, int y){
return (
x >= progressRectangle.x && x <= CANVAS_WIDTH - progressRectangle.x &&
y >= progressRectangle.x && y <= CANVAS_HEIGHT - progressRectangle.x
);
}*/
//-------------------------------------------------------
private boolean insideDraggCanvas(int x){
return (
x >= progressRectangle.x && x <= CANVAS_WIDTH - progressRectangle.x
);
}
//-------------------------------------------------------
public final void addActionListener(ActionListener li) {
actionListeners.addElement(li);
}
//--------------------------------------
public final void removeActionListener(ActionListener li) {
actionListeners.removeElement(li);
}
//--------------------------------------
protected final void fireActionPerformed(ActionEvent ev) {
Enumeration en = actionListeners.elements();
while ( en.hasMoreElements() ) {
final ActionListener li = (ActionListener)en.nextElement();
li.actionPerformed(ev);
}
}
//-------------------------------------------------------
public final void setLabel(String l) {
label = l;
repaint();
}
public final String getLabel() {
return label;
}
//--------------------------------------
public final boolean isFocusable() {
return focusable;
}
//-------------------------------------------------------
public final void setFocusable( boolean focusable) {
this.focusable = focusable;
super.setFocusable(focusable);
}
//-------------------------------------------------------
public final Dimension getPreferredSize() {
return getMinimumSize();
}
public final Dimension getMinimumSize() {
return new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT);
}
public final Dimension getMaximumSize() {
return getMinimumSize();
}
//-------------------------------------------------------
}