/* * Copyright 2017 Laszlo Balazs-Csiki * * This file is part of Pixelitor. Pixelitor is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License, version 3 as published by the Free * Software Foundation. * * Pixelitor 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 Pixelitor. If not, see <http://www.gnu.org/licenses/>. */ package pixelitor.filters.gui; import javax.swing.*; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Stroke; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Line2D; import static java.awt.RenderingHints.KEY_STROKE_CONTROL; import static java.awt.RenderingHints.VALUE_STROKE_PURE; /** * An abstract superclass for angle selectors and elevation angle selectors */ public abstract class AbstractAngleUI extends JComponent implements MouseListener, MouseMotionListener { final AngleParam model; static final int SIZE = 50; private static final Stroke ARROW_STROKE = new BasicStroke(1.7f); private static final Color ENABLED_ARROW_COLOR = new Color(45, 66, 85); private static final Color DISABLED_ARROW_COLOR = new Color(160, 160, 160); protected boolean enabled = true; int cx; int cy; AbstractAngleUI(AngleParam angleParam) { this.model = angleParam; Dimension size2D = new Dimension(SIZE + 1, SIZE + 1); setSize(size2D); setMinimumSize(size2D); setPreferredSize(size2D); addMouseListener(this); addMouseMotionListener(this); } private void updateAngle(int x, int y, boolean trigger) { if (!enabled) { return; } double angle = Math.atan2(y - cy, x - cx); repaint(); model.setValueInRadians(angle, trigger); } @Override public void mouseClicked(MouseEvent e) { // will be handled in mouseReleased } @Override public void mousePressed(MouseEvent e) { updateAngle(e.getX(), e.getY(), false); } @Override public void mouseReleased(MouseEvent e) { updateAngle(e.getX(), e.getY(), true); } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseDragged(MouseEvent e) { updateAngle(e.getX(), e.getY(), false); } @Override public void mouseMoved(MouseEvent e) { } void drawArrow(Graphics2D g2, double angle, float startX, float startY, float endX, float endY) { if (enabled) { g2.setColor(ENABLED_ARROW_COLOR); } else { g2.setColor(DISABLED_ARROW_COLOR); } g2.setStroke(ARROW_STROKE); g2.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_PURE); g2.draw(new Line2D.Float(startX, startY, endX, endY)); double backAngle1 = 2.8797926 + angle; double backAngle2 = 3.4033926 + angle; int arrowRadius = 10; float arrowEnd1X = (float) (endX + (arrowRadius * Math.cos(backAngle1))); float arrowEnd1Y = (float) (endY + (arrowRadius * Math.sin(backAngle1))); float arrowEnd2X = (float) (endX + (arrowRadius * Math.cos(backAngle2))); float arrowEnd2Y = (float) (endY + (arrowRadius * Math.sin(backAngle2))); g2.draw(new Line2D.Float(endX, endY, arrowEnd1X, arrowEnd1Y)); g2.draw(new Line2D.Float(endX, endY, arrowEnd2X, arrowEnd2Y)); } @Override public void setEnabled(boolean enabled) { this.enabled = enabled; super.setEnabled(enabled); repaint(); } }