Worked on GUI part of adding option to Pref window

This commit is contained in:
joelmoniz
2014-05-31 14:14:56 +05:30
parent 91504f30d5
commit 6cc59d9409
+717
View File
@@ -28,6 +28,11 @@ import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import processing.core.*;
@@ -107,6 +112,8 @@ public class Preferences {
int wide, high;
JTextField sketchbookLocationField;
JTextField presentColor;
JTextField presentColorHex;
JCheckBox editorAntialiasBox;
JCheckBox deletePreviousBox;
JCheckBox whinyBox;
@@ -368,6 +375,80 @@ public class Preferences {
fontSizeField.setSelectedItem(Preferences.getFont("editor.font.size"));
top += d.height + GUI_BETWEEN;
// Here I am
Container colorBox = Box.createHorizontalBox();
label = new JLabel("Background color when Presenting: ");
colorBox.add(label);
final String colorTip = "<html>" +
"Select the background color used when using Present.<br/>" +
"Present is used to present a sketch in full-screen, <br/>" +
"accessible from the Sketch menu.";
label.setToolTipText(colorTip);
presentColor = new JTextField(" ");
presentColor.setOpaque(true);
presentColor.setEnabled(false);
presentColor.setBorder(BorderFactory.createLineBorder(Color.BLACK));
presentColor.setBackground(Preferences.getColor("run.present.bgcolor"));
colorBox.add(presentColor);
colorBox.add(Box.createHorizontalStrut(GUI_SMALL));
label = new JLabel("#");
colorBox.add(label);
presentColorHex = new JTextField(6);
presentColorHex.setText(Preferences.get("run.present.bgcolor").substring(1));
presentColorHex.setEditable(false);
presentColorHex.setBackground(Color.WHITE);
final CustomColorChooser c = new CustomColorChooser(Preferences.getColor("run.present.bgcolor"),
presentColorHex, presentColor);
presentColorHex.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
c.show();
}
});
presentColorHex.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
c.hide();
}
});
colorBox.add(presentColorHex);
pain.add(colorBox);
d = colorBox.getPreferredSize();
colorBox.setBounds(left, top, d.width, d.height);
top += d.height + GUI_BETWEEN;
// till here
// [ ] Use smooth text in editor window
@@ -634,7 +715,643 @@ public class Preferences {
});
}
private class CustomColorChooser {
int hue, saturation, brightness; // range 360, 100, 100
int red, green, blue; // range 256, 256, 256
ColorRange range;
ColorSlider slider;
JTextField hueField, saturationField, brightnessField;
JTextField redField, greenField, blueField;
JTextField hexField;
JPanel colorPanel;
DocumentListener colorListener;
JDialog window;
JTextField externalHex, externalColor;
public CustomColorChooser(Color initialColor, final JTextField externalHex,
final JTextField externalColor) {
Frame owner = null;
this.externalHex = externalHex;
this.externalColor = externalColor;
window = new JDialog(owner, "Choose the background color for Present", true);
window.getContentPane().setLayout(new BorderLayout());
Box box = Box.createHorizontalBox();
box.setBorder(new EmptyBorder(12, 12, 12, 12));
range = new ColorRange();
range.init();
Box rangeBox = new Box(BoxLayout.Y_AXIS);
rangeBox.setAlignmentY(0);
rangeBox.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
rangeBox.add(range);
box.add(rangeBox);
box.add(Box.createHorizontalStrut(10));
slider = new ColorSlider();
slider.init();
Box sliderBox = new Box(BoxLayout.Y_AXIS);
sliderBox.setAlignmentY(0);
sliderBox.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
sliderBox.add(slider);
box.add(sliderBox);
box.add(Box.createHorizontalStrut(10));
box.add(createColorFields(PROMPT_OK, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
externalHex.setText(getHexColor().substring(1));
externalColor.setBackground(getColor());
hide();
}
}, PROMPT_CANCEL, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hide();
}
}));
box.add(Box.createHorizontalStrut(10));
window.getContentPane().add(box, BorderLayout.CENTER);
window.pack();
window.setResizable(false);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
window.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
hide();
}
});
Toolkit.registerWindowCloseKeys(window.getRootPane(), new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
hide();
}
});
Toolkit.setIcon(window);
colorListener = new ColorListener();
hueField.getDocument().addDocumentListener(colorListener);
saturationField.getDocument().addDocumentListener(colorListener);
brightnessField.getDocument().addDocumentListener(colorListener);
redField.getDocument().addDocumentListener(colorListener);
greenField.getDocument().addDocumentListener(colorListener);
blueField.getDocument().addDocumentListener(colorListener);
hexField.getDocument().addDocumentListener(colorListener);
setColor(initialColor);
}
public void show() {
window.setVisible(true);
window.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
public void hide() {
window.setVisible(false);
setColor(new Color(Integer.parseInt(externalHex.getText().substring(0, 2), 16),
Integer.parseInt(externalHex.getText().substring(2, 4), 16),
Integer.parseInt(externalHex.getText().substring(4, 6), 16)));
}
public Color getColor() {
return new Color(red, green, blue);
}
public void setColor(Color color) {
updateRGB(color.getRGB());
}
public String getHexColor() {
return "#" + PApplet.hex(red, 2) + PApplet.hex(green, 2) + PApplet.hex(blue, 2);
}
public class ColorListener implements DocumentListener {
public void changedUpdate(DocumentEvent e) {
}
public void removeUpdate(DocumentEvent e) {
}
boolean updating;
public void insertUpdate(DocumentEvent e) {
if (updating) return; // don't update forever recursively
updating = true;
Document doc = e.getDocument();
if (doc == hueField.getDocument()) {
hue = bounded(hue, hueField, 359);
updateRGB();
updateHex();
} else if (doc == saturationField.getDocument()) {
saturation = bounded(saturation, saturationField, 99);
updateRGB();
updateHex();
} else if (doc == brightnessField.getDocument()) {
brightness = bounded(brightness, brightnessField, 99);
updateRGB();
updateHex();
} else if (doc == redField.getDocument()) {
red = bounded(red, redField, 255);
updateHSB();
updateHex();
} else if (doc == greenField.getDocument()) {
green = bounded(green, greenField, 255);
updateHSB();
updateHex();
} else if (doc == blueField.getDocument()) {
blue = bounded(blue, blueField, 255);
updateHSB();
updateHex();
} else if (doc == hexField.getDocument()) {
String str = hexField.getText();
if (str.startsWith("#")) {
str = str.substring(1);
}
while (str.length() < 6) {
str += "0";
}
if (str.length() > 6) {
str = str.substring(0, 6);
}
updateRGB(Integer.parseInt(str, 16));
updateHSB();
}
range.redraw();
slider.redraw();
colorPanel.repaint();
updating = false;
}
}
/**
* Set the RGB values based on the current HSB values.
*/
protected void updateRGB() {
updateRGB(Color.HSBtoRGB(hue / 359f,
saturation / 99f,
brightness / 99f));
}
/**
* Set the RGB values based on a calculated ARGB int.
* Used by both updateRGB() to set the color from the HSB values,
* and by updateHex(), to unpack the hex colors and assign them.
*/
protected void updateRGB(int rgb) {
red = (rgb >> 16) & 0xff;
green = (rgb >> 8) & 0xff;
blue = rgb & 0xff;
redField.setText(String.valueOf(red));
greenField.setText(String.valueOf(green));
blueField.setText(String.valueOf(blue));
}
/**
* Set the HSB values based on the current RGB values.
*/
protected void updateHSB() {
float hsb[] = new float[3];
Color.RGBtoHSB(red, green, blue, hsb);
hue = (int) (hsb[0] * 359.0f);
saturation = (int) (hsb[1] * 99.0f);
brightness = (int) (hsb[2] * 99.0f);
hueField.setText(String.valueOf(hue));
saturationField.setText(String.valueOf(saturation));
brightnessField.setText(String.valueOf(brightness));
}
protected void updateHex() {
hexField.setText(getHexColor());
}
/**
* Get the bounded value for a specific range. If the value is outside
* the max, you can't edit right away, so just act as if it's already
* been bounded and return the bounded value, then fire an event to set
* it to the value that was just returned.
*/
protected int bounded(int current, final JTextField field, final int max) {
String text = field.getText();
if (text.length() == 0) {
return 0;
}
try {
int value = Integer.parseInt(text);
if (value > max) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
field.setText(String.valueOf(max));
}
});
return max;
}
return value;
} catch (NumberFormatException e) {
return current; // should not be reachable
}
}
protected Container createColorFields(String buttonName, ActionListener buttonListener,
String buttonName2, ActionListener buttonListener2) {
Box box = Box.createVerticalBox();
box.setAlignmentY(0);
final int GAP = Base.isWindows() ? 5 : 0;
final int BETWEEN = Base.isWindows() ? 8 : 6; //10;
Box row;
row = Box.createHorizontalBox();
if (Base.isMacOS()) {
row.add(Box.createHorizontalStrut(17));
} else {
row.add(createFixedLabel(""));
}
// Can't just set the bg color of the panel because it also tints the bevel
// (on OS X), which looks odd. So instead we override paintComponent().
colorPanel = new JPanel() {
public void paintComponent(Graphics g) {
g.setColor(new Color(red, green, blue));
Dimension size = getSize();
g.fillRect(0, 0, size.width, size.height);
}
};
colorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
Dimension dim = new Dimension(70, 25);
colorPanel.setMinimumSize(dim);
colorPanel.setMaximumSize(dim);
colorPanel.setPreferredSize(dim);
row.add(colorPanel);
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(BETWEEN));
row = Box.createHorizontalBox();
row.add(createFixedLabel("H"));
row.add(hueField = new NumberField(4, false));
row.add(new JLabel(" \u00B0")); // degree symbol
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(GAP));
row = Box.createHorizontalBox();
row.add(createFixedLabel("S"));
row.add(saturationField = new NumberField(4, false));
row.add(new JLabel(" %"));
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(GAP));
row = Box.createHorizontalBox();
row.add(createFixedLabel("B"));
row.add(brightnessField = new NumberField(4, false));
row.add(new JLabel(" %"));
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(BETWEEN));
row = Box.createHorizontalBox();
row.add(createFixedLabel("R"));
row.add(redField = new NumberField(4, false));
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(GAP));
row = Box.createHorizontalBox();
row.add(createFixedLabel("G"));
row.add(greenField = new NumberField(4, false));
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(GAP));
row = Box.createHorizontalBox();
row.add(createFixedLabel("B"));
row.add(blueField = new NumberField(4, false));
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(BETWEEN));
row = Box.createHorizontalBox();
row.add(createFixedLabel(""));
// Windows needs extra space, OS X and Linux do not
// Mac OS X needs 6 because #CCCCCC is quite wide
final int hexCount = Base.isWindows() ? 7 : 6;
row.add(hexField = new NumberField(hexCount, true));
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalStrut(GAP));
row = Box.createHorizontalBox();
if (Base.isMacOS()) {
row.add(Box.createHorizontalStrut(11));
} else {
row.add(createFixedLabel(""));
}
JButton button = new JButton(buttonName);
button.addActionListener(buttonListener);
row.add(button);
row.add(Box.createHorizontalGlue());
box.add(row);
row = Box.createHorizontalBox();
if (Base.isMacOS()) {
row.add(Box.createHorizontalStrut(11));
} else {
row.add(createFixedLabel(""));
}
JButton button2 = new JButton(buttonName2);
button2.addActionListener(buttonListener2);
row.add(button2);
row.add(Box.createHorizontalGlue());
box.add(row);
box.add(Box.createVerticalGlue());
return box;
}
int labelH;
/**
* return a label of a fixed width
*/
protected JLabel createFixedLabel(String title) {
JLabel label = new JLabel(title);
if (labelH == 0) {
labelH = label.getPreferredSize().height;
}
Dimension dim = new Dimension(15, labelH);
label.setPreferredSize(dim);
label.setMinimumSize(dim);
label.setMaximumSize(dim);
return label;
}
public class ColorRange extends PApplet {
static final int WIDE = 256;
static final int HIGH = 256;
int lastX, lastY;
public void setup() {
size(WIDE, HIGH);
noLoop();
colorMode(HSB, 360, 256, 256);
noFill();
rectMode(CENTER);
loadPixels();
}
public void draw() {
if ((width != WIDE) || (height < HIGH)) {
return;
}
int index = 0;
for (int j = 0; j < 256; j++) {
for (int i = 0; i < 256; i++) {
pixels[index++] = color(hue, i, 255 - j);
}
}
updatePixels();
stroke((brightness > 50) ? 0 : 255);
rect(lastX, lastY, 9, 9);
}
public void mousePressed() {
updateMouse();
}
public void mouseDragged() {
updateMouse();
}
public void updateMouse() {
if ((mouseX >= 0) && (mouseX < 256) &&
(mouseY >= 0) && (mouseY < 256)) {
int nsaturation = (int) (100 * (mouseX / 255.0f));
int nbrightness = 100 - ((int) (100 * (mouseY / 255.0f)));
saturationField.setText(String.valueOf(nsaturation));
brightnessField.setText(String.valueOf(nbrightness));
lastX = mouseX;
lastY = mouseY;
}
}
public Dimension getPreferredSize() {
return new Dimension(WIDE, HIGH);
}
public Dimension getMinimumSize() {
return new Dimension(WIDE, HIGH);
}
public Dimension getMaximumSize() {
return new Dimension(WIDE, HIGH);
}
public void keyPressed() {
if (key == ESC) {
CustomColorChooser.this.hide();
// don't quit out of processing
// http://dev.processing.org/bugs/show_bug.cgi?id=1006
key = 0;
}
}
}
public class ColorSlider extends PApplet {
static final int WIDE = 20;
static final int HIGH = 256;
public void setup() {
size(WIDE, HIGH); //, P3D);
colorMode(HSB, 255, 100, 100);
noLoop();
loadPixels();
}
public void draw() {
if ((width != WIDE) || (height < HIGH)) {
return;
}
int index = 0;
int sel = 255 - (int) (255 * (hue / 359f));
for (int j = 0; j < 256; j++) {
int c = color(255 - j, 100, 100);
if (j == sel) c = 0xFF000000;
for (int i = 0; i < WIDE; i++) {
g.pixels[index++] = c;
}
}
updatePixels();
}
public void mousePressed() {
updateMouse();
}
public void mouseDragged() {
updateMouse();
}
public void updateMouse() {
if ((mouseX >= 0) && (mouseX < 256) &&
(mouseY >= 0) && (mouseY < 256)) {
int nhue = 359 - (int) (359 * (mouseY / 255.0f));
hueField.setText(String.valueOf(nhue));
}
}
public Dimension getPreferredSize() {
return new Dimension(WIDE, HIGH);
}
public Dimension getMinimumSize() {
return new Dimension(WIDE, HIGH);
}
public Dimension getMaximumSize() {
return new Dimension(WIDE, HIGH);
}
public void keyPressed() {
if (key == ESC) {
CustomColorChooser.this.hide();
// don't quit out of processing
// http://dev.processing.org/bugs/show_bug.cgi?id=1006
key = 0;
}
}
}
/**
* Extension of JTextField that only allows numbers
*/
class NumberField extends JTextField {
public boolean allowHex;
public NumberField(int cols, boolean allowHex) {
super(cols);
this.allowHex = allowHex;
}
protected Document createDefaultModel() {
return new NumberDocument(this);
}
public Dimension getPreferredSize() {
if (!allowHex) {
return new Dimension(45, super.getPreferredSize().height);
}
return super.getPreferredSize();
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
}
/**
* Document model to go with JTextField that only allows numbers.
*/
class NumberDocument extends PlainDocument {
NumberField parentField;
public NumberDocument(NumberField parentField) {
this.parentField = parentField;
}
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
if (str == null) return;
char chars[] = str.toCharArray();
int charCount = 0;
// remove any non-digit chars
for (int i = 0; i < chars.length; i++) {
boolean ok = Character.isDigit(chars[i]);
if (parentField.allowHex) {
if ((chars[i] >= 'A') && (chars[i] <= 'F')) ok = true;
if ((chars[i] >= 'a') && (chars[i] <= 'f')) ok = true;
if ((offs == 0) && (i == 0) && (chars[i] == '#')) ok = true;
}
if (ok) {
if (charCount != i) { // shift if necessary
chars[charCount] = chars[i];
}
charCount++;
}
}
super.insertString(offs, new String(chars, 0, charCount), a);
}
}
}
public void sketchbookCallback(File file) {
if (file != null) {
sketchbookLocationField.setText(file.getAbsolutePath());