2 * Copyright © 2010 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 org.altusmetrum.altoslib_4.*;
23 import org.altusmetrum.altosuilib_2.*;
25 public class AltosDescent extends JComponent implements AltosFlightDisplay {
28 public abstract class DescentStatus implements AltosFontListener, AltosUnitsListener {
33 abstract void show(AltosState state, AltosListenerState listener_state);
36 label.setVisible(true);
37 value.setVisible(true);
38 lights.setVisible(true);
46 void show(String format, double value) {
47 show(String.format(format, value));
51 label.setVisible(false);
52 value.setVisible(false);
53 lights.setVisible(false);
61 public void font_size_changed(int font_size) {
62 label.setFont(Altos.label_font);
63 value.setFont(Altos.value_font);
66 public void units_changed(boolean imperial_units) {
69 public DescentStatus (GridBagLayout layout, int y, String text) {
70 GridBagConstraints c = new GridBagConstraints();
73 lights = new AltosLights();
74 c.gridx = 0; c.gridy = y;
75 c.anchor = GridBagConstraints.CENTER;
76 c.fill = GridBagConstraints.VERTICAL;
78 layout.setConstraints(lights, c);
81 label = new JLabel(text);
82 label.setFont(Altos.label_font);
83 label.setHorizontalAlignment(SwingConstants.LEFT);
84 c.gridx = 1; c.gridy = y;
85 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
86 c.anchor = GridBagConstraints.WEST;
87 c.fill = GridBagConstraints.VERTICAL;
90 layout.setConstraints(label, c);
93 value = new JTextField(Altos.text_width);
94 value.setFont(Altos.value_font);
95 value.setHorizontalAlignment(SwingConstants.RIGHT);
96 c.gridx = 4; c.gridy = y;
98 c.anchor = GridBagConstraints.WEST;
99 c.fill = GridBagConstraints.BOTH;
101 layout.setConstraints(value, c);
107 public abstract class DescentValue implements AltosFontListener, AltosUnitsListener {
117 abstract void show(AltosState state, AltosListenerState listener_state);
120 label.setVisible(true);
121 value.setVisible(true);
125 label.setVisible(false);
126 value.setVisible(false);
129 void show(String v) {
134 void show(double v) {
136 show(units.show(8, v));
139 void show(String format, double v) {
140 show(String.format(format, v));
143 public void font_size_changed(int font_size) {
144 label.setFont(Altos.label_font);
145 value.setFont(Altos.value_font);
148 public void units_changed(boolean imperial_units) {
153 public DescentValue (GridBagLayout layout, int x, int y, AltosUnits units, String text) {
155 GridBagConstraints c = new GridBagConstraints();
158 label = new JLabel(text);
159 label.setFont(Altos.label_font);
160 label.setHorizontalAlignment(SwingConstants.LEFT);
161 c.gridx = x + 1; c.gridy = y;
162 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
163 c.anchor = GridBagConstraints.WEST;
164 c.fill = GridBagConstraints.VERTICAL;
168 value = new JTextField(Altos.text_width);
169 value.setFont(Altos.value_font);
170 value.setHorizontalAlignment(SwingConstants.RIGHT);
171 c.gridx = x + 2; c.gridy = y;
173 c.anchor = GridBagConstraints.WEST;
174 c.fill = GridBagConstraints.BOTH;
179 public DescentValue (GridBagLayout layout, int x, int y, String text) {
180 this(layout, x, y, null, text);
184 public abstract class DescentDualValue implements AltosFontListener, AltosUnitsListener {
195 label.setVisible(true);
196 value1.setVisible(true);
197 value2.setVisible(true);
201 label.setVisible(false);
202 value1.setVisible(false);
203 value2.setVisible(false);
206 public void font_size_changed(int font_size) {
207 label.setFont(Altos.label_font);
208 value1.setFont(Altos.value_font);
209 value2.setFont(Altos.value_font);
212 public void units_changed(boolean imperial_units) {
215 abstract void show(AltosState state, AltosListenerState listener_state);
217 void show(String v1, String v2) {
222 void show(String f1, double v1, String f2, double v2) {
224 value1.setText(String.format(f1, v1));
225 value2.setText(String.format(f2, v2));
228 public DescentDualValue (GridBagLayout layout, int x, int y, String text) {
229 GridBagConstraints c = new GridBagConstraints();
232 label = new JLabel(text);
233 label.setFont(Altos.label_font);
234 label.setHorizontalAlignment(SwingConstants.LEFT);
235 c.gridx = x + 1; c.gridy = y;
236 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
237 c.anchor = GridBagConstraints.WEST;
238 c.fill = GridBagConstraints.VERTICAL;
240 layout.setConstraints(label, c);
243 value1 = new JTextField(Altos.text_width);
244 value1.setFont(Altos.value_font);
245 value1.setHorizontalAlignment(SwingConstants.RIGHT);
246 c.gridx = x + 2; c.gridy = y;
247 c.anchor = GridBagConstraints.WEST;
248 c.fill = GridBagConstraints.BOTH;
250 layout.setConstraints(value1, c);
253 value2 = new JTextField(Altos.text_width);
254 value2.setFont(Altos.value_font);
255 value2.setHorizontalAlignment(SwingConstants.RIGHT);
256 c.gridx = x + 4; c.gridy = y;
257 c.anchor = GridBagConstraints.WEST;
258 c.fill = GridBagConstraints.BOTH;
261 layout.setConstraints(value2, c);
266 class Height extends DescentValue {
267 void show (AltosState state, AltosListenerState listener_state) {
268 show(state.height());
270 public Height (GridBagLayout layout, int x, int y) {
271 super (layout, x, y, AltosConvert.height, "Height");
277 class Speed extends DescentValue {
278 void show (AltosState state, AltosListenerState listener_state) {
281 public Speed (GridBagLayout layout, int x, int y) {
282 super (layout, x, y, AltosConvert.speed, "Speed");
288 String pos(double p, String pos, String neg) {
294 int deg = (int) Math.floor(p);
295 double min = (p - Math.floor(p)) * 60.0;
296 return String.format("%s %d° %9.6f", h, deg, min);
299 class Lat extends DescentValue {
300 void show (AltosState state, AltosListenerState listener_state) {
301 if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
302 show(pos(state.gps.lat,"N", "S"));
306 public Lat (GridBagLayout layout, int x, int y) {
307 super (layout, x, y, "Latitude");
313 class Lon extends DescentValue {
314 void show (AltosState state, AltosListenerState listener_state) {
315 if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
316 show(pos(state.gps.lon,"W", "E"));
320 public Lon (GridBagLayout layout, int x, int y) {
321 super (layout, x, y, "Longitude");
327 class Distance extends DescentValue {
328 void show(AltosState state, AltosListenerState listener_state) {
329 if (state.from_pad != null)
330 show(state.from_pad.distance);
335 public Distance (GridBagLayout layout, int x, int y) {
336 super(layout, x, y, AltosConvert.distance, "Ground Distance");
343 class Apogee extends DescentStatus {
344 void show (AltosState state, AltosListenerState listener_state) {
345 show("%4.2f V", state.apogee_voltage);
346 lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good);
348 public Apogee (GridBagLayout layout, int y) {
349 super(layout, y, "Apogee Igniter Voltage");
355 class Main extends DescentStatus {
356 void show (AltosState state, AltosListenerState listener_state) {
357 show("%4.2f V", state.main_voltage);
358 lights.set(state.main_voltage >= AltosLib.ao_igniter_good);
360 public Main (GridBagLayout layout, int y) {
361 super(layout, y, "Main Igniter Voltage");
367 class Bearing extends DescentDualValue {
368 void show (AltosState state, AltosListenerState listener_state) {
369 if (state.from_pad != null) {
370 show( String.format("%3.0f°", state.from_pad.bearing),
371 state.from_pad.bearing_words(
372 AltosGreatCircle.BEARING_LONG));
377 public Bearing (GridBagLayout layout, int x, int y) {
378 super (layout, x, y, "Bearing");
384 class Range extends DescentValue {
385 void show (AltosState state, AltosListenerState listener_state) {
388 public Range (GridBagLayout layout, int x, int y) {
389 super (layout, x, y, AltosConvert.distance, "Range");
395 class Elevation extends DescentValue {
396 void show (AltosState state, AltosListenerState listener_state) {
397 show("%3.0f°", state.elevation);
399 public Elevation (GridBagLayout layout, int x, int y) {
400 super (layout, x, y, "Elevation");
406 public void reset() {
419 public void font_size_changed(int font_size) {
420 lat.font_size_changed(font_size);
421 lon.font_size_changed(font_size);
422 height.font_size_changed(font_size);
423 speed.font_size_changed(font_size);
424 bearing.font_size_changed(font_size);
425 range.font_size_changed(font_size);
426 distance.font_size_changed(font_size);
427 elevation.font_size_changed(font_size);
428 main.font_size_changed(font_size);
429 apogee.font_size_changed(font_size);
432 public void units_changed(boolean imperial_units) {
433 lat.units_changed(imperial_units);
434 lon.units_changed(imperial_units);
435 height.units_changed(imperial_units);
436 speed.units_changed(imperial_units);
437 bearing.units_changed(imperial_units);
438 range.units_changed(imperial_units);
439 distance.units_changed(imperial_units);
440 elevation.units_changed(imperial_units);
441 main.units_changed(imperial_units);
442 apogee.units_changed(imperial_units);
445 public void show(AltosState state, AltosListenerState listener_state) {
446 height.show(state, listener_state);
447 speed.show(state, listener_state);
448 if (state.gps != null && state.gps.connected) {
449 bearing.show(state, listener_state);
450 range.show(state, listener_state);
451 distance.show(state, listener_state);
452 elevation.show(state, listener_state);
453 lat.show(state, listener_state);
454 lon.show(state, listener_state);
463 if (state.main_voltage != AltosLib.MISSING)
464 main.show(state, listener_state);
467 if (state.apogee_voltage != AltosLib.MISSING)
468 apogee.show(state, listener_state);
473 public String getName() {
477 public AltosDescent() {
478 layout = new GridBagLayout();
482 /* Elements in descent display */
483 speed = new Speed(layout, 0, 0);
484 height = new Height(layout, 2, 0);
485 elevation = new Elevation(layout, 0, 1);
486 range = new Range(layout, 2, 1);
487 bearing = new Bearing(layout, 0, 2);
488 distance = new Distance(layout, 0, 3);
489 lat = new Lat(layout, 0, 4);
490 lon = new Lon(layout, 2, 4);
492 apogee = new Apogee(layout, 5);
493 main = new Main(layout, 6);