[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