You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

250 lines
9.0 KiB

package com.quillstudios.pokegoalshelper
import android.content.Context
import android.graphics.*
import android.util.Log
import android.view.*
import android.widget.TextView
import kotlin.math.min
class DetectionOverlay(private val context: Context) {
companion object {
private const val TAG = "DetectionOverlay"
}
private var windowManager: WindowManager? = null
private var overlayView: View? = null
private var isShowing = false
init {
windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
}
fun showOverlay(regions: Map<String, ScreenRegion>) {
try {
Log.i(TAG, "🎨 showOverlay called with ${regions.size} regions")
// Check overlay permission first
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (!android.provider.Settings.canDrawOverlays(context)) {
Log.e(TAG, "❌ OVERLAY PERMISSION NOT GRANTED! Cannot show overlay.")
return
} else {
Log.i(TAG, "✅ Overlay permission granted")
}
}
if (isShowing) {
Log.i(TAG, "🔄 Hiding existing overlay first")
hideOverlay()
}
Log.i(TAG, "🎨 Creating overlay view...")
val overlayLayout = OverlayView(context, regions)
val layoutParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
)
layoutParams.gravity = Gravity.TOP or Gravity.START
layoutParams.x = 0
layoutParams.y = 0
Log.i(TAG, "🎨 Adding view to WindowManager...")
windowManager?.addView(overlayLayout, layoutParams)
overlayView = overlayLayout
isShowing = true
Log.i(TAG, "✅ Detection overlay shown successfully with ${regions.size} regions")
// No auto-hide - overlay stays until manually hidden or new detections
} catch (e: Exception) {
Log.e(TAG, "❌ Error showing overlay", e)
}
}
fun hideOverlay() {
try {
if (isShowing && overlayView != null) {
windowManager?.removeView(overlayView)
overlayView = null
isShowing = false
Log.d(TAG, "Detection overlay hidden")
}
} catch (e: Exception) {
Log.e(TAG, "Error hiding overlay", e)
}
}
private class OverlayView(context: Context, private val regions: Map<String, ScreenRegion>) : View(context) {
private val rectPaint = Paint().apply {
color = Color.RED
style = Paint.Style.STROKE
strokeWidth = 4f
alpha = 200
}
private val fillPaint = Paint().apply {
color = Color.RED
style = Paint.Style.FILL
alpha = 50
}
private val textPaint = Paint().apply {
color = Color.WHITE
textSize = 32f
isAntiAlias = true
style = Paint.Style.FILL
setShadowLayer(4f, 2f, 2f, Color.BLACK)
}
private val backgroundPaint = Paint().apply {
color = Color.BLACK
style = Paint.Style.FILL
alpha = 150
}
private val colors = listOf(
Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.MAGENTA, Color.CYAN, Color.parseColor("#FFA500"), Color.parseColor("#FF6B35"),
Color.parseColor("#7209B7"), Color.parseColor("#2F9599"),
Color.parseColor("#F18F01"), Color.parseColor("#C73E1D")
)
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val displayMetrics = context.resources.displayMetrics
val screenWidth = displayMetrics.widthPixels
val screenHeight = displayMetrics.heightPixels
Log.i(TAG, "🎨 Drawing overlay on ${screenWidth}x${screenHeight} screen with ${regions.size} regions")
var colorIndex = 0
for ((name, region) in regions) {
try {
// Use different colors for each region
val color = colors[colorIndex % colors.size]
colorIndex++
rectPaint.color = color
fillPaint.color = color
fillPaint.alpha = 30
// Draw filled rectangle
canvas.drawRect(
region.x.toFloat(),
region.y.toFloat(),
(region.x + region.width).toFloat(),
(region.y + region.height).toFloat(),
fillPaint
)
// Draw border
canvas.drawRect(
region.x.toFloat(),
region.y.toFloat(),
(region.x + region.width).toFloat(),
(region.y + region.height).toFloat(),
rectPaint
)
// Draw label above the box
val labelText = formatRegionLabel(name, region)
val textX = region.x.toFloat() + 8f
// Calculate text background size
val textBounds = Rect()
textPaint.getTextBounds(labelText, 0, labelText.length, textBounds)
val textWidth = textBounds.width() + 16f
val textHeight = textBounds.height() + 16f
// Position text above the region box
val textY = region.y.toFloat() - 8f
val backgroundTop = textY - textHeight + 8f
val backgroundBottom = textY + 8f
// Draw text background above the box
canvas.drawRect(
textX - 8f,
backgroundTop,
textX + textWidth,
backgroundBottom,
backgroundPaint
)
// Draw text above the box
canvas.drawText(labelText, textX, textY, textPaint)
} catch (e: Exception) {
Log.e(TAG, "Error drawing region $name", e)
}
}
// Draw title at top
/*
val titleText = "Pokemon Detection Zones (${regions.size} regions)"
val titleX = 20f
val titleY = 80f
val titleBounds = Rect()
val titlePaint = Paint().apply {
color = Color.WHITE
textSize = 48f
isAntiAlias = true
style = Paint.Style.FILL
setShadowLayer(4f, 2f, 2f, Color.BLACK)
}
titlePaint.getTextBounds(titleText, 0, titleText.length, titleBounds)
// Draw title background
canvas.drawRect(
titleX - 16f,
titleY - titleBounds.height() - 16f,
titleX + titleBounds.width() + 32f,
titleY + 16f,
backgroundPaint
)
// Draw title
canvas.drawText(titleText, titleX, titleY, titlePaint)
*/
}
fun formatRegionLabel(name: String, region: ScreenRegion): String {
val shortName = when (name) {
"nickname" -> "NICKNAME"
"level" -> "LEVEL"
"species" -> "SPECIES"
"types" -> "TYPES"
"stats" -> "STATS"
"moves" -> "MOVES"
"nature" -> "NATURE"
"ability" -> "ABILITY"
"ot_name" -> "OT NAME"
"ot_id" -> "OT ID"
"gender" -> "GENDER"
"pokeball" -> "POKEBALL"
"favorite" -> "FAVORITE"
"stamps" -> "STAMPS"
"labels" -> "LABELS"
"marks" -> "MARKS"
"game_source" -> "GAME SOURCE"
else -> name.uppercase()
}
return "$shortName\n${region.width}x${region.height}"
}
}
}