Added new Gui with Progress Bar when editing a Replay using the ReplayEditor | https://trello.com/c/uGFDgv6E/
Added ProgressUpdateListener interface for the use with ProgressBars
This commit is contained in:
@@ -101,4 +101,6 @@ public class GuiConstants {
|
|||||||
public static final int REPLAY_SETTINGS_RESOURCEPACK_ID = 9010;
|
public static final int REPLAY_SETTINGS_RESOURCEPACK_ID = 9010;
|
||||||
public static final int REPLAY_SETTINGS_INDICATOR_ID = 9012;
|
public static final int REPLAY_SETTINGS_INDICATOR_ID = 9012;
|
||||||
public static final int REPLAY_SETTINGS_PATHPREVIEW_ID = 9013;
|
public static final int REPLAY_SETTINGS_PATHPREVIEW_ID = 9013;
|
||||||
|
|
||||||
|
public static final int REPLAY_EDITING_CANCEL_BUTTON = 1234;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ public class GuiProgressBar extends Gui {
|
|||||||
|
|
||||||
private String progressString = null;
|
private String progressString = null;
|
||||||
|
|
||||||
|
public GuiProgressBar() {
|
||||||
|
this(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public GuiProgressBar(int xPosition, int yPosition, int width, int height) {
|
public GuiProgressBar(int xPosition, int yPosition, int width, int height) {
|
||||||
this(xPosition, yPosition, width, height, 0);
|
this(xPosition, yPosition, width, height, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package eu.crushedpixel.replaymod.gui.elements.listeners;
|
||||||
|
|
||||||
|
public interface ProgressUpdateListener {
|
||||||
|
|
||||||
|
void onProgressChanged(float progress);
|
||||||
|
|
||||||
|
void onProgressChanged(float progress, String progressString);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiButton;
|
import net.minecraft.client.gui.GuiButton;
|
||||||
import net.minecraft.client.resources.I18n;
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -34,15 +35,21 @@ public class GuiConnectPart extends GuiStudioPart {
|
|||||||
private List<File> replayFiles;
|
private List<File> replayFiles;
|
||||||
private List<String> filesToConcat;
|
private List<String> filesToConcat;
|
||||||
|
|
||||||
|
private Thread filterThread;
|
||||||
|
private File outputFile;
|
||||||
|
|
||||||
public GuiConnectPart(int yPos) {
|
public GuiConnectPart(int yPos) {
|
||||||
super(yPos);
|
super(yPos);
|
||||||
this.mc = Minecraft.getMinecraft();
|
this.mc = Minecraft.getMinecraft();
|
||||||
fontRendererObj = mc.fontRendererObj;
|
fontRendererObj = mc.fontRendererObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyFilters(File replayFile, File outputFile) {
|
public void applyFilters(File replayFile, File outputFile) {
|
||||||
|
this.outputFile = outputFile;
|
||||||
|
filterThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
try {
|
try {
|
||||||
List<File> inputFiles = new ArrayList<File>();
|
List<File> inputFiles = new ArrayList<File>();
|
||||||
OUTER:
|
OUTER:
|
||||||
@@ -55,11 +62,24 @@ public class GuiConnectPart extends GuiStudioPart {
|
|||||||
}
|
}
|
||||||
throw new RuntimeException(fileName);
|
throw new RuntimeException(fileName);
|
||||||
}
|
}
|
||||||
StudioImplementation.connectReplayFiles(inputFiles, outputFile);
|
StudioImplementation.connectReplayFiles(inputFiles, outputFile, GuiConnectPart.this);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, "replay-editor-connect");
|
||||||
|
|
||||||
|
filterThread.start();
|
||||||
|
|
||||||
|
mc.displayGuiScreen(new GuiReplayEditingProcess(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public void cancelFilters() {
|
||||||
|
filterThread.stop();
|
||||||
|
FileUtils.deleteQuietly(outputFile);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package eu.crushedpixel.replaymod.gui.replayeditor;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
|
import eu.crushedpixel.replaymod.gui.GuiConstants;
|
||||||
|
import eu.crushedpixel.replaymod.gui.elements.GuiProgressBar;
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class GuiReplayEditingProcess extends GuiScreen {
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
private String pleaseWait;
|
||||||
|
private String cancelCallback;
|
||||||
|
|
||||||
|
private boolean finished = false;
|
||||||
|
|
||||||
|
private boolean callback = false;
|
||||||
|
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
|
private GuiProgressBar progressBar;
|
||||||
|
private GuiButton cancelButton;
|
||||||
|
|
||||||
|
private GuiStudioPart studioPart;
|
||||||
|
|
||||||
|
public GuiReplayEditingProcess(GuiStudioPart studioPart) {
|
||||||
|
this.studioPart = studioPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initGui() {
|
||||||
|
if(!initialized) {
|
||||||
|
title = I18n.format("replaymod.gui.editor.progress.title");
|
||||||
|
pleaseWait = I18n.format("replaymod.gui.editor.progress.pleasewait");
|
||||||
|
cancelCallback = I18n.format("replaymod.gui.rendering.cancel.callback");
|
||||||
|
|
||||||
|
progressBar = new GuiProgressBar();
|
||||||
|
cancelButton = new GuiButton(GuiConstants.REPLAY_EDITING_CANCEL_BUTTON, 0, 0, I18n.format("gui.cancel"));
|
||||||
|
}
|
||||||
|
|
||||||
|
progressBar.setBounds(10, this.height-30-20, this.width-20, 20);
|
||||||
|
|
||||||
|
cancelButton.xPosition = this.width - 5 - 150;
|
||||||
|
cancelButton.width = 150;
|
||||||
|
cancelButton.yPosition = this.height - 5 - 20;
|
||||||
|
|
||||||
|
buttonList.add(cancelButton);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||||
|
this.drawDefaultBackground();
|
||||||
|
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||||
|
this.drawCenteredString(mc.fontRendererObj, title, this.width / 2, 20, Color.WHITE.getRGB());
|
||||||
|
this.drawCenteredString(mc.fontRendererObj, pleaseWait, this.width / 2, 40, Color.WHITE.getRGB());
|
||||||
|
|
||||||
|
progressBar.setProgress(studioPart.getProgress());
|
||||||
|
progressBar.setProgressString(studioPart.getFilterProgressString());
|
||||||
|
progressBar.drawProgressBar();
|
||||||
|
|
||||||
|
if(studioPart.getProgress() >= 1f && !finished) {
|
||||||
|
finished = true;
|
||||||
|
cancelButton.displayString = I18n.format("gui.done");
|
||||||
|
ReplayMod.soundHandler.playRenderSuccessSound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void actionPerformed(GuiButton button) throws IOException {
|
||||||
|
if(!button.enabled) return;
|
||||||
|
if(button.id == GuiConstants.REPLAY_EDITING_CANCEL_BUTTON) {
|
||||||
|
if(finished) {
|
||||||
|
mc.displayGuiScreen(null);
|
||||||
|
} else {
|
||||||
|
if(!callback) {
|
||||||
|
callback = true;
|
||||||
|
button.displayString = cancelCallback;
|
||||||
|
} else {
|
||||||
|
studioPart.cancelFilters();
|
||||||
|
mc.displayGuiScreen(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
package eu.crushedpixel.replaymod.gui.replayeditor;
|
package eu.crushedpixel.replaymod.gui.replayeditor;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.gui.elements.listeners.ProgressUpdateListener;
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public abstract class GuiStudioPart extends GuiScreen {
|
public abstract class GuiStudioPart extends GuiScreen implements ProgressUpdateListener {
|
||||||
|
|
||||||
protected int yPos = 0;
|
protected int yPos = 0;
|
||||||
|
|
||||||
@@ -15,6 +16,8 @@ public abstract class GuiStudioPart extends GuiScreen {
|
|||||||
|
|
||||||
public abstract void applyFilters(File replayFile, File outputFile);
|
public abstract void applyFilters(File replayFile, File outputFile);
|
||||||
|
|
||||||
|
public abstract void cancelFilters();
|
||||||
|
|
||||||
public abstract String getDescription();
|
public abstract String getDescription();
|
||||||
|
|
||||||
public abstract String getTitle();
|
public abstract String getTitle();
|
||||||
@@ -26,4 +29,27 @@ public abstract class GuiStudioPart extends GuiScreen {
|
|||||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||||
super.mouseClicked(mouseX, mouseY, mouseButton);
|
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float progress;
|
||||||
|
private String progressString;
|
||||||
|
|
||||||
|
public float getProgress() {
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilterProgressString() {
|
||||||
|
return progressString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(float progress, String progressString) {
|
||||||
|
this.progress = progress;
|
||||||
|
this.progressString = progressString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(float progress) {
|
||||||
|
this.progress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import eu.crushedpixel.replaymod.studio.StudioImplementation;
|
|||||||
import eu.crushedpixel.replaymod.utils.TimestampUtils;
|
import eu.crushedpixel.replaymod.utils.TimestampUtils;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.resources.I18n;
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.lwjgl.input.Keyboard;
|
import org.lwjgl.input.Keyboard;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -24,6 +25,9 @@ public class GuiTrimPart extends GuiStudioPart {
|
|||||||
|
|
||||||
private List<GuiNumberInput> inputOrder = new ArrayList<GuiNumberInput>();
|
private List<GuiNumberInput> inputOrder = new ArrayList<GuiNumberInput>();
|
||||||
|
|
||||||
|
private Thread filterThread;
|
||||||
|
private File outputFile;
|
||||||
|
|
||||||
public GuiTrimPart(int yPos) {
|
public GuiTrimPart(int yPos) {
|
||||||
super(yPos);
|
super(yPos);
|
||||||
fontRendererObj = mc.fontRendererObj;
|
fontRendererObj = mc.fontRendererObj;
|
||||||
@@ -31,12 +35,29 @@ public class GuiTrimPart extends GuiStudioPart {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyFilters(File replayFile, File outputFile) {
|
public void applyFilters(File replayFile, File outputFile) {
|
||||||
|
this.outputFile = outputFile;
|
||||||
|
filterThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
try {
|
try {
|
||||||
StudioImplementation.trimReplay(replayFile, getStartTimestamp(), getEndTimestamp(), outputFile);
|
StudioImplementation.trimReplay(replayFile, getStartTimestamp(), getEndTimestamp(), outputFile, GuiTrimPart.this);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, "replay-editor-trim");
|
||||||
|
|
||||||
|
filterThread.start();
|
||||||
|
|
||||||
|
mc.displayGuiScreen(new GuiReplayEditingProcess(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public void cancelFilters() {
|
||||||
|
filterThread.stop();
|
||||||
|
FileUtils.deleteQuietly(outputFile);
|
||||||
|
}
|
||||||
|
|
||||||
private int valueOf(String text) {
|
private int valueOf(String text) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import de.johni0702.replaystudio.replay.ReplayMetaData;
|
|||||||
import de.johni0702.replaystudio.replay.ZipReplayFile;
|
import de.johni0702.replaystudio.replay.ZipReplayFile;
|
||||||
import de.johni0702.replaystudio.stream.PacketStream;
|
import de.johni0702.replaystudio.stream.PacketStream;
|
||||||
import de.johni0702.replaystudio.studio.ReplayStudio;
|
import de.johni0702.replaystudio.studio.ReplayStudio;
|
||||||
|
import eu.crushedpixel.replaymod.gui.elements.listeners.ProgressUpdateListener;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -20,7 +22,9 @@ import java.util.List;
|
|||||||
|
|
||||||
public class StudioImplementation {
|
public class StudioImplementation {
|
||||||
|
|
||||||
public static void trimReplay(File file, int beginning, int ending, File outputFile) throws IOException {
|
public static void trimReplay(File file, int beginning, int ending, File outputFile, ProgressUpdateListener updateListener) throws IOException {
|
||||||
|
updateListener.onProgressChanged(0f, I18n.format("replaymod.gui.editor.progress.status.initializing"));
|
||||||
|
|
||||||
ReplayStudio studio = new ReplayStudio();
|
ReplayStudio studio = new ReplayStudio();
|
||||||
studio.setWrappingEnabled(false);
|
studio.setWrappingEnabled(false);
|
||||||
ReplayFile replayFile = new ZipReplayFile(studio, file);
|
ReplayFile replayFile = new ZipReplayFile(studio, file);
|
||||||
@@ -39,24 +43,37 @@ public class StudioImplementation {
|
|||||||
ReplayOutputStream out = replayFile.writePacketData();
|
ReplayOutputStream out = replayFile.writePacketData();
|
||||||
PacketData packetData;
|
PacketData packetData;
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(1/4f, I18n.format("replaymod.gui.editor.progress.status.writing.raw"));
|
||||||
|
|
||||||
while((packetData = stream.next()) != null) {
|
while((packetData = stream.next()) != null) {
|
||||||
out.write(packetData);
|
out.write(packetData);
|
||||||
}
|
}
|
||||||
for(PacketData data : stream.end()) {
|
|
||||||
|
List<PacketData> endList = stream.end();
|
||||||
|
|
||||||
|
for(PacketData data : endList) {
|
||||||
out.write(data);
|
out.write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(2/4f, I18n.format("replaymod.gui.editor.progress.status.writing.zip"));
|
||||||
|
|
||||||
ReplayMetaData metaData = replayFile.getMetaData();
|
ReplayMetaData metaData = replayFile.getMetaData();
|
||||||
ending = Math.min(metaData.getDuration(), ending);
|
ending = Math.min(metaData.getDuration(), ending);
|
||||||
metaData.setDuration(ending - beginning);
|
metaData.setDuration(ending - beginning);
|
||||||
replayFile.writeMetaData(metaData);
|
replayFile.writeMetaData(metaData);
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(3/4f, I18n.format("replaymod.gui.editor.progress.status.writing.final"));
|
||||||
|
|
||||||
replayFile.saveTo(outputFile);
|
replayFile.saveTo(outputFile);
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(1f, I18n.format("replaymod.gui.editor.progress.status.finished"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void connectReplayFiles(List<File> filesToConnect, File outputFile) throws IOException {
|
public static void connectReplayFiles(List<File> filesToConnect, File outputFile, ProgressUpdateListener updateListener) throws IOException {
|
||||||
|
updateListener.onProgressChanged(0f, I18n.format("replaymod.gui.editor.progress.status.initializing"));
|
||||||
|
|
||||||
Validate.notEmpty(filesToConnect);
|
Validate.notEmpty(filesToConnect);
|
||||||
ReplayStudio studio = new ReplayStudio();
|
ReplayStudio studio = new ReplayStudio();
|
||||||
studio.setWrappingEnabled(false);
|
studio.setWrappingEnabled(false);
|
||||||
@@ -66,6 +83,12 @@ public class StudioImplementation {
|
|||||||
|
|
||||||
ConnectMetadataFilter metaDataFilter = new ConnectMetadataFilter();
|
ConnectMetadataFilter metaDataFilter = new ConnectMetadataFilter();
|
||||||
int startTime = 0;
|
int startTime = 0;
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(1/4f, I18n.format("replaymod.gui.editor.progress.status.writing.raw"));
|
||||||
|
|
||||||
|
float i = 0;
|
||||||
|
float size = filesToConnect.size();
|
||||||
|
|
||||||
for (File file : filesToConnect) {
|
for (File file : filesToConnect) {
|
||||||
ReplayFile replayFile = new ZipReplayFile(studio, file);
|
ReplayFile replayFile = new ZipReplayFile(studio, file);
|
||||||
PacketStream stream = studio.createReplayStream(replayFile.getPacketData(), true);
|
PacketStream stream = studio.createReplayStream(replayFile.getPacketData(), true);
|
||||||
@@ -93,11 +116,20 @@ public class StudioImplementation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
startTime += metaData.getDuration();
|
startTime += metaData.getDuration();
|
||||||
|
|
||||||
|
updateListener.onProgressChanged((1/4f)+((1/4f)*(i/size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(2/4f, I18n.format("replaymod.gui.editor.progress.status.writing.zip"));
|
||||||
|
|
||||||
metaDataFilter.writeTo(outputReplayFile);
|
metaDataFilter.writeTo(outputReplayFile);
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(3/4f, I18n.format("replaymod.gui.editor.progress.status.writing.final"));
|
||||||
|
|
||||||
outputReplayFile.saveTo(outputFile);
|
outputReplayFile.saveTo(outputFile);
|
||||||
|
|
||||||
|
updateListener.onProgressChanged(1f, I18n.format("replaymod.gui.editor.progress.status.finished"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,6 +180,15 @@ replaymod.gui.editor.trim.description=Removes the beginning and end of a Replay
|
|||||||
replaymod.gui.editor.connect.description=Connects multiple Replays in the specified order
|
replaymod.gui.editor.connect.description=Connects multiple Replays in the specified order
|
||||||
replaymod.gui.editor.modify.description=Provides several filters to modify Replay Files
|
replaymod.gui.editor.modify.description=Provides several filters to modify Replay Files
|
||||||
|
|
||||||
|
replaymod.gui.editor.progress.title=Editing Replay File...
|
||||||
|
replaymod.gui.editor.progress.pleasewait=Please wait while the Replay is being edited.
|
||||||
|
|
||||||
|
replaymod.gui.editor.progress.status.initializing=Initializing
|
||||||
|
replaymod.gui.editor.progress.status.writing.raw=Rewriting Replay...
|
||||||
|
replaymod.gui.editor.progress.status.writing.zip=Wrapping Replay File...
|
||||||
|
replaymod.gui.editor.progress.status.writing.final=Writing File to disk...
|
||||||
|
replaymod.gui.editor.progress.status.finished=Finished Editing!
|
||||||
|
|
||||||
#Cancel Replay GUI
|
#Cancel Replay GUI
|
||||||
replaymod.gui.cancelrender.title=Cancel Rendering
|
replaymod.gui.cancelrender.title=Cancel Rendering
|
||||||
replaymod.gui.cancelrender.message=Are you sure that you want to cancel the current rendering process?
|
replaymod.gui.cancelrender.message=Are you sure that you want to cancel the current rendering process?
|
||||||
|
|||||||
Reference in New Issue
Block a user