Skip to content

Commit e7a81c6

Browse files
committed
refactor(wand): 重构魔杖插件界面系统
- 移除旧的屏幕和菜单回调方法,统一使用 buildUi 方法构建界面 - 更新 AutoCharge 插件实现,使用新的界面构建方式 - 修改 Coordinate 类,移除预存储的窗口尺寸,改为实时获取 - 简化 BasePlugin 抽象类的界面相关方法定义
1 parent 97d151f commit e7a81c6

25 files changed

+1089
-1296
lines changed

src/main/java/org/creepebucket/programmable_magic/gui/lib/api/Coordinate.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,11 @@ public class Coordinate {
2121
public final BiFunction<Integer, Integer, Integer> y;
2222

2323
/**
24-
* 构造时捕获的窗口宽(缩放后)。
25-
*/
26-
public final int sw;
27-
28-
/**
29-
* 构造时捕获的窗口高(缩放后)。
30-
*/
31-
public final int sh;
32-
33-
/**
34-
* 创建一个坐标计算器,并捕获当前窗口缩放后的尺寸。
24+
* 创建一个坐标计算器。
3525
*/
3626
public Coordinate(BiFunction<Integer, Integer, Integer> x, BiFunction<Integer, Integer, Integer> y) {
3727
this.x = x;
3828
this.y = y;
39-
40-
var window = Minecraft.getInstance().getWindow();
41-
this.sw = window.getGuiScaledWidth();
42-
this.sh = window.getGuiScaledHeight();
4329
}
4430

4531
/**
@@ -59,12 +45,18 @@ public int toMenuY() {
5945
/**
6046
* 计算屏幕坐标 X。
6147
*/
62-
public int toScreenX() { return this.x.apply(this.sw, this.sh); }
48+
public int toScreenX() {
49+
var window = Minecraft.getInstance().getWindow();
50+
return this.x.apply(window.getGuiScaledWidth(), window.getGuiScaledHeight());
51+
}
6352

6453
/**
6554
* 计算屏幕坐标 Y。
6655
*/
67-
public int toScreenY() { return this.y.apply(this.sw, this.sh); }
56+
public int toScreenY() {
57+
var window = Minecraft.getInstance().getWindow();
58+
return this.y.apply(window.getGuiScaledWidth(), window.getGuiScaledHeight());
59+
}
6860

6961
/**
7062
* 以屏幕左上角为基准创建坐标。

src/main/java/org/creepebucket/programmable_magic/gui/lib/ui/UiRuntime.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ public void addWidget(Widget widget) {
7474
widget.onInitialize();
7575
}
7676

77+
/**
78+
* 移除全部控件并触发其移除回调。
79+
*/
80+
public void clearWidgets() {
81+
for (var w : this.widgets) w.onRemoved();
82+
this.widgets.clear();
83+
}
84+
7785
/**
7886
* 移除一个控件并触发其移除回调。
7987
*/
@@ -90,9 +98,15 @@ public void tick() {
9098
}
9199

92100
/**
93-
* 渲染所有控件。
101+
* 渲染背景控件。
102+
*/
103+
public void renderBackground(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
104+
}
105+
106+
/**
107+
* 渲染前景控件。
94108
*/
95-
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
109+
public void renderForeground(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
96110
for (var w : this.widgets) w.onRender(graphics, mouseX, mouseY, partialTick);
97111
}
98112

src/main/java/org/creepebucket/programmable_magic/gui/lib/ui/UiScreenBase.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* UI 屏幕基类:将 Minecraft 的输入/渲染生命周期桥接到 {@link UiRuntime}。
1616
*/
1717
public abstract class UiScreenBase<Menu extends UiMenuBase> extends SlotManipulationScreen<Menu> {
18+
private float lastPartialTick = 0.0F;
1819

1920
/**
2021
* 创建 UI 屏幕。
@@ -28,6 +29,8 @@ public UiScreenBase(Menu menu, Inventory playerInv, Component title) {
2829
*/
2930
@Override
3031
protected void init() {
32+
this.imageWidth = this.width;
33+
this.imageHeight = this.height;
3134
super.init();
3235

3336
updateUiBounds();
@@ -44,6 +47,8 @@ protected void init() {
4447
*/
4548
@Override
4649
public void resize(int width, int height) {
50+
this.imageWidth = width;
51+
this.imageHeight = height;
4752
super.resize(width, height);
4853
updateUiBounds();
4954
}
@@ -58,16 +63,26 @@ protected void containerTick() {
5863
}
5964

6065
/**
61-
* 渲染原生容器界面后,再渲染 UI 运行时控件
66+
* 渲染原生容器界面后,再渲染 UI 前景控件
6267
*/
6368
@Override
6469
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
70+
this.lastPartialTick = partialTick;
6571
super.render(graphics, mouseX, mouseY, partialTick);
66-
this.menu.ui().render(graphics, mouseX, mouseY, partialTick);
72+
this.renderTooltip(graphics, mouseX, mouseY);
6773
}
6874

6975
/**
70-
* 该基类不绘制背景;具体背景交由子类或控件自行实现。
76+
* 在标签层(renderLabels)渲染 UI 前景控件,确保其处于原生控件之后、tooltip 之前。
77+
*/
78+
@Override
79+
protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) {
80+
super.renderLabels(graphics, mouseX, mouseY);
81+
this.menu.ui().renderForeground(graphics, mouseX, mouseY, this.lastPartialTick);
82+
}
83+
84+
/**
85+
* 默认在背景层渲染 UI 背景控件。
7186
*/
7287
@Override
7388
protected void renderBg(GuiGraphics graphics, float partialTick, int mouseX, int mouseY) {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.creepebucket.programmable_magic.gui.lib.widgets;
2+
3+
import net.minecraft.client.gui.GuiGraphics;
4+
import net.minecraft.client.input.MouseButtonEvent;
5+
import net.minecraft.client.renderer.RenderPipelines;
6+
import net.minecraft.resources.Identifier;
7+
import org.creepebucket.programmable_magic.gui.lib.api.Coordinate;
8+
import org.creepebucket.programmable_magic.gui.lib.api.Widget;
9+
10+
import java.util.function.Consumer;
11+
12+
public class ImageButtonWidget extends Widget {
13+
private final Coordinate pos;
14+
private final int width;
15+
private final int height;
16+
private final Identifier normal;
17+
private final Identifier hover;
18+
private final Consumer<MouseButtonEvent> onPress;
19+
20+
public ImageButtonWidget(Coordinate pos, int width, int height, Identifier normal, Identifier hover, Runnable onPress) {
21+
this(pos, width, height, normal, hover, e -> onPress.run());
22+
}
23+
24+
public ImageButtonWidget(Coordinate pos, int width, int height, Identifier normal, Identifier hover, Consumer<MouseButtonEvent> onPress) {
25+
this.pos = pos;
26+
this.width = width;
27+
this.height = height;
28+
this.normal = normal;
29+
this.hover = hover;
30+
this.onPress = onPress;
31+
}
32+
33+
@Override
34+
public void onRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
35+
int sx = this.pos.toScreenX();
36+
int sy = this.pos.toScreenY();
37+
boolean hovered = mouseX >= sx && mouseX < sx + this.width && mouseY >= sy && mouseY < sy + this.height;
38+
var tex = hovered ? this.hover : this.normal;
39+
graphics.blit(RenderPipelines.GUI_TEXTURED, tex, this.pos.toMenuX(), this.pos.toMenuY(), 0, 0, this.width, this.height, this.width, this.height);
40+
}
41+
42+
@Override
43+
public boolean mouseClicked(MouseButtonEvent event, boolean fromMouse) {
44+
int x = this.pos.toScreenX();
45+
int y = this.pos.toScreenY();
46+
double mx = event.x();
47+
double my = event.y();
48+
if (mx < x || mx >= x + this.width || my < y || my >= y + this.height) return false;
49+
this.onPress.accept(event);
50+
return true;
51+
}
52+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.creepebucket.programmable_magic.gui.lib.widgets;
2+
3+
import org.creepebucket.programmable_magic.gui.lib.api.Coordinate;
4+
import org.creepebucket.programmable_magic.gui.lib.api.Widget;
5+
6+
import java.util.function.IntConsumer;
7+
import java.util.function.IntSupplier;
8+
9+
public class ScrollRegionWidget extends Widget {
10+
private final Coordinate pos;
11+
private final IntSupplier width;
12+
private final IntSupplier height;
13+
private final IntSupplier getValue;
14+
private final IntSupplier maxValue;
15+
private final IntConsumer setValue;
16+
17+
public ScrollRegionWidget(Coordinate pos, IntSupplier width, IntSupplier height, IntSupplier getValue, IntSupplier maxValue, IntConsumer setValue) {
18+
this.pos = pos;
19+
this.width = width;
20+
this.height = height;
21+
this.getValue = getValue;
22+
this.maxValue = maxValue;
23+
this.setValue = setValue;
24+
}
25+
26+
@Override
27+
public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
28+
int x = this.pos.toScreenX();
29+
int y = this.pos.toScreenY();
30+
int w = this.width.getAsInt();
31+
int h = this.height.getAsInt();
32+
if (mouseX < x || mouseX >= x + w || mouseY < y || mouseY >= y + h) return false;
33+
int d = scrollY > 0 ? -1 : (scrollY < 0 ? 1 : 0);
34+
int cur = this.getValue.getAsInt();
35+
int next = cur + d;
36+
int max = Math.max(0, this.maxValue.getAsInt());
37+
if (next < 0) next = 0;
38+
if (next > max) next = max;
39+
if (next == cur) return true;
40+
this.setValue.accept(next);
41+
return true;
42+
}
43+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.creepebucket.programmable_magic.gui.lib.widgets;
2+
3+
import net.minecraft.client.gui.GuiGraphics;
4+
import net.minecraft.client.input.MouseButtonEvent;
5+
import net.minecraft.client.renderer.RenderPipelines;
6+
import net.minecraft.resources.Identifier;
7+
import org.creepebucket.programmable_magic.gui.lib.api.Coordinate;
8+
import org.creepebucket.programmable_magic.gui.lib.api.Widget;
9+
10+
import java.util.function.BooleanSupplier;
11+
12+
public class SelectableImageButtonWidget extends Widget {
13+
private final Coordinate pos;
14+
private final int width;
15+
private final int height;
16+
private final Identifier normal;
17+
private final Identifier selected;
18+
private final BooleanSupplier isSelected;
19+
private final Runnable onPress;
20+
21+
public SelectableImageButtonWidget(Coordinate pos, int width, int height, Identifier normal, Identifier selected, BooleanSupplier isSelected, Runnable onPress) {
22+
this.pos = pos;
23+
this.width = width;
24+
this.height = height;
25+
this.normal = normal;
26+
this.selected = selected;
27+
this.isSelected = isSelected;
28+
this.onPress = onPress;
29+
}
30+
31+
@Override
32+
public void onRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
33+
var tex = this.isSelected.getAsBoolean() ? this.selected : this.normal;
34+
graphics.blit(RenderPipelines.GUI_TEXTURED, tex, this.pos.toMenuX(), this.pos.toMenuY(), 0, 0, this.width, this.height, this.width, this.height);
35+
}
36+
37+
@Override
38+
public boolean mouseClicked(MouseButtonEvent event, boolean fromMouse) {
39+
int x = this.pos.toScreenX();
40+
int y = this.pos.toScreenY();
41+
double mx = event.x();
42+
double my = event.y();
43+
if (mx < x || mx >= x + this.width || my < y || my >= y + this.height) return false;
44+
this.onPress.run();
45+
return true;
46+
}
47+
}

src/main/java/org/creepebucket/programmable_magic/gui/lib/widgets/SlotWidget.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public SlotWidget(Slot slot, Coordinate pos) {
2424
/**
2525
* 持续更新槽位的客户端坐标。
2626
*/
27+
@Override
28+
public void onInitialize() {
29+
onTick();
30+
}
31+
2732
@Override
2833
public void onTick() {
2934
ClientSlotManager.setClientPosition(this.slot, this.pos.toMenuX(), this.pos.toMenuY());
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.creepebucket.programmable_magic.gui.lib.widgets;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.client.gui.GuiGraphics;
5+
import org.creepebucket.programmable_magic.gui.lib.api.Coordinate;
6+
import org.creepebucket.programmable_magic.gui.lib.api.Widget;
7+
8+
import java.util.function.IntSupplier;
9+
import java.util.function.Supplier;
10+
11+
public class TextWidget extends Widget {
12+
private final Coordinate pos;
13+
private final Supplier<String> text;
14+
private final IntSupplier color;
15+
16+
public TextWidget(Coordinate pos, Supplier<String> text, IntSupplier color) {
17+
this.pos = pos;
18+
this.text = text;
19+
this.color = color;
20+
}
21+
22+
@Override
23+
public void onRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
24+
graphics.drawString(Minecraft.getInstance().font, this.text.get(),
25+
this.pos.toMenuX(),
26+
this.pos.toMenuY(),
27+
this.color.getAsInt());
28+
}
29+
}

src/main/java/org/creepebucket/programmable_magic/gui/lib/widgets/TextureWidget.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public TextureWidget(Coordinate pos, Identifier texture, int width, int height)
3232
@Override
3333
public void onRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
3434
graphics.blit(RenderPipelines.GUI_TEXTURED, this.texture,
35-
this.pos.toScreenX(), this.pos.toScreenY(),
35+
this.pos.toMenuX(), this.pos.toMenuY(),
3636
0, 0,
3737
this.width, this.height,
3838
this.width, this.height);

src/main/java/org/creepebucket/programmable_magic/gui/wand/MathUtils.java

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)