Skip to content

Commit 81766c6

Browse files
committed
Change how keyboard events are handled
In Forge 1.13.2 there's no current keyboard press logic, and in 1.14 there's some weirdness with multiple dispatching of keyboard presses. Additionally I want long press support to open the config menu.
1 parent ef5fb28 commit 81766c6

9 files changed

Lines changed: 168 additions & 37 deletions

File tree

src/main/java/com/irtimaled/bbor/client/ClientProxy.java

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.irtimaled.bbor.client;
22

33
import com.irtimaled.bbor.client.events.*;
4+
import com.irtimaled.bbor.client.gui.SettingsScreen;
5+
import com.irtimaled.bbor.client.keyboard.KeyListener;
46
import com.irtimaled.bbor.common.BoundingBoxType;
57
import com.irtimaled.bbor.common.CommonProxy;
68
import com.irtimaled.bbor.common.EventBus;
@@ -10,7 +12,6 @@
1012
import com.irtimaled.bbor.config.ConfigManager;
1113
import com.irtimaled.bbor.config.Setting;
1214
import net.minecraft.client.Minecraft;
13-
import net.minecraft.client.settings.KeyBinding;
1415
import net.minecraft.entity.player.EntityPlayer;
1516
import net.minecraft.network.NetworkManager;
1617
import net.minecraft.util.math.BlockPos;
@@ -22,25 +23,42 @@
2223
import static com.irtimaled.bbor.client.Constants.CHUNK_SIZE;
2324

2425
public class ClientProxy extends CommonProxy {
25-
public static final String KeyCategory = "Bounding Box Outline Reloaded";
26-
public static KeyBinding ActiveHotKey = new KeyBinding("Toggle On/Off", 0x42, KeyCategory);
27-
public static KeyBinding OuterBoxOnlyHotKey = new KeyBinding("Toggle Display Outer Box Only", 0x4f, KeyCategory);
26+
public static final String Name = "Bounding Box Outline Reloaded";
2827
public static boolean active;
2928

29+
static {
30+
KeyListener.register("Toggle Active", 0x42, Name)
31+
.onKeyPressHandler(ClientProxy::toggleActive)
32+
.onLongKeyPressHandler(60, SettingsScreen::show);
33+
KeyListener.register("Toggle Outer Box Only", 0x4f, Name)
34+
.onKeyPressHandler(ClientProxy::toggleOuterBoxesOnly);
35+
}
36+
37+
public static void toggleActive() {
38+
active = !active;
39+
if (active)
40+
PlayerData.setActiveY();
41+
}
42+
43+
private static void toggleOuterBoxesOnly() {
44+
Setting<Boolean> outerBoxesOnly = ConfigManager.outerBoxesOnly;
45+
outerBoxesOnly.set(!outerBoxesOnly.get());
46+
}
47+
3048
private ClientRenderer renderer;
3149

3250
@Override
3351
public void init() {
3452
super.init();
3553
EventBus.subscribe(Render.class, e -> render(e.getPartialTicks()));
36-
EventBus.subscribe(KeyPressed.class, e -> keyPressed());
3754
EventBus.subscribe(ConnectedToRemoteServer.class, e -> connectedToServer(e.getNetworkManager()));
3855
EventBus.subscribe(DisconnectedFromRemoteServer.class, e -> disconnectedFromServer());
3956
EventBus.subscribe(InitializeClientReceived.class, e -> setWorldData(e.getSeed(), e.getSpawnX(), e.getSpawnZ()));
4057
EventBus.subscribe(AddBoundingBoxReceived.class, e -> runOnCache(e.getDimensionType(), cache -> cache.addBoundingBoxes(e.getKey(), e.getBoundingBoxes())));
4158
EventBus.subscribe(RemoveBoundingBoxReceived.class, e -> removeBoundingBox(e.getDimensionType(), e.getKey()));
4259

4360
renderer = new ClientRenderer(this::getCache);
61+
KeyListener.init();
4462
}
4563

4664
private void render(float partialTicks) {
@@ -52,21 +70,6 @@ private void render(float partialTicks) {
5270
}
5371
}
5472

55-
public static void toggleActive() {
56-
active = !active;
57-
if (active)
58-
PlayerData.setActiveY();
59-
}
60-
61-
private void keyPressed() {
62-
if (ActiveHotKey.isPressed()) {
63-
toggleActive();
64-
} else if (OuterBoxOnlyHotKey.isPressed()) {
65-
Setting<Boolean> outerBoxesOnly = ConfigManager.outerBoxesOnly;
66-
outerBoxesOnly.set(!outerBoxesOnly.get());
67-
}
68-
}
69-
7073
private void connectedToServer(NetworkManager networkManager) {
7174
SocketAddress remoteAddress = networkManager.getRemoteAddress();
7275
if (remoteAddress instanceof InetSocketAddress) {

src/main/java/com/irtimaled/bbor/client/events/KeyPressed.java

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/main/java/com/irtimaled/bbor/client/gui/SettingsScreen.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private void buildTab(int tabIndex, CreateControl... createControls) {
110110
}
111111

112112
protected void initGui() {
113-
this.title = "Bounding Box Outline Reloaded";
113+
this.title = ClientProxy.Name;
114114

115115
this.controls = new HashSet<>();
116116
this.addTabs("General", "Structures", "Villages");
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.irtimaled.bbor.client.keyboard;
2+
3+
import net.minecraft.client.settings.KeyBinding;
4+
import net.minecraft.client.util.InputMappings;
5+
6+
public class Key extends KeyBinding {
7+
private InputMappings.Input input;
8+
private KeyHandler onKeyPress;
9+
private KeyHandler onLongKeyPress;
10+
private int longPressDuration;
11+
12+
Key(String description, int keyCode, String category) {
13+
super(description, keyCode, category);
14+
}
15+
16+
public Key onKeyPressHandler(KeyHandler onKeyPress) {
17+
this.onKeyPress = onKeyPress;
18+
return this;
19+
}
20+
21+
public Key onLongKeyPressHandler(int duration, KeyHandler onLongKeyPress) {
22+
this.longPressDuration = duration;
23+
this.onLongKeyPress = onLongKeyPress;
24+
return this;
25+
}
26+
27+
InputMappings.Input getInput() {
28+
if (input == null)
29+
return getDefault();
30+
return input;
31+
}
32+
33+
@Override
34+
public void bind(InputMappings.Input input) {
35+
this.input = input;
36+
super.bind(input);
37+
}
38+
39+
40+
private int pressDuration = 0;
41+
42+
@Override
43+
public boolean isPressed() {
44+
return pressDuration == 1;
45+
}
46+
47+
void release() {
48+
if (onKeyPress != null && (onLongKeyPress == null || pressDuration < longPressDuration)) {
49+
onKeyPress.handle();
50+
}
51+
52+
pressDuration = 0;
53+
}
54+
55+
void repeat() {
56+
if (onLongKeyPress == null) return;
57+
58+
if (pressDuration <= longPressDuration) {
59+
pressDuration++;
60+
}
61+
62+
if (pressDuration == longPressDuration) {
63+
onLongKeyPress.handle();
64+
}
65+
}
66+
67+
void press() {
68+
pressDuration++;
69+
}
70+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.irtimaled.bbor.client.keyboard;
2+
3+
@FunctionalInterface
4+
public interface KeyHandler {
5+
void handle();
6+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.irtimaled.bbor.client.keyboard;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.client.settings.KeyBinding;
5+
import net.minecraft.client.util.InputMappings;
6+
import org.lwjgl.glfw.GLFW;
7+
8+
import java.util.HashSet;
9+
import java.util.Set;
10+
11+
public class KeyListener {
12+
private static final Minecraft minecraft = Minecraft.getInstance();
13+
private static long mainWindowHandle;
14+
private static Set<Key> keys = new HashSet<>();
15+
16+
public static void init() {
17+
mainWindowHandle = minecraft.mainWindow.getHandle();
18+
GLFW.glfwSetKeyCallback(mainWindowHandle, KeyListener::onKeyEvent);
19+
}
20+
21+
public static Key register(String description, int keyCode, String category) {
22+
Key key = new Key(description, keyCode, category);
23+
keys.add(key);
24+
return key;
25+
}
26+
27+
private static void onKeyEvent(long windowHandle, int keyCode, int scanCode, int action, int modifiers) {
28+
if (windowHandle == mainWindowHandle && minecraft.currentScreen == null && keyCode != -1) {
29+
InputMappings.Input input = InputMappings.getInputByCode(keyCode, scanCode);
30+
for (Key key : keys) {
31+
if (key.getInput() == input) {
32+
switch (action) {
33+
case GLFW.GLFW_PRESS:
34+
key.press();
35+
break;
36+
case GLFW.GLFW_REPEAT:
37+
key.repeat();
38+
break;
39+
case GLFW.GLFW_RELEASE:
40+
key.release();
41+
return;
42+
}
43+
if (minecraft.currentScreen != null)
44+
key.release();
45+
return;
46+
}
47+
}
48+
}
49+
minecraft.keyboardListener.onKeyEvent(windowHandle, keyCode, scanCode, action, modifiers);
50+
}
51+
52+
public static KeyBinding[] keyBindings() {
53+
return keys.stream().toArray(KeyBinding[]::new);
54+
}
55+
}
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
package com.irtimaled.bbor.mixin.client;
22

33
import com.irtimaled.bbor.client.ClientProxy;
4-
import com.irtimaled.bbor.client.events.KeyPressed;
5-
import com.irtimaled.bbor.common.EventBus;
64
import com.irtimaled.bbor.config.ConfigManager;
75
import net.minecraft.client.Minecraft;
6+
import net.minecraft.client.main.GameConfiguration;
87
import org.spongepowered.asm.mixin.Mixin;
98
import org.spongepowered.asm.mixin.injection.At;
109
import org.spongepowered.asm.mixin.injection.Inject;
1110
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1211

1312
@Mixin(Minecraft.class)
1413
public class MixinMinecraft {
15-
@Inject(method = "init", at = @At("RETURN"))
16-
private void init(CallbackInfo ci) {
17-
ConfigManager.loadConfig(((Minecraft) (Object) this).gameDir);
18-
new ClientProxy().init();
14+
private ClientProxy clientProxy;
15+
16+
@Inject(method = "<init>", at = @At("RETURN"))
17+
private void constructor(GameConfiguration configuration, CallbackInfo ci) {
18+
ConfigManager.loadConfig(configuration.folderInfo.gameDir);
19+
clientProxy = new ClientProxy();
1920
}
2021

21-
@Inject(method = "processKeyBinds", at = @At("HEAD"))
22-
public void processKeyBinds(CallbackInfo ci) {
23-
EventBus.publish(new KeyPressed());
22+
@Inject(method = "init", at = @At("RETURN"))
23+
private void init(CallbackInfo ci) {
24+
clientProxy.init();
2425
}
2526
}

src/main/java/com/irtimaled/bbor/mixin/client/settings/MixinGameSettings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.irtimaled.bbor.mixin.client.settings;
22

3-
import com.irtimaled.bbor.client.ClientProxy;
3+
import com.irtimaled.bbor.client.keyboard.KeyListener;
44
import net.minecraft.client.GameSettings;
55
import net.minecraft.client.Minecraft;
66
import net.minecraft.client.settings.KeyBinding;
@@ -24,7 +24,7 @@ private void init(CallbackInfo ci) {
2424
}
2525

2626
private KeyBinding[] getKeysAll() {
27-
return ArrayUtils.addAll(keyBindings, ClientProxy.ActiveHotKey, ClientProxy.OuterBoxOnlyHotKey);
27+
return ArrayUtils.addAll(keyBindings, KeyListener.keyBindings());
2828
}
2929

3030
@Inject(method = "<init>(Lnet/minecraft/client/Minecraft;Ljava/io/File;)V", at = @At("RETURN"))

src/main/java/com/irtimaled/bbor/mixin/client/settings/MixinKeyBinding.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public class MixinKeyBinding {
1313
private static Map<String, Integer> CATEGORY_ORDER;
1414

1515
static {
16-
CATEGORY_ORDER.put(ClientProxy.KeyCategory, 0);
16+
CATEGORY_ORDER.put(ClientProxy.Name, 0);
1717
}
1818
}

0 commit comments

Comments
 (0)