Browse Source

Update mouse tutorial (#932)

pull/942/head
Andrew Rudenko 3 years ago committed by GitHub
parent
commit
11464f199e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 116
      tutorials/Mouse_Events/README.md
  2. BIN
      tutorials/Mouse_Events/mouse_click.gif
  3. BIN
      tutorials/Mouse_Events/mouse_enter.gif
  4. BIN
      tutorials/Mouse_Events/mouse_event.gif
  5. BIN
      tutorials/Mouse_Events/mouse_move.gif

116
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<MouseEvent?>(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)
![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`

BIN
tutorials/Mouse_Events/mouse_click.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 110 KiB

BIN
tutorials/Mouse_Events/mouse_enter.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 139 KiB

BIN
tutorials/Mouse_Events/mouse_event.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 889 KiB

After

Width:  |  Height:  |  Size: 61 KiB

BIN
tutorials/Mouse_Events/mouse_move.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 KiB

After

Width:  |  Height:  |  Size: 257 KiB

Loading…
Cancel
Save