mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 09:56:37 -04:00
wip input manager refactor + tests
This commit is contained in:
parent
e3666c80bd
commit
50045e8c70
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input.key.manager.binding.actions
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||
import de.bixilon.kutil.reflection.ReflectionUtil.forceSet
|
||||
import de.bixilon.minosoft.config.key.KeyActions
|
||||
import de.bixilon.minosoft.config.key.KeyBinding
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.BindingsManager
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.KeyBindingFilterState
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.KeyBindingState
|
||||
import de.bixilon.minosoft.test.IT.OBJENESIS
|
||||
import org.testng.Assert.assertFalse
|
||||
import org.testng.Assert.assertTrue
|
||||
import org.testng.annotations.Test
|
||||
|
||||
|
||||
val keysPressed = InputManager::class.java.getDeclaredField("pressed").apply { isAccessible = true }
|
||||
val bindingsPressed = BindingsManager::class.java.getDeclaredField("pressed").apply { isAccessible = true }
|
||||
val name = minosoft("dummy")
|
||||
|
||||
fun input(): InputManager {
|
||||
val manager = OBJENESIS.newInstance(InputManager::class.java)
|
||||
val bindings = OBJENESIS.newInstance(BindingsManager::class.java)
|
||||
bindingsPressed[bindings] = mutableSetOf<ResourceLocation>()
|
||||
manager::bindings.forceSet(bindings)
|
||||
|
||||
keysPressed[manager] = mutableSetOf<KeyCodes>()
|
||||
|
||||
return manager
|
||||
}
|
||||
|
||||
@Test(groups = ["input"])
|
||||
class Press {
|
||||
|
||||
fun `simple press`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Press.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.PRESS to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.satisfied)
|
||||
}
|
||||
|
||||
fun `wrong key`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Press.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.PRESS to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.satisfied)
|
||||
}
|
||||
|
||||
fun `multiple keys`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Press.check(
|
||||
state, setOf(KeyCodes.KEY_0, KeyCodes.KEY_1, KeyCodes.KEY_2), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.PRESS to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.result)
|
||||
}
|
||||
|
||||
fun `not pressed`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Press.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.PRESS to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.satisfied)
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = ["input"])
|
||||
class Release {
|
||||
|
||||
fun `simple release`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Release.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.RELEASE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.result)
|
||||
assertTrue(state.satisfied)
|
||||
}
|
||||
|
||||
fun `wrong key`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Release.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.RELEASE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.satisfied)
|
||||
}
|
||||
|
||||
fun `multiple keys`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Release.check(
|
||||
state, setOf(KeyCodes.KEY_0, KeyCodes.KEY_1, KeyCodes.KEY_2), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.RELEASE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.satisfied)
|
||||
}
|
||||
|
||||
fun pressed() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Release.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.RELEASE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.satisfied)
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = ["input"])
|
||||
class Change {
|
||||
|
||||
fun `simple press`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Change.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.CHANGE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.satisfied)
|
||||
assertTrue(state.forceNotify)
|
||||
}
|
||||
|
||||
fun `simple release`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Change.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.CHANGE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.satisfied)
|
||||
assertTrue(state.forceNotify)
|
||||
}
|
||||
|
||||
fun `wrong key`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Change.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.CHANGE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.satisfied)
|
||||
assertFalse(state.forceNotify)
|
||||
}
|
||||
|
||||
fun `multiple keys`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Change.check(
|
||||
state, setOf(KeyCodes.KEY_0, KeyCodes.KEY_1, KeyCodes.KEY_2), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.CHANGE to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.satisfied)
|
||||
assertTrue(state.forceNotify)
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = ["input"])
|
||||
class Modifier {
|
||||
|
||||
fun `simple press`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Modifier.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.MODIFIER to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.skip)
|
||||
assertTrue(state.satisfied)
|
||||
}
|
||||
|
||||
fun `simple release`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Modifier.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.MODIFIER to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.skip)
|
||||
assertFalse(state.satisfied)
|
||||
}
|
||||
|
||||
fun `wrong key`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Modifier.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.MODIFIER to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.skip)
|
||||
}
|
||||
|
||||
fun `multiple keys, not all pressed`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
KeyActionFilter.Modifier.check(
|
||||
state, setOf(KeyCodes.KEY_0, KeyCodes.KEY_1, KeyCodes.KEY_2), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.MODIFIER to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.satisfied)
|
||||
}
|
||||
|
||||
fun `multiple keys, all pressed`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
val input = input()
|
||||
val pressed = keysPressed.get(input).unsafeCast<MutableSet<KeyCodes>>()
|
||||
pressed += KeyCodes.KEY_0
|
||||
pressed += KeyCodes.KEY_1
|
||||
pressed += KeyCodes.KEY_2
|
||||
|
||||
KeyActionFilter.Modifier.check(
|
||||
state, setOf(KeyCodes.KEY_0, KeyCodes.KEY_1, KeyCodes.KEY_2), input, name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.MODIFIER to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_1,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.satisfied)
|
||||
assertFalse(state.skip)
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = ["input"])
|
||||
class Sticky {
|
||||
|
||||
fun `press key`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Sticky.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.STICKY to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.result)
|
||||
assertFalse(state.skip)
|
||||
assertTrue(state.satisfied)
|
||||
}
|
||||
|
||||
fun `release key`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Sticky.check(
|
||||
state, setOf(KeyCodes.KEY_0), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.STICKY to setOf(KeyCodes.KEY_0)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = false,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.skip)
|
||||
}
|
||||
|
||||
fun `wrong key`() {
|
||||
val state = KeyBindingFilterState(false)
|
||||
KeyActionFilter.Sticky.check(
|
||||
state, setOf(KeyCodes.KEY_1), input(), name,
|
||||
KeyBindingState(KeyBinding(mapOf(KeyActions.STICKY to setOf(KeyCodes.KEY_1)))),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertTrue(state.skip)
|
||||
}
|
||||
|
||||
fun `unpress`() {
|
||||
val state = KeyBindingFilterState(true)
|
||||
val input = input()
|
||||
val binding = KeyBinding(mapOf(KeyActions.STICKY to setOf(KeyCodes.KEY_0)))
|
||||
|
||||
val pressed = bindingsPressed[input.bindings].unsafeCast<MutableSet<ResourceLocation>>()
|
||||
pressed += name
|
||||
|
||||
KeyActionFilter.Sticky.check(
|
||||
state, setOf(KeyCodes.KEY_0), input, name,
|
||||
KeyBindingState(binding),
|
||||
KeyCodes.KEY_0,
|
||||
pressed = true,
|
||||
0L,
|
||||
)
|
||||
|
||||
assertFalse(state.result)
|
||||
assertFalse(state.skip)
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ class ViewManager(private val camera: Camera) {
|
||||
|
||||
|
||||
fun init() {
|
||||
camera.context.input.registerKeyCallback(
|
||||
camera.context.input.bindings.register(
|
||||
"minosoft:camera_debug_view".toResourceLocation(),
|
||||
KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
@ -48,7 +48,7 @@ class ViewManager(private val camera: Camera) {
|
||||
camera.context.connection.util.sendDebugMessage("Camera debug view: ${it.format()}")
|
||||
}
|
||||
|
||||
camera.context.input.registerKeyCallback(
|
||||
camera.context.input.bindings.register(
|
||||
"minosoft:camera_third_person".toResourceLocation(),
|
||||
KeyBinding(
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_F5),
|
||||
|
@ -78,12 +78,12 @@ class EntityRenderer(
|
||||
profile.hitbox::enabled.observe(this) { this.hitboxes = it }
|
||||
context.camera.offset::offset.observe(this) { reset = true }
|
||||
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
HITBOX_TOGGLE_KEY_COMBINATION,
|
||||
KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_B),
|
||||
), defaultPressed = profile.hitbox.enabled
|
||||
), pressed = profile.hitbox.enabled
|
||||
) {
|
||||
profile.hitbox.enabled = it
|
||||
connection.util.sendDebugMessage("Entity hit boxes: ${it.format()}")
|
||||
|
@ -33,7 +33,7 @@ class FunEffectManager(
|
||||
|
||||
|
||||
init {
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
"minosoft:switch_fun_settings".toResourceLocation(),
|
||||
KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
|
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.latch.AbstractLatch
|
||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||
import de.bixilon.kutil.observer.DataObserver.Companion.observed
|
||||
@ -120,11 +119,11 @@ class GUIRenderer(
|
||||
return popper.onCharPress(char) || dragged.onCharPress(char) || gui.onCharPress(char)
|
||||
}
|
||||
|
||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
||||
return popper.onKey(type, key) || dragged.onKey(type, key) || gui.onKey(type, key)
|
||||
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||
return popper.onKey(code, change) || dragged.onKey(code, change) || gui.onKey(code, change)
|
||||
}
|
||||
|
||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||
return popper.onScroll(scrollOffset) || dragged.onScroll(scrollOffset) || gui.onScroll(scrollOffset)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.elements.text
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedListOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedList
|
||||
import de.bixilon.kutil.time.TimeUtil.millis
|
||||
@ -93,7 +92,7 @@ open class TextFlowElement(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2): Boolean {
|
||||
this.scrollOffset += scrollOffset.y.toInt()
|
||||
return true
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
|
||||
@ -72,7 +71,7 @@ interface AbstractLayout<T : Element> : InputElement, DragTarget {
|
||||
return activeElement?.onCharPress(char) ?: false
|
||||
}
|
||||
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2): Boolean {
|
||||
val (element, offset) = getAt(position) ?: return false
|
||||
return element.onScroll(offset, scrollOffset)
|
||||
}
|
||||
@ -104,7 +103,7 @@ interface AbstractLayout<T : Element> : InputElement, DragTarget {
|
||||
return activeDragElement?.onDragLeave(draggable)
|
||||
}
|
||||
|
||||
override fun onDragScroll(position: Vec2, scrollOffset: Vec2d, draggable: Dragged): Element? {
|
||||
override fun onDragScroll(position: Vec2, scrollOffset: Vec2, draggable: Dragged): Element? {
|
||||
val (element, offset) = getAt(position) ?: return null
|
||||
return element.onDragScroll(offset, scrollOffset, draggable)
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
|
||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||
@ -71,7 +70,7 @@ class GUIManager(
|
||||
}
|
||||
|
||||
override fun postInit() {
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
"minosoft:back".toResourceLocation(),
|
||||
KeyBinding(
|
||||
KeyActions.RELEASE to setOf(KeyCodes.KEY_ESCAPE),
|
||||
@ -210,11 +209,11 @@ class GUIManager(
|
||||
return runForEach { it.onMouseMove(position) }
|
||||
}
|
||||
|
||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
||||
return runForEach { it.onKey(type, key) }
|
||||
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||
return runForEach { it.onKey(code, change) }
|
||||
}
|
||||
|
||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||
return runForEach { it.onScroll(scrollOffset) }
|
||||
}
|
||||
|
||||
@ -240,7 +239,7 @@ class GUIManager(
|
||||
return runForEachDrag { it.onDragKey(type, key, dragged) }
|
||||
}
|
||||
|
||||
override fun onDragScroll(scrollOffset: Vec2d, dragged: Dragged): Element? {
|
||||
override fun onDragScroll(scrollOffset: Vec2, dragged: Dragged): Element? {
|
||||
return runForEachDrag { it.onDragScroll(scrollOffset, dragged) }
|
||||
}
|
||||
|
||||
@ -266,7 +265,7 @@ class GUIManager(
|
||||
|
||||
private fun _push(element: GUIElement) {
|
||||
if (elementOrder.isEmpty()) {
|
||||
context.input.inputHandler = guiRenderer
|
||||
context.input.handler.handler = guiRenderer
|
||||
}
|
||||
orderLock.acquire()
|
||||
val copy = elementOrder.toList()
|
||||
@ -313,7 +312,7 @@ class GUIManager(
|
||||
|
||||
orderLock.acquire()
|
||||
if (elementOrder.isEmpty()) {
|
||||
context.input.inputHandler = null
|
||||
context.input.handler.handler = null
|
||||
guiRenderer.popper.clear()
|
||||
guiRenderer.dragged.element = null
|
||||
}
|
||||
@ -337,7 +336,7 @@ class GUIManager(
|
||||
toPop.onClose()
|
||||
orderLock.acquire()
|
||||
if (elementOrder.isEmpty()) {
|
||||
context.input.inputHandler = null
|
||||
context.input.handler.handler = null
|
||||
guiRenderer.popper.clear()
|
||||
guiRenderer.dragged.element = null
|
||||
orderLock.release()
|
||||
@ -365,7 +364,7 @@ class GUIManager(
|
||||
orderLock.unlock()
|
||||
guiRenderer.popper.clear()
|
||||
guiRenderer.dragged.element = null
|
||||
context.input.inputHandler = null
|
||||
context.input.handler.handler = null
|
||||
}
|
||||
|
||||
operator fun <T : GUIElement> get(builder: GUIBuilder<T>): T {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.time.TimeUtil.millis
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
@ -147,16 +146,16 @@ open class GUIMeshElement<T : Element>(
|
||||
return element.onMouseMove(position, position)
|
||||
}
|
||||
|
||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
||||
val mouseButton = MouseButtons[key] ?: return element.onKey(key, type)
|
||||
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||
val mouseButton = MouseButtons[code] ?: return element.onKey(code, change)
|
||||
val position = Vec2(lastPosition ?: return false)
|
||||
|
||||
val mouseAction = MouseActions[type] ?: return false
|
||||
val mouseAction = MouseActions[change] ?: return false
|
||||
|
||||
return element.onMouseAction(position, mouseButton, mouseAction, clickCounter.getClicks(mouseButton, mouseAction, position, millis()))
|
||||
}
|
||||
|
||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||
val position = Vec2(lastPosition ?: return false)
|
||||
return element.onScroll(position, scrollOffset)
|
||||
}
|
||||
@ -179,7 +178,7 @@ open class GUIMeshElement<T : Element>(
|
||||
return element.onDragMouseAction(position, mouseButton, mouseAction, clickCounter.getClicks(mouseButton, mouseAction, position, millis()), dragged)
|
||||
}
|
||||
|
||||
override fun onDragScroll(scrollOffset: Vec2d, dragged: Dragged): Element? {
|
||||
override fun onDragScroll(scrollOffset: Vec2, dragged: Dragged): Element? {
|
||||
return element.onDragScroll(Vec2(lastDragPosition ?: return null), scrollOffset, dragged)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui.dragged
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
@ -31,7 +30,7 @@ abstract class Dragged(guiRenderer: GUIRenderer) : Element(guiRenderer) {
|
||||
open fun onDragMove(position: Vec2, target: Element?) = Unit
|
||||
open fun onDragEnd(position: Vec2, target: Element?) = Unit
|
||||
|
||||
open fun onDragScroll(position: Vec2, scrollOffset: Vec2d, target: Element?) = Unit
|
||||
open fun onDragScroll(position: Vec2, scrollOffset: Vec2, target: Element?) = Unit
|
||||
|
||||
open fun onDragMouseAction(position: Vec2, button: MouseButtons, action: MouseActions, count: Int, target: Element?) = Unit
|
||||
open fun onDragKey(key: KeyCodes, type: KeyChangeTypes, target: Element?) = Unit
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui.dragged
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.time.TimeUtil.millis
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||
@ -120,22 +119,22 @@ class DraggedManager(
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
||||
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||
val element = element ?: return false
|
||||
val target = guiRenderer.gui.onDragKey(type, key, element.element)
|
||||
val mouseButton = MouseButtons[key]
|
||||
val target = guiRenderer.gui.onDragKey(change, code, element.element)
|
||||
val mouseButton = MouseButtons[code]
|
||||
if (mouseButton == null) {
|
||||
element.element.onDragKey(key, type, target)
|
||||
element.element.onDragKey(code, change, target)
|
||||
return true
|
||||
}
|
||||
|
||||
val mouseAction = MouseActions[type] ?: return false
|
||||
val mouseAction = MouseActions[change] ?: return false
|
||||
|
||||
element.element.onDragMouseAction(guiRenderer.currentMousePosition, mouseButton, mouseAction, clickCounter.getClicks(mouseButton, mouseAction, guiRenderer.currentMousePosition, millis()), target)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||
val element = element ?: return false
|
||||
val target = guiRenderer.gui.onDragScroll(scrollOffset, element.element)
|
||||
element.element.onDragScroll(guiRenderer.currentMousePosition, scrollOffset, target)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui.popper
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||
import de.bixilon.kutil.latch.SimpleLatch
|
||||
import de.bixilon.kutil.time.TimeUtil.millis
|
||||
@ -111,19 +110,19 @@ class PopperManager(
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
||||
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||
for ((index, element) in poppers.toList().withIndex()) {
|
||||
if (index != 0 && !element.activeWhenHidden) {
|
||||
continue
|
||||
}
|
||||
if (element.onKey(type, key)) {
|
||||
if (element.onKey(code, change)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||
for ((index, element) in poppers.toList().withIndex()) {
|
||||
if (index != 0 && !element.activeWhenHidden) {
|
||||
continue
|
||||
|
@ -28,7 +28,7 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
object ContainerGUIManager {
|
||||
|
||||
private fun registerLocalContainerEvent(guiRenderer: GUIRenderer) {
|
||||
guiRenderer.context.input.registerKeyCallback("minosoft:local_inventory".toResourceLocation(), KeyBinding(
|
||||
guiRenderer.context.input.bindings.register("minosoft:local_inventory".toResourceLocation(), KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_E),
|
||||
)) { guiRenderer.gui.open(LocalInventoryScreen) }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.menu
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||
@ -191,7 +190,7 @@ abstract class Menu(
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2): Boolean {
|
||||
val (element, delta) = getAt(position) ?: return true
|
||||
element.onScroll(delta, scrollOffset)
|
||||
return true
|
||||
|
@ -61,7 +61,7 @@ class HUDManager(
|
||||
val toggleKeyBinding = hudBuilder.ENABLE_KEY_BINDING ?: return
|
||||
val toggleKeyBindingName = hudBuilder.ENABLE_KEY_BINDING_NAME ?: return
|
||||
|
||||
context.input.registerKeyCallback(toggleKeyBindingName, toggleKeyBinding, defaultPressed = hudBuilder.DEFAULT_ENABLED) { hudElement.enabled = it }
|
||||
context.input.bindings.register(toggleKeyBindingName, toggleKeyBinding, pressed = hudBuilder.DEFAULT_ENABLED) { hudElement.enabled = it }
|
||||
}
|
||||
|
||||
private fun registerDefaultElements() {
|
||||
@ -93,10 +93,10 @@ class HUDManager(
|
||||
element.init()
|
||||
}
|
||||
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
"minosoft:enable_hud".toResourceLocation(), KeyBinding(
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_F1),
|
||||
), defaultPressed = enabled
|
||||
), pressed = enabled
|
||||
) { enabled = it }
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.chat
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
@ -36,7 +35,7 @@ abstract class AbstractChatElement(guiRenderer: GUIRenderer) : Element(guiRender
|
||||
messages.render(offset + Vec2i(ChatElement.CHAT_INPUT_MARGIN, 0), consumer, options)
|
||||
}
|
||||
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2d): Boolean {
|
||||
override fun onScroll(position: Vec2, scrollOffset: Vec2): Boolean {
|
||||
val size = messages.size
|
||||
if (position.y > size.y || position.x > messages.size.x) {
|
||||
return false
|
||||
|
@ -94,13 +94,13 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer),
|
||||
messages += it.message.text
|
||||
}
|
||||
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
"minosoft:open_chat".toResourceLocation(), KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_T),
|
||||
)
|
||||
) { guiRenderer.gui.open(ChatElement) }
|
||||
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
minosoft("open_command_chat"),
|
||||
KeyBinding(KeyActions.PRESS to setOf(KeyCodes.KEY_SLASH))
|
||||
) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
@ -29,7 +28,7 @@ interface DragTarget {
|
||||
fun onDragMove(position: Vec2, absolute: Vec2, draggable: Dragged): Element? = this.nullCast()
|
||||
fun onDragLeave(draggable: Dragged): Element? = this.nullCast()
|
||||
|
||||
fun onDragScroll(position: Vec2, scrollOffset: Vec2d, draggable: Dragged): Element? = this.nullCast()
|
||||
fun onDragScroll(position: Vec2, scrollOffset: Vec2, draggable: Dragged): Element? = this.nullCast()
|
||||
|
||||
fun onDragMouseAction(position: Vec2, button: MouseButtons, action: MouseActions, count: Int, draggable: Dragged): Element? = this.nullCast()
|
||||
fun onDragKey(key: KeyCodes, type: KeyChangeTypes, draggable: Dragged): Element? = this.nullCast()
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.gui.dragged.Dragged
|
||||
@ -24,6 +23,6 @@ interface DraggableHandler {
|
||||
|
||||
fun onDragMove(position: Vec2, dragged: Dragged): Element? = null
|
||||
fun onDragKey(type: KeyChangeTypes, key: KeyCodes, dragged: Dragged): Element? = null
|
||||
fun onDragScroll(scrollOffset: Vec2d, dragged: Dragged): Element? = null
|
||||
fun onDragScroll(scrollOffset: Vec2, dragged: Dragged): Element? = null
|
||||
fun onDragChar(char: Int, dragged: Dragged): Element? = null
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseActions
|
||||
import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseButtons
|
||||
@ -23,7 +22,7 @@ import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||
interface InputElement : MouseInputElement {
|
||||
|
||||
fun onMouseAction(position: Vec2, button: MouseButtons, action: MouseActions, count: Int) = false
|
||||
fun onScroll(position: Vec2, scrollOffset: Vec2d) = false
|
||||
fun onScroll(position: Vec2, scrollOffset: Vec2) = false
|
||||
|
||||
fun onKey(key: KeyCodes, type: KeyChangeTypes) = false
|
||||
fun onCharPress(char: Int) = false
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -13,10 +13,12 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||
|
||||
enum class ModifierKeys {
|
||||
CONTROL,
|
||||
ALT,
|
||||
SHIFT,
|
||||
SUPER,
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
|
||||
enum class ModifierKeys(vararg val codes: KeyCodes) {
|
||||
CONTROL(KeyCodes.KEY_LEFT_CONTROL, KeyCodes.KEY_RIGHT_CONTROL),
|
||||
ALT(KeyCodes.KEY_LEFT_ALT, KeyCodes.KEY_RIGHT_ALT),
|
||||
SHIFT(KeyCodes.KEY_LEFT_SHIFT, KeyCodes.KEY_RIGHT_SHIFT),
|
||||
SUPER(KeyCodes.KEY_LEFT_SUPER, KeyCodes.KEY_RIGHT_SUPER),
|
||||
;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class CameraInput(
|
||||
private var changeFly = false
|
||||
|
||||
private fun registerKeyBindings() {
|
||||
context.input.registerCheckCallback(
|
||||
context.input.bindings.registerCheck(
|
||||
MOVE_SPRINT_KEYBINDING to KeyBinding(
|
||||
KeyActions.CHANGE to setOf(KeyCodes.KEY_LEFT_CONTROL),
|
||||
),
|
||||
@ -74,7 +74,7 @@ class CameraInput(
|
||||
)
|
||||
|
||||
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
ZOOM_KEYBINDING, KeyBinding(
|
||||
KeyActions.CHANGE to setOf(KeyCodes.KEY_C),
|
||||
)
|
||||
@ -87,19 +87,19 @@ class CameraInput(
|
||||
|
||||
fun updateInput(delta: Double) {
|
||||
val input = PlayerMovementInput(
|
||||
forward = context.input.isKeyBindingDown(MOVE_FORWARDS_KEYBINDING),
|
||||
backward = context.input.isKeyBindingDown(MOVE_BACKWARDS_KEYBINDING),
|
||||
left = context.input.isKeyBindingDown(MOVE_LEFT_KEYBINDING),
|
||||
right = context.input.isKeyBindingDown(MOVE_RIGHT_KEYBINDING),
|
||||
jump = context.input.isKeyBindingDown(JUMP_KEYBINDING),
|
||||
sneak = context.input.isKeyBindingDown(SNEAK_KEYBINDING),
|
||||
sprint = context.input.isKeyBindingDown(MOVE_SPRINT_KEYBINDING),
|
||||
flyDown = context.input.isKeyBindingDown(FLY_DOWN_KEYBINDING),
|
||||
flyUp = context.input.isKeyBindingDown(FLY_UP_KEYBINDING),
|
||||
forward = MOVE_FORWARDS_KEYBINDING in context.input.bindings,
|
||||
backward = MOVE_BACKWARDS_KEYBINDING in context.input.bindings,
|
||||
left = MOVE_LEFT_KEYBINDING in context.input.bindings,
|
||||
right = MOVE_RIGHT_KEYBINDING in context.input.bindings,
|
||||
jump = JUMP_KEYBINDING in context.input.bindings,
|
||||
sneak = SNEAK_KEYBINDING in context.input.bindings,
|
||||
sprint = MOVE_SPRINT_KEYBINDING in context.input.bindings,
|
||||
flyDown = FLY_DOWN_KEYBINDING in context.input.bindings,
|
||||
flyUp = FLY_UP_KEYBINDING in context.input.bindings,
|
||||
)
|
||||
|
||||
val changeFly = context.input.isKeyBindingDown(CHANGE_FLY_KEYBINDING)
|
||||
val startElytraFly = context.input.isKeyBindingDown(START_ELYTRA_FLY_KEYBINDING)
|
||||
val changeFly = CHANGE_FLY_KEYBINDING in context.input.bindings
|
||||
val startElytraFly = START_ELYTRA_FLY_KEYBINDING in context.input.bindings
|
||||
val inputActions = MovementInputActions(
|
||||
toggleFly = changeFly != this.changeFly,
|
||||
startElytraFly = startElytraFly,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -14,14 +14,13 @@
|
||||
package de.bixilon.minosoft.gui.rendering.input
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||
|
||||
interface InputHandler {
|
||||
|
||||
fun onMouseMove(position: Vec2) = false
|
||||
fun onKey(type: KeyChangeTypes, key: KeyCodes) = false
|
||||
fun onScroll(scrollOffset: Vec2d) = false
|
||||
fun onKey(code: KeyCodes, change: KeyChangeTypes) = false
|
||||
fun onScroll(scrollOffset: Vec2) = false
|
||||
fun onCharPress(char: Int) = false
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import de.bixilon.minosoft.config.key.KeyActions
|
||||
import de.bixilon.minosoft.config.key.KeyBinding
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.data.container.types.PlayerInventory
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||
import de.bixilon.minosoft.gui.rendering.events.input.MouseScrollEvent
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
||||
import de.bixilon.minosoft.input.interaction.InteractionManager
|
||||
@ -29,19 +30,19 @@ class InteractionManagerKeys(
|
||||
) {
|
||||
|
||||
private fun registerAttack() {
|
||||
input.registerKeyCallback(ATTACK, KeyBinding(
|
||||
input.bindings.register(ATTACK, KeyBinding(
|
||||
KeyActions.CHANGE to setOf(KeyCodes.MOUSE_BUTTON_LEFT),
|
||||
)) { interactions.tryAttack(it) }
|
||||
}
|
||||
|
||||
private fun registerInteraction() {
|
||||
input.registerKeyCallback(USE_ITEM, KeyBinding(
|
||||
input.bindings.register(USE_ITEM, KeyBinding(
|
||||
KeyActions.CHANGE to setOf(KeyCodes.MOUSE_BUTTON_RIGHT),
|
||||
)) { interactions.use.change(it) }
|
||||
}
|
||||
|
||||
private fun registerPick() {
|
||||
input.registerKeyCallback("minosoft:pick_item".toResourceLocation(), KeyBinding(
|
||||
input.bindings.register(PICK, KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.MOUSE_BUTTON_MIDDLE),
|
||||
)
|
||||
) { interactions.pick.pickItem(false) } // ToDo: Combination for not copying nbt
|
||||
@ -50,25 +51,25 @@ class InteractionManagerKeys(
|
||||
private fun registerDrop() {
|
||||
// ToDo: This creates a weird condition, because we first drop the stack and then the single item
|
||||
// ToDo: Does this swing the arm?
|
||||
input.registerKeyCallback(DROP_ITEM_STACK, KeyBinding(
|
||||
input.bindings.register(DROP_ITEM_STACK, KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_Q),
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_LEFT_CONTROL)
|
||||
)) { interactions.drop.dropItem(true) }
|
||||
|
||||
input.registerKeyCallback(DROP_ITEM, KeyBinding(
|
||||
input.bindings.register(DROP_ITEM, KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_Q),
|
||||
)) { interactions.drop.dropItem(false) }
|
||||
}
|
||||
|
||||
private fun registerSpectate() {
|
||||
input.registerKeyCallback(STOP_SPECTATING, KeyBinding(
|
||||
input.bindings.register(STOP_SPECTATING, KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
||||
)) { interactions.spectate.spectate(null) }
|
||||
}
|
||||
|
||||
private fun registerHotbar() {
|
||||
for (i in 1..PlayerInventory.HOTBAR_SLOTS) {
|
||||
input.registerKeyCallback("minosoft:hotbar_slot_$i".toResourceLocation(), KeyBinding(
|
||||
input.bindings.register("minosoft:hotbar_slot_$i".toResourceLocation(), KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_CODE_MAP["$i"]!!),
|
||||
)) { interactions.hotbar.selectSlot(i - 1) }
|
||||
}
|
||||
@ -98,7 +99,7 @@ class InteractionManagerKeys(
|
||||
}
|
||||
|
||||
|
||||
input.registerKeyCallback("minosoft:swap_items".toResourceLocation(), KeyBinding(
|
||||
input.bindings.register(SWAP, KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_F),
|
||||
)) { interactions.hotbar.trySwap() }
|
||||
}
|
||||
@ -120,6 +121,8 @@ class InteractionManagerKeys(
|
||||
companion object {
|
||||
private val ATTACK = "minosoft:attack".toResourceLocation()
|
||||
private val USE_ITEM = "minosoft:use_item".toResourceLocation()
|
||||
private val SWAP = minosoft("swap_items")
|
||||
private val PICK = minosoft("pick_item")
|
||||
|
||||
private val DROP_ITEM = "minosoft:drop_item".toResourceLocation()
|
||||
private val DROP_ITEM_STACK = "minosoft:drop_item_stack".toResourceLocation()
|
||||
|
@ -20,9 +20,10 @@ import de.bixilon.minosoft.config.key.KeyBinding
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.BindingsManager
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.PolygonModes
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.CursorModes
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
|
||||
object DebugKeyBindings {
|
||||
@ -33,14 +34,14 @@ object DebugKeyBindings {
|
||||
val PAUSE_OUTGOING = minosoft("network_pause_outgoing")
|
||||
|
||||
fun register(context: RenderContext) {
|
||||
val manager = context.input
|
||||
val bindings = context.input.bindings
|
||||
|
||||
manager.registerNetwork()
|
||||
manager.registerRendering()
|
||||
bindings.registerNetwork(context.connection)
|
||||
bindings.registerRendering(context)
|
||||
}
|
||||
|
||||
private fun InputManager.registerNetwork() {
|
||||
registerKeyCallback(PAUSE_INCOMING, KeyBinding(
|
||||
private fun BindingsManager.registerNetwork(connection: PlayConnection) {
|
||||
register(PAUSE_INCOMING, KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_I),
|
||||
ignoreConsumer = true,
|
||||
@ -49,7 +50,7 @@ object DebugKeyBindings {
|
||||
connection.network.pauseReceiving(it)
|
||||
}
|
||||
|
||||
registerKeyCallback(PAUSE_OUTGOING, KeyBinding(
|
||||
register(PAUSE_OUTGOING, KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_O),
|
||||
ignoreConsumer = true,
|
||||
@ -59,8 +60,10 @@ object DebugKeyBindings {
|
||||
}
|
||||
}
|
||||
|
||||
private fun InputManager.registerRendering() {
|
||||
registerKeyCallback(DEBUG_POLYGON, KeyBinding(
|
||||
private fun BindingsManager.registerRendering(context: RenderContext) {
|
||||
val connection = context.connection
|
||||
|
||||
register(DEBUG_POLYGON, KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_P),
|
||||
)) {
|
||||
@ -70,11 +73,11 @@ object DebugKeyBindings {
|
||||
}
|
||||
|
||||
|
||||
registerKeyCallback(CURSOR_MODE, KeyBinding(
|
||||
register(CURSOR_MODE, KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_M),
|
||||
ignoreConsumer = true,
|
||||
), defaultPressed = StaticConfiguration.DEBUG_MODE) {
|
||||
), pressed = StaticConfiguration.DEBUG_MODE) {
|
||||
val next = when (context.window.cursorMode) {
|
||||
CursorModes.DISABLED -> CursorModes.NORMAL
|
||||
CursorModes.NORMAL -> CursorModes.DISABLED
|
||||
|
@ -25,17 +25,17 @@ object DefaultKeyBindings {
|
||||
val FULLSCREEN = minosoft("toggle_fullscreen")
|
||||
|
||||
fun register(context: RenderContext) {
|
||||
val inputHandler = context.input
|
||||
val bindings = context.input.bindings
|
||||
val window = context.window
|
||||
val connection = context.connection
|
||||
|
||||
inputHandler.registerKeyCallback(SCREENSHOT, KeyBinding(
|
||||
bindings.register(SCREENSHOT, KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_F2),
|
||||
ignoreConsumer = true,
|
||||
)) { context.screenshotTaker.takeScreenshot() }
|
||||
|
||||
|
||||
inputHandler.registerKeyCallback(FULLSCREEN, KeyBinding(
|
||||
bindings.register(FULLSCREEN, KeyBinding(
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_F11),
|
||||
ignoreConsumer = true,
|
||||
)) {
|
||||
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input.key.manager
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.input.InputHandler
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.CursorModes
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||
|
||||
class InputHandlerManager(
|
||||
val input: InputManager,
|
||||
) {
|
||||
private val context = input.context
|
||||
var handler: InputHandler? = null
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
field = value
|
||||
|
||||
if (value == null) {
|
||||
disable()
|
||||
} else {
|
||||
enable()
|
||||
}
|
||||
}
|
||||
private var skipChar = false
|
||||
private var skipMouse = false
|
||||
private var skipKey = false
|
||||
|
||||
|
||||
fun onMouse(position: Vec2): Boolean {
|
||||
if (skipMouse) {
|
||||
skipMouse = false
|
||||
return true
|
||||
}
|
||||
val handler = this.handler ?: return false
|
||||
|
||||
handler.onMouseMove(position)
|
||||
return true
|
||||
}
|
||||
|
||||
fun onKey(code: KeyCodes, change: KeyChangeTypes) {
|
||||
if (skipKey) {
|
||||
skipKey = false
|
||||
return
|
||||
}
|
||||
val handler = this.handler ?: return
|
||||
handler.onKey(code, change)
|
||||
}
|
||||
|
||||
fun onChar(char: Int) {
|
||||
if (skipChar) {
|
||||
skipChar = false
|
||||
return
|
||||
}
|
||||
val handler = this.handler ?: return
|
||||
handler.onCharPress(char)
|
||||
}
|
||||
|
||||
fun onScroll(delta: Vec2): Boolean {
|
||||
val handler = this.handler ?: return false
|
||||
handler.onScroll(delta)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
private fun enable() {
|
||||
context.window.cursorMode = CursorModes.NORMAL
|
||||
// todo: disable all key combinations
|
||||
}
|
||||
|
||||
private fun disable() {
|
||||
context.window.cursorMode = CursorModes.DISABLED
|
||||
}
|
||||
}
|
@ -15,16 +15,8 @@ package de.bixilon.minosoft.gui.rendering.input.key.manager
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
|
||||
import de.bixilon.kutil.collections.map.SynchronizedMap
|
||||
import de.bixilon.kutil.observer.map.MapObserver.Companion.observeMap
|
||||
import de.bixilon.kutil.time.TimeUtil.millis
|
||||
import de.bixilon.minosoft.config.StaticConfiguration
|
||||
import de.bixilon.minosoft.config.key.KeyActions
|
||||
import de.bixilon.minosoft.config.key.KeyBinding
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.events.input.CharInputEvent
|
||||
import de.bixilon.minosoft.gui.rendering.events.input.KeyInputEvent
|
||||
@ -32,311 +24,113 @@ import de.bixilon.minosoft.gui.rendering.events.input.MouseMoveEvent
|
||||
import de.bixilon.minosoft.gui.rendering.events.input.MouseScrollEvent
|
||||
import de.bixilon.minosoft.gui.rendering.gui.input.ModifierKeys
|
||||
import de.bixilon.minosoft.gui.rendering.input.CameraInput
|
||||
import de.bixilon.minosoft.gui.rendering.input.InputHandler
|
||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionManagerKeys
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.KeyBindingRegister
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.CursorModes
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.BindingsManager
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2dUtil.EMPTY
|
||||
import de.bixilon.minosoft.modding.EventPriorities
|
||||
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongMap
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap
|
||||
|
||||
class InputManager(
|
||||
val context: RenderContext,
|
||||
) {
|
||||
val connection: PlayConnection = context.connection
|
||||
val cameraInput = CameraInput(context, context.camera.matrixHandler)
|
||||
private val profile = connection.profiles.controls
|
||||
val bindings = BindingsManager(this)
|
||||
val handler = InputHandlerManager(this)
|
||||
|
||||
private val keyBindingCallbacks: SynchronizedMap<ResourceLocation, KeyBindingRegister> = synchronizedMapOf()
|
||||
private val keysDown: MutableList<KeyCodes> = mutableListOf()
|
||||
private val keyBindingsDown: MutableList<ResourceLocation> = mutableListOf()
|
||||
private val keysLastDownTime: MutableMap<KeyCodes, Long> = mutableMapOf()
|
||||
private val pressed: MutableSet<KeyCodes> = mutableSetOf()
|
||||
private val times: Object2LongMap<KeyCodes> = Object2LongOpenHashMap<KeyCodes>().apply { defaultReturnValue(-1L) }
|
||||
|
||||
|
||||
var mousePosition: Vec2d = Vec2d.EMPTY
|
||||
private set
|
||||
|
||||
val interactionKeys = InteractionManagerKeys(this, connection.camera.interactions)
|
||||
var inputHandler: InputHandler? = null
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
field = value
|
||||
|
||||
deactivateAll()
|
||||
|
||||
context.window.cursorMode = if (value == null) {
|
||||
CursorModes.DISABLED
|
||||
} else {
|
||||
CursorModes.NORMAL
|
||||
}
|
||||
}
|
||||
private var skipCharPress = false
|
||||
private var skipMouseMove = false
|
||||
|
||||
init {
|
||||
registerKeyCallback("minosoft:debug_change_cursor_mode".toResourceLocation(),
|
||||
KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_M),
|
||||
ignoreConsumer = true,
|
||||
), defaultPressed = StaticConfiguration.DEBUG_MODE) {
|
||||
val next = when (context.window.cursorMode) {
|
||||
CursorModes.DISABLED -> CursorModes.NORMAL
|
||||
CursorModes.NORMAL -> CursorModes.DISABLED
|
||||
CursorModes.HIDDEN -> CursorModes.NORMAL
|
||||
}
|
||||
context.window.cursorMode = next
|
||||
connection.util.sendDebugMessage("Cursor mode: ${next.format()}")
|
||||
}
|
||||
}
|
||||
|
||||
fun init() {
|
||||
interactionKeys.register()
|
||||
|
||||
connection.events.listen<CharInputEvent> { charInput(it.char) }
|
||||
connection.events.listen<KeyInputEvent> { keyInput(it.code, it.change) }
|
||||
connection.events.listen<CharInputEvent> { onChar(it.char) }
|
||||
connection.events.listen<KeyInputEvent> { onKey(it.code, it.change) }
|
||||
connection.events.listen<MouseScrollEvent>(priority = EventPriorities.LOW) { scroll(it.offset, it) }
|
||||
connection.events.listen<MouseMoveEvent> { onMouse(it.delta, it.position) }
|
||||
|
||||
connection.events.listen<MouseMoveEvent> {
|
||||
val inputHandler = inputHandler
|
||||
mousePosition = it.position
|
||||
if (inputHandler != null) {
|
||||
if (skipMouseMove) {
|
||||
skipMouseMove = false
|
||||
return@listen
|
||||
}
|
||||
inputHandler.onMouseMove(Vec2(it.position))
|
||||
return@listen
|
||||
}
|
||||
|
||||
cameraInput.updateMouse(it.delta)
|
||||
}
|
||||
|
||||
profile::keyBindings.observeMap(this) {
|
||||
for ((key, value) in it.adds) {
|
||||
val binding = keyBindingCallbacks[key] ?: continue
|
||||
binding.keyBinding = value
|
||||
}
|
||||
for ((key, value) in it.removes) {
|
||||
val binding = keyBindingCallbacks[key] ?: continue
|
||||
binding.keyBinding = binding.default
|
||||
}
|
||||
}
|
||||
cameraInput.init()
|
||||
}
|
||||
|
||||
private fun deactivateAll() {
|
||||
keysDown.clear()
|
||||
keysLastDownTime.clear()
|
||||
pressed.clear()
|
||||
times.clear()
|
||||
|
||||
for ((name, pair) in keyBindingCallbacks) {
|
||||
val down = name in keyBindingsDown
|
||||
if (!down || pair.defaultPressed) {
|
||||
continue
|
||||
}
|
||||
|
||||
// ToDo
|
||||
if (pair.keyBinding.action[KeyActions.DOUBLE_PRESS] != null) {
|
||||
continue
|
||||
}
|
||||
if (pair.keyBinding.action[KeyActions.STICKY] != null) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
for (callback in pair.callback) {
|
||||
callback(false)
|
||||
}
|
||||
keyBindingsDown -= name
|
||||
}
|
||||
// TODO: disable key bindings
|
||||
}
|
||||
|
||||
private fun keyInput(keyCode: KeyCodes, keyChangeType: KeyChangeTypes) {
|
||||
val inputHandler = inputHandler
|
||||
inputHandler?.onKey(keyChangeType, keyCode)
|
||||
private fun onMouse(delta: Vec2d, position: Vec2d) {
|
||||
this.mousePosition = position
|
||||
if (handler.onMouse(Vec2(position))) return
|
||||
cameraInput.updateMouse(delta)
|
||||
}
|
||||
|
||||
val keyDown = when (keyChangeType) {
|
||||
private fun onKey(code: KeyCodes, change: KeyChangeTypes) {
|
||||
this.handler.onKey(code, change)
|
||||
|
||||
val pressed = when (change) {
|
||||
KeyChangeTypes.PRESS -> true
|
||||
KeyChangeTypes.RELEASE -> false
|
||||
KeyChangeTypes.REPEAT -> return
|
||||
}
|
||||
|
||||
val currentTime = millis()
|
||||
val millis = millis()
|
||||
|
||||
if (keyDown) {
|
||||
keysDown += keyCode
|
||||
|
||||
if (pressed) {
|
||||
this.pressed += code
|
||||
} else {
|
||||
keysDown -= keyCode
|
||||
this.pressed -= code
|
||||
}
|
||||
|
||||
for ((resourceLocation, pair) in keyBindingCallbacks) {
|
||||
if (inputHandler != null && !pair.keyBinding.ignoreConsumer) {
|
||||
continue
|
||||
}
|
||||
var thisKeyBindingDown = keyDown
|
||||
var checksRun = 0
|
||||
var thisIsChange = true
|
||||
var saveDown = true
|
||||
bindings.onKey(code, pressed, millis)
|
||||
|
||||
pair.keyBinding.action[KeyActions.PRESS]?.let {
|
||||
if (!keyDown) {
|
||||
thisIsChange = false
|
||||
}
|
||||
if (it.contains(keyCode)) {
|
||||
saveDown = false
|
||||
} else {
|
||||
thisIsChange = false
|
||||
}
|
||||
checksRun++
|
||||
}
|
||||
|
||||
pair.keyBinding.action[KeyActions.RELEASE]?.let {
|
||||
if (keyDown) {
|
||||
thisIsChange = false
|
||||
}
|
||||
if (it.contains(keyCode)) {
|
||||
saveDown = false
|
||||
} else {
|
||||
thisIsChange = false
|
||||
}
|
||||
checksRun++
|
||||
}
|
||||
|
||||
pair.keyBinding.action[KeyActions.CHANGE]?.let {
|
||||
if (!it.contains(keyCode)) {
|
||||
thisIsChange = false
|
||||
}
|
||||
checksRun++
|
||||
}
|
||||
|
||||
pair.keyBinding.action[KeyActions.MODIFIER]?.let {
|
||||
if (!keysDown.containsAll(it)) {
|
||||
thisIsChange = false
|
||||
}
|
||||
checksRun++
|
||||
}
|
||||
|
||||
pair.keyBinding.action[KeyActions.STICKY]?.let {
|
||||
checksRun++
|
||||
if (!it.contains(keyCode)) {
|
||||
thisIsChange = false
|
||||
return@let
|
||||
}
|
||||
if (!keyDown) {
|
||||
thisIsChange = false
|
||||
return@let
|
||||
}
|
||||
thisKeyBindingDown = !keyBindingsDown.contains(resourceLocation)
|
||||
}
|
||||
|
||||
pair.keyBinding.action[KeyActions.DOUBLE_PRESS]?.let {
|
||||
checksRun++
|
||||
if (!keyDown) {
|
||||
thisIsChange = false
|
||||
return@let
|
||||
}
|
||||
if (!it.contains(keyCode)) {
|
||||
thisIsChange = false
|
||||
return@let
|
||||
}
|
||||
val lastDownTime = keysLastDownTime[keyCode]
|
||||
if (lastDownTime == null) {
|
||||
thisIsChange = false
|
||||
return@let
|
||||
}
|
||||
if (currentTime - lastDownTime > RenderConstants.DOUBLE_PRESS_KEY_PRESS_MAX_DELAY) {
|
||||
thisIsChange = false
|
||||
return@let
|
||||
}
|
||||
if (currentTime - pair.lastChange <= RenderConstants.DOUBLE_PRESS_DELAY_BETWEEN_PRESSED) {
|
||||
thisIsChange = false
|
||||
return@let
|
||||
}
|
||||
thisKeyBindingDown = !isKeyBindingDown(resourceLocation)
|
||||
}
|
||||
|
||||
if (!thisIsChange || checksRun == 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
pair.lastChange = millis()
|
||||
for (callback in pair.callback) {
|
||||
callback(thisKeyBindingDown)
|
||||
}
|
||||
|
||||
if (saveDown) {
|
||||
if (thisKeyBindingDown) {
|
||||
keyBindingsDown += resourceLocation
|
||||
} else {
|
||||
keyBindingsDown -= resourceLocation
|
||||
}
|
||||
}
|
||||
skipCharPress = true
|
||||
}
|
||||
if (keyDown) {
|
||||
keysLastDownTime[keyCode] = currentTime
|
||||
}
|
||||
|
||||
if (this.inputHandler == null) {
|
||||
skipCharPress = false
|
||||
skipMouseMove = false
|
||||
} else if (inputHandler != this.inputHandler) {
|
||||
skipCharPress = true
|
||||
skipMouseMove = true
|
||||
if (pressed) {
|
||||
times[code] = millis
|
||||
}
|
||||
}
|
||||
|
||||
private fun charInput(char: Int) {
|
||||
val inputHandler = inputHandler ?: return
|
||||
if (skipCharPress) {
|
||||
skipCharPress = false
|
||||
return
|
||||
private fun onChar(char: Int) {
|
||||
handler.onChar(char)
|
||||
}
|
||||
|
||||
private fun scroll(scrollOffset: Vec2d, event: MouseScrollEvent) {
|
||||
if (handler.onScroll(Vec2(scrollOffset))) return
|
||||
event.cancelled = true
|
||||
}
|
||||
|
||||
fun areKeysDown(vararg keys: KeyCodes): Boolean {
|
||||
for (key in keys) {
|
||||
if (key !in pressed) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
inputHandler.onCharPress(char)
|
||||
return
|
||||
return true
|
||||
}
|
||||
|
||||
private fun scroll(scrollOffset: Vec2d, event: MouseScrollEvent? = null) {
|
||||
val inputHandler = inputHandler
|
||||
if (inputHandler != null) {
|
||||
inputHandler.onScroll(scrollOffset)
|
||||
event?.cancelled = true
|
||||
fun areKeysDown(keys: Collection<KeyCodes>): Boolean {
|
||||
for (key in keys) {
|
||||
if (key !in pressed) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun registerKeyCallback(resourceLocation: ResourceLocation, defaultKeyBinding: KeyBinding, defaultPressed: Boolean = false, callback: ((keyDown: Boolean) -> Unit)) {
|
||||
val keyBinding = profile.keyBindings.getOrPut(resourceLocation) { defaultKeyBinding }
|
||||
val callbackPair = keyBindingCallbacks.synchronizedGetOrPut(resourceLocation) { KeyBindingRegister(keyBinding, defaultKeyBinding, defaultPressed) }
|
||||
callbackPair.callback += callback
|
||||
|
||||
if (keyBinding.action.containsKey(KeyActions.STICKY) && defaultPressed) {
|
||||
keyBindingsDown += resourceLocation
|
||||
}
|
||||
}
|
||||
|
||||
fun registerCheckCallback(vararg checks: Pair<ResourceLocation, KeyBinding>) {
|
||||
for ((resourceLocation, defaultKeyBinding) in checks) {
|
||||
keyBindingCallbacks.synchronizedGetOrPut(resourceLocation) { KeyBindingRegister(profile.keyBindings.getOrPut(resourceLocation) { defaultKeyBinding }, defaultKeyBinding) }
|
||||
}
|
||||
}
|
||||
|
||||
fun isKeyBindingDown(resourceLocation: ResourceLocation): Boolean {
|
||||
return keyBindingsDown.contains(resourceLocation)
|
||||
}
|
||||
|
||||
fun unregisterKeyBinding(it: ResourceLocation) {
|
||||
keyBindingCallbacks.remove(it)
|
||||
return true
|
||||
}
|
||||
|
||||
fun isKeyDown(vararg keys: KeyCodes): Boolean {
|
||||
for (key in keys) {
|
||||
if (keysDown.contains(key)) {
|
||||
if (key in pressed) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -344,16 +138,15 @@ class InputManager(
|
||||
}
|
||||
|
||||
fun isKeyDown(modifier: ModifierKeys): Boolean {
|
||||
return context.inputManager.isKeyDown(*when (modifier) {
|
||||
ModifierKeys.CONTROL -> arrayOf(KeyCodes.KEY_LEFT_CONTROL, KeyCodes.KEY_RIGHT_CONTROL)
|
||||
ModifierKeys.ALT -> arrayOf(KeyCodes.KEY_LEFT_ALT, KeyCodes.KEY_RIGHT_ALT)
|
||||
ModifierKeys.SHIFT -> arrayOf(KeyCodes.KEY_LEFT_SHIFT, KeyCodes.KEY_RIGHT_SHIFT)
|
||||
ModifierKeys.SUPER -> arrayOf(KeyCodes.KEY_LEFT_SUPER, KeyCodes.KEY_RIGHT_SUPER)
|
||||
})
|
||||
return isKeyDown(*modifier.codes)
|
||||
}
|
||||
|
||||
fun draw(delta: Double) {
|
||||
cameraInput.updateInput(delta)
|
||||
interactionKeys.draw()
|
||||
}
|
||||
|
||||
fun getLastPressed(key: KeyCodes): Long {
|
||||
return this.times.getLong(key)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input.key.manager.binding
|
||||
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
|
||||
import de.bixilon.kutil.collections.map.SynchronizedMap
|
||||
import de.bixilon.kutil.observer.map.MapObserver.Companion.observeMap
|
||||
import de.bixilon.minosoft.config.key.KeyActions
|
||||
import de.bixilon.minosoft.config.key.KeyBinding
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.actions.KeyActionFilter.Companion.filter
|
||||
|
||||
class BindingsManager(
|
||||
val input: InputManager,
|
||||
) {
|
||||
private val connection = input.context.connection
|
||||
private val profile = connection.profiles.controls
|
||||
|
||||
private val bindings: SynchronizedMap<ResourceLocation, KeyBindingState> = synchronizedMapOf()
|
||||
private val pressed: MutableSet<ResourceLocation> = mutableSetOf()
|
||||
|
||||
|
||||
init {
|
||||
profile::keyBindings.observeMap(this) {
|
||||
for ((key, value) in it.adds) {
|
||||
val binding = bindings[key] ?: continue
|
||||
binding.binding = value
|
||||
}
|
||||
for ((key, value) in it.removes) {
|
||||
val binding = bindings[key] ?: continue
|
||||
binding.binding = binding.default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun deactivateAll() {
|
||||
for ((name, pair) in bindings) {
|
||||
val down = name in pressed
|
||||
if (!down || pair.pressed) {
|
||||
continue
|
||||
}
|
||||
|
||||
// ToDo
|
||||
if (pair.binding.action[KeyActions.DOUBLE_PRESS] != null) {
|
||||
continue
|
||||
}
|
||||
if (pair.binding.action[KeyActions.STICKY] != null) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
for (callback in pair.callback) {
|
||||
callback(false)
|
||||
}
|
||||
pressed -= name
|
||||
}
|
||||
}
|
||||
|
||||
private fun onKey(name: ResourceLocation, state: KeyBindingState, pressed: Boolean, code: KeyCodes, millis: Long) {
|
||||
val filterState = KeyBindingFilterState(pressed)
|
||||
|
||||
val binding = state.binding
|
||||
|
||||
if (binding.action.isEmpty()) return
|
||||
|
||||
for ((action, keys) in binding.action) {
|
||||
val filter = action.filter()
|
||||
filter.check(filterState, keys, input, name, state, code, pressed, millis)
|
||||
}
|
||||
if (filterState.skip) return
|
||||
|
||||
val result = if (filterState.satisfied) filterState.result else false
|
||||
val previous = name in this
|
||||
if (previous == result && !filterState.forceNotify) return
|
||||
|
||||
for (callback in state.callback) {
|
||||
callback(result)
|
||||
}
|
||||
if (previous == result) return
|
||||
|
||||
state.lastChange = millis
|
||||
|
||||
if (result) {
|
||||
this.pressed += name
|
||||
} else {
|
||||
this.pressed -= name
|
||||
}
|
||||
// skipCharPress = true
|
||||
}
|
||||
|
||||
fun onKey(code: KeyCodes, pressed: Boolean, millis: Long) {
|
||||
val handler = input.handler.handler
|
||||
|
||||
for ((name, state) in bindings) {
|
||||
if (handler != null && !state.binding.ignoreConsumer) {
|
||||
continue
|
||||
}
|
||||
onKey(name, state, pressed, code, millis)
|
||||
}
|
||||
}
|
||||
|
||||
fun register(name: ResourceLocation, default: KeyBinding, pressed: Boolean = false, callback: KeyBindingCallback) {
|
||||
val keyBinding = profile.keyBindings.getOrPut(name) { default }
|
||||
val callbackPair = bindings.synchronizedGetOrPut(name) { KeyBindingState(keyBinding, default, pressed) }
|
||||
callbackPair.callback += callback
|
||||
|
||||
if (keyBinding.action.containsKey(KeyActions.STICKY) && pressed) {
|
||||
this.pressed += name
|
||||
}
|
||||
}
|
||||
|
||||
fun registerCheck(vararg checks: Pair<ResourceLocation, KeyBinding>) {
|
||||
for ((name, binding) in checks) {
|
||||
bindings.synchronizedGetOrPut(name) { KeyBindingState(profile.keyBindings.getOrPut(name) { binding }, binding) }
|
||||
}
|
||||
}
|
||||
|
||||
fun isDown(name: ResourceLocation): Boolean {
|
||||
return name in pressed
|
||||
}
|
||||
|
||||
operator fun contains(name: ResourceLocation) = isDown(name)
|
||||
|
||||
fun unregister(name: ResourceLocation) {
|
||||
bindings.remove(name)
|
||||
}
|
||||
|
||||
operator fun minusAssign(name: ResourceLocation) = unregister(name)
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input.key.manager.binding
|
||||
|
||||
typealias KeyBindingCallback = (Boolean) -> Unit
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input.key.manager.binding
|
||||
|
||||
data class KeyBindingFilterState(
|
||||
var result: Boolean,
|
||||
var satisfied: Boolean = true,
|
||||
var skip: Boolean = false,
|
||||
var forceNotify: Boolean = false,
|
||||
)
|
@ -11,15 +11,15 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input.key
|
||||
package de.bixilon.minosoft.gui.rendering.input.key.manager.binding
|
||||
|
||||
import de.bixilon.minosoft.config.key.KeyBinding
|
||||
|
||||
data class KeyBindingRegister(
|
||||
var keyBinding: KeyBinding,
|
||||
val default: KeyBinding,
|
||||
val defaultPressed: Boolean = false,
|
||||
val callback: MutableSet<(keyDown: Boolean) -> Unit> = mutableSetOf(),
|
||||
data class KeyBindingState(
|
||||
var binding: KeyBinding,
|
||||
val default: KeyBinding = binding,
|
||||
val pressed: Boolean = false,
|
||||
val callback: MutableSet<KeyBindingCallback> = mutableSetOf(),
|
||||
) {
|
||||
var lastChange = 0L
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input.key.manager.binding.actions
|
||||
|
||||
import de.bixilon.minosoft.config.key.KeyActions
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.KeyBindingFilterState
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.KeyBindingState
|
||||
|
||||
interface KeyActionFilter {
|
||||
|
||||
fun check(filter: KeyBindingFilterState, codes: Set<KeyCodes>, input: InputManager, name: ResourceLocation, state: KeyBindingState, code: KeyCodes, pressed: Boolean, millis: Long)
|
||||
|
||||
|
||||
object Press : KeyActionFilter {
|
||||
|
||||
override fun check(filter: KeyBindingFilterState, codes: Set<KeyCodes>, input: InputManager, name: ResourceLocation, state: KeyBindingState, code: KeyCodes, pressed: Boolean, millis: Long) {
|
||||
if (code in codes) return
|
||||
|
||||
filter.satisfied = false
|
||||
}
|
||||
}
|
||||
|
||||
object Release : KeyActionFilter {
|
||||
|
||||
override fun check(filter: KeyBindingFilterState, codes: Set<KeyCodes>, input: InputManager, name: ResourceLocation, state: KeyBindingState, code: KeyCodes, pressed: Boolean, millis: Long) {
|
||||
if (code in codes) return
|
||||
|
||||
filter.satisfied = false
|
||||
}
|
||||
}
|
||||
|
||||
object Change : KeyActionFilter {
|
||||
|
||||
override fun check(filter: KeyBindingFilterState, codes: Set<KeyCodes>, input: InputManager, name: ResourceLocation, state: KeyBindingState, code: KeyCodes, pressed: Boolean, millis: Long) {
|
||||
if (code !in codes) {
|
||||
filter.satisfied = false
|
||||
return
|
||||
}
|
||||
|
||||
filter.forceNotify = true
|
||||
}
|
||||
}
|
||||
|
||||
object Modifier : KeyActionFilter {
|
||||
|
||||
override fun check(filter: KeyBindingFilterState, codes: Set<KeyCodes>, input: InputManager, name: ResourceLocation, state: KeyBindingState, code: KeyCodes, pressed: Boolean, millis: Long) {
|
||||
if (code !in codes) {
|
||||
filter.skip = true
|
||||
return
|
||||
}
|
||||
if (codes.size == 1) { // optimize if (as most) key has just one modifier key
|
||||
if (pressed) return
|
||||
filter.satisfied = false
|
||||
return
|
||||
}
|
||||
if (input.areKeysDown(codes)) return
|
||||
|
||||
filter.satisfied = false
|
||||
}
|
||||
}
|
||||
|
||||
object Sticky : KeyActionFilter {
|
||||
|
||||
override fun check(filter: KeyBindingFilterState, codes: Set<KeyCodes>, input: InputManager, name: ResourceLocation, state: KeyBindingState, code: KeyCodes, pressed: Boolean, millis: Long) {
|
||||
if (!pressed) {
|
||||
// sticky keys are invoked on press and not on release
|
||||
filter.skip = true
|
||||
return
|
||||
}
|
||||
if (code !in codes) {
|
||||
filter.skip = true
|
||||
return
|
||||
}
|
||||
val wasPressed = name in input.bindings
|
||||
|
||||
filter.result = !wasPressed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object DoublePress : KeyActionFilter {
|
||||
|
||||
override fun check(filter: KeyBindingFilterState, codes: Set<KeyCodes>, input: InputManager, name: ResourceLocation, state: KeyBindingState, code: KeyCodes, pressed: Boolean, millis: Long) {
|
||||
if (!pressed) {
|
||||
filter.skip = true
|
||||
return
|
||||
}
|
||||
if (code !in codes) {
|
||||
filter.skip = true
|
||||
return
|
||||
}
|
||||
val previous = input.getLastPressed(code)
|
||||
if (previous < 0L) {
|
||||
filter.skip = true
|
||||
return
|
||||
}
|
||||
|
||||
if (millis - previous > RenderConstants.DOUBLE_PRESS_KEY_PRESS_MAX_DELAY) {
|
||||
filter.skip = true
|
||||
return
|
||||
}
|
||||
if (millis - state.lastChange <= RenderConstants.DOUBLE_PRESS_DELAY_BETWEEN_PRESSED) {
|
||||
filter.skip = false
|
||||
return
|
||||
}
|
||||
filter.result = input.bindings.isDown(name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
fun KeyActions.filter(): KeyActionFilter {
|
||||
return when (this) {
|
||||
KeyActions.PRESS -> Press
|
||||
KeyActions.RELEASE -> Release
|
||||
KeyActions.CHANGE -> Change
|
||||
KeyActions.MODIFIER -> Modifier
|
||||
KeyActions.STICKY -> Sticky
|
||||
KeyActions.DOUBLE_PRESS -> DoublePress
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -115,7 +115,7 @@ class WorldRenderer(
|
||||
}
|
||||
context.camera.offset::offset.observe(this) { silentlyClearChunkCache() }
|
||||
|
||||
context.input.registerKeyCallback("minosoft:clear_chunk_cache".toResourceLocation(), KeyBinding(
|
||||
context.input.bindings.register("minosoft:clear_chunk_cache".toResourceLocation(), KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_A),
|
||||
)) { clearChunkCache() }
|
||||
|
@ -59,12 +59,12 @@ class ChunkBorderRenderer(
|
||||
get() = mesh == null || !profile.chunkBorder.enabled
|
||||
|
||||
override fun init(latch: AbstractLatch) {
|
||||
context.input.registerKeyCallback(
|
||||
context.input.bindings.register(
|
||||
CHUNK_BORDER_TOGGLE_KEY_COMBINATION,
|
||||
KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_G),
|
||||
), defaultPressed = profile.chunkBorder.enabled
|
||||
), pressed = profile.chunkBorder.enabled
|
||||
) {
|
||||
profile.chunkBorder.enabled = it
|
||||
connection.util.sendDebugMessage("Chunk borders: ${it.format()}")
|
||||
|
@ -18,12 +18,12 @@ import de.bixilon.minosoft.config.DebugOptions
|
||||
import de.bixilon.minosoft.config.key.KeyActions
|
||||
import de.bixilon.minosoft.config.key.KeyBinding
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.RenderingStates
|
||||
import de.bixilon.minosoft.gui.rendering.world.light.debug.LightmapDebugWindow
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import de.bixilon.minosoft.util.delegate.JavaFXDelegate.observeFX
|
||||
|
||||
class RenderLight(val context: RenderContext) {
|
||||
@ -34,25 +34,23 @@ class RenderLight(val context: RenderContext) {
|
||||
fun init() {
|
||||
map.init()
|
||||
|
||||
context.input.registerKeyCallback(
|
||||
"minosoft:recalculate_light".toResourceLocation(),
|
||||
KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_A),
|
||||
)
|
||||
context.input.bindings.register(RECALCULATE, KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.PRESS to setOf(KeyCodes.KEY_A),
|
||||
)
|
||||
) {
|
||||
DefaultThreadPool += {
|
||||
connection.world.recalculateLight()
|
||||
connection.util.sendDebugMessage("Light recalculated and chunk cache cleared!")
|
||||
}
|
||||
}
|
||||
context.input.registerKeyCallback(
|
||||
"minosoft:toggle_fullbright".toResourceLocation(),
|
||||
context.input.bindings.register(
|
||||
FULLBRIGHT,
|
||||
KeyBinding(
|
||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||
KeyActions.STICKY to setOf(KeyCodes.KEY_C),
|
||||
),
|
||||
defaultPressed = connection.profiles.rendering.light.fullbright,
|
||||
pressed = connection.profiles.rendering.light.fullbright,
|
||||
) {
|
||||
connection.profiles.rendering.light.fullbright = it
|
||||
connection.util.sendDebugMessage("Fullbright: ${it.format()}")
|
||||
@ -76,4 +74,9 @@ class RenderLight(val context: RenderContext) {
|
||||
map.update()
|
||||
debugWindow?.update()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val RECALCULATE = minosoft("recalculate")
|
||||
val FULLBRIGHT = minosoft("fullbright")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user