From 8e21dda195015a3c9420553f874c10d3ebfa5dfa Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 3 Jan 2011 20:24:21 -0800 Subject: Complete rewrite of the organize module in Javascript using the Sencha JavaScript library. It's got all the functionality from the Flash version except it doesn't support creating new albums or uploading photos. Only tested in Chrome 10.0.x so far. --- modules/organize/css/organize.css | 60 +++++++++++++++++++++++++++++++++ modules/organize/css/organize_theme.css | 18 ---------- 2 files changed, 60 insertions(+), 18 deletions(-) create mode 100644 modules/organize/css/organize.css delete mode 100644 modules/organize/css/organize_theme.css (limited to 'modules/organize/css') diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css new file mode 100644 index 00000000..00395520 --- /dev/null +++ b/modules/organize/css/organize.css @@ -0,0 +1,60 @@ +.g-organize { + font-family: 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; +} + +.g-organize div.thumb { + padding: 8px; + margin: 8px; +} + +.g-organize div.selected { + background: #C9D8EB; +} + +.g-organize div.thumb img { + border: 4px solid white; +} + +.g-organize div.thumb:hover { + border: 2px solid #eee; + margin: 6px; + cursor: pointer; +} + +.g-organize div.thumb { + display: inline-block; +} + +.g-organize div.thumb div.icon { + position: relative; + padding: 0px; + margin: 0px; + visibility: hidden; + width: 16px; + height: 16px; + top: -16px; + margin-bottom: -16px; + padding-bottom: -16px; +} + +.g-organize div.thumb-album div.icon { + visibility: visible; +} + +.g-organize div.drop-target { + background: #eee; +} + +.g-organize div.active { + border-left: 4px solid #C9D8EB; + margin-left: 4px; +} + +div.multi-proxy div { + display: inline-block; +} + +.g-organize .x-tree-node-el { + font-size: 12px; + line-height: 20px; +} diff --git a/modules/organize/css/organize_theme.css b/modules/organize/css/organize_theme.css deleted file mode 100644 index e698f88d..00000000 --- a/modules/organize/css/organize_theme.css +++ /dev/null @@ -1,18 +0,0 @@ -/** ******************************************************************* - * Organize styles that are theme overrideable - *********************************************************************/ -#g-organize { - background-color: #FFFFFF; - border: 0px solid #000000; - color: #0E2B52; -} - -#g-organize-hover { - background-color: #CFDEFF; - display: none; -} - -#g-organize-active { - background-color: #6699CC; - display: none; -} -- cgit v1.2.3 From 51d66df1924b9fb835ed741042beddce4f6e899f Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 4 Jan 2011 00:14:53 -0800 Subject: Switch to using Ext.Element.mask for a custom busy message that looks a little cleaner. --- modules/organize/css/organize.css | 9 +++++++ modules/organize/views/organize_dialog.html.php | 32 +++++++++++++++---------- 2 files changed, 29 insertions(+), 12 deletions(-) (limited to 'modules/organize/css') diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index 00395520..be449138 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -58,3 +58,12 @@ div.multi-proxy div { font-size: 12px; line-height: 20px; } + +.loading div { + font-size: 1.1em; + padding-left: 24px; + background-color: white; + background-image: url(../vendor/ext/images/default/tree/loading.gif); + background-position: 4px 8px; + background-repeat: no-repeat; +} diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index 7c812f32..a3b1a1c5 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -20,13 +20,21 @@ * Utility functions for loading data and making changes * ******************************************************************************** */ + var start_busy = function(msg) { + outer.el.mask(msg, "loading"); + } + + var stop_busy = function() { + outer.el.unmask(); + } + var current_album_id = null; var load_album_data = function(id) { - Ext.Msg.wait(for_js() ?>); + start_busy(for_js() ?>); Ext.Ajax.request({ url: ''.replace("__ID__", id), success: function(xhr, opts) { - Ext.Msg.hide(); + stop_busy(); var album_info = Ext.util.JSON.decode(xhr.responseText); var store = new Ext.data.JsonStore({ autoDestroy: true, @@ -41,7 +49,7 @@ sort_order_combobox.setValue(album_info.sort_order); }, failure: function() { - Ext.Msg.hide(); + stop_busy(); Ext.Msg.alert( for_js() ?>); } @@ -55,17 +63,17 @@ }; var set_album_sort = function(params) { - Ext.Msg.wait(for_js() ?>); + start_busy(for_js() ?>); params['csrf'] = ''; Ext.Ajax.request({ url: ''.replace("__ID__", current_album_id), method: "post", success: function() { - Ext.Msg.hide(); + stop_busy(); reload_album_data(); }, failure: function() { - Ext.Msg.hide(); + stop_busy(); Ext.Msg.alert( for_js() ?>); }, @@ -137,16 +145,16 @@ for (var i = 0; i != nodes.length; i++) { source_ids.push(Ext.fly(nodes[i]).getAttribute("rel")); } - Ext.Msg.wait(for_js() ?>); + start_busy(for_js() ?>); Ext.Ajax.request({ url: '', method: "post", success: function() { - Ext.Msg.hide(); + stop_busy(); reload_album_data(); }, failure: function() { - Ext.Msg.hide(); + stop_busy(); Ext.Msg.alert( for_js() ?>); }, @@ -293,12 +301,12 @@ source_ids.push(node.getAttribute("rel")); } var target_id = target.getAttribute("ext:tree-node-id"); - Ext.Msg.wait(for_js() ?>); + start_busy(for_js() ?>); Ext.Ajax.request({ url: '', method: "post", success: function() { - Ext.Msg.hide(); + stop_busy(); reload_album_data(); v.getNodeById(target_id).reload(); @@ -311,7 +319,7 @@ } }, failure: function() { - Ext.Msg.hide(); + stop_busy(); Ext.Msg.alert( for_js() ?>); }, -- cgit v1.2.3 From 372905bd1310fc446db795661e1eb013674e5a75 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Wed, 5 Jan 2011 02:00:40 -0800 Subject: Support moving an item before or after the target. --- modules/organize/controllers/organize.php | 11 ++++++++--- modules/organize/css/organize.css | 7 ++++++- modules/organize/views/organize_dialog.html.php | 23 +++++++++++++++++------ 3 files changed, 31 insertions(+), 10 deletions(-) (limited to 'modules/organize/css') diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 18e6054b..c23d6d61 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -103,7 +103,7 @@ class Organize_Controller extends Controller { json::reply(null); } - function move_before() { + function rearrange() { access::verify_csrf(); $input = Input::instance(); @@ -125,20 +125,25 @@ class Organize_Controller extends Controller { } $source_ids = explode(",", $input->post("source_ids")); + $base_weight = $target->weight; + if ($input->post("relative") == "after") { + $base_weight++; + } + if ($source_ids) { // Make a hole the right size db::build() ->update("items") ->set("weight", db::expr("`weight` + " . count($source_ids))) ->where("parent_id", "=", $album->id) - ->where("weight", ">=", $target->weight) + ->where("weight", ">=", $base_weight) ->execute(); // Move all the source items to the right spots. for ($i = 0; $i < count($source_ids); $i++) { $source = ORM::factory("item", $source_ids[$i]); if ($source->parent_id = $album->id) { - $source->weight = $target->weight + $i; + $source->weight = $base_weight + $i; $source->save(); } } diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index be449138..82de9ad7 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -45,11 +45,16 @@ background: #eee; } -.g-organize div.active { +.g-organize div.active-left { border-left: 4px solid #C9D8EB; margin-left: 4px; } +.g-organize div.active-right { + border-right: 4px solid #C9D8EB; + margin-right: 4px; +} + div.multi-proxy div { display: inline-block; } diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index 773e1955..a482fb92 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -131,13 +131,22 @@ getTargetFromEvent: function(e) { return e.getTarget("div.thumb", 10); }, - onNodeEnter: function(target, dd, e, data) { - Ext.fly(target).addClass("active"); - }, onNodeOut: function(target, dd, e, data) { - Ext.fly(target).removeClass("active"); + Ext.fly(target).removeClass("active-left"); + Ext.fly(target).removeClass("active-right"); }, onNodeOver: function(target, dd, e, data) { + var target_x = Ext.lib.Dom.getX(target); + var target_center = target_x + (target.offsetWidth / 2); + if (Ext.lib.Event.getPageX(e) < target_center) { + Ext.fly(target).addClass("active-left"); + Ext.fly(target).removeClass("active-right"); + this.drop_side = "before"; + } else { + Ext.fly(target).removeClass("active-left"); + Ext.fly(target).addClass("active-right"); + this.drop_side = "after"; + } return Ext.dd.DropZone.prototype.dropAllowed; }, onNodeDrop: function(target, dd, e, data) { @@ -147,8 +156,9 @@ source_ids.push(Ext.fly(nodes[i]).getAttribute("rel")); } start_busy(for_js() ?>); + target = Ext.fly(target); Ext.Ajax.request({ - url: '', + url: '', method: "post", success: function() { stop_busy(); @@ -161,7 +171,8 @@ }, params: { source_ids: source_ids.join(","), - target_id: Ext.fly(target).getAttribute("rel"), + target_id: target.getAttribute("rel"), + relative: this.drop_side, // calculated in onNodeOver csrf: '' } }); -- cgit v1.2.3 From 28760daaefebf802dbe28ac171ea16aef3007418 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Wed, 5 Jan 2011 20:11:32 -0800 Subject: Improve IE grid compatibility by forcing a regular width/height for thumbnails and using float: left. --- modules/organize/css/organize.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'modules/organize/css') diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index 82de9ad7..81f41f21 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -5,6 +5,10 @@ .g-organize div.thumb { padding: 8px; margin: 8px; + width: 128px; + height: 128px; + vertical-align: middle; + float: left; } .g-organize div.selected { @@ -21,10 +25,6 @@ cursor: pointer; } -.g-organize div.thumb { - display: inline-block; -} - .g-organize div.thumb div.icon { position: relative; padding: 0px; -- cgit v1.2.3 From ce70669b8f09a9154723df80992ab6afe02c1d5c Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Wed, 5 Jan 2011 21:17:11 -0800 Subject: Visual tweaks for IE8 compatibility. Set the min width and min height to what IE8 wants the thumbnail's box to be when the inner image maxes out at 120 pixels (specified in Organize_Controller::album_info()). Avoid using inline-block. --- modules/organize/css/organize.css | 9 +++------ modules/organize/views/organize_dialog.html.php | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'modules/organize/css') diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index 81f41f21..6b034fc2 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -5,8 +5,8 @@ .g-organize div.thumb { padding: 8px; margin: 8px; - width: 128px; - height: 128px; + width: 144px; + height: 149px; vertical-align: middle; float: left; } @@ -17,6 +17,7 @@ .g-organize div.thumb img { border: 4px solid white; + margin: 0px; } .g-organize div.thumb:hover { @@ -55,10 +56,6 @@ margin-right: 4px; } -div.multi-proxy div { - display: inline-block; -} - .g-organize .x-tree-node-el { font-size: 12px; line-height: 20px; diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index 8ba9b3cc..eaba6cdd 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -109,7 +109,7 @@ var div = document.createElement("div"); div.className = "multi-proxy"; for (var i = 0; i != selected_nodes.length; i++) { - div.appendChild(selected_nodes[i].cloneNode(true)); + div.appendChild(Ext.get(selected_nodes[i]).dom.firstChild.cloneNode(true)); if ((i + 1) % 3 == 0) { div.appendChild(document.createElement("br")); } @@ -290,7 +290,7 @@ enableDD: true, dropConfig: { appendOnly: true, - ddGroup: "organizeDD", + ddGroup: "organizeDD" }, listeners: { "click": function(node) { -- cgit v1.2.3 From e6b3886f8f6a3a526876a80470420501bdb25612 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Wed, 5 Jan 2011 22:15:13 -0800 Subject: Functional improvements: - Add support for dragging a selection box. Visual improvements; - The "ghost" selection now has minimized thumbnails so that you're dragging a smaller div around the screen. --- modules/organize/css/organize.css | 12 ++ modules/organize/vendor/ext/js/DataView-more.js | 160 ++++++++++++++++++++++++ modules/organize/views/organize_dialog.html.php | 26 ++-- 3 files changed, 191 insertions(+), 7 deletions(-) create mode 100644 modules/organize/vendor/ext/js/DataView-more.js (limited to 'modules/organize/css') 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 @@ + +
 
+ diff --git a/modules/organize/views/organize_frame.html.php b/modules/organize/views/organize_frame.html.php index 16f78603..cdbf3be7 100644 --- a/modules/organize/views/organize_frame.html.php +++ b/modules/organize/views/organize_frame.html.php @@ -1,7 +1,7 @@ " /> " /> -" /> +" />