diff options
Diffstat (limited to 'src')
22 files changed, 669 insertions, 30 deletions
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java index cb80707..331f68b 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java @@ -1,6 +1,7 @@ package io.github.cottonmc.cotton.gui.client; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.LiteralText; import net.minecraft.text.Style; @@ -10,6 +11,7 @@ import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.impl.VisualLogger; import io.github.cottonmc.cotton.gui.impl.client.CottonScreenImpl; import io.github.cottonmc.cotton.gui.impl.client.MouseInputHandler; +import io.github.cottonmc.cotton.gui.impl.client.NarrationHelper; import io.github.cottonmc.cotton.gui.widget.WPanel; import io.github.cottonmc.cotton.gui.widget.WWidget; import org.jetbrains.annotations.Nullable; @@ -36,6 +38,8 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { @Nullable protected WWidget lastResponder = null; + + private final MouseInputHandler<CottonClientScreen> mouseInputHandler = new MouseInputHandler<>(this); public CottonClientScreen(GuiDescription description) { this(new LiteralText(""), description); @@ -46,7 +50,8 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { this.description = description; description.getRootPanel().validate(description); } - + + @Override public GuiDescription getDescription() { return description; } @@ -176,7 +181,7 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return true; - MouseInputHandler.onMouseDown(description, this, containerX, containerY, mouseButton); + mouseInputHandler.onMouseDown(containerX, containerY, mouseButton); return true; } @@ -187,7 +192,7 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { super.mouseReleased(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - MouseInputHandler.onMouseUp(description, this, containerX, containerY, mouseButton); + mouseInputHandler.onMouseUp(containerX, containerY, mouseButton); return true; } @@ -199,7 +204,7 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - MouseInputHandler.onMouseDrag(description, this, containerX, containerY, mouseButton, deltaX, deltaY); + mouseInputHandler.onMouseDrag(containerX, containerY, mouseButton, deltaX, deltaY); return true; } @@ -210,7 +215,7 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - MouseInputHandler.onMouseScroll(description, containerX, containerY, amount); + mouseInputHandler.onMouseScroll(containerX, containerY, amount); return true; } @@ -221,7 +226,7 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - MouseInputHandler.onMouseMove(description, containerX, containerY); + mouseInputHandler.onMouseMove(containerX, containerY); } @Override @@ -264,4 +269,9 @@ public class CottonClientScreen extends Screen implements CottonScreenImpl { return true; } + + @Override + protected void addElementNarrations(NarrationMessageBuilder builder) { + if (description != null) NarrationHelper.addNarrations(description.getRootPanel(), builder); + } } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java index 87d9453..953563c 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java @@ -1,6 +1,7 @@ package io.github.cottonmc.cotton.gui.client; import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.render.DiffuseLighting; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerEntity; @@ -8,12 +9,15 @@ import net.minecraft.text.LiteralText; import net.minecraft.text.Style; import net.minecraft.text.Text; +import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.SyncedGuiDescription; import io.github.cottonmc.cotton.gui.impl.VisualLogger; import io.github.cottonmc.cotton.gui.impl.client.CottonScreenImpl; import io.github.cottonmc.cotton.gui.impl.client.MouseInputHandler; +import io.github.cottonmc.cotton.gui.impl.client.NarrationHelper; import io.github.cottonmc.cotton.gui.widget.WPanel; import io.github.cottonmc.cotton.gui.widget.WWidget; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; import org.lwjgl.opengl.GL11; @@ -26,6 +30,7 @@ import org.lwjgl.opengl.GL11; public class CottonInventoryScreen<T extends SyncedGuiDescription> extends HandledScreen<T> implements CottonScreenImpl { protected SyncedGuiDescription description; @Nullable protected WWidget lastResponder = null; + private final MouseInputHandler<CottonInventoryScreen<T>> mouseInputHandler = new MouseInputHandler<>(this); /** * Constructs a new screen without a title. @@ -83,6 +88,12 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl VisualLogger.reset(); } + @ApiStatus.Internal + @Override + public GuiDescription getDescription() { + return description; + } + @Nullable @Override public WWidget getLastResponder() { @@ -187,7 +198,7 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - MouseInputHandler.onMouseDown(description, this, containerX, containerY, mouseButton); + mouseInputHandler.onMouseDown(containerX, containerY, mouseButton); return true; } @@ -197,7 +208,7 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl super.mouseReleased(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - MouseInputHandler.onMouseUp(description, this, containerX, containerY, mouseButton); + mouseInputHandler.onMouseUp(containerX, containerY, mouseButton); return true; } @@ -208,7 +219,7 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - MouseInputHandler.onMouseDrag(description, this, containerX, containerY, mouseButton, deltaX, deltaY); + mouseInputHandler.onMouseDrag(containerX, containerY, mouseButton, deltaX, deltaY); return true; } @@ -219,7 +230,7 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - MouseInputHandler.onMouseScroll(description, containerX, containerY, amount); + mouseInputHandler.onMouseScroll(containerX, containerY, amount); return true; } @@ -230,7 +241,7 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - MouseInputHandler.onMouseMove(description, containerX, containerY); + mouseInputHandler.onMouseMove(containerX, containerY); } @Override @@ -304,4 +315,9 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl return true; } + + @Override + protected void addElementNarrations(NarrationMessageBuilder builder) { + if (description != null) NarrationHelper.addNarrations(description.getRootPanel(), builder); + } } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/CottonScreenImpl.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/CottonScreenImpl.java index 2ef9632..cd215b3 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/CottonScreenImpl.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/CottonScreenImpl.java @@ -5,11 +5,14 @@ import net.fabricmc.api.Environment; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Style; +import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.widget.WWidget; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) public interface CottonScreenImpl { + GuiDescription getDescription(); + @Nullable WWidget getLastResponder(); diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/MouseInputHandler.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/MouseInputHandler.java index 45fc17f..055df75 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/MouseInputHandler.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/MouseInputHandler.java @@ -2,9 +2,9 @@ package io.github.cottonmc.cotton.gui.impl.client; import net.minecraft.client.gui.screen.Screen; -import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.widget.WWidget; import io.github.cottonmc.cotton.gui.widget.data.InputResult; +import io.github.cottonmc.cotton.gui.widget.data.ObservableProperty; import org.jetbrains.annotations.Nullable; import java.util.function.Function; @@ -12,10 +12,21 @@ import java.util.function.Function; /** * The implementation for mouse inputs. */ -public final class MouseInputHandler { - public static void onMouseDown(GuiDescription description, CottonScreenImpl screen, int containerX, int containerY, int mouseButton) { +public final class MouseInputHandler<S extends Screen & CottonScreenImpl> { + private final S screen; + private final ObservableProperty<WWidget> hovered = ObservableProperty.of(null); + + public MouseInputHandler(S screen) { + this.screen = screen; + hovered.addListener((property, from, to) -> { + if (from != null) from.setHovered(false); + if (to != null) to.setHovered(true); + }); + } + + public void onMouseDown(int containerX, int containerY, int mouseButton) { if (screen.getLastResponder() == null) { - WWidget lastResponder = description.getRootPanel().hit(containerX, containerY); + WWidget lastResponder = screen.getDescription().getRootPanel().hit(containerX, containerY); screen.setLastResponder(lastResponder); if (lastResponder != null) { runTree( @@ -28,7 +39,7 @@ public final class MouseInputHandler { } } - public static <S extends Screen & CottonScreenImpl> void onMouseUp(GuiDescription description, S screen, int containerX, int containerY, int mouseButton) { + public void onMouseUp(int containerX, int containerY, int mouseButton) { WWidget lastResponder = screen.getLastResponder(); if (lastResponder != null) { @@ -48,7 +59,7 @@ public final class MouseInputHandler { } } else { runTree( - description.getRootPanel().hit(containerX, containerY), + screen.getDescription().getRootPanel().hit(containerX, containerY), widget -> widget.onMouseUp(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), mouseButton) ); } @@ -56,7 +67,7 @@ public final class MouseInputHandler { screen.setLastResponder(null); } - public static <S extends Screen & CottonScreenImpl> void onMouseDrag(GuiDescription description, S screen, int containerX, int containerY, int mouseButton, double deltaX, double deltaY) { + public void onMouseDrag(int containerX, int containerY, int mouseButton, double deltaX, double deltaY) { WWidget lastResponder = screen.getLastResponder(); if (lastResponder != null) { @@ -68,22 +79,25 @@ public final class MouseInputHandler { if (containerX < 0 || containerY < 0 || containerX >= width || containerY >= height) return; runTree( - description.getRootPanel().hit(containerX, containerY), + screen.getDescription().getRootPanel().hit(containerX, containerY), widget -> widget.onMouseDrag(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), mouseButton, deltaX, deltaY) ); } } - public static void onMouseScroll(GuiDescription description, int containerX, int containerY, double amount) { + public void onMouseScroll(int containerX, int containerY, double amount) { runTree( - description.getRootPanel().hit(containerX, containerY), + screen.getDescription().getRootPanel().hit(containerX, containerY), widget -> widget.onMouseScroll(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), amount) ); } - public static void onMouseMove(GuiDescription description, int containerX, int containerY) { + public void onMouseMove(int containerX, int containerY) { + WWidget hit = screen.getDescription().getRootPanel().hit(containerX, containerY); + hovered.set(hit); + runTree( - description.getRootPanel().hit(containerX, containerY), + hit, widget -> widget.onMouseMove(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY()) ); } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationHelper.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationHelper.java new file mode 100644 index 0000000..54567be --- /dev/null +++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationHelper.java @@ -0,0 +1,49 @@ +package io.github.cottonmc.cotton.gui.impl.client; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; +import net.minecraft.text.TranslatableText; + +import io.github.cottonmc.cotton.gui.widget.WPanel; +import io.github.cottonmc.cotton.gui.widget.WWidget; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Environment(EnvType.CLIENT) +public final class NarrationHelper { + public static void addNarrations(WPanel rootPanel, NarrationMessageBuilder builder) { + List<WWidget> narratableWidgets = getAllWidgets(rootPanel) + .filter(WWidget::isNarratable) + .collect(Collectors.toList()); + + for (int i = 0, childCount = narratableWidgets.size(); i < childCount; i++) { + WWidget child = narratableWidgets.get(i); + if (!child.isFocused() && !child.isHovered()) continue; + + // replicates Screen.addElementNarrations + if (narratableWidgets.size() > 1) { + builder.put(NarrationPart.POSITION, new TranslatableText(NarrationMessages.Vanilla.SCREEN_POSITION_KEY, i + 1, childCount)); + + if (child.isFocused()) { + builder.put(NarrationPart.USAGE, NarrationMessages.Vanilla.COMPONENT_LIST_USAGE); + } + } + + child.addNarrations(builder.nextMessage()); + } + } + + private static Stream<WWidget> getAllWidgets(WPanel panel) { + return Stream.concat(Stream.of(panel), panel.streamChildren().flatMap(widget -> { + if (widget instanceof WPanel nested) { + return getAllWidgets(nested); + } + + return Stream.of(widget); + })); + } +} diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationMessages.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationMessages.java new file mode 100644 index 0000000..bc9ee48 --- /dev/null +++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationMessages.java @@ -0,0 +1,29 @@ +package io.github.cottonmc.cotton.gui.impl.client; + +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; + +public final class NarrationMessages { + public static final String ITEM_SLOT_TITLE_KEY = "widget.libgui.item_slot.narration.title"; + public static final String LABELED_SLIDER_TITLE_KEY = "widget.libgui.labeled_slider.narration.title"; + public static final Text PLAYER_INVENTORY_HOTBAR = new TranslatableText("widget.libgui.player_inventory.narration.hotbar"); + public static final Text SCROLL_BAR_TITLE = new TranslatableText("widget.libgui.scroll_bar.narration.title"); + public static final String SLIDER_MESSAGE_KEY = "widget.libgui.slider.narration.title"; + public static final Text SLIDER_USAGE = new TranslatableText("widget.libgui.slider.narration.usage"); + public static final String TAB_TITLE_KEY = "widget.libgui.tab.narration.title"; + public static final String TAB_POSITION_KEY = "widget.libgui.tab.narration.position"; + public static final String TEXT_FIELD_TITLE_KEY = "widget.libgui.text_field.narration.title"; + public static final String TEXT_FIELD_SUGGESTION_KEY = "widget.libgui.text_field.narration.suggestion"; + public static final String TOGGLE_BUTTON_NAMED_KEY = "widget.libgui.toggle_button.narration.named"; + public static final Text TOGGLE_BUTTON_OFF = new TranslatableText("widget.libgui.toggle_button.narration.off"); + public static final Text TOGGLE_BUTTON_ON = new TranslatableText("widget.libgui.toggle_button.narration.on"); + public static final String TOGGLE_BUTTON_UNNAMED_KEY = "widget.libgui.toggle_button.narration.unnamed"; + + public static final class Vanilla { + public static final Text BUTTON_USAGE_FOCUSED = new TranslatableText("narration.button.usage.focused"); + public static final Text BUTTON_USAGE_HOVERED = new TranslatableText("narration.button.usage.hovered"); + public static final Text COMPONENT_LIST_USAGE = new TranslatableText("narration.component_list.usage"); + public static final Text INVENTORY = new TranslatableText("container.inventory"); + public static final String SCREEN_POSITION_KEY = "narrator.position.screen"; + } +} diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java index 7fda1d9..2af6092 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java @@ -2,8 +2,12 @@ package io.github.cottonmc.cotton.gui.widget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; +import net.minecraft.text.TranslatableText; import net.minecraft.util.math.MathHelper; +import io.github.cottonmc.cotton.gui.impl.client.NarrationMessages; import io.github.cottonmc.cotton.gui.widget.data.Axis; import io.github.cottonmc.cotton.gui.widget.data.InputResult; import org.jetbrains.annotations.Nullable; @@ -342,6 +346,13 @@ public abstract class WAbstractSlider extends WWidget { return dragging; } + @Environment(EnvType.CLIENT) + @Override + public void addNarrations(NarrationMessageBuilder builder) { + builder.put(NarrationPart.TITLE, new TranslatableText(NarrationMessages.SLIDER_MESSAGE_KEY, value, min, max)); + builder.put(NarrationPart.USAGE, NarrationMessages.SLIDER_USAGE); + } + /** * Tests if the key should decrease sliders with the specified direction. * diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java index 15cd6bb..533e436 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java @@ -3,6 +3,8 @@ package io.github.cottonmc.cotton.gui.widget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.client.util.math.MatrixStack; @@ -12,6 +14,7 @@ import net.minecraft.util.Identifier; import io.github.cottonmc.cotton.gui.client.LibGui; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; +import io.github.cottonmc.cotton.gui.impl.client.NarrationMessages; import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; import io.github.cottonmc.cotton.gui.widget.data.InputResult; import io.github.cottonmc.cotton.gui.widget.icon.Icon; @@ -220,6 +223,20 @@ public class WButton extends WWidget { } @Environment(EnvType.CLIENT) + @Override + public void addNarrations(NarrationMessageBuilder builder) { + builder.put(NarrationPart.TITLE, ClickableWidget.getNarrationMessage(getLabel())); + + if (isEnabled()) { + if (isFocused()) { + builder.put(NarrationPart.USAGE, NarrationMessages.Vanilla.BUTTON_USAGE_FOCUSED); + } else if (isHovered()) { + builder.put(NarrationPart.USAGE, NarrationMessages.Vanilla.BUTTON_USAGE_HOVERED); + } + } + } + + @Environment(EnvType.CLIENT) static Identifier getTexture() { return LibGui.isDarkMode() ? DARK_WIDGETS_LOCATION : ClickableWidget.WIDGETS_TEXTURE; } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java index a99028c..a05b364 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java @@ -3,16 +3,23 @@ package io.github.cottonmc.cotton.gui.widget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.ValidatedSlot; import io.github.cottonmc.cotton.gui.client.BackgroundPainter; import io.github.cottonmc.cotton.gui.impl.VisualLogger; +import io.github.cottonmc.cotton.gui.impl.client.NarrationMessages; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; import io.github.cottonmc.cotton.gui.widget.icon.Icon; import org.jetbrains.annotations.Nullable; @@ -75,10 +82,12 @@ public class WItemSlot extends WWidget { private boolean insertingAllowed = true; private boolean takingAllowed = true; private int focusedSlot = -1; + private int hoveredSlot = -1; private Predicate<ItemStack> filter = DEFAULT_FILTER; private final Set<ChangeListener> listeners = new HashSet<>(); public WItemSlot(Inventory inventory, int startIndex, int slotsWide, int slotsHigh, boolean big) { + this(); this.inventory = inventory; this.startIndex = startIndex; this.slotsWide = slotsWide; @@ -87,7 +96,12 @@ public class WItemSlot extends WWidget { //this.ltr = ltr; } - private WItemSlot() {} + private WItemSlot() { + hoveredProperty().addListener((property, from, to) -> { + assert to != null; + if (!to) hoveredSlot = -1; + }); + } public static WItemSlot of(Inventory inventory, int index) { WItemSlot w = new WItemSlot(); @@ -124,7 +138,12 @@ public class WItemSlot extends WWidget { * @see WPlayerInvPanel */ public static WItemSlot ofPlayerStorage(Inventory inventory) { - WItemSlot w = new WItemSlot(); + WItemSlot w = new WItemSlot() { + @Override + protected Text getNarrationName() { + return inventory instanceof PlayerInventory inv ? inv.getDisplayName() : NarrationMessages.Vanilla.INVENTORY; + } + }; w.inventory = inventory; w.startIndex = 9; w.slotsWide = 9; @@ -415,6 +434,14 @@ public class WItemSlot extends WWidget { } @Override + public InputResult onMouseMove(int x, int y) { + int slotX = x / 18; + int slotY = y / 18; + hoveredSlot = slotX + slotY * slotsWide; + return InputResult.PROCESSED; + } + + @Override public void onHidden() { super.onHidden(); @@ -429,6 +456,34 @@ public class WItemSlot extends WWidget { backgroundPainter = BackgroundPainter.SLOT; } + @Environment(EnvType.CLIENT) + @Override + public void addNarrations(NarrationMessageBuilder builder) { + List<Text> parts = new ArrayList<>(); + Text name = getNarrationName(); + if (name != null) parts.add(name); + + if (focusedSlot >= 0) { + parts.add(new TranslatableText(NarrationMessages.ITEM_SLOT_TITLE_KEY, focusedSlot + 1, slotsWide * slotsHigh)); + } else if (hoveredSlot >= 0) { + parts.add(new TranslatableText(NarrationMessages.ITEM_SLOT_TITLE_KEY, hoveredSlot + 1, slotsWide * slotsHigh)); + } + + builder.put(NarrationPart.TITLE, parts.toArray(new Text[0])); + } + + /** + * Returns a "narration name" for this slot. + * It's narrated before the slot index. One example of a narration name would be "hotbar" for the player's hotbar. + * + * @return the narration name, or null if there's none for this slot + * @since 4.2.0 + */ + @Nullable + protected Text getNarrationName() { + return null; + } + /** * A listener for changes in an item slot. * diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java index 5c6b2da..83f0700 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java @@ -5,6 +5,8 @@ import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.LiteralText; import net.minecraft.text.Style; @@ -261,4 +263,10 @@ public class WLabel extends WWidget { this.verticalAlignment = align; return this; } + + @Environment(EnvType.CLIENT) + @Override + public void addNarrations(NarrationMessageBuilder builder) { + builder.put(NarrationPart.TITLE, text); + } } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java index 911d547..2f972ff 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java @@ -2,12 +2,16 @@ package io.github.cottonmc.cotton.gui.widget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.math.Vec3f; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; +import io.github.cottonmc.cotton.gui.impl.client.NarrationMessages; import io.github.cottonmc.cotton.gui.widget.data.Axis; import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; import org.jetbrains.annotations.Nullable; @@ -212,6 +216,17 @@ public class WLabeledSlider extends WAbstractSlider { ScreenDrawing.texturedRect(matrices, x + halfWidth, y, halfWidth, 20, texture, buttonEndLeft, buttonTop, 200 * px, buttonTop + buttonHeight, 0xFFFFFFFF); } + @Environment(EnvType.CLIENT) + @Override + public void addNarrations(NarrationMessageBuilder builder) { + if (getLabel() != null) { + builder.put(NarrationPart.TITLE, new TranslatableText(NarrationMessages.LABELED_SLIDER_TITLE_KEY, getLabel(), value, min, max)); + builder.put(NarrationPart.USAGE, NarrationMessages.SLIDER_USAGE); + } else { + super.addNarrations(builder); + } + } + /** * A label updater updates the label of a slider based on the current value. * diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java index 912c1c0..204ea93 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java @@ -7,6 +7,7 @@ import net.minecraft.client.util.math.MatrixStack; import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.client.BackgroundPainter; import io.github.cottonmc.cotton.gui.widget.data.Insets; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.AbstractList; @@ -247,6 +248,17 @@ public abstract class WPanel extends WWidget { } } + /** + * {@return a stream of all visible widgets in this panel} + * + * @experimental + * @since 4.2.0 + */ + @ApiStatus.Experimental + public final Stream<WWidget> streamChildren() { + return children.stream(); + } + @Override |
