UScreen: improved input handling (via optional interface) - #125
UScreen: improved input handling (via optional interface)#125Traben-0 wants to merge 62 commits into
Conversation
Linear: EM-1645
Linear: EM-1645
…via-esc-on-119-puts-you-in-the-menu-rather' into feature/em-1645-closing-uscreen-via-esc-on-119-puts-you-in-the-menu-rather # Conflicts: # src/main/kotlin/gg/essential/universal/UScreen.kt
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Johni0702
left a comment
There was a problem hiding this comment.
Looking at the integration in Elementa has given me two more ideas.
Linear: EM-1645
Linear: EM-1645
…via-esc-on-119-puts-you-in-the-menu-rather' into feature/em-1645-closing-uscreen-via-esc-on-119-puts-you-in-the-menu-rather
Johni0702
left a comment
There was a problem hiding this comment.
Looks good to me again, but let's wait with merging until we've got the whole stack (UC+Elementa+Essential) done, in case we find more stuff that should be changed along the way.
Linear: EM-1645
… modifiers Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
Linear: EM-1645
| // Must be called with consistently scaled scroll deltas on all mc/lwjgl versions. | ||
| // This is to ensure a consistent scrolling experience across all versions. | ||
| // See onMouseScrolled(Double) for further explanation. | ||
| fun uMouseScrolled(x: Double, y: Double, scrollX: Double, scrollY: Double): Boolean = |
There was a problem hiding this comment.
Thought: I know MC doesn't provide them for scrolling, but should we maybe supply modifiers here for consistency on our end?
There was a problem hiding this comment.
elementa has atleast 3 calls to check modifier key presses via UKeyboard.is*KeyDown() in scroll events, so there is a precedent for needing them.
Granted there is currently no technical different between supplying UKeyboard.getKeyModifiers() here and using the UKeyboard.is*KeyDown() further within the events, other than the mentioned consistency between the mouse events.
Would also cover us if MC ever added them.
There was a problem hiding this comment.
Good call. Yeah, I think that would make sense.
GLFW doesn't currently provide that info, but there's an issue for it, which suggests that it should be possible. That issue hasn't been closed yet, and I see no conceptual reason to pass the modifiers with scroll events (like there are in case of the charType events), so I can see no reason for us not to already include it in our API.
| else isControlKeyDown() | ||
|
|
||
| @JvmStatic | ||
| fun isCommandKeyDown(): Boolean = isKeyDown(KEY_LMETA) || isKeyDown(KEY_RMETA) |
There was a problem hiding this comment.
suggestion: Would call this isSuperKeyDown, for consistency with our Modifier.isSuper.
That, or isMetaKeyDown, since that's what we call our KEY_ constants. But I think staying consistent with the new stuff (and lwjgl3, which also calls them GLFW_KEY_LEFT/RIGHT_SUPER) is better here.
I don't think we're calling it Command anywhere else.
|
|
||
| @JvmStatic | ||
| fun isKeyComboCtrlA(key: Int): Boolean = key == KEY_A && isCtrlKeyDown() && !isShiftKeyDown() && !isAltKeyDown() | ||
| fun getKeyModifiers(): Modifiers = Modifiers(isControlKeyDown(), isShiftKeyDown(), isAltKeyDown(), isCommandKeyDown()) |
There was a problem hiding this comment.
thought: Not sure we should even provide this new variant of the getModifiers method.
You usually shouldn't be using getModifiers anyway because it depends on global state. You should be using the Modifiers instance that comes with your mouseClick/etc. call.
| data class Modifiers(val isCtrl: Boolean, val isShift: Boolean, val isAlt: Boolean) | ||
| data class Modifiers( | ||
| val isCtrl: Boolean, | ||
| val isShift: Boolean, | ||
| val isAlt: Boolean, | ||
| val isSuper: Boolean, | ||
| ) { |
There was a problem hiding this comment.
issue: Breaking change. Also need to supply a three-args copy method. See the red lines in the .api file diff.
| it.uCharTyped(typedChar.code) | ||
| } | ||
| } ?: @Suppress("DEPRECATION") onKeyPressed(keyCode, typedChar, UKeyboard.getModifiers()) | ||
| } ?: @Suppress("DEPRECATION") onKeyPressed(keyCode, typedChar, UKeyboard.getKeyModifiers()) |
There was a problem hiding this comment.
issue: Breaking change. We must only change the modifier we pass to the new methods, we must not change the ones we pass to the old methods because people might already be relying on that behavior.
| final override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { | ||
| inputHandler?.uMouseClicked(mouseX.restoreFrac(UMouse.Scaled.x), mouseY.restoreFrac(UMouse.Scaled.y), mouseButton, UKeyboard.getModifiers()) | ||
| inputHandler?.uMouseClicked(mouseX.restoreFrac(UMouse.Scaled.x), mouseY.restoreFrac(UMouse.Scaled.y), mouseButton, UKeyboard.getKeyModifiers()) | ||
| ?: @Suppress("DEPRECATION") onMouseClicked(mouseX.toDouble(), mouseY.toDouble(), mouseButton) | ||
| } | ||
|
|
||
| final override fun mouseReleased(mouseX: Int, mouseY: Int, state: Int) { | ||
| inputHandler?.uMouseReleased(mouseX.restoreFrac(UMouse.Scaled.x), mouseY.restoreFrac(UMouse.Scaled.y), state, UKeyboard.getModifiers()) | ||
| inputHandler?.uMouseReleased(mouseX.restoreFrac(UMouse.Scaled.x), mouseY.restoreFrac(UMouse.Scaled.y), state, UKeyboard.getKeyModifiers()) | ||
| ?: @Suppress("DEPRECATION") onMouseReleased(mouseX.toDouble(), mouseY.toDouble(), state) | ||
| } | ||
|
|
||
| final override fun mouseClickMove(mouseX: Int, mouseY: Int, clickedMouseButton: Int, timeSinceLastClick: Long) { | ||
| inputHandler?.uMouseDragged(mouseX.restoreFrac(UMouse.Scaled.x), mouseY.restoreFrac(UMouse.Scaled.y), clickedMouseButton, UKeyboard.getModifiers()) | ||
| inputHandler?.uMouseDragged(mouseX.restoreFrac(UMouse.Scaled.x), mouseY.restoreFrac(UMouse.Scaled.y), clickedMouseButton, UKeyboard.getKeyModifiers()) | ||
| ?: @Suppress("DEPRECATION") onMouseDragged(mouseX.toDouble(), mouseY.toDouble(), clickedMouseButton, timeSinceLastClick) | ||
| } |
There was a problem hiding this comment.
issue: Each of these has a pre-processed version that needs to be updated as well.
| val isOSModifier = if (UMinecraft.isRunningOnMac) isSuper else isCtrl | ||
| fun isPlatformModifierActive() = | ||
| if (UMinecraft.isRunningOnMac) isSuper && !isShift && !isAlt && !isCtrl | ||
| else isCtrl && !isShift && !isAlt && !isSuper |
There was a problem hiding this comment.
question: What's the motivation for this rename?
I personally prefer OS over Platform.
Platform is usually what we call the underlying Minecraft version (or standalone UC framework).
I'm also not convinced we should have the ModifierActive suffix. It's inconsistent with all the other properties (though admittedly this one also works somewhat differently, although not that differently).
The Modifier is somewhat redundant because it's in the Modifiers class and will usually be called like modifiers.isPlatformModifierActive().
The Active assumes that this class is only used for the active modifiers. That's not strictly necessary though. This class could also be used for other purposes (e.g. storing the modifiers for a set of keybindings). I suppose one could still say that the modifier is active for that keybind then, but it just feels a bit off.
question: What's the motivation for this being a function rather than a property now?
question: What's the motivation for checking that other modifiers aren't pressed?
While I suppose this is a common thing one might want when checking for common shortcut combos, it does prevent one from easily recognizing shortcuts which use multiple modifiers.
So maybe should be provided as a separate option, in addition to the basic one.
Edit: Ah, third question is answered by the next commit.
new implementation based on feedback from DJ's old PR
Old pr: #52
Internal issue reference: EM-1645