create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / components / compass / CompassSelector.java
1 package net.sf.openrocket.gui.components.compass;
2
3 import java.awt.event.MouseAdapter;
4 import java.awt.event.MouseEvent;
5
6 import net.sf.openrocket.gui.adaptors.DoubleModel;
7 import net.sf.openrocket.util.MathUtil;
8
9 /**
10  * Component that allows selecting a compass direction on a CompassSelector.
11  * 
12  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
13  */
14 public class CompassSelector extends CompassPointer {
15         
16         private final DoubleModel model;
17         
18         public CompassSelector(DoubleModel model) {
19                 super(model);
20                 this.model = model;
21                 
22                 MouseAdapter mouse = new MouseAdapter() {
23                         private boolean dragging = false;
24                         
25                         @Override
26                         public void mousePressed(MouseEvent e) {
27                                 if (!isWithinCircle(e))
28                                         return;
29                                 if (e.getButton() != MouseEvent.BUTTON1)
30                                         return;
31                                 dragging = true;
32                                 clicked(e);
33                         }
34                         
35                         @Override
36                         public void mouseReleased(MouseEvent e) {
37                                 if (e.getButton() != MouseEvent.BUTTON1)
38                                         return;
39                                 dragging = false;
40                         }
41                         
42                         
43                         @Override
44                         public void mouseDragged(MouseEvent e) {
45                                 if (!dragging)
46                                         return;
47                                 clicked(e);
48                         }
49                 };
50                 this.addMouseListener(mouse);
51                 this.addMouseMotionListener(mouse);
52                 
53         }
54         
55         private boolean isWithinCircle(MouseEvent e) {
56                 if (mid < 0 || width < 0) {
57                         return false;
58                 }
59                 
60                 int x = e.getX() - mid;
61                 int y = e.getY() - mid;
62                 
63                 double distance = Math.hypot(x, y);
64                 return distance < width / 2;
65         }
66         
67         private void clicked(MouseEvent e) {
68                 
69                 if (mid < 0 || width < 0) {
70                         return;
71                 }
72                 
73                 int x = e.getX() - mid;
74                 int y = e.getY() - mid;
75                 
76                 double distance = Math.hypot(x, y);
77                 
78                 double theta = Math.atan2(y, x);
79                 theta = MathUtil.reduce360(theta + Math.PI / 2);
80                 
81                 // Round the value appropriately
82                 theta = Math.toDegrees(theta);
83                 
84                 if (distance > 50) {
85                         theta = Math.round(theta);
86                 } else if (distance > 10) {
87                         theta = 5 * Math.round(theta / 5);
88                 } else {
89                         // Do nothing if too close to center
90                         return;
91                 }
92                 theta = Math.toRadians(theta);
93                 
94                 model.setValue(theta);
95         }
96         
97 }