AdvancementWidget.java
net.minecraft.client.gui.screens.advancements.AdvancementWidget
信息
- 全限定名:net.minecraft.client.gui.screens.advancements.AdvancementWidget
- 类型:public class
- 包:net.minecraft.client.gui.screens.advancements
- 源码路径:src/main/java/net/minecraft/client/gui/screens/advancements/AdvancementWidget.java
- 起始行号:L27
- 职责:
TODO
字段/常量
-
TITLE_BOX_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L28 - 说明:
TODO
- 类型:
-
HEIGHT- 类型:
int - 修饰符:
private static final - 源码定位:
L29 - 说明:
TODO
- 类型:
-
BOX_X- 类型:
int - 修饰符:
private static final - 源码定位:
L30 - 说明:
TODO
- 类型:
-
BOX_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L31 - 说明:
TODO
- 类型:
-
FRAME_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
ICON_X- 类型:
int - 修饰符:
private static final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
ICON_Y- 类型:
int - 修饰符:
private static final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
ICON_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
TITLE_PADDING_LEFT- 类型:
int - 修饰符:
private static final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
TITLE_PADDING_RIGHT- 类型:
int - 修饰符:
private static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
TITLE_X- 类型:
int - 修饰符:
private static final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
TITLE_PADDING_TOP- 类型:
int - 修饰符:
private static final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
TITLE_PADDING_BOTTOM- 类型:
int - 修饰符:
private static final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
TITLE_MAX_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
TITLE_MIN_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L42 - 说明:
TODO
- 类型:
-
TEST_SPLIT_OFFSETS- 类型:
int[] - 修饰符:
private static final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
tab- 类型:
AdvancementTab - 修饰符:
private final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
advancementNode- 类型:
AdvancementNode - 修饰符:
private final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
display- 类型:
DisplayInfo - 修饰符:
private final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
icon- 类型:
ItemStack - 修饰符:
private final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
titleLines- 类型:
List<FormattedCharSequence> - 修饰符:
private final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
width- 类型:
int - 修饰符:
private final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
description- 类型:
List<FormattedCharSequence> - 修饰符:
private final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
minecraft- 类型:
Minecraft - 修饰符:
private final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
parent- 类型:
AdvancementWidget - 修饰符:
private - 源码定位:
L52 - 说明:
TODO
- 类型:
-
children- 类型:
List<AdvancementWidget> - 修饰符:
private final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
progress- 类型:
AdvancementProgress - 修饰符:
private - 源码定位:
L54 - 说明:
TODO
- 类型:
-
x- 类型:
int - 修饰符:
private final - 源码定位:
L55 - 说明:
TODO
- 类型:
-
y- 类型:
int - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
public AdvancementWidget(AdvancementTab tab, Minecraft minecraft, AdvancementNode advancementNode, DisplayInfo display) @ L58
- 构造器名:AdvancementWidget
- 源码定位:L58
- 修饰符:public
参数:
- tab: AdvancementTab
- minecraft: Minecraft
- advancementNode: AdvancementNode
- display: DisplayInfo
说明:
TODO
方法
下面的方法块按源码顺序生成。
private int getMaxProgressWidth() @ L84
- 方法名:getMaxProgressWidth
- 源码定位:L84
- 返回类型:int
- 修饰符:private
参数:
- 无
说明:
TODO
private static float getMaxWidth(StringSplitter splitter, List<FormattedText> input) @ L95
- 方法名:getMaxWidth
- 源码定位:L95
- 返回类型:float
- 修饰符:private static
参数:
- splitter: StringSplitter
- input: List
说明:
TODO
private List<FormattedText> findOptimalLines(Component input, int preferredWidth) @ L99
- 方法名:findOptimalLines
- 源码定位:L99
- 返回类型:List
- 修饰符:private
参数:
- input: Component
- preferredWidth: int
说明:
TODO
private AdvancementWidget getFirstVisibleParent(AdvancementNode node) @ L120
- 方法名:getFirstVisibleParent
- 源码定位:L120
- 返回类型:AdvancementWidget
- 修饰符:private
参数:
- node: AdvancementNode
说明:
TODO
public void extractConnectivity(GuiGraphicsExtractor graphics, int xo, int yo, boolean background) @ L128
- 方法名:extractConnectivity
- 源码定位:L128
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- xo: int
- yo: int
- background: boolean
说明:
TODO
public void extractRenderState(GuiGraphicsExtractor graphics, int xo, int yo) @ L157
- 方法名:extractRenderState
- 源码定位:L157
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- xo: int
- yo: int
说明:
TODO
public int getWidth() @ L176
- 方法名:getWidth
- 源码定位:L176
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public void setProgress(AdvancementProgress progress) @ L180
- 方法名:setProgress
- 源码定位:L180
- 返回类型:void
- 修饰符:public
参数:
- progress: AdvancementProgress
说明:
TODO
public void addChild(AdvancementWidget widget) @ L184
- 方法名:addChild
- 源码定位:L184
- 返回类型:void
- 修饰符:public
参数:
- widget: AdvancementWidget
说明:
TODO
public void extractHover(GuiGraphicsExtractor graphics, int xo, int yo, float fade, int screenxo, int screenyo) @ L188
- 方法名:extractHover
- 源码定位:L188
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- xo: int
- yo: int
- fade: float
- screenxo: int
- screenyo: int
说明:
TODO
private void extractMultilineText(GuiGraphicsExtractor graphics, List<FormattedCharSequence> lines, int x, int y, int color) @ L285
- 方法名:extractMultilineText
- 源码定位:L285
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
- lines: List
- x: int
- y: int
- color: int
说明:
TODO
public boolean isMouseOver(int xo, int yo, int mouseX, int mouseY) @ L293
- 方法名:isMouseOver
- 源码定位:L293
- 返回类型:boolean
- 修饰符:public
参数:
- xo: int
- yo: int
- mouseX: int
- mouseY: int
说明:
TODO
public void attachToParent() @ L305
- 方法名:attachToParent
- 源码定位:L305
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public int getY() @ L314
- 方法名:getY
- 源码定位:L314
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public int getX() @ L318
- 方法名:getX
- 源码定位:L318
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class AdvancementWidget {
private static final Identifier TITLE_BOX_SPRITE = Identifier.withDefaultNamespace("advancements/title_box");
private static final int HEIGHT = 26;
private static final int BOX_X = 0;
private static final int BOX_WIDTH = 200;
private static final int FRAME_WIDTH = 26;
private static final int ICON_X = 8;
private static final int ICON_Y = 5;
private static final int ICON_WIDTH = 26;
private static final int TITLE_PADDING_LEFT = 3;
private static final int TITLE_PADDING_RIGHT = 5;
private static final int TITLE_X = 32;
private static final int TITLE_PADDING_TOP = 9;
private static final int TITLE_PADDING_BOTTOM = 8;
private static final int TITLE_MAX_WIDTH = 163;
private static final int TITLE_MIN_WIDTH = 80;
private static final int[] TEST_SPLIT_OFFSETS = new int[]{0, 10, -10, 25, -25};
private final AdvancementTab tab;
private final AdvancementNode advancementNode;
private final DisplayInfo display;
private final ItemStack icon;
private final List<FormattedCharSequence> titleLines;
private final int width;
private final List<FormattedCharSequence> description;
private final Minecraft minecraft;
private @Nullable AdvancementWidget parent;
private final List<AdvancementWidget> children = Lists.newArrayList();
private @Nullable AdvancementProgress progress;
private final int x;
private final int y;
public AdvancementWidget(AdvancementTab tab, Minecraft minecraft, AdvancementNode advancementNode, DisplayInfo display) {
this.tab = tab;
this.advancementNode = advancementNode;
this.display = display;
this.minecraft = minecraft;
this.titleLines = minecraft.font.split(display.getTitle(), 163);
this.x = Mth.floor(display.getX() * 28.0F);
this.y = Mth.floor(display.getY() * 27.0F);
int titleWidth = Math.max(this.titleLines.stream().mapToInt(minecraft.font::width).max().orElse(0), 80);
int maxProgressWidth = this.getMaxProgressWidth();
int longestDescLine = 29 + titleWidth + maxProgressWidth;
this.description = Language.getInstance()
.getVisualOrder(
this.findOptimalLines(
ComponentUtils.mergeStyles(display.getDescription(), Style.EMPTY.withColor(display.getType().getChatColor())), longestDescLine
)
);
for (FormattedCharSequence line : this.description) {
longestDescLine = Math.max(longestDescLine, minecraft.font.width(line));
}
this.width = longestDescLine + 3 + 5;
this.icon = display.getIcon().create();
}
private int getMaxProgressWidth() {
int maxCriteraRequired = this.advancementNode.advancement().requirements().size();
if (maxCriteraRequired <= 1) {
return 0;
} else {
int spacing = 8;
Component fakeMaxProgress = Component.translatable("advancements.progress", maxCriteraRequired, maxCriteraRequired);
return this.minecraft.font.width(fakeMaxProgress) + 8;
}
}
private static float getMaxWidth(StringSplitter splitter, List<FormattedText> input) {
return (float)input.stream().mapToDouble(splitter::stringWidth).max().orElse(0.0);
}
private List<FormattedText> findOptimalLines(Component input, int preferredWidth) {
StringSplitter splitter = this.minecraft.font.getSplitter();
List<FormattedText> bestSplit = null;
float bestDistance = Float.MAX_VALUE;
for (int testMargin : TEST_SPLIT_OFFSETS) {
List<FormattedText> testSplit = splitter.splitLines(input, preferredWidth - testMargin, Style.EMPTY);
float distance = Math.abs(getMaxWidth(splitter, testSplit) - preferredWidth);
if (distance <= 10.0F) {
return testSplit;
}
if (distance < bestDistance) {
bestDistance = distance;
bestSplit = testSplit;
}
}
return bestSplit;
}
private @Nullable AdvancementWidget getFirstVisibleParent(AdvancementNode node) {
do {
node = node.parent();
} while (node != null && node.advancement().display().isEmpty());
return node != null && !node.advancement().display().isEmpty() ? this.tab.getWidget(node.holder()) : null;
}
public void extractConnectivity(GuiGraphicsExtractor graphics, int xo, int yo, boolean background) {
if (this.parent != null) {
int depX = xo + this.parent.x + 13;
int splitX = xo + this.parent.x + 26 + 4;
int depY = yo + this.parent.y + 13;
int myX = xo + this.x + 13;
int myY = yo + this.y + 13;
int col = background ? -16777216 : -1;
if (background) {
graphics.horizontalLine(splitX, depX, depY - 1, col);
graphics.horizontalLine(splitX + 1, depX, depY, col);
graphics.horizontalLine(splitX, depX, depY + 1, col);
graphics.horizontalLine(myX, splitX - 1, myY - 1, col);
graphics.horizontalLine(myX, splitX - 1, myY, col);
graphics.horizontalLine(myX, splitX - 1, myY + 1, col);
graphics.verticalLine(splitX - 1, myY, depY, col);
graphics.verticalLine(splitX + 1, myY, depY, col);
} else {
graphics.horizontalLine(splitX, depX, depY, col);
graphics.horizontalLine(myX, splitX, myY, col);
graphics.verticalLine(splitX, myY, depY, col);
}
}
for (AdvancementWidget child : this.children) {
child.extractConnectivity(graphics, xo, yo, background);
}
}
public void extractRenderState(GuiGraphicsExtractor graphics, int xo, int yo) {
if (!this.display.isHidden() || this.progress != null && this.progress.isDone()) {
float amount = this.progress == null ? 0.0F : this.progress.getPercent();
AdvancementWidgetType iconFrame;
if (amount >= 1.0F) {
iconFrame = AdvancementWidgetType.OBTAINED;
} else {
iconFrame = AdvancementWidgetType.UNOBTAINED;
}
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, iconFrame.frameSprite(this.display.getType()), xo + this.x + 3, yo + this.y, 26, 26);
graphics.fakeItem(this.icon, xo + this.x + 8, yo + this.y + 5);
}
for (AdvancementWidget child : this.children) {
child.extractRenderState(graphics, xo, yo);
}
}
public int getWidth() {
return this.width;
}
public void setProgress(AdvancementProgress progress) {
this.progress = progress;
}
public void addChild(AdvancementWidget widget) {
this.children.add(widget);
}
public void extractHover(GuiGraphicsExtractor graphics, int xo, int yo, float fade, int screenxo, int screenyo) {
Font font = this.minecraft.font;
int titleBarHeight = 9 * this.titleLines.size() + 9 + 8;
int titleTop = yo + this.y + (26 - titleBarHeight) / 2;
int titleBarBottom = titleTop + titleBarHeight;
int descriptionTextHeight = this.description.size() * 9;
int descriptionHeight = 6 + descriptionTextHeight;
boolean leftSide = screenxo + xo + this.x + this.width + 26 >= this.tab.getScreen().width;
Component progressText = this.progress == null ? null : this.progress.getProgressText();
int progressWidth = progressText == null ? 0 : font.width(progressText);
boolean topSide = titleBarBottom + descriptionHeight >= 113;
float amount = this.progress == null ? 0.0F : this.progress.getPercent();
int firstHalfWidth = Mth.floor(amount * this.width);
AdvancementWidgetType firstHalf;
AdvancementWidgetType secondHalf;
AdvancementWidgetType iconFrame;
if (amount >= 1.0F) {
firstHalfWidth = this.width / 2;
firstHalf = AdvancementWidgetType.OBTAINED;
secondHalf = AdvancementWidgetType.OBTAINED;
iconFrame = AdvancementWidgetType.OBTAINED;
} else if (firstHalfWidth < 2) {
firstHalfWidth = this.width / 2;
firstHalf = AdvancementWidgetType.UNOBTAINED;
secondHalf = AdvancementWidgetType.UNOBTAINED;
iconFrame = AdvancementWidgetType.UNOBTAINED;
} else if (firstHalfWidth > this.width - 2) {
firstHalfWidth = this.width / 2;
firstHalf = AdvancementWidgetType.OBTAINED;
secondHalf = AdvancementWidgetType.OBTAINED;
iconFrame = AdvancementWidgetType.UNOBTAINED;
} else {
firstHalf = AdvancementWidgetType.OBTAINED;
secondHalf = AdvancementWidgetType.UNOBTAINED;
iconFrame = AdvancementWidgetType.UNOBTAINED;
}
int secondBarWidth = this.width - firstHalfWidth;
int titleLeft;
if (leftSide) {
titleLeft = xo + this.x - this.width + 26 + 6;
} else {
titleLeft = xo + this.x;
}
int backgroundHeight = titleBarHeight + descriptionHeight;
if (!this.description.isEmpty()) {
if (topSide) {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, TITLE_BOX_SPRITE, titleLeft, titleBarBottom - backgroundHeight, this.width, backgroundHeight);
} else {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, TITLE_BOX_SPRITE, titleLeft, titleTop, this.width, backgroundHeight);
}
}
if (firstHalf != secondHalf) {
graphics.blitSprite(
RenderPipelines.GUI_TEXTURED, firstHalf.boxSprite(), 200, titleBarHeight, 0, 0, titleLeft, titleTop, firstHalfWidth, titleBarHeight
);
graphics.blitSprite(
RenderPipelines.GUI_TEXTURED,
secondHalf.boxSprite(),
200,
titleBarHeight,
200 - secondBarWidth,
0,
titleLeft + firstHalfWidth,
titleTop,
secondBarWidth,
titleBarHeight
);
} else {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, firstHalf.boxSprite(), titleLeft, titleTop, this.width, titleBarHeight);
}
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, iconFrame.frameSprite(this.display.getType()), xo + this.x + 3, yo + this.y, 26, 26);
int descriptionLeft = titleLeft + 5;
if (leftSide) {
this.extractMultilineText(graphics, this.titleLines, descriptionLeft, titleTop + 9, -1);
if (progressText != null) {
graphics.text(font, progressText, xo + this.x - progressWidth, titleTop + 9, -1);
}
} else {
this.extractMultilineText(graphics, this.titleLines, xo + this.x + 32, titleTop + 9, -1);
if (progressText != null) {
graphics.text(font, progressText, xo + this.x + this.width - progressWidth - 5, titleTop + 9, -1);
}
}
if (topSide) {
this.extractMultilineText(graphics, this.description, descriptionLeft, titleTop - descriptionTextHeight + 1, -16711936);
} else {
this.extractMultilineText(graphics, this.description, descriptionLeft, titleBarBottom, -16711936);
}
graphics.fakeItem(this.icon, xo + this.x + 8, yo + this.y + 5);
}
private void extractMultilineText(GuiGraphicsExtractor graphics, List<FormattedCharSequence> lines, int x, int y, int color) {
Font font = this.minecraft.font;
for (int i = 0; i < lines.size(); i++) {
graphics.text(font, lines.get(i), x, y + i * 9, color);
}
}
public boolean isMouseOver(int xo, int yo, int mouseX, int mouseY) {
if (!this.display.isHidden() || this.progress != null && this.progress.isDone()) {
int x0 = xo + this.x;
int x1 = x0 + 26;
int y0 = yo + this.y;
int y1 = y0 + 26;
return mouseX >= x0 && mouseX <= x1 && mouseY >= y0 && mouseY <= y1;
} else {
return false;
}
}
public void attachToParent() {
if (this.parent == null && this.advancementNode.parent() != null) {
this.parent = this.getFirstVisibleParent(this.advancementNode);
if (this.parent != null) {
this.parent.addChild(this);
}
}
}
public int getY() {
return this.y;
}
public int getX() {
return this.x;
}
}引用的其他类
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Language.getInstance()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Component.translatable()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ComponentUtils.mergeStyles()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.floor()
- 引用位置:
-
- 引用位置:
字段
- 引用位置: