From a3142ea85be7e090184843ce33b3902e014946ac Mon Sep 17 00:00:00 2001 From: eddy Date: Wed, 29 Jul 2026 20:25:27 +0200 Subject: [PATCH] Add user-defined button labels with color change on press - PrefsHelper: PREF_LABEL1, PREF_LABEL2 constants - SettingsActivity: EditText fields with Done-keyboard action to save labels - MainActivity: buttons show user label, colorAccent on press, textAllCaps disabled - activity_main.xml: textAllCaps=false for case-sensitive labels --- .../java/com/eddy/atomrelay/MainActivity.kt | 34 +++++++++++---- .../java/com/eddy/atomrelay/PrefsHelper.kt | 2 + .../com/eddy/atomrelay/SettingsActivity.kt | 31 +++++++++++++ .../app/src/main/res/layout/activity_main.xml | 2 + .../src/main/res/layout/activity_settings.xml | 43 +++++++++++++++++++ android/app/src/main/res/values/strings.xml | 5 +++ 6 files changed, 109 insertions(+), 8 deletions(-) diff --git a/android/app/src/main/java/com/eddy/atomrelay/MainActivity.kt b/android/app/src/main/java/com/eddy/atomrelay/MainActivity.kt index ed7e259..055cf5b 100644 --- a/android/app/src/main/java/com/eddy/atomrelay/MainActivity.kt +++ b/android/app/src/main/java/com/eddy/atomrelay/MainActivity.kt @@ -3,6 +3,7 @@ package com.eddy.atomrelay import android.content.Intent import android.content.pm.PackageManager +import android.content.res.ColorStateList import android.os.Bundle import android.os.Handler import android.os.Looper @@ -12,6 +13,7 @@ import android.widget.ImageButton import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat class MainActivity : AppCompatActivity(), BleCallbacks { @@ -28,6 +30,8 @@ class MainActivity : AppCompatActivity(), BleCallbacks { private lateinit var relay1Button: Button private lateinit var relay2Button: Button private var lastTheme: String? = null + private var originalTint1: ColorStateList? = null + private var originalTint2: ColorStateList? = null override fun onStatusChanged(status: BleStatus) { when (status) { @@ -61,8 +65,8 @@ class MainActivity : AppCompatActivity(), BleCallbacks { relay2Button.setOnTouchListener(null) relay1Button.setOnClickListener(null) relay2Button.setOnClickListener(null) - relay1Button.text = getString(R.string.button_retry_scan) - relay2Button.text = getString(R.string.button_hold) + loadButtonLabel(relay1Button, PrefsHelper.PREF_LABEL1, R.string.button_retry_scan) + loadButtonLabel(relay2Button, PrefsHelper.PREF_LABEL2, R.string.button_hold) relay2Button.isEnabled = false relay1Button.isEnabled = true relay1Button.setOnClickListener { @@ -113,6 +117,8 @@ class MainActivity : AppCompatActivity(), BleCallbacks { recreate() return } + loadButtonLabel(relay1Button, PrefsHelper.PREF_LABEL1, R.string.button_hold) + loadButtonLabel(relay2Button, PrefsHelper.PREF_LABEL2, R.string.button_hold) if (!manager.hasPermissions()) { requestPermissions() return @@ -142,17 +148,20 @@ class MainActivity : AppCompatActivity(), BleCallbacks { private fun setupRelayButton() { relay1Button.setOnClickListener(null) - relay1Button.text = getString(R.string.button_hold) + loadButtonLabel(relay1Button, PrefsHelper.PREF_LABEL1, R.string.button_hold) + originalTint1 = relay1Button.backgroundTintList + + val accentColor = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.colorAccent)) relay1Button.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { manager.sendRelayCommand(0x01.toByte()) - relay1Button.text = getString(R.string.button_on) + relay1Button.backgroundTintList = accentColor true } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { manager.sendRelayCommand(0x00.toByte()) - relay1Button.text = getString(R.string.button_hold) + relay1Button.backgroundTintList = originalTint1 true } else -> false @@ -162,17 +171,20 @@ class MainActivity : AppCompatActivity(), BleCallbacks { private fun setupRelay2Button() { relay2Button.setOnClickListener(null) - relay2Button.text = getString(R.string.button_hold) + loadButtonLabel(relay2Button, PrefsHelper.PREF_LABEL2, R.string.button_hold) + originalTint2 = relay2Button.backgroundTintList + + val accentColor = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.colorAccent)) relay2Button.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { manager.sendRelayCommand(0x02.toByte()) - relay2Button.text = getString(R.string.button_on) + relay2Button.backgroundTintList = accentColor true } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { manager.sendRelayCommand(0x03.toByte()) - relay2Button.text = getString(R.string.button_hold) + relay2Button.backgroundTintList = originalTint2 true } else -> false @@ -180,6 +192,12 @@ class MainActivity : AppCompatActivity(), BleCallbacks { } } + private fun loadButtonLabel(button: Button, prefKey: String, fallbackResId: Int) { + val prefs = PrefsHelper.getPrefs(this) + val label = prefs.getString(prefKey, "")?.trim() + button.text = if (label.isNullOrEmpty()) getString(fallbackResId) else label + } + private fun requestPermissions() { val perms = manager.getRequiredPermissions() ActivityCompat.requestPermissions(this, perms, 1) diff --git a/android/app/src/main/java/com/eddy/atomrelay/PrefsHelper.kt b/android/app/src/main/java/com/eddy/atomrelay/PrefsHelper.kt index 3e759b4..31147f9 100644 --- a/android/app/src/main/java/com/eddy/atomrelay/PrefsHelper.kt +++ b/android/app/src/main/java/com/eddy/atomrelay/PrefsHelper.kt @@ -13,6 +13,8 @@ object PrefsHelper { const val PREF_UUID = "device_uuid" const val PREF_SEQ = "seq_counter" const val PREF_THEME = "theme" + const val PREF_LABEL1 = "label_relay1" + const val PREF_LABEL2 = "label_relay2" const val SEQ_MAX = 1_000_000 fun applyTheme(context: Context) { diff --git a/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt b/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt index 50fc1f9..7380b34 100644 --- a/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt +++ b/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt @@ -17,8 +17,11 @@ import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager import android.widget.Button import android.widget.CheckBox +import android.widget.EditText import android.widget.ProgressBar import android.widget.RadioGroup import android.widget.TextView @@ -136,6 +139,7 @@ class SettingsActivity : AppCompatActivity() { registerReceiver(usbDetachedReceiver, IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED), Context.RECEIVER_EXPORTED) setupThemeButtons() + setupLabelEditTexts() } override fun onResume() { @@ -200,6 +204,33 @@ class SettingsActivity : AppCompatActivity() { return true } + private fun setupLabelEditTexts() { + val prefs = PrefsHelper.getPrefs(this) + val label1 = findViewById(R.id.labelRelay1) + val label2 = findViewById(R.id.labelRelay2) + val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + + label1.setText(prefs.getString(PrefsHelper.PREF_LABEL1, "")) + label2.setText(prefs.getString(PrefsHelper.PREF_LABEL2, "")) + + label1.setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_DONE) { + prefs.edit().putString(PrefsHelper.PREF_LABEL1, label1.text.toString().trim()).apply() + imm.hideSoftInputFromWindow(label1.windowToken, 0) + label1.clearFocus() + } + false + } + label2.setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_DONE) { + prefs.edit().putString(PrefsHelper.PREF_LABEL2, label2.text.toString().trim()).apply() + imm.hideSoftInputFromWindow(label2.windowToken, 0) + label2.clearFocus() + } + false + } + } + // === Key Exchange === private fun startKeyExchange() { diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml index 419c6e7..50ac9ab 100644 --- a/android/app/src/main/res/layout/activity_main.xml +++ b/android/app/src/main/res/layout/activity_main.xml @@ -26,6 +26,7 @@ android:layout_height="200dp" android:text="1" android:textSize="24sp" + android:textAllCaps="false" android:enabled="false" />