-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-show the tooltip on mouse-move following a click in TooltipArea. #1209
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,9 +26,7 @@ import androidx.compose.runtime.setValue | |
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.ExperimentalComposeUiApi | ||
import androidx.compose.ui.geometry.Offset | ||
import androidx.compose.ui.input.pointer.changedToDown | ||
import androidx.compose.ui.input.pointer.PointerEventPass | ||
import androidx.compose.ui.input.pointer.PointerInputScope | ||
import androidx.compose.ui.input.pointer.pointerInput | ||
import androidx.compose.ui.layout.onGloballyPositioned | ||
import androidx.compose.ui.layout.positionInWindow | ||
|
@@ -37,14 +35,14 @@ import androidx.compose.ui.geometry.Rect | |
import androidx.compose.ui.input.pointer.AwaitPointerEventScope | ||
import androidx.compose.ui.input.pointer.PointerEvent | ||
import androidx.compose.ui.input.pointer.PointerEventType | ||
import androidx.compose.ui.input.pointer.areAnyPressed | ||
import androidx.compose.ui.layout.boundsInWindow | ||
import androidx.compose.ui.unit.Dp | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.unit.DpOffset | ||
import androidx.compose.ui.window.Popup | ||
import androidx.compose.ui.window.PopupPositionProvider | ||
import androidx.compose.ui.window.rememberPopupPositionProviderAtPosition | ||
import androidx.compose.ui.window.rememberCursorPositionProvider | ||
import androidx.compose.ui.window.rememberComponentRectPositionProvider | ||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.Job | ||
|
@@ -105,14 +103,15 @@ fun TooltipArea( | |
content: @Composable () -> Unit | ||
) { | ||
var parentBounds by remember { mutableStateOf(Rect.Zero) } | ||
var popupPosition by remember { mutableStateOf(Offset.Zero) } | ||
var cursorPosition by remember { mutableStateOf(Offset.Zero) } | ||
var isVisible by remember { mutableStateOf(false) } | ||
val scope = rememberCoroutineScope() | ||
var job: Job? by remember { mutableStateOf(null) } | ||
|
||
fun startShowing() { | ||
job?.cancel() | ||
if (job?.isActive == true) { // Don't restart the job if it's already active | ||
return | ||
} | ||
job = scope.launch { | ||
delay(delayMillis.toLong()) | ||
isVisible = true | ||
|
@@ -121,6 +120,7 @@ fun TooltipArea( | |
|
||
fun hide() { | ||
job?.cancel() | ||
job = null | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because why not. |
||
isVisible = false | ||
} | ||
|
||
|
@@ -135,19 +135,21 @@ fun TooltipArea( | |
.onGloballyPositioned { parentBounds = it.boundsInWindow() } | ||
.onPointerEvent(PointerEventType.Enter) { | ||
cursorPosition = it.position | ||
startShowing() | ||
if (!isVisible && !it.buttons.areAnyPressed) { | ||
startShowing() | ||
} | ||
Comment on lines
+138
to
+140
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This fixes the case of press -> exit -> enter |
||
} | ||
.onPointerEvent(PointerEventType.Move) { | ||
cursorPosition = it.position | ||
hideIfNotHovered(parentBounds.topLeft + it.position) | ||
igordmn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!isVisible && !it.buttons.areAnyPressed) { | ||
startShowing() | ||
} | ||
Comment on lines
+144
to
+146
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re-show the tooltip on mouse-move (but no buttons pressed). |
||
} | ||
.onPointerEvent(PointerEventType.Exit) { | ||
hideIfNotHovered(parentBounds.topLeft + it.position) | ||
} | ||
.pointerInput(Unit) { | ||
detectDown { | ||
hide() | ||
} | ||
.onPointerEvent(PointerEventType.Press, pass = PointerEventPass.Initial) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know, but it was in the code already, so I decided not to change it just in case. |
||
hide() | ||
Comment on lines
-147
to
+152
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why there was a need for a custom implementation here. |
||
} | ||
) { | ||
content() | ||
|
@@ -157,6 +159,7 @@ fun TooltipArea( | |
popupPositionProvider = tooltipPlacement.positionProvider(cursorPosition), | ||
onDismissRequest = { isVisible = false } | ||
) { | ||
var popupPosition by remember { mutableStateOf(Offset.Zero) } | ||
Box( | ||
Modifier | ||
.onGloballyPositioned { popupPosition = it.positionInWindow() } | ||
|
@@ -191,18 +194,6 @@ private fun Modifier.onPointerEvent( | |
} | ||
} | ||
|
||
private suspend fun PointerInputScope.detectDown(onDown: (Offset) -> Unit) { | ||
while (true) { | ||
awaitPointerEventScope { | ||
val event = awaitPointerEvent(PointerEventPass.Initial) | ||
val down = event.changes.find { it.changedToDown() } | ||
if (down != null) { | ||
onDown(down.position) | ||
} | ||
} | ||
} | ||
} | ||
|
||
Comment on lines
-194
to
-205
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why this was needed, and in any case it's buggy - you're supposed to put the |
||
/** | ||
* An interface for providing a [PopupPositionProvider] for the tooltip. | ||
*/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed because this function is now potentially called on every mouse-move, and we don't want to restart the timer.