如何在 Jetpack Compose for Desktop 上最好地显示弹出菜单?

How to best show a popup menu on Jetpack Compose for Desktop?

所以我有了弹出菜单的概念...

@Composable
expect fun PopupMenu(
    menuItems: List<String>,
    onClickCallbacks: List<() -> Unit>,
    showMenu: Boolean,
    onDismiss: () -> Unit,
    toggle: @Composable () -> Unit,
)

我有一个桌面弹出菜单实现...

@Composable
actual fun PopupMenu(
    menuItems: List<String>,
    onClickCallbacks: List<() -> Unit>,
    showMenu: Boolean,
    onDismiss: () -> Unit,
    toggle: @Composable () -> Unit,
) {
    DropdownMenu(
        expanded = showMenu,
        onDismissRequest = { onDismiss() },
    ) {
        menuItems.forEachIndexed { index, item ->
            DropdownMenuItem(onClick = {
                onDismiss()
                onClickCallbacks[index]
            }) {
                Text(text = item)
            }
        }
    }
}

我想弄清楚的是,如何在此处显示它?

@Composable
fun OneCard(content: MutableState<TextFieldValue>, onValueChange: (TextFieldValue) -> Unit ) {
    Card(modifier = Modifier.draggable(DraggableState {  }, Orientation.Vertical)
        .then(Modifier.padding(16.dp))) {
        OutlinedTextField(
            value = content.value,
            onValueChange = onValueChange,
            placeholder = { TextFieldValue(text = "Your thoughts?") },
            modifier = Modifier.selectable(
                selected = false,
                onClick = {
                    // TODO: How to show popup menu on right click, or perhaps after a delay,
                    //       somewhere near the selected text?
                }
            )
        )
    }
}

CursorDropdownMenu 可以在这种情况下使用,例如这里是如何在鼠标右键单击时显示它:

var expanded by remember { mutableStateOf(false) }
Box(
    Modifier
        .fillMaxSize()
        .mouseClickable {
            if (buttons.isSecondaryPressed) {
                expanded = true
            }
        }
)
// tmp fix for https://github.com/JetBrains/compose-jb/issues/2012
var renderCount by remember { mutableStateOf(0) }
listOf(renderCount, renderCount - 1).forEach { renderId ->
    val isActive = renderId == renderCount
    key(renderId) {
        CursorDropdownMenu(
            expanded = expanded && isActive,
            onDismissRequest = {
                if (isActive) {
                    renderCount += 1
                    expanded = false
                }
            },
        ) {
            DropdownMenuItem({}) {
                Text("First item")
            }
            DropdownMenuItem({}) {
                Text("Second item")
            }
        }
    }
}