libaltos: fix test harness main type
[fw/altos] / altosui / AltosConfigPyroUI.java
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
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.
7  *
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.
12  *
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.
16  */
17
18 package altosui;
19
20 import java.awt.*;
21 import java.awt.event.*;
22 import javax.swing.*;
23 import javax.swing.event.*;
24 import org.altusmetrum.altoslib_2.*;
25 import org.altusmetrum.altosuilib_1.*;
26
27 public class AltosConfigPyroUI
28         extends AltosUIDialog
29         implements ItemListener, DocumentListener, AltosUnitsListener
30 {
31         AltosConfigUI   owner;
32         Container       pane;
33
34         static Insets il = new Insets(4,4,4,4);
35         static Insets ir = new Insets(4,4,4,4);
36
37         static String[] state_names;
38
39         static void make_state_names() {
40                 if (state_names == null) {
41
42                         state_names = new String[AltosLib.ao_flight_landed - AltosLib.ao_flight_boost + 1];
43                         for (int state = AltosLib.ao_flight_boost; state <= AltosLib.ao_flight_landed; state++)
44                                 state_names[state - AltosLib.ao_flight_boost] = AltosLib.state_name_capital(state);
45                 }
46         }
47
48         class PyroItem implements ItemListener, DocumentListener, AltosUnitsListener
49         {
50                 public int              flag;
51                 public JRadioButton     enable;
52                 public JTextField       value;
53                 public JComboBox        combo;
54                 AltosConfigPyroUI       ui;
55                 boolean                 setting;
56
57                 public void set_enable(boolean enable) {
58                         if (value != null)
59                                 value.setEnabled(enable);
60                         if (combo != null)
61                                 combo.setEnabled(enable);
62                 }
63
64                 public void itemStateChanged(ItemEvent e) {
65                         set_enable(enable.isSelected());
66                         if (!setting) 
67                                 ui.set_dirty();
68                 }
69
70                 public void changedUpdate(DocumentEvent e) {
71                         if (!setting) 
72                                 ui.set_dirty();
73                 }
74
75                 public void insertUpdate(DocumentEvent e) {
76                         if (!setting) 
77                                 ui.set_dirty();
78                 }
79
80                 public void removeUpdate(DocumentEvent e) {
81                         if (!setting) 
82                                 ui.set_dirty();
83                 }
84
85                 public void units_changed(boolean imperial_units) {
86                         AltosUnits units = AltosPyro.pyro_to_units(flag);
87
88                         if (units != null) {
89                                 try {
90                                         double v = units.parse(value.getText(), !imperial_units);
91                                         set(enabled(), v);
92                                 } catch (NumberFormatException ne) {
93                                         set(enabled(), 0.0);
94                                 }
95                         }
96                 }
97
98                 public void set(boolean new_enable, double new_value) {
99                         setting = true;
100                         enable.setSelected(new_enable);
101                         set_enable(new_enable);
102                         if (value != null) {
103                                 double  scale = AltosPyro.pyro_to_scale(flag);
104                                 double  unit_value = new_value;
105                                 AltosUnits units = AltosPyro.pyro_to_units(flag);
106                                 if (units != null)
107                                         unit_value = units.value(new_value);
108                                 String  format = "%6.0f";
109                                 if (scale >= 10)
110                                         format = "%6.1f";
111                                 else if (scale >= 100)
112                                         format = "%6.2f";
113                                 value.setText(String.format(format, unit_value));
114                         }
115                         if (combo != null)
116                                 if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed)
117                                         combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost);
118                         setting = false;
119                 }
120
121                 public boolean enabled() {
122                         return enable.isSelected();
123                 }
124
125                 public double value() {
126                         if (value != null) {
127                                 AltosUnits units = AltosPyro.pyro_to_units(flag);
128                                 if (units != null)
129                                         return units.parse(value.getText());
130                                 return Double.parseDouble(value.getText());
131                         }
132                         if (combo != null)
133                                 return combo.getSelectedIndex() + AltosLib.ao_flight_boost;
134                         return 0;
135                 }
136
137                 public PyroItem(AltosConfigPyroUI in_ui, int in_flag, int x, int y) {
138
139                         ui = in_ui;
140                         flag = in_flag;
141
142                         GridBagConstraints      c;
143                         c = new GridBagConstraints();
144                         c.gridx = x; c.gridy = y;
145                         c.gridwidth = 1;
146                         c.fill = GridBagConstraints.NONE;
147                         c.anchor = GridBagConstraints.LINE_START;
148                         c.insets = il;
149                         enable = new JRadioButton();
150                         enable.addItemListener(this);
151                         pane.add(enable, c);
152                         
153                         if ((flag & AltosPyro.pyro_no_value) == 0) {
154                                 c = new GridBagConstraints();
155                                 c.gridx = x+1; c.gridy = y;
156                                 c.gridwidth = 1;
157                                 c.fill = GridBagConstraints.NONE;
158                                 c.anchor = GridBagConstraints.LINE_START;
159                                 c.insets = il;
160                                 if ((flag & AltosPyro.pyro_state_value) != 0) {
161                                         make_state_names();
162                                         combo = new JComboBox(state_names);
163                                         combo.addItemListener(this);
164                                         pane.add(combo, c);
165                                 } else {
166                                         value = new JTextField(10);
167                                         value.getDocument().addDocumentListener(this);
168                                         pane.add(value, c);
169                                 }
170                         }
171                 }
172         }
173
174         class PyroColumn implements AltosUnitsListener {
175                 public PyroItem[]       items;
176                 public JLabel           label;
177                 int                     channel;
178
179                 public void set(AltosPyro pyro) {
180                         int row = 0;
181                         for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
182                                 if ((AltosPyro.pyro_all & flag) != 0) {
183                                         items[row].set((pyro.flags & flag) != 0,
184                                                        pyro.get_value(flag));
185                                         row++;
186                                 }
187                         }
188                 }
189
190                 public AltosPyro get() {
191                         AltosPyro       p = new AltosPyro(channel);
192
193                         int row = 0;
194                         for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
195                                 if ((AltosPyro.pyro_all & flag) != 0) {
196                                         if (items[row].enabled()) {
197                                                 p.flags |= flag;
198                                                 p.set_value(flag, items[row].value());
199                                         }
200                                         row++;
201                                 }
202                         }
203                         return p;
204                 }
205
206                 public void units_changed(boolean imperial_units) {
207                         int row = 0;
208                         for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
209                                 if ((AltosPyro.pyro_all & flag) != 0) {
210                                         items[row].units_changed(imperial_units);
211                                         row++;
212                                 }
213                         }
214                 }
215
216                 public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) {
217
218                         channel = in_channel;
219
220                         int     nrow = 0;
221                         for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
222                                 if ((flag & AltosPyro.pyro_all) != 0)
223                                         nrow++;
224
225                         items = new PyroItem[nrow];
226                         int row = 0;
227                         
228                         GridBagConstraints      c;
229                         c = new GridBagConstraints();
230                         c.gridx = x; c.gridy = y;
231                         c.gridwidth = 2;
232                         c.fill = GridBagConstraints.NONE;
233                         c.anchor = GridBagConstraints.CENTER;
234                         c.insets = il;
235                         label = new JLabel(String.format("Pyro Channel %d", channel));
236                         pane.add(label, c);
237                         y++;
238
239                         for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
240                                 if ((flag & AltosPyro.pyro_all) != 0) {
241                                         items[row] = new PyroItem(ui, flag, x, y + row);
242                                         row++;
243                                 }
244                 }
245         }
246
247         PyroColumn[]    columns;
248         JLabel[]        labels;
249
250         public void set_pyros(AltosPyro[] pyros) {
251                 for (int i = 0; i < pyros.length; i++) {
252                         if (pyros[i].channel < columns.length)
253                                 columns[pyros[i].channel].set(pyros[i]);
254                 }
255         }
256
257         public AltosPyro[] get_pyros() {
258                 AltosPyro[]     pyros = new AltosPyro[columns.length];
259                 for (int c = 0; c < columns.length; c++)
260                         pyros[c] = columns[c].get();
261                 return pyros;
262         }
263
264         public void set_dirty() {
265                 owner.set_dirty();
266         }
267
268         public void itemStateChanged(ItemEvent e) {
269                 owner.set_dirty();
270         }
271
272         public void changedUpdate(DocumentEvent e) {
273                 owner.set_dirty();
274         }
275
276         public void insertUpdate(DocumentEvent e) {
277                 owner.set_dirty();
278         }
279
280         public void removeUpdate(DocumentEvent e) {
281                 owner.set_dirty();
282         }
283
284         public void units_changed(boolean imperial_units) {
285                 for (int c = 0; c < columns.length; c++)
286                         columns[c].units_changed(imperial_units);
287                 int r = 0;
288                 for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
289                         String n = AltosPyro.pyro_to_name(flag);
290                         if (n != null) {
291                                 labels[r].setText(n);
292                                 r++;
293                         }
294                 }
295         }
296
297         /* A window listener to catch closing events and tell the config code */
298         class ConfigListener extends WindowAdapter {
299                 AltosConfigPyroUI       ui;
300                 AltosConfigUI           owner;
301
302                 public ConfigListener(AltosConfigPyroUI this_ui, AltosConfigUI this_owner) {
303                         ui = this_ui;
304                         owner = this_owner;
305                 }
306
307                 public void windowClosing(WindowEvent e) {
308                         ui.setVisible(false);
309                 }
310         }
311
312         public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros) {
313
314                 super(in_owner, "Configure Pyro Channels", false);
315
316                 owner = in_owner;
317
318                 GridBagConstraints      c;
319
320                 pane = getContentPane();
321                 pane.setLayout(new GridBagLayout());
322
323                 int     nrow = 0;
324                 for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
325                         if ((flag & AltosPyro.pyro_all) != 0)
326                                 nrow++;
327
328                 labels = new JLabel[nrow];
329
330                 int     row = 1;
331
332                 for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
333                         String  n;
334
335                         n = AltosPyro.pyro_to_name(flag);
336                         if (n != null) {
337                                 c = new GridBagConstraints();
338                                 c.gridx = 0; c.gridy = row;
339                                 c.gridwidth = 1;
340                                 c.fill = GridBagConstraints.NONE;
341                                 c.anchor = GridBagConstraints.LINE_START;
342                                 c.insets = il;
343                                 JLabel label = new JLabel(n);
344                                 pane.add(label, c);
345                                 labels[row-1] = label;
346                                 row++;
347                         }
348                 }
349
350                 columns = new PyroColumn[pyros.length];
351
352                 for (int i = 0; i < pyros.length; i++) {
353                         columns[i] = new PyroColumn(this, i*2 + 1, 0, i);
354                         columns[i].set(pyros[i]);
355                 }
356                 addWindowListener(new ConfigListener(this, owner));
357                 AltosPreferences.register_units_listener(this);
358         }
359
360         public void dispose() {
361                 AltosPreferences.unregister_units_listener(this);
362                 super.dispose();
363         }
364
365         public void make_visible() {
366                 pack();
367                 setVisible(true);
368         }
369 }