diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/Later.java b/src/hdskins/java/com/voxelmodpack/hdskins/Later.java index 8503de38..2e979663 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/Later.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/Later.java @@ -7,6 +7,8 @@ public final class Later extends Thread { protected Later(int delay, Runnable runnable) { super(runnable); this.delay = delay; + setDaemon(true); + setName("Later#" + getId()); } public static void performLater(int delay, Runnable callable) { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java new file mode 100644 index 00000000..25059878 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java @@ -0,0 +1,184 @@ +package com.voxelmodpack.hdskins.gui; + +import java.awt.Canvas; +import java.awt.Frame; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowStateListener; +import java.io.Closeable; +import java.io.IOException; +import java.util.TooManyListenersException; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; + +import org.lwjgl.LWJGLException; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.DisplayMode; + +import com.google.common.collect.Lists; +import com.voxelmodpack.hdskins.Later; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.ResourceLocation; + +public class GLWindow implements Closeable { + + static GLWindow instance = null; + + public static GLWindow current() { + if (instance == null) { + instance = new GLWindow(); + } + return instance; + } + + private final DropTarget dt; + + private final JFrame frame; + + private DropTargetListener saved = null; + + private final int frameX = 15; + private final int frameY = 36; + + private final Minecraft mc = Minecraft.getMinecraft(); + + private int state = 0; + + private GLWindow() { + int x = Display.getX(); + int y = Display.getY(); + + int w = Display.getWidth() + frameX; + + int h = Display.getHeight() + frameY; + + Canvas canvas = new Canvas(); + + frame = new JFrame(Display.getTitle()); + frame.setResizable(Display.isResizable()); + frame.setLocation(x, y); + frame.setSize(w, h); + frame.getContentPane().setLayout(null); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent windowEvent) { + Minecraft.getMinecraft().shutdown(); + } + }); + frame.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent componentEvent) { + canvas.setBounds(0, 0, frame.getWidth() - frameX, frame.getHeight() - frameY); + } + }); + frame.addWindowStateListener(new WindowStateListener() { + @Override + public void windowStateChanged(WindowEvent event) { + state = event.getNewState(); + Later.performLater(1, () -> { + canvas.setBounds(0, 0, frame.getWidth() - frameX, frame.getHeight() - frameY); + }); + } + }); + setIcons(frame); + + frame.getContentPane().add(canvas); + frame.setVisible(true); + + try { + Display.setParent(canvas); + } catch (LWJGLException e) { + e.printStackTrace(); + } + + if (Display.getWidth() == Display.getDesktopDisplayMode().getWidth()) { + frame.setExtendedState(Frame.MAXIMIZED_BOTH); + } + + state = frame.getExtendedState(); + + if (mc.isFullScreen()) { + try { + Display.setFullscreen(true); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + + dt = new DropTarget(); + canvas.setDropTarget(dt); + } + + private final void setIcons(JFrame frame) { + try { + frame.setIconImages(Lists.newArrayList( + ImageIO.read(mc.getResourceManager().getResource(new ResourceLocation("icons/icon_16x16.png")).getInputStream()), + ImageIO.read(mc.getResourceManager().getResource(new ResourceLocation("icons/icon_32x32.png")).getInputStream()) + )); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void setDropTargetListener(DropTargetListener dtl) { + if (saved != null) { + dt.removeDropTargetListener(saved); + } + if (dtl != null) { + try { + dt.addDropTargetListener(dtl); + } catch (TooManyListenersException e) { } + saved = dtl; + } + } + + public static void dispose() { + if (instance != null) { + try { + instance.close(); + } catch (IOException ignored) { + } + } + } + + @Override + public void close() throws IOException { + mc.addScheduledTask(() -> { + try { + Display.setParent(null); + } catch (LWJGLException e) { + e.printStackTrace(); + } + + try { + if (mc.isFullScreen()) { + Display.setFullscreen(true); + } else { + if ((state & JFrame.MAXIMIZED_BOTH) == JFrame.MAXIMIZED_BOTH) { + Display.setLocation(0, 0); + Display.setDisplayMode(Display.getDesktopDisplayMode()); + } else { + Display.setDisplayMode(new DisplayMode(mc.displayWidth, mc.displayHeight)); + Display.setLocation(frame.getX(), frame.getY()); + } + Display.setResizable(false); + Display.setResizable(true); + } + } catch (LWJGLException e) { + e.printStackTrace(); + } + + frame.setVisible(false); + frame.dispose(); + + instance = null; + }); + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java index 22b08264..9ab9853a 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java @@ -35,18 +35,15 @@ import net.minecraft.util.text.TextFormatting; import org.apache.commons.io.FilenameUtils; import org.apache.logging.log4j.LogManager; import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.GLU; -import java.awt.Color; -import java.awt.Window.Type; -import java.awt.dnd.DropTarget; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.DoubleBuffer; import java.nio.file.Path; + import javax.annotation.Nullable; import javax.imageio.ImageIO; import javax.swing.*; @@ -91,8 +88,6 @@ public class GuiSkins extends GuiScreen implements FutureCallback { - files.stream().findFirst().ifPresent(instance::loadLocalFile); - }); - fileDrop.setVisible(true); - fileDrop.requestFocusInWindow(); - } catch (Exception e) { - e.printStackTrace(); - } + GLWindow.current().setDropTargetListener((FileDropListener) files -> { + files.stream().findFirst().ifPresent(instance::loadLocalFile); + }); } private void initPanoramaRenderer() { @@ -247,14 +207,6 @@ public class GuiSkins extends GuiScreen implements FutureCallback { - if (!(Minecraft.getMinecraft().currentScreen instanceof GuiSkins)) { - if (fileDrop != null) { - fileDrop.setVisible(false); - } - } - }); } private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) { @@ -307,7 +259,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback