diff options
-rw-r--r-- | modules/organize/css/organize.css | 12 | ||||
-rw-r--r-- | modules/organize/vendor/ext/js/DataView-more.js | 160 | ||||
-rw-r--r-- | modules/organize/views/organize_dialog.html.php | 26 |
3 files changed, 191 insertions, 7 deletions
diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index 6b034fc2..c14faf8c 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -42,6 +42,18 @@ visibility: visible; } +.g-organize div.drag-ghost { + width: 300px; + height: 180px; +} + +.g-organize div.drag-ghost div { + width: 72px; + height: 72px; + vertical-align: baseline; + float: left; +} + .g-organize div.drop-target { background: #eee; } diff --git a/modules/organize/vendor/ext/js/DataView-more.js b/modules/organize/vendor/ext/js/DataView-more.js new file mode 100644 index 00000000..1bab1e70 --- /dev/null +++ b/modules/organize/vendor/ext/js/DataView-more.js @@ -0,0 +1,160 @@ +/*! + * Ext JS Library 3.3.1 + * Copyright(c) 2006-2010 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +/** + * @class Ext.DataView.LabelEditor + * @extends Ext.Editor + * + */ +Ext.DataView.LabelEditor = Ext.extend(Ext.Editor, { + alignment: "tl-tl", + hideEl : false, + cls: "x-small-editor", + shim: false, + completeOnEnter: true, + cancelOnEsc: true, + labelSelector: 'span.x-editable', + + constructor: function(cfg, field){ + Ext.DataView.LabelEditor.superclass.constructor.call(this, + field || new Ext.form.TextField({ + allowBlank: false, + growMin:90, + growMax:240, + grow:true, + selectOnFocus:true + }), cfg + ); + }, + + init : function(view){ + this.view = view; + view.on('render', this.initEditor, this); + this.on('complete', this.onSave, this); + }, + + initEditor : function(){ + this.view.on({ + scope: this, + containerclick: this.doBlur, + click: this.doBlur + }); + this.view.getEl().on('mousedown', this.onMouseDown, this, {delegate: this.labelSelector}); + }, + + doBlur: function(){ + if(this.editing){ + this.field.blur(); + } + }, + + onMouseDown : function(e, target){ + if(!e.ctrlKey && !e.shiftKey){ + var item = this.view.findItemFromChild(target); + e.stopEvent(); + var record = this.view.store.getAt(this.view.indexOf(item)); + this.startEdit(target, record.data[this.dataIndex]); + this.activeRecord = record; + }else{ + e.preventDefault(); + } + }, + + onSave : function(ed, value){ + this.activeRecord.set(this.dataIndex, value); + } +}); + + +Ext.DataView.DragSelector = function(cfg){ + cfg = cfg || {}; + var view, proxy, tracker; + var rs, bodyRegion, dragRegion = new Ext.lib.Region(0,0,0,0); + var dragSafe = cfg.dragSafe === true; + + this.init = function(dataView){ + view = dataView; + view.on('render', onRender); + }; + + function fillRegions(){ + rs = []; + view.all.each(function(el){ + rs[rs.length] = el.getRegion(); + }); + bodyRegion = view.el.getRegion(); + } + + function cancelClick(){ + return false; + } + + function onBeforeStart(e){ + return !dragSafe || e.target == view.el.dom; + } + + function onStart(e){ + view.on('containerclick', cancelClick, view, {single:true}); + if(!proxy){ + proxy = view.el.createChild({cls:'x-view-selector'}); + }else{ + if(proxy.dom.parentNode !== view.el.dom){ + view.el.dom.appendChild(proxy.dom); + } + proxy.setDisplayed('block'); + } + fillRegions(); + view.clearSelections(); + } + + function onDrag(e){ + var startXY = tracker.startXY; + var xy = tracker.getXY(); + + var x = Math.min(startXY[0], xy[0]); + var y = Math.min(startXY[1], xy[1]); + var w = Math.abs(startXY[0] - xy[0]); + var h = Math.abs(startXY[1] - xy[1]); + + dragRegion.left = x; + dragRegion.top = y; + dragRegion.right = x+w; + dragRegion.bottom = y+h; + + dragRegion.constrainTo(bodyRegion); + proxy.setRegion(dragRegion); + + for(var i = 0, len = rs.length; i < len; i++){ + var r = rs[i], sel = dragRegion.intersect(r); + if(sel && !r.selected){ + r.selected = true; + view.select(i, true); + }else if(!sel && r.selected){ + r.selected = false; + view.deselect(i); + } + } + } + + function onEnd(e){ + if (!Ext.isIE) { + view.un('containerclick', cancelClick, view); + } + if(proxy){ + proxy.setDisplayed(false); + } + } + + function onRender(view){ + tracker = new Ext.dd.DragTracker({ + onBeforeStart: onBeforeStart, + onStart: onStart, + onDrag: onDrag, + onEnd: onEnd + }); + tracker.initEl(view.el); + } +};
\ No newline at end of file diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index a1d57958..d9303075 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -9,6 +9,7 @@ </style> <script type="text/javascript" src="<?= url::file("modules/organize/vendor/ext/js/ext-base.js") ?>"></script> <script type="text/javascript" src="<?= url::file("modules/organize/vendor/ext/js/ext-all.js") ?>"></script> +<script type="text/javascript" src="<?= url::file("modules/organize/vendor/ext/js/DataView-more.js") ?>"></script> <script type="text/javascript"> Ext.BLANK_IMAGE_URL = "<?= url::file("modules/organize/vendor/ext/images/default/s.gif") ?>"; Ext.Ajax.timeout = 1000000; // something really large @@ -87,6 +88,9 @@ autoScroll: true, enableDragDrop: true, itemSelector: "div.thumb", + plugins: [ + new Ext.DataView.DragSelector({dragSafe: true}) + ], listeners: { "render": function(v) { v.dragZone = new Ext.dd.DragZone(v.getEl(), { @@ -106,15 +110,23 @@ if (selected_nodes.length == 1) { drag_data.ddel = target; } else { - var div = document.createElement("div"); - div.className = "multi-proxy"; + var drag_ghost = document.createElement("div"); + drag_ghost.className = "drag-ghost"; for (var i = 0; i != selected_nodes.length; i++) { - div.appendChild(Ext.get(selected_nodes[i]).dom.firstChild.cloneNode(true)); - if ((i + 1) % 3 == 0) { - div.appendChild(document.createElement("br")); - } + var inner = document.createElement("div"); + drag_ghost.appendChild(inner); + + var img = Ext.get(selected_nodes[i]).dom.firstChild; + var child = inner.appendChild(img.cloneNode(true)); + Ext.get(child).setWidth(Ext.fly(img).getWidth() / 2); + Ext.get(child).setHeight(Ext.fly(img).getHeight() / 2); } - drag_data.ddel = div; + // The contents of the ghost float, and the ghost is wide enough for + // 4 images across so make sure that the ghost is tall enough. Thumbnails + // are max 120px high max, and ghost thumbs are half of that, but leave some + // padding because IE is unpredictable. + drag_ghost.style.height = Math.ceil(i/4) * 72 + "px"; + drag_data.ddel = drag_ghost; } return drag_data; } |