mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-26 09:38:08 -05:00
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",
|
||||
"client.itemgroup.MixinItemGroup",
|
||||
"client.itemgroup.MixinCreativePlayerInventoryGui",
|
||||
"client.keybinding.MixinGameOptions",
|
||||
"client.keybinding.MixinKeyBinding",
|
||||
"client.model.MixinModelLoader",
|
||||
"client.render.MixinBlockColorMap",
|
||||
"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