/*
* @(#)ColorPickerSliderUI.java
*
* $Date: 2012-07-03 01:10:05 -0500 (Tue, 03 Jul 2012) $
*
* Copyright (c) 2011 by Jeremy Wood.
* All rights reserved.
*
* The copyright of this software is owned by Jeremy Wood.
* You may not use, copy or modify this software, except in
* accordance with the license agreement you entered into with
* Jeremy Wood. For details see accompanying license terms.
*
* This software is probably, but not necessarily, discussed here:
* http://javagraphics.java.net/
*
* That site should also contain the most recent official version
* of this software. (See the SVN repository for more details.)
*/
package com.bric.plaf;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.event.MouseInputAdapter;
import javax.swing.plaf.basic.BasicSliderUI;
import com.bric.swing.ColorPicker;
import com.bric.swing.ColorPickerPanel;
/** This is a SliderUI designed specifically for the
* <code>ColorPicker</code>.
*
*/
public class ColorPickerSliderUI extends BasicSliderUI {
ColorPicker colorPicker;
/** Half of the height of the arrow */
int ARROW_HALF = 8;
int[] intArray = new int[ Toolkit.getDefaultToolkit().getScreenSize().height ];
BufferedImage bi = new BufferedImage(1,intArray.length,BufferedImage.TYPE_INT_RGB);
int lastMode = -1;
public ColorPickerSliderUI(JSlider b,ColorPicker cp) {
super(b);
colorPicker = cp;
cp.getColorPanel().addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
ColorPickerSliderUI.this.calculateGeometry();
slider.repaint();
}
});
}
@Override
public void paintThumb(Graphics g) {
int y = thumbRect.y+thumbRect.height/2;
Polygon polygon = new Polygon();
polygon.addPoint(0,y-ARROW_HALF);
polygon.addPoint(ARROW_HALF,y);
polygon.addPoint(0,y+ARROW_HALF);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.black);
g2.fill(polygon);
g2.setColor(Color.white);
g2.setStroke(new BasicStroke(1));
g2.draw(polygon);
}
@Override
protected void calculateThumbSize() {
super.calculateThumbSize();
thumbRect.height+=4;
thumbRect.y-=2;
}
@Override
protected void calculateTrackRect() {
super.calculateTrackRect();
ColorPickerPanel cp = colorPicker.getColorPanel();
int size = Math.min(ColorPickerPanel.MAX_SIZE, Math.min(cp.getWidth(), cp.getHeight()));
int max = slider.getHeight()-ARROW_HALF*2-2;
if(size>max) {
size = max;
}
trackRect.y = slider.getHeight()/2-size/2;
trackRect.height = size;
}
@Override
public synchronized void paintTrack(Graphics g) {
int mode = colorPicker.getMode();
if(mode==ColorPicker.HUE || mode==ColorPicker.BRI || mode==ColorPicker.SAT) {
float[] hsb = colorPicker.getHSB();
if(mode==ColorPicker.HUE) {
for(int y = 0; y<trackRect.height; y++) {
float hue = ((float)y)/((float)trackRect.height);
intArray[y] = Color.HSBtoRGB( hue, 1, 1);
}
} else if(mode==ColorPicker.SAT) {
for(int y = 0; y<trackRect.height; y++) {
float sat = 1-((float)y)/((float)trackRect.height);
intArray[y] = Color.HSBtoRGB( hsb[0], sat, hsb[2]);
}
} else {
for(int y = 0; y<trackRect.height; y++) {
float bri = 1-((float)y)/((float)trackRect.height);
intArray[y] = Color.HSBtoRGB( hsb[0], hsb[1], bri);
}
}
} else {
int[] rgb = colorPicker.getRGB();
if(mode==ColorPicker.RED) {
for(int y = 0; y<trackRect.height; y++) {
int red = 255-(int)(y*255/trackRect.height+.49);
intArray[y] = (red << 16)+(rgb[1] << 8)+(rgb[2]);
}
} else if(mode==ColorPicker.GREEN) {
for(int y = 0; y<trackRect.height; y++) {
int green = 255-(int)(y*255/trackRect.height+.49);
intArray[y] = (rgb[0] << 16)+(green << 8)+(rgb[2]);
}
} else if(mode==ColorPicker.BLUE) {
for(int y = 0; y<trackRect.height; y++) {
int blue = 255-(int)(y*255/trackRect.height+.49);
intArray[y] = (rgb[0] << 16)+(rgb[1] << 8)+(blue);
}
}
}
Graphics2D g2 = (Graphics2D)g;
Rectangle r = new Rectangle(6, trackRect.y, 14, trackRect.height);
if(slider.hasFocus()) {
PlafPaintUtils.paintFocus(g2,r,3);
}
bi.getRaster().setDataElements(0,0,1,trackRect.height,intArray);
TexturePaint p = new TexturePaint(bi,new Rectangle(0,trackRect.y,1,bi.getHeight()));
g2.setPaint(p);
g2.fillRect(r.x,r.y,r.width,r.height);
PlafPaintUtils.drawBevel(g2, r);
}
@Override
public void paintFocus(Graphics g) {}
/** This overrides the default behavior for this slider
* and sets the thumb to where the user clicked.
* From a design standpoint, users probably don't want to
* scroll through several colors to get where they clicked:
* they simply want the color they selected.
*/
MouseInputAdapter myMouseListener = new MouseInputAdapter() {
@Override
public void mousePressed(MouseEvent e) {
slider.setValueIsAdjusting(true);
updateSliderValue(e);
}
private void updateSliderValue(MouseEvent e) {
int v;
if(slider.getOrientation()==SwingConstants.HORIZONTAL) {
int x = e.getX();
v = valueForXPosition(x);
} else {
int y = e.getY();
v = valueForYPosition(y);
}
slider.setValue(v);
}
@Override
public void mouseReleased(MouseEvent e) {
updateSliderValue(e);
slider.setValueIsAdjusting(false);
}
@Override
public void mouseDragged(MouseEvent e) {
updateSliderValue(e);
}
};
@Override
protected void installListeners(JSlider slider) {
super.installListeners(slider);
slider.removeMouseListener(trackListener);
slider.removeMouseMotionListener(trackListener);
slider.addMouseListener(myMouseListener);
slider.addMouseMotionListener(myMouseListener);
slider.setOpaque(false);
}
@Override
protected void uninstallListeners(JSlider slider) {
super.uninstallListeners(slider);
slider.removeMouseListener(myMouseListener);
slider.removeMouseMotionListener(myMouseListener);
}
}