X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/examples/key-feed-viewer/viewer/FeedPanel.js diff --git a/examples/key-feed-viewer/viewer/FeedPanel.js b/examples/key-feed-viewer/viewer/FeedPanel.js new file mode 100644 index 00000000..60767823 --- /dev/null +++ b/examples/key-feed-viewer/viewer/FeedPanel.js @@ -0,0 +1,274 @@ +/** + * @class FeedViewer.FeedPanel + * @extends Ext.panel.Panel + * + * Shows a list of available feeds. Also has the ability to add/remove and load feeds. + * + * @constructor + * Create a new Feed Panel + * @param {Object} config The config object + */ + +Ext.define('FeedViewer.FeedPanel', { + extend: 'Ext.panel.Panel', + + alias: 'widget.feedpanel', + + initComponent: function(){ + Ext.apply(this, { + layout: 'fit', + title: 'Feeds', + animCollapse: true, + items: this.createView(), + dockedItems: [this.createToolbar()] + }); + this.createMenu(); + this.addEvents( + /** + * @event feedremove Fired when a feed is removed + * @param {FeedPanel} this + * @param {String} title The title of the feed + * @param {String} url The url of the feed + */ + 'feedremove', + + /** + * @event feedselect Fired when a feed is selected + * @param {FeedPanel} this + * @param {String} title The title of the feed + * @param {String} url The url of the feed + */ + 'feedselect' + ); + + this.callParent(arguments); + }, + + // template method + afterRender: function(){ + this.callParent(arguments); + var view = this.view; + view.getSelectionModel().select(view.store.first()); + }, + + /** + * Create the DataView to be used for the feed list. + * @private + * @return {Ext.view.View} + */ + createView: function(){ + var view = this.view = Ext.create('widget.dataview', { + store: Ext.create('Ext.data.Store', { + model: 'Feed', + data: this.feeds + }), + selModel: { + mode: 'SINGLE', + listeners: { + scope: this, + selectionchange: this.onSelectionChange + } + }, + listeners: { + scope: this, + contextmenu: this.onContextMenu + }, + trackOver: true, + cls: 'feed-list', + itemSelector: '.feed-list-item', + overItemCls: 'feed-list-item-hover', + tpl: '
{title}
' + }); + + view.on('render', function() { + + }, this); + return this.view; + }, + + /** + * Creates the toolbar to be used for controlling feeds. + * @private + * @return {Ext.toolbar.Toolbar} + */ + createToolbar: function(){ + this.createActions(); + this.toolbar = Ext.create('widget.toolbar', { + items: [this.addAction, this.removeAction] + }); + return this.toolbar; + }, + + /** + * Create actions to share between toolbar and menu + * @private + */ + createActions: function(){ + this.addAction = Ext.create('Ext.Action', { + scope: this, + handler: this.onAddFeedClick, + text: 'Add feed', + iconCls: 'feed-add' + }); + + this.removeAction = Ext.create('Ext.Action', { + itemId: 'remove', + scope: this, + handler: this.onRemoveFeedClick, + text: 'Remove feed', + iconCls: 'feed-remove' + }); + }, + + /** + * Create the context menu + * @private + */ + createMenu: function(){ + this.menu = Ext.create('widget.menu', { + items: [{ + scope: this, + handler: this.onLoadClick, + text: 'Load feed', + iconCls: 'feed-load' + }, this.removeAction, '-', this.addAction], + listeners: { + hide: function(c){ + c.activeFeed = null; + } + } + }); + }, + + /** + * Used when view selection changes so we can disable toolbar buttons. + * @private + */ + onSelectionChange: function(){ + var selected = this.getSelectedItem(); + this.toolbar.getComponent('remove').setDisabled(!selected); + this.loadFeed(selected); + }, + + /** + * React to the load feed menu click. + * @private + */ + onLoadClick: function(){ + this.loadFeed(this.menu.activeFeed); + }, + + /** + * Loads a feed. + * @private + * @param {Ext.data.Model} rec The feed + */ + loadFeed: function(rec){ + if (rec) { + this.fireEvent('feedselect', this, rec.get('title'), rec.get('url')); + } + }, + + /** + * Gets the currently selected record in the view. + * @private + * @return {Ext.data.Model} Returns the selected model. false if nothing is selected. + */ + getSelectedItem: function(){ + return this.view.getSelectionModel().getSelection()[0] || false; + }, + + /** + * Listens for the context menu event on the view + * @private + */ + onContextMenu: function(view, index, el, event){ + var menu = this.menu; + + event.stopEvent(); + menu.activeFeed = view.store.getAt(index); + menu.showAt(event.getXY()); + }, + + /** + * React to a feed being removed + * @private + */ + onRemoveFeedClick: function(){ + var active = this.menu.activeFeed || this.getSelectedItem(); + + + this.animateNode(this.view.getNode(active), 1, 0, { + scope: this, + afteranimate: function(){ + this.view.store.remove(active); + } + }); + this.fireEvent('feedremove', this, active.get('title'), active.get('url')); + + }, + + /** + * React to a feed attempting to be added + * @private + */ + onAddFeedClick: function(){ + var win = Ext.create('widget.feedwindow', { + listeners: { + scope: this, + feedvalid: this.onFeedValid + } + }); + win.show(); + }, + + /** + * React to a validation on a feed passing + * @private + * @param {FeedViewer.FeedWindow} win + * @param {String} title The title of the feed + * @param {String} url The url of the feed + */ + onFeedValid: function(win, title, url){ + var view = this.view, + store = view.store, + rec; + + rec = store.add({ + url: url, + title: title + })[0]; + this.animateNode(view.getNode(rec), 0, 1); + }, + + /** + * Animate a node in the view when it is added/removed + * @private + * @param {Mixed} el The element to animate + * @param {Number} start The start opacity + * @param {Number} end The end opacity + * @param {Object} listeners (optional) Any listeners + */ + animateNode: function(el, start, end, listeners){ + Ext.create('Ext.fx.Anim', { + target: Ext.get(el), + duration: 500, + from: { + opacity: start + }, + to: { + opacity: end + }, + listeners: listeners + }); + }, + + // Inherit docs + onDestroy: function(){ + Ext.destroy( + this.viewNav, + this.menu + ); + this.callParent(arguments); + } +});