Skip to content

Instantly share code, notes, and snippets.

@Densamisten
Created September 14, 2024 06:57
Show Gist options
  • Save Densamisten/206a9fe7cc044f56ce00052520c53100 to your computer and use it in GitHub Desktop.
Save Densamisten/206a9fe7cc044f56ce00052520c53100 to your computer and use it in GitHub Desktop.
package exonihility.client.util.screenshot.manage_screenshots;
import exonihility.Allyship;
import exonihility.client.AllyshipClient;
import exonihility.client.util.cape.GifDecoder;
import exonihility.client.util.screenshot.manage_screenshots.ScreenshotImage;
import net.minecraft.client.gui.CubeMapRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.RotatingCubeMapRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class CapesScreen extends Screen {
private final String title;
private final Screen parent;
private boolean doBackgroundFade = true;
private long backgroundFadeStart;
private float backgroundAlpha;
private List<File> gifFiles;
private int currentGifIndex = 0;
private GifDecoder.GifImage currentGifImage;
private BufferedImage currentGifFrame;
private int currentFrameIndex = 0;
private long lastFrameTime = 0;
public CapesScreen(String title, Screen parent) {
super(Text.translatable("screenshot.success"));
this.title = title;
this.parent = parent;
gifFiles = new ArrayList<>();
loadCurrentImage();
}
@Override
public void close() {
client.setScreen(this.parent);
}
private void loadCurrentImage() {
if (!gifFiles.isEmpty()) {
File currentFile = gifFiles.get(currentGifIndex);
try {
if (currentFile.getName().endsWith(".gif")) {
// Load GIF
byte[] gifData = Files.readAllBytes(currentFile.toPath());
currentGifImage = GifDecoder.read(gifData);
BufferedImage frame = currentGifImage.getFrame(0); // Load the first frame
currentGifFrame = resizeImage(frame, 128, 128); // Resize if necessary
currentFrameIndex = 0; // Reset the frame index to the first frame
} else if (currentFile.getName().endsWith(".png")) {
// Load PNG
BufferedImage pngImage = javax.imageio.ImageIO.read(currentFile); // Use ImageIO to read the PNG
currentGifFrame = resizeImage(pngImage, 128, 128); // Resize the PNG image to fit
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private BufferedImage resizeImage(BufferedImage originalImage, int maxWidth, int maxHeight) {
int originalWidth = originalImage.getWidth();
int originalHeight = originalImage.getHeight();
// Calculate scaling factor to maintain aspect ratio
double scaleFactor = Math.min((double) maxWidth / originalWidth, (double) maxHeight / originalHeight);
// If the image is smaller than 512x512, don't scale
if (scaleFactor >= 1.0) {
return originalImage;
}
// Calculate the new width and height
int newWidth = (int) (originalWidth * scaleFactor);
int newHeight = (int) (originalHeight * scaleFactor);
// Create a new scaled BufferedImage
BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = resizedImage.createGraphics();
g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
g2d.dispose();
return resizedImage;
}
private void drawGifFrame(DrawContext context, BufferedImage frame, int x, int y) {
// Ensure the image is in a format that uses DataBufferInt
if (frame.getType() != BufferedImage.TYPE_INT_ARGB && frame.getType() != BufferedImage.TYPE_INT_RGB) {
BufferedImage convertedImg = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = convertedImg.createGraphics();
g2d.drawImage(frame, 0, 0, null);
g2d.dispose();
frame = convertedImg; // Replace the original frame with the converted image
}
// Now we can safely cast to DataBufferInt
int[] pixels = ((java.awt.image.DataBufferInt) frame.getRaster().getDataBuffer()).getData();
for (int py = 0; py < frame.getHeight(); py++) {
for (int px = 0; px < frame.getWidth(); px++) {
int color = pixels[px + py * frame.getWidth()];
context.fill(x + px, y + py, x + px + 1, y + py + 1, color);
}
}
}
private void updateImageFrame() {
if (currentGifImage != null) {
if (System.currentTimeMillis() - lastFrameTime > currentGifImage.getDelay(currentFrameIndex) * 10L) {
currentFrameIndex = (currentFrameIndex + 1) % currentGifImage.getFrameCount();
BufferedImage nextFrame = currentGifImage.getFrame(currentFrameIndex);
currentGifFrame = resizeImage(nextFrame, 128, 128);
lastFrameTime = System.currentTimeMillis();
}
}
// No update is needed for PNG since it's a static image
}
@Override
protected void init() {
AllyshipClient.list.clear();
AllyshipClient.list.add("None");
File capeDirectory = new File(client.runDirectory, "capes");
listFilesForFolder(capeDirectory);
addDrawableChild(ButtonWidget.builder(Text.translatable("screen.allyship.button.capes_folder"), button -> {
if (!capeDirectory.exists()) new File(String.valueOf(capeDirectory)).mkdirs();
Util.getOperatingSystem().open(capeDirectory);
}).dimensions(width / 2 - 150 - 4, height - 32, 150, 20).build());
this.addDrawableChild(ButtonWidget.builder(Text.literal("Change Cape"), (button) -> {
if (AllyshipClient.list.indexOf(AllyshipClient.cape) + 1 == AllyshipClient.list.size()) {
AllyshipClient.cape = AllyshipClient.list.get(0);
AllyshipClient.capeCacheIdentifier = null;
}else{
AllyshipClient.cape = AllyshipClient.list.get(AllyshipClient.list.indexOf(AllyshipClient.cape) + 1);
};
}).dimensions((this.width / 2) - 205, (this.height / 4) + 96, 100, 20).build());
// Centered "Previous" button
int buttonWidth = 80;
int imageWidth = (currentGifFrame != null) ? currentGifFrame.getWidth() : 120; // Example width
int imageX = (this.width / 2) - (imageWidth / 2); // Center the image
addDrawableChild(ButtonWidget.builder(Text.literal("Previous"), button -> {
currentGifIndex = (currentGifIndex > 0) ? currentGifIndex - 1 : gifFiles.size() - 1;
loadCurrentImage(); // Load the previous GIF after changing index
}).dimensions(imageX - buttonWidth - 10, this.height / 2, buttonWidth, 20).build()); // Position to the left of the image
// Centered "Next" button
addDrawableChild(ButtonWidget.builder(Text.literal("Next"), button -> {
currentGifIndex = (currentGifIndex < gifFiles.size() - 1) ? currentGifIndex + 1 : 0;
loadCurrentImage(); // Load the next GIF after changing index
}).dimensions(imageX + imageWidth + 10, this.height / 2, buttonWidth, 20).build()); // Position to the right of the image
addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, button -> this.close()).dimensions(width / 2 + 4, height - 32, 150, 20).build());
}
private void listFilesForFolder(File folder) {
for (final File fileEntry : Objects.requireNonNull(folder.listFiles())) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry); // Recursively look in subdirectories
} else if (fileEntry.getName().endsWith(".gif") || fileEntry.getName().endsWith(".png")) {
gifFiles.add(fileEntry); // Add GIF and PNG files to the list
}
}
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
if (this.backgroundFadeStart == 0L && this.doBackgroundFade)
this.backgroundFadeStart = Util.getMeasuringTimeMs();
if (doBackgroundFade) {
float progress = (float) (Util.getMeasuringTimeMs() - this.backgroundFadeStart) / 2000.0F;
float widgetProgress = 1.0F;
if (progress > 1.0F) {
this.doBackgroundFade = false;
backgroundAlpha = 1.0F;
} else {
progress = MathHelper.clamp(progress, 0.0F, 1.0F);
widgetProgress = MathHelper.clampedMap(progress, 0.0F, 0.5F, 0.0F, 1.0F);
backgroundAlpha = MathHelper.clampedMap(progress, 0.0F, 0.5F, 0.0F, 1.0F);
}
this.setWidgetOpacity(widgetProgress);
}
// Render the GIF frame if available
if (currentGifImage != null && currentGifFrame != null) {
int imageX = (this.width / 2) - (currentGifFrame.getWidth() / 2);
int imageY = (this.height / 2) - (currentGifFrame.getHeight() / 2);
drawGifFrame(context, currentGifFrame, imageX, imageY);
// Update the frame for animation
updateImageFrame();
}
super.render(context, mouseX, mouseY, delta);
context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 20, 0xffffff);
}
private void setWidgetOpacity(float alpha) {
for (Element element : this.children()) {
if (element instanceof ClickableWidget clickableWidget) {
clickableWidget.setAlpha(alpha);
}
}
}
@Override
public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment