460a3a25d9b399d47ee590cb419fcaeee55a5430
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / AltosMapView.java
1 /*
2  * Copyright © 2015 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.AltosDroid;
19
20 import java.util.*;
21 import java.io.*;
22
23 import org.altusmetrum.altoslib_7.*;
24
25 import android.app.Activity;
26 import android.graphics.*;
27 import android.os.Bundle;
28 import android.support.v4.app.Fragment;
29 import android.support.v4.app.FragmentTransaction;
30 import android.view.*;
31 import android.widget.*;
32 import android.location.Location;
33 import android.content.*;
34 import android.util.*;
35
36 public class AltosMapView extends View implements ScaleGestureDetector.OnScaleGestureListener {
37         ScaleGestureDetector    scale_detector;
38         boolean                 scaling;
39         TabMapOffline           tab;
40
41         class Line {
42                 AltosLatLon     a, b;
43
44                 void paint() {
45                         if (a != null && b != null) {
46                                 AltosPointDouble        a_screen = tab.map.transform.screen(a);
47                                 AltosPointDouble        b_screen = tab.map.transform.screen(b);
48                                 tab.paint.setColor(0xff8080ff);
49                                 tab.canvas.drawLine((float) a_screen.x, (float) a_screen.y,
50                                                     (float) b_screen.x, (float) b_screen.y,
51                                                     tab.paint);
52                         }
53                 }
54
55                 void set_a(AltosLatLon a) {
56                         this.a = a;
57                 }
58
59                 void set_b(AltosLatLon b) {
60                         this.b = b;
61                 }
62
63                 Line() {
64                 }
65         }
66
67         Line line = new Line();
68
69         private void draw_bitmap(AltosLatLon lat_lon, Bitmap bitmap, int off_x, int off_y) {
70                 if (lat_lon != null && tab.map != null && tab.map.transform != null) {
71                         AltosPointInt pt = new AltosPointInt(tab.map.transform.screen(lat_lon));
72
73                         tab.canvas.drawBitmap(bitmap, pt.x - off_x, pt.y - off_y, tab.paint);
74                 }
75         }
76
77         private void draw_positions() {
78                 line.set_a(tab.map.last_position);
79                 line.set_b(tab.here);
80                 line.paint();
81                 draw_bitmap(tab.pad, tab.pad_bitmap, tab.pad_off_x, tab.pad_off_y);
82                 for (Rocket rocket : tab.rockets.values())
83                         rocket.paint();
84                 draw_bitmap(tab.here, tab.here_bitmap, tab.here_off_x, tab.here_off_y);
85         }
86
87         @Override public void invalidate() {
88                 Rect r = new Rect();
89                 getDrawingRect(r);
90                 super.invalidate();
91         }
92
93         @Override public void invalidate(int l, int t, int r, int b) {
94                 Rect rect = new Rect();
95                 getDrawingRect(rect);
96                 super.invalidate();
97         }
98
99         @Override
100         protected void onDraw(Canvas view_canvas) {
101                 tab.canvas = view_canvas;
102                 tab.paint = new Paint(Paint.ANTI_ALIAS_FLAG);
103                 tab.paint.setStrokeWidth(tab.stroke_width);
104                 tab.paint.setStrokeCap(Paint.Cap.ROUND);
105                 tab.paint.setStrokeJoin(Paint.Join.ROUND);
106                 tab.paint.setTextSize(40);
107                 tab.map.paint();
108                 draw_positions();
109                 tab.canvas = null;
110         }
111
112         public boolean onScale(ScaleGestureDetector detector) {
113                 float   f = detector.getScaleFactor();
114                 if (f <= 0.8) {
115                         tab.map.set_zoom(tab.map.get_zoom() - 1);
116                         return true;
117                 }
118                 if (f >= 1.2) {
119                         tab.map.set_zoom(tab.map.get_zoom() + 1);
120                         return true;
121                 }
122                 return false;
123         }
124
125         public boolean onScaleBegin(ScaleGestureDetector detector) {
126                 return true;
127         }
128
129         public void onScaleEnd(ScaleGestureDetector detector) {
130         }
131
132         @Override
133         public boolean dispatchTouchEvent(MotionEvent event) {
134                 scale_detector.onTouchEvent(event);
135
136                 if (scale_detector.isInProgress()) {
137                         scaling = true;
138                 }
139
140                 if (scaling) {
141                         if (event.getAction() == MotionEvent.ACTION_UP) {
142                                 scaling = false;
143                         }
144                         return true;
145                 }
146
147                 if (event.getAction() == MotionEvent.ACTION_DOWN) {
148                         tab.map.touch_start((int) event.getX(), (int) event.getY(), true);
149                 } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
150                         tab.map.touch_continue((int) event.getX(), (int) event.getY(), true);
151                 }
152                 return true;
153         }
154
155         public void set_tab(TabMapOffline tab) {
156                 this.tab = tab;
157         }
158
159         public AltosMapView(Context context, AttributeSet attrs) {
160                 super(context, attrs);
161                 scale_detector = new ScaleGestureDetector(context, this);
162         }
163 }