IDEA-114685 Color editor should open with a single click on the color square

This commit is contained in:
Vassiliy Kudryashov
2014-03-24 13:44:57 +04:00
parent b38c029253
commit 74576a17b8
3 changed files with 103 additions and 162 deletions
@@ -16,7 +16,7 @@
package com.intellij.ui;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -24,193 +24,110 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ColorPanel extends JComponent {
private static final Dimension SIZE = new Dimension(25, 15);
public class ColorPanel extends JPanel {
public static final Color DISABLED_COLOR = UIUtil.getPanelBackground();
private boolean isFiringEvent = false;
private ColorBox myFgSelectedColorBox;
private boolean isEditable = true;
private final List<ActionListener> myListeners = new CopyOnWriteArrayList<ActionListener>();
@Nullable private Color myColor = null;
public ColorPanel() {
this(10);
}
public ColorPanel(int boxSize) {
myFgSelectedColorBox = new ColorBox(null, (boxSize + 2) * 2, true);
myFgSelectedColorBox.setSelectColorAction(
new Runnable() {
public void run() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Color color = ColorChooser.chooseColor(ColorPanel.this, UIBundle.message("color.panel.select.color.dialog.description"), myColor);
if (color != null) {
myColor = color;
fireActionEvent();
}
}
);
JPanel selectedColorPanel = new JPanel(new GridBagLayout());
selectedColorPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
myFgSelectedColorBox.setBorder(BorderFactory.createEtchedBorder());
selectedColorPanel.add(myFgSelectedColorBox, new GridBagConstraints());
setLayout(new BorderLayout());
add(selectedColorPanel, BorderLayout.WEST);
});
}
public void setEnabled(boolean enabled) {
myFgSelectedColorBox.setEnabled(enabled);
super.setEnabled(enabled);
repaint();
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g.create();
try {
if (myColor != null && isEnabled()) {
g2d.setColor(myColor);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(ColorUtil.darker(myColor, 2));
g2d.draw(new Rectangle2D.Double(0.5, 0.5, getWidth()-1, getHeight()-1));
}
g2d.setColor(UIUtil.getBorderColor());
g2d.draw(new Rectangle2D.Double(1.5, 1.5, getWidth() - 3, getHeight() - 3));
} finally {
g2d.dispose();
}
}
@Override
public Dimension getPreferredSize() {
return SIZE;
}
@Override
public Dimension getMaximumSize() {
return SIZE;
}
@Override
public Dimension getMinimumSize() {
return SIZE;
}
@Override
public String getToolTipText() {
if (myColor == null || !isEnabled()) {
return null;
}
StringBuilder buffer = new StringBuilder("0x").append(ColorUtil.toHex(myColor).toUpperCase());
if (isEnabled()) {
buffer.append(" (Click to customize)");
}
return buffer.toString();
}
private void fireActionEvent() {
if (!isEditable) return;
if (!isFiringEvent){
isFiringEvent = true;
ActionEvent actionevent = null;
Object[] listeners = listenerList.getListenerList();
for(int i = listeners.length - 2; i >= 0; i -= 2){
if (listeners[i] != ActionListener.class) continue;
if (actionevent == null){
actionevent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "colorPanelChanged");
if (!isFiringEvent) {
try {
isFiringEvent = true;
ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "colorPanelChanged");
for (ActionListener listener : myListeners) {
listener.actionPerformed(event);
}
((ActionListener)listeners[i + 1]).actionPerformed(actionevent);
}
isFiringEvent = false;
finally {
isFiringEvent = false;
}
}
}
public void removeActionListener(ActionListener actionlistener) {
listenerList.remove(ActionListener.class, actionlistener);
myListeners.remove(actionlistener);
}
public void addActionListener(ActionListener actionlistener) {
listenerList.add(ActionListener.class, actionlistener);
myListeners.add(actionlistener);
}
@Nullable
public Color getSelectedColor() {
return myFgSelectedColorBox.getColor();
return myColor;
}
public void setSelectedColor(Color color) {
myFgSelectedColorBox.setColor(color);
public void setSelectedColor(@Nullable Color color) {
myColor = color;
repaint();
}
public void setEditable(boolean isEditable) {
this.isEditable = isEditable;
myFgSelectedColorBox.setSelectable(isEditable);
}
private class ColorBox extends JComponent {
private final Dimension mySize;
private boolean isSelectable;
private Runnable mySelectColorAction = null;
private Color myColor;
@NonNls public static final String RGB = "RGB";
public ColorBox(Color color, int size, boolean isSelectable) {
mySize = new Dimension(size, size);
this.isSelectable = isSelectable;
myColor = color;
updateToolTip();
//TODO[anton,vova] investigate
addMouseListener(new MouseAdapter(){
public void mouseReleased(MouseEvent mouseevent) {
if (!isEnabled()){
return;
}
if (mouseevent.isPopupTrigger()){
selectColor();
}
}
public void mousePressed(MouseEvent mouseevent) {
if (!isEnabled()){
return;
}
if (mouseevent.getClickCount() == 2){
selectColor();
}
else{
if (SwingUtilities.isLeftMouseButton(mouseevent)){
setSelectedColor(myColor);
fireActionEvent();
}
else{
if (mouseevent.isPopupTrigger()){
selectColor();
}
}
}
}
});
}
public void setSelectColorAction(Runnable selectColorAction) {
mySelectColorAction = selectColorAction;
}
private void selectColor() {
if (isSelectable){
Color color = ColorChooser.chooseColor(ColorPanel.this, UIBundle.message("color.panel.select.color.dialog.description"), myColor);
if (color != null){
setColor(color);
if (mySelectColorAction != null){
mySelectColorAction.run();
}
}
}
}
public Dimension getMinimumSize() {
return mySize;
}
public Dimension getMaximumSize() {
return mySize;
}
public Dimension getPreferredSize() {
return mySize;
}
public void paintComponent(Graphics g) {
if (isEnabled()){
g.setColor(myColor);
}
else{
g.setColor(DISABLED_COLOR);
}
g.fillRect(0, 0, getWidth(), getHeight());
}
private void updateToolTip() {
if (myColor == null){
return;
}
StringBuilder buffer = new StringBuilder(64);
buffer.append(RGB + ": ");
buffer.append(myColor.getRed());
buffer.append(", ");
buffer.append(myColor.getGreen());
buffer.append(", ");
buffer.append(myColor.getBlue());
if (isSelectable) {
buffer.append(" (" + UIBundle.message("color.panel.right.click.to.customize.tooltip.suffix") + ")");
}
setToolTipText(buffer.toString());
}
public void setColor(Color color) {
myColor = color;
updateToolTip();
repaint();
}
public Color getColor() {
return myColor;
}
private void setSelectable(boolean selectable) {
isSelectable = selectable;
}
}
}
@@ -1,5 +1,4 @@
color.panel.select.color.dialog.description=Select Color
color.panel.right.click.to.customize.tooltip.suffix=Right-click to customize
insert.file.path.to.text.action.name=Insert Path
order.entries.panel.export.column.name=Export
tree.view.expand.all.action.name=Expand All
@@ -37,7 +37,27 @@ public class ColorUtil {
public static Color softer(@NotNull Color color) {
if (color.getBlue() > 220 && color.getRed() > 220 && color.getGreen() > 220) return color;
final float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
return Color.getHSBColor(hsb[0], 0.6f *hsb[1], hsb[2]);
return Color.getHSBColor(hsb[0], 0.6f * hsb[1], hsb[2]);
}
public static Color darker(@NotNull Color color, int tones) {
final float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
float brightness = hsb[2];
for (int i = 0; i < tones; i++) {
brightness = Math.max(0, brightness / 1.1F);
if (brightness == 0) break;
}
return Color.getHSBColor(hsb[0], hsb[1], brightness);
}
public static Color brighter(@NotNull Color color, int tones) {
final float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
float brightness = hsb[2];
for (int i = 0; i < tones; i++) {
brightness = Math.min(1, brightness * 1.1F);
if (brightness == 1) break;
}
return Color.getHSBColor(hsb[0], hsb[1], brightness);
}
public static Color dimmer(@NotNull Color color) {
@@ -52,6 +72,7 @@ public class ColorUtil {
final int n = (int)(colorComponent * d);
return n > 255 ? 255 : n < 0 ? 0 : n;
}
public static Color shift(Color c, double d) {
return new Color(shift(c.getRed(), d), shift(c.getGreen(), d), shift(c.getBlue(), d), c.getAlpha());
}
@@ -95,9 +116,11 @@ public class ColorUtil {
17 * Integer.valueOf(String.valueOf(str.charAt(0)), 16).intValue(),
17 * Integer.valueOf(String.valueOf(str.charAt(1)), 16).intValue(),
17 * Integer.valueOf(String.valueOf(str.charAt(2)), 16).intValue());
} else if (str.length() == 6) {
}
else if (str.length() == 6) {
return Color.decode("0x" + str);
} else {
}
else {
throw new IllegalArgumentException("Should be String of 3 or 6 chars length.");
}
}
@@ -106,7 +129,8 @@ public class ColorUtil {
public static Color fromHex(String str, @Nullable Color defaultValue) {
try {
return fromHex(str);
} catch (Exception e) {
}
catch (Exception e) {
return defaultValue;
}
}
@@ -124,6 +148,7 @@ public class ColorUtil {
/**
* Checks whether color is dark or not based on perceptional luminosity
* http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
*
* @param c color to check
* @return dark or not
*/