altoslib/altosuilib: Change versions to altoslib:4, altosuilib:2
[fw/altos] / altosui / AltosAscent.java
1 /*
2  * Copyright © 2010 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 javax.swing.*;
22 import org.altusmetrum.altoslib_4.*;
23 import org.altusmetrum.altosuilib_2.*;
24
25 public class AltosAscent extends JComponent implements AltosFlightDisplay {
26         GridBagLayout   layout;
27         JLabel                  cur, max;
28
29         public class AscentStatus {
30                 JLabel          label;
31                 JTextField      value;
32                 AltosLights     lights;
33
34                 void show() {
35                         value.setVisible(true);
36                         lights.setVisible(true);
37                         label.setVisible(true);
38                 }
39
40                 void hide() {
41                         value.setVisible(false);
42                         lights.setVisible(false);
43                         label.setVisible(false);
44                 }
45
46                 void show(AltosState state, AltosListenerState listener_state) {}
47
48                 void show(String s) {
49                         show();
50                         value.setText(s);
51                 }
52
53                 void show(AltosUnits units, double v) {
54                         show(units.show(8, v));
55                 }
56
57                 void show(String format, double v) {
58                         show(String.format(format, v));
59                 }
60
61                 void reset() {
62                         value.setText("");
63                         lights.set(false);
64                 }
65
66                 void set_font() {
67                         label.setFont(Altos.label_font);
68                         value.setFont(Altos.value_font);
69                 }
70
71                 public AscentStatus (GridBagLayout layout, int y, String text) {
72                         GridBagConstraints      c = new GridBagConstraints();
73                         c.weighty = 1;
74
75                         lights = new AltosLights();
76                         c.gridx = 0; c.gridy = y;
77                         c.anchor = GridBagConstraints.CENTER;
78                         c.fill = GridBagConstraints.VERTICAL;
79                         c.weightx = 0;
80                         layout.setConstraints(lights, c);
81                         add(lights);
82
83                         label = new JLabel(text);
84                         label.setFont(Altos.label_font);
85                         label.setHorizontalAlignment(SwingConstants.LEFT);
86                         c.gridx = 1; c.gridy = y;
87                         c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
88                         c.anchor = GridBagConstraints.WEST;
89                         c.fill = GridBagConstraints.VERTICAL;
90                         c.weightx = 0;
91                         layout.setConstraints(label, c);
92                         add(label);
93
94                         value = new JTextField(Altos.text_width);
95                         value.setFont(Altos.value_font);
96                         value.setHorizontalAlignment(SwingConstants.RIGHT);
97                         c.gridx = 2; c.gridy = y;
98                         c.gridwidth = 2;
99                         c.anchor = GridBagConstraints.WEST;
100                         c.fill = GridBagConstraints.BOTH;
101                         c.weightx = 1;
102                         layout.setConstraints(value, c);
103                         add(value);
104
105                 }
106         }
107
108         public class AscentValue {
109                 JLabel          label;
110                 JTextField      value;
111                 void show(AltosState state, AltosListenerState listener_state) {}
112
113                 void reset() {
114                         value.setText("");
115                 }
116
117                 void show() {
118                         label.setVisible(true);
119                         value.setVisible(true);
120                 }
121
122                 void show(String s) {
123                         show();
124                         value.setText(s);
125                 }
126
127                 void show(AltosUnits units, double v) {
128                         show(units.show(8, v));
129                 }
130
131                 void show(String format, double v) {
132                         show(String.format(format, v));
133                 }
134
135                 void hide() {
136                         label.setVisible(false);
137                         value.setVisible(false);
138                 }
139                 void set_font() {
140                         label.setFont(Altos.label_font);
141                         value.setFont(Altos.value_font);
142                 }
143
144                 public AscentValue (GridBagLayout layout, int y, String text) {
145                         GridBagConstraints      c = new GridBagConstraints();
146                         c.weighty = 1;
147
148                         label = new JLabel(text);
149                         label.setFont(Altos.label_font);
150                         label.setHorizontalAlignment(SwingConstants.LEFT);
151                         c.gridx = 1; c.gridy = y;
152                         c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
153                         c.anchor = GridBagConstraints.WEST;
154                         c.fill = GridBagConstraints.VERTICAL;
155                         c.weightx = 0;
156                         layout.setConstraints(label, c);
157                         add(label);
158
159                         value = new JTextField(Altos.text_width);
160                         value.setFont(Altos.value_font);
161                         value.setHorizontalAlignment(SwingConstants.RIGHT);
162                         c.gridx = 2; c.gridy = y;
163                         c.anchor = GridBagConstraints.WEST;
164                         c.fill = GridBagConstraints.BOTH;
165                         c.gridwidth = 2;
166                         c.weightx = 1;
167                         layout.setConstraints(value, c);
168                         add(value);
169                 }
170         }
171
172         public class AscentValueHold {
173                 JLabel          label;
174                 JTextField      value;
175                 JTextField      max_value;
176                 double          max;
177
178                 void show(AltosState state, AltosListenerState listener_state) {}
179
180                 void reset() {
181                         value.setText("");
182                         max_value.setText("");
183                         max = AltosLib.MISSING;
184                 }
185
186                 void set_font() {
187                         label.setFont(Altos.label_font);
188                         value.setFont(Altos.value_font);
189                         max_value.setFont(Altos.value_font);
190                 }
191
192                 void show(AltosUnits units, double v) {
193                         if (v == AltosLib.MISSING) {
194                                 value.setText("Missing");
195                                 max_value.setText("Missing");
196                         } else {
197                                 value.setText(units.show(8, v));
198                                 if (v > max || max == AltosLib.MISSING) {
199                                         max_value.setText(units.show(8, v));
200                                         max = v;
201                                 }
202                         }
203                 }
204
205                 void hide() {
206                         label.setVisible(false);
207                         value.setVisible(false);
208                         max_value.setVisible(false);
209                 }
210
211                 public AscentValueHold (GridBagLayout layout, int y, String text) {
212                         GridBagConstraints      c = new GridBagConstraints();
213                         c.weighty = 1;
214
215                         label = new JLabel(text);
216                         label.setFont(Altos.label_font);
217                         label.setHorizontalAlignment(SwingConstants.LEFT);
218                         c.gridx = 1; c.gridy = y;
219                         c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
220                         c.anchor = GridBagConstraints.WEST;
221                         c.fill = GridBagConstraints.VERTICAL;
222                         c.weightx = 0;
223                         layout.setConstraints(label, c);
224                         add(label);
225
226                         value = new JTextField(Altos.text_width);
227                         value.setFont(Altos.value_font);
228                         value.setHorizontalAlignment(SwingConstants.RIGHT);
229                         c.gridx = 2; c.gridy = y;
230                         c.anchor = GridBagConstraints.EAST;
231                         c.fill = GridBagConstraints.BOTH;
232                         c.weightx = 1;
233                         layout.setConstraints(value, c);
234                         add(value);
235
236                         max_value = new JTextField(Altos.text_width);
237                         max_value.setFont(Altos.value_font);
238                         max_value.setHorizontalAlignment(SwingConstants.RIGHT);
239                         c.gridx = 3; c.gridy = y;
240                         c.anchor = GridBagConstraints.EAST;
241                         c.fill = GridBagConstraints.BOTH;
242                         c.weightx = 1;
243                         layout.setConstraints(max_value, c);
244                         add(max_value);
245                 }
246         }
247
248
249         class Height extends AscentValueHold {
250                 void show (AltosState state, AltosListenerState listener_state) {
251                         show(AltosConvert.height, state.height());
252                 }
253                 public Height (GridBagLayout layout, int y) {
254                         super (layout, y, "Height");
255                 }
256         }
257
258         Height  height;
259
260         class Speed extends AscentValueHold {
261                 void show (AltosState state, AltosListenerState listener_state) {
262                         show(AltosConvert.speed, state.speed());
263                 }
264                 public Speed (GridBagLayout layout, int y) {
265                         super (layout, y, "Speed");
266                 }
267         }
268
269         Speed   speed;
270
271         class Accel extends AscentValueHold {
272                 void show (AltosState state, AltosListenerState listener_state) {
273                         show(AltosConvert.accel, state.acceleration());
274                 }
275                 public Accel (GridBagLayout layout, int y) {
276                         super (layout, y, "Acceleration");
277                 }
278         }
279
280         Accel   accel;
281
282         class Orient extends AscentValueHold {
283                 void show (AltosState state, AltosListenerState listener_state) {
284                         show(AltosConvert.orient, state.orient());
285                 }
286                 public Orient (GridBagLayout layout, int y) {
287                         super (layout, y, "Tilt Angle");
288                 }
289         }
290
291         Orient  orient;
292
293         String pos(double p, String pos, String neg) {
294                 String  h = pos;
295                 if (p < 0) {
296                         h = neg;
297                         p = -p;
298                 }
299                 int deg = (int) Math.floor(p);
300                 double min = (p - Math.floor(p)) * 60.0;
301                 return String.format("%s %4d° %9.6f", h, deg, min);
302         }
303
304         class Apogee extends AscentStatus {
305                 void show (AltosState state, AltosListenerState listener_state) {
306                         show("%4.2f V", state.apogee_voltage);
307                         lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good);
308                 }
309                 public Apogee (GridBagLayout layout, int y) {
310                         super(layout, y, "Apogee Igniter Voltage");
311                 }
312         }
313
314         Apogee apogee;
315
316         class Main extends AscentStatus {
317                 void show (AltosState state, AltosListenerState listener_state) {
318                         show("%4.2f V", state.main_voltage);
319                         lights.set(state.main_voltage >= AltosLib.ao_igniter_good);
320                 }
321                 public Main (GridBagLayout layout, int y) {
322                         super(layout, y, "Main Igniter Voltage");
323                 }
324         }
325
326         Main main;
327
328         class Lat extends AscentValue {
329                 void show (AltosState state, AltosListenerState listener_state) {
330                         if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
331                                 show(pos(state.gps.lat,"N", "S"));
332                         else
333                                 show("???");
334                 }
335                 public Lat (GridBagLayout layout, int y) {
336                         super (layout, y, "Latitude");
337                 }
338         }
339
340         Lat lat;
341
342         class Lon extends AscentValue {
343                 void show (AltosState state, AltosListenerState listener_state) {
344                         if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
345                                 show(pos(state.gps.lon,"E", "W"));
346                         else
347                                 show("???");
348                 }
349                 public Lon (GridBagLayout layout, int y) {
350                         super (layout, y, "Longitude");
351                 }
352         }
353
354         Lon lon;
355
356         public void reset() {
357                 lat.reset();
358                 lon.reset();
359                 main.reset();
360                 apogee.reset();
361                 height.reset();
362                 speed.reset();
363                 accel.reset();
364                 orient.reset();
365         }
366
367         public void set_font() {
368                 cur.setFont(Altos.label_font);
369                 max.setFont(Altos.label_font);
370                 lat.set_font();
371                 lon.set_font();
372                 main.set_font();
373                 apogee.set_font();
374                 height.set_font();
375                 speed.set_font();
376                 accel.set_font();
377                 orient.set_font();
378         }
379
380         public void show(AltosState state, AltosListenerState listener_state) {
381                 if (state.gps != null && state.gps.connected) {
382                         lat.show(state, listener_state);
383                         lon.show(state, listener_state);
384                 } else {
385                         lat.hide();
386                         lon.hide();
387                 }
388                 height.show(state, listener_state);
389                 if (state.main_voltage != AltosLib.MISSING)
390                         main.show(state, listener_state);
391                 else
392                         main.hide();
393                 if (state.apogee_voltage != AltosLib.MISSING)
394                         apogee.show(state, listener_state);
395                 else
396                         apogee.hide();
397                 speed.show(state, listener_state);
398                 accel.show(state, listener_state);
399                 if (state.orient() != AltosLib.MISSING)
400                         orient.show(state, listener_state);
401                 else
402                         orient.hide();
403         }
404
405         public void labels(GridBagLayout layout, int y) {
406                 GridBagConstraints      c;
407
408                 cur = new JLabel("Current");
409                 cur.setFont(Altos.label_font);
410                 c = new GridBagConstraints();
411                 c.gridx = 2; c.gridy = y;
412                 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
413                 layout.setConstraints(cur, c);
414                 add(cur);
415
416                 max = new JLabel("Maximum");
417                 max.setFont(Altos.label_font);
418                 c.gridx = 3; c.gridy = y;
419                 layout.setConstraints(max, c);
420                 add(max);
421         }
422
423         public String getName() {
424                 return "Ascent";
425         }
426
427         public AltosAscent() {
428                 layout = new GridBagLayout();
429
430                 setLayout(layout);
431
432                 /* Elements in ascent display:
433                  *
434                  * lat
435                  * lon
436                  * height
437                  */
438                 int y = 0;
439                 labels(layout, y++);
440                 height = new Height(layout, y++);
441                 speed = new Speed(layout, y++);
442                 accel = new Accel(layout, y++);
443                 orient = new Orient(layout, y++);
444                 lat = new Lat(layout, y++);
445                 lon = new Lon(layout, y++);
446                 apogee = new Apogee(layout, y++);
447                 main = new Main(layout, y++);
448         }
449 }