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
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}"
|
|
}
|
|
}
|
|
}
|