diff --git a/jGui b/jGui index 7713f298..6aeba190 160000 --- a/jGui +++ b/jGui @@ -1 +1 @@ -Subproject commit 7713f2985a7c4f536ce1e677faae2e317edaf981 +Subproject commit 6aeba190a60af65ea69f2d912d5802913c855aee diff --git a/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java b/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java index dd18f384..70aca0d2 100644 --- a/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java +++ b/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java @@ -20,6 +20,6 @@ public class AdvancedScreenshots implements Extra { } private void takeScreenshot() { - ReplayMod.instance.runLater(() -> new GuiCreateScreenshot(mod).display()); + ReplayMod.instance.runLater(() -> new GuiCreateScreenshot(mod).open()); } } diff --git a/src/main/java/com/replaymod/extras/advancedscreenshots/GuiCreateScreenshot.java b/src/main/java/com/replaymod/extras/advancedscreenshots/GuiCreateScreenshot.java index 2f908952..be3f43f3 100644 --- a/src/main/java/com/replaymod/extras/advancedscreenshots/GuiCreateScreenshot.java +++ b/src/main/java/com/replaymod/extras/advancedscreenshots/GuiCreateScreenshot.java @@ -27,7 +27,7 @@ public class GuiCreateScreenshot extends GuiRenderSettings implements Loadable { private final ReplayMod mod; public GuiCreateScreenshot(ReplayMod mod) { - super(null, null); + super(GuiRenderSettings.createBaseScreen(), null, null); this.mod = mod; @@ -64,7 +64,7 @@ public class GuiCreateScreenshot extends GuiRenderSettings implements Loadable { } catch (Throwable t) { error(LOGGER, GuiCreateScreenshot.this, CrashReport.create(t, "Rendering video"), () -> {}); - display(); // Re-show the render settings gui and the new error popup + getScreen().display(); // Re-show the render settings gui and the new error popup } }); }); @@ -75,6 +75,18 @@ public class GuiCreateScreenshot extends GuiRenderSettings implements Loadable { return container; } + @Override + public void open() { + super.open(); + getScreen().display(); + } + + @Override + public void close() { + super.close(); + getMinecraft().openScreen(null); + } + @Override public void load() { // pause replay when opening this gui diff --git a/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java b/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java index 79b33ca7..b66c1e16 100644 --- a/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java +++ b/src/main/java/com/replaymod/render/gui/GuiRenderQueue.java @@ -6,6 +6,7 @@ import com.google.common.util.concurrent.Futures; import com.replaymod.core.ReplayMod; import com.replaymod.core.utils.Utils; import com.replaymod.core.versions.MCVer; +import com.replaymod.render.RenderSettings; import com.replaymod.render.ReplayModRender; import com.replaymod.render.VideoWriter; import com.replaymod.render.rendering.VideoRenderer; @@ -41,6 +42,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Supplier; import static com.replaymod.render.ReplayModRender.LOGGER; @@ -77,9 +79,11 @@ public class GuiRenderQueue extends AbstractGuiPopup implements renameButton, removeButton), closeButton); - private final AbstractGuiScreen container; + private final AbstractGuiScreen container; private final ReplayHandler replayHandler; private final Set selectedEntries = new HashSet<>(); + private final Supplier timelineSupplier; + private boolean opened; { popup.setLayout(new CustomLayout() { @@ -100,64 +104,23 @@ public class GuiRenderQueue extends AbstractGuiPopup implements }).addElements(null, title, list, buttonPanel); } - public GuiRenderQueue(AbstractGuiScreen container, GuiRenderSettings guiRenderSettings, ReplayHandler replayHandler, Timeline timeline) { + private final List jobs = ReplayModRender.instance.getRenderQueue(); + + public GuiRenderQueue(AbstractGuiScreen container, ReplayHandler replayHandler, Supplier timelineSupplier) { super(container); this.container = container; this.replayHandler = replayHandler; + this.timelineSupplier = timelineSupplier; LOGGER.trace("Opening render queue popup"); setBackgroundColor(Colors.DARK_TRANSPARENT); - List queue = ReplayModRender.instance.getRenderQueue(); - - for (RenderJob renderJob : queue) { + for (RenderJob renderJob : jobs) { LOGGER.trace("Adding {} to job queue list", renderJob); list.getListPanel().addElements(null, new Entry(renderJob)); } - addButton.onClick(() -> { - LOGGER.trace("Add button clicked"); - // Open popup - GuiYesNoPopup popup = GuiYesNoPopup.open(container) - .setYesI18nLabel("replaymod.gui.add").setNoI18nLabel("replaymod.gui.cancel"); - popup.getInfo().setLayout(new HorizontalLayout(HorizontalLayout.Alignment.CENTER).setSpacing(5)); - // Add content - GuiLabel label = new GuiLabel().setI18nText("replaymod.gui.renderqueue.jobname").setColor(Colors.BLACK); - GuiTextField nameField = new GuiTextField().setSize(150, 20).setFocused(true); - nameField.setText(guiRenderSettings.getOutputFile().getName()); - popup.getInfo().addElements(new HorizontalLayout.Data(0.5), label, nameField); - // Disable "Yes" button while name is empty - nameField.onTextChanged(old -> popup.getYesButton().setEnabled(!nameField.getText().isEmpty())).onEnter(() -> { - if (popup.getYesButton().isEnabled()) { - popup.getYesButton().onClick(); - } - }); - // Register callback - Futures.addCallback(popup.getFuture(), new FutureCallback() { - @Override - public void onSuccess(@Nullable Boolean result) { - if (result == Boolean.TRUE) { - RenderJob newJob = new RenderJob(); - newJob.setName(nameField.getText()); - newJob.setSettings(guiRenderSettings.save(false)); - newJob.setTimeline(timeline); - LOGGER.trace("Adding new job: {}", newJob); - queue.add(newJob); - list.getListPanel().addElements(null, new Entry(newJob)); - } else { - LOGGER.trace("Adding cancelled"); - } - } - - @Override - public void onFailure(Throwable t) { - LOGGER.error("Add Job popup:", t); - } - }); - }); - if (guiRenderSettings != null) { - addButton.setEnabled(guiRenderSettings.renderButton.isEnabled()); - } + addButton.onClick(this::addButtonClicked); renameButton.onClick(() -> { Entry selectedEntry = selectedEntries.iterator().next(); @@ -200,7 +163,7 @@ public class GuiRenderQueue extends AbstractGuiPopup implements for (Entry entry : selectedEntries) { LOGGER.trace("Remove button clicked for {}", entry.job); list.getListPanel().removeElement(entry); - queue.remove(entry.job); + jobs.remove(entry.job); } selectedEntries.clear(); updateButtons(); @@ -260,9 +223,72 @@ public class GuiRenderQueue extends AbstractGuiPopup implements } } + private GuiRenderSettings addButtonClicked() { + Timeline timeline = timelineSupplier.get(); + if (timeline != null) { + GuiRenderSettings popup = addJob(timeline); + popup.open(); + return popup; + } else { + return null; + } + } + + public GuiRenderSettings addJob(Timeline timeline) { + return new GuiRenderSettings(container, replayHandler, timeline) { + { + if (!jobs.isEmpty()) { + buttonPanel.removeElement(renderButton); + } + queueButton.onClick(() -> { + RenderSettings settings = save(false); + + RenderJob newJob = new RenderJob(); + newJob.setName(settings.getOutputFile().getName()); + newJob.setSettings(settings); + newJob.setTimeline(timeline); + LOGGER.trace("Adding new job: {}", newJob); + jobs.add(newJob); + list.getListPanel().addElements(null, new Entry(newJob)); + updateButtons(); + + // Need to close the inner popup before we can open the outer one + close(); + if (!opened) { + GuiRenderQueue.this.open(); + } + }); + } + + @Override + public void close() { + super.close(); + if (!opened && jobs.isEmpty()) { + GuiRenderQueue.this.close(); + } + } + }; + } + @Override public void open() { + if (jobs.isEmpty()) { + if (addButtonClicked() == null) { + close(); + } + return; + } + super.open(); + opened = true; + } + + @Override + protected void close() { + if (opened) { + super.close(); + } + opened = false; } @Override diff --git a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java index 8c1ee452..44911560 100644 --- a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java +++ b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java @@ -14,6 +14,7 @@ import com.replaymod.render.VideoWriter; import com.replaymod.render.rendering.VideoRenderer; import com.replaymod.replay.ReplayHandler; import com.replaymod.replaystudio.pathing.path.Timeline; +import de.johni0702.minecraft.gui.container.AbstractGuiScreen; import de.johni0702.minecraft.gui.container.GuiContainer; import de.johni0702.minecraft.gui.container.GuiPanel; import de.johni0702.minecraft.gui.container.GuiScreen; @@ -21,11 +22,11 @@ import de.johni0702.minecraft.gui.container.GuiVerticalList; import de.johni0702.minecraft.gui.element.*; import de.johni0702.minecraft.gui.element.advanced.GuiColorPicker; import de.johni0702.minecraft.gui.element.advanced.GuiDropdownMenu; -import de.johni0702.minecraft.gui.function.Closeable; import de.johni0702.minecraft.gui.layout.CustomLayout; import de.johni0702.minecraft.gui.layout.GridLayout; 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.popup.GuiFileChooserPopup; import de.johni0702.minecraft.gui.utils.Colors; import de.johni0702.minecraft.gui.utils.Consumer; @@ -57,8 +58,9 @@ import static com.replaymod.render.ReplayModRender.LOGGER; import net.minecraft.text.TranslatableText; //#endif -public class GuiRenderSettings extends GuiScreen implements Closeable { - public final GuiPanel contentPanel = new GuiPanel(this).setBackgroundColor(Colors.DARK_TRANSPARENT); +public class GuiRenderSettings extends AbstractGuiPopup { + { disablePopupBackground(); } + public final GuiPanel contentPanel = new GuiPanel(popup).setBackgroundColor(new Color(0, 0, 0, 230)); public final GuiVerticalList settingsList = new GuiVerticalList(contentPanel).setDrawSlider(true); public final GuiDropdownMenu renderMethodDropdown = @@ -227,12 +229,9 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { public final GuiPanel buttonPanel = new GuiPanel(contentPanel).setLayout(new HorizontalLayout().setSpacing(4)); - public final GuiButton queueButton = new GuiButton(buttonPanel).onClick(new Runnable() { - @Override - public void run() { - new GuiRenderQueue(GuiRenderSettings.this, GuiRenderSettings.this, replayHandler, timeline).open(); - } - }).setSize(100, 20).setI18nLabel("replaymod.gui.renderqueue.open"); + public final GuiButton queueButton = new GuiButton(buttonPanel) + .setSize(100, 20) + .setI18nLabel("replaymod.gui.rendersettings.addtoqueue"); public final GuiButton renderButton = new GuiButton(buttonPanel).onClick(() -> ReplayMod.instance.runLaterWithoutLock(new Runnable() { @Override public void run() { @@ -245,7 +244,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { LOGGER.error("Rendering video:", e); NoticeScreen errorScreen = new NoticeScreen( //#if MC>=11400 - GuiRenderSettings.this::display, + getScreen()::display, new TranslatableText("replaymod.gui.rendering.error.title"), new TranslatableText("replaymod.gui.rendering.error.message") //#else @@ -263,26 +262,17 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { }); } catch (Throwable t) { error(LOGGER, GuiRenderSettings.this, CrashReport.create(t, "Rendering video"), () -> {}); - display(); // Re-show the render settings gui and the new error popup + getScreen().display(); // Re-show the render settings gui and the new error popup } } })).setSize(100, 20).setI18nLabel("replaymod.gui.render"); - public final GuiButton cancelButton = new GuiButton(buttonPanel).onClick(new Runnable() { - @Override - public void run() { - getMinecraft().openScreen(null); - } - }).setSize(100, 20).setI18nLabel("replaymod.gui.cancel"); + public final GuiButton cancelButton = new GuiButton(buttonPanel) + .onClick(this::close) + .setSize(100, 20) + .setI18nLabel("replaymod.gui.cancel"); { - setBackground(Background.NONE); Utils.link(videoWidth, videoHeight, bitRateField); - setLayout(new CustomLayout() { - @Override - protected void layout(GuiScreen container, int width, int height) { - pos(contentPanel, width / 2 - width(contentPanel) / 2, height / 2 - height(contentPanel) / 2); - } - }); contentPanel.setLayout(new CustomLayout() { @Override @@ -294,7 +284,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { @Override public ReadableDimension calcMinSize(GuiContainer container) { - ReadableDimension screenSize = getMinSize(); + ReadableDimension screenSize = getContainer().getMinSize(); return new Dimension(screenSize.getWidth() - 40, screenSize.getHeight() - 40); } }); @@ -319,12 +309,15 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { }); } + private final AbstractGuiScreen screen; private final ReplayHandler replayHandler; private final Timeline timeline; private File outputFile; private boolean userDefinedOutputFileName; - public GuiRenderSettings(ReplayHandler replayHandler, Timeline timeline) { + public GuiRenderSettings(AbstractGuiScreen container, ReplayHandler replayHandler, Timeline timeline) { + super(container); + this.screen = container; this.replayHandler = replayHandler; this.timeline = timeline; @@ -361,10 +354,12 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { String error = updateResolution(); if (error == null) { renderButton.setEnabled().setTooltip(null); + queueButton.setEnabled().setTooltip(null); videoWidth.setTextColor(Colors.WHITE); videoHeight.setTextColor(Colors.WHITE); } else { renderButton.setDisabled().setTooltip(new GuiTooltip().setI18nText(error)); + queueButton.setDisabled().setTooltip(new GuiTooltip().setI18nText(error)); videoWidth.setTextColor(Colors.RED); videoHeight.setTextColor(Colors.RED); } @@ -574,8 +569,8 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { return new File(folder, fileName + "." + encodingPreset.getFileExtension()); } - public File getOutputFile() { - return outputFile; + public AbstractGuiScreen getScreen() { + return screen; } protected File conformExtension(File file, RenderSettings.EncodingPreset preset) { @@ -595,6 +590,11 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { true, false, false, false, null, 360, 180, false, RenderSettings.AntiAliasing.NONE, "", RenderSettings.EncodingPreset.MP4_DEFAULT.getValue(), false); } + @Override + public void open() { + super.open(); + } + @Override public void close() { RenderSettings settings = save(true); @@ -604,9 +604,21 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { } catch (IOException e) { LOGGER.error("Saving render settings:", e); } + super.close(); } public ReplayHandler getReplayHandler() { return replayHandler; } + + @Override + protected GuiRenderSettings getThis() { + return this; + } + + public static GuiScreen createBaseScreen() { + GuiScreen screen = new GuiScreen(); + screen.setBackground(AbstractGuiScreen.Background.NONE); + return screen; + } } diff --git a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java index ed50d309..52191ff5 100644 --- a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java +++ b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java @@ -12,6 +12,7 @@ import com.replaymod.pathing.player.RealtimeTimelinePlayer; import com.replaymod.pathing.properties.CameraProperties; import com.replaymod.pathing.properties.SpectatorProperty; import com.replaymod.pathing.properties.TimestampProperty; +import com.replaymod.render.gui.GuiRenderQueue; import com.replaymod.render.gui.GuiRenderSettings; import com.replaymod.replay.ReplayHandler; import com.replaymod.replay.camera.CameraEntity; @@ -27,8 +28,10 @@ import com.replaymod.simplepathing.SPTimeline.SPPath; import com.replaymod.simplepathing.Setting; import de.johni0702.minecraft.gui.GuiRenderer; import de.johni0702.minecraft.gui.RenderInfo; +import de.johni0702.minecraft.gui.container.AbstractGuiScreen; import de.johni0702.minecraft.gui.container.GuiContainer; import de.johni0702.minecraft.gui.container.GuiPanel; +import de.johni0702.minecraft.gui.container.GuiScreen; import de.johni0702.minecraft.gui.element.GuiElement; import de.johni0702.minecraft.gui.element.GuiHorizontalScrollbar; import de.johni0702.minecraft.gui.element.GuiLabel; @@ -100,7 +103,15 @@ public class GuiPathing { public void run() { Timeline timeline = preparePathsForPlayback(false); if (timeline == null) return; - new GuiRenderSettings(replayHandler, timeline).display(); + GuiScreen screen = GuiRenderSettings.createBaseScreen(); + new GuiRenderQueue(screen, replayHandler, () -> preparePathsForPlayback(false)) { + @Override + protected void close() { + super.close(); + getMinecraft().openScreen(null); + } + }.open(); + screen.display(); } }).setSize(20, 20).setTexture(ReplayMod.TEXTURE, ReplayMod.TEXTURE_SIZE).setTexturePosH(40, 0) .setTooltip(new GuiTooltip().setI18nText("replaymod.gui.ingame.menu.renderpath")); diff --git a/src/main/resources/assets/replaymod/lang b/src/main/resources/assets/replaymod/lang index 4dff53a1..a30b45e9 160000 --- a/src/main/resources/assets/replaymod/lang +++ b/src/main/resources/assets/replaymod/lang @@ -1 +1 @@ -Subproject commit 4dff53a1ff914f4baa04949d0ffeb8725abc3eef +Subproject commit a30b45e9b83e06d77d4a39015d27eb18f94c468e