[Commits] r2573 - in sandbox/camptocamp/alpgis/geoext: examples lib/GeoExt/plugins resources tests/lib/GeoExt/plugins

commits at geoext.org commits at geoext.org
Fri Jan 21 15:33:57 CET 2011


Author: pgiraud
Date: 2011-01-21 15:33:57 +0100 (Fri, 21 Jan 2011)
New Revision: 2573

Added:
   sandbox/camptocamp/alpgis/geoext/examples/tree-actions.html
   sandbox/camptocamp/alpgis/geoext/examples/tree-actions.js
   sandbox/camptocamp/alpgis/geoext/lib/GeoExt/plugins/TreeNodeActions.js
   sandbox/camptocamp/alpgis/geoext/resources/bullet_arrow_down.png
   sandbox/camptocamp/alpgis/geoext/resources/bullet_arrow_up.png
   sandbox/camptocamp/alpgis/geoext/resources/delete.png
   sandbox/camptocamp/alpgis/geoext/tests/lib/GeoExt/plugins/TreeNodeActions.html
Log:
Applying patch for #348

Added: sandbox/camptocamp/alpgis/geoext/examples/tree-actions.html
===================================================================
--- sandbox/camptocamp/alpgis/geoext/examples/tree-actions.html	                        (rev 0)
+++ sandbox/camptocamp/alpgis/geoext/examples/tree-actions.html	2011-01-21 14:33:57 UTC (rev 2573)
@@ -0,0 +1,65 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>GeoExt Actions Tree</title>
+        
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/adapter/ext/ext-base.js"></script>
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/ext-all-debug.js"></script>
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-3.2.1/resources/css/ext-all.css" />
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-3.2.1/examples/shared/examples.css" />
+        <script src="http://www.openlayers.org/api/2.10/OpenLayers.js"></script>
+        <script type="text/javascript" src="../lib/GeoExt.js"></script>
+
+        <script type="text/javascript" src="tree-actions.js"></script>
+
+        <style type="text/css">
+        .gx-tree-layer-actions {
+            float: right;
+        }
+        .gx-tree-layer-action {
+            background-position: center center;
+            background-repeat: no-repeat;
+            border: 0 none;
+            height: 16px;
+            margin: 0;
+            padding: 0;
+            vertical-align: top;
+            width: 16px;
+        }
+        .gx-tree-layer-actions .delete {
+            background: transparent url(../resources/images/default/delete.png);
+        }
+        .gx-tree-layer-actions .up {
+            background: transparent url(../resources/images/default/bullet_arrow_up.png);
+        }
+        .gx-tree-layer-actions .down {
+            background: transparent url(../resources/images/default/bullet_arrow_down.png);
+        }
+        .gx-tree-layer-actions .disabled {
+            opacity: 0.2;
+        }
+        .x-tree-node-el {
+            border-bottom: 1px solid #ddd;
+        }
+        .x-tree-no-lines .x-tree-elbow,
+        .x-tree-no-lines .x-tree-elbow-end,
+        .x-tree-node-collapsed .x-tree-node-icon,
+        .x-tree-node-expanded .x-tree-node-icon,
+        .x-tree-node-leaf .gx-tree-layer-icon {
+           width: 0px; !important;
+        }
+    </style>
+
+    </head>
+    <body>
+        <div id="desc">
+            <h1>GeoExt Tree Node UI</h1>
+
+            <p>This example shows how to add tools (actions) in
+            tree nodes. The tools added here allow moving the layers up and
+            down and deleting them.</p>
+
+            <p>The js is not minified so it is readable. See
+            <a href="tree-actions.js">tree-actions.js</a>.</p>
+        </div>
+    </body>
+</html>

Added: sandbox/camptocamp/alpgis/geoext/examples/tree-actions.js
===================================================================
--- sandbox/camptocamp/alpgis/geoext/examples/tree-actions.js	                        (rev 0)
+++ sandbox/camptocamp/alpgis/geoext/examples/tree-actions.js	2011-01-21 14:33:57 UTC (rev 2573)
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2008-2009 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.namespace("GeoExt.examples");
+
+// this function takes action based on the "action"
+// parameter, it is used as a listener to layer
+// nodes' "action" events
+GeoExt.examples.onAction = function(node, action, evt) {
+    var layer = node.layer;
+    switch(action) {
+    case "down":
+        layer.map.raiseLayer(layer, -1);
+        break;
+    case "up":
+        layer.map.raiseLayer(layer, +1);
+        break;
+    case "delete":
+        layer.destroy();
+        break;
+    }
+};
+
+// custom layer node UI class
+GeoExt.examples.LayerNodeUI = Ext.extend(
+    GeoExt.tree.LayerNodeUI,
+    new GeoExt.tree.TreeNodeUIEventMixin()
+);
+
+Ext.onReady(function() {
+    Ext.QuickTips.init();
+
+    // the map panel
+    var mapPanel = new GeoExt.MapPanel({
+        border: true,
+        region: "center",
+        center: [146.1569825, -41.6109735],
+        zoom: 6,
+        layers: [
+            new OpenLayers.Layer.WMS("Tasmania State Boundaries",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_state_boundaries"
+                }, {
+                    buffer: 0,
+                    // exclude this layer from layer container nodes
+                    displayInLayerSwitcher: false
+               }),
+            new OpenLayers.Layer.WMS("Water",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_water_bodies",
+                    transparent: true,
+                    format: "image/gif"
+                }, {
+                    buffer: 0
+                }),
+            new OpenLayers.Layer.WMS("Cities",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_cities",
+                    transparent: true,
+                    format: "image/gif"
+                }, {
+                    buffer: 0
+                }),
+            new OpenLayers.Layer.WMS("Tasmania Roads",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_roads",
+                    transparent: true,
+                    format: "image/gif"
+                }, {
+                    buffer: 0
+                })
+        ]
+    });
+
+    // the layer tree panel. In this tree the node actions are set using 
+    // the loader's "baseAttrs" property.
+    var tree = new Ext.tree.TreePanel({
+        region: "west",
+        width: 250,
+        title: "Layer Tree",
+        loader: {
+            applyLoader: false,
+            uiProviders: {
+                "ui": GeoExt.examples.LayerNodeUI
+            }
+        },
+        // apply the tree node actions plugin to layer nodes
+        plugins: [{
+            ptype: "gx_treenodeactions",
+            listeners: {
+                action: GeoExt.examples.onAction
+            }
+        }],
+        root: {
+            nodeType: "gx_layercontainer",
+            loader: {
+                baseAttrs: {
+                    radioGroup: "radiogroup",
+                    uiProvider: "ui",
+                    actions: [{
+                        action: "delete",
+                        qtip: "delete"
+                    }, {
+                        action: "up",
+                        qtip: "move up",
+                        update: function(el) { 
+                            // "this" references the tree node 
+                            var layer = this.layer, map = layer.map; 
+                            if (map.getLayerIndex(layer) == map.layers.length - 1) { 
+                                el.addClass('disabled'); 
+                            } else { 
+                                el.removeClass('disabled'); 
+                            } 
+                        } 
+                    }, { 
+                        action: "down", 
+                        qtip: "move down", 
+                        update: function(el) { 
+                            // "this" references the tree node 
+                            var layer = this.layer, map = layer.map; 
+                            if (map.getLayerIndex(layer) == 1) { 
+                                el.addClass('disabled'); 
+                            } else { 
+                                el.removeClass('disabled'); 
+                            } 
+                        } 
+                    }]
+                }
+            }
+        },
+        rootVisible: false,
+        lines: false
+    });
+
+    // the viewport
+    new Ext.Viewport({
+        layout: "fit",
+        hideBorders: true,
+        items: {
+            layout: "border",
+            deferredRender: false,
+            items: [
+                mapPanel,
+                tree, {
+                region: "east",
+                contentEl: "desc",
+                width: 250
+            }]
+        }
+    });
+});

Added: sandbox/camptocamp/alpgis/geoext/lib/GeoExt/plugins/TreeNodeActions.js
===================================================================
--- sandbox/camptocamp/alpgis/geoext/lib/GeoExt/plugins/TreeNodeActions.js	                        (rev 0)
+++ sandbox/camptocamp/alpgis/geoext/lib/GeoExt/plugins/TreeNodeActions.js	2011-01-21 14:33:57 UTC (rev 2573)
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2008-2009 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.namespace("GeoExt.plugins");
+
+/** api: (define)
+ *  module = GeoExt.plugins
+ *  class = TreeNodeActions
+ */
+
+/** api: constructor
+ *  A plugin to create tree node UIs with actions.
+ *
+ *  An action is a clickable image in a tree node, which, when clicked,
+ *  leads to an "action" event being triggered by the node.
+ *
+ *  To set actions in a node an ``actions`` property must be provided in
+ *  the node config options. This property  is an array of 
+ *  action objects, each action object has the following property:
+ *
+ *  * "action" ``String`` the name of the action. It is used as
+ *    the name of the ``<img>`` class. The ``img`` tag being placed in a
+ *    div whose class is "gx-tree-layer-actions" a CSS selector for the
+ *    action is ``.gx-tree-layer-actions .action-name``. The name of the
+ *    action is also provided in the "action" event for listeners to know
+ *    which action got clicked. (required)
+ *  * "qtip" ``String`` the tooltip displayed when the action
+ *    image is hovered. (required)
+ *  * "update" ``Function`` a function executed after the action is
+ *    rendered in the node, it receives the ``Ext.Element`` object
+ *    representing the image and executes with the node as its
+ *    scope. For example, this function can be used to hide the
+ *    action based on some condition. (optional)
+ */
+
+/** api: example
+ *  Sample code to create a layer node UI with an actions mixin:
+ *
+ *  .. code-block:: javascript
+ *
+ *      var uiClass = Ext.extend(
+ *          GeoExt.tree.LayerNodeUI,
+ *          new GeoExt.plugins.TreeNodeActions()
+ *      );
+ *
+ */
+
+GeoExt.plugins.TreeNodeActions = Ext.extend(Ext.util.Observable, { 
+    /** private: constant[actionsCls]
+     */
+    actionsCls: "gx-tree-layer-actions",
+ 
+    /** private: constant[actionCls]
+     */
+    actionCls: "gx-tree-layer-action",
+
+    /** private: method[constructor]
+     *  :param config: ``Object``
+     */
+    constructor: function(config) {
+        Ext.apply(this.initialConfig, Ext.apply({}, config));
+        Ext.apply(this, config);
+
+        this.addEvents(
+
+            /** api: event[radiochange]
+             *  Fires when an action image is clicked.
+             *
+             *  Listener arguments:
+             *  
+             *  * node - ``Ext.TreeNode`` The node of the clicked action image.
+             */
+            "action"
+        );
+
+        GeoExt.plugins.TreeNodeActions.superclass.constructor.apply(this, arguments);
+    },
+
+    /** private: method[init]
+     *  :param tree: ``Ext.tree.TreePanel`` The tree.
+     */
+    init: function(tree) {
+        tree.on({
+            "rendernode": this.onRenderNode,
+            "rawclicknode": this.onRawClickNode,
+            "beforedestroy": this.onBeforeDestroy,
+            scope: this
+        });
+    },
+
+    /** private: method[onRenderNode]
+     *  :param node: ``Ext.tree.TreeNode``
+     */
+    onRenderNode: function(node) {
+        var rendered = node.rendered;
+        if(!rendered) {
+            var attr = node.attributes;
+            var actions = attr.actions || this.actions;
+            if(actions && actions.length > 0) {
+                var html = ['<div class="', this.actionsCls, '">'];
+                for(var i=0,len=actions.length; i<len; i++) {
+                    var a = actions[i];
+                    html = html.concat([
+                        '<img id="'+node.id+'_'+a.action,
+                        '" ext:qtip="'+a.qtip,
+                        '" src="'+Ext.BLANK_IMAGE_URL,
+                        '" class="'+this.actionCls+' '+a.action+'" />'
+                    ]);
+                }
+                html.concat(['</div>']);
+                Ext.DomHelper.insertFirst(node.ui.elNode, html.join(""));
+            }
+            if (node.layer.map) {
+                this.updateActions(node);
+            } else if (node.layerStore) {
+                node.layerStore.on({
+                    'bind': function() {
+                        this.updateActions(node);
+                    },
+                    scope: this
+                });
+            }
+        }
+    },
+
+    /** private: method[updateActions]
+     *
+     *  Update all the actions.
+     */
+    updateActions: function(node) {
+        var actions = node.attributes.actions || this.actions || [];
+        Ext.each(actions, function(a, index) {
+            var el = Ext.get(node.id + '_' + a.action);
+            if (el && typeof a.update == "function") {
+                a.update.call(node, el);
+            }
+        });
+    },
+ 
+    /** private: method[onRawClickNode]
+     *  :param node: ``Ext.tree.TreeNode``
+     *  :param e: ``Ext.EventObject``
+     */
+    onRawClickNode: function(node, e) {
+        if(e.getTarget('.' + this.actionCls, 1)) {
+            var t = e.getTarget('.' + this.actionCls, 1);
+            var action = t.className.replace(this.actionCls + ' ', '');
+            this.fireEvent("action", node, action, e);
+            return false;
+        }
+    },
+    
+    /** private: method[onBeforeDestroy]
+     */
+    onBeforeDestroy: function(tree) {
+        tree.un("rendernode", this.onRenderNode, this);
+        tree.un("rawclicknode", this.onRawClickNode, this);
+        tree.un("beforedestroy", this.onBeforeDestroy, this);
+    }
+});
+
+Ext.preg("gx_treenodeactions", GeoExt.plugins.TreeNodeActions);

Added: sandbox/camptocamp/alpgis/geoext/resources/bullet_arrow_down.png
===================================================================
(Binary files differ)


Property changes on: sandbox/camptocamp/alpgis/geoext/resources/bullet_arrow_down.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/camptocamp/alpgis/geoext/resources/bullet_arrow_up.png
===================================================================
(Binary files differ)


Property changes on: sandbox/camptocamp/alpgis/geoext/resources/bullet_arrow_up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/camptocamp/alpgis/geoext/resources/delete.png
===================================================================
(Binary files differ)


Property changes on: sandbox/camptocamp/alpgis/geoext/resources/delete.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/camptocamp/alpgis/geoext/tests/lib/GeoExt/plugins/TreeNodeActions.html
===================================================================
--- sandbox/camptocamp/alpgis/geoext/tests/lib/GeoExt/plugins/TreeNodeActions.html	                        (rev 0)
+++ sandbox/camptocamp/alpgis/geoext/tests/lib/GeoExt/plugins/TreeNodeActions.html	2011-01-21 14:33:57 UTC (rev 2573)
@@ -0,0 +1,84 @@
+<html>
+    <head>
+        <script src="../../../../../openlayers/lib/OpenLayers.js"></script>
+        <script src="../../../../../ext/adapter/ext/ext-base.js"></script>
+        <script src="../../../../../ext/ext-all-debug.js"></script>
+        <script src="../../../../lib/GeoExt.js"></script>
+    
+        <script>
+        function test_ui_node_action(t) {
+            t.plan(6);
+
+            // setup
+
+            var UI, node, tree, ui, elNode;
+
+            UI = Ext.extend(
+                GeoExt.tree.LayerNodeUI,
+                new GeoExt.tree.TreeNodeUIEventMixin()
+            );
+
+            node = new GeoExt.tree.LayerNode({
+                uiProvider: UI,
+                layer: new OpenLayers.Layer(),
+                actions: [{
+                    action: "foo-action",
+                    qtip: "foo-qtip"
+                }]
+            });
+            tree  = new Ext.tree.TreePanel({
+                renderTo: "tree",
+                root: node,
+                plugins: [new GeoExt.plugins.TreeNodeActions({
+                    listeners: {
+                        action: function(n, a, e) {
+                            log.push({n: n, a: a, e: e});
+                        }
+                    }
+                })]
+            });
+            ui = node.ui;
+            elNode = Ext.fly(ui.elNode);
+
+            // 2 tests
+            t.ok(elNode.first().hasClass("gx-tree-layer-actions"),
+                 "the actions div is at correct location and " +
+                 "has a correct class");
+            t.ok(elNode.first().first() &&
+                 elNode.first().first().hasClass("gx-tree-layer-action") &&
+                 elNode.first().first().hasClass("foo-action"),
+                 "the action div is at correct location and " +
+                 "has correct classes");
+
+            // simulate click
+            var log = [];
+            var e = {
+                getTarget: function(selector) {
+                    if (selector == "." + "gx-tree-layer-action") {
+                        return {
+                            className: "gx-tree-layer-action" + " foo-action"
+                        };
+                    }
+                }
+            };
+            
+            ui.onClick(e);
+            t.eq(log.length, 1,
+                 "click on action img triggers \"action\" event");
+            t.ok(log[0].n == node,
+                 "\"action\" listener given expected node");
+            t.eq(log[0].a, "foo-action",
+                 "\"action\" listener given expected action");
+            t.ok(log[0].e == e,
+                 "\"action\" listener given expected event");
+
+            // teardown
+
+            tree.destroy();
+        }
+        </script>
+    </head>
+    <body>
+        <div id="tree" style="width: 100px; height: 100px;"></div>
+    </body>
+</html>



More information about the Commits mailing list