package net.minecraft.client.gui.components.events; import com.mojang.datafixers.util.Pair; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.ListIterator; import java.util.Optional; import java.util.function.BooleanSupplier; import java.util.function.Supplier; import javax.annotation.Nullable; import net.minecraft.client.gui.ComponentPath; import net.minecraft.client.gui.navigation.FocusNavigationEvent; import net.minecraft.client.gui.navigation.ScreenAxis; import net.minecraft.client.gui.navigation.ScreenDirection; import net.minecraft.client.gui.navigation.ScreenPosition; import net.minecraft.client.gui.navigation.ScreenRectangle; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import org.joml.Vector2i; @OnlyIn(Dist.CLIENT) public interface ContainerEventHandler extends GuiEventListener { List children(); default Optional getChildAt(double p_94730_, double p_94731_) { for (GuiEventListener guieventlistener : this.children()) { if (guieventlistener.isMouseOver(p_94730_, p_94731_)) { return Optional.of(guieventlistener); } } return Optional.empty(); } @Override default boolean mouseClicked(double p_94695_, double p_94696_, int p_94697_) { Optional optional = this.getChildAt(p_94695_, p_94696_); if (optional.isEmpty()) { return false; } else { GuiEventListener guieventlistener = optional.get(); if (guieventlistener.mouseClicked(p_94695_, p_94696_, p_94697_)) { this.setFocused(guieventlistener); if (p_94697_ == 0) { this.setDragging(true); } } return true; } } @Override default boolean mouseReleased(double p_94722_, double p_94723_, int p_94724_) { if (p_94724_ == 0 && this.isDragging()) { this.setDragging(false); if (this.getFocused() != null) { return this.getFocused().mouseReleased(p_94722_, p_94723_, p_94724_); } } return false; } @Override default boolean mouseDragged(double p_94699_, double p_94700_, int p_94701_, double p_94702_, double p_94703_) { return this.getFocused() != null && this.isDragging() && p_94701_ == 0 ? this.getFocused().mouseDragged(p_94699_, p_94700_, p_94701_, p_94702_, p_94703_) : false; } boolean isDragging(); void setDragging(boolean p_94720_); @Override default boolean mouseScrolled(double p_94686_, double p_94687_, double p_94688_, double p_299502_) { return this.getChildAt(p_94686_, p_94687_).filter(p_296182_ -> p_296182_.mouseScrolled(p_94686_, p_94687_, p_94688_, p_299502_)).isPresent(); } @Override default boolean keyPressed(int p_94710_, int p_94711_, int p_94712_) { return this.getFocused() != null && this.getFocused().keyPressed(p_94710_, p_94711_, p_94712_); } @Override default boolean keyReleased(int p_94715_, int p_94716_, int p_94717_) { return this.getFocused() != null && this.getFocused().keyReleased(p_94715_, p_94716_, p_94717_); } @Override default boolean charTyped(char p_94683_, int p_94684_) { return this.getFocused() != null && this.getFocused().charTyped(p_94683_, p_94684_); } @Nullable GuiEventListener getFocused(); void setFocused(@Nullable GuiEventListener p_94713_); @Override default void setFocused(boolean p_265504_) { } @Override default boolean isFocused() { return this.getFocused() != null; } @Nullable @Override default ComponentPath getCurrentFocusPath() { GuiEventListener guieventlistener = this.getFocused(); return guieventlistener != null ? ComponentPath.path(this, guieventlistener.getCurrentFocusPath()) : null; } @Nullable @Override default ComponentPath nextFocusPath(FocusNavigationEvent p_265668_) { GuiEventListener guieventlistener = this.getFocused(); if (guieventlistener != null) { ComponentPath componentpath = guieventlistener.nextFocusPath(p_265668_); if (componentpath != null) { return ComponentPath.path(this, componentpath); } } if (p_265668_ instanceof FocusNavigationEvent.TabNavigation focusnavigationevent$tabnavigation) { return this.handleTabNavigation(focusnavigationevent$tabnavigation); } else { return p_265668_ instanceof FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation ? this.handleArrowNavigation(focusnavigationevent$arrownavigation) : null; } } @Nullable private ComponentPath handleTabNavigation(FocusNavigationEvent.TabNavigation p_265354_) { boolean flag = p_265354_.forward(); GuiEventListener guieventlistener = this.getFocused(); List list = new ArrayList<>(this.children()); Collections.sort(list, Comparator.comparingInt(p_374572_ -> p_374572_.getTabOrderGroup())); int j = list.indexOf(guieventlistener); int i; if (guieventlistener != null && j >= 0) { i = j + (flag ? 1 : 0); } else if (flag) { i = 0; } else { i = list.size(); } ListIterator listiterator = list.listIterator(i); BooleanSupplier booleansupplier = flag ? listiterator::hasNext : listiterator::hasPrevious; Supplier supplier = flag ? listiterator::next : listiterator::previous; while (booleansupplier.getAsBoolean()) { GuiEventListener guieventlistener1 = supplier.get(); ComponentPath componentpath = guieventlistener1.nextFocusPath(p_265354_); if (componentpath != null) { return ComponentPath.path(this, componentpath); } } return null; } @Nullable private ComponentPath handleArrowNavigation(FocusNavigationEvent.ArrowNavigation p_265760_) { GuiEventListener guieventlistener = this.getFocused(); if (guieventlistener == null) { ScreenDirection screendirection = p_265760_.direction(); ScreenRectangle screenrectangle1 = this.getBorderForArrowNavigation(screendirection.getOpposite()); return ComponentPath.path(this, this.nextFocusPathInDirection(screenrectangle1, screendirection, null, p_265760_)); } else { ScreenRectangle screenrectangle = guieventlistener.getRectangle(); return ComponentPath.path(this, this.nextFocusPathInDirection(screenrectangle, p_265760_.direction(), guieventlistener, p_265760_)); } } @Nullable private ComponentPath nextFocusPathInDirection(ScreenRectangle p_265054_, ScreenDirection p_265167_, @Nullable GuiEventListener p_265476_, FocusNavigationEvent p_265762_) { ScreenAxis screenaxis = p_265167_.getAxis(); ScreenAxis screenaxis1 = screenaxis.orthogonal(); ScreenDirection screendirection = screenaxis1.getPositive(); int i = p_265054_.getBoundInDirection(p_265167_.getOpposite()); List list = new ArrayList<>(); for (GuiEventListener guieventlistener : this.children()) { if (guieventlistener != p_265476_) { ScreenRectangle screenrectangle = guieventlistener.getRectangle(); if (screenrectangle.overlapsInAxis(p_265054_, screenaxis1)) { int j = screenrectangle.getBoundInDirection(p_265167_.getOpposite()); if (p_265167_.isAfter(j, i)) { list.add(guieventlistener); } else if (j == i && p_265167_.isAfter(screenrectangle.getBoundInDirection(p_265167_), p_265054_.getBoundInDirection(p_265167_))) { list.add(guieventlistener); } } } } Comparator comparator = Comparator.comparing( p_264674_ -> p_264674_.getRectangle().getBoundInDirection(p_265167_.getOpposite()), p_265167_.coordinateValueComparator() ); Comparator comparator1 = Comparator.comparing( p_264676_ -> p_264676_.getRectangle().getBoundInDirection(screendirection.getOpposite()), screendirection.coordinateValueComparator() ); list.sort(comparator.thenComparing(comparator1)); for (GuiEventListener guieventlistener1 : list) { ComponentPath componentpath = guieventlistener1.nextFocusPath(p_265762_); if (componentpath != null) { return componentpath; } } return this.nextFocusPathVaguelyInDirection(p_265054_, p_265167_, p_265476_, p_265762_); } @Nullable private ComponentPath nextFocusPathVaguelyInDirection(ScreenRectangle p_265390_, ScreenDirection p_265687_, @Nullable GuiEventListener p_265498_, FocusNavigationEvent p_265048_) { ScreenAxis screenaxis = p_265687_.getAxis(); ScreenAxis screenaxis1 = screenaxis.orthogonal(); List> list = new ArrayList<>(); ScreenPosition screenposition = ScreenPosition.of(screenaxis, p_265390_.getBoundInDirection(p_265687_), p_265390_.getCenterInAxis(screenaxis1)); for (GuiEventListener guieventlistener : this.children()) { if (guieventlistener != p_265498_) { ScreenRectangle screenrectangle = guieventlistener.getRectangle(); ScreenPosition screenposition1 = ScreenPosition.of( screenaxis, screenrectangle.getBoundInDirection(p_265687_.getOpposite()), screenrectangle.getCenterInAxis(screenaxis1) ); if (p_265687_.isAfter(screenposition1.getCoordinate(screenaxis), screenposition.getCoordinate(screenaxis))) { long i = Vector2i.distanceSquared( screenposition.x(), screenposition.y(), screenposition1.x(), screenposition1.y() ); list.add(Pair.of(guieventlistener, i)); } } } list.sort(Comparator.comparingDouble(Pair::getSecond)); for (Pair pair : list) { ComponentPath componentpath = pair.getFirst().nextFocusPath(p_265048_); if (componentpath != null) { return componentpath; } } return null; } }