-
Notifications
You must be signed in to change notification settings - Fork 137
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
Scrollbar doesn't move if cursor moves outside control while dragging #374
Comments
I put together a quick proof-of-concept fix for this; this is the diff: diff --git a/zircon.core/src/commonMain/kotlin/org/hexworks/zircon/internal/uievent/impl/UIEventToComponentDispatcher.kt b/zircon.core/src/commonMain/kotlin/org/hexworks/zircon/internal/uievent/impl/UIEventToComponentDispatcher.kt
index 8c1e9b180..e0765354a 100644
--- a/zircon.core/src/commonMain/kotlin/org/hexworks/zircon/internal/uievent/impl/UIEventToComponentDispatcher.kt
+++ b/zircon.core/src/commonMain/kotlin/org/hexworks/zircon/internal/uievent/impl/UIEventToComponentDispatcher.kt
@@ -39,6 +39,7 @@ class UIEventToComponentDispatcher(
private var lastMousePosition = Position.unknown()
private var lastHoveredComponent: InternalComponent = root
+ private var lastPressedComponent: InternalComponent? = null
private val shortcutsConfig = RuntimeConfig.config.shortcutsConfig
@@ -192,13 +193,23 @@ class UIEventToComponentDispatcher(
phase: UIEventPhase,
previousResult: UIEventResponse
): UIEventResponse {
+ val realComponent = lastPressedComponent
+ ?.takeIf { phase == TARGET && (event.type == MOUSE_DRAGGED || event.type == MOUSE_RELEASED) }
+ ?: component
var result = previousResult
- result = result.pickByPrecedence(component.process(event, phase))
+ result = result.pickByPrecedence(realComponent.process(event, phase))
if (result.shouldStopPropagation()) {
// logger.debug("Propagation was stopped by component: $component.")
} else if (result.allowsDefaults()) {
// logger.debug("Trying defaults for component $component, with event $event and phase $phase")
- result = result.pickByPrecedence(tryDefaultsFor(component, event, phase))
+ result = result.pickByPrecedence(tryDefaultsFor(realComponent, event, phase))
+ if (phase == TARGET) {
+ if (event.type == MOUSE_PRESSED) {
+ lastPressedComponent = component
+ } else if (lastPressedComponent != null && event.type == MOUSE_RELEASED) {
+ lastPressedComponent = null
+ }
+ }
}
return result
} This works for me -- you can start clicking on the scrollbar and then keep moving even when the cursor has moved outside the control. Thoughts, @adam-arold? In fact, this even works if you move the cursor outside the window, but only for the top and left edges, for some reason. Fixing that is out of scope for this issue and, IMO, low priority anyway. But scrollbars near the right and bottom edge of a windowed game might be significantly affected. There are some weird edge cases I didn't really try to address here. If you start dragging with your left mouse button, and then start dragging with your right mouse button without letting up on the left button...well, maybe it'd work? Hurts to think about. Don't do that 😛 |
I dig this. 👍 I'm pretty sure there are some bugs lurking there, but we'll go through that bridge when we get there. |
Agree that the potential for edge cases not covered here is high. Like if I let go while outside the control, does that work? What if I'm outside the window? Does this impact non-scroll controls in a meaningful way? (though at least on Windows, if you click on a button, then move the mouse somewhere else, then come back to the button and release your click, it'll act as if it was a simple down-up click. So maybe we want this code change to affect everything.) |
We do have a state transition lookup so it shouldn't mess with component states. The logic itself seems sound. I'd merge this then we can play around with the examples and see if something blows up. If the tests pass there is a good chance that this will be OK. |
… to original component. Closes Hexworks#374.
There is one problem with the
ScrollBar
though and I don't know a good solution for this. If you drag the scroll button itself, move it hen move the mouse out of the scroll bar, then it no longer receives mouse events (since the mouse is no longer over it). I think there might be a solution for this somehow using event bubbling, but I'm not 100% sure.Originally posted by @adam-arold in #25 (comment)
The text was updated successfully, but these errors were encountered: