feat: add movable shader building overlay with touch handling

- Add touch event handling to ShaderBuildingOverlayView for dragging
- Implement boundary constraints to keep overlay within screen bounds
- Add visual feedback with border color changes during dragging
- Add resetPosition() method to restore overlay to default position
- Move ShaderBuildingOverlayView to separate FrameLayout for absolute positioning
- Set container to non-clickable to prevent interference with input controls
- Maintain clickable/focusable state only on the overlay view itself

Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
Zephyron
2025-08-17 17:03:52 +10:00
parent f76a40fa12
commit 2d43a2d47b
2 changed files with 67 additions and 9 deletions

View File

@@ -7,6 +7,7 @@ import android.content.Context
import android.graphics.* import android.graphics.*
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.view.MotionEvent
import android.view.View import android.view.View
import kotlin.math.* import kotlin.math.*
@@ -86,6 +87,11 @@ class ShaderBuildingOverlayView @JvmOverloads constructor(
private var animationProgress: Float = 0f private var animationProgress: Float = 0f
private var isAnimating: Boolean = false private var isAnimating: Boolean = false
// Touch handling for dragging
private var lastTouchX: Float = 0f
private var lastTouchY: Float = 0f
private var isDragging: Boolean = false
fun updatePerformanceStats(fps: Float, frameTime: Float, speed: Float, shaders: Int) { fun updatePerformanceStats(fps: Float, frameTime: Float, speed: Float, shaders: Int) {
try { try {
currentFps = fps currentFps = fps
@@ -218,6 +224,50 @@ class ShaderBuildingOverlayView @JvmOverloads constructor(
drawPerformanceGraph(canvas) drawPerformanceGraph(canvas)
} }
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
lastTouchX = event.x
lastTouchY = event.y
isDragging = true
borderPaint.color = Color.parseColor("#FF5722") // Red border when dragging
invalidate()
return true
}
MotionEvent.ACTION_MOVE -> {
if (isDragging) {
val deltaX = event.x - lastTouchX
val deltaY = event.y - lastTouchY
// Update position with boundary constraints
val newX = (x + deltaX).coerceIn(0f, (parent as View).width - width.toFloat())
val newY = (y + deltaY).coerceIn(0f, (parent as View).height - height.toFloat())
x = newX
y = newY
lastTouchX = event.x
lastTouchY = event.y
invalidate()
}
return true
}
MotionEvent.ACTION_UP -> {
isDragging = false
borderPaint.color = Color.parseColor("#FF9800") // Orange border when not dragging
invalidate()
return true
}
}
return super.onTouchEvent(event)
}
fun resetPosition() {
x = 0f
y = 0f
invalidate()
}
private fun drawPerformanceGraph(canvas: Canvas) { private fun drawPerformanceGraph(canvas: Canvas) {
if (frameTimeHistory.isEmpty()) return if (frameTimeHistory.isEmpty()) return

View File

@@ -177,17 +177,25 @@
android:focusable="false" android:focusable="false"
android:visibility="gone" /> android:visibility="gone" />
</LinearLayout>
</FrameLayout>
<FrameLayout
android:id="@+id/movable_overlay_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:focusable="false">
<org.citron.citron_emu.views.ShaderBuildingOverlayView <org.citron.citron_emu.views.ShaderBuildingOverlayView
android:id="@+id/shader_building_overlay_view" android:id="@+id/shader_building_overlay_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:clickable="true"
android:clickable="false" android:focusable="true"
android:focusable="false"
android:visibility="gone" /> android:visibility="gone" />
</LinearLayout>
</FrameLayout> </FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>