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.
18 package org.altusmetrum.telegps;
22 import org.altusmetrum.altoslib_4.*;
23 import org.altusmetrum.altosuilib_2.*;
25 public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
29 public abstract class Info implements AltosFontListener, AltosUnitsListener {
37 value.setVisible(true);
38 lights.setVisible(true);
39 label.setVisible(true);
43 value.setVisible(false);
44 lights.setVisible(false);
45 label.setVisible(false);
48 abstract void show(AltosState state, AltosListenerState listener_state);
57 show(units.show(8, v));
60 void show(String format, double v) {
61 show(String.format(format, v));
64 void show(String format, int v) {
65 show(String.format(format, v));
73 public void font_size_changed(int font_size) {
74 label.setFont(AltosUILib.label_font);
75 value.setFont(AltosUILib.value_font);
78 public void units_changed(boolean imperial_units) {
83 public Info (GridBagLayout layout, int y, AltosUnits units, String text) {
86 GridBagConstraints c = new GridBagConstraints();
89 lights = new AltosLights();
90 c.gridx = 0; c.gridy = y;
91 c.anchor = GridBagConstraints.CENTER;
92 c.fill = GridBagConstraints.VERTICAL;
94 layout.setConstraints(lights, c);
97 label = new JLabel(text);
98 label.setFont(AltosUILib.label_font);
99 label.setHorizontalAlignment(SwingConstants.LEFT);
100 c.gridx = 1; c.gridy = y;
101 c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
102 c.anchor = GridBagConstraints.WEST;
103 c.fill = GridBagConstraints.VERTICAL;
105 layout.setConstraints(label, c);
108 value = new JTextField(AltosUILib.text_width);
109 value.setFont(AltosUILib.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);
120 public Info (GridBagLayout layout, int y, String text) {
121 this(layout, y, null, text);
125 public abstract class Value implements AltosFontListener, AltosUnitsListener {
129 double v = AltosLib.MISSING;
131 abstract void show(AltosState state, AltosListenerState listener_state);
138 label.setVisible(true);
139 value.setVisible(true);
142 void show(String s) {
147 void show(double v) {
149 show(units.show(8, v));
152 void show(String format, double v) {
153 show(String.format(format, v));
157 label.setVisible(false);
158 value.setVisible(false);
160 public void font_size_changed(int font_size) {
161 label.setFont(AltosUILib.label_font);
162 value.setFont(AltosUILib.value_font);
164 public void units_changed(boolean imperial_units) {
169 public Value (GridBagLayout layout, int y, String text) {
170 GridBagConstraints c = new GridBagConstraints();
173 label = new JLabel(text);
174 label.setFont(AltosUILib.label_font);
175 label.setHorizontalAlignment(SwingConstants.LEFT);
176 c.gridx = 1; c.gridy = y;
177 c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
178 c.anchor = GridBagConstraints.WEST;
179 c.fill = GridBagConstraints.VERTICAL;
181 layout.setConstraints(label, c);
184 value = new JTextField(AltosUILib.text_width);
185 value.setFont(AltosUILib.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);
197 public abstract class DualValue implements AltosFontListener, AltosUnitsListener {
212 lights.setVisible(true);
213 label.setVisible(true);
214 value1.setVisible(true);
215 value2.setVisible(true);
220 lights.setVisible(false);
221 label.setVisible(false);
222 value1.setVisible(false);
223 value2.setVisible(false);
226 public void font_size_changed(int font_size) {
227 label.setFont(AltosUILib.label_font);
228 value1.setFont(AltosUILib.value_font);
229 value2.setFont(AltosUILib.value_font);
232 public void units_changed(boolean imperial_units) {
235 abstract void show(AltosState state, AltosListenerState listener_state);
237 void show(String v1, String v2) {
243 void show(String f1, double v1, String f2, double v2) {
245 value1.setText(String.format(f1, v1));
246 value2.setText(String.format(f2, v2));
249 void show(String f1, int v1, String f2, int v2) {
251 value1.setText(String.format(f1, v1));
252 value2.setText(String.format(f2, v2));
255 public DualValue (GridBagLayout layout, int y, String text, boolean want_lights) {
256 GridBagConstraints c = new GridBagConstraints();
260 lights = new AltosLights();
261 c.gridx = 0; c.gridy = y;
262 c.anchor = GridBagConstraints.CENTER;
263 c.fill = GridBagConstraints.VERTICAL;
265 layout.setConstraints(lights, c);
269 label = new JLabel(text);
270 label.setFont(AltosUILib.label_font);
271 label.setHorizontalAlignment(SwingConstants.LEFT);
272 c.gridx = 1; c.gridy = y;
273 c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
274 c.anchor = GridBagConstraints.WEST;
275 c.fill = GridBagConstraints.VERTICAL;
277 layout.setConstraints(label, c);
280 value1 = new JTextField(AltosUILib.text_width);
281 value1.setFont(AltosUILib.value_font);
282 value1.setHorizontalAlignment(SwingConstants.RIGHT);
283 c.gridx = 2; c.gridy = y;
284 c.anchor = GridBagConstraints.WEST;
285 c.fill = GridBagConstraints.BOTH;
287 layout.setConstraints(value1, c);
290 value2 = new JTextField(AltosUILib.text_width);
291 value2.setFont(AltosUILib.value_font);
292 value2.setHorizontalAlignment(SwingConstants.RIGHT);
293 c.gridx = 3; c.gridy = y;
294 c.anchor = GridBagConstraints.WEST;
295 c.fill = GridBagConstraints.BOTH;
298 layout.setConstraints(value2, c);
303 abstract public class ValueHold implements AltosFontListener, AltosUnitsListener {
306 JTextField max_value;
311 abstract void show(AltosState state, AltosListenerState listener_state);
315 max_value.setText("");
316 max = AltosLib.MISSING;
319 public void font_size_changed(int font_size) {
320 label.setFont(AltosUILib.label_font);
321 value.setFont(AltosUILib.value_font);
322 max_value.setFont(AltosUILib.value_font);
325 public void units_changed(boolean imperial_units) {
329 void show(double v) {
331 if (v == AltosLib.MISSING) {
332 value.setText("Missing");
334 value.setText(units.show(8, v));
335 if (v > max || max == AltosLib.MISSING)
338 if (max == AltosLib.MISSING)
339 max_value.setText("Missing");
341 max_value.setText(units.show(8, max));
345 label.setVisible(false);
346 value.setVisible(false);
347 max_value.setVisible(false);
350 public ValueHold (GridBagLayout layout, int y, AltosUnits units, String text) {
352 GridBagConstraints c = new GridBagConstraints();
355 label = new JLabel(text);
356 label.setFont(AltosUILib.label_font);
357 label.setHorizontalAlignment(SwingConstants.LEFT);
358 c.gridx = 1; c.gridy = y;
359 c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
360 c.anchor = GridBagConstraints.WEST;
361 c.fill = GridBagConstraints.VERTICAL;
363 layout.setConstraints(label, c);
366 value = new JTextField(AltosUILib.text_width);
367 value.setFont(AltosUILib.value_font);
368 value.setHorizontalAlignment(SwingConstants.RIGHT);
369 c.gridx = 2; c.gridy = y;
370 c.anchor = GridBagConstraints.EAST;
371 c.fill = GridBagConstraints.BOTH;
373 layout.setConstraints(value, c);
376 max_value = new JTextField(AltosUILib.text_width);
377 max_value.setFont(AltosUILib.value_font);
378 max_value.setHorizontalAlignment(SwingConstants.RIGHT);
379 c.gridx = 3; c.gridy = y;
380 c.anchor = GridBagConstraints.EAST;
381 c.fill = GridBagConstraints.BOTH;
383 layout.setConstraints(max_value, c);
389 class Altitude extends ValueHold {
390 void show (AltosState state, AltosListenerState listener_state) {
391 show(state.altitude());
393 public Altitude (GridBagLayout layout, int y) {
394 super (layout, y, AltosConvert.height, "Altitude");
400 class AscentRate extends ValueHold {
401 void show (AltosState state, AltosListenerState listener_state) {
402 show(state.gps_ascent_rate());
404 public AscentRate (GridBagLayout layout, int y) {
405 super (layout, y, AltosConvert.speed, "Ascent Rate");
409 AscentRate ascent_rate;
411 class GroundSpeed extends ValueHold {
412 void show (AltosState state, AltosListenerState listener_state) {
413 show(state.gps_ground_speed());
415 public GroundSpeed (GridBagLayout layout, int y) {
416 super (layout, y, AltosConvert.speed, "Ground Speed");
420 GroundSpeed ground_speed;
422 String pos(double p, String pos, String neg) {
428 int deg = (int) Math.floor(p);
429 double min = (p - Math.floor(p)) * 60.0;
430 return String.format("%s %4d° %9.6f", h, deg, min);
433 class Course extends DualValue {
434 void show (AltosState state, AltosListenerState listener_state) {
435 double course = state.gps_course();
436 if (course != AltosLib.MISSING)
437 show( String.format("%3.0f°", course),
438 AltosConvert.bearing_to_words(
439 AltosConvert.BEARING_LONG,
442 public Course (GridBagLayout layout, int y) {
443 super (layout, y, "Course", false);
449 class Lat extends Value {
450 void show (AltosState state, AltosListenerState listener_state) {
451 if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
452 show(pos(state.gps.lat,"N", "S"));
456 public Lat (GridBagLayout layout, int y) {
457 super (layout, y, "Latitude");
463 class Lon extends Value {
464 void show (AltosState state, AltosListenerState listener_state) {
465 if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
466 show(pos(state.gps.lon,"E", "W"));
470 public Lon (GridBagLayout layout, int y) {
471 super (layout, y, "Longitude");
477 class GPSLocked extends DualValue {
478 void show (AltosState state, AltosListenerState listener_state) {
479 if (state == null || state.gps == null)
482 int soln = state.gps.nsat;
483 int nsat = state.gps.cc_gps_sat != null ? state.gps.cc_gps_sat.length : 0;
484 show("%4d in solution", soln,
485 "%4d in view", nsat);
486 lights.set(state.gps.locked && soln >= 4);
489 public GPSLocked (GridBagLayout layout, int y) {
490 super (layout, y, "GPS Locked", true);
494 GPSLocked gps_locked;
496 public void reset() {
500 ground_speed.reset();
506 public void font_size_changed(int font_size) {
507 cur.setFont(AltosUILib.label_font);
508 max.setFont(AltosUILib.label_font);
509 lat.font_size_changed(font_size);
510 lon.font_size_changed(font_size);
511 altitude.font_size_changed(font_size);
512 ground_speed.font_size_changed(font_size);
513 ascent_rate.font_size_changed(font_size);
514 course.font_size_changed(font_size);
515 gps_locked.font_size_changed(font_size);
518 public void units_changed(boolean imperial_units) {
519 lat.units_changed(imperial_units);
520 lon.units_changed(imperial_units);
521 altitude.units_changed(imperial_units);
522 ground_speed.units_changed(imperial_units);
523 ascent_rate.units_changed(imperial_units);
524 course.units_changed(imperial_units);
525 gps_locked.units_changed(imperial_units);
528 public void show(AltosState state, AltosListenerState listener_state) {
529 if (state.gps != null && state.gps.connected) {
530 lat.show(state, listener_state);
531 lon.show(state, listener_state);
536 altitude.show(state, listener_state);
537 ground_speed.show(state, listener_state);
538 ascent_rate.show(state, listener_state);
539 course.show(state, listener_state);
540 gps_locked.show(state, listener_state);
543 public void labels(GridBagLayout layout, int y) {
544 GridBagConstraints c;
546 cur = new JLabel("Current");
547 cur.setFont(AltosUILib.label_font);
548 c = new GridBagConstraints();
549 c.gridx = 2; c.gridy = y;
550 c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
551 layout.setConstraints(cur, c);
554 max = new JLabel("Maximum");
555 max.setFont(AltosUILib.label_font);
556 c.gridx = 3; c.gridy = y;
557 layout.setConstraints(max, c);
561 public String getName() {
565 public TeleGPSInfo() {
566 layout = new GridBagLayout();
570 /* Elements in ascent display:
578 altitude = new Altitude(layout, y++);
579 ground_speed = new GroundSpeed(layout, y++);
580 ascent_rate = new AscentRate(layout, y++);
581 course = new Course(layout, y++);
582 lat = new Lat(layout, y++);
583 lon = new Lon(layout, y++);
584 gps_locked = new GPSLocked(layout, y++);