OpenLayers OpenLayers

Ticket #926: 2.5-google-style-bubbles.patch

File 2.5-google-style-bubbles.patch, 48.8 kB (added by rdewit, 1 year ago)

Google style popups for 2.5. No guarantees. Need img-corners.zip as well.

  • lib/OpenLayers/Popup/AnchoredBubble.js

    old new  
    1 /* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modified BSD license. 
    2  * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt  
     1/***********************************************************************************/ 
     2 
     3 
     4/* Copyright (c) 2006-2007 MetaCarta, Inc., published under the BSD license. 
     5 * See http://svn.openlayers.org/trunk/openlayers/release-license.txt  
    36 * for the full text of the license. */ 
    47 
    58 
    69/** 
    7  * @requires OpenLayers/Popup/Anchored.j
     10 * @clas
    811 *  
    9  * Class: OpenLayers.Popup.AnchoredBubble 
    10  *  
    11  * Inherits from:  
    12  *  - <OpenLayers.Popup.Anchored> 
     12 * @requires OpenLayers/Popup/Anchored.js 
    1313 */ 
    14 OpenLayers.Popup.AnchoredBubble =  
    15   OpenLayers.Class(OpenLayers.Popup.Anchored, { 
    1614 
    17     /** 
    18      * Property: rounded 
    19      * {Boolean} Has the popup been rounded yet? 
    20      */ 
    21     rounded: false,  
    22      
     15OpenLayers.Popup.AnchoredBubble = OpenLayers.Class( OpenLayers.Popup.Anchored, { 
     16 
    2317    /**  
    24      * Constructor: OpenLayers.Popup.AnchoredBubble 
    25      *  
    26      * Parameters: 
    27      * id - {String} 
    28      * lonlat - {<OpenLayers.LonLat>} 
    29      * size - {<OpenLayers.Size>} 
    30      * contentHTML - {String} 
    31      * anchor - {Object} Object to which we'll anchor the popup. Must expose  
    32      *     a 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>)  
    33      *     (Note that this is generally an <OpenLayers.Icon>). 
    34      * closeBox - {Boolean} 
    35      */ 
    36     initialize:function(id, lonlat, size, contentHTML, anchor, closeBox) { 
     18    * @constructor 
     19    *  
     20    * @param {String} id 
     21    * @param {OpenLayers.LonLat} lonlat 
     22    * @param {OpenLayers.Size} size 
     23    * @param {String} contentHTML 
     24    * @param {Object} anchor  Object which must expose a  
     25    *                         - 'size' (OpenLayers.Size) and  
     26    *                         - 'offset' (OpenLayers.Pixel)  
     27    *                         (this is generally an OpenLayers.Icon) 
     28    * @param {Boolean} closeBox 
     29    */ 
     30    initialize:function(id, lonlat, size, contentHTML, anchor, closeBox) 
     31    { 
    3732        OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments); 
    3833    }, 
    3934 
    4035    /**  
    41      * Method: draw 
    42      *  
    43      * Parameters: 
    44      * px - {<OpenLayers.Pixel>} 
    45      *  
    46      * Returns: 
    47      * {DOMElement} Reference to a div that contains the drawn popup. 
    48      */ 
     36    * @param {OpenLayers.Pixel} px 
     37    *  
     38    * @returns Reference to a div that contains the drawn popup 
     39    * @type DOMElement 
     40    */ 
    4941    draw: function(px) { 
    5042         
    5143        OpenLayers.Popup.Anchored.prototype.draw.apply(this, arguments); 
    5244 
    5345        this.setContentHTML(); 
    54          
    55         //set the popup color and opacity            
    56         this.setBackgroundColor();  
    57         this.setOpacity(); 
    5846 
    5947        return this.div; 
    6048    }, 
    6149 
    6250    /** 
    63      * Method: moveTo 
    64      * The popup may have been moved to a new relative location, in which case 
    65      *     we will want to re-do the rico corners. 
    66      *  
    67      * Parameters: 
    68      * px - {<OpenLayers.Pixel>} 
    69      */ 
    70     moveTo: function(px) { 
    71         OpenLayers.Popup.Anchored.prototype.moveTo.apply(this, arguments); 
    72         this.setRicoCorners(!this.rounded); 
    73         this.rounded = true; 
    74     }, 
    75  
    76     /** 
    77      * APIMethod: setSize 
    78      *  
    79      * Parameters: 
    80      * size - {<OpenLayers.Size>} 
    81      */ 
    82     setSize:function(size) {  
     51    * @param {OpenLayers.Size} size 
     52    */ 
     53    setSize:function(size) 
     54    {  
    8355        OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments); 
    84          
    85         if (this.contentDiv != null) { 
    86  
    87             var contentSize = this.size.clone(); 
    88             contentSize.h -= (2 * OpenLayers.Popup.AnchoredBubble.CORNER_SIZE); 
    89             contentSize.h -= (2 * this.padding); 
    90      
    91             this.contentDiv.style.height = contentSize.h + "px"; 
    92             this.contentDiv.style.width  = contentSize.w + "px"; 
    93              
    94             if (this.map) { 
    95                 //size has changed - must redo corners         
    96                 this.setRicoCorners(!this.rounded); 
    97                 this.rounded = true; 
    98             }     
    99         } 
    10056    },   
    101  
    102     /** 
    103      * APIMethod: setBackgroundColor 
    104      *  
    105      * Parameters: 
    106      * color - {String} 
    107      */ 
    108     setBackgroundColor:function(color) {  
    109         if (color != undefined) { 
    110             this.backgroundColor = color;  
    111         } 
    112          
    113         if (this.div != null) { 
    114             if (this.contentDiv != null) { 
    115                 this.div.style.background = "transparent"; 
    116                 OpenLayers.Rico.Corner.changeColor(this.contentDiv,  
    117                                                    this.backgroundColor); 
    118             } 
    119         } 
    120     },   
    12157     
    12258    /** 
    123      * APIMethod: setOpacity 
    124      *  
    125      * Parameters:  
    126      * opacity - {float} 
     59     * @param {float} opacity 
    12760     */ 
    128     setOpacity:function(opacity) {  
    129         if (opacity != undefined) { 
     61    setOpacity:function(opacity) 
     62    {  
     63        if (opacity != undefined) 
     64        { 
    13065            this.opacity = opacity;  
    13166        } 
    13267         
    133         if (this.div != null) { 
    134             if (this.contentDiv != null) { 
    135                 OpenLayers.Rico.Corner.changeOpacity(this.contentDiv,  
    136                                                      this.opacity); 
     68        if (this.div != null) 
     69        { 
     70            if (this.contentDiv != null) 
     71            { 
     72                OpenLayers.Rico.Corner.changeOpacity(this.contentDiv, this.opacity); 
    13773            } 
    13874        } 
    13975    },   
    140   
    141     /**  
    142      * Method: setBorder 
    143      * Always sets border to 0. Bubble Popups can not have a border. 
    144      *  
    145      * Parameters: 
    146      * border - {Integer} 
    147      */ 
    148     setBorder:function(border) {  
    149         this.border = 0; 
    150     },       
    151   
    152     /**  
    153      * Method: setRicoCorners 
    154      * Update RICO corners according to the popup's current relative postion. 
    155      *   
    156      * Parameters: 
    157      * firstTime - {Boolean} This the first time the corners are being rounded. 
    158      */ 
    159     setRicoCorners:function(firstTime) { 
    160      
    161         var corners = this.getCornersToRound(this.relativePosition); 
    162         var options = {corners: corners, 
    163                          color: this.backgroundColor, 
    164                        bgColor: "transparent", 
    165                          blend: false}; 
    16676 
    167         if (firstTime) { 
    168             OpenLayers.Rico.Corner.round(this.div, options); 
    169         } else { 
    170             OpenLayers.Rico.Corner.reRound(this.groupDiv, options); 
    171             //set the popup color and opacity 
    172             this.setBackgroundColor();  
    173             this.setOpacity(); 
    174         } 
    175     }, 
    176  
    177     /**  
    178      * Method: getCornersToRound 
    179      *   
    180      * Returns: 
    181      * {String} The proper corners string ("tr tl bl br") for rico to round. 
    182      */ 
    183     getCornersToRound:function() { 
    184  
    185         var corners = ['tl', 'tr', 'bl', 'br']; 
    186  
    187         //we want to round all the corners _except_ the opposite one.  
    188         var corner = OpenLayers.Bounds.oppositeQuadrant(this.relativePosition); 
    189         OpenLayers.Util.removeItem(corners, corner); 
    190  
    191         return corners.join(" "); 
    192     }, 
    193  
    19477    CLASS_NAME: "OpenLayers.Popup.AnchoredBubble" 
    19578}); 
    19679 
    197 /** 
    198  * Constant: CORNER_SIZE 
    199  * {Integer} 5. Border space for the RICO corners. 
    200  */ 
    201 OpenLayers.Popup.AnchoredBubble.CORNER_SIZE = 5; 
    20280 
     81 
  • lib/OpenLayers/Popup/Anchored.js

    old new  
    1 /* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modified BSD license. 
    2  * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt  
     1/**********************************************************************************************/ 
     2 
     3/* Copyright (c) 2006-2007 MetaCarta, Inc., published under the BSD license. 
     4 * See http://svn.openlayers.org/trunk/openlayers/release-license.txt  
    35 * for the full text of the license. */ 
    46 
    57 
    68/** 
     9 * @class 
     10 *  
    711 * @requires OpenLayers/Popup.js 
    8  *  
    9  * Class: OpenLayers.Popup.Anchored 
    10  *  
    11  * Inherits from: 
    12  *  - <OpenLayers.Popup> 
    1312 */ 
    14 OpenLayers.Popup.Anchored =  
    15   OpenLayers.Class(OpenLayers.Popup, { 
     13OpenLayers.Popup.Anchored = OpenLayers.Class( OpenLayers.Popup, { 
    1614 
    17     /**  
    18      * Parameter: relativePosition 
    19      * {String} Relative position of the popup ("lr", "ll", "tr", or "tl"). 
    20      */ 
    21     relativePosition: null, 
     15    /** "lr", "ll", "tr", "tl" - relative position of the popup. 
     16     * @type String */ 
     17    relativePosition: "tl", 
    2218 
    23     /** 
    24      * Parameter: anchor 
    25      * {Object} Object to which we'll anchor the popup. Must expose a  
    26      *     'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>). 
    27      */ 
     19    /** Object which must have expose a 'size' (OpenLayers.Size) and  
     20     *                                 'offset' (OpenLayers.Pixel)  
     21     * @type Object */ 
    2822    anchor: null, 
     23     
     24    /** number of X pixels required to pan the map for the popup to be visible 
     25     * @type Unsigned Integer */ 
     26    differenceX : 0, 
     27     
     28    /** number of Y pixels required to pan the map for the popup to be visible 
     29     * @type Unsigned Integer */ 
     30    differenceY : 0, 
    2931 
    3032    /**  
    31     * Constructor: OpenLayers.Popup.Anchored 
     33    * @constructor 
    3234    *  
    33     * Parameters: 
    34     * id - {String} 
    35     * lonlat - {<OpenLayers.LonLat>} 
    36     * size - {<OpenLayers.Size>} 
    37     * contentHTML - {String} 
    38     * anchor - {Object} Object which must expose a 'size' <OpenLayers.Size>  
    39     *     and 'offset' <OpenLayers.Pixel> (generally an <OpenLayers.Icon>). 
    40     * closeBox - {Boolean} 
     35    * @param {String} id 
     36    * @param {OpenLayers.LonLat} lonlat 
     37    * @param {OpenLayers.Size} size 
     38    * @param {String} contentHTML 
     39    * @param {Object} anchor  Object which must expose a  
     40    *                         - 'size' (OpenLayers.Size) and  
     41    *                         - 'offset' (OpenLayers.Pixel)  
     42    *                         (this is generally an OpenLayers.Icon) 
     43    * @param {Boolean} closeBox 
    4144    */ 
    42     initialize:function(id, lonlat, size, contentHTML, anchor, closeBox) { 
     45    initialize:function(id, lonlat, size, contentHTML, anchor, closeBox) 
     46    { 
    4347        var newArguments = new Array(id, lonlat, size, contentHTML, closeBox); 
    4448        OpenLayers.Popup.prototype.initialize.apply(this, newArguments); 
    4549 
    46         this.anchor = (anchor != null) ? anchor  
    47                                        : { size: new OpenLayers.Size(0,0), 
    48                                            offset: new OpenLayers.Pixel(0,0)}
     50        this.anchor = (anchor != null) ? anchor : { size: new OpenLayers.Size(0,0), offset: new OpenLayers.Pixel(0,0)}; 
     51         
     52        this.registerEvents()
    4953    }, 
    5054 
    5155    /**  
    52     * Method: draw 
    53     *  
    54     * Parameters: 
    55     * px - {<OpenLayers.Pixel>} 
    56     *  
    57     * Returns:  
    58     * {DOMElement} Reference to a div that contains the drawn popup. 
    59      */ 
    60     draw: function(px)
    61         if (px == null) { 
    62             if ((this.lonlat != null) && (this.map != null))
     56    * @param {OpenLayers.Pixel} px 
     57    *  
     58    * @returns Reference to a div that contains the drawn popup 
     59    * @type DOMElement 
     60    */ 
     61    draw: function(px)  
     62    { 
     63        if (px == null)  
     64       
     65            if ((this.lonlat != null) && (this.map != null))  
     66           
    6367                px = this.map.getLayerPxFromLonLat(this.lonlat); 
    6468            } 
    6569        } 
    6670         
    67         //calculate relative position 
    68         this.relativePosition = this.calculateRelativePosition(px); 
     71        // check the popup is in view, if not reposition it 
     72        this.updatePos(); 
    6973         
     74        // return result of base draw call 
    7075        return OpenLayers.Popup.prototype.draw.apply(this, arguments); 
    7176    }, 
    7277     
    73     /**  
    74      * Method: calculateRelativePosition 
    75      *  
    76      * Parameters: 
    77      * px - {<OpenLayers.Pixel>} 
    78      *  
    79      * Returns: 
    80      * {String} The relative position ("br" "tr" "tl "bl") at which the popup 
    81      *     should be placed. 
    82      */ 
    83     calculateRelativePosition:function(px) { 
    84         var lonlat = this.map.getLonLatFromLayerPx(px);         
     78    updatePos : function() 
     79    { 
     80        var oMapSize = support.getPos(this.map.div); 
     81        var oPopupPx = this.calculateNewPx(this.map.getLayerPxFromLonLat(this.lonlat)); 
     82        oPopupPx = this.map.getViewPortPxFromLayerPx(oPopupPx); 
     83 
     84        var x2 = parseInt(oPopupPx.x + this.size.w); 
     85        var y2 = parseInt(oPopupPx.y + this.size.h); 
    8586         
    86         var extent = this.map.getExtent(); 
    87         var quadrant = extent.determineQuadrant(lonlat); 
     87        // if left is not visible ? 
     88        if (oPopupPx.x < oMapSize.x) 
     89        { 
     90            this.differenceX = parseInt(oPopupPx.x - oMapSize.x); 
     91        } 
    8892         
    89         return OpenLayers.Bounds.oppositeQuadrant(quadrant); 
    90     },  
    91  
     93        // if right is not visible 
     94        if (x2 > oMapSize.w) 
     95        { 
     96            this.differenceX = parseInt(x2 - oMapSize.w); 
     97        } 
     98         
     99        // if bottom is not visible 
     100        if (y2 > oMapSize.h) 
     101        { 
     102            this.differenceY = parseInt(y2 - oMapSize.h); 
     103        } 
     104         
     105        // if top is not visible 
     106        if (oPopupPx.y < oMapSize.y) 
     107        { 
     108            this.differenceY = parseInt(oPopupPx.y - oMapSize.y); 
     109        } 
     110         
     111        // if a difference has been assigned call the Shit Method 
     112        if (this.differenceX!=0 || this.differenceY!=0) 
     113        { 
     114            ShiftMap(this); 
     115        } 
     116    }, 
     117    /* 
     118     registerEvents:function() { 
     119        this.events = new OpenLayers.Events(this, this.div, null, true); 
     120        this.events.register("mousedown", this, this.onmousedown); 
     121        this.events.register("mousemove", this, this.onmousemove); 
     122        this.events.register("mouseup", this, this.onmouseup); 
     123        this.events.register("click", this, OpenLayers.Util.safeStopPropagation); 
     124        this.events.register("mouseout", this, this.onmouseout); 
     125        this.events.register("dblclick", this, OpenLayers.Util.safeStopPropagation); 
     126     }, 
     127    */ 
    92128    /** 
    93      * Method: moveTo 
    94      * Since the popup is moving to a new px, it might need also to be moved 
    95      *     relative to where the marker is. 
    96      *  
    97      * Parameters: 
    98      * px - {<OpenLayers.Pixel>} 
    99      */ 
    100     moveTo: function(px) { 
    101         this.relativePosition = this.calculateRelativePosition(px); 
    102          
     129    * @param {OpenLayers.Pixel} px 
     130    */ 
     131    moveTo: function(px)  
     132    { 
    103133        var newPx = this.calculateNewPx(px); 
    104134         
    105135        var newArguments = new Array(newPx);         
     
    107137    }, 
    108138     
    109139    /** 
    110      * Method: setSize 
    111      *  
    112      * Parameters: 
    113      * size - {<OpenLayers.Size>} 
    114      */ 
    115     setSize:function(size) {  
     140    * @param {OpenLayers.Size} size 
     141    */ 
     142    setSize : function(size)  
     143    {  
    116144        OpenLayers.Popup.prototype.setSize.apply(this, arguments); 
    117145 
    118         if ((this.lonlat) && (this.map)) { 
     146        if ((this.lonlat) && (this.map)) 
     147        { 
    119148            var px = this.map.getLayerPxFromLonLat(this.lonlat); 
    120149            this.moveTo(px); 
    121150        } 
    122     },   
    123      
     151    }, 
     152         
    124153    /**  
    125      * Method: calculateNewPx 
     154     * @private  
    126155     *  
    127      * Parameters: 
    128      * px - {<OpenLayers.Pixel>} 
     156     * @param {OpenLayers.Pixel} px 
    129157     *  
    130      * Returns: 
    131      * {<OpenLayers.Pixel>} The the new px position of the popup on the screen 
    132      *     relative to the passed-in px. 
     158     * @returns The the new px position of the popup on the screen 
     159     *           relative to the passed-in px 
     160     * @type OpenLayers.Pixel 
    133161     */ 
    134162    calculateNewPx:function(px) { 
    135163        var newPx = px.offset(this.anchor.offset); 
     
    139167         
    140168        var left = (this.relativePosition.charAt(1) == 'l'); 
    141169        newPx.x += (left) ? -this.size.w : this.anchor.size.w; 
    142  
     170        newPx.x += 55; 
     171        newPx.y -= 15; 
     172         
    143173        return newPx;    
    144174    }, 
    145175 
    146176    CLASS_NAME: "OpenLayers.Popup.Anchored" 
    147177}); 
     178 
     179 
  • lib/OpenLayers/Popup.js

    old new  
    1 /* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modified BSD license. 
    2  * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt  
     1/* Copyright (c) 2006-2007 MetaCarta, Inc., published under the BSD license. 
     2 * See http://svn.openlayers.org/trunk/openlayers/release-license.txt  
    33 * for the full text of the license. */ 
    44 
     5/** Corners object contains image information for image required to create popup corners. 
     6 * I decided to simply call it corners in an attempt to keep the code readable later on. 
     7 * Created to simplify updating of the popup shape, still needs some work to make it truly generic. 
     8 * */ 
     9CORNERS = { 
    510 
    6 /** 
    7  * Class: OpenLayers.Popup 
    8  * 
    9  * A popup is a small div that can opened and closed on the map. 
    10  * Typically opened in response to clicking on a marker.   
    11  * See <OpenLayers.Marker>.  Popup's don't require their own 
    12  * layer and are added the the map using the <OpenLayers.Map.addPopup> 
    13  * method. 
    14  * 
    15  * Example: 
    16  * (code) 
    17  * popup = new OpenLayers.Popup("chicken",  
    18  *                    new OpenLayers.LonLat(5,40), 
    19  *                    new OpenLayers.Size(200,200), 
    20  *                    "example popup", 
    21  *                    true); 
    22  *        
    23  * map.addPopup(popup); 
    24  * (end) 
    25  */ 
     11    /* top images*/ 
     12    TL : {src:'corners/topl.png', sizing: 'scale'}, 
     13    TM : {src:'corners/topm.png', sizing: 'crop'}, 
     14    TR : {src:'corners/topr.png', sizing: 'scale'}, 
     15     
     16    /* middle images */ 
     17    ML : {src:'corners/midl.png', sizing: 'crop'}, 
     18    MR : {src:'corners/midr.png', sizing: 'crop'}, 
     19     
     20    /* bottom images */ 
     21    BL : {src:'corners/botl.png', sizing: 'scale'}, 
     22    BM : {src:'corners/botm.png', sizing: 'crop'}, 
     23    BR : {src:'corners/botr.png', sizing: 'scale'} 
     24
     25 
    2626OpenLayers.Popup = OpenLayers.Class({ 
    2727 
    28     /**  
    29      * Property: events   
    30      * {<OpenLayers.Events>} custom event manager  
    31      */ 
     28    /** @type OpenLayers.Events*/ 
    3229    events: null, 
    3330     
    34     /** Property: id 
    35      * {String} the unique identifier assigned to this popup. 
    36      */ 
     31    /** @type String */ 
    3732    id: "", 
    3833 
    39     /**  
    40      * Property: lonlat  
    41      * {<OpenLayers.LonLat>} the position of this popup on the map 
    42      */ 
     34    /** @type OpenLayers.LonLat */ 
    4335    lonlat: null, 
    4436 
    45     /**  
    46      * Property: div  
    47      * {DOMElement} the div that contains this popup. 
    48      */ 
     37    /** @type DOMElement */ 
    4938    div: null, 
    5039 
    51     /**  
    52      * Property: size  
    53      * {<OpenLayers.Size>} the width and height of the popup. 
    54      */ 
     40    /** @type OpenLayers.Size*/ 
    5541    size: null,     
    5642 
    57     /**  
    58      * Property: contentHTML  
    59      * {String} The HTML that this popup displays. 
    60      */ 
     43    /** @type String */ 
    6144    contentHTML: "", 
    6245     
    63     /**  
    64      * Property: backgroundColor  
    65      * {String} the background color used by the popup. 
    66      */ 
    67     backgroundColor: "", 
    68      
    69     /**  
    70      * Property: opacity  
    71      * {float} the opacity of this popup (between 0.0 and 1.0) 
    72      */ 
     46    /** @type float */ 
    7347    opacity: "", 
    74  
    75     /**  
    76      * Property: border  
    77      * {String} the border size of the popup.  (eg 2px) 
    78      */ 
    79     border: "", 
    8048     
    81     /**  
    82      * Property: contentDiv  
    83      * {DOMElement} a reference to the element that holds the content of 
    84      *              the div. 
    85      */ 
    86     contentDiv: null, 
    87      
    88     /**  
    89      * Property: groupDiv  
    90      * {DOMElement} the parent of <OpenLayers.Popup.contentDiv>  
    91      */ 
    92     groupDiv: null, 
     49    /** @type DOMElement */ 
     50    contentDiv:null, 
    9351 
    94     /**  
    95      * Property: padding  
    96      * {int} the internal padding of the content div. 
    97      */ 
    98     padding: 5, 
     52    /** @type int */ 
     53    padding: 0, 
    9954 
     55    /** this gets set in Map.js when the popup is added to the map 
     56     * @type OpenLayers.Map */ 
     57    map: null, 
    10058 
    101     /**  
    102      * Property: map  
    103      * {<OpenLayers.Map>} this gets set in Map.js when the popup is added to the map 
     59    /* how often the increment method will be called in milliseconds 1000 = 1 second 
     60     * @type int */ 
     61    slideTimerInterval: null, 
     62 
     63    /* total duration for slide effect to complete 
     64     * @type int */ 
     65    slideAnimationTime: null, 
     66     
     67    /* 
     68     * sh: part of closeboxcallback hack 
    10469     */ 
    105     map: null, 
     70   closeBoxCallback: null, 
    10671 
    10772    /**  
    108     * Constructor: OpenLayers.Popup 
    109     * Create a popup. 
     73    * @constructor 
    11074    *  
    111     * Parameters:  
    112     * id - {String} a unqiue identifier for this popup.  If null is passed 
    113     *               an identifier will be automatically generated.  
    114     * lonlat - {<OpenLayers.LonLat>}  The position on the map the popup will 
    115     *                                 be shown. 
    116     * size - {<OpenLayers.Size>}      The size of the popup. 
    117     * contentHTML - {String}          The HTML content to display inside the  
    118     *                                 popup. 
    119     * closeBox - {Boolean}            Whether to display a close box inside 
    120     *                                 the popup.  
     75    * @param {String} id 
     76    * @param {OpenLayers.LonLat} lonlat 
     77    * @param {OpenLayers.Size} size 
     78    * @param {String} contentHTML 
     79    * @param {Boolean} closeBox 
    12180    */ 
    122     initialize:function(id, lonlat, size, contentHTML, closeBox) { 
    123         if (id == null) { 
     81    initialize:function(id, lonlat, size, contentHTML, closeBox) 
     82    { 
     83        // how often the increment method will be called in milliseconds 1000 = 1 second 
     84        this.slideTimerInterval = 10; 
     85 
     86        // total duration for slide effect to complete 
     87        this.slideAnimationTime = 2000; 
     88 
     89 
     90        if (id == null) 
     91        { 
    12492            id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); 
    12593        } 
    126  
     94        this.size = (size != null) ? size : new OpenLayers.Size(200,200); 
    12795        this.id = id; 
    12896        this.lonlat = lonlat; 
    129         this.size = (size != null) ? size  
    130                                   : new OpenLayers.Size( 
    131                                                    OpenLayers.Popup.WIDTH, 
    132                                                    OpenLayers.Popup.HEIGHT); 
    133         if (contentHTML != null) {  
    134              this.contentHTML = contentHTML; 
    135         } 
    136         this.backgroundColor = OpenLayers.Popup.COLOR; 
    137         this.opacity = OpenLayers.Popup.OPACITY; 
    138         this.border = OpenLayers.Popup.BORDER; 
     97         
     98        // assign content to object scoped variable 
     99        if (contentHTML != null) this.contentHTML = contentHTML; 
    139100 
    140         this.div = OpenLayers.Util.createDiv(this.id, null, null,  
    141                                              null, null, null, "hidden"); 
     101        // construct container div (main) 
     102        this.div = OpenLayers.Util.createDiv(this.id, null, null, null, null, null); 
    142103        this.div.className = 'olPopup'; 
     104        
     105        // construct content div 
     106        var id = this.div.id + "_contentDiv"; 
     107        this.contentDiv = OpenLayers.Util.createDiv(id, null, this.size.clone(), null, "static", null); 
     108        this.contentDiv.className = 'olPopupContent'; 
     109        
     110        // determine actual render dimensions 
     111        this.getRenderedDimensions(); 
    143112         
    144         this.groupDiv = OpenLayers.Util.createDiv(null, null, null,  
    145                                                     null, "relative", null, 
    146                                                     "hidden"); 
     113        // insert png corners 
     114        this.insertCorners(); 
    147115 
    148         var id = this.div.id + "_contentDiv"; 
    149         this.contentDiv = OpenLayers.Util.createDiv(id, null, this.size.clone(),  
    150                                                     null, "relative", null, 
    151                                                     "hidden"); 
    152         this.contentDiv.className = 'olPopupContent';                                             
    153         this.groupDiv.appendChild(this.contentDiv); 
    154         this.div.appendChild(this.groupDiv); 
     116        // create close button 
     117        var oBtnClose = document.createElement("A"); 
     118            oBtnClose.className="close"; 
     119            oBtnClose.style.position="absolute"; 
     120            oBtnClose.style.height= 13 + "px"; 
     121            oBtnClose.style.width= 13 + "px"; 
     122            oBtnClose.style.left= "233px"; 
     123            oBtnClose.style.top= "20px"; 
     124            oBtnClose.title="close popup"; 
     125            //oBtnClose.href="#"; 
     126            this.div.appendChild(oBtnClose); 
     127         
     128        // register close button event 
     129        var closeEvents = new OpenLayers.Events(this, oBtnClose); 
     130            closeEvents.register("mousedown", this, this.hide); 
    155131 
    156         if (closeBox) { 
     132        // register object events 
     133        this.registerEvents(); 
     134         
     135        // move the popup into position 
     136        this.updatePosition(); 
     137         
     138        //closebox by stefan 
     139        if (closeBox == true) { 
    157140           // close icon 
    158141            var closeSize = new OpenLayers.Size(17,17); 
    159142            var img = OpenLayers.Util.getImagesLocation() + "close.gif"; 
     
    163146                                                                img); 
    164147            closeImg.style.right = this.padding + "px"; 
    165148            closeImg.style.top = this.padding + "px"; 
    166             this.groupDiv.appendChild(closeImg); 
     149            closeImg.style.border = "none"; 
     150            oBtnClose.appendChild(closeImg); 
    167151 
    168             var closePopup = function(e) { 
     152            /*var closePopup = function(e) { 
     153                 
     154                console.info("image"); 
     155                console.info(e); 
     156                 
     157                if (this.closeBoxCallback != null) { 
     158                    this.closeBoxCallback(); 
     159                } 
    169160                this.hide(); 
    170161                OpenLayers.Event.stop(e); 
    171162            } 
    172163            OpenLayers.Event.observe(closeImg, "click",  
    173                     OpenLayers.Function.bindAsEventListener(closePopup, this)); 
     164                                     closePopup.bindAsEventListener(this));*/ 
    174165 
    175166        } 
     167    }, 
     168     
     169    /** 
     170     * inserts corners into main container and merges elements. Although this has been constructed in a generic manner, it still  
     171     * requires more work before it can fully support unlimited shapes. The google drop shadow is achieved by inserting a shadow popup, this could be extended to offer 
     172     * the same functionallity but it would need some pondering to ensure the UI remains responsive. 
     173     */ 
     174    insertCorners : function () 
     175    {    
    176176 
    177         this.registerEvents(); 
     177        // Hack to hardcode width/height of popup 
     178        // since size.w and size.h don't always work as expected 
     179        // TBD: really fix it instead of hack (rdewit) 
     180 
     181        // ensure a safe minimum width and height 
     182        this.size.w = Math.max(this.size.w, 85); // minimum width must be 85, otherwise bubble goes wrong  
     183        this.size.h = Math.max(this.size.h, 15); // minimum height must be 15, otherwise bubble goes wrong  
     184 
     185        // user can override values with these values 
     186        if ((typeof POPUP_WIDTH) != "undefined") { 
     187          this.size.w = POPUP_WIDTH; 
     188        } 
     189        if (typeof POPUP_HEIGHT != "undefined") { 
     190          this.size.h = POPUP_HEIGHT; 
     191        } 
     192 
     193        // ie hack required for abs positioning   
     194        var arVersion = navigator.appVersion.split("MSIE"); 
     195        var version = parseFloat(arVersion[1]); 
     196     
     197        //alert("inserting corners: " + this.size); 
     198        // retrive image path  
     199        var sImgLoc = OpenLayers.Util.getImagesLocation(); 
     200                
     201        // insert top left 0,0 
     202        var topl = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel(0,0), new OpenLayers.Size(38, 28), sImgLoc + CORNERS.TL.src, "absolute", 0, CORNERS.TL.sizing); 
     203        this.div.appendChild(topl); 
     204         
     205        // insert top middle  
     206        var topm = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel(38,0), new OpenLayers.Size(parseInt(this.size.w - 22), 28), sImgLoc + CORNERS.TM.src, "absolute", 0, CORNERS.TM.sizing); 
     207        this.div.appendChild(topm); 
     208         
     209        // insert top right  
     210        var topr = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel(parseInt(38 + this.size.w - ((version<7) ? 22:23)), 0), new OpenLayers.Size(38, 28), sImgLoc + CORNERS.TR.src, "absolute", 0, CORNERS.TR.sizing); 
     211        this.div.appendChild(topr); 
     212         
     213        // insert middle left 
     214        var midl = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel(0,28), new OpenLayers.Size(38, parseInt(this.size.h - 12)), sImgLoc + CORNERS.ML.src, "absolute", 0, CORNERS.ML.sizing); 
     215        this.div.appendChild(midl); 
     216         
     217        // insert content 
     218        this.contentDiv.style.position = "absolute"; 
     219        this.contentDiv.style.backgroundColor="white"; 
     220        this.contentDiv.style.top = 15 + "px"; 
     221        this.contentDiv.style.left = 15 + "px"; 
     222        this.contentDiv.style.width = this.size.w + "px"; 
     223        this.contentDiv.style.height = this.size.h + "px"; 
     224         
     225        // insert middle right w:38, h:600 
     226        var midr = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel(parseInt(38 + this.size.w -22), 28), new OpenLayers.Size(38, parseInt(this.size.h - 13)), sImgLoc + CORNERS.MR.src, "absolute", 0, CORNERS.MR.sizing); 
     227        this.div.appendChild(midr); 
     228         
     229        // calculate middle width inc content 
     230        var iMaxW = 38 + this.size.w + 38; 
     231         
     232        // insert bottom left 
     233        var botl = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel(0, 28 + this.size.h - 12), new OpenLayers.Size(38, 39), sImgLoc + CORNERS.BL.src, "absolute", 0, CORNERS.BL.sizing); 
     234        this.div.appendChild(botl); 
     235         
     236        // insert bottom middle 
     237        var botm = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel(38, 28 + this.size.h - 13), new OpenLayers.Size(iMaxW - (38 + 97) -((version<7) ? 21:22), 40), sImgLoc + CORNERS.BM.src, "absolute", 0, CORNERS.BM.sizing); 
     238        this.div.appendChild(botm); 
     239         
     240        // insert bottom right inc handle 
     241        var botr = OpenLayers.Util.createAlphaImageDiv("", new OpenLayers.Pixel((iMaxW - (38 + 97)) + 38 -((version<7) ? 21:22), 28 + this.size.h - 13), new OpenLayers.Size(97, 68), sImgLoc + CORNERS.BR.src, "absolute", 0, CORNERS.BR.sizing); 
     242        this.div.appendChild(botr); 
     243 
     244        //this.div.style.border="1px solid red"; 
     245        // append content to main popup. 
     246        // inserted last to ensure the browser assigns correct z-index to place content on top 
     247        this.div.appendChild(this.contentDiv); 
     248 
     249        // update object size to reflect corners/shadow 
     250        this.size = new OpenLayers.Size(this.size.w + 53, this.size.h + 40); 
    178251    }, 
     252     
     253    /** 
     254     * renders the contentHTML offscreen to determine actual dimensions for popup sizing. 
     255     * as we need layout to determine dimensions the content is rendered -99999px to the left and absolute 
     256     * to ensure the scrollbars do not flicker 
     257     */ 
     258    getRenderedDimensions : function() 
     259    { 
     260        // ensure content is set to contentDIV 
     261        this.setContentHTML(); 
     262         
     263        // create temp container div with restricted size 
     264        var container = document.createElement("div"); 
     265            container.className = 'olPopup'; 
     266            container.style.overflow=""; 
     267            container.style.position = "absolute"; 
     268            container.style.left="-9999999999px"; 
     269            container.style.width="20px"; 
     270            container.style.height="20px"; 
     271            container.style.color="white"; 
     272             
     273        // create temp content div and assign content 
     274        var content = document.createElement("div"); 
     275            content.innerHTML = this.contentHTML; 
     276            content.className = 'olPopupContent'; 
     277            content.style.overflow = "auto"; 
     278         
     279        // add content to restricted container  
     280        container.appendChild(content); 
     281         
     282        // append container to body for rendering 
     283        document.body.appendChild(container); 
     284         
     285        // calculate scroll width of content and add corners and shadow width 
     286        var w = parseInt(content.scrollWidth);// + 49 + 30; 
     287         
     288        // update container width to allow height to adjust 
     289        container.style.width = w + "px"; 
     290         
     291        // capture height and add shadow and corner image widths 
     292        var h = parseInt(content.scrollHeight);// + 96 + 45; 
     293         
     294        // update object size values 
     295        this.size = new OpenLayers.Size(w, h); 
     296             
     297        // remove elements 
     298        document.body.removeChild(container); 
     299         
     300        // cleanup 
     301        container = null; 
     302        content = null; 
     303    }, 
    179304 
    180305    /**  
    181      * Method: destroy 
    182      * nullify references to prevent circular references and memory leaks 
    183      */ 
     306    */ 
    184307    destroy: function() { 
     308     
    185309        if (this.map != null) { 
    186310            this.map.removePopup(this); 
    187             this.map = null; 
    188311        } 
    189         this.events.destroy(); 
    190         this.events = null; 
    191312        this.div = null; 
     313        this.map = null; 
     314         
     315         
    192316    }, 
    193317 
    194318    /**  
    195     * Method: draw 
    196     * Constructs the elements that make up the popup. 
    197     * 
    198     * Parameters: 
    199     * px - {<OpenLayers.Pixel>} the position the popup in pixels. 
     319    * @param {OpenLayers.Pixel} px 
    200320    *  
    201     * Returns: 
    202     * {DOMElement} Reference to a div that contains the drawn popup 
     321    * @returns Reference to a div that contains the drawn popup 
     322    * @type DOMElement 
    203323    */ 
    204     draw: function(px) { 
    205         if (px == null) { 
    206             if ((this.lonlat != null) && (this.map != null)) { 
     324    draw: function(px) 
     325    { 
     326        if (px == null) 
     327        { 
     328            if ((this.lonlat != null) && (this.map != null))  
     329            { 
    207330                px = this.map.getLayerPxFromLonLat(this.lonlat); 
    208331            } 
    209332        } 
    210333         
    211334        this.setSize(); 
    212         this.setBackgroundColor(); 
    213         this.setOpacity(); 
    214         this.setBorder(); 
    215335        this.setContentHTML(); 
    216336        this.moveTo(px); 
    217337 
     
    219339    }, 
    220340 
    221341    /**  
    222      * Method: updatePosition 
    223342     * if the popup has a lonlat and its map members set,  
    224      * then have it move itself to its proper position 
     343     * then have it move itself to its proper position 
    225344     */ 
    226     updatePosition: function() { 
    227         if ((this.lonlat) && (this.map))
    228                 var px = this.map.getLayerPxFromLonLat(this.lonlat); 
    229                 if (px)
    230                     this.moveTo(px);            
    231                 }     
     345    updatePosition: function() 
     346   
     347        if ((this.lonlat) && (this.map) && (this.anchor))  
     348       
     349            var px = this.map.getLayerPxFromLonLat(this.lonlat); 
     350            this.moveTo(px);            
    232351        } 
    233352    }, 
    234353 
    235354    /** 
    236      * Method: moveTo 
    237      *  
    238      * Parameters: 
    239      * px - {<OpenLayers.Pixel>} the top and left position of the popup div.  
    240      */ 
    241     moveTo: function(px) { 
    242         if ((px != null) && (this.div != null)) { 
     355    * @param {OpenLayers.Pixel} px 
     356    */ 
     357    moveTo: function(px)  
     358    { 
     359        if ((px != null) && (this.div != null))  
     360        { 
    243361            this.div.style.left = px.x + "px"; 
    244362            this.div.style.top = px.y + "px"; 
    245363        } 
    246364    }, 
    247365 
    248366    /** 
    249      * Method: visible 
    250