create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / components / compass / CompassPointer.java
1 package net.sf.openrocket.gui.components.compass;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.RenderingHints;
8
9 import javax.swing.event.ChangeEvent;
10 import javax.swing.event.ChangeListener;
11
12 import net.sf.openrocket.gui.Resettable;
13 import net.sf.openrocket.gui.adaptors.DoubleModel;
14
15 /**
16  * A component that draws a pointer onto a compass rose.
17  * 
18  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
19  */
20 public class CompassPointer extends CompassRose implements Resettable {
21         
22         private static final Color PRIMARY_POINTER_COLOR = new Color(1.0f, 0.2f, 0.2f);
23         private static final Color SECONDARY_POINTER_COLOR = new Color(0.2f, 0.2f, 0.2f, 0.2f);
24         
25         private final DoubleModel model;
26         private final ChangeListener listener;
27         
28         protected int width = -1;
29         protected int mid = -1;
30         
31         private DoubleModel secondaryModel;
32         
33         private float pointerLength = 0.95f;
34         private float pointerWidth = 0.1f;
35         private float pointerArrowWidth = 0.2f;
36         private boolean pointerArrow = true;
37         
38         
39
40         public CompassPointer(DoubleModel model) {
41                 super();
42                 this.model = model;
43                 listener = new ChangeListener() {
44                         @Override
45                         public void stateChanged(ChangeEvent e) {
46                                 CompassPointer.this.repaint();
47                         }
48                 };
49                 model.addChangeListener(listener);
50         }
51         
52         
53         @Override
54         public void paintComponent(Graphics g) {
55                 super.paintComponent(g);
56                 
57                 Graphics2D g2 = (Graphics2D) g;
58                 
59
60                 Dimension dimension = this.getSize();
61                 
62                 width = Math.min(dimension.width, dimension.height);
63                 mid = width / 2;
64                 width = (int) (getScaler() * width);
65                 
66
67                 g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
68                 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
69                 
70
71                 if (secondaryModel != null) {
72                         drawArrow(secondaryModel.getValue(), SECONDARY_POINTER_COLOR, g2);
73                 }
74                 drawArrow(model.getValue(), PRIMARY_POINTER_COLOR, g2);
75                 
76
77         }
78         
79         
80         private void drawArrow(double angle, Color color, Graphics2D g2) {
81                 
82                 int pLength = (int) (width * pointerLength / 2);
83                 int pWidth = (int) (width * pointerWidth / 2);
84                 int pArrowWidth = (int) (width * pointerArrowWidth / 2);
85                 
86                 int[] x = new int[8];
87                 int[] y = new int[8];
88                 
89                 g2.setColor(color);
90                 
91
92                 double sin = Math.sin(angle);
93                 double cos = Math.cos(angle);
94                 
95                 int n = 0;
96                 
97                 // Top part
98                 x[n] = 0;
99                 y[n] = -pLength;
100                 n++;
101                 if (pointerArrow) {
102                         x[n] = -pArrowWidth;
103                         y[n] = -pLength + 2 * pArrowWidth;
104                         n++;
105                         x[n] = -pWidth;
106                         y[n] = -pLength + 2 * pArrowWidth;
107                         n++;
108                 }
109                 
110                 // Bottom part
111                 x[n] = -pWidth;
112                 y[n] = pLength;
113                 n++;
114                 x[n] = 0;
115                 y[n] = pLength - pWidth;
116                 n++;
117                 x[n] = pWidth;
118                 y[n] = pLength;
119                 n++;
120                 
121                 // Top part
122                 if (pointerArrow) {
123                         x[n] = pWidth;
124                         y[n] = -pLength + 2 * pArrowWidth;
125                         n++;
126                         x[n] = pArrowWidth;
127                         y[n] = -pLength + 2 * pArrowWidth;
128                         n++;
129                 }
130                 
131                 // Rotate and shift
132                 for (int i = 0; i < n; i++) {
133                         double x2, y2;
134                         x2 = cos * x[i] - sin * y[i];
135                         y2 = sin * x[i] + cos * y[i];
136                         
137                         x[i] = (int) (x2 + mid);
138                         y[i] = (int) (y2 + mid);
139                 }
140                 
141                 g2.fillPolygon(x, y, n);
142                 
143                 g2.setColor(color.darker());
144                 g2.drawPolygon(x, y, n);
145                 
146         }
147         
148         
149         public boolean isPointerArrow() {
150                 return pointerArrow;
151         }
152         
153         
154         public void setPointerArrow(boolean useArrow) {
155                 this.pointerArrow = useArrow;
156                 repaint();
157         }
158         
159         
160         public float getPointerLength() {
161                 return pointerLength;
162         }
163         
164         
165         public void setPointerLength(float pointerLength) {
166                 this.pointerLength = pointerLength;
167                 repaint();
168         }
169         
170         
171         public float getPointerWidth() {
172                 return pointerWidth;
173         }
174         
175         
176         public void setPointerWidth(float pointerWidth) {
177                 this.pointerWidth = pointerWidth;
178                 repaint();
179         }
180         
181         
182         public float getPointerArrowWidth() {
183                 return pointerArrowWidth;
184         }
185         
186         
187         public void setPointerArrowWidth(float pointerArrowWidth) {
188                 this.pointerArrowWidth = pointerArrowWidth;
189                 repaint();
190         }
191         
192         
193
194         public DoubleModel getSecondaryModel() {
195                 return secondaryModel;
196         }
197         
198         
199         public void setSecondaryModel(DoubleModel secondaryModel) {
200                 if (this.secondaryModel != null) {
201                         this.secondaryModel.removeChangeListener(listener);
202                 }
203                 this.secondaryModel = secondaryModel;
204                 if (this.secondaryModel != null) {
205                         this.secondaryModel.addChangeListener(listener);
206                 }
207         }
208         
209         
210         @Override
211         public void resetModel() {
212                 model.removeChangeListener(listener);
213                 setSecondaryModel(null);
214         }
215         
216
217
218 }