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:
CrushedPixel
2015-07-02 23:08:09 +02:00
parent 088bb00ab3
commit 8c81dd414e
9 changed files with 237 additions and 23 deletions

View File

@@ -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;
} }

View File

@@ -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);
} }

View File

@@ -0,0 +1,9 @@
package eu.crushedpixel.replaymod.gui.elements.listeners;
public interface ProgressUpdateListener {
void onProgressChanged(float progress);
void onProgressChanged(float progress, String progressString);
}

View File

@@ -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,31 +35,50 @@ 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) {
try { this.outputFile = outputFile;
List<File> inputFiles = new ArrayList<File>(); filterThread = new Thread(new Runnable() {
OUTER: @Override
for (String fileName : filesToConcat) { public void run() {
for (File file : replayFiles) { try {
if (fileName.equals(FilenameUtils.getBaseName(file.getAbsolutePath()))) { List<File> inputFiles = new ArrayList<File>();
inputFiles.add(file); OUTER:
continue OUTER; for (String fileName : filesToConcat) {
for (File file : replayFiles) {
if (fileName.equals(FilenameUtils.getBaseName(file.getAbsolutePath()))) {
inputFiles.add(file);
continue OUTER;
}
}
throw new RuntimeException(fileName);
} }
StudioImplementation.connectReplayFiles(inputFiles, outputFile, GuiConnectPart.this);
} catch (Exception e) {
e.printStackTrace();
} }
throw new RuntimeException(fileName);
} }
StudioImplementation.connectReplayFiles(inputFiles, outputFile); }, "replay-editor-connect");
} catch (Exception e) {
e.printStackTrace(); filterThread.start();
}
mc.displayGuiScreen(new GuiReplayEditingProcess(this));
}
@Override
@SuppressWarnings("deprecation")
public void cancelFilters() {
filterThread.stop();
FileUtils.deleteQuietly(outputFile);
} }
@Override @Override

View File

@@ -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);
}
}
}
}
}

View File

@@ -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;
}
} }

View File

@@ -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,11 +35,28 @@ public class GuiTrimPart extends GuiStudioPart {
@Override @Override
public void applyFilters(File replayFile, File outputFile) { public void applyFilters(File replayFile, File outputFile) {
try { this.outputFile = outputFile;
StudioImplementation.trimReplay(replayFile, getStartTimestamp(), getEndTimestamp(), outputFile); filterThread = new Thread(new Runnable() {
} catch(Exception e) { @Override
e.printStackTrace(); public void run() {
} try {
StudioImplementation.trimReplay(replayFile, getStartTimestamp(), getEndTimestamp(), outputFile, GuiTrimPart.this);
} catch(Exception e) {
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) {

View File

@@ -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"));
} }
} }

View File

@@ -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?