blob: 16e5caf00a31e3cb6c18ba75964163ebf86df95f [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.
*/
package com.intellij.openapi.progress.util;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Rectangle2D;
/**
* @author Eugene Belyaev
*/
public class ColorProgressBar extends JComponent {
private static final Dimension PREFERRED_SIZE = new Dimension(146, 17);
public static final Color GREEN = new JBColor(new Color(0x2fd432), new Color(0x287528));
public static final Color RED = new Color(0xd2451e);
public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue);
public static final Color YELLOW = new Color(0xd4b721);
private static final Color SHADOW1 = new JBColor(Gray._190, UIUtil.getBorderColor()) ;
private static final Color SHADOW2 = Gray._105;
private static final int BRICK_WIDTH = 6;
private static final int BRICK_SPACE = 1;
private static final int INDETERMINATE_BRICKS_DRAW = 5;
private static final double INDETERMINATE_INC_OFFSET = 0.02;
private double myFraction = 0.0;
private Color myColor = BLUE;
private double myIndeterminateInc = INDETERMINATE_INC_OFFSET;
private boolean myIndeterminate = false;
public boolean isIndeterminate() {
return myIndeterminate;
}
public void setIndeterminate(boolean indeterminate) {
this.myIndeterminate = indeterminate;
}
public ColorProgressBar() {
updateUI();
}
public void setColor(Color color) {
myColor = color;
if (isDisplayable()) repaint();
}
public double getFraction() {
return myFraction;
}
public void setFraction(double fraction) {
if (Double.isNaN(fraction)) {
fraction = 1.0;
}
if (myIndeterminate) {
if (myFraction >= 1.0) {
myIndeterminateInc = -INDETERMINATE_INC_OFFSET;
}
else if (myFraction <= 0) {
myIndeterminateInc = INDETERMINATE_INC_OFFSET;
}
final boolean changed = myFraction == 0 || getBricksToDraw(myFraction) != getBricksToDraw(myFraction + myIndeterminateInc);
myFraction += myIndeterminateInc;
if (changed) {
repaint();
}
}
else {
boolean changed = myFraction == 0 || getBricksToDraw(myFraction) != getBricksToDraw(fraction);
myFraction = fraction;
if (changed) {
repaint();
}
}
}
private int getBricksToDraw(double fraction) {
int bricksTotal = (getWidth() - 8) / (BRICK_WIDTH + BRICK_SPACE);
return (int)(bricksTotal * fraction) + 1;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
final GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
Graphics2D g2 = (Graphics2D)g;
if (myFraction > 1) {
myFraction = 1;
}
Dimension size = getSize();
g2.setPaint(UIUtil.getListBackground());
Rectangle2D rect = new Rectangle2D.Double(2, 2, size.width - 4, size.height - 4);
g2.fill(rect);
g2.setPaint(new JBColor(SHADOW1, UIUtil.getBorderColor()));
rect.setRect(1, 1, size.width - 2, size.height - 2);
g2.drawRoundRect(1, 1, size.width - 2, size.height - 2, 5, 5);
g2.setPaint(SHADOW2);
g2.drawRoundRect(0, 0, size.width - 2, size.height - 2, 5, 5);
int y_center = size.height / 2;
int y_steps = size.height / 2 - 3;
int alpha_step = y_steps > 0 ? (255 - 70) / y_steps : 255 - 70;
int x_offset = 4;
g.setClip(4, 3, size.width - 8, size.height - 6);
int bricksToDraw = myFraction == 0 ? 0 : getBricksToDraw(myFraction);
if (myIndeterminate) {
int startFrom = bricksToDraw < INDETERMINATE_BRICKS_DRAW ? 0 : bricksToDraw - INDETERMINATE_BRICKS_DRAW;
int endTo = bricksToDraw + INDETERMINATE_BRICKS_DRAW < getBricksToDraw(1) ? bricksToDraw + INDETERMINATE_BRICKS_DRAW : getBricksToDraw(1);
for (int i = startFrom; i <= endTo; i++) {
g2.setPaint(myColor);
int startXOffset = x_offset + (BRICK_WIDTH + BRICK_SPACE) * i;
UIUtil.drawLine(g2, startXOffset, y_center, startXOffset + BRICK_WIDTH - 1, y_center);
for (int j = 0; j < y_steps; j++) {
Color color = ColorUtil.toAlpha(myColor, 255 - alpha_step * (j + 1));
g2.setPaint(color);
UIUtil.drawLine(g2, startXOffset, y_center - 1 - j, startXOffset + BRICK_WIDTH - 1, y_center - 1 - j);
if (!(y_center % 2 != 0 && j == y_steps - 1)) {
UIUtil.drawLine(g2, startXOffset, y_center + 1 + j, startXOffset + BRICK_WIDTH - 1, y_center + 1 + j);
}
}
g2.setColor(
ColorUtil.toAlpha(myColor, 255 - alpha_step * (y_steps / 2 + 1)));
g2.drawRect(startXOffset, y_center - y_steps, BRICK_WIDTH - 1, size.height - 7);
}
} else {
for (int i = 0; i < bricksToDraw; i++) {
g2.setPaint(myColor);
UIUtil.drawLine(g2, x_offset, y_center, x_offset + BRICK_WIDTH - 1, y_center);
for (int j = 0; j < y_steps; j++) {
Color color = ColorUtil.toAlpha(myColor, 255 - alpha_step * (j + 1));
g2.setPaint(color);
UIUtil.drawLine(g2, x_offset, y_center - 1 - j, x_offset + BRICK_WIDTH - 1, y_center - 1 - j);
if (!(y_center % 2 != 0 && j == y_steps - 1)) {
UIUtil.drawLine(g2, x_offset, y_center + 1 + j, x_offset + BRICK_WIDTH - 1, y_center + 1 + j);
}
}
g2.setColor(
ColorUtil.toAlpha(myColor, 255 - alpha_step * (y_steps / 2 + 1)));
g2.drawRect(x_offset, y_center - y_steps, BRICK_WIDTH - 1, size.height - 7);
x_offset += BRICK_WIDTH + BRICK_SPACE;
}
}
config.restore();
}
public Dimension getPreferredSize() {
return PREFERRED_SIZE;
}
public Dimension getMaximumSize() {
Dimension dimension = getPreferredSize();
dimension.width = Short.MAX_VALUE;
return dimension;
}
public Dimension getMinimumSize() {
Dimension dimension = getPreferredSize();
dimension.width = 13;
return dimension;
}
public Color getColor() {
return myColor;
}
@SuppressWarnings({"HardCodedStringLiteral"})
public static void main(String[] args) {
JFrame frame = new JFrame("ColorProgressBar Test");
frame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
frame.setSize(800, 600);
frame.setLocation(0, 0);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
final ColorProgressBar colorProgressBar = new ColorProgressBar();
colorProgressBar.setFraction(0.5);
colorProgressBar.setIndeterminate(true);
contentPane.add(colorProgressBar, BorderLayout.NORTH);
frame.setVisible(true);
JButton b = new JButton ("X");
b.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e) {
colorProgressBar.setFraction(1);
}
});
contentPane.add(b, BorderLayout.SOUTH);
}
}