Author SHA1 Message Date
DarkKronicle 68f2b97f97 Merge pull request #29 from Ginsway/zh-cn 2023-04-17 10:24:42 -06:00
DarkKronicle 75584fa3c2 Merge pull request #32 from diademiemi/main 2023-04-17 10:24:12 -06:00
diademiemi 324b01a6dc Run on 1.19.4 2023-03-30 20:59:49 +02:00
DarkKronicle 79e7212336 1.19.3 update 2023-01-23 15:06:20 -07:00
DarkKronicle 9db76f31c9 1.19.3 update (still bugs) 2023-01-23 12:16:58 -07:00
Ginsway 36c07ad2b5 Create zh_cn.json 2023-01-04 22:43:17 +08:00
DarkKronicle 75935c7df0 Fix starting message bug 2022-10-26 20:52:11 -06:00
DarkKronicle bb49775203 Wrong url 2022-09-04 16:36:08 -06:00
DarkKronicle 0d81abefb4 Using new gradle script 2022-09-04 16:33:04 -06:00
DarkKronicle f6a32e1ddd Fix for 1.19.1 2022-08-06 10:21:24 -06:00
DarkKronicle 35e37ce002 1.19 update 2022-07-25 15:41:46 -06:00
DarkKronicle 752c6210ab [skip ci] Fixing smooth scrolling 2022-04-20 11:40:58 -06:00
DarkKronicle 1c59f990db Merge pull request #15 from Kale-Ko/main
Add/change start message on chat window change
2022-04-19 11:04:53 -06:00
Kale-Ko e1cc8fd342 Add config entry 2022-04-19 13:00:02 -04:00
Kale-Ko ea6063c726 Fix the fix 2022-04-19 12:41:09 -04:00
Kale-Ko 6ce1176e85 Fix empty start messages 2022-04-19 12:23:15 -04:00
Kale-Ko 15e3b3b31b Add/change start message on chat window change 2022-04-19 12:21:30 -04:00
DarkKronicle 23f0eaa336 [skip ci] BUMP 2022-04-16 20:42:29 -06:00
DarkKronicle 711d3bc97e [skip ci] Configuration options 2022-04-16 20:41:37 -06:00
DarkKronicle 9e66118e8e Adding smooth scrolling (7 hours) 2022-04-16 19:42:37 -06:00
DarkKronicle c9160224fa [skip ci] Bug fixes and more window configuration 2022-04-10 14:38:57 -06:00
DarkKronicle a67b75ec7a [skip ci] bump version 2022-03-08 11:06:00 -07:00
DarkKronicle ef7349787c 1.18.2 release 2022-03-08 11:02:49 -07:00
DarkKronicle e9fdf5d02e [skip ci] Fixing crash 2022-02-03 14:13:56 -07:00
DarkKronicle 7102d5ed52 [skip ci] 1.2.1 2022-02-02 19:56:19 -07:00
DarkKronicle e7a8dcacd5 RC to copy 2022-02-01 21:23:32 -07:00
DarkKronicle c35c5f97d6 [skip ci] Updating required dependencies 2022-01-31 07:53:25 -07:00
DarkKronicle bcc4460939 Always initializing the processor 2022-01-29 10:07:12 -07:00
DarkKronicle e6d3348fae More KONSTRUCT 2022-01-27 19:23:09 -07:00
DarkKronicle 098471dda6 GUI fixes and adding konstruct tabs 2022-01-26 21:46:41 -07:00
DarkKronicle 68149258df Fixing outline transparency, chat head transparency, and resizing 2022-01-24 21:45:37 -07:00
DarkKronicle 39a421a409 Update to 1.18 2021-12-19 14:53:22 -07:00
DarkKronicle 36eb8b0c71 Bump 2021-11-18 20:31:26 -07:00
DarkKronicle d71f08fca0 Updating to ACC 1.3.0 2021-11-18 16:45:49 -07:00
DarkKronicle b43a42b74f Fixing translations 2021-11-10 14:33:01 -07:00
DarkKronicle 8baa25d9f0 Enforcing up to date acc 2021-11-10 14:29:28 -07:00
DarkKronicle 1a570aa37f Updating configs to ACC 2021-11-10 14:16:34 -07:00
DarkKronicle bf5c4f058f Bumping version 2021-11-08 20:12:44 -07:00
DarkKronicle 85a0132865 Merge branch 'Pablo/PR5' 2021-10-31 21:13:00 -06:00
DarkKronicle 82b28e65df Fixing merge 2021-10-31 21:12:28 -06:00
DarkKronicle 3c24000aa6 Relative width/height for chat windows + reset button 2021-10-31 21:07:24 -06:00
Pablete1234 5eaaa2965e Cleanup & fix remaining bits on vanilla chat integration 2021-11-01 03:52:20 +01:00
DarkKronicle bf1b525861 Merge pull request #3 from DarkKronicle/feature/vanilla_hud_patch
Feature/vanilla hud patch
2021-10-31 15:12:12 -06:00
51 changed files with 2486 additions and 1623 deletions

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Change wrapper permissions
run: chmod +x ./gradlew
- name: Upload to Discord
run: ./gradlew discord --stacktrace
if: |
!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.pull_request.title, '[ci skip]')
env:
discord_webhook: ${{ secrets.DISCORD_WEBHOOK }}
action_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Capture build artifacts
uses: actions/upload-artifact@v2
with:
name: Artifacts
path: build/libs/
+36
View File
@@ -0,0 +1,36 @@
on:
workflow_dispatch:
inputs:
previousVersion:
description: 'Previous Version (Do not include v prefix, must be same as the last version tag! Example: 1.4.1)'
required: true
version:
description: 'Version (Do not include v prefix! Example: 1.4.2)'
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Fetch tags
run: git fetch --tags
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Change wrapper permissions
run: chmod +x ./gradlew
- name: Upload to websites
run: ./gradlew publishThirdParty --stacktrace -PlastTag="v${{ github.event.inputs.previousVersion }}" -PcurrentTag="v${{ github.event.inputs.version }}"
if: |
!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.pull_request.title, '[ci skip]')
env:
modrinth_token: ${{ secrets.MODRINTH_TOKEN }}
curseforge_token: ${{ secrets.CURSEFORGE_TOKEN }}
github_token: ${{ secrets.GH_API_KEY }}
discord_release_webhook: ${{ secrets.DISCORD_RELEASE_WEBHOOK }}
- name: Capture build artifacts
uses: actions/upload-artifact@v2
with:
name: Artifacts
path: build/libs/
+11 -27
View File
@@ -1,18 +1,21 @@
plugins {
id 'fabric-loom' version '0.8-SNAPSHOT'
id 'fabric-loom' version '1.0-SNAPSHOT'
id 'maven-publish'
id "io.freefair.lombok" version "6.0.0-m2"
id "com.diffplug.spotless" version "5.17.1"
}
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
apply from: 'https://raw.githubusercontent.com/DarkKronicle/GradleScripts/main/gradle/publish.gradle'
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
archivesBaseName = project.archives_base_name
version = project.mod_version
version = "${project.minecraft_version}-${project.mod_version}"
group = project.maven_group
minecraft {
Properties additionalProperties = new Properties()
if (file("extra.properties").exists()) {
additionalProperties.load(file("extra.properties").newReader())
}
repositories {
@@ -26,7 +29,7 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
modImplementation "fi.dy.masa.malilib:malilib-fabric-1.17.1:${project.malilib_version}"
modImplementation "fi.dy.masa.malilib:malilib-fabric-1.19.4:${project.malilib_version}"
modImplementation "com.github.DarkKronicle:AdvancedChatCore:${project.advancedchat_version}"
}
@@ -40,7 +43,7 @@ processResources {
tasks.withType(JavaCompile).configureEach {
it.options.encoding = "UTF-8"
it.options.release = 16
it.options.release = 17
}
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
@@ -55,25 +58,6 @@ jar {
from "LICENSE.txt"
}
spotless {
ratchetFrom 'origin/main'
format 'misc', {
// define the files to apply `misc` to
target '*.gradle', '*.md', '.gitignore'
// define the steps to apply to those files
trimTrailingWhitespace()
indentWithTabs() // or spaces. Takes an integer argument if you don't like 4
endWithNewline()
}
java {
target 'src/*/java/**/*.java'
googleJavaFormat('1.12.0').aosp().reflowLongStrings()
removeUnusedImports()
licenseHeaderFile "HEADER.txt"
}
}
// configure the maven publication
publishing {
publications {
+27 -13
View File
@@ -1,15 +1,29 @@
minecraft_version=1.17.1
yarn_mappings=1.17.1+build.40
loader_version=0.12.3
mod_version=1.0.1
minecraft_version=1.19.4
yarn_mappings=1.19.4+build.1
loader_version=0.14.11
fabric_api_version=0.76.0+1.19.4
mod_version=1.3.8
maven_group=io.github.darkkronicle
archives_base_name=AdvancedChatHUD
fabric_api_version=0.41.0+1.17
malilib_version = 0.10.0-dev.26
startParameter.excludedTaskNames=spotlessCheck
org.gradle.jvmargs=-Xmx1G --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
advancedchat_version=1.1.0-beta1
malilib_version = 0.15.2
org.gradle.jvmargs=-Xmx1G
advancedchat_version=v1.5.10
# Uploading data
curseforge_slug=advancedchathud
curseforge_id=541708
modrinth_slug=advancedchathud
modrinth_id=lBFvglCF
# default_release_type can be stable, beta, or alpha
default_release_type=stable
project_name=AdvancedChatHUD
project_url=https://modrinth.com/mod/advancedchathud
project_logo=https://raw.githubusercontent.com/Prospector/images/master/modmenu-logo.png
project_color=0x134bff
changelog_hide_unimportant_commits=true
changelog_max_commit_search=200
discord_webhook_changelog_line_limit=10
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+1 -1
View File
@@ -1,10 +1,10 @@
pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
mavenCentral()
gradlePluginPortal()
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 DarkKronicle
* Copyright (C) 2021-2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -7,7 +7,7 @@
*/
package io.github.darkkronicle.advancedchathud;
import fi.dy.masa.malilib.event.InitializationHandler;
import io.github.darkkronicle.advancedchatcore.ModuleHandler;
import io.github.darkkronicle.advancedchathud.tabs.MainChatTab;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
@@ -25,6 +25,6 @@ public class AdvancedChatHud implements ClientModInitializer {
@Override
public void onInitializeClient() {
// This will run after AdvancedChatCore's because of load order
InitializationHandler.getInstance().registerInitializationHandler(new HudInitHandler());
ModuleHandler.getInstance().registerInitHandler(MOD_ID, 0, new HudInitHandler());
}
}
@@ -43,8 +43,12 @@ public class HudChatMessage {
}
}
}
if (forward) tabs.add(AdvancedChatHud.MAIN_CHAT_TAB);
for (AbstractChatTab tab : tabs) tab.addNewUnread();
if (forward) {
tabs.add(AdvancedChatHud.MAIN_CHAT_TAB);
}
for (AbstractChatTab tab : tabs) {
tab.addNewUnread();
}
}
public HudChatMessage(ChatMessage message, List<AbstractChatTab> tabs) {
@@ -60,6 +60,15 @@ public class HudChatMessageHolder implements IChatMessageProcessor {
HudChatMessage remove = getMessage(message);
if (remove != null) {
messages.remove(remove);
WindowManager.getInstance().onRemoveMessage(remove.getMessage());
}
}
public void removeChatMessage(ChatMessage message) {
HudChatMessage m = getMessageFromContent(message);
if (m != null) {
messages.remove(m);
WindowManager.getInstance().onRemoveMessage(message);
}
}
@@ -71,4 +80,13 @@ public class HudChatMessageHolder implements IChatMessageProcessor {
}
return null;
}
public HudChatMessage getMessageFromContent(ChatMessage message) {
for (HudChatMessage m : messages) {
if (m.getMessage().isSimilar(message) && m.getMessage().getTime().equals(message.getTime())) {
return m;
}
}
return null;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 DarkKronicle
* Copyright (C) 2021-2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -15,8 +15,8 @@ import io.github.darkkronicle.advancedchatcore.AdvancedChatCore;
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.advancedchathud.config.GuiTabManager;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.config.gui.GuiTabManager;
import io.github.darkkronicle.advancedchathud.gui.HudSection;
import io.github.darkkronicle.advancedchathud.gui.WindowManager;
import io.github.darkkronicle.advancedchathud.itf.IChatHud;
@@ -32,26 +32,21 @@ public class HudInitHandler implements IInitializationHandler {
@Override
public void registerModHandlers() {
AdvancedChatCore.FORWARD_TO_HUD = false;
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);
}
});
ConfigManager.getInstance().registerConfigHandler(AdvancedChatHud.MOD_ID, new HudConfigStorage());
GuiConfigHandler.getInstance().addTab(
GuiConfigHandler.children("advancedchathud", "advancedchathud.tab.advancedchathud",
GuiConfigHandler.wrapSaveableOptions(
"hud_general",
"advancedchathud.tab.general",
HudConfigStorage.General.OPTIONS
),
GuiConfigHandler.wrapScreen(
"tabs",
"advancedchathud.tab.tabs",
(parent) -> new GuiTabManager()
)
)
);
IChatHud.getInstance().setTab(AdvancedChatHud.MAIN_CHAT_TAB = new MainChatTab());
// Register on the clear
@@ -60,5 +55,6 @@ public class HudInitHandler implements IInitializationHandler {
ChatHistory.getInstance().addOnClear(() -> HudChatMessageHolder.getInstance().clear());
ChatHistory.getInstance().addOnUpdate(HudChatMessageHolder.getInstance());
RenderEventHandler.getInstance().registerGameOverlayRenderer(WindowManager.getInstance());
ResolutionEventHandler.ON_RESOLUTION_CHANGE.add(WindowManager.getInstance());
}
}
@@ -0,0 +1,19 @@
/*
* Copyright (C) 2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud;
import java.util.ArrayList;
import java.util.List;
public interface ResolutionEventHandler {
List<ResolutionEventHandler> ON_RESOLUTION_CHANGE = new ArrayList<>();
void onResolutionChange();
}
@@ -13,12 +13,13 @@ 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;
import fi.dy.masa.malilib.config.options.ConfigInteger;
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.config.SaveableConfig;
import io.github.darkkronicle.advancedchatcore.config.options.ConfigColor;
import io.github.darkkronicle.advancedchatcore.interfaces.IJsonSave;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.util.Colors;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import java.util.ArrayList;
@@ -41,65 +42,71 @@ public class ChatTab {
private UUID uuid = UUID.randomUUID();
private ConfigStorage.SaveableConfig<ConfigString> name =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigString> name =
SaveableConfig.fromConfig(
"name",
new ConfigString(translate("name"), "Boring Chat Tab", translate("info.name")));
private SaveableConfig<ConfigInteger> order =
SaveableConfig.fromConfig(
"order",
new ConfigInteger(translate("order"), 0, translate("info.order")));
private List<Match> matches =
new ArrayList<>(
Collections.singleton(new Match("I will match to text!", FindType.LITERAL)));
private ConfigStorage.SaveableConfig<ConfigString> startingMessage =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigString> startingMessage =
SaveableConfig.fromConfig(
"startingMessage",
new ConfigString(
translate("startingmessage"), "", translate("info.startingmessage")));
private ConfigStorage.SaveableConfig<ConfigBoolean> forward =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigBoolean> forward =
SaveableConfig.fromConfig(
"forward",
new ConfigBoolean(translate("forward"), true, translate("info.forward")));
private ConfigStorage.SaveableConfig<ConfigString> abbreviation =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigString> abbreviation =
SaveableConfig.fromConfig(
"abbreviation",
new ConfigString(
translate("abbreviation"), "BCT", translate("info.abbreviation")));
private ConfigStorage.SaveableConfig<ConfigSimpleColor> mainColor =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigColor> mainColor =
SaveableConfig.fromConfig(
"mainColor",
new ConfigSimpleColor(
new ConfigColor(
translate("maincolor"),
ColorUtil.GRAY.withAlpha(100),
Colors.getInstance().getColorOrWhite("gray").withAlpha(100),
translate("info.maincolor")));
private ConfigStorage.SaveableConfig<ConfigSimpleColor> borderColor =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigColor> borderColor =
SaveableConfig.fromConfig(
"borderColor",
new ConfigSimpleColor(
new ConfigColor(
translate("bordercolor"),
ColorUtil.BLACK.withAlpha(180),
Colors.getInstance().getColorOrWhite("black").withAlpha(180),
translate("info.bordercolor")));
private ConfigStorage.SaveableConfig<ConfigSimpleColor> innerColor =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigColor> innerColor =
SaveableConfig.fromConfig(
"innerColor",
new ConfigSimpleColor(
new ConfigColor(
translate("innercolor"),
ColorUtil.BLACK.withAlpha(100),
Colors.getInstance().getColorOrWhite("black").withAlpha(100),
translate("info.innercolor")));
private ConfigStorage.SaveableConfig<ConfigBoolean> showUnread =
ConfigStorage.SaveableConfig.fromConfig(
private SaveableConfig<ConfigBoolean> showUnread =
SaveableConfig.fromConfig(
"showUnread",
new ConfigBoolean(
translate("showunread"), false, translate("info.showunread")));
private final ImmutableList<ConfigStorage.SaveableConfig<?>> options =
private final ImmutableList<SaveableConfig<?>> options =
ImmutableList.of(
name,
order,
startingMessage,
forward,
abbreviation,
@@ -109,9 +116,10 @@ public class ChatTab {
showUnread);
/** Options that the main tab can use */
private final ImmutableList<ConfigStorage.SaveableConfig<?>> mainEditableOptions =
private final ImmutableList<SaveableConfig<?>> mainEditableOptions =
ImmutableList.of(
name,
order,
startingMessage,
abbreviation,
mainColor,
@@ -143,7 +151,10 @@ public class ChatTab {
Matcher.quoteReplacement(matches.get(0).getPattern()))
.replaceAll(
Pattern.quote("<findtype>"),
Matcher.quoteReplacement(getFind().getDisplayName())));
Matcher.quoteReplacement(getFind().getDisplayName()))
.replaceAll(
Pattern.quote("<order>"),
Matcher.quoteReplacement(order.config.getStringValue())));
}
return hover;
}
@@ -153,7 +164,7 @@ public class ChatTab {
@Override
public ChatTab load(JsonObject obj) {
ChatTab t = new ChatTab();
for (ConfigStorage.SaveableConfig<?> conf : t.getOptions()) {
for (SaveableConfig<?> conf : t.getOptions()) {
IConfigBase option = conf.config;
if (obj.has(conf.key)) {
option.setValueFromJsonElement(obj.get(conf.key));
@@ -190,7 +201,7 @@ public class ChatTab {
public JsonObject save(ChatTab tab) {
Match.MatchSerializer serializer = new Match.MatchSerializer();
JsonObject obj = new JsonObject();
for (ConfigStorage.SaveableConfig<?> option : tab.getOptions()) {
for (SaveableConfig<?> option : tab.getOptions()) {
obj.add(option.key, option.config.getAsJsonElement());
}
JsonArray find = new JsonArray();
@@ -1,173 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
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.GuiUtils;
import fi.dy.masa.malilib.util.KeyCodes;
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;
private final boolean main;
public GuiTabEditor(Screen parent, ChatTab tab) {
this(parent, tab, false);
}
public GuiTabEditor(Screen parent, ChatTab tab, boolean main) {
super(10, 50, AdvancedChatHud.MOD_ID, parent, tab.getName().config.getStringValue());
this.tab = tab;
this.main = main;
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;
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(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<>();
List<ConfigStorage.SaveableConfig<? extends IConfigBase>> options;
if (main) {
options = tab.getMainEditableOptions();
} else {
options = tab.getOptions();
}
for (ConfigStorage.SaveableConfig<? extends IConfigBase> s : options) {
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);
}
@Override
public boolean onKeyTyped(int keyCode, int scanCode, int modifiers) {
// Override so that on escape stuff still gets saved
if (this.activeKeybindButton != null) {
this.activeKeybindButton.onKeyPressed(keyCode);
return true;
} else {
if (this.getListWidget().onKeyTyped(keyCode, scanCode, modifiers)) {
return true;
}
if (keyCode == KeyCodes.KEY_ESCAPE
&& this.parentScreen != GuiUtils.getCurrentScreen()) {
// Make sure to save
closeGui(true);
return true;
}
return false;
}
}
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));
} else if (this.type == Type.MATCHES) {
parent.save();
GuiBase.openGui(new MatchesEditor(parent, parent.tab));
}
}
public enum Type {
BACK("back"),
EXPORT("export"),
MATCHES("matches");
private final String translation;
private static String translate(String key) {
return "advancedchathud.gui.button." + key;
}
Type(String key) {
this.translation = translate(key);
}
public String getDisplayName() {
return StringUtils.translate(translation);
}
}
}
}
@@ -1,145 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
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,5 +1,5 @@
/*
* Copyright (C) 2021 DarkKronicle
* Copyright (C) 2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -23,13 +23,17 @@ 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.advancedchatcore.config.ConfigStorage;
import io.github.darkkronicle.advancedchatcore.config.options.ConfigSimpleColor;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.config.SaveableConfig;
import io.github.darkkronicle.advancedchatcore.config.options.ConfigColor;
import io.github.darkkronicle.advancedchatcore.util.Colors;
import io.github.darkkronicle.advancedchatcore.util.EasingMethod;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.gui.WindowManager;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import io.github.darkkronicle.advancedchathud.tabs.MainChatTab;
import lombok.Getter;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -51,40 +55,46 @@ public class HudConfigStorage implements IConfigHandler {
return StringUtils.translate("advancedchathud.config.general." + key);
}
public static final ConfigStorage.SaveableConfig<ConfigBoolean> VANILLA_HUD =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigBoolean> VANILLA_HUD =
SaveableConfig.fromConfig(
"vanillHud",
new ConfigBoolean(
translate("vanillahud"), false, translate("info.vanillahud")));
public static final ConfigStorage.SaveableConfig<ConfigBoolean> CHAT_HEADS =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigBoolean> CHAT_HEADS =
SaveableConfig.fromConfig(
"chatHeads",
new ConfigBoolean(
translate("chatheads"), false, translate("info.chatheads")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> WIDTH =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigBoolean> TAB_BUTTONS_ON_RIGHT =
SaveableConfig.fromConfig(
"tabButtonsOnRight",
new ConfigBoolean(
translate("righttabbuttons"), false, translate("info.righttabbuttons")));
public static final SaveableConfig<ConfigInteger> WIDTH =
SaveableConfig.fromConfig(
"width",
new ConfigInteger(
translate("width"), 280, 100, 600, translate("info.width")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> HEIGHT =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> HEIGHT =
SaveableConfig.fromConfig(
"height",
new ConfigInteger(
translate("height"), 117, 20, 400, translate("info.height")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> X =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> X =
SaveableConfig.fromConfig(
"x", new ConfigInteger(translate("x"), 0, 0, 4000, translate("info.x")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> Y =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> Y =
SaveableConfig.fromConfig(
"y", new ConfigInteger(translate("y"), 30, 0, 4000, translate("info.y")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> MESSAGE_SPACE =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> MESSAGE_SPACE =
SaveableConfig.fromConfig(
"messageSpace",
new ConfigInteger(
translate("messagespace"),
@@ -93,62 +103,57 @@ public class HudConfigStorage implements IConfigHandler {
10,
translate("info.messagespace")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> LINE_SPACE =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> LINE_SPACE =
SaveableConfig.fromConfig(
"lineSpace",
new ConfigInteger(
translate("linespace"), 9, 8, 20, translate("info.linespace")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> LEFT_PAD =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> LEFT_PAD =
SaveableConfig.fromConfig(
"leftPad",
new ConfigInteger(
translate("leftpad"), 2, 0, 20, translate("info.leftpad")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> RIGHT_PAD =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> RIGHT_PAD =
SaveableConfig.fromConfig(
"rightPad",
new ConfigInteger(
translate("rightpad"), 2, 0, 20, translate("info.rightpad")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> BOTTOM_PAD =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> BOTTOM_PAD =
SaveableConfig.fromConfig(
"bottomPad",
new ConfigInteger(
translate("bottompad"), 1, 0, 20, translate("info.bottompad")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> TOP_PAD =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> TOP_PAD =
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(
public static final SaveableConfig<ConfigOptionList> VISIBILITY =
SaveableConfig.fromConfig(
"visibility",
new ConfigOptionList(
translate("visibility"),
Visibility.VANILLA,
translate("info.visibility")));
public static final ConfigStorage.SaveableConfig<ConfigDouble> CHAT_SCALE =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigDouble> CHAT_SCALE =
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(
public static final SaveableConfig<ConfigInteger> FADE_TIME =
SaveableConfig.fromConfig(
"fadeTime",
new ConfigInteger(
translate("fadetime"), 40, 0, 200, translate("info.fadetime")));
public static final ConfigStorage.SaveableConfig<ConfigInteger> FADE_START =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigInteger> FADE_START =
SaveableConfig.fromConfig(
"fadeStart",
new ConfigInteger(
translate("fadestart"),
@@ -157,46 +162,40 @@ public class HudConfigStorage implements IConfigHandler {
1000,
translate("info.fadestart")));
public static final ConfigStorage.SaveableConfig<ConfigOptionList> FADE_TYPE =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigOptionList> FADE_TYPE =
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(
public static final SaveableConfig<ConfigColor> EMPTY_TEXT_COLOR =
SaveableConfig.fromConfig(
"emptyTextColor",
new ConfigSimpleColor(
new ConfigColor(
translate("emptytextcolor"),
ColorUtil.WHITE,
Colors.getInstance().getColorOrWhite("white"),
translate("info.emptytextcolor")));
public static final ConfigStorage.SaveableConfig<ConfigOptionList> HUD_LINE_TYPE =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigOptionList> HUD_LINE_TYPE =
SaveableConfig.fromConfig(
"hudLineType",
new ConfigOptionList(
translate("hudlinetype"),
HudLineType.FULL,
translate("info.hudlinetype")));
public static final ConfigStorage.SaveableConfig<ConfigBoolean> ALTERNATE_LINES =
ConfigStorage.SaveableConfig.fromConfig(
public static final SaveableConfig<ConfigBoolean> ALTERNATE_LINES =
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(
public static final SaveableConfig<ConfigInteger> STORED_LINES =
SaveableConfig.fromConfig(
"storedLines",
new ConfigInteger(
translate("storedlines"),
@@ -205,32 +204,68 @@ public class HudConfigStorage implements IConfigHandler {
1000,
translate("info.storedlines")));
public static final ImmutableList<ConfigStorage.SaveableConfig<? extends IConfigBase>>
OPTIONS =
ImmutableList.of(
VANILLA_HUD,
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,
HUD_LINE_TYPE,
ALTERNATE_LINES,
SHOW_TIME,
STORED_LINES);
public static final SaveableConfig<ConfigBoolean> RENDER_IN_OTHER_GUI =
SaveableConfig.fromConfig(
"renderInOther",
new ConfigBoolean(
translate("renderinother"),
true,
translate("info.renderinother")));
public static final SaveableConfig<ConfigInteger> SCROLL_TIME =
SaveableConfig.fromConfig(
"scrollTime",
new ConfigInteger(
translate("scrolltime"),
200,
1,
2000,
translate("info.scrolltime")));
public static final SaveableConfig<ConfigOptionList> SCROLL_TYPE =
SaveableConfig.fromConfig(
"scrollType",
new ConfigOptionList(
translate("scrolltype"),
ConfigStorage.Easing.QUART,
translate("info.scrolltype")));
public static final SaveableConfig<ConfigBoolean> CHANGE_START_MESSAGE =
SaveableConfig.fromConfig(
"changeStartMessage",
new ConfigBoolean(
translate("changeStartMessage"),
true,
translate("info.changeStartMessage")));
public static final ImmutableList<SaveableConfig<? extends IConfigBase>> OPTIONS =
ImmutableList.of(
VANILLA_HUD,
CHAT_HEADS,
TAB_BUTTONS_ON_RIGHT,
WIDTH,
HEIGHT,
X,
Y,
MESSAGE_SPACE,
LINE_SPACE,
LEFT_PAD,
RIGHT_PAD,
BOTTOM_PAD,
TOP_PAD,
VISIBILITY,
CHAT_SCALE,
FADE_TIME,
FADE_START,
FADE_TYPE,
EMPTY_TEXT_COLOR,
HUD_LINE_TYPE,
ALTERNATE_LINES,
STORED_LINES,
RENDER_IN_OTHER_GUI,
SCROLL_TIME,
SCROLL_TYPE,
CHANGE_START_MESSAGE);
}
public static void loadFromFile() {
@@ -271,9 +306,7 @@ public class HudConfigStorage implements IConfigHandler {
}
ConfigStorage.readOptions(
root,
General.NAME,
(List<ConfigStorage.SaveableConfig<?>>) General.OPTIONS);
root, General.NAME, (List<SaveableConfig<?>>) General.OPTIONS);
int version = JsonUtils.getIntegerOrDefault(root, "configVersion", 0);
}
@@ -288,7 +321,7 @@ public class HudConfigStorage implements IConfigHandler {
JsonObject root = new JsonObject();
ConfigStorage.writeOptions(
root, General.NAME, (List<ConfigStorage.SaveableConfig<?>>) General.OPTIONS);
root, General.NAME, (List<SaveableConfig<?>>) General.OPTIONS);
root.add("maintab", tabJson.save(MAIN_TAB));
@@ -306,7 +339,9 @@ public class HudConfigStorage implements IConfigHandler {
@Override
public void load() {
MainChatTab.LOAD_ALL_JSON = true;
loadFromFile();
MainChatTab.LOAD_ALL_JSON = false;
}
@Override
@@ -1,112 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
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);
}
}
}
}
@@ -1,126 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
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());
}
}
}
}
@@ -1,93 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
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();
}
}
@@ -1,222 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
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();
}
}
@@ -1,158 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
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;
private boolean main = true;
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;
if (listIndex != 0) {
main = false;
// If it's 0 it's the main tab
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, parent.main));
}
}
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 "advancedchathud.config.tabmenu." + key;
}
public String getDisplayName() {
return StringUtils.translate(translate);
}
}
}
}
@@ -0,0 +1,155 @@
package io.github.darkkronicle.advancedchathud.config.gui;
import fi.dy.masa.malilib.config.IConfigBase;
import fi.dy.masa.malilib.config.options.ConfigBoolean;
import fi.dy.masa.malilib.config.options.ConfigInteger;
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.util.GuiUtils;
import fi.dy.masa.malilib.util.KeyCodes;
import io.github.darkkronicle.advancedchatcore.gui.buttons.BackButtonListener;
import io.github.darkkronicle.advancedchatcore.gui.buttons.Buttons;
import io.github.darkkronicle.advancedchatcore.interfaces.IClosable;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.gui.ChatWindow;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import java.util.ArrayList;
import java.util.List;
public class ChatWindowEditor extends GuiConfigsBase implements IClosable {
private final ChatWindow window;
private final ConfigInteger windowX = new ConfigInteger(
"advancedchathud.windowconfig.x",
HudConfigStorage.General.X.config.getIntegerValue(), 0, MinecraftClient.getInstance().getWindow().getScaledWidth(),
"advancedchathud.windowconfig.info.x");
private final ConfigInteger windowY = new ConfigInteger(
"advancedchathud.windowconfig.y",
HudConfigStorage.General.Y.config.getIntegerValue(), 0, MinecraftClient.getInstance().getWindow().getScaledHeight(),
"advancedchathud.windowconfig.info.y");
private final ConfigInteger windowWidth = new ConfigInteger(
"advancedchathud.windowconfig.width",
HudConfigStorage.General.WIDTH.config.getIntegerValue(), 40, MinecraftClient.getInstance().getWindow().getScaledWidth(),
"advancedchathud.windowconfig.info.width");
private final ConfigInteger windowHeight = new ConfigInteger(
"advancedchathud.windowconfig.height",
HudConfigStorage.General.HEIGHT.config.getIntegerValue(), 40, MinecraftClient.getInstance().getWindow().getScaledHeight(),
"advancedchathud.windowconfig.info.height");
private final ConfigBoolean renderRight = new ConfigBoolean(
"advancedchathud.windowconfig.renderright",
false,
"advancedchathud.windowconfig.info.renderright");
private final ConfigBoolean renderTopFirst = new ConfigBoolean(
"advancedchathud.windowconfig.rendertopfirst",
false,
"advancedchathud.windowconfig.info.rendertopfirst");
private final ConfigBoolean minimalist = new ConfigBoolean(
"advancedchathud.windowconfig.minimalist",
false,
"advancedchathud.windowconfig.info.minimalist");
public ChatWindowEditor(Screen parent, ChatWindow window) {
super(10, 50, AdvancedChatHud.MOD_ID, parent, "Chat Window");
this.window = window;
this.setParent(parent);
getSettings();
}
public void getSettings() {
windowX.setIntegerValue(window.getConvertedX());
windowY.setIntegerValue(window.getConvertedY());
windowWidth.setIntegerValue(window.getConvertedWidth());
windowHeight.setIntegerValue(window.getConvertedHeight());
renderRight.setBooleanValue(window.isRenderRight());
renderTopFirst.setBooleanValue(window.isRenderTopFirst());
minimalist.setBooleanValue(window.isMinimalist());
}
public void applySettings() {
window.setPosition(windowX.getIntegerValue(), windowY.getIntegerValue());
window.setDimensions(windowWidth.getIntegerValue(), windowHeight.getIntegerValue());
window.setRenderRight(renderRight.getBooleanValue());
window.setRenderTopFirst(renderTopFirst.getBooleanValue());
window.setMinimalist(minimalist.getBooleanValue());
}
@Override
public void initGui() {
super.initGui();
createButtons(10, 26);
}
private void createButtons(int x, int y) {
ButtonGeneric back = Buttons.BACK.createButton(x, y);
x += this.addButton(back, new BackButtonListener(this)).getWidth() + 2;
}
@Override
public List<ConfigOptionWrapper> getConfigs() {
ArrayList<IConfigBase> config = new ArrayList<>();
config.add(windowX);
config.add(windowY);
config.add(windowWidth);
config.add(windowHeight);
config.add(renderRight);
config.add(renderTopFirst);
config.add(minimalist);
return GuiConfigsBase.ConfigOptionWrapper.createFor(config);
}
@Override
public void close() {
save();
super.close();
}
@Override
protected void closeGui(boolean showParent) {
// Save the changes :)
save();
super.closeGui(showParent);
}
public void save() {
applySettings();
}
@Override
public boolean onKeyTyped(int keyCode, int scanCode, int modifiers) {
// Override so that on escape stuff still gets saved
if (this.activeKeybindButton != null) {
this.activeKeybindButton.onKeyPressed(keyCode);
return true;
} else {
if (this.getListWidget().onKeyTyped(keyCode, scanCode, modifiers)) {
return true;
}
if (keyCode == KeyCodes.KEY_ESCAPE
&& this.parentScreen != GuiUtils.getCurrentScreen()) {
// Make sure to save
closeGui(true);
return true;
}
return false;
}
}
@Override
public void close(ButtonBase button) {
closeGui(true);
}
}
@@ -0,0 +1,137 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config.gui;
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.GuiUtils;
import fi.dy.masa.malilib.util.KeyCodes;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.config.SaveableConfig;
import io.github.darkkronicle.advancedchatcore.gui.buttons.BackButtonListener;
import io.github.darkkronicle.advancedchatcore.gui.buttons.Buttons;
import io.github.darkkronicle.advancedchatcore.gui.buttons.NamedSimpleButton;
import io.github.darkkronicle.advancedchatcore.interfaces.IClosable;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.gui.screen.Screen;
public class GuiTabEditor extends GuiConfigsBase implements IClosable {
private final ChatTab tab;
private final boolean main;
public GuiTabEditor(Screen parent, ChatTab tab) {
this(parent, tab, false);
}
public GuiTabEditor(Screen parent, ChatTab tab, boolean main) {
super(10, 50, AdvancedChatHud.MOD_ID, parent, tab.getName().config.getStringValue());
this.tab = tab;
this.main = main;
this.setParent(parent);
}
@Override
public void initGui() {
super.initGui();
createButtons(10, 26);
}
private void createButtons(int x, int y) {
ButtonGeneric back = Buttons.BACK.createButton(x, y);
x += this.addButton(back, new BackButtonListener(this)).getWidth() + 2;
x += this.addButton(
x,
y,
"advancedchathud.gui.button.export",
(button, mouseButton) -> {
save();
GuiBase.openGui(SharingScreen.fromTab(tab, this));
}) + 2;
if (!main) {
x += this.addButton(x, y, "advancedchathud.gui.button.matches", (button, mouseButton) -> {
save();
GuiBase.openGui(new MatchesEditor(this, tab));
}) + 2;
}
}
private int addButton(int x, int y, String translation, IButtonActionListener listener) {
return addButton(new NamedSimpleButton(x, y, StringUtils.translate(translation)), listener)
.getWidth();
}
@Override
public List<ConfigOptionWrapper> getConfigs() {
ArrayList<IConfigBase> config = new ArrayList<>();
List<SaveableConfig<? extends IConfigBase>> options;
if (main) {
options = tab.getMainEditableOptions();
} else {
options = tab.getOptions();
}
for (SaveableConfig<? extends IConfigBase> s : options) {
config.add(s.config);
}
return GuiConfigsBase.ConfigOptionWrapper.createFor(config);
}
@Override
public void close() {
save();
super.close();
}
@Override
protected void closeGui(boolean showParent) {
// Save the changes :)
save();
super.closeGui(showParent);
}
public void save() {
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
}
@Override
public boolean onKeyTyped(int keyCode, int scanCode, int modifiers) {
// Override so that on escape stuff still gets saved
if (this.activeKeybindButton != null) {
this.activeKeybindButton.onKeyPressed(keyCode);
return true;
} else {
if (this.getListWidget().onKeyTyped(keyCode, scanCode, modifiers)) {
return true;
}
if (keyCode == KeyCodes.KEY_ESCAPE
&& this.parentScreen != GuiUtils.getCurrentScreen()) {
// Make sure to save
closeGui(true);
return true;
}
return false;
}
}
@Override
public void close(ButtonBase button) {
closeGui(true);
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config.gui;
import fi.dy.masa.malilib.gui.GuiBase;
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.gui.GuiConfigHandler;
import io.github.darkkronicle.advancedchatcore.gui.ConfigGuiListBase;
import io.github.darkkronicle.advancedchatcore.gui.buttons.NamedSimpleButton;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import java.util.List;
public class GuiTabManager extends ConfigGuiListBase<ChatTab, WidgetTabEntry, WidgetListTabs> {
public GuiTabManager() {
super();
this.title = StringUtils.translate("advancedchat.screen.main");
}
@Override
protected WidgetListTabs createListWidget(int listX, int listY) {
return new WidgetListTabs(
listX, listY, this.getBrowserWidth(), this.getBrowserHeight(), null, this);
}
@Override
public void initGuiConfig(int x, int y) {
x = this.width - 10;
y -= 48;
x -= this.addButton(x, y, "advancedchathud.gui.button.addtab", (button, mouseButton) -> {
HudConfigStorage.TABS.add(new ChatTab());
this.getListWidget().refreshEntries();
}) + 2;
x -= this.addButton(x, y, "advancedchathud.gui.button.import", (button, mouseButton) ->
GuiBase.openGui(new SharingScreen(null, this))
) + 2;
x -= this.addButton(x, y, "advancedchathud.gui.button.reload", (button, mouseButton) ->
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs()
) + 2;
}
protected int addButton(int x, int y, String translation, IButtonActionListener listener) {
ButtonGeneric button = new NamedSimpleButton(x, y, StringUtils.translate(translation), false);
this.addButton(button, listener);
return button.getWidth();
}
}
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config.gui;
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.gui.CoreGuiListBase;
import io.github.darkkronicle.advancedchatcore.gui.buttons.BackButtonListener;
import io.github.darkkronicle.advancedchatcore.gui.buttons.Buttons;
import io.github.darkkronicle.advancedchatcore.gui.buttons.NamedSimpleButton;
import io.github.darkkronicle.advancedchatcore.interfaces.IClosable;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.Match;
import net.minecraft.client.gui.screen.Screen;
public class MatchesEditor extends CoreGuiListBase<Match, WidgetMatchEntry, WidgetListMatches>
implements IClosable {
private final ChatTab tab;
protected MatchesEditor(Screen parent, ChatTab tab) {
super(10, 60);
this.title = StringUtils.translate("advancedchathud.config.match.screen.name");
this.tab = tab;
this.setParent(parent);
}
@Override
public void initGui() {
super.initGui();
int y = 26;
int x = this.width - 10;
this.addButton(x, y, "advancedchathud.gui.button.addmatch",
(button, mouseButton) -> this.addMatch());
this.addButton(Buttons.BACK.createButton(10, y), new BackButtonListener(this));
}
protected void addButton(int x, int y, String translation, IButtonActionListener listener) {
ButtonGeneric button = new NamedSimpleButton(x, y, StringUtils.translate(translation), false);
// Right aline
this.addButton(button, listener);
}
@Override
protected void closeGui(boolean showParent) {
getListWidget().save();
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
super.closeGui(showParent);
}
@Override
protected WidgetListMatches createListWidget(int listX, int listY) {
return new WidgetListMatches(
listX, listY, this.getBrowserWidth(), this.getBrowserHeight(), null, tab, this);
}
public void addMatch() {
tab.getMatches().add(new Match("I will match to text!", FindType.LITERAL));
getListWidget().refreshEntries();
}
@Override
public void close(ButtonBase button) {
this.closeGui(true);
}
}
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config.gui;
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.IButtonActionListener;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.gui.buttons.NamedSimpleButton;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
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.setFocused(true);
}
text.setFocused(true);
text.setDrawsBackground(true);
text.setEditable(true);
text.setFocused(true);
this.addTextField(text, null);
this.addButton(
x, y, "advancedchathud.gui.button.import", (button, mouseButton) -> importTab());
}
private void addButton(int x, int y, String translation, IButtonActionListener listener) {
this.addButton(new NamedSimpleButton(x, y, StringUtils.translate(translation)), listener);
}
public void importTab() {
ChatTab.ChatTabJsonSave tabSave = new ChatTab.ChatTabJsonSave();
ChatTab tab = tabSave.load(new JsonParser().parse(text.getText()).getAsJsonObject());
if (tab == null) {
throw new NullPointerException("Filter is null!");
}
HudConfigStorage.TABS.add(tab);
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
addGuiMessage(
Message.MessageType.SUCCESS,
5000,
StringUtils.translate("advancedchat.gui.message.successful"));
}
}
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config.gui;
import fi.dy.masa.malilib.gui.interfaces.ISelectionListener;
import io.github.darkkronicle.advancedchatcore.gui.WidgetConfigList;
import io.github.darkkronicle.advancedchatcore.gui.WidgetConfigListEntry;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.Match;
import java.util.Collection;
import net.minecraft.client.gui.screen.Screen;
public class WidgetListMatches extends WidgetConfigList<Match, WidgetMatchEntry> {
public final ChatTab tab;
public WidgetListMatches(
int x,
int y,
int width,
int height,
ISelectionListener<Match> selectionListener,
ChatTab parent,
Screen screen) {
super(x, y, width, height, selectionListener, screen);
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
public boolean onKeyTyped(int keyCode, int scanCode, int modifiers) {
boolean val = super.onKeyTyped(keyCode, scanCode, modifiers);
for (WidgetMatchEntry widget : this.listWidgets) {
widget.save();
}
return val;
}
public void save() {
for (WidgetMatchEntry widget : this.listWidgets) {
widget.save();
}
}
@Override
protected Collection<Match> getAllEntries() {
return tab.getMatches();
}
}
@@ -5,27 +5,27 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config;
package io.github.darkkronicle.advancedchathud.config.gui;
import fi.dy.masa.malilib.gui.interfaces.ISelectionListener;
import fi.dy.masa.malilib.gui.widgets.WidgetListBase;
import io.github.darkkronicle.advancedchatcore.gui.WidgetConfigList;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import javax.annotation.Nullable;
import net.minecraft.client.gui.screen.Screen;
public class WidgetListTabs extends WidgetListBase<ChatTab, WidgetTabEntry> {
public class WidgetListTabs extends WidgetConfigList<ChatTab, WidgetTabEntry> {
public WidgetListTabs(
int x,
int y,
int width,
int height,
@Nullable ISelectionListener<ChatTab> selectionListener,
ISelectionListener<ChatTab> selectionListener,
Screen parent) {
super(x, y, width, height, selectionListener);
this.browserEntryHeight = 22;
super(x, y, width, height, selectionListener, parent);
this.setParent(parent);
}
@@ -0,0 +1,130 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config.gui;
import fi.dy.masa.malilib.config.options.ConfigOptionList;
import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
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.wrappers.TextFieldWrapper;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.gui.WidgetConfigListEntry;
import io.github.darkkronicle.advancedchatcore.gui.buttons.NamedSimpleButton;
import io.github.darkkronicle.advancedchatcore.util.FindType;
import io.github.darkkronicle.advancedchatcore.util.TextUtil;
import io.github.darkkronicle.advancedchathud.config.Match;
import java.util.ArrayList;
import java.util.List;
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 WidgetConfigListEntry<Match> {
private TextFieldWrapper<GuiTextFieldGeneric> name;
private List<TextFieldWrapper<GuiTextFieldGeneric>> texts;
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, isOdd, entry, listIndex);
y += 1;
int pos = x + width - 2;
int removeWidth = 0;
if (listIndex != 0) {
// Always want one
removeWidth = addButton(pos, y, "advancedchathud.config.match.remove", (button, mouseButton) -> {
parent.tab.getMatches().remove(entry);
parent.refreshEntries();
}) + 1;
}
pos -= removeWidth;
int findWidth = getFindTypeWidth();
int nameWidth = width - findWidth - removeWidth;
this.findType.setOptionListValue(entry.getFindType());
ConfigButtonOptionList findType =
new ConfigButtonOptionList(pos - findWidth, y, findWidth, 20, this.findType);
this.addButton(
findType,
(button, mouseButton) -> {
entry.setFindType((FindType) this.findType.getOptionListValue());
});
pos -= findWidth + 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);
texts = new ArrayList<>();
texts.add(name);
}
private static int getFindTypeWidth() {
List<String> translations = new ArrayList<>();
for (FindType f : FindType.values()) {
translations.add(f.getDisplayName());
}
return TextUtil.getMaxLengthTranslation(translations) + 10;
}
@Override
public List<TextFieldWrapper<GuiTextFieldGeneric>> getTextFields() {
return texts;
}
@Override
public void renderEntry(int mouseX, int mouseY, boolean selected, MatrixStack matrixStack) {}
@Override
public String getName() {
return null;
}
public void save() {
entry.setPattern(name.getTextField().getText());
}
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, String translation, IButtonActionListener listener) {
ButtonGeneric button =
new NamedSimpleButton(x, y, StringUtils.translate(translation), false);
this.addButton(button, listener);
return button.getWidth();
}
}
@@ -0,0 +1,77 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.config.gui;
import fi.dy.masa.malilib.gui.GuiBase;
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.gui.WidgetConfigListEntry;
import io.github.darkkronicle.advancedchatcore.gui.buttons.NamedSimpleButton;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class WidgetTabEntry extends WidgetConfigListEntry<ChatTab> {
private final ChatTab tab;
private boolean main = true;
public WidgetTabEntry(
int x,
int y,
int width,
int height,
boolean isOdd,
ChatTab tab,
int listIndex,
WidgetListTabs parent) {
super(x, y, width, height, isOdd, tab, listIndex, tab.getWidgetHoverLines());
this.tab = tab;
y += 1;
int pos = x + width - 2;
if (listIndex != 0) {
main = false;
// If it's 0 it's the main tab
pos -=
addButton(
pos,
y,
"advancedchathud.config.tabmenu.remove",
(button, mouseButton) -> {
HudConfigStorage.TABS.remove(tab);
parent.refreshEntries();
AdvancedChatHud.MAIN_CHAT_TAB.setUpTabs();
});
}
pos -=
addButton(
pos,
y,
"advancedchathud.config.tabmenu.configure",
(button, mouseButton) -> {
GuiBase.openGui(new GuiTabEditor(parent.getParent(), tab, main));
});
setButtonStartX(pos);
}
protected int addButton(int x, int y, String translation, IButtonActionListener listener) {
ButtonGeneric button =
new NamedSimpleButton(x, y, StringUtils.translate(translation), false);
this.addButton(button, listener);
return button.getWidth();
}
@Override
public String getName() {
return tab.getName().config.getStringValue();
}
}
@@ -14,11 +14,7 @@ import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.chat.ChatMessage;
import io.github.darkkronicle.advancedchatcore.config.ConfigStorage;
import io.github.darkkronicle.advancedchatcore.interfaces.IJsonSave;
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.advancedchatcore.util.*;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.HudChatMessage;
import io.github.darkkronicle.advancedchathud.HudChatMessageHolder;
@@ -27,6 +23,8 @@ import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import io.github.darkkronicle.advancedchathud.util.ScissorUtil;
import lombok.Getter;
import lombok.Setter;
import net.fabricmc.api.EnvType;
@@ -40,19 +38,31 @@ import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.text.TextColor;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
@Environment(EnvType.CLIENT)
public class ChatWindow {
private int scrolledLines = 0;
private double scrolledHeight = 0;
private double scrollStart = 0;
private double scrollEnd = 0;
@Getter private int y;
private long lastScroll = 0;
private int scrollDuration = 200;
@Getter private int x;
@Getter @Setter private double yPercent;
@Getter private int width;
@Getter @Setter private double xPercent;
@Getter private int height;
@Getter @Setter private double widthPercent;
@Getter @Setter private double heightPercent;
@Getter @Setter private boolean renderRight = false;
@Getter @Setter private boolean minimalist = false;
@Getter @Setter private boolean renderTopFirst = false;
private final MinecraftClient client;
@@ -75,18 +85,40 @@ public class ChatWindow {
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();
int scaledHeight = client.getWindow().getScaledHeight();
int scaledWidth = client.getWindow().getScaledWidth();
this.yPercent =
((double) (scaledHeight - HudConfigStorage.General.Y.config.getIntegerValue()))
/ scaledHeight;
this.xPercent =
((double) HudConfigStorage.General.X.config.getIntegerValue()) / scaledWidth;
this.widthPercent =
((double) HudConfigStorage.General.WIDTH.config.getIntegerValue()) / scaledWidth;
this.heightPercent =
((double) HudConfigStorage.General.HEIGHT.config.getIntegerValue()) / scaledHeight;
this.setTab(tab);
}
public void setRelativePosition(double x, double y) {
if (x > 2) {
x = 0;
}
if (y > 2) {
y = 0;
}
this.xPercent = x;
this.yPercent = y;
}
public void setPosition(int x, int y) {
this.x = x;
this.y = y;
int scaledHeight = client.getWindow().getScaledHeight();
this.xPercent = ((double) x) / client.getWindow().getScaledWidth();
this.yPercent = ((double) y) / scaledHeight;
}
public void setRelativeDimensions(double width, double height) {
this.widthPercent = width;
this.heightPercent = height;
}
public void setTab(AbstractChatTab tab) {
@@ -96,6 +128,7 @@ public class ChatWindow {
for (int i = messages.size() - 1; i >= 0; i--) {
addMessage(messages.get(i), false, false);
}
WindowManager.getInstance().setSelected(this);
}
public void addMessage(HudChatMessage message) {
@@ -109,8 +142,8 @@ public class ChatWindow {
newMessage.setCreationTick(MinecraftClient.getInstance().inGameHud.getTicks());
}
this.lines.add(0, newMessage);
if (scrolledLines > 0) {
scrolledLines++;
if (scrolledHeight > 0) {
scrolledHeight += (HudConfigStorage.General.LINE_SPACE.config.getIntegerValue()) * newMessage.getLineCount() + HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue();
}
int visibleMessagesMaxSize =
HudConfigStorage.General.STORED_LINES.config.getIntegerValue();
@@ -120,6 +153,22 @@ public class ChatWindow {
}
}
public int getConvertedX() {
return (int) ((double) client.getWindow().getScaledWidth() * xPercent);
}
public int getConvertedY() {
return (int) ((double) client.getWindow().getScaledHeight() * yPercent);
}
public int getConvertedWidth() {
return (int) ((double) client.getWindow().getScaledWidth() * widthPercent);
}
public int getConvertedHeight() {
return (int) ((double) client.getWindow().getScaledHeight() * heightPercent);
}
public int getTotalLines() {
int count = 0;
for (ChatMessage line : lines) {
@@ -129,23 +178,41 @@ public class ChatWindow {
}
public void scroll(double amount) {
this.scrolledLines = (int) ((double) this.scrolledLines + amount);
int totalLines = getTotalLines();
if (this.scrolledLines > totalLines) {
this.scrolledLines = totalLines;
this.scrollEnd = this.scrolledHeight + amount * 15;
this.scrollStart = this.scrolledHeight;
lastScroll = Util.getMeasuringTimeMs();
}
public void updateScroll() {
long time = Util.getMeasuringTimeMs();
scrollDuration = 300;
scrolledHeight = scrollStart + (
(scrollEnd - scrollStart) * (1 - ((ConfigStorage.Easing) HudConfigStorage.General.SCROLL_TYPE.config.getOptionListValue()).apply(
1 - ((float) (time - lastScroll)) / HudConfigStorage.General.SCROLL_TIME.config.getIntegerValue()
))
);
int totalHeight = getTotalHeight();
if (this.scrolledHeight > totalHeight) {
scrollStart = totalHeight;
scrollEnd = totalHeight;
lastScroll = 0;
this.scrolledHeight = totalHeight;
}
if (this.scrolledLines <= 0) {
this.scrolledLines = 0;
if (this.scrolledHeight <= 0) {
scrollStart = 0;
scrollEnd = 0;
lastScroll = 0;
this.scrolledHeight = 0;
}
}
private static void drawRect(
public static void drawRect(
MatrixStack stack, int x, int y, int width, int height, int color) {
DrawableHelper.fill(stack, x, y, x + width, y + height, color);
}
private static void fill(MatrixStack stack, int x, int y, int x2, int y2, int color) {
public static void fill(MatrixStack stack, int x, int y, int x2, int y2, int color) {
DrawableHelper.fill(stack, x, y, x2, y2, color);
}
@@ -158,7 +225,10 @@ public class ChatWindow {
}
public void resetScroll() {
this.scrolledLines = 0;
this.lastScroll = 0;
this.scrollStart = 0;
this.scrollEnd = 0;
this.scrolledHeight = 0;
}
public int getPaddedWidth() {
@@ -173,11 +243,11 @@ public class ChatWindow {
}
private int getActualY(int y) {
return (int) Math.ceil(this.y / getScale()) - y;
return (int) Math.ceil(this.getConvertedY() / getScale()) - y;
}
private int getLeftX() {
return (int) Math.ceil(x / getScale());
return (int) Math.ceil(this.getConvertedX() / getScale());
}
private int getPaddedLeftX() {
@@ -185,7 +255,7 @@ public class ChatWindow {
+ (int)
Math.ceil(
HudConfigStorage.General.LEFT_PAD.config.getIntegerValue()
+ headOffset()));
+ (renderRight ? 0 : headOffset())));
}
private double getScale() {
@@ -197,19 +267,19 @@ public class ChatWindow {
}
private int getPaddedRightX() {
return (getRightX() - HudConfigStorage.General.RIGHT_PAD.config.getIntegerValue());
return (getRightX() - HudConfigStorage.General.RIGHT_PAD.config.getIntegerValue() - (renderRight ? headOffset() : 0));
}
public int getActualHeight() {
return height + getBarHeight();
return getConvertedHeight() + getBarHeight();
}
private int getScaledHeight() {
return (int) Math.ceil(height / getScale());
return (int) Math.ceil(getConvertedHeight() / getScale());
}
private int getScaledWidth() {
return (int) Math.ceil(width / getScale());
return (int) Math.ceil(getConvertedWidth() / getScale());
}
private int getBarHeight() {
@@ -221,30 +291,41 @@ public class ChatWindow {
}
public boolean isMouseOver(double mouseX, double mouseY) {
int x = getConvertedX();
int y = getConvertedY();
return (x <= mouseX
&& x + width >= mouseX
&& x + getConvertedWidth() >= mouseX
&& y >= mouseY
&& y - getActualHeight() <= mouseY);
}
public int getTotalHeight() {
return getTotalLines() * HudConfigStorage.General.LINE_SPACE.config.getIntegerValue() + (lines.size() - 1) * HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue();
}
public void render(MatrixStack matrixStack, int ticks, boolean focused) {
if (!focused) {
resetScroll();
}
updateScroll();
if (visibility == HudConfigStorage.Visibility.FOCUSONLY && !focused) {
return;
}
int lineCount = lines.size();
int totalLines = getTotalLines();
boolean chatFocused = visibility == HudConfigStorage.Visibility.ALWAYS || focused;
int totalHeight = getTotalHeight();
if (scrolledLines > totalLines) {
scrolledLines = totalLines;
if (scrolledHeight > totalHeight) {
scrolledHeight = totalHeight;
}
matrixStack.push();
matrixStack.scale((float) getScale(), (float) getScale(), 1);
int lines = 0;
int currentHeight = 0;
int renderedLines = 0;
int scaledWidth = getScaledWidth();
int scaledHeight = getScaledHeight();
@@ -252,54 +333,68 @@ public class ChatWindow {
int padLX = getPaddedLeftX();
int rightX = getRightX();
int padRX = getPaddedRightX();
int limit = getScaledHeight() - HudConfigStorage.General.TOP_PAD.config.getIntegerValue() + HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
int lastY = 0;
LimitedInteger y =
new LimitedInteger(
getScaledHeight()
- HudConfigStorage.General.TOP_PAD.config.getIntegerValue(),
HudConfigStorage.General.BOTTOM_PAD.config.getIntegerValue());
getScaledHeight() - HudConfigStorage.General.TOP_PAD.config.getIntegerValue() + (HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue() + HudConfigStorage.General.LINE_SPACE.config.getIntegerValue() * (renderTopFirst ? 2 : 1)),
renderTopFirst ? HudConfigStorage.General.TOP_PAD.config.getIntegerValue() + HudConfigStorage.General.LINE_SPACE.config.getIntegerValue(): HudConfigStorage.General.BOTTOM_PAD.config.getIntegerValue());
double scale = client.getWindow().getScaleFactor();
ScissorUtil.applyScissorBox(
(int) (getConvertedX() * scale),
(int) ((client.getWindow().getScaledHeight() - getConvertedY()) * scale),
(int) (getConvertedWidth() * scale),
(int) (getConvertedHeight() * scale));
boolean foundScroll = false;
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;
int lineIndex = renderTopFirst ? i : message.getLineCount() - i - 1;
lines++;
if (lines < scrolledLines) {
if (currentHeight < scrolledHeight - HudConfigStorage.General.LINE_SPACE.config.getIntegerValue()) {
currentHeight += HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
continue;
}
if (!y.incrementIfPossible(
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue())) {
boolean renderBelow = false;
if (!foundScroll) {
foundScroll = true;
y.incrementIfPossible(currentHeight - (int) scrolledHeight - HudConfigStorage.General.LINE_SPACE.config.getIntegerValue() + client.textRenderer.fontHeight);
renderBelow = true;
}
currentHeight += HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
if (!y.incrementIfPossible(HudConfigStorage.General.LINE_SPACE.config.getIntegerValue())) {
break;
}
ChatMessage.AdvancedChatLine line = message.getLines().get(i);
ChatMessage.AdvancedChatLine line = message.getLines().get(renderTopFirst ? message.getLineCount() - i - 1 : i);
drawLine(
matrixStack,
line,
leftX,
y.getValue(),
renderTopFirst ? limit - y.getValue() + client.textRenderer.fontHeight : y.getValue(),
padLX,
padRX,
lineIndex,
j,
renderedLines,
chatFocused,
ticks);
ticks,
renderBelow ? y.getValue() - lastY - HudConfigStorage.General.LINE_SPACE.config.getIntegerValue() - 1 : 0);
lastY = y.getValue();
renderedLines++;
}
if (lines >= scrolledLines) {
if (lines == lineCount) {
if (currentHeight >= scrolledHeight) {
if (lines == totalLines) {
break;
}
if (!y.isPossible(
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue()
+ HudConfigStorage.General.MESSAGE_SPACE.config
.getIntegerValue())
|| !y.incrementIfPossible(
HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue())) {
if (!y.isPossible(HudConfigStorage.General.LINE_SPACE.config.getIntegerValue() + HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue()) || !y.incrementIfPossible(HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue())) {
break;
}
}
currentHeight += HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue();
}
ScissorUtil.resetScissor();
if (renderedLines == 0) {
y.setValue(0);
}
@@ -308,6 +403,9 @@ public class ChatWindow {
if (isSelected()) {
tab.resetUnread();
}
}
if (focused && !isMinimalist()) {
drawOutline(
matrixStack,
leftX,
@@ -317,7 +415,7 @@ public class ChatWindow {
tab.getBorderColor().color());
int scaledBar = getBarHeight();
int newY = getScaledHeight() + scaledBar;
String label = tab.getAbreviation();
String label = tab.getAbbreviation();
int labelWidth = StringUtils.getStringWidth(label) + 8;
drawRect(
matrixStack,
@@ -332,14 +430,14 @@ public class ChatWindow {
getActualY(newY),
labelWidth,
scaledBar,
tab.getBorderColor().withAlpha(180).color());
DrawableHelper.drawCenteredText(
tab.getBorderColor().color());
DrawableHelper.drawCenteredTextWithShadow(
matrixStack,
MinecraftClient.getInstance().textRenderer,
tab.getAbreviation(),
tab.getAbbreviation(),
leftX + (labelWidth) / 2,
getActualY(newY - 3),
ColorUtil.WHITE.color());
Colors.getInstance().getColorOrWhite("white").color());
drawRect(
matrixStack,
leftX + labelWidth,
@@ -427,34 +525,37 @@ public class ChatWindow {
double mouseX = client.mouse.getX() / 2;
double mouseY = client.mouse.getY() / 2;
if (isMouseOverVisibility(mouseX, mouseY)) {
DrawableHelper.drawStringWithShadow(
DrawableHelper.drawCenteredTextWithShadow(
matrixStack,
client.textRenderer,
visibility.getDisplayName(),
(int) (mouseX / getScale() + 4),
(int) (mouseY / getScale() - 16),
ColorUtil.WHITE.color());
Colors.getInstance().getColorOrWhite("white").color());
}
}
if (chatFocused) {
fill(
matrixStack,
leftX,
getActualY(y.getValue()),
rightX,
getActualY(getScaledHeight()),
tab.getInnerColor().color());
if (y.getValue() < getScaledHeight()) {
// Check to see if we've already gone above the boundaries
fill(
matrixStack,
leftX,
getActualY(renderTopFirst ? limit - y.getValue() : y.getValue()),
rightX,
getActualY(renderTopFirst ? 0 : getScaledHeight()),
tab.getInnerColor().color());
}
// Scroll bar
float add = (float) (scrolledLines) / (totalLines + 1);
int scrollHeight = (int) (add * getScaledHeight());
float add = (float) (scrolledHeight) / (getTotalHeight());
int scrollHeight = (int) (add * (getScaledHeight() - 10));
drawRect(
matrixStack,
getScaledWidth() + leftX - 1,
getActualY(scrollHeight + 10),
1,
10,
ColorUtil.WHITE.color());
Colors.getInstance().getColorOrWhite("white").color());
}
matrixStack.pop();
}
@@ -470,19 +571,20 @@ public class ChatWindow {
int messageIndex,
int renderedLines,
boolean focused,
int ticks) {
int ticks,
int renderBelow) {
int height = HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
if (renderedLines == 0) {
if (focused) {
height += HudConfigStorage.General.BOTTOM_PAD.config.getIntegerValue();
height += renderTopFirst ? HudConfigStorage.General.TOP_PAD.config.getIntegerValue() + HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue() + 1 : HudConfigStorage.General.BOTTOM_PAD.config.getIntegerValue();
height += renderBelow;
}
} 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();
Color background = line.getParent().getBackgroundColor();
Color text = HudConfigStorage.General.EMPTY_TEXT_COLOR.config.get();
if (background == null) {
background = tab.getInnerColor();
}
@@ -527,41 +629,61 @@ public class ChatWindow {
// Get line
Text render = line.getText();
if (line.getParent().getStacks() > 0 && lineIndex == 0) {
FluidText toPrint = new FluidText(render);
TextBuilder toPrint = new TextBuilder().append(render);
Style style = Style.EMPTY;
TextColor color = TextColor.fromRgb(ColorUtil.GRAY.color());
TextColor color =
TextColor.fromRgb(Colors.getInstance().getColorOrWhite("gray").color());
style = style.withColor(color);
toPrint.getRawTexts()
.add(new RawText(" (" + (line.getParent().getStacks() + 1) + ")", style));
render = toPrint;
toPrint.append(new RawText(" (" + (line.getParent().getStacks() + 1) + ")", style));
render = toPrint.build();
}
int backgroundWidth;
int scaledWidth = getScaledWidth();
int lineWidth = client.textRenderer.getWidth(render) + 2;
if (!focused
&& HudConfigStorage.General.HUD_LINE_TYPE.config.getOptionListValue()
== HudConfigStorage.HudLineType.COMPACT) {
backgroundWidth = client.textRenderer.getWidth(render) + 4 + headOffset();
backgroundWidth = lineWidth + headOffset();
} else {
backgroundWidth = getScaledWidth();
backgroundWidth = scaledWidth;
}
// Draw background
drawRect(matrixStack, x, getActualY(y), backgroundWidth, height, background.color());
int backgroundY = getActualY(y);
if (renderTopFirst && renderedLines == 0) {
backgroundY -= 1 + HudConfigStorage.General.TOP_PAD.config.getIntegerValue();
}
if (renderRight) {
drawRect(matrixStack, x + (scaledWidth - backgroundWidth), backgroundY, backgroundWidth, height, background.color());
} else {
drawRect(matrixStack, x, backgroundY, backgroundWidth, height, background.color());
}
if (lineIndex == line.getParent().getLineCount() - 1
&& line.getParent().getOwner() != null
&& HudConfigStorage.General.CHAT_HEADS.config.getBooleanValue()) {
// Allow head to be transparent
RenderUtils.setupBlend();
// Draw head
RenderSystem.setShaderColor(1, 1, 1, applied);
RenderSystem.setShaderTexture(0, line.getParent().getOwner().getTexture());
int headX;
if (renderRight) {
headX = pRX + 2;
} else {
headX = pLX - 10;
}
int headY = getActualY(y);
DrawableHelper.drawTexture(
matrixStack, pLX - 10, getActualY(y), 8, 8, 8, 8, 8, 8, 64, 64);
matrixStack, headX, headY, 8, 8, 8, 8, 8, 8, 64, 64);
DrawableHelper.drawTexture(
matrixStack, pLX - 10, getActualY(y), 8, 8, 40, 8, 8, 8, 64, 64);
matrixStack, headX, headY, 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());
matrixStack, render.asOrderedText(), renderRight ? pRX - lineWidth : pLX, getActualY(y) + 1, text.color());
}
public Style getText(double mouseX, double mouseY) {
@@ -569,7 +691,7 @@ public class ChatWindow {
return null;
}
double relX = mouseX;
double relY = y - mouseY;
double relY = getConvertedY() - mouseY;
double trueX = relX / getScale() - getPaddedLeftX();
double trueY = relY / getScale();
// Divide it by chat scale to get where it actually is
@@ -580,37 +702,45 @@ public class ChatWindow {
return null;
}
int lines = 0;
int lineCount = this.lines.size();
int lineHeight = 0;
boolean foundScroll = false;
LimitedInteger y =
new LimitedInteger(
getScaledHeight(),
getScaledHeight() + HudConfigStorage.General.LINE_SPACE.config.getIntegerValue(),
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) {
lineHeight += HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
if (lineHeight < scrolledHeight) {
continue;
}
if (!y.incrementIfPossible(
HudConfigStorage.General.LINE_SPACE.config.getIntegerValue())) {
if (!foundScroll) {
foundScroll = true;
trueY -= lineHeight - (int) scrolledHeight - HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
}
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);
double truestX = trueX;
if (renderRight) {
truestX = trueX - (getScaledWidth() - line.getWidth()) + headOffset() + HudConfigStorage.General.RIGHT_PAD.config.getIntegerValue() + HudConfigStorage.General.LEFT_PAD.config.getIntegerValue();
}
return this.client
.textRenderer
.getTextHandler()
.getStyleAt(line.getText(), (int) trueX);
.getStyleAt(line.getText(), (int) truestX);
}
}
if (lines >= scrolledLines) {
if (lines == lineCount) {
if (lineHeight >= scrolledHeight) {
if (lineHeight == getTotalHeight()) {
break;
}
if (!y.isPossible(
@@ -622,24 +752,89 @@ public class ChatWindow {
break;
}
}
lineHeight += HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue();
}
return null;
}
public ChatMessage getMessage(double mouseX, double mouseY) {
if (!WindowManager.getInstance().isChatFocused()) {
return null;
}
double relX = mouseX;
double relY = getConvertedY() - mouseY;
if (renderTopFirst) {
relY = getConvertedHeight() - relY;
}
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 lineHeight = 0;
boolean foundScroll = false;
LimitedInteger y = new LimitedInteger(getScaledHeight() + HudConfigStorage.General.LINE_SPACE.config.getIntegerValue(), 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--) {
lineHeight += HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
if (lineHeight < scrolledHeight) {
continue;
}
if (!foundScroll) {
foundScroll = true;
trueY -= lineHeight - (int) scrolledHeight - HudConfigStorage.General.LINE_SPACE.config.getIntegerValue();
}
if (!y.incrementIfPossible(HudConfigStorage.General.LINE_SPACE.config.getIntegerValue())) {
break;
}
if (trueY <= y.getValue() && trueY >= y.getValue() - HudConfigStorage.General.LINE_SPACE.config.getIntegerValue()) {
return message;
}
}
if (lineHeight >= scrolledHeight) {
if (lineHeight == getTotalHeight()) {
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;
}
}
lineHeight += HudConfigStorage.General.MESSAGE_SPACE.config.getIntegerValue();
}
return null;
}
public boolean isMouseOverDragBar(double mouseX, double mouseY) {
int x = getConvertedX();
int y = getConvertedY();
int width = getConvertedWidth();
int height = getConvertedHeight();
return (isMouseOver(mouseX, mouseY)
&& mouseX <= x + width - (getScaledBarHeight() * 3)
&& mouseY <= y - height);
}
public boolean onMouseClicked(double mouseX, double mouseY, int button) {
int convX = getConvertedX();
int width = getConvertedWidth();
boolean onButtons =
isMouseOverDragBar(mouseX - (getScaledBarHeight() * 3), mouseY)
&& mouseX >= x + width - getScaledBarHeight() * 3;
&& mouseX >= convX + width - getScaledBarHeight() * 3;
if (!onButtons) {
return false;
}
int x = width - (int) (mouseX - this.x);
int x = width - (int) (mouseX - convX);
// Visibility | Resize | Close
if (x <= getScaledBarHeight()) {
// Close
@@ -655,6 +850,10 @@ public class ChatWindow {
}
public boolean isMouseOverResize(double mouseX, double mouseY) {
int x = getConvertedX();
int y = getConvertedY();
int width = getConvertedWidth();
int height = getConvertedHeight();
return (isMouseOver(mouseX, mouseY)
&& mouseX >= x + width - (getScaledBarHeight() * 2)
&& mouseX <= x + width - (getScaledBarHeight())
@@ -662,6 +861,10 @@ public class ChatWindow {
}
public boolean isMouseOverVisibility(double mouseX, double mouseY) {
int x = getConvertedX();
int y = getConvertedY();
int width = getConvertedWidth();
int height = getConvertedHeight();
return (isMouseOver(mouseX, mouseY)
&& mouseX >= x + width - (getScaledBarHeight() * 3)
&& mouseX <= x + width - (getScaledBarHeight() * 2)
@@ -669,10 +872,10 @@ public class ChatWindow {
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
this.widthPercent = (double) width / client.getWindow().getScaledWidth();
this.heightPercent = (double) height / client.getWindow().getScaledHeight();
for (ChatMessage m : lines) {
m.formatChildren(this.width);
m.formatChildren(getPaddedWidth());
}
}
@@ -700,6 +903,23 @@ public class ChatWindow {
this.lines.clear();
}
public void removeMessage(ChatMessage remove) {
ChatMessage toRemove = null;
for (ChatMessage line : lines) {
if (remove.isSimilar(line) && remove.getTime().equals(line.getTime())) {
toRemove = line;
break;
}
}
if (toRemove != null) {
lines.remove(toRemove);
}
}
public void toggleMinimalist() {
minimalist = !minimalist;
}
public static class ChatWindowSerializer implements IJsonSave<ChatWindow> {
@Override
@@ -716,25 +936,44 @@ public class ChatWindow {
}
ChatWindow window = new ChatWindow(tab);
window.setSelected(obj.get("selected").getAsBoolean());
window.setPosition(obj.get("x").getAsInt(), obj.get("y").getAsInt());
if (obj.has("renderRight")) {
window.setRenderRight(obj.get("renderRight").getAsBoolean());
}
if (obj.has("renderTopFirst")) {
window.setRenderTopFirst(obj.get("renderTopFirst").getAsBoolean());
}
if (obj.has("minimalist")) {
window.setMinimalist(obj.get("minimalist").getAsBoolean());
}
window.setRelativePosition(obj.get("x").getAsDouble(), obj.get("y").getAsDouble());
window.setVisibility(
HudConfigStorage.Visibility.fromVisibilityString(
obj.get("visibility").getAsString()));
window.setDimensions(obj.get("width").getAsInt(), obj.get("height").getAsInt());
window.setRelativeDimensions(
obj.get("width").getAsDouble(), obj.get("height").getAsDouble());
return window;
}
@Override
public JsonObject save(ChatWindow chatWindow) {
JsonObject obj = new JsonObject();
obj.addProperty("x", chatWindow.getX());
obj.addProperty("y", chatWindow.getY());
obj.addProperty("width", chatWindow.getWidth());
obj.addProperty("height", chatWindow.getHeight());
obj.addProperty("x", chatWindow.getXPercent());
obj.addProperty("y", chatWindow.getYPercent());
obj.addProperty("width", chatWindow.getWidthPercent());
obj.addProperty("height", chatWindow.getHeightPercent());
obj.addProperty("visibility", chatWindow.getVisibility().getStringValue());
obj.addProperty("tabuuid", chatWindow.getTab().getUuid().toString());
obj.addProperty("selected", chatWindow.isSelected());
obj.addProperty("renderRight", chatWindow.isRenderRight());
obj.addProperty("renderTopFirst", chatWindow.isRenderTopFirst());
obj.addProperty("minimalist", chatWindow.isMinimalist());
return obj;
}
}
public void onResolutionChange() {
for (ChatMessage m : lines) {
m.formatChildren(getConvertedWidth());
}
}
}
@@ -7,29 +7,64 @@
*/
package io.github.darkkronicle.advancedchathud.gui;
import fi.dy.masa.malilib.gui.button.ButtonBase;
import fi.dy.masa.malilib.util.InfoUtils;
import fi.dy.masa.malilib.util.StringUtils;
import io.github.darkkronicle.advancedchatcore.chat.AdvancedChatScreen;
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.gui.ContextMenu;
import io.github.darkkronicle.advancedchatcore.gui.IconButton;
import io.github.darkkronicle.advancedchatcore.interfaces.AdvancedChatScreenSection;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.util.*;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.HudChatMessageHolder;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.itf.IChatHud;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import io.github.darkkronicle.advancedchathud.tabs.CustomChatTab;
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;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.Level;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
@Environment(EnvType.CLIENT)
public class HudSection extends AdvancedChatScreenSection {
private static final Identifier ADD_ICON =
new Identifier(AdvancedChatHud.MOD_ID, "textures/gui/chatwindow/add_window.png");
private static final Identifier RESET_ICON =
new Identifier(AdvancedChatHud.MOD_ID, "textures/gui/chatwindow/reset_windows.png");
private ContextMenu menu = null;
private ChatMessage message = null;
public HudSection(AdvancedChatScreen screen) {
super(screen);
}
private ColorUtil.SimpleColor getColor() {
ColorUtil.SimpleColor baseColor;
private Color getColor() {
Color baseColor;
ChatWindow sel = WindowManager.getInstance().getSelected();
if (sel == null) {
baseColor = HudConfigStorage.MAIN_TAB.getInnerColor().config.getSimpleColor();
baseColor = HudConfigStorage.MAIN_TAB.getInnerColor().config.get();
} else {
baseColor = sel.getTab().getInnerColor();
}
@@ -38,19 +73,104 @@ public class HudSection extends AdvancedChatScreenSection {
@Override
public void initGui() {
int x = 2;
int space = 2;
int y = MinecraftClient.getInstance().getWindow().getScaledHeight() - 31;
for (AbstractChatTab tab : AdvancedChatHud.MAIN_CHAT_TAB.getAllChatTabs()) {
TabButton button = TabButton.fromTab(tab, x, y);
getScreen().addButton(button, null);
x += button.getWidth() + space;
boolean left = !HudConfigStorage.General.TAB_BUTTONS_ON_RIGHT.config.getBooleanValue();
List<AbstractChatTab> tabs = new ArrayList<>(AdvancedChatHud.MAIN_CHAT_TAB.getAllChatTabs());
if (!left) {
Collections.reverse(tabs);
}
getScreen().addButton(new NewWindowButton(x, y), null);
RowList<ButtonBase> rows = left ? getScreen().getLeftSideButtons() : getScreen().getRightSideButtons();
rows.createSection("tabs", 0);
for (AbstractChatTab tab : tabs) {
rows.add("tabs", TabButton.fromTab(tab, 0, 0));
}
IconButton window = new IconButton(0, 0, 14, 32, ADD_ICON, (button) -> WindowManager.getInstance().onTabAddButton(IChatHud.getInstance().getTab()));
IconButton reset = new IconButton(0, 0, 14, 32, RESET_ICON, (button) -> WindowManager.getInstance().reset());
if (left) {
rows.add("tabs", window);
rows.add("tabs", reset);
} else {
rows.add("tabs", window, 0);
rows.add("tabs", reset, 0);
}
if (getScreen().getChatField().getText().isEmpty()) {
ChatWindow chatWindow = WindowManager.getInstance().getSelected();
if (chatWindow == null) {
return;
}
AbstractChatTab tab = chatWindow.getTab();
if (tab instanceof CustomChatTab custom) {
getScreen().getChatField().setText(custom.getStartingMessage());
getScreen().getChatField().setCursor(custom.getStartingMessage().length());
}
}
}
@Override
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
if (menu != null) {
menu.render(mouseX, mouseY, true, matrixStack);
}
}
public void createContextMenu(int mouseX, int mouseY) {
LinkedHashMap<Text, ContextMenu.ContextConsumer> actions = new LinkedHashMap<>();
message = WindowManager.getInstance().getMessage(mouseX, mouseY);
if (message != null) {
TextBuilder data = new TextBuilder();
try {
data.append(
message.getTime().format(DateTimeFormatter.ofPattern(ConfigStorage.General.TIME_FORMAT.config.getStringValue())), Style.EMPTY.withFormatting(Formatting.AQUA)
);
} catch (IllegalArgumentException e) {
AdvancedChatHud.LOGGER.log(Level.WARN, "Can't format time for context menu!", e);
}
if (message.getOwner() != null) {
data.append(" - ", Style.EMPTY.withFormatting(Formatting.GRAY));
if (message.getOwner().getEntry().getDisplayName() != null) {
data.append(message.getOwner().getEntry().getDisplayName());
} else {
data.append(message.getOwner().getEntry().getProfile().getName());
}
}
if (!data.build().getString().isBlank()) {
actions.put(data.build(), (x, y) -> {
InfoUtils.printActionbarMessage("advancedchathud.context.nothing");
});
}
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.copy")), (x, y) -> {
MinecraftClient.getInstance().keyboard.setClipboard(message.getOriginalText().getString());
InfoUtils.printActionbarMessage("advancedchathud.context.copied");
});
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.delete")), (x, y) -> {
HudChatMessageHolder.getInstance().removeChatMessage(message);
});
if (message.getOwner() != null) {
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.messageowner")), (x, y) -> {
getScreen().getChatField().setText("/msg " + message.getOwner().getEntry().getProfile().getName() + " ");
});
}
}
ChatWindow hovered = WindowManager.getInstance().getHovered(mouseX, mouseY);
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.removeallwindows")), (x, y) -> WindowManager.getInstance().reset());
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.clearallmessages")), (x, y) -> WindowManager.getInstance().clear());
if (hovered != null) {
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.duplicatewindow")), (x, y) -> WindowManager.getInstance().duplicateTab(hovered, x, y));
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.configurewindow")), (x, y) -> WindowManager.getInstance().configureTab(getScreen(), hovered));
actions.put(Text.literal(StringUtils.translate("advancedchathud.context.minimalist")), (x, y) -> hovered.toggleMinimalist());
}
menu = new ContextMenu(mouseX, mouseY, actions, () -> menu = null);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button == 1) {
createContextMenu((int) mouseX, (int) mouseY);
return true;
}
if (menu != null && menu.onMouseClicked((int) mouseX, (int) mouseY, button)) {
return true;
}
return WindowManager.getInstance().mouseClicked(getScreen(), mouseX, mouseY, button);
}
@@ -1,70 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.gui;
import fi.dy.masa.malilib.render.RenderUtils;
import io.github.darkkronicle.advancedchatcore.gui.CleanButton;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.itf.IChatHud;
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.util.Identifier;
public class NewWindowButton extends CleanButton {
private static final int PADDING = 3;
private static final int SIZE = PADDING + 9 + PADDING;
private static final Identifier ADD_ICON =
new Identifier(AdvancedChatHud.MOD_ID, "textures/gui/chatwindow/add_window.png");
public NewWindowButton(int x, int y) {
super(x, y, SIZE, SIZE, null, null);
}
@Override
public void render(int mouseX, int mouseY, boolean unused, MatrixStack matrixStack) {
int relMX = mouseX - x;
int relMY = mouseY - y;
hovered = relMX >= 0 && relMX <= width && relMY >= 0 && relMY <= height;
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, plusBack.color());
RenderUtils.color(1, 1, 1, 1);
RenderUtils.bindTexture(ADD_ICON);
DrawableHelper.drawTexture(
matrixStack,
x + PADDING,
y + PADDING,
width - (PADDING * 2),
height - (PADDING * 2),
0,
0,
32,
32,
32,
32);
}
@Override
protected boolean onMouseClickedImpl(int mouseX, int mouseY, int mouseButton) {
this.mc
.getSoundManager()
.play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
WindowManager.getInstance().onTabAddButton(IChatHud.getInstance().getTab());
return true;
}
}
@@ -10,11 +10,12 @@ 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.advancedchatcore.util.Color;
import io.github.darkkronicle.advancedchatcore.util.Colors;
import io.github.darkkronicle.advancedchatcore.util.TextUtil;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.itf.IChatHud;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import io.github.darkkronicle.advancedchathud.util.TextUtil;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
@@ -30,7 +31,7 @@ public class TabButton extends CleanButton {
private static final int RED = 0xFF_FF_55_55;
private TabButton(AbstractChatTab tab, int x, int y, int width, int height) {
super(x, y, width, height, tab.getMainColor(), tab.getAbreviation());
super(x, y, width, height, tab.getMainColor(), tab.getAbbreviation());
this.tab = tab;
}
@@ -39,9 +40,9 @@ public class TabButton extends CleanButton {
int relMX = mouseX - x;
int relMY = mouseY - y;
hovered = relMX >= 0 && relMX <= width && relMY >= 0 && relMY <= height;
ColorUtil.SimpleColor color = baseColor;
Color color = baseColor;
if (hovered) {
color = ColorUtil.WHITE.withAlpha(color.alpha());
color = Colors.getInstance().getColorOrWhite("hover").withAlpha(color.alpha());
}
boolean selected = false;
@@ -54,11 +55,7 @@ public class TabButton extends CleanButton {
}
}
if (!selected) {
color =
new ColorUtil.SimpleColor(
color.red() / 2, color.green(), color.blue() / 2, 100);
} else {
color = color.withAlpha(230);
color = new Color(color.red() / 2, color.green() / 2, color.blue() / 2, 100);
}
RenderUtils.drawRect(x, y, width, height, color.color());
@@ -86,10 +83,10 @@ public class TabButton extends CleanButton {
}
public static TabButton fromTab(AbstractChatTab tab, int x, int y) {
int width = StringUtils.getStringWidth(tab.getAbreviation()) + PADDING * 2;
int width = StringUtils.getStringWidth(tab.getAbbreviation()) + PADDING * 2;
if (tab.isShowUnread()) {
width += UNREAD_WIDTH;
}
return new TabButton(tab, x, y, width, PADDING + 9 + PADDING);
return new TabButton(tab, x, y, width, PADDING + 8 + PADDING);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 DarkKronicle
* Copyright (C) 2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,27 +9,40 @@ package io.github.darkkronicle.advancedchathud.gui;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import fi.dy.masa.malilib.gui.GuiBase;
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.advancedchatcore.util.SyncTaskQueue;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.HudChatMessage;
import io.github.darkkronicle.advancedchathud.HudChatMessageHolder;
import io.github.darkkronicle.advancedchathud.ResolutionEventHandler;
import io.github.darkkronicle.advancedchathud.config.HudConfigStorage;
import io.github.darkkronicle.advancedchathud.config.gui.ChatWindowEditor;
import io.github.darkkronicle.advancedchathud.itf.IChatHud;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import io.github.darkkronicle.advancedchathud.tabs.CustomChatTab;
import io.github.darkkronicle.advancedchathud.tabs.MainChatTab;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
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 {
public class WindowManager implements IRenderer, ResolutionEventHandler {
private static final WindowManager INSTANCE = new WindowManager();
private final MinecraftClient client;
private LinkedList<ChatWindow> windows = new LinkedList<>();
private final List<ChatWindow> windows = new ArrayList<>(8);
private int dragX = 0;
private int dragY = 0;
private ChatWindow drag = null;
@@ -47,13 +60,19 @@ public class WindowManager implements IRenderer {
windows.clear();
}
private void addWindow(ChatWindow window) {
// Remove duplicates being spawned from somewhere
windows.removeIf(w -> w == window);
windows.add(window);
}
public void loadFromJson(JsonArray array) {
reset();
if (!HudConfigStorage.General.VANILLA_HUD.config.getBooleanValue()) {
if (array == null || array.size() == 0) {
ChatWindow base = new ChatWindow(AdvancedChatHud.MAIN_CHAT_TAB);
base.setSelected(true);
windows.add(base);
addWindow(base);
return;
}
} else {
@@ -76,7 +95,7 @@ public class WindowManager implements IRenderer {
AdvancedChatHud.LOGGER.error("Error while loading in ChatWindow ", err);
continue;
}
windows.add(w);
addWindow(w);
}
}
@@ -91,8 +110,13 @@ public class WindowManager implements IRenderer {
@Override
public void onRenderGameOverlayPost(MatrixStack matrixStack) {
boolean isFocused = isChatFocused();
int ticks = client.inGameHud.getTicks();
if (!HudConfigStorage.General.RENDER_IN_OTHER_GUI.config.getBooleanValue() && !isFocused && client.currentScreen != null) {
return;
}
for (int i = windows.size() - 1; i >= 0; i--) {
windows.get(i).render(matrixStack, client.inGameHud.getTicks(), isChatFocused());
windows.get(i).render(matrixStack, ticks, isFocused);
}
}
@@ -104,7 +128,14 @@ public class WindowManager implements IRenderer {
public boolean scroll(double amount, double mouseX, double mouseY) {
for (ChatWindow w : windows) {
if (w.isSelected() || w.isMouseOver(mouseX, mouseY)) {
// Prioritize mouse over first
if (w.isMouseOver(mouseX, mouseY)) {
w.scroll(amount);
return true;
}
}
for (ChatWindow w : windows) {
if (w.isSelected()) {
w.scroll(amount);
return true;
}
@@ -121,6 +152,15 @@ public class WindowManager implements IRenderer {
return null;
}
public ChatMessage getMessage(double mouseX, double mouseY) {
for (ChatWindow w : windows) {
if (w.isMouseOver(mouseX, mouseY)) {
return w.getMessage(mouseX, mouseY);
}
}
return null;
}
public boolean isChatFocused() {
return this.client.currentScreen instanceof AdvancedChatScreen;
}
@@ -144,8 +184,40 @@ public class WindowManager implements IRenderer {
for (ChatWindow w : windows) {
w.setSelected(window.equals(w));
}
windows.remove(window);
windows.addFirst(window);
windows.removeIf(w -> w == window);
windows.add(0, window);
if (!HudConfigStorage.General.CHANGE_START_MESSAGE.config.getBooleanValue() || !(client.currentScreen instanceof AdvancedChatScreen screen)) {
return;
}
if (window.getTab() instanceof MainChatTab) {
for (ChatWindow w : windows) {
if (w.getTab() instanceof CustomChatTab tab2) {
if (screen.getChatField().getText().startsWith(tab2.getStartingMessage()) && tab2.getStartingMessage().length() > 0) {
screen.getChatField().setText(screen.getChatField().getText().substring(tab2.getStartingMessage().length()));
break;
}
}
}
} else if (window.getTab() instanceof CustomChatTab tab) {
boolean replaced = false;
for (ChatWindow w : windows) {
if (w.getTab() instanceof CustomChatTab tab2) {
if (screen.getChatField().getText().startsWith(tab2.getStartingMessage()) && tab2.getStartingMessage().length() > 0) {
screen.getChatField().setText(tab.getStartingMessage() + screen.getChatField().getText().substring(tab2.getStartingMessage().length()));
replaced = true;
break;
}
}
}
if (!replaced) {
screen.getChatField().setText(tab.getStartingMessage() + screen.getChatField().getText());
}
}
}
public boolean mouseClicked(Screen screen, double mouseX, double mouseY, int button) {
@@ -167,13 +239,13 @@ public class WindowManager implements IRenderer {
setSelected(over);
if (over.isMouseOverDragBar(mouseX, mouseY)) {
drag = over;
dragX = (int) mouseX - over.getX();
dragY = (int) mouseY - over.getY();
dragX = (int) mouseX - over.getConvertedX();
dragY = (int) mouseY - over.getConvertedY();
resize = false;
} else if (over.isMouseOverResize(mouseX, mouseY)) {
drag = over;
dragX = (int) mouseX - over.getWidth();
dragY = (int) mouseY + over.getHeight();
dragX = (int) mouseX - over.getConvertedWidth();
dragY = (int) mouseY + over.getConvertedHeight();
resize = true;
}
Style style = over.getText(mouseX, mouseY);
@@ -196,7 +268,7 @@ public class WindowManager implements IRenderer {
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());
x = Math.min(x, client.getWindow().getScaledWidth() - drag.getConvertedWidth());
y = Math.min(y, client.getWindow().getScaledHeight());
drag.setPosition(x, y);
return true;
@@ -234,8 +306,8 @@ public class WindowManager implements IRenderer {
if (sel == null) {
sel = window;
}
window.setPosition(sel.getX() + 15, sel.getY() + 15);
windows.add(window);
window.setPosition(sel.getConvertedX() + 15, sel.getConvertedY() + 15);
// windows.add(window);
setSelected(window);
}
@@ -268,4 +340,45 @@ public class WindowManager implements IRenderer {
w.clearLines();
}
}
@Override
public void onResolutionChange() {
// Delay resolution change because when toggling full screen it can take a render cycle for it to apply
SyncTaskQueue.getInstance().add(2, () -> {
for (ChatWindow w : windows) {
w.onResolutionChange();
}
});
}
public void onRemoveMessage(ChatMessage remove) {
IChatHud.getInstance().removeMessage(remove);
for (ChatWindow w : windows) {
w.removeMessage(remove);
}
}
public void duplicateTab(ChatWindow hovered, int x, int y) {
ChatWindow window = new ChatWindow(IChatHud.getInstance().getTab());
window.setRelativeDimensions(hovered.getWidthPercent(), hovered.getHeightPercent());
window.setVisibility(hovered.getVisibility());
window.setPosition(x, y);
setSelected(window);
}
public ChatWindow getHovered(int x, int y) {
int windowHeight = client.getWindow().getScaledHeight();
for (ChatWindow w : windows) {
int wX = w.getConvertedX();
int wY = w.getConvertedY();
if (x >= wX && x <= wX + w.getConvertedWidth() && y <= wY && y >= wY - w.getConvertedHeight()) {
return w;
}
}
return null;
}
public void configureTab(AdvancedChatScreen screen, ChatWindow window) {
GuiBase.openGui(new ChatWindowEditor(screen, window));
}
}
@@ -7,6 +7,7 @@
*/
package io.github.darkkronicle.advancedchathud.itf;
import io.github.darkkronicle.advancedchatcore.chat.ChatMessage;
import io.github.darkkronicle.advancedchathud.HudChatMessage;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import net.fabricmc.api.EnvType;
@@ -29,4 +30,6 @@ public interface IChatHud {
static IChatHud getInstance() {
return (IChatHud) MinecraftClient.getInstance().inGameHud.getChatHud();
}
void removeMessage(ChatMessage remove);
}
@@ -16,7 +16,6 @@ import io.github.darkkronicle.advancedchathud.itf.IChatHud;
import io.github.darkkronicle.advancedchathud.tabs.AbstractChatTab;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
@@ -41,17 +40,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public abstract class MixinChatHud implements IChatHud {
@Shadow @Final private MinecraftClient client;
@Shadow @Final private List<ChatHudLine<Text>> messages;
@Shadow @Final private List<ChatHudLine<OrderedText>> visibleMessages;
@Shadow @Final private List<ChatHudLine> messages;
@Shadow @Final private List<ChatHudLine.Visible> visibleMessages;
@Shadow private int scrolledLines;
@Shadow private boolean hasUnreadNewMessages;
private AbstractChatTab tab;
@Shadow
public abstract void reset();
@Shadow
public abstract int getWidth();
@@ -62,27 +58,62 @@ public abstract class MixinChatHud implements IChatHud {
protected abstract boolean isChatFocused();
@Shadow
public abstract void scroll(double amount);
@Shadow
public abstract void clear(boolean clearHistory);
@Shadow
public abstract int getVisibleLineCount();
@Shadow
protected abstract boolean isChatHidden();
public abstract void scroll(int amount);
@Shadow
public abstract int getHeight();
@Inject(at = @At("HEAD"), method = "scroll", cancellable = true)
private void scroll(int amount, CallbackInfo ci) {
// Only scroll if nothing is focused
if (WindowManager.getInstance().getSelected() != null) {
ci.cancel();
}
}
@Inject(at = @At("HEAD"), method = "render", cancellable = true)
private void render(MatrixStack stack, int delta, int mouseX, int mouseY, CallbackInfo ci) {
// Ignore rendering vanilla chat if disabled
if (!HudConfigStorage.General.VANILLA_HUD.config.getBooleanValue()) {
ci.cancel();
}
}
@Inject(at = @At("HEAD"), method = "getTextStyleAt", cancellable = true)
public void getTextHead(double x, double y, CallbackInfoReturnable<Style> cir) {
// Ignore checking vanilla chat for hovered text if disabled
if (!HudConfigStorage.General.VANILLA_HUD.config.getBooleanValue()) {
cir.setReturnValue(WindowManager.getInstance().getText(x, y));
}
}
@Inject(at = @At("RETURN"), method = "getTextStyleAt", cancellable = true)
public void getTextReturn(double x, double y, CallbackInfoReturnable<Style> cir) {
// If vanilla chat didn't find any text, search on our own windows
if (cir.getReturnValue() == null) {
cir.setReturnValue(WindowManager.getInstance().getText(x, y));
}
}
public AbstractChatTab getTab() {
return tab;
}
public void setTab(AbstractChatTab tab) {
this.tab = tab;
this.messages.clear();
this.visibleMessages.clear();
List<HudChatMessage> messages = HudChatMessageHolder.getInstance().getMessages();
for (int i = messages.size() - 1; i >= 0; i--) {
addMessage(messages.get(i));
}
}
@Override
public boolean isOver(double mouseX, double mouseY) {
mouseX = mouseX - 4;
mouseY = client.getWindow().getScaledHeight() - mouseY - 40;
mouseX = mouseX * getChatScale();
mouseY = mouseY * getChatScale();
return mouseX > 0 && mouseX < getWidth() && mouseY > 0 && mouseY < getHeight();
public void removeMessage(ChatMessage remove) {
// Reset messages that exist
setTab(this.tab);
}
@Override
@@ -90,8 +121,9 @@ public abstract class MixinChatHud implements IChatHud {
if (tab == null || !hudMsg.getTabs().contains(tab)) {
return;
}
;
tab.resetUnread();
if (HudConfigStorage.General.VANILLA_HUD.config.getBooleanValue()) {
tab.resetUnread();
}
int width = MathHelper.floor((double) this.getWidth() / this.getChatScale());
@@ -104,12 +136,11 @@ public abstract class MixinChatHud implements IChatHud {
OrderedText orderedText;
for (Iterator<OrderedText> text = list.iterator();
text.hasNext();
this.visibleMessages.add(
0, new ChatHudLine<>(msg.getCreationTick(), orderedText, msg.getId()))) {
this.visibleMessages.add(0, new ChatHudLine.Visible(msg.getCreationTick(), orderedText, msg.getIndicator(), !text.hasNext()))) {
orderedText = text.next();
if (this.isChatFocused() && this.scrolledLines > 0) {
this.hasUnreadNewMessages = true;
this.scroll(1.0D);
this.scroll(1);
}
}
@@ -118,85 +149,24 @@ public abstract class MixinChatHud implements IChatHud {
this.visibleMessages.remove(this.visibleMessages.size() - 1);
}
this.messages.add(
0, new ChatHudLine<>(msg.getCreationTick(), msg.getDisplayText(), msg.getId()));
this.messages.add(0, new ChatHudLine(msg.getCreationTick(), msg.getDisplayText(), msg.getSignature(), msg.getIndicator()));
while (this.messages.size()
> HudConfigStorage.General.STORED_LINES.config.getIntegerValue()) {
this.messages.remove(this.messages.size() - 1);
}
}
@Inject(at = @At("HEAD"), method = "scroll", cancellable = true)
private void scroll(double amount, CallbackInfo ci) {
if (WindowManager.getInstance().getSelected() != null) {
// Only scroll if nothing is focused
ci.cancel();
}
}
@Shadow
public abstract void clear(boolean clearHistory);
public AbstractChatTab getTab() {
return tab;
}
@Shadow public abstract void reset();
@Inject(at = @At("HEAD"), method = "render", cancellable = true)
private void render(MatrixStack stack, int delta, CallbackInfo ci) {
if (!HudConfigStorage.General.VANILLA_HUD.config.getBooleanValue()) {
ci.cancel();
}
}
@Override
public boolean isOver(double mouseX, double mouseY) {
double minX = 4 - (4 * getChatScale());
double maxX = 4 + (getWidth() + 4 * getChatScale());
@Inject(at = @At("HEAD"), method = "getText", cancellable = true)
private void getTextAt(double x, double y, CallbackInfoReturnable<Style> ci) {
// Set new text value from cooooolness
if (!HudConfigStorage.General.VANILLA_HUD.config.getBooleanValue()) {
ci.setReturnValue(WindowManager.getInstance().getText(x, y));
return;
}
// Prioritize main first
// TODO figure out how to use intrinsic
if (this.isChatFocused() && !this.client.options.hudHidden && !isChatHidden()) {
double d = x - 2.0D;
double e = (double) this.client.getWindow().getScaledHeight() - y - 40.0D;
d = MathHelper.floor(d / this.getChatScale());
e =
MathHelper.floor(
e
/ (this.getChatScale()
* (this.client.options.chatLineSpacing + 1.0D)));
if (d >= 0.0D && e >= 0.0D) {
int i = Math.min(getVisibleLineCount(), this.visibleMessages.size());
if (d
<= (double)
MathHelper.floor((double) this.getWidth() / this.getChatScale())) {
Objects.requireNonNull(this.client.textRenderer);
if (e < (double) (9 * i + i)) {
Objects.requireNonNull(this.client.textRenderer);
int j = (int) (e / 9.0D + (double) this.scrolledLines);
if (j >= 0 && j < this.visibleMessages.size()) {
ChatHudLine<OrderedText> chatHudLine = this.visibleMessages.get(j);
ci.setReturnValue(
this.client
.textRenderer
.getTextHandler()
.getStyleAt(chatHudLine.getText(), (int) d));
return;
}
}
}
}
}
ci.setReturnValue(WindowManager.getInstance().getText(x, y));
}
public void setTab(AbstractChatTab tab) {
this.tab = tab;
this.messages.clear();
this.visibleMessages.clear();
List<HudChatMessage> messages = HudChatMessageHolder.getInstance().getMessages();
for (int i = messages.size() - 1; i >= 0; i--) {
addMessage(messages.get(i));
}
this.reset();
mouseY = (client.getWindow().getScaledHeight() - mouseY - 40) / getChatScale();
return mouseX >= minX && mouseX < maxX && mouseY >= 0 && mouseY < getHeight();
}
}
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.mixin;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
import io.github.darkkronicle.advancedchathud.ResolutionEventHandler;
import net.minecraft.client.MinecraftClient;
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;
@Mixin(MinecraftClient.class)
public class MixinMinecraftClient {
@Inject(method = "onResolutionChanged", at = @At("HEAD"))
private void onResChange(CallbackInfo ci) {
for (ResolutionEventHandler handler : ResolutionEventHandler.ON_RESOLUTION_CHANGE) {
handler.onResolutionChange();
}
}
}
@@ -7,7 +7,7 @@
*/
package io.github.darkkronicle.advancedchathud.tabs;
import io.github.darkkronicle.advancedchatcore.util.ColorUtil;
import io.github.darkkronicle.advancedchatcore.util.Color;
import java.util.UUID;
import lombok.Data;
import net.fabricmc.api.EnvType;
@@ -21,24 +21,24 @@ 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;
protected String abbreviation;
protected Color mainColor;
protected Color borderColor;
protected Color innerColor;
protected UUID uuid;
private int unread = 0;
protected boolean showUnread;
public AbstractChatTab(
String name,
String abreviation,
ColorUtil.SimpleColor mainColor,
ColorUtil.SimpleColor borderColor,
ColorUtil.SimpleColor innerColor,
String abbreviation,
Color mainColor,
Color borderColor,
Color innerColor,
boolean showUnread,
UUID uuid) {
this.name = name;
this.abreviation = abreviation;
this.abbreviation = abbreviation;
this.mainColor = mainColor;
this.showUnread = showUnread;
this.innerColor = innerColor;
@@ -0,0 +1,173 @@
/*
* Copyright (C) 2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.tabs;
import io.github.darkkronicle.Konstruct.NodeException;
import io.github.darkkronicle.Konstruct.functions.Function;
import io.github.darkkronicle.Konstruct.functions.ObjectFunction;
import io.github.darkkronicle.Konstruct.nodes.Node;
import io.github.darkkronicle.Konstruct.parser.IntRange;
import io.github.darkkronicle.Konstruct.parser.ParseContext;
import io.github.darkkronicle.Konstruct.parser.Result;
import io.github.darkkronicle.Konstruct.type.IntegerObject;
import io.github.darkkronicle.Konstruct.type.KonstructObject;
import io.github.darkkronicle.Konstruct.type.NullObject;
import io.github.darkkronicle.advancedchatcore.util.Color;
import io.github.darkkronicle.advancedchathud.config.ChatTab;
import lombok.Getter;
import java.util.List;
import java.util.Optional;
public class ChatTabObject extends KonstructObject<ChatTabObject> {
private static abstract class ColorFunction implements ObjectFunction<ChatTabObject> {
@Override
public Result parse(ParseContext context, ChatTabObject self, List<Node> input) {
Result r1 = Function.parseArgument(context, input, 0);
IntegerObject c1 = new IntegerObject(IntegerObject.fromObject(r1.getContent()).orElse(0));
Result r2 = Function.parseArgument(context, input, 1);
IntegerObject c2 = new IntegerObject(IntegerObject.fromObject(r2.getContent()).orElse(0));
Result r3 = Function.parseArgument(context, input, 2);
IntegerObject c3 = new IntegerObject(IntegerObject.fromObject(r3.getContent()).orElse(0));
Result r4 = Function.parseArgument(context, input, 3);
IntegerObject c4 = new IntegerObject(IntegerObject.fromObject(r4.getContent()).orElse(0));
setColor(self, new Color(c1.getValue(), c2.getValue(), c3.getValue(), c4.getValue()));
return Result.success(new NullObject());
}
@Override
public IntRange getArgumentCount() {
return IntRange.of(4);
}
public abstract void setColor(ChatTabObject tabObject, Color color);
}
private final static List<ObjectFunction<ChatTabObject>> FUNCTIONS = List.of(
new ColorFunction() {
@Override
public void setColor(ChatTabObject tabObj, Color color) {
tabObj.tab.setMainColor(color);
}
@Override
public String getName() {
return "setMainColor";
}
},
new ColorFunction() {
@Override
public void setColor(ChatTabObject tabObj, Color color) {
tabObj.tab.setBorderColor(color);
}
@Override
public String getName() {
return "setBorderColor";
}
},
new ColorFunction() {
@Override
public void setColor(ChatTabObject tabObj, Color color) {
tabObj.tab.setInnerColor(color);
}
@Override
public String getName() {
return "setInnerColor";
}
},
new ObjectFunction<>() {
@Override
public Result parse(ParseContext context, ChatTabObject self, List<Node> input) {
Result s1 = Function.parseArgument(context, input, 0);
self.tab.setAbbreviation(s1.getContent().getString());
return Result.success((KonstructObject<?>) null);
}
@Override
public String getName() {
return "setAbbreviation";
}
@Override
public IntRange getArgumentCount() {
return IntRange.of(1);
}
},
new ObjectFunction<>() {
@Override
public Result parse(ParseContext context, ChatTabObject self, List<Node> input) {
Result s1 = Function.parseArgument(context, input, 0);
self.tab.setForward(s1.getContent().getBoolean());
return Result.success((KonstructObject<?>) null);
}
@Override
public String getName() {
return "setForward";
}
@Override
public IntRange getArgumentCount() {
return IntRange.of(1);
}
},
new ObjectFunction<>() {
@Override
public Result parse(ParseContext context, ChatTabObject self, List<Node> input) {
Result s1 = Function.parseArgument(context, input, 0);
Optional<Function> function = context.getFunction(s1.getContent().getString());
if (function.isEmpty()) {
throw new NodeException("Function " + s1.getContent().getString() + " does not exist!");
}
if (!function.get().getArgumentCount().equals(IntRange.of(2))) {
throw new NodeException("Function " + function.get() + " has to have 2 arguments!");
}
self.tab.setFunction(function.get());
return Result.success(new NullObject());
}
@Override
public String getName() {
return "setShouldAdd";
}
@Override
public IntRange getArgumentCount() {
return IntRange.of(1);
}
}
);
@Getter
private final CustomChatTab tab;
public ChatTabObject(CustomChatTab tab) {
super(FUNCTIONS);
this.tab = tab;
}
@Override
public String getString() {
return "chattab-" + tab.toString();
}
@Override
public String getTypeName() {
return "chattab";
}
}
@@ -7,52 +7,100 @@
*/
package io.github.darkkronicle.advancedchathud.tabs;
import io.github.darkkronicle.advancedchatcore.util.FluidText;
import io.github.darkkronicle.Konstruct.functions.Function;
import io.github.darkkronicle.Konstruct.nodes.LiteralNode;
import io.github.darkkronicle.Konstruct.nodes.Node;
import io.github.darkkronicle.Konstruct.parser.*;
import io.github.darkkronicle.Konstruct.type.BooleanObject;
import io.github.darkkronicle.advancedchatcore.util.SearchUtils;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
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 lombok.Setter;
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 List<Match> matches;
@Getter private boolean forward;
@Setter
@Getter
private boolean forward;
@Getter private String startingMessage;
@Getter
@Setter
private String startingMessage;
@Getter private ChatTab storage;
@Getter
@Setter
private ChatTab tab;
public CustomChatTab(ChatTab storage) {
@Setter
private Function function;
public CustomChatTab(ChatTab tab) {
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(),
storage.getUuid());
this.storage = storage;
this.matches = new ArrayList<>(storage.getMatches());
this.forward = storage.getForward().config.getBooleanValue();
this.startingMessage = storage.getStartingMessage().config.getStringValue();
tab.getName().config.getStringValue(),
tab.getAbbreviation().config.getStringValue(),
tab.getMainColor().config.get(),
tab.getBorderColor().config.get(),
tab.getInnerColor().config.get(),
tab.getShowUnread().config.getBooleanValue(),
tab.getUuid()
);
this.tab = tab;
this.matches = new ArrayList<>(tab.getMatches());
this.forward = tab.getForward().config.getBooleanValue();
this.startingMessage = tab.getStartingMessage().config.getStringValue();
setDefaultFunction();
}
public void setDefaultFunction() {
function = new Function() {
@Override
public Result parse(ParseContext context, List<Node> input) {
CustomChatTab self = ((ChatTabObject) Function.parseArgument(context, input, 0).getContent()).getTab();
String search = Function.parseArgument(context, input, 1).getContent().getString();
for (Match m : self.matches) {
if (SearchUtils.isMatch(search, m.getPattern(), m.getFindType())) {
return Result.success(new BooleanObject(true));
}
}
return Result.success(new BooleanObject(false));
}
@Override
public IntRange getArgumentCount() {
return IntRange.of(2);
}
};
}
@Override
public boolean shouldAdd(Text text) {
FluidText newText = new FluidText(text);
String search = newText.getString();
for (Match m : matches) {
if (SearchUtils.isMatch(search, m.getPattern(), m.getFindType())) {
return true;
String search = text.getString();
ParseContext context = AdvancedChatHud.MAIN_CHAT_TAB.getProcessor().createContext();
Result result = function.parse(context, List.of(new Node() {
@Override
public Result parse(ParseContext context) {
return Result.success(new ChatTabObject(CustomChatTab.this));
}
}
return false;
@Override
public List<Node> getChildren() {
return new ArrayList<>(0);
}
@Override
public void addChild(Node node) {
}
}, new LiteralNode(search)));
return result.getContent().getBoolean();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 DarkKronicle
* Copyright (C) 2021-2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -7,14 +7,30 @@
*/
package io.github.darkkronicle.advancedchathud.tabs;
import com.google.gson.JsonArray;
import fi.dy.masa.malilib.util.FileUtils;
import io.github.darkkronicle.Konstruct.NodeException;
import io.github.darkkronicle.Konstruct.functions.Function;
import io.github.darkkronicle.Konstruct.nodes.Node;
import io.github.darkkronicle.Konstruct.parser.*;
import io.github.darkkronicle.Konstruct.type.NullObject;
import io.github.darkkronicle.advancedchatcore.konstruct.AdvancedChatKonstruct;
import io.github.darkkronicle.advancedchathud.AdvancedChatHud;
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 java.util.UUID;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import io.github.darkkronicle.advancedchathud.gui.WindowManager;
import io.github.darkkronicle.advancedchathud.util.FileUtil;
import lombok.Getter;
import net.minecraft.text.Text;
import org.apache.logging.log4j.Level;
/** Main chat tab that manages other chat tabs. */
public class MainChatTab extends AbstractChatTab {
@@ -23,27 +39,41 @@ public class MainChatTab extends AbstractChatTab {
@Getter private ArrayList<CustomChatTab> customChatTabs = new ArrayList<>();
public static boolean LOAD_ALL_JSON = false;
@Getter
private NodeProcessor processor = null;
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.getMainColor().config.get(),
HudConfigStorage.MAIN_TAB.getBorderColor().config.get(),
HudConfigStorage.MAIN_TAB.getInnerColor().config.get(),
HudConfigStorage.MAIN_TAB.getShowUnread().config.getBooleanValue(),
HudConfigStorage.MAIN_TAB.getUuid());
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.abbreviation = HudConfigStorage.MAIN_TAB.getAbbreviation().config.getStringValue();
this.mainColor = HudConfigStorage.MAIN_TAB.getMainColor().config.get();
this.innerColor = HudConfigStorage.MAIN_TAB.getInnerColor().config.get();
this.borderColor = HudConfigStorage.MAIN_TAB.getBorderColor().config.get();
this.showUnread = HudConfigStorage.MAIN_TAB.getShowUnread().config.getBooleanValue();
this.uuid = HudConfigStorage.MAIN_TAB.getUuid();
}
public CustomChatTab getCustom(String name) {
for (CustomChatTab tab : customChatTabs) {
if (tab.getName().equals(name)) {
return tab;
}
}
return null;
}
@Override
public boolean shouldAdd(Text text) {
return true;
@@ -51,14 +81,52 @@ public class MainChatTab extends AbstractChatTab {
/** Method used for loading in tabs from the config. */
public void setUpTabs() {
JsonArray windows = null;
if (LOAD_ALL_JSON) {
windows = WindowManager.getInstance().saveJson();
}
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);
}
customChatTabs.sort((customTab1, customTab2) -> {
Comparator<CustomChatTab> comparator = Comparator.comparingInt(tab -> tab.getTab().getOrder().config.getIntegerValue());
int num = comparator.compare(customTab1, customTab2);
if (num != 0) {
return num;
}
return customTab1.getTab().getName().config.getStringValue().compareTo(customTab2.getTab().getName().config.getStringValue());
});
allChatTabs.addAll(customChatTabs);
Path konstructDir = FileUtils.getConfigDirectory().toPath().resolve("advancedchat").resolve("konstructTabs");
konstructDir.toFile().mkdirs();
processor = AdvancedChatKonstruct.getInstance().copy();
processor.addFunction("getTab", new Function() {
@Override
public Result parse(ParseContext context, List<Node> input) {
CustomChatTab tab = getCustom(Function.parseArgument(context, input, 0).getContent().getString());
if (tab == null) {
return Result.success(new NullObject());
}
return Result.success(new ChatTabObject(tab));
}
@Override
public IntRange getArgumentCount() {
return IntRange.of(1);
}
});
Optional<List<Path>> files = FileUtil.getFilesWithExtensionCaught(konstructDir, ".knst");
if (files.isPresent() && files.get().size() != 0) {
this.loadKonstruct(files.get());
}
for (HudChatMessage message : HudChatMessageHolder.getInstance().getMessages()) {
ArrayList<AbstractChatTab> tabs = new ArrayList<>();
for (AbstractChatTab t : allChatTabs) {
@@ -69,6 +137,27 @@ public class MainChatTab extends AbstractChatTab {
message.setTabs(tabs);
}
this.refreshOptions();
if (windows != null) {
WindowManager.getInstance().loadFromJson(windows);
}
}
public void loadKonstruct(List<Path> paths) {
for (Path path : paths) {
try {
loadKonstruct(path);
} catch (IOException e) {
AdvancedChatHud.LOGGER.log(Level.ERROR, "Error reading " + path + ".", e);
} catch (NodeException e) {
AdvancedChatHud.LOGGER.log(Level.ERROR, "Error setting up konstruct script " + path, e);
}
}
}
private void loadKonstruct(Path path) throws IOException, NodeException {
String contents = String.join("\n", Files.readAllLines(path)).replaceAll("\r", "");
Node node = AdvancedChatKonstruct.getInstance().getNode(contents);
processor.parse(node);
}
public AbstractChatTab fromUUID(UUID uuid) {
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2022 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.util;
import lombok.experimental.UtilityClass;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@UtilityClass
public class FileUtil {
// https://mkyong.com/java/how-to-find-files-with-certain-extension-only/
public List<Path> getFilesWithExtension(Path directory, String extension) throws IOException {
if (!directory.toFile().isDirectory()) {
throw new IllegalArgumentException("Directory has to be directory!");
}
List<Path> paths;
try (Stream<Path> walk = Files.walk(directory)) {
paths = walk
.filter(p -> !Files.isDirectory(p))
.filter(p -> p.toString().endsWith(extension))
.collect(Collectors.toList());
}
return paths;
}
public Optional<List<Path>> getFilesWithExtensionCaught(Path directory, String extension) {
try {
return Optional.of(getFilesWithExtension(directory, extension));
} catch (IOException e) {
return Optional.empty();
}
}
}
@@ -0,0 +1,25 @@
package io.github.darkkronicle.advancedchathud.util;
import com.mojang.blaze3d.platform.GlStateManager;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class ScissorUtil {
private ScissorUtil() {}
public static void applyScissorBox(int x, int y, int width, int height) {
GlStateManager._enableScissorTest();
GlStateManager._scissorBox(x, y, width, height);
}
public static void applyScissor(int x1, int y1, int x2, int y2) {
GlStateManager._enableScissorTest();
GlStateManager._scissorBox(x1, y1, x2 - x1, y2 - y1);
}
public static void resetScissor() {
GlStateManager._disableScissorTest();
}
}
@@ -1,25 +0,0 @@
/*
* Copyright (C) 2021 DarkKronicle
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package io.github.darkkronicle.advancedchathud.util;
public class TextUtil {
private static final char[] SUPERSCRIPTS =
new char[] {
'\u2070', '\u00B9', '\u00B2', '\u00B3', '\u2074', '\u2075', '\u2076', '\u2077',
'\u2078', '\u2079'
};
public static String toSuperscript(int num) {
StringBuilder sb = new StringBuilder();
do {
sb.append(SUPERSCRIPTS[num % 10]);
} while ((num /= 10) > 0);
return sb.reverse().toString();
}
}
@@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"MixinChatHud"
"MixinChatHud",
"MixinMinecraftClient"
],
"injectors": {
"defaultRequire": 1
@@ -0,0 +1,14 @@
def staffShouldAdd(tab, text) {
if (isMatch('coolserver.net', server, 'literal') {
tab.setHidden(false);
return(isMatch('''^\[StaffChat\]''', text, 'regex'))
};
tab.setHidden(true);
false
};
# Gets tab with the name "staff"
staff = getTab('staff')
# Set the function via name reference
staff.setShouldAdd('staffShouldAdd')
@@ -2,14 +2,16 @@
"advancedchat.config.yes": "Correct!",
"advancedchathud.gui.button.addtab": "New Chat Tab",
"advancedchathud.tab.general": "§9Chat HUD",
"advancedchathud.gui.button.reload": "Reload Konstruct Tabs",
"advancedchathud.tab.advancedchathud": "§9HUD",
"advancedchathud.tab.general": "§7Chat HUD",
"advancedchathud.tab.tabs": "§bChat Tabs",
"advancedchathud.config.general.timeformat": "Time Format",
"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.matches": "§6Matches",
"advancedchathud.gui.button.back": "Back",
"advancedchathud.gui.button.export": "Export",
"advancedchathud.gui.button.addmatch": "§aAdd Match",
@@ -74,12 +76,22 @@
"advancedchathud.config.general.info.showtime": "Whether or not the §6time §ris displayed in the §9Chat HUD §r \nThe format can be configured in §7General§r",
"advancedchathud.config.general.storedlines": "Stored Lines",
"advancedchathud.config.general.info.storedlines": "The §6maximum§r amount of lines stored in the §9Chat HUD§r \n§7Excessively large values may result in out-of-memory errors!",
"advancedchathud.config.general.righttabbuttons": "Right Tab Buttons",
"advancedchathud.config.general.info.righttabbuttons": "Whether or not §6tab buttons§r will display on the right side",
"advancedchathud.config.general.renderinother": "Render Chat in Other GUI",
"advancedchathud.config.general.info.renderinother": "Whether or not §6tab buttons§r will display on the right side",
"advancedchathud.config.general.scrolltime": "Scroll Time",
"advancedchathud.config.general.info.scrolltime": "Time it takes in milliseconds to complete the scroll animation",
"advancedchathud.config.general.scrolltype": "Scroll Type",
"advancedchathud.config.general.info.scrolltype": "The type of animation for scrolling",
"advancedchathud.config.general.persistenttext": "Persistent Text",
"advancedchathud.config.general.info.persistenttext": "Whether or not messages that are §6typed but not sent§r are kept after closing the §9Chat Box",
"advancedchathud.config.general.moretext": "Extended Text Limit",
"advancedchathud.config.general.info.moretext": "Whether or not messages that are §6over the 256 character limit§r are broken into multiple chat messages",
"advancedchathud.config.general.sendtocurrenttab": "Always Send Message to Focused Tab",
"advancedchathud.config.general.info.sendtocurrenttab": "Whether or not messages §6sent by you§r are displayed in the currently focused tab, §6regardless of the chat filter",
"advancedchathud.config.general.changeStartMessage": "Change Start Message",
"advancedchathud.config.general.info.changeStartMessage": "Whether or not to change the start message when you switch chat windows",
"advancedchathud.config.tabmenu.configure": "§bConfigure",
"advancedchathud.config.tabmenu.remove": "§cDelete",
@@ -88,6 +100,8 @@
"advancedchathud.gui.button.import": "Import Tab",
"advancedchathud.config.tab.name": "Tab Name",
"advancedchathud.config.tab.info.name": "What the tab shows up as §6in the config \n§7§oIt is good practice to name your tabs meaningfully!",
"advancedchathud.config.tab.order": "Order",
"advancedchathud.config.tab.info.order": "The number that sorts the tabs. If this number is lower, it will be higher on the list.",
"advancedchathud.config.tab.startingmessage": "Starting Message",
"advancedchathud.config.tab.info.startingmessage": "What text shows up §6when the tab is focused§r",
"advancedchathud.config.tab.abbreviation": "Tab HUD Abbreviation",
@@ -108,9 +122,35 @@
"advancedchathud.config.tab.showunread": "Show Unread Messages",
"advancedchathud.config.tab.info.showunread": "Whether or not the number of §6unread messages§r are displayed for the §bchat tab§r",
"advancedchathud.windowconfig.x": "Window X",
"advancedchathud.windowconfig.info.x": "The X value for the window",
"advancedchathud.windowconfig.y": "Window Y",
"advancedchathud.windowconfig.info.y": "The Y value for the window",
"advancedchathud.windowconfig.width": "Window Width",
"advancedchathud.windowconfig.info.width": "The width value for the window",
"advancedchathud.windowconfig.height": "Window Height",
"advancedchathud.windowconfig.info.height": "The height value for the window",
"advancedchathud.windowconfig.renderright": "Align Right",
"advancedchathud.windowconfig.info.renderright": "If the text should render aligned to the right side",
"advancedchathud.windowconfig.rendertopfirst": "Render Top First",
"advancedchathud.windowconfig.info.rendertopfirst": "Renders messages top down",
"advancedchathud.windowconfig.minimalist": "Minimalist Mode",
"advancedchathud.windowconfig.info.minimalist": "Enables a less cluttered window design. When active moving will not be possible.\nThe right click context menu can toggle this",
"advancedchat.config.findtype.literal": "§6Literal",
"advancedchat.config.findtype.upperlower": "§eUpper-Lower",
"advancedchat.config.findtype.regex": "§bRegEx",
"advancedchat.config.findtype.all": "§dAll"
"advancedchat.config.findtype.all": "§dAll",
"advancedchathud.context.copied": "§aCopied",
"advancedchathud.context.copy": "Copy",
"advancedchathud.context.delete": "Delete",
"advancedchathud.context.minimalist": "Toggle Minimalist",
"advancedchathud.context.removeallwindows": "Remove All Windows",
"advancedchathud.context.clearallmessages": "Clear All Messages",
"advancedchathud.context.duplicatewindow": "Duplicate Window",
"advancedchathud.context.configurewindow": "Configure Window",
"advancedchathud.context.messageowner": "Reply"
}
@@ -0,0 +1,156 @@
{
"advancedchat.config.yes": "正确!",
"advancedchathud.gui.button.addtab": "新建聊天选项卡",
"advancedchathud.gui.button.reload": "重新加载构造标签栏",
"advancedchathud.tab.advancedchathud": "§9HUD§r",
"advancedchathud.tab.general": "§7聊天HUD§r",
"advancedchathud.tab.tabs": "§b聊天选项卡§r",
"advancedchathud.config.general.timeformat": "时间格式",
"advancedchathud.config.general.info.timeformat": "如果同时为§9聊天 HUD§r和§a聊天日志§r启用了显示时间,则§6显示时间§r。\n有关格式请参阅§6简单日期格式§r类。",
"advancedchathud.config.general.chatheads": "显示聊天头像",
"advancedchathud.config.general.info.chatheads": "信息发送人的§6头像§r是否显示在其信息旁边",
"advancedchathud.gui.button.matches": "§6匹配§r",
"advancedchathud.gui.button.back": "返回",
"advancedchathud.gui.button.export": "导出",
"advancedchathud.gui.button.addmatch": "§a添加匹配项§r",
"advancedchathud.config.match.remove": "§c删除§r",
"advancedchathud.config.match.screen.name": "匹配",
"advancedchathud.config.general.vanillahud": "移除原版聊天HUD",
"advancedchathud.config.general.info.vanillahud": "启用§6原版聊天HUD§r,其作用主要类似于§9聊天窗口§r.\n§6原版聊天HUD§r可以使用§9聊天选项卡§r 如果您单击它然后更改选项卡",
"advancedchathud.config.general.width": "默认聊天宽度",
"advancedchathud.config.general.info.width": "§9聊天HUD§r的§6宽度§r\n覆盖原版聊天宽度!",
"advancedchathud.config.general.height": "默认聊天高度",
"advancedchathud.config.general.info.height": "§9聊天HUD§r的§6高度§r\n覆盖原版聊天高度!",
"advancedchathud.config.general.showtabs": "显示聊天标签页",
"advancedchathud.config.general.info.showtabs": "§b聊天选项卡§r是否在§9聊天HUD§r中的§6边框§r上可见",
"advancedchathud.config.general.leftpad": "左侧聊天框间距",
"advancedchathud.config.general.info.leftpad": "聊天框的§6左侧§r与§6文本开始§r的位置之间的间距",
"advancedchathud.config.general.rightpad": "右侧聊天框间距",
"advancedchathud.config.general.info.rightpad": "聊天框的§6右侧§r与§6文本结束§r的位置之间的间距",
"advancedchathud.config.general.bottompad": "下侧聊天框间距",
"advancedchathud.config.general.info.bottompad": "聊天框的§6底侧§r与§6最新消息§r之间的间距",
"advancedchathud.config.general.toppad": "上侧聊天框间距",
"advancedchathud.config.general.info.toppad": "聊天框的§6顶侧与§6旧消息§r之间的间距量",
"advancedchathud.config.general.tabsidechars": "最大缩写长度",
"advancedchathud.config.general.info.tabsidechars": "用于§b聊天选项卡§r中的§6缩写§r的最多字符数\n影响聊天选项卡的外观§6边框§r和§9聊天HUD§r",
"advancedchathud.config.general.visibility": "聊天可见性",
"advancedchathud.config.general.info.visibility": "§9聊天HUD§r的显示模式\n§6原版§r-§9聊天HUD§r渲染就像§6原版\n§a总是§r-渲染§9聊天HUD§6在任何时候\n§c仅对焦§r-渲染§9聊天HUD§r当§6聊天框§r被打开",
"advancedchathud.config.visibility.vanilla": "§6原版§r",
"advancedchathud.config.visibility.always": "§a总是§r",
"advancedchathud.config.visibility.focus_only": "§c仅对焦§r",
"advancedchathud.config.general.linespace": "行距",
"advancedchathud.config.general.info.linespace": "聊天栏的§6行距§r(以像素为单位)",
"advancedchathud.config.general.x": "默认聊天 X",
"advancedchathud.config.general.info.x": "聊天框的§6X坐标§r,从屏幕§6左下角开始§r",
"advancedchathud.config.general.y": "默认聊天 Y",
"advancedchathud.config.general.info.y": "聊天框的§6Y坐标§r,从屏幕§6左下角开始§r",
"advancedchathud.config.general.messagespace": "在消息之间的间距",
"advancedchathud.config.general.info.messagespace": "§6单个消息§r之间间距",
"advancedchathud.config.general.chatscale": "聊天扩展",
"advancedchathud.config.general.info.chatscale": "聊天框的文本§6内部§r的§6大小§r。不影响§9聊天 HUD§r的大小!",
"advancedchathud.config.general.fadetime": "淡入淡出速度",
"advancedchathud.config.general.info.fadetime": "消息§6淡出§r的速度",
"advancedchathud.config.general.fadestart": "淡进淡出的时间",
"advancedchathud.config.general.info.fadestart": "在新收到的消息开始消失之前的§6刻数§r",
"advancedchathud.config.general.fadetype": "淡入淡出样式",
"advancedchathud.config.general.info.fadetype": "用于淡入淡出动画的§6缓动函数§r\n原版使用§6线性§r缓动",
"advancedchat.config.easing.linear": "§c线性缓动§r",
"advancedchat.config.easing.sine": "§6正弦缓动§r",
"advancedchat.config.easing.quad": "§e二次缓动§r",
"advancedchat.config.easing.quart": "§a四次缓动§r",
"advancedchat.config.easing.circ": "§b曲线缓动§r",
"advancedchathud.config.general.hudbackgroundcolor": "HUD背景颜色",
"advancedchathud.config.general.info.hudbackgroundcolor": "§9聊天HUD§r的§6背景颜色§r",
"advancedchathud.config.general.emptytextcolor": "空文本颜色",
"advancedchathud.config.general.info.emptytextcolor": "没有格式的文本的颜色(例如使用 §6§r格式化的文本)",
"advancedchathud.config.general.hudlinetype": "背景行样式",
"advancedchathud.config.general.info.hudlinetype": "§6未聚焦§r的§9聊天HUD§r的§6背景§r如何适应消息\n§6完整§r-使背景适合§9聊天HUD§r的§6宽度§r\n§b紧凑§r-使背景适合每§6行§r的长度",
"advancedchathud.config.hudlinetype.full": "§6完整§r",
"advancedchathud.config.hudlinetype.compact": "§b紧凑§r",
"advancedchathud.config.general.alternatelines": "条纹化消息",
"advancedchathud.config.general.info.alternatelines": "是否对其他§6每条消息§r的背景进行不同的颜色以创建§6条纹§r效果\n§7有助于区分消息§r",
"advancedchathud.config.general.showtime": "显示时间",
"advancedchathud.config.general.info.showtime": "§6时间§r是否显示在§9聊天HUD§r中\n格式可以在§7常规§r中配置",
"advancedchathud.config.general.storedlines": "存储行",
"advancedchathud.config.general.info.storedlines": "§9聊天HUD§r中存储的§6最大§r行数\n§7值过大可能会导致内存不足错误!§r",
"advancedchathud.config.general.righttabbuttons": "右标签按钮",
"advancedchathud.config.general.info.righttabbuttons": "§6选项卡按钮§r是否显示在右侧",
"advancedchathud.config.general.renderinother": "在其他GUI中呈现聊天",
"advancedchathud.config.general.info.renderinother": "§6选项卡按钮§r是否显示在右侧",
"advancedchathud.config.general.scrolltime": "滚动时间",
"advancedchathud.config.general.info.scrolltime": "完成滚动动画所需的时间(以毫秒为单位)",
"advancedchathud.config.general.scrolltype": "滚动类型",
"advancedchathud.config.general.info.scrolltype": "滚动动画的类型",
"advancedchathud.config.general.persistenttext": "保留文本",
"advancedchathud.config.general.info.persistenttext": "关闭§9聊天框§r后是否保留§6已输入但未发送§r的消息",
"advancedchathud.config.general.moretext": "扩展文本限制",
"advancedchathud.config.general.info.moretext": "超过§6256个字符§r限制的消息分为多个聊天消息",
"advancedchathud.config.general.sendtocurrenttab": "始终将消息发送到焦点选项卡",
"advancedchathud.config.general.info.sendtocurrenttab": "§6您发送的消息§r是否显示在当前焦点选项卡中,§6无论聊天过滤器是什么§r",
"advancedchathud.config.general.changeStartMessage": "更改开始消息",
"advancedchathud.config.general.info.changeStartMessage": "切换聊天窗口时是否更改开始消息",
"advancedchathud.config.tabmenu.configure": "§b配置§r",
"advancedchathud.config.tabmenu.remove": "§c删除§r",
"advancedchathud.config.tabdescription": "§7名称§r: <name> \n§a查找字符串§r: <find>\n§e查找类型§r: <findtype>",
"advancedchathud.gui.button.import": "导入选项卡",
"advancedchathud.config.tab.name": "选项卡名称",
"advancedchathud.config.tab.info.name": "选项卡在§6配置§r中的显示方式\n§7§o有意义地命名选项卡是一种很好的做法!§r",
"advancedchathud.config.tab.order": "顺序",
"advancedchathud.config.tab.info.order": "对选项卡进行排序的数字,如果此数字较低,则列表中将较高。",
"advancedchathud.config.tab.startingmessage": "起始消息",
"advancedchathud.config.tab.info.startingmessage": "§6选项卡聚焦时§r显示哪些文本",
"advancedchathud.config.tab.abbreviation": "选项卡 HUD 缩写",
"advancedchathud.config.tab.info.abbreviation": "如果在§9聊天HUD§r设置下启用了§6显示聊天选项卡§r,选项卡在§9聊天HUD§6一侧§r显示的内容",
"advancedchathud.config.tab.forward": "将消息转发到主消息",
"advancedchathud.config.tab.info.forward": "发送到此聊天选项卡的消息是否也显示在§6主聊天选项卡§r中",
"advancedchathud.config.tab.forwardtoggle": "%s",
"advancedchathud.config.tab.findstring": "查找字符串",
"advancedchathud.config.tab.info.findstring": "将被§6剪切§r并§6转移到此选项卡§r的字符串",
"advancedchathud.config.tab.findtype": "查找类型",
"advancedchathud.config.tab.info.findtype": "如何找到匹配项\n§6文字§r-§6完全匹配§r字符串\n§e比较§r-像§6字符, §r但不§6区分大小写\n§b正则§r-将字符串解析为§6正则表达式\n§d所有§r-将§6所有§r文本传递到选项卡,无论要查找的字符串是什么",
"advancedchathud.config.tab.maincolor": "主题色",
"advancedchathud.config.tab.info.maincolor": "§b聊天选项卡§r的§6主题色§r",
"advancedchathud.config.tab.bordercolor": "边框颜色",
"advancedchathud.config.tab.info.bordercolor": "§b聊天选项卡§6边框§r的颜色",
"advancedchathud.config.tab.innercolor": "背景颜色",
"advancedchathud.config.tab.info.innercolor": "§b聊天选项卡§6背景§r的颜色",
"advancedchathud.config.tab.showunread": "显示未读信息",
"advancedchathud.config.tab.info.showunread": "是否为§b聊天选项卡§r显示§6未读消息数§r",
"advancedchathud.windowconfig.x": "窗口 X",
"advancedchathud.windowconfig.info.x": "窗口的 X 值",
"advancedchathud.windowconfig.y": "窗口 Y",
"advancedchathud.windowconfig.info.y": "窗口的 Y 值",
"advancedchathud.windowconfig.width": "窗口宽度",
"advancedchathud.windowconfig.info.width": "窗口的宽度值",
"advancedchathud.windowconfig.height": "窗口高度",
"advancedchathud.windowconfig.info.height": "窗口的高度值",
"advancedchathud.windowconfig.renderright": "右对齐",
"advancedchathud.windowconfig.info.renderright": "文本应呈现与右侧对齐",
"advancedchathud.windowconfig.rendertopfirst": "渲染顶部首先",
"advancedchathud.windowconfig.info.rendertopfirst": "自上而下呈现消息",
"advancedchathud.windowconfig.minimalist": "极简模式",
"advancedchathud.windowconfig.info.minimalist": "启用不那么杂乱的窗口设计。当主动移动是不可能的。\n右键单击context menu可以切换此选项。",
"advancedchat.config.findtype.literal": "§6文字§r",
"advancedchat.config.findtype.upperlower": "§e比较§r",
"advancedchat.config.findtype.regex": "§b正则§r",
"advancedchat.config.findtype.all": "§d所有§r",
"advancedchathud.context.copied": "§a复制§r",
"advancedchathud.context.copy": "复制",
"advancedchathud.context.delete": "删除",
"advancedchathud.context.minimalist": "切换极简模式",
"advancedchathud.context.removeallwindows": "删除所有窗口",
"advancedchathud.context.clearallmessages": "清除所有信息",
"advancedchathud.context.duplicatewindow": "复制窗口",
"advancedchathud.context.configurewindow": "配置窗口",
"advancedchathud.context.messageowner": "回复"
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

+4 -4
View File
@@ -24,11 +24,11 @@
"advancedchathud.mixins.json"
],
"depends": {
"fabricloader": ">=0.8.9+build.204",
"fabricloader": ">=0.14.18",
"fabric": "*",
"minecraft": ">=1.17.0",
"malilib": ">=0.10.0-dev.20",
"advancedchatcore": ">=1.0.0"
"minecraft": ">=1.19.4",
"malilib": ">=0.15.2",
"advancedchatcore": ">=1.5.10-1.19"
},
"custom": {
"acmodule": true,