From 66c595eb042a08801729b29b2f82061bb2b4a7d3 Mon Sep 17 00:00:00 2001 From: CrushedPixel Date: Mon, 13 Jul 2015 01:21:48 +0200 Subject: [PATCH] Marker Keyframes are now being saved in a KeyframeList in the ReplayHandler Made MarkerKeyframes names editable in GuiEditKeyframe Shows "Unnamed Marker" if Marker name is empty --- .../replaymod/gui/GuiEditKeyframe.java | 60 +++++++++++++------ .../elements/timelines/GuiMarkerTimeline.java | 5 +- .../replaymod/interpolation/KeyframeList.java | 8 +++ .../replaymod/replay/ReplayHandler.java | 23 ++++--- .../replaymod/utils/ReplayFileIO.java | 3 +- 5 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiEditKeyframe.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiEditKeyframe.java index 89ca9ebd..4138121b 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/GuiEditKeyframe.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiEditKeyframe.java @@ -1,10 +1,13 @@ package eu.crushedpixel.replaymod.gui; import eu.crushedpixel.replaymod.ReplayMod; +import eu.crushedpixel.replaymod.gui.elements.GuiAdvancedTextField; import eu.crushedpixel.replaymod.gui.elements.GuiArrowButton; +import eu.crushedpixel.replaymod.gui.elements.GuiDraggingNumberInput; import eu.crushedpixel.replaymod.gui.elements.GuiNumberInput; -import eu.crushedpixel.replaymod.holders.Keyframe; import eu.crushedpixel.replaymod.holders.AdvancedPosition; +import eu.crushedpixel.replaymod.holders.Keyframe; +import eu.crushedpixel.replaymod.holders.Marker; import eu.crushedpixel.replaymod.holders.TimestampValue; import eu.crushedpixel.replaymod.interpolation.KeyframeList; import eu.crushedpixel.replaymod.replay.ReplayHandler; @@ -31,6 +34,8 @@ public class GuiEditKeyframe extends GuiScreen { private GuiNumberInput xCoord, yCoord, zCoord, pitch, yaw, roll; private GuiNumberInput min, sec, ms; + private GuiAdvancedTextField markerNameInput; + private List inputs = new ArrayList(); private List posInputs = new ArrayList(); @@ -41,6 +46,7 @@ public class GuiEditKeyframe extends GuiScreen { private Keyframe keyframeBackup; private boolean save; private boolean posKeyframe; + private boolean markerKeyframe; private Keyframe previous, next; @@ -55,12 +61,12 @@ public class GuiEditKeyframe extends GuiScreen { this.keyframe = keyframe; this.keyframeBackup = keyframe.copy(); this.posKeyframe = keyframe.getValue() instanceof AdvancedPosition; + this.markerKeyframe = keyframe.getValue() instanceof Marker; boolean timeKeyframe = keyframe.getValue() instanceof TimestampValue; - ReplayHandler.selectKeyframe(null); - KeyframeList positionKeyframes = ReplayHandler.getPositionKeyframes(); KeyframeList timeKeyframes = ReplayHandler.getTimeKeyframes(); + KeyframeList markerKeyframes = ReplayHandler.getMarkers(); if(posKeyframe) { previous = positionKeyframes.getPreviousKeyframe(keyframe.getRealTimestamp() - 1); @@ -72,10 +78,11 @@ public class GuiEditKeyframe extends GuiScreen { next = timeKeyframes.getNextKeyframe(keyframe.getRealTimestamp() + 1); screenTitle = I18n.format("replaymod.gui.editkeyframe.title.time"); + } else if(markerKeyframe) { + previous = markerKeyframes.getPreviousKeyframe(keyframe.getRealTimestamp() - 1); + next = markerKeyframes.getNextKeyframe(keyframe.getRealTimestamp() + 1); } - ReplayHandler.selectKeyframe(keyframe); - ReplayMod.replaySender.setReplaySpeed(0); } @@ -97,9 +104,9 @@ public class GuiEditKeyframe extends GuiScreen { //Real Time Input int timestamp = keyframe.getRealTimestamp(); - min = new GuiNumberInput(fontRendererObj, 0, 0, 30, 0, 9, TimestampUtils.getMinutesFromTimestamp(timestamp), false); - sec = new GuiNumberInput(fontRendererObj, 0, 0, 25, 0, 59, TimestampUtils.getSecondsFromTimestamp(timestamp), false); - ms = new GuiNumberInput(fontRendererObj, 0, 0, 35, 0, 999, TimestampUtils.getMillisecondsFromTimestamp(timestamp), false); + min = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 30, 0d, 9d, (double)TimestampUtils.getMinutesFromTimestamp(timestamp), false); + sec = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 25, 0d, 59d, (double)TimestampUtils.getSecondsFromTimestamp(timestamp), false); + ms = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 35, 0d, 999d, (double)TimestampUtils.getMillisecondsFromTimestamp(timestamp), false); inputs.add(min); inputs.add(sec); @@ -108,12 +115,12 @@ public class GuiEditKeyframe extends GuiScreen { //Position/Virtual Time Input if(posKeyframe) { AdvancedPosition pos = ((Keyframe)keyframe).getValue(); - xCoord = new GuiNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getX()), true); - yCoord = new GuiNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getY()), true); - zCoord = new GuiNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getZ()), true); - yaw = new GuiNumberInput(fontRendererObj, 0, 0, 100, -90d, 90d, RoundUtils.round2Decimals(pos.getYaw()), true); - pitch = new GuiNumberInput(fontRendererObj, 0, 0, 100, -180d, 180d, RoundUtils.round2Decimals(pos.getPitch()), true); - roll = new GuiNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getRoll()), true); + xCoord = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getX()), true); + yCoord = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getY()), true); + zCoord = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getZ()), true); + yaw = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 100, -90d, 90d, RoundUtils.round2Decimals(pos.getYaw()), true); + pitch = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 100, -180d, 180d, RoundUtils.round2Decimals(pos.getPitch()), true); + roll = new GuiDraggingNumberInput(fontRendererObj, 0, 0, 100, null, null, RoundUtils.round2Decimals(pos.getRoll()), true); posInputs.add(xCoord); posInputs.add(yCoord); @@ -123,6 +130,14 @@ public class GuiEditKeyframe extends GuiScreen { posInputs.add(roll); inputs.addAll(posInputs); + } else if(markerKeyframe) { + String name = ((Keyframe)keyframe).getValue().getName(); + if(name == null) name = ""; + markerNameInput = new GuiAdvancedTextField(fontRendererObj, 0, 0, 200, 20); + markerNameInput.hint = I18n.format("replaymod.gui.editkeyframe.markername"); + markerNameInput.setText(name); + + inputs.add(markerNameInput); } } @@ -159,6 +174,9 @@ public class GuiEditKeyframe extends GuiScreen { input.yPosition = i < 3 ? virtualY + 20 + i*30 : virtualY + 20 + (i-3)*30; i++; } + } else if(markerKeyframe) { + markerNameInput.xPosition = width/2 - 100; + markerNameInput.yPosition = height/2-10; } saveButton.yPosition = cancelButton.yPosition = virtualY + virtualHeight - 20 - 5; @@ -184,15 +202,23 @@ public class GuiEditKeyframe extends GuiScreen { @Override public void onGuiClosed() { if(!save) { - ReplayHandler.removeKeyframe(keyframe); - ReplayHandler.addKeyframe(keyframeBackup); - ReplayHandler.selectKeyframe(keyframeBackup); + if(!markerKeyframe) { + ReplayHandler.removeKeyframe(keyframe); + ReplayHandler.addKeyframe(keyframeBackup); + ReplayHandler.selectKeyframe(keyframeBackup); + } else { + ReplayHandler.getMarkers().remove(keyframe); + ReplayHandler.getMarkers().add(keyframeBackup); + ReplayHandler.selectMarkerKeyframe(keyframeBackup); + } } else { keyframe.setRealTimestamp(TimestampUtils.calculateTimestamp(min.getIntValue(), sec.getIntValue(), ms.getIntValue())); if(posKeyframe) { ((Keyframe)keyframe).setValue(new AdvancedPosition(xCoord.getPreciseValue(), yCoord.getPreciseValue(), zCoord.getPreciseValue(), new Float(pitch.getPreciseValue()), (float) yaw.getPreciseValue(), (float) roll.getPreciseValue(), null)); + } else if(markerKeyframe) { + ((Keyframe)keyframe).getValue().setName(markerNameInput.getText().trim()); } } ReplayHandler.fireKeyframesModifyEvent(); diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java index 5c6fb827..77f12c83 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java @@ -1,6 +1,7 @@ package eu.crushedpixel.replaymod.gui.elements.timelines; import eu.crushedpixel.replaymod.ReplayMod; +import eu.crushedpixel.replaymod.gui.GuiEditKeyframe; import eu.crushedpixel.replaymod.holders.Keyframe; import eu.crushedpixel.replaymod.holders.Marker; import eu.crushedpixel.replaymod.replay.ReplayHandler; @@ -51,7 +52,7 @@ public class GuiMarkerTimeline extends GuiTimeline { long currentTime = System.currentTimeMillis(); if(closest != null) { if(currentTime - clickTime < 500) { // if double clicked then open GUI instead - //TODO: Make Marker Name editable + mc.displayGuiScreen(new GuiEditKeyframe(closest)); this.clickedKeyFrame = null; } else { this.clickedKeyFrame = closest; @@ -155,7 +156,7 @@ public class GuiMarkerTimeline extends GuiTimeline { if(MouseUtils.isMouseWithinBounds(keyframeX - 2, this.positionY + BORDER_TOP + 10 + 1, 5, 5)) { Point mouse = MouseUtils.getMousePos(); String markerName = marker.getValue().getName(); - if(markerName == null) markerName = I18n.format("replaymod.gui.ingame.unnamedmarker"); + if(markerName == null || markerName.isEmpty()) markerName = I18n.format("replaymod.gui.ingame.unnamedmarker"); ReplayMod.tooltipRenderer.drawTooltip(mouse.getX(), mouse.getY(), markerName, null, Color.WHITE); drawn = true; diff --git a/src/main/java/eu/crushedpixel/replaymod/interpolation/KeyframeList.java b/src/main/java/eu/crushedpixel/replaymod/interpolation/KeyframeList.java index 4e9fc8de..d9ca259b 100644 --- a/src/main/java/eu/crushedpixel/replaymod/interpolation/KeyframeList.java +++ b/src/main/java/eu/crushedpixel/replaymod/interpolation/KeyframeList.java @@ -2,11 +2,13 @@ package eu.crushedpixel.replaymod.interpolation; import eu.crushedpixel.replaymod.holders.Keyframe; import eu.crushedpixel.replaymod.holders.KeyframeComparator; +import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.Collections; import java.util.List; +@NoArgsConstructor public class KeyframeList extends ArrayList> { private static final KeyframeComparator KEYFRAME_COMPARATOR = new KeyframeComparator(); @@ -15,6 +17,12 @@ public class KeyframeList extends ArrayList private Interpolation interpolation; + public KeyframeList(List> initial) { + for(Keyframe kf : initial) { + add(kf); + } + } + @Override public boolean add(Keyframe t) { //remove keyframes that have same timestamp diff --git a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java index 917744af..9936730b 100755 --- a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java @@ -59,8 +59,8 @@ public class ReplayHandler { private static Entity currentEntity = null; private static AdvancedPosition lastPosition = null; - private static Keyframe[] initialMarkers = new Keyframe[0]; - private static List> markerKeyframes = new ArrayList>(); + private static KeyframeList initialMarkers = new KeyframeList(); + private static KeyframeList markerKeyframes = new KeyframeList(); private static float cameraTilt = 0; @@ -95,13 +95,13 @@ public class ReplayHandler { } } - public static Keyframe[] getMarkers() { - return markerKeyframes.toArray(new Keyframe[markerKeyframes.size()]); + public static KeyframeList getMarkers() { + return markerKeyframes; } - public static void setMarkers(Keyframe[] m, boolean write) { + public static void setMarkers(KeyframeList m, boolean write) { markerKeyframes.clear(); - Collections.addAll(markerKeyframes, m); + markerKeyframes.addAll(m); if(write) { try { @@ -440,12 +440,9 @@ public class ReplayHandler { KeyframeSet[] paths = currentReplayFile.paths().get(); ReplayHandler.setKeyframeRepository(paths == null ? new KeyframeSet[0] : paths, false); - List> markerList = currentReplayFile.markers().get(); - Keyframe[] markers; - if(markerList == null) markers = new Keyframe[0]; - else markers = markerList.toArray(new Keyframe[markerList.size()]); - ReplayHandler.setMarkers(markers, false); - ReplayHandler.initialMarkers = markers; + KeyframeList markerList = new KeyframeList(currentReplayFile.markers().get()); + ReplayHandler.setMarkers(markerList, false); + ReplayHandler.initialMarkers = markerList; PlayerVisibility visibility = currentReplayFile.visibility().get(); PlayerHandler.loadPlayerVisibilityConfiguration(visibility); @@ -522,7 +519,7 @@ public class ReplayHandler { try { //only if Marker keyframes changed, rewrite them - if(!Arrays.equals(getMarkers(), initialMarkers)) { + if(!initialMarkers.equals(markerKeyframes)) { File markerFile = File.createTempFile(ReplayFile.ENTRY_MARKERS, "json"); ReplayFileIO.write(getMarkers(), markerFile); ReplayMod.replayFileAppender.registerModifiedFile(markerFile, ReplayFile.ENTRY_MARKERS, ReplayHandler.getReplayFile()); diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java index 545002ae..66493600 100755 --- a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java +++ b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java @@ -4,6 +4,7 @@ import com.google.gson.Gson; import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.assets.CustomObjectRepository; import eu.crushedpixel.replaymod.holders.*; +import eu.crushedpixel.replaymod.interpolation.KeyframeList; import eu.crushedpixel.replaymod.recording.PacketSerializer; import eu.crushedpixel.replaymod.recording.ReplayMetaData; import io.netty.buffer.ByteBuf; @@ -163,7 +164,7 @@ public class ReplayFileIO { write((Object) metaData, file); } - public static void write(Keyframe[] markers, File file) throws IOException { + public static void write(KeyframeList markers, File file) throws IOException { write((Object) markers, file); }