diff --git a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt index 2f11f27..e1fd8e0 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt @@ -522,10 +522,11 @@ class MainActivity : AppCompatActivity(), SensorEventListener { R.string.direction_arrow_description, distanceText ) - // Update compass view + // Update compass view (large arrow gets a north indicator) binding.compassDistanceText.text = distanceText binding.compassAddressText.text = selected.shelter.adresse binding.directionArrow.setDirection(arrowAngle) + binding.directionArrow.setNorthAngle(-deviceHeading) binding.directionArrow.contentDescription = getString( R.string.direction_arrow_description, distanceText ) @@ -840,6 +841,7 @@ class MainActivity : AppCompatActivity(), SensorEventListener { val arrowAngle = bearing - deviceHeading binding.directionArrow.setDirection(arrowAngle) + binding.directionArrow.setNorthAngle(-deviceHeading) binding.miniArrow.setDirection(arrowAngle) } diff --git a/app/src/main/java/no/naiv/tilfluktsrom/ui/DirectionArrowView.kt b/app/src/main/java/no/naiv/tilfluktsrom/ui/DirectionArrowView.kt index edd3154..aa50e8f 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/ui/DirectionArrowView.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/ui/DirectionArrowView.kt @@ -17,6 +17,9 @@ import no.naiv.tilfluktsrom.R * rotationAngle = shelterBearing - deviceHeading * This gives the direction the user needs to walk, adjusted for which * way they're currently facing. + * + * Optionally draws a discrete north indicator on the perimeter so users + * can validate compass calibration against a known direction. */ class DirectionArrowView @JvmOverloads constructor( context: Context, @@ -25,6 +28,7 @@ class DirectionArrowView @JvmOverloads constructor( ) : View(context, attrs, defStyleAttr) { private var rotationAngle = 0f + private var northAngle = Float.NaN private val arrowPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = context.getColor(R.color.shelter_primary) @@ -37,7 +41,18 @@ class DirectionArrowView @JvmOverloads constructor( strokeWidth = 4f } + private val northPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + color = 0x99CFD8DC.toInt() // text_secondary at ~60% opacity + style = Paint.Style.FILL + } + + private val northTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + color = 0x99CFD8DC.toInt() + textAlign = Paint.Align.CENTER + } + private val arrowPath = Path() + private val northPath = Path() /** * Set the rotation angle in degrees. @@ -48,6 +63,16 @@ class DirectionArrowView @JvmOverloads constructor( invalidate() } + /** + * Set the angle to north in the view's coordinate space. + * This is typically -deviceHeading (where north is on screen). + * Set to Float.NaN to hide the north indicator. + */ + fun setNorthAngle(degrees: Float) { + northAngle = degrees + invalidate() + } + override fun onDraw(canvas: Canvas) { super.onDraw(canvas) @@ -55,6 +80,11 @@ class DirectionArrowView @JvmOverloads constructor( val cy = height / 2f val size = minOf(width, height) * 0.4f + // Draw north indicator first (behind the main arrow) + if (!northAngle.isNaN()) { + drawNorthIndicator(canvas, cx, cy, size) + } + canvas.save() canvas.rotate(rotationAngle, cx, cy) @@ -74,4 +104,32 @@ class DirectionArrowView @JvmOverloads constructor( canvas.restore() } + + /** + * Draw a small north indicator: a tiny triangle and "N" label + * placed on the perimeter of the view, pointing inward toward center. + */ + private fun drawNorthIndicator(canvas: Canvas, cx: Float, cy: Float, arrowSize: Float) { + val radius = arrowSize * 1.35f + val tickSize = arrowSize * 0.1f + + // Scale "N" text relative to the view + northTextPaint.textSize = arrowSize * 0.18f + + canvas.save() + canvas.rotate(northAngle, cx, cy) + + // Small triangle at the top of the perimeter circle + northPath.reset() + northPath.moveTo(cx, cy - radius) + northPath.lineTo(cx - tickSize, cy - radius - tickSize * 1.8f) + northPath.lineTo(cx + tickSize, cy - radius - tickSize * 1.8f) + northPath.close() + canvas.drawPath(northPath, northPaint) + + // "N" label just outside the triangle + canvas.drawText("N", cx, cy - radius - tickSize * 2.2f, northTextPaint) + + canvas.restore() + } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index d5c3c30..4c8701e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -31,14 +31,15 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" + android:accessibilityLiveRegion="polite" android:textColor="@color/status_text" android:textSize="12sp" tools:text="@string/status_ready" /> @@ -80,6 +82,7 @@ android:layout_width="match_parent" android:layout_height="0dp" android:background="@color/compass_bg" + android:contentDescription="@string/a11y_compass" android:visibility="gone" app:layout_constraintTop_toBottomOf="@id/statusBar" app:layout_constraintBottom_toTopOf="@id/bottomSheet"> @@ -223,8 +226,8 @@ diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index bab61b6..3dc77cf 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -67,6 +67,8 @@ Retning til tilfluktsrom, %s unna %1$s, %2$s, %3$d plasser Upresist kompass - %s + Tilfluktsromkart + Kompassnavigasjon Sivilforsvarsinformasjon diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml index a4de381..129289d 100644 --- a/app/src/main/res/values-nn/strings.xml +++ b/app/src/main/res/values-nn/strings.xml @@ -67,6 +67,8 @@ Retning til tilfluktsrom, %s unna %1$s, %2$s, %3$d plassar Upresis kompass - %s + Tilfluktsromkart + Kompassnavigasjon Sivilforsvarsinformasjon diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 43b3945..c742ab4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,6 +67,8 @@ Direction to shelter, %s away %1$s, %2$s, %3$d places Low accuracy - %s + Shelter map + Compass navigation Civil defense information diff --git a/pwa/index.html b/pwa/index.html index bfbd7e6..c6088c1 100644 --- a/pwa/index.html +++ b/pwa/index.html @@ -1,5 +1,5 @@ - + @@ -16,47 +16,47 @@
-
- +
+ -
-
-
+
+
+ -
+ -
+ -
-
+
+
+
-
-
-
+