haunt / commit
Fix map label overlap, add x/y to points list
.../main/java/net/fuzzyworld/haunt/MainActivity.kt | 7 ++++++ .../net/fuzzyworld/haunt/debug/DebugViewModel.kt | 8 ++++++ .../java/net/fuzzyworld/haunt/debug/MapView.kt | 9 +++---- .../net/fuzzyworld/haunt/debug/PointsAdapter.kt | 9 +++++++ app/src/main/res/layout/item_debug_point.xml | 29 ++++++++++++++++------ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt b/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt index 3b1ca30..f031591 100644 --- a/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt +++ b/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt @@ -68,6 +68,13 @@ class MainActivity : AppCompatActivity() { binding.mapView.savedPoints = points } } + + lifecycleScope.launch { + vm.axisBssids.collectLatest { bssids -> + adapter.axisBssids = bssids + adapter.notifyDataSetChanged() + } + } } private fun showAddPointDialog() { diff --git a/app/src/main/java/net/fuzzyworld/haunt/debug/DebugViewModel.kt b/app/src/main/java/net/fuzzyworld/haunt/debug/DebugViewModel.kt index 3ca000c..2cf3fc5 100644 --- a/app/src/main/java/net/fuzzyworld/haunt/debug/DebugViewModel.kt +++ b/app/src/main/java/net/fuzzyworld/haunt/debug/DebugViewModel.kt @@ -6,7 +6,10 @@ import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import net.fuzzyworld.haunt.ranging.RttRangingManager import java.util.UUID @@ -24,6 +27,11 @@ class DebugViewModel(application: Application) : AndroidViewModel(application) { val isRttAvailable: Boolean get() = rttManager.isAvailable + // Sorted union of all BSSIDs ever seen — defines the x/y axes for the map and list + val axisBssids: StateFlow<List<String>> = combine(_readings, _points) { r, p -> + (r.map { it.bssid } + p.flatMap { it.readings.keys }).distinct().sorted() + }.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) + // Last known distance per BSSID — used to fill gaps when an AP temporarily drops out private val lastKnownReadings: MutableMap<String, Double> = mutableMapOf() diff --git a/app/src/main/java/net/fuzzyworld/haunt/debug/MapView.kt b/app/src/main/java/net/fuzzyworld/haunt/debug/MapView.kt index 28a019c..290c712 100644 --- a/app/src/main/java/net/fuzzyworld/haunt/debug/MapView.kt +++ b/app/src/main/java/net/fuzzyworld/haunt/debug/MapView.kt @@ -139,15 +139,14 @@ class MapView @JvmOverloads constructor( labelPaint.color = Color.BLACK } - // Axis labels + // Axis legend — top-right corner, away from all grid labels val bssids = allBssids + dimLabelPaint.textAlign = Paint.Align.RIGHT if (bssids.isNotEmpty()) { - dimLabelPaint.textAlign = Paint.Align.RIGHT - canvas.drawText("→ ${bssids[0].takeLast(5)}", width - 4f, height - 6f, dimLabelPaint) + canvas.drawText("x → …${bssids[0].takeLast(5)}", width - 6f, 22f, dimLabelPaint) } if (bssids.size > 1) { - dimLabelPaint.textAlign = Paint.Align.LEFT - canvas.drawText("↓ ${bssids[1].takeLast(5)}", 4f, padPx - 10f, dimLabelPaint) + canvas.drawText("y ↓ …${bssids[1].takeLast(5)}", width - 6f, 44f, dimLabelPaint) } } } diff --git a/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt b/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt index daa3cfc..a9cf5dd 100644 --- a/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt +++ b/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt @@ -11,6 +11,7 @@ class PointsAdapter( ) : RecyclerView.Adapter<PointsAdapter.ViewHolder>() { private var points: List<DebugPoint> = emptyList() + var axisBssids: List<String> = emptyList() fun submitList(list: List<DebugPoint>) { points = list @@ -35,6 +36,14 @@ class PointsAdapter( if (!hasFocus) onRename(point.id, b.nameEdit.text.toString().trim().ifEmpty { point.name }) } b.deleteButton.setOnClickListener { onDelete(point.id) } + + val x = axisBssids.getOrNull(0)?.let { point.readings[it] } + val y = axisBssids.getOrNull(1)?.let { point.readings[it] } + b.xyText.text = when { + x != null && y != null -> "x: ${"%.2f".format(x)} m y: ${"%.2f".format(y)} m" + x != null -> "x: ${"%.2f".format(x)} m" + else -> "" + } } } } diff --git a/app/src/main/res/layout/item_debug_point.xml b/app/src/main/res/layout/item_debug_point.xml index 435275a..46c61e4 100644 --- a/app/src/main/res/layout/item_debug_point.xml +++ b/app/src/main/res/layout/item_debug_point.xml @@ -5,7 +5,7 @@ android:orientation="horizontal" android:gravity="center_vertical" android:paddingHorizontal="12dp" - android:paddingVertical="6dp"> + android:paddingVertical="4dp"> <View android:id="@+id/colorSwatch" @@ -13,15 +13,30 @@ android:layout_height="20dp" android:layout_marginEnd="10dp" /> - <EditText - android:id="@+id/nameEdit" + <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:background="@null" - android:singleLine="true" - android:textSize="15sp" - android:imeOptions="actionDone" /> + android:orientation="vertical"> + + <EditText + android:id="@+id/nameEdit" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@null" + android:singleLine="true" + android:textSize="15sp" + android:imeOptions="actionDone" /> + + <TextView + android:id="@+id/xyText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="monospace" + android:textSize="11sp" + android:textColor="#888888" /> + + </LinearLayout> <ImageButton android:id="@+id/deleteButton"