mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-10-01 15:41:36 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93f568dd8d | ||
|
|
d46769b0cb | ||
|
|
fce05870c5 | ||
|
|
d749af0a9c | ||
|
|
076f6bfacf | ||
|
|
a4f3b701e5 | ||
|
|
da134247b1 | ||
|
|
e36a700d9f |
@@ -15,7 +15,7 @@ android {
|
|||||||
minSdk = 28
|
minSdk = 28
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "Alpha 0.1"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@@ -91,4 +91,7 @@ dependencies {
|
|||||||
implementation("com.google.android.material:material:1.2.0")
|
implementation("com.google.android.material:material:1.2.0")
|
||||||
implementation(libs.protobuf.javalite)
|
implementation(libs.protobuf.javalite)
|
||||||
implementation("androidx.compose.material:material")
|
implementation("androidx.compose.material:material")
|
||||||
|
implementation("androidx.glance:glance:1.1.1")
|
||||||
|
implementation("androidx.glance:glance-appwidget:1.1.1")
|
||||||
|
implementation("androidx.work:work-runtime-ktx:2.9.0")
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,15 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<receiver android:name=".widget.CharacterDisplayWidgetReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data
|
||||||
|
android:name="android.appwidget.provider"
|
||||||
|
android:resource="@xml/widget_info" />
|
||||||
|
</receiver>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -21,6 +21,8 @@ interface AdventureDao {
|
|||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
SELECT
|
||||||
uc.*,
|
uc.*,
|
||||||
|
c.stage,
|
||||||
|
c.attribute,
|
||||||
c.sprite1 AS spriteIdle,
|
c.sprite1 AS spriteIdle,
|
||||||
c.spritesWidth AS spriteWidth,
|
c.spritesWidth AS spriteWidth,
|
||||||
c.spritesHeight AS spriteHeight,
|
c.spritesHeight AS spriteHeight,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.room.Insert
|
|||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Upsert
|
import androidx.room.Upsert
|
||||||
|
import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory
|
import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory
|
||||||
@@ -45,6 +46,8 @@ interface UserCharacterDao {
|
|||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
uc.*,
|
uc.*,
|
||||||
|
c.stage,
|
||||||
|
c.attribute,
|
||||||
c.sprite1 AS spriteIdle,
|
c.sprite1 AS spriteIdle,
|
||||||
c.spritesWidth AS spriteWidth,
|
c.spritesWidth AS spriteWidth,
|
||||||
c.spritesHeight AS spriteHeight,
|
c.spritesHeight AS spriteHeight,
|
||||||
@@ -65,6 +68,8 @@ interface UserCharacterDao {
|
|||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
uc.*,
|
uc.*,
|
||||||
|
c.stage,
|
||||||
|
c.attribute,
|
||||||
c.sprite1 AS spriteIdle,
|
c.sprite1 AS spriteIdle,
|
||||||
c.spritesWidth AS spriteWidth,
|
c.spritesWidth AS spriteWidth,
|
||||||
c.spritesHeight AS spriteHeight,
|
c.spritesHeight AS spriteHeight,
|
||||||
@@ -91,6 +96,8 @@ interface UserCharacterDao {
|
|||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
uc.*,
|
uc.*,
|
||||||
|
c.stage,
|
||||||
|
c.attribute,
|
||||||
c.sprite1 AS spriteIdle,
|
c.sprite1 AS spriteIdle,
|
||||||
c.spritesWidth AS spriteWidth,
|
c.spritesWidth AS spriteWidth,
|
||||||
c.spritesHeight AS spriteHeight,
|
c.spritesHeight AS spriteHeight,
|
||||||
@@ -116,4 +123,15 @@ interface UserCharacterDao {
|
|||||||
|
|
||||||
@Query("UPDATE UserCharacter SET isActive = 1 WHERE id = :id")
|
@Query("UPDATE UserCharacter SET isActive = 1 WHERE id = :id")
|
||||||
fun setActiveCharacter(id: Long)
|
fun setActiveCharacter(id: Long)
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"""
|
||||||
|
SELECT c.*
|
||||||
|
FROM Character c
|
||||||
|
join UserCharacter uc on c.id = uc.charId
|
||||||
|
where uc.id = :charId
|
||||||
|
LIMIT 1
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
suspend fun getCharacterInfo(charId: Long): Character
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.github.nacabaro.vbhelper.domain.characters
|
|||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
foreignKeys = [
|
foreignKeys = [
|
||||||
@@ -14,13 +15,18 @@ import androidx.room.ForeignKey
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
/*
|
||||||
|
* Character represents a character on a DIM card. There should only be one of these per dimId
|
||||||
|
* and monIndex.
|
||||||
|
* TODO: Customs will mean this should be unique per cardName and monIndex
|
||||||
|
*/
|
||||||
data class Character (
|
data class Character (
|
||||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||||
val dimId: Long,
|
val dimId: Long,
|
||||||
val monIndex: Int,
|
val monIndex: Int,
|
||||||
val name: ByteArray,
|
val name: ByteArray,
|
||||||
val stage: Int, // These should be replaced with enums
|
val stage: Int, // These should be replaced with enums
|
||||||
val attribute: Int, // This one too
|
val attribute: NfcCharacter.Attribute, // This one too
|
||||||
val baseHp: Int,
|
val baseHp: Int,
|
||||||
val baseBp: Int,
|
val baseBp: Int,
|
||||||
val baseAp: Int,
|
val baseAp: Int,
|
||||||
|
|||||||
@@ -17,11 +17,12 @@ import com.github.nacabaro.vbhelper.domain.characters.Character
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
/**
|
||||||
|
* UserCharacter represents and instance of a character. The charId should map to a Character
|
||||||
|
*/
|
||||||
data class UserCharacter (
|
data class UserCharacter (
|
||||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||||
var charId: Long,
|
var charId: Long,
|
||||||
var stage: Int,
|
|
||||||
var attribute: NfcCharacter.Attribute,
|
|
||||||
var ageInDays: Int,
|
var ageInDays: Int,
|
||||||
var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim
|
var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim
|
||||||
var mood: Int,
|
var mood: Int,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImp
|
|||||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
|
||||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreen
|
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreen
|
||||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
||||||
|
import com.github.nacabaro.vbhelper.screens.settingsScreen.CreditsScreen
|
||||||
import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreenControllerImpl
|
||||||
|
|
||||||
data class AppNavigationHandlers(
|
data class AppNavigationHandlers(
|
||||||
@@ -125,6 +126,11 @@ fun AppNavigation(
|
|||||||
.adventureScreenController
|
.adventureScreenController
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
composable(NavigationItems.Credits.route) {
|
||||||
|
CreditsScreen(
|
||||||
|
navController = navController
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ fun BottomNavigationBar(navController: NavController) {
|
|||||||
NavigationItems.Dex,
|
NavigationItems.Dex,
|
||||||
NavigationItems.Storage,
|
NavigationItems.Storage,
|
||||||
)
|
)
|
||||||
|
|
||||||
NavigationBar {
|
NavigationBar {
|
||||||
val currentBackStackEntry = navController.currentBackStackEntryAsState()
|
val currentBackStackEntry = navController.currentBackStackEntryAsState()
|
||||||
val currentRoute = currentBackStackEntry.value?.destination?.route
|
val currentRoute = currentBackStackEntry.value?.destination?.route
|
||||||
|
|||||||
@@ -20,4 +20,5 @@ sealed class NavigationItems (
|
|||||||
object ItemsStore : NavigationItems("ItemsStore", R.drawable.baseline_data_24, "Items store")
|
object ItemsStore : NavigationItems("ItemsStore", R.drawable.baseline_data_24, "Items store")
|
||||||
object ApplyItem : NavigationItems("ApplyItem/{itemId}", R.drawable.baseline_data_24, "Apply item")
|
object ApplyItem : NavigationItems("ApplyItem/{itemId}", R.drawable.baseline_data_24, "Apply item")
|
||||||
object Adventure : NavigationItems("Adventure", R.drawable.baseline_fort_24, "Adventure")
|
object Adventure : NavigationItems("Adventure", R.drawable.baseline_fort_24, "Adventure")
|
||||||
|
object Credits : NavigationItems("Credits", R.drawable.baseline_data_24, "Credits")
|
||||||
}
|
}
|
||||||
+1
-1
@@ -72,7 +72,7 @@ class AdventureScreenControllerImpl(
|
|||||||
private suspend fun generateItem(characterId: Long): ItemDtos.PurchasedItem {
|
private suspend fun generateItem(characterId: Long): ItemDtos.PurchasedItem {
|
||||||
val character = database
|
val character = database
|
||||||
.userCharacterDao()
|
.userCharacterDao()
|
||||||
.getCharacter(characterId)
|
.getCharacterInfo(characterId)
|
||||||
|
|
||||||
val randomItem = database
|
val randomItem = database
|
||||||
.itemDao()
|
.itemDao()
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BetaWarning(
|
||||||
|
onDismissRequest: () -> Unit
|
||||||
|
) {
|
||||||
|
Dialog(
|
||||||
|
onDismissRequest = onDismissRequest
|
||||||
|
) {
|
||||||
|
Card {
|
||||||
|
Column (
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "This application is currently in alpha and it is not complete. Do not use to store important characters for you, as any future updates might delete all your characters. Sorry for the inconvenience!"
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.padding(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "Also, this application does not work yet with the original VB."
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.padding(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "Thank you for your understanding and patience. Sincerely, the dev team."
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.padding(8.dp))
|
||||||
|
Button(
|
||||||
|
onClick = onDismissRequest
|
||||||
|
) {
|
||||||
|
Text(text = "Dismiss")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@ fun HomeScreen(
|
|||||||
val beData = remember { mutableStateOf<BECharacterData?>(null) }
|
val beData = remember { mutableStateOf<BECharacterData?>(null) }
|
||||||
val vbData = remember { mutableStateOf<VBCharacterData?>(null) }
|
val vbData = remember { mutableStateOf<VBCharacterData?>(null) }
|
||||||
var adventureMissionsFinished by rememberSaveable { mutableStateOf(false) }
|
var adventureMissionsFinished by rememberSaveable { mutableStateOf(false) }
|
||||||
|
var betaWarning by rememberSaveable { mutableStateOf(true) }
|
||||||
|
|
||||||
LaunchedEffect(storageRepository, activeMon) {
|
LaunchedEffect(storageRepository, activeMon) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
@@ -140,6 +141,12 @@ fun HomeScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (betaWarning) {
|
||||||
|
BetaWarning {
|
||||||
|
betaWarning = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-2
@@ -167,8 +167,6 @@ class ScanScreenControllerImpl(
|
|||||||
|
|
||||||
val characterData = UserCharacter(
|
val characterData = UserCharacter(
|
||||||
charId = cardCharData.id,
|
charId = cardCharData.id,
|
||||||
stage = nfcCharacter.stage.toInt(),
|
|
||||||
attribute = nfcCharacter.attribute,
|
|
||||||
ageInDays = nfcCharacter.ageInDays.toInt(),
|
ageInDays = nfcCharacter.ageInDays.toInt(),
|
||||||
nextAdventureMissionStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
nextAdventureMissionStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
||||||
mood = nfcCharacter.mood.toInt(),
|
mood = nfcCharacter.mood.toInt(),
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.settingsScreen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CreditsScreen(
|
||||||
|
navController: NavController
|
||||||
|
) {
|
||||||
|
Scaffold (
|
||||||
|
topBar = {
|
||||||
|
TopBanner(
|
||||||
|
text = "Credits",
|
||||||
|
onBackClick = {
|
||||||
|
navController.popBackStack()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
) { contentPadding ->
|
||||||
|
Column (
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
|
) {
|
||||||
|
SettingsSection("Reverse engineering")
|
||||||
|
SettingsEntry(title = "cyanic", description = "Reversed the firmware and helped us during development.") { }
|
||||||
|
SettingsSection("Application development")
|
||||||
|
SettingsEntry(title = "cfogrady", description = "Developed vb-lib-nfc and part of this application.") { }
|
||||||
|
SettingsEntry(title = "nacabaro", description = "Developed this application.") { }
|
||||||
|
SettingsEntry(title = "lightheel", description = "Developing the battling part for this application, including server. Still in the works.") { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-1
@@ -18,6 +18,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsScreen(
|
fun SettingsScreen(
|
||||||
@@ -52,7 +53,9 @@ fun SettingsScreen(
|
|||||||
}
|
}
|
||||||
SettingsEntry(title = "Rename DiM/BEm", description = "Set card name") { }
|
SettingsEntry(title = "Rename DiM/BEm", description = "Set card name") { }
|
||||||
SettingsSection("About and credits")
|
SettingsSection("About and credits")
|
||||||
SettingsEntry(title = "Credits", description = "Credits") { }
|
SettingsEntry(title = "Credits", description = "Credits") {
|
||||||
|
navController.navigate(NavigationItems.Credits.route)
|
||||||
|
}
|
||||||
SettingsEntry(title = "About", description = "About") { }
|
SettingsEntry(title = "About", description = "About") { }
|
||||||
SettingsSection("Data management")
|
SettingsSection("Data management")
|
||||||
SettingsEntry(title = "Export data", description = "Export application database") {
|
SettingsEntry(title = "Export data", description = "Export application database") {
|
||||||
|
|||||||
+2
-1
@@ -11,6 +11,7 @@ import androidx.activity.result.ActivityResultLauncher
|
|||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import com.github.cfogrady.vb.dim.card.BemCard
|
import com.github.cfogrady.vb.dim.card.BemCard
|
||||||
import com.github.cfogrady.vb.dim.card.DimReader
|
import com.github.cfogrady.vb.dim.card.DimReader
|
||||||
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.domain.Sprites
|
import com.github.nacabaro.vbhelper.domain.Sprites
|
||||||
@@ -144,7 +145,7 @@ class SettingsScreenControllerImpl(
|
|||||||
monIndex = index,
|
monIndex = index,
|
||||||
name = card.spriteData.sprites[spriteCounter].pixelData,
|
name = card.spriteData.sprites[spriteCounter].pixelData,
|
||||||
stage = characters[index].stage,
|
stage = characters[index].stage,
|
||||||
attribute = characters[index].attribute,
|
attribute = NfcCharacter.Attribute.entries[characters[index].attribute],
|
||||||
baseHp = characters[index].hp,
|
baseHp = characters[index].hp,
|
||||||
baseBp = characters[index].dp,
|
baseBp = characters[index].dp,
|
||||||
baseAp = characters[index].ap,
|
baseAp = characters[index].ap,
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.widget
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.glance.GlanceTheme
|
||||||
|
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.glance.background
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||||
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
|
import androidx.glance.GlanceId
|
||||||
|
import androidx.glance.GlanceModifier
|
||||||
|
import androidx.glance.Image
|
||||||
|
import androidx.glance.ImageProvider
|
||||||
|
import androidx.glance.appwidget.GlanceAppWidget
|
||||||
|
import androidx.glance.appwidget.provideContent
|
||||||
|
import androidx.glance.layout.Alignment
|
||||||
|
import androidx.glance.layout.Column
|
||||||
|
import androidx.glance.layout.fillMaxSize
|
||||||
|
import androidx.glance.layout.size
|
||||||
|
import androidx.glance.state.PreferencesGlanceStateDefinition
|
||||||
|
import androidx.glance.text.Text
|
||||||
|
import androidx.glance.unit.ColorProvider
|
||||||
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
|
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||||
|
|
||||||
|
/*
|
||||||
|
RANT: Why did they have to create the components from Jetpack Compose
|
||||||
|
with a different API for Glance? Now there are things I use in Jetpack Compose
|
||||||
|
like the filterQuality, which isn't here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
val CURRENT_IMAGE_KEY = booleanPreferencesKey("current_image")
|
||||||
|
|
||||||
|
class CharacterDisplayWidget : GlanceAppWidget() {
|
||||||
|
override suspend fun provideGlance(context: Context, id: GlanceId) {
|
||||||
|
val application = context.applicationContext as VBHelper
|
||||||
|
val storageRepository = application.container.db
|
||||||
|
|
||||||
|
val currentCharacter = storageRepository
|
||||||
|
.userCharacterDao()
|
||||||
|
.getActiveCharacter()
|
||||||
|
|
||||||
|
val multiplier = 4
|
||||||
|
|
||||||
|
provideContent {
|
||||||
|
var bitmapIdle1 by remember { mutableStateOf<Bitmap?>(null) }
|
||||||
|
var bitmapIdle2 by remember { mutableStateOf<Bitmap?>(null) }
|
||||||
|
var dpSize by remember { mutableStateOf(0.dp) }
|
||||||
|
|
||||||
|
if (currentCharacter != null) {
|
||||||
|
val currentCharacterBitmapIdle1 = BitmapData(
|
||||||
|
currentCharacter.spriteIdle,
|
||||||
|
currentCharacter.spriteWidth,
|
||||||
|
currentCharacter.spriteHeight
|
||||||
|
)
|
||||||
|
|
||||||
|
val currentCharacterBitmapIdle2 = BitmapData(
|
||||||
|
currentCharacter.spriteIdle2,
|
||||||
|
currentCharacter.spriteWidth,
|
||||||
|
currentCharacter.spriteHeight
|
||||||
|
)
|
||||||
|
|
||||||
|
bitmapIdle1 = currentCharacterBitmapIdle1.getBitmap()
|
||||||
|
bitmapIdle2 = currentCharacterBitmapIdle2.getBitmap()
|
||||||
|
|
||||||
|
val density: Float = application.resources.displayMetrics.density
|
||||||
|
dpSize = (currentCharacterBitmapIdle1.width * multiplier / density).dp
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetContent(
|
||||||
|
imageBitmapFrame1 = bitmapIdle1,
|
||||||
|
imageBitmapFrame2 = bitmapIdle2,
|
||||||
|
dpSize = dpSize
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun WidgetContent(
|
||||||
|
imageBitmapFrame1: Bitmap?,
|
||||||
|
imageBitmapFrame2: Bitmap?,
|
||||||
|
dpSize: Dp
|
||||||
|
) {
|
||||||
|
GlanceTheme {
|
||||||
|
Column (
|
||||||
|
horizontalAlignment = Alignment.Horizontal.CenterHorizontally,
|
||||||
|
verticalAlignment = Alignment.Vertical.CenterVertically,
|
||||||
|
modifier = GlanceModifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(ColorProvider(MaterialTheme.colorScheme.background))
|
||||||
|
) {
|
||||||
|
if (imageBitmapFrame1 != null) {
|
||||||
|
Image(
|
||||||
|
provider = ImageProvider(
|
||||||
|
bitmap = imageBitmapFrame1
|
||||||
|
),
|
||||||
|
contentDescription = "Character",
|
||||||
|
modifier = GlanceModifier
|
||||||
|
.size(dpSize)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Text(
|
||||||
|
text = "No character selected"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.widget
|
||||||
|
|
||||||
|
import androidx.glance.state.PreferencesGlanceStateDefinition
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.widget
|
||||||
|
|
||||||
|
import androidx.glance.appwidget.GlanceAppWidget
|
||||||
|
import androidx.glance.appwidget.GlanceAppWidgetReceiver
|
||||||
|
|
||||||
|
class CharacterDisplayWidgetReceiver : GlanceAppWidgetReceiver() {
|
||||||
|
override val glanceAppWidget: GlanceAppWidget = CharacterDisplayWidget()
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.widget
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.glance.appwidget.GlanceAppWidgetManager
|
||||||
|
import androidx.glance.appwidget.state.updateAppWidgetState
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
|
||||||
|
class CharacterDisplayWidgetWorker(
|
||||||
|
appContext: Context,
|
||||||
|
workerParams: WorkerParameters
|
||||||
|
) : CoroutineWorker(appContext, workerParams) {
|
||||||
|
|
||||||
|
override suspend fun doWork(): Result {
|
||||||
|
// Get all widget IDs for your ImageSwapWidget
|
||||||
|
val glanceIds = GlanceAppWidgetManager(applicationContext)
|
||||||
|
.getGlanceIds(CharacterDisplayWidget::class.java)
|
||||||
|
|
||||||
|
glanceIds.forEach { glanceId ->
|
||||||
|
// Update the widget's state (toggle the boolean)
|
||||||
|
updateAppWidgetState(
|
||||||
|
context = applicationContext,
|
||||||
|
glanceId = glanceId
|
||||||
|
) { prefs ->
|
||||||
|
val currentImageIsImage1 = prefs[CURRENT_IMAGE_KEY] ?: true
|
||||||
|
prefs[CURRENT_IMAGE_KEY] = !currentImageIsImage1 // Toggle the boolean
|
||||||
|
}
|
||||||
|
// Trigger the widget to redraw itself with the new state
|
||||||
|
CharacterDisplayWidget().update(applicationContext, glanceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indicate that the work was successful
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:initialLayout="@layout/glance_default_loading_layout"
|
||||||
|
android:minWidth="40dp"
|
||||||
|
android:minHeight="20dp"
|
||||||
|
android:minResizeWidth="20dp"
|
||||||
|
android:previewImage="@drawable/baseline_image_24"
|
||||||
|
android:resizeMode="horizontal|vertical"
|
||||||
|
android:updatePeriodMillis="300000"
|
||||||
|
android:widgetCategory="home_screen" />
|
||||||
Reference in New Issue
Block a user