Add a Save, refactored Copy.
This commit is contained in:
parent
f4cc2f6382
commit
6c570d7eaf
@ -3,11 +3,17 @@ package net.sf.openrocket.gui.figure3d.photo;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
|
import java.awt.datatransfer.DataFlavor;
|
||||||
|
import java.awt.datatransfer.Transferable;
|
||||||
|
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
@ -17,6 +23,7 @@ import javax.swing.JMenu;
|
|||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
|
||||||
import net.sf.openrocket.database.Databases;
|
import net.sf.openrocket.database.Databases;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
@ -26,6 +33,7 @@ import net.sf.openrocket.gui.main.SwingExceptionHandler;
|
|||||||
import net.sf.openrocket.gui.util.FileHelper;
|
import net.sf.openrocket.gui.util.FileHelper;
|
||||||
import net.sf.openrocket.gui.util.GUIUtil;
|
import net.sf.openrocket.gui.util.GUIUtil;
|
||||||
import net.sf.openrocket.gui.util.Icons;
|
import net.sf.openrocket.gui.util.Icons;
|
||||||
|
import net.sf.openrocket.gui.util.SimpleFileFilter;
|
||||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.logging.LoggingSystemSetup;
|
import net.sf.openrocket.logging.LoggingSystemSetup;
|
||||||
@ -114,6 +122,7 @@ public class PhotoFrame extends JFrame {
|
|||||||
if (option == JFileChooser.APPROVE_OPTION) {
|
if (option == JFileChooser.APPROVE_OPTION) {
|
||||||
File file = chooser.getSelectedFile();
|
File file = chooser.getSelectedFile();
|
||||||
log.debug("Opening File " + file.getAbsolutePath());
|
log.debug("Opening File " + file.getAbsolutePath());
|
||||||
|
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
|
||||||
GeneralRocketLoader grl = new GeneralRocketLoader(file);
|
GeneralRocketLoader grl = new GeneralRocketLoader(file);
|
||||||
try {
|
try {
|
||||||
OpenRocketDocument doc = grl.load();
|
OpenRocketDocument doc = grl.load();
|
||||||
@ -125,6 +134,60 @@ public class PhotoFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
menu.add(item);
|
menu.add(item);
|
||||||
|
|
||||||
|
|
||||||
|
item = new JMenuItem("Save Image...", KeyEvent.VK_S); //TODO Trans
|
||||||
|
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_KEY));
|
||||||
|
// // Open a rocket design
|
||||||
|
item.getAccessibleContext().setAccessibleDescription("Save Image"); //TODO Trans
|
||||||
|
item.setIcon(Icons.FILE_OPEN);
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
log.info(Markers.USER_MARKER, "Save... selected");
|
||||||
|
photoPanel.addImageCallback(new PhotoPanel.ImageCallback() {
|
||||||
|
@Override
|
||||||
|
public void performAction(final BufferedImage image) {
|
||||||
|
log.info("Got image {} to save...", image);
|
||||||
|
|
||||||
|
final FileFilter png = new SimpleFileFilter("PNG Image", ".png"); //TODO Trans
|
||||||
|
|
||||||
|
final JFileChooser chooser = new JFileChooser();
|
||||||
|
|
||||||
|
chooser.addChoosableFileFilter(png);
|
||||||
|
chooser.setFileFilter(png);
|
||||||
|
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||||
|
|
||||||
|
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||||
|
final int option = chooser.showSaveDialog(PhotoFrame.this);
|
||||||
|
|
||||||
|
if (option != JFileChooser.APPROVE_OPTION) {
|
||||||
|
log.info(Markers.USER_MARKER, "User decided not to save, option=" + option);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final File file = FileHelper.forceExtension(chooser.getSelectedFile(), "png");
|
||||||
|
if (file == null) {
|
||||||
|
log.info(Markers.USER_MARKER, "User did not select a file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
|
||||||
|
log.info(Markers.USER_MARKER, "User chose to save image as {}", file);
|
||||||
|
|
||||||
|
if ( FileHelper.confirmWrite(file, PhotoFrame.this) ){
|
||||||
|
try {
|
||||||
|
ImageIO.write(image, "png", file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(item);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Edit
|
// // Edit
|
||||||
@ -137,7 +200,40 @@ public class PhotoFrame extends JFrame {
|
|||||||
Action action = new AbstractAction("Copy") {
|
Action action = new AbstractAction("Copy") {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
photoPanel.doCopy();
|
photoPanel.addImageCallback(new PhotoPanel.ImageCallback() {
|
||||||
|
@Override
|
||||||
|
public void performAction(final BufferedImage image) {
|
||||||
|
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new Transferable() {
|
||||||
|
@Override
|
||||||
|
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||||
|
if (flavor.equals(DataFlavor.imageFlavor) && image != null) {
|
||||||
|
return image;
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedFlavorException(flavor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataFlavor[] getTransferDataFlavors() {
|
||||||
|
DataFlavor[] flavors = new DataFlavor[1];
|
||||||
|
flavors[0] = DataFlavor.imageFlavor;
|
||||||
|
return flavors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||||
|
DataFlavor[] flavors = getTransferDataFlavors();
|
||||||
|
for (int i = 0; i < flavors.length; i++) {
|
||||||
|
if (flavor.equals(flavors[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
item = new JMenuItem(action);
|
item = new JMenuItem(action);
|
||||||
|
@ -3,17 +3,14 @@ package net.sf.openrocket.gui.figure3d.photo;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.SplashScreen;
|
import java.awt.SplashScreen;
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.datatransfer.DataFlavor;
|
|
||||||
import java.awt.datatransfer.Transferable;
|
|
||||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import javax.media.opengl.DebugGL2;
|
import javax.media.opengl.DebugGL2;
|
||||||
import javax.media.opengl.GL;
|
import javax.media.opengl.GL;
|
||||||
@ -71,9 +68,18 @@ public class PhotoPanel extends JPanel implements GLEventListener {
|
|||||||
private Component canvas;
|
private Component canvas;
|
||||||
private TextureCache textureCache = new TextureCache();
|
private TextureCache textureCache = new TextureCache();
|
||||||
private double ratio;
|
private double ratio;
|
||||||
private boolean doCopy = false;
|
|
||||||
private boolean needUpdate = false;
|
private boolean needUpdate = false;
|
||||||
|
|
||||||
|
private List<ImageCallback> imageCallbacks = new java.util.Vector<PhotoPanel.ImageCallback>();
|
||||||
|
|
||||||
|
interface ImageCallback {
|
||||||
|
public void performAction(BufferedImage i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addImageCallback(ImageCallback a) {
|
||||||
|
imageCallbacks.add(a);
|
||||||
|
}
|
||||||
|
|
||||||
private RocketRenderer rr;
|
private RocketRenderer rr;
|
||||||
private PhotoSettings p;
|
private PhotoSettings p;
|
||||||
|
|
||||||
@ -109,11 +115,6 @@ public class PhotoPanel extends JPanel implements GLEventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void doCopy() {
|
|
||||||
doCopy = true;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
PhotoSettings getSettings() {
|
PhotoSettings getSettings() {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -204,7 +205,7 @@ public class PhotoPanel extends JPanel implements GLEventListener {
|
|||||||
final double x2 = (width - 2 * e.getX()) / width;
|
final double x2 = (width - 2 * e.getX()) / width;
|
||||||
final double y2 = (2 * e.getY() - height) / height;
|
final double y2 = (2 * e.getY() - height) / height;
|
||||||
|
|
||||||
p.setViewAltAz(p.getViewAlt() - (y1-y2), p.getViewAz() + (x1-x2));
|
p.setViewAltAz(p.getViewAlt() - (y1 - y2), p.getViewAz() + (x1 - x2));
|
||||||
|
|
||||||
lastX = e.getX();
|
lastX = e.getX();
|
||||||
lastY = e.getY();
|
lastY = e.getY();
|
||||||
@ -249,11 +250,19 @@ public class PhotoPanel extends JPanel implements GLEventListener {
|
|||||||
gl.glAccum(GL2.GL_RETURN, 1.0f);
|
gl.glAccum(GL2.GL_RETURN, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doCopy) {
|
if (!imageCallbacks.isEmpty()) {
|
||||||
copy(drawable);
|
BufferedImage i = (new AWTGLReadBufferUtil(GLProfile.get(GLProfile.GL2), false)).readPixelsToBufferedImage(
|
||||||
doCopy = false;
|
drawable.getGL(), 0, 0, drawable.getWidth(), drawable.getHeight(), true);
|
||||||
|
final Vector<ImageCallback> cbs = new Vector<PhotoPanel.ImageCallback>(imageCallbacks);
|
||||||
|
imageCallbacks.clear();
|
||||||
|
for (ImageCallback ia : cbs) {
|
||||||
|
try {
|
||||||
|
ia.performAction(i);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.error("Image Callback {} threw", i, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void convertColor(Color color, float[] out) {
|
private static void convertColor(Color color, float[] out) {
|
||||||
@ -472,40 +481,4 @@ public class PhotoPanel extends JPanel implements GLEventListener {
|
|||||||
gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0);
|
gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copy(final GLAutoDrawable drawable) {
|
|
||||||
|
|
||||||
final BufferedImage image = (new AWTGLReadBufferUtil(GLProfile.get(GLProfile.GL2), false))
|
|
||||||
.readPixelsToBufferedImage(drawable.getGL(), 0, 0, drawable.getWidth(), drawable.getHeight(), true);
|
|
||||||
|
|
||||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new Transferable() {
|
|
||||||
@Override
|
|
||||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
|
||||||
if (flavor.equals(DataFlavor.imageFlavor) && image != null) {
|
|
||||||
return image;
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedFlavorException(flavor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataFlavor[] getTransferDataFlavors() {
|
|
||||||
DataFlavor[] flavors = new DataFlavor[1];
|
|
||||||
flavors[0] = DataFlavor.imageFlavor;
|
|
||||||
return flavors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
|
||||||
DataFlavor[] flavors = getTransferDataFlavors();
|
|
||||||
for (int i = 0; i < flavors.length; i++) {
|
|
||||||
if (flavor.equals(flavors[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user