AbstractGameRulesScreen.java
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen
信息
- 全限定名:net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen
- 类型:public abstract class
- 包:net.minecraft.client.gui.screens.worldselection
- 源码路径:src/main/java/net/minecraft/client/gui/screens/worldselection/AbstractGameRulesScreen.java
- 起始行号:L47
- 继承:Screen
- 职责:
TODO
字段/常量
-
TITLE- 类型:
Component - 修饰符:
protected static final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
SEARCH_HINT- 类型:
Component - 修饰符:
private static final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
SEARCH_BOX_HEIGHT- 类型:
int - 修饰符:
private static final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
invalidEntries- 类型:
Set<AbstractGameRulesScreen.RuleEntry> - 修饰符:
private final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
exitCallback- 类型:
Consumer<Optional<GameRules>> - 修饰符:
private final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
layout- 类型:
HeaderAndFooterLayout - 修饰符:
protected final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
gameRules- 类型:
GameRules - 修饰符:
protected final - 源码定位:
L54 - 说明:
TODO
- 类型:
-
searchBox- 类型:
EditBox - 修饰符:
protected - 源码定位:
L55 - 说明:
TODO
- 类型:
-
ruleList- 类型:
AbstractGameRulesScreen.RuleList - 修饰符:
protected - 源码定位:
L56 - 说明:
TODO
- 类型:
-
doneButton- 类型:
Button - 修饰符:
protected - 源码定位:
L57 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.BooleanRuleEntry- 类型:
class - 修饰符:
public - 源码定位:
L138 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.CategoryRuleEntry- 类型:
class - 修饰符:
public - 源码定位:
L161 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.EntryFactory- 类型:
interface - 修饰符:
private - 源码定位:
L202 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.GameRuleEntry- 类型:
class - 修饰符:
public abstract - 源码定位:
L207 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.IntegerRuleEntry- 类型:
class - 修饰符:
public - 源码定位:
L239 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.RuleEntry- 类型:
class - 修饰符:
public abstract static - 源码定位:
L271 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen.RuleList- 类型:
class - 修饰符:
public - 源码定位:
L280 - 说明:
TODO
- 类型:
构造器
public AbstractGameRulesScreen(GameRules gameRules, Consumer<Optional<GameRules>> exitCallback) @ L59
- 构造器名:AbstractGameRulesScreen
- 源码定位:L59
- 修饰符:public
参数:
- gameRules: GameRules
- exitCallback: Consumer<Optional
>
说明:
TODO
方法
下面的方法块按源码顺序生成。
protected void createAndConfigureSearchBox(LinearLayout headerLayout) @ L66
- 方法名:createAndConfigureSearchBox
- 源码定位:L66
- 返回类型:void
- 修饰符:protected
参数:
- headerLayout: LinearLayout
说明:
TODO
protected void init() @ L72
- 方法名:init
- 源码定位:L72
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected abstract void initContent() @ L86
- 方法名:initContent
- 源码定位:L86
- 返回类型:void
- 修饰符:protected abstract
参数:
- 无
说明:
TODO
protected abstract void onDone() @ L88
- 方法名:onDone
- 源码定位:L88
- 返回类型:void
- 修饰符:protected abstract
参数:
- 无
说明:
TODO
protected void repositionElements() @ L90
- 方法名:repositionElements
- 源码定位:L90
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected void setInitialFocus() @ L98
- 方法名:setInitialFocus
- 源码定位:L98
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
private void markInvalid(AbstractGameRulesScreen.RuleEntry invalidEntry) @ L105
- 方法名:markInvalid
- 源码定位:L105
- 返回类型:void
- 修饰符:private
参数:
- invalidEntry: AbstractGameRulesScreen.RuleEntry
说明:
TODO
private void clearInvalid(AbstractGameRulesScreen.RuleEntry invalidEntry) @ L110
- 方法名:clearInvalid
- 源码定位:L110
- 返回类型:void
- 修饰符:private
参数:
- invalidEntry: AbstractGameRulesScreen.RuleEntry
说明:
TODO
private void updateDoneButton() @ L115
- 方法名:updateDoneButton
- 源码定位:L115
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
protected void closeAndDiscardChanges() @ L121
- 方法名:closeAndDiscardChanges
- 源码定位:L121
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected void closeAndApplyChanges() @ L125
- 方法名:closeAndApplyChanges
- 源码定位:L125
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected void filterGameRules(String filter) @ L129
- 方法名:filterGameRules
- 源码定位:L129
- 返回类型:void
- 修饰符:protected
参数:
- filter: String
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public abstract class AbstractGameRulesScreen extends Screen {
protected static final Component TITLE = Component.translatable("editGamerule.title");
private static final Component SEARCH_HINT = Component.translatable("gui.game_rule.search").withStyle(EditBox.SEARCH_HINT_STYLE);
private static final int SEARCH_BOX_HEIGHT = 15;
private final Set<AbstractGameRulesScreen.RuleEntry> invalidEntries = Sets.newHashSet();
private final Consumer<Optional<GameRules>> exitCallback;
protected final HeaderAndFooterLayout layout;
protected final GameRules gameRules;
protected @Nullable EditBox searchBox;
protected AbstractGameRulesScreen.@Nullable RuleList ruleList;
protected @Nullable Button doneButton;
public AbstractGameRulesScreen(GameRules gameRules, Consumer<Optional<GameRules>> exitCallback) {
super(TITLE);
this.gameRules = gameRules;
this.exitCallback = exitCallback;
this.layout = new HeaderAndFooterLayout(this, (int)(12.0 + 9.0 + 15.0), 33);
}
protected void createAndConfigureSearchBox(LinearLayout headerLayout) {
this.searchBox = headerLayout.addChild(new EditBox(this.font, 200, 15, Component.empty()));
this.searchBox.setHint(SEARCH_HINT);
this.searchBox.setResponder(this::filterGameRules);
}
@Override
protected void init() {
LinearLayout header = this.layout.addToHeader(LinearLayout.vertical().spacing(4));
header.defaultCellSetting().alignHorizontallyCenter();
header.addChild(new StringWidget(TITLE, this.font));
this.createAndConfigureSearchBox(header);
this.initContent();
LinearLayout footer = this.layout.addToFooter(LinearLayout.horizontal().spacing(8));
this.doneButton = footer.addChild(Button.builder(CommonComponents.GUI_DONE, button -> this.onDone()).build());
footer.addChild(Button.builder(CommonComponents.GUI_CANCEL, button -> this.onClose()).build());
this.layout.visitWidgets(x$0 -> this.addRenderableWidget(x$0));
this.repositionElements();
}
protected abstract void initContent();
protected abstract void onDone();
@Override
protected void repositionElements() {
this.layout.arrangeElements();
if (this.ruleList != null) {
this.ruleList.updateSize(this.width, this.layout);
}
}
@Override
protected void setInitialFocus() {
if (this.searchBox != null) {
this.setInitialFocus(this.searchBox);
}
}
private void markInvalid(AbstractGameRulesScreen.RuleEntry invalidEntry) {
this.invalidEntries.add(invalidEntry);
this.updateDoneButton();
}
private void clearInvalid(AbstractGameRulesScreen.RuleEntry invalidEntry) {
this.invalidEntries.remove(invalidEntry);
this.updateDoneButton();
}
private void updateDoneButton() {
if (this.doneButton != null) {
this.doneButton.active = this.invalidEntries.isEmpty();
}
}
protected void closeAndDiscardChanges() {
this.exitCallback.accept(Optional.empty());
}
protected void closeAndApplyChanges() {
this.exitCallback.accept(Optional.of(this.gameRules));
}
protected void filterGameRules(String filter) {
if (this.ruleList != null) {
this.ruleList.populateChildren(filter);
this.ruleList.setScrollAmount(0.0);
this.repositionElements();
}
}
@OnlyIn(Dist.CLIENT)
public class BooleanRuleEntry extends AbstractGameRulesScreen.GameRuleEntry {
private final CycleButton<Boolean> checkbox;
public BooleanRuleEntry(Component name, List<FormattedCharSequence> tooltip, String narration, GameRule<Boolean> gameRule) {
Objects.requireNonNull(AbstractGameRulesScreen.this);
super(tooltip, name);
this.checkbox = CycleButton.onOffBuilder(AbstractGameRulesScreen.this.gameRules.get(gameRule))
.displayOnlyValue()
.withCustomNarration(button -> button.createDefaultNarrationMessage().append("\n").append(narration))
.create(10, 5, 44, 20, name, (button, newValue) -> AbstractGameRulesScreen.this.gameRules.set(gameRule, newValue, null));
this.children.add(this.checkbox);
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
this.extractLabel(graphics, this.getContentY(), this.getContentX());
this.checkbox.setX(this.getContentRight() - 45);
this.checkbox.setY(this.getContentY());
this.checkbox.extractRenderState(graphics, mouseX, mouseY, a);
}
}
@OnlyIn(Dist.CLIENT)
public class CategoryRuleEntry extends AbstractGameRulesScreen.RuleEntry {
private final Component label;
public CategoryRuleEntry(Component label) {
Objects.requireNonNull(AbstractGameRulesScreen.this);
super(null);
this.label = label;
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
graphics.centeredText(AbstractGameRulesScreen.this.minecraft.font, this.label, this.getContentXMiddle(), this.getContentY() + 5, -1);
}
@Override
public List<? extends GuiEventListener> children() {
return ImmutableList.of();
}
@Override
public List<? extends NarratableEntry> narratables() {
return ImmutableList.of(new NarratableEntry() {
{
Objects.requireNonNull(CategoryRuleEntry.this);
}
@Override
public NarratableEntry.NarrationPriority narrationPriority() {
return NarratableEntry.NarrationPriority.HOVERED;
}
@Override
public void updateNarration(NarrationElementOutput output) {
output.add(NarratedElementType.TITLE, CategoryRuleEntry.this.label);
}
});
}
}
@FunctionalInterface
@OnlyIn(Dist.CLIENT)
private interface EntryFactory<T> {
AbstractGameRulesScreen.RuleEntry create(Component name, List<FormattedCharSequence> tooltip, String narration, GameRule<T> gameRule);
}
@OnlyIn(Dist.CLIENT)
public abstract class GameRuleEntry extends AbstractGameRulesScreen.RuleEntry {
private final List<FormattedCharSequence> label;
protected final List<AbstractWidget> children;
public GameRuleEntry(List<FormattedCharSequence> tooltip, Component label) {
Objects.requireNonNull(AbstractGameRulesScreen.this);
super(tooltip);
this.children = Lists.newArrayList();
this.label = AbstractGameRulesScreen.this.minecraft.font.split(label, 170);
}
@Override
public List<? extends GuiEventListener> children() {
return this.children;
}
@Override
public List<? extends NarratableEntry> narratables() {
return this.children;
}
protected void extractLabel(GuiGraphicsExtractor graphics, int rowTop, int rowLeft) {
if (this.label.size() == 1) {
graphics.text(AbstractGameRulesScreen.this.minecraft.font, this.label.get(0), rowLeft, rowTop + 5, -1);
} else if (this.label.size() >= 2) {
graphics.text(AbstractGameRulesScreen.this.minecraft.font, this.label.get(0), rowLeft, rowTop, -1);
graphics.text(AbstractGameRulesScreen.this.minecraft.font, this.label.get(1), rowLeft, rowTop + 10, -1);
}
}
}
@OnlyIn(Dist.CLIENT)
public class IntegerRuleEntry extends AbstractGameRulesScreen.GameRuleEntry {
private final EditBox input;
public IntegerRuleEntry(Component label, List<FormattedCharSequence> tooltip, String narration, GameRule<Integer> gameRule) {
Objects.requireNonNull(AbstractGameRulesScreen.this);
super(tooltip, label);
this.input = new EditBox(AbstractGameRulesScreen.this.minecraft.font, 10, 5, 44, 20, label.copy().append("\n").append(narration).append("\n"));
this.input.setValue(AbstractGameRulesScreen.this.gameRules.getAsString(gameRule));
this.input.setResponder(v -> {
DataResult<Integer> value = gameRule.deserialize(v);
if (value.isSuccess()) {
this.input.setTextColor(-2039584);
AbstractGameRulesScreen.this.clearInvalid(this);
AbstractGameRulesScreen.this.gameRules.set(gameRule, value.getOrThrow(), null);
} else {
this.input.setTextColor(-65536);
AbstractGameRulesScreen.this.markInvalid(this);
}
});
this.children.add(this.input);
}
@Override
public void extractContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float a) {
this.extractLabel(graphics, this.getContentY(), this.getContentX());
this.input.setX(this.getContentRight() - 45);
this.input.setY(this.getContentY());
this.input.extractRenderState(graphics, mouseX, mouseY, a);
}
}
@OnlyIn(Dist.CLIENT)
public abstract static class RuleEntry extends ContainerObjectSelectionList.Entry<AbstractGameRulesScreen.RuleEntry> {
private final @Nullable List<FormattedCharSequence> tooltip;
public RuleEntry(@Nullable List<FormattedCharSequence> tooltip) {
this.tooltip = tooltip;
}
}
@OnlyIn(Dist.CLIENT)
public class RuleList extends ContainerObjectSelectionList<AbstractGameRulesScreen.RuleEntry> {
private static final int ITEM_HEIGHT = 24;
private final GameRules gameRules;
public RuleList(GameRules gameRules) {
Objects.requireNonNull(AbstractGameRulesScreen.this);
super(
Minecraft.getInstance(),
AbstractGameRulesScreen.this.width,
AbstractGameRulesScreen.this.layout.getContentHeight(),
AbstractGameRulesScreen.this.layout.getHeaderHeight(),
24
);
this.gameRules = gameRules;
this.populateChildren("");
}
private void populateChildren(String filter) {
this.clearEntries();
final Map<GameRuleCategory, Map<GameRule<?>, AbstractGameRulesScreen.RuleEntry>> entries = Maps.newHashMap();
final String lowerCaseFilter = filter.toLowerCase(Locale.ROOT);
this.gameRules
.visitGameRuleTypes(
new GameRuleTypeVisitor() {
{
Objects.requireNonNull(RuleList.this);
}
@Override
public void visitBoolean(GameRule<Boolean> gameRule) {
this.addEntry(gameRule, (x$0, x$1, x$2, x$3) -> AbstractGameRulesScreen.this.new BooleanRuleEntry(x$0, x$1, x$2, x$3));
}
@Override
public void visitInteger(GameRule<Integer> gameRule) {
this.addEntry(gameRule, (x$0, x$1, x$2, x$3) -> AbstractGameRulesScreen.this.new IntegerRuleEntry(x$0, x$1, x$2, x$3));
}
private <T> void addEntry(GameRule<T> gameRule, AbstractGameRulesScreen.EntryFactory<T> factory) {
Component readableName = Component.translatable(gameRule.getDescriptionId());
String descriptionKey = gameRule.getDescriptionId() + ".description";
Optional<MutableComponent> optionalDescription = Optional.of(Component.translatable(descriptionKey))
.filter(ComponentUtils::isTranslationResolvable);
if (AbstractGameRulesScreen.RuleList.matchesFilter(
gameRule.id(), readableName.getString(), gameRule.category().label().getString(), optionalDescription, lowerCaseFilter
)) {
Component actualName = Component.literal(gameRule.id()).withStyle(ChatFormatting.YELLOW);
Component defaultValue = Component.translatable(
"editGamerule.default", Component.literal(gameRule.serialize(gameRule.defaultValue()))
)
.withStyle(ChatFormatting.GRAY);
List<FormattedCharSequence> tooltip;
String narration;
if (optionalDescription.isPresent()) {
Builder<FormattedCharSequence> result = ImmutableList.<FormattedCharSequence>builder().add(actualName.getVisualOrderText());
AbstractGameRulesScreen.this.font.split(optionalDescription.get(), 150).forEach(result::add);
tooltip = result.add(defaultValue.getVisualOrderText()).build();
narration = optionalDescription.get().getString() + "\n" + defaultValue.getString();
} else {
tooltip = ImmutableList.of(actualName.getVisualOrderText(), defaultValue.getVisualOrderText());
narration = defaultValue.getString();
}
entries.computeIfAbsent(gameRule.category(), k -> Maps.newHashMap())
.put(gameRule, factory.create(readableName, tooltip, narration, gameRule));
}
}
}
);
entries.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey(Comparator.comparing(GameRuleCategory::getDescriptionId)))
.forEach(
e -> {
this.addEntry(
AbstractGameRulesScreen.this.new CategoryRuleEntry(e.getKey().label().withStyle(ChatFormatting.BOLD, ChatFormatting.YELLOW))
);
e.getValue()
.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey(Comparator.comparing(GameRule::getDescriptionId)))
.forEach(v -> this.addEntry(v.getValue()));
}
);
}
private static boolean matchesFilter(
String gameRuleId, String readableName, String categoryName, Optional<MutableComponent> optionalDescription, String lowerCaseFilter
) {
return toLowerCaseMatchesFilter(gameRuleId, lowerCaseFilter)
|| toLowerCaseMatchesFilter(readableName, lowerCaseFilter)
|| toLowerCaseMatchesFilter(categoryName, lowerCaseFilter)
|| optionalDescription.<Boolean>map(description -> toLowerCaseMatchesFilter(description.getString(), lowerCaseFilter)).orElse(false);
}
private static boolean toLowerCaseMatchesFilter(String gameRuleId, String lowerCaseFilter) {
return gameRuleId.toLowerCase(Locale.ROOT).contains(lowerCaseFilter);
}
@Override
public void extractWidgetRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
super.extractWidgetRenderState(graphics, mouseX, mouseY, a);
AbstractGameRulesScreen.RuleEntry hovered = this.getHovered();
if (hovered != null && hovered.tooltip != null) {
graphics.setTooltipForNextFrame(hovered.tooltip, mouseX, mouseY);
}
}
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Button.builder()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CycleButton.onOffBuilder()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
EditBox()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
StringWidget()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
HeaderAndFooterLayout()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
LinearLayout.horizontal(), LinearLayout.vertical()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
NarratableEntry()
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Component.empty(), Component.literal(), Component.translatable()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GameRuleTypeVisitor()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置: