package tk.amberide.ide.gui.editor.map; import tk.amberide.ide.os.OS; import tk.amberide.engine.data.map.LevelMap; import tk.amberide.engine.data.map.codec.Codec; import tk.amberide.ide.gui.misc.ErrorHandler; import tk.amberide.engine.input.AbstractKeyboard; import static tk.amberide.engine.input.AbstractKeyboard.getEventKey; import static tk.amberide.engine.input.AbstractKeyboard.getEventKeyState; import static tk.amberide.engine.input.AbstractKeyboard.isKeyDown; import tk.amberide.engine.input.AbstractMouse; import java.awt.*; import java.io.DataOutputStream; import java.io.FileOutputStream; import org.lwjgl.LWJGLException; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.AWTGLCanvas; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.PixelFormat; import javax.swing.*; /** * * @author Tudor */ public abstract class AbstractGLMapComponent extends AWTGLCanvas implements IMapComponent { protected final MapContext context = new MapContext(); protected Thread renderingThread; protected boolean running; protected boolean modified = false; static { System.setProperty("org.lwjgl.opengl.Display.allowSoftwareOpenGL", "true"); } public AbstractGLMapComponent() throws LWJGLException { super(new PixelFormat(8, 16, 0)); } public AbstractGLMapComponent(LevelMap map) throws LWJGLException { this(); context.map = map; (renderingThread = new Thread() { @Override public void run() { running = true; while (running) { if (isShowing()) { repaint(); Display.sync(120); } else { OS.sleep(300); // Prevent useless CPU cycles when not showing repaint(); } } } }).start(); } @Override protected void paintGL() { pollInput(); } protected void pollInput() { try { if (!AbstractKeyboard.isCreated()) { AbstractKeyboard.create(AbstractKeyboard.AWT); } if (!AbstractMouse.isCreated()) { AbstractMouse.create(AbstractMouse.AWT); } } catch (LWJGLException ex) { ex.printStackTrace(); return; } if(!isFocusOwner()) { return; } doScroll(AbstractMouse.getDWheel()); while (AbstractKeyboard.next()) { if (getEventKeyState()) { int key; switch (key = getEventKey()) { case Keyboard.KEY_Z: if (isKeyDown(Keyboard.KEY_RCONTROL) || isKeyDown(Keyboard.KEY_LCONTROL) && !context.undoStack.empty()) { context.redoStack.push(context.map.clone()); context.map = context.undoStack.pop(); } break; case Keyboard.KEY_Y: if (isKeyDown(Keyboard.KEY_RCONTROL) || isKeyDown(Keyboard.KEY_LCONTROL) && !context.redoStack.empty()) { context.undoStack.push(context.map.clone()); context.map = context.redoStack.pop(); } break; case Keyboard.KEY_S: if (isKeyDown(Keyboard.KEY_RCONTROL) || isKeyDown(Keyboard.KEY_LCONTROL)) { save(); } break; default: doKey(key); } } } } protected void doKey(int keycode) { } protected void doScroll(int delta) { } @Override protected void exceptionOccurred(LWJGLException gle) { ErrorHandler.alert(gle); } public MapContext getMapContext() { return context; } public Component getComponent() { return this; } public boolean modified() { return modified; } public JComponent getStatusBar() { return null; } private boolean saving; public void save() { if (!saving) { saving = true; new Thread() { @Override public void run() { try { FileOutputStream fos = new FileOutputStream(context.outputFile); Codec.getLatestCodec().compileMap(context.map, new DataOutputStream(fos)); fos.close(); saving = false; } catch (Exception ex) { ErrorHandler.alert(ex); saving = false; } } }.start(); modified = false; } } protected boolean isInBounds(int x, int y) { return !(x < 0 || x > context.map.getWidth() - 1 || y < 0 || y > context.map.getLength() - 1); } }