|
|
|
@@ -17,6 +17,7 @@ import java.util.List;
|
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
import net.fabricmc.api.EnvType;
|
|
|
|
|
import net.fabricmc.api.Environment;
|
|
|
|
|
import net.minecraft.util.Util;
|
|
|
|
|
import net.minecraft.util.math.BlockPos;
|
|
|
|
|
import net.minecraft.text.Text;
|
|
|
|
|
import net.minecraft.client.font.TextRenderer;
|
|
|
|
@@ -38,6 +39,9 @@ import net.minecraft.text.StringVisitable;
|
|
|
|
|
*/
|
|
|
|
|
public final class AutoStoreGui
|
|
|
|
|
extends Screen {
|
|
|
|
|
// ---- 外部链接 ----
|
|
|
|
|
private static final String GIT_REPO_URL = "https://git.bgjq.top/Lyizai/AutoStore/";
|
|
|
|
|
private static final String HOMEPAGE_URL = "https://8w.bgjq.top/";
|
|
|
|
|
private final AutoStoreModClient mod;
|
|
|
|
|
private final ExpansionConfig config;
|
|
|
|
|
private final ExpansionController controller;
|
|
|
|
@@ -89,7 +93,7 @@ extends Screen {
|
|
|
|
|
this.mapY = 40;
|
|
|
|
|
this.mapW = Math.max(120, this.panelX - this.mapX - 8);
|
|
|
|
|
// 底部信息区高度(日志 + 状态文本),地图填满其上方空间
|
|
|
|
|
int infoHeight = 78;
|
|
|
|
|
int infoHeight = 88;
|
|
|
|
|
this.mapH = Math.max(140, this.height - this.mapY - infoHeight - 8);
|
|
|
|
|
|
|
|
|
|
// 屏幕较矮时压缩垂直间距,保证右侧面板内容不被截断
|
|
|
|
@@ -99,6 +103,9 @@ extends Screen {
|
|
|
|
|
|
|
|
|
|
// ===== 顶部控制按钮 =====
|
|
|
|
|
int topX = this.panelX;
|
|
|
|
|
// 左上角外部链接按钮:Git 仓库与官网(点击在系统浏览器打开)
|
|
|
|
|
this.addDrawableChild(ButtonWidget.builder(Text.literal((String)"Git \u4ed3\u5e93"), button -> this.openUrl(GIT_REPO_URL)).dimensions(this.mapX, 8, 70, 16).build());
|
|
|
|
|
this.addDrawableChild(ButtonWidget.builder(Text.literal((String)"\u5b98\u7f51"), button -> this.openUrl(HOMEPAGE_URL)).dimensions(this.mapX + 76, 8, 50, 16).build());
|
|
|
|
|
ButtonWidget startButton = ButtonWidget.builder(Text.literal((String)"\u5f00\u59cb\u81ea\u52a8\u6269\u5730"), button -> this.start()).dimensions(topX, 34, 154, 30).build();
|
|
|
|
|
ButtonWidget stopButton = ButtonWidget.builder(Text.literal((String)"\u505c\u6b62"), button -> this.controller.stop()).dimensions(topX + 160, 34, 74, 30).build();
|
|
|
|
|
this.addDrawableChild(startButton);
|
|
|
|
@@ -158,6 +165,15 @@ extends Screen {
|
|
|
|
|
this.initializeMapView();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 在系统默认浏览器中打开外部链接(失败时静默忽略) */
|
|
|
|
|
private void openUrl(String url) {
|
|
|
|
|
try {
|
|
|
|
|
Util.getOperatingSystem().open(new java.net.URI(url));
|
|
|
|
|
} catch (Exception ignored) {
|
|
|
|
|
// 链接打开失败不影响界面正常使用
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 创建整数输入框(初始值为 value,最多 12 位) */
|
|
|
|
|
private TextFieldWidget numberField(int value, int x, int y, int width) {
|
|
|
|
|
TextFieldWidget field = new TextFieldWidget(this.textRenderer, x, y, width, 20, Text.literal((String)""));
|
|
|
|
@@ -422,26 +438,50 @@ extends Screen {
|
|
|
|
|
|
|
|
|
|
/** 绘制右侧信息面板:字段标签、运行日志与状态/进度信息 */
|
|
|
|
|
private void drawInfo(DrawContext context) {
|
|
|
|
|
int shown;
|
|
|
|
|
// ===== 右侧配置面板字段标签 =====
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, "\u90a6\u56fd", this.panelX + 4, this.stateFieldY + 4, -5592406);
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, "\u76ee\u6807\u6570\u91cf", this.panelX + 4, this.targetFieldY + 4, -5592406);
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, "\u6743\u9650\u8bbe\u7f6e", this.panelX + 4, this.advancedY, -5592406);
|
|
|
|
|
int belowY = this.mapY + this.mapH + 12;
|
|
|
|
|
|
|
|
|
|
// ===== 底部信息面板:日志(左)+ 状态(右),均单行截断,避免换行导致的重叠 =====
|
|
|
|
|
int infoTop = this.mapY + this.mapH + 10;
|
|
|
|
|
int logWidth = Math.max(120, (int)(this.mapW * 0.52));
|
|
|
|
|
int statusX = this.mapX + logWidth + 20;
|
|
|
|
|
int statusWidth = this.mapW - logWidth - 20;
|
|
|
|
|
int statusX = this.mapX + logWidth + 24;
|
|
|
|
|
int statusWidth = this.mapW - logWidth - 24;
|
|
|
|
|
|
|
|
|
|
// 半透明面板背景,使信息区与地图明显分隔
|
|
|
|
|
context.fill(this.mapX, infoTop - 2, this.mapX + this.mapW, infoTop + 74, 0x30000000);
|
|
|
|
|
// 两栏标题与竖向分隔线
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, "\u8fd0\u884c\u65e5\u5fd7", this.mapX + 2, infoTop, -5592406);
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, "\u72b6\u6001\u4fe1\u606f", statusX, infoTop, -5592406);
|
|
|
|
|
context.fill(statusX - 12, infoTop - 1, statusX - 11, infoTop + 58, -12761518);
|
|
|
|
|
|
|
|
|
|
// 运行日志:最多 4 条,最新日志在最下方
|
|
|
|
|
List<String> logs = this.controller.logs();
|
|
|
|
|
for (int i = shown = Math.min(4, logs.size()); i > 0; --i) {
|
|
|
|
|
String trimmed = this.textRenderer.trimToWidth(logs.get(logs.size() - i), logWidth);
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, trimmed, this.mapX, belowY + (shown - i) * 12, -6577233);
|
|
|
|
|
int shown = Math.min(4, logs.size());
|
|
|
|
|
for (int i = 0; i < shown; ++i) {
|
|
|
|
|
String trimmed = this.textRenderer.trimToWidth(logs.get(logs.size() - shown + i), logWidth - 4);
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, trimmed, this.mapX + 2, infoTop + 12 + i * 12, -6577233);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 状态信息:单行截断 + 固定 12px 行距,彻底消除换行重叠
|
|
|
|
|
int target = this.config.targetCount;
|
|
|
|
|
String targetText = target > 0 ? Integer.toString(target) : "\u6301\u7eed";
|
|
|
|
|
context.drawWrappedTextWithShadow(this.textRenderer, Text.literal(("\u72b6\u6001\uff1a" + this.controller.status())), statusX, belowY, statusWidth, -1);
|
|
|
|
|
context.drawWrappedTextWithShadow(this.textRenderer, Text.literal(("\u8fdb\u5ea6\uff1a" + this.controller.completedClaims() + " / " + targetText + "\uff0c\u7b49\u5f85\uff1a" + this.controller.lastProgress() + "%")), statusX, belowY + 14, statusWidth, -1);
|
|
|
|
|
context.drawWrappedTextWithShadow(this.textRenderer, Text.literal(("\u961f\u5217\uff1a" + this.controller.queuedTargets() + "\uff0c\u6570\u636e\u9519\u8bef\uff1a" + (this.mod.dataService().lastError().isEmpty() ? "\u65e0" : this.mod.dataService().lastError()))), statusX, belowY + 30, statusWidth, -1);
|
|
|
|
|
context.drawWrappedTextWithShadow(this.textRenderer, Text.literal(this.refreshStatusText()), statusX, belowY + 46, statusWidth, -5592406);
|
|
|
|
|
context.drawWrappedTextWithShadow(this.textRenderer, Text.literal((String)"\u5f00\u59cb\u524d\u8bf7\u786e\u8ba4\u5df2\u624b\u52a8\u6267\u884c /u claimmode"), statusX, belowY + 62, statusWidth, -13210);
|
|
|
|
|
String error = this.mod.dataService().lastError();
|
|
|
|
|
String[] statusLines = new String[]{
|
|
|
|
|
"\u72b6\u6001\uff1a" + this.controller.status(),
|
|
|
|
|
"\u8fdb\u5ea6\uff1a" + this.controller.completedClaims() + " / " + targetText + "\uff0c\u7b49\u5f85\uff1a" + this.controller.lastProgress() + "%",
|
|
|
|
|
"\u961f\u5217\uff1a" + this.controller.queuedTargets() + "\uff0c\u6570\u636e\u9519\u8bef\uff1a" + (error.isEmpty() ? "\u65e0" : error),
|
|
|
|
|
this.refreshStatusText()
|
|
|
|
|
};
|
|
|
|
|
for (int i = 0; i < statusLines.length; ++i) {
|
|
|
|
|
String trimmed = this.textRenderer.trimToWidth(statusLines[i], statusWidth);
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, trimmed, statusX, infoTop + 12 + i * 12, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 底部整行提示
|
|
|
|
|
String hint = this.textRenderer.trimToWidth("\u5f00\u59cb\u524d\u8bf7\u786e\u8ba4\u5df2\u624b\u52a8\u6267\u884c /u claimmode", this.mapW);
|
|
|
|
|
context.drawTextWithShadow(this.textRenderer, hint, this.mapX + 2, infoTop + 62, -13210);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 生成地图刷新状态文本(显示上次成功刷新距今的时间) */
|
|
|
|
|