aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java7
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java7
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationHelper.java49
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationMessages.java29
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java11
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java18
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java30
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WLabeledSlider.java15
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java11
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java9
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java10
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java17
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java15
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java26
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java25
-rw-r--r--src/main/resources/assets/libgui/lang/en_us.json20
16 files changed, 293 insertions, 6 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 674fd77..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;
@@ -267,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 01a5092..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;
@@ -13,6 +14,7 @@ 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;
@@ -313,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/NarrationHelper.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NarrationHelper.java
new file mode 100644
index 0000000..9b44210
--- /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)
+ .filter(WWidget::isFocused) // TODO: || isHovered
+ .collect(Collectors.toList());
+
+ for (int i = 0, childCount = narratableWidgets.size(); i < childCount; i++) {
+ WWidget child = narratableWidgets.get(i);
+
+ // replicates Screen.addElementNarrations
+ if (narratableWidgets.size() > 1) {
+ builder.put(NarrationPart.POSITION, new TranslatableText(NarrationMessages.Vanilla.SCREEN_POSITION_KEY, i + 1, childCount));
+
+ if (child.isFocused()) { // TODO: this check is currently useless but will be used with hovering
+ 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..c6fdfc2 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,21 @@ 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 {
+ // TODO: hovering, again
+ 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..18c812d 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,22 @@ 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.icon.Icon;
import org.jetbrains.annotations.Nullable;
@@ -124,7 +130,12 @@ public class WItemSlot extends WWidget {
* @see WPlayerInvPanel
*/
public static WItemSlot ofPlayerStorage(Inventory inventory) {
- WItemSlot w = new WItemSlot();
+ WItemSlot w = new WItemSlot() {
+ @Override
+ Text getExtraNarrationMessage() {
+ return inventory instanceof PlayerInventory inv ? inv.getDisplayName() : NarrationMessages.Vanilla.INVENTORY;
+ }
+ };
w.inventory = inventory;
w.startIndex = 9;
w.slotsWide = 9;
@@ -429,6 +440,23 @@ public class WItemSlot extends WWidget {
backgroundPainter = BackgroundPainter.SLOT;
}
+ @Environment(EnvType.CLIENT)
+ @Override
+ public void addNarrations(NarrationMessageBuilder builder) {
+ if (focusedSlot >= 0) {
+ List<Text> parts = new ArrayList<>();
+ Text extra = getExtraNarrationMessage();
+ if (extra != null) parts.add(extra);
+ parts.add(new TranslatableText(NarrationMessages.ITEM_SLOT_TITLE_KEY, focusedSlot + 1, slotsWide * slotsHigh));
+ builder.put(NarrationPart.TITLE, parts.toArray(new Text[0]));
+ }
+ }
+
+ @Nullable
+ Text getExtraNarrationMessage() {
+ return null;
+ }
+
/**
* A listener for changes in an item slot.
*
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..3358d0a 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,16 @@ public abstract class WPanel extends WWidget {
}
}
+ /**
+ * {@return a stream of all visible widgets in this panel}
+ *
+ * @since 4.2.0
+ */
+ @ApiStatus.Experimental
+ public final Stream<WWidget> streamChildren() {
+ return children.stream();
+ }
+
@Override
public String toString() {
return getClass().getSimpleName() + " {\n" + children.stream().map(Object::toString).map(x -> x + ",").flatMap(x -> Stream.of(x.split("\n")).filter(y -> !y.isEmpty()).map(y -> "\t" + y)).collect(Collectors.joining("\n")) + "\n}";
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java
index c105924..d86e40a 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPlayerInvPanel.java
@@ -3,9 +3,11 @@ package io.github.cottonmc.cotton.gui.widget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.text.Text;
import io.github.cottonmc.cotton.gui.GuiDescription;
import io.github.cottonmc.cotton.gui.client.BackgroundPainter;
+import io.github.cottonmc.cotton.gui.impl.client.NarrationMessages;
import org.jetbrains.annotations.Nullable;
/**
@@ -54,7 +56,12 @@ public class WPlayerInvPanel extends WPlainPanel {
}
inv = WItemSlot.ofPlayerStorage(playerInventory);
- hotbar = WItemSlot.of(playerInventory, 0, 9, 1);
+ hotbar = new WItemSlot(playerInventory, 0, 9, 1, false) {
+ @Override
+ Text getExtraNarrationMessage() {
+ return NarrationMessages.PLAYER_INVENTORY_HOTBAR;
+ }
+ };
this.add(inv, 0, y);
this.add(hotbar, 0, y + 58);
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java
index 0eb7818..2882dbd 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java
@@ -2,10 +2,13 @@ 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 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.Axis;
import io.github.cottonmc.cotton.gui.widget.data.InputResult;
@@ -264,4 +267,11 @@ public class WScrollBar extends WWidget {
}
if (this.value<0) this.value = 0;
}
+
+ @Environment(EnvType.CLIENT)
+ @Override
+ public void addNarrations(NarrationMessageBuilder builder) {
+ builder.put(NarrationPart.TITLE, NarrationMessages.SCROLL_BAR_TITLE);
+ builder.put(NarrationPart.USAGE, NarrationMessages.SLIDER_USAGE);
+ }
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java
index 2ee7e92..88c0db5 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java
@@ -4,16 +4,20 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
+import net.minecraft.client.gui.screen.narration.NarrationPart;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import io.github.cottonmc.cotton.gui.client.BackgroundPainter;
import io.github.cottonmc.cotton.gui.client.LibGui;
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
import io.github.cottonmc.cotton.gui.impl.LibGuiCommon;
+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 io.github.cottonmc.cotton.gui.widget.data.InputResult;
@@ -354,10 +358,23 @@ public class WTabPanel extends WPanel {
}
}
+ @Environment(EnvType.CLIENT)
@Override
public void addTooltip(TooltipBuilder tooltip) {
data.addTooltip(tooltip);
}
+
+ @Environment(EnvType.CLIENT)
+ @Override
+ public void addNarrations(NarrationMessageBuilder builder) {
+ Text label = data.getTitle(); // TODO: a separate narration message
+
+ if (label != null) {
+ builder.put(NarrationPart.TITLE, new TranslatableText(NarrationMessages.TAB_TITLE_KEY, label));
+ }
+
+ builder.put(NarrationPart.POSITION, new TranslatableText(NarrationMessages.TAB_POSITION_KEY, tabWidgets.indexOf(this) + 1, tabWidgets.size()));
+ }
}
/**
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java
index 60ae5d4..e9e2692 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java
@@ -7,6 +7,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.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
@@ -16,11 +18,13 @@ import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
import io.github.cottonmc.cotton.gui.client.BackgroundPainter;
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.InputResult;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
@@ -431,7 +435,16 @@ public class WTextField extends WWidget {
}
}
}
-
+
+ @Override
+ public void addNarrations(NarrationMessageBuilder builder) {
+ builder.put(NarrationPart.TITLE, new TranslatableText(NarrationMessages.TEXT_FIELD_TITLE_KEY, text));
+
+ if (suggestion != null) {
+ builder.put(NarrationPart.HINT, new TranslatableText(NarrationMessages.TEXT_FIELD_SUGGESTION_KEY, suggestion));
+ }
+ }
+
/**
* From an X offset past the left edge of a TextRenderer.draw, finds out what the closest caret
* position (division between letters) is.
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java
index 8953f4d..d4fb728 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java
@@ -3,15 +3,19 @@ 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.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
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.LibGuiCommon;
+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.data.Texture;
import org.jetbrains.annotations.Nullable;
@@ -202,4 +206,26 @@ public class WToggleButton extends WWidget {
this.focusImage = focusImage;
return this;
}
+
+ @Environment(EnvType.CLIENT)
+ @Override
+ public void addNarrations(NarrationMessageBuilder builder) {
+ Text onOff = isOn ? NarrationMessages.TOGGLE_BUTTON_ON : NarrationMessages.TOGGLE_BUTTON_OFF;
+ Text title;
+
+ if (label != null) {
+ title = new TranslatableText(NarrationMessages.TOGGLE_BUTTON_NAMED_KEY, label, onOff);
+ } else {
+ title = new TranslatableText(NarrationMessages.TOGGLE_BUTTON_UNNAMED_KEY, onOff);
+ }
+
+ builder.put(NarrationPart.TITLE, title);
+
+ if (isFocused()) {
+ builder.put(NarrationPart.USAGE, NarrationMessages.Vanilla.BUTTON_USAGE_FOCUSED);
+ } else {
+ // TODO: hovering, again
+ builder.put(NarrationPart.USAGE, NarrationMessages.Vanilla.BUTTON_USAGE_HOVERED);
+ }
+ }
}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java
index 30e14d5..3beacee 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java
@@ -6,6 +6,7 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.util.math.MatrixStack;
import io.github.cottonmc.cotton.gui.GuiDescription;
@@ -465,6 +466,30 @@ public class WWidget {
}
/**
+ * {@return whether this widget can be narrated}
+ *
+ * @see #addNarrations(NarrationMessageBuilder)
+ * @since 4.2.0
+ */
+ public boolean isNarratable() {
+ return true;
+ }
+
+ /**
+ * Adds the narrations of this widget to a narration builder.
+ * Narrations will only apply if this widget {@linkplain #isNarratable() is narratable}.
+ *
+ * <p>As of LibGui 4.2.0, the widget also needs to be {@linkplain #canFocus() focusable}, but that is
+ * planned to be changed in the future to include "hoverable" widgets.
+ *
+ * @param builder the narration builder, cannot be null
+ * @since 4.2.0
+ */
+ @Environment(EnvType.CLIENT)
+ public void addNarrations(NarrationMessageBuilder builder) {
+ }
+
+ /**
* Tests if the provided key code is an activation key for widgets.
*
* <p>The activation keys are Enter, keypad Enter, and Space.
diff --git a/src/main/resources/assets/libgui/lang/en_us.json b/src/main/resources/assets/libgui/lang/en_us.json
index 5ed8bfb..4f0f9a1 100644
--- a/src/main/resources/assets/libgui/lang/en_us.json
+++ b/src/main/resources/assets/libgui/lang/en_us.json
@@ -1,4 +1,18 @@
{
- "options.libgui.libgui_settings": "LibGui Settings",
- "option.libgui.darkmode": "Dark Mode"
-}
+ "options.libgui.libgui_settings": "LibGui Settings",
+ "option.libgui.darkmode": "Dark Mode",
+ "widget.libgui.item_slot.narration.title": "Item slot %s out of %s",
+ "widget.libgui.labeled_slider.narration.title": "%s slider: at %s between %s and %s",
+ "widget.libgui.player_inventory.narration.hotbar": "Hotbar",
+ "widget.libgui.scroll_bar.narration.title": "Scroll bar",
+ "widget.libgui.slider.narration.title": "Slider: at %s between %s and %s",
+ "widget.libgui.slider.narration.usage": "Move by dragging or with arrow keys",
+ "widget.libgui.tab.narration.title": "%s tab",
+ "widget.libgui.tab.narration.position": "Tab %s out of %s",
+ "widget.libgui.text_field.narration.title": "Text field: %s",
+ "widget.libgui.text_field.narration.suggestion": "Suggestion: %s",
+ "widget.libgui.toggle_button.narration.unnamed": "Toggle button: %s",
+ "widget.libgui.toggle_button.narration.named": "Toggle button: %s (%s)",
+ "widget.libgui.toggle_button.narration.on": "On",
+ "widget.libgui.toggle_button.narration.off": "Off"
+}