@@ -4,8 +4,14 @@ import android.content.Context
44import android.graphics.Canvas
55import android.graphics.Color
66import android.graphics.Paint
7+ import android.graphics.RectF
8+ import android.graphics.Typeface
79import android.util.AttributeSet
810import android.view.View
11+ import java.time.Instant
12+ import java.time.ZoneOffset
13+ import java.time.format.DateTimeFormatter
14+ import java.util.Locale
915import kotlin.math.hypot
1016import kotlin.math.max
1117import kotlin.math.min
@@ -45,12 +51,49 @@ class EclipseRenderView @JvmOverloads constructor(
4551 style = Paint .Style .STROKE
4652 color = Color .rgb(230 , 243 , 255 )
4753 }
54+ private val debugPanelPaint = Paint (Paint .ANTI_ALIAS_FLAG ).apply {
55+ style = Paint .Style .FILL
56+ color = Color .parseColor(" #8A000000" )
57+ }
58+ private val debugPanelStrokePaint = Paint (Paint .ANTI_ALIAS_FLAG ).apply {
59+ style = Paint .Style .STROKE
60+ color = Color .parseColor(" #66FFFFFF" )
61+ }
62+ private val debugTextPaint = Paint (Paint .ANTI_ALIAS_FLAG ).apply {
63+ style = Paint .Style .FILL
64+ color = Color .WHITE
65+ textAlign = Paint .Align .CENTER
66+ typeface = Typeface .MONOSPACE
67+ }
4868
4969 private var showMoon = false
5070 private var sunRadiusNorm = DEFAULT_SUN_RADIUS_NORM
5171 private var moonRadiusNorm = 0f
5272 private var moonCenterXNorm = DEFAULT_CENTER_NORM
5373 private var moonCenterYNorm = DEFAULT_CENTER_NORM
74+ private var debugOverlayEnabled = false
75+ private var debugLatitudeDeg: Double? = null
76+ private var debugLongitudeDeg: Double? = null
77+ private var debugEpochMillis: Long = System .currentTimeMillis()
78+
79+ fun setDebugOverlayEnabled (enabled : Boolean ) {
80+ if (debugOverlayEnabled == enabled) {
81+ return
82+ }
83+ debugOverlayEnabled = enabled
84+ invalidate()
85+ }
86+
87+ fun updateDebugOverlay (
88+ latitudeDeg : Double? ,
89+ longitudeDeg : Double? ,
90+ epochMillis : Long ,
91+ ) {
92+ debugLatitudeDeg = latitudeDeg
93+ debugLongitudeDeg = longitudeDeg
94+ debugEpochMillis = epochMillis
95+ invalidate()
96+ }
5497
5598 fun renderSunOnly (sunRadiusNorm : Float = DEFAULT_SUN_RADIUS_NORM ) {
5699 showMoon = false
@@ -126,6 +169,7 @@ class EclipseRenderView @JvmOverloads constructor(
126169 canvas.drawCircle(centerX, centerY, max(1f , sunRadius - 1.5f ), sunRingPaint)
127170
128171 if (! showMoon) {
172+ drawDebugOverlay(canvas, centerX, centerY, minDimension)
129173 return
130174 }
131175
@@ -154,6 +198,8 @@ class EclipseRenderView @JvmOverloads constructor(
154198 (moonRadius + minDimension * TOTALITY_RING_OFFSET_NORM ) * totalityRingScale
155199 canvas.drawCircle(moonCenterX, moonCenterY, totalityRingRadius, totalityRingPaint)
156200 }
201+
202+ drawDebugOverlay(canvas, centerX, centerY, minDimension)
157203 }
158204
159205 private fun calculateTotalityBlend (
@@ -182,7 +228,61 @@ class EclipseRenderView @JvmOverloads constructor(
182228 return t * t * (3f - 2f * t)
183229 }
184230
231+ private fun drawDebugOverlay (
232+ canvas : Canvas ,
233+ centerX : Float ,
234+ centerY : Float ,
235+ minDimension : Float ,
236+ ) {
237+ if (! debugOverlayEnabled) {
238+ return
239+ }
240+
241+ val coordinateText = if (debugLatitudeDeg != null && debugLongitudeDeg != null ) {
242+ String .format(
243+ Locale .US ,
244+ " LAT %.4f LON %.4f" ,
245+ debugLatitudeDeg,
246+ debugLongitudeDeg,
247+ )
248+ } else {
249+ " LAT --.-- LON --.--"
250+ }
251+ val utcText = " UTC ${DEBUG_TIME_FORMATTER .format(Instant .ofEpochMilli(debugEpochMillis))} "
252+
253+ val textSize = max(9f , minDimension * DEBUG_TEXT_SIZE_RATIO )
254+ debugTextPaint.textSize = textSize
255+ val lineHeight = textSize * DEBUG_LINE_HEIGHT_MULTIPLIER
256+ val panelPaddingX = textSize * 0.7f
257+ val panelPaddingY = textSize * 0.5f
258+ val panelWidth = max(
259+ debugTextPaint.measureText(coordinateText),
260+ debugTextPaint.measureText(utcText),
261+ ) + panelPaddingX * 2f
262+ val panelHeight = lineHeight * 2f + panelPaddingY * 2f
263+ val panelRect = RectF (
264+ centerX - panelWidth / 2f ,
265+ centerY - panelHeight / 2f ,
266+ centerX + panelWidth / 2f ,
267+ centerY + panelHeight / 2f ,
268+ )
269+ val cornerRadius = max(8f , textSize * 0.7f )
270+ debugPanelStrokePaint.strokeWidth = max(1f , textSize * 0.08f )
271+
272+ canvas.drawRoundRect(panelRect, cornerRadius, cornerRadius, debugPanelPaint)
273+ canvas.drawRoundRect(panelRect, cornerRadius, cornerRadius, debugPanelStrokePaint)
274+
275+ val firstLineBaseline =
276+ panelRect.top + panelPaddingY - debugTextPaint.fontMetrics.ascent
277+ val secondLineBaseline = firstLineBaseline + lineHeight
278+
279+ canvas.drawText(coordinateText, centerX, firstLineBaseline, debugTextPaint)
280+ canvas.drawText(utcText, centerX, secondLineBaseline, debugTextPaint)
281+ }
282+
185283 companion object {
284+ private val DEBUG_TIME_FORMATTER : DateTimeFormatter =
285+ DateTimeFormatter .ofPattern(" yyyy-MM-dd HH:mm:ss" ).withZone(ZoneOffset .UTC )
186286 private const val DEFAULT_SUN_RADIUS_NORM = 0.24f
187287 private const val SUN_GLOW_MULTIPLIER = 1.65f
188288 private const val RENDER_ZOOM_MULTIPLIER = 1.9f
@@ -199,5 +299,7 @@ class EclipseRenderView @JvmOverloads constructor(
199299 private const val TOTALITY_RING_STROKE_NORM = 4f / 300f
200300 private const val TOTALITY_CORONA_STROKE_NORM = 16f / 300f
201301 private const val MIN_VISIBLE_TOTALITY_BLEND = 0.002f
302+ private const val DEBUG_TEXT_SIZE_RATIO = 0.041f
303+ private const val DEBUG_LINE_HEIGHT_MULTIPLIER = 1.2f
202304 }
203305}
0 commit comments