From 392bbeb996743d259e87b9c1e46acdfb1a67e04a Mon Sep 17 00:00:00 2001 From: ml Date: Sat, 13 Jun 2026 14:28:58 +0200 Subject: [PATCH] Rework UI with drawer menu, hero disks, and sound toggle --- .../MainActivity.kt | 173 ++++++++- .../app/src/main/res/layout/activity_main.xml | 351 +++++++++++------- .../res/splash-screen.jpeg | Bin 0 -> 111055 bytes .../res/splash-screen.png | Bin 0 -> 284399 bytes 4 files changed, 379 insertions(+), 145 deletions(-) create mode 100644 SchwertUndMagieOnPebbleCompanionApp/res/splash-screen.jpeg create mode 100644 SchwertUndMagieOnPebbleCompanionApp/res/splash-screen.png diff --git a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt index 3d96f19..ba0a39b 100644 --- a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt +++ b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt @@ -11,9 +11,15 @@ import android.util.Log import android.widget.Button import android.widget.ScrollView import android.widget.TextView +import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.GravityCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.drawerlayout.widget.DrawerLayout import fi.iki.elonen.NanoHTTPD import java.io.File import java.text.SimpleDateFormat @@ -23,9 +29,13 @@ import java.util.Locale private const val PORT = 8888 private const val TAG = "SuM" -private data class DiskSlot(val episode: Int, val part: Char, val btnId: Int) { - val fileName: String get() = "SCHWUM${episode}${part}.D64" -} +private data class DiskSlot( + val episode: Int, + val part: Char, + val btnId: Int, + val label: String, + val fileName: String = "SCHWUM${episode}${part}.D64" +) class MainActivity : AppCompatActivity() { @@ -39,6 +49,8 @@ class MainActivity : AppCompatActivity() { private val mainHandler = Handler(Looper.getMainLooper()) private val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) + private lateinit var drawerLayout: DrawerLayout + private var server: CompanionServer? = null private val engine = C64Engine() private var emuThread: Thread? = null @@ -48,12 +60,20 @@ class MainActivity : AppCompatActivity() { // ---- disk slots --------------------------------------------------------- private val diskSlots = listOf( - DiskSlot(1, 'A', R.id.btn_ep_1a), DiskSlot(1, 'B', R.id.btn_ep_1b), - DiskSlot(2, 'A', R.id.btn_ep_2a), DiskSlot(2, 'B', R.id.btn_ep_2b), - DiskSlot(3, 'A', R.id.btn_ep_3a), DiskSlot(3, 'B', R.id.btn_ep_3b), - DiskSlot(4, 'A', R.id.btn_ep_4a), DiskSlot(4, 'B', R.id.btn_ep_4b), + DiskSlot(1, 'A', R.id.btn_ep_1a, "Folge 1: Das geheimnisvolle Kraut"), + DiskSlot(1, 'B', R.id.btn_ep_1b, "Folge 2: Der unheimliche Tempel"), + DiskSlot(2, 'A', R.id.btn_ep_2a, "Folge 3: Das Piratenhaus"), + DiskSlot(2, 'B', R.id.btn_ep_2b, "Folge 4: Die Burg des Magiers"), + DiskSlot(3, 'A', R.id.btn_ep_3a, "Folge 5: Das Haus des Vampirs"), + DiskSlot(3, 'B', R.id.btn_ep_3b, "Folge 6: Der Turm des Todes"), + DiskSlot(4, 'A', R.id.btn_ep_4a, "Folge 7: Unter Wasser"), + DiskSlot(4, 'B', R.id.btn_ep_4b, "Folge 8: Insel der Wunder"), + DiskSlot(0, ' ', R.id.btn_hero_1, "Held 1", "HELD1.D64"), + DiskSlot(0, ' ', R.id.btn_hero_2, "Held 2", "HELD2.D64"), + DiskSlot(0, ' ', R.id.btn_hero_3, "Held 3", "HELD3.D64"), ) private val episodeButtons = mutableMapOf() + private val loadedADisks = mutableSetOf() // ---- Disk import (multi-select) ----------------------------------------- @@ -83,6 +103,18 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + drawerLayout = findViewById(R.id.drawer_layout) + + // On Android 15+ the app draws behind the status bar (edge-to-edge enforced). + // Shift the main content down by the actual status bar height so the + // hamburger button isn't hidden underneath it. + val mainContent = findViewById(R.id.main_content) + ViewCompat.setOnApplyWindowInsetsListener(mainContent) { view, insets -> + val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + val pad8 = (8 * resources.displayMetrics.density).toInt() + view.setPadding(pad8, bars.top + pad8, pad8, pad8) + insets + } tvStatus = findViewById(R.id.tv_status) tvTime = findViewById(R.id.tv_time) tvLog = findViewById(R.id.tv_log) @@ -90,6 +122,13 @@ class MainActivity : AppCompatActivity() { display = findViewById(R.id.c64_display) keyboard = findViewById(R.id.c64_keyboard) + findViewById