/** * Process all the listeners and call methods in the renderer. */ /* Copyright 2016-2017 Will Winder This file is part of Universal Gcode Sender (UGS). UGS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. UGS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with UGS. If not, see <http://www.gnu.org/licenses/>. */ package com.willwinder.ugs.nbm.visualizer; import com.willwinder.ugs.nbm.visualizer.shared.GcodeRenderer; import com.google.common.eventbus.Subscribe; import com.jogamp.opengl.util.FPSAnimator; import com.willwinder.ugs.nbm.visualizer.renderables.GcodeModel; import com.willwinder.ugs.nbm.visualizer.renderables.Highlight; import com.willwinder.ugs.nbm.visualizer.renderables.Selection; import com.willwinder.ugs.nbm.visualizer.renderables.SizeDisplay; import com.willwinder.ugs.nbp.lib.eventbus.HighlightEvent; import com.willwinder.universalgcodesender.listeners.ControllerListener; import com.willwinder.universalgcodesender.listeners.ControllerStatus; import com.willwinder.universalgcodesender.listeners.UGSEventListener; import com.willwinder.universalgcodesender.model.Position; import com.willwinder.universalgcodesender.model.UGSEvent; import com.willwinder.universalgcodesender.types.GcodeCommand; import java.awt.Point; import java.awt.event.InputEvent; 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 java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.event.WindowListener; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; import javax.swing.SwingUtilities; import javax.vecmath.Point3d; /** * * @author wwinder */ public class RendererInputHandler implements WindowListener, MouseWheelListener, MouseMotionListener, MouseListener, KeyListener, PreferenceChangeListener, ControllerListener, UGSEventListener { final private GcodeRenderer gcodeRenderer; final private FPSAnimator animator; private final GcodeModel gcodeModel; private final Highlight highlight; private final SizeDisplay sizeDisplay; private final Selection selection; private final VisualizerPopupMenu visualizerPopupMenu; public RendererInputHandler(GcodeRenderer gr, FPSAnimator a, VisualizerPopupMenu popup) { gcodeRenderer = gr; animator = a; visualizerPopupMenu = popup; gcodeModel = new GcodeModel(); highlight = new Highlight(gcodeModel); sizeDisplay = new SizeDisplay(); selection = new Selection(); gr.registerRenderable(gcodeModel); gr.registerRenderable(highlight); gr.registerRenderable(sizeDisplay); gr.registerRenderable(selection); } @Subscribe public void highlightEventListener(HighlightEvent he) { highlight.setHighlightedLines(he.getLines()); gcodeRenderer.forceRedraw(); } @Override public void preferenceChange(PreferenceChangeEvent evt) { gcodeRenderer.reloadPreferences(); } public void setGcodeFile(String file) { gcodeModel.setGcodeFile(file); gcodeRenderer.setObjectSize(gcodeModel.getMin(), gcodeModel.getMax()); } public void setProcessedGcodeFile(String file) { gcodeModel.setProcessedGcodeFile(file); gcodeRenderer.setObjectSize(gcodeModel.getMin(), gcodeModel.getMax()); } /** * UGS Event Listener */ @Override public void UGSEvent(UGSEvent cse) { if (cse.isFileChangeEvent()) { animator.pause(); switch (cse.getFileState()) { case FILE_LOADING: setGcodeFile(cse.getFile()); break; case FILE_LOADED: setProcessedGcodeFile(cse.getFile()); break; } animator.resume(); } } /** * Mouse Motion Listener */ @Override public void mouseDragged(java.awt.event.MouseEvent e) { // Don't rotate if we're making a selection. if (selecting){ gcodeRenderer.mouseMoved(new Point(e.getX(), e.getY())); selection.setEnd(gcodeRenderer.getMouseWorldLocation()); gcodeRenderer.forceRedraw(); return; } if (SwingUtilities.isLeftMouseButton(e)) { int x = e.getX(); int y = e.getY(); int panMouseButton = InputEvent.BUTTON2_MASK; // TODO: Make configurable if (e.isShiftDown() || e.getModifiers() == panMouseButton) { gcodeRenderer.mousePan(new Point(x,y)); } else { gcodeRenderer.mouseRotate(new Point(x,y)); } } } @Override public void mouseMoved(java.awt.event.MouseEvent e) { gcodeRenderer.mouseMoved(new Point(e.getX(), e.getY())); gcodeRenderer.forceRedraw(); } /** * Mouse Wheel Listener */ @Override public void mouseWheelMoved(MouseWheelEvent e) { gcodeRenderer.zoom(e.getWheelRotation()); gcodeRenderer.forceRedraw(); } /** * Window Listener */ @Override public void windowDeactivated(java.awt.event.WindowEvent e) { // Run this on another thread than the AWT event queue to // make sure the call to Animator.stop() completes before // exiting new Thread(animator::stop).start(); } @Override public void windowOpened(java.awt.event.WindowEvent e) { } @Override public void windowClosing(java.awt.event.WindowEvent e) { } @Override public void windowClosed(java.awt.event.WindowEvent e) { } @Override public void windowIconified(java.awt.event.WindowEvent e) { } @Override public void windowDeiconified(java.awt.event.WindowEvent e) { } @Override public void windowActivated(java.awt.event.WindowEvent e) { } /** * Mouse Listener */ @Override public void mouseClicked(MouseEvent e) { // Show popup if (SwingUtilities.isRightMouseButton(e) || e.isControlDown()) { Point3d coords = gcodeRenderer.getMouseWorldLocation(); this.visualizerPopupMenu.setJogLocation(coords.x, coords.y); this.visualizerPopupMenu.show(e.getComponent(), e.getX(), e.getY()); } } private boolean selecting = false; private Point3d selectionStart = null; private Point3d selectionEnd = null; /** * Mouse pressed is called on mouse-down. * Mouse released and mouse clicked are called on mouse-up. */ @Override public void mousePressed(MouseEvent e) { // Zoom if (e.getButton() == MouseEvent.BUTTON1 && e.isMetaDown()) { selecting = true; selectionStart = gcodeRenderer.getMouseWorldLocation(); selection.setStart(selectionStart); } else { animator.start(); } } @Override public void mouseReleased(MouseEvent e) { // Finish selecting. if (selecting) { selecting = false; selectionEnd = gcodeRenderer.getMouseWorldLocation(); gcodeRenderer.zoomToRegion(selectionStart, selectionEnd, 1.0); selection.clear(); gcodeRenderer.forceRedraw(); } animator.stop(); } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } /** * Key Listener */ /** * KeyListener method. */ @Override public void keyTyped(KeyEvent ke) { } /** * KeyListener method. */ @Override public void keyPressed(KeyEvent ke) { animator.start(); int DELTA_SIZE = 1; switch(ke.getKeyCode()) { case KeyEvent.VK_UP: gcodeRenderer.pan(0, DELTA_SIZE); //this.eye.y+=DELTA_SIZE; break; case KeyEvent.VK_DOWN: gcodeRenderer.pan(0, -DELTA_SIZE); break; case KeyEvent.VK_LEFT: gcodeRenderer.pan(-DELTA_SIZE, 0); break; case KeyEvent.VK_RIGHT: gcodeRenderer.pan(DELTA_SIZE, 0); break; case KeyEvent.VK_MINUS: if (ke.isControlDown()) gcodeRenderer.zoom(-1); break; case KeyEvent.VK_0: case KeyEvent.VK_ESCAPE: gcodeRenderer.resetView(); break; } switch(ke.getKeyChar()) { case '+': if (ke.isControlDown()) gcodeRenderer.zoom(1); break; } } /** * KeyListener method. */ @Override public void keyReleased(KeyEvent ke) { animator.stop(); } /** * Controller listener methods */ @Override public void statusStringListener(ControllerStatus status) { sizeDisplay.setUnits(status.getMachineCoord().getUnits()); gcodeRenderer.setMachineCoordinate(status.getMachineCoord()); gcodeRenderer.setWorkCoordinate(status.getWorkCoord()); gcodeRenderer.forceRedraw(); } @Override public void controlStateChange(UGSEvent.ControlState state) { } @Override public void fileStreamComplete(String filename, boolean success) { } @Override public void commandSkipped(GcodeCommand command) { } @Override public void commandSent(GcodeCommand command) { } @Override public void commandComplete(GcodeCommand command) { gcodeModel.setCurrentCommandNumber(command.getCommandNumber()); // TODO: When to redraw?? } @Override public void commandComment(String comment) { } @Override public void probeCoordinates(Position p) { } @Override public void messageForConsole(MessageType type, String msg) { } @Override public void postProcessData(int numRows) { } }