[495] | 1 | define([ |
---|
[510] | 2 | "../lib/object", |
---|
[495] | 3 | "./Selector", |
---|
| 4 | "dijit/layout/ContentPane", |
---|
| 5 | "dijit/layout/TabContainer", |
---|
| 6 | "dojo/_base/array", |
---|
| 7 | "dojo/_base/declare", |
---|
| 8 | "dojo/_base/lang", |
---|
| 9 | "dojo/_base/window", |
---|
| 10 | "dojo/when", |
---|
| 11 | "dojox/widget/Standby" |
---|
[510] | 12 | ], function(objectFuns, Selector, ContentPane, TabContainer, array, declare, lang, win, when, Standby) { |
---|
[495] | 13 | return declare([TabContainer],{ |
---|
| 14 | tabPosition: 'left-h', |
---|
| 15 | |
---|
| 16 | // interface the client must implement |
---|
| 17 | getCategories: function(){ return []; }, |
---|
| 18 | getCategoryName: function(category){ return ""; }, |
---|
| 19 | getCategoryCount: function(category){ return 0; }, |
---|
| 20 | getTopics: function(category){ return []; }, |
---|
| 21 | getTopicName: function(topic){ return "";}, |
---|
| 22 | getTopicCount: function(topic){ return 0; }, |
---|
| 23 | getItems: function(category,topic){ return []; }, |
---|
| 24 | getItemName: function(item){ return ""; }, |
---|
| 25 | getItemActions: function(item){ return {}; }, // {name:{'callback'(item,sel),'icon','description'}} |
---|
| 26 | getSelectedItemActions: function(){ return {}; }, // {name:{'callback'(item,sel),'icon','description'}} |
---|
| 27 | areItemsEqual: function(i1,i2){ return i1 === i2; }, |
---|
| 28 | |
---|
| 29 | dndType: "", |
---|
| 30 | |
---|
| 31 | _dataMap: null, |
---|
| 32 | _busyCount: 0, |
---|
| 33 | constructor: function() { |
---|
| 34 | this._dataMap = {}; |
---|
| 35 | }, |
---|
| 36 | startup: function() { |
---|
| 37 | if ( this._started ){ return; } |
---|
| 38 | this.inherited(arguments); |
---|
| 39 | this._busyWidget = new Standby({ |
---|
| 40 | target: this.domNode, |
---|
| 41 | duration: 200 |
---|
| 42 | }).placeAt(win.body()); |
---|
| 43 | this._busyWidget.startup(); |
---|
| 44 | this.watch("selectedChildWidget",lang.hitch(this,'_handleChangeTab')); |
---|
| 45 | when(this.getCategories()) |
---|
| 46 | .then(lang.hitch(this,'_addCategories')); |
---|
| 47 | }, |
---|
| 48 | _addCategories: function(categories) { |
---|
| 49 | array.forEach(categories, function(category) { |
---|
| 50 | this._addCategory(category); |
---|
| 51 | }, this); |
---|
| 52 | }, |
---|
| 53 | _handleChangeTab: function(name,oldTab,newTab) { |
---|
| 54 | this._fillCategory(newTab.__category); |
---|
| 55 | }, |
---|
| 56 | _addCategory: function(category) { |
---|
| 57 | var name = this.getCategoryName(category); |
---|
| 58 | var count = this.getCategoryCount(category); |
---|
| 59 | if (this._dataMap[name] === undefined) { |
---|
| 60 | var tab = new ContentPane({ |
---|
| 61 | __category: category, |
---|
| 62 | title: (name||'[No category]')+(count&&' ('+count+')') |
---|
| 63 | }); |
---|
| 64 | tab.startup(); |
---|
| 65 | this._dataMap[name] = { |
---|
| 66 | _widget: tab |
---|
| 67 | }; |
---|
| 68 | this.addChild(tab); |
---|
| 69 | } |
---|
| 70 | }, |
---|
| 71 | _fillCategory: function(category) { |
---|
| 72 | var name = this.getCategoryName(category); |
---|
| 73 | var map = this._dataMap[name]; |
---|
| 74 | if (!map._filled) { |
---|
| 75 | this._busy(); |
---|
| 76 | map._filled = true; |
---|
| 77 | when(this.getTopics(category)) |
---|
| 78 | .then(lang.hitch(this,'_addTopicsToCategory',category)) |
---|
| 79 | .always(lang.hitch(this,'_done')); |
---|
| 80 | } |
---|
| 81 | }, |
---|
| 82 | _addTopicsToCategory: function(category,topics) { |
---|
| 83 | array.forEach(topics, function(topic) { |
---|
| 84 | var cname = this.getCategoryName(category); |
---|
| 85 | var tname = this.getTopicName(topic); |
---|
| 86 | this._addTopicToCategory(category,topic); |
---|
| 87 | }, this); |
---|
| 88 | }, |
---|
| 89 | _addTopicToCategory: function(category,topic) { |
---|
| 90 | var map = this._dataMap[this.getCategoryName(category)]; |
---|
| 91 | var name = this.getTopicName(topic); |
---|
| 92 | var count = this.getTopicCount(topic); |
---|
| 93 | if (map[name] === undefined) { |
---|
| 94 | var w = new Selector({ |
---|
| 95 | __category: category, |
---|
| 96 | __topic: topic, |
---|
| 97 | dndType: this.dndType, |
---|
| 98 | title: (name||'[No topic]')+(count&&" ("+count+")"), |
---|
| 99 | selectedActions: lang.hitch(this,'getSelectedItemActions'), |
---|
| 100 | itemActions: lang.hitch(this,'getItemActions'), |
---|
| 101 | itemTitle: lang.hitch(this,'getItemName'), |
---|
| 102 | itemEquals: lang.hitch(this,'areItemsEqual') |
---|
| 103 | }).placeAt(map._widget.containerNode); |
---|
| 104 | w.startup(); |
---|
| 105 | map[name] = { |
---|
| 106 | _widget: w |
---|
| 107 | }; |
---|
| 108 | this._fillTopicInCategory(category,topic); |
---|
| 109 | } |
---|
| 110 | }, |
---|
| 111 | _fillTopicInCategory: function(category,topic) { |
---|
| 112 | var map = this._dataMap[this.getCategoryName(category)][this.getTopicName(topic)]; |
---|
| 113 | if (!map._filled) { |
---|
| 114 | map._filled = true; |
---|
| 115 | this._busy(); |
---|
| 116 | when(this.getItems(category,topic)) |
---|
| 117 | .then(lang.hitch(this,function(items){ |
---|
| 118 | array.forEach(items,map._widget.addItem,map._widget); |
---|
| 119 | })).always(lang.hitch(this,'_done')); |
---|
| 120 | } |
---|
| 121 | }, |
---|
| 122 | removeItem: function(item) { |
---|
| 123 | var cmap = this._dataMap; |
---|
[510] | 124 | objectFuns.forEach(cmap,function(tmap,cat){ |
---|
| 125 | objectFuns.forEach(tmap,function(topObj,top){ |
---|
| 126 | var widget = topObj._widget; |
---|
| 127 | if ( widget ) { widget.removeItem(item); } |
---|
| 128 | },this); |
---|
| 129 | },this); |
---|
[495] | 130 | }, |
---|
| 131 | _busy: function() { |
---|
| 132 | if ( this._busyCount === 0 ) { |
---|
| 133 | this._busyWidget.show(); |
---|
| 134 | } |
---|
| 135 | this._busyCount++; |
---|
| 136 | }, |
---|
| 137 | _done: function() { |
---|
| 138 | if ( this._busyCount > 0 ) { |
---|
| 139 | this._busyCount--; |
---|
| 140 | if ( this._busyCount === 0 ) { |
---|
| 141 | this._busyWidget.hide(); |
---|
| 142 | } |
---|
| 143 | } else { |
---|
| 144 | console.warn('_done() was called more times than _busy().'); |
---|
| 145 | } |
---|
| 146 | }, |
---|
| 147 | destroy: function() { |
---|
| 148 | this._busyWidget.destroyRecursive(); |
---|
| 149 | this.inherited(arguments); |
---|
| 150 | } |
---|
| 151 | }); |
---|
| 152 | }); |
---|