diff --git a/tutorials/Mouse_Events/README.md b/tutorials/Mouse_Events/README.md index 69411100d1..5d767897c7 100644 --- a/tutorials/Mouse_Events/README.md +++ b/tutorials/Mouse_Events/README.md @@ -16,10 +16,11 @@ so code like this will work on both platforms: import androidx.compose.desktop.Window import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.material.Text +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -29,9 +30,9 @@ import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.sp fun main() = Window(title = "Compose for Desktop", size = IntSize(400, 400)) { - var count = remember { mutableStateOf(0) } + var count by remember { mutableStateOf(0) } Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth()) { - var text = remember { mutableStateOf("Click magenta box!") } + var text by remember { mutableStateOf("Click magenta box!") } Column { @OptIn(ExperimentalFoundationApi::class) Box( @@ -41,17 +42,17 @@ fun main() = Window(title = "Compose for Desktop", size = IntSize(400, 400)) { .fillMaxHeight(0.2f) .combinedClickable( onClick = { - text.value = "Click! ${count.value++}" + text = "Click! ${count++}" }, onDoubleClick = { - text.value = "Double click! ${count.value++}" + text = "Double click! ${count++}" }, onLongClick = { - text.value = "Long click! ${count.value++}" + text = "Long click! ${count++}" } ) ) - Text(text = text.value, fontSize = 40.sp) + Text(text = text, fontSize = 40.sp) } } } @@ -69,6 +70,8 @@ color according to the mouse pointer position: import androidx.compose.desktop.Window import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -78,18 +81,18 @@ import androidx.compose.ui.input.pointer.pointerMoveFilter import androidx.compose.ui.unit.IntSize fun main() = Window(title = "Compose for Desktop", size = IntSize(400, 400)) { - var color = remember { mutableStateOf(Color(0, 0, 0)) } + var color by remember { mutableStateOf(Color(0, 0, 0)) } Box( - modifier = Modifier - .wrapContentSize(Alignment.Center) - .fillMaxSize() - .background(color = color.value) - .pointerMoveFilter( - onMove = { - color.value = Color(it.x.toInt() % 256, it.y.toInt() % 256, 0) - false - } - ) + modifier = Modifier + .wrapContentSize(Alignment.Center) + .fillMaxSize() + .background(color = color) + .pointerMoveFilter( + onMove = { + color = Color(it.x.toInt() % 256, it.y.toInt() % 256, 0) + false + } + ) ) } ``` @@ -104,6 +107,8 @@ import androidx.compose.desktop.Window import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.Text +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -115,25 +120,28 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp fun main() = Window(title = "Compose for Desktop", size = IntSize(400, 400)) { - Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { + Column( + Modifier.background(Color.White), + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { repeat(10) { index -> - var active = remember { mutableStateOf(false) } + var active by remember { mutableStateOf(false) } Text( modifier = Modifier .fillMaxWidth() - .background(color = if (active.value) Color.Green else Color.White) + .background(color = if (active) Color.Green else Color.White) .pointerMoveFilter( onEnter = { - active.value = true + active = true false }, onExit = { - active.value = false + active = false false } ), fontSize = 30.sp, - fontStyle = if (active.value) FontStyle.Italic else FontStyle.Normal, + fontStyle = if (active) FontStyle.Italic else FontStyle.Normal, text = "Item $index" ) } @@ -144,54 +152,46 @@ fun main() = Window(title = "Compose for Desktop", size = IntSize(400, 400)) { ### Mouse right/middle clicks and keyboard modifiers -While first-class support for pointer type-specific data, like pressed mouse buttons, is still in development in Compose, there is an available raw AWT mouse event object in Compose for Desktop, that can be used as a workaround when you need advanced functionality. +Compose for Desktop contains desktop-only `Modifier.mouseClickable`, where data about pressed mouse buttons and keyboard modifiers is available. This is an experimental API, which means that it's likely to be changed before release. ```kotlin import androidx.compose.desktop.Window -import androidx.compose.foundation.gestures.forEachGesture -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.ExperimentalDesktopApi +import androidx.compose.foundation.mouseClickable import androidx.compose.material.Text import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.input.pointer.AwaitPointerEventScope -import androidx.compose.ui.input.pointer.PointerEvent -import androidx.compose.ui.input.pointer.changedToDown -import androidx.compose.ui.input.pointer.consumeDownChange -import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.IntSize -import java.awt.event.MouseEvent +@OptIn(ExperimentalDesktopApi::class) fun main() = Window(title = "Compose for Desktop", size = IntSize(400, 400)) { - var lastEvent by remember { mutableStateOf(null) } - Column { - Text( - text = "Custom button", - modifier = Modifier.pointerInput(Unit) { - forEachGesture { - awaitPointerEventScope { - lastEvent = awaitEventFirstDown().also { - it.changes.forEach { it.consumeDownChange() } - }.mouseEvent - } + var clickableText by remember { mutableStateOf("Click me!") } + + Text( + modifier = Modifier.mouseClickable( + onClick = { + clickableText = buildString { + append("Buttons pressed:\n") + append("primary: ${buttons.isPrimaryPressed}\t") + append("secondary: ${buttons.isSecondaryPressed}\t") + append("tertiary: ${buttons.isTertiaryPressed}\t") + + append("\n\nKeyboard modifiers pressed:\n") + + append("alt: ${keyboardModifiers.isAltPressed}\t") + append("ctrl: ${keyboardModifiers.isCtrlPressed}\t") + append("meta: ${keyboardModifiers.isMetaPressed}\t") + append("shift: ${keyboardModifiers.isShiftPressed}\t") } } - ) - Text("Mouse event: ${lastEvent?.paramString()}") - } - -} - -private suspend fun AwaitPointerEventScope.awaitEventFirstDown(): PointerEvent { - var event: PointerEvent - do { - event = awaitPointerEvent() - } while ( - !event.changes.all { it.changedToDown() } + ), + text = clickableText ) - return event } ``` -![Application running](mouse_event.gif) \ No newline at end of file +![Application running](mouse_event.gif) + +If you need more information about events there is an available raw AWT mouse event object in `mouseEvent` property of `PointerEvent` \ No newline at end of file diff --git a/tutorials/Mouse_Events/mouse_click.gif b/tutorials/Mouse_Events/mouse_click.gif index af4a909ef6..c9eaa6b08e 100644 Binary files a/tutorials/Mouse_Events/mouse_click.gif and b/tutorials/Mouse_Events/mouse_click.gif differ diff --git a/tutorials/Mouse_Events/mouse_enter.gif b/tutorials/Mouse_Events/mouse_enter.gif index f0f1e17228..cfc625f2b1 100644 Binary files a/tutorials/Mouse_Events/mouse_enter.gif and b/tutorials/Mouse_Events/mouse_enter.gif differ diff --git a/tutorials/Mouse_Events/mouse_event.gif b/tutorials/Mouse_Events/mouse_event.gif index 0cde3989a5..e2b73febbf 100644 Binary files a/tutorials/Mouse_Events/mouse_event.gif and b/tutorials/Mouse_Events/mouse_event.gif differ diff --git a/tutorials/Mouse_Events/mouse_move.gif b/tutorials/Mouse_Events/mouse_move.gif index 7ba17915e9..1ad33e4ed2 100644 Binary files a/tutorials/Mouse_Events/mouse_move.gif and b/tutorials/Mouse_Events/mouse_move.gif differ