mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-22 12:31:48 +01:00
Add color selection to OSC
* Add bold text and antialiasing for osc buttons * Fix osc dpad and button position (widder than taller) * Set default OSC color to white background with black text
This commit is contained in:
parent
66d2965c63
commit
1282362fce
@ -184,6 +184,7 @@ dependencies {
|
||||
|
||||
/* Other Java */
|
||||
implementation 'info.debatty:java-string-similarity:2.0.0'
|
||||
implementation 'com.github.KikiManjaro:colorpicker:v1.1.12'
|
||||
}
|
||||
|
||||
kapt {
|
||||
|
@ -6,9 +6,12 @@
|
||||
package emu.skyline.input.onscreen
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import androidx.core.content.ContextCompat
|
||||
import emu.skyline.input.ButtonId
|
||||
import kotlin.math.roundToInt
|
||||
@ -17,13 +20,13 @@ import kotlin.math.roundToInt
|
||||
* Converts relative values, such as coordinates and boundaries, to their absolute counterparts, also handles layout modifications like scaling and custom positioning
|
||||
*/
|
||||
abstract class OnScreenButton(
|
||||
onScreenControllerView : OnScreenControllerView,
|
||||
val buttonId : ButtonId,
|
||||
private val defaultRelativeX : Float,
|
||||
private val defaultRelativeY : Float,
|
||||
private val defaultRelativeWidth : Float,
|
||||
private val defaultRelativeHeight : Float,
|
||||
drawableId : Int
|
||||
onScreenControllerView : OnScreenControllerView,
|
||||
val buttonId : ButtonId,
|
||||
private val defaultRelativeX : Float,
|
||||
private val defaultRelativeY : Float,
|
||||
private val defaultRelativeWidth : Float,
|
||||
private val defaultRelativeHeight : Float,
|
||||
drawableId : Int
|
||||
) {
|
||||
companion object {
|
||||
/**
|
||||
@ -37,7 +40,11 @@ abstract class OnScreenButton(
|
||||
|
||||
protected val drawable = ContextCompat.getDrawable(onScreenControllerView.context, drawableId)!!
|
||||
|
||||
private val buttonSymbolPaint = Paint().apply { color = Color.GRAY }
|
||||
internal val buttonSymbolPaint = Paint().apply {
|
||||
color = config.textColor
|
||||
typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
|
||||
isAntiAlias = true
|
||||
}
|
||||
private val textBoundsRect = Rect()
|
||||
|
||||
var relativeX = config.relativeX
|
||||
@ -83,6 +90,7 @@ abstract class OnScreenButton(
|
||||
buttonSymbolPaint.apply {
|
||||
textSize = size
|
||||
textAlign = Paint.Align.LEFT
|
||||
color = config.textColor
|
||||
this.alpha = alpha
|
||||
getTextBounds(text, 0, text.length, textBoundsRect)
|
||||
}
|
||||
@ -92,15 +100,25 @@ abstract class OnScreenButton(
|
||||
open fun render(canvas : Canvas) {
|
||||
val bounds = currentBounds
|
||||
val alpha = if (isPressed) (config.alpha - 130).coerceIn(30..255) else config.alpha
|
||||
renderColors(drawable)
|
||||
drawable.apply {
|
||||
this.bounds = bounds
|
||||
this.alpha = alpha
|
||||
draw(canvas)
|
||||
}
|
||||
|
||||
renderCenteredText(canvas, buttonId.short!!, itemWidth.coerceAtMost(itemHeight) * 0.4f, bounds.centerX().toFloat(), bounds.centerY().toFloat(), alpha)
|
||||
}
|
||||
|
||||
private fun renderColors(drawable : Drawable) {
|
||||
when (drawable) {
|
||||
is GradientDrawable -> drawable.setColor(config.backgroundColor)
|
||||
is LayerDrawable -> {
|
||||
for (i in 0 until drawable.numberOfLayers) renderColors(drawable.getDrawable(i))
|
||||
}
|
||||
else -> drawable.setTint(config.backgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun isTouched(x : Float, y : Float) : Boolean
|
||||
|
||||
open fun onFingerDown(x : Float, y : Float) {
|
||||
|
@ -6,11 +6,14 @@
|
||||
package emu.skyline.input.onscreen
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import emu.skyline.input.ButtonId
|
||||
import emu.skyline.utils.sharedPreferences
|
||||
|
||||
interface ControllerConfiguration {
|
||||
var alpha : Int
|
||||
var textColor : Int
|
||||
var backgroundColor : Int
|
||||
var enabled : Boolean
|
||||
var globalScale : Float
|
||||
var relativeX : Float
|
||||
@ -22,6 +25,8 @@ interface ControllerConfiguration {
|
||||
*/
|
||||
class ControllerConfigurationDummy(defaultRelativeX : Float, defaultRelativeY : Float) : ControllerConfiguration {
|
||||
override var alpha : Int = 255
|
||||
override var textColor = Color.argb(180, 0, 0, 0)
|
||||
override var backgroundColor = Color.argb(180, 255, 255, 255)
|
||||
override var enabled = true
|
||||
override var globalScale = 1f
|
||||
override var relativeX = defaultRelativeX
|
||||
@ -32,6 +37,8 @@ class ControllerConfigurationImpl(private val context : Context, private val but
|
||||
private inline fun <reified T> config(default : T, prefix : String = "${buttonId.name}_") = sharedPreferences(context, default, prefix, "controller_config")
|
||||
|
||||
override var alpha by config(255, "")
|
||||
override var textColor by config(Color.argb(180, 0, 0, 0))
|
||||
override var backgroundColor by config(Color.argb(180, 255, 255, 255))
|
||||
override var enabled by config(true)
|
||||
override var globalScale by config(1.15f, "")
|
||||
override var relativeX by config(defaultRelativeX)
|
||||
|
@ -292,6 +292,14 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun getTextColor() : Int {
|
||||
return controls.globalTextColor
|
||||
}
|
||||
|
||||
fun getBackGroundColor() : Int {
|
||||
return controls.globalBackgroundColor
|
||||
}
|
||||
|
||||
fun setOnButtonStateChangedListener(listener : OnButtonStateChangedListener) {
|
||||
onButtonStateChangedListener = listener
|
||||
}
|
||||
@ -306,4 +314,18 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
|
||||
controls.allButtons.first { it.buttonId == buttonId }.config.enabled = enabled
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setTextColor(color : Int) {
|
||||
for (button in controls.allButtons) {
|
||||
button.config.textColor = color
|
||||
}
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setBackGroundColor(color : Int) {
|
||||
for (button in controls.allButtons) {
|
||||
button.config.backgroundColor = color
|
||||
}
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,10 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import emu.skyline.R
|
||||
import emu.skyline.databinding.OnScreenEditActivityBinding
|
||||
import emu.skyline.settings.AppSettings
|
||||
import emu.skyline.utils.SwitchColors
|
||||
import emu.skyline.utils.SwitchColors.*
|
||||
import petrov.kristiyan.colorpicker.DoubleColorPicker
|
||||
import petrov.kristiyan.colorpicker.DoubleColorPicker.OnChooseDoubleColorListener
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@ -41,10 +45,11 @@ class OnScreenEditActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun toggleFabVisibility(visible : Boolean) {
|
||||
actions.forEach {
|
||||
if (it.first != R.drawable.ic_close)
|
||||
if (visible) fabMapping[it.first]!!.show()
|
||||
else fabMapping[it.first]!!.hide()
|
||||
fabMapping.forEach { (id, fab) ->
|
||||
if (id != R.drawable.ic_close) {
|
||||
if (visible) fab.show()
|
||||
else fab.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,30 +64,53 @@ class OnScreenEditActivity : AppCompatActivity() {
|
||||
val checkArray = buttonProps.map { it.second }.toBooleanArray()
|
||||
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setMultiChoiceItems(buttonProps.map {
|
||||
val longText = getString(it.first.long!!)
|
||||
if (it.first.short == longText) longText else "$longText: ${it.first.short}"
|
||||
}.toTypedArray(), checkArray) { _, which, isChecked ->
|
||||
checkArray[which] = isChecked
|
||||
}.setPositiveButton(R.string.confirm) { _, _ ->
|
||||
buttonProps.forEachIndexed { index, pair ->
|
||||
if (checkArray[index] != pair.second)
|
||||
binding.onScreenControllerView.setButtonEnabled(pair.first, checkArray[index])
|
||||
}
|
||||
}.setNegativeButton(R.string.cancel, null)
|
||||
.setOnDismissListener { fullScreen() }
|
||||
.show()
|
||||
.setMultiChoiceItems(buttonProps.map {
|
||||
val longText = getString(it.first.long!!)
|
||||
if (it.first.short == longText) longText else "$longText: ${it.first.short}"
|
||||
}.toTypedArray(), checkArray) { _, which, isChecked ->
|
||||
checkArray[which] = isChecked
|
||||
}.setPositiveButton(R.string.confirm) { _, _ ->
|
||||
buttonProps.forEachIndexed { index, pair ->
|
||||
if (checkArray[index] != pair.second)
|
||||
binding.onScreenControllerView.setButtonEnabled(pair.first, checkArray[index])
|
||||
}
|
||||
}.setNegativeButton(R.string.cancel, null)
|
||||
.setOnDismissListener { fullScreen() }
|
||||
.show()
|
||||
}
|
||||
|
||||
private val paletteAction : () -> Unit = {
|
||||
DoubleColorPicker(this@OnScreenEditActivity).apply {
|
||||
setTitle(this@OnScreenEditActivity.getString(R.string.osc_background_color))
|
||||
setDefaultColorButton(binding.onScreenControllerView.getBackGroundColor())
|
||||
setRoundColorButton(true)
|
||||
setColors(*SwitchColors.colors.toIntArray())
|
||||
setDefaultDoubleColorButton(binding.onScreenControllerView.getTextColor())
|
||||
setSecondTitle(this@OnScreenEditActivity.getString(R.string.osc_text_color))
|
||||
setOnChooseDoubleColorListener(object : OnChooseDoubleColorListener {
|
||||
override fun onChooseColor(position : Int, color : Int, position2 : Int, color2 : Int) {
|
||||
binding.onScreenControllerView.setBackGroundColor(SwitchColors.colors[position])
|
||||
binding.onScreenControllerView.setTextColor(SwitchColors.colors[position2])
|
||||
}
|
||||
|
||||
override fun onCancel() {}
|
||||
})
|
||||
show()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private val actions : List<Pair<Int, () -> Unit>> = listOf(
|
||||
Pair(R.drawable.ic_restore, { binding.onScreenControllerView.resetControls() }),
|
||||
Pair(R.drawable.ic_toggle, toggleAction),
|
||||
Pair(R.drawable.ic_edit, editAction),
|
||||
Pair(R.drawable.ic_zoom_out, { binding.onScreenControllerView.decreaseScale() }),
|
||||
Pair(R.drawable.ic_zoom_in, { binding.onScreenControllerView.increaseScale() }),
|
||||
Pair(R.drawable.ic_opacity_minus) { binding.onScreenControllerView.decreaseOpacity() },
|
||||
Pair(R.drawable.ic_opacity_plus) { binding.onScreenControllerView.increaseOpacity() },
|
||||
Pair(R.drawable.ic_close, closeAction)
|
||||
Pair(R.drawable.ic_palette, paletteAction),
|
||||
Pair(R.drawable.ic_restore) { binding.onScreenControllerView.resetControls() },
|
||||
Pair(R.drawable.ic_toggle, toggleAction),
|
||||
Pair(R.drawable.ic_edit, editAction),
|
||||
Pair(R.drawable.ic_zoom_out) { binding.onScreenControllerView.decreaseScale() },
|
||||
Pair(R.drawable.ic_zoom_in) { binding.onScreenControllerView.increaseScale() },
|
||||
Pair(R.drawable.ic_opacity_minus) { binding.onScreenControllerView.decreaseOpacity() },
|
||||
Pair(R.drawable.ic_opacity_plus) { binding.onScreenControllerView.increaseOpacity() },
|
||||
Pair(R.drawable.ic_close, closeAction)
|
||||
)
|
||||
|
||||
private val fabMapping = mutableMapOf<Int, FloatingActionButton>()
|
||||
|
@ -7,13 +7,15 @@ package emu.skyline.input.onscreen
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.PointF
|
||||
import android.graphics.Typeface
|
||||
import android.os.SystemClock
|
||||
import androidx.core.graphics.minus
|
||||
import emu.skyline.R
|
||||
import emu.skyline.input.ButtonId
|
||||
import emu.skyline.input.ButtonId.*
|
||||
import emu.skyline.input.StickId
|
||||
import emu.skyline.input.StickId.*
|
||||
import emu.skyline.input.StickId.Left
|
||||
import emu.skyline.input.StickId.Right
|
||||
import emu.skyline.utils.add
|
||||
import emu.skyline.utils.multiply
|
||||
import kotlin.math.roundToInt
|
||||
@ -65,6 +67,10 @@ class JoystickButton(
|
||||
var shortDoubleTapped = false
|
||||
private set
|
||||
|
||||
init {
|
||||
innerButton.buttonSymbolPaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
|
||||
}
|
||||
|
||||
override fun renderCenteredText(canvas : Canvas, text : String, size : Float, x : Float, y : Float, alpha : Int) = Unit
|
||||
|
||||
override fun render(canvas : Canvas) {
|
||||
@ -193,14 +199,14 @@ class TriggerButton(
|
||||
|
||||
class Controls(onScreenControllerView : OnScreenControllerView) {
|
||||
private val buttonA = CircularButton(onScreenControllerView, A, 0.95f, 0.65f, 0.025f)
|
||||
private val buttonB = CircularButton(onScreenControllerView, B, 0.9f, 0.75f, 0.025f)
|
||||
private val buttonX = CircularButton(onScreenControllerView, X, 0.9f, 0.55f, 0.025f)
|
||||
private val buttonB = CircularButton(onScreenControllerView, B, 0.9f, 0.765f, 0.025f)
|
||||
private val buttonX = CircularButton(onScreenControllerView, X, 0.9f, 0.535f, 0.025f)
|
||||
private val buttonY = CircularButton(onScreenControllerView, Y, 0.85f, 0.65f, 0.025f)
|
||||
|
||||
private val buttonDpadLeft = CircularButton(onScreenControllerView, DpadLeft, 0.2f, 0.65f, 0.025f)
|
||||
private val buttonDpadUp = CircularButton(onScreenControllerView, DpadUp, 0.25f, 0.55f, 0.025f)
|
||||
private val buttonDpadUp = CircularButton(onScreenControllerView, DpadUp, 0.25f, 0.535f, 0.025f)
|
||||
private val buttonDpadRight = CircularButton(onScreenControllerView, DpadRight, 0.3f, 0.65f, 0.025f)
|
||||
private val buttonDpadDown = CircularButton(onScreenControllerView, DpadDown, 0.25f, 0.75f, 0.025f)
|
||||
private val buttonDpadDown = CircularButton(onScreenControllerView, DpadDown, 0.25f, 0.765f, 0.025f)
|
||||
|
||||
private val buttonL = RectangularButton(onScreenControllerView, L, 0.1f, 0.25f, 0.09f, 0.1f)
|
||||
private val buttonR = RectangularButton(onScreenControllerView, R, 0.9f, 0.25f, 0.09f, 0.1f)
|
||||
@ -248,4 +254,16 @@ class Controls(onScreenControllerView : OnScreenControllerView) {
|
||||
set(value) {
|
||||
circularButtons.first().config.alpha = value
|
||||
}
|
||||
|
||||
/**
|
||||
* We can take any of the global text color variables from the buttons
|
||||
*/
|
||||
val globalTextColor
|
||||
get() = circularButtons.first().config.textColor
|
||||
|
||||
/**
|
||||
* We can take any of the global background color variables from the buttons
|
||||
*/
|
||||
val globalBackgroundColor
|
||||
get() = circularButtons.first().config.backgroundColor
|
||||
}
|
||||
|
25
app/src/main/java/emu/skyline/utils/Colors.kt
Normal file
25
app/src/main/java/emu/skyline/utils/Colors.kt
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
*/
|
||||
|
||||
package emu.skyline.utils
|
||||
|
||||
import android.graphics.Color
|
||||
|
||||
enum class SwitchColors(val color : Int) {
|
||||
GRAY(Color.GRAY),
|
||||
TRANSPARENT(Color.argb(180, 0, 0, 0)),
|
||||
WHITE(Color.argb(180, 255, 255, 255)),
|
||||
NEON_YELLOW(Color.argb(180, 230, 255, 0)),
|
||||
NEON_PURPLE(Color.argb(180, 180, 0, 230)),
|
||||
NEON_RED(Color.argb(180, 255, 60, 40)),
|
||||
MARIO_RED(Color.argb(180, 225, 15, 0)),
|
||||
NEON_BLUE(Color.argb(180, 10, 185, 230)),
|
||||
BLUE(Color.argb(180, 70, 85, 245)),
|
||||
NEON_GREEN(Color.argb(180, 30, 220, 0));
|
||||
|
||||
companion object {
|
||||
val colors = SwitchColors.values().map { clr -> clr.color }
|
||||
}
|
||||
}
|
10
app/src/main/res/drawable/ic_palette.xml
Normal file
10
app/src/main/res/drawable/ic_palette.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,3c-4.97,0 -9,4.03 -9,9s4.03,9 9,9c0.83,0 1.5,-0.67 1.5,-1.5 0,-0.39 -0.15,-0.74 -0.39,-1.01 -0.23,-0.26 -0.38,-0.61 -0.38,-0.99 0,-0.83 0.67,-1.5 1.5,-1.5L16,16c2.76,0 5,-2.24 5,-5 0,-4.42 -4.03,-8 -9,-8zM6.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,9 6.5,9 8,9.67 8,10.5 7.33,12 6.5,12zM9.5,8C8.67,8 8,7.33 8,6.5S8.67,5 9.5,5s1.5,0.67 1.5,1.5S10.33,8 9.5,8zM14.5,8c-0.83,0 -1.5,-0.67 -1.5,-1.5S13.67,5 14.5,5s1.5,0.67 1.5,1.5S15.33,8 14.5,8zM17.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S16.67,9 17.5,9s1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5z" />
|
||||
</vector>
|
@ -155,6 +155,8 @@
|
||||
<string name="osc_feedback">Enable Haptic Feedback</string>
|
||||
<string name="osc_feedback_description">Excludes joysticks and hardware controls</string>
|
||||
<string name="osc_edit">Edit On-Screen Controls layout</string>
|
||||
<string name="osc_text_color">Text color</string>
|
||||
<string name="osc_background_color">Background color</string>
|
||||
<string name="setup_guide">Setup Guide</string>
|
||||
<string name="setup_guide_description">Sequentially map every stick and button</string>
|
||||
<string name="joystick">Joystick</string>
|
||||
|
@ -9,6 +9,7 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -28,6 +29,7 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user