altosui/telegps: Reduce CPU time needed for flight displays
[fw/altos] / altosui / AltosLanded.java
index d34efe6dbcfb8f2a7540754809bcfb4df77e790c..760b2d64e1456a6ebb4ddccf68414b4621eac4c8 100644 (file)
@@ -20,38 +20,77 @@ package altosui;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import javax.swing.filechooser.FileNameExtensionFilter;
-import javax.swing.table.*;
 import java.io.*;
-import java.util.*;
-import java.text.*;
-import java.util.prefs.*;
-import java.util.concurrent.LinkedBlockingQueue;
+import org.altusmetrum.altoslib_4.*;
+import org.altusmetrum.altosuilib_2.*;
 
-public class AltosLanded extends JComponent implements AltosFlightDisplay {
+public class AltosLanded extends JComponent implements AltosFlightDisplay, ActionListener, HierarchyListener {
        GridBagLayout   layout;
-       Font            label_font;
-       Font            value_font;
 
-       public class LandedValue {
+       private AltosState              last_state;
+       private AltosListenerState      last_listener_state;
+
+       public abstract class LandedValue implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
-               void show(AltosState state, int crc_errors) {}
+               AltosUnits      units;
+               double          v;
+               String          last_value = "";
+
+               abstract void show(AltosState state, AltosListenerState listener_state);
 
                void reset() {
                        value.setText("");
                }
 
+               void show() {
+                       label.setVisible(true);
+                       value.setVisible(true);
+               }
+
+               void show(String s) {
+                       show();
+                       if (!last_value.equals(s)) {
+                               value.setText(s);
+                               last_value = s;
+                       }
+               }
+
+               void show(double v) {
+                       this.v = v;
+                       if (v == AltosLib.MISSING)
+                               show("Missing");
+                       else
+                               show(units.show(8, v));
+               }
+
                void show(String format, double v) {
-                       value.setText(String.format(format, v));
+                       show(String.format(format, v));
                }
 
-               public LandedValue (GridBagLayout layout, int y, String text) {
+               public void font_size_changed(int font_size) {
+                       label.setFont(Altos.label_font);
+                       value.setFont(Altos.value_font);
+               }
+
+               public void units_changed(boolean imperial_units) {
+                       if (units != null)
+                               show(v);
+               }
+
+               void hide() {
+                       label.setVisible(false);
+                       value.setVisible(false);
+               }
+
+               public LandedValue (GridBagLayout layout, int y, AltosUnits units, String text) {
+                       this.units = units;
+
                        GridBagConstraints      c = new GridBagConstraints();
                        c.weighty = 1;
 
                        label = new JLabel(text);
-                       label.setFont(label_font);
+                       label.setFont(Altos.label_font);
                        label.setHorizontalAlignment(SwingConstants.LEFT);
                        c.gridx = 0; c.gridy = y;
                        c.insets = new Insets(10, 10, 10, 10);
@@ -62,7 +101,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
-                       value.setFont(value_font);
+                       value.setEditable(false);
+                       value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 1; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
@@ -71,6 +111,10 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
                        layout.setConstraints(value, c);
                        add(value);
                }
+
+               public LandedValue (GridBagLayout layout, int y, String text) {
+                       this(layout, y, null, text);
+               }
        }
 
        String pos(double p, String pos, String neg) {
@@ -85,11 +129,12 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
        }
 
        class Lat extends LandedValue {
-               void show (AltosState state, int crc_errors) {
-                       if (state.gps != null)
-                               value.setText(pos(state.gps.lat,"N", "S"));
+               void show (AltosState state, AltosListenerState listener_state) {
+                       show();
+                       if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
+                               show(pos(state.gps.lat,"N", "S"));
                        else
-                               value.setText("???");
+                               show("???");
                }
                public Lat (GridBagLayout layout, int y) {
                        super (layout, y, "Latitude");
@@ -99,11 +144,12 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
        Lat lat;
 
        class Lon extends LandedValue {
-               void show (AltosState state, int crc_errors) {
-                       if (state.gps != null)
-                               value.setText(pos(state.gps.lon,"E", "W"));
+               void show (AltosState state, AltosListenerState listener_state) {
+                       show();
+                       if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
+                               show(pos(state.gps.lon,"E", "W"));
                        else
-                               value.setText("???");
+                               show("???");
                }
                public Lon (GridBagLayout layout, int y) {
                        super (layout, y, "Longitude");
@@ -113,11 +159,12 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
        Lon lon;
 
        class Bearing extends LandedValue {
-               void show (AltosState state, int crc_errors) {
+               void show (AltosState state, AltosListenerState listener_state) {
+                       show();
                        if (state.from_pad != null)
                                show("%3.0f°", state.from_pad.bearing);
                        else
-                               value.setText("???");
+                               show("???");
                }
                public Bearing (GridBagLayout layout, int y) {
                        super (layout, y, "Bearing");
@@ -127,47 +174,48 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
        Bearing bearing;
 
        class Distance extends LandedValue {
-               void show (AltosState state, int crc_errors) {
+               void show (AltosState state, AltosListenerState listener_state) {
+                       show();
                        if (state.from_pad != null)
-                               show("%6.0f m", state.from_pad.distance);
+                               show(state.from_pad.distance);
                        else
-                               value.setText("???");
+                               show("???");
                }
                public Distance (GridBagLayout layout, int y) {
-                       super (layout, y, "Distance");
+                       super (layout, y, AltosConvert.distance, "Distance");
                }
        }
 
        Distance distance;
 
        class Height extends LandedValue {
-               void show (AltosState state, int crc_errors) {
-                       show("%6.0f m", state.max_height);
+               void show (AltosState state, AltosListenerState listener_state) {
+                       show(state.max_height());
                }
                public Height (GridBagLayout layout, int y) {
-                       super (layout, y, "Maximum Height");
+                       super (layout, y, AltosConvert.height, "Maximum Height");
                }
        }
 
        Height  height;
 
        class Speed extends LandedValue {
-               void show (AltosState state, int crc_errors) {
-                       show("%6.0f m/s", state.max_speed);
+               void show (AltosState state, AltosListenerState listener_state) {
+                       show(state.max_speed());
                }
                public Speed (GridBagLayout layout, int y) {
-                       super (layout, y, "Maximum Speed");
+                       super (layout, y, AltosConvert.speed, "Maximum Speed");
                }
        }
 
        Speed   speed;
 
        class Accel extends LandedValue {
-               void show (AltosState state, int crc_errors) {
-                       show("%6.0f m/s²", state.max_acceleration);
+               void show (AltosState state, AltosListenerState listener_state) {
+                       show(state.max_acceleration());
                }
                public Accel (GridBagLayout layout, int y) {
-                       super (layout, y, "Maximum Acceleration");
+                       super (layout, y, AltosConvert.accel, "Maximum Acceleration");
                }
        }
 
@@ -183,21 +231,107 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
                accel.reset();
        }
 
-       public void show(AltosState state, int crc_errors) {
-               bearing.show(state, crc_errors);
-               distance.show(state, crc_errors);
-               lat.show(state, crc_errors);
-               lon.show(state, crc_errors);
-               height.show(state, crc_errors);
-               speed.show(state, crc_errors);
-               accel.show(state, crc_errors);
+       public void font_size_changed(int font_size) {
+               lat.font_size_changed(font_size);
+               lon.font_size_changed(font_size);
+               bearing.font_size_changed(font_size);
+               distance.font_size_changed(font_size);
+               height.font_size_changed(font_size);
+               speed.font_size_changed(font_size);
+               accel.font_size_changed(font_size);
+       }
+
+       public void units_changed(boolean imperial_units) {
+               lat.units_changed(imperial_units);
+               lon.units_changed(imperial_units);
+               bearing.units_changed(imperial_units);
+               distance.units_changed(imperial_units);
+               height.units_changed(imperial_units);
+               speed.units_changed(imperial_units);
+               accel.units_changed(imperial_units);
+       }
+
+       public void show(AltosState state, AltosListenerState listener_state) {
+               if (!isShowing()) {
+                       last_state = state;
+                       last_listener_state = listener_state;
+                       return;
+               }
+
+               if (state.gps != null && state.gps.connected) {
+                       bearing.show(state, listener_state);
+                       distance.show(state, listener_state);
+                       lat.show(state, listener_state);
+                       lon.show(state, listener_state);
+               } else {
+                       bearing.hide();
+                       distance.hide();
+                       lat.hide();
+                       lon.hide();
+               }
+               height.show(state, listener_state);
+               speed.show(state, listener_state);
+               accel.show(state, listener_state);
+               if (reader.backing_file() != null)
+                       graph.setEnabled(true);
+       }
+
+       JButton graph;
+       AltosFlightReader reader;
+
+       public void actionPerformed(ActionEvent e) {
+               String  cmd = e.getActionCommand();
+
+               if (cmd.equals("graph")) {
+                       File    file = reader.backing_file();
+                       if (file != null) {
+                               String  filename = file.getName();
+                               try {
+                                       AltosStateIterable states = null;
+                                       if (filename.endsWith("eeprom")) {
+                                               FileInputStream in = new FileInputStream(file);
+                                               states = new AltosEepromFile(in);
+                                       } else if (filename.endsWith("telem")) {
+                                               FileInputStream in = new FileInputStream(file);
+                                               states = new AltosTelemetryFile(in);
+                                       } else {
+                                               throw new FileNotFoundException(filename);
+                                       }
+                                       try {
+                                               new AltosGraphUI(states, file);
+                                       } catch (InterruptedException ie) {
+                                       } catch (IOException ie) {
+                                       }
+                               } catch (FileNotFoundException fe) {
+                                       JOptionPane.showMessageDialog(null,
+                                                                     fe.getMessage(),
+                                                                     "Cannot open file",
+                                                                     JOptionPane.ERROR_MESSAGE);
+                               }
+                       }
+               }
        }
 
-       public AltosLanded() {
+       public String getName() {
+               return "Landed";
+       }
+
+       public void hierarchyChanged(HierarchyEvent e) {
+               if (last_state != null && isShowing()) {
+                       AltosState              state = last_state;
+                       AltosListenerState      listener_state = last_listener_state;
+
+                       last_state = null;
+                       last_listener_state = null;
+                       show(state, listener_state);
+               }
+       }
+
+       public AltosLanded(AltosFlightReader in_reader) {
                layout = new GridBagLayout();
 
-               label_font = new Font("Dialog", Font.PLAIN, 22);
-               value_font = new Font("Monospaced", Font.PLAIN, 22);
+               reader = in_reader;
+
                setLayout(layout);
 
                /* Elements in descent display */
@@ -208,5 +342,21 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
                height = new Height(layout, 4);
                speed = new Speed(layout, 5);
                accel = new Accel(layout, 6);
+
+               graph = new JButton ("Graph Flight");
+               graph.setActionCommand("graph");
+               graph.addActionListener(this);
+               graph.setEnabled(false);
+
+               GridBagConstraints      c = new GridBagConstraints();
+
+               c.gridx = 0; c.gridy = 7;
+               c.insets = new Insets(10, 10, 10, 10);
+               c.anchor = GridBagConstraints.WEST;
+               c.weightx = 0;
+               c.weighty = 0;
+               c.fill = GridBagConstraints.VERTICAL;
+               add(graph, c);
+               addHierarchyListener(this);
        }
 }