1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2 * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3 * full text of the license. */
7 * @requires OpenLayers/Popup.js
11 * Class: OpenLayers.Popup.Anchored
14 * - <OpenLayers.Popup>
16 OpenLayers.Popup.Anchored =
17 OpenLayers.Class(OpenLayers.Popup, {
20 * Parameter: relativePosition
21 * {String} Relative position of the popup ("br", "tr", "tl" or "bl").
23 relativePosition: null,
26 * APIProperty: keepInMap
27 * {Boolean} If panMapIfOutOfView is false, and this property is true,
28 * contrain the popup such that it always fits in the available map
29 * space. By default, this is set. If you are creating popups that are
30 * near map edges and not allowing pannning, and especially if you have
31 * a popup which has a fixedRelativePosition, setting this to false may
32 * be a smart thing to do.
34 * For anchored popups, default is true, since subclasses will
35 * usually want this functionality.
41 * {Object} Object to which we'll anchor the popup. Must expose a
42 * 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>).
47 * Constructor: OpenLayers.Popup.Anchored
51 * lonlat - {<OpenLayers.LonLat>}
52 * contentSize - {<OpenLayers.Size>}
53 * contentHTML - {String}
54 * anchor - {Object} Object which must expose a 'size' <OpenLayers.Size>
55 * and 'offset' <OpenLayers.Pixel> (generally an <OpenLayers.Icon>).
56 * closeBox - {Boolean}
57 * closeBoxCallback - {Function} Function to be called on closeBox click.
59 initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,
62 id, lonlat, contentSize, contentHTML, closeBox, closeBoxCallback
64 OpenLayers.Popup.prototype.initialize.apply(this, newArguments);
66 this.anchor = (anchor != null) ? anchor
67 : { size: new OpenLayers.Size(0,0),
68 offset: new OpenLayers.Pixel(0,0)};
76 this.relativePosition = null;
78 OpenLayers.Popup.prototype.destroy.apply(this, arguments);
83 * Overridden from Popup since user might hide popup and then show() it
84 * in a new location (meaning we might want to update the relative
85 * position on the show)
88 this.updatePosition();
89 OpenLayers.Popup.prototype.show.apply(this, arguments);
94 * Since the popup is moving to a new px, it might need also to be moved
95 * relative to where the marker is. We first calculate the new
96 * relativePosition, and then we calculate the new px where we will
97 * put the popup, based on the new relative position.
99 * If the relativePosition has changed, we must also call
100 * updateRelativePosition() to make any visual changes to the popup
101 * which are associated with putting it in a new relativePosition.
104 * px - {<OpenLayers.Pixel>}
106 moveTo: function(px) {
107 var oldRelativePosition = this.relativePosition;
108 this.relativePosition = this.calculateRelativePosition(px);
110 var newPx = this.calculateNewPx(px);
112 var newArguments = new Array(newPx);
113 OpenLayers.Popup.prototype.moveTo.apply(this, newArguments);
115 //if this move has caused the popup to change its relative position,
116 // we need to make the appropriate cosmetic changes.
117 if (this.relativePosition != oldRelativePosition) {
118 this.updateRelativePosition();
126 * contentSize - {<OpenLayers.Size>} the new size for the popup's
127 * contents div (in pixels).
129 setSize:function(contentSize) {
130 OpenLayers.Popup.prototype.setSize.apply(this, arguments);
132 if ((this.lonlat) && (this.map)) {
133 var px = this.map.getLayerPxFromLonLat(this.lonlat);
139 * Method: calculateRelativePosition
142 * px - {<OpenLayers.Pixel>}
145 * {String} The relative position ("br" "tr" "tl" "bl") at which the popup
148 calculateRelativePosition:function(px) {
149 var lonlat = this.map.getLonLatFromLayerPx(px);
151 var extent = this.map.getExtent();
152 var quadrant = extent.determineQuadrant(lonlat);
154 return OpenLayers.Bounds.oppositeQuadrant(quadrant);
158 * Method: updateRelativePosition
159 * The popup has been moved to a new relative location, so we may want to
160 * make some cosmetic adjustments to it.
162 * Note that in the classic Anchored popup, there is nothing to do
163 * here, since the popup looks exactly the same in all four positions.
164 * Subclasses such as the AnchoredBubble and Framed, however, will
165 * want to do something special here.
167 updateRelativePosition: function() {
168 //to be overridden by subclasses
172 * Method: calculateNewPx
175 * px - {<OpenLayers.Pixel>}
178 * {<OpenLayers.Pixel>} The the new px position of the popup on the screen
179 * relative to the passed-in px.
181 calculateNewPx:function(px) {
182 var newPx = px.offset(this.anchor.offset);
184 //use contentSize if size is not already set
185 var size = this.size || this.contentSize;
187 var top = (this.relativePosition.charAt(0) == 't');
188 newPx.y += (top) ? -size.h : this.anchor.size.h;
190 var left = (this.relativePosition.charAt(1) == 'l');
191 newPx.x += (left) ? -size.w : this.anchor.size.w;
196 CLASS_NAME: "OpenLayers.Popup.Anchored"