ConfigItem: add colour field
[fanfix.git] / src / be / nikiroo / utils / ui / ConfigItem.java
CommitLineData
d350b96b
NR
1package be.nikiroo.utils.ui;
2
3import java.awt.BorderLayout;
424dcb0d 4import java.awt.Color;
c637d2e0 5import java.awt.Dimension;
424dcb0d
NR
6import java.awt.Graphics2D;
7import java.awt.event.ActionEvent;
8import java.awt.event.ActionListener;
9import java.awt.image.BufferedImage;
10
11import javax.swing.Icon;
12import javax.swing.ImageIcon;
13import javax.swing.JButton;
9e834013 14import javax.swing.JCheckBox;
424dcb0d 15import javax.swing.JColorChooser;
8517b60c 16import javax.swing.JLabel;
d350b96b
NR
17import javax.swing.JPanel;
18import javax.swing.JTextField;
d350b96b
NR
19
20import be.nikiroo.utils.resources.Bundle;
9e834013
NR
21import be.nikiroo.utils.resources.Meta.Format;
22import be.nikiroo.utils.resources.MetaInfo;
d350b96b
NR
23
24/**
25 * A graphical item that reflect a configuration option from the given
26 * {@link Bundle}.
27 *
28 * @author niki
db31c358 29 *
d350b96b
NR
30 * @param <E>
31 * the type of {@link Bundle} to edit
32 */
33public class ConfigItem<E extends Enum<E>> extends JPanel {
34 private static final long serialVersionUID = 1L;
db31c358 35
9e834013 36 public ConfigItem(final MetaInfo<E> info) {
d350b96b 37 this.setLayout(new BorderLayout());
d350b96b 38
9e834013
NR
39 if (info.getFormat() == Format.BOOLEAN) {
40 final JCheckBox field = new JCheckBox();
41 field.setToolTipText(info.getDescription());
42 Boolean state = info.getBoolean();
43 if (state == null) {
44 info.getDefaultBoolean();
db31c358 45 }
d350b96b 46
9e834013
NR
47 // Should not happen!
48 if (state == null) {
49 System.err
8517b60c
NR
50 .println("No default value given for BOOLEAN parameter \""
51 + info.getName()
52 + "\", we consider it is FALSE");
9e834013
NR
53 state = false;
54 }
d350b96b 55
9e834013
NR
56 field.setSelected(state);
57
8517b60c 58 info.addReloadedListener(new Runnable() {
9e834013
NR
59 @Override
60 public void run() {
8517b60c
NR
61 Boolean state = info.getBoolean();
62 if (state == null) {
63 info.getDefaultBoolean();
64 }
65 if (state == null) {
66 state = false;
67 }
68
69 field.setSelected(state);
70 }
71 });
72 info.addSaveListener(new Runnable() {
73 @Override
74 public void run() {
75 info.setBoolean(field.isSelected());
9e834013
NR
76 }
77 });
78
c637d2e0 79 field.setText(info.getName());
9e834013 80 this.add(field, BorderLayout.CENTER);
424dcb0d
NR
81 } else if (info.getFormat() == Format.COLOR) {
82 final JTextField field = new JTextField();
83 field.setToolTipText(info.getDescription());
84 field.setText(info.getString());
85
86 info.addReloadedListener(new Runnable() {
87 @Override
88 public void run() {
89 field.setText(info.getString());
90 }
91 });
92 info.addSaveListener(new Runnable() {
93 @Override
94 public void run() {
95 info.setString(field.getText());
96 }
97 });
98
99 this.add(label(info.getName()), BorderLayout.WEST);
100 JPanel pane = new JPanel(new BorderLayout());
101
102 final JButton colorWheel = new JButton();
103 colorWheel.setIcon(getIcon(17, info.getColor()));
104 colorWheel.addActionListener(new ActionListener() {
105 @Override
106 public void actionPerformed(ActionEvent e) {
107 Color initialColor = new Color(info.getColor(), true);
108 Color newColor = JColorChooser.showDialog(ConfigItem.this,
109 info.getName(), initialColor);
110 if (newColor != null) {
111 info.setColor(newColor.getRGB());
112 field.setText(info.getString());
113 colorWheel.setIcon(getIcon(17, info.getColor()));
114 }
115 }
116 });
117 pane.add(colorWheel, BorderLayout.WEST);
118 pane.add(field, BorderLayout.CENTER);
119 this.add(pane, BorderLayout.CENTER);
9e834013
NR
120 } else {
121 final JTextField field = new JTextField();
122 field.setToolTipText(info.getDescription());
123 field.setText(info.getString());
124
8517b60c 125 info.addReloadedListener(new Runnable() {
9e834013
NR
126 @Override
127 public void run() {
128 field.setText(info.getString());
129 }
130 });
8517b60c
NR
131 info.addSaveListener(new Runnable() {
132 @Override
133 public void run() {
134 info.setString(field.getText());
135 }
136 });
9e834013 137
c637d2e0 138 this.add(label(info.getName()), BorderLayout.WEST);
9e834013 139 this.add(field, BorderLayout.CENTER);
d350b96b 140 }
d350b96b 141 }
c637d2e0
NR
142
143 /**
144 * Create a label which width is constrained in lock steps.
145 *
146 * @param text
147 * the text of the label
148 *
149 * @return the label
150 */
151 private JLabel label(String text) {
152 final JLabel label = new JLabel(text);
153
154 Dimension ps = label.getPreferredSize();
155 if (ps == null) {
156 ps = label.getSize();
157 }
158
159 int w = ps.width;
160 int step = 80;
161 for (int i = 2 * step; i < 10 * step; i += step) {
162 if (w < i) {
163 w = i;
164 break;
165 }
166 }
167
168 ps.width = w;
169 label.setSize(ps);
170 label.setPreferredSize(ps);
171
172 return label;
173 }
424dcb0d
NR
174
175 /**
176 * Return an {@link Icon} to use as a colour badge for the colour field
177 * controls.
178 *
179 * @param size
180 * the size of the badge
181 * @param color
182 * the colour of the badge
183 *
184 * @return the badge
185 */
186 private Icon getIcon(int size, int color) {
187 Color c = new Color(color, true);
188 int avg = (c.getRed() + c.getGreen() + c.getBlue()) / 3;
189 Color border = (avg >= 128 ? Color.BLACK : Color.WHITE);
190
191 BufferedImage img = new BufferedImage(size, size,
192 BufferedImage.TYPE_4BYTE_ABGR);
193
194 Graphics2D g = img.createGraphics();
195 try {
196 g.setColor(c);
197 g.fillRect(0, 0, img.getWidth(), img.getHeight());
198 g.setColor(border);
199 g.drawRect(0, 0, img.getWidth() - 1, img.getHeight() - 1);
200 } finally {
201 g.dispose();
202 }
203
204 return new ImageIcon(img);
205 }
d350b96b 206}