mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -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() {
|
fun init() {
|
||||||
camera.context.input.registerKeyCallback(
|
camera.context.input.bindings.register(
|
||||||
"minosoft:camera_debug_view".toResourceLocation(),
|
"minosoft:camera_debug_view".toResourceLocation(),
|
||||||
KeyBinding(
|
KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
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.connection.util.sendDebugMessage("Camera debug view: ${it.format()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
camera.context.input.registerKeyCallback(
|
camera.context.input.bindings.register(
|
||||||
"minosoft:camera_third_person".toResourceLocation(),
|
"minosoft:camera_third_person".toResourceLocation(),
|
||||||
KeyBinding(
|
KeyBinding(
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_F5),
|
KeyActions.STICKY to setOf(KeyCodes.KEY_F5),
|
||||||
|
@ -78,12 +78,12 @@ class EntityRenderer(
|
|||||||
profile.hitbox::enabled.observe(this) { this.hitboxes = it }
|
profile.hitbox::enabled.observe(this) { this.hitboxes = it }
|
||||||
context.camera.offset::offset.observe(this) { reset = true }
|
context.camera.offset::offset.observe(this) { reset = true }
|
||||||
|
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
HITBOX_TOGGLE_KEY_COMBINATION,
|
HITBOX_TOGGLE_KEY_COMBINATION,
|
||||||
KeyBinding(
|
KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_B),
|
KeyActions.STICKY to setOf(KeyCodes.KEY_B),
|
||||||
), defaultPressed = profile.hitbox.enabled
|
), pressed = profile.hitbox.enabled
|
||||||
) {
|
) {
|
||||||
profile.hitbox.enabled = it
|
profile.hitbox.enabled = it
|
||||||
connection.util.sendDebugMessage("Entity hit boxes: ${it.format()}")
|
connection.util.sendDebugMessage("Entity hit boxes: ${it.format()}")
|
||||||
|
@ -33,7 +33,7 @@ class FunEffectManager(
|
|||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
"minosoft:switch_fun_settings".toResourceLocation(),
|
"minosoft:switch_fun_settings".toResourceLocation(),
|
||||||
KeyBinding(
|
KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.gui
|
package de.bixilon.minosoft.gui.rendering.gui
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kutil.latch.AbstractLatch
|
import de.bixilon.kutil.latch.AbstractLatch
|
||||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||||
import de.bixilon.kutil.observer.DataObserver.Companion.observed
|
import de.bixilon.kutil.observer.DataObserver.Companion.observed
|
||||||
@ -120,11 +119,11 @@ class GUIRenderer(
|
|||||||
return popper.onCharPress(char) || dragged.onCharPress(char) || gui.onCharPress(char)
|
return popper.onCharPress(char) || dragged.onCharPress(char) || gui.onCharPress(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||||
return popper.onKey(type, key) || dragged.onKey(type, key) || gui.onKey(type, key)
|
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)
|
return popper.onScroll(scrollOffset) || dragged.onScroll(scrollOffset) || gui.onScroll(scrollOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.elements.text
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
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.synchronizedListOf
|
||||||
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedList
|
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedList
|
||||||
import de.bixilon.kutil.time.TimeUtil.millis
|
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()
|
this.scrollOffset += scrollOffset.y.toInt()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.gui
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
|
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
|
||||||
@ -72,7 +71,7 @@ interface AbstractLayout<T : Element> : InputElement, DragTarget {
|
|||||||
return activeElement?.onCharPress(char) ?: false
|
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
|
val (element, offset) = getAt(position) ?: return false
|
||||||
return element.onScroll(offset, scrollOffset)
|
return element.onScroll(offset, scrollOffset)
|
||||||
}
|
}
|
||||||
@ -104,7 +103,7 @@ interface AbstractLayout<T : Element> : InputElement, DragTarget {
|
|||||||
return activeDragElement?.onDragLeave(draggable)
|
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
|
val (element, offset) = getAt(position) ?: return null
|
||||||
return element.onDragScroll(offset, scrollOffset, draggable)
|
return element.onDragScroll(offset, scrollOffset, draggable)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.gui.gui
|
package de.bixilon.minosoft.gui.rendering.gui.gui
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||||
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
|
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
|
||||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||||
@ -71,7 +70,7 @@ class GUIManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun postInit() {
|
override fun postInit() {
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
"minosoft:back".toResourceLocation(),
|
"minosoft:back".toResourceLocation(),
|
||||||
KeyBinding(
|
KeyBinding(
|
||||||
KeyActions.RELEASE to setOf(KeyCodes.KEY_ESCAPE),
|
KeyActions.RELEASE to setOf(KeyCodes.KEY_ESCAPE),
|
||||||
@ -210,11 +209,11 @@ class GUIManager(
|
|||||||
return runForEach { it.onMouseMove(position) }
|
return runForEach { it.onMouseMove(position) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||||
return runForEach { it.onKey(type, key) }
|
return runForEach { it.onKey(code, change) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||||
return runForEach { it.onScroll(scrollOffset) }
|
return runForEach { it.onScroll(scrollOffset) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +239,7 @@ class GUIManager(
|
|||||||
return runForEachDrag { it.onDragKey(type, key, dragged) }
|
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) }
|
return runForEachDrag { it.onDragScroll(scrollOffset, dragged) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +265,7 @@ class GUIManager(
|
|||||||
|
|
||||||
private fun _push(element: GUIElement) {
|
private fun _push(element: GUIElement) {
|
||||||
if (elementOrder.isEmpty()) {
|
if (elementOrder.isEmpty()) {
|
||||||
context.input.inputHandler = guiRenderer
|
context.input.handler.handler = guiRenderer
|
||||||
}
|
}
|
||||||
orderLock.acquire()
|
orderLock.acquire()
|
||||||
val copy = elementOrder.toList()
|
val copy = elementOrder.toList()
|
||||||
@ -313,7 +312,7 @@ class GUIManager(
|
|||||||
|
|
||||||
orderLock.acquire()
|
orderLock.acquire()
|
||||||
if (elementOrder.isEmpty()) {
|
if (elementOrder.isEmpty()) {
|
||||||
context.input.inputHandler = null
|
context.input.handler.handler = null
|
||||||
guiRenderer.popper.clear()
|
guiRenderer.popper.clear()
|
||||||
guiRenderer.dragged.element = null
|
guiRenderer.dragged.element = null
|
||||||
}
|
}
|
||||||
@ -337,7 +336,7 @@ class GUIManager(
|
|||||||
toPop.onClose()
|
toPop.onClose()
|
||||||
orderLock.acquire()
|
orderLock.acquire()
|
||||||
if (elementOrder.isEmpty()) {
|
if (elementOrder.isEmpty()) {
|
||||||
context.input.inputHandler = null
|
context.input.handler.handler = null
|
||||||
guiRenderer.popper.clear()
|
guiRenderer.popper.clear()
|
||||||
guiRenderer.dragged.element = null
|
guiRenderer.dragged.element = null
|
||||||
orderLock.release()
|
orderLock.release()
|
||||||
@ -365,7 +364,7 @@ class GUIManager(
|
|||||||
orderLock.unlock()
|
orderLock.unlock()
|
||||||
guiRenderer.popper.clear()
|
guiRenderer.popper.clear()
|
||||||
guiRenderer.dragged.element = null
|
guiRenderer.dragged.element = null
|
||||||
context.input.inputHandler = null
|
context.input.handler.handler = null
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun <T : GUIElement> get(builder: GUIBuilder<T>): T {
|
operator fun <T : GUIElement> get(builder: GUIBuilder<T>): T {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.gui
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kutil.time.TimeUtil.millis
|
import de.bixilon.kutil.time.TimeUtil.millis
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||||
@ -147,16 +146,16 @@ open class GUIMeshElement<T : Element>(
|
|||||||
return element.onMouseMove(position, position)
|
return element.onMouseMove(position, position)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||||
val mouseButton = MouseButtons[key] ?: return element.onKey(key, type)
|
val mouseButton = MouseButtons[code] ?: return element.onKey(code, change)
|
||||||
val position = Vec2(lastPosition ?: return false)
|
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()))
|
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)
|
val position = Vec2(lastPosition ?: return false)
|
||||||
return element.onScroll(position, scrollOffset)
|
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)
|
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)
|
return element.onDragScroll(Vec2(lastDragPosition ?: return null), scrollOffset, dragged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.gui.dragged
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
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 onDragMove(position: Vec2, target: Element?) = Unit
|
||||||
open fun onDragEnd(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 onDragMouseAction(position: Vec2, button: MouseButtons, action: MouseActions, count: Int, target: Element?) = Unit
|
||||||
open fun onDragKey(key: KeyCodes, type: KeyChangeTypes, target: Element?) = Unit
|
open fun onDragKey(key: KeyCodes, type: KeyChangeTypes, target: Element?) = Unit
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.gui.dragged
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kutil.time.TimeUtil.millis
|
import de.bixilon.kutil.time.TimeUtil.millis
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||||
@ -120,22 +119,22 @@ class DraggedManager(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onKey(type: KeyChangeTypes, key: KeyCodes): Boolean {
|
override fun onKey(code: KeyCodes, change: KeyChangeTypes): Boolean {
|
||||||
val element = element ?: return false
|
val element = element ?: return false
|
||||||
val target = guiRenderer.gui.onDragKey(type, key, element.element)
|
val target = guiRenderer.gui.onDragKey(change, code, element.element)
|
||||||
val mouseButton = MouseButtons[key]
|
val mouseButton = MouseButtons[code]
|
||||||
if (mouseButton == null) {
|
if (mouseButton == null) {
|
||||||
element.element.onDragKey(key, type, target)
|
element.element.onDragKey(code, change, target)
|
||||||
return true
|
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)
|
element.element.onDragMouseAction(guiRenderer.currentMousePosition, mouseButton, mouseAction, clickCounter.getClicks(mouseButton, mouseAction, guiRenderer.currentMousePosition, millis()), target)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||||
val element = element ?: return false
|
val element = element ?: return false
|
||||||
val target = guiRenderer.gui.onDragScroll(scrollOffset, element.element)
|
val target = guiRenderer.gui.onDragScroll(scrollOffset, element.element)
|
||||||
element.element.onDragScroll(guiRenderer.currentMousePosition, scrollOffset, target)
|
element.element.onDragScroll(guiRenderer.currentMousePosition, scrollOffset, target)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.gui.popper
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||||
import de.bixilon.kutil.latch.SimpleLatch
|
import de.bixilon.kutil.latch.SimpleLatch
|
||||||
import de.bixilon.kutil.time.TimeUtil.millis
|
import de.bixilon.kutil.time.TimeUtil.millis
|
||||||
@ -111,19 +110,19 @@ class PopperManager(
|
|||||||
return false
|
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()) {
|
for ((index, element) in poppers.toList().withIndex()) {
|
||||||
if (index != 0 && !element.activeWhenHidden) {
|
if (index != 0 && !element.activeWhenHidden) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (element.onKey(type, key)) {
|
if (element.onKey(code, change)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onScroll(scrollOffset: Vec2d): Boolean {
|
override fun onScroll(scrollOffset: Vec2): Boolean {
|
||||||
for ((index, element) in poppers.toList().withIndex()) {
|
for ((index, element) in poppers.toList().withIndex()) {
|
||||||
if (index != 0 && !element.activeWhenHidden) {
|
if (index != 0 && !element.activeWhenHidden) {
|
||||||
continue
|
continue
|
||||||
|
@ -28,7 +28,7 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
|||||||
object ContainerGUIManager {
|
object ContainerGUIManager {
|
||||||
|
|
||||||
private fun registerLocalContainerEvent(guiRenderer: GUIRenderer) {
|
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),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_E),
|
||||||
)) { guiRenderer.gui.open(LocalInventoryScreen) }
|
)) { guiRenderer.gui.open(LocalInventoryScreen) }
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.menu
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||||
@ -191,7 +190,7 @@ abstract class Menu(
|
|||||||
return true
|
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
|
val (element, delta) = getAt(position) ?: return true
|
||||||
element.onScroll(delta, scrollOffset)
|
element.onScroll(delta, scrollOffset)
|
||||||
return true
|
return true
|
||||||
|
@ -61,7 +61,7 @@ class HUDManager(
|
|||||||
val toggleKeyBinding = hudBuilder.ENABLE_KEY_BINDING ?: return
|
val toggleKeyBinding = hudBuilder.ENABLE_KEY_BINDING ?: return
|
||||||
val toggleKeyBindingName = hudBuilder.ENABLE_KEY_BINDING_NAME ?: 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() {
|
private fun registerDefaultElements() {
|
||||||
@ -93,10 +93,10 @@ class HUDManager(
|
|||||||
element.init()
|
element.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
"minosoft:enable_hud".toResourceLocation(), KeyBinding(
|
"minosoft:enable_hud".toResourceLocation(), KeyBinding(
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_F1),
|
KeyActions.STICKY to setOf(KeyCodes.KEY_F1),
|
||||||
), defaultPressed = enabled
|
), pressed = enabled
|
||||||
) { enabled = it }
|
) { enabled = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.chat
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
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)
|
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
|
val size = messages.size
|
||||||
if (position.y > size.y || position.x > messages.size.x) {
|
if (position.y > size.y || position.x > messages.size.x) {
|
||||||
return false
|
return false
|
||||||
|
@ -94,13 +94,13 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer),
|
|||||||
messages += it.message.text
|
messages += it.message.text
|
||||||
}
|
}
|
||||||
|
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
"minosoft:open_chat".toResourceLocation(), KeyBinding(
|
"minosoft:open_chat".toResourceLocation(), KeyBinding(
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_T),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_T),
|
||||||
)
|
)
|
||||||
) { guiRenderer.gui.open(ChatElement) }
|
) { guiRenderer.gui.open(ChatElement) }
|
||||||
|
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
minosoft("open_command_chat"),
|
minosoft("open_command_chat"),
|
||||||
KeyBinding(KeyActions.PRESS to setOf(KeyCodes.KEY_SLASH))
|
KeyBinding(KeyActions.PRESS to setOf(KeyCodes.KEY_SLASH))
|
||||||
) {
|
) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
import de.bixilon.kutil.cast.CastUtil.nullCast
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
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 onDragMove(position: Vec2, absolute: Vec2, draggable: Dragged): Element? = this.nullCast()
|
||||||
fun onDragLeave(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 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()
|
fun onDragKey(key: KeyCodes, type: KeyChangeTypes, draggable: Dragged): Element? = this.nullCast()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.gui.dragged.Dragged
|
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 onDragMove(position: Vec2, dragged: Dragged): Element? = null
|
||||||
fun onDragKey(type: KeyChangeTypes, key: KeyCodes, 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
|
fun onDragChar(char: Int, dragged: Dragged): Element? = null
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
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.MouseActions
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseButtons
|
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 {
|
interface InputElement : MouseInputElement {
|
||||||
|
|
||||||
fun onMouseAction(position: Vec2, button: MouseButtons, action: MouseActions, count: Int) = false
|
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 onKey(key: KeyCodes, type: KeyChangeTypes) = false
|
||||||
fun onCharPress(char: Int) = false
|
fun onCharPress(char: Int) = false
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.gui.input
|
||||||
|
|
||||||
enum class ModifierKeys {
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
CONTROL,
|
|
||||||
ALT,
|
enum class ModifierKeys(vararg val codes: KeyCodes) {
|
||||||
SHIFT,
|
CONTROL(KeyCodes.KEY_LEFT_CONTROL, KeyCodes.KEY_RIGHT_CONTROL),
|
||||||
SUPER,
|
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 var changeFly = false
|
||||||
|
|
||||||
private fun registerKeyBindings() {
|
private fun registerKeyBindings() {
|
||||||
context.input.registerCheckCallback(
|
context.input.bindings.registerCheck(
|
||||||
MOVE_SPRINT_KEYBINDING to KeyBinding(
|
MOVE_SPRINT_KEYBINDING to KeyBinding(
|
||||||
KeyActions.CHANGE to setOf(KeyCodes.KEY_LEFT_CONTROL),
|
KeyActions.CHANGE to setOf(KeyCodes.KEY_LEFT_CONTROL),
|
||||||
),
|
),
|
||||||
@ -74,7 +74,7 @@ class CameraInput(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
ZOOM_KEYBINDING, KeyBinding(
|
ZOOM_KEYBINDING, KeyBinding(
|
||||||
KeyActions.CHANGE to setOf(KeyCodes.KEY_C),
|
KeyActions.CHANGE to setOf(KeyCodes.KEY_C),
|
||||||
)
|
)
|
||||||
@ -87,19 +87,19 @@ class CameraInput(
|
|||||||
|
|
||||||
fun updateInput(delta: Double) {
|
fun updateInput(delta: Double) {
|
||||||
val input = PlayerMovementInput(
|
val input = PlayerMovementInput(
|
||||||
forward = context.input.isKeyBindingDown(MOVE_FORWARDS_KEYBINDING),
|
forward = MOVE_FORWARDS_KEYBINDING in context.input.bindings,
|
||||||
backward = context.input.isKeyBindingDown(MOVE_BACKWARDS_KEYBINDING),
|
backward = MOVE_BACKWARDS_KEYBINDING in context.input.bindings,
|
||||||
left = context.input.isKeyBindingDown(MOVE_LEFT_KEYBINDING),
|
left = MOVE_LEFT_KEYBINDING in context.input.bindings,
|
||||||
right = context.input.isKeyBindingDown(MOVE_RIGHT_KEYBINDING),
|
right = MOVE_RIGHT_KEYBINDING in context.input.bindings,
|
||||||
jump = context.input.isKeyBindingDown(JUMP_KEYBINDING),
|
jump = JUMP_KEYBINDING in context.input.bindings,
|
||||||
sneak = context.input.isKeyBindingDown(SNEAK_KEYBINDING),
|
sneak = SNEAK_KEYBINDING in context.input.bindings,
|
||||||
sprint = context.input.isKeyBindingDown(MOVE_SPRINT_KEYBINDING),
|
sprint = MOVE_SPRINT_KEYBINDING in context.input.bindings,
|
||||||
flyDown = context.input.isKeyBindingDown(FLY_DOWN_KEYBINDING),
|
flyDown = FLY_DOWN_KEYBINDING in context.input.bindings,
|
||||||
flyUp = context.input.isKeyBindingDown(FLY_UP_KEYBINDING),
|
flyUp = FLY_UP_KEYBINDING in context.input.bindings,
|
||||||
)
|
)
|
||||||
|
|
||||||
val changeFly = context.input.isKeyBindingDown(CHANGE_FLY_KEYBINDING)
|
val changeFly = CHANGE_FLY_KEYBINDING in context.input.bindings
|
||||||
val startElytraFly = context.input.isKeyBindingDown(START_ELYTRA_FLY_KEYBINDING)
|
val startElytraFly = START_ELYTRA_FLY_KEYBINDING in context.input.bindings
|
||||||
val inputActions = MovementInputActions(
|
val inputActions = MovementInputActions(
|
||||||
toggleFly = changeFly != this.changeFly,
|
toggleFly = changeFly != this.changeFly,
|
||||||
startElytraFly = startElytraFly,
|
startElytraFly = startElytraFly,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
package de.bixilon.minosoft.gui.rendering.input
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2
|
import de.bixilon.kotlinglm.vec2.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||||
|
|
||||||
interface InputHandler {
|
interface InputHandler {
|
||||||
|
|
||||||
fun onMouseMove(position: Vec2) = false
|
fun onMouseMove(position: Vec2) = false
|
||||||
fun onKey(type: KeyChangeTypes, key: KeyCodes) = false
|
fun onKey(code: KeyCodes, change: KeyChangeTypes) = false
|
||||||
fun onScroll(scrollOffset: Vec2d) = false
|
fun onScroll(scrollOffset: Vec2) = false
|
||||||
fun onCharPress(char: Int) = 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.KeyBinding
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.data.container.types.PlayerInventory
|
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.events.input.MouseScrollEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
||||||
import de.bixilon.minosoft.input.interaction.InteractionManager
|
import de.bixilon.minosoft.input.interaction.InteractionManager
|
||||||
@ -29,19 +30,19 @@ class InteractionManagerKeys(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
private fun registerAttack() {
|
private fun registerAttack() {
|
||||||
input.registerKeyCallback(ATTACK, KeyBinding(
|
input.bindings.register(ATTACK, KeyBinding(
|
||||||
KeyActions.CHANGE to setOf(KeyCodes.MOUSE_BUTTON_LEFT),
|
KeyActions.CHANGE to setOf(KeyCodes.MOUSE_BUTTON_LEFT),
|
||||||
)) { interactions.tryAttack(it) }
|
)) { interactions.tryAttack(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerInteraction() {
|
private fun registerInteraction() {
|
||||||
input.registerKeyCallback(USE_ITEM, KeyBinding(
|
input.bindings.register(USE_ITEM, KeyBinding(
|
||||||
KeyActions.CHANGE to setOf(KeyCodes.MOUSE_BUTTON_RIGHT),
|
KeyActions.CHANGE to setOf(KeyCodes.MOUSE_BUTTON_RIGHT),
|
||||||
)) { interactions.use.change(it) }
|
)) { interactions.use.change(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerPick() {
|
private fun registerPick() {
|
||||||
input.registerKeyCallback("minosoft:pick_item".toResourceLocation(), KeyBinding(
|
input.bindings.register(PICK, KeyBinding(
|
||||||
KeyActions.PRESS to setOf(KeyCodes.MOUSE_BUTTON_MIDDLE),
|
KeyActions.PRESS to setOf(KeyCodes.MOUSE_BUTTON_MIDDLE),
|
||||||
)
|
)
|
||||||
) { interactions.pick.pickItem(false) } // ToDo: Combination for not copying nbt
|
) { interactions.pick.pickItem(false) } // ToDo: Combination for not copying nbt
|
||||||
@ -50,25 +51,25 @@ class InteractionManagerKeys(
|
|||||||
private fun registerDrop() {
|
private fun registerDrop() {
|
||||||
// ToDo: This creates a weird condition, because we first drop the stack and then the single item
|
// ToDo: This creates a weird condition, because we first drop the stack and then the single item
|
||||||
// ToDo: Does this swing the arm?
|
// 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.PRESS to setOf(KeyCodes.KEY_Q),
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_LEFT_CONTROL)
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_LEFT_CONTROL)
|
||||||
)) { interactions.drop.dropItem(true) }
|
)) { interactions.drop.dropItem(true) }
|
||||||
|
|
||||||
input.registerKeyCallback(DROP_ITEM, KeyBinding(
|
input.bindings.register(DROP_ITEM, KeyBinding(
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_Q),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_Q),
|
||||||
)) { interactions.drop.dropItem(false) }
|
)) { interactions.drop.dropItem(false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerSpectate() {
|
private fun registerSpectate() {
|
||||||
input.registerKeyCallback(STOP_SPECTATING, KeyBinding(
|
input.bindings.register(STOP_SPECTATING, KeyBinding(
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
||||||
)) { interactions.spectate.spectate(null) }
|
)) { interactions.spectate.spectate(null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerHotbar() {
|
private fun registerHotbar() {
|
||||||
for (i in 1..PlayerInventory.HOTBAR_SLOTS) {
|
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"]!!),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_CODE_MAP["$i"]!!),
|
||||||
)) { interactions.hotbar.selectSlot(i - 1) }
|
)) { 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),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_F),
|
||||||
)) { interactions.hotbar.trySwap() }
|
)) { interactions.hotbar.trySwap() }
|
||||||
}
|
}
|
||||||
@ -120,6 +121,8 @@ class InteractionManagerKeys(
|
|||||||
companion object {
|
companion object {
|
||||||
private val ATTACK = "minosoft:attack".toResourceLocation()
|
private val ATTACK = "minosoft:attack".toResourceLocation()
|
||||||
private val USE_ITEM = "minosoft:use_item".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 = "minosoft:drop_item".toResourceLocation()
|
||||||
private val DROP_ITEM_STACK = "minosoft:drop_item_stack".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.config.key.KeyCodes
|
||||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
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.base.PolygonModes
|
||||||
import de.bixilon.minosoft.gui.rendering.system.window.CursorModes
|
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
|
import de.bixilon.minosoft.util.KUtil.format
|
||||||
|
|
||||||
object DebugKeyBindings {
|
object DebugKeyBindings {
|
||||||
@ -33,14 +34,14 @@ object DebugKeyBindings {
|
|||||||
val PAUSE_OUTGOING = minosoft("network_pause_outgoing")
|
val PAUSE_OUTGOING = minosoft("network_pause_outgoing")
|
||||||
|
|
||||||
fun register(context: RenderContext) {
|
fun register(context: RenderContext) {
|
||||||
val manager = context.input
|
val bindings = context.input.bindings
|
||||||
|
|
||||||
manager.registerNetwork()
|
bindings.registerNetwork(context.connection)
|
||||||
manager.registerRendering()
|
bindings.registerRendering(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InputManager.registerNetwork() {
|
private fun BindingsManager.registerNetwork(connection: PlayConnection) {
|
||||||
registerKeyCallback(PAUSE_INCOMING, KeyBinding(
|
register(PAUSE_INCOMING, KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_I),
|
KeyActions.STICKY to setOf(KeyCodes.KEY_I),
|
||||||
ignoreConsumer = true,
|
ignoreConsumer = true,
|
||||||
@ -49,7 +50,7 @@ object DebugKeyBindings {
|
|||||||
connection.network.pauseReceiving(it)
|
connection.network.pauseReceiving(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
registerKeyCallback(PAUSE_OUTGOING, KeyBinding(
|
register(PAUSE_OUTGOING, KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_O),
|
KeyActions.STICKY to setOf(KeyCodes.KEY_O),
|
||||||
ignoreConsumer = true,
|
ignoreConsumer = true,
|
||||||
@ -59,8 +60,10 @@ object DebugKeyBindings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InputManager.registerRendering() {
|
private fun BindingsManager.registerRendering(context: RenderContext) {
|
||||||
registerKeyCallback(DEBUG_POLYGON, KeyBinding(
|
val connection = context.connection
|
||||||
|
|
||||||
|
register(DEBUG_POLYGON, KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_P),
|
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.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_M),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_M),
|
||||||
ignoreConsumer = true,
|
ignoreConsumer = true,
|
||||||
), defaultPressed = StaticConfiguration.DEBUG_MODE) {
|
), pressed = StaticConfiguration.DEBUG_MODE) {
|
||||||
val next = when (context.window.cursorMode) {
|
val next = when (context.window.cursorMode) {
|
||||||
CursorModes.DISABLED -> CursorModes.NORMAL
|
CursorModes.DISABLED -> CursorModes.NORMAL
|
||||||
CursorModes.NORMAL -> CursorModes.DISABLED
|
CursorModes.NORMAL -> CursorModes.DISABLED
|
||||||
|
@ -25,17 +25,17 @@ object DefaultKeyBindings {
|
|||||||
val FULLSCREEN = minosoft("toggle_fullscreen")
|
val FULLSCREEN = minosoft("toggle_fullscreen")
|
||||||
|
|
||||||
fun register(context: RenderContext) {
|
fun register(context: RenderContext) {
|
||||||
val inputHandler = context.input
|
val bindings = context.input.bindings
|
||||||
val window = context.window
|
val window = context.window
|
||||||
val connection = context.connection
|
val connection = context.connection
|
||||||
|
|
||||||
inputHandler.registerKeyCallback(SCREENSHOT, KeyBinding(
|
bindings.register(SCREENSHOT, KeyBinding(
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_F2),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_F2),
|
||||||
ignoreConsumer = true,
|
ignoreConsumer = true,
|
||||||
)) { context.screenshotTaker.takeScreenshot() }
|
)) { context.screenshotTaker.takeScreenshot() }
|
||||||
|
|
||||||
|
|
||||||
inputHandler.registerKeyCallback(FULLSCREEN, KeyBinding(
|
bindings.register(FULLSCREEN, KeyBinding(
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_F11),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_F11),
|
||||||
ignoreConsumer = true,
|
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.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2d
|
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.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.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.RenderContext
|
||||||
import de.bixilon.minosoft.gui.rendering.events.input.CharInputEvent
|
import de.bixilon.minosoft.gui.rendering.events.input.CharInputEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.events.input.KeyInputEvent
|
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.events.input.MouseScrollEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.input.ModifierKeys
|
import de.bixilon.minosoft.gui.rendering.gui.input.ModifierKeys
|
||||||
import de.bixilon.minosoft.gui.rendering.input.CameraInput
|
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.interaction.InteractionManagerKeys
|
||||||
import de.bixilon.minosoft.gui.rendering.input.key.KeyBindingRegister
|
import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.BindingsManager
|
||||||
import de.bixilon.minosoft.gui.rendering.system.window.CursorModes
|
|
||||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2dUtil.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2dUtil.EMPTY
|
||||||
import de.bixilon.minosoft.modding.EventPriorities
|
import de.bixilon.minosoft.modding.EventPriorities
|
||||||
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
|
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.util.KUtil.format
|
import it.unimi.dsi.fastutil.objects.Object2LongMap
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap
|
||||||
|
|
||||||
class InputManager(
|
class InputManager(
|
||||||
val context: RenderContext,
|
val context: RenderContext,
|
||||||
) {
|
) {
|
||||||
val connection: PlayConnection = context.connection
|
val connection: PlayConnection = context.connection
|
||||||
val cameraInput = CameraInput(context, context.camera.matrixHandler)
|
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 pressed: MutableSet<KeyCodes> = mutableSetOf()
|
||||||
private val keysDown: MutableList<KeyCodes> = mutableListOf()
|
private val times: Object2LongMap<KeyCodes> = Object2LongOpenHashMap<KeyCodes>().apply { defaultReturnValue(-1L) }
|
||||||
private val keyBindingsDown: MutableList<ResourceLocation> = mutableListOf()
|
|
||||||
private val keysLastDownTime: MutableMap<KeyCodes, Long> = mutableMapOf()
|
|
||||||
|
|
||||||
|
|
||||||
var mousePosition: Vec2d = Vec2d.EMPTY
|
var mousePosition: Vec2d = Vec2d.EMPTY
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val interactionKeys = InteractionManagerKeys(this, connection.camera.interactions)
|
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() {
|
fun init() {
|
||||||
interactionKeys.register()
|
interactionKeys.register()
|
||||||
|
|
||||||
connection.events.listen<CharInputEvent> { charInput(it.char) }
|
connection.events.listen<CharInputEvent> { onChar(it.char) }
|
||||||
connection.events.listen<KeyInputEvent> { keyInput(it.code, it.change) }
|
connection.events.listen<KeyInputEvent> { onKey(it.code, it.change) }
|
||||||
connection.events.listen<MouseScrollEvent>(priority = EventPriorities.LOW) { scroll(it.offset, it) }
|
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()
|
cameraInput.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deactivateAll() {
|
private fun deactivateAll() {
|
||||||
keysDown.clear()
|
pressed.clear()
|
||||||
keysLastDownTime.clear()
|
times.clear()
|
||||||
|
|
||||||
for ((name, pair) in keyBindingCallbacks) {
|
// TODO: disable key bindings
|
||||||
val down = name in keyBindingsDown
|
|
||||||
if (!down || pair.defaultPressed) {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDo
|
private fun onMouse(delta: Vec2d, position: Vec2d) {
|
||||||
if (pair.keyBinding.action[KeyActions.DOUBLE_PRESS] != null) {
|
this.mousePosition = position
|
||||||
continue
|
if (handler.onMouse(Vec2(position))) return
|
||||||
}
|
cameraInput.updateMouse(delta)
|
||||||
if (pair.keyBinding.action[KeyActions.STICKY] != null) {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onKey(code: KeyCodes, change: KeyChangeTypes) {
|
||||||
|
this.handler.onKey(code, change)
|
||||||
|
|
||||||
for (callback in pair.callback) {
|
val pressed = when (change) {
|
||||||
callback(false)
|
|
||||||
}
|
|
||||||
keyBindingsDown -= name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun keyInput(keyCode: KeyCodes, keyChangeType: KeyChangeTypes) {
|
|
||||||
val inputHandler = inputHandler
|
|
||||||
inputHandler?.onKey(keyChangeType, keyCode)
|
|
||||||
|
|
||||||
val keyDown = when (keyChangeType) {
|
|
||||||
KeyChangeTypes.PRESS -> true
|
KeyChangeTypes.PRESS -> true
|
||||||
KeyChangeTypes.RELEASE -> false
|
KeyChangeTypes.RELEASE -> false
|
||||||
KeyChangeTypes.REPEAT -> return
|
KeyChangeTypes.REPEAT -> return
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentTime = millis()
|
val millis = millis()
|
||||||
|
|
||||||
if (keyDown) {
|
|
||||||
keysDown += keyCode
|
if (pressed) {
|
||||||
|
this.pressed += code
|
||||||
} else {
|
} else {
|
||||||
keysDown -= keyCode
|
this.pressed -= code
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((resourceLocation, pair) in keyBindingCallbacks) {
|
bindings.onKey(code, pressed, millis)
|
||||||
if (inputHandler != null && !pair.keyBinding.ignoreConsumer) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var thisKeyBindingDown = keyDown
|
|
||||||
var checksRun = 0
|
|
||||||
var thisIsChange = true
|
|
||||||
var saveDown = true
|
|
||||||
|
|
||||||
pair.keyBinding.action[KeyActions.PRESS]?.let {
|
if (pressed) {
|
||||||
if (!keyDown) {
|
times[code] = millis
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun charInput(char: Int) {
|
private fun onChar(char: Int) {
|
||||||
val inputHandler = inputHandler ?: return
|
handler.onChar(char)
|
||||||
if (skipCharPress) {
|
|
||||||
skipCharPress = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
inputHandler.onCharPress(char)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scroll(scrollOffset: Vec2d, event: MouseScrollEvent? = null) {
|
private fun scroll(scrollOffset: Vec2d, event: MouseScrollEvent) {
|
||||||
val inputHandler = inputHandler
|
if (handler.onScroll(Vec2(scrollOffset))) return
|
||||||
if (inputHandler != null) {
|
event.cancelled = true
|
||||||
inputHandler.onScroll(scrollOffset)
|
|
||||||
event?.cancelled = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerKeyCallback(resourceLocation: ResourceLocation, defaultKeyBinding: KeyBinding, defaultPressed: Boolean = false, callback: ((keyDown: Boolean) -> Unit)) {
|
fun areKeysDown(vararg keys: KeyCodes): Boolean {
|
||||||
val keyBinding = profile.keyBindings.getOrPut(resourceLocation) { defaultKeyBinding }
|
for (key in keys) {
|
||||||
val callbackPair = keyBindingCallbacks.synchronizedGetOrPut(resourceLocation) { KeyBindingRegister(keyBinding, defaultKeyBinding, defaultPressed) }
|
if (key !in pressed) {
|
||||||
callbackPair.callback += callback
|
return false
|
||||||
|
|
||||||
if (keyBinding.action.containsKey(KeyActions.STICKY) && defaultPressed) {
|
|
||||||
keyBindingsDown += resourceLocation
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
fun registerCheckCallback(vararg checks: Pair<ResourceLocation, KeyBinding>) {
|
fun areKeysDown(keys: Collection<KeyCodes>): Boolean {
|
||||||
for ((resourceLocation, defaultKeyBinding) in checks) {
|
for (key in keys) {
|
||||||
keyBindingCallbacks.synchronizedGetOrPut(resourceLocation) { KeyBindingRegister(profile.keyBindings.getOrPut(resourceLocation) { defaultKeyBinding }, defaultKeyBinding) }
|
if (key !in pressed) {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
fun isKeyBindingDown(resourceLocation: ResourceLocation): Boolean {
|
|
||||||
return keyBindingsDown.contains(resourceLocation)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun unregisterKeyBinding(it: ResourceLocation) {
|
|
||||||
keyBindingCallbacks.remove(it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isKeyDown(vararg keys: KeyCodes): Boolean {
|
fun isKeyDown(vararg keys: KeyCodes): Boolean {
|
||||||
for (key in keys) {
|
for (key in keys) {
|
||||||
if (keysDown.contains(key)) {
|
if (key in pressed) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,16 +138,15 @@ class InputManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isKeyDown(modifier: ModifierKeys): Boolean {
|
fun isKeyDown(modifier: ModifierKeys): Boolean {
|
||||||
return context.inputManager.isKeyDown(*when (modifier) {
|
return isKeyDown(*modifier.codes)
|
||||||
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)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun draw(delta: Double) {
|
fun draw(delta: Double) {
|
||||||
cameraInput.updateInput(delta)
|
cameraInput.updateInput(delta)
|
||||||
interactionKeys.draw()
|
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.
|
* 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
|
import de.bixilon.minosoft.config.key.KeyBinding
|
||||||
|
|
||||||
data class KeyBindingRegister(
|
data class KeyBindingState(
|
||||||
var keyBinding: KeyBinding,
|
var binding: KeyBinding,
|
||||||
val default: KeyBinding,
|
val default: KeyBinding = binding,
|
||||||
val defaultPressed: Boolean = false,
|
val pressed: Boolean = false,
|
||||||
val callback: MutableSet<(keyDown: Boolean) -> Unit> = mutableSetOf(),
|
val callback: MutableSet<KeyBindingCallback> = mutableSetOf(),
|
||||||
) {
|
) {
|
||||||
var lastChange = 0L
|
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.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.MODIFIER to setOf(KeyCodes.KEY_F3),
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_A),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_A),
|
||||||
)) { clearChunkCache() }
|
)) { clearChunkCache() }
|
||||||
|
@ -59,12 +59,12 @@ class ChunkBorderRenderer(
|
|||||||
get() = mesh == null || !profile.chunkBorder.enabled
|
get() = mesh == null || !profile.chunkBorder.enabled
|
||||||
|
|
||||||
override fun init(latch: AbstractLatch) {
|
override fun init(latch: AbstractLatch) {
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
CHUNK_BORDER_TOGGLE_KEY_COMBINATION,
|
CHUNK_BORDER_TOGGLE_KEY_COMBINATION,
|
||||||
KeyBinding(
|
KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_G),
|
KeyActions.STICKY to setOf(KeyCodes.KEY_G),
|
||||||
), defaultPressed = profile.chunkBorder.enabled
|
), pressed = profile.chunkBorder.enabled
|
||||||
) {
|
) {
|
||||||
profile.chunkBorder.enabled = it
|
profile.chunkBorder.enabled = it
|
||||||
connection.util.sendDebugMessage("Chunk borders: ${it.format()}")
|
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.KeyActions
|
||||||
import de.bixilon.minosoft.config.key.KeyBinding
|
import de.bixilon.minosoft.config.key.KeyBinding
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
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.eros.util.JavaFXUtil
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderingStates
|
import de.bixilon.minosoft.gui.rendering.RenderingStates
|
||||||
import de.bixilon.minosoft.gui.rendering.world.light.debug.LightmapDebugWindow
|
import de.bixilon.minosoft.gui.rendering.world.light.debug.LightmapDebugWindow
|
||||||
import de.bixilon.minosoft.util.KUtil.format
|
import de.bixilon.minosoft.util.KUtil.format
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
|
||||||
import de.bixilon.minosoft.util.delegate.JavaFXDelegate.observeFX
|
import de.bixilon.minosoft.util.delegate.JavaFXDelegate.observeFX
|
||||||
|
|
||||||
class RenderLight(val context: RenderContext) {
|
class RenderLight(val context: RenderContext) {
|
||||||
@ -34,9 +34,7 @@ class RenderLight(val context: RenderContext) {
|
|||||||
fun init() {
|
fun init() {
|
||||||
map.init()
|
map.init()
|
||||||
|
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(RECALCULATE, KeyBinding(
|
||||||
"minosoft:recalculate_light".toResourceLocation(),
|
|
||||||
KeyBinding(
|
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||||
KeyActions.PRESS to setOf(KeyCodes.KEY_A),
|
KeyActions.PRESS to setOf(KeyCodes.KEY_A),
|
||||||
)
|
)
|
||||||
@ -46,13 +44,13 @@ class RenderLight(val context: RenderContext) {
|
|||||||
connection.util.sendDebugMessage("Light recalculated and chunk cache cleared!")
|
connection.util.sendDebugMessage("Light recalculated and chunk cache cleared!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context.input.registerKeyCallback(
|
context.input.bindings.register(
|
||||||
"minosoft:toggle_fullbright".toResourceLocation(),
|
FULLBRIGHT,
|
||||||
KeyBinding(
|
KeyBinding(
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F4),
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_C),
|
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.profiles.rendering.light.fullbright = it
|
||||||
connection.util.sendDebugMessage("Fullbright: ${it.format()}")
|
connection.util.sendDebugMessage("Fullbright: ${it.format()}")
|
||||||
@ -76,4 +74,9 @@ class RenderLight(val context: RenderContext) {
|
|||||||
map.update()
|
map.update()
|
||||||
debugWindow?.update()
|
debugWindow?.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
val RECALCULATE = minosoft("recalculate")
|
||||||
|
val FULLBRIGHT = minosoft("fullbright")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user