diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9e700f0..b68afb1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -91,4 +91,7 @@ dependencies { implementation("com.google.android.material:material:1.2.0") implementation(libs.protobuf.javalite) 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") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d3a5163..7f87d3e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,15 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidget.kt b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidget.kt new file mode 100644 index 0000000..5dc1396 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidget.kt @@ -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(null) } + var bitmapIdle2 by remember { mutableStateOf(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" + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetPreferences.kt b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetPreferences.kt new file mode 100644 index 0000000..7d0f825 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetPreferences.kt @@ -0,0 +1,3 @@ +package com.github.nacabaro.vbhelper.widget + +import androidx.glance.state.PreferencesGlanceStateDefinition diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetReceiver.kt b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetReceiver.kt new file mode 100644 index 0000000..cea351d --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetReceiver.kt @@ -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() +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetWorker.kt b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetWorker.kt new file mode 100644 index 0000000..5fa9d6e --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/widget/CharacterDisplayWidgetWorker.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/res/xml/widget_info.xml b/app/src/main/res/xml/widget_info.xml new file mode 100644 index 0000000..5297356 --- /dev/null +++ b/app/src/main/res/xml/widget_info.xml @@ -0,0 +1,10 @@ + + \ No newline at end of file