Merge branch 'buttonbox' of git://git.gag.com/fw/altos into buttonbox
authorAnthony Towns <aj@erisian.com.au>
Mon, 22 Nov 2010 22:07:04 +0000 (08:07 +1000)
committerAnthony Towns <aj@erisian.com.au>
Mon, 22 Nov 2010 22:07:04 +0000 (08:07 +1000)
ao-tools/altosui/AltosSiteMap.java
ao-tools/altosui/AltosSiteMapTile.java
ao-tools/altosui/GrabNDrag.java

index 5e34dd49477115b12514e80be42184feb5939124..8097060508989859c30ba1ee23efdfc76f549bb0 100644 (file)
@@ -40,6 +40,8 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
 
        static final int px_size = 512;
 
+       static final int MAX_TILE_DELTA = 100;
+
        private static Point2D.Double translatePoint(Point2D.Double p,
                        Point2D.Double d)
        {
@@ -228,9 +230,9 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
                // if insufficient gps data, nothing to update
                if (state.gps == null)
                        return;
+               if (state.pad_lat == 0 && state.pad_lon == 0)
+                       return;
                if (!state.gps.locked) {
-                       if (state.pad_lat == 0 && state.pad_lon == 0)
-                               return;
                        if (state.gps.nsat < 4)
                                return;
                }
@@ -258,41 +260,105 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
                                if (0 <= ref.y && ref.y < px_size)
                                        in_any = true;
                }
-               if (!in_any) {
-                       final AltosSiteMapTile tile = new AltosSiteMapTile(px_size);
-                       final Point offset = tileOffset(pt);
-                       mapTiles.put(offset, tile);
 
+               Point offset = tileOffset(pt);
+               if (!in_any) {
                        Point2D.Double ref, lref;
                        ref = translatePoint(pt, tileCoordOffset(offset));
                        lref = translatePoint(last_pt, tileCoordOffset(offset));
-                       tile.show(state, crc_errors, lref, ref);
 
+                       AltosSiteMapTile tile = createTile(offset);
+                       tile.show(state, crc_errors, lref, ref);
                        initMap(tile, offset);
+                       finishTileLater(tile, offset);
+               }
 
-                       SwingUtilities.invokeLater( new Runnable() {
-                               public void run() {
-                                       addTileAt(tile, offset);
-                                       setViewportView(comp);
-                               }
-                       } );
+               scrollRocketToVisible(pt);
+
+               if (offset != tileOffset(last_pt)) {
+                       ensureTilesAround(offset);
                }
+
                last_pt = pt;
                last_state = state.state;
        }
 
+       private AltosSiteMapTile createTile(Point offset) {
+               AltosSiteMapTile tile = new AltosSiteMapTile(px_size);
+               mapTiles.put(offset, tile);
+               return tile;
+       }
+       private void finishTileLater(final AltosSiteMapTile tile,
+                                    final Point offset)
+       {
+               SwingUtilities.invokeLater( new Runnable() {
+                       public void run() {
+                               addTileAt(tile, offset);
+                       }
+               } );
+       }
+
+       private void ensureTilesAround(Point base_offset) {
+               for (int x = -1; x <= 1; x++) {
+                       for (int y = -1; y <= 1; y++) {
+                               Point offset = new Point(base_offset.x + x, base_offset.y + y);
+                               if (mapTiles.containsKey(offset))
+                                       continue;
+                               AltosSiteMapTile tile = createTile(offset);
+                               initMap(tile, offset);
+                               finishTileLater(tile, offset);
+                       }
+               }
+       }
+
+       private Point topleft = new Point(0,0);
+       private void scrollRocketToVisible(Point2D.Double pt) {
+               Rectangle r = comp.getVisibleRect();
+               Point2D.Double copt = translatePoint(pt, tileCoordOffset(topleft));
+               int dx = (int)copt.x - r.width/2 - r.x;
+               int dy = (int)copt.y - r.height/2 - r.y;
+               if (Math.abs(dx) > r.width/4 || Math.abs(dy) > r.height/4) {
+                       r.x += dx;
+                       r.y += dy;
+                       comp.scrollRectToVisible(r);
+               }
+       }
+
        private void addTileAt(AltosSiteMapTile tile, Point offset) {
+               if (Math.abs(offset.x) >= MAX_TILE_DELTA ||
+                               Math.abs(offset.y) >= MAX_TILE_DELTA)
+               {
+                       System.out.printf("Rocket too far away from pad (tile %d,%d)\n",
+                                         offset.x, offset.y);
+                       return;
+               }
+
+               boolean review = false;
+               Rectangle r = comp.getVisibleRect();
+               if (offset.x < topleft.x) {
+                       r.x += (topleft.x - offset.x) * px_size;
+                       topleft.x = offset.x;
+                       review = true;
+               }
+               if (offset.y < topleft.y) {
+                       r.y += (topleft.y - offset.y) * px_size;
+                       topleft.y = offset.y;
+                       review = true;
+               }
                GridBagConstraints c = new GridBagConstraints();
                c.anchor = GridBagConstraints.CENTER;
                c.fill = GridBagConstraints.BOTH;
-
                // put some space between the map tiles, debugging only
                // c.insets = new Insets(5, 5, 5, 5);
-               //
-               c.gridx = offset.x + 100;
-               c.gridy = offset.y + 100;
+
+               c.gridx = offset.x + MAX_TILE_DELTA;
+               c.gridy = offset.y + MAX_TILE_DELTA;
                layout.setConstraints(tile, c);
+
                comp.add(tile);
+               if (review) {
+                       comp.scrollRectToVisible(r);
+               }
        }
 
        private AltosSiteMap(boolean knowWhatYouAreDoing) {
@@ -301,27 +367,18 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
                }
        }
 
-       JComponent comp;
-       private GridBagLayout layout;
+       JComponent comp = new JComponent() { };
+       private GridBagLayout layout = new GridBagLayout();
 
        public AltosSiteMap() {
-               comp = new JComponent() {
-                       GrabNDrag scroller = new GrabNDrag(this);
-                       {
-                               addMouseMotionListener(scroller);
-                               addMouseListener(scroller);
-                               setAutoscrolls(true);
-                       }
-               };
+               GrabNDrag scroller = new GrabNDrag(comp);
 
-               layout = new GridBagLayout();
                comp.setLayout(layout);
 
                for (int x = -1; x <= 1; x++) {
                        for (int y = -1; y <= 1; y++) {
-                               AltosSiteMapTile t = new AltosSiteMapTile(px_size);
                                Point offset = new Point(x, y);
-                               mapTiles.put(offset, t);
+                               AltosSiteMapTile t = createTile(offset);
                                addTileAt(t, offset);
                        }
                }
index ea8c8bd9eafb302d272020751e3ae4fc76d29dff..8301f42b007e7fa9907991c3920543ce033e4946 100644 (file)
@@ -52,30 +52,16 @@ public class AltosSiteMapTile extends JLayeredPane {
                Color.BLACK   // landed
        };
 
-       boolean drawn_landed_circle = false;
-       boolean drawn_boost_circle = false;
-       public void show(AltosState state, int crc_errors,
-                        Point2D.Double last_pt, Point2D.Double pt)
+       private boolean drawn_landed_circle = false;
+       private boolean drawn_boost_circle = false;
+       public synchronized void show(AltosState state, int crc_errors,
+                                     Point2D.Double last_pt, Point2D.Double pt)
        {
                if (0 <= state.state && state.state < stateColors.length) {
                        g2d.setColor(stateColors[state.state]);
                }
                g2d.draw(new Line2D.Double(last_pt, pt));
 
-               int px_size = getWidth();
-               if (0 <= pt.x && pt.x < px_size) {
-                       if (0 <= pt.y && pt.y < px_size) {
-                               int dx = 500, dy = 250;
-                               if (state.state > 2) {
-                                       dx = Math.min(200, 20 + (int) Math.abs(last_pt.x - pt.x));
-                                       dy = Math.min(100, 10 + (int) Math.abs(last_pt.y - pt.y));
-                               }
-                               Rectangle r = new Rectangle((int)pt.x-dx, (int)pt.y-dy,
-                                                           dx*2, dy*2);
-                               scrollRectToVisible(r);
-                       }
-               }
-
                if (state.state == 3 && !drawn_boost_circle) {
                        drawn_boost_circle = true;
                        g2d.setColor(Color.RED);
index b44f3fe2551712611b22e631d47debf59a4f84b0..e6b87b5832e82bbdec9ce236c27d2c97822bbfeb 100644 (file)
@@ -29,23 +29,26 @@ import java.util.*;
 import java.text.*;
 
 class GrabNDrag extends MouseInputAdapter {
-    private JComponent scroll;
-    private Point startPt = new Point();
+       private JComponent scroll;
+       private Point startPt = new Point();
 
-    public GrabNDrag(JComponent parent) {
-        scroll = parent;
-    }
+       public GrabNDrag(JComponent scroll) {
+               this.scroll = scroll;
+               scroll.addMouseMotionListener(this);
+               scroll.addMouseListener(this);
+               scroll.setAutoscrolls(true);
+       }
 
-    public void mousePressed(MouseEvent e) {
-        startPt.setLocation(e.getPoint());
-    }
-    public void mouseDragged(MouseEvent e) {
-        int xd = e.getX() - startPt.x;
-        int yd = e.getY() - startPt.y;
+       public void mousePressed(MouseEvent e) {
+               startPt.setLocation(e.getPoint());
+       }
+       public void mouseDragged(MouseEvent e) {
+               int xd = e.getX() - startPt.x;
+               int yd = e.getY() - startPt.y;
 
-        Rectangle r = scroll.getVisibleRect();
-        r.x -= xd;
-        r.y -= yd;
-        scroll.scrollRectToVisible(r);
-    }
+               Rectangle r = scroll.getVisibleRect();
+               r.x -= xd;
+               r.y -= yd;
+               scroll.scrollRectToVisible(r);
+       }
 }