--- /dev/null
+<html>\r
+<head>\r
+ <title>The source code</title>\r
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
+</head>\r
+<body onload="prettyPrint();">\r
+ <pre class="prettyprint lang-js">Ext.onReady(function(){\r
+\r
+ Ext.QuickTips.init();\r
+ // Album toolbar\r
+ var newIndex = 3;\r
+ var tb = new Ext.Toolbar({\r
+ items:[{\r
+ text: 'New Album',\r
+ iconCls: 'album-btn',\r
+ handler: function(){\r
+ var node = root.appendChild(new Ext.tree.TreeNode({\r
+ text:'Album ' + (++newIndex),\r
+ cls:'album-node',\r
+ allowDrag:false\r
+ }));\r
+ tree.getSelectionModel().select(node);\r
+ setTimeout(function(){\r
+ ge.editNode = node;\r
+ ge.startEdit(node.ui.textNode);\r
+ }, 10);\r
+ }\r
+ }]\r
+ });\r
+\r
+ // set up the Album tree\r
+ var tree = new Ext.tree.TreePanel({\r
+ // tree\r
+ animate:true,\r
+ enableDD:true,\r
+ containerScroll: true,\r
+ ddGroup: 'organizerDD',\r
+ rootVisible:false,\r
+ // layout\r
+ region:'west',\r
+ width:200,\r
+ split:true,\r
+ // panel\r
+ title:'My Albums',\r
+ autoScroll:true,\r
+ tbar: tb,\r
+ margins: '5 0 5 5'\r
+ });\r
+\r
+ var root = new Ext.tree.TreeNode({\r
+ text: 'Albums',\r
+ allowDrag:false,\r
+ allowDrop:false\r
+ });\r
+ tree.setRootNode(root);\r
+\r
+ root.appendChild(\r
+ new Ext.tree.TreeNode({text:'Album 1', cls:'album-node', allowDrag:false}),\r
+ new Ext.tree.TreeNode({text:'Album 2', cls:'album-node', allowDrag:false}),\r
+ new Ext.tree.TreeNode({text:'Album 3', cls:'album-node', allowDrag:false})\r
+ );\r
+\r
+ // add an inline editor for the nodes\r
+ var ge = new Ext.tree.TreeEditor(tree, {/* fieldconfig here */ }, {\r
+ allowBlank:false,\r
+ blankText:'A name is required',\r
+ selectOnFocus:true\r
+ });\r
+\r
+ // Set up images view\r
+\r
+ var view = new Ext.DataView({\r
+ itemSelector: 'div.thumb-wrap',\r
+ style:'overflow:auto',\r
+ multiSelect: true,\r
+ plugins: new Ext.DataView.DragSelector({dragSafe:true}),\r
+ store: new Ext.data.JsonStore({\r
+ url: '../view/get-images.php',\r
+ autoLoad: true,\r
+ root: 'images',\r
+ id:'name',\r
+ fields:[\r
+ 'name', 'url',\r
+ {name: 'shortName', mapping: 'name', convert: shortName}\r
+ ]\r
+ }),\r
+ tpl: new Ext.XTemplate(\r
+ '<tpl for=".">',\r
+ '<div class="thumb-wrap" id="{name}">',\r
+ '<div class="thumb"><img src="../view/{url}" class="thumb-img"></div>',\r
+ '<span>{shortName}</span></div>',\r
+ '</tpl>'\r
+ )\r
+ });\r
+\r
+ var images = new Ext.Panel({\r
+ id:'images',\r
+ title:'My Images',\r
+ region:'center',\r
+ margins: '5 5 5 0',\r
+ layout:'fit',\r
+ \r
+ items: view\r
+ });\r
+\r
+ var layout = new Ext.Panel({\r
+ layout: 'border',\r
+ width:650,\r
+ height:400,\r
+ items: [tree, images]\r
+ });\r
+\r
+ layout.render('layout');\r
+\r
+ var dragZone = new ImageDragZone(view, {containerScroll:true,\r
+ ddGroup: 'organizerDD'});\r
+});\r
+\r
+\r
+\r
+<div id="method-App.user.FormPanel-ImageDragZone"></div>/**\r
+ * Create a DragZone instance for our JsonView\r
+ */\r
+ImageDragZone = function(view, config){\r
+ this.view = view;\r
+ ImageDragZone.superclass.constructor.call(this, view.getEl(), config);\r
+};\r
+Ext.extend(ImageDragZone, Ext.dd.DragZone, {\r
+ // We don't want to register our image elements, so let's \r
+ // override the default registry lookup to fetch the image \r
+ // from the event instead\r
+ getDragData : function(e){\r
+ var target = e.getTarget('.thumb-wrap');\r
+ if(target){\r
+ var view = this.view;\r
+ if(!view.isSelected(target)){\r
+ view.onClick(e);\r
+ }\r
+ var selNodes = view.getSelectedNodes();\r
+ var dragData = {\r
+ nodes: selNodes\r
+ };\r
+ if(selNodes.length == 1){\r
+ dragData.ddel = target;\r
+ dragData.single = true;\r
+ }else{\r
+ var div = document.createElement('div'); // create the multi element drag "ghost"\r
+ div.className = 'multi-proxy';\r
+ for(var i = 0, len = selNodes.length; i < len; i++){\r
+ div.appendChild(selNodes[i].firstChild.firstChild.cloneNode(true)); // image nodes only\r
+ if((i+1) % 3 == 0){\r
+ div.appendChild(document.createElement('br'));\r
+ }\r
+ }\r
+ var count = document.createElement('div'); // selected image count\r
+ count.innerHTML = i + ' images selected';\r
+ div.appendChild(count);\r
+ \r
+ dragData.ddel = div;\r
+ dragData.multi = true;\r
+ }\r
+ return dragData;\r
+ }\r
+ return false;\r
+ },\r
+\r
+ // this method is called by the TreeDropZone after a node drop\r
+ // to get the new tree node (there are also other way, but this is easiest)\r
+ getTreeNode : function(){\r
+ var treeNodes = [];\r
+ var nodeData = this.view.getRecords(this.dragData.nodes);\r
+ for(var i = 0, len = nodeData.length; i < len; i++){\r
+ var data = nodeData[i].data;\r
+ treeNodes.push(new Ext.tree.TreeNode({\r
+ text: data.name,\r
+ icon: '../view/'+data.url,\r
+ data: data,\r
+ leaf:true,\r
+ cls: 'image-node'\r
+ }));\r
+ }\r
+ return treeNodes;\r
+ },\r
+ \r
+ // the default action is to "highlight" after a bad drop\r
+ // but since an image can't be highlighted, let's frame it \r
+ afterRepair:function(){\r
+ for(var i = 0, len = this.dragData.nodes.length; i < len; i++){\r
+ Ext.fly(this.dragData.nodes[i]).frame('#8db2e3', 1);\r
+ }\r
+ this.dragging = false; \r
+ },\r
+ \r
+ // override the default repairXY with one offset for the margins and padding\r
+ getRepairXY : function(e){\r
+ if(!this.dragData.multi){\r
+ var xy = Ext.Element.fly(this.dragData.ddel).getXY();\r
+ xy[0]+=3;xy[1]+=3;\r
+ return xy;\r
+ }\r
+ return false;\r
+ }\r
+});\r
+\r
+// Utility functions\r
+\r
+function shortName(name){\r
+ if(name.length > 15){\r
+ return name.substr(0, 12) + '...';\r
+ }\r
+ return name;\r
+};\r
+</pre> \r
+</body>\r
+</html>
\ No newline at end of file