From 19fbed0ef244699eb288ac62087a83dc6a4c48ab Mon Sep 17 00:00:00 2001 From: Nacho Date: Sun, 5 Jan 2025 17:38:12 +0100 Subject: [PATCH 1/3] More things! - Started slowly implementing the original model. - Names are bitmaps, so we use that. - Sprites are stored in RoomDB as bitmap. - Can now import DiMs, need to implement BEms. - Can also view all the sprites for all the DiMs and now you can view DiMs individually (these two are temporary). Things to do next - Use the new model when uploading characters from the watch. - Figure out why my implementation of ABGR to BGRA isn't working (or something like that) - Improve data retrieval from the database, maybe using flows and properly implemented view models. As of now the interface is quite flickery. - Improve code that handles DiMs and BEms. As for bugs - Interface sometimes likes flickering a lot, need to figure out why - I cannot for the life of me create transparent bitmaps... help! - Something else I might be forgetting... Going to continue working in this branch. --- .../github/nacabaro/vbhelper/MainActivity.kt | 124 +++++++++++++++++- .../vbhelper/components/CharacterEntry.kt | 52 ++++++++ .../vbhelper/components/StorageEntry.kt | 64 +++++++++ .../nacabaro/vbhelper/components/TopBanner.kt | 2 +- .../nacabaro/vbhelper/daos/CharacterDao.kt | 26 ++++ .../github/nacabaro/vbhelper/daos/DiMDao.kt | 6 +- .../nacabaro/vbhelper/database/AppDatabase.kt | 13 +- .../vbhelper/domain/{Mon.kt => Character.kt} | 13 +- .../github/nacabaro/vbhelper/domain/Dim.kt | 4 + .../nacabaro/vbhelper/domain/Evolutions.kt | 4 +- .../nacabaro/vbhelper/domain/Sprites.kt | 12 ++ .../nacabaro/vbhelper/domain/UserMonsters.kt | 2 +- .../vbhelper/navigation/AppNavigation.kt | 24 +++- .../vbhelper/navigation/BottomNavItem.kt | 2 + .../nacabaro/vbhelper/screens/DexScreen.kt | 76 +++++++++-- .../nacabaro/vbhelper/screens/DimScreen.kt | 82 ++++++++++++ .../vbhelper/screens/SettingsScreen.kt | 9 +- .../nacabaro/vbhelper/screens/SpriteViewer.kt | 89 +++++++++++++ .../vbhelper/screens/StorageScreen.kt | 36 +---- .../nacabaro/vbhelper/source/DexRepository.kt | 18 +++ .../nacabaro/vbhelper/source/SpriteRepo.kt | 12 ++ .../main/res/drawable/baseline_image_24.xml | 5 + 22 files changed, 605 insertions(+), 70 deletions(-) create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/components/StorageEntry.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt rename app/src/main/java/com/github/nacabaro/vbhelper/domain/{Mon.kt => Character.kt} (68%) create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/domain/Sprites.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/screens/SpriteViewer.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/source/SpriteRepo.kt create mode 100644 app/src/main/res/drawable/baseline_image_24.xml diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt b/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt index f262ee2..c0f6d21 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt @@ -10,25 +10,31 @@ import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.lifecycleScope +import com.github.cfogrady.vb.dim.card.DimReader import com.github.nacabaro.vbhelper.navigation.AppNavigation import com.github.cfogrady.vbnfc.CryptographicTransformer -import com.github.cfogrady.vbnfc.R import com.github.cfogrady.vbnfc.TagCommunicator import com.github.cfogrady.vbnfc.be.BENfcCharacter import com.github.cfogrady.vbnfc.data.DeviceType import com.github.cfogrady.vbnfc.data.NfcCharacter import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.domain.Dim +import com.github.nacabaro.vbhelper.domain.Sprites +import com.github.nacabaro.vbhelper.domain.Character import com.github.nacabaro.vbhelper.temporary_domain.TemporaryBECharacterData import com.github.nacabaro.vbhelper.temporary_domain.TemporaryCharacterData import com.github.nacabaro.vbhelper.temporary_domain.TemporaryTransformationHistory import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { private lateinit var nfcAdapter: NfcAdapter @@ -36,10 +42,14 @@ class MainActivity : ComponentActivity() { private var nfcCharacter = MutableStateFlow(null) + private lateinit var activityResultLauncher: ActivityResultLauncher + // EXTRACTED DIRECTLY FROM EXAMPLE APP override fun onCreate(savedInstanceState: Bundle?) { deviceToCryptographicTransformers = getMapOfCryptographicTransformers() + registerFileActivityResult() + val maybeNfcAdapter = NfcAdapter.getDefaultAdapter(this) if (maybeNfcAdapter == null) { Toast.makeText(this, "No NFC on device!", Toast.LENGTH_SHORT).show() @@ -57,11 +67,109 @@ class MainActivity : ComponentActivity() { } } + private fun registerFileActivityResult() { + activityResultLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + lifecycleScope.launch { + if (it.resultCode != RESULT_OK) { + Toast.makeText(applicationContext, "Import operation cancelled.", Toast.LENGTH_SHORT).show() + } + val contentResolver = applicationContext.contentResolver + val inputStream = contentResolver.openInputStream(it.data!!.data!!) + inputStream.use { fileReader -> + val dimReader = DimReader() + val card = dimReader.readCard(fileReader, false) + val dimModel = Dim( + id = card.header.dimId, + logo = card.spriteData.sprites[0].pixelData, + name = card.spriteData.text, // TODO Make user write card name + stageCount = card.adventureLevels.levels.size, + logoHeight = card.spriteData.sprites[0].height, + logoWidth = card.spriteData.sprites[0].width + ) + val application = applicationContext as VBHelper + val storageRepository = application.container.db + storageRepository.dimDao().insertNewDim(dimModel) + + val characters = card.characterStats.characterEntries + + /* + Confusing math for me ahead + sprite[0] logo + sprite[10] name + sprite[10 + 1] character_1 + sprite[10 + 2] character_2 + sprite[16] name 1 + sprite[17] character_1 + sprite[18] character_2 + sprite[23] name 2 + sprite[24] character_1 + sprite[25] character_2 + sprite[23 + 12 + 1] name 3 + sprite[23 + 12 + 2] character_1 + sprite[23 + 12 + 3] character_2 + */ + + var spriteCounter = 10 + var domainCharacters = mutableListOf() + + for (index in 0 until characters.size) { + domainCharacters.add( + Character( + id = 0, + dimId = card.header.dimId, + monIndex = index, + name = card.spriteData.sprites[spriteCounter].pixelData, + stage = characters[index].stage, + attribute = characters[index].attribute, + baseHp = characters[index].hp, + baseBp = characters[index].dp, + baseAp = characters[index].ap, + sprite1 = card.spriteData.sprites[spriteCounter + 1].pixelData, + sprite2 = card.spriteData.sprites[spriteCounter + 2].pixelData, + nameWidth = card.spriteData.sprites[spriteCounter].width, + nameHeight = card.spriteData.sprites[spriteCounter].height, + spritesWidth = card.spriteData.sprites[spriteCounter + 1].width, + spritesHeight = card.spriteData.sprites[spriteCounter + 1].height + ) + ) + + if (index == 0) { + spriteCounter += 6 + } else if (index == 1) { + spriteCounter += 7 + } else { + spriteCounter += 14 + } + } + + storageRepository + .characterDao() + .insertCharacter(*domainCharacters.toTypedArray()) + + val sprites = card.spriteData.sprites.map { sprite -> + Sprites( + id = 0, + sprite = sprite.pixelData, + width = sprite.width, + height = sprite.height + ) + } + storageRepository + .characterDao() + .insertSprite(*sprites.toTypedArray()) + } + inputStream?.close() + Toast.makeText(applicationContext, "Import successful!", Toast.LENGTH_SHORT).show() + } + } + } + @Composable private fun MainApplication() { var isDoneReadingCharacter by remember { mutableStateOf(false) } - val application = LocalContext.current.applicationContext as VBHelper - val storageRepository = application.container.db + AppNavigation( isDoneReadingCharacter = isDoneReadingCharacter, onClickRead = { @@ -75,6 +183,13 @@ class MainActivity : ComponentActivity() { }, onClickScan = { isDoneReadingCharacter = false + }, + onClickImportCard = { + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = "*/*" + } + activityResultLauncher.launch(intent) } ) } @@ -160,6 +275,7 @@ class MainActivity : ComponentActivity() { */ private fun addCharacterScannedIntoDatabase() { val beCharacter = nfcCharacter as MutableStateFlow + val temporaryCharacterData = TemporaryCharacterData( dimId = nfcCharacter.value!!.dimId.toInt(), charIndex = nfcCharacter.value!!.charIndex.toInt(), diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt b/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt new file mode 100644 index 0000000..e644947 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt @@ -0,0 +1,52 @@ +package com.github.nacabaro.vbhelper.components + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Card +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp + +@Composable +fun CharacterEntry( + name: ImageBitmap, + icon: ImageBitmap, + modifier: Modifier = Modifier, + onClick: () -> Unit = { } +) { + Card( + shape = MaterialTheme.shapes.medium, + onClick = onClick, + modifier = modifier + .padding(8.dp) + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxSize() + ) { + Image( + bitmap = icon, + contentDescription = "Icon", + modifier = Modifier + .padding(8.dp) + .size(64.dp) + ) + Image( + bitmap = name, + contentDescription = "Name", + modifier = Modifier + .padding(8.dp) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/StorageEntry.kt b/app/src/main/java/com/github/nacabaro/vbhelper/components/StorageEntry.kt new file mode 100644 index 0000000..a5cf0ab --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/components/StorageEntry.kt @@ -0,0 +1,64 @@ +package com.github.nacabaro.vbhelper.components + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Card +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp + +@Composable +fun StorageEntry( + name: String, + nameBitmap: ImageBitmap? = null, + modifier: Modifier = Modifier, + icon: Int? = null, + bitmap: ImageBitmap? = null, + onClick: () -> Unit = { } +) { + Card( + shape = MaterialTheme.shapes.medium, + onClick = onClick, + modifier = modifier + .padding(8.dp) + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxSize() + ) { + if (bitmap != null) { + Image( + bitmap = bitmap, + contentDescription = name, + modifier = Modifier + .padding(8.dp) + .size(64.dp) + ) + } else if (icon != null) { + Image( + painter = painterResource(id = icon), + contentDescription = name, + modifier = Modifier + .padding(8.dp) + .size(64.dp) + ) + } + Text( + text = name, + textAlign = TextAlign.Center, + modifier = Modifier + .padding(8.dp) + ) + } + } +} diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt b/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt index 19e1e64..03f1efd 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt @@ -20,7 +20,7 @@ fun TopBanner( text: String, modifier: Modifier = Modifier, onGearClick: (() -> Unit)? = null, - onBackClick: (() -> Unit)? = null + onBackClick: (() -> Unit)? = null, ) { Box( // Use Box to overlay elements modifier = modifier diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt new file mode 100644 index 0000000..4c689f6 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt @@ -0,0 +1,26 @@ +package com.github.nacabaro.vbhelper.daos + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import com.github.nacabaro.vbhelper.domain.Character +import com.github.nacabaro.vbhelper.domain.Sprites +import org.w3c.dom.CharacterData + +@Dao +interface CharacterDao { + @Insert + suspend fun insertCharacter(vararg characterData: Character) + + @Query("SELECT * FROM Character") + suspend fun getAllCharacters(): List + + @Query("SELECT * FROM Character WHERE dimId = :dimId") + suspend fun getCharacterByDimId(dimId: Int): List + + @Insert + suspend fun insertSprite(vararg sprite: Sprites) + + @Query("SELECT * FROM Sprites") + suspend fun getAllSprites(): List +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt index a2e7d84..9d87be4 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt @@ -2,15 +2,15 @@ package com.github.nacabaro.vbhelper.daos import androidx.room.Dao import androidx.room.Insert +import androidx.room.OnConflictStrategy import androidx.room.Query import com.github.nacabaro.vbhelper.domain.Dim -import kotlinx.coroutines.flow.Flow @Dao interface DiMDao { - @Insert + @Insert(onConflict = OnConflictStrategy.IGNORE) suspend fun insertNewDim(dim: Dim) @Query("SELECT * FROM Dim") - fun getAllDims(): Flow> + suspend fun getAllDims(): List } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt index c143009..eae83d6 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt @@ -2,6 +2,11 @@ package com.github.nacabaro.vbhelper.database import androidx.room.Database import androidx.room.RoomDatabase +import com.github.nacabaro.vbhelper.daos.CharacterDao +import com.github.nacabaro.vbhelper.daos.DiMDao +import com.github.nacabaro.vbhelper.domain.Character +import com.github.nacabaro.vbhelper.domain.Dim +import com.github.nacabaro.vbhelper.domain.Sprites import com.github.nacabaro.vbhelper.temporary_daos.TemporaryMonsterDao import com.github.nacabaro.vbhelper.temporary_domain.TemporaryBECharacterData import com.github.nacabaro.vbhelper.temporary_domain.TemporaryCharacterData @@ -12,10 +17,14 @@ import com.github.nacabaro.vbhelper.temporary_domain.TemporaryTransformationHist entities = [ TemporaryCharacterData::class, TemporaryBECharacterData::class, - TemporaryTransformationHistory::class + TemporaryTransformationHistory::class, + Dim::class, + Character::class, + Sprites::class ] ) abstract class AppDatabase : RoomDatabase() { abstract fun temporaryMonsterDao(): TemporaryMonsterDao - + abstract fun dimDao(): DiMDao + abstract fun characterDao(): CharacterDao } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/Mon.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Character.kt similarity index 68% rename from app/src/main/java/com/github/nacabaro/vbhelper/domain/Mon.kt rename to app/src/main/java/com/github/nacabaro/vbhelper/domain/Character.kt index b600adc..9292978 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/Mon.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Character.kt @@ -14,15 +14,20 @@ import androidx.room.ForeignKey ) ] ) -data class Mon ( - @PrimaryKey val id: Int, +data class Character ( + @PrimaryKey(autoGenerate = true) val id: Long, val dimId: Int, val monIndex: Int, - val name: String, + val name: ByteArray, val stage: Int, // These should be replaced with enums val attribute: Int, // This one too val baseHp: Int, val baseBp: Int, val baseAp: Int, - val evoTime: Int, // In minutes + val sprite1: ByteArray, + val sprite2: ByteArray, + val nameWidth: Int, + val nameHeight: Int, + val spritesWidth: Int, + val spritesHeight: Int ) \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/Dim.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Dim.kt index 199a248..cd4df43 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/Dim.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Dim.kt @@ -1,5 +1,6 @@ package com.github.nacabaro.vbhelper.domain +import android.icu.text.ListFormatter.Width import androidx.room.Entity import androidx.room.PrimaryKey @@ -7,6 +8,9 @@ import androidx.room.PrimaryKey data class Dim( @PrimaryKey(autoGenerate = true) val id: Int, + val logo: ByteArray, + val logoWidth: Int, + val logoHeight: Int, val name: String, val stageCount: Int ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/Evolutions.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Evolutions.kt index 58c9163..ba4583e 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/Evolutions.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Evolutions.kt @@ -7,13 +7,13 @@ import androidx.room.PrimaryKey @Entity( foreignKeys = [ ForeignKey( - entity = Mon::class, + entity = Character::class, parentColumns = ["id"], childColumns = ["monId"], onDelete = ForeignKey.CASCADE ), ForeignKey( - entity = Mon::class, + entity = Character::class, parentColumns = ["id"], childColumns = ["nextMon"], onDelete = ForeignKey.CASCADE diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/Sprites.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Sprites.kt new file mode 100644 index 0000000..cf4de84 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/Sprites.kt @@ -0,0 +1,12 @@ +package com.github.nacabaro.vbhelper.domain + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity +data class Sprites( + @PrimaryKey(autoGenerate = true) val id : Int, + val sprite: ByteArray, + val width: Int, + val height: Int +) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/UserMonsters.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/UserMonsters.kt index c4c2270..df1aee5 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/UserMonsters.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/UserMonsters.kt @@ -13,7 +13,7 @@ import androidx.room.PrimaryKey onDelete = ForeignKey.CASCADE ), ForeignKey( - entity = Mon::class, + entity = Character::class, parentColumns = ["id"], childColumns = ["monId"], onDelete = ForeignKey.CASCADE diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt index 0371b5e..9b8e89e 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt @@ -1,5 +1,6 @@ package com.github.nacabaro.vbhelper.navigation +import android.util.Log import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable @@ -9,15 +10,18 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.github.nacabaro.vbhelper.screens.BattlesScreen import com.github.nacabaro.vbhelper.screens.DexScreen +import com.github.nacabaro.vbhelper.screens.DiMScreen import com.github.nacabaro.vbhelper.screens.HomeScreen import com.github.nacabaro.vbhelper.screens.ScanScreen import com.github.nacabaro.vbhelper.screens.SettingsScreen +import com.github.nacabaro.vbhelper.screens.SpriteViewer import com.github.nacabaro.vbhelper.screens.StorageScreen @Composable fun AppNavigation( onClickRead: () -> Unit, onClickScan: () -> Unit, + onClickImportCard: () -> Unit, isDoneReadingCharacter: Boolean ) { val navController = rememberNavController() @@ -53,13 +57,31 @@ fun AppNavigation( ) } composable(BottomNavItem.Dex.route) { - DexScreen() + DexScreen( + navController = navController + ) } composable(BottomNavItem.Settings.route) { SettingsScreen( + navController = navController, + onClickImportCard = onClickImportCard + ) + } + composable(BottomNavItem.Viewer.route) { + SpriteViewer( navController = navController ) } + composable(BottomNavItem.CardView.route) { + val dimId = it.arguments?.getString("dimId") + Log.d("dimId", dimId.toString()) + if (dimId != null) { + DiMScreen( + navController = navController, + dimId = dimId.toInt() + ) + } + } } } } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt index af0dd02..cb93839 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt @@ -13,4 +13,6 @@ sealed class BottomNavItem ( object Dex : BottomNavItem("Dex", R.drawable.baseline_menu_book_24, "Dex") object Storage : BottomNavItem("Storage", R.drawable.baseline_catching_pokemon_24, "Storage") object Settings : BottomNavItem("Settings", R.drawable.baseline_settings_24, "Settings") + object Viewer : BottomNavItem("Viewer", R.drawable.baseline_image_24, "Viewer") + object CardView : BottomNavItem("Card/{dimId}", R.drawable.baseline_image_24, "Card") } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt index 655b58d..522ba13 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt @@ -1,5 +1,7 @@ package com.github.nacabaro.vbhelper.screens +import android.graphics.Bitmap +import android.util.Log import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -7,38 +9,88 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.material3.Card import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp +import androidx.navigation.NavController import com.github.nacabaro.vbhelper.R import com.github.nacabaro.vbhelper.components.TopBanner +import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.domain.Dim +import com.github.nacabaro.vbhelper.navigation.BottomNavItem +import com.github.nacabaro.vbhelper.source.DexRepository +import kotlinx.coroutines.launch +import java.nio.ByteBuffer @Composable -fun DexScreen() { +fun DexScreen( + navController: NavController +) { + val coroutineScope = rememberCoroutineScope() + val application = LocalContext.current.applicationContext as VBHelper + val dexRepository = DexRepository(application.container.db) + + val dimList = remember { mutableStateListOf() } + + LaunchedEffect(dexRepository) { + coroutineScope.launch { + dimList.clear() + dimList.addAll(dexRepository.getAllDims()) + } + } + Scaffold ( - topBar = { TopBanner("Discovered Digimon") } + topBar = { + TopBanner( + text = "Discovered Digimon", + onGearClick = { + navController.navigate(BottomNavItem.Viewer.route) + } + ) + } ) { contentPadding -> LazyColumn ( modifier = Modifier .padding(top = contentPadding.calculateTopPadding()) ) { - items(100) { i -> + items(dimList) { + val bitmap = remember (it.logo) { + Bitmap.createBitmap(it.logoWidth, it.logoHeight, Bitmap.Config.RGB_565).apply { + copyPixelsFromBuffer(ByteBuffer.wrap(it.logo)) + } + } + val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() } + + Log.d("DexScreen", "dimList: ${it.id}") + DexDiMEntry( - name = "Digimon $i", - icon = R.drawable.baseline_egg_24, - onClick = {}, + name = it.name, + logo = imageBitmap, + onClick = { + navController + .navigate( + BottomNavItem + .CardView.route + .replace("{dimId}", "${it.id}") + ) + }, modifier = Modifier .fillMaxWidth() - .padding( - vertical = 8.dp, - horizontal = 16.dp - ) + .padding(8.dp) ) } } @@ -48,7 +100,7 @@ fun DexScreen() { @Composable fun DexDiMEntry( name: String, - icon: Int, + logo: ImageBitmap, onClick: () -> Unit, modifier: Modifier = Modifier ) { @@ -64,7 +116,7 @@ fun DexDiMEntry( .padding(8.dp) ) { Image ( - painter = painterResource(id = icon), + bitmap = logo, contentDescription = name, modifier = Modifier .padding(8.dp) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt new file mode 100644 index 0000000..096247a --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt @@ -0,0 +1,82 @@ +package com.github.nacabaro.vbhelper.screens + +import android.graphics.Bitmap +import android.util.Log +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext +import androidx.navigation.NavController +import com.github.nacabaro.vbhelper.components.CharacterEntry +import com.github.nacabaro.vbhelper.components.StorageEntry +import com.github.nacabaro.vbhelper.components.TopBanner +import com.github.nacabaro.vbhelper.domain.Character +import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.navigation.BottomNavItem +import com.github.nacabaro.vbhelper.source.DexRepository +import kotlinx.coroutines.launch +import java.nio.ByteBuffer + +@Composable +fun DiMScreen( + navController: NavController, + dimId: Int +) { + val coroutineScope = rememberCoroutineScope() + val application = LocalContext.current.applicationContext as VBHelper + val dexRepository = DexRepository(application.container.db) + + val characterList = remember { mutableStateListOf() } + + Log.d("dimId", dimId.toString()) + + LaunchedEffect(dexRepository) { + coroutineScope.launch { + characterList.clear() + characterList.addAll(dexRepository.getCharactersByDimId(dimId)) + } + } + + Scaffold ( + topBar = { + TopBanner( + text = "Discovered Digimon", + onBackClick = { + navController.popBackStack() + } + ) + } + ) { contentPadding -> + LazyVerticalGrid( + columns = GridCells.Fixed(3), + contentPadding = contentPadding + ) { + items(characterList) { character -> + val bitmapName = remember (character.name) { + Bitmap.createBitmap(character.nameWidth, character.nameHeight, Bitmap.Config.RGB_565).apply { + copyPixelsFromBuffer(ByteBuffer.wrap(character.name)) + } + } + val bitmapCharacter = remember (character.sprite1) { + Bitmap.createBitmap(character.spritesWidth, character.spritesHeight, Bitmap.Config.RGB_565).apply { + copyPixelsFromBuffer(ByteBuffer.wrap(character.sprite1)) + } + } + val imageBitmapName = remember(bitmapName) { bitmapName.asImageBitmap() } + val imageBitmapCharacter = remember(bitmapCharacter) { bitmapCharacter.asImageBitmap() } + CharacterEntry( + name = imageBitmapName, + icon = imageBitmapCharacter, + onClick = { } + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt index 560c3a2..7b425c7 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt @@ -29,7 +29,8 @@ import java.io.FileInputStream @Composable fun SettingsScreen( navController: NavController, - dimReader: DimReader = DimReader() + //dimReader: DimReader = DimReader(), + onClickImportCard: () -> Unit ) { Scaffold ( topBar = { @@ -56,7 +57,8 @@ fun SettingsScreen( SettingsEntry(title = "Import transform functions", description = "Import standard vital bracelet keys") { } SettingsEntry(title = "Import decryption key", description = "Import standard vital bracelet keys") { } SettingsSection("DiM/BEm management") - SettingsEntry(title = "Import DiM card", description = "Import DiM card file") { + SettingsEntry(title = "Import DiM card", description = "Import DiM/BEm card file") { + onClickImportCard() // placeholder // val file = File("dummy_file.bin") //filePicker() // val fileInputStream = FileInputStream(file) @@ -69,9 +71,6 @@ fun SettingsScreen( // val logo = beMemory.spriteData.sprites[0] // } } - SettingsEntry(title = "Import BEm card", description = "Import BEm card file") { - // placeholder - } SettingsSection("About and credits") SettingsEntry(title = "Credits", description = "Credits") { } SettingsEntry(title = "About", description = "About") { } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/SpriteViewer.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/SpriteViewer.kt new file mode 100644 index 0000000..c7dea43 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/SpriteViewer.kt @@ -0,0 +1,89 @@ +package com.github.nacabaro.vbhelper.screens + +import android.graphics.Bitmap +import android.util.Log +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.github.nacabaro.vbhelper.components.TopBanner +import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.domain.Sprites +import com.github.nacabaro.vbhelper.source.SpriteRepo +import kotlinx.coroutines.launch +import java.nio.ByteBuffer + +@Composable +fun SpriteViewer( + navController: NavController +) { + val coroutineScope = rememberCoroutineScope() + val application = LocalContext.current.applicationContext as VBHelper + val db = application.container.db + val spriteRepo = SpriteRepo(db) + + val spriteList = remember { mutableStateListOf() } + + Log.d("SpriteViewer", "spriteList: $spriteList") + + LaunchedEffect(spriteRepo) { + coroutineScope.launch { + spriteList.clear() + spriteList.addAll(spriteRepo.getAllSprites()) + } + } + + Scaffold ( + topBar = { + TopBanner( + text = "Sprite viewer", + onBackClick = { + navController.popBackStack() + } + ) + }, + modifier = Modifier + .fillMaxSize() + ) { contentPadding -> + LazyColumn ( + modifier = Modifier + .padding(top = contentPadding.calculateTopPadding()) + ) { + items(spriteList) { sprite -> + val bitmap = remember (sprite.sprite) { + Log.d("SpriteViewer", "sprite: $sprite") + Bitmap.createBitmap(sprite.width, sprite.height, Bitmap.Config.RGB_565).apply { + copyPixelsFromBuffer(ByteBuffer.wrap(sprite.sprite)) + } + } + val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() } + Image( + bitmap = imageBitmap, + contentDescription = "Sprite", + modifier = Modifier + .size(256.dp) + ) + } + } + } +} + diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt index 66b9baf..6372d17 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt @@ -38,6 +38,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.github.nacabaro.vbhelper.R +import com.github.nacabaro.vbhelper.components.StorageEntry import com.github.nacabaro.vbhelper.components.TopBanner import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.source.StorageRepository @@ -112,41 +113,6 @@ fun StorageScreen() { } } -@Composable -fun StorageEntry( - name: String, - icon: Int, - onClick: () -> Unit = {}, - modifier: Modifier = Modifier -) { - Card( - shape = MaterialTheme.shapes.medium, - onClick = onClick, - modifier = modifier - .padding(8.dp) - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxSize() - ) { - Image( - painter = painterResource(id = icon), - contentDescription = name, - modifier = Modifier - .padding(8.dp) - .size(64.dp) - ) - Text( - text = name, - textAlign = TextAlign.Center, - modifier = Modifier - .padding(8.dp) - ) - } - } -} - @Composable fun StorageDialog( characterId: Long, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt b/app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt new file mode 100644 index 0000000..5e9a103 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt @@ -0,0 +1,18 @@ +package com.github.nacabaro.vbhelper.source + +import com.github.nacabaro.vbhelper.database.AppDatabase +import com.github.nacabaro.vbhelper.domain.Character +import com.github.nacabaro.vbhelper.domain.Dim +import kotlinx.coroutines.flow.Flow + +class DexRepository ( + private val db: AppDatabase +) { + suspend fun getAllDims(): List { + return db.dimDao().getAllDims() + } + + suspend fun getCharactersByDimId(dimId: Int): List { + return db.characterDao().getCharacterByDimId(dimId) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/source/SpriteRepo.kt b/app/src/main/java/com/github/nacabaro/vbhelper/source/SpriteRepo.kt new file mode 100644 index 0000000..84c0dbb --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/source/SpriteRepo.kt @@ -0,0 +1,12 @@ +package com.github.nacabaro.vbhelper.source + +import com.github.nacabaro.vbhelper.database.AppDatabase +import com.github.nacabaro.vbhelper.domain.Sprites + +class SpriteRepo ( + private val db: AppDatabase +) { + suspend fun getAllSprites(): List { + return db.characterDao().getAllSprites() + } +} diff --git a/app/src/main/res/drawable/baseline_image_24.xml b/app/src/main/res/drawable/baseline_image_24.xml new file mode 100644 index 0000000..fd890ce --- /dev/null +++ b/app/src/main/res/drawable/baseline_image_24.xml @@ -0,0 +1,5 @@ + + + + + From 4e2b9eb5412b538c9d340a2c323d9b377290b97c Mon Sep 17 00:00:00 2001 From: Nacho Date: Sun, 5 Jan 2025 18:13:41 +0100 Subject: [PATCH 2/3] Fixed flickering and banner overlapping --- .../vbhelper/components/CharacterEntry.kt | 31 +++++-------------- .../nacabaro/vbhelper/components/TopBanner.kt | 3 ++ .../nacabaro/vbhelper/screens/DexScreen.kt | 17 +++++----- .../nacabaro/vbhelper/screens/DimScreen.kt | 22 +++---------- 4 files changed, 23 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt b/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt index e644947..44a21b7 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt @@ -1,24 +1,19 @@ package com.github.nacabaro.vbhelper.components import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.Card import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.FilterQuality import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @Composable fun CharacterEntry( - name: ImageBitmap, icon: ImageBitmap, modifier: Modifier = Modifier, onClick: () -> Unit = { } @@ -28,25 +23,15 @@ fun CharacterEntry( onClick = onClick, modifier = modifier .padding(8.dp) + .size(96.dp) ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, + Image( + bitmap = icon, + contentDescription = "Icon", + filterQuality = FilterQuality.None, modifier = Modifier + .padding(8.dp) .fillMaxSize() - ) { - Image( - bitmap = icon, - contentDescription = "Icon", - modifier = Modifier - .padding(8.dp) - .size(64.dp) - ) - Image( - bitmap = name, - contentDescription = "Name", - modifier = Modifier - .padding(8.dp) - ) - } + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt b/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt index 03f1efd..55c4fa0 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt @@ -1,10 +1,12 @@ package com.github.nacabaro.vbhelper.components +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -24,6 +26,7 @@ fun TopBanner( ) { Box( // Use Box to overlay elements modifier = modifier + .background(MaterialTheme.colorScheme.background) .fillMaxWidth() .padding(16.dp) ) { diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt index 522ba13..d9cb68a 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt @@ -1,7 +1,6 @@ package com.github.nacabaro.vbhelper.screens import android.graphics.Bitmap -import android.util.Log import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -16,18 +15,17 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.FilterQuality import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.github.nacabaro.vbhelper.R import com.github.nacabaro.vbhelper.components.TopBanner import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.domain.Dim @@ -44,12 +42,12 @@ fun DexScreen( val application = LocalContext.current.applicationContext as VBHelper val dexRepository = DexRepository(application.container.db) - val dimList = remember { mutableStateListOf() } + val dimList = remember { mutableStateOf>(emptyList()) } LaunchedEffect(dexRepository) { coroutineScope.launch { - dimList.clear() - dimList.addAll(dexRepository.getAllDims()) + val newDimList = dexRepository.getAllDims() + dimList.value = newDimList // Replace the entire list atomically } } @@ -67,7 +65,7 @@ fun DexScreen( modifier = Modifier .padding(top = contentPadding.calculateTopPadding()) ) { - items(dimList) { + items(dimList.value) { val bitmap = remember (it.logo) { Bitmap.createBitmap(it.logoWidth, it.logoHeight, Bitmap.Config.RGB_565).apply { copyPixelsFromBuffer(ByteBuffer.wrap(it.logo)) @@ -75,8 +73,6 @@ fun DexScreen( } val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() } - Log.d("DexScreen", "dimList: ${it.id}") - DexDiMEntry( name = it.name, logo = imageBitmap, @@ -118,6 +114,7 @@ fun DexDiMEntry( Image ( bitmap = logo, contentDescription = name, + filterQuality = FilterQuality.None, modifier = Modifier .padding(8.dp) .size(64.dp) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt index 096247a..abfd00f 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt @@ -1,25 +1,22 @@ package com.github.nacabaro.vbhelper.screens import android.graphics.Bitmap -import android.util.Log import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext import androidx.navigation.NavController import com.github.nacabaro.vbhelper.components.CharacterEntry -import com.github.nacabaro.vbhelper.components.StorageEntry import com.github.nacabaro.vbhelper.components.TopBanner import com.github.nacabaro.vbhelper.domain.Character import com.github.nacabaro.vbhelper.di.VBHelper -import com.github.nacabaro.vbhelper.navigation.BottomNavItem import com.github.nacabaro.vbhelper.source.DexRepository import kotlinx.coroutines.launch import java.nio.ByteBuffer @@ -33,14 +30,12 @@ fun DiMScreen( val application = LocalContext.current.applicationContext as VBHelper val dexRepository = DexRepository(application.container.db) - val characterList = remember { mutableStateListOf() } - - Log.d("dimId", dimId.toString()) + val characterList = remember { mutableStateOf>(emptyList()) } LaunchedEffect(dexRepository) { coroutineScope.launch { - characterList.clear() - characterList.addAll(dexRepository.getCharactersByDimId(dimId)) + val newCharacterList = dexRepository.getCharactersByDimId(dimId) + characterList.value = newCharacterList } } @@ -58,21 +53,14 @@ fun DiMScreen( columns = GridCells.Fixed(3), contentPadding = contentPadding ) { - items(characterList) { character -> - val bitmapName = remember (character.name) { - Bitmap.createBitmap(character.nameWidth, character.nameHeight, Bitmap.Config.RGB_565).apply { - copyPixelsFromBuffer(ByteBuffer.wrap(character.name)) - } - } + items(characterList.value) { character -> val bitmapCharacter = remember (character.sprite1) { Bitmap.createBitmap(character.spritesWidth, character.spritesHeight, Bitmap.Config.RGB_565).apply { copyPixelsFromBuffer(ByteBuffer.wrap(character.sprite1)) } } - val imageBitmapName = remember(bitmapName) { bitmapName.asImageBitmap() } val imageBitmapCharacter = remember(bitmapCharacter) { bitmapCharacter.asImageBitmap() } CharacterEntry( - name = imageBitmapName, icon = imageBitmapCharacter, onClick = { } ) From 5691f998f291cf98172f0be5ca38c4da1579838a Mon Sep 17 00:00:00 2001 From: Nacho Date: Sun, 5 Jan 2025 22:18:39 +0100 Subject: [PATCH 3/3] Cleaned settings screen --- .../vbhelper/screens/SettingsScreen.kt | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt index 7b425c7..37356b9 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt @@ -17,19 +17,11 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController -import com.github.cfogrady.vb.dim.card.BemCard -import com.github.cfogrady.vb.dim.card.DimCard -import com.github.cfogrady.vb.dim.card.DimReader -import com.github.cfogrady.vb.dim.sprite.SpriteData -import com.github.cfogrady.vb.dim.sprite.SpriteData.Sprite import com.github.nacabaro.vbhelper.components.TopBanner -import java.io.File -import java.io.FileInputStream @Composable fun SettingsScreen( navController: NavController, - //dimReader: DimReader = DimReader(), onClickImportCard: () -> Unit ) { Scaffold ( @@ -57,20 +49,8 @@ fun SettingsScreen( SettingsEntry(title = "Import transform functions", description = "Import standard vital bracelet keys") { } SettingsEntry(title = "Import decryption key", description = "Import standard vital bracelet keys") { } SettingsSection("DiM/BEm management") - SettingsEntry(title = "Import DiM card", description = "Import DiM/BEm card file") { - onClickImportCard() - // placeholder -// val file = File("dummy_file.bin") //filePicker() -// val fileInputStream = FileInputStream(file) -// fileInputStream.use { -// val card = dimReader.readCard(fileInputStream, false) -// if (card is DimCard) { -// val logo = card.spriteData.sprites[0] -// } -// val beMemory = card as BemCard -// val logo = beMemory.spriteData.sprites[0] -// } - } + SettingsEntry(title = "Import DiM card", description = "Import DiM/BEm card file", onClick = onClickImportCard) + SettingsEntry(title = "Rename DiM/BEm", description = "Set card name") { } SettingsSection("About and credits") SettingsEntry(title = "Credits", description = "Credits") { } SettingsEntry(title = "About", description = "About") { }