Java tutorial
/* * Copyright (c) 2012 European Synchrotron Radiation Facility, * Diamond Light Source Ltd. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package fable.imageviewer.views; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.opengl.GLCanvas; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GLContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import fable.framework.toolbox.FableUtils; /************************************************************************** * Copyright (c) 2005 Bo Majewski All rights reserved. This program and the * accompanying materials are made available under the terms of the Eclipse * Public License v1.0 which accompanies this distribution, and is available * at http://www.eclipse.org/org/documents/epl-v10.html * * Contributors: Bo Majewski - initial API and implementation *************************************************************************/ /** * Implements a scene grip, capable of rotating and moving a GL scene with * the help of the mouse and keyboard. * * @author Bo Majewski */ public class SceneGrip extends MouseAdapter implements MouseMoveListener, Listener, KeyListener { private static Logger logger = LoggerFactory.getLogger(SceneGrip.class); private int canvasWidth = 0; private int canvasHeight = 0; private GLCanvas canvas; private float xrot; private float yrot; private float zoff; private float xoff; private float yoff; private float xcpy; private float ycpy; private float xscale; private float yscale; private boolean move; private int xdown; private int ydown; private int mouseDown; private IImageSizeProvider prov; public SceneGrip(final GLCanvas canvas, IImageSizeProvider prov) { this.canvas = canvas; this.prov = prov; this.init(); } protected void init() { canvas.setCurrent(); Rectangle bounds = canvas.getBounds(); canvasWidth = bounds.width; canvasHeight = bounds.height; this.xrot = this.yrot = 0.0f; this.xoff = this.yoff = 0.0f; if (prov.getImageWidth() != 0) { xscale = canvasWidth / prov.getImageWidth(); } if (prov.getImageHeight() != 0) { yscale = canvasHeight / prov.getImageHeight(); } zoff = 1.0f; if (xscale < yscale) zoff = xscale; else zoff = yscale; logger.debug("xscale = " + xscale + " yscale = " + yscale + " zoff = " + zoff); } public void mouseDown(MouseEvent e) { if (++this.mouseDown == 1) { if ((this.move = e.button == 3)) { this.xcpy = xoff; this.ycpy = yoff; ((Control) e.widget).setCursor(e.widget.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); } else { this.xcpy = xrot; this.ycpy = yrot; ((Control) e.widget).setCursor(e.widget.getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL)); } this.xdown = e.x; this.ydown = e.y; } } public void mouseUp(MouseEvent e) { if (--this.mouseDown == 0) { ((Control) e.widget).setCursor(e.widget.getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); } } public void mouseMove(MouseEvent e) { Point p = ((Control) e.widget).getSize(); if (this.mouseDown > 0) { int dx = e.x - this.xdown; int dy = e.y - this.ydown; if (this.move) { yoff = this.ycpy + ((canvasHeight / 2.f) * dy) / (2.0f * p.y); xoff = this.xcpy + ((canvasWidth / 2.f) * dx) / (2.0f * p.x); } else { xrot = this.xcpy + dy / 2.0f; yrot = this.ycpy + dx / 2.0f; } } } public void handleEvent(Event event) { this.zoff *= 1.1f; } public void zoomIn() { this.zoff *= 1.05f; } public void zoomOut() { this.zoff *= .95f; } public void rotate(final int direction) { switch (direction) { case SWT.ARROW_UP: this.xrot -= 5f; break; case SWT.ARROW_DOWN: this.xrot += 5f; break; case SWT.ARROW_LEFT: this.yrot += 5f; break; case SWT.ARROW_RIGHT: this.yrot -= 5f; break; default: return; } } public void translate(final int direction) { switch (direction) { case SWT.ARROW_UP: this.yoff -= (float) canvasHeight / 10.f; break; case SWT.ARROW_DOWN: this.yoff += (float) canvasHeight / 10.f; break; case SWT.ARROW_LEFT: this.xoff -= (float) canvasWidth / 10.f; break; case SWT.ARROW_RIGHT: this.xoff += (float) canvasWidth / 10; break; default: return; } } public void keyPressed(KeyEvent e) { if ((e.stateMask & SWT.CONTROL) != 0) { rotate(e.keyCode); return; } translate(e.keyCode); switch (e.keyCode) { case SWT.PAGE_UP: zoomIn(); break; case SWT.PAGE_DOWN: zoomOut(); break; case SWT.HOME: this.init(); break; } } public void keyReleased(KeyEvent e) { } /** * Warning called constantly in display loop - change with care. */ public void adjust() { canvas.setCurrent(); try { GLContext.useContext(canvas); } catch (LWJGLException ex) { FableUtils.excMsg(ReliefView.class, "Error in adjust using GLContext.useContext", ex); } // gl = context.getGL (); GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); /* set the orthogonal projection to the size of the window */ GL11.glOrtho(0, canvasWidth, canvasHeight, 0, -1.0e5f, 1.0e5f); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glLoadIdentity(); GL11.glTranslatef(canvasWidth / 2 + this.xoff, canvasHeight / 2 + this.yoff, 0); GL11.glScalef(zoff, zoff, zoff); /* * zoff has no effect on the orthogonal projection therefore zoom by * passing zoff to scale */ GL11.glRotatef(this.xrot, 1f, 0.0f, 0.0f); GL11.glRotatef(this.yrot, 0.0f, 1f, 0.0f); GL11.glTranslatef(-prov.getImageWidth() / 2, -prov.getImageHeight() / 2, 0); } public void setOffsets(float x, float y, float z) { this.xoff = x; this.yoff = y; this.zoff = z; } public void setRotation(float x, float y) { this.xrot = x; this.yrot = y; } public void setBounds(Rectangle bounds) { canvasWidth = bounds.width; canvasHeight = bounds.height; } }