Skip to content

Commit

Permalink
✨ The useful update, part two.
Browse files Browse the repository at this point in the history
Added/changed:
- Added utilities to viewer screens
- Subtle design improvements to viewer screens
- Copying screenshots works now
- 9 billion other things
  • Loading branch information
worldwidepixel committed Aug 8, 2024
1 parent 2541608 commit e4b8850
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/client/java/dev/spiritstudios/snapper/Snapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -14,6 +13,8 @@ public class Snapper implements ClientModInitializer {
public static final String MODID = "snapper";
public static final Logger LOGGER = LoggerFactory.getLogger(MODID);

// TELL COPY-LOGIC THAT THE GAME IS NOT HEADLESS

private static final KeyBinding SCREENSHOT_MENU_KEY = KeyBindingHelper.registerKeyBinding(
new KeyBinding(
"key.snapper.screenshot_menu",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
;
backgroundAlpha = MathHelper.clampedMap(progress, 0.0F, 0.5F, 0.0F, 1.0F);
}
//this.setWidgetOpacity(widgetProgress); // SORT OF IMPORTANT
this.setWidgetOpacity(widgetProgress); // SORT OF IMPORTANT
}

super.render(context, mouseX, mouseY, delta);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package dev.spiritstudios.snapper.gui;

import dev.spiritstudios.snapper.util.ScreenshotActions;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.*;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;

import java.io.File;

public class RenameScreenshotScreen extends Screen {

private final File screenshot;
private final TextFieldWidget renameInput;
private final Text RENAME_INPUT_TEXT = Text.translatable("text.snapper.rename_input");
private final MinecraftClient client = MinecraftClient.getInstance();
private final TextRenderer textRenderer = client.textRenderer;
private final Screen parent;

protected RenameScreenshotScreen(File screenshot, Screen parent) {
super(Text.translatable("text.snapper.rename"));
this.screenshot = screenshot;
this.renameInput = new TextFieldWidget(textRenderer, 200, 20, RENAME_INPUT_TEXT);
this.parent = parent;
}

@Override
protected void init() {
this.addDrawableChild(new TextWidget(RENAME_INPUT_TEXT, textRenderer)).setPosition(this.width / 2 - textRenderer.getWidth(RENAME_INPUT_TEXT) / 2, this.height / 2 - 20);
this.addDrawableChild(this.renameInput).setPosition(this.width / 2 - 100, this.height / 2);
this.renameInput.setText(this.screenshot.getName());
this.addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.rename"), button -> {
this.renameScreenshot(this.renameInput.getText());
})
.dimensions(width / 2 - 150 - 4, height - 32, 150, 20)
.build()
);

this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> this.close())
.dimensions(width / 2 + 4, height - 32, 150, 20)
.build()
);
}

private void renameScreenshot(String newName) {
if (newName == null || !newName.endsWith(".png")) {
return;
}
ScreenshotActions.renameScreenshot(screenshot, newName);
client.setScreen(this.parent);
// Should I make this an if-else statement just to bug Echo?
}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 15, 0xFFFFFF);
}

@Override
public void close() {
this.client.setScreen(this.parent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
import dev.spiritstudios.snapper.Snapper;
import dev.spiritstudios.snapper.gui.widget.ScreenshotListWidget;
import dev.spiritstudios.snapper.util.ScreenshotActions;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.*;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.InputUtil;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -55,8 +58,11 @@ protected void init() {
);

this.viewButton = addDrawableChild(
ButtonWidget.builder(Text.translatable("button.snapper.view"), button ->
this.client.setScreen(new ScreenshotViewerScreen(selectedScreenshot.iconFileName, selectedScreenshot.icon, selectedScreenshot.iconPath, selectedScreenshot.screenParent)))
ButtonWidget.builder(Text.translatable("button.snapper.view"), button -> {
if (selectedScreenshot != null) {
this.client.setScreen(new ScreenshotViewerScreen(selectedScreenshot.icon, selectedScreenshot.screenshot, selectedScreenshot.screenParent));
}
})
.width(100)
.build()
);
Expand All @@ -76,7 +82,11 @@ protected void init() {
.build()
);

this.renameButton = addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.rename"), button -> ScreenshotActions.renameScreenshot(selectedScreenshot.screenshot, Util.getFormattedCurrentTime() + "_test" + ".png"))
this.renameButton = addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.rename"), button -> {
if (this.selectedScreenshot != null) {
client.setScreen(new RenameScreenshotScreen(this.selectedScreenshot.screenshot, this));
}
})
.width(74)
.build()
);
Expand Down Expand Up @@ -133,6 +143,24 @@ public void imageSelected(@Nullable ScreenshotListWidget.ScreenshotEntry screens
}
}

@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
long handle = MinecraftClient.getInstance().getWindow().getHandle();
if (super.keyPressed(keyCode, scanCode, modifiers)) {
return true;
} else if (keyCode == GLFW.GLFW_KEY_F5) {
client.setScreen(new ScreenshotScreen(this.parent));
return true;
} else if ((InputUtil.isKeyPressed(handle, GLFW.GLFW_KEY_LEFT_CONTROL) || InputUtil.isKeyPressed(handle, GLFW.GLFW_KEY_RIGHT_CONTROL)) && InputUtil.isKeyPressed(handle, InputUtil.GLFW_KEY_C)) {
if (selectedScreenshot != null) {
ScreenshotActions.copyScreenshot(selectedScreenshot.screenshot);
return true;
}
}
return false;
}


@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package dev.spiritstudios.snapper.gui;

import com.mojang.blaze3d.systems.RenderSystem;
import dev.spiritstudios.snapper.Snapper;
import dev.spiritstudios.snapper.util.ScreenshotActions;
import dev.spiritstudios.snapper.util.ScreenshotIcon;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AxisGridWidget;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.DirectionalLayoutWidget;
import net.minecraft.client.gui.widget.SimplePositioningWidget;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;

import javax.imageio.ImageIO;
Expand All @@ -20,28 +26,41 @@
public class ScreenshotViewerScreen extends Screen {
private final MinecraftClient client = MinecraftClient.getInstance();
private final ScreenshotIcon icon;
private final Path iconPath;
private Path iconPath;
private final String title;
private final int imageWidth;
private final int imageHeight;
private final Screen parent;
private final File screenshot;

public ScreenshotViewerScreen(String title, ScreenshotIcon icon, Path path, Screen parent) {
private static final Identifier MENU_DECOR_BACKGROUND_TEXTURE = Identifier.ofVanilla("textures/gui/menu_list_background.png");
private static final Identifier INWORLD_MENU_DECOR_BACKGROUND_TEXTURE = Identifier.ofVanilla("textures/gui/inworld_menu_list_background.png");

public ScreenshotViewerScreen(ScreenshotIcon icon, File screenshot, Screen parent) {
super(Text.translatable("menu.snapper.viewermenu"));
this.parent = parent;

try {
this.iconPath = Path.of(screenshot.getCanonicalPath());
} catch (IOException e) {
this.iconPath = null;
Snapper.LOGGER.error("FAILED TO GET PATH OF IMAGE");
client.setScreen(this.parent);
}

BufferedImage img = null;
try {
img = ImageIO.read(new File(String.valueOf(path)));
img = ImageIO.read(new File(String.valueOf(this.iconPath)));
} catch (IOException e) {
Snapper.LOGGER.error("Image failed to read.");
this.client.setScreen(parent);
}

this.icon = icon;
this.title = title;
this.iconPath = path;
this.title = screenshot.getName();
this.imageWidth = img != null ? img.getWidth() : 0;
this.imageHeight = img != null ? img.getHeight() : 0;
this.screenshot = screenshot;
}

@Override
Expand All @@ -51,26 +70,83 @@ public void close() {

@Override
protected void init() {
addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.open"), button -> Util.getOperatingSystem().open(this.iconPath))
.dimensions(width / 2 - 150 - 4, height - 32, 150, 20)

// OPEN FOLDER

ButtonWidget folderButton = addDrawableChild(
ButtonWidget.builder(Text.translatable("button.snapper.folder"), button ->
Util.getOperatingSystem().open(new File(client.runDirectory, "screenshots")))
.width(100)
.build()
);

addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, button -> this.close())
.dimensions(width / 2 + 4, height - 32, 150, 20)
// OPEN IMAGE EXTERNALLY

ButtonWidget openButton = addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.open"), button ->
Util.getOperatingSystem().open(this.iconPath))
.width(100)
.build()
);

// EXIT PAGE

ButtonWidget doneButton = addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, button ->
this.close())
.width(100)
.build()
);

// DELETE SCREENSHOT

ButtonWidget deleteButton = addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.delete"), button -> {
ScreenshotActions.deleteScreenshot(this.screenshot, this.parent);
})
.width(100)
.build()
);

// RENAME SCREENSHOT

ButtonWidget renameButton = addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.rename"), button -> {
if (this.screenshot != null) {
client.setScreen(new RenameScreenshotScreen(this.screenshot, this.parent));
}
})
.width(100)
.build());

// COPY SCREENSHOT

ButtonWidget copyButton = addDrawableChild(ButtonWidget.builder(Text.translatable("button.snapper.copy"), button -> ScreenshotActions.copyScreenshot(this.screenshot))
.width(100)
.build()
);

DirectionalLayoutWidget verticalButtonLayout = DirectionalLayoutWidget.vertical().spacing(4);
AxisGridWidget firstRowWidget = verticalButtonLayout.add(new AxisGridWidget(308, 20, AxisGridWidget.DisplayAxis.HORIZONTAL));
firstRowWidget.add(deleteButton);
firstRowWidget.add(renameButton);
firstRowWidget.add(copyButton);
AxisGridWidget secondRowWidget = verticalButtonLayout.add(new AxisGridWidget(308, 20, AxisGridWidget.DisplayAxis.HORIZONTAL));
secondRowWidget.add(openButton);
secondRowWidget.add(folderButton);
secondRowWidget.add(doneButton);
verticalButtonLayout.refreshPositions();
SimplePositioningWidget.setPos(verticalButtonLayout, 0, this.height - 66, this.width, 64);

}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
this.drawMenuBackground(context);
this.drawHeaderAndFooterSeparators(context);
context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 20, 16777215);
int finalHeight = this.height - 48 - 48;
int finalHeight = this.height - 48 - 68;
float scaleFactor = (float) finalHeight / imageHeight;
int finalWidth = (int) (imageWidth * scaleFactor);

context.drawTexture(this.icon.getTextureId(), (this.width / 2) - (finalWidth / 2), this.height - 48 - finalHeight, 0, 0, finalWidth, finalHeight, finalWidth, finalHeight);
context.drawTexture(this.icon.getTextureId(), (this.width / 2) - (finalWidth / 2), this.height - 68 - finalHeight, 0, 0, finalWidth, finalHeight, finalWidth, finalHeight);
if (FabricLoader.getInstance().isDevelopmentEnvironment()) renderDebugInfo(context);
}

Expand All @@ -85,4 +161,30 @@ private void renderDebugInfo(DrawContext context) {
context.drawCenteredTextWithShadow(this.textRenderer, "Scale Factor: %s".formatted(scaleFactor), this.width / 2, 50, 0xffffff);
context.drawCenteredTextWithShadow(this.textRenderer, "Scaled Size: %dx%d".formatted(finalWidth, finalHeight), this.width / 2, 60, 0xffffff);
}

private void drawMenuBackground(DrawContext context) {
RenderSystem.enableBlend();
Identifier identifier = this.client.world == null ? MENU_DECOR_BACKGROUND_TEXTURE : INWORLD_MENU_DECOR_BACKGROUND_TEXTURE;
context.drawTexture(
identifier,
0,
48,
0,
0,
width,
height - 68 - 48,
32,
32
);
RenderSystem.disableBlend();
}

protected void drawHeaderAndFooterSeparators(DrawContext context) {
RenderSystem.enableBlend();
Identifier identifier = this.client.world == null ? Screen.HEADER_SEPARATOR_TEXTURE : Screen.INWORLD_HEADER_SEPARATOR_TEXTURE;
Identifier identifier2 = this.client.world == null ? Screen.FOOTER_SEPARATOR_TEXTURE : Screen.INWORLD_FOOTER_SEPARATOR_TEXTURE;
context.drawTexture(identifier, 0, 48 - 2, 0, 0, width, 2, 32, 2);
context.drawTexture(identifier2, 0, height - 68, 0, 0, width, 2, 32, 2);
RenderSystem.disableBlend();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (this.icon == null) return false;
this.client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));

this.client.setScreen(new ScreenshotViewerScreen(this.iconFileName, this.icon, this.iconPath, this.screenParent));
this.client.setScreen(new ScreenshotViewerScreen(this.icon, this.screenshot, this.screenParent));
return true;
}

Expand Down
Loading

0 comments on commit e4b8850

Please sign in to comment.