altosdroid: Add imperial unit support
authorKeith Packard <keithp@keithp.com>
Sat, 6 Sep 2014 07:14:26 +0000 (00:14 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 6 Sep 2014 07:37:57 +0000 (00:37 -0700)
Provides a menu entry to switch units, changes all value displays to
use the AltosLib units conversion code.

Signed-off-by: Keith Packard <keithp@keithp.com>
13 files changed:
altosdroid/Notebook
altosdroid/res/menu/option_menu.xml
altosdroid/res/values/strings.xml
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java
altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java
altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java
altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java
altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java
altoslib/AltosPreferences.java

index ebb3578d0f4d4202db3390151338053e4f9bd868..e611683617b1f594a412b9cef0586333c900f3bd 100644 (file)
@@ -29,4 +29,6 @@ Desired AltosDroid feature list
 
  *) Imperial Units mode
 
 
  *) Imperial Units mode
 
+       Done
+
  *) TeleBT battery voltage
  *) TeleBT battery voltage
index 4321d6e74d469872dcde4be0ff15b1cb0413bfa4..3bd5a54e2bb4b6d6dd0abcb81f5fb39d94e7954e 100644 (file)
@@ -26,4 +26,7 @@
     <item android:id="@+id/select_rate"
           android:icon="@android:drawable/ic_menu_preferences"
           android:title="@string/select_rate" />
     <item android:id="@+id/select_rate"
           android:icon="@android:drawable/ic_menu_preferences"
           android:title="@string/select_rate" />
+    <item android:id="@+id/change_units"
+         android:icon="@android:drawable/ic_menu_view"
+         android:title="@string/change_units" />
 </menu>
 </menu>
index 6ea9fec21af615664c9971bfe6fa1a0b823238f7..0cc9934937ad07634cbf97a75c19b5d51020f75d 100644 (file)
@@ -30,6 +30,7 @@
        <string name="quit">Quit</string>
        <string name="select_freq">Select radio frequency</string>
        <string name="select_rate">Select data rate</string>
        <string name="quit">Quit</string>
        <string name="select_freq">Select radio frequency</string>
        <string name="select_rate">Select data rate</string>
+       <string name="change_units">Change units</string>
 
        <!-- DeviceListActivity -->
        <string name="scanning">scanning for devices…</string>
 
        <!-- DeviceListActivity -->
        <string name="scanning">scanning for devices…</string>
index d276798eb929e0665e3ea416d4b3abfda0380a31..f6cceac947dbab97cc6b6d838a7fd22e2f21f960 100644 (file)
@@ -54,7 +54,7 @@ import android.location.Location;
 
 import org.altusmetrum.altoslib_5.*;
 
 
 import org.altusmetrum.altoslib_5.*;
 
-public class AltosDroid extends FragmentActivity {
+public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        // Debugging
        static final String TAG = "AltosDroid";
        static final boolean D = true;
        // Debugging
        static final String TAG = "AltosDroid";
        static final boolean D = true;
@@ -187,6 +187,11 @@ public class AltosDroid extends FragmentActivity {
                mTabs.remove(mTab);
        }
 
                mTabs.remove(mTab);
        }
 
+       public void units_changed(boolean imperial_units) {
+               for (AltosDroidTab mTab : mTabs)
+                       mTab.units_changed(imperial_units);
+       }
+
        void update_title(TelemetryState telemetry_state) {
                switch (telemetry_state.connect) {
                case TelemetryState.CONNECT_CONNECTED:
        void update_title(TelemetryState telemetry_state) {
                switch (telemetry_state.connect) {
                case TelemetryState.CONNECT_CONNECTED:
@@ -226,7 +231,15 @@ public class AltosDroid extends FragmentActivity {
                }
        }
 
                }
        }
 
+       boolean registered_units_listener;
+
        void update_state(TelemetryState telemetry_state) {
        void update_state(TelemetryState telemetry_state) {
+
+               if (!registered_units_listener) {
+                       registered_units_listener = true;
+                       AltosPreferences.register_units_listener(this);
+               }
+
                update_title(telemetry_state);
                update_ui(telemetry_state.state, telemetry_state.location);
                if (telemetry_state.connect == TelemetryState.CONNECT_CONNECTED)
                update_title(telemetry_state);
                update_ui(telemetry_state.state, telemetry_state.location);
                if (telemetry_state.connect == TelemetryState.CONNECT_CONNECTED)
@@ -656,6 +669,10 @@ public class AltosDroid extends FragmentActivity {
                        AlertDialog alert_rate = builder_rate.create();
                        alert_rate.show();
                        return true;
                        AlertDialog alert_rate = builder_rate.create();
                        alert_rate.show();
                        return true;
+               case R.id.change_units:
+                       boolean imperial = AltosPreferences.imperial_units();
+                       AltosPreferences.set_imperial_units(!imperial);
+                       return true;
                }
                return false;
        }
                }
                return false;
        }
index 72b8488bfbb85c395eef0b0b5e1d5528021565f5..9cef131905abad0c1437dc1722aa155a0cbfba38 100644 (file)
@@ -27,6 +27,9 @@ public class AltosDroidPreferences extends AltosPreferences {
        static String active_device_address;
 
        public static void init(Context context) {
        static String active_device_address;
 
        public static void init(Context context) {
+               if (backend != null)
+                       return;
+
                AltosPreferences.init(new AltosDroidPreferencesBackend(context));
 
                active_device_address = backend.getString(activeDevicePreference, null);
                AltosPreferences.init(new AltosDroidPreferencesBackend(context));
 
                active_device_address = backend.getString(activeDevicePreference, null);
index 7b5b01b3ba332510a2976953c9bf0e8eab3c7edc..8e625da6563b8268242d9166a6019cc23e47fac3 100644 (file)
@@ -27,8 +27,9 @@ import android.support.v4.app.FragmentTransaction;
 import android.support.v4.app.FragmentManager;
 import android.location.Location;
 import android.util.Log;
 import android.support.v4.app.FragmentManager;
 import android.location.Location;
 import android.util.Log;
+import android.widget.TextView;
 
 
-public abstract class AltosDroidTab extends Fragment {
+public abstract class AltosDroidTab extends Fragment implements AltosUnitsListener {
        AltosState              last_state;
        AltosGreatCircle        last_from_receiver;
        Location                last_receiver;
        AltosState              last_state;
        AltosGreatCircle        last_from_receiver;
        Location                last_receiver;
@@ -37,6 +38,21 @@ public abstract class AltosDroidTab extends Fragment {
 
        public abstract String tab_name();
 
 
        public abstract String tab_name();
 
+       public void units_changed(boolean imperial_units) {
+               if (!isHidden() && last_state != null)
+                       show(last_state, last_from_receiver, last_receiver);
+       }
+
+       public void set_value(TextView text_view,
+                             AltosUnits units,
+                             int width,
+                             double value) {
+               if (value == AltosLib.MISSING)
+                       text_view.setText("");
+               else
+                       text_view.setText(units.show(width, value));
+       }
+
        public void set_visible(boolean visible) {
                FragmentTransaction     ft = AltosDroid.fm.beginTransaction();
                if (visible) {
        public void set_visible(boolean visible) {
                FragmentTransaction     ft = AltosDroid.fm.beginTransaction();
                if (visible) {
@@ -44,9 +60,6 @@ public abstract class AltosDroidTab extends Fragment {
                        AltosGreatCircle        from_receiver = last_from_receiver;
                        Location                receiver = last_receiver;
 
                        AltosGreatCircle        from_receiver = last_from_receiver;
                        Location                receiver = last_receiver;
 
-                       last_state = null;
-                       last_from_receiver = null;
-                       last_receiver = null;
                        show(state, from_receiver, receiver);
                        ft.show(this);
                } else
                        show(state, from_receiver, receiver);
                        ft.show(this);
                } else
@@ -55,15 +68,15 @@ public abstract class AltosDroidTab extends Fragment {
        }
 
        public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver, boolean is_current) {
        }
 
        public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver, boolean is_current) {
+               last_state = state;
+               last_from_receiver = from_receiver;
+               last_receiver = receiver;
                if (is_current) {
                        if (AltosDroid.D) Log.d(AltosDroid.TAG, String.format("%s: visible, performing update", tab_name()));
 
                        show(state, from_receiver, receiver);
                } else {
                        if (AltosDroid.D) Log.d(AltosDroid.TAG, String.format("%s: not visible, skipping update", tab_name()));
                if (is_current) {
                        if (AltosDroid.D) Log.d(AltosDroid.TAG, String.format("%s: visible, performing update", tab_name()));
 
                        show(state, from_receiver, receiver);
                } else {
                        if (AltosDroid.D) Log.d(AltosDroid.TAG, String.format("%s: not visible, skipping update", tab_name()));
-                       last_state = state;
-                       last_from_receiver = from_receiver;
-                       last_receiver = receiver;
                        return;
                }
        }
                        return;
                }
        }
index b8def36750c7b83df79622186fa100a80c1e6c56..969992d3026c20f4fa1d94793353dd03457d6956 100644 (file)
@@ -68,12 +68,14 @@ public class AltosVoice {
                        if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) &&
                            state.state > AltosLib.ao_flight_boost) {
                                if (state.max_speed() != AltosLib.MISSING)
                        if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) &&
                            state.state > AltosLib.ao_flight_boost) {
                                if (state.max_speed() != AltosLib.MISSING)
-                                       speak(String.format("max speed: %d meters per second.", (int) (state.max_speed() + 0.5)));
+                                       speak(String.format("Max speed: %s.",
+                                                           AltosConvert.speed.say_units(state.max_speed())));
                                spoke = true;
                        } else if ((old_state == null || old_state.state < AltosLib.ao_flight_drogue) &&
                                   state.state >= AltosLib.ao_flight_drogue) {
                                if (state.max_height() != AltosLib.MISSING)
                                spoke = true;
                        } else if ((old_state == null || old_state.state < AltosLib.ao_flight_drogue) &&
                                   state.state >= AltosLib.ao_flight_drogue) {
                                if (state.max_height() != AltosLib.MISSING)
-                                       speak(String.format("max height: %d meters.", (int) (state.max_height() + 0.5)));
+                                       speak(String.format("Max height: %s.",
+                                                           AltosConvert.height.say_units(state.max_height())));
                                spoke = true;
                        }
                }
                                spoke = true;
                        }
                }
@@ -126,17 +128,17 @@ public class AltosVoice {
                                        position = state.from_pad;
 
                                if (position != null) {
                                        position = state.from_pad;
 
                                if (position != null) {
-                                       speak(String.format("Height %d, bearing %s %d, elevation %d, range %d.\n",
-                                                           (int) (state.height() + 0.5),
+                                       speak(String.format("Height %s, bearing %s %d, elevation %d, range %s.\n",
+                                                           AltosConvert.height.say_units(state.height()),
                                                            position.bearing_words(
                                                                    AltosGreatCircle.BEARING_VOICE),
                                                            (int) (position.bearing + 0.5),
                                                            (int) (position.elevation + 0.5),
                                                            position.bearing_words(
                                                                    AltosGreatCircle.BEARING_VOICE),
                                                            (int) (position.bearing + 0.5),
                                                            (int) (position.elevation + 0.5),
-                                                           (int) (position.range + 0.5)));
+                                                           AltosConvert.distance.say_units(position.range)));
                                }
                        } else if (state.state > AltosLib.ao_flight_pad) {
                                if (state.height() != AltosLib.MISSING)
                                }
                        } else if (state.state > AltosLib.ao_flight_pad) {
                                if (state.height() != AltosLib.MISSING)
-                                       speak(String.format("%d meters", (int) (state.height() + 0.5)));
+                                       speak(AltosConvert.height.say_units(state.height()));
                        } else {
                                reported_landing = 0;
                        }
                        } else {
                                reported_landing = 0;
                        }
@@ -155,9 +157,9 @@ public class AltosVoice {
                                else
                                        speak("rocket may have crashed");
                                if (state.from_pad != null)
                                else
                                        speak("rocket may have crashed");
                                if (state.from_pad != null)
-                                       speak(String.format("Bearing %d degrees, range %d meters.",
+                                       speak(String.format("Bearing %d degrees, range %s.",
                                                            (int) (state.from_pad.bearing + 0.5),
                                                            (int) (state.from_pad.bearing + 0.5),
-                                                           (int) (state.from_pad.distance + 0.5)));
+                                                           AltosConvert.distance.say_units(state.from_pad.distance)));
                                ++reported_landing;
                        }
                }
                                ++reported_landing;
                        }
                }
index c146c27746d274dbde683582fff5dc9ee56064fa..fa4e3c8b3da13e7c5c957a422bf7e85ab1da9d62 100644 (file)
@@ -91,12 +91,13 @@ public class TabAscent extends AltosDroidTab {
 
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (state != null) {
 
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (state != null) {
-                       mHeightView.setText(AltosDroid.number("%6.0f m", state.height()));
-                       mMaxHeightView.setText(AltosDroid.number("%6.0f m", state.max_height()));
-                       mSpeedView.setText(AltosDroid.number("%6.0f m/s", state.speed()));
-                       mMaxSpeedView.setText(AltosDroid.number("%6.0f m/s", state.max_speed()));
-                       mAccelView.setText(AltosDroid.number("%6.0f m/s²", state.acceleration()));
-                       mMaxAccelView.setText(AltosDroid.number("%6.0f m/s²", state.max_acceleration()));
+                       set_value(mHeightView, AltosConvert.height, 6, state.height());
+                       set_value(mHeightView, AltosConvert.height, 6, state.height());
+                       set_value(mMaxHeightView, AltosConvert.height, 6, state.max_height());
+                       set_value(mSpeedView, AltosConvert.speed, 6, state.speed());
+                       set_value(mMaxSpeedView, AltosConvert.speed, 6, state.max_speed());
+                       set_value(mAccelView, AltosConvert.accel, 6, state.acceleration());
+                       set_value(mMaxAccelView, AltosConvert.accel, 6, state.max_acceleration());
 
                        if (state.gps != null) {
                                mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
 
                        if (state.gps != null) {
                                mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
index 6d781efd36a3e43dbde3988d02227c33cc302d39..28068666a4df627de6302450d8182936706205fa 100644 (file)
@@ -93,14 +93,14 @@ public class TabDescent extends AltosDroidTab {
 
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (state != null) {
 
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (state != null) {
-                       mSpeedView.setText(AltosDroid.number("%6.0f m/s", state.speed()));
-                       mHeightView.setText(AltosDroid.number("%6.0f m", state.height()));
+                       set_value(mSpeedView, AltosConvert.speed, 6, state.speed());
+                       set_value(mHeightView, AltosConvert.height, 6, state.height());
                        if (from_receiver != null) {
                                mElevationView.setText(AltosDroid.number("%3.0f°", from_receiver.elevation));
                        if (from_receiver != null) {
                                mElevationView.setText(AltosDroid.number("%3.0f°", from_receiver.elevation));
-                               mRangeView.setText(AltosDroid.number("%6.0f m", from_receiver.range));
+                               set_value(mRangeView, AltosConvert.distance, 6, from_receiver.range);
                                mBearingView.setText(AltosDroid.number("%3.0f°", from_receiver.bearing));
                                mCompassView.setText(from_receiver.bearing_words(AltosGreatCircle.BEARING_LONG));
                                mBearingView.setText(AltosDroid.number("%3.0f°", from_receiver.bearing));
                                mCompassView.setText(from_receiver.bearing_words(AltosGreatCircle.BEARING_LONG));
-                               mDistanceView.setText(AltosDroid.number("%6.0f m", from_receiver.distance));
+                               set_value(mDistanceView, AltosConvert.distance, 6, from_receiver.distance);
                        } else { 
                                mElevationView.setText("<unknown>");
                                mRangeView.setText("<unknown>");
                        } else { 
                                mElevationView.setText("<unknown>");
                                mRangeView.setText("<unknown>");
index 32c235e1b627dfbb0a2dbc48f94034cf2b94550c..b257b9365d652c51fc67a3db2676138bb1fe53c6 100644 (file)
@@ -78,7 +78,7 @@ public class TabLanded extends AltosDroidTab {
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (from_receiver != null) {
                        mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (from_receiver != null) {
                        mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
-                       mDistanceView.setText(String.format("%6.0f m", from_receiver.distance));
+                       set_value(mDistanceView, AltosConvert.distance, 6, from_receiver.distance);
                }
                if (state != null && state.gps != null) {
                        mTargetLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
                }
                if (state != null && state.gps != null) {
                        mTargetLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
@@ -91,12 +91,9 @@ public class TabLanded extends AltosDroidTab {
                }
 
                if (state != null) {
                }
 
                if (state != null) {
-                       mMaxHeightView.setText(String.format("%6.0f m", state.max_height()));
-                       if (state.max_acceleration() != AltosLib.MISSING)
-                               mMaxAccelView.setText(String.format("%6.0f m/s²", state.max_acceleration()));
-                       else
-                               mMaxAccelView.setText("missing");
-                       mMaxSpeedView.setText(String.format("%6.0f m/s", state.max_speed()));
+                       set_value(mMaxHeightView, AltosConvert.height, 6, state.max_height());
+                       set_value(mMaxAccelView, AltosConvert.accel, 6, state.max_acceleration());
+                       set_value(mMaxSpeedView, AltosConvert.speed, 6, state.max_speed());
                }
        }
 }
                }
        }
 }
index 811e5482bcb442595d36777c9f820355a430ed31..ab338ac26284cc45370a291d1edd99999435dee0 100644 (file)
@@ -158,7 +158,7 @@ public class TabMap extends AltosDroidTab {
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (from_receiver != null) {
                        mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
        public void show(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (from_receiver != null) {
                        mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
-                       mDistanceView.setText(String.format("%6.0f m", from_receiver.distance));
+                       set_value(mDistanceView, AltosConvert.distance, 6, from_receiver.distance);
                }
 
                if (state != null) {
                }
 
                if (state != null) {
index 1068fa46f63ed11fa3fd803429054a81470f3d2e..32df71d760a2543d55945f967ce2edfcd4a99a5f 100644 (file)
@@ -159,12 +159,12 @@ public class TabPad extends AltosDroidTab {
                }
 
                if (receiver != null) {
                }
 
                if (receiver != null) {
-                       double altitude = 0;
+                       double altitude = AltosLib.MISSING;
                        if (receiver.hasAltitude())
                                altitude = receiver.getAltitude();
                        mPadLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S"));
                        mPadLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E"));
                        if (receiver.hasAltitude())
                                altitude = receiver.getAltitude();
                        mPadLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S"));
                        mPadLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E"));
-                       mPadAltitudeView.setText(AltosDroid.number("%4.0f m", altitude));
+                       set_value(mPadAltitudeView, AltosConvert.height, 6, altitude);
                }
        }
 
                }
        }
 
index af87b213ee575a9c0f7990cb1505cb5b9ecb521e..dba57dcb73d055f0509257e809346c721dacde92 100644 (file)
@@ -157,6 +157,10 @@ public class AltosPreferences {
        public static int launcher_channel;
 
        public static void init(AltosPreferencesBackend in_backend) {
        public static int launcher_channel;
 
        public static void init(AltosPreferencesBackend in_backend) {
+
+               if (backend != null)
+                       return;
+
                backend = in_backend;
 
                /* Initialize logdir from preferences */
                backend = in_backend;
 
                /* Initialize logdir from preferences */