altoslib: Add getBytes/putBytes interface to AltosPreferencesBackend
[fw/altos] / altosuilib / AltosUIMapLine.java
1 /*
2  * Copyright © 2014 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package org.altusmetrum.altosuilib_3;
19
20 import java.awt.*;
21 import java.awt.event.*;
22 import javax.swing.*;
23 import java.io.*;
24 import java.lang.Math;
25 import java.awt.geom.*;
26 import java.util.*;
27 import java.util.concurrent.*;
28 import org.altusmetrum.altoslib_5.*;
29
30 public class AltosUIMapLine {
31         AltosUILatLon   start, end;
32
33         private Font    font = null;
34         static public int stroke_width = 6;
35
36         public void set_font(Font font) {
37                 this.font = font;
38         }
39
40         private AltosUILatLon lat_lon(MouseEvent e, AltosUIMapTransform t) {
41                 return t.screen_lat_lon(e.getPoint());
42         }
43
44         public void dragged(MouseEvent e, AltosUIMapTransform t) {
45                 end = lat_lon(e, t);
46         }
47
48         public void pressed(MouseEvent e, AltosUIMapTransform t) {
49                 start = lat_lon(e, t);
50                 end = null;
51         }
52
53         private String line_dist() {
54                 String  format;
55                 AltosGreatCircle        g = new AltosGreatCircle(start.lat, start.lon,
56                                                                  end.lat, end.lon);
57                 double  distance = g.distance;
58
59                 if (AltosConvert.imperial_units) {
60                         distance = AltosConvert.meters_to_feet(distance);
61                         if (distance < 10000) {
62                                 format = "%4.0fft";
63                         } else {
64                                 distance /= 5280;
65                                 if (distance < 10)
66                                         format = "%5.3fmi";
67                                 else if (distance < 100)
68                                         format = "%5.2fmi";
69                                 else if (distance < 1000)
70                                         format = "%5.1fmi";
71                                 else
72                                         format = "%5.0fmi";
73                         }
74                 } else {
75                         if (distance < 10000) {
76                                 format = "%4.0fm";
77                         } else {
78                                 distance /= 1000;
79                                 if (distance < 100)
80                                         format = "%5.2fkm";
81                                 else if (distance < 1000)
82                                         format = "%5.1fkm";
83                                 else
84                                         format = "%5.0fkm";
85                         }
86                 }
87                 return String.format(format, distance);
88         }
89
90         public void paint(Graphics2D g, AltosUIMapTransform t) {
91
92                 if (start == null || end == null)
93                         return;
94
95                 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
96
97                 Line2D.Double line = new Line2D.Double(t.screen(start),
98                                                        t.screen(end));
99
100                 g.setColor(Color.WHITE);
101                 g.setStroke(new BasicStroke(stroke_width+4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
102                 g.draw(line);
103
104                 g.setColor(Color.BLUE);
105                 g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
106                 g.draw(line);
107
108                 String  message = line_dist();
109                 Rectangle2D     bounds;
110                 bounds = font.getStringBounds(message, g.getFontRenderContext());
111
112                 float x = (float) line.x1;
113                 float y = (float) line.y1 + (float) bounds.getHeight() / 2.0f;
114
115                 if (line.x1 < line.x2) {
116                         x -= (float) bounds.getWidth() + 2.0f;
117                 } else {
118                         x += 2.0f;
119                 }
120
121                 g.setFont(font);
122                 g.setColor(Color.WHITE);
123                 for (int dy = -2; dy <= 2; dy += 2)
124                         for (int dx = -2; dx <= 2; dx += 2)
125                                 g.drawString(message, x + dx, y + dy);
126                 g.setColor(Color.BLUE);
127                 g.drawString(message, x, y);
128         }
129 }