package net.sf.openrocket.gui.components.compass; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.util.MathUtil; /** * Component that allows selecting a compass direction on a CompassSelector. * * @author Sampo Niskanen <sampo.niskanen@iki.fi> */ public class CompassSelector extends CompassPointer { private final DoubleModel model; public CompassSelector(DoubleModel model) { super(model); this.model = model; MouseAdapter mouse = new MouseAdapter() { private boolean dragging = false; @Override public void mousePressed(MouseEvent e) { if (!isWithinCircle(e)) return; if (e.getButton() != MouseEvent.BUTTON1) return; dragging = true; clicked(e); } @Override public void mouseReleased(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON1) return; dragging = false; } @Override public void mouseDragged(MouseEvent e) { if (!dragging) return; clicked(e); } }; this.addMouseListener(mouse); this.addMouseMotionListener(mouse); } private boolean isWithinCircle(MouseEvent e) { if (mid < 0 || width < 0) { return false; } int x = e.getX() - mid; int y = e.getY() - mid; double distance = Math.hypot(x, y); return distance < width / 2; } private void clicked(MouseEvent e) { if (mid < 0 || width < 0) { return; } int x = e.getX() - mid; int y = e.getY() - mid; double distance = Math.hypot(x, y); double theta = Math.atan2(y, x); theta = MathUtil.reduce360(theta + Math.PI / 2); // Round the value appropriately theta = Math.toDegrees(theta); if (distance > 50) { theta = Math.round(theta); } else if (distance > 10) { theta = 5 * Math.round(theta / 5); } else { // Do nothing if too close to center return; } theta = Math.toRadians(theta); model.setValue(theta); } }