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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 import java.awt.event.*;
25 import javax.swing.event.*;
26 import org.altusmetrum.altoslib_14.*;
27 import org.altusmetrum.altosuilib_14.*;
29 public class AltosConfigPyroUI
31 implements ItemListener, DocumentListener, AltosUnitsListener, ActionListener
33 AltosConfigFCUI owner;
36 static Insets il = new Insets(4,4,4,4);
37 static Insets ir = new Insets(4,4,4,4);
39 static String[] state_names;
41 static void make_state_names() {
42 if (state_names == null) {
44 state_names = new String[AltosLib.ao_flight_landed - AltosLib.ao_flight_boost + 1];
45 for (int state = AltosLib.ao_flight_boost; state <= AltosLib.ao_flight_landed; state++)
46 state_names[state - AltosLib.ao_flight_boost] = AltosLib.state_name_capital(state);
50 class PyroItem implements ItemListener, DocumentListener, AltosUnitsListener
53 public JCheckBox enable;
54 public JTextField value;
55 public JComboBox<String> combo;
59 public void set_enable(boolean enable) {
61 value.setEnabled(enable);
63 combo.setEnabled(enable);
66 public void itemStateChanged(ItemEvent e) {
67 set_enable(enable.isSelected());
72 public void changedUpdate(DocumentEvent e) {
77 public void insertUpdate(DocumentEvent e) {
82 public void removeUpdate(DocumentEvent e) {
87 public void units_changed(boolean imperial_units) {
88 AltosUnits units = AltosPyro.pyro_to_units(flag);
92 double v = units.parse_locale(value.getText(), !imperial_units);
94 } catch (ParseException pe) {
100 public void set(boolean new_enable, double new_value) {
102 enable.setSelected(new_enable);
103 set_enable(new_enable);
105 double scale = AltosPyro.pyro_to_scale(flag);
106 double unit_value = new_value;
107 AltosUnits units = AltosPyro.pyro_to_units(flag);
109 unit_value = units.parse_value(new_value);
113 else if (scale >= 10)
117 value.setText(String.format(format, unit_value));
120 if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed)
121 combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost);
125 public boolean enabled() {
126 return enable.isSelected();
129 public double value() throws AltosConfigDataException {
131 AltosUnits units = AltosPyro.pyro_to_units(flag);
134 return units.parse_locale(value.getText());
135 return AltosParse.parse_double_locale(value.getText());
136 } catch (ParseException e) {
137 throw new AltosConfigDataException("\"%s\": %s\n", value.getText(), e.getMessage());
141 return combo.getSelectedIndex() + AltosLib.ao_flight_boost;
145 public PyroItem(AltosConfigPyroUI in_ui, int in_flag, int x, int y) {
150 GridBagConstraints c;
151 c = new GridBagConstraints();
152 c.gridx = x; c.gridy = y;
154 c.fill = GridBagConstraints.NONE;
155 c.anchor = GridBagConstraints.LINE_START;
157 enable = new JCheckBox();
158 enable.addItemListener(this);
161 if ((flag & AltosPyro.pyro_no_value) == 0) {
162 c = new GridBagConstraints();
163 c.gridx = x+1; c.gridy = y;
165 c.fill = GridBagConstraints.NONE;
166 c.anchor = GridBagConstraints.LINE_START;
168 if ((flag & AltosPyro.pyro_state_value) != 0) {
170 combo = new JComboBox<String>(state_names);
171 combo.addItemListener(this);
174 value = new JTextField(10);
175 value.getDocument().addDocumentListener(this);
182 class PyroColumn implements AltosUnitsListener {
183 public PyroItem[] items;
187 public void set(AltosPyro pyro) {
189 if ((pyro.flags & AltosPyro.pyro_deprecate) != 0) {
190 JOptionPane.showMessageDialog(owner,
191 String.format("Pyro settings “Ascending” and “Descending” are deprecated.\n" +
192 "Clearing %s configuration.", AltosLib.igniter_name(pyro.channel)),
193 "Deprecated Pyro Settings",
194 JOptionPane.ERROR_MESSAGE);
198 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
199 if ((AltosPyro.pyro_all_useful & flag) != 0) {
200 items[row].set((pyro.flags & flag) != 0,
201 pyro.get_value(flag));
207 public AltosPyro get() throws AltosConfigDataException {
208 AltosPyro p = new AltosPyro(channel);
211 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
212 if ((AltosPyro.pyro_all_useful & flag) != 0) {
213 if (items[row].enabled()) {
216 p.set_value(flag, items[row].value());
217 } catch (AltosConfigDataException ae) {
218 throw new AltosConfigDataException("%s, %s",
219 AltosPyro.pyro_to_name(flag),
229 public void units_changed(boolean imperial_units) {
231 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
232 if ((AltosPyro.pyro_all_useful & flag) != 0) {
233 items[row].units_changed(imperial_units);
239 public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) {
241 channel = in_channel;
244 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
245 if ((flag & AltosPyro.pyro_all_useful) != 0)
248 items = new PyroItem[nrow];
251 GridBagConstraints c;
252 c = new GridBagConstraints();
253 c.gridx = x; c.gridy = y;
255 c.fill = GridBagConstraints.NONE;
256 c.anchor = GridBagConstraints.CENTER;
258 label = new JLabel(String.format("Pyro Channel %c", 'A' + channel));
262 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
263 if ((flag & AltosPyro.pyro_all_useful) != 0) {
264 items[row] = new PyroItem(ui, flag, x, y + row);
270 PyroColumn[] columns;
273 public void set_pyros(AltosPyro[] pyros) {
274 for (int i = 0; i < pyros.length; i++) {
275 if (pyros[i].channel < columns.length)
276 columns[pyros[i].channel].set(pyros[i]);
280 public AltosPyro[] get_pyros() throws AltosConfigDataException {
281 AltosPyro[] pyros = new AltosPyro[columns.length];
282 for (int c = 0; c < columns.length; c++) {
284 pyros[c] = columns[c].get();
285 } catch (AltosConfigDataException ae) {
286 throw new AltosConfigDataException ("Channel %c, %s", c + 'A', ae.getMessage());
292 JLabel pyro_firing_time_label;
293 JComboBox<String> pyro_firing_time_value;
295 static String[] pyro_firing_time_values = {
296 "0.050", "0.100", "0.250", "0.500", "1.0", "2.0"
299 boolean initializing;
301 public void set_pyro_firing_time(double new_pyro_firing_time) {
303 pyro_firing_time_value.setSelectedItem(Double.toString(new_pyro_firing_time));
304 pyro_firing_time_value.setEnabled(new_pyro_firing_time >= 0);
305 initializing = false;
308 public double get_pyro_firing_time() throws AltosConfigDataException {
309 String v = pyro_firing_time_value.getSelectedItem().toString();
312 return AltosParse.parse_double_locale(v);
313 } catch (ParseException e) {
314 throw new AltosConfigDataException("Invalid pyro firing time \"%s\"", v);
318 public void set_dirty() {
323 public void itemStateChanged(ItemEvent e) {
328 public void changedUpdate(DocumentEvent e) {
333 public void insertUpdate(DocumentEvent e) {
338 public void removeUpdate(DocumentEvent e) {
343 public void units_changed(boolean imperial_units) {
344 for (int c = 0; c < columns.length; c++)
345 columns[c].units_changed(imperial_units);
347 for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
348 if ((flag & AltosPyro.pyro_all_useful) != 0) {
349 String n = AltosPyro.pyro_to_name(flag);
351 labels[r].setText(n);
358 /* A window listener to catch closing events and tell the config code */
359 class ConfigListener extends WindowAdapter {
360 AltosConfigPyroUI ui;
361 AltosConfigFCUI owner;
363 public ConfigListener(AltosConfigPyroUI this_ui, AltosConfigFCUI this_owner) {
368 public void windowClosing(WindowEvent e) {
369 ui.setVisible(false);
373 /* Listen for events from our buttons */
374 public void actionPerformed(ActionEvent e) {
375 String cmd = e.getActionCommand();
377 if (cmd.equals("Close"))
381 public AltosConfigPyroUI(AltosConfigFCUI in_owner, AltosPyro[] pyros, double pyro_firing_time) {
383 super(in_owner, "Configure Pyro Channels", false);
387 GridBagConstraints c;
389 pane = getScrollablePane();
390 pane.setLayout(new GridBagLayout());
393 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
394 if ((flag & AltosPyro.pyro_all_useful) != 0)
397 labels = new JLabel[nrow];
401 for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
404 if ((flag & AltosPyro.pyro_all_useful) != 0) {
405 n = AltosPyro.pyro_to_name(flag);
407 c = new GridBagConstraints();
408 c.gridx = 0; c.gridy = row;
410 c.fill = GridBagConstraints.NONE;
411 c.anchor = GridBagConstraints.LINE_START;
413 JLabel label = new JLabel(n);
415 labels[row-1] = label;
421 columns = new PyroColumn[pyros.length];
423 for (int i = 0; i < pyros.length; i++) {
424 columns[i] = new PyroColumn(this, i*2 + 1, 0, i);
425 columns[i].set(pyros[i]);
428 /* Pyro firing time */
429 c = new GridBagConstraints();
430 c.gridx = 0; c.gridy = row;
432 c.fill = GridBagConstraints.NONE;
433 c.anchor = GridBagConstraints.LINE_START;
436 pyro_firing_time_label = new JLabel("Pyro Firing Time(s):");
437 pane.add(pyro_firing_time_label, c);
439 c = new GridBagConstraints();
440 c.gridx = 2; c.gridy = row;
442 c.fill = GridBagConstraints.HORIZONTAL;
444 c.anchor = GridBagConstraints.LINE_START;
447 pyro_firing_time_value = new JComboBox<String>(pyro_firing_time_values);
448 pyro_firing_time_value.setEditable(true);
449 pyro_firing_time_value.addItemListener(this);
450 set_pyro_firing_time(pyro_firing_time);
451 pane.add(pyro_firing_time_value, c);
452 pyro_firing_time_value.setToolTipText("Length of extra pyro channel firing pulse");
454 c = new GridBagConstraints();
455 c.gridx = pyros.length*2-1;
456 c.fill = GridBagConstraints.HORIZONTAL;
459 JButton close = new JButton("Close");
461 close.addActionListener(this);
462 close.setActionCommand("Close");
464 addWindowListener(new ConfigListener(this, owner));
465 AltosPreferences.register_units_listener(this);
468 public void dispose() {
469 AltosPreferences.unregister_units_listener(this);
473 public void make_visible() {