https://kotlinlang.org logo
Title
t

Thomas

01/12/2021, 8:01 PM
An undecorated Compose for Desktop AlertDialog can be dragged around using good old Swing. Will be posting the short piece of code soon, this clip is to wet your appetite. 😂 The white bar at the bottom needs to be investigated, I think it might be a reproducible issue in Compose for Desktop. If so, will open an issue on GitHub
:jetpack-compose: 1
🎉 9
k

Kirill Grouchnikov

01/13/2021, 5:14 AM
Not sure how it is on other platforms, but the expectation on macOS and Windows is to not be able to drag a dialog from "grabbing" it anywhere. It is only expected to happen in the title area.
👍 1
t

Thomas

01/13/2021, 6:35 AM
Agreed. I will be elaborating on this in my post. Currently this is a fancy hack, by no means sure I want to see this in production. 😀 From a ux point of view there is probably no point in moving an Alert, too. I currently explore possibilities, which is probably the best way to really get to know something, in this case Compose for Desktop
My post will need some more time, so here is the code I use in my app TKDupeFinder to create the movable
AlertDialog
. As you can see the code makes a couple of assumptions, that's why I call it a hack. 🙂 For example: will
AppManager.windows.last().window
really always refer to the dialog? Also, upon recompositions we may get unwanted double listener registrations, so I need to make sure the listeners are set only if needed (will likely use client properties). Finally, clicking and dragging inteferes with normal Compose behavior. So, again, in this version it's a hack, yet a cool one.
if (isConfirmDialogVisible.value) {
AlertDialog(onDismissRequest = {
isConfirmDialogVisible.value = false
},
properties = DesktopDialogProperties(undecorated = true),
modifier = Modifier.border(width = 1.dp,
MaterialTheme.colors.primary),
title = {
Text(RESOURCE_BUNDLE.getString("confirm_deletion"))
},
text = {
ScrollableColumn {
val sb = StringBuilder()
selectedFiles.forEach {
sb.append(checksums[currentPos], it.name).appendLine()
}
Text(sb.toString())
}
},
dismissButton = {
Button(onClick = {
isConfirmDialogVisible.value = false
}) {
Text(RESOURCE_BUNDLE.getString("cancel"))
}
},
confirmButton = {
Button(onClick = {
isConfirmDialogVisible.value = false
selectedFiles.forEach {
df.deleteFile(checksums[currentPos], it)
}
selected.clear()
}) {
Text(RESOURCE_BUNDLE.getString("delete"))
}
})
val window = AppManager.windows.last().window
val component = window.contentPane.getComponent(0)
val adapter = object : MouseInputAdapter() {
private lateinit var initialClick: Point
override fun mousePressed(e: MouseEvent) {
initialClick = e.point
}
override fun mouseDragged(e: MouseEvent) {
val dx = e.x - initialClick.x
val dy = e.y - initialClick.y
window.setLocation(window.location.x + dx,
window.location.y + dy)
}
}
component.addMouseMotionListener(adapter)
component.addMouseListener(adapter)
}