Working version

This commit is contained in:
DarkKronicle committed 2021-10-22 21:25:19 -06:00
1 parent 4913d891bd
commit ee0243dd7e
26 files changed
+2986 -38

No files matched your search

+1
View File
@@ -1,6 +1,7 @@
plugins {
id 'fabric-loom' version '0.8-SNAPSHOT'
id 'maven-publish'
id "io.freefair.lombok" version "6.0.0-m2"
}
sourceCompatibility = JavaVersion.VERSION_16
+1 -1
View File
@@ -13,4 +13,4 @@ archives_base_name=ACModuleTemplate
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_api_version=0.37.2+1.17
malilib_version = 0.10.0-dev.22+beta.1
advancedchat_version=v1.1.0-beta1
advancedchat_version=1.1.0-beta1
@@ -1,6 +1,7 @@
package io.github.darkkronicle.advancedchathud;
import fi.dy.masa.malilib.event.InitializationHandler;
import io.github.darkkronicle.advancedchathud.tabs.MainChatTab;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -9,11 +10,13 @@ import net.fabricmc.api.Environment;
public class AdvancedChatHud implements ClientModInitializer {
public static final String MOD_ID = "advancedchathud";
public static MainChatTab MAIN_CHAT_TAB;
@Override
public void onInitializeClient() {
// This will run after AdvancedChatCore's because of load order
InitializationHandler.getInstance().registerInitializationHandler(new HudInitHandler());
InitializationHandler
.getInstance()
.registerInitializationHandler(new HudInitHandler());
}
}
@@ -0,0 +1,55 @@
package io.github.darkkronicle.advancedchathud;
import io.github.darkkronicle.advancedchatcore.chat.ChatMessage;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import io.github.darkkronicle.advancedchathud.tabs.CustomChatTab;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class HudChatMessage {
@Setter
@Getter
private List<AbstractChatTab> tabs;
@Getter
private final ChatMessage message;
public HudChatMessage(ChatMessage message) {
this(message, new ArrayList<>());
ArrayList<AbstractChatTab> added = new ArrayList<>();
boolean forward = true;
if (AdvancedChatHud.MAIN_CHAT_TAB.getCustomChatTabs().size() > 0) {
for (CustomChatTab tab : AdvancedChatHud.MAIN_CHAT_TAB.getCustomChatTabs()) {
if (!tab.shouldAdd(message.getOriginalText())) {
continue;
}
if (added.contains(tab)) {
continue;
}
added.add(tab);
if (!tab.isForward()) {
forward = false;
break;
}
}
}
if (forward) {
added.add(AdvancedChatHud.MAIN_CHAT_TAB);
}
for (AbstractChatTab tab : added) {
tab.addNewUnread();
}
setTabs(added);
}
public HudChatMessage(ChatMessage message, List<AbstractChatTab> tabs) {
this.message = message;
this.tabs = tabs;
}
}
@@ -0,0 +1,71 @@
package io.github.darkkronicle.advancedchathud;
import io.github.darkkronicle.advancedchatcore.chat.ChatMessage;
import io.github.darkkronicle.advancedchatcore.interfaces.IChatMessageProcessor;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.gui.WindowManager;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class HudChatMessageHolder implements IChatMessageProcessor {
@Getter
private final List<HudChatMessage> messages = new ArrayList<>();
private static final HudChatMessageHolder INSTANCE = new HudChatMessageHolder();
private HudChatMessageHolder() {}
public static HudChatMessageHolder getInstance() {
return INSTANCE;
}
@Override
public void onMessageUpdate(ChatMessage message, UpdateType type) {
if (type == UpdateType.ADDED) {
addMessage(new HudChatMessage(message));
} else if (type == UpdateType.REMOVE) {
remove(message);
} else if (type == UpdateType.STACK) {
HudChatMessage m = getMessage(message);
if (m != null) {
WindowManager.getInstance().onStackedMessage(m);
}
}
}
public void addMessage(HudChatMessage message) {
messages.add(0, message);
WindowManager.getInstance().onNewMessage(message);
while (
messages.size() >
HudConfigStorage.General.STORED_LINES.config.getIntegerValue()
) {
messages.remove(messages.size() - 1);
}
}
public void clear() {
this.messages.clear();
}
public void remove(ChatMessage message) {
HudChatMessage remove = getMessage(message);
if (remove != null) {
messages.remove(remove);
}
}
public HudChatMessage getMessage(ChatMessage message) {
for (HudChatMessage m : messages) {
if (m.getMessage().getUuid().equals(message.getUuid())) {
return m;
}
}
return null;
}
}
@@ -1,28 +1,86 @@
package io.github.darkkronicle.advancedchathud;
import fi.dy.masa.malilib.config.ConfigManager;
import fi.dy.masa.malilib.event.RenderEventHandler;
import fi.dy.masa.malilib.interfaces.IInitializationHandler;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchatcore.chat.ChatHistory;
import io.github.darkkronicle.advancedchatcore.chat.ChatScreenSectionHolder;
import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfigHandler;
import io.github.darkkronicle.advancedchatcore.interfaces.IChatMessageProcessor;
import io.github.darkkronicle.advancedchathud.config.GuiTabManager;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.gui.HudSection;
import io.github.darkkronicle.advancedchathud.gui.WindowManager;
import io.github.darkkronicle.advancedchathud.tabs.MainChatTab;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screen.Screen;
@Environment(EnvType.CLIENT)
public class HudInitHandler implements IInitializationHandler {
@Override
public void registerModHandlers() {
ConfigManager.getInstance().registerConfigHandler(AdvancedChatHud.MOD_ID, new HudConfigStorage());
GuiConfigHandler.getInstance().addGuiSection(GuiConfigHandler.createGuiConfigSection(
StringUtils.translate("advancedchathud.tab.general"), HudConfigStorage.General.OPTIONS
));
ConfigManager
.getInstance()
.registerConfigHandler(
AdvancedChatHud.MOD_ID,
new HudConfigStorage()
);
GuiConfigHandler
.getInstance()
.addGuiSection(
GuiConfigHandler.createGuiConfigSection(
StringUtils.translate("advancedchathud.tab.general"),
HudConfigStorage.General.OPTIONS
)
);
GuiConfigHandler
.getInstance()
.addGuiSection(
new GuiConfigHandler.Tab() {
@Override
public String getName() {
return StringUtils.translate(
"advancedchathud.tab.tabs"
);
}
@Override
public Screen getScreen(
List<GuiConfigHandler.TabButton> buttons
) {
return new GuiTabManager(buttons);
}
}
);
AdvancedChatHud.MAIN_CHAT_TAB = new MainChatTab();
// Register on new message
ChatHistory.getInstance().addOnMessage(chatMessage -> System.out.println("Chat message happened!"));
// Register on the clear
ChatHistory.getInstance().addOnClear(() -> System.out.println(HudConfigStorage.General.STRING_STUFF.config.getStringValue()));
ChatScreenSectionHolder
.getInstance()
.addSectionSupplier(HudSection::new);
ChatHistory
.getInstance()
.addOnClear(() -> WindowManager.getInstance().clear());
ChatHistory
.getInstance()
.addOnClear(() -> HudChatMessageHolder.getInstance().clear());
ChatHistory
.getInstance()
.addOnUpdate((message, type) -> {
if (type == IChatMessageProcessor.UpdateType.ADDED) {
HudChatMessageHolder
.getInstance()
.addMessage(new HudChatMessage(message));
} else if (type == IChatMessageProcessor.UpdateType.REMOVE) {
HudChatMessageHolder.getInstance().remove(message);
}
});
RenderEventHandler
.getInstance()
.registerGameOverlayRenderer(WindowManager.getInstance());
}
}
@@ -0,0 +1,196 @@
package io.github.darkkronicle.advancedchathud.config;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonObject;
import fi.dy.masa.malilib.config.IConfigBase;
import fi.dy.masa.malilib.config.options.ConfigBoolean;
import fi.dy.masa.malilib.config.options.ConfigOptionList;
import fi.dy.masa.malilib.config.options.ConfigString;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
import io.github.darkkronicle.advancedchatcore.config.options.ConfigSimpleColor;
import io.github.darkkronicle.advancedchatcore.interfaces.IJsonSave;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.Data;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Data
@Environment(EnvType.CLIENT)
public class ChatTab {
private static String translate(String key) {
return StringUtils.translate("advancedchathud.config.tab." + key);
}
private ConfigStorage.SaveableConfig<ConfigString> name = ConfigStorage.SaveableConfig.fromConfig(
"name",
new ConfigString(
translate("name"),
"Boring Chat Tab",
translate("info.name")
)
);
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 ConfigStorage.SaveableConfig<ConfigString> startingMessage = ConfigStorage.SaveableConfig.fromConfig(
"startingMessage",
new ConfigString(
translate("startingmessage"),
"",
translate("info.startingmessage")
)
);
private ConfigStorage.SaveableConfig<ConfigBoolean> forward = ConfigStorage.SaveableConfig.fromConfig(
"forward",
new ConfigBoolean(translate("forward"), true, translate("info.forward"))
);
private ConfigStorage.SaveableConfig<ConfigString> abbreviation = ConfigStorage.SaveableConfig.fromConfig(
"abbreviation",
new ConfigString(
translate("abbreviation"),
"BCT",
translate("info.abbreviation")
)
);
private ConfigStorage.SaveableConfig<ConfigSimpleColor> mainColor = ConfigStorage.SaveableConfig.fromConfig(
"mainColor",
new ConfigSimpleColor(
translate("maincolor"),
ColorUtil.GRAY.withAlpha(100),
translate("info.maincolor")
)
);
private ConfigStorage.SaveableConfig<ConfigSimpleColor> borderColor = ConfigStorage.SaveableConfig.fromConfig(
"borderColor",
new ConfigSimpleColor(
translate("bordercolor"),
ColorUtil.BLACK.withAlpha(180),
translate("info.bordercolor")
)
);
private ConfigStorage.SaveableConfig<ConfigSimpleColor> innerColor = ConfigStorage.SaveableConfig.fromConfig(
"innerColor",
new ConfigSimpleColor(
translate("innercolor"),
ColorUtil.BLACK.withAlpha(100),
translate("info.innercolor")
)
);
private ConfigStorage.SaveableConfig<ConfigBoolean> showUnread = ConfigStorage.SaveableConfig.fromConfig(
"showUnread",
new ConfigBoolean(
translate("showunread"),
false,
translate("info.showunread")
)
);
private final ImmutableList<ConfigStorage.SaveableConfig<?>> options = ImmutableList.of(
name,
findString,
findType,
startingMessage,
forward,
abbreviation,
mainColor,
borderColor,
innerColor,
showUnread
);
public FindType getFind() {
return (FindType) findType.config.getOptionListValue();
}
public List<String> getWidgetHoverLines() {
String translated = StringUtils.translate(
"advancedchat.config.filterdescription"
);
ArrayList<String> hover = new ArrayList<>();
for (String s : translated.split("\n")) {
hover.add(
s
.replaceAll(
Pattern.quote("<name>"),
Matcher.quoteReplacement(name.config.getStringValue())
)
.replaceAll(
Pattern.quote("<starting>"),
Matcher.quoteReplacement(
startingMessage.config.getStringValue()
)
)
.replaceAll(
Pattern.quote("<forward>"),
Matcher.quoteReplacement(
forward.config.getStringValue()
)
)
.replaceAll(
Pattern.quote("<find>"),
Matcher.quoteReplacement(
findString.config.getStringValue()
)
)
.replaceAll(
Pattern.quote("<findtype>"),
Matcher.quoteReplacement(getFind().getDisplayName())
)
);
}
return hover;
}
public static class ChatTabJsonSave implements IJsonSave<ChatTab> {
@Override
public ChatTab load(JsonObject obj) {
ChatTab t = new ChatTab();
for (ConfigStorage.SaveableConfig<?> conf : t.getOptions()) {
IConfigBase option = conf.config;
if (obj.has(conf.key)) {
option.setValueFromJsonElement(obj.get(conf.key));
}
}
return t;
}
@Override
public JsonObject save(ChatTab tab) {
JsonObject obj = new JsonObject();
for (ConfigStorage.SaveableConfig<?> option : tab.getOptions()) {
obj.add(option.key, option.config.getAsJsonElement());
}
return obj;
}
}
}
@@ -0,0 +1,143 @@
package io.github.darkkronicle.advancedchathud.config;
import fi.dy.masa.malilib.config.IConfigBase;
import fi.dy.masa.malilib.gui.GuiBase;
import fi.dy.masa.malilib.gui.GuiConfigsBase;
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.config.ConfigStorage;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.gui.screen.Screen;
public class GuiTabEditor extends GuiConfigsBase {
private final ChatTab tab;
public GuiTabEditor(Screen parent, ChatTab tab) {
super(
10,
50,
AdvancedChatHud.MOD_ID,
null,
tab.getName().config.getStringValue()
);
this.tab = tab;
this.setParent(parent);
}
@Override
public void initGui() {
super.initGui();
createButtons(10, 26);
}
private void createButtons(int x, int y) {
String backText = ButtonListener.Type.BACK.getDisplayName();
int backWidth = StringUtils.getStringWidth(backText) + 10;
int topx = x;
ButtonGeneric back = new ButtonGeneric(
x + backWidth,
y,
backWidth,
true,
backText
);
this.addButton(
back,
new ButtonListener(ButtonListener.Type.BACK, this)
);
topx += back.getWidth() + 2;
String exportText = ButtonListener.Type.EXPORT.getDisplayName();
int exportWidth = StringUtils.getStringWidth(exportText) + 10;
ButtonGeneric export = new ButtonGeneric(
topx + exportWidth,
y,
exportWidth,
true,
exportText
);
this.addButton(
export,
new ButtonListener(ButtonListener.Type.EXPORT, this)
);
}
@Override
public List<ConfigOptionWrapper> getConfigs() {
ArrayList<IConfigBase> config = new ArrayList<>();
for (ConfigStorage.SaveableConfig<? extends IConfigBase> s : tab.getOptions()) {
config.add(s.config);
}
return GuiConfigsBase.ConfigOptionWrapper.createFor(config);
}
@Override
public void onClose() {
save();
super.onClose();
}
@Override
protected void closeGui(boolean showParent) {
// Save the changes :)
save();
super.closeGui(showParent);
}
public void save() {
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
}
public void back() {
closeGui(true);
}
public static class ButtonListener implements IButtonActionListener {
private final GuiTabEditor parent;
private final ButtonListener.Type type;
public ButtonListener(ButtonListener.Type type, GuiTabEditor parent) {
this.type = type;
this.parent = parent;
}
@Override
public void actionPerformedWithButton(
ButtonBase button,
int mouseButton
) {
if (this.type == ButtonListener.Type.BACK) {
parent.back();
} else if (this.type == ButtonListener.Type.EXPORT) {
parent.save();
GuiBase.openGui(SharingScreen.fromTab(parent.tab, parent));
}
}
public enum Type {
BACK("back"),
EXPORT("export");
private final String translation;
private static String translate(String key) {
return "advancedchat.gui.button." + key;
}
Type(String key) {
this.translation = translate(key);
}
public String getDisplayName() {
return StringUtils.translate(translation);
}
}
}
}
@@ -0,0 +1,164 @@
package io.github.darkkronicle.advancedchathud.config;
import fi.dy.masa.malilib.gui.GuiBase;
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.gui.interfaces.ISelectionListener;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.config.gui.GuiConfigHandler;
import java.util.List;
import javax.annotation.Nullable;
public class GuiTabManager
extends GuiListBase<ChatTab, WidgetTabEntry, WidgetListTabs>
implements ISelectionListener<ChatTab> {
private List<GuiConfigHandler.TabButton> tabButtons;
public GuiTabManager(List<GuiConfigHandler.TabButton> tabButtons) {
super(10, 60);
this.title = StringUtils.translate("advancedchat.screen.main");
this.tabButtons = tabButtons;
}
@Override
protected WidgetListTabs createListWidget(int listX, int listY) {
return new WidgetListTabs(
listX,
listY,
this.getBrowserWidth(),
this.getBrowserHeight(),
null,
this
);
}
@Override
protected int getBrowserWidth() {
return this.width - 20;
}
@Override
public void initGui() {
super.initGui();
int x = 10;
int y = 26;
int rows = 1;
for (GuiConfigHandler.TabButton tab : tabButtons) {
int newY = this.createButton(tab, y);
if (newY != y) {
rows++;
y = newY;
}
}
this.setListPosition(this.getListX(), 68 + (rows - 1) * 22);
this.reCreateListWidget();
this.getListWidget().refreshEntries();
y += 24;
x = this.width - 10;
x -= this.addButton(x, y, ButtonListener.Type.ADD_TAB) + 2;
x -= this.addButton(x, y, ButtonListener.Type.IMPORT) + 2;
}
private int createButton(GuiConfigHandler.TabButton button, int y) {
this.addButton(
button.getButton(),
new ButtonListenerConfigTabs(button)
);
return button.getButton().getY();
}
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();
}
private static class ButtonListener implements IButtonActionListener {
private final ButtonListener.Type type;
private final GuiTabManager gui;
public ButtonListener(ButtonListener.Type type, GuiTabManager gui) {
this.type = type;
this.gui = gui;
}
@Override
public void actionPerformedWithButton(
ButtonBase button,
int mouseButton
) {
if (this.type == ButtonListener.Type.ADD_TAB) {
HudConfigStorage.TABS.add(new ChatTab());
this.gui.getListWidget().refreshEntries();
} else if (this.type == Type.IMPORT) {
GuiBase.openGui(new SharingScreen(null, gui));
}
}
public enum Type {
ADD_TAB("addtab"),
IMPORT("import");
private static String translate(String key) {
return "advancedchathud.gui.button." + key;
}
private final String translationKey;
Type(String translationKey) {
this.translationKey = translate(translationKey);
}
public String getDisplayName() {
return StringUtils.translate(this.translationKey);
}
}
}
@Override
protected int getBrowserHeight() {
return this.height - 6 - this.getListY();
}
@Override
public void onSelectionChange(@Nullable ChatTab entry) {}
private static class ButtonListenerConfigTabs
implements IButtonActionListener {
private final GuiConfigHandler.TabButton tabButton;
public ButtonListenerConfigTabs(GuiConfigHandler.TabButton tabButton) {
this.tabButton = tabButton;
}
@Override
public void actionPerformedWithButton(
ButtonBase button,
int mouseButton
) {
GuiConfigHandler.getInstance().activeTab =
this.tabButton.getTab().getName();
GuiBase.openGui(
this.tabButton.getTab()
.getScreen(GuiConfigHandler.getInstance().getButtons())
);
}
}
}
@@ -1,81 +1,408 @@
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 com.google.gson.JsonPrimitive;
import fi.dy.masa.malilib.config.IConfigBase;
import fi.dy.masa.malilib.config.IConfigHandler;
import fi.dy.masa.malilib.config.IConfigOptionListEntry;
import fi.dy.masa.malilib.config.options.ConfigBoolean;
import fi.dy.masa.malilib.config.options.ConfigDouble;
import fi.dy.masa.malilib.config.options.ConfigInteger;
import fi.dy.masa.malilib.config.options.ConfigOptionList;
import fi.dy.masa.malilib.config.options.ConfigString;
import fi.dy.masa.malilib.util.FileUtils;
import fi.dy.masa.malilib.util.JsonUtils;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
import io.github.darkkronicle.advancedchatcore.config.options.ConfigSimpleColor;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.io.File;
import java.util.List;
import net.minecraft.util.Identifier;
@Environment(EnvType.CLIENT)
public class HudConfigStorage implements IConfigHandler {
public static final String CONFIG_FILE_NAME = AdvancedChatHud.MOD_ID + ".json";
public static final String CONFIG_FILE_NAME =
AdvancedChatHud.MOD_ID + ".json";
private static final int CONFIG_VERSION = 1;
public static final List<ChatTab> TABS = new ArrayList<>();
public static ChatTab MAIN_TAB = new ChatTab();
public static class General {
public static final String NAME = "general";
public static String translate(String key) {
return StringUtils.translate("advancedchat.module.config.general." + key);
return StringUtils.translate(
"advancedchathud.config.general." + key
);
}
public final static ConfigStorage.SaveableConfig<ConfigString> STRING_STUFF = ConfigStorage.SaveableConfig.fromConfig("string_stuff",
new ConfigString(translate("string_stuff"), "Very cool string stuff", translate("info.string_stuff")));
public final static ConfigStorage.SaveableConfig<ConfigBoolean> YES = ConfigStorage.SaveableConfig.fromConfig("yes",
new ConfigBoolean(translate("yes"), true, translate("info.yes")));
public final static ImmutableList<ConfigStorage.SaveableConfig<? extends IConfigBase>> OPTIONS = ImmutableList.of(
STRING_STUFF,
YES
public static final ConfigStorage.SaveableConfig<ConfigBoolean> CHAT_HEADS = ConfigStorage.SaveableConfig.fromConfig(
"chatHeads",
new ConfigBoolean(
translate("chatheads"),
false,
translate("info.chatheads")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> WIDTH = ConfigStorage.SaveableConfig.fromConfig(
"width",
new ConfigInteger(
translate("width"),
280,
100,
600,
translate("info.width")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> HEIGHT = ConfigStorage.SaveableConfig.fromConfig(
"height",
new ConfigInteger(
translate("height"),
117,
20,
400,
translate("info.height")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> X = ConfigStorage.SaveableConfig.fromConfig(
"x",
new ConfigInteger(translate("x"), 0, 0, 4000, translate("info.x"))
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> Y = ConfigStorage.SaveableConfig.fromConfig(
"y",
new ConfigInteger(translate("y"), 30, 0, 4000, translate("info.y"))
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> MESSAGE_SPACE = ConfigStorage.SaveableConfig.fromConfig(
"messageSpace",
new ConfigInteger(
translate("messagespace"),
0,
0,
10,
translate("info.messagespace")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> LINE_SPACE = ConfigStorage.SaveableConfig.fromConfig(
"lineSpace",
new ConfigInteger(
translate("linespace"),
9,
8,
20,
translate("info.linespace")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> LEFT_PAD = ConfigStorage.SaveableConfig.fromConfig(
"leftPad",
new ConfigInteger(
translate("leftpad"),
2,
0,
20,
translate("info.leftpad")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> RIGHT_PAD = ConfigStorage.SaveableConfig.fromConfig(
"rightPad",
new ConfigInteger(
translate("rightpad"),
2,
0,
20,
translate("info.rightpad")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> BOTTOM_PAD = ConfigStorage.SaveableConfig.fromConfig(
"bottomPad",
new ConfigInteger(
translate("bottompad"),
1,
0,
20,
translate("info.bottompad")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> TOP_PAD = ConfigStorage.SaveableConfig.fromConfig(
"topPad",
new ConfigInteger(
translate("toppad"),
0,
0,
20,
translate("info.toppad")
)
);
public static final ConfigStorage.SaveableConfig<ConfigBoolean> SHOW_TABS = ConfigStorage.SaveableConfig.fromConfig(
"showTabs",
new ConfigBoolean(
translate("showtabs"),
true,
translate("info.showtabs")
)
);
public static final ConfigStorage.SaveableConfig<ConfigOptionList> VISIBILITY = ConfigStorage.SaveableConfig.fromConfig(
"visibility",
new ConfigOptionList(
translate("visibility"),
Visibility.VANILLA,
translate("info.visibility")
)
);
public static final ConfigStorage.SaveableConfig<ConfigDouble> CHAT_SCALE = ConfigStorage.SaveableConfig.fromConfig(
translate("chatScale"),
new ConfigDouble(
translate("chatscale"),
1,
0,
1,
translate("info.chatscale")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> FADE_TIME = ConfigStorage.SaveableConfig.fromConfig(
"fadeTime",
new ConfigInteger(
translate("fadetime"),
40,
0,
200,
translate("info.fadetime")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> FADE_START = ConfigStorage.SaveableConfig.fromConfig(
"fadeStart",
new ConfigInteger(
translate("fadestart"),
100,
20,
1000,
translate("info.fadestart")
)
);
public static final ConfigStorage.SaveableConfig<ConfigOptionList> FADE_TYPE = ConfigStorage.SaveableConfig.fromConfig(
"fadeType",
new ConfigOptionList(
translate("fadetype"),
ConfigStorage.Easing.LINEAR,
translate("info.fadetype")
)
);
public static final ConfigStorage.SaveableConfig<ConfigSimpleColor> EMPTY_TEXT_COLOR = ConfigStorage.SaveableConfig.fromConfig(
"emptyTextColor",
new ConfigSimpleColor(
translate("emptytextcolor"),
ColorUtil.WHITE,
translate("info.emptytextcolor")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> TAB_SIDE_CHARS = ConfigStorage.SaveableConfig.fromConfig(
"tabSideChars",
new ConfigInteger(
translate("tabsidechars"),
3,
1,
10,
translate("info.tabsidechars")
)
);
public static final ConfigStorage.SaveableConfig<ConfigOptionList> HUD_LINE_TYPE = ConfigStorage.SaveableConfig.fromConfig(
"hudLineType",
new ConfigOptionList(
translate("hudlinetype"),
HudLineType.FULL,
translate("info.hudlinetype")
)
);
public static final ConfigStorage.SaveableConfig<ConfigBoolean> ALTERNATE_LINES = ConfigStorage.SaveableConfig.fromConfig(
"alternateLines",
new ConfigBoolean(
translate("alternatelines"),
false,
translate("info.alternatelines")
)
);
public static final ConfigStorage.SaveableConfig<ConfigBoolean> SHOW_TIME = ConfigStorage.SaveableConfig.fromConfig(
"showTime",
new ConfigBoolean(
translate("showtime"),
false,
translate("info.showtime")
)
);
public static final ConfigStorage.SaveableConfig<ConfigInteger> STORED_LINES = ConfigStorage.SaveableConfig.fromConfig(
"storedLines",
new ConfigInteger(
translate("storedlines"),
200,
20,
1000,
translate("info.storedlines")
)
);
public static final ConfigStorage.SaveableConfig<ConfigBoolean> PERSISTENT_TEXT = ConfigStorage.SaveableConfig.fromConfig(
"persistentText",
new ConfigBoolean(
translate("persistenttext"),
false,
translate("info.persistenttext")
)
);
public static final ConfigStorage.SaveableConfig<ConfigBoolean> MORE_TEXT = ConfigStorage.SaveableConfig.fromConfig(
"moreText",
new ConfigBoolean(
translate("moretext"),
false,
translate("info.moretext")
)
);
public static final ConfigStorage.SaveableConfig<ConfigBoolean> SEND_TO_CURRENT_TAB = ConfigStorage.SaveableConfig.fromConfig(
"sendToCurrentTab",
new ConfigBoolean(
translate("sendtocurrenttab"),
false,
translate("info.sendtocurrenttab")
)
);
public static final ImmutableList<ConfigStorage.SaveableConfig<? extends IConfigBase>> OPTIONS = ImmutableList.of(
CHAT_HEADS,
WIDTH,
HEIGHT,
X,
Y,
MESSAGE_SPACE,
LINE_SPACE,
LEFT_PAD,
RIGHT_PAD,
BOTTOM_PAD,
TOP_PAD,
SHOW_TABS,
VISIBILITY,
CHAT_SCALE,
FADE_TIME,
FADE_START,
FADE_TYPE,
EMPTY_TEXT_COLOR,
TAB_SIDE_CHARS,
HUD_LINE_TYPE,
ALTERNATE_LINES,
SHOW_TIME,
STORED_LINES,
PERSISTENT_TEXT,
MORE_TEXT,
SEND_TO_CURRENT_TAB
);
}
public static void loadFromFile() {
File configFile = FileUtils
.getConfigDirectory()
.toPath()
.resolve("advancedchat")
.resolve(CONFIG_FILE_NAME)
.toFile();
File configFile = FileUtils.getConfigDirectory().toPath().resolve("advancedchat").resolve(CONFIG_FILE_NAME).toFile();
if (configFile.exists() && configFile.isFile() && configFile.canRead()) {
if (
configFile.exists() && configFile.isFile() && configFile.canRead()
) {
JsonElement element = ConfigStorage.parseJsonFile(configFile);
if (element != null && element.isJsonObject()) {
ChatTab.ChatTabJsonSave tabJson = new ChatTab.ChatTabJsonSave();
JsonObject root = element.getAsJsonObject();
JsonElement tab = root.get("maintab");
if (tab.isJsonObject()) {
MAIN_TAB = tabJson.load(tab.getAsJsonObject());
}
JsonElement tabs = root.get("tabs");
TABS.clear();
if (tabs.isJsonArray()) {
for (JsonElement t : tabs.getAsJsonArray()) {
if (t.isJsonObject()) {
TABS.add(tabJson.load(t.getAsJsonObject()));
}
}
}
ConfigStorage.readOptions(
root,
General.NAME,
(List<ConfigStorage.SaveableConfig<?>>) General.OPTIONS
);
ConfigStorage.readOptions(root, General.NAME, (List<ConfigStorage.SaveableConfig<?>>) General.OPTIONS);
int version = JsonUtils.getIntegerOrDefault(root, "configVersion", 0);
int version = JsonUtils.getIntegerOrDefault(
root,
"configVersion",
0
);
}
}
}
public static void saveFromFile() {
File dir = FileUtils.getConfigDirectory().toPath().resolve("advancedchat").toFile();
File dir = FileUtils
.getConfigDirectory()
.toPath()
.resolve("advancedchat")
.toFile();
if ((dir.exists() && dir.isDirectory()) || dir.mkdirs()) {
ChatTab.ChatTabJsonSave tabJson = new ChatTab.ChatTabJsonSave();
JsonObject root = new JsonObject();
ConfigStorage.writeOptions(root, General.NAME, (List<ConfigStorage.SaveableConfig<?>>) General.OPTIONS);
ConfigStorage.writeOptions(
root,
General.NAME,
(List<ConfigStorage.SaveableConfig<?>>) General.OPTIONS
);
root.add("maintab", tabJson.save(MAIN_TAB));
JsonArray tabs = new JsonArray();
for (ChatTab tab : TABS) {
tabs.add(tabJson.save(tab));
}
root.add("tabs", tabs);
root.add("config_version", new JsonPrimitive(CONFIG_VERSION));
ConfigStorage.writeJsonToFile(root, new File(dir, CONFIG_FILE_NAME));
ConfigStorage.writeJsonToFile(
root,
new File(dir, CONFIG_FILE_NAME)
);
}
}
@@ -89,4 +416,126 @@ public class HudConfigStorage implements IConfigHandler {
saveFromFile();
}
public enum HudLineType implements IConfigOptionListEntry {
FULL("full"),
COMPACT("compact");
public final String configString;
private static String translate(String key) {
return StringUtils.translate(
"advancedchat.config.hudlinetype." + key
);
}
HudLineType(String configString) {
this.configString = configString;
}
@Override
public String getStringValue() {
return configString;
}
@Override
public String getDisplayName() {
return translate(configString);
}
@Override
public IConfigOptionListEntry cycle(boolean forward) {
int id = this.ordinal();
if (forward) {
id++;
} else {
id--;
}
if (id >= values().length) {
id = 0;
} else if (id < 0) {
id = values().length - 1;
}
return values()[id % values().length];
}
@Override
public IConfigOptionListEntry fromString(String value) {
return fromHudLineTypeString(value);
}
public static HudLineType fromHudLineTypeString(String hudlinetype) {
for (HudLineType h : HudLineType.values()) {
if (h.configString.equals(hudlinetype)) {
return h;
}
}
return HudLineType.FULL;
}
}
public enum Visibility implements IConfigOptionListEntry {
VANILLA("vanilla"),
ALWAYS("always"),
FOCUSONLY("focus_only");
private final String configString;
@Getter
private final Identifier texture;
private static String translate(String key) {
return StringUtils.translate(
"advancedchathud.config.visibility." + key
);
}
Visibility(String configString) {
this.texture =
new Identifier(
AdvancedChatHud.MOD_ID,
"textures/gui/chatwindow/" + configString + ".png"
);
this.configString = configString;
}
@Override
public String getStringValue() {
return configString;
}
@Override
public String getDisplayName() {
return translate(configString);
}
@Override
public Visibility cycle(boolean forward) {
int id = this.ordinal();
if (forward) {
id++;
} else {
id--;
}
if (id >= values().length) {
id = 0;
} else if (id < 0) {
id = values().length - 1;
}
return values()[id % values().length];
}
@Override
public Visibility fromString(String value) {
return fromVisibilityString(value);
}
public static Visibility fromVisibilityString(String visibility) {
for (Visibility v : Visibility.values()) {
if (v.configString.equals(visibility)) {
return v;
}
}
return Visibility.VANILLA;
}
}
}
@@ -0,0 +1,131 @@
package io.github.darkkronicle.advancedchathud.config;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;
import fi.dy.masa.malilib.gui.GuiBase;
import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
import fi.dy.masa.malilib.gui.Message;
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.advancedchathud.AdvancedChatHud;
import net.minecraft.client.gui.screen.Screen;
/**
* Screen for importing and exporting {@link ChatTab}.
*/
public class SharingScreen extends GuiBase {
private final String starting;
private static final Gson GSON = new GsonBuilder().create();
private GuiTextFieldGeneric text;
public SharingScreen(String starting, Screen parent) {
this.setParent(parent);
this.setTitle(StringUtils.translate("advancedchat.gui.menu.import"));
this.starting = starting;
}
/**
* Creates a SharingScreen from a tab
*/
public static SharingScreen fromTab(ChatTab tab, Screen parent) {
ChatTab.ChatTabJsonSave tabJsonSave = new ChatTab.ChatTabJsonSave();
return new SharingScreen(GSON.toJson(tabJsonSave.save(tab)), parent);
}
@Override
public void init() {
int x = this.width / 2 - 150;
int y = 50;
text = new GuiTextFieldGeneric(x, y, 300, 20, client.textRenderer);
y -= 24;
text.setMaxLength(12800);
if (starting != null) {
text.setText(starting);
text.setTextFieldFocused(true);
}
text.changeFocus(true);
text.setDrawsBackground(true);
text.setEditable(true);
text.changeFocus(true);
this.addTextField(text, null);
String tabName = ButtonListener.Type.IMPORT_TAB.getDisplayName();
int tabWidth = StringUtils.getStringWidth(tabName) + 10;
this.addButton(
new ButtonGeneric(x, y, tabWidth, 20, tabName),
new ButtonListener(ButtonListener.Type.IMPORT_TAB, this)
);
}
private static class ButtonListener implements IButtonActionListener {
public enum Type {
IMPORT_TAB("importtab");
public final String translationString;
private static String translate(String key) {
return "advancedchat.gui.button." + key;
}
Type(String key) {
this.translationString = translate(key);
}
public String getDisplayName() {
return StringUtils.translate(translationString);
}
}
private final Type type;
private final SharingScreen parent;
public ButtonListener(Type type, SharingScreen parent) {
this.type = type;
this.parent = parent;
}
@Override
public void actionPerformedWithButton(
ButtonBase button,
int mouseButton
) {
try {
if (parent.text.getText().equals("")) {
throw new NullPointerException("Message can't be blank!");
}
if (type == Type.IMPORT_TAB) {
ChatTab.ChatTabJsonSave tabSave = new ChatTab.ChatTabJsonSave();
ChatTab tab = tabSave.load(
new JsonParser()
.parse(parent.text.getText())
.getAsJsonObject()
);
if (tab == null) {
throw new NullPointerException("Filter is null!");
}
HudConfigStorage.TABS.add(tab);
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
parent.addGuiMessage(
Message.MessageType.SUCCESS,
5000,
StringUtils.translate(
"advancedchat.gui.message.successful"
)
);
}
} catch (Exception e) {
parent.addGuiMessage(
Message.MessageType.ERROR,
10000,
StringUtils.translate("advancedchat.gui.message.error") +
": " +
e.getMessage()
);
}
}
}
}
@@ -0,0 +1,48 @@
package io.github.darkkronicle.advancedchathud.config;
import fi.dy.masa.malilib.gui.interfaces.ISelectionListener;
import fi.dy.masa.malilib.gui.widgets.WidgetListBase;
import java.util.Collection;
import javax.annotation.Nullable;
import net.minecraft.client.gui.screen.Screen;
public class WidgetListTabs extends WidgetListBase<ChatTab, WidgetTabEntry> {
public WidgetListTabs(
int x,
int y,
int width,
int height,
@Nullable ISelectionListener<ChatTab> selectionListener,
Screen parent
) {
super(x, y, width, height, selectionListener);
this.browserEntryHeight = 22;
this.setParent(parent);
}
@Override
protected WidgetTabEntry createListEntryWidget(
int x,
int y,
int listIndex,
boolean isOdd,
ChatTab entry
) {
return new WidgetTabEntry(
x,
y,
this.browserEntryWidth,
this.getBrowserEntryHeightFor(entry),
isOdd,
entry,
listIndex,
this
);
}
@Override
protected Collection<ChatTab> getAllEntries() {
return HudConfigStorage.TABS;
}
}
@@ -0,0 +1,190 @@
package io.github.darkkronicle.advancedchathud.config;
import com.mojang.blaze3d.systems.RenderSystem;
import fi.dy.masa.malilib.gui.GuiBase;
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.gui.widgets.WidgetListEntryBase;
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.advancedchathud.AdvancedChatHud;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.util.math.MatrixStack;
/*
This class is based heavily off of https://github.com/maruohon/minihud/blob/d565d39c68bdcd3ed1e1cf2007491e03d9659f34/src/main/java/fi/dy/masa/minihud/gui/widgets/WidgetShapeEntry.java#L19 which is off the GNU LGPL
*/
@Environment(EnvType.CLIENT)
public class WidgetTabEntry extends WidgetListEntryBase<ChatTab> {
private final WidgetListTabs parent;
private final boolean isOdd;
private final List<String> hoverLines;
private final int buttonStartX;
private final ChatTab tab;
public WidgetTabEntry(
int x,
int y,
int width,
int height,
boolean isOdd,
ChatTab tab,
int listIndex,
WidgetListTabs parent
) {
super(x, y, width, height, tab, listIndex);
this.parent = parent;
this.isOdd = isOdd;
this.hoverLines = tab.getWidgetHoverLines();
this.tab = tab;
y += 1;
int pos = x + width - 2;
pos -= addButton(pos, y, ButtonListener.Type.REMOVE);
pos -= addButton(pos, y, ButtonListener.Type.CONFIGURE);
buttonStartX = pos;
}
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
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()
);
}
String name = this.tab.getName().config.getStringValue();
this.drawString(
this.x + 4,
this.y + 7,
ColorUtil.WHITE.color(),
name,
matrixStack
);
RenderUtils.color(1f, 1f, 1f, 1f);
RenderSystem.disableBlend();
super.render(mouseX, mouseY, selected, matrixStack);
RenderUtils.disableDiffuseLighting();
}
@Override
public void postRenderHovered(
int mouseX,
int mouseY,
boolean selected,
MatrixStack matrixStack
) {
super.postRenderHovered(mouseX, mouseY, selected, matrixStack);
if (
mouseX >= this.x &&
mouseX < this.buttonStartX &&
mouseY >= this.y &&
mouseY <= this.y + this.height
) {
RenderUtils.drawHoverText(
mouseX,
mouseY,
this.hoverLines,
matrixStack
);
}
}
private static class ButtonListener implements IButtonActionListener {
private final Type type;
private final WidgetTabEntry parent;
public ButtonListener(Type type, WidgetTabEntry parent) {
this.parent = parent;
this.type = type;
}
@Override
public void actionPerformedWithButton(
ButtonBase button,
int mouseButton
) {
if (type == Type.REMOVE) {
HudConfigStorage.TABS.remove(parent.tab);
parent.parent.refreshEntries();
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
}
if (type == Type.CONFIGURE) {
GuiBase.openGui(
new GuiTabEditor(parent.parent.getParent(), parent.tab)
);
}
}
public enum Type {
CONFIGURE("configure"),
REMOVE("remove");
private final String translate;
Type(String name) {
this.translate = translate(name);
}
private static String translate(String key) {
return "advancedchat.config.tabmenu." + key;
}
public String getDisplayName() {
return StringUtils.translate(translate);
}
}
}
}
@@ -0,0 +1,741 @@
package io.github.darkkronicle.advancedchathud.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import fi.dy.masa.malilib.render.RenderUtils;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.chat.ChatHistory;
import io.github.darkkronicle.advancedchatcore.chat.ChatMessage;
import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.util.EasingMethod;
import io.github.darkkronicle.advancedchatcore.util.FluidText;
import io.github.darkkronicle.advancedchatcore.util.LimitedInteger;
import io.github.darkkronicle.advancedchatcore.util.RawText;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.HudChatMessage;
import io.github.darkkronicle.advancedchathud.HudChatMessageHolder;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.text.TextColor;
import net.minecraft.util.Identifier;
@Environment(EnvType.CLIENT)
public class ChatWindow {
private int scrolledLines = 0;
@Getter
private int y;
@Getter
private int x;
@Getter
private int width;
@Getter
private int height;
private final MinecraftClient client;
private HudConfigStorage.Visibility visibility = (HudConfigStorage.Visibility) HudConfigStorage.General.VISIBILITY.config.getOptionListValue();
private List<ChatMessage> lines;
@Getter
@Setter
private boolean selected;
@Getter
private AbstractChatTab tab;
private static final Identifier X_ICON = new Identifier(
AdvancedChatHud.MOD_ID,
"textures/gui/chatwindow/x_icon.png"
);
public ChatWindow(AbstractChatTab tab) {
this.client = MinecraftClient.getInstance();
this.y =
client.getWindow().getScaledHeight() -
HudConfigStorage.General.Y.config.getIntegerValue();
this.x = HudConfigStorage.General.X.config.getIntegerValue();
this.width = HudConfigStorage.General.WIDTH.config.getIntegerValue();
this.height = HudConfigStorage.General.HEIGHT.config.getIntegerValue();
this.setTab(tab);
}
public void setPosition(int x, int y) {
this.x = x;
this.y = y;
}
public void setTab(AbstractChatTab tab) {
this.tab = tab;
this.lines = new ArrayList<>();
List<HudChatMessage> messages = HudChatMessageHolder
.getInstance()
.getMessages();
for (int i = messages.size() - 1; i >= 0; i--) {
addMessage(messages.get(i));
}
}
public void addMessage(HudChatMessage message) {
this.addMessage(message, false, false);
}
public void addMessage(
HudChatMessage message,
boolean force,
boolean updateCreation
) {
if (force || message.getTabs().contains(tab)) {
ChatMessage newMessage = message
.getMessage()
.shallowClone(getPaddedWidth());
newMessage.setCreationTick(
MinecraftClient.getInstance().inGameHud.getTicks()
);
this.lines.add(0, newMessage);
if (scrolledLines > 0) {
scrolledLines++;
}
int visibleMessagesMaxSize = HudConfigStorage.General.STORED_LINES.config.getIntegerValue();
while (this.lines.size() > visibleMessagesMaxSize) {
this.lines.remove(this.lines.size() - 1);
}
}
}
public void scroll(double amount) {
this.scrolledLines = (int) ((double) this.scrolledLines + amount);
if (this.scrolledLines > lines.size()) {
this.scrolledLines = lines.size();
}
if (this.scrolledLines <= 0) {
this.scrolledLines = 0;
}
}
public void resetScroll() {
this.scrolledLines = 0;
}
public int getPaddedWidth() {
return (
getScaledWidth() -
HudConfigStorage.General.LEFT_PAD.config.getIntegerValue() -
HudConfigStorage.General.RIGHT_PAD.config.getIntegerValue() -
headOffset()
);
}
private int headOffset() {
return HudConfigStorage.General.CHAT_HEADS.config.getBooleanValue()
? 10
: 0;
}
private int getActualY(int y) {
return (int) Math.ceil(this.y / getScale()) - y;
}
private int getLeftX() {
return (int) Math.ceil(x / getScale());
}
private int getPaddedLeftX() {
return (
getLeftX() +
(int) Math.ceil(
HudConfigStorage.General.LEFT_PAD.config.getIntegerValue() +
headOffset() /
getScale()
)
);
}
private double getScale() {
return HudConfigStorage.General.CHAT_SCALE.config.getDoubleValue();
}
private int getRightX() {
return getLeftX() + getScaledWidth();
}
private int getPaddedRightX() {
return (
getRightX() -
HudConfigStorage.General.RIGHT_PAD.config.getIntegerValue()
);
}
public int getActualHeight() {
return height + getBarHeight();
}
private int getScaledHeight() {
return (int) Math.ceil(height / getScale());
}
private int getScaledWidth() {
return (int) Math.ceil(width / getScale());
}
private int getBarHeight() {
return 14;
}
private int getScaledBarHeight() {
return (int) Math.ceil(14 * getScale());
}
public boolean isMouseOver(double mouseX, double mouseY) {
return (
x <= mouseX &&
x + width >= mouseX &&
y >= mouseY &&
y - getActualHeight() <= mouseY
);
}
public void render(MatrixStack matrixStack, int ticks, boolean focused) {
if (visibility == HudConfigStorage.Visibility.FOCUSONLY && !focused) {
return;
}
int lineCount = lines.size();
boolean chatFocused =
visibility == HudConfigStorage.Visibility.ALWAYS || focused;
if (scrolledLines > lineCount) {
scrolledLines = lineCount;
}
matrixStack.push();
matrixStack.scale((float) getScale(), (float) getScale(), 1);
int lines = 0;
int renderedLines = 0;
int scaledWidth = getScaledWidth();
int scaledHeight = getScaledHeight();
int leftX = getLeftX();
int padLX = getPaddedLeftX();
int rightX = getRightX();
int padRX = getPaddedRightX();
LimitedInteger y = new LimitedInteger(
getScaledHeight() -
HudConfigStorage.General.TOP_PAD.config.getIntegerValue(),
HudConfigStorage.General.BOTTOM_PAD.config.getIntegerValue()
);
for (int j = 0; j < this.lines.size(); j++) {
ChatMessage message = this.lines.get(j);
// To get the proper index of reversed
for (int i = message.getLineCount() - 1; i >= 0; i--) {
int lineIndex = message.getLineCount() - i - 1;
lines++;
if (lines < scrolledLines) {
continue;
}
if (
!y.incrementIfPossible(
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue()
)
) {
break;
}
ChatMessage.AdvancedChatLine line = message.getLines().get(i);
drawLine(
matrixStack,
line,
leftX,
y.getValue(),
padLX,
padRX,
lineIndex,
j,
renderedLines,
chatFocused,
ticks
);
renderedLines++;
}
if (lines >= scrolledLines) {
if (lines == lineCount) {
break;
}
if (
!y.isPossible(
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue() +
HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue()
) ||
!y.incrementIfPossible(
HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue()
)
) {
break;
}
}
}
if (renderedLines == 0) {
y.setValue(0);
}
if (focused) {
if (isSelected()) {
tab.resetUnread();
}
RenderUtils.drawOutline(
leftX,
getActualY(0) - scaledHeight - 1,
scaledWidth,
scaledHeight + 1,
tab.getBorderColor().color()
);
int scaledBar = getBarHeight();
int newY = getScaledHeight() + scaledBar;
String label = tab.getAbreviation();
int labelWidth = StringUtils.getStringWidth(label) + 8;
RenderUtils.drawRect(
leftX,
getActualY(newY),
labelWidth,
scaledBar,
tab.getMainColor().color()
);
RenderUtils.drawOutline(
leftX,
getActualY(newY),
labelWidth,
scaledBar,
tab.getBorderColor().withAlpha(180).color()
);
DrawableHelper.drawCenteredText(
matrixStack,
MinecraftClient.getInstance().textRenderer,
tab.getAbreviation(),
leftX + (labelWidth) / 2,
getActualY(newY - 3),
ColorUtil.WHITE.color()
);
RenderUtils.drawRect(
leftX + labelWidth,
getActualY(newY),
getScaledWidth() - labelWidth,
scaledBar,
selected
? tab.getMainColor().color()
: tab.getInnerColor().color()
);
RenderUtils.drawOutline(
leftX + labelWidth,
getActualY(newY),
getScaledWidth() - labelWidth,
scaledBar,
tab.getBorderColor().color()
);
RenderUtils.drawOutline(
rightX - scaledBar,
getActualY(newY),
scaledBar,
scaledBar,
tab.getBorderColor().color()
);
RenderUtils.drawOutline(
rightX - scaledBar * 2 + 1,
getActualY(newY),
scaledBar,
scaledBar,
tab.getBorderColor().color()
);
RenderUtils.drawOutline(
rightX - scaledBar * 3 + 2,
getActualY(newY),
scaledBar,
scaledBar,
tab.getBorderColor().color()
);
RenderUtils.color(1, 1, 1, 1);
RenderUtils.bindTexture(X_ICON);
DrawableHelper.drawTexture(
matrixStack,
rightX - scaledBar * 2 + 2,
getActualY(newY - 1),
scaledBar - 2,
scaledBar - 2,
0,
0,
32,
32,
32,
32
);
RenderUtils.bindTexture(visibility.getTexture());
DrawableHelper.drawTexture(
matrixStack,
rightX - scaledBar * 3 + 3,
getActualY(newY - 1),
scaledBar - 2,
scaledBar - 2,
0,
0,
32,
32,
32,
32
);
}
if (chatFocused) {
drawRect(
leftX,
getActualY(y.getValue()),
rightX,
getActualY(getScaledHeight()),
tab.getInnerColor().color()
);
// Scroll bar
float add = (float) (scrolledLines) / (lineCount + 1);
int scrollHeight = (int) (add * getScaledHeight());
RenderUtils.drawRect(
getScaledWidth() + leftX - 1,
getActualY(scrollHeight + 10),
1,
10,
ColorUtil.WHITE.color()
);
}
matrixStack.pop();
}
private void drawLine(
MatrixStack matrixStack,
ChatMessage.AdvancedChatLine line,
int x,
int y,
int pLX,
int pRX,
int lineIndex,
int messageIndex,
int renderedLines,
boolean focused,
int ticks
) {
int height = HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
if (renderedLines == 0) {
if (focused) {
height +=
HudConfigStorage.General.BOTTOM_PAD.config.getIntegerValue();
}
} else if (lineIndex == 0) {
height +=
HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue();
// Start of a line
}
ColorUtil.SimpleColor background = line.getParent().getBackground();
ColorUtil.SimpleColor text = HudConfigStorage.General.EMPTY_TEXT_COLOR.config.getSimpleColor();
if (background == null) {
background = tab.getInnerColor();
}
if (
messageIndex % 2 == 0 &&
HudConfigStorage.General.ALTERNATE_LINES.config.getBooleanValue()
) {
if (background.alpha() <= 215) {
background = background.withAlpha(background.alpha() + 40);
} else {
background = background.withAlpha(background.alpha() - 40);
}
}
float applied = 1;
if (!focused) {
// Find fade percentage
int fadeStart = HudConfigStorage.General.FADE_START.config.getIntegerValue();
int fadeStop =
fadeStart +
HudConfigStorage.General.FADE_TIME.config.getIntegerValue();
int timeAlive = ticks - line.getParent().getCreationTick();
float percent = (float) Math.min(
1,
(double) (timeAlive - fadeStart) /
(double) (fadeStop - fadeStart)
);
applied =
1 -
(float) (
(EasingMethod) HudConfigStorage.General.FADE_TYPE.config.getOptionListValue()
).apply(percent);
applied = Math.max(0, applied);
if (applied <= 0) {
return;
}
if (applied < 1) {
// Adjust color for background and text due to fade
background = ColorUtil.fade(background, applied);
text = ColorUtil.fade(text, applied);
}
}
// Get line
Text render = line.getText();
if (line.getParent().getStacks() > 0 && lineIndex == 0) {
FluidText toPrint = new FluidText(render);
Style style = Style.EMPTY;
TextColor color = TextColor.fromRgb(ColorUtil.GRAY.color());
style = style.withColor(color);
toPrint
.getRawTexts()
.add(
new RawText(
" (" + (line.getParent().getStacks() + 1) + ")",
style
)
);
render = toPrint;
}
int backgroundWidth;
if (
!focused &&
HudConfigStorage.General.HUD_LINE_TYPE.config.getOptionListValue() ==
HudConfigStorage.HudLineType.COMPACT
) {
backgroundWidth =
client.textRenderer.getWidth(render) + 4 + headOffset();
} else {
backgroundWidth = getScaledWidth();
}
// Draw background
RenderUtils.drawRect(
x,
getActualY(y),
backgroundWidth,
height,
background.color()
);
if (
lineIndex == line.getParent().getLineCount() - 1 &&
line.getParent().getOwner() != null &&
HudConfigStorage.General.CHAT_HEADS.config.getBooleanValue()
) {
RenderSystem.setShaderColor(1, 1, 1, applied);
RenderSystem.setShaderTexture(
0,
line.getParent().getOwner().getTexture()
);
DrawableHelper.drawTexture(
matrixStack,
pLX - 10,
getActualY(y),
8,
8,
8,
8,
8,
8,
64,
64
);
DrawableHelper.drawTexture(
matrixStack,
pLX - 10,
getActualY(y),
8,
8,
40,
8,
8,
8,
64,
64
);
RenderSystem.setShaderColor(1, 1, 1, 1);
}
client.textRenderer.drawWithShadow(
matrixStack,
render.asOrderedText(),
pLX,
getActualY(y) + 1,
text.color()
);
}
public Style getText(double mouseX, double mouseY) {
if (!WindowManager.getInstance().isChatFocused()) {
return null;
}
double relX = mouseX;
double relY = y - mouseY;
double trueX = relX / getScale() - getPaddedLeftX();
double trueY = relY / getScale();
// Divide it by chat scale to get where it actually is
if (trueX < 0.0D || trueY < 0.0D) {
return null;
}
if (trueY > getScaledHeight() || trueX > getScaledWidth()) {
return null;
}
int lines = 0;
int lineCount = this.lines.size();
LimitedInteger y = new LimitedInteger(
getScaledHeight(),
HudConfigStorage.General.BOTTOM_PAD.config.getIntegerValue()
);
for (ChatMessage message : this.lines) {
// To get the proper index of reversed
for (int i = message.getLineCount() - 1; i >= 0; i--) {
lines++;
if (lines < scrolledLines) {
continue;
}
if (
!y.incrementIfPossible(
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue()
)
) {
break;
}
if (
trueY <= y.getValue() &&
trueY >=
y.getValue() -
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue()
) {
ChatMessage.AdvancedChatLine line = message
.getLines()
.get(i);
return this.client.textRenderer.getTextHandler()
.getStyleAt(line.getText(), (int) trueX);
}
}
if (lines >= scrolledLines) {
if (lines == lineCount) {
break;
}
if (
!y.isPossible(
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue() +
HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue()
) ||
!y.incrementIfPossible(
HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue()
)
) {
break;
}
}
}
return null;
}
private static void drawRect(int x1, int y1, int x2, int y2, int color) {
if (y1 > y2) {
int med = y2;
y2 = y1;
y1 = med;
}
if (x1 > x2) {
int med = x2;
x2 = x1;
x1 = med;
}
RenderUtils.drawRect(x1, y1, x2 - x1, y2 - y1, color);
}
public boolean isMouseOverDragBar(double mouseX, double mouseY) {
return (
isMouseOver(mouseX, mouseY) &&
mouseX <= x + width - (getScaledBarHeight() * 3) &&
mouseY <= y - height
);
}
public boolean onMouseClicked(double mouseX, double mouseY, int button) {
boolean onButtons =
isMouseOverDragBar(mouseX - (getScaledBarHeight() * 2), mouseY) &&
mouseX >= x + width - getScaledBarHeight() * 3;
if (!onButtons) {
return false;
}
int x = width - (int) (mouseX - this.x);
if (x >= 13 && x <= 26) {
WindowManager.getInstance().deleteWindow(this);
} else if (x >= 26) {
visibility = visibility.cycle(true);
}
this.client.getSoundManager()
.play(
PositionedSoundInstance.master(
SoundEvents.UI_BUTTON_CLICK,
1.0F
)
);
return true;
}
public boolean isMouseOverResize(double mouseX, double mouseY) {
return (
isMouseOver(mouseX, mouseY) &&
mouseX >= x + width - (getScaledBarHeight()) &&
mouseY <= y - height
);
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
for (ChatMessage m : lines) {
m.formatChildren(this.width);
}
}
public void stackMessage(HudChatMessage message) {
ChatMessage toRemove = null;
for (ChatMessage line : lines) {
if (message.getMessage().isSimilar(line)) {
if (
!ConfigStorage.General.CHAT_STACK_UPDATE.config.getBooleanValue()
) {
// Just update the message and don't resend it
line.setStacks(message.getMessage().getStacks());
return;
}
toRemove = line;
break;
}
}
if (toRemove != null) {
// Remove and then readd it with the updated stack information
lines.remove(toRemove);
addMessage(message, true, true);
}
}
public void clearLines() {
this.lines.clear();
}
}
@@ -0,0 +1,101 @@
package io.github.darkkronicle.advancedchathud.gui;
import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
import io.github.darkkronicle.advancedchatcore.interfaces.AdvancedChatScreenSection;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.HoverEvent;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class HudSection extends AdvancedChatScreenSection {
public HudSection(AdvancedChatScreen screen) {
super(screen);
}
private ColorUtil.SimpleColor getColor() {
ColorUtil.SimpleColor baseColor;
ChatWindow sel = WindowManager.getInstance().getSelected();
if (sel == null) {
baseColor =
HudConfigStorage.MAIN_TAB
.getInnerColor()
.config.getSimpleColor();
} else {
baseColor = sel.getTab().getInnerColor();
}
return baseColor;
}
@Override
public void initGui() {
int x = 2;
int space = 2;
int y =
MinecraftClient.getInstance().getWindow().getScaledHeight() -
15 -
11;
for (AbstractChatTab tab : AdvancedChatHud.MAIN_CHAT_TAB.getAllChatTabs()) {
TabButton button = TabButton.fromTab(tab, x, y);
getScreen().addButton(button, null);
x += button.getWidth() + space;
}
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
return WindowManager
.getInstance()
.mouseClicked(getScreen(), mouseX, mouseY, button);
}
@Override
public boolean mouseReleased(
double mouseX,
double mouseY,
int mouseButton
) {
return WindowManager
.getInstance()
.mouseReleased(mouseX, mouseY, mouseButton);
}
@Override
public boolean mouseDragged(
double mouseX,
double mouseY,
int button,
double deltaX,
double deltaY
) {
return WindowManager
.getInstance()
.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
if (amount > 1.0D) {
amount = 1.0D;
}
if (amount < -1.0D) {
amount = -1.0D;
}
if (!Screen.hasShiftDown()) {
amount *= 7.0D;
}
WindowManager.getInstance().scroll(amount, mouseX, mouseY);
return true;
}
}
@@ -0,0 +1,141 @@
package io.github.darkkronicle.advancedchathud.gui;
import fi.dy.masa.malilib.render.RenderUtils;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.gui.CleanButton;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
public class TabButton extends CleanButton {
private final AbstractChatTab tab;
private TabButton(
AbstractChatTab tab,
int x,
int y,
int width,
int height
) {
super(x, y, width, height, tab.getMainColor(), tab.getAbreviation());
this.tab = tab;
}
@Override
public void render(
int mouseX,
int mouseY,
boolean selected,
MatrixStack matrixStack
) {
int relMX = mouseX - x;
int relMY = mouseY - y;
hovered = relMX >= 0 && relMX <= width && relMY >= 0 && relMY <= height;
ColorUtil.SimpleColor color = baseColor;
if (hovered) {
color = ColorUtil.WHITE.withAlpha(color.alpha());
}
ColorUtil.SimpleColor plusBack = ColorUtil.BLACK.withAlpha(100);
boolean plusHovered = hovered && relMX >= width - height;
if (plusHovered) {
plusBack = ColorUtil.WHITE.withAlpha(plusBack.alpha());
}
RenderUtils.drawRect(x, y, width - height, height, color.color());
RenderUtils.drawOutline(
x,
y,
width - height + 1,
height,
ColorUtil.BLACK.withAlpha(180).color()
);
RenderUtils.drawRect(
x + width - height,
y,
height,
height,
plusBack.color()
);
ColorUtil.SimpleColor crossColor = ColorUtil.WHITE.withAlpha(
plusBack.alpha()
);
RenderUtils.drawVerticalLine(
x + width - (int) Math.floor((float) height / 2) - 1,
y + 1,
height - 2,
crossColor.color()
);
RenderUtils.drawHorizontalLine(
x + width - height + 1,
y + (int) Math.floor((float) height / 2),
height - 2,
crossColor.color()
);
RenderUtils.drawOutline(
x + width - height,
y,
height,
height,
ColorUtil.BLACK.withAlpha(180).color()
);
int center = tab.isShowUnread()
? ((width - 20 - height) / 2)
: ((width - height) / 2);
drawCenteredString(
x + center,
(y + (height / 2) - 3),
ColorUtil.WHITE.color(),
displayString,
matrixStack
);
if (tab.isShowUnread() && tab.getUnread() > 0) {
String unread;
if (tab.getUnread() <= 99) {
unread = tab.getUnread() + "";
} else {
unread = "99+";
}
drawString(
x + width - height - 16,
(y + (height / 2) - 3),
ColorUtil.WHITE.color(),
unread,
matrixStack
);
}
}
@Override
protected boolean onMouseClickedImpl(
int mouseX,
int mouseY,
int mouseButton
) {
this.mc.getSoundManager()
.play(
PositionedSoundInstance.master(
SoundEvents.UI_BUTTON_CLICK,
1.0F
)
);
if (mouseX - x >= width - height) {
// Plus button
WindowManager.getInstance().onTabAddButton(tab);
} else {
WindowManager.getInstance().onTabButton(tab);
}
return true;
}
public static TabButton fromTab(AbstractChatTab tab, int x, int y) {
int width = StringUtils.getStringWidth(tab.getAbreviation()) + 19;
// TODO here something
if (tab.isShowUnread()) {
width += 16;
}
return new TabButton(tab, x, y, width, 11);
}
}
@@ -0,0 +1,225 @@
package io.github.darkkronicle.advancedchathud.gui;
import fi.dy.masa.malilib.interfaces.IRenderer;
import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
import io.github.darkkronicle.advancedchatcore.chat.ChatMessage;
import io.github.darkkronicle.advancedchathud.HudChatMessage;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import java.util.LinkedList;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Style;
@Environment(EnvType.CLIENT)
public class WindowManager implements IRenderer {
private static final WindowManager INSTANCE = new WindowManager();
private final MinecraftClient client;
private LinkedList<ChatWindow> windows = new LinkedList<>();
private int dragX = 0;
private int dragY = 0;
private ChatWindow drag = null;
private boolean resize = false;
public static WindowManager getInstance() {
return INSTANCE;
}
private WindowManager() {
client = MinecraftClient.getInstance();
}
@Override
public void onRenderGameOverlayPost(MatrixStack matrixStack) {
for (int i = windows.size() - 1; i >= 0; i--) {
windows
.get(i)
.render(
matrixStack,
client.inGameHud.getTicks(),
isChatFocused()
);
}
}
public void resetScroll() {
for (ChatWindow w : windows) {
w.resetScroll();
}
}
public void scroll(double amount) {
for (ChatWindow w : windows) {
if (w.isSelected()) {
w.scroll(amount);
}
}
}
public void scroll(double amount, double mouseX, double mouseY) {
for (ChatWindow w : windows) {
if (w.isSelected() || w.isMouseOver(mouseX, mouseY)) {
w.scroll(amount);
}
}
}
public Style getText(double mouseX, double mouseY) {
for (ChatWindow w : windows) {
if (w.isMouseOver(mouseX, mouseY)) {
return w.getText(mouseX, mouseY);
}
}
return null;
}
public boolean isChatFocused() {
return this.client.currentScreen instanceof AdvancedChatScreen;
}
public ChatWindow getSelected() {
for (ChatWindow w : windows) {
if (w.isSelected()) {
return w;
}
}
return null;
}
public void setSelected(ChatWindow window) {
for (ChatWindow w : windows) {
w.setSelected(window.equals(w));
}
windows.remove(window);
windows.addFirst(window);
}
public boolean mouseClicked(
Screen screen,
double mouseX,
double mouseY,
int button
) {
ChatWindow over = null;
for (ChatWindow w : windows) {
if (w.isMouseOver(mouseX, mouseY)) {
over = w;
break;
}
}
if (over == null) {
return false;
}
if (button == 0) {
setSelected(over);
if (over.isMouseOverDragBar(mouseX, mouseY)) {
drag = over;
dragX = (int) mouseX - over.getX();
dragY = (int) mouseY - over.getY();
resize = false;
} else if (over.isMouseOverResize(mouseX, mouseY)) {
drag = over;
dragX = (int) mouseX - over.getWidth();
dragY = (int) mouseY + over.getHeight();
resize = true;
}
Style style = over.getText(mouseX, mouseY);
if (style != null && screen.handleTextClick(style)) {
return true;
}
if (over.onMouseClicked(mouseX, mouseY, button)) {
return true;
}
}
return true;
}
public boolean mouseDragged(
double mouseX,
double mouseY,
int button,
double deltaX,
double deltaY
) {
if (drag != null && !resize) {
int x = Math.max((int) mouseX - dragX, 0);
int y = Math.max((int) mouseY - dragY, drag.getActualHeight());
x =
Math.min(
x,
client.getWindow().getScaledWidth() - drag.getWidth()
);
y = Math.min(y, client.getWindow().getScaledHeight());
drag.setPosition(x, y);
return true;
} else if (drag != null) {
int width = Math.max((int) mouseX - dragX, 80);
int height = Math.max(dragY - (int) mouseY, 40);
drag.setDimensions(width, height);
return true;
}
return false;
}
public boolean mouseReleased(
double mouseX,
double mouseY,
int mouseButton
) {
if (drag != null) {
drag = null;
return true;
}
return false;
}
public void onTabButton(AbstractChatTab tab) {
for (ChatWindow w : windows) {
if (w.isSelected()) {
w.setTab(tab);
}
}
}
public void onTabAddButton(AbstractChatTab tab) {
ChatWindow window = new ChatWindow(tab);
ChatWindow sel = getSelected();
if (sel == null) {
sel = window;
}
window.setPosition(sel.getX() + 15, sel.getY() + 15);
windows.add(window);
setSelected(window);
}
public void deleteWindow(ChatWindow chatWindow) {
windows.remove(chatWindow);
if (!windows.isEmpty()) {
for (ChatWindow w : windows) {
w.setSelected(false);
}
windows.get(0).setSelected(true);
}
}
public void onStackedMessage(HudChatMessage message) {
for (ChatWindow w : windows) {
w.stackMessage(message);
}
}
public void onNewMessage(HudChatMessage message) {
for (ChatWindow w : windows) {
w.addMessage(message);
}
}
public void clear() {
for (ChatWindow w : windows) {
w.clearLines();
}
}
}
@@ -0,0 +1,42 @@
package io.github.darkkronicle.advancedchathud.mixin;
import io.github.darkkronicle.advancedchathud.gui.WindowManager;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.hud.ChatHud;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(value = ChatHud.class, priority = 1050)
@Environment(EnvType.CLIENT)
public class MixinChatHud {
@Inject(at = @At("HEAD"), method = "getText", cancellable = true)
private void getTextAt(
double X,
double Y,
CallbackInfoReturnable<Style> ci
) {
ci.setReturnValue(WindowManager.getInstance().getText(X, Y));
}
@Inject(at = @At("HEAD"), method = "render", cancellable = true)
private void render(MatrixStack stack, int delta, CallbackInfo ci) {
ci.cancel();
}
@Inject(
at = @At("HEAD"),
method = "addMessage(Lnet/minecraft/text/Text;I)V",
cancellable = true
)
private void add(Text message, int messageId, CallbackInfo ci) {
ci.cancel();
}
}
@@ -0,0 +1,56 @@
package io.github.darkkronicle.advancedchathud.tabs;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import lombok.Data;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.text.Text;
/**
* Base ChatTab that allows for custom chat tabs in AdvancedChatHud.
*/
@Environment(EnvType.CLIENT)
@Data
public abstract class AbstractChatTab {
// Each tab stores their own messages.
protected String name;
protected String abreviation;
protected ColorUtil.SimpleColor mainColor;
protected ColorUtil.SimpleColor borderColor;
protected ColorUtil.SimpleColor innerColor;
private int unread = 0;
protected boolean showUnread;
public AbstractChatTab(
String name,
String abreviation,
ColorUtil.SimpleColor mainColor,
ColorUtil.SimpleColor borderColor,
ColorUtil.SimpleColor innerColor,
boolean showUnread
) {
this.name = name;
this.abreviation = abreviation;
this.mainColor = mainColor;
this.showUnread = showUnread;
this.innerColor = innerColor;
this.borderColor = borderColor;
}
public void addNewUnread() {
this.unread++;
}
public void resetUnread() {
this.unread = 0;
}
/**
* If the inputted message should be put into the chat tab.
*
* @param text Object to search.
* @return True if it should be added.
*/
public abstract boolean shouldAdd(Text text);
}
@@ -0,0 +1,56 @@
package io.github.darkkronicle.advancedchathud.tabs;
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 lombok.Getter;
import net.minecraft.text.Text;
/**
* ChatTab that loads from {@link ChatTab}.
* Easy to customize.
*/
public class CustomChatTab extends AbstractChatTab {
@Getter
private String name;
@Getter
private FindType findType;
@Getter
private String findString;
@Getter
private boolean forward;
@Getter
private String startingMessage;
@Getter
private ChatTab storage;
public CustomChatTab(ChatTab storage) {
super(
storage.getName().config.getStringValue(),
storage.getAbbreviation().config.getStringValue(),
storage.getMainColor().config.getSimpleColor(),
storage.getBorderColor().config.getSimpleColor(),
storage.getInnerColor().config.getSimpleColor(),
storage.getShowUnread().config.getBooleanValue()
);
this.storage = storage;
this.findType = storage.getFind();
this.findString = storage.getFindString().config.getStringValue();
this.forward = storage.getForward().config.getBooleanValue();
this.startingMessage =
storage.getStartingMessage().config.getStringValue();
}
@Override
public boolean shouldAdd(Text text) {
FluidText newText = new FluidText(text);
return SearchUtils.isMatch(newText.getString(), findString, findType);
}
}
@@ -0,0 +1,76 @@
package io.github.darkkronicle.advancedchathud.tabs;
import io.github.darkkronicle.advancedchathud.HudChatMessage;
import io.github.darkkronicle.advancedchathud.HudChatMessageHolder;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import java.util.ArrayList;
import lombok.Getter;
import net.minecraft.text.Text;
/**
* Main chat tab that manages other chat tabs.
*/
public class MainChatTab extends AbstractChatTab {
@Getter
private ArrayList<AbstractChatTab> allChatTabs = new ArrayList<>();
@Getter
private ArrayList<CustomChatTab> customChatTabs = new ArrayList<>();
public MainChatTab() {
super(
"Main",
HudConfigStorage.MAIN_TAB.getAbbreviation().config.getStringValue(),
HudConfigStorage.MAIN_TAB.getMainColor().config.getSimpleColor(),
HudConfigStorage.MAIN_TAB.getBorderColor().config.getSimpleColor(),
HudConfigStorage.MAIN_TAB.getInnerColor().config.getSimpleColor(),
HudConfigStorage.MAIN_TAB.getShowUnread().config.getBooleanValue()
);
setUpTabs();
}
public void refreshOptions() {
this.abreviation =
HudConfigStorage.MAIN_TAB.getAbbreviation().config.getStringValue();
this.mainColor =
HudConfigStorage.MAIN_TAB.getMainColor().config.getSimpleColor();
this.innerColor =
HudConfigStorage.MAIN_TAB.getInnerColor().config.getSimpleColor();
this.borderColor =
HudConfigStorage.MAIN_TAB.getBorderColor().config.getSimpleColor();
this.showUnread =
HudConfigStorage.MAIN_TAB.getShowUnread().config.getBooleanValue();
}
@Override
public boolean shouldAdd(Text text) {
return true;
}
/**
* Method used for loading in tabs from the config.
*/
public void setUpTabs() {
customChatTabs = new ArrayList<>();
allChatTabs = new ArrayList<>();
allChatTabs.add(this);
for (ChatTab tab : HudConfigStorage.TABS) {
CustomChatTab customTab = new CustomChatTab(tab);
customChatTabs.add(customTab);
allChatTabs.add(customTab);
}
for (HudChatMessage message : HudChatMessageHolder
.getInstance()
.getMessages()) {
ArrayList<AbstractChatTab> tabs = new ArrayList<>();
for (AbstractChatTab t : allChatTabs) {
if (t.shouldAdd(message.getMessage().getOriginalText())) {
tabs.add(t);
}
}
message.setTabs(tabs);
}
}
}
@@ -3,6 +3,7 @@
"package": "io.github.darkkronicle.advancedchathud.mixin",
"compatibilityLevel": "JAVA_16",
"mixins": [
"MixinChatHud"
],
"client": [
],
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB