Skip to content

Commit

Permalink
Create config menu with ModMenu
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinrobot committed Aug 10, 2023
1 parent 70bdeaa commit e1410df
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 0 deletions.
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ repositories {
maven {
url 'https://jitpack.io'
}
maven {
url 'https://maven.terraformersmc.com/releases'
content {
includeGroup 'com.terraformersmc'
}
}
}

loom {
Expand Down Expand Up @@ -47,6 +53,8 @@ dependencies {

// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"

modClientCompileOnly "com.terraformersmc:modmenu:7.2.1"

// WebP support for ImageIO, not fully working with animated WebP
modImplementation "com.twelvemonkeys.imageio:imageio-webp:3.9.4"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package net.vinrobot.mcemote.client;

import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import net.vinrobot.mcemote.MinecraftEmote;
import net.vinrobot.mcemote.client.widget.ConfigurationScreen;
import net.vinrobot.mcemote.config.ConfigurationManager;

public class MinecraftEmoteModMenuApi implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
final ConfigurationManager configManager = MinecraftEmote.getInstance().getConfigManager();
return parent -> new ConfigurationScreen(parent, configManager);
}
}
43 changes: 43 additions & 0 deletions src/client/java/net/vinrobot/mcemote/client/widget/BaseScreen.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package net.vinrobot.mcemote.client.widget;

import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.text.Text;

public class BaseScreen extends Screen {
private final Screen parent;

private static final int GRADIENT_START_COLOR = 0xFF000000;
private static final int GRADIENT_END_COLOR = 0x00000000;

public BaseScreen(final Screen parent, final Text title) {
super(title);
this.parent = parent;
}

@Override
public void close() {
this.client.setScreen(this.parent);
}

public void renderBackground(final DrawContext context, final int marginTop, final int marginBottom) {
final int bottom = this.height - marginBottom;

// Background (Middle)
context.setShaderColor(0.125F, 0.125F, 0.125F, 1.0F);
context.drawTexture(Screen.OPTIONS_BACKGROUND_TEXTURE, 0, marginTop, this.width, bottom, this.width, bottom - marginTop, 32, 32);
context.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);

// Background (Top & Bottom), based on Screen.renderBackgroundTexture(DrawContext)
context.setShaderColor(0.25F, 0.25F, 0.25F, 1.0F);
context.drawTexture(Screen.OPTIONS_BACKGROUND_TEXTURE, 0, 0, 0.0F, 0.0F, this.width, marginTop, 32, 32);
context.drawTexture(Screen.OPTIONS_BACKGROUND_TEXTURE, 0, bottom, 0.0F, bottom, this.width, this.height - bottom, 32, 32);
context.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);

// Gradients
final RenderLayer guiOverlay = RenderLayer.getGuiOverlay();
context.fillGradient(guiOverlay, 0, marginTop, this.width, marginTop + 4, GRADIENT_START_COLOR, GRADIENT_END_COLOR, 0);
context.fillGradient(guiOverlay, 0, bottom - 4, this.width, bottom, GRADIENT_END_COLOR, GRADIENT_START_COLOR, 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package net.vinrobot.mcemote.client.widget;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.vinrobot.mcemote.config.Configuration;
import net.vinrobot.mcemote.config.ConfigurationManager;

public class ConfigurationScreen extends BaseScreen {
private static final Text MENU_TITLE = Text.translatableWithFallback("mcemote.options.title", "Minecraft Emote Options");
private static final Text TWITCH_ID_LABEL = Text.translatableWithFallback("mcemote.options.twitchId", "Twitch ID");

private static final int TITLE_COLOR = 0xFFFFFF;
private static final int LABEL_COLOR = 0xA0A0A0;
private static final int TEXTFIELD_VALID_COLOR = 0xE0E0E0;
private static final int TEXTFIELD_INVALID_COLOR = 0xFF0000;

private final ConfigurationManager configManager;

private ButtonWidget doneButton;
private TextFieldWidget twitchIdField;

public ConfigurationScreen(final Screen parent, final ConfigurationManager configManager) {
super(parent, MENU_TITLE);
this.configManager = configManager;
}

@Override
public void tick() {
super.tick();
this.twitchIdField.tick();
}

@Override
protected void init() {
final int widgetWidth = 200;
final int widgetHeight = 20;
final int widgetX = (this.width - widgetWidth) / 2;
final Configuration config = this.configManager.getConfig();

this.twitchIdField = new TextFieldWidget(this.textRenderer, widgetX, 75, widgetWidth, widgetHeight, TWITCH_ID_LABEL);
this.twitchIdField.setMaxLength(32);
this.twitchIdField.setText(config.twitchId().get());
this.twitchIdField.setChangedListener((value) -> this.validateInputs());
this.addDrawableChild(this.twitchIdField);

final int buttonSpacing = widgetHeight + 6;
int buttonY = this.height - 5;

buttonY -= buttonSpacing;
this.doneButton = this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, this::saveAndClose)
.dimensions(widgetX, buttonY, widgetWidth, widgetHeight).build());

buttonY -= buttonSpacing;
this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, this::discardAndClose)
.dimensions(widgetX, buttonY, widgetWidth, widgetHeight).build());

this.validateInputs();
}

@Override
public void resize(MinecraftClient client, int width, int height) {
final String twitchIdValue = this.twitchIdField.getText();
super.resize(client, width, height);
this.twitchIdField.setText(twitchIdValue);
}

private void saveAndClose(final ButtonWidget ignored) {
final Configuration config = this.configManager.getConfig();

final String twitchIdValue = this.twitchIdField.getText();
config.twitchId().set(twitchIdValue);

this.configManager.save();
this.close();
}

private void discardAndClose(final ButtonWidget ignored) {
this.close();
}

private void validateInputs() {
final Configuration config = this.configManager.getConfig();

final String twitchIdValue = this.twitchIdField.getText();
final boolean isTwitchIdValid = twitchIdValue != null && config.twitchId().isValid(twitchIdValue);

this.twitchIdField.setEditableColor(isTwitchIdValid ? TEXTFIELD_VALID_COLOR : TEXTFIELD_INVALID_COLOR);

this.doneButton.active = isTwitchIdValid;
}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
this.renderBackground(context, 41, 67);

context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 16, TITLE_COLOR);
context.drawTextWithShadow(this.textRenderer, TWITCH_ID_LABEL, this.width / 2 - 100, 60, LABEL_COLOR);

super.render(context, mouseX, mouseY, delta);
}
}
3 changes: 3 additions & 0 deletions src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
],
"client": [
"net.vinrobot.mcemote.client.MinecraftEmoteModClient"
],
"modmenu": [
"net.vinrobot.mcemote.client.MinecraftEmoteModMenuApi"
]
},
"accessWidener": "mcemote.accesswidener",
Expand Down

0 comments on commit e1410df

Please sign in to comment.