From bb579d5c31cecdbf15013928f3e89b241a41b41b Mon Sep 17 00:00:00 2001 From: Alex Vanyo Date: Fri, 27 Dec 2024 19:20:27 -0600 Subject: [PATCH] Fix initial Coil rendering with graphicsLayer Fixes #2282 --- .../ui/cells/CellStateDragAndDrop.android.kt | 54 ++++++++++++------- .../ui/cells/CellStateDragAndDrop.desktop.kt | 2 + .../ui/cells/CellStateDragAndDrop.kt | 1 + 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/ui-cells/src/androidMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.android.kt b/ui-cells/src/androidMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.android.kt index 98119ede33..3c5fc3c9e9 100644 --- a/ui-cells/src/androidMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.android.kt +++ b/ui-cells/src/androidMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.android.kt @@ -21,6 +21,7 @@ import android.content.ClipDescription import android.os.Build import android.view.View import androidx.compose.foundation.draganddrop.dragAndDropSource +import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -30,7 +31,10 @@ import androidx.compose.ui.draganddrop.DragAndDropEvent import androidx.compose.ui.draganddrop.DragAndDropTransferData import androidx.compose.ui.draganddrop.mimeTypes import androidx.compose.ui.draganddrop.toAndroidDragEvent +import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.layer.drawLayer +import androidx.compose.ui.graphics.rememberGraphicsLayer import com.alexvanyo.composelife.model.CellState import com.alexvanyo.composelife.model.CellStateParser import com.alexvanyo.composelife.model.DeserializationResult @@ -38,28 +42,40 @@ import com.alexvanyo.composelife.model.RunLengthEncodedCellStateSerializer import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first +@Composable actual fun Modifier.cellStateDragAndDropSource( getCellState: () -> CellState, -): Modifier = - dragAndDropSource( - transferData = { - val clipData = ClipData.newPlainText( - "cellState", - RunLengthEncodedCellStateSerializer.serializeToString(getCellState()) - .joinToString("\n"), - ) +): Modifier { + // TODO: Remove graphics layer workaround once default drag decoration works with Coil. + // https://github.com/coil-kt/coil/issues/2150 + val graphicsLayer = rememberGraphicsLayer() + return drawWithCache { + graphicsLayer.record { drawContent() } + onDrawWithContent { drawLayer(graphicsLayer) } + } + .dragAndDropSource( + drawDragDecoration = { + drawLayer(graphicsLayer) + }, + transferData = { + val clipData = ClipData.newPlainText( + "cellState", + RunLengthEncodedCellStateSerializer.serializeToString(getCellState()) + .joinToString("\n"), + ) - DragAndDropTransferData( - clipData = clipData, - localState = clipData, - flags = if (Build.VERSION.SDK_INT >= 24) { - View.DRAG_FLAG_GLOBAL - } else { - 0 - }, - ) - }, - ) + DragAndDropTransferData( + clipData = clipData, + localState = clipData, + flags = if (Build.VERSION.SDK_INT >= 24) { + View.DRAG_FLAG_GLOBAL + } else { + 0 + }, + ) + }, + ) +} internal actual fun cellStateShouldStartDragAndDrop(event: DragAndDropEvent): Boolean = event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) diff --git a/ui-cells/src/desktopMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.desktop.kt b/ui-cells/src/desktopMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.desktop.kt index a665b1e15b..818485ab22 100644 --- a/ui-cells/src/desktopMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.desktop.kt +++ b/ui-cells/src/desktopMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.desktop.kt @@ -17,6 +17,7 @@ package com.alexvanyo.composelife.ui.cells import androidx.compose.foundation.draganddrop.dragAndDropSource +import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -41,6 +42,7 @@ import java.awt.dnd.DropTargetDragEvent import java.awt.dnd.DropTargetDropEvent @OptIn(ExperimentalComposeUiApi::class) +@Composable actual fun Modifier.cellStateDragAndDropSource(getCellState: () -> CellState): Modifier = dragAndDropSource { offset -> DragAndDropTransferData( diff --git a/ui-cells/src/jbMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.kt b/ui-cells/src/jbMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.kt index c6ede3ae4e..03845bd8b3 100644 --- a/ui-cells/src/jbMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.kt +++ b/ui-cells/src/jbMain/kotlin/com/alexvanyo/composelife/ui/cells/CellStateDragAndDrop.kt @@ -27,6 +27,7 @@ import com.alexvanyo.composelife.model.CellState /** * A [Modifier] for a drag-and-drop source for a [CellState]. */ +@Composable expect fun Modifier.cellStateDragAndDropSource(getCellState: () -> CellState): Modifier /**