Skip to content

Commit 82bbb73

Browse files
committed
Fixed bind logic
1 parent b758103 commit 82bbb73

File tree

5 files changed

+110
-120
lines changed

5 files changed

+110
-120
lines changed

src/main/kotlin/com/lambda/config/settings/complex/KeybindSetting.kt

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,8 @@ class KeybindSetting(
8181
}
8282

8383
lambdaTooltip {
84-
if (!listening) {
85-
description.ifBlank { "Click to set. Right-click to unbind. Esc cancels. Backspace/Delete unbinds." }
86-
} else {
87-
"Listening… Press a key to bind. Esc to cancel. Backspace/Delete to unbind."
88-
}
89-
}
90-
91-
onItemClick(ImGuiMouseButton.Right) {
92-
value = Bind.EMPTY
93-
listening = false
84+
if (!listening) description.ifBlank { "Click to set. Esc cancels. Backspace/Delete unbinds." }
85+
else "Listening… Press a key to bind. Esc to cancel. Backspace/Delete to unbind."
9486
}
9587

9688
if (listening && !isAnyItemHovered && isMouseClicked(ImGuiMouseButton.Left)) {
@@ -106,25 +98,31 @@ class KeybindSetting(
10698
lambdaTooltip("Clear binding")
10799
}
108100

109-
val keypoll = InputUtils.lastKeyboardEvent ?: return
110-
val mousepoll = InputUtils.lastMouseEvent ?: return
111-
112101
if (listening) {
113-
val isModKey = keypoll.keyCode in GLFW_KEY_LEFT_SHIFT..GLFW_KEY_RIGHT_SUPER
114-
115-
if ((keypoll.isPressed && !isModKey)
116-
|| (keypoll.isReleased && isModKey)
117-
) {
118-
when (keypoll.translated) {
119-
KeyCode.ESCAPE -> {}
120-
KeyCode.BACKSPACE, KeyCode.DELETE -> value = Bind.EMPTY
121-
else -> value = Bind(keypoll.keyCode, keypoll.modifiers, -1)
102+
InputUtils.newMouseEvent()
103+
?.let {
104+
value = Bind(0, it.modifiers, it.button)
105+
listening = false
106+
return
107+
}
108+
109+
InputUtils.newKeyboardEvent()
110+
?.let {
111+
val isModKey = it.keyCode in GLFW_KEY_LEFT_SHIFT..GLFW_KEY_RIGHT_SUPER
112+
113+
// If a mod key is pressed first ignore it unless it was released without any other keys
114+
if ((it.isPressed && !isModKey) || (it.isReleased && isModKey)) {
115+
when (it.translated) {
116+
KeyCode.ESCAPE -> {}
117+
KeyCode.BACKSPACE, KeyCode.DELETE -> value = Bind.EMPTY
118+
else -> value = Bind(it.keyCode, it.modifiers, -1)
119+
}
120+
121+
listening = false
122+
}
123+
124+
return
122125
}
123-
listening = false
124-
} else if (mousepoll.action == Mouse.Action.Click.ordinal) {
125-
value = Bind(0, mousepoll.modifiers, mousepoll.button)
126-
listening = false
127-
}
128126
}
129127
}
130128

@@ -177,16 +175,20 @@ data class Bind(
177175
}
178176

179177
val name: String
180-
get() = buildString {
181-
if (mouse >= 0) append("${Mouse.Button.fromMouseCode(mouse)} + ")
182-
if (modifiers > 0) append("${truemods.joinToString(separator = "+") { it.name }} +")
183-
if (key > 0) append(KeyCode.fromKeyCode(key))
178+
get() {
179+
if (mouse < 0 && modifiers <= 0 && key <= 0) return "Unbound"
180+
181+
val list = mutableListOf<Any>()
182+
183+
if (mouse >= 0) list.add(Mouse.entries[mouse])
184+
if (modifiers > 0) list.add(truemods.joinToString(separator = "+") { it.name })
185+
if (key > 0) list.add(KeyCode.fromKeyCode(key))
184186

185-
if (mouse < 0 && modifiers <= 0 && key <= 0) append("Unbound")
187+
return list.joinToString(separator = "+") { it.toString() }
186188
}
187189

188190
override fun toString() =
189-
"Key Code: $key"
191+
"Key Code: $key, Modifiers: ${truemods.joinToString(separator = "+") { it.name }}, Mouse Button: ${Mouse.entries.getOrNull(mouse) ?: "None"}"
190192

191193
companion object {
192194
val EMPTY = Bind(0, 0)

src/main/kotlin/com/lambda/event/events/KeyboardEvent.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,10 @@ sealed class KeyboardEvent {
5252
val translated: KeyCode
5353
get() = KeyCode.virtualMapUS(keyCode, scanCode)
5454

55-
val isPressed = action == GLFW_PRESS
55+
val isPressed = action >= GLFW_PRESS
5656
val isReleased = action == GLFW_RELEASE
5757

5858
fun satisfies(bind: Bind) = bind.key == keyCode && bind.modifiers == modifiers
59-
60-
val hasShift = modifiers and GLFW_MOD_SHIFT != 0
61-
val hasControl = modifiers and GLFW_MOD_CONTROL != 0
62-
val hasAlt = modifiers and GLFW_MOD_ALT != 0
63-
val hasSuper = modifiers and GLFW_MOD_SUPER != 0
64-
val hasCapsLock = modifiers and GLFW_MOD_CAPS_LOCK != 0
65-
val hasNumLock = modifiers and GLFW_MOD_NUM_LOCK != 0
6659
}
6760

6861
/**

src/main/kotlin/com/lambda/event/events/MouseEvent.kt

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,38 +36,16 @@ sealed class MouseEvent {
3636
* @property button The button that was clicked
3737
* @property action The action performed (e.g., press or release)
3838
* @property modifiers An integer representing any modifiers (e.g., shift or ctrl) active during the event
39-
* @property position The x and y position of the mouse on the screen
4039
*/
4140
data class Click(
4241
val button: Int,
4342
val action: Int,
4443
val modifiers: Int,
45-
val position: Vec2d,
4644
) : ICancellable by Cancellable() {
47-
constructor(button: Mouse.Button, action: Mouse.Action, modifiers: Int, position: Vec2d) : this(
48-
button.ordinal,
49-
action.ordinal,
50-
modifiers,
51-
position
52-
)
53-
54-
fun satisfies(bind: Bind) = bind.modifiers == modifiers && bind.mouse == button
55-
5645
val isReleased = action == 0
5746
val isPressed = action == 1
5847

59-
val isMainButton = button <= 2
60-
val isSideButton = button > 2
61-
val isLeftButton = button == 0
62-
val isRightButton = button == 1
63-
val isMiddleButton = button == 2
64-
65-
val hasShift = hasModifier(GLFW_MOD_SHIFT)
66-
val hasControl = hasModifier(GLFW_MOD_CONTROL)
67-
val hasAlt = hasModifier(GLFW_MOD_ALT)
68-
val hasSuper = hasModifier(GLFW_MOD_SUPER)
69-
val hasCapsLock = hasModifier(GLFW_MOD_CAPS_LOCK)
70-
val hasNumLock = hasModifier(GLFW_MOD_NUM_LOCK)
48+
fun satisfies(bind: Bind) = bind.modifiers == modifiers && bind.mouse == button
7149

7250
fun hasModifier(mod: Int) = modifiers and mod == mod
7351
}

src/main/kotlin/com/lambda/util/InputUtils.kt

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,81 @@
1717

1818
package com.lambda.util
1919

20+
import com.lambda.Lambda.mc
2021
import com.lambda.context.SafeContext
2122
import com.lambda.core.Loadable
2223
import com.lambda.event.events.KeyboardEvent
2324
import com.lambda.event.events.MouseEvent
24-
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
25-
import com.lambda.util.math.Vec2d
26-
import net.minecraft.client.util.InputUtil
25+
import org.lwjgl.glfw.GLFW
26+
import org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_ALT
27+
import org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_CONTROL
28+
import org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_SHIFT
29+
import org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_SUPER
30+
import org.lwjgl.glfw.GLFW.GLFW_KEY_RIGHT_ALT
31+
import org.lwjgl.glfw.GLFW.GLFW_KEY_RIGHT_CONTROL
32+
import org.lwjgl.glfw.GLFW.GLFW_KEY_RIGHT_SHIFT
33+
import org.lwjgl.glfw.GLFW.GLFW_KEY_RIGHT_SUPER
34+
import org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_1
35+
import org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_8
36+
import org.lwjgl.glfw.GLFW.GLFW_PRESS
37+
import org.lwjgl.glfw.GLFW.glfwGetKey
38+
import org.lwjgl.glfw.GLFW.glfwGetMouseButton
2739

2840
object InputUtils : Loadable {
29-
var lastKeyboardEvent: KeyboardEvent.Press? = null; private set
30-
var lastMouseEvent: MouseEvent.Click? = null; private set
41+
private val keys = KeyCode.entries.map { it.code }
42+
private val scancodes = keys.associateWith { GLFW.glfwGetKeyScancode(it) }
43+
44+
private val mouses = GLFW_MOUSE_BUTTON_1..GLFW_MOUSE_BUTTON_8
45+
46+
private val modMap = mapOf(
47+
GLFW_KEY_LEFT_SHIFT to 0x1,
48+
GLFW_KEY_RIGHT_SHIFT to 0x1,
49+
GLFW_KEY_LEFT_CONTROL to 0x2,
50+
GLFW_KEY_RIGHT_CONTROL to 0x2,
51+
GLFW_KEY_LEFT_ALT to 0x4,
52+
GLFW_KEY_RIGHT_ALT to 0x4,
53+
GLFW_KEY_LEFT_SUPER to 0x8,
54+
GLFW_KEY_RIGHT_SUPER to 0x8,
55+
)
3156

3257
/**
3358
* Returns whether any of the key-codes (not scan-codes) are being pressed
3459
*/
3560
fun SafeContext.isKeyPressed(vararg keys: Int) =
36-
keys.any { InputUtil.isKeyPressed(mc.window.handle, it) }
61+
keys.any { glfwGetKey(mc.window.handle, it) >= GLFW_PRESS }
62+
63+
/**
64+
* Creates a new event from the currently pressed keys
65+
*/
66+
fun newKeyboardEvent(): KeyboardEvent.Press? {
67+
val pressedKeys = keys
68+
.associateWith { glfwGetKey(mc.window.handle, it) }
69+
.filter { (_, state) -> state >= GLFW_PRESS }
70+
71+
val mods = pressedKeys.keys
72+
.filter { it in GLFW_KEY_LEFT_SHIFT..GLFW_KEY_RIGHT_SUPER }
73+
.foldRight(0) { v, acc -> acc or modMap.getValue(v) }
74+
75+
val key = pressedKeys
76+
.firstNotNullOfOrNull { (key, state) -> key to state } ?: return null
77+
78+
val scancode = scancodes.getValue(key.first)
79+
80+
return KeyboardEvent.Press(key.first, scancode, key.second, mods)
81+
}
82+
83+
/**
84+
* Creates a new mouse event from the current glfw states.
85+
*/
86+
fun newMouseEvent(): MouseEvent.Click? {
87+
val mods = (GLFW_KEY_LEFT_SHIFT..GLFW_KEY_RIGHT_SUPER)
88+
.filter { glfwGetKey(mc.window.handle, it) >= GLFW_PRESS }
89+
.foldRight(0) { v, acc -> acc or modMap.getValue(v) }
90+
91+
val mouse = mouses
92+
.firstOrNull { glfwGetMouseButton(mc.window.handle, it) == GLFW_PRESS }
93+
?: return null
3794

38-
init {
39-
// hacking imgui jni lib rn because it's missing a lot of native functions including i/o stuff
40-
listenUnsafe<KeyboardEvent.Press> { lastKeyboardEvent = it }
41-
listenUnsafe<MouseEvent.Click> { lastMouseEvent = it }
95+
return MouseEvent.Click(mouse, GLFW_PRESS, mods)
4296
}
4397
}

src/main/kotlin/com/lambda/util/Mouse.kt

Lines changed: 9 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,50 +17,13 @@
1717

1818
package com.lambda.util
1919

20-
import org.lwjgl.glfw.GLFW
21-
22-
class Mouse {
23-
enum class Button {
24-
Left,
25-
Right,
26-
Middle,
27-
Button4,
28-
Button5,
29-
Button6,
30-
Button7,
31-
Button8;
32-
33-
val isMainButton get() = ordinal == GLFW.GLFW_MOUSE_BUTTON_LEFT || ordinal == GLFW.GLFW_MOUSE_BUTTON_RIGHT
34-
35-
companion object {
36-
private val mouseCodeMap = entries.associateBy { it.ordinal }
37-
private val nameMap = entries.associateBy { it.name.lowercase() }
38-
39-
@Throws(IllegalArgumentException::class)
40-
fun fromMouseCode(code: Int) =
41-
mouseCodeMap[code] ?: throw IllegalArgumentException("Mouse code $code not found in mouseCodeMap.")
42-
43-
@Throws(IllegalArgumentException::class)
44-
fun fromMouseName(name: String) =
45-
nameMap[name.lowercase()] ?: throw IllegalArgumentException("Mouse name '$name' not found in nameMap.")
46-
}
47-
}
48-
49-
enum class Action {
50-
Release,
51-
Click;
52-
53-
companion object {
54-
private val mouseActionMap = entries.associateBy { it.ordinal }
55-
private val nameMap = entries.associateBy { it.name.lowercase() }
56-
57-
@Throws(IllegalArgumentException::class)
58-
fun fromActionCode(code: Int) =
59-
mouseActionMap[code] ?: throw IllegalArgumentException("Action code $code not found in mouseActionMap.")
60-
61-
@Throws(IllegalArgumentException::class)
62-
fun fromActionName(name: String) =
63-
nameMap[name.lowercase()] ?: throw IllegalArgumentException("Action name '$name' not found in nameMap.")
64-
}
65-
}
20+
enum class Mouse {
21+
Left,
22+
Right,
23+
Middle,
24+
Button4,
25+
Button5,
26+
Button6,
27+
Button7,
28+
Button8;
6629
}

0 commit comments

Comments
 (0)