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 if (v == AltosLib.MISSING)
139 show(units.show(8, v));
142 void show(String format, double v) {
143 if (v == AltosLib.MISSING)
146 show(String.format(format, v));
149 public void font_size_changed(int font_size) {
150 label.setFont(Altos.label_font);
151 value.setFont(Altos.value_font);
154 public void units_changed(boolean imperial_units) {
159 public DescentValue (GridBagLayout layout, int x, int y, AltosUnits units, String text) {
161 GridBagConstraints c = new GridBagConstraints();
164 label = new JLabel(text);
165 label.setFont(Altos.label_font);
166 label.setHorizontalAlignment(SwingConstants.LEFT);
167 c.gridx = x + 1; c.gridy = y;
168 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
169 c.anchor = GridBagConstraints.WEST;
170 c.fill = GridBagConstraints.VERTICAL;
174 value = new JTextField(Altos.text_width);
175 value.setFont(Altos.value_font);
176 value.setHorizontalAlignment(SwingConstants.RIGHT);
177 c.gridx = x + 2; c.gridy = y;
179 c.anchor = GridBagConstraints.WEST;
180 c.fill = GridBagConstraints.BOTH;
185 public DescentValue (GridBagLayout layout, int x, int y, String text) {
186 this(layout, x, y, null, text);
190 public abstract class DescentDualValue implements AltosFontListener, AltosUnitsListener {
201 label.setVisible(true);
202 value1.setVisible(true);
203 value2.setVisible(true);
207 label.setVisible(false);
208 value1.setVisible(false);
209 value2.setVisible(false);
212 public void font_size_changed(int font_size) {
213 label.setFont(Altos.label_font);
214 value1.setFont(Altos.value_font);
215 value2.setFont(Altos.value_font);
218 public void units_changed(boolean imperial_units) {
221 abstract void show(AltosState state, AltosListenerState listener_state);
223 void show(String v1, String v2) {
228 void show(String f1, double v1, String f2, double v2) {
230 value1.setText(String.format(f1, v1));
231 value2.setText(String.format(f2, v2));
234 public DescentDualValue (GridBagLayout layout, int x, int y, String text) {
235 GridBagConstraints c = new GridBagConstraints();
238 label = new JLabel(text);
239 label.setFont(Altos.label_font);
240 label.setHorizontalAlignment(SwingConstants.LEFT);
241 c.gridx = x + 1; c.gridy = y;
242 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
243 c.anchor = GridBagConstraints.WEST;
244 c.fill = GridBagConstraints.VERTICAL;
246 layout.setConstraints(label, c);
249 value1 = new JTextField(Altos.text_width);
250 value1.setFont(Altos.value_font);
251 value1.setHorizontalAlignment(SwingConstants.RIGHT);
252 c.gridx = x + 2; c.gridy = y;
253 c.anchor = GridBagConstraints.WEST;
254 c.fill = GridBagConstraints.BOTH;
256 layout.setConstraints(value1, c);
259 value2 = new JTextField(Altos.text_width);
260 value2.setFont(Altos.value_font);
261 value2.setHorizontalAlignment(SwingConstants.RIGHT);
262 c.gridx = x + 4; c.gridy = y;
263 c.anchor = GridBagConstraints.WEST;
264 c.fill = GridBagConstraints.BOTH;
267 layout.setConstraints(value2, c);
272 class Height extends DescentValue {
273 void show (AltosState state, AltosListenerState listener_state) {
274 show(state.height());
276 public Height (GridBagLayout layout, int x, int y) {
277 super (layout, x, y, AltosConvert.height, "Height");
283 class Speed extends DescentValue {
284 void show (AltosState state, AltosListenerState listener_state) {
287 public Speed (GridBagLayout layout, int x, int y) {
288 super (layout, x, y, AltosConvert.speed, "Speed");
294 String pos(double p, String pos, String neg) {
300 int deg = (int) Math.floor(p);
301 double min = (p - Math.floor(p)) * 60.0;
302 return String.format("%s %d° %9.6f", h, deg, min);
305 class Lat extends DescentValue {
306 void show (AltosState state, AltosListenerState listener_state) {
307 if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
308 show(pos(state.gps.lat,"N", "S"));
312 public Lat (GridBagLayout layout, int x, int y) {
313 super (layout, x, y, "Latitude");
319 class Lon extends DescentValue {
320 void show (AltosState state, AltosListenerState listener_state) {
321 if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
322 show(pos(state.gps.lon,"W", "E"));
326 public Lon (GridBagLayout layout, int x, int y) {
327 super (layout, x, y, "Longitude");
333 class Distance extends DescentValue {
334 void show(AltosState state, AltosListenerState listener_state) {
335 if (state.from_pad != null)
336 show(state.from_pad.distance);
341 public Distance (GridBagLayout layout, int x, int y) {
342 super(layout, x, y, AltosConvert.distance, "Ground Distance");
349 class Apogee extends DescentStatus {
350 void show (AltosState state, AltosListenerState listener_state) {
351 show("%4.2f V", state.apogee_voltage);
352 lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good);
354 public Apogee (GridBagLayout layout, int y) {
355 super(layout, y, "Apogee Igniter Voltage");
361 class Main extends DescentStatus {
362 void show (AltosState state, AltosListenerState listener_state) {
363 show("%4.2f V", state.main_voltage);
364 lights.set(state.main_voltage >= AltosLib.ao_igniter_good);
366 public Main (GridBagLayout layout, int y) {
367 super(layout, y, "Main Igniter Voltage");
373 class Bearing extends DescentDualValue {
374 void show (AltosState state, AltosListenerState listener_state) {
375 if (state.from_pad != null) {
376 show( String.format("%3.0f°", state.from_pad.bearing),
377 state.from_pad.bearing_words(
378 AltosGreatCircle.BEARING_LONG));
383 public Bearing (GridBagLayout layout, int x, int y) {
384 super (layout, x, y, "Bearing");
390 class Range extends DescentValue {
391 void show (AltosState state, AltosListenerState listener_state) {
394 public Range (GridBagLayout layout, int x, int y) {
395 super (layout, x, y, AltosConvert.distance, "Range");
401 class Elevation extends DescentValue {
402 void show (AltosState state, AltosListenerState listener_state) {
403 show("%3.0f°", state.elevation);
405 public Elevation (GridBagLayout layout, int x, int y) {
406 super (layout, x, y, "Elevation");
412 public void reset() {
425 public void font_size_changed(int font_size) {
426 lat.font_size_changed(font_size);
427 lon.font_size_changed(font_size);
428 height.font_size_changed(font_size);
429 speed.font_size_changed(font_size);
430 bearing.font_size_changed(font_size);
431 range.font_size_changed(font_size);
432 distance.font_size_changed(font_size);
433 elevation.font_size_changed(font_size);
434 main.font_size_changed(font_size);
435 apogee.font_size_changed(font_size);
438 public void units_changed(boolean imperial_units) {
439 lat.units_changed(imperial_units);
440 lon.units_changed(imperial_units);
441 height.units_changed(imperial_units);
442 speed.units_changed(imperial_units);
443 bearing.units_changed(imperial_units);
444 range.units_changed(imperial_units);
445 distance.units_changed(imperial_units);
446 elevation.units_changed(imperial_units);
447 main.units_changed(imperial_units);
448 apogee.units_changed(imperial_units);
451 public void show(AltosState state, AltosListenerState listener_state) {
452 height.show(state, listener_state);
453 speed.show(state, listener_state);
454 if (state.gps != null && state.gps.connected) {
455 bearing.show(state, listener_state);
456 range.show(state, listener_state);
457 distance.show(state, listener_state);
458 elevation.show(state, listener_state);
459 lat.show(state, listener_state);
460 lon.show(state, listener_state);
469 if (state.main_voltage != AltosLib.MISSING)
470 main.show(state, listener_state);
473 if (state.apogee_voltage != AltosLib.MISSING)
474 apogee.show(state, listener_state);
479 public String getName() {
483 public AltosDescent() {
484 layout = new GridBagLayout();
488 /* Elements in descent display */
489 speed = new Speed(layout, 0, 0);
490 height = new Height(layout, 2, 0);
491 elevation = new Elevation(layout, 0, 1);
492 range = new Range(layout, 2, 1);
493 bearing = new Bearing(layout, 0, 2);
494 distance = new Distance(layout, 0, 3);
495 lat = new Lat(layout, 0, 4);
496 lon = new Lon(layout, 2, 4);
498 apogee = new Apogee(layout, 5);
499 main = new Main(layout, 6);