Skip to content

Commit

Permalink
feat: New configuration screen
Browse files Browse the repository at this point in the history
  • Loading branch information
Norbiros committed Sep 3, 2024
1 parent d9703b9 commit 9ea4b99
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package dev.norbiros.emojitype.config;

import dev.norbiros.emojitype.emoji.EmojiCode;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.EditBoxWidget;
import net.minecraft.client.gui.widget.ElementListWidget;
import net.minecraft.text.Text;

import java.util.ArrayList;
import java.util.List;

public class EmojiListWidget extends ElementListWidget<EmojiListWidget.EmojiWidgetEntry> {
public EmojiListWidget(MinecraftClient client, int width, int height, int top, int itemHeight) {
super(client, width, height, top, itemHeight);
}

public void addEntry(EmojiCode emoji) {
this.addEntry(new EmojiListWidget.EmojiWidgetEntry(width, emoji, this));
}

public void addEntryAfter(EmojiCode emoji, EmojiWidgetEntry element) {
var index = this.children().indexOf(element);
this.children().add(index + 1, new EmojiListWidget.EmojiWidgetEntry(width, emoji, this));
}

public List<String> getCurrentCodes() {
List<String> codes = new ArrayList<>();
for (EmojiWidgetEntry entry : this.children()) {
codes.add(entry.getEmojiCode().toString());
}
return codes;
}

@Override
public int getRowWidth() {
return width - 40;
}

@Override
protected int getScrollbarX() {
return width - 12;
}

public static class EmojiWidgetEntry extends ElementListWidget.Entry<EmojiWidgetEntry> {

private final EmojiListWidget parent;
List<ClickableWidget> elements = new ArrayList<>();

public EmojiWidgetEntry(int entryWidth, EmojiCode emoji, EmojiListWidget parent) {
this.parent = parent;
MinecraftClient client = MinecraftClient.getInstance();

var editBoxWidgetEmoji = new EditBoxWidget(client.textRenderer,
entryWidth / 2 - 200,
0,
110,
18,
Text.empty(),
Text.empty()
);
editBoxWidgetEmoji.setText(emoji.getEmoji());
this.elements.add(editBoxWidgetEmoji);

var editBoxWidgetCode = new EditBoxWidget(client.textRenderer,
entryWidth / 2 - 85,
0,
235,
18,
Text.empty(),
Text.empty()
);
var emojiCode = emoji.getCode();
editBoxWidgetCode.setText(emojiCode.substring(1, emojiCode.length() - 1));
this.elements.add(editBoxWidgetCode);

this.elements.add(ButtonWidget
.builder(Text.literal("➕"), button -> this.parent.addEntryAfter(EmojiCode.EMPTY, this))
.dimensions(entryWidth / 2 + 157, 0, 20, 20)
.tooltip(Tooltip.of(Text.translatable("config.emojitype.add_entry_below_tooltip")))
.build()
);
this.elements.add(ButtonWidget
.builder(Text.literal("❌"), button -> this.parent.removeEntry(this))
.dimensions(entryWidth / 2 + 180, 0, 20, 20)
.tooltip(Tooltip.of(Text.translatable("config.emojitype.remove_entry_tooltip")))
.build()
);
}

public EmojiCode getEmojiCode() {
EditBoxWidget emoji = (EditBoxWidget) this.elements.get(0);
EditBoxWidget key = (EditBoxWidget) this.elements.get(1);

return new EmojiCode(":" + key.getText() + ":", emoji.getText());
}

public List<? extends Element> children() {
return this.elements;
}

public List<? extends Selectable> selectableChildren() {
return this.elements;
}

@Override
public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
for (ClickableWidget element : this.elements) {
if (element instanceof ButtonWidget) {
element.setY(y - 1);
} else {
element.setY(y);
}
element.render(context, mouseX, mouseY, tickDelta);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,88 @@

import dev.norbiros.emojitype.EmojiType;
import dev.norbiros.emojitype.emoji.EmojiCode;
import me.shedaniel.clothconfig2.api.ConfigBuilder;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.DirectionalLayoutWidget;
import net.minecraft.client.gui.widget.ThreePartsLayoutWidget;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class EmojiTypeConfig {
public static Screen createConfigScreen(Screen parent) {
ConfigUtil.deserialise();
ConfigBuilder builder = ConfigBuilder
.create()
.setParentScreen(parent)
.setTitle(Text.translatable("config.emojitype.title"))
.setSavingRunnable(ConfigUtil::serialise);

ConfigEntryBuilder entryBuilder = builder.entryBuilder();
builder.getOrCreateCategory(Text.translatable("config.emojitype.category"))
.addEntry(entryBuilder.startStrList(Text.translatable("config.emojitype.codes"), ConfigUtil.emojiCodeStrings)
.setDefaultValue(() -> {
ArrayList<String> l = new ArrayList<>();
for (EmojiCode ec : EmojiType.DEFAULT_EMOJI_CODES) {
l.add(ec.toString());
}
return l;
})
.setSaveConsumer((List<String> lstr) -> {
ConfigUtil.emojiCodeStrings.clear();
ConfigUtil.emojiCodeStrings.addAll(lstr);
})
.build());
return builder.build();
public class EmojiTypeConfig extends Screen {
public final ThreePartsLayoutWidget layout = new ThreePartsLayoutWidget(this);
protected final Screen parent;
public boolean shouldSaveConfig = true;
private @Nullable EmojiListWidget body;

public EmojiTypeConfig(Screen parent) {
super(Text.translatable("config.emojitype.title"));
this.parent = parent;
this.layout.setHeaderHeight(30);
this.layout.setFooterHeight(30);
}

public static Screen createConfigScreen(Screen parent) {
ConfigUtil.deserialise();
return new EmojiTypeConfig(parent);
}

@Override
protected void init() {
this.layout.addHeader(this.title, this.textRenderer);

var emojiListWidget = new EmojiListWidget(client, width, height - 30 - 30, 30, 20);
for (EmojiCode emoji : EmojiType.emojiCodes) {
emojiListWidget.addEntry(emoji);
}
this.body = this.layout.addBody(emojiListWidget);

this.initFooter();

this.layout.forEachChild(this::addDrawableChild);
this.initTabNavigation();
}


@Override
protected void initTabNavigation() {
this.layout.refreshPositions();
if (this.body != null) {
this.body.position(this.width, this.layout);
}
}

protected void initFooter() {
DirectionalLayoutWidget directionalLayoutWidget = this.layout.addFooter(DirectionalLayoutWidget.horizontal()).spacing(8);

directionalLayoutWidget.add(ButtonWidget.builder(Text.translatable("config.emojitype.cancel"), (button) -> {
this.shouldSaveConfig = false;
this.close();
}).width(100).build());

directionalLayoutWidget.add(ButtonWidget.builder(Text.translatable("config.emojitype.reset_all"), (button) -> {
if (this.body == null) {
return;
}
this.body.children().clear();
for (EmojiCode emoji : EmojiType.DEFAULT_EMOJI_CODES) {
this.body.addEntry(emoji);
}
}).width(100).build());

directionalLayoutWidget.add(ButtonWidget.builder(Text.translatable("config.emojitype.save_and_quit"), (button) -> this.close()).width(100).build());
}

@Override
public void close() {
if (this.body != null && this.shouldSaveConfig) {
var codes = this.body.getCurrentCodes();
ConfigUtil.emojiCodeStrings.clear();
ConfigUtil.emojiCodeStrings.addAll(codes);
ConfigUtil.serialise();
}

if (this.client != null) {
this.client.setScreen(this.parent);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.Optional;

public class EmojiCode {
public static EmojiCode EMPTY = new EmojiCode("::", "");
public static String DELIMITER = ";";
private final String code;
private final String emoji;
Expand Down Expand Up @@ -43,10 +44,6 @@ public boolean match(String string, int charIndex) {
}

public String toString() {
if (code.length() >= 3) {
return code.substring(1, code.length() - 1) + DELIMITER + emoji;
} else {
return code + DELIMITER + emoji;
}
return code.substring(1, code.length() - 1) + DELIMITER + emoji;
}
}
7 changes: 5 additions & 2 deletions common/src/main/resources/assets/emojitype/lang/en_us.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"config.emojitype.title": "Emoji Type Config",
"config.emojitype.category": "Emoji Type Category",
"config.emojitype.codes": "Emoji Codes",
"config.emojitype.cancel": "Cancel",
"config.emojitype.reset_all": "Reset config",
"config.emojitype.save_and_quit": "Save & Quit",
"config.emojitype.add_entry_below_tooltip": "Add below",
"config.emojitype.remove_entry_tooltip": "Remove",
"modmenu.descriptionTranslation.emojitype": "A mod that lets you type minecraft emojis easier!"
}
7 changes: 5 additions & 2 deletions common/src/main/resources/assets/emojitype/lang/pl_pl.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"config.emojitype.title": "Konfiguracja Emoji Type",
"config.emojitype.category": "Kategoria Emoji Type",
"config.emojitype.codes": "Kody Emotikonów",
"config.emojitype.cancel": "Anuluj",
"config.emojitype.reset_all": "Zresetuj konfigurację",
"config.emojitype.save_and_quit": "Zapisz i wyjdź",
"config.emojitype.add_entry_below_tooltip": "Dodaj poniżej",
"config.emojitype.remove_entry_tooltip": "Usuń",
"modmenu.descriptionTranslation.emojitype": "Mod ułatwiający wpisywanie emotek w Minecraft!"
}
2 changes: 0 additions & 2 deletions common/src/main/resources/assets/emojitype/lang/zh_tw.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"config.emojitype.title": "表情符號輸入設定",
"config.emojitype.category": "表情符號類別",
"config.emojitype.codes": "表情符號代碼",
"modmenu.descriptionTranslation.emojitype": "一個讓你更容易輸入 Minecraft 表情符號的模組!"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import dev.norbiros.emojitype.config.EmojiTypeConfig;
import net.fabricmc.loader.api.FabricLoader;

public class ModMenuIntegration implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
if (!FabricLoader.getInstance().isModLoaded("cloth-config2")) {
return null;
}

return EmojiTypeConfig::createConfigScreen;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import dev.norbiros.emojitype.EmojiType;
import dev.norbiros.emojitype.config.EmojiTypeConfig;
import net.neoforged.fml.ModList;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
Expand All @@ -12,9 +11,7 @@ public class EmojitypeNeoforge {
public EmojitypeNeoforge() {
EmojiType.init();

if (ModList.get().isLoaded("cloth_config")) {
ModLoadingContext.get().registerExtensionPoint(IConfigScreenFactory.class,
() -> (client, parent) -> EmojiTypeConfig.createConfigScreen(parent));
}
ModLoadingContext.get().registerExtensionPoint(IConfigScreenFactory.class,
() -> (client, parent) -> EmojiTypeConfig.createConfigScreen(parent));
}
}

0 comments on commit 9ea4b99

Please sign in to comment.