mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 16:24:23 +01:00
Handle file drop events directly into the client
This commit is contained in:
parent
f39d55826c
commit
6cc976f1f8
5 changed files with 222 additions and 54 deletions
|
@ -7,6 +7,8 @@ public final class Later extends Thread {
|
||||||
protected Later(int delay, Runnable runnable) {
|
protected Later(int delay, Runnable runnable) {
|
||||||
super(runnable);
|
super(runnable);
|
||||||
this.delay = delay;
|
this.delay = delay;
|
||||||
|
setDaemon(true);
|
||||||
|
setName("Later#" + getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void performLater(int delay, Runnable callable) {
|
public static void performLater(int delay, Runnable callable) {
|
||||||
|
|
184
src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java
Normal file
184
src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java
Normal file
|
@ -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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,18 +35,15 @@ import net.minecraft.util.text.TextFormatting;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.Display;
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.util.glu.GLU;
|
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.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.DoubleBuffer;
|
import java.nio.DoubleBuffer;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -91,8 +88,6 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
private float uploadOpacity = 0.0F;
|
private float uploadOpacity = 0.0F;
|
||||||
private float lastPartialTick;
|
private float lastPartialTick;
|
||||||
|
|
||||||
private static JFrame fileDrop;
|
|
||||||
|
|
||||||
private static GuiSkins instance;
|
private static GuiSkins instance;
|
||||||
|
|
||||||
private MinecraftProfileTexture.Type textureType = SKIN;
|
private MinecraftProfileTexture.Type textureType = SKIN;
|
||||||
|
@ -177,7 +172,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initGui() {
|
public void initGui() {
|
||||||
Later.performLater(1, this::enableDnd);
|
enableDnd();
|
||||||
|
|
||||||
this.initPanoramaRenderer();
|
this.initPanoramaRenderer();
|
||||||
this.buttonList.clear();
|
this.buttonList.clear();
|
||||||
|
@ -197,44 +192,9 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableDnd() {
|
private void enableDnd() {
|
||||||
if (fileDrop != null) {
|
GLWindow.current().setDropTargetListener((FileDropListener) files -> {
|
||||||
fileDrop.setVisible(true);
|
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
||||||
fileDrop.requestFocusInWindow();
|
});
|
||||||
fileDrop.setLocation(Display.getX(), Display.getY());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileDrop = new JFrame("Skin Drop");
|
|
||||||
fileDrop.setType(Type.UTILITY);
|
|
||||||
fileDrop.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
|
||||||
fileDrop.setResizable(false);
|
|
||||||
fileDrop.setTitle("Skin Drop");
|
|
||||||
fileDrop.setSize(256, 256);
|
|
||||||
fileDrop.setAlwaysOnTop(true);
|
|
||||||
fileDrop.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
|
|
||||||
fileDrop.setLocation(Display.getX(), Display.getY());
|
|
||||||
fileDrop.getContentPane().setLayout(null);
|
|
||||||
|
|
||||||
JPanel panel = new JPanel();
|
|
||||||
panel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY));
|
|
||||||
panel.setBounds(10, 11, 230, 205);
|
|
||||||
fileDrop.getContentPane().add(panel);
|
|
||||||
JLabel txtInst = new JLabel("Drop skin file here");
|
|
||||||
txtInst.setHorizontalAlignment(SwingConstants.CENTER);
|
|
||||||
txtInst.setVerticalAlignment(SwingConstants.CENTER);
|
|
||||||
panel.add(txtInst);
|
|
||||||
|
|
||||||
DropTarget dt = new DropTarget();
|
|
||||||
fileDrop.setDropTarget(dt);
|
|
||||||
try {
|
|
||||||
dt.addDropTargetListener((FileDropListener) files -> {
|
|
||||||
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
|
||||||
});
|
|
||||||
fileDrop.setVisible(true);
|
|
||||||
fileDrop.requestFocusInWindow();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPanoramaRenderer() {
|
private void initPanoramaRenderer() {
|
||||||
|
@ -247,14 +207,6 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
localPlayer.releaseTextures();
|
localPlayer.releaseTextures();
|
||||||
remotePlayer.releaseTextures();
|
remotePlayer.releaseTextures();
|
||||||
HDSkinManager.clearSkinCache();
|
HDSkinManager.clearSkinCache();
|
||||||
|
|
||||||
Later.performLater(1, () -> {
|
|
||||||
if (!(Minecraft.getMinecraft().currentScreen instanceof GuiSkins)) {
|
|
||||||
if (fileDrop != null) {
|
|
||||||
fileDrop.setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) {
|
private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) {
|
||||||
|
@ -307,7 +259,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
this.selectedSkin = null;
|
this.selectedSkin = null;
|
||||||
this.localPlayer.releaseTextures();
|
this.localPlayer.releaseTextures();
|
||||||
this.openFileThread = new ThreadOpenFilePNG(this.mc, I18n.format("hdskins.open.title"), this::onFileOpenDialogClosed);
|
this.openFileThread = new ThreadOpenFilePNG(this.mc, I18n.format("hdskins.open.title"), this::onFileOpenDialogClosed);
|
||||||
this.openFileThread.setParent(fileDrop).start();
|
this.openFileThread.start();
|
||||||
guiButton.enabled = false;
|
guiButton.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.voxelmodpack.hdskins.mixin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.lwjgl.LWJGLException;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import com.voxelmodpack.hdskins.gui.GLWindow;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.crash.CrashReport;
|
||||||
|
|
||||||
|
@Mixin(Minecraft.class)
|
||||||
|
public class MixinMinecraft {
|
||||||
|
|
||||||
|
//public void displayCrashReport(CrashReport crashReportIn)
|
||||||
|
@Inject(method = "displayCrashReport(Lnet/minecraft/crash/CrashReport;)V", at = @At("HEAD"))
|
||||||
|
private void onGameCrash(CrashReport report, CallbackInfo info) {
|
||||||
|
GLWindow.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "init()V", at = @At("RETURN"))
|
||||||
|
private void onInit(CallbackInfo info) throws LWJGLException, IOException {
|
||||||
|
GLWindow.current();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
"package": "com.voxelmodpack.hdskins.mixin",
|
"package": "com.voxelmodpack.hdskins.mixin",
|
||||||
"refmap": "hdskins.mixin.refmap.json",
|
"refmap": "hdskins.mixin.refmap.json",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
|
"MixinMinecraft",
|
||||||
"MixinGuiMainMenu",
|
"MixinGuiMainMenu",
|
||||||
"MixinImageBufferDownload",
|
"MixinImageBufferDownload",
|
||||||
"MixinPlayerInfo",
|
"MixinPlayerInfo",
|
||||||
|
|
Loading…
Reference in a new issue