parent
7a53265d8d
commit
3a3e686e4c
|
@ -35,14 +35,15 @@ android {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
implementation 'androidx.core:core-ktx:1.3.2'
|
implementation 'androidx.core:core-ktx:1.6.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||||
implementation 'com.google.android.material:material:1.3.0'
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
|
|
||||||
implementation 'net.cachapa.expandablelayout:expandablelayout:2.9.2'
|
implementation 'net.cachapa.expandablelayout:expandablelayout:2.9.2'
|
||||||
|
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||||
}
|
}
|
|
@ -27,6 +27,7 @@
|
||||||
<action android:name="android.nfc.action.TECH_DISCOVERED" />
|
<action android:name="android.nfc.action.TECH_DISCOVERED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity android:name=".activity.SettingsActivity" android:configChanges="uiMode|orientation" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -1,77 +1,89 @@
|
||||||
package com.github.brokenithm
|
package com.github.brokenithm
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
|
||||||
class BrokenithmApplication : Application() {
|
class BrokenithmApplication : Application() {
|
||||||
var lastServer: String
|
|
||||||
get() {
|
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
|
||||||
return config.getString("server", "") ?: ""
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
|
||||||
config.edit().putString("server", value).apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
var enableAir: Boolean
|
abstract class BasePreference<T>(context: Context, fileName: String) {
|
||||||
get() {
|
protected val config: SharedPreferences = context.getSharedPreferences(fileName, MODE_PRIVATE)
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
abstract fun value(): T
|
||||||
return config.getBoolean("enable_air", true)
|
abstract fun update(value: T)
|
||||||
}
|
}
|
||||||
set(value) {
|
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
|
||||||
config.edit().putBoolean("enable_air", value).apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
var airSource: Int
|
abstract class Settings<T>(context: Context) : BasePreference<T>(context, settings_preference)
|
||||||
get() {
|
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
|
||||||
return config.getInt("air_source", 3)
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
|
||||||
config.edit().putInt("air_source", value).apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
var simpleAir: Boolean
|
open class StringPreference(
|
||||||
get() {
|
context: Context,
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
private val key: String,
|
||||||
return config.getBoolean("simple_air", false)
|
private val defValue: String
|
||||||
}
|
) : Settings<String>(context) {
|
||||||
set(value) {
|
override fun value() = config.getString(key, defValue) ?: defValue
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
override fun update(value: String) = config.edit().putString(key, value).apply()
|
||||||
config.edit().putBoolean("simple_air", value).apply()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var showDelay: Boolean
|
open class BooleanPreference(
|
||||||
get() {
|
context: Context,
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
private val key: String,
|
||||||
return config.getBoolean("show_delay", false)
|
private val defValue: Boolean
|
||||||
}
|
) : Settings<Boolean>(context) {
|
||||||
set(value) {
|
override fun value() = config.getBoolean(key, defValue)
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
override fun update(value: Boolean) = config.edit().putBoolean(key, value).apply()
|
||||||
config.edit().putBoolean("show_delay", value).apply()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var enableVibrate: Boolean
|
open class IntegerPreference(
|
||||||
get() {
|
context: Context,
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
private val key: String,
|
||||||
return config.getBoolean("enable_vibrate", true)
|
private val defValue: Int
|
||||||
}
|
) : Settings<Int>(context) {
|
||||||
set(value) {
|
override fun value() = config.getInt(key, defValue)
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
override fun update(value: Int) = config.edit().putInt(key, value).apply()
|
||||||
config.edit().putBoolean("enable_vibrate", value).apply()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var tcpMode: Boolean
|
open class FloatPreference(
|
||||||
get() {
|
context: Context,
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
private val key: String,
|
||||||
return config.getBoolean("tcp_mode", false)
|
private val defValue: Float
|
||||||
}
|
) : Settings<Float>(context) {
|
||||||
set(value) {
|
override fun value() = config.getString(key, defValue.toString())?.toFloat() ?: defValue
|
||||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
override fun update(value: Float) = config.edit().putString(key, value.toString()).apply()
|
||||||
config.edit().putBoolean("tcp_mode", value).apply()
|
}
|
||||||
}
|
|
||||||
|
lateinit var lastServer : StringPreference
|
||||||
|
lateinit var enableAir : BooleanPreference
|
||||||
|
lateinit var airSource : IntegerPreference
|
||||||
|
lateinit var simpleAir : BooleanPreference
|
||||||
|
lateinit var showDelay : BooleanPreference
|
||||||
|
lateinit var enableVibrate : BooleanPreference
|
||||||
|
lateinit var tcpMode : BooleanPreference
|
||||||
|
lateinit var enableNFC : BooleanPreference
|
||||||
|
lateinit var wideTouchRange : BooleanPreference
|
||||||
|
lateinit var enableTouchSize : BooleanPreference
|
||||||
|
lateinit var fatTouchThreshold : FloatPreference
|
||||||
|
lateinit var extraFatTouchThreshold : FloatPreference
|
||||||
|
lateinit var gyroAirLowestBound : FloatPreference
|
||||||
|
lateinit var gyroAirHighestBound : FloatPreference
|
||||||
|
lateinit var accelAirThreshold : FloatPreference
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
lastServer = StringPreference(this, "server", "")
|
||||||
|
enableAir = BooleanPreference(this, "enable_air", true)
|
||||||
|
airSource = IntegerPreference(this, "air_source", 3)
|
||||||
|
simpleAir = BooleanPreference(this, "simple_air", false)
|
||||||
|
showDelay = BooleanPreference(this, "show_delay", false)
|
||||||
|
enableVibrate = BooleanPreference(this, "enable_vibrate", true)
|
||||||
|
tcpMode = BooleanPreference(this, "tcp_mode", false)
|
||||||
|
enableNFC = BooleanPreference(this, "enable_nfc", true)
|
||||||
|
wideTouchRange = BooleanPreference(this, "wide_touch_range", false)
|
||||||
|
enableTouchSize = BooleanPreference(this, "enable_touch_size", false)
|
||||||
|
fatTouchThreshold = FloatPreference(this, "fat_touch_threshold", 0.027f)
|
||||||
|
extraFatTouchThreshold = FloatPreference(this, "extra_fat_touch_threshold", 0.035f)
|
||||||
|
gyroAirLowestBound = FloatPreference(this, "gyro_air_lowest", 0.8f)
|
||||||
|
gyroAirHighestBound = FloatPreference(this, "gyro_air_highest", 1.35f)
|
||||||
|
accelAirThreshold = FloatPreference(this, "accel_air_threshold", 2f)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val settings_preference = "settings"
|
private const val settings_preference = "settings"
|
||||||
|
|
|
@ -48,8 +48,9 @@ class MainActivity : AppCompatActivity() {
|
||||||
private val numOfGaps = 16
|
private val numOfGaps = 16
|
||||||
private val buttonWidthToGap = 7.428571f
|
private val buttonWidthToGap = 7.428571f
|
||||||
private val numOfAirBlock = 6
|
private val numOfAirBlock = 6
|
||||||
private val fatTouchSizeThreshold = 0.027f
|
private var mEnableTouchSize = false
|
||||||
private val extraFatTouchSizeThreshold = 0.035f
|
private var mFatTouchSizeThreshold = 0.027f
|
||||||
|
private var mExtraFatTouchSizeThreshold = 0.035f
|
||||||
private var mCurrentDelay = 0f
|
private var mCurrentDelay = 0f
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
|
@ -68,6 +69,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
private lateinit var mButtonRenderer: View
|
private lateinit var mButtonRenderer: View
|
||||||
|
|
||||||
// vibrator
|
// vibrator
|
||||||
|
private var mEnableVibrate = true
|
||||||
private lateinit var vibrator: Vibrator
|
private lateinit var vibrator: Vibrator
|
||||||
private lateinit var vibratorTask: AsyncTaskUtil.AsyncTask<Unit, Unit, Unit>
|
private lateinit var vibratorTask: AsyncTaskUtil.AsyncTask<Unit, Unit, Unit>
|
||||||
private lateinit var vibrateMethod: (Long) -> Unit
|
private lateinit var vibrateMethod: (Long) -> Unit
|
||||||
|
@ -80,7 +82,6 @@ class MainActivity : AppCompatActivity() {
|
||||||
private var mSimpleAir = false
|
private var mSimpleAir = false
|
||||||
private var mDebugInfo = false
|
private var mDebugInfo = false
|
||||||
private var mShowDelay = false
|
private var mShowDelay = false
|
||||||
private var mEnableVibrate = true
|
|
||||||
private lateinit var mDelayText: TextView
|
private lateinit var mDelayText: TextView
|
||||||
private var windowWidth = 0f
|
private var windowWidth = 0f
|
||||||
private var windowHeight = 0f
|
private var windowHeight = 0f
|
||||||
|
@ -89,9 +90,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
// sensor
|
// sensor
|
||||||
private var mSensorManager: SensorManager? = null
|
private var mSensorManager: SensorManager? = null
|
||||||
private var mSensorCallback: ((Float) -> Unit)? = null
|
private var mSensorCallback: ((Float) -> Unit)? = null
|
||||||
|
private var mGyroLowestBound = 0.8f
|
||||||
|
private var mGyroHighestBound = 1.35f
|
||||||
|
private var mAccelThreshold = 2f
|
||||||
private val listener = object : SensorEventListener {
|
private val listener = object : SensorEventListener {
|
||||||
|
|
||||||
val threshold = 2f
|
|
||||||
var current = 0
|
var current = 0
|
||||||
var lastAcceleration = 0f
|
var lastAcceleration = 0f
|
||||||
|
|
||||||
|
@ -101,6 +103,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
override fun onSensorChanged(event: SensorEvent?) {
|
override fun onSensorChanged(event: SensorEvent?) {
|
||||||
event ?: return
|
event ?: return
|
||||||
|
val threshold = mAccelThreshold
|
||||||
when (event.sensor.type) {
|
when (event.sensor.type) {
|
||||||
Sensor.TYPE_LINEAR_ACCELERATION -> {
|
Sensor.TYPE_LINEAR_ACCELERATION -> {
|
||||||
if (mAirSource != 2)
|
if (mAirSource != 2)
|
||||||
|
@ -165,7 +168,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
private var adapter: NfcAdapter? = null
|
private var adapter: NfcAdapter? = null
|
||||||
private val mAimeKey = byteArrayOf(0x57, 0x43, 0x43, 0x46, 0x76, 0x32)
|
private val mAimeKey = byteArrayOf(0x57, 0x43, 0x43, 0x46, 0x76, 0x32)
|
||||||
private var enableNFC = true
|
private var mEnableNFC = true
|
||||||
private var hasCard = false
|
private var hasCard = false
|
||||||
private var cardType = CardType.CARD_AIME
|
private var cardType = CardType.CARD_AIME
|
||||||
private val cardId = ByteArray(10)
|
private val cardId = ByteArray(10)
|
||||||
|
@ -183,7 +186,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
cardId[9] = 0
|
cardId[9] = 0
|
||||||
cardType = CardType.CARD_FELICA
|
cardType = CardType.CARD_FELICA
|
||||||
hasCard = true
|
hasCard = true
|
||||||
Log.d(TAG, "found felica card: ${cardId.toHexString().removeRange(16..19)}")
|
Log.d(TAG, "Found FeliCa card: ${cardId.toHexString().removeRange(16..19)}")
|
||||||
while (felica.isConnected) Thread.sleep(50)
|
while (felica.isConnected) Thread.sleep(50)
|
||||||
hasCard = false
|
hasCard = false
|
||||||
felica.close()
|
felica.close()
|
||||||
|
@ -203,11 +206,11 @@ class MainActivity : AppCompatActivity() {
|
||||||
block.copyInto(cardId, 0, 6, 16)
|
block.copyInto(cardId, 0, 6, 16)
|
||||||
cardType = CardType.CARD_AIME
|
cardType = CardType.CARD_AIME
|
||||||
hasCard = true
|
hasCard = true
|
||||||
Log.d(TAG, "found aime card: ${cardId.toHexString()}")
|
Log.d(TAG, "Found Aime card: ${cardId.toHexString()}")
|
||||||
while (mifare.isConnected) Thread.sleep(50)
|
while (mifare.isConnected) Thread.sleep(50)
|
||||||
hasCard = false
|
hasCard = false
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "nfc auth failed")
|
Log.d(TAG, "NFC auth failed")
|
||||||
}
|
}
|
||||||
mifare.close()
|
mifare.close()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -236,18 +239,13 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val settings = findViewById<Button>(R.id.button_settings)
|
||||||
|
settings.setOnClickListener { startActivity(Intent(this, SettingsActivity::class.java)) }
|
||||||
|
|
||||||
mDelayText = findViewById(R.id.text_delay)
|
mDelayText = findViewById(R.id.text_delay)
|
||||||
|
|
||||||
findViewById<CheckBox>(R.id.check_vibrate).apply {
|
|
||||||
setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
mEnableVibrate = isChecked
|
|
||||||
app.enableVibrate = isChecked
|
|
||||||
}
|
|
||||||
isChecked = app.enableVibrate
|
|
||||||
}
|
|
||||||
|
|
||||||
val editServer = findViewById<EditText>(R.id.edit_server).apply {
|
val editServer = findViewById<EditText>(R.id.edit_server).apply {
|
||||||
setText(app.lastServer)
|
setText(app.lastServer.value())
|
||||||
}
|
}
|
||||||
findViewById<Button>(R.id.button_start).setOnClickListener {
|
findViewById<Button>(R.id.button_start).setOnClickListener {
|
||||||
val server = editServer.text.toString()
|
val server = editServer.text.toString()
|
||||||
|
@ -259,8 +257,9 @@ class MainActivity : AppCompatActivity() {
|
||||||
mExitFlag = false
|
mExitFlag = false
|
||||||
(it as Button).setText(R.string.stop)
|
(it as Button).setText(R.string.stop)
|
||||||
editServer.isEnabled = false
|
editServer.isEnabled = false
|
||||||
|
settings.isEnabled = false
|
||||||
|
|
||||||
app.lastServer = server
|
app.lastServer.update(server)
|
||||||
val address = parseAddress(server)
|
val address = parseAddress(server)
|
||||||
if (!mTCPMode)
|
if (!mTCPMode)
|
||||||
sendConnect(address)
|
sendConnect(address)
|
||||||
|
@ -273,6 +272,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
mExitFlag = true
|
mExitFlag = true
|
||||||
(it as Button).setText(R.string.start)
|
(it as Button).setText(R.string.start)
|
||||||
editServer.isEnabled = true
|
editServer.isEnabled = true
|
||||||
|
settings.isEnabled = true
|
||||||
senderTask.cancel()
|
senderTask.cancel()
|
||||||
receiverTask.cancel()
|
receiverTask.cancel()
|
||||||
pingPongTask.cancel()
|
pingPongTask.cancel()
|
||||||
|
@ -289,16 +289,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val checkSimpleAir = findViewById<CheckBox>(R.id.check_simple_air)
|
val checkSimpleAir = findViewById<CheckBox>(R.id.check_simple_air)
|
||||||
findViewById<CheckBox>(R.id.check_enable_air).apply {
|
mAirSource = app.airSource.value()
|
||||||
setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
mEnableAir = isChecked
|
|
||||||
checkSimpleAir.isEnabled = isChecked
|
|
||||||
app.enableAir = isChecked
|
|
||||||
}
|
|
||||||
isChecked = app.enableAir
|
|
||||||
checkSimpleAir.isEnabled = isChecked
|
|
||||||
}
|
|
||||||
mAirSource = app.airSource
|
|
||||||
findViewById<TextView>(R.id.text_switch_air).apply {
|
findViewById<TextView>(R.id.text_switch_air).apply {
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
mAirSource = when (mAirSource) {
|
mAirSource = when (mAirSource) {
|
||||||
|
@ -325,7 +316,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.airSource = mAirSource
|
app.airSource.update(mAirSource)
|
||||||
}
|
}
|
||||||
text = getString(when (mAirSource) {
|
text = getString(when (mAirSource) {
|
||||||
0 -> { checkSimpleAir.isEnabled = false; R.string.disable_air }
|
0 -> { checkSimpleAir.isEnabled = false; R.string.disable_air }
|
||||||
|
@ -337,12 +328,12 @@ class MainActivity : AppCompatActivity() {
|
||||||
checkSimpleAir.apply {
|
checkSimpleAir.apply {
|
||||||
setOnCheckedChangeListener { _, isChecked ->
|
setOnCheckedChangeListener { _, isChecked ->
|
||||||
mSimpleAir = isChecked
|
mSimpleAir = isChecked
|
||||||
app.simpleAir = isChecked
|
app.simpleAir.update(isChecked)
|
||||||
}
|
}
|
||||||
isChecked = app.simpleAir
|
isChecked = app.simpleAir.value()
|
||||||
}
|
}
|
||||||
mEnableAir = app.enableAir
|
mEnableAir = app.enableAir.value()
|
||||||
mSimpleAir = app.simpleAir
|
mSimpleAir = app.simpleAir.value()
|
||||||
|
|
||||||
findViewById<View>(R.id.button_test).setOnTouchListener { view, event ->
|
findViewById<View>(R.id.button_test).setOnTouchListener { view, event ->
|
||||||
mTestButton = when(event.actionMasked) {
|
mTestButton = when(event.actionMasked) {
|
||||||
|
@ -365,12 +356,12 @@ class MainActivity : AppCompatActivity() {
|
||||||
setOnCheckedChangeListener { _, isChecked ->
|
setOnCheckedChangeListener { _, isChecked ->
|
||||||
mShowDelay = isChecked
|
mShowDelay = isChecked
|
||||||
mDelayText.visibility = if (isChecked) View.VISIBLE else View.GONE
|
mDelayText.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||||
app.showDelay = isChecked
|
app.showDelay.update(isChecked)
|
||||||
}
|
}
|
||||||
isChecked = app.showDelay
|
isChecked = app.showDelay.value()
|
||||||
}
|
}
|
||||||
|
|
||||||
mTCPMode = app.tcpMode
|
mTCPMode = app.tcpMode.value()
|
||||||
findViewById<TextView>(R.id.text_mode).apply {
|
findViewById<TextView>(R.id.text_mode).apply {
|
||||||
text = getString(if (mTCPMode) R.string.tcp else R.string.udp)
|
text = getString(if (mTCPMode) R.string.tcp else R.string.udp)
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
|
@ -383,7 +374,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
mTCPMode = true
|
mTCPMode = true
|
||||||
R.string.tcp
|
R.string.tcp
|
||||||
})
|
})
|
||||||
app.tcpMode = mTCPMode
|
app.tcpMode.update(mTCPMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
initTasks()
|
initTasks()
|
||||||
|
@ -393,8 +384,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
vibratorTask.execute(lifecycleScope)
|
vibratorTask.execute(lifecycleScope)
|
||||||
|
|
||||||
mSensorCallback = {
|
mSensorCallback = {
|
||||||
val lowest = 0.8f
|
val lowest = mGyroLowestBound
|
||||||
val highest = 1.35f
|
val highest = mGyroHighestBound
|
||||||
val steps = (highest - lowest) / numOfAirBlock
|
val steps = (highest - lowest) / numOfAirBlock
|
||||||
val current = abs(it)
|
val current = abs(it)
|
||||||
mCurrentAirHeight = if (mSimpleAir) {
|
mCurrentAirHeight = if (mSimpleAir) {
|
||||||
|
@ -452,11 +443,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
val textInfo = findViewById<TextView>(R.id.text_info)
|
val textInfo = findViewById<TextView>(R.id.text_info)
|
||||||
findViewById<CheckBox>(R.id.check_debug).setOnCheckedChangeListener { _, isChecked ->
|
findViewById<CheckBox>(R.id.check_debug).setOnCheckedChangeListener { _, isChecked ->
|
||||||
mDebugInfo = isChecked
|
mDebugInfo = isChecked
|
||||||
textInfo.visibility = if (isChecked) {
|
textInfo.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gapWidth = windowWidth / (numOfButtons * buttonWidthToGap + numOfGaps)
|
gapWidth = windowWidth / (numOfButtons * buttonWidthToGap + numOfGaps)
|
||||||
|
@ -510,44 +497,64 @@ class MainActivity : AppCompatActivity() {
|
||||||
var index = pointPos.toInt()
|
var index = pointPos.toInt()
|
||||||
if (index > numOfButtons) index = numOfButtons
|
if (index > numOfButtons) index = numOfButtons
|
||||||
|
|
||||||
var centerButton = index * 2
|
if (mEnableTouchSize) {
|
||||||
if (touchedButtons.contains(centerButton)) centerButton++
|
var centerButton = index * 2
|
||||||
var leftButton = ((index - 1) * 2).coerceAtLeast(0)
|
if (touchedButtons.contains(centerButton)) centerButton++
|
||||||
if (touchedButtons.contains(leftButton)) leftButton++
|
var leftButton = ((index - 1) * 2).coerceAtLeast(0)
|
||||||
var rightButton = ((index + 1) * 2).coerceAtMost(numOfButtons * 2)
|
if (touchedButtons.contains(leftButton)) leftButton++
|
||||||
if (touchedButtons.contains(rightButton)) rightButton++
|
var rightButton = ((index + 1) * 2).coerceAtMost(numOfButtons * 2)
|
||||||
var left2Button = ((index - 2) * 2).coerceAtLeast(0)
|
if (touchedButtons.contains(rightButton)) rightButton++
|
||||||
if (touchedButtons.contains(left2Button)) left2Button++
|
var left2Button = ((index - 2) * 2).coerceAtLeast(0)
|
||||||
var right2Button = ((index + 2) * 2).coerceAtMost(numOfButtons * 2)
|
if (touchedButtons.contains(left2Button)) left2Button++
|
||||||
if (touchedButtons.contains(right2Button)) right2Button++
|
var right2Button = ((index + 2) * 2).coerceAtMost(numOfButtons * 2)
|
||||||
|
if (touchedButtons.contains(right2Button)) right2Button++
|
||||||
|
|
||||||
val currentSize = event.getSize(i)
|
val currentSize = event.getSize(i)
|
||||||
maxTouchedSize = maxTouchedSize.coerceAtLeast(currentSize)
|
maxTouchedSize = maxTouchedSize.coerceAtLeast(currentSize)
|
||||||
|
|
||||||
touchedButtons.add(centerButton)
|
touchedButtons.add(centerButton)
|
||||||
when ((pointPos - index) * 4) {
|
when ((pointPos - index) * 4) {
|
||||||
in 0f..1f -> {
|
in 0f..1f -> {
|
||||||
touchedButtons.add(leftButton)
|
touchedButtons.add(leftButton)
|
||||||
if (currentSize >= extraFatTouchSizeThreshold) {
|
if (currentSize >= mExtraFatTouchSizeThreshold) {
|
||||||
touchedButtons.add(left2Button)
|
touchedButtons.add(left2Button)
|
||||||
|
touchedButtons.add(rightButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in 1f..3f -> {
|
||||||
|
if (currentSize >= mFatTouchSizeThreshold) {
|
||||||
|
touchedButtons.add(leftButton)
|
||||||
|
touchedButtons.add(rightButton)
|
||||||
|
}
|
||||||
|
if (currentSize >= mExtraFatTouchSizeThreshold) {
|
||||||
|
touchedButtons.add(left2Button)
|
||||||
|
touchedButtons.add(right2Button)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in 3f..4f -> {
|
||||||
touchedButtons.add(rightButton)
|
touchedButtons.add(rightButton)
|
||||||
|
if (currentSize >= mExtraFatTouchSizeThreshold) {
|
||||||
|
touchedButtons.add(leftButton)
|
||||||
|
touchedButtons.add(right2Button)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in 1f..3f -> {
|
} else {
|
||||||
if (currentSize >= fatTouchSizeThreshold) {
|
if (index > 15) index = 15
|
||||||
touchedButtons.add(leftButton)
|
var targetIndex = index * 2
|
||||||
touchedButtons.add(rightButton)
|
if (touchedButtons.contains(targetIndex)) targetIndex++
|
||||||
|
touchedButtons.add(targetIndex)
|
||||||
|
if (index > 0) {
|
||||||
|
if ((pointPos - index) * 4 < 1) {
|
||||||
|
targetIndex = (index - 1) * 2
|
||||||
|
if (touchedButtons.contains(targetIndex)) targetIndex++
|
||||||
|
touchedButtons.add(targetIndex)
|
||||||
}
|
}
|
||||||
if (currentSize >= extraFatTouchSizeThreshold) {
|
} else if (index < 31) {
|
||||||
touchedButtons.add(left2Button)
|
if ((pointPos - index) * 4 > 3) {
|
||||||
touchedButtons.add(right2Button)
|
targetIndex = (index + 1) * 2
|
||||||
}
|
if (touchedButtons.contains(targetIndex)) targetIndex++
|
||||||
}
|
touchedButtons.add(targetIndex)
|
||||||
in 3f..4f -> {
|
|
||||||
touchedButtons.add(rightButton)
|
|
||||||
if (currentSize >= extraFatTouchSizeThreshold) {
|
|
||||||
touchedButtons.add(leftButton)
|
|
||||||
touchedButtons.add(right2Button)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,6 +589,18 @@ class MainActivity : AppCompatActivity() {
|
||||||
val accel = mSensorManager?.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
|
val accel = mSensorManager?.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
|
||||||
mSensorManager?.registerListener(listener, accel, 10000)
|
mSensorManager?.registerListener(listener, accel, 10000)
|
||||||
enableNfcForegroundDispatch()
|
enableNfcForegroundDispatch()
|
||||||
|
loadPreference()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadPreference() {
|
||||||
|
mEnableTouchSize = app.enableTouchSize.value()
|
||||||
|
mFatTouchSizeThreshold = app.fatTouchThreshold.value()
|
||||||
|
mExtraFatTouchSizeThreshold = app.extraFatTouchThreshold.value()
|
||||||
|
mEnableNFC = app.enableNFC.value()
|
||||||
|
mEnableVibrate = app.enableVibrate.value()
|
||||||
|
mGyroLowestBound = app.gyroAirLowestBound.value()
|
||||||
|
mGyroHighestBound = app.gyroAirHighestBound.value()
|
||||||
|
mAccelThreshold = app.accelAirThreshold.value()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun enableNfcForegroundDispatch() {
|
private fun enableNfcForegroundDispatch() {
|
||||||
|
@ -657,6 +676,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Char.byte() = code.toByte()
|
||||||
private fun initTasks() {
|
private fun initTasks() {
|
||||||
receiverTask = AsyncTaskUtil.AsyncTask.make(
|
receiverTask = AsyncTaskUtil.AsyncTask.make(
|
||||||
doInBackground = {
|
doInBackground = {
|
||||||
|
@ -671,10 +691,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
try {
|
try {
|
||||||
val dataSize = mTCPSocket.getInputStream().read(buffer, 0, 256)
|
val dataSize = mTCPSocket.getInputStream().read(buffer, 0, 256)
|
||||||
if (dataSize >= 3) {
|
if (dataSize >= 3) {
|
||||||
if (dataSize >= 100 && buffer[1] == 'L'.toByte() && buffer[2] == 'E'.toByte() && buffer[3] == 'D'.toByte()) {
|
if (dataSize >= 100 && buffer[1] == 'L'.byte() && buffer[2] == 'E'.byte() && buffer[3] == 'D'.byte()) {
|
||||||
setLED(buffer)
|
setLED(buffer)
|
||||||
}
|
}
|
||||||
if (dataSize >= 4 && buffer[1] == 'P'.toByte() && buffer[2] == 'O'.toByte() && buffer[3] == 'N'.toByte()) {
|
if (dataSize >= 4 && buffer[1] == 'P'.byte() && buffer[2] == 'O'.byte() && buffer[3] == 'N'.byte()) {
|
||||||
val delay = calculateDelay(buffer)
|
val delay = calculateDelay(buffer)
|
||||||
if (delay > 0f)
|
if (delay > 0f)
|
||||||
mCurrentDelay = delay
|
mCurrentDelay = delay
|
||||||
|
@ -709,10 +729,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
if (packet.address.hostAddress == address.toHostString() && packet.port == address.port) {
|
if (packet.address.hostAddress == address.toHostString() && packet.port == address.port) {
|
||||||
val data = packet.data
|
val data = packet.data
|
||||||
if (data.size >= 3) {
|
if (data.size >= 3) {
|
||||||
if (data.size >= 100 && data[1] == 'L'.toByte() && data[2] == 'E'.toByte() && data[3] == 'D'.toByte()) {
|
if (data.size >= 100 && data[1] == 'L'.byte() && data[2] == 'E'.byte() && data[3] == 'D'.byte()) {
|
||||||
setLED(data)
|
setLED(data)
|
||||||
}
|
}
|
||||||
if (data.size >= 4 && data[1] == 'P'.toByte() && data[2] == 'O'.toByte() && data[3] == 'N'.toByte()) {
|
if (data.size >= 4 && data[1] == 'P'.byte() && data[2] == 'O'.byte() && data[3] == 'N'.byte()) {
|
||||||
val delay = calculateDelay(data)
|
val delay = calculateDelay(data)
|
||||||
if (delay > 0f)
|
if (delay > 0f)
|
||||||
mCurrentDelay = delay
|
mCurrentDelay = delay
|
||||||
|
@ -747,7 +767,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
val buffer = applyKeys(buttons, IoBuffer())
|
val buffer = applyKeys(buttons, IoBuffer())
|
||||||
try {
|
try {
|
||||||
mTCPSocket.getOutputStream().write(constructBuffer(buffer))
|
mTCPSocket.getOutputStream().write(constructBuffer(buffer))
|
||||||
if (enableNFC)
|
if (mEnableNFC)
|
||||||
mTCPSocket.getOutputStream().write(constructCardData())
|
mTCPSocket.getOutputStream().write(constructCardData())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
@ -780,7 +800,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
val packet = constructPacket(buffer)
|
val packet = constructPacket(buffer)
|
||||||
try {
|
try {
|
||||||
socket.send(packet)
|
socket.send(packet)
|
||||||
if (enableNFC)
|
if (mEnableNFC)
|
||||||
socket.send(constructCardPacket())
|
socket.send(constructCardPacket())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
@ -824,6 +844,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
enum class FunctionButton {
|
enum class FunctionButton {
|
||||||
UNDEFINED, FUNCTION_COIN, FUNCTION_CARD
|
UNDEFINED, FUNCTION_COIN, FUNCTION_CARD
|
||||||
}
|
}
|
||||||
|
@ -864,7 +885,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
val selfAddress = getLocalIPAddress()
|
val selfAddress = getLocalIPAddress()
|
||||||
if (selfAddress.isEmpty()) return@thread
|
if (selfAddress.isEmpty()) return@thread
|
||||||
val buffer = ByteArray(21)
|
val buffer = ByteArray(21)
|
||||||
byteArrayOf('C'.toByte(), 'O'.toByte(), 'N'.toByte()).copyInto(buffer, 1)
|
byteArrayOf('C'.byte(), 'O'.byte(), 'N'.byte()).copyInto(buffer, 1)
|
||||||
ByteBuffer.wrap(buffer)
|
ByteBuffer.wrap(buffer)
|
||||||
.put(4, if (selfAddress.size == 4) 1.toByte() else 2.toByte())
|
.put(4, if (selfAddress.size == 4) 1.toByte() else 2.toByte())
|
||||||
.putShort(5, serverPort.toShort())
|
.putShort(5, serverPort.toShort())
|
||||||
|
@ -887,7 +908,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
private fun sendDisconnect(address: InetSocketAddress?) {
|
private fun sendDisconnect(address: InetSocketAddress?) {
|
||||||
address ?: return
|
address ?: return
|
||||||
thread {
|
thread {
|
||||||
val buffer = byteArrayOf(3, 'D'.toByte(), 'I'.toByte(), 'S'.toByte())
|
val buffer = byteArrayOf(3, 'D'.byte(), 'I'.byte(), 'S'.byte())
|
||||||
if (mTCPMode) {
|
if (mTCPMode) {
|
||||||
try {
|
try {
|
||||||
mTCPSocket.getOutputStream().write(buffer)
|
mTCPSocket.getOutputStream().write(buffer)
|
||||||
|
@ -914,7 +935,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
private fun sendFunctionKey(address: InetSocketAddress?, function: FunctionButton) {
|
private fun sendFunctionKey(address: InetSocketAddress?, function: FunctionButton) {
|
||||||
address ?: return
|
address ?: return
|
||||||
thread {
|
thread {
|
||||||
val buffer = byteArrayOf(4, 'F'.toByte(), 'N'.toByte(), 'C'.toByte(), function.ordinal.toByte())
|
val buffer = byteArrayOf(4, 'F'.byte(), 'N'.byte(), 'C'.byte(), function.ordinal.toByte())
|
||||||
if (mTCPMode) {
|
if (mTCPMode) {
|
||||||
try {
|
try {
|
||||||
mTCPSocket.getOutputStream().write(buffer)
|
mTCPSocket.getOutputStream().write(buffer)
|
||||||
|
@ -944,7 +965,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
if (System.currentTimeMillis() - lastPingTime < pingInterval) return
|
if (System.currentTimeMillis() - lastPingTime < pingInterval) return
|
||||||
lastPingTime = System.currentTimeMillis()
|
lastPingTime = System.currentTimeMillis()
|
||||||
val buffer = ByteArray(12)
|
val buffer = ByteArray(12)
|
||||||
byteArrayOf(11, 'P'.toByte(), 'I'.toByte(), 'N'.toByte()).copyInto(buffer)
|
byteArrayOf(11, 'P'.byte(), 'I'.byte(), 'N'.byte()).copyInto(buffer)
|
||||||
ByteBuffer.wrap(buffer, 4, 8).putLong(SystemClock.elapsedRealtimeNanos())
|
ByteBuffer.wrap(buffer, 4, 8).putLong(SystemClock.elapsedRealtimeNanos())
|
||||||
try {
|
try {
|
||||||
val socket = DatagramSocket()
|
val socket = DatagramSocket()
|
||||||
|
@ -963,7 +984,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
if (System.currentTimeMillis() - lastPingTime < pingInterval) return
|
if (System.currentTimeMillis() - lastPingTime < pingInterval) return
|
||||||
lastPingTime = System.currentTimeMillis()
|
lastPingTime = System.currentTimeMillis()
|
||||||
val buffer = ByteArray(12)
|
val buffer = ByteArray(12)
|
||||||
byteArrayOf(11, 'P'.toByte(), 'I'.toByte(), 'N'.toByte()).copyInto(buffer)
|
byteArrayOf(11, 'P'.byte(), 'I'.byte(), 'N'.byte()).copyInto(buffer)
|
||||||
ByteBuffer.wrap(buffer, 4, 8).putLong(SystemClock.elapsedRealtimeNanos())
|
ByteBuffer.wrap(buffer, 4, 8).putLong(SystemClock.elapsedRealtimeNanos())
|
||||||
try {
|
try {
|
||||||
mTCPSocket.getOutputStream().write(buffer)
|
mTCPSocket.getOutputStream().write(buffer)
|
||||||
|
@ -1004,7 +1025,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private fun constructCardData(): ByteArray {
|
private fun constructCardData(): ByteArray {
|
||||||
val buf = ByteArray(24)
|
val buf = ByteArray(24)
|
||||||
byteArrayOf(15, 'C'.toByte(), 'R'.toByte(), 'D'.toByte()).copyInto(buf)
|
byteArrayOf(15, 'C'.byte(), 'R'.byte(), 'D'.byte()).copyInto(buf)
|
||||||
buf[4] = if (hasCard) 1 else 0
|
buf[4] = if (hasCard) 1 else 0
|
||||||
buf[5] = cardType.ordinal.toByte()
|
buf[5] = cardType.ordinal.toByte()
|
||||||
if (hasCard)
|
if (hasCard)
|
||||||
|
@ -1024,10 +1045,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
return buffer.apply {
|
return buffer.apply {
|
||||||
if (mEnableAir) {
|
if (mEnableAir) {
|
||||||
buffer.length = 47
|
buffer.length = 47
|
||||||
buffer.header = byteArrayOf('I'.toByte(), 'N'.toByte(), 'P'.toByte())
|
buffer.header = byteArrayOf('I'.byte(), 'N'.byte(), 'P'.byte())
|
||||||
} else {
|
} else {
|
||||||
buffer.length = 41
|
buffer.length = 41
|
||||||
buffer.header = byteArrayOf('I'.toByte(), 'P'.toByte(), 'T'.toByte())
|
buffer.header = byteArrayOf('I'.byte(), 'P'.byte(), 'T'.byte())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.keys != null && event.keys.isNotEmpty()) {
|
if (event.keys != null && event.keys.isNotEmpty()) {
|
||||||
|
@ -1076,14 +1097,12 @@ class MainActivity : AppCompatActivity() {
|
||||||
else -> continue
|
else -> continue
|
||||||
}
|
}
|
||||||
val right = left + width
|
val right = left + width
|
||||||
mLEDCanvas.drawRect(left, 0f, right, drawHeight.toFloat(), makePaint(color.toInt()))
|
mLEDCanvas.drawRect(left, 0f, right, drawHeight.toFloat(), color.toPaint())
|
||||||
drawXOffset += width
|
drawXOffset += width
|
||||||
}
|
}
|
||||||
mButtonRenderer.postInvalidate()
|
mButtonRenderer.postInvalidate()
|
||||||
}
|
}
|
||||||
private fun makePaint(color: Int): Paint {
|
private fun Long.toPaint(): Paint = Paint().apply { color = toInt() }
|
||||||
return Paint().apply { this.color = color }
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "Brokenithm"
|
private const val TAG = "Brokenithm"
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.github.brokenithm.activity
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import com.github.brokenithm.R
|
||||||
|
import com.github.brokenithm.fragment.SettingsFragment
|
||||||
|
|
||||||
|
class SettingsActivity : FragmentActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_settings)
|
||||||
|
supportFragmentManager.beginTransaction().replace(R.id.settings_container, SettingsFragment()).commit()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.github.brokenithm.fragment
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.InputType
|
||||||
|
import android.widget.EditText
|
||||||
|
import androidx.preference.EditTextPreference
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import com.github.brokenithm.R
|
||||||
|
|
||||||
|
class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
preferenceManager.sharedPreferencesName = "settings"
|
||||||
|
setPreferencesFromResource(R.xml.preferences, rootKey)
|
||||||
|
val setDecimalEdit = { editText: EditText -> editText.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL }
|
||||||
|
val entries = listOf("fat_touch_threshold", "extra_fat_touch_threshold", "gyro_air_lowest", "gyro_air_highest", "accel_air_threshold")
|
||||||
|
for (entry in entries)
|
||||||
|
findPreference<EditTextPreference>(entry)?.setOnBindEditTextListener(setDecimalEdit)
|
||||||
|
}
|
||||||
|
}
|
|
@ -110,18 +110,6 @@
|
||||||
app:layout_constraintStart_toEndOf="@+id/button_coin"
|
app:layout_constraintStart_toEndOf="@+id/button_coin"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/check_enable_air"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:text="@string/enable_air"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/button_card"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_switch_air"
|
android:id="@+id/text_switch_air"
|
||||||
android:layout_width="90dp"
|
android:layout_width="90dp"
|
||||||
|
@ -215,25 +203,15 @@
|
||||||
app:layout_constraintStart_toEndOf="@+id/button_service"
|
app:layout_constraintStart_toEndOf="@+id/button_service"
|
||||||
app:layout_constraintTop_toTopOf="@+id/button_service" />
|
app:layout_constraintTop_toTopOf="@+id/button_service" />
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/check_vibrate"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:text="@string/enable_vibration"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/check_show_delay"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/check_show_delay" />
|
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/check_simple_air"
|
android:id="@+id/check_simple_air"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:text="@string/simple_air"
|
android:text="@string/simple_air"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
app:layout_constraintStart_toEndOf="@+id/check_vibrate"
|
app:layout_constraintBottom_toBottomOf="@+id/check_show_delay"
|
||||||
app:layout_constraintTop_toTopOf="@+id/check_vibrate" />
|
app:layout_constraintStart_toEndOf="@+id/check_show_delay"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/check_show_delay" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_mode"
|
android:id="@+id/text_mode"
|
||||||
|
@ -253,6 +231,16 @@
|
||||||
app:layout_constraintStart_toEndOf="@+id/check_simple_air"
|
app:layout_constraintStart_toEndOf="@+id/check_simple_air"
|
||||||
app:layout_constraintTop_toTopOf="@+id/check_simple_air" />
|
app:layout_constraintTop_toTopOf="@+id/check_simple_air" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_settings"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="@string/settings"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/text_mode"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/text_mode"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/text_mode" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</net.cachapa.expandablelayout.ExpandableLayout>
|
</net.cachapa.expandablelayout.ExpandableLayout>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/layout_top"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="#202020"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_title2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:text="Brokenithm-Evolved Settings"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/settings_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/layout_top">
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -27,4 +27,14 @@
|
||||||
<string name="accel_air">Accel Air</string>
|
<string name="accel_air">Accel Air</string>
|
||||||
<string name="touch_air">Touch Air</string>
|
<string name="touch_air">Touch Air</string>
|
||||||
<string name="enable_air">Enable Air</string>
|
<string name="enable_air">Enable Air</string>
|
||||||
|
|
||||||
|
<string name="settings">Settings</string>
|
||||||
|
<string name="gyro_air_highest">Gyro Air Highest Bound</string>
|
||||||
|
<string name="accel_air_threshold">Accel Air Threshold</string>
|
||||||
|
<string name="gyro_air_lowest">Gyro Air Lowest Bound</string>
|
||||||
|
<string name="extra_fat_touch_threshold">Extra Fat Touch Threshold</string>
|
||||||
|
<string name="fat_touch_threshold">Fat Touch Threshold</string>
|
||||||
|
<string name="enable_touch_size">Enable Touch Size Check</string>
|
||||||
|
<string name="enable_nfc">Enable NFC</string>
|
||||||
|
<string name="enable_vibrate">Enable Vibration</string>
|
||||||
</resources>
|
</resources>
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="Common">
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="enable_vibrate"
|
||||||
|
android:title="@string/enable_vibrate" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="enable_nfc"
|
||||||
|
android:title="@string/enable_nfc" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
<PreferenceCategory android:title="Touch Judge">
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="enable_touch_size"
|
||||||
|
android:title="@string/enable_touch_size" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="0.027"
|
||||||
|
android:key="fat_touch_threshold"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:title="@string/fat_touch_threshold" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="0.035"
|
||||||
|
android:key="extra_fat_touch_threshold"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:title="@string/extra_fat_touch_threshold" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
<PreferenceCategory android:title="Sensor">
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="0.8"
|
||||||
|
android:key="gyro_air_lowest"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:title="@string/gyro_air_lowest" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="1.35"
|
||||||
|
android:key="gyro_air_highest"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:title="@string/gyro_air_highest" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="2.0"
|
||||||
|
android:key="accel_air_threshold"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:title="@string/accel_air_threshold" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
</PreferenceScreen>
|
|
@ -1,12 +1,12 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = "1.4.30"
|
ext.kotlin_version = "1.5.21"
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "com.android.tools.build:gradle:4.1.2"
|
classpath 'com.android.tools.build:gradle:4.2.2'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||||
|
|
Loading…
Reference in New Issue