Skip to content

Commit

Permalink
Implement text fields in 1.21.2+
Browse files Browse the repository at this point in the history
  • Loading branch information
Pixaurora committed Jan 21, 2025
1 parent 6f47dd5 commit b5fbaf3
Show file tree
Hide file tree
Showing 16 changed files with 149 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import net.pixaurora.kitten_heart.impl.KitTunes;

public interface GuiTexture extends AbstractTexture {
public static GuiTexture of(String path, Size size) {
return of(KitTunes.resource(path), size);
}

public static GuiTexture of(ResourcePath path, Size size) {
return new TextureImpl(KitTunes.UI_LAYER.convertToGuiAsset(path), size);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package net.pixaurora.kitten_cube.impl.ui.widget.text;

import net.pixaurora.kitten_cube.impl.math.Point;
import net.pixaurora.kitten_cube.impl.text.Component;
import net.pixaurora.kitten_cube.impl.ui.controls.MouseButton;
import net.pixaurora.kitten_cube.impl.ui.display.GuiDisplay;
import net.pixaurora.kitten_cube.impl.ui.widget.Widget;
import net.pixaurora.kitten_cube.impl.ui.widget.event.WindowUpdateEvent;
import net.pixaurora.kitten_heart.impl.KitTunes;

public interface TextField extends Widget {
public static TextField regular() {
return KitTunes.UI_LAYER.newTextField(TextFieldBackground.REGULAR_BACKGROUND);
public static TextField regular(Component defaultText, int maxLength) {
return KitTunes.UI_LAYER.newTextField(TextFieldBackground.REGULAR_BACKGROUND, defaultText, maxLength);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
import java.util.function.Function;

import net.pixaurora.kitten_cube.impl.math.Size;
import net.pixaurora.kitten_cube.impl.ui.texture.Texture;
import net.pixaurora.kitten_heart.impl.KitTunes;
import net.pixaurora.kitten_cube.impl.ui.texture.GuiTexture;

public class TextFieldBackground<T> {
public static final TextFieldBackground<Texture> REGULAR_BACKGROUND = new TextFieldBackground<>(
Texture.of(KitTunes.resource("textures/gui/sprites/widget/text_field/normal.png"), Size.of(200, 20)),
Texture.of(KitTunes.resource("textures/gui/sprites/widget/text_field/highlighted.png"), Size.of(200, 20)));
public static final TextFieldBackground<GuiTexture> REGULAR_BACKGROUND = new TextFieldBackground<>(
GuiTexture.of("textures/gui/sprites/widget/text_field/normal.png", Size.of(200, 20)),
GuiTexture.of("textures/gui/sprites/widget/text_field/highlighted.png", Size.of(200, 20)));

private final T normal;
private final T highlighted;
Expand All @@ -27,7 +26,7 @@ public T normal() {
return normal;
}

public T getHighlighted() {
public T highlighted() {
return highlighted;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import net.pixaurora.kitten_cube.impl.text.TextProcessor;
import net.pixaurora.kitten_cube.impl.ui.screen.Screen;
import net.pixaurora.kitten_cube.impl.ui.sound.SoundPlayer;
import net.pixaurora.kitten_cube.impl.ui.texture.Texture;
import net.pixaurora.kitten_cube.impl.ui.texture.GuiTexture;
import net.pixaurora.kitten_cube.impl.ui.toast.Toast;
import net.pixaurora.kitten_cube.impl.ui.widget.text.TextField;
import net.pixaurora.kitten_cube.impl.ui.widget.text.TextFieldBackground;
Expand Down Expand Up @@ -36,7 +36,7 @@ public interface UICompat extends SoundPlayer, TextProcessor {

public FileAccess accessResource(ResourcePath path) throws IOException;

public default TextField newTextField(TextFieldBackground<Texture> background) {
public default TextField newTextField(TextFieldBackground<GuiTexture> background, Component defaultText, int maxLength) {
throw new RuntimeException("No implementation for `newTextField` defined!");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ protected Alignment alignmentMethod() {

@Override
protected void firstInit() {
WidgetContainer<TextField> textField = this.addWidget(TextField.regular()).anchor(WidgetAnchor.TOP_MIDDLE);
WidgetContainer<TextField> textField = this.addWidget(TextField.regular(Component.literal("write in me!!"), 64)).anchor(WidgetAnchor.TOP_MIDDLE);
this.addWidget(RectangularButton.vanillaButton(Component.literal("log text field"),
button -> KitTunes.LOGGER.info("Text field input: " + textField.get().input())))
.anchor(WidgetAnchor.TOP_MIDDLE)
Expand Down
1 change: 1 addition & 0 deletions projects/kitten-square/r1.21.2/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod {
entrypoint("modmenu", "net.pixaurora.kitten_square.impl.compat.ModMenuIntegration")

intermediaryMappings = "net.fabricmc:intermediary"
accessWidener("kitten_square.accesswidener")
mixin("kitten_square.mixins.json")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.pixaurora.kitten_square.impl.mixin;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

import com.llamalad7.mixinextras.injector.ModifyReceiver;

import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.WidgetSprites;
import net.pixaurora.kitten_square.impl.ui.widget.TextFieldImpl;

@Mixin(EditBox.class)
public class EditBoxMixin {
/**
* Because the field for the background is both private and static, the only way to modify it in our subclass is when it is used.
*/
@ModifyReceiver(
method = "renderWidget",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/components/WidgetSprites;get(ZZ)Lnet/minecraft/resources/ResourceLocation;")
)
private WidgetSprites replaceBackground(WidgetSprites receiver, boolean a, boolean b) {
EditBox instance = (EditBox) (Object) this;
if (instance instanceof TextFieldImpl) {
return ((TextFieldImpl) instance).background();
} else {
return receiver;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
import net.pixaurora.kitten_cube.impl.text.Component;
import net.pixaurora.kitten_cube.impl.ui.screen.Screen;
import net.pixaurora.kitten_cube.impl.ui.sound.Sound;
import net.pixaurora.kitten_cube.impl.ui.texture.GuiTexture;
import net.pixaurora.kitten_cube.impl.ui.widget.text.TextBox;
import net.pixaurora.kitten_cube.impl.ui.widget.text.TextField;
import net.pixaurora.kitten_cube.impl.ui.widget.text.TextFieldBackground;
import net.pixaurora.kitten_heart.impl.resource.ResourcePathUtils;
import net.pixaurora.kitten_heart.impl.resource.temp.FileAccess;
import net.pixaurora.kitten_heart.impl.service.UICompat;
Expand All @@ -25,6 +28,7 @@
import net.pixaurora.kitten_square.impl.ui.screen.ScreenImpl;
import net.pixaurora.kitten_square.impl.ui.toast.ToastImpl;
import net.pixaurora.kitten_square.impl.ui.widget.TextBoxImpl;
import net.pixaurora.kitten_square.impl.ui.widget.TextFieldImpl;

public class UICompatImpl implements UICompat {
private final Minecraft client = Minecraft.getInstance();
Expand All @@ -47,6 +51,15 @@ public static MutableComponent internalToMinecraftType(Component component) {
}
}

public static net.minecraft.client.gui.screens.Screen internalToMinecraftType(Screen screen,
boolean creatingNewScreen) {
if (screen instanceof MinecraftScreen) {
return ((MinecraftScreen) screen).parent();
} else {
return creatingNewScreen ? new ScreenImpl(screen) : Minecraft.getInstance().screen;
}
}

@Override
public void sendToast(net.pixaurora.kitten_cube.impl.ui.toast.Toast toast) {
this.client.getToastManager().addToast(new ToastImpl(toast));
Expand Down Expand Up @@ -94,13 +107,7 @@ public void playSound(Sound sound) {

@Override
public void setScreen(Screen screen) {
net.minecraft.client.gui.screens.Screen mcScreen;
if (screen instanceof MinecraftScreen) {
mcScreen = ((MinecraftScreen) screen).parent();
} else {
mcScreen = new ScreenImpl(screen);
}
this.client.setScreen(mcScreen);
this.client.setScreen(internalToMinecraftType(screen, true));
}

@Override
Expand All @@ -122,4 +129,18 @@ public FileAccess accessResource(ResourcePath path) throws IOException {

return FileAccess.create(resource.open());
}

@Override
public TextField newTextField(TextFieldBackground<GuiTexture> background, Component defaultText, int maxLength) {
return new TextFieldImpl(this.client.font, background, defaultText, maxLength);
}

@Override
public void addTextField(Screen screen, TextField field) {
if (!(field instanceof TextFieldImpl)) {
throw new RuntimeException("Internal text field is of an unconvertable type `" + field.getClass().getName() + "`!");
}

internalToMinecraftType(screen, false).addRenderableWidget((TextFieldImpl) field);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public boolean shouldCloseOnEsc() {

@Override
public boolean mouseClicked(double x, double y, int button) {
super.mouseClicked(x, y, button);

Point mousePos = Point.of((int) x, (int) y);

this.screen.handleClick(mousePos, MouseButton.fromGlfwCode(button));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.pixaurora.kitten_square.impl.ui.widget;

import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.WidgetSprites;
import net.minecraft.resources.ResourceLocation;
import net.pixaurora.kitten_cube.impl.math.Size;
import net.pixaurora.kitten_cube.impl.text.Component;
import net.pixaurora.kitten_cube.impl.ui.texture.GuiTexture;
import net.pixaurora.kitten_cube.impl.ui.widget.text.TextField;
import net.pixaurora.kitten_cube.impl.ui.widget.text.TextFieldBackground;
import net.pixaurora.kitten_square.impl.service.UICompatImpl;

public class TextFieldImpl extends EditBox implements TextField {
private final WidgetSprites background;
private final Size size;

public TextFieldImpl(Font font, TextFieldBackground<GuiTexture> background, Component defaultText, int maxLength) {
super(font, background.normal().size().width(), background.normal().size().height(),
UICompatImpl.internalToMinecraftType(defaultText));

TextFieldBackground<ResourceLocation> background0 = background.map(texture -> UICompatImpl.internalToMinecraftType(texture.path()));
this.background = new WidgetSprites(background0.normal(), background0.highlighted());

this.size = background.normal().size();

this.setMaxLength(maxLength);
}

@Override
public Size size() {
return this.size;
}

@Override
public String input() {
return this.getValue();
}

@Override
public void setPos(int x, int y) {
this.setX(x);
this.setY(y);
}

// For the Mixin class associated with EditBox
public WidgetSprites background() {
return this.background;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
accessWidener v2 named

accessible method net/minecraft/client/gui/screens/Screen addRenderableWidget (Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"compatibilityLevel": "JAVA_21",
"mixins": [],
"client": [
"EditBoxMixin",
"GuiMixin"
],
"injectors": {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"gui": {
"scaling": {
"type": "nine_slice",
"width": 200,
"height": 20,
"border": 1
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"gui": {
"scaling": {
"type": "nine_slice",
"width": 200,
"height": 20,
"border": 1
}
}
}

0 comments on commit b5fbaf3

Please sign in to comment.