Re-work Replay Editor UI
This commit is contained in:
@@ -40,9 +40,9 @@ public class MainMenuHandler {
|
|||||||
if (x(button) + button.width < gui.width / 2 - 100
|
if (x(button) + button.width < gui.width / 2 - 100
|
||||||
|| x(button) > gui.width / 2 + 100
|
|| x(button) > gui.width / 2 + 100
|
||||||
|| y(button) > gui.height / 4 + 10 + 4 * 24) continue;
|
|| y(button) > gui.height / 4 + 10 + 4 * 24) continue;
|
||||||
// Move button up to make space for two rows of buttons
|
// Move button up to make space for one rows of buttons
|
||||||
// and then move back down by 10 to compensate for the space to the exit button that was already there
|
// and then move back down by 10 to compensate for the space to the exit button that was already there
|
||||||
int offset = -2 * 24 + 10;
|
int offset = -1 * 24 + 10;
|
||||||
y(button, y(button) + offset);
|
y(button, y(button) + offset);
|
||||||
|
|
||||||
//#if MC>=11300
|
//#if MC>=11300
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class ReplayModEditor implements Module {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initClient() {
|
public void initClient() {
|
||||||
new GuiHandler(this).register();
|
new GuiHandler().register();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReplayMod getCore() {
|
public ReplayMod getCore() {
|
||||||
|
|||||||
262
src/main/java/com/replaymod/editor/gui/GuiEditReplay.java
Normal file
262
src/main/java/com/replaymod/editor/gui/GuiEditReplay.java
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
package com.replaymod.editor.gui;
|
||||||
|
|
||||||
|
import com.replaymod.core.ReplayMod;
|
||||||
|
import com.replaymod.core.utils.Utils;
|
||||||
|
import com.replaymod.editor.ReplayModEditor;
|
||||||
|
import com.replaymod.replay.gui.overlay.GuiMarkerTimeline;
|
||||||
|
import com.replaymod.replaystudio.data.Marker;
|
||||||
|
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
||||||
|
import com.replaymod.replaystudio.studio.ReplayStudio;
|
||||||
|
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||||
|
import de.johni0702.minecraft.gui.container.GuiContainer;
|
||||||
|
import de.johni0702.minecraft.gui.container.GuiPanel;
|
||||||
|
import de.johni0702.minecraft.gui.element.GuiButton;
|
||||||
|
import de.johni0702.minecraft.gui.element.GuiHorizontalScrollbar;
|
||||||
|
import de.johni0702.minecraft.gui.element.GuiTexturedButton;
|
||||||
|
import de.johni0702.minecraft.gui.element.GuiTooltip;
|
||||||
|
import de.johni0702.minecraft.gui.element.advanced.GuiProgressBar;
|
||||||
|
import de.johni0702.minecraft.gui.element.advanced.GuiTimelineTime;
|
||||||
|
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
||||||
|
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
||||||
|
import de.johni0702.minecraft.gui.layout.VerticalLayout;
|
||||||
|
import de.johni0702.minecraft.gui.popup.AbstractGuiPopup;
|
||||||
|
import de.johni0702.minecraft.gui.utils.lwjgl.Color;
|
||||||
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
|
import net.minecraft.crash.CrashReport;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class GuiEditReplay extends AbstractGuiPopup<GuiEditReplay> {
|
||||||
|
private final Path inputPath;
|
||||||
|
|
||||||
|
private final EditTimeline timeline;
|
||||||
|
|
||||||
|
private final GuiTimelineTime<GuiMarkerTimeline> timelineTime = new GuiTimelineTime<>();
|
||||||
|
|
||||||
|
private final GuiHorizontalScrollbar scrollbar = new GuiHorizontalScrollbar().setSize(300, 9);
|
||||||
|
|
||||||
|
|
||||||
|
private final GuiTexturedButton zoomInButton = new GuiTexturedButton().setSize(9, 9)
|
||||||
|
.onClick(() -> zoomTimeline(2d / 3d))
|
||||||
|
.setTexture(ReplayMod.TEXTURE, ReplayMod.TEXTURE_SIZE).setTexturePosH(40, 20)
|
||||||
|
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.ingame.menu.zoomin"));
|
||||||
|
|
||||||
|
private final GuiTexturedButton zoomOutButton = new GuiTexturedButton().setSize(9, 9)
|
||||||
|
.onClick(() -> zoomTimeline(3d / 2d))
|
||||||
|
.setTexture(ReplayMod.TEXTURE, ReplayMod.TEXTURE_SIZE).setTexturePosH(40, 30)
|
||||||
|
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.ingame.menu.zoomout"));
|
||||||
|
|
||||||
|
private final GuiPanel zoomButtonPanel = new GuiPanel()
|
||||||
|
.setLayout(new VerticalLayout(VerticalLayout.Alignment.CENTER).setSpacing(2))
|
||||||
|
.addElements(null, zoomInButton, zoomOutButton);
|
||||||
|
|
||||||
|
private Set<Marker> markers;
|
||||||
|
|
||||||
|
protected GuiEditReplay(GuiContainer container, Path inputPath) throws IOException {
|
||||||
|
super(container);
|
||||||
|
this.inputPath = inputPath;
|
||||||
|
|
||||||
|
try (ZipReplayFile replayFile = new ZipReplayFile(new ReplayStudio(), inputPath.toFile())) {
|
||||||
|
markers = replayFile.getMarkers().or(HashSet::new);
|
||||||
|
timeline = new EditTimeline(new HashSet<>(markers), markers -> this.markers = markers);
|
||||||
|
timeline.setSize(300, 20)
|
||||||
|
.setMarkers()
|
||||||
|
.setLength(replayFile.getMetaData().getDuration())
|
||||||
|
.onClick(timeline::setCursorPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
timelineTime.setTimeline(timeline);
|
||||||
|
|
||||||
|
scrollbar.onValueChanged(() -> {
|
||||||
|
timeline.setOffset((int) (scrollbar.getPosition() * timeline.getLength()));
|
||||||
|
timeline.setZoom(scrollbar.getZoom());
|
||||||
|
}).setZoom(1);
|
||||||
|
|
||||||
|
GuiPanel timelinePanel = new GuiPanel()
|
||||||
|
.setSize(300, 40)
|
||||||
|
.setLayout(new CustomLayout<GuiPanel>() {
|
||||||
|
@Override
|
||||||
|
protected void layout(GuiPanel container, int width, int height) {
|
||||||
|
pos(zoomButtonPanel, width - width(zoomButtonPanel), 10);
|
||||||
|
pos(timelineTime, 0, 2);
|
||||||
|
size(timelineTime, x(zoomButtonPanel), 8);
|
||||||
|
pos(timeline, 0, y(timelineTime) + height(timelineTime));
|
||||||
|
size(timeline, x(zoomButtonPanel) - 2, 20);
|
||||||
|
pos(scrollbar, 0, y(timeline) + height(timeline) + 1);
|
||||||
|
size(scrollbar, x(zoomButtonPanel) - 2, 9);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addElements(null, timelineTime, timeline, scrollbar, zoomButtonPanel);
|
||||||
|
|
||||||
|
GuiButton buttonAddSplit = new GuiButton()
|
||||||
|
.setSize(100, 20)
|
||||||
|
.setI18nLabel("replaymod.gui.edit.split")
|
||||||
|
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.edit.split.tooltip"))
|
||||||
|
.onClick(() -> {
|
||||||
|
Marker marker = new Marker();
|
||||||
|
marker.setTime(timeline.getCursorPosition());
|
||||||
|
marker.setName(MarkerProcessor.MARKER_NAME_SPLIT);
|
||||||
|
timeline.addMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
GuiButton buttonInsertCut = new GuiButton()
|
||||||
|
.setSize(100, 20)
|
||||||
|
.setI18nLabel("replaymod.gui.edit.cut.start")
|
||||||
|
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.edit.cut.tooltip"))
|
||||||
|
.onClick(() -> {
|
||||||
|
Marker marker = new Marker();
|
||||||
|
marker.setTime(timeline.getCursorPosition());
|
||||||
|
marker.setName(MarkerProcessor.MARKER_NAME_START_CUT);
|
||||||
|
timeline.addMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
GuiButton buttonEndCut = new GuiButton()
|
||||||
|
.setSize(100, 20)
|
||||||
|
.setI18nLabel("replaymod.gui.edit.cut.end")
|
||||||
|
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.edit.cut.tooltip"))
|
||||||
|
.onClick(() -> {
|
||||||
|
Marker marker = new Marker();
|
||||||
|
marker.setTime(timeline.getCursorPosition());
|
||||||
|
marker.setName(MarkerProcessor.MARKER_NAME_END_CUT);
|
||||||
|
timeline.addMarker(marker);
|
||||||
|
});
|
||||||
|
|
||||||
|
GuiPanel controlPanel = new GuiPanel()
|
||||||
|
.setLayout(new HorizontalLayout().setSpacing(4))
|
||||||
|
.addElements(null, buttonAddSplit, buttonInsertCut, buttonEndCut);
|
||||||
|
|
||||||
|
GuiButton applyButton = new GuiButton().setI18nLabel("replaymod.gui.edit.apply").setSize(150, 20).onClick(this::apply);
|
||||||
|
GuiButton closeButton = new GuiButton().setI18nLabel("replaymod.gui.close").setSize(150, 20).onClick(this::close);
|
||||||
|
GuiPanel buttonPanel = new GuiPanel()
|
||||||
|
.setLayout(new HorizontalLayout().setSpacing(8))
|
||||||
|
.addElements(null, applyButton, closeButton);
|
||||||
|
|
||||||
|
popup.setLayout(new VerticalLayout(VerticalLayout.Alignment.TOP).setSpacing(10));
|
||||||
|
popup.addElements(new VerticalLayout.Data(0.5), timelinePanel, controlPanel, buttonPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void zoomTimeline(double factor) {
|
||||||
|
scrollbar.setZoom(scrollbar.getZoom() * factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void apply() {
|
||||||
|
ProgressPopup progressPopup = new ProgressPopup(this);
|
||||||
|
|
||||||
|
new Thread(() -> {
|
||||||
|
try (ZipReplayFile replayFile = new ZipReplayFile(new ReplayStudio(), inputPath.toFile())) {
|
||||||
|
replayFile.writeMarkers(markers);
|
||||||
|
replayFile.save();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Utils.error(ReplayModEditor.LOGGER, this, CrashReport.makeCrashReport(e, "Writing markers"), this::close);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
MarkerProcessor.apply(inputPath, progressPopup.progressBar::setProgress);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Utils.error(ReplayModEditor.LOGGER, this, CrashReport.makeCrashReport(e, "Running marker processor"), this::close);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplayMod.instance.runLater(() -> {
|
||||||
|
progressPopup.close();
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void open() {
|
||||||
|
super.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GuiEditReplay getThis() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProgressPopup extends AbstractGuiPopup<ProgressPopup> {
|
||||||
|
private final GuiProgressBar progressBar = new GuiProgressBar(popup).setSize(300, 20);
|
||||||
|
|
||||||
|
ProgressPopup(GuiContainer container) {
|
||||||
|
super(container);
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ProgressPopup getThis() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EditTimeline extends GuiMarkerTimeline {
|
||||||
|
EditTimeline(Set<Marker> markers, Consumer<Set<Marker>> saveMarkers) {
|
||||||
|
super(markers, saveMarkers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawMarkers(GuiRenderer renderer, ReadableDimension size) {
|
||||||
|
drawCutQuads(renderer, size);
|
||||||
|
super.drawMarkers(renderer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawMarker(GuiRenderer renderer, ReadableDimension size, Marker marker, int markerX) {
|
||||||
|
if (MarkerProcessor.MARKER_NAME_SPLIT.equals(marker.getName())) {
|
||||||
|
int height = size.getHeight() - BORDER_BOTTOM - BORDER_TOP - MARKER_SIZE + 1;
|
||||||
|
for (int y = 0; y < height; y += 3) {
|
||||||
|
renderer.drawRect(markerX, BORDER_TOP + y, 1, 2, Color.WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.drawMarker(renderer, size, marker, markerX);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawCutQuads(GuiRenderer renderer, ReadableDimension size) {
|
||||||
|
boolean inCut = false;
|
||||||
|
int startTime = 0;
|
||||||
|
for (Marker marker : markers.stream().sorted(Comparator.comparing(Marker::getTime)).collect(Collectors.toList())) {
|
||||||
|
if (MarkerProcessor.MARKER_NAME_START_CUT.equals(marker.getName()) && !inCut) {
|
||||||
|
inCut = true;
|
||||||
|
startTime = marker.getTime();
|
||||||
|
} else if (MarkerProcessor.MARKER_NAME_END_CUT.equals(marker.getName()) && inCut) {
|
||||||
|
drawCutQuad(renderer, size, startTime, marker.getTime());
|
||||||
|
inCut = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inCut) {
|
||||||
|
drawCutQuad(renderer, size, startTime, getLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawCutQuad(GuiRenderer renderer, ReadableDimension size, int startFrameTime, int endFrameTime) {
|
||||||
|
int visibleWidth = size.getWidth() - BORDER_LEFT - BORDER_RIGHT;
|
||||||
|
int startTime = getOffset();
|
||||||
|
int visibleTime = (int) (getZoom() * getLength());
|
||||||
|
int endTime = getOffset() + visibleTime;
|
||||||
|
|
||||||
|
if (startFrameTime >= endTime || endFrameTime <= startTime) {
|
||||||
|
return; // Segment out of display range
|
||||||
|
}
|
||||||
|
|
||||||
|
double relativeStart = startFrameTime - startTime;
|
||||||
|
double relativeEnd = endFrameTime - startTime;
|
||||||
|
int startX = BORDER_LEFT + Math.max(0, (int) (relativeStart / visibleTime * visibleWidth) + MARKER_SIZE / 2 + 1);
|
||||||
|
int endX = BORDER_LEFT + Math.min(visibleWidth, (int) (relativeEnd / visibleTime * visibleWidth) - MARKER_SIZE / 2);
|
||||||
|
if (startX < endX) {
|
||||||
|
renderer.drawRect(startX + 1, size.getHeight() - BORDER_BOTTOM - MARKER_SIZE,
|
||||||
|
endX - startX - 2, MARKER_SIZE - 2, Color.RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MarkerProcessor {
|
public class MarkerProcessor {
|
||||||
@@ -49,7 +50,7 @@ public class MarkerProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void apply(Path path) throws IOException {
|
public static void apply(Path path, Consumer<Float> progress) throws IOException {
|
||||||
if (!hasWork(path)) {
|
if (!hasWork(path)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -71,6 +72,7 @@ public class MarkerProcessor {
|
|||||||
Iterator<Marker> markerIterator = markers.iterator();
|
Iterator<Marker> markerIterator = markers.iterator();
|
||||||
boolean anySplit = markers.stream().anyMatch(m -> m.getName().equals(MARKER_NAME_SPLIT));
|
boolean anySplit = markers.stream().anyMatch(m -> m.getName().equals(MARKER_NAME_SPLIT));
|
||||||
|
|
||||||
|
int inputDuration = inputReplayFile.getMetaData().getDuration();
|
||||||
ReplayInputStream replayInputStream = inputReplayFile.getPacketData(studio, true);
|
ReplayInputStream replayInputStream = inputReplayFile.getPacketData(studio, true);
|
||||||
int timeOffset = 0;
|
int timeOffset = 0;
|
||||||
SquashFilter cutFilter = null;
|
SquashFilter cutFilter = null;
|
||||||
@@ -142,6 +144,7 @@ public class MarkerProcessor {
|
|||||||
duration = nextPacket.getTime() - timeOffset;
|
duration = nextPacket.getTime() - timeOffset;
|
||||||
}
|
}
|
||||||
nextPacket = replayInputStream.readPacket();
|
nextPacket = replayInputStream.readPacket();
|
||||||
|
progress.accept((float) nextPacket.getTime() / (float) inputDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
package com.replaymod.editor.handler;
|
package com.replaymod.editor.handler;
|
||||||
|
|
||||||
|
import com.replaymod.core.utils.Utils;
|
||||||
import com.replaymod.editor.ReplayModEditor;
|
import com.replaymod.editor.ReplayModEditor;
|
||||||
import com.replaymod.editor.gui.GuiReplayEditor;
|
import com.replaymod.editor.gui.GuiEditReplay;
|
||||||
|
import com.replaymod.replay.gui.screen.GuiReplayViewer;
|
||||||
|
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
||||||
|
import de.johni0702.minecraft.gui.container.GuiPanel;
|
||||||
import de.johni0702.minecraft.gui.container.GuiScreen;
|
import de.johni0702.minecraft.gui.container.GuiScreen;
|
||||||
import net.minecraft.client.gui.GuiButton;
|
import de.johni0702.minecraft.gui.element.GuiElement;
|
||||||
import net.minecraft.client.gui.GuiMainMenu;
|
import net.minecraft.crash.CrashReport;
|
||||||
import net.minecraft.client.resources.I18n;
|
|
||||||
import net.minecraftforge.client.event.GuiScreenEvent;
|
import net.minecraftforge.client.event.GuiScreenEvent;
|
||||||
|
|
||||||
//#if MC>=10800
|
//#if MC>=10800
|
||||||
//#if MC>=11300
|
//#if MC>=11300
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import java.util.ArrayList;
|
|
||||||
//#else
|
//#else
|
||||||
//$$ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
//$$ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
//#endif
|
//#endif
|
||||||
@@ -19,48 +21,42 @@ import java.util.ArrayList;
|
|||||||
//$$ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
//$$ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
import static com.replaymod.core.versions.MCVer.*;
|
||||||
|
|
||||||
public class GuiHandler {
|
public class GuiHandler {
|
||||||
private static final int BUTTON_REPLAY_EDITOR = 17890237;
|
|
||||||
|
|
||||||
private final ReplayModEditor mod;
|
|
||||||
|
|
||||||
public GuiHandler(ReplayModEditor mod) {
|
|
||||||
this.mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register() {
|
public void register() {
|
||||||
FML_BUS.register(this);
|
FML_BUS.register(this);
|
||||||
FORGE_BUS.register(this);
|
FORGE_BUS.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) {
|
public void injectIntoReplayViewer(GuiScreenEvent.InitGuiEvent.Post event) {
|
||||||
if (!(getGui(event) instanceof GuiMainMenu)) {
|
AbstractGuiScreen guiScreen = GuiScreen.from(getGui(event));
|
||||||
|
if (!(guiScreen instanceof GuiReplayViewer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final GuiReplayViewer replayViewer = (GuiReplayViewer) guiScreen;
|
||||||
GuiButton button = new GuiButton(BUTTON_REPLAY_EDITOR, getGui(event).width / 2 + 2,
|
// Inject Edit button
|
||||||
getGui(event).height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayeditor")) {
|
for (GuiElement element : replayViewer.replayButtonPanel.getChildren()) {
|
||||||
//#if MC>=11300
|
if (element instanceof GuiPanel && (((GuiPanel) element).getChildren().isEmpty())) {
|
||||||
|
new de.johni0702.minecraft.gui.element.GuiButton((GuiPanel) element).onClick(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(double mouseX, double mouseY) {
|
public void run() {
|
||||||
onButton(new GuiScreenEvent.ActionPerformedEvent.Pre(getGui(event), this, new ArrayList<>()));
|
try {
|
||||||
|
new GuiEditReplay(replayViewer, replayViewer.list.getSelected().file.toPath()) {
|
||||||
|
@Override
|
||||||
|
protected void close() {
|
||||||
|
super.close();
|
||||||
|
replayViewer.list.load();
|
||||||
}
|
}
|
||||||
//#endif
|
}.open();
|
||||||
};
|
} catch (IOException e) {
|
||||||
button.width = button.width / 2 - 2;
|
Utils.error(ReplayModEditor.LOGGER, replayViewer, CrashReport.makeCrashReport(e, "Opening replay editor"), () -> {});
|
||||||
addButton(event, button);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@SubscribeEvent
|
}).setSize(73, 20).setI18nLabel("replaymod.gui.replayeditor").setDisabled();
|
||||||
public void onButton(GuiScreenEvent.ActionPerformedEvent.Pre event) {
|
|
||||||
if(!getButton(event).enabled) return;
|
|
||||||
|
|
||||||
if (getGui(event) instanceof GuiMainMenu) {
|
|
||||||
if (getButton(event).id == BUTTON_REPLAY_EDITOR) {
|
|
||||||
new GuiReplayEditor(GuiScreen.wrap(getGui(event)), mod.getCore()).display();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,12 @@ public class GuiHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiButton button = new GuiButton(BUTTON_REPLAY_CENTER, getGui(event).width / 2 - 100,
|
GuiButton button = new GuiButton(
|
||||||
getGui(event).height / 4 + 10 + 4 * 24, I18n.format("replaymod.gui.replaycenter")) {
|
BUTTON_REPLAY_CENTER,
|
||||||
|
getGui(event).width / 2 + 2,
|
||||||
|
getGui(event).height / 4 + 10 + 4 * 24,
|
||||||
|
I18n.format("replaymod.gui.replaycenter")
|
||||||
|
) {
|
||||||
//#if MC>=11300
|
//#if MC>=11300
|
||||||
@Override
|
@Override
|
||||||
public void onClick(double mouseX, double mouseY) {
|
public void onClick(double mouseX, double mouseY) {
|
||||||
@@ -58,6 +62,7 @@ public class GuiHandler {
|
|||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
};
|
};
|
||||||
|
button.width = button.width / 2 - 2;
|
||||||
addButton(event, button);
|
addButton(event, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
|
|||||||
replayFile.close();
|
replayFile.close();
|
||||||
|
|
||||||
if (core.getSettingsRegistry().get(Setting.AUTO_POST_PROCESS)) {
|
if (core.getSettingsRegistry().get(Setting.AUTO_POST_PROCESS)) {
|
||||||
MarkerProcessor.apply(outputPath);
|
MarkerProcessor.apply(outputPath, progress -> {});
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("Saving replay file:", e);
|
logger.error("Saving replay file:", e);
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class ReplayHandler {
|
|||||||
*/
|
*/
|
||||||
private boolean suppressCameraMovements;
|
private boolean suppressCameraMovements;
|
||||||
|
|
||||||
private final List<Marker> markers;
|
private Set<Marker> markers;
|
||||||
|
|
||||||
private final GuiReplayOverlay overlay;
|
private final GuiReplayOverlay overlay;
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ public class ReplayHandler {
|
|||||||
|
|
||||||
FML_BUS.post(new ReplayOpenEvent.Pre(this));
|
FML_BUS.post(new ReplayOpenEvent.Pre(this));
|
||||||
|
|
||||||
markers = new ArrayList<>(replayFile.getMarkers().or(Collections.emptySet()));
|
markers = replayFile.getMarkers().or(Collections.emptySet());
|
||||||
|
|
||||||
fullReplaySender = new FullReplaySender(this, replayFile, false);
|
fullReplaySender = new FullReplaySender(this, replayFile, false);
|
||||||
//#if MC>=10904
|
//#if MC>=10904
|
||||||
@@ -432,26 +432,6 @@ public class ReplayHandler {
|
|||||||
this.suppressCameraMovements = suppressCameraMovements;
|
this.suppressCameraMovements = suppressCameraMovements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all markers.
|
|
||||||
* When changed, {@link #saveMarkers()} should be called to save the changes.
|
|
||||||
* @return Collection of markers in no particular order
|
|
||||||
*/
|
|
||||||
public Collection<Marker> getMarkers() {
|
|
||||||
return markers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves all markers.
|
|
||||||
*/
|
|
||||||
public void saveMarkers() {
|
|
||||||
try {
|
|
||||||
replayFile.writeMarkers(new HashSet<>(markers));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spectate the specified entity.
|
* Spectate the specified entity.
|
||||||
* When the entity is {@code null} or the camera entity, the camera becomes the view entity.
|
* When the entity is {@code null} or the camera entity, the camera becomes the view entity.
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import com.replaymod.replay.camera.CameraControllerRegistry;
|
|||||||
import com.replaymod.replay.camera.CameraEntity;
|
import com.replaymod.replay.camera.CameraEntity;
|
||||||
import com.replaymod.replay.camera.ClassicCameraController;
|
import com.replaymod.replay.camera.ClassicCameraController;
|
||||||
import com.replaymod.replay.camera.VanillaCameraController;
|
import com.replaymod.replay.camera.VanillaCameraController;
|
||||||
import com.replaymod.replay.gui.overlay.GuiMarkerTimeline;
|
|
||||||
import com.replaymod.replay.gui.screen.GuiModCompatWarning;
|
import com.replaymod.replay.gui.screen.GuiModCompatWarning;
|
||||||
import com.replaymod.replay.handler.GuiHandler;
|
import com.replaymod.replay.handler.GuiHandler;
|
||||||
import com.replaymod.replaystudio.data.Marker;
|
import com.replaymod.replaystudio.data.Marker;
|
||||||
@@ -75,24 +74,12 @@ public class ReplayModReplay implements Module {
|
|||||||
marker.setYaw(camera.rotationYaw);
|
marker.setYaw(camera.rotationYaw);
|
||||||
marker.setPitch(camera.rotationPitch);
|
marker.setPitch(camera.rotationPitch);
|
||||||
marker.setRoll(camera.roll);
|
marker.setRoll(camera.roll);
|
||||||
replayHandler.getMarkers().add(marker);
|
replayHandler.getOverlay().timeline.addMarker(marker);
|
||||||
replayHandler.saveMarkers();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registry.registerRaw(Keyboard.KEY_DELETE, () -> {
|
|
||||||
if (replayHandler != null) {
|
|
||||||
GuiMarkerTimeline timeline = replayHandler.getOverlay().timeline;
|
|
||||||
if (timeline.getSelectedMarker() != null) {
|
|
||||||
replayHandler.getMarkers().remove(timeline.getSelectedMarker());
|
|
||||||
replayHandler.saveMarkers();
|
|
||||||
timeline.setSelectedMarker(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
registry.registerKeyBinding("replaymod.input.thumbnail", Keyboard.KEY_N, new Runnable() {
|
registry.registerKeyBinding("replaymod.input.thumbnail", Keyboard.KEY_N, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import de.johni0702.minecraft.gui.utils.lwjgl.ReadablePoint;
|
|||||||
|
|
||||||
//#if MC>=11300
|
//#if MC>=11300
|
||||||
import com.replaymod.core.versions.MCVer.Keyboard;
|
import com.replaymod.core.versions.MCVer.Keyboard;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
//#else
|
//#else
|
||||||
//$$ import org.lwjgl.input.Keyboard;
|
//$$ import org.lwjgl.input.Keyboard;
|
||||||
//#endif
|
//#endif
|
||||||
@@ -25,8 +27,7 @@ public class GuiEditMarkerPopup extends AbstractGuiPopup<GuiEditMarkerPopup> imp
|
|||||||
return new GuiNumberField().setSize(150, 20).setValidateOnFocusChange(true);
|
return new GuiNumberField().setSize(150, 20).setValidateOnFocusChange(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ReplayHandler replayHandler;
|
private final Consumer<Marker> onSave;
|
||||||
private final Marker marker;
|
|
||||||
|
|
||||||
public final GuiLabel title = new GuiLabel().setI18nText("replaymod.gui.editkeyframe.title.marker");
|
public final GuiLabel title = new GuiLabel().setI18nText("replaymod.gui.editkeyframe.title.marker");
|
||||||
|
|
||||||
@@ -65,6 +66,7 @@ public class GuiEditMarkerPopup extends AbstractGuiPopup<GuiEditMarkerPopup> imp
|
|||||||
public final GuiButton saveButton = new GuiButton().onClick(new Runnable() {
|
public final GuiButton saveButton = new GuiButton().onClick(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Marker marker = new Marker();
|
||||||
marker.setName(Strings.emptyToNull(nameField.getText()));
|
marker.setName(Strings.emptyToNull(nameField.getText()));
|
||||||
marker.setTime(timeField.getInteger());
|
marker.setTime(timeField.getInteger());
|
||||||
marker.setX(xField.getDouble());
|
marker.setX(xField.getDouble());
|
||||||
@@ -73,7 +75,7 @@ public class GuiEditMarkerPopup extends AbstractGuiPopup<GuiEditMarkerPopup> imp
|
|||||||
marker.setYaw(yawField.getFloat());
|
marker.setYaw(yawField.getFloat());
|
||||||
marker.setPitch(pitchField.getFloat());
|
marker.setPitch(pitchField.getFloat());
|
||||||
marker.setRoll(rollField.getFloat());
|
marker.setRoll(rollField.getFloat());
|
||||||
replayHandler.saveMarkers();
|
onSave.accept(marker);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}).setSize(150, 20).setI18nLabel("replaymod.gui.save");
|
}).setSize(150, 20).setI18nLabel("replaymod.gui.save");
|
||||||
@@ -89,10 +91,9 @@ public class GuiEditMarkerPopup extends AbstractGuiPopup<GuiEditMarkerPopup> imp
|
|||||||
.setLayout(new HorizontalLayout(HorizontalLayout.Alignment.CENTER).setSpacing(7))
|
.setLayout(new HorizontalLayout(HorizontalLayout.Alignment.CENTER).setSpacing(7))
|
||||||
.addElements(new HorizontalLayout.Data(0.5), saveButton, cancelButton);
|
.addElements(new HorizontalLayout.Data(0.5), saveButton, cancelButton);
|
||||||
|
|
||||||
public GuiEditMarkerPopup(ReplayHandler replayHandler, GuiContainer container, Marker marker) {
|
public GuiEditMarkerPopup(GuiContainer container, Marker marker, Consumer<Marker> onSave) {
|
||||||
super(container);
|
super(container);
|
||||||
this.replayHandler = replayHandler;
|
this.onSave = onSave;
|
||||||
this.marker = marker;
|
|
||||||
|
|
||||||
setBackgroundColor(Colors.DARK_TRANSPARENT);
|
setBackgroundColor(Colors.DARK_TRANSPARENT);
|
||||||
|
|
||||||
|
|||||||
@@ -2,27 +2,46 @@ package com.replaymod.replay.gui.overlay;
|
|||||||
|
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
import com.replaymod.replay.ReplayHandler;
|
import com.replaymod.replay.ReplayHandler;
|
||||||
|
import com.replaymod.replay.ReplayModReplay;
|
||||||
import com.replaymod.replaystudio.data.Marker;
|
import com.replaymod.replaystudio.data.Marker;
|
||||||
import com.replaymod.replaystudio.util.Location;
|
import com.replaymod.replaystudio.util.Location;
|
||||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||||
import de.johni0702.minecraft.gui.RenderInfo;
|
import de.johni0702.minecraft.gui.RenderInfo;
|
||||||
import de.johni0702.minecraft.gui.element.advanced.AbstractGuiTimeline;
|
import de.johni0702.minecraft.gui.element.advanced.AbstractGuiTimeline;
|
||||||
import de.johni0702.minecraft.gui.function.Draggable;
|
import de.johni0702.minecraft.gui.function.Draggable;
|
||||||
|
import de.johni0702.minecraft.gui.function.Typeable;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.Point;
|
import de.johni0702.minecraft.gui.utils.lwjgl.Point;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadablePoint;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadablePoint;
|
||||||
import net.minecraft.client.resources.I18n;
|
import net.minecraft.client.resources.I18n;
|
||||||
|
|
||||||
|
//#if MC>=11300
|
||||||
|
import com.replaymod.core.versions.MCVer.Keyboard;
|
||||||
|
//#else
|
||||||
|
//$$ import org.lwjgl.input.Keyboard;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static de.johni0702.minecraft.gui.utils.Utils.clamp;
|
import static de.johni0702.minecraft.gui.utils.Utils.clamp;
|
||||||
|
|
||||||
public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> implements Draggable {
|
public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> implements Draggable, Typeable {
|
||||||
protected static final int TEXTURE_MARKER_X = 109;
|
protected static final int TEXTURE_MARKER_X = 109;
|
||||||
protected static final int TEXTURE_MARKER_Y = 20;
|
protected static final int TEXTURE_MARKER_Y = 20;
|
||||||
protected static final int TEXTURE_MARKER_SELECTED_X = 114;
|
protected static final int TEXTURE_MARKER_SELECTED_X = 114;
|
||||||
protected static final int TEXTURE_MARKER_SELECTED_Y = 20;
|
protected static final int TEXTURE_MARKER_SELECTED_Y = 20;
|
||||||
protected static final int MARKER_SIZE = 5;
|
protected static final int MARKER_SIZE = 5;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private final ReplayHandler replayHandler;
|
private final ReplayHandler replayHandler;
|
||||||
|
private final Consumer<Set<Marker>> saveMarkers;
|
||||||
|
protected Set<Marker> markers;
|
||||||
|
|
||||||
private ReadableDimension lastSize;
|
private ReadableDimension lastSize;
|
||||||
|
|
||||||
@@ -32,8 +51,27 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
|
|||||||
private boolean dragging;
|
private boolean dragging;
|
||||||
private long lastClickTime;
|
private long lastClickTime;
|
||||||
|
|
||||||
public GuiMarkerTimeline(ReplayHandler replayHandler) {
|
public GuiMarkerTimeline(@Nonnull ReplayHandler replayHandler) {
|
||||||
this.replayHandler = replayHandler;
|
this.replayHandler = replayHandler;
|
||||||
|
try {
|
||||||
|
this.markers = replayHandler.getReplayFile().getMarkers().or(HashSet::new);
|
||||||
|
} catch (IOException e) {
|
||||||
|
ReplayModReplay.LOGGER.error("Failed to get markers from replay", e);
|
||||||
|
this.markers = new HashSet<>();
|
||||||
|
}
|
||||||
|
this.saveMarkers = (markers) -> {
|
||||||
|
try {
|
||||||
|
replayHandler.getReplayFile().writeMarkers(markers);
|
||||||
|
} catch (IOException e) {
|
||||||
|
ReplayModReplay.LOGGER.error("Failed to save markers to replay", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public GuiMarkerTimeline(Set<Marker> markers, Consumer<Set<Marker>> saveMarkers) {
|
||||||
|
this.replayHandler = null;
|
||||||
|
this.markers = markers;
|
||||||
|
this.saveMarkers = saveMarkers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,7 +90,7 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
|
|||||||
protected void drawMarkers(GuiRenderer renderer, ReadableDimension size) {
|
protected void drawMarkers(GuiRenderer renderer, ReadableDimension size) {
|
||||||
renderer.bindTexture(ReplayMod.TEXTURE);
|
renderer.bindTexture(ReplayMod.TEXTURE);
|
||||||
|
|
||||||
for (Marker marker : replayHandler.getMarkers()) {
|
for (Marker marker : markers) {
|
||||||
drawMarker(renderer, size, marker);
|
drawMarker(renderer, size, marker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +101,10 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
|
|||||||
double positionInVisible = markerPos - getOffset();
|
double positionInVisible = markerPos - getOffset();
|
||||||
double fractionOfVisible = positionInVisible / visibleLength;
|
double fractionOfVisible = positionInVisible / visibleLength;
|
||||||
int markerX = (int) (BORDER_LEFT + fractionOfVisible * (size.getWidth() - BORDER_LEFT - BORDER_RIGHT));
|
int markerX = (int) (BORDER_LEFT + fractionOfVisible * (size.getWidth() - BORDER_LEFT - BORDER_RIGHT));
|
||||||
|
drawMarker(renderer, size, marker, markerX);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void drawMarker(GuiRenderer renderer, ReadableDimension size, Marker marker, int markerX) {
|
||||||
int textureX, textureY;
|
int textureX, textureY;
|
||||||
if (marker.equals(selectedMarker)) {
|
if (marker.equals(selectedMarker)) {
|
||||||
textureX = TEXTURE_MARKER_SELECTED_X;
|
textureX = TEXTURE_MARKER_SELECTED_X;
|
||||||
@@ -99,7 +140,7 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
|
|||||||
|
|
||||||
int visibleLength = (int) (getLength() * getZoom());
|
int visibleLength = (int) (getLength() * getZoom());
|
||||||
int contentWidth = lastSize.getWidth() - BORDER_LEFT - BORDER_RIGHT;
|
int contentWidth = lastSize.getWidth() - BORDER_LEFT - BORDER_RIGHT;
|
||||||
for (Marker marker : replayHandler.getMarkers()) {
|
for (Marker marker : markers) {
|
||||||
int markerPos = clamp(marker.getTime(), getOffset(), getOffset() + visibleLength);
|
int markerPos = clamp(marker.getTime(), getOffset(), getOffset() + visibleLength);
|
||||||
double positionInVisible = markerPos - getOffset();
|
double positionInVisible = markerPos - getOffset();
|
||||||
double fractionOfVisible = positionInVisible / visibleLength;
|
double fractionOfVisible = positionInVisible / visibleLength;
|
||||||
@@ -122,16 +163,24 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
|
|||||||
draggingStartX = position.getX();
|
draggingStartX = position.getX();
|
||||||
draggingTimeDelta = marker.getTime() - getTimeAt(position.getX(), position.getY());
|
draggingTimeDelta = marker.getTime() - getTimeAt(position.getX(), position.getY());
|
||||||
} else { // Double click
|
} else { // Double click
|
||||||
new GuiEditMarkerPopup(replayHandler, getContainer(), marker).open();
|
new GuiEditMarkerPopup(getContainer(), marker, (updatedMarker) -> {
|
||||||
|
markers.remove(marker);
|
||||||
|
markers.add(updatedMarker);
|
||||||
|
saveMarkers.accept(markers);
|
||||||
|
}).open();
|
||||||
}
|
}
|
||||||
lastClickTime = now;
|
lastClickTime = now;
|
||||||
} else if (button == 1) { // Right click
|
} else if (button == 1) { // Right click
|
||||||
selectedMarker = null;
|
selectedMarker = null;
|
||||||
|
if (replayHandler != null) {
|
||||||
replayHandler.setTargetPosition(new Location(
|
replayHandler.setTargetPosition(new Location(
|
||||||
marker.getX(), marker.getY(), marker.getZ(),
|
marker.getX(), marker.getY(), marker.getZ(),
|
||||||
marker.getPitch(), marker.getYaw()
|
marker.getPitch(), marker.getYaw()
|
||||||
));
|
));
|
||||||
replayHandler.doJump(marker.getTime(), false);
|
replayHandler.doJump(marker.getTime(), false);
|
||||||
|
} else {
|
||||||
|
setCursorPosition(marker.getTime());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -164,7 +213,7 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
|
|||||||
mouseDrag(position, button, 0);
|
mouseDrag(position, button, 0);
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
dragging = false;
|
dragging = false;
|
||||||
replayHandler.saveMarkers();
|
saveMarkers.accept(markers);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,4 +236,19 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
|
|||||||
public Marker getSelectedMarker() {
|
public Marker getSelectedMarker() {
|
||||||
return selectedMarker;
|
return selectedMarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean typeKey(ReadablePoint mousePosition, int keyCode, char keyChar, boolean ctrlDown, boolean shiftDown) {
|
||||||
|
if (keyCode == Keyboard.KEY_DELETE && selectedMarker != null) {
|
||||||
|
markers.remove(selectedMarker);
|
||||||
|
saveMarkers.accept(markers);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMarker(Marker marker) {
|
||||||
|
markers.add(marker);
|
||||||
|
saveMarkers.accept(markers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ public class GuiHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GuiButton button = new GuiButton(BUTTON_REPLAY_VIEWER, getGui(event).width / 2 - 100,
|
GuiButton button = new GuiButton(BUTTON_REPLAY_VIEWER, getGui(event).width / 2 - 100,
|
||||||
getGui(event).height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayviewer")) {
|
getGui(event).height / 4 + 10 + 4 * 24, I18n.format("replaymod.gui.replayviewer")) {
|
||||||
//#if MC>=11300
|
//#if MC>=11300
|
||||||
@Override
|
@Override
|
||||||
public void onClick(double mouseX, double mouseY) {
|
public void onClick(double mouseX, double mouseY) {
|
||||||
|
|||||||
Reference in New Issue
Block a user