import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.media.opengl.DebugGL;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.swing.BorderFactory;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.deadtroll.controller.Trab03Controller;
import com.deadtroll.model.Circulo;
import com.deadtroll.model.Cor;
import com.deadtroll.model.Poligono;
import com.deadtroll.model.PoligonoAberto;
import com.deadtroll.model.PoligonoFechado;
import com.deadtroll.model.Ponto2d;
import com.deadtroll.model.Spline;
import com.deadtroll.renderer.Renderable;
import com.deadtroll.renderer.Renderer;
import com.deadtroll.util.MathUtil;
import com.deadtroll.util.NDCUtil;
import com.sun.opengl.util.GLUT;
/**
*
*
*/
public class Trab03 implements GLEventListener, KeyListener, MouseMotionListener, MouseListener, ChangeListener {
private GL gl;
private GLU glu;
private GLUT glut;
private GLAutoDrawable glDrawable;
// par�metros de configura��o
private float tamanhoCursor = 2.5f;
// atributos de estado
private float mousePos[] = {0.0f,0.0f};
private Trab03Controller controller;
private Renderer renderer;
private float minOrthoX = -50.0f;
private float maxOrthoX = 50.0f;
private float minOrthoY = -50.0f;
private float maxOrthoY = 50.0f;
private float minOrthoXTransf;
private float maxOrthoXTransf;
private float minOrthoYTransf;
private float maxOrthoYTransf;
private float gdWidth;
private float gdHeight;
private float zoomFactor = 1.0f;
private float wTransX=0.0f;
private float wTransY=0.0f;
private JColorChooser colorChooser;
private Renderable objetoAdicao;
private boolean movendoPonto;
// "render" feito logo ap�s a inicializa��o do contexto OpenGL.
public void init(GLAutoDrawable drawable) {
glDrawable = drawable;
gl = drawable.getGL();
glu = new GLU();
glut = new GLUT();
glDrawable.setGL(new DebugGL(gl));
controller = new Trab03Controller();
renderer = new Renderer();
controller.setModoCursor(Trab03Controller.MODO_SELECAO_VERTICES);
controller.setModoTransformacao(Trab03Controller.MODO_TRANSFORMACAO_TRANSLACAO);
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
gl.glEnable(GL.GL_LINE_STIPPLE);
gdWidth = glDrawable.getWidth();
gdHeight = glDrawable.getHeight();
}
// m�todo definido na interface GLEventListener.
// "render" feito pelo cliente OpenGL.
public void display(GLAutoDrawable arg0) {
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
this.minOrthoXTransf = this.minOrthoX*this.zoomFactor+this.wTransX;
this.maxOrthoXTransf = this.maxOrthoX*this.zoomFactor+this.wTransX;
this.minOrthoYTransf = this.minOrthoY*this.zoomFactor+this.wTransY;
this.maxOrthoYTransf = this.maxOrthoY*this.zoomFactor+this.wTransY;
// configurar window
glu.gluOrtho2D(minOrthoXTransf, maxOrthoXTransf, minOrthoYTransf, maxOrthoYTransf);
// configurar cor de desenho (valores r, g, b)
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glLineWidth(1.0f);
gl.glBegin(GL.GL_LINES);
// eixo X
gl.glVertex2f(-40.0f, 0.0f);
gl.glVertex2f(40.0f, 0.0f);
// eixo Y
gl.glVertex2f(0.0f, 40.0f);
gl.glVertex2f(0.0f, -40.0f);
gl.glEnd();
this.renderer.draw(gl, glut, controller.getObjects());
desenharStatus();
desenharCursor();
gl.glFlush();
}
private void desenharStatus() {
gl.glRasterPos2f(minOrthoXTransf+(10.0f*zoomFactor), minOrthoYTransf+(7.0f*zoomFactor));
glut.glutBitmapString(GLUT.BITMAP_TIMES_ROMAN_10, this.controller.descricaoModoCursor());
gl.glRasterPos2f(minOrthoXTransf+(10.0f*zoomFactor), minOrthoYTransf+(5.0f*zoomFactor));
glut.glutBitmapString(GLUT.BITMAP_TIMES_ROMAN_10, this.controller.descricaoModoTransformacao());
gl.glRasterPos2f(minOrthoXTransf+(10.0f*zoomFactor), minOrthoYTransf+(2.0f*zoomFactor));
glut.glutBitmapString(GLUT.BITMAP_TIMES_ROMAN_10, "Tecle H para ver a lista de comandos.");
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glRasterPos2f(minOrthoXTransf+(45.0f*zoomFactor), minOrthoYTransf+(2.0f*zoomFactor));
glut.glutBitmapString(GLUT.BITMAP_TIMES_ROMAN_10, this.controller.getEstadoTransformacoes());
gl.glColor3f(0.0f, 0.0f, 0.0f);
}
private void desenharCursor() {
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glBegin(GL.GL_LINES);
gl.glVertex2f(mousePos[0]-tamanhoCursor, mousePos[1]);
gl.glVertex2f(mousePos[0]+tamanhoCursor, mousePos[1]);
gl.glVertex2f(mousePos[0], mousePos[1]-tamanhoCursor);
gl.glVertex2f(mousePos[0], mousePos[1]+tamanhoCursor);
gl.glEnd();
gl.glColor3f(0.0f, 0.0f, 0.0f);
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_P) {
this.controller.setModoCursor(Trab03Controller.MODO_SELECAO_POLIGONOS);
} else if (e.getKeyCode() == KeyEvent.VK_V) {
this.controller.setModoCursor(Trab03Controller.MODO_SELECAO_VERTICES);
} else if (e.getKeyCode() == KeyEvent.VK_A) {
this.controller.setModoCursor(Trab03Controller.MODO_ADICAO_VERTICES);
} else if (e.getKeyCode() == KeyEvent.VK_M) {
this.controller.setModoCursor(Trab03Controller.MODO_SELECAO_VERTICES);
} else if (e.getKeyCode() == KeyEvent.VK_R) {
this.controller.setModoCursor(Trab03Controller.MODO_REMOCAO_VERTICES);
} else if (e.getKeyCode() == KeyEvent.VK_E) {
this.controller.setModoCursor(Trab03Controller.MODO_REMOCAO_POLIGONOS);
} else if (e.getKeyCode() == KeyEvent.VK_C) {
if (this.controller.modoSelecaoPoligonos()) {
Renderable objeto = this.controller.getObjetoSelecionado();
if (objeto != null) {
colorChooser = new JColorChooser();
colorChooser.getSelectionModel().addChangeListener(this);
colorChooser.setBorder(BorderFactory.createTitledBorder("Escolha a cor"));
colorChooser.setPreferredSize(new Dimension(400, 300));
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(colorChooser, BorderLayout.CENTER);
JFrame frame = new JFrame("Sele��o de cor");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}
}
} else if (e.getKeyCode() == KeyEvent.VK_H) {
String help = "";
help += "Teclas do controle de cursor:\n\n";
help += "P: Sele��o/movimenta��o de pol�gonos\n";
help += "V: Sele��o de v�rtices\n";
help += "A: Adi��o de v�rtices (se objeto j� selecionado)\n";
help += "C: Sele��o de cores (se objeto j� selecionado)\n";
help += "M: Sele��o/movimenta��o de v�rtices\n";
help += "R: Remo��o de v�rtices\n";
help += "E: Remo��o de pol�gonos\n";
help += "F5: Adi��o de splines\n";
help += "F6: Adi��o de c�rculos\n";
help += "F7: Adi��o de pol�gonos abertos\n";
help += "F8: adi��o de pol�gonos fechados\n";
help += "+: Aumenta zoom\n";
help += "-: Diminui zoom\n";
help += "Shift+Direcionais: Controla scroll\n";
help += "H: Help\n\n";
help += "Teclas do controle de transforma��o de objetos\n\n";
help += "F1: Transla��o (Direcionais para movimenta��o)\n";
help += "F2: Escala (Teclas para up e down para alterar escala) \n";
help += "F3: Rota��o (Teclas esquerda e direita para alterar rota��o)";
JOptionPane.showMessageDialog(null, help, "Help", JOptionPane.INFORMATION_MESSAGE);
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
if (e.isShiftDown()) {
this.wTransX += 5.0f;
} else if (this.controller.modoSelecaoPoligonos()) {
if (this.controller.modoTransformacaoRotacao()) {
this.controller.aplicarRotacaoHor();
} else if (this.controller.modoTransformacaoTranslacao()) {
this.controller.aumentarTranslacaoX();
}
}
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
if (e.isShiftDown()) {
this.wTransX -= 5.0f;
} else if (this.controller.modoSelecaoPoligonos()) {
if (this.controller.modoTransformacaoRotacao()) {
this.controller.aplicarRotacaoAntiHor();
} else if (this.controller.modoTransformacaoTranslacao()) {
this.controller.diminuirTranslacaoX();
}
}
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
if (e.isShiftDown()) {
this.wTransY += 5.0f;
} else if (this.controller.modoSelecaoPoligonos()) {
if (this.controller.modoTransformacaoEscala()) {
this.controller.aumentarEscala();
} else if (this.controller.modoTransformacaoTranslacao()) {
this.controller.aumentarTranslacaoY();
}
}
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
if (e.isShiftDown()) {
this.wTransY -= 5.0f;
} else if (this.controller.modoSelecaoPoligonos()) {
if (this.controller.modoTransformacaoEscala()) {
this.controller.diminuirEscala();
} else if (this.controller.modoTransformacaoTranslacao()) {
this.controller.diminuirTranslacaoY();
}
}
} else if (e.getKeyCode() == KeyEvent.VK_F1) {
controller.setModoTransformacao(Trab03Controller.MODO_TRANSFORMACAO_TRANSLACAO);
} else if (e.getKeyCode() == KeyEvent.VK_F2) {
controller.setModoTransformacao(Trab03Controller.MODO_TRANSFORMACAO_ESCALA);
} else if (e.getKeyCode() == KeyEvent.VK_F3) {
controller.setModoTransformacao(Trab03Controller.MODO_TRANSFORMACAO_ROTACAO);
} else if (e.getKeyCode() == KeyEvent.VK_F5) {
controller.setModoCursor(Trab03Controller.MODO_ADICAO_SPLINE);
this.objetoAdicao = null;
} else if (e.getKeyCode() == KeyEvent.VK_F6) {
controller.setModoCursor(Trab03Controller.MODO_ADICAO_CIRCULO);
this.objetoAdicao = null;
} else if (e.getKeyCode() == KeyEvent.VK_F7) {
controller.setModoCursor(Trab03Controller.MODO_ADICAO_POLIGONO_ABERTO);
this.objetoAdicao = null;
} else if (e.getKeyCode() == KeyEvent.VK_F8) {
controller.setModoCursor(Trab03Controller.MODO_ADICAO_POLIGONO_FECHADO);
this.objetoAdicao = null;
} else if (e.getKeyChar() == '+') {
if (zoomFactor > 0.1) {
zoomFactor -= 0.1f;
}
} else if (e.getKeyChar() == '-') {
if (zoomFactor < 10.0f) {
zoomFactor += 0.1f;
}
}
glDrawable.display();
}
// m�todo definido na interface GLEventListener.
// "render" feito depois que a janela foi redimensionada.
public void reshape(GLAutoDrawable glDrawable,
int x,
int y,
int width,
int height) {
if (glDrawable != null) {
maxOrthoX = (maxOrthoX * width)/gdWidth;
minOrthoX = (minOrthoX * width)/gdWidth;
minOrthoY = (minOrthoY * height)/gdHeight;
maxOrthoY = (maxOrthoY * height)/gdHeight;
gdWidth = width;
gdHeight = height;
glDrawable.repaint();
}
}
// m�todo definido na interface GLEventListener.
// "render" feito quando o modo ou dispositivo de exibi��o associado foi alterado.
public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent e) {
}
@Override
public void mouseDragged(MouseEvent event) {
mousePos[0] = NDCUtil.xScreenParaOrtho(event.getX(), glDrawable.getWidth(), minOrthoXTransf, maxOrthoXTransf);
mousePos[1] = NDCUtil.yScreenParaOrtho(event.getY(), glDrawable.getHeight(), minOrthoYTransf, maxOrthoYTransf);
Ponto2d pontoMouse = new Ponto2d(mousePos[0], mousePos[1]);
if (this.controller.modoSelecaoVertices()) {
if (this.movendoPonto) {
this.controller.getVerticeSelecionado().setX(pontoMouse.getX());
this.controller.getVerticeSelecionado().setY(pontoMouse.getY());
}
} else if (this.controller.modoSelecaoPoligonos()) {
if (this.controller.movendoPoligono()) {
Renderable objeto = this.controller.getObjetoSelecionado();
if (objeto != null) {
Ponto2d pontoMouseDrag = objeto.getPontoMouseDrag();
float transX = pontoMouse.getX() - pontoMouseDrag.getX();
float transY = pontoMouse.getY() - pontoMouseDrag.getY();
objeto.setTranslacaoX(transX);
objeto.setTranslacaoY(transY);
}
}
}
glDrawable.display();
}
@Override
public void mouseMoved(MouseEvent event) {
if (glDrawable != null) {
// mudar a posi��o atual do mouse para exibir o cursor
mousePos[0] = NDCUtil.xScreenParaOrtho(event.getX(), glDrawable.getWidth(), minOrthoXTransf, maxOrthoXTransf);
mousePos[1] = NDCUtil.yScreenParaOrtho(event.getY(), glDrawable.getHeight(), minOrthoYTransf, maxOrthoYTransf);
Ponto2d pontoMouse = new Ponto2d(this.mousePos[0], this.mousePos[1]);
if (this.controller.modoAdicaoCirculo()) {
if (objetoAdicao != null) {
Circulo circulo = (Circulo)objetoAdicao;
float raio = MathUtil.calcularDistancia(circulo.getCentro(), pontoMouse);
circulo.setRaio(raio);
}
}
glDrawable.display();
}
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
Ponto2d pontoMouse = new Ponto2d(this.mousePos[0], this.mousePos[1]);
if (this.controller.modoAdicaoCirculo()) {
if (this.objetoAdicao == null) {
this.objetoAdicao = new Circulo(pontoMouse, 0.0f);
this.controller.addObject(this.objetoAdicao);
} else {
Circulo circulo = (Circulo)this.objetoAdicao;
float raio = MathUtil.calcularDistancia(circulo.getCentro(), pontoMouse);
circulo.setRaio(raio);
this.objetoAdicao = null;
}
} else if (this.controller.modoAdicaoSpline()) {
if (this.objetoAdicao == null) {
this.objetoAdicao = new Spline();
((Spline)this.objetoAdicao).adicionarPonto(pontoMouse);
this.controller.addObject(this.objetoAdicao);
} else {
Spline spline = (Spline)this.objetoAdicao;
if (spline.getNumPontos() < 3) {
spline.adicionarPonto(pontoMouse);
} else {
spline.adicionarPonto(pontoMouse);
this.objetoAdicao = null;
}
}
} else if (this.controller.modoAdicaoPoligonoAberto() || this.controller.modoAdicaoPoligonoFechado()) {
if (this.objetoAdicao == null) {
if (this.controller.modoAdicaoPoligonoAberto()) {
this.objetoAdicao = new PoligonoAberto();
} else {
this.objetoAdicao = new PoligonoFechado();
}
((Poligono)this.objetoAdicao).adicionarPonto(pontoMouse);
this.controller.addObject(this.objetoAdicao);
} else {
Poligono poligono = (Poligono)this.objetoAdicao;
poligono.adicionarPonto(pontoMouse);
}
} else if (this.controller.modoSelecaoVertices()) {
if (this.controller.selecionarVertice(pontoMouse)) {
this.movendoPonto = true;
}
} else if (this.controller.modoAdicaoVertices()) {
this.controller.adicionarVertice(pontoMouse);
} else if (this.controller.modoRemocaoVertices()) {
if (this.controller.selecionarVertice(pontoMouse)) {
this.controller.removerVerticeSelecionado();
}
} else if (this.controller.modoRemocaoPoligonos()) {
if (this.controller.select(pontoMouse)) {
this.controller.removerPoligonoSelecionado();
}
} else if (this.controller.modoSelecaoPoligonos()) {
if (this.controller.select(pontoMouse)) {
glDrawable.display();
} else {
this.controller.desmarcarObjetoSelecionado();
glDrawable.display();
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
float x = NDCUtil.xScreenParaOrtho(e.getX(), glDrawable.getWidth(), minOrthoXTransf, maxOrthoXTransf);
float y = NDCUtil.yScreenParaOrtho(e.getY(), glDrawable.getHeight(), minOrthoYTransf, maxOrthoYTransf);
Ponto2d pontoMouse = new Ponto2d(x,y);
if (this.controller.modoSelecaoVertices()) {
if (this.movendoPonto) {
this.controller.getVerticeSelecionado().setX(pontoMouse.getX());
this.controller.getVerticeSelecionado().setY(pontoMouse.getY());
}
this.movendoPonto = false;
} else if (this.controller.modoSelecaoPoligonos()) {
if (this.controller.movendoPoligono()) {
Renderable objeto = this.controller.getObjetoSelecionado();
if (objeto != null) {
Ponto2d pontoMouseDrag = objeto.getPontoMouseDrag();
float transX = pontoMouse.getX() - pontoMouseDrag.getX();
float transY = pontoMouse.getY() - pontoMouseDrag.getY();
objeto.setTranslacaoX(transX);
objeto.setTranslacaoY(transY);
this.controller.setMovendoPoligono(false);
}
}
}
glDrawable.display();
}
@Override
public void stateChanged(ChangeEvent e) {
if (this.controller.modoSelecaoPoligonos()) {
Renderable objeto = this.controller.getObjetoSelecionado();
if (objeto != null && colorChooser != null) {
Color color = colorChooser.getColor();
objeto.setCor(new Cor((byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()));
glDrawable.display();
}
}
}
}