diff --git a/src/main/java/eu/crushedpixel/replaymod/assets/AssetRepository.java b/src/main/java/eu/crushedpixel/replaymod/assets/AssetRepository.java new file mode 100644 index 00000000..9d4763d3 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/assets/AssetRepository.java @@ -0,0 +1,68 @@ +package eu.crushedpixel.replaymod.assets; + +import eu.crushedpixel.replaymod.ReplayMod; +import eu.crushedpixel.replaymod.replay.ReplayHandler; +import eu.crushedpixel.replaymod.utils.ReplayFile; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.ArrayUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class AssetRepository { + + private List replayAssets; + + public AssetRepository() { + replayAssets = new ArrayList(); + } + + public ReplayAsset addAsset(String assetFileName, InputStream inputStream) throws IOException { + ReplayAsset asset = assetFromFileName(assetFileName); + + asset.loadFromStream(inputStream); + + replayAssets.add(asset); + + return asset; + } + + public void removeAsset(ReplayAsset asset) { + replayAssets.remove(asset); + } + + public void saveAssets() { + for(ReplayAsset asset : replayAssets) { + try { + String filepath = ReplayFile.ENTRY_ASSET_FOLDER + asset.getDisplayString() + "." + asset.getSavedFileExtension(); + + File toAdd = File.createTempFile(asset.getDisplayString(), asset.getSavedFileExtension()); + FileOutputStream fos = new FileOutputStream(toAdd); + asset.writeToStream(fos); + + ReplayMod.replayFileAppender.registerModifiedFile(toAdd, filepath, ReplayHandler.getReplayFile()); + } catch(IOException e) { + e.printStackTrace(); + } + } + + } + + public static ReplayAsset assetFromFileName(String filename) { + String baseName = FilenameUtils.getBaseName(filename); + String extension = FilenameUtils.getExtension(filename); + + if(ArrayUtils.contains(AssetFileUtils.fileExtensionsForAssetClass(ReplayImageAsset.class), extension)) { + return new ReplayImageAsset(baseName); + } + + throw new UnsupportedOperationException("Can't create ReplayAsset from File "+filename); + } + + + +} diff --git a/src/main/java/eu/crushedpixel/replaymod/assets/ReplayAsset.java b/src/main/java/eu/crushedpixel/replaymod/assets/ReplayAsset.java new file mode 100644 index 00000000..d4a71f48 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/assets/ReplayAsset.java @@ -0,0 +1,22 @@ +package eu.crushedpixel.replaymod.assets; + +import eu.crushedpixel.replaymod.holders.GuiEntryListEntry; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public interface ReplayAsset extends GuiEntryListEntry { + + String getSavedFileExtension(); + + void loadFromStream(InputStream inputStream) throws IOException; + void writeToStream(OutputStream outputStream) throws IOException; + + void drawToScreen(int x, int y, int maxWidth, int maxHeight); + + void setAssetName(String name); + + T getObject(); + +} diff --git a/src/main/java/eu/crushedpixel/replaymod/assets/ReplayImageAsset.java b/src/main/java/eu/crushedpixel/replaymod/assets/ReplayImageAsset.java new file mode 100644 index 00000000..501a6f90 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/assets/ReplayImageAsset.java @@ -0,0 +1,85 @@ +package eu.crushedpixel.replaymod.assets; + +import eu.crushedpixel.replaymod.registry.ResourceHelper; +import eu.crushedpixel.replaymod.utils.BoundingUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.util.Dimension; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.UUID; + +public class ReplayImageAsset implements ReplayAsset { + + private final Minecraft mc = Minecraft.getMinecraft(); + + private BufferedImage object; + + private String name; + + public ReplayImageAsset(String name) { + this.name = name; + } + + @Override + public void setAssetName(String name) { + this.name = name; + } + + @Override + public String getDisplayString() { + return name; + } + + @Override + public String getSavedFileExtension() { + return "png"; + } + + @Override + public void loadFromStream(InputStream inputStream) throws IOException { + this.object = ImageIO.read(inputStream); + ResourceHelper.freeResource(previewResource); + } + + @Override + public void writeToStream(OutputStream outputStream) throws IOException { + ImageIO.write(object, "png", outputStream); + } + + @Override + public BufferedImage getObject() { + return object; + } + + private ResourceLocation previewResource = new ResourceLocation("/asset/"+ UUID.randomUUID().toString()); + private DynamicTexture dynamicTexture; + + @Override + public void drawToScreen(int x, int y, int maxWidth, int maxHeight) { + if(object == null) return; + if(!ResourceHelper.isRegistered(previewResource) || dynamicTexture == null) { + dynamicTexture = new DynamicTexture(object); + mc.getTextureManager().loadTexture(previewResource, dynamicTexture); + ResourceHelper.registerResource(previewResource); + } + + mc.renderEngine.bindTexture(previewResource); + + Dimension dimension = BoundingUtils.fitIntoBounds(new Dimension(object.getWidth(), object.getHeight()), new Dimension(maxWidth, maxHeight)); + + Gui.drawScaledCustomSizeModalRect(x, y, 0, 0, object.getWidth(), object.getHeight(), dimension.getWidth(), dimension.getHeight(), object.getWidth(), object.getHeight()); + } + + @Override + protected void finalize() throws Throwable { + ResourceHelper.freeResource(previewResource); + super.finalize(); + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java b/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java index 5dcf511b..be3afd57 100755 --- a/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java @@ -1,8 +1,9 @@ package eu.crushedpixel.replaymod.events.handlers; import eu.crushedpixel.replaymod.ReplayMod; +import eu.crushedpixel.replaymod.assets.AssetRepository; import eu.crushedpixel.replaymod.entities.CameraEntity.MoveDirection; -import eu.crushedpixel.replaymod.gui.GuiAssetAdder; +import eu.crushedpixel.replaymod.gui.GuiAssetManager; import eu.crushedpixel.replaymod.gui.GuiKeyframeRepository; import eu.crushedpixel.replaymod.gui.GuiMouseInput; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; @@ -202,8 +203,8 @@ public class KeyInputHandler { ReplayMod.replaySettings.setShowPathPreview(!ReplayMod.replaySettings.showPathPreview()); } - if(kb.getKeyDescription().equals(KeybindRegistry.KEY_ADD_ASSETS) && (kb.isPressed() || kb.getKeyCode() == keyCode)) { - mc.displayGuiScreen(new GuiAssetAdder()); + if(kb.getKeyDescription().equals(KeybindRegistry.KEY_ASSET_MANAGER) && (kb.isPressed() || kb.getKeyCode() == keyCode)) { + mc.displayGuiScreen(new GuiAssetManager(new AssetRepository())); } } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetManager.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetManager.java new file mode 100644 index 00000000..6307463a --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetManager.java @@ -0,0 +1,175 @@ +package eu.crushedpixel.replaymod.gui; + +import eu.crushedpixel.replaymod.assets.AssetFileUtils; +import eu.crushedpixel.replaymod.assets.AssetRepository; +import eu.crushedpixel.replaymod.assets.ReplayAsset; +import eu.crushedpixel.replaymod.gui.elements.*; +import eu.crushedpixel.replaymod.gui.elements.listeners.FileChooseListener; +import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; +import eu.crushedpixel.replaymod.utils.MouseUtils; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.Point; + +import java.awt.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public class GuiAssetManager extends GuiScreen { + + private String screenTitle; + + private boolean initialized = false; + private GuiEntryList assetGuiEntryList; + private GuiAdvancedButton removeButton; + private GuiAdvancedTextField assetNameInput; + private GuiFileChooser fileChooser, addButton; + + private ComposedElement inputElements; + + private ComposedElement composedElement; + + private AssetRepository assetRepository; + + private ReplayAsset currentAsset; + + public GuiAssetManager(AssetRepository assetRepository) { + this.assetRepository = assetRepository; + } + + @Override + public void initGui() { + if(!initialized) { + screenTitle = I18n.format("replaymod.gui.assets.title"); + + assetGuiEntryList = new GuiEntryList(fontRendererObj, 0, 0, 0, 0); + addButton = new GuiFileChooser(0, 0, 0, I18n.format("replaymod.gui.add"), null, AssetFileUtils.getAllAvailableExtensions()) { + @Override + protected void updateDisplayString() { + this.displayString = baseString; + } + }; + + addButton.addFileChooseListener(new FileChooseListener() { + @Override + public void onFileChosen(File file) { + try { + ReplayAsset newAsset = assetRepository.addAsset(file.getName(), new FileInputStream(file)); + assetGuiEntryList.addElement(newAsset); + } catch(Exception e) { + e.printStackTrace(); + } + } + }); + + removeButton = new GuiAdvancedButton(0, 0, 0, I18n.format("replaymod.gui.remove")) { + @Override + public void performAction() { + assetRepository.removeAsset(currentAsset); + assetGuiEntryList.removeElement(assetGuiEntryList.getSelectionIndex()); + } + }; + + assetNameInput = new GuiAdvancedTextField(fontRendererObj, 0, 0, 150, 20); + assetNameInput.hint = I18n.format("replaymod.gui.assets.namehint"); + + fileChooser = new GuiFileChooser(0, 0, 0, I18n.format("replaymod.gui.assets.changefile"), null, new String[0]) { + @Override + protected void updateDisplayString() { + this.displayString = baseString; + } + }; + fileChooser.addFileChooseListener(new FileChooseListener() { + @Override + public void onFileChosen(File file) { + if(currentAsset == null) return; + try { + currentAsset.loadFromStream(new FileInputStream(file)); + } catch(IOException e) { + e.printStackTrace(); + } + } + }); + + fileChooser.width = 150; + + inputElements = new ComposedElement(assetNameInput, fileChooser); + composedElement = new ComposedElement(assetGuiEntryList, addButton, removeButton, inputElements); + + inputElements.setEnabled(false); + + assetGuiEntryList.addSelectionListener(new SelectionListener() { + @Override + public void onSelectionChanged(int selectionIndex) { + currentAsset = assetGuiEntryList.getElement(selectionIndex); + inputElements.setEnabled(currentAsset != null); + + assetNameInput.setText(currentAsset != null ? currentAsset.getDisplayString() : ""); + fileChooser.setAllowedExtensions(currentAsset != null ? AssetFileUtils.fileExtensionsForAssetClass(currentAsset.getClass()) : new String[0]); + } + }); + } + + int visibleEntries = (int)Math.floor(((double)this.height-(45+20+15+20))/14); + + assetGuiEntryList.width = 150; + assetGuiEntryList.xPosition = width/2 - assetGuiEntryList.width - 5; + assetGuiEntryList.setVisibleElements(visibleEntries); + + assetGuiEntryList.yPosition = assetNameInput.yPosition = 45; + + addButton.xPosition = assetGuiEntryList.xPosition-1; + addButton.width = 77; + removeButton.width = 76; + removeButton.xPosition = addButton.xPosition+addButton.width; + + addButton.yPosition = removeButton.yPosition = assetGuiEntryList.yPosition+assetGuiEntryList.height+2; + + assetNameInput.xPosition = fileChooser.xPosition = this.width / 2 + 5; + fileChooser.yPosition = assetNameInput.yPosition + 20 + 5; + + initialized = true; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + this.drawCenteredString(fontRendererObj, screenTitle, this.width / 2, 5, Color.WHITE.getRGB()); + + int leftBorder = 10; + int topBorder = 20; + + drawGradientRect(leftBorder, topBorder, width - leftBorder, this.height - 10, -1072689136, -804253680); + + composedElement.draw(mc, mouseX, mouseY); + + if(currentAsset != null) { + int y = fileChooser.yPosition + 20 + 5; + int height = (addButton.yPosition+addButton.height)-y; + + GL11.glColor4f(1, 1, 1, 1); + currentAsset.drawToScreen(fileChooser.xPosition, y, 150, height); + } + + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + composedElement.mouseClick(mc, mouseX, mouseY, mouseButton); + super.mouseClicked(mouseX, mouseY, mouseButton); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + Point mousePos = MouseUtils.getMousePos(); + composedElement.buttonPressed(mc, mousePos.getX(), mousePos.getY(), typedChar, keyCode); + super.keyTyped(typedChar, keyCode); + } + + @Override + public void updateScreen() { + composedElement.tick(mc); + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiFileChooser.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiFileChooser.java index 8a3d67df..5c876ff6 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiFileChooser.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiFileChooser.java @@ -2,7 +2,7 @@ package eu.crushedpixel.replaymod.gui.elements; import eu.crushedpixel.replaymod.gui.elements.listeners.FileChooseListener; import lombok.Getter; -import net.minecraft.client.Minecraft; +import lombok.Setter; import java.awt.*; import java.io.File; @@ -20,8 +20,9 @@ public class GuiFileChooser extends GuiAdvancedButton { updateDisplayString(); } - private String baseString; + protected String baseString; + @Setter private String[] allowedExtensions = null; private List listeners = new ArrayList(); @@ -45,49 +46,44 @@ public class GuiFileChooser extends GuiAdvancedButton { } @Override - public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { - boolean success = super.mousePressed(mc, mouseX, mouseY); - if (success) { - new Thread(new Runnable() { - @Override - public void run() { - Frame frame = new Frame(); - FileDialog fileDialog = new FileDialog(frame); + public void performAction() { + new Thread(new Runnable() { + @Override + public void run() { + Frame frame = new Frame(); + FileDialog fileDialog = new FileDialog(frame); - fileDialog.setFilenameFilter(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - if(allowedExtensions == null) return true; - for(String extension : allowedExtensions) { - String[] split = name.split("\\."); - String ext = split[split.length-1]; - if(extension.equalsIgnoreCase(ext)) return true; - } - - return false; + fileDialog.setFilenameFilter(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + if(allowedExtensions == null) return true; + for(String extension : allowedExtensions) { + String[] split = name.split("\\."); + String ext = split[split.length-1]; + if(extension.equalsIgnoreCase(ext)) return true; } - }); - //frame.setVisible(true); - fileDialog.setVisible(true); - - String filename = fileDialog.getFile(); - String directory = fileDialog.getDirectory(); - if(filename != null) { - selectedFile = new File(directory, filename); - - updateDisplayString(); - - for(FileChooseListener listener : listeners) { - listener.onFileChosen(selectedFile); - } + return false; } + }); - frame.dispose(); + //frame.setVisible(true); + fileDialog.setVisible(true); + + String filename = fileDialog.getFile(); + String directory = fileDialog.getDirectory(); + if(filename != null) { + selectedFile = new File(directory, filename); + + updateDisplayString(); + + for(FileChooseListener listener : listeners) { + listener.onFileChosen(selectedFile); + } } - }, "replaymod-file-chooser").start(); - } - return success; - } + frame.dispose(); + } + }, "replaymod-file-chooser").start(); + } } diff --git a/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java b/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java index ed1c6071..ef2d0bc8 100755 --- a/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java +++ b/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java @@ -22,7 +22,7 @@ public class KeybindRegistry { public static final String KEY_PLAY_PAUSE = "replaymod.input.playpause"; public static final String KEY_ADD_MARKER = "replaymod.input.marker"; public static final String KEY_PATH_PREVIEW = "replaymod.input.pathpreview"; - public static final String KEY_ADD_ASSETS = "replaymod.input.addassets"; + public static final String KEY_ASSET_MANAGER = "replaymod.input.assetmanager"; private static Minecraft mc = Minecraft.getMinecraft(); public static void initialize() { @@ -40,7 +40,7 @@ public class KeybindRegistry { bindings.add(new KeyBinding(KEY_ROLL_COUNTERCLOCKWISE, Keyboard.KEY_J, "replaymod.title")); bindings.add(new KeyBinding(KEY_PLAY_PAUSE, Keyboard.KEY_P, "replaymod.title")); bindings.add(new KeyBinding(KEY_PATH_PREVIEW, Keyboard.KEY_H, "replaymod.title")); - bindings.add(new KeyBinding(KEY_ADD_ASSETS, Keyboard.KEY_G, "replaymod.title")); + bindings.add(new KeyBinding(KEY_ASSET_MANAGER, Keyboard.KEY_G, "replaymod.title")); mc.gameSettings.keyBindings = bindings.toArray(new KeyBinding[bindings.size()]); diff --git a/src/main/java/eu/crushedpixel/replaymod/registry/ResourceHelper.java b/src/main/java/eu/crushedpixel/replaymod/registry/ResourceHelper.java index 7532d4fd..b0da9596 100755 --- a/src/main/java/eu/crushedpixel/replaymod/registry/ResourceHelper.java +++ b/src/main/java/eu/crushedpixel/replaymod/registry/ResourceHelper.java @@ -30,9 +30,14 @@ public class ResourceHelper { return openResources.contains(loc); } - public static void freeResource(ResourceLocation loc) { - Minecraft.getMinecraft().getTextureManager().deleteTexture(loc); - openResources.remove(loc); + public static void freeResource(final ResourceLocation loc) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + Minecraft.getMinecraft().getTextureManager().deleteTexture(loc); + openResources.remove(loc); + } + }); } public static void freeAllResources() { diff --git a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java index a971f451..6daf301d 100755 --- a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java @@ -562,6 +562,7 @@ public class ReplayHandler { try { ReplayMod.overlay.resetUI(true); } catch(Exception e) { + e.printStackTrace(); // TODO: Fix exceptionsudo } @@ -584,6 +585,7 @@ public class ReplayHandler { t.printStackTrace(); } }; + INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, null, networkManager, new GameProfile(UUID.randomUUID(), "Player")); networkManager.setNetHandler(pc); diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/BoundingUtils.java b/src/main/java/eu/crushedpixel/replaymod/utils/BoundingUtils.java new file mode 100644 index 00000000..6358007f --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/utils/BoundingUtils.java @@ -0,0 +1,25 @@ +package eu.crushedpixel.replaymod.utils; + +import org.lwjgl.util.Dimension; + +public class BoundingUtils { + + public static Dimension fitIntoBounds(Dimension toFit, Dimension bounds) { + int width = toFit.getWidth(); + int height = toFit.getHeight(); + + float w = (float)width/bounds.getWidth(); + float h = (float)height/bounds.getHeight(); + + if(w > h) { + height = (int)(height/w); + width = (int)(width/w); + } else { + height = (int)(height/h); + width = (int)(width/h); + } + + return new Dimension(width, height); + } + +} diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java index 7236a860..3e15e0a3 100644 --- a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java +++ b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java @@ -4,6 +4,7 @@ import com.google.common.base.Supplier; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import eu.crushedpixel.replaymod.assets.AssetRepository; import eu.crushedpixel.replaymod.holders.KeyframeSet; import eu.crushedpixel.replaymod.holders.MarkerKeyframe; import eu.crushedpixel.replaymod.holders.PlayerVisibility; @@ -14,6 +15,7 @@ import org.apache.commons.compress.archivers.zip.ZipFile; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; +import java.util.Enumeration; import java.util.HashMap; import java.util.Map; @@ -32,6 +34,7 @@ public class ReplayFile extends ZipFile { public static final String ENTRY_VISIBILITY_OLD = "visibility"; public static final String ENTRY_VISIBILITY = "visibility" + JSON_FILE_EXTENSION; public static final String ENTRY_MARKERS = "markers" + JSON_FILE_EXTENSION; + public static final String ENTRY_ASSET_FOLDER = "asset/"; private final File file; @@ -220,4 +223,32 @@ public class ReplayFile extends ZipFile { } }; } + + public Supplier assetRepository() { + return new Supplier() { + @Override + @SuppressWarnings("unchecked") + public AssetRepository get() { + AssetRepository assetRepository = new AssetRepository(); + + Enumeration entries = getEntries(); + + while(entries.hasMoreElements()) { + + try { + ZipArchiveEntry entry = entries.nextElement(); + + if(entry.getName().startsWith(ENTRY_ASSET_FOLDER)) { + String name = entry.getName().substring(ENTRY_ASSET_FOLDER.length()); + assetRepository.addAsset(name, getInputStream(entry)); + } + } catch(IOException e) { + e.printStackTrace(); + } + } + + return assetRepository; + } + }; + } } diff --git a/src/main/java/eu/crushedpixel/replaymod/video/frame/FrameRenderer.java b/src/main/java/eu/crushedpixel/replaymod/video/frame/FrameRenderer.java index 2d9c0faa..9b7bc955 100644 --- a/src/main/java/eu/crushedpixel/replaymod/video/frame/FrameRenderer.java +++ b/src/main/java/eu/crushedpixel/replaymod/video/frame/FrameRenderer.java @@ -1,6 +1,7 @@ package eu.crushedpixel.replaymod.video.frame; import eu.crushedpixel.replaymod.settings.RenderOptions; +import eu.crushedpixel.replaymod.utils.BoundingUtils; import eu.crushedpixel.replaymod.video.entity.CustomEntityRenderer; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; @@ -9,6 +10,7 @@ import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Timer; import org.lwjgl.BufferUtils; +import org.lwjgl.util.Dimension; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; @@ -120,18 +122,12 @@ public abstract class FrameRenderer { * @param height Height of the box */ public void renderPreview(int x, int y, int width, int height) { - int actualWidth = width; - int actualHeight = height; - if (width / height > getVideoWidth() / getVideoHeight()) { - actualWidth = height * getVideoWidth() / getVideoHeight(); - } else { - actualHeight = width * getVideoHeight() / getVideoWidth(); - } + Dimension dimension = BoundingUtils.fitIntoBounds(new Dimension(x, y), new Dimension(width, height)); - x += (width - actualWidth) / 2; - y += (height - actualHeight) / 2; + x += (width - dimension.getWidth()) / 2; + y += (height - dimension.getHeight()) / 2; - drawPreviewTexture(x, y, actualWidth, actualHeight); + drawPreviewTexture(x, y, dimension.getWidth(), dimension.getHeight()); } public static void renderNoPreview(int x, int y, int width, int height) { diff --git a/src/main/resources/assets/replaymod/lang/en_US.lang b/src/main/resources/assets/replaymod/lang/en_US.lang index 3bbe7e2c..1d4ced1c 100644 --- a/src/main/resources/assets/replaymod/lang/en_US.lang +++ b/src/main/resources/assets/replaymod/lang/en_US.lang @@ -257,7 +257,7 @@ replaymod.input.resettilt=Reset Camera Tilt replaymod.input.playpause=Play/Pause Replay replaymod.input.marker=Add Event Marker replaymod.input.pathpreview=Toggle Path Preview -replaymod.input.addassets=Add Assets +replaymod.input.assetmanager=Open Asset Manager #Keyframe Presets GUI replaymod.gui.keyframerepository.title=Keyframe Repository @@ -357,10 +357,10 @@ replaymod.gui.ingame.unnamedmarker=Unnamed Event Marker replaymod.gui.clearcallback.title=Clear all Keyframes? replaymod.gui.clearcallback.message=This Callback can be disabled in the Replay Settings. -#Asset Adder Gui +#Asset Manager Gui replaymod.gui.assets.title=Asset Manager -replaymod.gui.assets.filechooser=Image File +replaymod.gui.assets.filechooser=Asset File replaymod.gui.assets.defaultname=New Asset replaymod.gui.assets.emptylist=No Assets available replaymod.gui.assets.namehint=Asset Name -replaymod.gui.assets.backvisible=Visible from behind \ No newline at end of file +replaymod.gui.assets.changefile=Change Asset File \ No newline at end of file diff --git a/src/main/resources/assets/replaymod/replay_gui.png b/src/main/resources/assets/replaymod/replay_gui.png index 64648ab2..04dbf78b 100755 Binary files a/src/main/resources/assets/replaymod/replay_gui.png and b/src/main/resources/assets/replaymod/replay_gui.png differ