Перекомпоновка триггера вниз по составляемой иерархии

Я пытаюсь реализовать представление графа (узлы графа как Cards) с перемещаемым (перетаскиванием) рабочим пространством и узлами графа с помощью Jetbrains Compose (рабочий стол /JVM).

Мне удалось сделать перетаскиваемые узлы графа ( GraphNodeBox), а затем я хотел переместить все узлы при обнаружении перетаскивания во внешнем контейнере узлов ( ViewBox), но изменение состояния не вызывает перекомпоновку узлов графа. Я отлаживал, зарегистрировал изменение состояния (когда все смещения узлов обновлено), и оно выполняется при перетаскивании, но пользовательский интерфейс не перерисовывается.

      @Composable
fun ViewBox() {
    var graphNodes by remember {
        mutableStateOf(listOf(GraphNode(Item("Test Item")), GraphNode(Item("Test Item 2"))))
    }

    Box(
        modifier = Modifier.fillMaxSize()
            .background(Color.Magenta)
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    change.consumeAllChanges()
                    graphNodes = graphNodes.map { graphNode ->
                        GraphNode.OffsetLens.modify(graphNode) { it + dragAmount }
                    }
                }
            }
    ) {
        graphNodes.forEach { // it happens only once initially and is not called again when `graphNodes` state is changed
            GraphNodeBox(it)
        }
    }
}

@Composable
fun GraphNodeBox(graphNode: GraphNode) {
    var offset by remember { mutableStateOf(IntOffset(0, 0)) }

    Card(
        modifier = Modifier.padding(5.dp)
            .offset { offset }
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    change.consumeAllChanges()
                    offset += IntOffset(dragAmount.x.toInt(), dragAmount.y.toInt()) // this works like a charm and the offset update triggers recomposition
                }
            }
    ) {
        Row {
            Column(modifier = Modifier.padding(10.dp)) {
                Text(
                    text = graphNode.item.name,
                    style = MaterialTheme.typography.subtitle1
                )
                Text(
                    text = graphNode.item.stereotypes.joinToString { it.toString() },
                    style = MaterialTheme.typography.subtitle2
                )
            }
        }
    }
}

data class GraphNode(
    val item: Item,
    val offset: Offset = Offset(0f, 0f)
) {
    companion object {
        val OffsetLens: Lens<GraphNode, Offset> = PLens(
            get = { it.offset },
            set = { graphNode, value -> graphNode.copy(offset = value) }
        )
    }
}

Похоже, что обновление состояния внешнего компонента не влияет на вложенные компоненты.

Мне, вероятно, не хватает идеи Jetbrains Compose, и ее нужно реализовать каким-то другим способом, но я не могу придумать правильную реализацию.

0 ответов

Другие вопросы по тегам