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.
21 import java.awt.event.*;
23 import org.altusmetrum.altoslib_4.*;
24 import org.altusmetrum.altosuilib_2.*;
26 public class AltosAscent extends JComponent implements AltosFlightDisplay, HierarchyListener {
30 private AltosState last_state;
31 private AltosListenerState last_listener_state;
33 public class AscentStatus implements AltosFontListener, AltosUnitsListener {
41 value.setVisible(true);
42 lights.setVisible(true);
43 label.setVisible(true);
47 value.setVisible(false);
48 lights.setVisible(false);
49 label.setVisible(false);
52 void show(AltosState state, AltosListenerState listener_state) {}
61 show(units.show(8, v));
64 void show(String format, double v) {
65 show(String.format(format, v));
73 public void font_size_changed(int font_size) {
74 label.setFont(Altos.label_font);
75 value.setFont(Altos.value_font);
78 public void units_changed(boolean imperial_units) {
83 public AscentStatus (GridBagLayout layout, int y, AltosUnits units, String text) {
85 GridBagConstraints c = new GridBagConstraints();
88 lights = new AltosLights();
89 c.gridx = 0; c.gridy = y;
90 c.anchor = GridBagConstraints.CENTER;
91 c.fill = GridBagConstraints.VERTICAL;
93 layout.setConstraints(lights, c);
96 label = new JLabel(text);
97 label.setFont(Altos.label_font);
98 label.setHorizontalAlignment(SwingConstants.LEFT);
99 c.gridx = 1; c.gridy = y;
100 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
101 c.anchor = GridBagConstraints.WEST;
102 c.fill = GridBagConstraints.VERTICAL;
104 layout.setConstraints(label, c);
107 value = new JTextField(Altos.text_width);
108 value.setEditable(false);
109 value.setFont(Altos.value_font);
110 value.setHorizontalAlignment(SwingConstants.RIGHT);
111 c.gridx = 2; c.gridy = y;
113 c.anchor = GridBagConstraints.WEST;
114 c.fill = GridBagConstraints.BOTH;
116 layout.setConstraints(value, c);
122 public abstract class AscentValue implements AltosFontListener, AltosUnitsListener {
128 abstract void show(AltosState state, AltosListenerState listener_state);
135 label.setVisible(true);
136 value.setVisible(true);
139 void show(String s) {
144 void show(double v) {
146 show(units.show(8, v));
149 void show(String format, double v) {
150 show(String.format(format, v));
154 label.setVisible(false);
155 value.setVisible(false);
158 public void font_size_changed(int font_size) {
159 label.setFont(Altos.label_font);
160 value.setFont(Altos.value_font);
163 public void units_changed(boolean imperial_units) {
168 public AscentValue (GridBagLayout layout, int y, AltosUnits units, String text) {
169 GridBagConstraints c = new GridBagConstraints();
172 label = new JLabel(text);
173 label.setFont(Altos.label_font);
174 label.setHorizontalAlignment(SwingConstants.LEFT);
175 c.gridx = 1; c.gridy = y;
176 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
177 c.anchor = GridBagConstraints.WEST;
178 c.fill = GridBagConstraints.VERTICAL;
180 layout.setConstraints(label, c);
183 value = new JTextField(Altos.text_width);
184 value.setEditable(false);
185 value.setFont(Altos.value_font);
186 value.setHorizontalAlignment(SwingConstants.RIGHT);
187 c.gridx = 2; c.gridy = y;
188 c.anchor = GridBagConstraints.WEST;
189 c.fill = GridBagConstraints.BOTH;
192 layout.setConstraints(value, c);
196 public AscentValue (GridBagLayout layout, int y, String text) {
197 this(layout, y, null, text);
201 public class AscentValueHold implements AltosFontListener, AltosUnitsListener {
204 JTextField max_value;
209 void show(AltosState state, AltosListenerState listener_state) {}
213 max_value.setText("");
214 max = AltosLib.MISSING;
217 public void font_size_changed(int font_size) {
218 label.setFont(Altos.label_font);
219 value.setFont(Altos.value_font);
220 max_value.setFont(Altos.value_font);
223 public void units_changed(boolean imperial_units) {
227 void show(double v, double max) {
230 if (v == AltosLib.MISSING) {
231 value.setText("Missing");
233 value.setText(units.show(8, v));
235 if (max == AltosLib.MISSING)
236 max_value.setText("Missing");
238 max_value.setText(units.show(8, max));
242 label.setVisible(false);
243 value.setVisible(false);
244 max_value.setVisible(false);
247 public AscentValueHold (GridBagLayout layout, int y, AltosUnits units, String text) {
249 GridBagConstraints c = new GridBagConstraints();
252 label = new JLabel(text);
253 label.setFont(Altos.label_font);
254 label.setHorizontalAlignment(SwingConstants.LEFT);
255 c.gridx = 1; c.gridy = y;
256 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
257 c.anchor = GridBagConstraints.WEST;
258 c.fill = GridBagConstraints.VERTICAL;
260 layout.setConstraints(label, c);
263 value = new JTextField(Altos.text_width);
264 value.setEditable(false);
265 value.setFont(Altos.value_font);
266 value.setHorizontalAlignment(SwingConstants.RIGHT);
267 c.gridx = 2; c.gridy = y;
268 c.anchor = GridBagConstraints.EAST;
269 c.fill = GridBagConstraints.BOTH;
271 layout.setConstraints(value, c);
274 max_value = new JTextField(Altos.text_width);
275 max_value.setEditable(false);
276 max_value.setFont(Altos.value_font);
277 max_value.setHorizontalAlignment(SwingConstants.RIGHT);
278 c.gridx = 3; c.gridy = y;
279 c.anchor = GridBagConstraints.EAST;
280 c.fill = GridBagConstraints.BOTH;
282 layout.setConstraints(max_value, c);
287 class Height extends AscentValueHold {
288 void show (AltosState state, AltosListenerState listener_state) {
289 show(state.height(), state.max_height());
291 public Height (GridBagLayout layout, int y) {
292 super (layout, y, AltosConvert.height, "Height");
298 class Speed extends AscentValueHold {
299 void show (AltosState state, AltosListenerState listener_state) {
300 show(state.speed(), state.max_speed());
302 public Speed (GridBagLayout layout, int y) {
303 super (layout, y, AltosConvert.speed, "Speed");
309 class Accel extends AscentValueHold {
310 void show (AltosState state, AltosListenerState listener_state) {
311 show(state.acceleration(), state.max_acceleration());
313 public Accel (GridBagLayout layout, int y) {
314 super (layout, y, AltosConvert.accel, "Acceleration");
320 class Orient extends AscentValueHold {
321 void show (AltosState state, AltosListenerState listener_state) {
322 show(state.orient(), state.max_orient());
324 public Orient (GridBagLayout layout, int y) {
325 super (layout, y, AltosConvert.orient, "Tilt Angle");
331 String pos(double p, String pos, String neg) {
337 int deg = (int) Math.floor(p);
338 double min = (p - Math.floor(p)) * 60.0;
339 return String.format("%s %4d° %9.6f", h, deg, min);
342 class Apogee extends AscentStatus {
343 void show (AltosState state, AltosListenerState listener_state) {
344 show("%4.2f V", state.apogee_voltage);
345 lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good);
347 public Apogee (GridBagLayout layout, int y) {
348 super(layout, y, null, "Apogee Igniter Voltage");
354 class Main extends AscentStatus {
355 void show (AltosState state, AltosListenerState listener_state) {
356 show("%4.2f V", state.main_voltage);
357 lights.set(state.main_voltage >= AltosLib.ao_igniter_good);
359 public Main (GridBagLayout layout, int y) {
360 super(layout, y, null, "Main Igniter Voltage");
366 class Lat extends AscentValue {
367 void show (AltosState state, AltosListenerState listener_state) {
368 if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
369 show(pos(state.gps.lat,"N", "S"));
373 public Lat (GridBagLayout layout, int y) {
374 super (layout, y, "Latitude");
380 class Lon extends AscentValue {
381 void show (AltosState state, AltosListenerState listener_state) {
382 if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
383 show(pos(state.gps.lon,"E", "W"));
387 public Lon (GridBagLayout layout, int y) {
388 super (layout, y, "Longitude");
394 public void reset() {
405 public void font_size_changed(int font_size) {
406 cur.setFont(Altos.label_font);
407 max.setFont(Altos.label_font);
408 lat.font_size_changed(font_size);
409 lon.font_size_changed(font_size);
410 main.font_size_changed(font_size);
411 apogee.font_size_changed(font_size);
412 height.font_size_changed(font_size);
413 speed.font_size_changed(font_size);
414 accel.font_size_changed(font_size);
415 orient.font_size_changed(font_size);
418 public void units_changed(boolean imperial_units) {
419 lat.units_changed(imperial_units);
420 lon.units_changed(imperial_units);
421 main.units_changed(imperial_units);
422 apogee.units_changed(imperial_units);
423 height.units_changed(imperial_units);
424 speed.units_changed(imperial_units);
425 accel.units_changed(imperial_units);
426 orient.units_changed(imperial_units);
429 public void show(AltosState state, AltosListenerState listener_state) {
432 last_listener_state = listener_state;
436 if (state.gps != null && state.gps.connected) {
437 lat.show(state, listener_state);
438 lon.show(state, listener_state);
443 height.show(state, listener_state);
444 if (state.main_voltage != AltosLib.MISSING)
445 main.show(state, listener_state);
448 if (state.apogee_voltage != AltosLib.MISSING)
449 apogee.show(state, listener_state);
452 speed.show(state, listener_state);
453 accel.show(state, listener_state);
454 if (state.orient() != AltosLib.MISSING)
455 orient.show(state, listener_state);
460 public void labels(GridBagLayout layout, int y) {
461 GridBagConstraints c;
463 cur = new JLabel("Current");
464 cur.setFont(Altos.label_font);
465 c = new GridBagConstraints();
466 c.gridx = 2; c.gridy = y;
467 c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
468 layout.setConstraints(cur, c);
471 max = new JLabel("Maximum");
472 max.setFont(Altos.label_font);
473 c.gridx = 3; c.gridy = y;
474 layout.setConstraints(max, c);
478 public String getName() {
482 public void hierarchyChanged(HierarchyEvent e) {
483 if (last_state != null && isShowing()) {
484 AltosState state = last_state;
485 AltosListenerState listener_state = last_listener_state;
488 last_listener_state = null;
489 show(state, listener_state);
493 public AltosAscent() {
494 layout = new GridBagLayout();
498 /* Elements in ascent display:
506 height = new Height(layout, y++);
507 speed = new Speed(layout, y++);
508 accel = new Accel(layout, y++);
509 orient = new Orient(layout, y++);
510 lat = new Lat(layout, y++);
511 lon = new Lon(layout, y++);
512 apogee = new Apogee(layout, y++);
513 main = new Main(layout, y++);
514 addHierarchyListener(this);