package net.minecraft.client.gui; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.components.events.ContainerEventHandler; import net.minecraft.client.gui.components.events.GuiEventListener; import org.jetbrains.annotations.Nullable; /** * Represents a path of components in a user interface hierarchy. *

* It provides methods to create and manipulate component paths. */ @Environment(EnvType.CLIENT) public interface ComponentPath { /** * Creates a leaf component path with the specified {@code GuiEventListener} component. *

* @return a new leaf component path. * * @param component the component associated with the leaf path */ static ComponentPath leaf(GuiEventListener component) { return new ComponentPath.Leaf(component); } /** * Creates a component path with the specified {@code ContainerEventHandler} component and an optional child path. *

* @return a new component path, or {@code null} if the child path is null * * @param component the component associated with the path * @param childPath the child path associated with the component */ @Nullable static ComponentPath path(ContainerEventHandler component, @Nullable ComponentPath childPath) { return childPath == null ? null : new ComponentPath.Path(component, childPath); } /** * Creates a new {@code ComponentPath} leaf node with the specified {@code GuiEventListener} component and an array of {@code ContainerEventHandler} ancestors. *

* @return a new component path * * @param leafComponent the new 'Leaf' component associated with the path * @param ancestorComponents the array of ancestor components associated with the path, ordered in reverse ascending order towards root. */ static ComponentPath path(GuiEventListener leafComponent, ContainerEventHandler... ancestorComponents) { ComponentPath componentPath = leaf(leafComponent); for (ContainerEventHandler containerEventHandler : ancestorComponents) { componentPath = path(containerEventHandler, componentPath); } return componentPath; } /** * {@return the {@code GuiEventListener} component associated with this component path} */ GuiEventListener component(); /** * Applies focus to or removes focus from the component associated with this component path. * * @param focused {@code true} to apply focus, {@code false} to remove focus. */ void applyFocus(boolean focused); /** * The {@code Leaf} class represents a leaf component path in the hierarchy. */ @Environment(EnvType.CLIENT) public record Leaf(GuiEventListener component) implements ComponentPath { @Override public void applyFocus(boolean focused) { this.component.setFocused(focused); } } /** * The {@code Path} class represents a non-leaf component path in the hierarchy. */ @Environment(EnvType.CLIENT) public record Path(ContainerEventHandler component, ComponentPath childPath) implements ComponentPath { @Override public void applyFocus(boolean focused) { if (!focused) { this.component.setFocused(null); } else { this.component.setFocused(this.childPath.component()); } this.childPath.applyFocus(focused); } } }