package net.minecraft.client.gui.components; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.InputType; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.narration.NarratedElementType; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.navigation.CommonInputs; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.sounds.SoundManager; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.ARGB; import net.minecraft.util.Mth; @Environment(EnvType.CLIENT) public abstract class AbstractSliderButton extends AbstractWidget { private static final ResourceLocation SLIDER_SPRITE = ResourceLocation.withDefaultNamespace("widget/slider"); private static final ResourceLocation HIGHLIGHTED_SPRITE = ResourceLocation.withDefaultNamespace("widget/slider_highlighted"); private static final ResourceLocation SLIDER_HANDLE_SPRITE = ResourceLocation.withDefaultNamespace("widget/slider_handle"); private static final ResourceLocation SLIDER_HANDLE_HIGHLIGHTED_SPRITE = ResourceLocation.withDefaultNamespace("widget/slider_handle_highlighted"); protected static final int TEXT_MARGIN = 2; private static final int HANDLE_WIDTH = 8; private static final int HANDLE_HALF_WIDTH = 4; protected double value; private boolean canChangeValue; public AbstractSliderButton(int x, int y, int width, int height, Component message, double value) { super(x, y, width, height, message); this.value = value; } private ResourceLocation getSprite() { return this.isActive() && this.isFocused() && !this.canChangeValue ? HIGHLIGHTED_SPRITE : SLIDER_SPRITE; } private ResourceLocation getHandleSprite() { return !this.isActive() || !this.isHovered && !this.canChangeValue ? SLIDER_HANDLE_SPRITE : SLIDER_HANDLE_HIGHLIGHTED_SPRITE; } @Override protected MutableComponent createNarrationMessage() { return Component.translatable("gui.narrate.slider", this.getMessage()); } @Override public void updateWidgetNarration(NarrationElementOutput narrationElementOutput) { narrationElementOutput.add(NarratedElementType.TITLE, this.createNarrationMessage()); if (this.active) { if (this.isFocused()) { narrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.slider.usage.focused")); } else { narrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.slider.usage.hovered")); } } } @Override public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { Minecraft minecraft = Minecraft.getInstance(); guiGraphics.blitSprite(RenderType::guiTextured, this.getSprite(), this.getX(), this.getY(), this.getWidth(), this.getHeight(), ARGB.white(this.alpha)); guiGraphics.blitSprite( RenderType::guiTextured, this.getHandleSprite(), this.getX() + (int)(this.value * (this.width - 8)), this.getY(), 8, this.getHeight(), ARGB.white(this.alpha) ); int i = this.active ? 16777215 : 10526880; this.renderScrollingString(guiGraphics, minecraft.font, 2, i | Mth.ceil(this.alpha * 255.0F) << 24); } @Override public void onClick(double mouseX, double mouseY) { this.setValueFromMouse(mouseX); } @Override public void setFocused(boolean focused) { super.setFocused(focused); if (!focused) { this.canChangeValue = false; } else { InputType inputType = Minecraft.getInstance().getLastInputType(); if (inputType == InputType.MOUSE || inputType == InputType.KEYBOARD_TAB) { this.canChangeValue = true; } } } @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (CommonInputs.selected(keyCode)) { this.canChangeValue = !this.canChangeValue; return true; } else { if (this.canChangeValue) { boolean bl = keyCode == 263; if (bl || keyCode == 262) { float f = bl ? -1.0F : 1.0F; this.setValue(this.value + f / (this.width - 8)); return true; } } return false; } } private void setValueFromMouse(double mouseX) { this.setValue((mouseX - (this.getX() + 4)) / (this.width - 8)); } private void setValue(double value) { double d = this.value; this.value = Mth.clamp(value, 0.0, 1.0); if (d != this.value) { this.applyValue(); } this.updateMessage(); } @Override protected void onDrag(double mouseX, double mouseY, double dragX, double dragY) { this.setValueFromMouse(mouseX); super.onDrag(mouseX, mouseY, dragX, dragY); } @Override public void playDownSound(SoundManager handler) { } @Override public void onRelease(double mouseX, double mouseY) { super.playDownSound(Minecraft.getInstance().getSoundManager()); } protected abstract void updateMessage(); protected abstract void applyValue(); }