forked from FabricMC/fabric
Keybinding API (#57)
This commit is contained in:
parent
1345c08cb8
commit
c42667b035
7 changed files with 313 additions and 0 deletions
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.api.client.keybinding;
|
||||||
|
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
import net.minecraft.client.util.InputUtil;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expanded version of {@link KeyBinding} for use by Fabric mods.
|
||||||
|
*
|
||||||
|
* *ALL* instantiated FabricKeyBindings should be registered in
|
||||||
|
* {@link KeyBindingRegistry#register(FabricKeyBinding)}!
|
||||||
|
*/
|
||||||
|
public class FabricKeyBinding extends KeyBinding {
|
||||||
|
protected FabricKeyBinding(Identifier id, InputUtil.Type type, int code, String category) {
|
||||||
|
super("key." + id.toString().replace(':', '.'), type, code, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
protected final FabricKeyBinding binding;
|
||||||
|
|
||||||
|
protected Builder(FabricKeyBinding binding) {
|
||||||
|
this.binding = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FabricKeyBinding build() {
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder create(Identifier id, InputUtil.Type type, int code, String category) {
|
||||||
|
return new Builder(new FabricKeyBinding(id, type, code, category));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.api.client.keybinding;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for registering key bindings.
|
||||||
|
*
|
||||||
|
* @see KeyBinding
|
||||||
|
*/
|
||||||
|
public interface KeyBindingRegistry {
|
||||||
|
static KeyBindingRegistry INSTANCE = KeyBindingRegistryImpl.INSTANCE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new key binding category.
|
||||||
|
* @param categoryName The key binding category name.
|
||||||
|
* @return True if a new category was added.
|
||||||
|
*/
|
||||||
|
boolean addCategory(String categoryName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new key binding.
|
||||||
|
* @param binding The key binding.
|
||||||
|
* @return True if a new key binding was registered.
|
||||||
|
*/
|
||||||
|
boolean register(FabricKeyBinding binding);
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.impl.client.keybinding;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
|
||||||
|
import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class KeyBindingRegistryImpl implements KeyBindingRegistry {
|
||||||
|
public static final KeyBindingRegistryImpl INSTANCE = new KeyBindingRegistryImpl();
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
|
private Map<String, Integer> cachedCategoryMap;
|
||||||
|
private List<FabricKeyBinding> fabricKeyBindingList;
|
||||||
|
|
||||||
|
private KeyBindingRegistryImpl() {
|
||||||
|
fabricKeyBindingList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Integer> getCategoryMap() {
|
||||||
|
if (cachedCategoryMap == null) {
|
||||||
|
try {
|
||||||
|
//noinspection JavaReflectionMemberAccess
|
||||||
|
Method m = KeyBinding.class.getDeclaredMethod("fabric_getCategoryMap");
|
||||||
|
m.setAccessible(true);
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
cachedCategoryMap = (Map<String, Integer>) m.invoke(null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cachedCategoryMap == null) {
|
||||||
|
throw new RuntimeException("Cached key binding category map missing!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachedCategoryMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasCategory(String categoryName) {
|
||||||
|
return getCategoryMap().containsKey(categoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addCategory(String categoryName) {
|
||||||
|
Map<String, Integer> map = getCategoryMap();
|
||||||
|
if (map.containsKey(categoryName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Integer> largest = map.values().stream().max(Integer::compareTo);
|
||||||
|
int largestInt = largest.orElse(0);
|
||||||
|
map.put(categoryName, largestInt + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean register(FabricKeyBinding binding) {
|
||||||
|
for (KeyBinding exBinding : fabricKeyBindingList) {
|
||||||
|
if (exBinding == binding) {
|
||||||
|
return false;
|
||||||
|
} else if (exBinding.method_1431().equals(binding.method_1431())) {
|
||||||
|
throw new RuntimeException("Attempted to register two key bindings with equal ID: " + binding.method_1431() + "!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasCategory(binding.method_1423())) {
|
||||||
|
LOGGER.warn("Tried to register key binding with unregistered category '" + binding.method_1423() + "' - please use addCategory to ensure intended category ordering!");
|
||||||
|
addCategory(binding.method_1423());
|
||||||
|
}
|
||||||
|
|
||||||
|
fabricKeyBindingList.add(binding);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyBinding[] process(KeyBinding[] keysAll) {
|
||||||
|
List<KeyBinding> newKeysAll = new ArrayList<>();
|
||||||
|
for (KeyBinding binding : keysAll) {
|
||||||
|
if (!(binding instanceof FabricKeyBinding)) {
|
||||||
|
newKeysAll.add(binding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newKeysAll.addAll(fabricKeyBindingList);
|
||||||
|
return newKeysAll.toArray(new KeyBinding[0]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.mixin.client.keybinding;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
|
||||||
|
import net.minecraft.client.settings.GameOptions;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(GameOptions.class)
|
||||||
|
public class MixinGameOptions {
|
||||||
|
@Shadow
|
||||||
|
public KeyBinding[] keysAll;
|
||||||
|
|
||||||
|
@Inject(at = @At("HEAD"), method = "load()V")
|
||||||
|
public void loadHook(CallbackInfo info) {
|
||||||
|
keysAll = KeyBindingRegistryImpl.INSTANCE.process(keysAll);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.mixin.client.keybinding;
|
||||||
|
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mixin(KeyBinding.class)
|
||||||
|
public class MixinKeyBinding {
|
||||||
|
@Shadow
|
||||||
|
private static Map<String, Integer> field_1656;
|
||||||
|
|
||||||
|
private static Map<String, Integer> fabric_getCategoryMap() {
|
||||||
|
return field_1656;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@
|
||||||
"bugfix.MixinBiomeColors",
|
"bugfix.MixinBiomeColors",
|
||||||
"client.itemgroup.MixinItemGroup",
|
"client.itemgroup.MixinItemGroup",
|
||||||
"client.itemgroup.MixinCreativePlayerInventoryGui",
|
"client.itemgroup.MixinCreativePlayerInventoryGui",
|
||||||
|
"client.keybinding.MixinGameOptions",
|
||||||
|
"client.keybinding.MixinKeyBinding",
|
||||||
"client.model.MixinModelLoader",
|
"client.model.MixinModelLoader",
|
||||||
"client.render.MixinBlockColorMap",
|
"client.render.MixinBlockColorMap",
|
||||||
"client.render.MixinBlockEntityRenderManager",
|
"client.render.MixinBlockEntityRenderManager",
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.keybinding;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
|
||||||
|
import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry;
|
||||||
|
import net.minecraft.client.util.InputUtil;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class KeyBindingModClient implements ClientModInitializer {
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
KeyBindingRegistry.INSTANCE.addCategory("fabric.test");
|
||||||
|
KeyBindingRegistry.INSTANCE.register(
|
||||||
|
FabricKeyBinding.Builder.create(
|
||||||
|
new Identifier("fabric:test"),
|
||||||
|
InputUtil.Type.KEY_KEYBOARD,
|
||||||
|
37,
|
||||||
|
"fabric.test"
|
||||||
|
).build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue