Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
applicationId = "io.github.iso53.nothingcompass"
minSdk = 27
targetSdk = 36
versionCode = 2
versionName = "1.2.0"
versionCode = 3
versionName = "1.3.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ private void setupRecyclerView() {
v -> showThemeSelectionDialog()));
items.add(new OptionItem(getString(R.string.item_haptic_feedback), null,
R.drawable.ic_vibration, v -> showHapticFeedbackSelectionDialog()));
items.add(new OptionItem(getString(R.string.item_high_precision), null,
R.drawable.precision, v -> showHighPrecisionSelectionDialog()));
items.add(new OptionItem(getString(R.string.item_north_reference), null,
R.drawable.ic_compass, v -> showNorthReferenceSelectionDialog()));

Expand Down Expand Up @@ -152,6 +154,23 @@ private void showHapticFeedbackSelectionDialog() {
}).show();
}

private void showHighPrecisionSelectionDialog() {
String[] options = {getString(R.string.high_precision_on),
getString(R.string.high_precision_off)};

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean currentHighPrecision = prefs.getBoolean(PreferenceConstants.HIGH_PRECISION, false);

int checkedItem = currentHighPrecision ? 0 : 1;

new MaterialAlertDialogBuilder(this).setTitle(R.string.item_high_precision)
.setSingleChoiceItems(options, checkedItem, (dialog, which) -> {
boolean enabled = (which == 0);
prefs.edit().putBoolean(PreferenceConstants.HIGH_PRECISION, enabled).apply();
dialog.dismiss();
}).show();
}

private void openPlayStore() {
String packageName = getPackageName();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
levelMeterView.setHapticFeedbackEnabled(enabled);
});

preferenceStore.getHighPrecision().observe(getViewLifecycleOwner(), enabled -> {
levelMeterView.setHighPrecisionEnabled(enabled);
});

// Initially show inclinometer, hide level meter
inclinometerView.setAlpha(1f);
inclinometerView.setIsActive(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ private PreferenceConstants() {
public static final String APP_LAUNCH_COUNT = "app_launch_count";
public static final String HAS_ASKED_FOR_REVIEW = "has_asked_for_review";
public static final String THEME = "theme";
public static final String HIGH_PRECISION = "high_precision";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ public class PreferenceStore {

private final MutableLiveData<Boolean> trueNorth = new MutableLiveData<>();
private final MutableLiveData<Boolean> hapticFeedback = new MutableLiveData<>();
private final MutableLiveData<Boolean> highPrecision = new MutableLiveData<>();

private final SharedPreferences sharedPreferences;

private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener;
private final Observer<Boolean> trueNorthObserver;
private final Observer<Boolean> hapticFeedbackObserver;
private final Observer<Boolean> highPrecisionObserver;

public PreferenceStore(@NonNull Context context, @NonNull Lifecycle lifecycle) {
this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
Expand All @@ -37,6 +39,9 @@ public PreferenceStore(@NonNull Context context, @NonNull Lifecycle lifecycle) {
case PreferenceConstants.HAPTIC_FEEDBACK:
updateHapticFeedback();
break;
case PreferenceConstants.HIGH_PRECISION:
updateHighPrecision();
break;
}
};

Expand All @@ -50,14 +55,21 @@ public PreferenceStore(@NonNull Context context, @NonNull Lifecycle lifecycle) {
Log.d(TAG, "Persisted hapticFeedback: " + value);
};

this.highPrecisionObserver = value -> {
sharedPreferences.edit().putBoolean(PreferenceConstants.HIGH_PRECISION, value).apply();
Log.d(TAG, "Persisted highPrecision: " + value);
};

updateTrueNorth();
updateHapticFeedback();
updateHighPrecision();

lifecycle.addObserver(new DefaultLifecycleObserver() {
@Override
public void onCreate(@NonNull LifecycleOwner owner) {
trueNorth.observeForever(trueNorthObserver);
hapticFeedback.observeForever(hapticFeedbackObserver);
highPrecision.observeForever(highPrecisionObserver);

sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
}
Expand All @@ -68,6 +80,7 @@ public void onDestroy(@NonNull LifecycleOwner owner) {

trueNorth.removeObserver(trueNorthObserver);
hapticFeedback.removeObserver(hapticFeedbackObserver);
highPrecision.removeObserver(highPrecisionObserver);
}
});
}
Expand All @@ -80,6 +93,10 @@ public MutableLiveData<Boolean> getHapticFeedback() {
return hapticFeedback;
}

public MutableLiveData<Boolean> getHighPrecision() {
return highPrecision;
}

private void updateTrueNorth() {
boolean storedValue = sharedPreferences.getBoolean(PreferenceConstants.TRUE_NORTH, false);
if (!Boolean.valueOf(storedValue).equals(trueNorth.getValue())) {
Expand All @@ -93,4 +110,11 @@ private void updateHapticFeedback() {
hapticFeedback.setValue(storedValue);
}
}

private void updateHighPrecision() {
boolean storedValue = sharedPreferences.getBoolean(PreferenceConstants.HIGH_PRECISION, false);
if (!Boolean.valueOf(storedValue).equals(highPrecision.getValue())) {
highPrecision.setValue(storedValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class LevelMeterView extends FrameLayout {
private int lastVibrationDegree = 0;
private boolean isActive = false;
private boolean isHapticFeedbackEnabled = true;
private boolean isHighPrecisionEnabled = false;

public LevelMeterView(Context c, AttributeSet a) {
super(c, a);
Expand Down Expand Up @@ -220,6 +221,11 @@ public void setHapticFeedbackEnabled(boolean enabled) {
this.isHapticFeedbackEnabled = enabled;
}

public void setHighPrecisionEnabled(boolean enabled) {
this.isHighPrecisionEnabled = enabled;
invalidate();
}

private void performHapticFeedback() {
Vibrator vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator()) {
Expand Down Expand Up @@ -249,13 +255,24 @@ private void updateOrientation() {
}

private void updateDegreeDisplay() {
int displayDegree = calculateDisplayDegree();
float degreeValue = calculateDegreeValue();
String displayDegree;

if (isHighPrecisionEnabled) {
if (Math.abs(degreeValue) < 0.005f) {
degreeValue = 0f;
}
displayDegree = String.format(java.util.Locale.getDefault(), "%.2f", degreeValue);
} else {
displayDegree = String.valueOf(Math.round(degreeValue));
}

degreeTextView.setTextColor(getDegreeTextColor());
degreeTextView.setText(" " + displayDegree + "°");
degreeTextView.setRotation(spin - 90f);
}

private int calculateDisplayDegree() {
private float calculateDegreeValue() {
// Calculate angle relative to nearest 90-degree orientation (0, 90, 180, 270)
float normalizedSpin = normalizeAngle(spin, 360f);
float angleFromNearest90 = normalizedSpin % 90f;
Expand All @@ -268,7 +285,7 @@ private int calculateDisplayDegree() {
degreeValue = angleFromNearest90 - 90f; // 45 to 90 becomes -45 to 0
}

return Math.round(degreeValue);
return degreeValue;
}

// Color helper methods
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/precision.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,600L200,600L200,760Q200,760 200,760Q200,760 200,760L360,760L360,840L200,840ZM600,840L600,760L760,760Q760,760 760,760Q760,760 760,760L760,600L840,600L840,760Q840,793 816.5,816.5Q793,840 760,840L600,840ZM120,360L120,200Q120,167 143.5,143.5Q167,120 200,120L360,120L360,200L200,200Q200,200 200,200Q200,200 200,200L200,360L120,360ZM760,360L760,200Q760,200 760,200Q760,200 760,200L600,200L600,120L760,120Q793,120 816.5,143.5Q840,167 840,200L840,360L760,360ZM338.5,621.5Q280,563 280,480Q280,397 338.5,338.5Q397,280 480,280Q563,280 621.5,338.5Q680,397 680,480Q680,563 621.5,621.5Q563,680 480,680Q397,680 338.5,621.5ZM565,565Q600,530 600,480Q600,430 565,395Q530,360 480,360Q430,360 395,395Q360,430 360,480Q360,530 395,565Q430,600 480,600Q530,600 565,565ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
<string name="item_haptic_feedback">Haptic feedback</string>
<string name="haptic_feedback_on">On</string>
<string name="haptic_feedback_off">Off</string>
<string name="item_high_precision">High precision</string>
<string name="high_precision_on">On</string>
<string name="high_precision_off">Off</string>
<string name="item_north_reference">Compass Reference</string>
<string name="north_reference_true">True North</string>
<string name="north_reference_magnetic">Magnetic North</string>
Expand Down
Loading