Skip to content

Commit

Permalink
完成声音包 GUI 界面的设计
Browse files Browse the repository at this point in the history
  • Loading branch information
TartaricAcid committed Oct 19, 2023
1 parent 2b2829c commit 620bab5
Show file tree
Hide file tree
Showing 9 changed files with 455 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.github.tartaricacid.touhoulittlemaid.client.download.pojo.DownloadInfo;
import com.github.tartaricacid.touhoulittlemaid.client.gui.entity.ModelDownloadGui;
import com.github.tartaricacid.touhoulittlemaid.client.gui.entity.model.MaidModelGui;
import com.github.tartaricacid.touhoulittlemaid.client.gui.sound.MaidSoundPackGui;
import com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button.MaidTabButton;
import com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button.ScheduleButton;
import com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button.TaskButton;
Expand Down Expand Up @@ -335,6 +336,7 @@ private void addDownloadButton() {
});
soundDownload = new ImageButton(leftPos + 41, topPos + 217, 20, 20, 21, 86, 20, BUTTON,
(b) -> {
Minecraft.getInstance().setScreen(new MaidSoundPackGui(maid));
});
this.addRenderableWidget(modelDownload);
this.addRenderableWidget(soundDownload);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package com.github.tartaricacid.touhoulittlemaid.client.gui.sound;

import com.github.tartaricacid.touhoulittlemaid.TouhouLittleMaid;
import com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button.FlatColorButton;
import com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button.SoundElementButton;
import com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button.SoundPackButton;
import com.github.tartaricacid.touhoulittlemaid.client.sound.CustomSoundLoader;
import com.github.tartaricacid.touhoulittlemaid.client.sound.data.MaidSoundInstance;
import com.github.tartaricacid.touhoulittlemaid.client.sound.pojo.SoundPackInfo;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.github.tartaricacid.touhoulittlemaid.init.InitSounds;
import com.github.tartaricacid.touhoulittlemaid.network.NetworkHandler;
import com.github.tartaricacid.touhoulittlemaid.network.message.SetMaidSoundIdMessage;
import com.github.tartaricacid.touhoulittlemaid.util.ParseI18n;
import com.mojang.blaze3d.audio.SoundBuffer;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.Util;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.ConfirmLinkScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.commons.lang3.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class MaidSoundPackGui extends Screen {
private static final ResourceLocation ICON = new ResourceLocation(TouhouLittleMaid.MOD_ID, "textures/gui/maid_custom_sound.png");
private final int packPerSize = 4;
private final int soundPerSize = 13;
private final EntityMaid maid;
private String selectSoundId = null;
private int startX;
private int startY;
private int packPage = 0;
private int soundPage = 0;
private int packMaxPage = 0;
private int soundMaxPage = 0;

public MaidSoundPackGui(EntityMaid maid) {
super(Component.literal("Maid Custom Sound Pack GUI"));
this.maid = maid;
}

@Override
protected void init() {
this.clearWidgets();

this.startX = (width - 400) / 2;
this.startY = (height - 220) / 2;
this.packMaxPage = (CustomSoundLoader.CACHE.size() - 1) / packPerSize;
this.soundMaxPage = 0;

int yOffset = 19;
List<String> soundPackIds = List.copyOf(CustomSoundLoader.CACHE.keySet());
int startPackIndex = packPage * packPerSize;
if (startPackIndex >= soundPackIds.size()) {
this.packPage = 0;
startPackIndex = 0;
}
int endPackIndex = Math.min(soundPackIds.size(), startPackIndex + packPerSize);
for (int i = startPackIndex; i < endPackIndex; i++) {
String soundId = soundPackIds.get(i);
SoundPackInfo info = CustomSoundLoader.getSoundCache(soundId).getInfo();
SoundPackButton button = new SoundPackButton(startX + 5, startY + yOffset, info, b -> {
this.selectSoundId = soundId;
this.soundPage = 0;
this.init();
});
if (StringUtils.isNotBlank(info.getDescription())) {
MutableComponent description = ParseI18n.parse(info.getDescription());
button.setTooltips(Collections.singletonList(description));
}
if (soundId.equals(selectSoundId)) {
button.setSelect(true);
}
this.addRenderableWidget(button);
yOffset += 45;
}

if (StringUtils.isNotBlank(selectSoundId) && CustomSoundLoader.CACHE.containsKey(selectSoundId)) {
yOffset = 41;
boolean otherColor = false;
Map<ResourceLocation, List<SoundBuffer>> buffers = CustomSoundLoader.getSoundCache(selectSoundId).getBuffers();
List<ResourceLocation> soundIds = List.copyOf(buffers.keySet());
this.soundMaxPage = (buffers.size() - 1) / soundPerSize;
int startSoundIndex = soundPage * soundPerSize;
if (startSoundIndex >= soundIds.size()) {
this.soundPage = 0;
startSoundIndex = 0;
}
int endSoundIndex = Math.min(soundIds.size(), startSoundIndex + soundPerSize);
for (int i = startSoundIndex; i < endSoundIndex; i++) {
ResourceLocation soundEvent = soundIds.get(i);
this.addRenderableWidget(new SoundElementButton(startX + 245, startY + yOffset, 152, 12, soundEvent, buffers.get(soundEvent), otherColor, (b) -> {
SoundElementButton soundButton = (SoundElementButton) b;
SoundEvent event = ForgeRegistries.SOUND_EVENTS.getValue(soundButton.getSoundEvent());
if (minecraft != null && event != null) {
minecraft.getSoundManager().play(new MaidSoundInstance(event, this.selectSoundId, this.maid));
}
}).setTooltips("tooltips.touhou_little_maid.custom_sound.play_sound"));
otherColor = !otherColor;
yOffset += 12;
}
}

this.addRenderableWidget(new FlatColorButton(startX + 245, startY + 19, 110, 18, Component.translatable("gui.touhou_little_maid.custom_sound.pack.apply"), (b) -> {
if (StringUtils.isNotBlank(selectSoundId) && CustomSoundLoader.CACHE.containsKey(selectSoundId)) {
NetworkHandler.CHANNEL.sendToServer(new SetMaidSoundIdMessage(this.maid.getId(), this.selectSoundId));
}
}));
this.addRenderableWidget(new FlatColorButton(startX + 358, startY + 19, 18, 18, Component.empty(), (b) -> {
if (StringUtils.isNotBlank(selectSoundId) && CustomSoundLoader.CACHE.containsKey(selectSoundId)) {
String url = CustomSoundLoader.getSoundCache(selectSoundId).getInfo().getUrl();
if (StringUtils.isNotBlank(url) && minecraft != null) {
minecraft.setScreen(new ConfirmLinkScreen(yes -> {
if (yes) {
Util.getPlatform().openUri(url);
}
minecraft.setScreen(this);
}, url, false));
}
}
}).setTooltips("tooltips.touhou_little_maid.custom_sound.open_url"));
this.addRenderableWidget(new FlatColorButton(startX + 379, startY + 19, 18, 18, Component.empty(), (b) -> {
if (minecraft != null) {
minecraft.getSoundManager().play(new MaidSoundInstance(InitSounds.MAID_CREDIT.get(), this.selectSoundId, this.maid));
}
}).setTooltips("tooltips.touhou_little_maid.custom_sound.credit"));

this.addRenderableWidget(new FlatColorButton(startX + 5, startY + 201, 32, 16, Component.literal("<"), (b) -> {
if (this.packPage > 0) {
packPage--;
this.init();
}
}));
this.addRenderableWidget(new FlatColorButton(startX + 203, startY + 201, 32, 16, Component.literal(">"), (b) -> {
if ((packPage + 1) * packPerSize < CustomSoundLoader.CACHE.size()) {
packPage++;
this.init();
}
}));

this.addRenderableWidget(new FlatColorButton(startX + 245, startY + 201, 16, 16, Component.literal("<"), (b) -> {
if (this.soundPage > 0) {
soundPage--;
this.init();
}
}));
this.addRenderableWidget(new FlatColorButton(startX + 381, startY + 201, 16, 16, Component.literal(">"), (b) -> {
if (StringUtils.isNotBlank(selectSoundId) && CustomSoundLoader.CACHE.containsKey(selectSoundId)) {
Map<ResourceLocation, List<SoundBuffer>> buffers = CustomSoundLoader.getSoundCache(selectSoundId).getBuffers();
if ((soundPage + 1) * soundPerSize < buffers.size()) {
soundPage++;
this.init();
}
}
}));
}

@Override
public void render(GuiGraphics graphics, int pMouseX, int pMouseY, float pPartialTick) {
this.renderBackground(graphics);
graphics.fill(startX, startY, startX + 240, startY + 220, 0xFF2A2A2A);
graphics.drawCenteredString(font, Component.translatable("gui.touhou_little_maid.custom_sound.pack.title"), startX + 120, startY + 6, 0xFFFFFF);
graphics.drawCenteredString(font, String.format("%d/%d", packPage + 1, packMaxPage + 1), startX + 120, startY + 206, 0xBBBBBB);

graphics.fill(startX + 242, startY, startX + 400, startY + 220, 0xFF2A2A2A);
graphics.drawCenteredString(font, Component.translatable("gui.touhou_little_maid.custom_sound.sounds.preview"), startX + 321, startY + 6, 0xFFFFFF);
graphics.drawCenteredString(font, String.format("%d/%d", soundPage + 1, soundMaxPage + 1), startX + 321, startY + 206, 0xBBBBBB);

super.render(graphics, pMouseX, pMouseY, pPartialTick);

RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, ICON);
graphics.blit(ICON, startX + 359, startY + 20, 0, 0, 16, 16, 256, 256);
graphics.blit(ICON, startX + 380, startY + 20, 16, 0, 16, 16, 256, 256);

this.renderables.stream().filter(b -> b instanceof FlatColorButton).forEach(b -> ((FlatColorButton) b).renderToolTip(graphics, this, pMouseX, pMouseY));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;

import java.util.Collections;
import java.util.List;


public class FlatColorButton extends Button {
private boolean isSelect = false;
private List<Component> tooltips;

public FlatColorButton(int pX, int pY, int pWidth, int pHeight, Component pMessage, OnPress pOnPress) {
super(pX, pY, pWidth, pHeight, pMessage, pOnPress, DEFAULT_NARRATION);
}

public FlatColorButton setTooltips(String key) {
tooltips = Collections.singletonList(Component.translatable(key));
return this;
}

public FlatColorButton setTooltips(List<Component> tooltips) {
this.tooltips = tooltips;
return this;
}

public void renderToolTip(GuiGraphics graphics, Screen screen, int pMouseX, int pMouseY) {
if (this.isHovered && tooltips != null) {
graphics.renderComponentTooltip(screen.getMinecraft().font, tooltips, pMouseX, pMouseY);
}
}

@Override
public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float pPartialTick) {
Minecraft minecraft = Minecraft.getInstance();
Font font = minecraft.font;
if (isSelect) {
graphics.fillGradient(this.getX(), this.getY(), this.getX() + this.width, this.getY() + this.height, 0xff_1E90FF, 0xff_1E90FF);
} else {
graphics.fillGradient(this.getX(), this.getY(), this.getX() + this.width, this.getY() + this.height, 0xff_434242, 0xff_434242);
}
if (this.isHoveredOrFocused()) {
graphics.fillGradient(this.getX(), this.getY() + 1, this.getX() + 1, this.getY() + this.height - 1, 0xff_F3EFE0, 0xff_F3EFE0);
graphics.fillGradient(this.getX(), this.getY(), this.getX() + this.width, this.getY() + 1, 0xff_F3EFE0, 0xff_F3EFE0);
graphics.fillGradient(this.getX() + this.width - 1, this.getY() + 1, this.getX() + this.width, this.getY() + this.height - 1, 0xff_F3EFE0, 0xff_F3EFE0);
graphics.fillGradient(this.getX(), this.getY() + this.height - 1, this.getX() + this.width, this.getY() + this.height, 0xff_F3EFE0, 0xff_F3EFE0);
}
int i = getFGColor();
this.renderString(graphics, minecraft.font, i | Mth.ceil(this.alpha * 255.0F) << 24);
}

@Override
public void renderString(GuiGraphics graphics, Font font, int pColor) {
graphics.drawCenteredString(font, this.getMessage(), this.getX() + this.width / 2, this.getY() + (this.height - 8) / 2, 0xF3EFE0);
}

public void setSelect(boolean select) {
isSelect = select;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button;

import com.mojang.blaze3d.audio.SoundBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;

import java.util.List;

public class SoundElementButton extends FlatColorButton {
private final ResourceLocation soundEvent;
private final int soundCount;
private final boolean otherColor;

public SoundElementButton(int pX, int pY, int pWidth, int pHeight, ResourceLocation soundEvent, List<SoundBuffer> sounds, boolean otherColor, OnPress pOnPress) {
super(pX, pY, pWidth, pHeight, Component.translatable(soundEvent.toLanguageKey("button")), pOnPress);
this.soundEvent = soundEvent;
this.soundCount = sounds.size();
this.otherColor = otherColor;
}

@Override
public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float pPartialTick) {
Minecraft minecraft = Minecraft.getInstance();
if (otherColor) {
graphics.fillGradient(this.getX(), this.getY(), this.getX() + this.width, this.getY() + this.height, 0x5f_9e9e9e, 0x5f_9e9e9e);
} else {
graphics.fillGradient(this.getX(), this.getY(), this.getX() + this.width, this.getY() + this.height, 0xff_434242, 0xff_434242);
}
if (this.isHoveredOrFocused()) {
graphics.fillGradient(this.getX(), this.getY() + 1, this.getX() + 1, this.getY() + this.height - 1, 0xff_F3EFE0, 0xff_F3EFE0);
graphics.fillGradient(this.getX(), this.getY(), this.getX() + this.width, this.getY() + 1, 0xff_F3EFE0, 0xff_F3EFE0);
graphics.fillGradient(this.getX() + this.width - 1, this.getY() + 1, this.getX() + this.width, this.getY() + this.height - 1, 0xff_F3EFE0, 0xff_F3EFE0);
graphics.fillGradient(this.getX(), this.getY() + this.height - 1, this.getX() + this.width, this.getY() + this.height, 0xff_F3EFE0, 0xff_F3EFE0);
}
int i = getFGColor();
this.renderString(graphics, minecraft.font, i | Mth.ceil(this.alpha * 255.0F) << 24);
}

@Override
public void renderString(GuiGraphics graphics, Font font, int pColor) {
graphics.drawString(font, "▷", this.getX() + 5, this.getY() + (this.height - 8) / 2, 0xe0e0e0);
graphics.drawString(font, this.getMessage(), this.getX() + 15, this.getY() + (this.height - 8) / 2, 0xfafafa);
String countText = soundCount + "♫";
int countTextWidth = font.width(countText);
graphics.drawString(font, countText, this.getX() + this.getWidth() - countTextWidth - 5, this.getY() + (this.height - 8) / 2, 0xCCCCCC);
}

public ResourceLocation getSoundEvent() {
return soundEvent;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button;

import com.github.tartaricacid.touhoulittlemaid.TouhouLittleMaid;
import com.github.tartaricacid.touhoulittlemaid.client.sound.pojo.SoundPackInfo;
import com.github.tartaricacid.touhoulittlemaid.util.ParseI18n;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

public class SoundPackButton extends FlatColorButton {
private static final ResourceLocation ICON = new ResourceLocation(TouhouLittleMaid.MOD_ID, "textures/gui/maid_custom_sound.png");
private final SoundPackInfo info;

public SoundPackButton(int pX, int pY, SoundPackInfo info, OnPress onPress) {
super(pX, pY, 230, 43, Component.empty(), onPress);
this.info = info;
}

@Override
public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float pPartialTick) {
super.renderWidget(graphics, mouseX, mouseY, pPartialTick);
ResourceLocation icon = info.getIcon();
if (icon == null) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, ICON);
graphics.blit(ICON, this.getX() + 4, this.getY() + 4, 0, 16, 32, 32, 256, 256);
}
}

@Override
@SuppressWarnings("all")
public void renderString(GuiGraphics graphics, Font font, int pColor) {
int startX = this.getX() + 42;
int startY = this.getY() + 7;

MutableComponent packName = ParseI18n.parse(info.getPackName());
String version = info.getVersion();
List<String> author = info.getAuthor();
String date = info.getDate();

graphics.drawString(font, packName, startX, startY, ChatFormatting.WHITE.getColor());

if (StringUtils.isNotBlank(version)) {
int titleWidth = font.width(packName);
graphics.drawString(font, "§nv" + version, startX + titleWidth + 5, startY, ChatFormatting.AQUA.getColor());
}

if (!author.isEmpty()) {
startY += 10;
String authorListText = StringUtils.joinWith(I18n.get("gui.touhou_little_maid.resources_download.author.delimiter"), author);
String authorText = I18n.get("gui.touhou_little_maid.resources_download.author", authorListText);
graphics.drawString(font, authorText, startX, startY, ChatFormatting.GOLD.getColor());
}

if (StringUtils.isNotBlank(date)) {
startY += 10;
MutableComponent dateText = Component.translatable("gui.touhou_little_maid.skin.text.date", date);
graphics.drawString(font, dateText, startX, startY, ChatFormatting.GREEN.getColor());
}
}
}
Loading

0 comments on commit 620bab5

Please sign in to comment.