Fixed NPE in GuiReplayEditor when no Replays are available (returns to main menu)

Renamed .gui.replaystudio package to resemble the new GUI name (.gui.replayeditor)
This commit is contained in:
CrushedPixel
2015-05-31 11:46:14 +02:00
parent f29e1dd558
commit e1012cfefc
6 changed files with 14 additions and 8 deletions

View File

@@ -0,0 +1,198 @@
package eu.crushedpixel.replaymod.gui.replayeditor;
import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.elements.GuiArrowButton;
import eu.crushedpixel.replaymod.gui.elements.GuiDropdown;
import eu.crushedpixel.replaymod.gui.elements.GuiEntryList;
import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
import org.apache.commons.io.FilenameUtils;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class GuiConnectPart extends GuiStudioPart {
private final String DESCRIPTION = I18n.format("replaymod.gui.editor.connect.description");
private final String TITLE = I18n.format("replaymod.gui.editor.connect.title");
private boolean initialized = false;
private GuiEntryList<String> concatList;
private GuiDropdown<String> replayDropdown;
private GuiButton removeButton, addButton;
private GuiArrowButton upButton, downButton;
private List<File> replayFiles;
private List<String> filesToConcat;
public GuiConnectPart(int yPos) {
super(yPos);
this.mc = Minecraft.getMinecraft();
fontRendererObj = mc.fontRendererObj;
}
@Override
public void applyFilters(File replayFile, File outputFile) {
//TODO
}
@Override
public String getDescription() {
return DESCRIPTION;
}
@Override
public String getTitle() {
return TITLE;
}
@Override
public void initGui() {
if(!initialized) {
concatList = new GuiEntryList(1, fontRendererObj, 30, yPos, 150, 0);
filesToConcat = new ArrayList<String>();
String selectedName = FilenameUtils.getBaseName(GuiReplayEditor.instance.getSelectedFile().getAbsolutePath());
filesToConcat.add(selectedName);
concatList.setElements(filesToConcat);
concatList.setSelectionIndex(0);
replayDropdown = new GuiDropdown(1, fontRendererObj, 250, yPos + 5, 0, 4);
replayDropdown.clearElements();
replayFiles = ReplayFileIO.getAllReplayFiles();
int index = -1;
int i = 0;
for(File file : replayFiles) {
String name = FilenameUtils.getBaseName(file.getAbsolutePath());
replayDropdown.addElement(name);
if(name.equals(selectedName)) {
index = i;
}
i++;
}
replayDropdown.setSelectionPos(index);
replayDropdown.addSelectionListener(new SelectionListener() {
@Override
public void onSelectionChanged(int selectionIndex) {
try {
filesToConcat.set(concatList.getSelectionIndex(), replayDropdown.getElement(selectionIndex));
concatList.setElements(filesToConcat);
} catch(Exception e) {
} //Sorry, too lazy to properly avoid this Exception here
}
});
concatList.addSelectionListener(new SelectionListener() {
@Override
public void onSelectionChanged(int selectionIndex) {
String selName = (String) concatList.getElement(selectionIndex);
int i = 0;
for(Object s : replayDropdown.getAllElements()) {
String str = (String) s;
if(str.equals(selName)) {
replayDropdown.setSelectionIndex(i);
break;
}
i++;
}
removeButton.enabled = upButton.enabled = downButton.enabled = !(selectionIndex < 0 || selectionIndex >= filesToConcat.size());
if(upButton.enabled && selectionIndex == 0) upButton.enabled = false;
if(downButton.enabled && selectionIndex == filesToConcat.size() - 1) downButton.enabled = false;
}
});
upButton = new GuiArrowButton(GuiConstants.REPLAY_EDITOR_UP_BUTTON, 195, yPos + 40, "", GuiArrowButton.Direction.UP);
buttonList.add(upButton);
downButton = new GuiArrowButton(GuiConstants.REPLAY_EDITOR_DOWN_BUTTON, 219, yPos + 40, "", GuiArrowButton.Direction.DOWN);
buttonList.add(downButton);
int w = GuiReplayEditor.instance.width - 243 - 20 - 4;
removeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_REMOVE_BUTTON, 249, yPos + 40, I18n.format("replaymod.gui.remove"));
buttonList.add(removeButton);
addButton = new GuiButton(GuiConstants.REPLAY_EDITOR_ADD_BUTTON, 0, yPos + 40, I18n.format("replaymod.gui.add"));
buttonList.add(addButton);
concatList.setSelectionIndex(0);
}
int w = GuiReplayEditor.instance.width - 249 - 20 - 4;
addButton.xPosition = 249 + 6 + (w / 2);
addButton.width = w / 2 + 2;
removeButton.width = w / 2 + 2;
replayDropdown.width = GuiReplayEditor.instance.width - 250 - 18;
int h = GuiReplayEditor.instance.height - yPos - 20;
int rows = (int) (h / (float) GuiEntryList.elementHeight);
concatList.setVisibleElements(rows);
initialized = true;
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton); //call this first to ensure the dropdown is still open
concatList.mouseClicked(mouseX, mouseY, mouseButton);
replayDropdown.mouseClicked(mouseX, mouseY, mouseButton);
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawScreen(mouseX, mouseY, partialTicks);
concatList.drawTextBox();
replayDropdown.drawTextBox();
drawString(fontRendererObj, I18n.format("replaymod.gui.replay")+":", 200, yPos + 5 + 7, Color.WHITE.getRGB());
}
@Override
public void updateScreen() {
if(!initialized) initGui();
}
@Override
public void keyTyped(char typedChar, int keyCode) {
}
@Override
protected void actionPerformed(GuiButton button) {
if(!button.enabled || replayDropdown.isExpanded()) {
return;
}
if(button.id == GuiConstants.REPLAY_EDITOR_ADD_BUTTON) {
filesToConcat.add(FilenameUtils.getBaseName(replayFiles.get(0).getAbsolutePath()));
concatList.setElements(filesToConcat);
concatList.setSelectionIndex(filesToConcat.size() - 1);
} else if(button.id == GuiConstants.REPLAY_EDITOR_REMOVE_BUTTON) {
int indexBefore = concatList.getSelectionIndex();
if(indexBefore >= 0 && indexBefore < filesToConcat.size()) {
filesToConcat.remove(indexBefore);
concatList.setElements(filesToConcat);
if(filesToConcat.size() <= indexBefore) {
concatList.setSelectionIndex(filesToConcat.size() - 1);
} else {
concatList.setSelectionIndex(indexBefore);
}
}
}
}
}

View File

@@ -0,0 +1,223 @@
package eu.crushedpixel.replaymod.gui.replayeditor;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.elements.GuiDropdown;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import org.apache.commons.io.FilenameUtils;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class GuiReplayEditor extends GuiScreen {
private static final int tabYPos = 110;
public static GuiReplayEditor instance = null;
private StudioTab currentTab = StudioTab.TRIM;
private GuiDropdown replayDropdown;
private GuiButton saveModeButton, saveButton;
private boolean overrideSave = false;
private boolean initialized = false;
private List<File> replayFiles = new ArrayList<File>();
public GuiReplayEditor() {
instance = this;
}
public File getSelectedFile() {
try {
return replayFiles.get(replayDropdown.getSelectionIndex());
} catch(ArrayIndexOutOfBoundsException e) {
return null;
}
}
private void refreshReplayDropdown() {
replayDropdown.clearElements();
replayFiles = ReplayFileIO.getAllReplayFiles();
if(replayFiles.size() == 0) {
mc.displayGuiScreen(null);
ReplayMod.guiEventHandler.replayCount = 0;
return;
}
for(File file : replayFiles) {
String name = FilenameUtils.getBaseName(file.getAbsolutePath());
replayDropdown.addElement(name);
}
}
@Override
public void initGui() {
List<GuiButton> tabButtons = new ArrayList<GuiButton>();
tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_TRIM_TAB, 0, 0, I18n.format("replaymod.gui.editor.trim.title")));
tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_CONNECT_TAB, 0, 0, I18n.format("replaymod.gui.editor.connect.title")));
tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_MODIFY_TAB, 0, 0, I18n.format("replaymod.gui.editor.modify.title")));
int w = this.width - 30;
int w2 = w / tabButtons.size();
int i = 0;
for(GuiButton b : tabButtons) {
int x = 15 + (w2 * i);
b.xPosition = x + 2;
b.yPosition = 30;
b.width = w2 - 4;
buttonList.add(b);
i++;
}
int modeWidth = tabButtons.get(0).width;
if(!initialized) {
replayDropdown = new GuiDropdown(1, fontRendererObj, 15 + 2 + 1 + 80, 60, this.width - 30 - 8 - 80 - modeWidth - 4, 5);
refreshReplayDropdown();
} else {
replayDropdown.width = this.width - 30 - 8 - 80 - modeWidth - 4;
}
if(!initialized) {
saveModeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON, width - 15 - modeWidth - 3, 60, getSaveModeLabel());
} else {
saveModeButton.xPosition = width - 15 - modeWidth - 3;
}
saveModeButton.width = modeWidth;
buttonList.add(saveModeButton);
GuiButton backButton = new GuiButton(GuiConstants.REPLAY_EDITOR_BACK_BUTTON, width - 70 - 18, height - 20 - 5, I18n.format("replaymod.gui.back"));
backButton.width = 70;
buttonList.add(backButton);
saveButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVE_BUTTON, width - 70 - 18, height - (2 * 20) - 5 - 3, I18n.format("replaymod.gui.save"));
saveButton.width = 70;
buttonList.add(saveButton);
for(StudioTab tab : StudioTab.values()) {
tab.getStudioPart().initGui();
}
initialized = true;
}
private String getSaveModeLabel() {
return overrideSave ? I18n.format("replaymod.gui.editor.savemode.override") : I18n.format("replaymod.gui.editor.savemode.newfile");
}
;
@Override
protected void actionPerformed(GuiButton button) throws IOException {
if(!button.enabled) return;
if(button.id == GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON) {
overrideSave = !overrideSave;
button.displayString = getSaveModeLabel();
} else if(button.id == GuiConstants.REPLAY_EDITOR_BACK_BUTTON) {
mc.displayGuiScreen(new GuiMainMenu());
} else if(button.id == GuiConstants.REPLAY_EDITOR_TRIM_TAB) {
currentTab = StudioTab.TRIM;
} else if(button.id == GuiConstants.REPLAY_EDITOR_CONNECT_TAB) {
currentTab = StudioTab.CONNECT;
} else if(button.id == GuiConstants.REPLAY_EDITOR_MODIFY_TAB) {
currentTab = StudioTab.MODIFY;
} else if(button.id == GuiConstants.REPLAY_EDITOR_SAVE_BUTTON) {
File outputFile = getSelectedFile();
File folder = ReplayFileIO.getReplayFolder();
if(!overrideSave) {
String name = FilenameUtils.getBaseName(outputFile.getAbsolutePath()) + "_edited";
File f = new File(folder, name + ".mcpr");
int num = 0;
while(f.exists()) {
num++;
String fileName = name + "_" + num;
f = new File(folder, fileName + ".mcpr");
}
outputFile = f;
}
currentTab.getStudioPart().applyFilters(getSelectedFile(), outputFile);
}
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
throws IOException {
replayDropdown.mouseClicked(mouseX, mouseY, mouseButton);
currentTab.getStudioPart().mouseClicked(mouseX, mouseY, mouseButton);
super.mouseClicked(mouseX, mouseY, mouseButton);
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks);
currentTab.getStudioPart().drawScreen(mouseX, mouseY, partialTicks);
drawCenteredString(fontRendererObj, "§n" + currentTab.getStudioPart().getTitle(), width / 2, 92, Color.WHITE.getRGB());
List<String> rows = new ArrayList<String>();
String remaining = currentTab.getStudioPart().getDescription();
while(remaining.length() > 0) {
String[] split = remaining.split(" ");
String b = "";
for(String sp : split) {
b += sp + " ";
if(fontRendererObj.getStringWidth(b.trim()) > width - 30 - 70 - 20) {
b = b.substring(0, b.trim().length() - (sp.length()));
break;
}
}
String trimmed = b.trim();
rows.add(trimmed);
try {
remaining = remaining.substring(trimmed.length() + 1);
} catch(Exception e) {
break;
}
}
int i = 0;
for(String row : rows) {
drawString(fontRendererObj, row, 30, height - (15 * (rows.size() - i)), Color.WHITE.getRGB());
i++;
}
drawCenteredString(fontRendererObj, I18n.format("replaymod.gui.replayeditor"), this.width / 2, 10, 16777215);
drawString(fontRendererObj, I18n.format("replaymod.gui.editor.replayfile"), 30, 67, Color.WHITE.getRGB());
replayDropdown.drawTextBox();
}
@Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
currentTab.getStudioPart().keyTyped(typedChar, keyCode);
super.keyTyped(typedChar, keyCode);
}
@Override
public void updateScreen() {
currentTab.getStudioPart().updateScreen();
super.updateScreen();
}
private enum StudioTab {
TRIM(new GuiTrimPart(tabYPos)), CONNECT(new GuiConnectPart(tabYPos)), MODIFY(new GuiConnectPart(tabYPos));
private GuiStudioPart studioPart;
private StudioTab(GuiStudioPart part) {
this.studioPart = part;
}
public GuiStudioPart getStudioPart() {
return studioPart;
}
}
}

View File

@@ -0,0 +1,29 @@
package eu.crushedpixel.replaymod.gui.replayeditor;
import net.minecraft.client.gui.GuiScreen;
import java.io.File;
import java.io.IOException;
public abstract class GuiStudioPart extends GuiScreen {
protected int yPos = 0;
public GuiStudioPart(int yPos) {
this.yPos = yPos;
}
public abstract void applyFilters(File replayFile, File outputFile);
public abstract String getDescription();
public abstract String getTitle();
@Override
public abstract void keyTyped(char typedChar, int keyCode);
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton);
}
}

View File

@@ -0,0 +1,158 @@
package eu.crushedpixel.replaymod.gui.replayeditor;
import eu.crushedpixel.replaymod.gui.elements.GuiNumberInput;
import eu.crushedpixel.replaymod.studio.StudioImplementation;
import eu.crushedpixel.replaymod.utils.TimestampUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import org.lwjgl.input.Keyboard;
import java.awt.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class GuiTrimPart extends GuiStudioPart {
private static final String DESCRIPTION = I18n.format("replaymod.gui.editor.trim.description");
private final String TITLE = I18n.format("replaymod.gui.editor.trim.title");
private Minecraft mc = Minecraft.getMinecraft();
private boolean initialized = false;
private GuiNumberInput startMinInput, startSecInput, startMsInput;
private GuiNumberInput endMinInput, endSecInput, endMsInput;
private List<GuiNumberInput> inputOrder = new ArrayList<GuiNumberInput>();
public GuiTrimPart(int yPos) {
super(yPos);
fontRendererObj = mc.fontRendererObj;
}
@Override
public void applyFilters(File replayFile, File outputFile) {
try {
StudioImplementation.trimReplay(replayFile, false, getStartTimestamp(), getEndTimestamp(), outputFile);
} catch(Exception e) {
e.printStackTrace();
}
}
private int valueOf(String text) {
try {
return Integer.valueOf(text);
} catch(NumberFormatException e) {
return 0;
}
}
private int getStartTimestamp() {
int mins = valueOf(startMinInput.getText());
int secs = valueOf(startSecInput.getText());
int ms = valueOf(startMsInput.getText());
return TimestampUtils.calculateTimestamp(mins, secs, ms);
}
private int getEndTimestamp() {
int mins = valueOf(endMinInput.getText());
int secs = valueOf(endSecInput.getText());
int ms = valueOf(endMsInput.getText());
return TimestampUtils.calculateTimestamp(mins, secs, ms);
}
@Override
public String getDescription() {
return DESCRIPTION;
}
@Override
public String getTitle() {
return TITLE;
}
@Override
public void initGui() {
if(!initialized) {
startMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos, 30, null, 999d, null, false);
startSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos, 25, null, 99d, null, false);
startMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos, 30, null, 999d, null, false);
endMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos + 30, 30, null, 999d, null, false);
endSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos + 30, 25, null, 99d, null, false);
endMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos + 30, 30, null, 999d, null, false);
inputOrder.clear();
inputOrder.add(startMinInput);
inputOrder.add(startSecInput);
inputOrder.add(startMsInput);
inputOrder.add(endMinInput);
inputOrder.add(endSecInput);
inputOrder.add(endMsInput);
}
initialized = true;
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
for(GuiNumberInput input : inputOrder) {
input.mouseClicked(mouseX, mouseY, mouseButton);
}
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.start")+":", 30, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.end")+":", 30, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.minutes"), 105, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.minutes"), 105, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.seconds"), 150, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.seconds"), 150, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.milliseconds"), 200, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, I18n.format("replaymod.gui.milliseconds"), 200, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "Timestamp: " + getStartTimestamp(), 230, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "Timestamp: " + getEndTimestamp(), 230, yPos + 30 + 7, Color.WHITE.getRGB());
for(GuiNumberInput input : inputOrder) {
input.drawTextBox();
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
@Override
public void updateScreen() {
if(!initialized) {
initGui();
} else {
for(GuiNumberInput input : inputOrder) {
input.updateCursorCounter();
}
}
}
@Override
public void keyTyped(char typedChar, int keyCode) {
if(keyCode == Keyboard.KEY_TAB) { //Tab handling
int i = 0;
for(GuiNumberInput input : inputOrder) {
if(input.isFocused()) {
input.setFocused(false);
i++;
if(i >= inputOrder.size()) i = 0;
inputOrder.get(i).setFocused(true);
break;
}
i++;
}
} else {
for(GuiNumberInput input : inputOrder) {
input.textboxKeyTyped(typedChar, keyCode);
}
}
}
}