2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 import java.awt.event.*;
24 import javax.swing.event.*;
25 import org.altusmetrum.altoslib_8.*;
26 import org.altusmetrum.altosuilib_8.*;
28 public class AltosConfigPyroUI
30 implements ItemListener, DocumentListener, AltosUnitsListener, ActionListener
35 static Insets il = new Insets(4,4,4,4);
36 static Insets ir = new Insets(4,4,4,4);
38 static String[] state_names;
40 static void make_state_names() {
41 if (state_names == null) {
43 state_names = new String[AltosLib.ao_flight_landed - AltosLib.ao_flight_boost + 1];
44 for (int state = AltosLib.ao_flight_boost; state <= AltosLib.ao_flight_landed; state++)
45 state_names[state - AltosLib.ao_flight_boost] = AltosLib.state_name_capital(state);
49 class PyroItem implements ItemListener, DocumentListener, AltosUnitsListener
52 public JCheckBox enable;
53 public JTextField value;
54 public JComboBox<String> combo;
58 public void set_enable(boolean enable) {
60 value.setEnabled(enable);
62 combo.setEnabled(enable);
65 public void itemStateChanged(ItemEvent e) {
66 set_enable(enable.isSelected());
71 public void changedUpdate(DocumentEvent e) {
76 public void insertUpdate(DocumentEvent e) {
81 public void removeUpdate(DocumentEvent e) {
86 public void units_changed(boolean imperial_units) {
87 AltosUnits units = AltosPyro.pyro_to_units(flag);
91 double v = units.parse_locale(value.getText(), !imperial_units);
93 } catch (ParseException pe) {
99 public void set(boolean new_enable, double new_value) {
101 enable.setSelected(new_enable);
102 set_enable(new_enable);
104 double scale = AltosPyro.pyro_to_scale(flag);
105 double unit_value = new_value;
106 AltosUnits units = AltosPyro.pyro_to_units(flag);
108 unit_value = units.value(new_value);
112 else if (scale >= 10)
116 value.setText(String.format(format, unit_value));
119 if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed)
120 combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost);
124 public boolean enabled() {
125 return enable.isSelected();
128 public double value() throws AltosConfigDataException {
130 AltosUnits units = AltosPyro.pyro_to_units(flag);
133 return units.parse_locale(value.getText());
134 return AltosParse.parse_double_locale(value.getText());
135 } catch (ParseException e) {
136 throw new AltosConfigDataException("\"%s\": %s\n", value.getText(), e.getMessage());
140 return combo.getSelectedIndex() + AltosLib.ao_flight_boost;
144 public PyroItem(AltosConfigPyroUI in_ui, int in_flag, int x, int y) {
149 GridBagConstraints c;
150 c = new GridBagConstraints();
151 c.gridx = x; c.gridy = y;
153 c.fill = GridBagConstraints.NONE;
154 c.anchor = GridBagConstraints.LINE_START;
156 enable = new JCheckBox();
157 enable.addItemListener(this);
160 if ((flag & AltosPyro.pyro_no_value) == 0) {
161 c = new GridBagConstraints();
162 c.gridx = x+1; c.gridy = y;
164 c.fill = GridBagConstraints.NONE;
165 c.anchor = GridBagConstraints.LINE_START;
167 if ((flag & AltosPyro.pyro_state_value) != 0) {
169 combo = new JComboBox<String>(state_names);
170 combo.addItemListener(this);
173 value = new JTextField(10);
174 value.getDocument().addDocumentListener(this);
181 class PyroColumn implements AltosUnitsListener {
182 public PyroItem[] items;
186 public void set(AltosPyro pyro) {
188 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
189 if ((AltosPyro.pyro_all & flag) != 0) {
190 items[row].set((pyro.flags & flag) != 0,
191 pyro.get_value(flag));
197 public AltosPyro get() throws AltosConfigDataException {
198 AltosPyro p = new AltosPyro(channel);
201 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
202 if ((AltosPyro.pyro_all & flag) != 0) {
203 if (items[row].enabled()) {
206 p.set_value(flag, items[row].value());
207 } catch (AltosConfigDataException ae) {
208 throw new AltosConfigDataException("%s, %s",
209 AltosPyro.pyro_to_name(flag),
219 public void units_changed(boolean imperial_units) {
221 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
222 if ((AltosPyro.pyro_all & flag) != 0) {
223 items[row].units_changed(imperial_units);
229 public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) {
231 channel = in_channel;
234 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
235 if ((flag & AltosPyro.pyro_all) != 0)
238 items = new PyroItem[nrow];
241 GridBagConstraints c;
242 c = new GridBagConstraints();
243 c.gridx = x; c.gridy = y;
245 c.fill = GridBagConstraints.NONE;
246 c.anchor = GridBagConstraints.CENTER;
248 label = new JLabel(String.format("Pyro Channel %c", 'A' + channel));
252 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
253 if ((flag & AltosPyro.pyro_all) != 0) {
254 items[row] = new PyroItem(ui, flag, x, y + row);
260 PyroColumn[] columns;
263 public void set_pyros(AltosPyro[] pyros) {
264 for (int i = 0; i < pyros.length; i++) {
265 if (pyros[i].channel < columns.length)
266 columns[pyros[i].channel].set(pyros[i]);
270 public AltosPyro[] get_pyros() throws AltosConfigDataException {
271 AltosPyro[] pyros = new AltosPyro[columns.length];
272 for (int c = 0; c < columns.length; c++) {
274 pyros[c] = columns[c].get();
275 } catch (AltosConfigDataException ae) {
276 throw new AltosConfigDataException ("Channel %c, %s", c + 'A', ae.getMessage());
282 JLabel pyro_firing_time_label;
283 JComboBox<String> pyro_firing_time_value;
285 static String[] pyro_firing_time_values = {
286 "0.050", "0.100", "0.250", "0.500", "1.0", "2.0"
289 boolean initializing;
291 public void set_pyro_firing_time(double new_pyro_firing_time) {
293 pyro_firing_time_value.setSelectedItem(Double.toString(new_pyro_firing_time));
294 pyro_firing_time_value.setEnabled(new_pyro_firing_time >= 0);
295 initializing = false;
298 public double get_pyro_firing_time() throws AltosConfigDataException {
299 String v = pyro_firing_time_value.getSelectedItem().toString();
302 return AltosParse.parse_double_locale(v);
303 } catch (ParseException e) {
304 throw new AltosConfigDataException("Invalid pyro firing time \"%s\"", v);
308 public void set_dirty() {
313 public void itemStateChanged(ItemEvent e) {
318 public void changedUpdate(DocumentEvent e) {
323 public void insertUpdate(DocumentEvent e) {
328 public void removeUpdate(DocumentEvent e) {
333 public void units_changed(boolean imperial_units) {
334 for (int c = 0; c < columns.length; c++)
335 columns[c].units_changed(imperial_units);
337 for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
338 String n = AltosPyro.pyro_to_name(flag);
340 labels[r].setText(n);
346 /* A window listener to catch closing events and tell the config code */
347 class ConfigListener extends WindowAdapter {
348 AltosConfigPyroUI ui;
351 public ConfigListener(AltosConfigPyroUI this_ui, AltosConfigUI this_owner) {
356 public void windowClosing(WindowEvent e) {
357 ui.setVisible(false);
361 /* Listen for events from our buttons */
362 public void actionPerformed(ActionEvent e) {
363 String cmd = e.getActionCommand();
365 if (cmd.equals("Close"))
369 public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros, double pyro_firing_time) {
371 super(in_owner, "Configure Pyro Channels", false);
375 GridBagConstraints c;
377 pane = getContentPane();
378 pane.setLayout(new GridBagLayout());
381 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
382 if ((flag & AltosPyro.pyro_all) != 0)
385 labels = new JLabel[nrow];
389 for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
392 n = AltosPyro.pyro_to_name(flag);
394 c = new GridBagConstraints();
395 c.gridx = 0; c.gridy = row;
397 c.fill = GridBagConstraints.NONE;
398 c.anchor = GridBagConstraints.LINE_START;
400 JLabel label = new JLabel(n);
402 labels[row-1] = label;
407 columns = new PyroColumn[pyros.length];
409 for (int i = 0; i < pyros.length; i++) {
410 columns[i] = new PyroColumn(this, i*2 + 1, 0, i);
411 columns[i].set(pyros[i]);
414 /* Pyro firing time */
415 c = new GridBagConstraints();
416 c.gridx = 0; c.gridy = row;
418 c.fill = GridBagConstraints.NONE;
419 c.anchor = GridBagConstraints.LINE_START;
422 pyro_firing_time_label = new JLabel("Pyro Firing Time(s):");
423 pane.add(pyro_firing_time_label, c);
425 c = new GridBagConstraints();
426 c.gridx = 2; c.gridy = row;
428 c.fill = GridBagConstraints.HORIZONTAL;
430 c.anchor = GridBagConstraints.LINE_START;
433 pyro_firing_time_value = new JComboBox<String>(pyro_firing_time_values);
434 pyro_firing_time_value.setEditable(true);
435 pyro_firing_time_value.addItemListener(this);
436 set_pyro_firing_time(pyro_firing_time);
437 pane.add(pyro_firing_time_value, c);
438 pyro_firing_time_value.setToolTipText("Length of extra pyro channel firing pulse");
440 c = new GridBagConstraints();
441 c.gridx = pyros.length*2-1;
442 c.fill = GridBagConstraints.HORIZONTAL;
445 JButton close = new JButton("Close");
447 close.addActionListener(this);
448 close.setActionCommand("Close");
450 addWindowListener(new ConfigListener(this, owner));
451 AltosPreferences.register_units_listener(this);
454 public void dispose() {
455 AltosPreferences.unregister_units_listener(this);
459 public void make_visible() {