package org.geogebra.desktop.geogebra3D.euclidian3D;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import javax.swing.JPanel;
import javax.swing.border.Border;
import org.geogebra.common.awt.GBufferedImage;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.awt.GDimension;
import org.geogebra.common.awt.GFont;
import org.geogebra.common.awt.GGraphics2D;
import org.geogebra.common.awt.GPointWithZ;
import org.geogebra.common.euclidian.EuclidianStyleBar;
import org.geogebra.common.euclidian3D.Mouse3DEvent;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianController3D;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.ManagerShadersElementsGlobalBuffer;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.Renderer;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.Renderer.RendererType;
import org.geogebra.common.javax.swing.GBox;
import org.geogebra.common.main.App.ExportType;
import org.geogebra.common.main.settings.EuclidianSettings;
import org.geogebra.common.plugin.EuclidianStyleConstants;
import org.geogebra.common.util.debug.Log;
import org.geogebra.desktop.awt.GBufferedImageD;
import org.geogebra.desktop.awt.GColorD;
import org.geogebra.desktop.awt.GDimensionD;
import org.geogebra.desktop.awt.GFontD;
import org.geogebra.desktop.awt.GGraphics2DD;
import org.geogebra.desktop.euclidian.EuclidianControllerListeners;
import org.geogebra.desktop.euclidian.EuclidianViewJPanelD;
import org.geogebra.desktop.euclidian.MyZoomerD;
import org.geogebra.desktop.euclidianND.EuclidianViewInterfaceD;
import org.geogebra.desktop.export.GraphicExportDialog;
import org.geogebra.desktop.geogebra3D.App3D;
import org.geogebra.desktop.geogebra3D.euclidian3D.opengl.RendererCheckGLVersionD;
import org.geogebra.desktop.geogebra3D.euclidian3D.printer3D.ExportToPrinter3DD;
import org.geogebra.desktop.geogebra3D.euclidianInput3D.Mouse3DEventD;
import org.geogebra.desktop.io.MyImageIO;
import org.geogebra.desktop.javax.swing.GBoxD;
import org.geogebra.desktop.main.AppD;
/**
* 3D view for desktop
*
* @author mathieu
*
*/
public class EuclidianView3DD extends EuclidianView3D
implements EuclidianViewInterfaceD {
/** Java component for this view */
protected EuclidianViewJPanelD evjpanel;
/**
* constructor
*
* @param ec
* controller
* @param settings
* settings
*/
public EuclidianView3DD(EuclidianController3D ec,
EuclidianSettings settings) {
super(ec, settings);
initView(false);
EuclidianSettings es = null;
if (settings != null) {
es = settings;
} else {
es = getApplication().getSettings().getEuclidian(3);
}
if (es != null) {
settingsChanged(es);
es.addListener(this);
}
}
private Component canvas;
@Override
protected void createPanel() {
evjpanel = new EuclidianViewJPanelD(this);
canvas = (Component) renderer.getCanvas();
getJPanel().setLayout(new BorderLayout());
getJPanel().add(BorderLayout.CENTER, canvas);
// register Listener
((EuclidianControllerListeners) getEuclidianController())
.addListenersTo(canvas);
canvas.setFocusable(true);
}
@Override
protected Renderer createRenderer() {
// set stereo on/off
getCompanion().setIsStereoBuffered(((App3D) app).isStereo3D());
// lines below for testing
// return new RendererCheckGLVersionD(this, !app.isApplet(),
// RendererType.SHADER);
// return new RendererCheckGLVersionD(this, !app.isApplet(),
// RendererType.GL2);
// we don't want shaders with win os < vista
if (!app.isApplet() && !AppD.WINDOWS_VISTA_OR_EARLIER) {
return new RendererCheckGLVersionD(this, canUseCanvas());
}
if (app.useShaders()) {
return new RendererCheckGLVersionD(this, !app.isApplet(),
RendererType.SHADER);
}
return new RendererCheckGLVersionD(this, canUseCanvas(),
RendererType.GL2);
}
private ExportToPrinter3DD exportToPrinter;
@Override
protected void createExportToPrinter3D() {
if (hasPrinter()) {
exportToPrinter = new ExportToPrinter3DD();
}
}
public boolean hasPrinter() {
return false;
}
private boolean doExportToPrinter3D = true;
/**
* export drawables to 3D printer file
*/
public void exportToPrinter3D() {
if (hasPrinter()) {
if (doExportToPrinter3D) {
try {
StringBuilder sb = new StringBuilder();
sb.append("test");
exportToPrinter.getFormat().getExtension(sb);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(sb.toString()),
"UTF-8"));
sb.setLength(0);
exportToPrinter.getFormat().getScriptStart(sb);
writer.write(sb.toString());
exportToPrinter.startFile(writer, this,
(ManagerShadersElementsGlobalBuffer) renderer
.getGeometryManager());
// Log.debug("=== Creating 3D printer file === ");
renderer.drawable3DLists.exportToPrinter3D(exportToPrinter);
sb.setLength(0);
exportToPrinter.getFormat().getScriptEnd(sb);
writer.write(sb.toString());
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
doExportToPrinter3D = false;
}
}
}
private boolean canUseCanvas() {
if (app.isApplet()) {
return false;
}
// TODO remove that (quick fix for jogl 2.3.2)
if (AppD.MAC_OS) {
Log.debug("XXXXXXXXXXXXXXX mac osx");
return false;
}
return true;
}
@Override
public void setBackground(GColor updatedColor, GColor applyedColor) {
super.setBackground(updatedColor, applyedColor);
evjpanel.setBackground(GColorD.getAwtColor(bgApplyedColor));
}
@Override
public void setTransparentCursor() {
setCursor(((AppD) app).getTransparentCursor());
}
// ////////////////////////////
// EVJPANEL
// ////////////////////////////
/**
* @param cursor
* new cursor
*/
@Override
public void setCursor(Cursor cursor) {
evjpanel.setCursor(cursor);
}
@Override
public boolean hasFocus() {
return evjpanel.hasFocus();
}
@Override
public void repaint() {
this.updateBackgroundIfNecessary();
evjpanel.repaint();
}
@Override
public void add(GBox box) {
evjpanel.add(((GBoxD) box).getImpl());
}
@Override
public void remove(GBox box) {
evjpanel.remove(((GBoxD) box).getImpl());
}
/**
* @return underlying component
*/
@Override
public JPanel getJPanel() {
return evjpanel;
}
/**
* This view should be focused
*/
@Override
public void requestFocus() {
evjpanel.requestFocus();
}
@Override
public GFont getFont() {
return new GFontD(evjpanel.getFont());
}
/**
* @return mouse position
*/
@Override
public java.awt.Point getMousePosition() {
return evjpanel.getMousePosition();
}
/**
* @see JPanel#getFontMetrics(Font)
* @param font
* font
* @return font metrics
*/
public FontMetrics getFontMetrics(Font font) {
return evjpanel.getFontMetrics(font);
}
/**
* @return whethe this view is visible
*/
@Override
public boolean isShowing() {
return evjpanel.isShowing();
}
@Override
public boolean requestFocusInWindow() {
return evjpanel.requestFocusInWindow();
}
/**
* @see JPanel#setPreferredSize(Dimension)
* @param preferredSize
* prefered size
*/
public void setPreferredSize(Dimension preferredSize) {
evjpanel.setPreferredSize(preferredSize);
}
@Override
public void setPreferredSize(GDimension preferredSize) {
evjpanel.setPreferredSize(GDimensionD.getAWTDimension(preferredSize));
}
/**
* @see JPanel#revalidate()
*/
public void revalidate() {
evjpanel.revalidate();
}
/**
* @see JPanel#addMouseListener(MouseListener)
* @param ml
* mouse listener
*/
public void addMouseListener(MouseListener ml) {
canvas.addMouseListener(ml);
}
/**
* @see JPanel#removeComponentListener(ComponentListener)
* @param ml
* mouse listener
*/
public void removeMouseListener(MouseListener ml) {
canvas.removeMouseListener(ml);
}
/**
* @see JPanel#addMouseMotionListener(MouseMotionListener)
* @param mml
* mouse motion listener
*/
public void addMouseMotionListener(MouseMotionListener mml) {
canvas.addMouseMotionListener(mml);
}
/**
* @see JPanel#removeMouseMotionListener(MouseMotionListener)
* @param mml
* mouse motion listener
*/
public void removeMouseMotionListener(MouseMotionListener mml) {
canvas.removeMouseMotionListener(mml);
}
/**
* @see JPanel#addMouseWheelListener(MouseWheelListener)
* @param mwl
* mouse wheel listener
*/
public void addMouseWheelListener(MouseWheelListener mwl) {
canvas.addMouseWheelListener(mwl);
}
/**
* @see JPanel#removeMouseWheelListener(MouseWheelListener)
* @param mwl
* mouse wheel listener
*/
public void removeMouseWheelListener(MouseWheelListener mwl) {
canvas.removeMouseWheelListener(mwl);
}
/**
* @see JPanel#dispatchEvent(AWTEvent)
* @param componentEvent
* component event
*/
public void dispatchEvent(ComponentEvent componentEvent) {
evjpanel.dispatchEvent(componentEvent);
}
/**
* @see JPanel#setBorder(Border)
* @param border
* new border
*/
@Override
public void setBorder(Border border) {
evjpanel.setBorder(border);
}
/**
* @see JPanel#addComponentListener(ComponentListener)
* @param componentListener
* component listener
*/
public void addComponentListener(ComponentListener componentListener) {
canvas.addComponentListener(componentListener);
}
/**
* @param dimension
* new size
*/
public void setSize(Dimension dimension) {
evjpanel.setSize(dimension);
}
/**
* @return prefered size
*/
public Dimension getPreferredSize() {
return evjpanel.getPreferredSize();
}
/**
* @see EuclidianViewJPanelD#processMouseEventImpl(MouseEvent)
* @param e
* mouse event
*/
protected void processMouseEvent(MouseEvent e) {
evjpanel.processMouseEventImpl(e);
}
/**
* Initializes this panel
*
* @param repaint
* ignored parameter
*/
protected void initPanel(boolean repaint) {
// preferred size
evjpanel.setPreferredSize(null);
}
// @Override
@Override
public void setToolTipText(String plain) {
if ((tooltipsInThisView == EuclidianStyleConstants.TOOLTIPS_ON)
|| (tooltipsInThisView == EuclidianStyleConstants.TOOLTIPS_AUTOMATIC)) {
evjpanel.setToolTipText(plain);
}
}
@Override
public int getWidth() {
return evjpanel.getWidth();
}
@Override
public int getHeight() {
return evjpanel.getHeight();
}
@Override
protected void updateSizeKeepDrawables() {
// not needed for 3D
}
// temp image
private final Graphics2D g2Dtemp = new BufferedImage(5, 5,
BufferedImage.TYPE_INT_RGB).createGraphics();
/**
* @return temporary graphics that is stored in this view
*/
final public Graphics2D getTempGraphics2D() {
g2Dtemp.setFont(((AppD) app).getPlainFont());
return g2Dtemp;
}
@Override
final public GGraphics2D getTempGraphics2D(GFont font) {
g2Dtemp.setFont(GFontD.getAwtFont(font));
return new GGraphics2DD(g2Dtemp);
}
@Override
final protected void setHeight(int height) {
//
}
@Override
final protected void setWidth(int width) {
//
}
@Override
final protected void setStyleBarMode(int mode) {
if (hasStyleBar()) {
getStyleBar().setMode(mode);
}
}
@Override
protected MyZoomerD newZoomer() {
return new MyZoomerD(this);
}
@Override
protected boolean getShiftDown() {
return ((AppD) app).getShiftDown();
}
@Override
protected void setDefault2DCursor() {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
@Override
public App3D getApplication() {
return (App3D) this.app;
}
@Override
public GBufferedImage getExportImage(double scale) {
return getExportImage(scale, false, ExportType.PNG);
}
@Override
public GBufferedImage getExportImage(double scale, boolean transparency,
ExportType exportType)
throws OutOfMemoryError {
getRenderer().needExportImage(scale, true);
return getRenderer().getExportImage();
}
private boolean exportToClipboard;
private File exportFile;
private int exportDPI;
@Override
public void exportImagePNG(double scale, boolean transparency, int dpi,
File file, boolean exportToClipboard0, ExportType exportType) {
exportDPI = dpi;
exportFile = file;
this.exportToClipboard = exportToClipboard0;
getRenderer().needExportImage(scale, false);
}
/**
* write current renderer's image to current export file
*/
public void writeExportImage() {
if (exportFile == null) {
Log.debug("exportFile not set");
return;
}
try {
BufferedImage img = GBufferedImageD
.getAwtBufferedImage(getRenderer().getExportImage());
MyImageIO.write(img, "png", exportDPI, exportFile);
if (exportToClipboard) {
GraphicExportDialog.sendToClipboard(exportFile);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected EuclidianStyleBar newEuclidianStyleBar() {
return new EuclidianStyleBar3D(this);
}
@Override
public boolean suggestRepaint() {
return false;
// only for web
}
@Override
public void exportPaintPre(GGraphics2D g2d, double scale,
boolean transparency) {
Log.error("exportPaintPre unimplemented");
}
@Override
public void repaintView() {
// done by FPS animator
}
@Override
protected void drawBackgroundImage(GGraphics2D g2d) {
// nothing to do here
}
@Override
public Mouse3DEvent createMouse3DEvent(GPointWithZ mouse3DLoc) {
return new Mouse3DEventD(mouse3DLoc, getJPanel());
}
@Override
public void readText(String text) {
// TODO Auto-generated method stub
}
@Override
protected EuclidianStyleBar newDynamicStyleBar() {
// TODO Auto-generated method stub
return null;
}
@Override
protected void addDynamicStylebarToEV(EuclidianStyleBar dynamicStylebar) {
// TODO Auto-generated method stub
}
}