Ticket #926: 2.5-google-style-bubbles.patch
| File 2.5-google-style-bubbles.patch, 48.8 kB (added by rdewit, 2 years ago) |
|---|
-
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 3 6 * for the full text of the license. */ 4 7 5 8 6 9 /** 7 * @ requires OpenLayers/Popup/Anchored.js10 * @class 8 11 * 9 * Class: OpenLayers.Popup.AnchoredBubble 10 * 11 * Inherits from: 12 * - <OpenLayers.Popup.Anchored> 12 * @requires OpenLayers/Popup/Anchored.js 13 13 */ 14 OpenLayers.Popup.AnchoredBubble =15 OpenLayers.Class(OpenLayers.Popup.Anchored, {16 14 17 /** 18 * Property: rounded 19 * {Boolean} Has the popup been rounded yet? 20 */ 21 rounded: false, 22 15 OpenLayers.Popup.AnchoredBubble = OpenLayers.Class( OpenLayers.Popup.Anchored, { 16 23 17 /** 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 { 37 32 OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments); 38 33 }, 39 34 40 35 /** 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 */ 49 41 draw: function(px) { 50 42 51 43 OpenLayers.Popup.Anchored.prototype.draw.apply(this, arguments); 52 44 53 45 this.setContentHTML(); 54 55 //set the popup color and opacity56 this.setBackgroundColor();57 this.setOpacity();58 46 59 47 return this.div; 60 48 }, 61 49 62 50 /** 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 { 83 55 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 corners96 this.setRicoCorners(!this.rounded);97 this.rounded = true;98 }99 }100 56 }, 101 102 /**103 * APIMethod: setBackgroundColor104 *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 },121 57 122 58 /** 123 * APIMethod: setOpacity 124 * 125 * Parameters: 126 * opacity - {float} 59 * @param {float} opacity 127 60 */ 128 setOpacity:function(opacity) { 129 if (opacity != undefined) { 61 setOpacity:function(opacity) 62 { 63 if (opacity != undefined) 64 { 130 65 this.opacity = opacity; 131 66 } 132 67 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); 137 73 } 138 74 } 139 75 }, 140 141 /**142 * Method: setBorder143 * 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: setRicoCorners154 * 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};166 76 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 opacity172 this.setBackgroundColor();173 this.setOpacity();174 }175 },176 177 /**178 * Method: getCornersToRound179 *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 194 77 CLASS_NAME: "OpenLayers.Popup.AnchoredBubble" 195 78 }); 196 79 197 /**198 * Constant: CORNER_SIZE199 * {Integer} 5. Border space for the RICO corners.200 */201 OpenLayers.Popup.AnchoredBubble.CORNER_SIZE = 5;202 80 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 3 5 * for the full text of the license. */ 4 6 5 7 6 8 /** 9 * @class 10 * 7 11 * @requires OpenLayers/Popup.js 8 *9 * Class: OpenLayers.Popup.Anchored10 *11 * Inherits from:12 * - <OpenLayers.Popup>13 12 */ 14 OpenLayers.Popup.Anchored = 15 OpenLayers.Class(OpenLayers.Popup, { 13 OpenLayers.Popup.Anchored = OpenLayers.Class( OpenLayers.Popup, { 16 14 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", 22 18 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 */ 28 22 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, 29 31 30 32 /** 31 * Constructor: OpenLayers.Popup.Anchored33 * @constructor 32 34 * 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 41 44 */ 42 initialize:function(id, lonlat, size, contentHTML, anchor, closeBox) { 45 initialize:function(id, lonlat, size, contentHTML, anchor, closeBox) 46 { 43 47 var newArguments = new Array(id, lonlat, size, contentHTML, closeBox); 44 48 OpenLayers.Popup.prototype.initialize.apply(this, newArguments); 45 49 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(); 49 53 }, 50 54 51 55 /** 52 * Method: draw53 *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 { 63 67 px = this.map.getLayerPxFromLonLat(this.lonlat); 64 68 } 65 69 } 66 70 67 // calculate relative position68 this. relativePosition = this.calculateRelativePosition(px);71 // check the popup is in view, if not reposition it 72 this.updatePos(); 69 73 74 // return result of base draw call 70 75 return OpenLayers.Popup.prototype.draw.apply(this, arguments); 71 76 }, 72 77 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); 85 86 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 } 88 92 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 */ 92 128 /** 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 { 103 133 var newPx = this.calculateNewPx(px); 104 134 105 135 var newArguments = new Array(newPx); … … 107 137 }, 108 138 109 139 /** 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 { 116 144 OpenLayers.Popup.prototype.setSize.apply(this, arguments); 117 145 118 if ((this.lonlat) && (this.map)) { 146 if ((this.lonlat) && (this.map)) 147 { 119 148 var px = this.map.getLayerPxFromLonLat(this.lonlat); 120 149 this.moveTo(px); 121 150 } 122 }, 123 151 }, 152 124 153 /** 125 * Method: calculateNewPx154 * @private 126 155 * 127 * Parameters: 128 * px - {<OpenLayers.Pixel>} 156 * @param {OpenLayers.Pixel} px 129 157 * 130 * Returns:131 * {<OpenLayers.Pixel>} The the new px position of the popup on the screen132 * 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 133 161 */ 134 162 calculateNewPx:function(px) { 135 163 var newPx = px.offset(this.anchor.offset); … … 139 167 140 168 var left = (this.relativePosition.charAt(1) == 'l'); 141 169 newPx.x += (left) ? -this.size.w : this.anchor.size.w; 142 170 newPx.x += 55; 171 newPx.y -= 15; 172 143 173 return newPx; 144 174 }, 145 175 146 176 CLASS_NAME: "OpenLayers.Popup.Anchored" 147 177 }); 178 179 -
lib/OpenLayers/Popup.js
old new 1 /* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modifiedBSD license.2 * See http://svn.openlayers.org/trunk/openlayers/re pository-license.txt1 /* Copyright (c) 2006-2007 MetaCarta, Inc., published under the BSD license. 2 * See http://svn.openlayers.org/trunk/openlayers/release-license.txt 3 3 * for the full text of the license. */ 4 4 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 * */ 9 CORNERS = { 5 10 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 26 26 OpenLayers.Popup = OpenLayers.Class({ 27 27 28 /** 29 * Property: events 30 * {<OpenLayers.Events>} custom event manager 31 */ 28 /** @type OpenLayers.Events*/ 32 29 events: null, 33 30 34 /** Property: id 35 * {String} the unique identifier assigned to this popup. 36 */ 31 /** @type String */ 37 32 id: "", 38 33 39 /** 40 * Property: lonlat 41 * {<OpenLayers.LonLat>} the position of this popup on the map 42 */ 34 /** @type OpenLayers.LonLat */ 43 35 lonlat: null, 44 36 45 /** 46 * Property: div 47 * {DOMElement} the div that contains this popup. 48 */ 37 /** @type DOMElement */ 49 38 div: null, 50 39 51 /** 52 * Property: size 53 * {<OpenLayers.Size>} the width and height of the popup. 54 */ 40 /** @type OpenLayers.Size*/ 55 41 size: null, 56 42 57 /** 58 * Property: contentHTML 59 * {String} The HTML that this popup displays. 60 */ 43 /** @type String */ 61 44 contentHTML: "", 62 45 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 */ 73 47 opacity: "", 74 75 /**76 * Property: border77 * {String} the border size of the popup. (eg 2px)78 */79 border: "",80 48 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, 93 51 94 /** 95 * Property: padding 96 * {int} the internal padding of the content div. 97 */ 98 padding: 5, 52 /** @type int */ 53 padding: 0, 99 54 55 /** this gets set in Map.js when the popup is added to the map 56 * @type OpenLayers.Map */ 57 map: null, 100 58 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 104 69 */ 105 map: null,70 closeBoxCallback: null, 106 71 107 72 /** 108 * Constructor: OpenLayers.Popup 109 * Create a popup. 73 * @constructor 110 74 * 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 121 80 */ 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 { 124 92 id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); 125 93 } 126 94 this.size = (size != null) ? size : new OpenLayers.Size(200,200); 127 95 this.id = id; 128 96 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; 139 100 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); 142 103 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(); 143 112 144 this.groupDiv = OpenLayers.Util.createDiv(null, null, null, 145 null, "relative", null, 146 "hidden"); 113 // insert png corners 114 this.insertCorners(); 147 115 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); 155 131 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) { 157 140 // close icon 158 141 var closeSize = new OpenLayers.Size(17,17); 159 142 var img = OpenLayers.Util.getImagesLocation() + "close.gif"; … … 163 146 img); 164 147 closeImg.style.right = this.padding + "px"; 165 148 closeImg.style.top = this.padding + "px"; 166 this.groupDiv.appendChild(closeImg); 149 closeImg.style.border = "none"; 150 oBtnClose.appendChild(closeImg); 167 151 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 } 169 160 this.hide(); 170 161 OpenLayers.Event.stop(e); 171 162 } 172 163 OpenLayers.Event.observe(closeImg, "click", 173 OpenLayers.Function.bindAsEventListener(closePopup, this));164 closePopup.bindAsEventListener(this));*/ 174 165 175 166 } 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 { 176 176 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); 178 251 }, 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 }, 179 304 180 305 /** 181 * Method: destroy 182 * nullify references to prevent circular references and memory leaks 183 */ 306 */ 184 307 destroy: function() { 308 185 309 if (this.map != null) { 186 310 this.map.removePopup(this); 187 this.map = null;188 311 } 189 this.events.destroy();190 this.events = null;191 312 this.div = null; 313 this.map = null; 314 315 192 316 }, 193 317 194 318 /** 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 200 320 * 201 * Returns:202 * {DOMElement} Reference to a div that contains the drawn popup321 * @returns Reference to a div that contains the drawn popup 322 * @type DOMElement 203 323 */ 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 { 207 330 px = this.map.getLayerPxFromLonLat(this.lonlat); 208 331 } 209 332 } 210 333 211 334 this.setSize(); 212 this.setBackgroundColor();213 this.setOpacity();214 this.setBorder();215 335 this.setContentHTML(); 216 336 this.moveTo(px); 217 337 … … 219 339 }, 220 340 221 341 /** 222 * Method: updatePosition223 342 * if the popup has a lonlat and its map members set, 224 * then have it move itself to its proper position343 * then have it move itself to its proper position 225 344 */ 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); 232 351 } 233 352 }, 234 353 235 354 /** 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 { 243 361 this.div.style.left = px.x + "px"; 244 362 this.div.style.top = px.y + "px"; 245 363 } 246 364 }, 247 365 248 366 /** 249 * Method: visible 250 * 251 * Returns: 252 * {Boolean} Boolean indicating whether or not the popup is visible 367 * @returns Boolean indicating whether or not the popup is visible 368 * @type Boolean 253 369 */ 254 visible: function() { 370 visible: function() 371 { 255 372 return OpenLayers.Element.visible(this.div); 256 373 }, 257 374 258 375 /** 259 * Method: toggle 260 * Toggles visibility of the popup. 376 * 261 377 */ 262 toggle: function() { 378 toggle: function() 379 { 263 380 OpenLayers.Element.toggle(this.div); 264 381 }, 265 382 266 383 /** 267 * Method: show 268 * Makes the popup visible. 384 * 269 385 */ 270 show: function() { 386 show: function() 387 { 271 388 OpenLayers.Element.show(this.div); 272 389 }, 273 390 274 391 /** 275 * Method: hide 276 * Makes the popup invisible. 392 * 277 393 */ 278 hide: function() { 394 hide: function() 395 { 396 if (this.closeBoxCallback != null) { 397 this.closeBoxCallback(); 398 } 399 if (this.map) this.map.removePopup(this); 279 400 OpenLayers.Element.hide(this.div); 280 401 }, 281 402 282 403 /** 283 * Method: setSize 284 * Used to adjust the size of the popup. 285 * 286 * Parameters: 287 * size - {<OpenLayers.Size>} the new size of the popup in pixels. 288 */ 289 setSize:function(size) { 290 if (size != undefined) { 404 * @param {OpenLayers.Size} size 405 */ 406 setSize:function(size) 407 { 408 if (size != undefined) 409 { 291 410 this.size = size; 292 411 } 293 412 294 if (this.div != null) { 295 this.div.style.width = this.size.w + "px"; 296 this.div.style.height = this.size.h + "px"; 413 if (this.div != null) 414 { 415 this.div.style.width = this.size.w + "px"; 416 this.div.style.height = this.size.h + "px"; 297 417 } 298 if (this.contentDiv != null){299 this.contentDiv.style.width = this.size.w + "px";300 this.contentDiv.style.height = this.size.h + "px";301 }302 418 }, 303 419 304 420 /** 305 * Method: setBackgroundColor 306 * Sets the background color of the popup. 307 * Parameters: 308 * color - {String} the background color. eg "#FFBBBB" 421 * @param {float} opacity 309 422 */ 310 setBackgroundColor:function(color) {311 if (color != undefined) {312 this.backgroundColor = color;313 }314 315 if (this.div != null) {316 this.div.style.backgroundColor = this.backgroundColor;317 }318 },319 320 /**321 * Method: setOpacity322 * Sets the opacity of the popup.323 *324 * Parameters:325 * opacity - {float} A value between 0.0 (transparent) and 1.0 (solid).326 */327 423 setOpacity:function(opacity) { 328 424 if (opacity != undefined) { 329 425 this.opacity = opacity; … … 336 432 // for IE 337 433 this.div.style.filter = 'alpha(opacity=' + this.opacity*100 + ')'; 338 434 } 339 }, 435 }, 340 436 341 437 /** 342 * Method: setBorder 343 * Sets the border style of the popup. 344 * 345 * Parameters: 346 * border - {String} The border style value. eg 2px 438 * @param {String} contentHTML 347 439 */ 348 setBorder:function(border) {349 if (border != undefined) {350 this.border = border;351 }352 353 if (this.div != null) {354 this.div.style.border = this.border;355 }356 },357 358 /**359 * Method: setContentHTML360 * Allows the user to set the HTML content of the popup.361 *362 * Parameters:363 * contentHTML - {String} HTML for the div.364 */365 440 setContentHTML:function(contentHTML) { 366 441 if (contentHTML != null) { 367 442 this.contentHTML = contentHTML; … … 371 446 this.contentDiv.innerHTML = this.contentHTML; 372 447 } 373 448 }, 374 375 376 377 /** 378 * Method: registerEvents 379 * Registers events on the popup. 380 * 381 * Do this in a separate function so that subclasses can 449 450 /** Do this in a separate function so that subclasses can 382 451 * choose to override it if they wish to deal differently 383 452 * with mouse events 384 453 * … … 397 466 */ 398 467 registerEvents:function() { 399 468 this.events = new OpenLayers.Events(this, this.div, null, true); 400 401 469 this.events.register("mousedown", this, this.onmousedown); 402 470 this.events.register("mousemove", this, this.onmousemove); 403 471 this.events.register("mouseup", this, this.onmouseup); 404 this.events.register("click", this, this.onclick);472 this.events.register("click", this, OpenLayers.Util.safeStopPropagation); 405 473 this.events.register("mouseout", this, this.onmouseout); 406 this.events.register("dblclick", this, this.ondblclick);474 this.events.register("dblclick", this, OpenLayers.Util.safeStopPropagation); 407 475 }, 408 476 409 /** 410 * Method: onmousedown 411 * When mouse goes down within the popup, make a note of 477 478 /** When mouse goes down within the popup, make a note of 412 479 * it locally, and then do not propagate the mousedown 413 480 * (but do so safely so that user can select text inside) 414 481 * 415 * Parameters: 416 * evt - {Event} 482 * @param {Event} evt 417 483 */ 418 484 onmousedown: function (evt) { 419 485 this.mousedown = true; 420 OpenLayers. Event.stop(evt, true);486 OpenLayers.Util.safeStopPropagation(evt); 421 487 }, 422 488 423 /** 424 * Method: onmousemove 425 * If the drag was started within the popup, then 489 /** If the drag was started within the popup, then 426 490 * do not propagate the mousemove (but do so safely 427 491 * so that user can select text inside) 428 492 * 429 * Parameters: 430 * evt - {Event} 493 * @param {Event} evt 431 494 */ 432 495 onmousemove: function (evt) { 433 496 if (this.mousedown) { 434 OpenLayers. Event.stop(evt, true);497 OpenLayers.Util.safeStopPropagation(evt); 435 498 } 436 499 }, 437 500 438 /** 439 * Method: onmouseup 440 * When mouse comes up within the popup, after going down 501 /** When mouse comes up within the popup, after going down 441 502 * in it, reset the flag, and then (once again) do not 442 503 * propagate the event, but do so safely so that user can 443 504 * select text inside 444 505 * 445 * Parameters: 446 * evt - {Event} 506 * @param {Event} evt 447 507 */ 448 508 onmouseup: function (evt) { 449 509 if (this.mousedown) { 450 510 this.mousedown = false; 451 OpenLayers. Event.stop(evt, true);511 OpenLayers.Util.safeStopPropagation(evt); 452 512 } 453 513 }, 454 514 455 /** 456 * Method: onclick 457 * Ignore clicks, but allowing default browser handling 458 * 459 * Parameters: 460 * evt - {Event} 461 */ 462 onclick: function (evt) { 463 OpenLayers.Event.stop(evt, true); 464 }, 465 466 /** 467 * Method: onmouseout 468 * When mouse goes out of the popup set the flag to false so that 515 /** When mouse goes out of the popup set the flag to false so that 469 516 * if they let go and then drag back in, we won't be confused. 470 517 * 471 * Parameters: 472 * evt - {Event} 518 * @param {Event} evt 519 * 520 * @type Boolean 473 521 */ 474 522 onmouseout: function (evt) { 475 523 this.mousedown = false; 476 524 }, 477 525 478 /**479 * Method: ondblclick480 * Ignore double-clicks, but allowing default browser handling481 *482 * Parameters:483 * evt - {Event}484 */485 ondblclick: function (evt) {486 OpenLayers.Event.stop(evt, true);487 },488 489 526 CLASS_NAME: "OpenLayers.Popup" 490 527 }); 491 528 492 OpenLayers.Popup.WIDTH = 200; 493 OpenLayers.Popup.HEIGHT = 200; 494 OpenLayers.Popup.COLOR = "white"; 495 OpenLayers.Popup.OPACITY = 1; 496 OpenLayers.Popup.BORDER = "0px"; 529 530 531 /** 532 * ShiftMap is a function called by the Anchor class to slide the current popup into view. 533 * Popups are displayed exclusivly meaning "there can be only one" at a time. 534 * This function was not embedded into any OpenLayer classes due to the nature of its operation and scoping issues. 535 * 536 * @Function 537 */ 538 function ShiftMap(obj) 539 { 540 541 542 543 var o = obj; // copy object locally to facilitate timeout execution 544 545 if (o!=null) 546 { 547 548 549 // record the date and time of first call to this method using anchor object as scope 550 if (!o.ShiftStartTime) o.ShiftStartTime = (new Date()).getTime(); 551 552 if (o.differenceX!=0) 553 { 554 // 555 // X difference detected, process 556 // 557 558 // determine direction of motion 559 var dir = (o.differenceX>0) ? "+":"-"; 560 561 // calculated elapsed time since start of animation 562 var elapsed = (new Date()).getTime() - o.ShiftStartTime; 563 564 // calculated the required incrememt to ensure animation is complete within predefined timescale 565 var increment = Math.round(elapsed / obj.slideAnimationTime * Math.abs(o.differenceX)); 566 567 switch(dir) 568 { 569 case "+": 570 { 571 if ((o) && (o.differenceX>1) && (o.map)) 572 { 573 o.differenceX-=increment; 574 o.map.pan(+increment,0); 575 window.setTimeout(function() { ShiftMap(o); }, obj.slideTimerInterval); 576 } 577 }break; 578 579 case "-": 580 { 581 if ((o) && (o.differenceX<1) && (o.map)) 582 { 583 o.differenceX+=increment; 584 o.map.pan(-increment,0); 585 window.setTimeout(function() { ShiftMap(o); }, obj.slideTimerInterval); 586 } 587 }break; 588 } 589 } 590 591 if (o.differenceY!=0) 592 { 593 // 594 // Y difference detected, process 595 // 596 597 // determine direction of motion 598 var dir = (o.differenceY>0) ? "+":"-"; 599 600 // calculated elapsed time since start of animation 601 var elapsed = (new Date()).getTime() - o.ShiftStartTime; 602 603 // calculated the required incrememt to ensure animation is complete within predefined timescale 604 var increment = Math.round(elapsed / obj.slideAnimationTime * Math.abs(o.differenceY)); 605 606 switch(dir) 607 { 608 case "+": 609 { 610 if ((o) && (o.differenceY>1) && (o.map)) 611 { 612 o.differenceY-=increment; 613 o.map.pan(0,+increment); 614 window.setTimeout(function() { ShiftMap(o); }, obj.slideTimerInterval); 615 } 616 }break; 617 618 case "-": 619 { 620 if ((o) && (o.differenceY<1) && (o.map)) 621 { 622 o.differenceY+=increment; 623 o.map.pan(0,-increment); 624 window.setTimeout(function() { ShiftMap(o); }, obj.slideTimerInterval); 625 } 626 }break; 627 } 628 } 629 } 630 } 631 632 633 /** 634 * Custom support object containg static methods required by the updated Popup and associated Classes, could be merged into the OpenLayers.Util collection 635 * I have included an opacity fade method, however with the map I am using for testing loading slow, sliding and fading appeared too much. 636 * 637 * @Object 638 */ 639 var support = { 640 641 viewport : function() 642 { 643 return { 644 height : (document.body.clientHeight || document.documentElement.clientHeight || window.innerHeight || 0), 645 width : (document.body.clientWidth || document.documentElement.clientWidth || window.innerWidth || 0), 646 scrollX : (document.body.scrollLeft || document.documentElement.scrollLeft || self.pageXOffset || 0), 647 scrollY : (document.body.scrollTop || document.documentElement.scrollTop || self.pageYOffset || 0) 648 }; 649 }, 650 651 /* return position of element */ 652 getPos : function(el) 653 { 654 var x=0, y=0, w=0, h=0; 655 656 if (document.getBoxObjectFor) 657 { 658 659 var bo = document.getBoxObjectFor(el); 660 return {x:bo.x, y:bo.y, w:bo.width, h:bo.height} 661 } 662 else if (el.getBoundingClientRect) 663 { 664 var rect = el.getBoundingClientRect(); 665 return {x:rect.left + support.viewport().scrollX, y:rect.top + support.viewport().scrollY, w:(rect.right - rect.left), h:(rect.bottom - rect.top)} 666 } 667 else 668 { 669 670 w = el.offsetWidth; 671 h = el.offsetHeight; 672 do { x += el.offsetLeft || 0; y += el.offsetTop || 0; el = el.offsetParent; } while (el); 673 return {x:x, y:y, w:w, h:h} 674 } 675 }, 676 677 fade : function(id, opacStart, opacEnd, millisec, func) 678 { 679 //speed for each frame 680 var speed = Math.round(millisec / 100); 681 var timer = 0; 682 683 //determine the direction for the blending, if start and end are the same nothing happens 684 if(opacStart > opacEnd) 685 { 686 for(i = opacStart; i >= opacEnd; i--) 687 { 688 689 setTimeout("support.changeOpac(" + i + ",'" + id + "')",(timer * speed)); 690 timer++; 691 } 692 } 693 else if(opacStart < opacEnd) 694 { 695 for(i = opacStart; i <= opacEnd; i++) 696 { 697 setTimeout("support.changeOpac(" + i + ",'" + id + "')",(timer * speed)); 698 timer++; 699 } 700 } 701 if (opacStart == opacEnd) 702 { 703 func(); 704 } 705 }, 706 707 //change the opacity for different browsers 708 changeOpac : function(opacity, id) 709 { 710 var object = document.getElementById(id).style; 711 object.opacity = (opacity / 100); 712 object.MozOpacity = (opacity / 100); 713 object.KhtmlOpacity = (opacity / 100); 714 object.filter = "alpha(opacity=" + opacity + ")"; 715 } 716 }
