Changeset 336

Show
Ignore:
Timestamp:
08/10/07 23:13:15 (1 year ago)
Author:
tom
Message:

wellColor and things were broken, changed it to drawWell and drawGridArea instead

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/as3/lib/com/modestmaps/core/TileGrid.as

    r297 r336  
    3232        protected var _width:Number; 
    3333        protected var _height:Number; 
    34         protected var _draggable:Boolean;           
     34        protected var _draggable:Boolean;         
    3535     
    3636        // Row and column counts are kept up-to-date. 
     
    7878        protected var _mapProvider:IMapProvider; 
    7979     
    80         protected var _wellColor:uint = 0x000000
    81         protected var _gridAreaColor:uint = 0x000000
     80        protected var _drawWell:Boolean = true
     81        protected var _drawGridArea:Boolean = true
    8282     
    8383        public function init(width:Number, height:Number, draggable:Boolean, provider:IMapProvider, map:Map):void 
     
    106106       /** 
    107107        * Set initTileCoord and initTilePoint for use by initializeTiles(). 
    108            */ 
    109            public function setInitialTile(coord:Coordinate, point:Point):void 
    110            { 
    111                _initTileCoord = coord; 
    112                _initTilePoint = point; 
    113 //             Reactor.callNextFrame(initializeTiles); 
    114            } 
    115             
    116           /** 
    117            * Reset tile grid with a new initial tile, and expire old tiles in the background. 
    118            */ 
    119            public function resetTiles(coord:Coordinate, point:Point):void 
    120            { 
     108        */ 
     109        public function setInitialTile(coord:Coordinate, point:Point):void 
     110        { 
     111            _initTileCoord = coord; 
     112            _initTilePoint = point; 
     113//            Reactor.callNextFrame(initializeTiles); 
     114        } 
     115         
     116       /** 
     117        * Reset tile grid with a new initial tile, and expire old tiles in the background. 
     118        */ 
     119        public function resetTiles(coord:Coordinate, point:Point):void 
     120        { 
    121121                //trace('resetting tiles...'); 
    122                if (!_tiles) 
     122            if (!_tiles) 
    123123                { 
    124124                    //trace("no _tiles for resetTiles() yet"); 
    125                    setInitialTile(coord, point); 
    126                    return; 
    127                } 
    128             
     125                setInitialTile(coord, point); 
     126                return; 
     127            } 
     128         
    129129                //trace('REALLY resetting tiles...'); 
    130130 
     
    132132                    var initTile:Tile; 
    133133                    var condemnedTiles:/*Tile*/Array = activeTiles(); 
    134                  
     134         
    135135                    for (var i:int = 0; i < condemnedTiles.length; i++) 
    136136                    { 
    137137                        condemnedTiles[i].expire(); 
    138138                    } 
    139                  
     139         
    140140                    Reactor.callLater(condemnationDelay(), destroyTiles, condemnedTiles); 
    141141 
    142                     zoomLevel = coord.zoom;                             
     142                    zoomLevel = coord.zoom;                 
    143143                    initTile = createTile(this, coord, point.x, point.y); 
    144                                                                                   
     144                                                                           
    145145                    centerWell(true); 
    146                  
     146         
    147147                    _rows = 1; 
    148148                    _columns = 1; 
    149                  
     149         
    150150                    allocateTiles(); 
    151151                } 
     
    153153                    trace(e.getStackTrace()); 
    154154                } 
    155                 
    156            } 
    157             
    158           /** 
    159            * Create the first tiles, based on initTileCoord and initTilePoint. 
    160            */ 
    161            protected function initializeTiles():void 
    162            { 
    163                var initTile:Tile; 
    164                 
    165 //             trace('initializing...'); 
     155             
     156        } 
     157         
     158       /** 
     159        * Create the first tiles, based on initTileCoord and initTilePoint. 
     160        */ 
     161        protected function initializeTiles():void 
     162        { 
     163            var initTile:Tile; 
     164             
     165//            trace('initializing...'); 
    166166 
    167167                if (!_initTileCoord) { 
    168168                    trace("no _initTileCoord"); 
    169                     return;                     
    170                 }              
    171                                         
    172                // impose some limits 
    173                zoomLevel = _initTileCoord.zoom; 
    174                topLeftOutLimit = _mapProvider.outerLimits()[0]; 
    175                bottomRightInLimit = _mapProvider.outerLimits()[1]; 
    176                 
     169                    return;             
     170                }            
     171                          
     172            // impose some limits 
     173            zoomLevel = _initTileCoord.zoom; 
     174            topLeftOutLimit = _mapProvider.outerLimits()[0]; 
     175            bottomRightInLimit = _mapProvider.outerLimits()[1]; 
     176             
    177177                //trace('REALLY initializing, like _tiles and shit...'); 
    178                 
     178             
    179179                _tiles = []; 
    180                initTile = createTile(this, _initTileCoord, _initTilePoint.x, _initTilePoint.y); 
    181                                                                           
    182                centerWell(false); 
    183          
    184                _rows = 1; 
    185                _columns = 1; 
    186                 
    187                // buffer must not be negative! 
    188                _tileBuffer = Math.max(0, _tileBuffer); 
    189                 
    190                allocateTiles(); 
    191                 
    192                // let 'em know we're coming 
    193                markers.indexAtZoom(zoomLevel); 
    194                 
    195                updateMarkers(); 
    196            } 
    197             
    198            public function putMarker(id:String, coord:Coordinate, location:Location):Marker 
    199            { 
    200                var marker:Marker = new Marker(id, coord, location); 
    201                //trace('Marker '+id+': '+coord.toString()); 
    202                markers.put(marker); 
    203          
    204                updateMarkers(); 
    205                return marker; 
    206            } 
    207          
    208            public function removeMarker(id:String):void 
    209            { 
    210                var marker:Marker = markers.getMarker(id); 
    211                if (marker) 
    212                    markers.remove(marker); 
    213            } 
    214                  
    215           /** 
    216            * Create the well clip, assign event handlers. 
    217            */ 
    218            protected function buildWell():void 
    219            { 
    220                _well = new Sprite(); 
    221                _well.name = 'well'; 
    222                 
     180            initTile = createTile(this, _initTileCoord, _initTilePoint.x, _initTilePoint.y); 
     181                                                                       
     182            centerWell(false); 
     183     
     184            _rows = 1; 
     185            _columns = 1; 
     186             
     187            // buffer must not be negative! 
     188            _tileBuffer = Math.max(0, _tileBuffer); 
     189             
     190            allocateTiles(); 
     191             
     192            // let 'em know we're coming 
     193            markers.indexAtZoom(zoomLevel); 
     194             
     195            updateMarkers(); 
     196        } 
     197         
     198        public function putMarker(id:String, coord:Coordinate, location:Location):Marker 
     199        { 
     200            var marker:Marker = new Marker(id, coord, location); 
     201            //trace('Marker '+id+': '+coord.toString()); 
     202            markers.put(marker); 
     203     
     204            updateMarkers(); 
     205            return marker; 
     206        } 
     207     
     208        public function removeMarker(id:String):void 
     209        { 
     210            var marker:Marker = markers.getMarker(id); 
     211            if (marker) 
     212                markers.remove(marker); 
     213        } 
     214         
     215       /** 
     216        * Create the well clip, assign event handlers. 
     217        */ 
     218        protected function buildWell():void 
     219        { 
     220            _well = new Sprite(); 
     221            _well.name = 'well'; 
     222             
    223223                if (_draggable)  
    224224                { 
     
    227227                    _well.addEventListener(MouseEvent.MOUSE_UP, stopWellDrag); 
    228228                } 
    229                 
    230                addChild(_well);                 
    231                centerWell(false); 
    232            } 
    233             
    234           /** 
    235            * Create the mask clip. 
    236            */ 
    237            protected function buildMask():void 
    238            { 
    239                _mask = new Sprite(); 
    240                _mask.name = 'mask'; 
    241                // as3 masks need to be child, so add the mask to the grid not the well 
     229             
     230            addChild(_well);             
     231            centerWell(false); 
     232        } 
     233         
     234       /** 
     235        * Create the mask clip. 
     236        */ 
     237        protected function buildMask():void 
     238        { 
     239            _mask = new Sprite(); 
     240            _mask.name = 'mask'; 
     241            // as3 masks need to be child, so add the mask to the grid not the well 
    242242                // because well children are all tiles 
    243243                addChild(_mask); 
    244                this.mask = _mask; 
    245            } 
    246             
    247             
    248            public function getMapProvider():IMapProvider 
    249            { 
    250                return _mapProvider;  
    251            } 
    252          
    253            public function setMapProvider(mapProvider:IMapProvider):void 
    254            { 
    255                var previousGeometry:String = _mapProvider.geometry(); 
    256          
    257                _mapProvider = mapProvider;  
    258                topLeftOutLimit = _mapProvider.outerLimits()[0]; 
    259                bottomRightInLimit = _mapProvider.outerLimits()[1]; 
    260          
    261                if (_mapProvider.geometry() != previousGeometry) 
     244            this.mask = _mask; 
     245        } 
     246         
     247         
     248        public function getMapProvider():IMapProvider 
     249        { 
     250            return _mapProvider;  
     251        } 
     252     
     253        public function setMapProvider(mapProvider:IMapProvider):void 
     254        { 
     255            var previousGeometry:String = _mapProvider.geometry(); 
     256     
     257            _mapProvider = mapProvider;  
     258            topLeftOutLimit = _mapProvider.outerLimits()[0]; 
     259            bottomRightInLimit = _mapProvider.outerLimits()[1]; 
     260     
     261            if (_mapProvider.geometry() != previousGeometry) 
    262262                { 
    263                    markers.initializeIndex(); 
    264                    markers.indexAtZoom(zoomLevel); 
    265                    updateMarkers(); 
    266                } 
    267            } 
    268             
    269             
    270           /** 
    271            * Create a new tile, add it to _tiles array, and return it. 
    272            */ 
    273            protected function createTile(grid:TileGrid, coord:Coordinate, x:Number, y:Number):Tile 
    274            { 
    275                var tile:Tile = new Tile(grid, coord, x, y); 
    276                tile.name = 'tile' + _tiles.length; 
    277                _well.addChild(tile); 
    278                                 
    279                tile.redraw(); 
    280                _tiles.push(tile); 
    281                 
    282                return tile; 
    283            } 
    284          
    285           /** 
    286            * Remove an old tile from the _tiles array, then destroy it. 
    287            */ 
    288            protected function destroyTile(tile:Tile):void 
    289            { 
     263                markers.initializeIndex(); 
     264                markers.indexAtZoom(zoomLevel); 
     265                updateMarkers(); 
     266            } 
     267        } 
     268         
     269         
     270       /** 
     271        * Create a new tile, add it to _tiles array, and return it. 
     272        */ 
     273        protected function createTile(grid:TileGrid, coord:Coordinate, x:Number, y:Number):Tile 
     274        { 
     275            var tile:Tile = new Tile(grid, coord, x, y); 
     276            tile.name = 'tile' + _tiles.length; 
     277            _well.addChild(tile); 
     278                         
     279            tile.redraw(); 
     280            _tiles.push(tile); 
     281             
     282            return tile; 
     283        } 
     284     
     285       /** 
     286        * Remove an old tile from the _tiles array, then destroy it. 
     287        */ 
     288        protected function destroyTile(tile:Tile):void 
     289        { 
    290290                //trace('Destroying tile: '+tile.toString()); 
    291                _tiles.splice(tileIndex(tile), 1); 
    292                tile.cancelDraw(); 
    293                _well.removeChild(tile); 
    294            } 
    295             
    296           /* 
    297            * Slowly mete out destruction to a list of tiles. 
    298            */ 
    299            protected function destroyTiles(tiles:/*Tile*/Array):void 
    300            { 
    301                if (tiles.length) 
     291            _tiles.splice(tileIndex(tile), 1); 
     292            tile.cancelDraw(); 
     293            _well.removeChild(tile); 
     294        } 
     295         
     296       /* 
     297        * Slowly mete out destruction to a list of tiles. 
     298        */ 
     299        protected function destroyTiles(tiles:/*Tile*/Array):void 
     300        { 
     301            if (tiles.length) 
    302302                { 
    303                    destroyTile(Tile(tiles.shift())); 
    304                    Reactor.callLater(0, destroyTiles, tiles); 
    305                } 
    306            } 
    307          
    308           /* 
    309            * Reposition tiles and schedule a recursive call for the next frame. 
    310            */ 
    311            protected function onWellDrag(previousPosition:Point):void 
    312            { 
    313                if(positionTiles()) 
    314                    updateMarkers(); 
    315          
    316                if(previousPosition.x != _well.x || previousPosition.y != _well.y) 
    317                    _map.onPanned(new Point(_well.x - _startingWellPosition.x, _well.y - _startingWellPosition.y)); 
    318                 
    319                _wellDragTask = Reactor.callNextFrame(onWellDrag, new Point(_well.x, _well.y)); 
    320            } 
    321             
    322           /* 
    323            * Return the point position of a tile with the given coordinate in the 
    324            * context of the given movie clip. 
    325            * 
    326            * Respect infinite rows or columns, to bind movement on one (or no) axis. 
    327            */ 
    328            public function coordinatePoint(coord:Coordinate, context:Sprite, fearBigNumbers:Boolean=false):Point 
    329            { 
    330                // pick a reference tile, an arbitrary choice 
    331                // but known to exist regardless of grid size. 
    332                var tile:Tile = activeTiles()[0]; 
    333             
    334                // get the position of the reference tile. 
    335                var point:Point = new Point(tile.x, tile.y); 
    336                 
    337                // make sure coord is using the same zoom level 
    338                coord = coord.zoomTo(tile.coord.zoom); 
    339                 
    340                // store the infinite 
    341                var force:Point = new Point(0, 0); 
    342                 
    343                if(coord.column == Number.POSITIVE_INFINITY || coord.column == Number.NEGATIVE_INFINITY) { 
    344                    force.x = coord.column; 
    345                } else { 
    346                    point.x += TILE_WIDTH * (coord.column - tile.coord.column);          
    347                } 
    348                 
    349                if(coord.row == Number.POSITIVE_INFINITY || coord.row == Number.NEGATIVE_INFINITY) { 
    350                    force.y = coord.row; 
    351                } else { 
    352                    point.y += TILE_HEIGHT * (coord.row - tile.coord.row); 
    353                } 
    354                 
    355                if(fearBigNumbers) { 
    356                    if(point.x < -1e6) { 
    357                        force.x = Number.NEGATIVE_INFINITY; 
    358                    } 
    359                    if(point.x > 1e6) { 
    360                        force.x = Number.POSITIVE_INFINITY; 
    361                    } 
    362                    if(point.y < -1e6) { 
    363                        force.y = Number.NEGATIVE_INFINITY; 
    364                    } 
    365                    if(point.y > 1e6) { 
    366                        force.y = Number.POSITIVE_INFINITY; 
    367                    } 
    368                } 
    369                 
    370                point = _well.localToGlobal(point); 
    371                point = context.globalToLocal(point); 
    372          
    373                if(force.x) { 
    374                    point.x = force.x; 
    375                } 
    376                if(force.y) { 
    377                    point.y = force.y; 
    378                } 
    379                return point; 
    380            } 
    381             
    382            public function pointCoordinate(point:Point, context:Sprite=null):Coordinate 
    383            { 
    384                var tile:Tile; 
    385                var tileCoord:Coordinate; 
    386                var pointCoord:Coordinate; 
    387                 
    388                if (null == context) context = this; 
    389                // point is assumed to be in tile grid local coordinates 
    390                point = context.localToGlobal(point); 
    391                point = _well.globalToLocal(point); 
    392          
    393                // an arbitrary reference tile, zoomed to the maximum 
    394                tile = activeTiles()[0]; 
    395                tileCoord = tile.coord.zoomTo(Coordinate.MAX_ZOOM); 
    396                 
    397                // distance in tile widths from reference tile to point 
    398                var xTiles:Number = (point.x - tile.x) / TILE_WIDTH; 
    399                var yTiles:Number = (point.y - tile.y) / TILE_HEIGHT; 
    400          
    401                // distance in rows & columns at maximum zoom 
    402                var xDistance:Number = xTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); 
    403                var yDistance:Number = yTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); 
    404                 
    405                // new point coordinate reflecting that distance 
    406                pointCoord = new Coordinate(Math.round(tileCoord.row + yDistance), 
    407                                            Math.round(tileCoord.column + xDistance), 
    408                                            tileCoord.zoom); 
    409                 
    410                return pointCoord.zoomTo(tile.coord.zoom); 
    411            } 
    412             
    413            public function topLeftCoordinate():Coordinate 
    414            { 
    415                var point:Point = new Point(0, 0); 
    416                return pointCoordinate(point); 
    417            } 
    418             
    419            public function centerCoordinate():Coordinate 
    420            { 
    421                var point:Point = new Point(_width/2, _height/2); 
    422                return pointCoordinate(point); 
    423            } 
    424             
    425            public function bottomRightCoordinate():Coordinate 
    426            { 
    427                var point:Point = new Point(_width, _height); 
    428                return pointCoordinate(point); 
    429            } 
    430             
    431           /* 
    432            * Start dragging the well with the mouse. 
    433            * Calls onWellDrag(). 
    434            */ 
    435            protected function getWellBounds(fearBigNumbers:Boolean):Bounds 
    436            { 
    437                var min:Point, max:Point; 
    438          
    439                // "min" = furthest well position left & up, 
    440                // use the location of the bottom-right limit 
    441                min = coordinatePoint(bottomRightInLimit, this, fearBigNumbers); 
    442                min.x = _well.x - min.x + _width; 
    443                min.y = _well.y - min.y + _height; 
    444                 
    445                // "max" = furthest well position right & down, 
    446                // use the location of the top-left limit 
    447                max = coordinatePoint(topLeftOutLimit, this, fearBigNumbers); 
    448                max.x = _well.x - max.x; 
    449                max.y = _well.y - max.y; 
    450                 
     303                destroyTile(Tile(tiles.shift())); 
     304                Reactor.callLater(0, destroyTiles, tiles); 
     305            } 
     306        } 
     307     
     308       /* 
     309        * Reposition tiles and schedule a recursive call for the next frame. 
     310        */ 
     311        protected function onWellDrag(previousPosition:Point):void 
     312        { 
     313            if(positionTiles()) 
     314                updateMarkers(); 
     315     
     316            if(previousPosition.x != _well.x || previousPosition.y != _well.y) 
     317                _map.onPanned(new Point(_well.x - _startingWellPosition.x, _well.y - _startingWellPosition.y)); 
     318             
     319            _wellDragTask = Reactor.callNextFrame(onWellDrag, new Point(_well.x, _well.y)); 
     320        } 
     321         
     322       /* 
     323        * Return the point position of a tile with the given coordinate in the 
     324        * context of the given movie clip. 
     325        * 
     326        * Respect infinite rows or columns, to bind movement on one (or no) axis. 
     327        */ 
     328        public function coordinatePoint(coord:Coordinate, context:Sprite, fearBigNumbers:Boolean=false):Point 
     329        { 
     330            // pick a reference tile, an arbitrary choice 
     331            // but known to exist regardless of grid size. 
     332            var tile:Tile = activeTiles()[0]; 
     333         
     334            // get the position of the reference tile. 
     335            var point:Point = new Point(tile.x, tile.y); 
     336             
     337            // make sure coord is using the same zoom level 
     338            coord = coord.zoomTo(tile.coord.zoom); 
     339             
     340            // store the infinite 
     341            var force:Point = new Point(0, 0); 
     342             
     343            if(coord.column == Number.POSITIVE_INFINITY || coord.column == Number.NEGATIVE_INFINITY) { 
     344                force.x = coord.column; 
     345            } else { 
     346                point.x += TILE_WIDTH * (coord.column - tile.coord.column);             
     347            } 
     348             
     349            if(coord.row == Number.POSITIVE_INFINITY || coord.row == Number.NEGATIVE_INFINITY) { 
     350                force.y = coord.row; 
     351            } else { 
     352                point.y += TILE_HEIGHT * (coord.row - tile.coord.row); 
     353            } 
     354             
     355            if(fearBigNumbers) { 
     356                if(point.x < -1e6) { 
     357                    force.x = Number.NEGATIVE_INFINITY; 
     358                } 
     359                if(point.x > 1e6) { 
     360                    force.x = Number.POSITIVE_INFINITY; 
     361                } 
     362                if(point.y < -1e6) { 
     363                    force.y = Number.NEGATIVE_INFINITY; 
     364                } 
     365                if(point.y > 1e6) { 
     366                    force.y = Number.POSITIVE_INFINITY; 
     367                } 
     368            } 
     369             
     370            point = _well.localToGlobal(point); 
     371            point = context.globalToLocal(point); 
     372     
     373            if(force.x) { 
     374                point.x = force.x; 
     375            } 
     376            if(force.y) { 
     377                point.y = force.y; 
     378            } 
     379            return point; 
     380        } 
     381         
     382        public function pointCoordinate(point:Point, context:Sprite=null):Coordinate 
     383        { 
     384            var tile:Tile; 
     385            var tileCoord:Coordinate; 
     386            var pointCoord:Coordinate; 
     387             
     388            if (null == context) context = this; 
     389            // point is assumed to be in tile grid local coordinates 
     390            point = context.localToGlobal(point); 
     391            point = _well.globalToLocal(point); 
     392     
     393            // an arbitrary reference tile, zoomed to the maximum 
     394            tile = activeTiles()[0]; 
     395            tileCoord = tile.coord.zoomTo(Coordinate.MAX_ZOOM); 
     396             
     397            // distance in tile widths from reference tile to point 
     398            var xTiles:Number = (point.x - tile.x) / TILE_WIDTH; 
     399            var yTiles:Number = (point.y - tile.y) / TILE_HEIGHT; 
     400     
     401            // distance in rows & columns at maximum zoom 
     402            var xDistance:Number = xTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); 
     403            var yDistance:Number = yTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); 
     404             
     405            // new point coordinate reflecting that distance 
     406            pointCoord = new Coordinate(Math.round(tileCoord.row + yDistance), 
     407                                        Math.round(tileCoord.column + xDistance), 
     408                                        tileCoord.zoom); 
     409             
     410            return pointCoord.zoomTo(tile.coord.zoom); 
     411        } 
     412         
     413        public function topLeftCoordinate():Coordinate 
     414        { 
     415            var point:Point = new Point(0, 0); 
     416            return pointCoordinate(point); 
     417        } 
     418         
     419        public function centerCoordinate():Coordinate 
     420        { 
     421            var point:Point = new Point(_width/2, _height/2); 
     422            return pointCoordinate(point); 
     423        } 
     424         
     425        public function bottomRightCoordinate():Coordinate 
     426        { 
     427            var point:Point = new Point(_width, _height); 
     428            return pointCoordinate(point); 
     429        } 
     430         
     431       /* 
     432        * Start dragging the well with the mouse. 
     433        * Calls onWellDrag(). 
     434        */ 
     435        protected function getWellBounds(fearBigNumbers:Boolean):Bounds 
     436        { 
     437            var min:Point, max:Point; 
     438     
     439            // "min" = furthest well position left & up, 
     440            // use the location of the bottom-right limit 
     441            min = coordinatePoint(bottomRightInLimit, this, fearBigNumbers); 
     442            min.x = _well.x - min.x + _width; 
     443            min.y = _well.y - min.y + _height; 
     444             
     445            // "max" = furthest well position right & down, 
     446            // use the location of the top-left limit 
     447            max = coordinatePoint(topLeftOutLimit, this, fearBigNumbers); 
     448            max.x = _well.x - max.x; 
     449            max.y = _well.y - max.y; 
     450             
    451451                //trace('min/max for drag: '+min+', '+max+' ('+topLeftOutLimit+', '+bottomRightInLimit+')'); 
    452                 
    453                // weird negative edge conditions, limit all movement on an axis 
    454                if(min.x > max.x) 
    455                    min.x = max.x = _well.x; 
    456          
    457                if(min.y > max.y) 
    458                    min.y = max.y = _well.y; 
    459                     
    460                return new Bounds(min, max); 
    461            } 
    462             
    463           /* 
    464            * Start dragging the well with the mouse. 
    465            * Calls onWellDrag(). 
    466            */ 
    467            public function startWellDrag(event:MouseEvent):void 
    468            { 
    469                 stage.addEventListener(MouseEvent.MOUSE_UP, stopWellDrag);              
    470                stage.addEventListener(MouseEvent.MOUSE_OUT, stopWellDrag); 
    471  
    472                var bounds:Bounds = getWellBounds(true); 
    473                 
    474                // startDrag seems to hate the infinities, 
    475                // so we'll fudge it with some implausibly large numbers. 
    476                 
    477                var xMin:Number = (bounds.min.x == Number.POSITIVE_INFINITY) 
    478                                    ? 100000 
    479                                    : ((bounds.min.x == Number.NEGATIVE_INFINITY) 
    480                                        ? -100000 
    481                                        : bounds.min.x); 
    482                 
    483                var yMin:Number = (bounds.min.y == Number.POSITIVE_INFINITY) 
    484                                    ? 100000 
    485                                    : ((bounds.min.y == Number.NEGATIVE_INFINITY) 
    486                                        ? -100000 
    487                                        : bounds.min.y); 
    488                 
    489                var xMax:Number = (bounds.max.x == Number.POSITIVE_INFINITY) 
    490                                    ? 100000 
    491                                    : ((bounds.max.x == Number.NEGATIVE_INFINITY) 
    492                                        ? -100000 
    493                                        : bounds.max.x); 
    494                 
    495                var yMax:Number = (bounds.max.y == Number.POSITIVE_INFINITY) 
    496                                    ? 100000 
    497                                    : ((bounds.max.y == Number.NEGATIVE_INFINITY) 
    498                                        ? -100000 
    499                                        : bounds.max.y); 
    500                                         
     452             
     453            // weird negative edge conditions, limit all movement on an axis 
     454            if(min.x > max.x) 
     455                min.x = max.x = _well.x; 
     456     
     457            if(min.y > max.y) 
     458                min.y = max.y = _well.y; 
     459                 
     460            return new Bounds(min, max); 
     461        } 
     462         
     463       /* 
     464        * Start dragging the well with the mouse. 
     465        * Calls onWellDrag(). 
     466        */ 
     467        public function startWellDrag(event:MouseEvent):void 
     468        { 
     469                stage.addEventListener(MouseEvent.MOUSE_UP, stopWellDrag);             
     470            stage.addEventListener(MouseEvent.MOUSE_OUT, stopWellDrag); 
     471 
     472            var bounds:Bounds = getWellBounds(true); 
     473             
     474            // startDrag seems to hate the infinities, 
     475            // so we'll fudge it with some implausibly large numbers. 
     476             
     477            var xMin:Number = (bounds.min.x == Number.POSITIVE_INFINITY) 
     478                                ? 100000 
     479                                : ((bounds.min.x == Number.NEGATIVE_INFINITY) 
     480                                    ? -100000 
     481                                    : bounds.min.x); 
     482             
     483            var yMin:Number = (bounds.min.y == Number.POSITIVE_INFINITY) 
     484                                ? 100000 
     485                                : ((bounds.min.y == Number.NEGATIVE_INFINITY) 
     486                                    ? -100000 
     487                                    : bounds.min.y); 
     488             
     489            var xMax:Number = (bounds.max.x == Number.POSITIVE_INFINITY) 
     490                                ? 100000 
     491                                : ((bounds.max.x == Number.NEGATIVE_INFINITY) 
     492                                    ? -100000 
     493                                    : bounds.max.x); 
     494             
     495            var yMax:Number = (bounds.max.y == Number.POSITIVE_INFINITY) 
     496                                ? 100000 
     497                                : ((bounds.max.y == Number.NEGATIVE_INFINITY) 
     498                                    ? -100000 
     499                                    : bounds.max.y); 
     500                                     
    501501                //trace('Drag bounds would be: '+xMin+', '+yMin+', '+xMax+', '+yMax); 
    502502                                 
    503503                _startingWellPosition = new Point(_well.x, _well.y); 
    504504                //trace('Starting well position: '+_startingWellPosition.toString()); 
    505                 
    506                _map.onStartPan(); 
    507                var rect:Rectangle = new Rectangle(xMin, yMin, xMax - xMin, yMax - yMin); 
    508                _well.startDrag(false, rect); 
    509                onWellDrag(_startingWellPosition.clone()); 
    510            } 
    511             
    512           /* 
    513            * Stop dragging the well with the mouse. 
    514            * Halts _wellDragTask. 
    515            */ 
    516            public function stopWellDrag(event:MouseEvent):void 
    517            { 
    518                stage.removeEventListener(MouseEvent.MOUSE_OUT, stopWellDrag); 
    519  
    520                _map.onStopPan(); 
    521                if (_wellDragTask) { 
     505             
     506            _map.onStartPan(); 
     507            var rect:Rectangle = new Rectangle(xMin, yMin, xMax - xMin, yMax - yMin); 
     508            _well.startDrag(false, rect); 
     509            onWellDrag(_startingWellPosition.clone()); 
     510        } 
     511         
     512       /* 
     513        * Stop dragging the well with the mouse. 
     514        * Halts _wellDragTask. 
     515        */ 
     516        public function stopWellDrag(event:MouseEvent):void 
     517        { 
     518            stage.removeEventListener(MouseEvent.MOUSE_OUT, stopWellDrag); 
     519 
     520            _map.onStopPan(); 
     521            if (_wellDragTask) { 
    522522                    _wellDragTask.call();   // issue final onPan, notify markers, etc. 
    523523                    _wellDragTask.cancel(); // but cancel the follow-on call 
    524524                } 
    525                _well.stopDrag(); 
    526          
    527                if(positionTiles()) 
    528                    updateMarkers(); 
    529          
    530                centerWell(true); 
    531            } 
    532             
    533            public function zoomBy(amount:Number, redraw:Boolean):void 
    534            { 
    535                if(!_tiles) 
    536                    return; 
    537                 
    538                var roundScale:Number = Math.round(_well.scaleX * 10000.0) / 10000.0; 
    539                if(amount > 0 && zoomLevel >= bottomRightInLimit.zoom && roundScale) 
    540                    return; 
    541             
    542                if(amount < 0 && zoomLevel <= topLeftOutLimit.zoom && roundScale) 
    543                    return; 
    544             
    545                _well.scaleX *= Math.pow(2, amount); 
    546                _well.scaleY *= Math.pow(2, amount); 
    547                 
    548                boundWell(); 
    549                 
    550                if(redraw) { 
    551                    normalizeWell(); 
    552                    allocateTiles(); 
     525            _well.stopDrag(); 
     526     
     527            if(positionTiles()) 
     528                updateMarkers(); 
     529     
     530            centerWell(true); 
     531        } 
     532         
     533        public function zoomBy(amount:Number, redraw:Boolean):void 
     534        { 
     535            if(!_tiles) 
     536                return; 
     537             
     538            var roundScale:Number = Math.round(_well.scaleX * 10000.0) / 10000.0; 
     539            if(amount > 0 && zoomLevel >= bottomRightInLimit.zoom && roundScale) 
     540                return; 
     541         
     542            if(amount < 0 && zoomLevel <= topLeftOutLimit.zoom && roundScale) 
     543                return; 
     544         
     545            _well.scaleX *= Math.pow(2, amount); 
     546            _well.scaleY *= Math.pow(2, amount); 
     547  &nb