Skip to content

Commit

Permalink
Implement keybinds
Browse files Browse the repository at this point in the history
  • Loading branch information
shedaniel committed Oct 27, 2023
1 parent 1086bc2 commit e4d3062
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@

package me.shedaniel.rei.impl.client.gui.config;

import me.shedaniel.clothconfig2.api.ModifierKeyCode;
import me.shedaniel.rei.impl.client.gui.config.options.CompositeOption;
import me.shedaniel.rei.impl.client.gui.modules.Menu;
import org.jetbrains.annotations.Nullable;

public interface ConfigAccess {
<T> T get(CompositeOption<T> option);

<T> void set(CompositeOption<T> option, T value);

<T> T getDefault(CompositeOption<T> option);

void closeMenu();

void openMenu(Menu menu);

void focusKeycode(CompositeOption<ModifierKeyCode> option);

@Nullable
CompositeOption<ModifierKeyCode> getFocusedKeycode();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
package me.shedaniel.rei.impl.client.gui.config;

import com.google.common.base.Preconditions;
import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.architectury.utils.value.IntValue;
import me.shedaniel.clothconfig2.api.Modifier;
import me.shedaniel.clothconfig2.api.ModifierKeyCode;
import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.gui.widgets.Widget;
Expand Down Expand Up @@ -61,6 +64,9 @@ public class REIConfigScreen extends Screen implements ConfigAccess {
private OptionCategory activeCategory;
@Nullable
private Menu menu;
@Nullable
private CompositeOption<ModifierKeyCode> focusedKeycodeOption = null;
private ModifierKeyCode partialKeycode = null;

public REIConfigScreen(Screen parent) {
this(parent, AllREIConfigCategories.CATEGORIES);
Expand Down Expand Up @@ -168,15 +174,52 @@ public boolean mouseDragged(double mouseX, double mouseY, int button, double del

@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (menu != null && menu.mouseClicked(mouseX, mouseY, button))
if (menu != null) {
if (!menu.mouseClicked(mouseX, mouseY, button))
closeMenu();
return true;
}

if (this.focusedKeycodeOption != null && this.partialKeycode != null) {
if (this.partialKeycode.isUnknown()) {
this.partialKeycode.setKeyCode(InputConstants.Type.MOUSE.getOrCreate(button));
} else if (this.partialKeycode.getType() == InputConstants.Type.KEYSYM) {
Modifier modifier = this.partialKeycode.getModifier();
int code = this.partialKeycode.getKeyCode().getValue();
if (Minecraft.ON_OSX ? code == 343 || code == 347 : code == 341 || code == 345) {
this.partialKeycode.setModifier(Modifier.of(modifier.hasAlt(), true, modifier.hasShift()));
this.partialKeycode.setKeyCode(InputConstants.Type.MOUSE.getOrCreate(button));
return true;
}

if (code == 344 || code == 340) {
this.partialKeycode.setModifier(Modifier.of(modifier.hasAlt(), modifier.hasControl(), true));
this.partialKeycode.setKeyCode(InputConstants.Type.MOUSE.getOrCreate(button));
return true;
}

if (code == 342 || code == 346) {
this.partialKeycode.setModifier(Modifier.of(true, modifier.hasControl(), modifier.hasShift()));
this.partialKeycode.setKeyCode(InputConstants.Type.MOUSE.getOrCreate(button));
return true;
}
}

return true;
}

return super.mouseClicked(mouseX, mouseY, button);
}

@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
if (menu != null && menu.mouseReleased(mouseX, mouseY, button))
return true;
if (this.focusedKeycodeOption != null && this.partialKeycode != null && !this.partialKeycode.isUnknown()) {
this.set(this.focusedKeycodeOption, this.partialKeycode);
this.focusKeycode(null);
return true;
}
for (GuiEventListener entry : children())
if (entry.mouseReleased(mouseX, mouseY, button))
return true;
Expand All @@ -193,11 +236,79 @@ public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
return super.mouseScrolled(mouseX, mouseY, amount);
}

@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (this.focusedKeycodeOption != null) {
if (keyCode != 256) {
if (this.partialKeycode.isUnknown()) {
this.partialKeycode.setKeyCode(InputConstants.getKey(keyCode, scanCode));
} else {
Modifier modifier = this.partialKeycode.getModifier();
if (this.partialKeycode.getType() == InputConstants.Type.KEYSYM) {
int code = this.partialKeycode.getKeyCode().getValue();
if (Minecraft.ON_OSX ? code == 343 || code == 347 : code == 341 || code == 345) {
this.partialKeycode.setModifier(Modifier.of(modifier.hasAlt(), true, modifier.hasShift()));
this.partialKeycode.setKeyCode(InputConstants.getKey(keyCode, scanCode));
return true;
}

if (code == 344 || code == 340) {
this.partialKeycode.setModifier(Modifier.of(modifier.hasAlt(), modifier.hasControl(), true));
this.partialKeycode.setKeyCode(InputConstants.getKey(keyCode, scanCode));
return true;
}

if (code == 342 || code == 346) {
this.partialKeycode.setModifier(Modifier.of(true, modifier.hasControl(), modifier.hasShift()));
this.partialKeycode.setKeyCode(InputConstants.getKey(keyCode, scanCode));
return true;
}
}

if (Minecraft.ON_OSX ? keyCode == 343 || keyCode == 347 : keyCode == 341 || keyCode == 345) {
this.partialKeycode.setModifier(Modifier.of(modifier.hasAlt(), true, modifier.hasShift()));
return true;
}

if (keyCode == 344 || keyCode == 340) {
this.partialKeycode.setModifier(Modifier.of(modifier.hasAlt(), modifier.hasControl(), true));
return true;
}

if (keyCode == 342 || keyCode == 346) {
this.partialKeycode.setModifier(Modifier.of(true, modifier.hasControl(), modifier.hasShift()));
return true;
}
}
} else {
this.set(this.focusedKeycodeOption, ModifierKeyCode.unknown());
this.focusKeycode(null);
}

return true;
}

return super.keyPressed(keyCode, scanCode, modifiers);
}

@Override
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
if (this.focusedKeycodeOption != null && this.partialKeycode != null) {
this.set(this.focusedKeycodeOption, this.partialKeycode);
this.focusKeycode(null);
return true;
}

return super.keyReleased(keyCode, scanCode, modifiers);
}

@Override
public void openMenu(Menu menu) {
this.menu = menu;
this.widgets.add(menu);
}

@Override
public void closeMenu() {
this.widgets.remove(menu);
this.menu = null;
Expand All @@ -217,4 +328,22 @@ public <T> void set(CompositeOption<T> option, T value) {
public <T> T getDefault(CompositeOption<T> option) {
return (T) getDefaultOptions().get(option);
}

@Override
public void focusKeycode(CompositeOption<ModifierKeyCode> option) {
this.focusedKeycodeOption = option;

if (this.focusedKeycodeOption != null) {
this.partialKeycode = this.get(this.focusedKeycodeOption);
this.partialKeycode.setKeyCodeAndModifier(InputConstants.UNKNOWN, Modifier.none());
} else {
this.partialKeycode = null;
}
}

@Override
@Nullable
public CompositeOption<ModifierKeyCode> getFocusedKeycode() {
return this.focusedKeycodeOption;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@

package me.shedaniel.rei.impl.client.gui.config.components;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import me.shedaniel.clothconfig2.api.ModifierKeyCode;
import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.math.impl.PointHelper;
Expand All @@ -44,6 +46,7 @@
import net.minecraft.resources.ResourceLocation;

import java.util.Objects;
import java.util.function.BiConsumer;

import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.literal;
import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.translatable;
Expand All @@ -52,13 +55,7 @@ public class ConfigOptionValueWidget {
public static <T> WidgetWithBounds create(ConfigAccess access, CompositeOption<T> option) {
OptionValueEntry<T> entry = option.getEntry();
T value = access.get(option);
Component[] text = new Component[1];

if (entry instanceof OptionValueEntry.Selection<T> selection) {
text[0] = selection.getOption(value);
} else {
text[0] = literal(value.toString());
}
Component[] text = {entry.getOption(value)};

if (value.equals(Objects.requireNonNullElseGet(option.getDefaultValue(), () -> access.getDefault(option)))) {
text[0] = translatable("config.rei.value.default", text[0]);
Expand All @@ -77,38 +74,9 @@ public static <T> WidgetWithBounds create(ConfigAccess access, CompositeOption<T
});

if (entry instanceof OptionValueEntry.Selection<T> selection) {
int noOfOptions = selection.getOptions().size();
if (noOfOptions == 2) {
label.clickable().onClick($ -> {
access.set(option, selection.getOptions().get((selection.getOptions().indexOf(access.get(option)) + 1) % 2));
text[0] = selection.getOption(access.get(option));

if (access.get(option).equals(Objects.requireNonNullElseGet(option.getDefaultValue(), () -> access.getDefault(option)))) {
text[0] = translatable("config.rei.value.default", text[0]);
}
});
} else if (noOfOptions >= 2) {
label.clickable().onClick($ -> {
Menu menu = new Menu(MatrixUtils.transform(matrix[0], label.getBounds()), CollectionUtils.map(selection.getOptions(), opt -> {
Component selectionOption = selection.getOption(opt);
if (opt.equals(access.getDefault(option))) {
selectionOption = translatable("config.rei.value.default", selectionOption);
}

return ToggleMenuEntry.of(selectionOption, () -> false, o -> {
((REIConfigScreen) Minecraft.getInstance().screen).closeMenu();
access.set(option, opt);
text[0] = selection.getOption(opt);

if (access.get(option).equals(access.getDefault(option))) {
text[0] = translatable("config.rei.value.default", text[0]);
}
});
}), false);
((REIConfigScreen) Minecraft.getInstance().screen).closeMenu();
((REIConfigScreen) Minecraft.getInstance().screen).openMenu(menu);
});
}
applySelection(access, option, selection, label, text, matrix);
} else if (access.get(option) instanceof ModifierKeyCode) {
applyKeycode(access, option, label, text, matrix);
}

return Widgets.concatWithBounds(() -> new Rectangle(-label.getBounds().width, 0, label.getBounds().width + 8, 14),
Expand All @@ -118,4 +86,59 @@ public static <T> WidgetWithBounds create(ConfigAccess access, CompositeOption<T
new Rectangle(1, 1, 4, 6), 0, 0, 1, 1, 1, 1), 0, 0.5, 0)
);
}

private static <T> void applySelection(ConfigAccess access, CompositeOption<T> option, OptionValueEntry.Selection<T> selection, Label label, Component[] text, Matrix4f[] matrix) {
int noOfOptions = selection.getOptions().size();
if (noOfOptions == 2) {
label.clickable().onClick($ -> {
access.set(option, selection.getOptions().get((selection.getOptions().indexOf(access.get(option)) + 1) % 2));
text[0] = selection.getOption(access.get(option));

if (access.get(option).equals(Objects.requireNonNullElseGet(option.getDefaultValue(), () -> access.getDefault(option)))) {
text[0] = translatable("config.rei.value.default", text[0]);
}
});
} else if (noOfOptions >= 2) {
label.clickable().onClick($ -> {
Menu menu = new Menu(MatrixUtils.transform(matrix[0], label.getBounds()), CollectionUtils.map(selection.getOptions(), opt -> {
Component selectionOption = selection.getOption(opt);
if (opt.equals(access.getDefault(option))) {
selectionOption = translatable("config.rei.value.default", selectionOption);
}

return ToggleMenuEntry.of(selectionOption, () -> false, o -> {
((REIConfigScreen) Minecraft.getInstance().screen).closeMenu();
access.set(option, opt);
text[0] = selection.getOption(opt);

if (access.get(option).equals(access.getDefault(option))) {
text[0] = translatable("config.rei.value.default", text[0]);
}
});
}), false);
access.closeMenu();
access.openMenu(menu);
});
}
}

private static <T> void applyKeycode(ConfigAccess access, CompositeOption<T> option, Label label, Component[] text, Matrix4f[] matrix) {
label.clickable().onClick($ -> {
access.closeMenu();
access.focusKeycode((CompositeOption<ModifierKeyCode>) option);
});
BiConsumer<PoseStack, Label> render = label.getOnRender();
label.onRender((poses, $) -> {
render.accept(poses, $);
text[0] = ((ModifierKeyCode) access.get(option)).getLocalizedName();

if (access.getFocusedKeycode() == option) {
text[0] = literal("> ").withStyle(ChatFormatting.YELLOW)
.append(text[0].copy().withStyle(ChatFormatting.YELLOW))
.append(literal(" <").withStyle(ChatFormatting.YELLOW));
} else if (access.get(option).equals(access.getDefault(option))) {
text[0] = translatable("config.rei.value.default", text[0]);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import me.shedaniel.rei.impl.client.gui.config.ConfigAccess;
import me.shedaniel.rei.impl.client.gui.config.options.CompositeOption;
import me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.network.chat.MutableComponent;
Expand All @@ -47,6 +48,7 @@
import java.util.ArrayList;
import java.util.List;

import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.literal;
import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.translatable;

public class ConfigOptionWidget {
Expand All @@ -59,7 +61,15 @@ public static <T> WidgetWithBounds create(ConfigAccess access, CompositeOption<T
WidgetWithBounds optionValue = ConfigOptionValueWidget.create(access, option);
widgets.add(Widgets.withTranslate(optionValue, () -> Matrix4f.createTranslateMatrix(width - optionValue.getBounds().width - optionValue.getBounds().x, 0, 0)));
widgets.add(new WidgetWithBounds() {
final MutableComponent description = option.getDescription().copy().withStyle(style -> style.withColor(0xFF757575));
final MutableComponent description = Util.make(() -> {
MutableComponent description = option.getDescription().copy().withStyle(style -> style.withColor(0xFF757575));
if (description.getString().endsWith(".desc")) {
return literal("");
} else {
return description;
}
});

final List<FormattedCharSequence> split = Minecraft.getInstance().font.split(description, width);
final boolean hasPreview = option.hasPreview();
final Label previewLabel = Widgets.createLabel(new Point(), translatable("config.rei.texts.preview"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static OptionCategory make(String key) {
.add(APPEARANCE_TOOLTIPS);
OptionCategory KEYBINDS = make("keybinds")
.add(KEYBINDS_KEYBINDS)
.add(KEYBINDS_ADVANCED);
/*.add(KEYBINDS_ADVANCED)*/;
OptionCategory CHEATS = make("cheats")
.add(CHEATS_CHEATS)
.add(CHEATS_ADVANCED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ static <T> OptionGroup make(String id) {
OptionGroup APPEARANCE_TOOLTIPS = make("appearance.tooltips")
.add(APPEND_MOD_NAMES)
.add(APPEND_FAVORITES_HINT);
OptionGroup KEYBINDS_KEYBINDS = make("keybinds.keybinds");
OptionGroup KEYBINDS_KEYBINDS = make("keybinds.keybinds")
.add(RECIPE_KEYBIND)
.add(USAGE_KEYBIND)
.add(HIDE_KEYBIND)
.add(PREVIOUS_PAGE_KEYBIND)
.add(NEXT_PAGE_KEYBIND)
.add(FOCUS_SEARCH_KEYBIND)
.add(COPY_RECIPE_ID_KEYBIND)
.add(FAVORITE_KEYBIND)
.add(EXPORT_IMAGE_KEYBIND)
.add(BACK_KEYBIND);
OptionGroup KEYBINDS_ADVANCED = make("keybinds.advanced")
.add(USE_NATIVE_KEYBINDS);
OptionGroup CHEATS_CHEATS = make("cheats.cheats")
Expand Down
Loading

0 comments on commit e4d3062

Please sign in to comment.