Adding multiple matches per tab

This commit is contained in:
DarkKronicle committed 2021-10-25 21:20:26 -06:00
1 parent fd2974551a
commit ed019753d9
8 files changed
+597 -30

No files matched your search

@@ -1,6 +1,8 @@
package io.github.darkkronicle.advancedchathud.config;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import fi.dy.masa.malilib.config.IConfigBase;
import fi.dy.masa.malilib.config.options.ConfigBoolean;
@@ -14,6 +16,7 @@ import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
@@ -41,21 +44,9 @@ public class ChatTab {
)
);
private ConfigStorage.SaveableConfig<ConfigString> findString = ConfigStorage.SaveableConfig.fromConfig(
"findString",
new ConfigString(
translate("findstring"),
"Divert this message!",
translate("info.findstring")
)
);
private ConfigStorage.SaveableConfig<ConfigOptionList> findType = ConfigStorage.SaveableConfig.fromConfig(
"findType",
new ConfigOptionList(
translate("findtype"),
FindType.LITERAL,
translate("info.findtype")
private List<Match> matches = new ArrayList<>(
Collections.singleton(
new Match("I will match to text!", FindType.LITERAL)
)
);
@@ -120,8 +111,6 @@ public class ChatTab {
private final ImmutableList<ConfigStorage.SaveableConfig<?>> options = ImmutableList.of(
name,
findString,
findType,
startingMessage,
forward,
abbreviation,
@@ -145,7 +134,7 @@ public class ChatTab {
);
public FindType getFind() {
return (FindType) findType.config.getOptionListValue();
return matches.get(0).getFindType();
}
public List<String> getWidgetHoverLines() {
@@ -174,9 +163,7 @@ public class ChatTab {
)
.replaceAll(
Pattern.quote("<find>"),
Matcher.quoteReplacement(
findString.config.getStringValue()
)
Matcher.quoteReplacement(matches.get(0).getPattern())
)
.replaceAll(
Pattern.quote("<findtype>"),
@@ -198,6 +185,19 @@ public class ChatTab {
option.setValueFromJsonElement(obj.get(conf.key));
}
}
Match.MatchSerializer serializer = new Match.MatchSerializer();
JsonElement findArr = obj.get("match");
if (findArr != null && findArr.isJsonArray()) {
t.getMatches().clear();
for (JsonElement o : findArr.getAsJsonArray()) {
if (o.isJsonObject()) {
Match match = serializer.load(o.getAsJsonObject());
if (match != null) {
t.getMatches().add(match);
}
}
}
}
if (obj.has("uuid")) {
try {
t.setUuid(UUID.fromString(obj.get("uuid").getAsString()));
@@ -215,10 +215,21 @@ public class ChatTab {
@Override
public JsonObject save(ChatTab tab) {
Match.MatchSerializer serializer = new Match.MatchSerializer();
JsonObject obj = new JsonObject();
for (ConfigStorage.SaveableConfig<?> option : tab.getOptions()) {
obj.add(option.key, option.config.getAsJsonElement());
}
JsonArray find = new JsonArray();
if (tab.getMatches().size() == 0) {
tab
.getMatches()
.add(new Match("I will match to text!", FindType.LITERAL));
}
for (Match m : tab.getMatches()) {
find.add(serializer.save(m));
}
obj.add("match", find);
obj.addProperty("uuid", tab.getUuid().toString());
return obj;
}
@@ -60,6 +60,23 @@ public class GuiTabEditor extends GuiConfigsBase {
);
topx += back.getWidth() + 2;
if (!main) {
String matchesText = ButtonListener.Type.MATCHES.getDisplayName();
int matchesWidth = StringUtils.getStringWidth(matchesText) + 10;
ButtonGeneric match = new ButtonGeneric(
topx + matchesWidth,
y,
matchesWidth,
true,
matchesText
);
this.addButton(
match,
new ButtonListener(ButtonListener.Type.MATCHES, this)
);
topx += match.getWidth() + 2;
}
String exportText = ButtonListener.Type.EXPORT.getDisplayName();
int exportWidth = StringUtils.getStringWidth(exportText) + 10;
ButtonGeneric export = new ButtonGeneric(
@@ -156,17 +173,21 @@ public class GuiTabEditor extends GuiConfigsBase {
} else if (this.type == ButtonListener.Type.EXPORT) {
parent.save();
GuiBase.openGui(SharingScreen.fromTab(parent.tab, parent));
} else if (this.type == Type.MATCHES) {
parent.save();
GuiBase.openGui(new MatchesEditor(parent, parent.tab));
}
}
public enum Type {
BACK("back"),
EXPORT("export");
EXPORT("export"),
MATCHES("matches");
private final String translation;
private static String translate(String key) {
return "advancedchat.gui.button." + key;
return "advancedchathud.gui.button." + key;
}
Type(String key) {
@@ -0,0 +1,38 @@
package io.github.darkkronicle.advancedchathud.config;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.darkkronicle.advancedchatcore.interfaces.IJsonSave;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Match {
private String pattern;
private FindType findType;
public static class MatchSerializer implements IJsonSave<Match> {
@Override
public Match load(JsonObject obj) {
JsonElement pattern = obj.get("pattern");
JsonElement findType = obj.get("findtype");
if (pattern == null || findType == null) {
return null;
}
FindType type = FindType.fromFindType(findType.getAsString());
return new Match(pattern.getAsString(), type);
}
@Override
public JsonObject save(Match match) {
JsonObject obj = new JsonObject();
obj.addProperty("pattern", match.getPattern());
obj.addProperty("findtype", match.getFindType().configString);
return obj;
}
}
}
@@ -0,0 +1,130 @@
package io.github.darkkronicle.advancedchathud.config;
import fi.dy.masa.malilib.gui.GuiListBase;
import fi.dy.masa.malilib.gui.button.ButtonBase;
import fi.dy.masa.malilib.gui.button.ButtonGeneric;
import fi.dy.masa.malilib.gui.button.IButtonActionListener;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import net.minecraft.client.gui.screen.Screen;
public class MatchesEditor
extends GuiListBase<Match, WidgetMatchEntry, WidgetListMatches> {
private final ChatTab tab;
@Override
public void initGui() {
super.initGui();
this.setListPosition(this.getListX(), 68);
int y = 26;
int x = this.width - 10;
this.addButton(x, y, ButtonListener.Type.ADD_MATCH, true);
this.addButton(2, y, ButtonListener.Type.BACK, false);
}
@Override
protected void closeGui(boolean showParent) {
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
super.closeGui(showParent);
}
protected MatchesEditor(Screen parent, ChatTab tab) {
super(10, 60);
this.title =
StringUtils.translate("advancedchathud.config.match.screen.name");
this.tab = tab;
this.setParent(parent);
}
protected int addButton(
int x,
int y,
ButtonListener.Type type,
boolean rightAlign
) {
ButtonGeneric button = new ButtonGeneric(
x,
y,
-1,
rightAlign,
type.getDisplayName()
);
this.addButton(button, new ButtonListener(type, this));
return button.getWidth();
}
@Override
protected WidgetListMatches createListWidget(int listX, int listY) {
return new WidgetListMatches(
listX,
listY,
this.getBrowserWidth(),
this.getBrowserHeight(),
null,
tab,
this
);
}
@Override
protected int getBrowserWidth() {
return this.width - 20;
}
@Override
protected int getBrowserHeight() {
return this.height - 6 - this.getListY();
}
public void addMatch() {
tab
.getMatches()
.add(new Match("I will match to text!", FindType.LITERAL));
getListWidget().refreshEntries();
}
public void back() {
this.closeGui(true);
}
private static class ButtonListener implements IButtonActionListener {
private final ButtonListener.Type type;
private final MatchesEditor gui;
public ButtonListener(ButtonListener.Type type, MatchesEditor gui) {
this.type = type;
this.gui = gui;
}
@Override
public void actionPerformedWithButton(
ButtonBase button,
int mouseButton
) {
if (this.type == ButtonListener.Type.ADD_MATCH) {
this.gui.addMatch();
} else if (this.type == ButtonListener.Type.BACK) {
this.gui.back();
}
}
public enum Type {
ADD_MATCH("advancedchathud.gui.button.addmatch"),
BACK("advancedchathud.button.back");
private final String translationKey;
Type(String translationKey) {
this.translationKey = translationKey;
}
public String getDisplayName() {
return StringUtils.translate(this.translationKey);
}
}
}
}
@@ -0,0 +1,93 @@
package io.github.darkkronicle.advancedchathud.config;
import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
import fi.dy.masa.malilib.gui.interfaces.ISelectionListener;
import fi.dy.masa.malilib.gui.widgets.WidgetListBase;
import fi.dy.masa.malilib.gui.wrappers.TextFieldWrapper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.minecraft.client.gui.screen.Screen;
public class WidgetListMatches extends WidgetListBase<Match, WidgetMatchEntry> {
public final ChatTab tab;
protected final List<TextFieldWrapper<GuiTextFieldGeneric>> textFields = new ArrayList<>();
@Override
protected void reCreateListEntryWidgets() {
textFields.clear();
super.reCreateListEntryWidgets();
}
public void addTextField(TextFieldWrapper<GuiTextFieldGeneric> text) {
textFields.add(text);
}
@Override
public boolean onMouseClicked(int mouseX, int mouseY, int mouseButton) {
clearTextFieldFocus();
return super.onMouseClicked(mouseX, mouseY, mouseButton);
}
protected void clearTextFieldFocus() {
for (TextFieldWrapper<GuiTextFieldGeneric> field : this.textFields) {
GuiTextFieldGeneric textField = field.getTextField();
if (textField.isFocused()) {
textField.setFocused(false);
break;
}
}
}
@Override
public boolean onKeyTyped(int keyCode, int scanCode, int modifiers) {
for (WidgetMatchEntry widget : this.listWidgets) {
if (widget.onKeyTyped(keyCode, scanCode, modifiers)) {
return true;
}
}
return super.onKeyTyped(keyCode, scanCode, modifiers);
}
public WidgetListMatches(
int x,
int y,
int width,
int height,
ISelectionListener<Match> selectionListener,
ChatTab parent,
Screen screen
) {
super(x, y, width, height, selectionListener);
this.browserEntryHeight = 22;
this.tab = parent;
this.setParent(screen);
}
@Override
protected WidgetMatchEntry createListEntryWidget(
int x,
int y,
int listIndex,
boolean isOdd,
Match entry
) {
return new WidgetMatchEntry(
x,
y,
this.browserEntryWidth,
this.getBrowserEntryHeightFor(entry),
isOdd,
entry,
listIndex,
this
);
}
@Override
protected Collection<Match> getAllEntries() {
return tab.getMatches();
}
}
@@ -0,0 +1,263 @@
package io.github.darkkronicle.advancedchathud.config;
import com.mojang.blaze3d.systems.RenderSystem;
import fi.dy.masa.malilib.config.options.ConfigOptionList;
import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
import fi.dy.masa.malilib.gui.button.ButtonBase;
import fi.dy.masa.malilib.gui.button.ButtonGeneric;
import fi.dy.masa.malilib.gui.button.ConfigButtonOptionList;
import fi.dy.masa.malilib.gui.button.IButtonActionListener;
import fi.dy.masa.malilib.gui.interfaces.ITextFieldListener;
import fi.dy.masa.malilib.gui.widgets.WidgetBase;
import fi.dy.masa.malilib.gui.widgets.WidgetListEntryBase;
import fi.dy.masa.malilib.gui.wrappers.TextFieldWrapper;
import fi.dy.masa.malilib.render.RenderUtils;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack;
@Environment(EnvType.CLIENT)
public class WidgetMatchEntry extends WidgetListEntryBase<Match> {
private final WidgetListMatches parent;
private final boolean isOdd;
private TextFieldWrapper<GuiTextFieldGeneric> name;
private ConfigOptionList findType = new ConfigOptionList(
"advancedchathud.config.match.findtype",
FindType.LITERAL,
"advancedchathud.config.match.info.findtype"
);
public WidgetMatchEntry(
int x,
int y,
int width,
int height,
boolean isOdd,
Match entry,
int listIndex,
WidgetListMatches parent
) {
super(x, y, width, height, entry, listIndex);
this.isOdd = isOdd;
this.parent = parent;
y += 1;
int pos = x + width - 2;
int removeWidth = 0;
if (listIndex != 0) {
// Always want one
removeWidth = addButton(pos, y, ButtonListener.Type.REMOVE) + 1;
}
pos -= removeWidth;
int replaceWidth = 100;
int nameWidth = width - replaceWidth - removeWidth;
this.findType.setOptionListValue(entry.getFindType());
ConfigButtonOptionList findType = new ConfigButtonOptionList(
pos - replaceWidth,
y,
replaceWidth,
20,
this.findType
);
this.addButton(
findType,
(button, mouseButton) -> {
entry.setFindType(
(FindType) this.findType.getOptionListValue()
);
}
);
pos -= replaceWidth + 1;
GuiTextFieldGeneric nameField = new GuiTextFieldGeneric(
pos - nameWidth,
y,
nameWidth,
20,
MinecraftClient.getInstance().textRenderer
);
nameField.setMaxLength(64000);
nameField.setText(entry.getPattern());
name = new TextFieldWrapper<>(nameField, new SaveListener(this));
parent.addTextField(name);
}
private static class SaveListener
implements ITextFieldListener<GuiTextFieldGeneric> {
private final WidgetMatchEntry parent;
public SaveListener(WidgetMatchEntry parent) {
this.parent = parent;
}
@Override
public boolean onTextChange(GuiTextFieldGeneric textField) {
parent.entry.setPattern(textField.getText());
return false;
}
}
protected int addButton(int x, int y, ButtonListener.Type type) {
ButtonGeneric button = new ButtonGeneric(
x,
y,
-1,
true,
type.getDisplayName()
);
this.addButton(button, new ButtonListener(type, this));
return button.getWidth() + 1;
}
@Override
protected boolean onKeyTypedImpl(int keyCode, int scanCode, int modifiers) {
if (this.name.isFocused()) {
return this.name.onKeyTyped(keyCode, scanCode, modifiers);
}
return false;
}
@Override
protected boolean onCharTypedImpl(char charIn, int modifiers) {
if (this.name.onCharTyped(charIn, modifiers)) {
return true;
}
return super.onCharTypedImpl(charIn, modifiers);
}
@Override
protected boolean onMouseClickedImpl(
int mouseX,
int mouseY,
int mouseButton
) {
if (super.onMouseClickedImpl(mouseX, mouseY, mouseButton)) {
return true;
}
boolean ret = false;
if (this.name != null) {
ret =
this.name.getTextField()
.mouseClicked(mouseX, mouseY, mouseButton);
}
if (!this.subWidgets.isEmpty()) {
for (WidgetBase widget : this.subWidgets) {
ret |=
widget.isMouseOver(mouseX, mouseY) &&
widget.onMouseClicked(mouseX, mouseY, mouseButton);
}
}
return ret;
}
protected void drawTextFields(
int mouseX,
int mouseY,
MatrixStack matrixStack
) {
if (this.name != null) {
this.name.getTextField().render(matrixStack, mouseX, mouseY, 0f);
}
}
private static class ButtonListener implements IButtonActionListener {
private final ButtonListener.Type type;
private final WidgetMatchEntry parent;
public ButtonListener(
ButtonListener.Type type,
WidgetMatchEntry parent
) {
this.parent = parent;
this.type = type;
}
@Override
public void actionPerformedWithButton(
ButtonBase button,
int mouseButton
) {
if (type == ButtonListener.Type.REMOVE) {
parent.parent.tab.getMatches().remove(parent.entry);
parent.parent.refreshEntries();
}
}
public enum Type {
REMOVE("remove");
private final String translate;
Type(String name) {
this.translate = translate(name);
}
private static String translate(String key) {
return "advancedchathud.config.match." + key;
}
public String getDisplayName() {
return StringUtils.translate(translate);
}
}
}
@Override
public void render(
int mouseX,
int mouseY,
boolean selected,
MatrixStack matrixStack
) {
RenderUtils.color(1f, 1f, 1f, 1f);
// Draw a lighter background for the hovered and the selected entry
if (selected || this.isMouseOver(mouseX, mouseY)) {
RenderUtils.drawRect(
this.x,
this.y,
this.width,
this.height,
ColorUtil.WHITE.withAlpha(150).color()
);
} else if (this.isOdd) {
RenderUtils.drawRect(
this.x,
this.y,
this.width,
this.height,
ColorUtil.WHITE.withAlpha(70).color()
);
} else {
RenderUtils.drawRect(
this.x,
this.y,
this.width,
this.height,
ColorUtil.WHITE.withAlpha(50).color()
);
}
RenderUtils.color(1f, 1f, 1f, 1f);
RenderSystem.disableBlend();
this.drawTextFields(mouseX, mouseY, matrixStack);
super.render(mouseX, mouseY, selected, matrixStack);
RenderUtils.disableDiffuseLighting();
}
}
@@ -4,6 +4,9 @@ import io.github.darkkronicle.advancedchatcore.util.FindType;
import io.github.darkkronicle.advancedchatcore.util.FluidText;
import io.github.darkkronicle.advancedchatcore.util.SearchUtils;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.Match;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import net.minecraft.text.Text;
@@ -17,10 +20,7 @@ public class CustomChatTab extends AbstractChatTab {
private String name;
@Getter
private FindType findType;
@Getter
private String findString;
private List<Match> matches;
@Getter
private boolean forward;
@@ -42,8 +42,7 @@ public class CustomChatTab extends AbstractChatTab {
storage.getUuid()
);
this.storage = storage;
this.findType = storage.getFind();
this.findString = storage.getFindString().config.getStringValue();
this.matches = new ArrayList<>(storage.getMatches());
this.forward = storage.getForward().config.getBooleanValue();
this.startingMessage =
storage.getStartingMessage().config.getStringValue();
@@ -52,6 +51,12 @@ public class CustomChatTab extends AbstractChatTab {
@Override
public boolean shouldAdd(Text text) {
FluidText newText = new FluidText(text);
return SearchUtils.isMatch(newText.getString(), findString, findType);
String search = newText.getString();
for (Match m : matches) {
if (SearchUtils.isMatch(search, m.getPattern(), m.getFindType())) {
return true;
}
}
return false;
}
}
@@ -9,6 +9,12 @@
"advancedchathud.config.general.info.timeformat": "How time is displayed if §6Show Time§r is enabled for both the §9Chat HUD§r and the §aChat Log§r. \nSee the §6SimpleDateFormat§r class for the format ",
"advancedchathud.config.general.chatheads": "Display Chat Heads",
"advancedchathud.config.general.info.chatheads": "Whether or not the §6head of the message sender§r displays beside their message",
"advancedchathud.gui.button.matches": "Matches",
"advancedchathud.gui.button.back": "Back",
"advancedchathud.gui.button.export": "Export",
"advancedchathud.gui.button.addmatch": "§aAdd Match",
"advancedchathud.config.match.remove": "§cRemove",
"advancedchathud.config.match.screen.name": "Matches",
"advancedchathud.config.general.width": "Chat Width",
"advancedchathud.config.general.info.width": "The §6width §rof the §9Chat HUD \nOverrides Vanilla chat width!",