create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / components / compass / CompassRose.java
1 package net.sf.openrocket.gui.components.compass;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Font;
6 import java.awt.Graphics;
7 import java.awt.Graphics2D;
8 import java.awt.RenderingHints;
9 import java.awt.font.GlyphVector;
10 import java.awt.geom.Rectangle2D;
11
12 import javax.swing.JComponent;
13
14 import net.sf.openrocket.l10n.Translator;
15 import net.sf.openrocket.startup.Application;
16
17 /**
18  * A component that draws a compass rose.  This class has no other functionality, but superclasses
19  * may add functionality to it.
20  * 
21  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
22  */
23 public class CompassRose extends JComponent {
24         private static final Translator trans = Application.getTranslator();
25         
26
27         private static final Color MAIN_COLOR = new Color(0.4f, 0.4f, 1.0f);
28         private static final float MAIN_LENGTH = 0.95f;
29         private static final float MAIN_WIDTH = 0.15f;
30         
31         private static final int CIRCLE_BORDER = 2;
32         private static final Color CIRCLE_HIGHLIGHT = new Color(1.0f, 1.0f, 1.0f, 0.7f);
33         private static final Color CIRCLE_SHADE = new Color(0.0f, 0.0f, 0.0f, 0.2f);
34         
35         private static final Color MARKER_COLOR = Color.BLACK;
36         
37
38         private double scaler;
39         
40         private double markerRadius;
41         private Font markerFont;
42         
43         
44         /**
45          * Construct a compass rose with the default settings.
46          */
47         public CompassRose() {
48                 this(0.8, 1.1, Font.decode("Serif-PLAIN-16"));
49         }
50         
51         
52         /**
53          * Construct a compass rose with the specified settings.
54          * 
55          * @param scaler                The scaler of the rose.  The bordering circle will we this portion of the component dimensions.
56          * @param markerRadius  The radius for the marker positions (N/E/S/W), or NaN for no markers.  A value greater than one
57          *                                              will position the markers outside of the bordering circle.
58          * @param markerFont    The font used for the markers.
59          */
60         public CompassRose(double scaler, double markerRadius, Font markerFont) {
61                 this.scaler = scaler;
62                 this.markerRadius = markerRadius;
63                 this.markerFont = markerFont;
64         }
65         
66         
67
68         @Override
69         public void paintComponent(Graphics g) {
70                 
71                 Graphics2D g2 = (Graphics2D) g;
72                 
73                 int[] x = new int[3];
74                 int[] y = new int[3];
75                 Dimension dimension = this.getSize();
76                 
77                 int width = Math.min(dimension.width, dimension.height);
78                 int mid = width / 2;
79                 width = (int) (scaler * width);
80                 
81                 int mainLength = (int) (width * MAIN_LENGTH / 2);
82                 int mainWidth = (int) (width * MAIN_WIDTH / 2);
83                 
84
85                 g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
86                 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
87                 
88                 g2.setColor(MAIN_COLOR);
89                 
90                 // North
91                 x[0] = mid;
92                 y[0] = mid;
93                 x[1] = mid;
94                 y[1] = mid - mainLength;
95                 x[2] = mid - mainWidth;
96                 y[2] = mid - mainWidth;
97                 g2.fillPolygon(x, y, 3);
98                 
99                 x[2] = mid + mainWidth;
100                 g2.drawPolygon(x, y, 3);
101                 
102                 // East
103                 x[0] = mid;
104                 y[0] = mid;
105                 x[1] = mid + mainLength;
106                 y[1] = mid;
107                 x[2] = mid + mainWidth;
108                 y[2] = mid - mainWidth;
109                 g2.fillPolygon(x, y, 3);
110                 
111                 y[2] = mid + mainWidth;
112                 g2.drawPolygon(x, y, 3);
113                 
114                 // South
115                 x[0] = mid;
116                 y[0] = mid;
117                 x[1] = mid;
118                 y[1] = mid + mainLength;
119                 x[2] = mid + mainWidth;
120                 y[2] = mid + mainWidth;
121                 g2.fillPolygon(x, y, 3);
122                 
123                 x[2] = mid - mainWidth;
124                 g2.drawPolygon(x, y, 3);
125                 
126                 // West
127                 x[0] = mid;
128                 y[0] = mid;
129                 x[1] = mid - mainLength;
130                 y[1] = mid;
131                 x[2] = mid - mainWidth;
132                 y[2] = mid + mainWidth;
133                 g2.fillPolygon(x, y, 3);
134                 
135                 y[2] = mid - mainWidth;
136                 g2.drawPolygon(x, y, 3);
137                 
138
139                 // Border circle
140                 g2.setColor(CIRCLE_SHADE);
141                 g2.drawArc(mid - width / 2 + CIRCLE_BORDER, mid - width / 2 + CIRCLE_BORDER,
142                                         width - 2 * CIRCLE_BORDER, width - 2 * CIRCLE_BORDER, 45, 180);
143                 g2.setColor(CIRCLE_HIGHLIGHT);
144                 g2.drawArc(mid - width / 2 + CIRCLE_BORDER, mid - width / 2 + CIRCLE_BORDER,
145                                 width - 2 * CIRCLE_BORDER, width - 2 * CIRCLE_BORDER, 180 + 45, 180);
146                 
147
148                 // Draw direction markers
149                 if (!Double.isNaN(markerRadius) && markerFont != null) {
150                         
151                         int pos = (int) (width * markerRadius / 2);
152                         
153                         g2.setColor(MARKER_COLOR);
154                         drawMarker(g2, mid, mid - pos, trans.get("lbl.north"));
155                         drawMarker(g2, mid + pos, mid, trans.get("lbl.east"));
156                         drawMarker(g2, mid, mid + pos, trans.get("lbl.south"));
157                         drawMarker(g2, mid - pos, mid, trans.get("lbl.west"));
158                         
159                 }
160                 
161         }
162         
163         
164
165         private void drawMarker(Graphics2D g2, float x, float y, String str) {
166                 GlyphVector gv = markerFont.createGlyphVector(g2.getFontRenderContext(), str);
167                 Rectangle2D rect = gv.getVisualBounds();
168                 
169                 x -= rect.getWidth() / 2;
170                 y += rect.getHeight() / 2;
171                 
172                 g2.drawGlyphVector(gv, x, y);
173                 
174         }
175         
176         
177
178
179
180         public double getScaler() {
181                 return scaler;
182         }
183         
184         
185         public void setScaler(double scaler) {
186                 this.scaler = scaler;
187                 repaint();
188         }
189         
190         
191         public double getMarkerRadius() {
192                 return markerRadius;
193         }
194         
195         
196         public void setMarkerRadius(double markerRadius) {
197                 this.markerRadius = markerRadius;
198                 repaint();
199         }
200         
201         
202         public Font getMarkerFont() {
203                 return markerFont;
204         }
205         
206         
207         public void setMarkerFont(Font markerFont) {
208                 this.markerFont = markerFont;
209                 repaint();
210         }
211         
212         @Override
213         public Dimension getPreferredSize() {
214                 Dimension dim = super.getPreferredSize();
215                 int min = Math.min(dim.width, dim.height);
216                 dim.setSize(min, min);
217                 return dim;
218         }
219         
220
221 }