[Commits] r214 - in sandbox/opengeo/drake/trunk: core/lib/GeoExt/widgets/popup core/tests core/tests/widgets examples
commits at geoext.org
commits at geoext.org
Sun Mar 1 03:00:58 CET 2009
Author: sbenthall
Date: 2009-03-01 03:00:57 +0100 (Sun, 01 Mar 2009)
New Revision: 214
Added:
sandbox/opengeo/drake/trunk/core/tests/widgets/
sandbox/opengeo/drake/trunk/core/tests/widgets/Popup.html
Modified:
sandbox/opengeo/drake/trunk/core/lib/GeoExt/widgets/popup/Popup.js
sandbox/opengeo/drake/trunk/core/tests/list-tests.html
sandbox/opengeo/drake/trunk/examples/popup.html
Log:
tests, better docs, and example improvement for Popup
Modified: sandbox/opengeo/drake/trunk/core/lib/GeoExt/widgets/popup/Popup.js
===================================================================
--- sandbox/opengeo/drake/trunk/core/lib/GeoExt/widgets/popup/Popup.js 2009-02-27 21:10:33 UTC (rev 213)
+++ sandbox/opengeo/drake/trunk/core/lib/GeoExt/widgets/popup/Popup.js 2009-03-01 02:00:57 UTC (rev 214)
@@ -1,34 +1,64 @@
-/*
- * POPUPS
+Ext.namespace("GeoExt.popup");
+/**
+ * Class: GeoExt.popup.Popup
+ * Popups are a specialized Window that supports anchoring
+ * to a particular feature in a MapPanel. When a popup
+ * is anchored to a feature, that means that the popup
+ * will visibly point to the feature on the map, and move
+ * accordingly when the map is panned or zoomed.
*
- * The plan here is to
- * use Ext component and call it a popup by making it follow the map.
- * Listens for events appropriately.
- * Styling to make it look like bubble with tail? Separate task. AH: Ext.Panel would be easier to style than Ext.Window
- * PopupManager -- for handling global logic.
+ * Usage example:
+ * (start code)
*
+ * var popup = new GeoExt.popup.Popup({
+ * title: 'My Popup',
+ * feature: feature,
+ * width: 200,
+ * html: "<div>Popup content</div>",
+ * collapsible: true
+ * })
+ *
+ * (end)
+ *
+ * Extends: Ext.Window
*/
-
-Ext.namespace("GeoExt.popup");
GeoExt.popup.Popup = Ext.extend(Ext.Window, {
- //is this double base class kosher?
- //it's probably not what I want.
- popupCls: "gx-popup",
-
+ /**
+ * APIProperty: anchored
+ * {Boolean} True if this popup begins anchored to
+ * its feature. Defaults to true.
+ */
anchored: true,
+ /**
+ * APIProperty: panIn
+ * {Boolean} True if the popup should pan the map so
+ * that the popup is fully in view when it is rendered. Default is true.
+ */
panIn: true,
+ /**
+ * APIProperty: unpinnable
+ * {Boolean} True if the popup should have a
+ * "unpin" tool that unanchors it from its feature.
+ * Default is true.
+ */
+ unpinnable: true,
+
+ /*
+ * Some Ext.Window defaults need to be overriden here
+ * because some Ext.Window behavior is not currently supported.
+ */
animCollapse: false,
- unpinnable: true,
-
draggable: false,
- //currently looks weird with shadow because of the anchor
shadow: false,
+ popupCls: "gx-popup",
+
+ //private
initComponent: function(){
this.baseCls = this.popupCls + " " + this.baseCls;
@@ -38,22 +68,18 @@
},
-
// private
onRender: function(ct, position){
-
GeoExt.popup.Popup.superclass.onRender.call(this, ct, position);
this.ancCls = this.popupCls + "-anc";
//create anchor dom element.
this.createElement("anc", this.el);
-
},
// private
initTools : function(){
-
if(this.unpinnable){
this.addTool({
id: 'unpin',
@@ -65,7 +91,17 @@
},
- /* Adds this popup to a MapPanel*/
+
+ /**
+ * APIMethod: addToMapPanel
+ * Adds this popup to a MapPanel. Assumes that the
+ * MapPanel's map is already initialized and that the
+ * Popup's feature is on the map.
+ *
+ * Parameters:
+ * mapPanel - {<GeoExt.MapPanel>} a MapPanel to which to
+ * add this popup.
+ */
addToMapPanel: function(mapPanel){
this.mapPanel = mapPanel;
this.map = this.mapPanel.map;
@@ -81,15 +117,16 @@
}
this.show();
-
+
+ /* Panning */
if(this.panIn){
this.panIntoView();
}
},
-
- //overwriting because need to take into account anchor height
+ //private
+ //overwriting because this needs to take into account anchor height
setSize: function(w, h){
if(this.anc){
var ancSize = this.getAnchorElement().getSize();
@@ -104,27 +141,28 @@
GeoExt.popup.Popup.superclass.setSize.call(this, w, h);
},
- /*
- * Positions the popup relative to its feature
- */
+ //private
+ // Positions the popup relative to its feature
position: function(){
var centerLonLat = this.feature.geometry.getBounds().getCenterLonLat();
var centerPx = this.map.getViewPortPxFromLonLat(centerLonLat);
- //this is for positioning with the anchor on the bottom.
- //will have to functionalize this later and allow
+ //This works for positioning with the anchor on the bottom.
+
+ //Will have to functionalize this out later and allow
//for other positions relative to the feature.
var anchorSelector = "div." + this.ancCls;
var dx = this.anc.down(anchorSelector).getLeft(true) + this.anc.down(anchorSelector).getWidth() / 2;
var dy = this.el.getHeight();
- //assuming for now that the map viewport takes up
+ //Assuming for now that the map viewport takes up
//the entire area of the MapPanel
this.setPosition(centerPx.x - dx, centerPx.y - dy);
},
+ //private
getAnchorElement: function(){
var anchorSelector = "div." + this.ancCls;
var anc = Ext.get(this.el.child(anchorSelector));
@@ -132,7 +170,7 @@
},
- /*
+ /* private
* Anchors a popup to its feature
* by registering listeners that reposition the popup
* when the map is moved.
@@ -159,14 +197,14 @@
this.position,
this
);
-
-
},
- /*
+ /**
+ * APIMethod: unanchor
+ * Unanchors a popup from its feature.
+ * Currently, this removes the popup from its MapPanel
+ * and adds it to the page body.
*
- *
- *
*/
unanchor: function(){
@@ -180,31 +218,23 @@
this.un("collapse", this.position);
this.un("expand", this.position);
- //Making the window draggable
-
- //may be kludgy to do this here.
- //other option would be to just create
- //a new popup that has same content, isn't
- //draggable.
+ //make the window draggable
this.draggable = true;
this.header.addClass("x-window-draggable");
this.dd = new Ext.Window.DD(this);
//remove anchor
- //var anchorSelector = "div." + this.ancCls;
- //var anc = Ext.get(this.el.child(anchorSelector));
- //anc.remove();
this.getAnchorElement().remove();
this.anc = null;
//hide unpin tool
this.tools.unpin.hide();
- //keep track of whether this has been collapsed
+ //keep track of whether the popup has been collapsed
var collapsed = this.collapsed;
//Steps to move this window out to the body
- //later, make 'unpinned' container configurable
+ //TODO: Make 'unpinned' container configurable
this.mapPanel.remove(this, false);
this.container = Ext.getBody()
@@ -215,6 +245,7 @@
this.setPagePosition(xy[0],xy[1]);
this.show();
+ //recollapse if it was collapsed before
if(collapsed){
this.collapse();
}
@@ -222,8 +253,10 @@
},
/*
- * Pans the map to move the popup completely into the
- * map viewport
+ * APIMethod: panIntoView
+ * Pans the MapPanel's map so that an anchored popup
+ * can come entirely into view, with padding specified
+ * as per normal OpenLayers.Map popup padding.
*/
panIntoView: function(){
if(!this.anchored){
@@ -236,6 +269,7 @@
var centerLonLat = this.feature.geometry.getBounds().getCenterLonLat();
var centerPx = this.map.getViewPortPxFromLonLat(centerLonLat);
+
//assumed viewport takes up whole body element of map panel
var popupPos = this.getPosition(true);
@@ -269,6 +303,7 @@
},
+ //private
//Cleanup. Not sure if this is the right way to do it.
beforeDestroy: function(){
this.map.events.un({
Modified: sandbox/opengeo/drake/trunk/core/tests/list-tests.html
===================================================================
--- sandbox/opengeo/drake/trunk/core/tests/list-tests.html 2009-02-27 21:10:33 UTC (rev 213)
+++ sandbox/opengeo/drake/trunk/core/tests/list-tests.html 2009-03-01 02:00:57 UTC (rev 214)
@@ -3,4 +3,5 @@
<li>data/FeatureStoreMediator.html</li>
<li>data/LayerStoreMediator.html</li>
<li>data/ProtocolProxy.html</li>
+ <li>widgets/Popup.html</li>
</ul>
Added: sandbox/opengeo/drake/trunk/core/tests/widgets/Popup.html
===================================================================
--- sandbox/opengeo/drake/trunk/core/tests/widgets/Popup.html (rev 0)
+++ sandbox/opengeo/drake/trunk/core/tests/widgets/Popup.html 2009-03-01 02:00:57 UTC (rev 214)
@@ -0,0 +1,204 @@
+<!DOCTYPE html>
+<html debug="true">
+ <head>
+ <script type="text/javascript" src="../../.././externals/ext/adapter/ext/ext-base.js"></script>
+ <script type="text/javascript" src="../../../../externals/ext/ext-all-debug.js"></script>
+
+ <script type="text/javascript" src="../../../../externals/openlayers/lib/OpenLayers.js"></script>
+
+ <script>
+ window.scriptLocation = "../../";
+ </script>
+ <script type="text/javascript" src="../../lib/GeoExt.js"></script>
+
+ <script type="text/javascript">
+
+ function makeFeature() {
+ return new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(100,50),
+ {
+ name : "My Feature"
+ }
+ )
+ }
+
+ function setupContext() {
+ var map = new OpenLayers.Map({
+ projection: new OpenLayers.Projection("EPSG:4326"),
+ })
+
+ var vector = new OpenLayers.Layer.Vector("Vector Layer",{
+ styleMap: new OpenLayers.StyleMap()
+ });
+
+ var feature = makeFeature();
+
+ vector.addFeatures(feature);
+ map.addLayers([
+ new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'} ),
+ vector
+ ]);
+
+ var view = new Ext.Viewport({
+ layout : "border",
+ items : [{
+ xtype: "gx_mappanel",
+ region: "center",
+ map : map
+ }]
+ });
+
+ return {
+ feature : feature,
+ vector : vector,
+ map : map,
+ mapPanel : view.items.items[0],
+ view : view
+ };
+
+ }
+
+
+ function popup(feature){
+ pop = new GeoExt.popup.Popup({
+ title: 'My Popup',
+ feature: feature,
+ width:200,
+ html: bogusMarkup,
+ collapsible: true
+ });
+
+ return pop;
+ }
+
+ var bogusMarkup = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit."
+
+ function test_addtomappanel(t) {
+ t.plan(1);
+
+ var context = setupContext();
+
+ var pop = popup(context.feature, context.mapPanel);
+
+ pop.addToMapPanel(context.mapPanel);
+
+ t.ok(context.mapPanel.el.child("div." + pop.popupCls),"Map panel contains popup");
+ }
+
+ function test_anchor(t) {
+ t.plan(4);
+
+ var context = setupContext();
+
+ var pop = popup(context.feature, context.mapPanel);
+
+ pop.addToMapPanel(context.mapPanel);
+
+ pop.on({
+ 'move' : function(c,x,y){
+ t.ok(true,"Move event fired on " + action); //should happen twice, on call to position()
+ },
+ scope : this
+ });
+
+ t.ok(pop.getAnchorElement(), "Popup has anchor element");
+
+ var action = "map move";
+ context.map.events.triggerEvent("move");
+
+ action = "popup collapse";
+ pop.collapse();
+
+ action = "popup expand"
+ pop.expand();
+ }
+
+
+ function test_unanchor(t) {
+ t.plan(6);
+
+ var context = setupContext();
+
+ var pop = popup(context.feature, context.mapPanel);
+
+ pop.addToMapPanel(context.mapPanel);
+
+ pop.collapse();
+
+ var origPos = pop.getPosition();
+
+ pop.unanchor();
+
+ var newPos = pop.getPosition();
+
+ t.ok(!pop.getAnchorElement(),"Anchor element removed");
+ t.ok(!this.collapsed, "Preserved collapsed state");
+ t.ok(!context.mapPanel.el.child("div." + pop.popupCls),"Map panel does not contain popup");
+ t.ok(Ext.getBody().child("div." + pop.popupCls),"Document body contains popup element");
+ t.eq(origPos[0],newPos[0],"Popup remains in same position (X)");
+ t.eq(origPos[1],newPos[1],"Popup remains in same position (Y)");
+
+ pop.on({
+ 'move' : function(c,x,y){
+ t.ok(false,"Move event fired improperly on " + action); //should happen twice, on call to position()
+ },
+ scope : this
+ });
+
+ var action = "map move";
+ context.map.events.triggerEvent("move");
+
+ action = "popup expand"
+ pop.expand();
+
+ action = "popup collapse";
+ pop.collapse();
+
+ }
+
+/*
+ function test_readRecords(t) {
+ t.plan(9);
+ // setup
+ var reader, features, info, records;
+ reader = new GeoExt.data.FeatureReader({}, [
+ {'name': 'foo'},
+ {'name': 'bar'}
+ ]);
+ features = [
+ new OpenLayers.Feature.Vector(null, {
+ 'foo': 'foo_0',
+ 'bar': 'bar_0'
+ }),
+ new OpenLayers.Feature.Vector()
+ ];
+ features[0].fid = 1;
+ features[0].state = OpenLayers.State.INSERT;
+ features[1].fid = 2;
+ features[1].state = OpenLayers.State.DELETE;
+ // 8 tests
+ info = reader.readRecords(features);
+ records = info.records;
+ t.eq(info.totalRecords, 2, 'readRecords returns correct number of records');
+ t.eq(records[0].get('foo'), 'foo_0', 'readRecords correctly set feature properties in record');
+ t.eq(records[0].get('fid'), 1, 'readRecords correctly set feature fid in record');
+ t.eq(records[0].get('state'), OpenLayers.State.INSERT, 'readRecords correctly set feature state in record');
+ t.ok(records[0].get('feature') == features[0], 'readRecords correctly set feature in record');
+ t.eq(records[1].get('fid'), 2, 'readRecords correctly set feature fid in record (no properties case)');
+ t.eq(records[1].get('state'), OpenLayers.State.DELETE, 'readRecords correctly set feature state in record (no properties case)');
+ t.ok(records[1].get('feature') == features[1], 'readRecords correctly set feature in record (no properties case)');
+ // 1 test
+ reader.totalRecords = 20;
+ info = reader.readRecords(features);
+ t.eq(info.totalRecords, 20,
+ "readRecords returns correct number of records");
+ }
+*/
+ </script>
+ <body>
+ <div id="map"></div>
+ </body>
+</html>
Property changes on: sandbox/opengeo/drake/trunk/core/tests/widgets/Popup.html
___________________________________________________________________
Name: svn:mime-type
+ text/html
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: sandbox/opengeo/drake/trunk/examples/popup.html
===================================================================
--- sandbox/opengeo/drake/trunk/examples/popup.html 2009-02-27 21:10:33 UTC (rev 213)
+++ sandbox/opengeo/drake/trunk/examples/popup.html 2009-03-01 02:00:57 UTC (rev 214)
@@ -62,8 +62,8 @@
closeAction: "hide",
width: 650,
height: 356,
- x: 40,
- y: 60,
+ x: 10,
+ y: 10,
items: {
xtype: "gx_mappanel",
region: "center",
@@ -117,5 +117,6 @@
<body>
<div id="map"></div>
<div id="container"></div>
+ <div>Click on the point in the map panel to open a popup.</div>
</body>
</html>
More information about the Commits
mailing list