[Commits] r2754 - sandbox/gxm/geoext/gxm/lib/widgets

commits at geoext.org commits at geoext.org
Wed Jul 20 14:54:09 CEST 2011


Author: marcjansen
Date: 2011-07-20 14:54:09 +0200 (Wed, 20 Jul 2011)
New Revision: 2754

Added:
   sandbox/gxm/geoext/gxm/lib/widgets/Button.js
   sandbox/gxm/geoext/gxm/lib/widgets/LayerList.js
   sandbox/gxm/geoext/gxm/lib/widgets/MapPanel.js
   sandbox/gxm/geoext/gxm/lib/widgets/SegmentedButton.js
Log:
move widgets to their own directory

Copied: sandbox/gxm/geoext/gxm/lib/widgets/Button.js (from rev 2739, sandbox/gxm/geoext/gxm/lib/Button.js)
===================================================================
--- sandbox/gxm/geoext/gxm/lib/widgets/Button.js	                        (rev 0)
+++ sandbox/gxm/geoext/gxm/lib/widgets/Button.js	2011-07-20 12:54:09 UTC (rev 2754)
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2008-2011 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+Ext.ns('GXM');
+
+GXM.Button = Ext.extend(Ext.Button, {
+    exclusiveGroup:null,
+    map: null,
+    mappanel: null,
+    uScope: null,
+    uHandler: null,
+    control:null,
+    initComponent : function(){
+        GXM.Button.superclass.initComponent.call(this);
+        
+        // register button for de/activating in exclusiveGroups
+        GXM.Button.manager.register(this);
+        
+        if (!this.map && this.mapPanel && this.mapPanel.map) {
+            this.map = this.mapPanel.map;  
+        } else if (!this.map && this.control && this.control.map) {
+            this.map = this.control.map;  
+        }
+        
+        // store the user scope and handlers
+        this.uScope = this.scope;
+        this.uHandler = this.handler;
+        
+        this.scope = this;
+        this.handler = this.pHandler;      
+        
+        if (this.control) {
+            if (this.map  && !this.control.map ) {
+                this.map.addControl(this.control);
+                if(this.pressed && this.control.map) {
+                    this.control.activate();
+                }
+                this.control.events.on({
+                    activate: this.onCtrlActivate,
+                    deactivate: this.onCtrlDeactivate,
+                    scope: this
+                });
+            }
+        }
+        
+    },
+
+    pHandler: function(cmp) {
+        var ctrl = this.control;
+        if(ctrl &&
+           ctrl.type === OpenLayers.Control.TYPE_BUTTON) {
+            ctrl.trigger();
+        } else {
+            if ( !ctrl.active ) {
+                ctrl.activate();
+            } else {
+                ctrl.deactivate();
+            }
+        }
+        if(this.uHandler) {
+            // adding the controls active state as last arg for the callback
+            var args = Ext.toArray(arguments);
+            args.push(ctrl.active);
+            this.uHandler.apply(this.uScope, args);
+        }
+    },
+          
+    getExclusiveGroupMembers: function() {
+        var members = [];
+        var myGroup = this.exclusiveGroup;
+        if (myGroup) {
+            GXM.Button.manager.each(function(id, btn) {
+                if(btn.exclusiveGroup === myGroup) {
+                    members.push(btn);
+                }
+            });
+        }
+        return members;
+    },
+    
+    onCtrlActivate: function(){
+        var exclusiveGroupMembers = this.getExclusiveGroupMembers();
+        var myId = this.id;
+        this._isDeactivating = true;
+        Ext.each(exclusiveGroupMembers, function(member) {
+            if (myId !== member.id) {
+                member.control.deactivate();
+                // we usually do not need to consider the visual apperance of 
+                // buttons, but the members of our exclusive grop might be 
+                // spread accross different gxm_segmentedbuttons
+                if (member.pressed) {
+                    member.pressed = false;
+                    member.removeCls(member.pressedCls);
+                }
+            }
+        });
+        this._isDeactivating = false;
+
+        if (!this.getEl().hasCls(this.pressedCls)) {
+            this.addCls(this.pressedCls);
+        }
+    },
+    onCtrlDeactivate: function(){
+        if(!this._isDeactivating) {
+            this.removeCls(this.pressedCls);
+        }
+    }
+});
+
+Ext.reg('gxm_button', GXM.Button);
+
+// usually a Ext.ComponentQuery.query('gxm_button[exclusiveGroup="humpty"]') 
+// would be enough, but it seems as if we currently hav a bug in sencha:
+// http://www.sencha.com/forum/showthread.php?120633-Ext.ComponentQuery.query()-not-working
+GXM.Button.manager = new Ext.AbstractManager();
\ No newline at end of file

Copied: sandbox/gxm/geoext/gxm/lib/widgets/LayerList.js (from rev 2739, sandbox/gxm/geoext/gxm/lib/LayerList.js)
===================================================================
--- sandbox/gxm/geoext/gxm/lib/widgets/LayerList.js	                        (rev 0)
+++ sandbox/gxm/geoext/gxm/lib/widgets/LayerList.js	2011-07-20 12:54:09 UTC (rev 2754)
@@ -0,0 +1,71 @@
+// requires model/Layer.js
+
+GXM.LayerList = Ext.extend(Ext.List, {
+    
+    layers: null,
+    
+    mapPanel: null,
+    
+    map: null,
+    
+    onItemTap: function(item, index, e){
+        var record = this.getStore().getAt(index);
+        var layer = record.get('layer');
+        if (layer.isBaseLayer) {
+            this.map.setBaseLayer(layer);
+        }
+        else {
+            layer.setVisibility(!layer.getVisibility());
+        }
+        this.refresh();
+        GXM.LayerList.superclass.onItemTap.call(this, arguments);
+    },
+    
+    initComponent: function(){
+        
+        if (this.mapPanel && this.mapPanel instanceof GXM.MapPanel) {
+            this.map = this.mapPanel.map;
+            this.store = this.mapPanel.layers;
+        } else {
+            this.store = this.layers || this.store;
+        }
+        
+        //TODO: or only one if that returns correct CSS-class?
+        this.itemTpl = new Ext.XTemplate(
+            '<tpl if="this.isVisible(layer)">', 
+                '<span class="gxm-visible-layer-indicator"></span>' ,
+            '</tpl>', 
+            '<tpl if="!this.isVisible(layer)">', 
+                '<span class="gxm-invisible-layer-indicator"></span>' ,
+            '</tpl>', 
+            '<span class="gxm-layer-item">{name}</span>',
+            {
+                // template member functions
+                isVisible: function(layer) {
+                    var visible = false;
+                    if (layer.isBaseLayer && layer.map.baseLayer === layer) {
+                        visible = true;
+                    } else {
+                        visible = !!layer.getVisibility();
+                    }
+                    return visible;
+                }
+            }
+        );
+
+        if (this.map) {
+            this.map.events.on({
+                "changelayer": this.onChangeLayer,
+                scope: this
+            });
+        }
+        
+        GXM.LayerList.superclass.initComponent.call(this);
+    },
+    
+    onChangeLayer: function(evt){
+        this.refresh();
+    }
+    
+});
+Ext.reg('gxm_layerlist', GXM.LayerList);

Copied: sandbox/gxm/geoext/gxm/lib/widgets/MapPanel.js (from rev 2739, sandbox/gxm/geoext/gxm/lib/MapPanel.js)
===================================================================
--- sandbox/gxm/geoext/gxm/lib/widgets/MapPanel.js	                        (rev 0)
+++ sandbox/gxm/geoext/gxm/lib/widgets/MapPanel.js	2011-07-20 12:54:09 UTC (rev 2754)
@@ -0,0 +1,279 @@
+Ext.ns('GXM');
+
+/**
+ * @requires lib/data/LayerStore.js
+ */
+
+// mappanel
+GXM.MapPanel = Ext.extend(Ext.Component, {
+    map: null,
+    center: null,
+    bounds: null,
+    //TODO: do we really wish to have this fullscreen?
+    //TODO: is this in any case a usefull default?
+    fullscreen: true, 
+    getDefaultControls: function() {
+        return [
+            new OpenLayers.Control.TouchNavigation(),
+            new OpenLayers.Control.Attribution()
+        ];   
+    },
+    initComponent: function(){
+        
+        
+        // check config-property map for an existing OpenLayers.Map-instance, a
+        // conf object for an OpenLayers.Map or null
+        if ( !(this.map instanceof OpenLayers.Map) ) {
+            this.controls = this.defaultControls;
+            var mapConf = Ext.applyIf(this.map || {}, {
+                allOverlays: true,
+                controls: this.getDefaultControls()
+            });
+            this.map = new OpenLayers.Map(mapConf);
+        }
+        // this.map is now initialized in any case
+        
+        
+        
+        // check config-property layers for any layers to be added to the map
+        if ( this.layers ) {
+            // normalize the case where this.layers was not an array but a layer 
+            if(this.layers instanceof OpenLayers.Layer) {
+                this.layers = [this.layers];
+            }
+            this.map.addLayers(this.layers);
+            
+        }
+        
+        // create a layerstore with the current maps layers
+        this.layers = new GXM.data.LayerStore({
+            data: this.map.layers
+        });
+        
+        // check config-property controls
+        if ( this.controls ) {
+            // normalize the case where this.controls was not an array but a control 
+            if(this.controls instanceof OpenLayers.Control) {
+                this.controls = [this.controls];
+            }
+            this.map.addControls(this.controls);
+        }
+        
+        // check config-property center
+        if ( Ext.isString(this.center) ) {
+            this.center = OpenLayers.LonLat.fromString(this.center);
+        } else if(Ext.isArray(this.center)) {
+            //TODO: this method does not exist. but IMO should
+            // this.center = OpenLayers.LonLat.fromArray(this.center);
+            this.center = new OpenLayers.LonLat(this.center[0], this.center[1]);
+        } 
+
+        
+        // check config-property bounds
+        if ( Ext.isString(this.extent) ) {
+            this.extent = OpenLayers.Bounds.fromString(this.extent);
+        } else if(Ext.isArray(this.extent)) {
+            this.extent = OpenLayers.Bounds.fromArray(this.extent);
+        }
+        GXM.MapPanel.superclass.initComponent.call(this);
+        // events
+        this.addEvents(
+            /** private: event[aftermapmove]
+             *  Fires after the map is moved.
+             */
+            "aftermapmove",
+
+            /** private: event[afterlayervisibilitychange]
+             *  Fires after a layer changed visibility.
+             */
+            "afterlayervisibilitychange",
+
+            /** private: event[afterlayeropacitychange]
+             *  Fires after a layer changed opacity.
+             */
+            "afterlayeropacitychange",
+
+            /** private: event[afterlayerorderchange]
+             *  Fires after a layer order changed.
+             */
+            "afterlayerorderchange",
+
+            /** private: event[afterlayernamechange]
+             *  Fires after a layer name changed.
+             */
+            "afterlayernamechange",
+
+            /** private: event[afterlayeradd]
+             *  Fires after a layer added to the map.
+             */
+            "afterlayeradd",
+
+            /** private: event[afterlayerremove]
+             *  Fires after a layer removed from the map.
+             */
+            "afterlayerremove"
+        );
+        this.map.events.on({
+            "moveend": this.onMoveend,
+            "changelayer": this.onChangelayer,
+            "addlayer": this.onAddlayer,
+            "removelayer": this.onRemovelayer,
+            scope: this
+        });
+        
+        
+    },
+    /** private: method[onMoveend]
+     *
+     *  The "moveend" listener.
+     */
+    onMoveend: function() {
+        this.fireEvent("aftermapmove");
+    },
+
+    /** private: method[onChangelayer]
+     *  :param e: ``Object``
+     *
+     * The "changelayer" listener.
+     */
+    onChangelayer: function(e) {
+        if(e.property) {
+            if(e.property === "visibility") {
+                this.fireEvent("afterlayervisibilitychange");
+            } else if(e.property === "order") {
+                this.fireEvent("afterlayerorderchange");
+            } else if(e.property === "name") {
+                this.fireEvent("afterlayernamechange");
+            } else if(e.property === "opacity") {
+                this.fireEvent("afterlayeropacitychange");
+            }
+        }
+    },
+
+    /** private: method[onAddlayer]
+     */
+    onAddlayer: function() {
+		
+		//CM
+		// update the layerstore by creating a new one 
+		// with the current maps layers
+		//TODO: sync?
+        this.layers = new GXM.data.LayerStore({
+            data: this.map.layers
+        });
+		
+        this.fireEvent("afterlayeradd");
+    },
+
+    /** private: method[onRemovelayer]
+     */
+    onRemovelayer: function() {
+		
+		//CM
+		// update the layerstore by creating a new one 
+		// with the current maps layers
+		//TODO: sync?
+        this.layers = new GXM.data.LayerStore({
+            data: this.map.layers
+        });
+		
+        this.fireEvent("afterlayerremove");
+    },
+      
+    afterRender: function(){
+        GXM.MapPanel.superclass.afterRender.apply(this, arguments);
+        var me = this;
+        if(!me.ownerCt) {
+            me.renderMap();
+        } else {
+            //TODO: check if we need this
+            me.ownerCt.on("move", me.updateMapSize, me);
+            me.ownerCt.on({
+                "afterlayout": {
+                    fn: me.renderMap,
+                    scope: me,
+                    single: true
+                }
+            });
+        }
+    },
+    renderMap: function(){
+        var me = this;
+        var map = me.map;
+        
+        if (me.el && me.el.dom && me.el.dom.firstChild) {
+            Ext.fly(me.el.dom.firstChild).remove();
+        }
+        map.render(me.el.dom);
+        
+        if (!map.getCenter()) {
+            
+            if (this.center || this.zoom ) {
+                // center and/or zoom?
+                map.setCenter(this.center, this.zoom);
+            } else if (this.extent instanceof OpenLayers.Bounds) {
+                // extent
+                map.zoomToExtent(this.extent, true);
+            }else {           
+                map.zoomToMaxExtent();
+            }    
+        }      
+    },
+    //TODO: check if we need this
+    updateMapSize: function() {
+        if(this.map) {
+            this.map.updateSize();
+        }
+    },
+    
+    
+    /** private: method[beforeDestroy]
+     *  Private method called during the destroy sequence.
+     */
+    beforeDestroy: function() {
+        if(this.ownerCt) {
+            this.ownerCt.un("move", this.updateMapSize, this);
+        }
+        if(this.map && this.map.events) {
+            this.map.events.un({
+                "moveend": this.onMoveend,
+                "changelayer": this.onChangelayer,
+                "addlayer": this.onAddlayer,
+                "removelayer": this.onRemovelayer,
+                scope: this
+            });
+        }
+        // if the map panel was passed a map instance, this map instance
+        // is under the user's responsibility
+        if(!this.initialConfig.map ||
+           !(this.initialConfig.map instanceof OpenLayers.Map)) {         
+            if(this.map && this.map.destroy) {
+                this.map.destroy();
+            }
+        }
+        delete this.map;
+        GXM.MapPanel.superclass.beforeDestroy.apply(this, arguments);
+    }
+    
+});
+
+/** api: function[guess]
+ *  :return: ``GXM.MapPanel`` The first map panel found by the Ext
+ *      component manager.
+ *  
+ *  Convenience function for guessing the map panel of an application. This
+ *     can reliably be used for all applications that just have one map panel
+ *     in the viewport.
+ */
+GXM.MapPanel.guess = function() {
+    var guess;
+    Ext.ComponentMgr.all.each(function(cmpId, cmp) { 
+        if (cmp instanceof GXM.MapPanel) {
+            guess = cmp;
+            return false; // return early
+        } 
+    });
+    return guess;
+};
+
+Ext.reg('gxm_mappanel', GXM.MapPanel);

Copied: sandbox/gxm/geoext/gxm/lib/widgets/SegmentedButton.js (from rev 2739, sandbox/gxm/geoext/gxm/lib/SegmentedButton.js)
===================================================================
--- sandbox/gxm/geoext/gxm/lib/widgets/SegmentedButton.js	                        (rev 0)
+++ sandbox/gxm/geoext/gxm/lib/widgets/SegmentedButton.js	2011-07-20 12:54:09 UTC (rev 2754)
@@ -0,0 +1,50 @@
+Ext.ns('GXM');
+GXM.SegmentedButton = Ext.extend(Ext.SegmentedButton, {
+    initComponent: function(){
+        // we need to adjust the defaults-property so that child elements 
+        // (buttons) act as expected and all have the needed properties:
+        //   - map => the same the segmented button belongs to
+        //   - xtype => 'gxm_button'
+        //   - exclusiveGroup (only needed sometimes, see below)
+                
+        // if we were called with an exclusiveGroup-property, we guess that the
+        // user wants to disallowMultiple in any case:
+        if (this.exclusiveGroup) {
+            this.allowMultiple = false;
+        }
+        
+        // initialize the soon to be default for child buttons
+        var exclusiveGroup;
+        // shall we act as an exclusive group of buttons? 
+        if (!this.allowMultiple) {
+            // yes, do we already have a group name?
+            if(!this.exclusiveGroup) {
+                // no, generate_one
+                this.exclusiveGroup = Ext.id(null, "gxm-gen-exclusive-group");
+            }
+            exclusiveGroup = this.exclusiveGroup;
+        }
+        
+        // this are the defaults for all child-buttons
+        var defaults = {
+            map: this.map,
+            xtype: 'gxm_button',
+            exclusiveGroup: exclusiveGroup
+        };
+        
+        // apply to any supplied defaults when constructing this segmented 
+        // button 
+        var appliedDefaults = Ext.applyIf(this.defaults || {}, defaults);        
+        this.defaults = appliedDefaults;
+        
+        // if we only have one item, than this segmented button
+        // acts as if he was a toggleButton (like in Ext JS).
+        // to mimic this behaviour we simply allowDepress in that case:
+        if (this.items && this.items.length === 1) {
+            this.allowDepress = true;
+        }
+        
+        GXM.SegmentedButton.superclass.initComponent.call(this);
+    }    
+});
+Ext.reg('gxm_segmentedbutton', GXM.SegmentedButton);
\ No newline at end of file



More information about the Commits mailing list