From 541bb378ddece2eab135a8066a16994e94436dea Mon Sep 17 00:00:00 2001 From: Giulio Cesare Solaroli Date: Mon, 03 Oct 2011 16:04:12 +0000 Subject: Merge pull request #1 from gcsolaroli/master First version of the restructured repository --- (limited to 'frontend/beta/js/YUI-extensions/layout') diff --git a/frontend/beta/js/YUI-extensions/layout/BasicLayoutRegion.js b/frontend/beta/js/YUI-extensions/layout/BasicLayoutRegion.js new file mode 100644 index 0000000..b7ea273 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/BasicLayoutRegion.js @@ -0,0 +1,265 @@ +/** + * @class YAHOO.ext.BasicLayoutRegion + * @extends YAHOO.ext.util.Observable + * This class represents a lightweight region in a layout manager. This region does not move dom nodes + * and does not have a titlebar, tabs or any other features. All it does is size and position + * panels. To create a BasicLayoutRegion, add lightweight:true or basic:true to your regions config. + */ +YAHOO.ext.BasicLayoutRegion = function(mgr, config, pos, skipConfig){ + this.mgr = mgr; + this.position = pos; + this.events = { + /** + * @event beforeremove + * Fires before a panel is removed (or closed). To cancel the removal set "e.cancel = true" on the event argument. + * @param {YAHOO.ext.LayoutRegion} this + * @param {YAHOO.ext.ContentPanel} panel The panel + * @param {Object} e The cancel event object + */ + 'beforeremove' : true, + /** + * @event invalidated + * Fires when the layout for this region is changed. + * @param {YAHOO.ext.LayoutRegion} this + */ + 'invalidated' : true, + /** + * @event visibilitychange + * Fires when this region is shown or hidden + * @param {YAHOO.ext.LayoutRegion} this + * @param {Boolean} visibility true or false + */ + 'visibilitychange' : true, + /** + * @event paneladded + * Fires when a panel is added. + * @param {YAHOO.ext.LayoutRegion} this + * @param {YAHOO.ext.ContentPanel} panel The panel + */ + 'paneladded' : true, + /** + * @event panelremoved + * Fires when a panel is removed. + * @param {YAHOO.ext.LayoutRegion} this + * @param {YAHOO.ext.ContentPanel} panel The panel + */ + 'panelremoved' : true, + /** + * @event collapsed + * Fires when this region is collapsed. + * @param {YAHOO.ext.LayoutRegion} this + */ + 'collapsed' : true, + /** + * @event expanded + * Fires when this region is expanded. + * @param {YAHOO.ext.LayoutRegion} this + */ + 'expanded' : true, + /** + * @event panelactivated + * Fires when a panel is activated. + * @param {YAHOO.ext.LayoutRegion} this + * @param {YAHOO.ext.ContentPanel} panel The activated panel + */ + 'panelactivated' : true, + /** + * @event resized + * Fires when the user resizes this region. + * @param {YAHOO.ext.LayoutRegion} this + * @param {Number} newSize The new size (width for east/west, height for north/south) + */ + 'resized' : true + }; + /** A collection of panels in this region. @type YAHOO.ext.util.MixedCollection */ + this.panels = new YAHOO.ext.util.MixedCollection(); + this.panels.getKey = this.getPanelId.createDelegate(this); + this.box = null; + this.activePanel = null; + if(skipConfig !== true){ + this.applyConfig(config); + } +}; + +YAHOO.extendX(YAHOO.ext.BasicLayoutRegion, YAHOO.ext.util.Observable, { + getPanelId : function(p){ + return p.getId(); + }, + + applyConfig : function(config){ + this.margins = config.margins || this.margins || {top: 0, left: 0, right:0, bottom: 0}; + this.config = config; + }, + + /** + * Resizes the region to the specified size. For vertical regions (west, east) this adjusts + * the width, for horizontal (north, south) the height. + * @param {Number} newSize The new width or height + */ + resizeTo : function(newSize){ + if(this.activePanel){ + var el = this.activePanel.getEl(); + switch(this.position){ + case 'east': + case 'west': + el.setWidth(newSize); + this.fireEvent('resized', this, newSize); + break; + case 'north': + case 'south': + el.setHeight(newSize); + this.fireEvent('resized', this, newSize); + break; + } + } + }, + + getBox : function(){ + return this.activePanel ? this.activePanel.getEl().getBox(false, true) : null; + }, + + getMargins : function(){ + return this.margins; + }, + + updateBox : function(box){ + this.box = box; + var el = this.activePanel.getEl(); + el.dom.style.left = box.x + 'px'; + el.dom.style.top = box.y + 'px'; + el.setSize(box.width, box.height); + }, + + /** + * Returns the container element for this region. + * @return {YAHOO.ext.Element} + */ + getEl : function(){ + return this.activePanel; + }, + + /** + * Returns true if this region is currently visible. + * @return {Boolean} + */ + isVisible : function(){ + return this.activePanel ? true : false; + }, + + setActivePanel : function(panel){ + panel = this.getPanel(panel); + if(this.activePanel && this.activePanel != panel){ + this.activePanel.setActiveState(false); + this.activePanel.getEl().setStyle({left:-10000,right:-10000}); + } + this.activePanel = panel; + panel.setActiveState(true); + if(this.box){ + panel.setSize(this.box.width, this.box.height); + } + this.fireEvent('panelactivated', this, panel); + this.fireEvent('invalidated'); + }, + + /** + * Show the specified panel. + * @param {Number/String/ContentPanel} panelId The panels index, id or the panel itself + * @return {YAHOO.ext.ContentPanel} The shown panel or null + */ + showPanel : function(panel){ + if(panel = this.getPanel(panel)){ + this.setActivePanel(panel); + } + return panel; + }, + + /** + * Get the active panel for this region. + * @return {YAHOO.ext.ContentPanel} The active panel or null + */ + getActivePanel : function(){ + return this.activePanel; + }, + + /** + * Add the passed ContentPanel(s) + * @param {ContentPanel...} panel The ContentPanel(s) to add (you can pass more than one) + * @return {YAHOO.ext.ContentPanel} The panel added (if only one was added) + */ + add : function(panel){ + if(arguments.length > 1){ + for(var i = 0, len = arguments.length; i < len; i++) { + this.add(arguments[i]); + } + return null; + } + if(this.hasPanel(panel)){ + this.showPanel(panel); + return panel; + } + panel.setRegion(this); + this.panels.add(panel); + panel.getEl().setStyle('position', 'absolute'); + if(!panel.background){ + this.setActivePanel(panel); + if(this.config.initialSize && this.panels.getCount()==1){ + this.resizeTo(this.config.initialSize); + } + } + this.fireEvent('paneladded', this, panel); + return panel; + }, + + /** + * Returns true if the panel is in this region. + * @param {Number/String/ContentPanel} panel The panels index, id or the panel itself + * @return {Boolean} + */ + hasPanel : function(panel){ + if(typeof panel == 'object'){ // must be panel obj + panel = panel.getId(); + } + return this.getPanel(panel) ? true : false; + }, + + /** + * Removes the specified panel. If preservePanel is not true (either here or in the config), the panel is destroyed. + * @param {Number/String/ContentPanel} panel The panels index, id or the panel itself + * @param {Boolean} preservePanel Overrides the config preservePanel option + * @return {YAHOO.ext.ContentPanel} The panel that was removed + */ + remove : function(panel, preservePanel){ + panel = this.getPanel(panel); + if(!panel){ + return null; + } + var e = {}; + this.fireEvent('beforeremove', this, panel, e); + if(e.cancel === true){ + return null; + } + var panelId = panel.getId(); + this.panels.removeKey(panelId); + return panel; + }, + + /** + * Returns the panel specified or null if it's not in this region. + * @param {Number/String/ContentPanel} panel The panels index, id or the panel itself + * @return {YAHOO.ext.ContentPanel} + */ + getPanel : function(id){ + if(typeof id == 'object'){ // must be panel obj + return id; + } + return this.panels.get(id); + }, + + /** + * Returns this regions position (north/south/east/west/center). + * @return {String} + */ + getPosition: function(){ + return this.position; + } +}); diff --git a/frontend/beta/js/YUI-extensions/layout/BorderLayout.js b/frontend/beta/js/YUI-extensions/layout/BorderLayout.js new file mode 100644 index 0000000..0529c24 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/BorderLayout.js @@ -0,0 +1,281 @@ +/** + * @class YAHOO.ext.BorderLayout + * @extends YAHOO.ext.LayoutManager + * This class represents a common layout manager used in desktop applications. For screenshots and more details, + * please see:

+ * Cross Browser Layouts - Part 1
+ * Cross Browser Layouts - Part 2

+ * Example: +

+ var layout = new YAHOO.ext.BorderLayout(document.body, {
+    north: {
+        initialSize: 25,
+        titlebar: false
+    },
+    west: {
+        split:true,
+        initialSize: 200,
+        minSize: 175,
+        maxSize: 400,
+        titlebar: true,
+        collapsible: true
+    },
+    east: {
+        split:true,
+        initialSize: 202,
+        minSize: 175,
+        maxSize: 400,
+        titlebar: true,
+        collapsible: true
+    },
+    south: {
+        split:true,
+        initialSize: 100,
+        minSize: 100,
+        maxSize: 200,
+        titlebar: true,
+        collapsible: true
+    },
+    center: {
+        titlebar: true,
+        autoScroll:true,
+        resizeTabs: true,
+        minTabWidth: 50,
+        preferredTabWidth: 150
+    }
+});
+
+// shorthand
+var CP = YAHOO.ext.ContentPanel;
+
+layout.beginUpdate();
+layout.add('north', new CP('north', 'North'));
+layout.add('south', new CP('south', {title: 'South', closable: true}));
+layout.add('west', new CP('west', {title: 'West'}));
+layout.add('east', new CP('autoTabs', {title: 'Auto Tabs', closable: true}));
+layout.add('center', new CP('center1', {title: 'Close Me', closable: true}));
+layout.add('center', new CP('center2', {title: 'Center Panel', closable: false}));
+layout.getRegion('center').showPanel('center1');
+layout.endUpdate();
+
+* @constructor +* Create a new BorderLayout +* @param {String/HTMLElement/Element} container The container this layout is bound to +* @param {Object} config Configuration options + */ +YAHOO.ext.BorderLayout = function(container, config){ + config = config || {}; + YAHOO.ext.BorderLayout.superclass.constructor.call(this, container); + this.factory = config.factory || YAHOO.ext.BorderLayout.RegionFactory; + /** + * True to hide the center panel while performing layouts. This helps when the center region contains + * heavy components such as a yui-ext grid. + * @type Boolean + */ + this.hideOnLayout = config.hideOnLayout || false; + for(var i = 0, len = this.factory.validRegions.length; i < len; i++) { + var target = this.factory.validRegions[i]; + if(config[target]){ + this.addRegion(target, config[target]); + } + } + //this.dragOverDelegate = YAHOO.ext.EventManager.wrap(this.onDragOver, this, true); +}; + +YAHOO.extendX(YAHOO.ext.BorderLayout, YAHOO.ext.LayoutManager, { + /** + * Creates and adds a new region if it doesn't already exist. + * @param {String} target The target region key (north, south, east, west or center). + * @param {Object} config The regions config object + * @return {BorderLayoutRegion} The new region + */ + addRegion : function(target, config){ + if(!this.regions[target]){ + var r = this.factory.create(target, this, config); + this.regions[target] = r; + r.on('visibilitychange', this.layout, this, true); + r.on('paneladded', this.layout, this, true); + r.on('panelremoved', this.layout, this, true); + r.on('invalidated', this.layout, this, true); + r.on('resized', this.onRegionResized, this, true); + r.on('collapsed', this.onRegionCollapsed, this, true); + r.on('expanded', this.onRegionExpanded, this, true); + } + return this.regions[target]; + }, + + /** + * Performs a layout update. + */ + layout : function(){ + if(this.updating) return; + //var bench = new YAHOO.ext.util.Bench(); + //bench.start('Layout...'); + var size = this.getViewSize(); + var w = size.width, h = size.height; + var centerW = w, centerH = h, centerY = 0, centerX = 0; + var x = 0, y = 0; + + var rs = this.regions; + var n = rs['north'], s = rs['south'], west = rs['west'], e = rs['east'], c = rs['center']; + if(this.hideOnLayout){ + c.el.setStyle('display', 'none'); + } + if(n && n.isVisible()){ + var b = n.getBox(); + var m = n.getMargins(); + b.width = w - (m.left+m.right); + b.x = m.left; + b.y = m.top; + centerY = b.height + b.y + m.bottom; + centerH -= centerY; + n.updateBox(this.safeBox(b)); + } + if(s && s.isVisible()){ + var b = s.getBox(); + var m = s.getMargins(); + b.width = w - (m.left+m.right); + b.x = m.left; + var totalHeight = (b.height + m.top + m.bottom); + b.y = h - totalHeight + m.top; + centerH -= totalHeight; + s.updateBox(this.safeBox(b)); + } + if(west && west.isVisible()){ + var b = west.getBox(); + var m = west.getMargins(); + b.height = centerH - (m.top+m.bottom); + b.x = m.left; + b.y = centerY + m.top; + var totalWidth = (b.width + m.left + m.right); + centerX += totalWidth; + centerW -= totalWidth; + west.updateBox(this.safeBox(b)); + } + if(e && e.isVisible()){ + var b = e.getBox(); + var m = e.getMargins(); + b.height = centerH - (m.top+m.bottom); + var totalWidth = (b.width + m.left + m.right); + b.x = w - totalWidth + m.left; + b.y = centerY + m.top; + centerW -= totalWidth; + e.updateBox(this.safeBox(b)); + } + if(c){ + var m = c.getMargins(); + var centerBox = { + x: centerX + m.left, + y: centerY + m.top, + width: centerW - (m.left+m.right), + height: centerH - (m.top+m.bottom) + }; + if(this.hideOnLayout){ + c.el.setStyle('display', 'block'); + } + c.updateBox(this.safeBox(centerBox)); + } + this.el.repaint(); + this.fireEvent('layout', this); + //bench.stop(); + //alert(bench.toString()); + }, + + safeBox : function(box){ + box.width = Math.max(0, box.width); + box.height = Math.max(0, box.height); + return box; + }, + + /** + * Adds a ContentPanel (or subclass) to this layout. + * @param {String} target The target region key (north, south, east, west or center). + * @param {YAHOO.ext.ContentPanel} panel The panel to add + * @return {YAHOO.ext.ContentPanel} The added panel + */ + add : function(target, panel){ + target = target.toLowerCase(); + return this.regions[target].add(panel); + }, + + /** + * Adds a ContentPanel (or subclass) to this layout. + * @param {String} target The target region key (north, south, east, west or center). + * @param {Number/String/YAHOO.ext.ContentPanel} panel The index, id or panel to remove + * @return {YAHOO.ext.ContentPanel} The removed panel + */ + remove : function(target, panel){ + target = target.toLowerCase(); + return this.regions[target].remove(panel); + }, + + /** + * Searches all regions for a panel with the specified id + * @param {String} panelId + * @return {YAHOO.ext.ContentPanel} The panel or null if it wasn't found + */ + findPanel : function(panelId){ + var rs = this.regions; + for(var target in rs){ + if(typeof rs[target] != 'function'){ + var p = rs[target].getPanel(panelId); + if(p){ + return p; + } + } + } + return null; + }, + + /** + * Searches all regions for a panel with the specified id and activates (shows) it. + * @param {String/ContentPanel} panelId The panels id or the panel itself + * @return {YAHOO.ext.ContentPanel} The shown panel or null + */ + showPanel : function(panelId) { + var rs = this.regions; + for(var target in rs){ + var r = rs[target]; + if(typeof r != 'function'){ + if(r.hasPanel(panelId)){ + return r.showPanel(panelId); + } + } + } + return null; + }, + + /** + * Restores this layouts state using YAHOO.ext.state.Manager or the state provided by the passed provider. + * @param {YAHOO.ext.state.Provider} provider (optional) An alternate state provider + */ + restoreState : function(provider){ + if(!provider){ + provider = YAHOO.ext.state.Manager; + } + var sm = new YAHOO.ext.LayoutStateManager(); + sm.init(this, provider); + } +}); + +YAHOO.ext.BorderLayout.RegionFactory = {}; +YAHOO.ext.BorderLayout.RegionFactory.validRegions = ['north','south','east','west','center']; +YAHOO.ext.BorderLayout.RegionFactory.create = function(target, mgr, config){ + target = target.toLowerCase(); + if(config.lightweight || config.basic){ + return new YAHOO.ext.BasicLayoutRegion(mgr, config, target); + } + switch(target){ + case 'north': + return new YAHOO.ext.NorthLayoutRegion(mgr, config); + case 'south': + return new YAHOO.ext.SouthLayoutRegion(mgr, config); + case 'east': + return new YAHOO.ext.EastLayoutRegion(mgr, config); + case 'west': + return new YAHOO.ext.WestLayoutRegion(mgr, config); + case 'center': + return new YAHOO.ext.CenterLayoutRegion(mgr, config); + } + throw 'Layout region "'+target+'" not supported.'; +}; diff --git a/frontend/beta/js/YUI-extensions/layout/BorderLayoutRegions.js b/frontend/beta/js/YUI-extensions/layout/BorderLayoutRegions.js new file mode 100644 index 0000000..9b4a09f --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/BorderLayoutRegions.js @@ -0,0 +1,207 @@ +/* + * These classes are private internal classes + */ +YAHOO.ext.CenterLayoutRegion = function(mgr, config){ + YAHOO.ext.CenterLayoutRegion.superclass.constructor.call(this, mgr, config, 'center'); + this.visible = true; + this.minWidth = config.minWidth || 20; + this.minHeight = config.minHeight || 20; +}; + +YAHOO.extendX(YAHOO.ext.CenterLayoutRegion, YAHOO.ext.LayoutRegion, { + hide : function(){ + // center panel can't be hidden + }, + + show : function(){ + // center panel can't be hidden + }, + + getMinWidth: function(){ + return this.minWidth; + }, + + getMinHeight: function(){ + return this.minHeight; + } +}); + + +YAHOO.ext.NorthLayoutRegion = function(mgr, config){ + YAHOO.ext.NorthLayoutRegion.superclass.constructor.call(this, mgr, config, 'north', 'n-resize'); + if(this.split){ + this.split.placement = YAHOO.ext.SplitBar.TOP; + this.split.orientation = YAHOO.ext.SplitBar.VERTICAL; + this.split.el.addClass('ylayout-split-v'); + } + if(typeof config.initialSize != 'undefined'){ + this.el.setHeight(config.initialSize); + } +}; +YAHOO.extendX(YAHOO.ext.NorthLayoutRegion, YAHOO.ext.SplitLayoutRegion, { + getBox : function(){ + if(this.collapsed){ + return this.collapsedEl.getBox(); + } + var box = this.el.getBox(); + if(this.split){ + box.height += this.split.el.getHeight(); + } + return box; + }, + + updateBox : function(box){ + if(this.split && !this.collapsed){ + box.height -= this.split.el.getHeight(); + this.split.el.setLeft(box.x); + this.split.el.setTop(box.y+box.height); + this.split.el.setWidth(box.width); + } + if(this.collapsed){ + this.el.setWidth(box.width); + var bodyWidth = box.width - this.el.getBorderWidth('rl'); + this.bodyEl.setWidth(bodyWidth); + if(this.activePanel && this.panelSize){ + this.activePanel.setSize(bodyWidth, this.panelSize.height); + } + } + YAHOO.ext.NorthLayoutRegion.superclass.updateBox.call(this, box); + } +}); + +YAHOO.ext.SouthLayoutRegion = function(mgr, config){ + YAHOO.ext.SouthLayoutRegion.superclass.constructor.call(this, mgr, config, 'south', 's-resize'); + if(this.split){ + this.split.placement = YAHOO.ext.SplitBar.BOTTOM; + this.split.orientation = YAHOO.ext.SplitBar.VERTICAL; + this.split.el.addClass('ylayout-split-v'); + } + if(typeof config.initialSize != 'undefined'){ + this.el.setHeight(config.initialSize); + } +}; +YAHOO.extendX(YAHOO.ext.SouthLayoutRegion, YAHOO.ext.SplitLayoutRegion, { + getBox : function(){ + if(this.collapsed){ + return this.collapsedEl.getBox(); + } + var box = this.el.getBox(); + if(this.split){ + var sh = this.split.el.getHeight(); + box.height += sh; + box.y -= sh; + } + return box; + }, + + updateBox : function(box){ + if(this.split && !this.collapsed){ + var sh = this.split.el.getHeight(); + box.height -= sh; + box.y += sh; + this.split.el.setLeft(box.x); + this.split.el.setTop(box.y-sh); + this.split.el.setWidth(box.width); + } + if(this.collapsed){ + this.el.setWidth(box.width); + var bodyWidth = box.width - this.el.getBorderWidth('rl'); + this.bodyEl.setWidth(bodyWidth); + if(this.activePanel && this.panelSize){ + this.activePanel.setSize(bodyWidth, this.panelSize.height); + } + } + YAHOO.ext.SouthLayoutRegion.superclass.updateBox.call(this, box); + } +}); + +YAHOO.ext.EastLayoutRegion = function(mgr, config){ + YAHOO.ext.EastLayoutRegion.superclass.constructor.call(this, mgr, config, 'east', 'e-resize'); + if(this.split){ + this.split.placement = YAHOO.ext.SplitBar.RIGHT; + this.split.orientation = YAHOO.ext.SplitBar.HORIZONTAL; + this.split.el.addClass('ylayout-split-h'); + } + if(typeof config.initialSize != 'undefined'){ + this.el.setWidth(config.initialSize); + } +}; +YAHOO.extendX(YAHOO.ext.EastLayoutRegion, YAHOO.ext.SplitLayoutRegion, { + getBox : function(){ + if(this.collapsed){ + return this.collapsedEl.getBox(); + } + var box = this.el.getBox(); + if(this.split){ + var sw = this.split.el.getWidth(); + box.width += sw; + box.x -= sw; + } + return box; + }, + + updateBox : function(box){ + if(this.split && !this.collapsed){ + var sw = this.split.el.getWidth(); + box.width -= sw; + this.split.el.setLeft(box.x); + this.split.el.setTop(box.y); + this.split.el.setHeight(box.height); + box.x += sw; + } + if(this.collapsed){ + this.el.setHeight(box.height); + var bodyHeight = this.config.titlebar ? box.height - (this.titleEl.getHeight()||0) : box.height; + bodyHeight -= this.el.getBorderWidth('tb'); + this.bodyEl.setHeight(bodyHeight); + if(this.activePanel && this.panelSize){ + this.activePanel.setSize(this.panelSize.width, bodyHeight); + } + } + YAHOO.ext.EastLayoutRegion.superclass.updateBox.call(this, box); + } +}); + +YAHOO.ext.WestLayoutRegion = function(mgr, config){ + YAHOO.ext.WestLayoutRegion.superclass.constructor.call(this, mgr, config, 'west', 'w-resize'); + if(this.split){ + this.split.placement = YAHOO.ext.SplitBar.LEFT; + this.split.orientation = YAHOO.ext.SplitBar.HORIZONTAL; + this.split.el.addClass('ylayout-split-h'); + } + if(typeof config.initialSize != 'undefined'){ + this.el.setWidth(config.initialSize); + } +}; +YAHOO.extendX(YAHOO.ext.WestLayoutRegion, YAHOO.ext.SplitLayoutRegion, { + getBox : function(){ + if(this.collapsed){ + return this.collapsedEl.getBox(); + } + var box = this.el.getBox(); + if(this.split){ + box.width += this.split.el.getWidth(); + } + return box; + }, + + updateBox : function(box){ + if(this.split && !this.collapsed){ + var sw = this.split.el.getWidth(); + box.width -= sw; + this.split.el.setLeft(box.x+box.width); + this.split.el.setTop(box.y); + this.split.el.setHeight(box.height); + } + if(this.collapsed){ + this.el.setHeight(box.height); + var bodyHeight = this.config.titlebar ? box.height - (this.titleEl.getHeight()||0) : box.height; + bodyHeight -= this.el.getBorderWidth('tb'); + this.bodyEl.setHeight(bodyHeight); + if(this.activePanel && this.panelSize){ + this.activePanel.setSize(this.panelSize.width, bodyHeight); + } + } + YAHOO.ext.WestLayoutRegion.superclass.updateBox.call(this, box); + } +}); diff --git a/frontend/beta/js/YUI-extensions/layout/ContentPanels.js b/frontend/beta/js/YUI-extensions/layout/ContentPanels.js new file mode 100644 index 0000000..7cfdde7 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/ContentPanels.js @@ -0,0 +1,325 @@ +/** + * @class YAHOO.ext.ContentPanel + * @extends YAHOO.ext.util.Observable + * A basic ContentPanel element. + * @cfg {Boolean} fitToFrame True for this panel to manually adjust it's size when the region resizes (defaults to false) + * @cfg {Boolean/Object} autoCreate True to auto generate the DOM element for this panel, or a DomHelper config of the element to create + * @cfg {Boolean} closable True if the panel can be closed/removed + * @cfg {Boolean} background True if the panel should not be activated when it is added (defaults to false) + * @cfg {String/HTMLElement/Element} resizeEl An element to resize if fitToFrame is true (instead of this panel's element) + * @cfg {Toolbar} toolbar A toolbar for this panel + * @cfg {Boolean} autoScroll True to scroll overflow in this panel (use with fitToFrame) + * @cfg {String} title The title for this panel + * @cfg {Array} adjustments Values to add to the width/height when doing a fitToFrame (default is [0, 0]) + * @constructor + * Create a new ContentPanel. + * @param {String/HTMLElement/Element} el The container element for this panel + * @param {String/Object} config A string to set only the title or a config object + * @param {String} content (optional) Set the HTML content for this panel + */ +YAHOO.ext.ContentPanel = function(el, config, content){ + YAHOO.ext.ContentPanel.superclass.constructor.call(this); + this.el = getEl(el, true); + if(!this.el && config && config.autoCreate){ + if(typeof config.autoCreate == 'object'){ + if(!config.autoCreate.id){ + config.autoCreate.id = el; + } + this.el = YAHOO.ext.DomHelper.append(document.body, + config.autoCreate, true); + }else{ + this.el = YAHOO.ext.DomHelper.append(document.body, + {tag: 'div', cls: 'ylayout-inactive-content', id: el}, true); + } + } + this.closable = false; + this.loaded = false; + this.active = false; + if(typeof config == 'string'){ + this.title = config; + }else{ + YAHOO.ext.util.Config.apply(this, config); + } + if(this.resizeEl){ + this.resizeEl = getEl(this.resizeEl, true); + }else{ + this.resizeEl = this.el; + } + this.events = { + /** + * @event activate + * Fires when this panel is activated. + * @param {YAHOO.ext.ContentPanel} this + */ + 'activate' : new YAHOO.util.CustomEvent('activate'), + /** + * @event deactivate + * Fires when this panel is activated. + * @param {YAHOO.ext.ContentPanel} this + */ + 'deactivate' : new YAHOO.util.CustomEvent('deactivate') + }; + if(this.autoScroll){ + this.resizeEl.setStyle('overflow', 'auto'); + } + if(content){ + this.setContent(content); + } +}; + +YAHOO.extendX(YAHOO.ext.ContentPanel, YAHOO.ext.util.Observable, { + setRegion : function(region){ + this.region = region; + if(region){ + this.el.replaceClass('ylayout-inactive-content', 'ylayout-active-content'); + }else{ + this.el.replaceClass('ylayout-active-content', 'ylayout-inactive-content'); + } + }, + + /** + * Returns the toolbar for this Panel if one was configured + * @return {YAHOO.ext.Toolbar} + */ + getToolbar : function(){ + return this.toolbar; + }, + + setActiveState : function(active){ + this.active = active; + if(!active){ + this.fireEvent('deactivate', this); + }else{ + this.fireEvent('activate', this); + } + }, + /** + * Updates this panel's element + * @param {String} content The new content + * @param {Boolean} loadScripts (optional) true to look for and process scripts + */ + setContent : function(content, loadScripts){ + this.el.update(content, loadScripts); + }, + + /** + * Get the {@link YAHOO.ext.UpdateManager} for this panel. Enables you to perform Ajax updates. + * @return {YAHOO.ext.UpdateManager} The UpdateManager + */ + getUpdateManager : function(){ + return this.el.getUpdateManager(); + }, + + /** + * Set a URL to be used to load the content for this panel. + * @param {String/Function} url The url to load the content from or a function to call to get the url + * @param {String/Object} params (optional) The string params for the update call or an object of the params. See {@link YAHOO.ext.UpdateManager#update} for more details. (Defaults to null) + * @param {Boolean} loadOnce (optional) Whether to only load the content once. If this is false it makes the Ajax call every time this panel is activated. (Defaults to false) + * @return {YAHOO.ext.UpdateManager} The UpdateManager + */ + setUrl : function(url, params, loadOnce){ + if(this.refreshDelegate){ + this.removeListener('activate', this.refreshDelegate); + } + this.refreshDelegate = this._handleRefresh.createDelegate(this, [url, params, loadOnce]); + this.on('activate', this._handleRefresh.createDelegate(this, [url, params, loadOnce])); + return this.el.getUpdateManager(); + }, + + _handleRefresh : function(url, params, loadOnce){ + if(!loadOnce || !this.loaded){ + var updater = this.el.getUpdateManager(); + updater.update(url, params, this._setLoaded.createDelegate(this)); + } + }, + + _setLoaded : function(){ + this.loaded = true; + }, + + /** + * Returns this panel's id + * @return {String} + */ + getId : function(){ + return this.el.id; + }, + + /** + * Returns this panel's element + * @return {YAHOO.ext.Element} + */ + getEl : function(){ + return this.el; + }, + + adjustForComponents : function(width, height){ + if(this.toolbar){ + var te = this.toolbar.getEl(); + height -= te.getHeight(); + te.setWidth(width); + } + if(this.adjustments){ + width += this.adjustments[0]; + height += this.adjustments[1]; + } + return {'width': width, 'height': height}; + }, + + setSize : function(width, height){ + if(this.fitToFrame){ + var size = this.adjustForComponents(width, height); + this.resizeEl.setSize(this.autoWidth ? 'auto' : size.width, size.height); + } + }, + + /** + * Returns this panel's title + * @return {String} + */ + getTitle : function(){ + return this.title; + }, + + /** + * Set this panel's title + * @param {String} title + */ + setTitle : function(title){ + this.title = title; + if(this.region){ + this.region.updatePanelTitle(this, title); + } + }, + + /** + * Returns true is this panel was configured to be closable + * @return {Boolean} + */ + isClosable : function(){ + return this.closable; + }, + + beforeSlide : function(){ + this.el.clip(); + this.resizeEl.clip(); + }, + + afterSlide : function(){ + this.el.unclip(); + this.resizeEl.unclip(); + }, + + /** + * Force a content refresh from the URL specified in the setUrl() method. + * Will fail silently if the setUrl method has not been called. + * This does not activate the panel, just updates its content. + */ + refresh : function(){ + if(this.refreshDelegate){ + this.loaded = false; + this.refreshDelegate(); + } + }, + + /** + * Destroys this panel + */ + destroy : function(){ + this.el.removeAllListeners(); + var tempEl = document.createElement('span'); + tempEl.appendChild(this.el.dom); + tempEl.innerHTML = ''; + this.el = null; + } +}); + +/** + * @class YAHOO.ext.GridPanel + * @extends YAHOO.ext.ContentPanel + * @constructor + * Create a new GridPanel. + * @param {YAHOO.ext.grid.Grid} grid The grid for this panel + * @param {String/Object} config A string to set only the title or a config object + */ +YAHOO.ext.GridPanel = function(grid, config){ + this.wrapper = YAHOO.ext.DomHelper.append(document.body, // wrapper for IE7 strict & safari scroll issue + {tag: 'div', cls: 'ylayout-grid-wrapper ylayout-inactive-content'}, true); + this.wrapper.dom.appendChild(grid.container.dom); + YAHOO.ext.GridPanel.superclass.constructor.call(this, this.wrapper, config); + if(this.toolbar){ + this.toolbar.el.insertBefore(this.wrapper.dom.firstChild); + } + grid.monitorWindowResize = false; // turn off autosizing + grid.autoHeight = false; + grid.autoWidth = false; + this.grid = grid; + this.grid.container.replaceClass('ylayout-inactive-content', 'ylayout-component-panel'); +}; + +YAHOO.extendX(YAHOO.ext.GridPanel, YAHOO.ext.ContentPanel, { + getId : function(){ + return this.grid.id; + }, + + /** + * Returns the grid for this panel + * @return {YAHOO.ext.grid.Grid} + */ + getGrid : function(){ + return this.grid; + }, + + setSize : function(width, height){ + var grid = this.grid; + var size = this.adjustForComponents(width, height); + grid.container.setSize(size.width, size.height); + grid.autoSize(); + }, + + beforeSlide : function(){ + this.grid.getView().wrapEl.clip(); + }, + + afterSlide : function(){ + this.grid.getView().wrapEl.unclip(); + }, + + destroy : function(){ + this.grid.getView().unplugDataModel(this.grid.getDataModel()); + this.grid.container.removeAllListeners(); + YAHOO.ext.GridPanel.superclass.destroy.call(this); + } +}); + + +/** + * @class YAHOO.ext.NestedLayoutPanel + * @extends YAHOO.ext.ContentPanel + * @constructor + * Create a new NestedLayoutPanel. + * @param {YAHOO.ext.BorderLayout} layout The layout for this panel + * @param {String/Object} config A string to set only the title or a config object + */ +YAHOO.ext.NestedLayoutPanel = function(layout, config){ + YAHOO.ext.NestedLayoutPanel.superclass.constructor.call(this, layout.getEl(), config); + layout.monitorWindowResize = false; // turn off autosizing + this.layout = layout; + this.layout.getEl().addClass('ylayout-nested-layout'); +}; + +YAHOO.extendX(YAHOO.ext.NestedLayoutPanel, YAHOO.ext.ContentPanel, { + setSize : function(width, height){ + var size = this.adjustForComponents(width, height); + this.layout.getEl().setSize(size.width, size.height); + this.layout.layout(); + }, + + /** + * Returns the nested BorderLayout for this panel + * @return {YAHOO.ext.BorderLayout} + */ + getLayout : function(){ + return this.layout; + } +}); diff --git a/frontend/beta/js/YUI-extensions/layout/LayoutManager.js b/frontend/beta/js/YUI-extensions/layout/LayoutManager.js new file mode 100644 index 0000000..c59bf0e --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/LayoutManager.js @@ -0,0 +1,135 @@ +/** + * @class YAHOO.ext.LayoutManager + * @extends YAHOO.ext.util.Observable + * Base class for layout managers. + */ +YAHOO.ext.LayoutManager = function(container){ + YAHOO.ext.LayoutManager.superclass.constructor.call(this); + this.el = getEl(container, true); + // ie scrollbar fix + if(this.el.dom == document.body && YAHOO.ext.util.Browser.isIE){ + document.body.scroll = 'no'; + } + this.id = this.el.id; + this.el.addClass('ylayout-container'); + /** false to disable window resize monitoring @type Boolean */ + this.monitorWindowResize = true; + this.regions = {}; + this.events = { + /** + * @event layout + * Fires when a layout is performed. + * @param {YAHOO.ext.LayoutManager} this + */ + 'layout' : new YAHOO.util.CustomEvent(), + /** + * @event regionresized + * Fires when the user resizes a region. + * @param {YAHOO.ext.LayoutRegion} region + * @param {Number} newSize The new size (width for east/west, height for north/south) + */ + 'regionresized' : new YAHOO.util.CustomEvent(), + /** + * @event regioncollapsed + * Fires when a region is collapsed. + * @param {YAHOO.ext.LayoutRegion} region + */ + 'regioncollapsed' : new YAHOO.util.CustomEvent(), + /** + * @event regionexpanded + * Fires when a region is expanded. + * @param {YAHOO.ext.LayoutRegion} region + */ + 'regionexpanded' : new YAHOO.util.CustomEvent() + }; + this.updating = false; + YAHOO.ext.EventManager.onWindowResize(this.onWindowResize, this, true); +}; + +YAHOO.extendX(YAHOO.ext.LayoutManager, YAHOO.ext.util.Observable, { + /** + * Returns true if this layout is currently being updated + * @return {Boolean} + */ + isUpdating : function(){ + return this.updating; + }, + + /** + * Suspend the LayoutManager from doing auto-layouts while + * making multiple add or remove calls + */ + beginUpdate : function(){ + this.updating = true; + }, + + /** + * Restore auto-layouts and optionally disable the manager from performing a layout + * @param {Boolean} noLayout true to disable a layout update + */ + endUpdate : function(noLayout){ + this.updating = false; + if(!noLayout){ + this.layout(); + } + }, + + layout: function(){ + + }, + + onRegionResized : function(region, newSize){ + this.fireEvent('regionresized', region, newSize); + this.layout(); + }, + + onRegionCollapsed : function(region){ + this.fireEvent('regioncollapsed', region); + }, + + onRegionExpanded : function(region){ + this.fireEvent('regionexpanded', region); + }, + + /** + * Returns the size of the current view, This method normalizes document.body and element embedded layouts and + * performs box-model adjustments. + * @return {Object} The size as an object {width: (the width), height: (the height)} + */ + getViewSize : function(){ + var size; + if(this.el.dom != document.body){ + this.el.beginMeasure(); + size = this.el.getSize(); + this.el.endMeasure(); + }else{ + size = {width: YAHOO.util.Dom.getViewportWidth(), height: YAHOO.util.Dom.getViewportHeight()}; + } + size.width -= this.el.getBorderWidth('lr')-this.el.getPadding('lr'); + size.height -= this.el.getBorderWidth('tb')-this.el.getPadding('tb'); + return size; + }, + + /** + * Returns the element this layout is bound to. + * @return {YAHOO.ext.Element} + */ + getEl : function(){ + return this.el; + }, + + /** + * Returns the specified region. + * @param {String} target The region key + * @return {YAHOO.ext.LayoutRegion} + */ + getRegion : function(target){ + return this.regions[target.toLowerCase()]; + }, + + onWindowResize : function(){ + if(this.monitorWindowResize){ + this.layout(); + } + } +}); diff --git a/frontend/beta/js/YUI-extensions/layout/LayoutRegion.js b/frontend/beta/js/YUI-extensions/layout/LayoutRegion.js new file mode 100644 index 0000000..fa8a1b6 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/LayoutRegion.js @@ -0,0 +1,496 @@ +/** + * @class YAHOO.ext.LayoutRegion + * @extends YAHOO.ext.util.Observable + * This class represents a region in a layout manager. + * @cfg {Boolean} collapsible False to disable collapsing (defaults to true) + * @cfg {Boolean} floatable False to disable floating (defaults to true) + * @cfg {Object} margins Margins for the element (defaults to {top: 0, left: 0, right:0, bottom: 0}) + * @cfg {Object} cmargins Margins for the element when collapsed (defaults to: north/south {top: 2, left: 0, right:0, bottom: 2} or east/west {top: 0, left: 2, right:2, bottom: 0}) + * @cfg {String} tabPosition 'top' or 'bottom' (defaults to 'bottom') + * @cfg {Boolean} alwaysShowTabs True to always display tabs even when only 1 panel (defaults to false) + * @cfg {Boolean} autoScroll True to enable overflow scrolling (defaults to false) + * @cfg {Boolean} titlebar True to display a title bar (defaults to true) + * @cfg {String} title The title for the region (overrides panel titles) + * @cfg {Boolean} animate True to animate expand/collapse (defaults to false) + * @cfg {Float} duration The duration of the expand/collapse animation in seconds + * @cfg {Float} slideDuration The duration of the slide out/in when collapsed in seconds + * @cfg {Boolean} autoHide False to disable disable autoHide when the mouse leaves the "floated" region (defaults to true) + * @cfg {Boolean} preservePanels True to preserve removed panels so they can be readded later (defaults to false) + * @cfg {Boolean} closeOnTabs True to place the close icon on the tabs instead of the region titlebar (defaults to false) + * @cfg {Boolean} hideTabs True to hide the tab strip (defaults to false) + * @cfg {Boolean} resizeTabs True to enable automatic tab resizing. This will resize the tabs so they are all the same size and fit within + * the space available, similar to FireFox 1.5 tabs (defaults to false) + * @cfg {Number} minTabWidth The minimum tab width (defaults to 40) + * @cfg {Number} preferredTabWidth The preferred tab width (defaults to 150) + */ +YAHOO.ext.LayoutRegion = function(mgr, config, pos){ + YAHOO.ext.LayoutRegion.superclass.constructor.call(this, mgr, config, pos, true); + var dh = YAHOO.ext.DomHelper; + /** This regions container element @type YAHOO.ext.Element */ + this.el = dh.append(mgr.el.dom, {tag: 'div', cls: 'ylayout-panel ylayout-panel-' + this.position}, true); + /** This regions title element @type YAHOO.ext.Element */ + this.titleEl = dh.append(this.el.dom, {tag: 'div', unselectable: 'on', cls: 'yunselectable ylayout-panel-hd ylayout-title-'+this.position, children:[ + {tag: 'span', cls: 'yunselectable ylayout-panel-hd-text', unselectable: 'on', html: ' '}, + {tag: 'div', cls: 'yunselectable ylayout-panel-hd-tools', unselectable: 'on'} + ]}, true); + this.titleEl.enableDisplayMode(); + /** This regions title text element @type HTMLElement */ + this.titleTextEl = this.titleEl.dom.firstChild; + this.tools = getEl(this.titleEl.dom.childNodes[1], true); + this.closeBtn = this.createTool(this.tools.dom, 'ylayout-close'); + this.closeBtn.enableDisplayMode(); + this.closeBtn.on('click', this.closeClicked, this, true); + this.closeBtn.hide(); + /** This regions body element @type YAHOO.ext.Element */ + this.bodyEl = dh.append(this.el.dom, {tag: 'div', cls: 'ylayout-panel-body'}, true); + this.visible = false; + this.collapsed = false; + this.hide(); + this.on('paneladded', this.validateVisibility, this, true); + this.on('panelremoved', this.validateVisibility, this, true); + + this.applyConfig(config); +}; + +YAHOO.extendX(YAHOO.ext.LayoutRegion, YAHOO.ext.BasicLayoutRegion, { + applyConfig : function(config){ + if(config.collapsible && this.position != 'center' && !this.collapsedEl){ + var dh = YAHOO.ext.DomHelper; + this.collapseBtn = this.createTool(this.tools.dom, 'ylayout-collapse-'+this.position); + this.collapseBtn.mon('click', this.collapse, this, true); + /** This regions collapsed element @type YAHOO.ext.Element */ + this.collapsedEl = dh.append(this.mgr.el.dom, {tag: 'div', cls: 'ylayout-collapsed ylayout-collapsed-'+this.position, children:[ + {tag: 'div', cls: 'ylayout-collapsed-tools'} + ]}, true); + if(config.floatable !== false){ + this.collapsedEl.addClassOnOver('ylayout-collapsed-over'); + this.collapsedEl.mon('click', this.collapseClick, this, true); + } + this.expandBtn = this.createTool(this.collapsedEl.dom.firstChild, 'ylayout-expand-'+this.position); + this.expandBtn.mon('click', this.expand, this, true); + } + if(this.collapseBtn){ + this.collapseBtn.setVisible(config.collapsible == true); + } + this.cmargins = config.cmargins || this.cmargins || + (this.position == 'west' || this.position == 'east' ? + {top: 0, left: 2, right:2, bottom: 0} : + {top: 2, left: 0, right:0, bottom: 2}); + this.margins = config.margins || this.margins || {top: 0, left: 0, right:0, bottom: 0}; + this.bottomTabs = config.tabPosition != 'top'; + this.autoScroll = config.autoScroll || false; + if(this.autoScroll){ + this.bodyEl.setStyle('overflow', 'auto'); + }else{ + this.bodyEl.setStyle('overflow', 'hidden'); + } + if((!config.titlebar && !config.title) || config.titlebar === false){ + this.titleEl.hide(); + }else{ + this.titleEl.show(); + if(config.title){ + this.titleTextEl.innerHTML = config.title; + } + } + this.duration = config.duration || .30; + this.slideDuration = config.slideDuration || .45; + this.config = config; + if(config.collapsed){ + this.collapse(true); + } + }, + /** + * Returns true if this region is currently visible. + * @return {Boolean} + */ + isVisible : function(){ + return this.visible; + }, + + getBox : function(){ + var b; + if(!this.collapsed){ + b = this.el.getBox(false, true); + }else{ + b = this.collapsedEl.getBox(false, true); + } + return b; + }, + + getMargins : function(){ + return this.collapsed ? this.cmargins : this.margins; + }, + + highlight : function(){ + this.el.addClass('ylayout-panel-dragover'); + }, + + unhighlight : function(){ + this.el.removeClass('ylayout-panel-dragover'); + }, + + updateBox : function(box){ + this.box = box; + if(!this.collapsed){ + this.el.dom.style.left = box.x + 'px'; + this.el.dom.style.top = box.y + 'px'; + this.el.setSize(box.width, box.height); + var bodyHeight = this.titleEl.isVisible() ? box.height - (this.titleEl.getHeight()||0) : box.height; + bodyHeight -= this.el.getBorderWidth('tb'); + bodyWidth = box.width - this.el.getBorderWidth('rl'); + this.bodyEl.setHeight(bodyHeight); + this.bodyEl.setWidth(bodyWidth); + var tabHeight = bodyHeight; + if(this.tabs){ + tabHeight = this.tabs.syncHeight(bodyHeight); + if(YAHOO.ext.util.Browser.isIE) this.tabs.el.repaint(); + } + this.panelSize = {width: bodyWidth, height: tabHeight}; + if(this.activePanel){ + this.activePanel.setSize(bodyWidth, tabHeight); + } + }else{ + this.collapsedEl.dom.style.left = box.x + 'px'; + this.collapsedEl.dom.style.top = box.y + 'px'; + this.collapsedEl.setSize(box.width, box.height); + } + if(this.tabs){ + this.tabs.autoSizeTabs(); + } + }, + + /** + * Returns the container element for this region. + * @return {YAHOO.ext.Element} + */ + getEl : function(){ + return this.el; + }, + + /** + * Hides this region. + */ + hide : function(){ + if(!this.collapsed){ + this.el.dom.style.left = '-2000px'; + this.el.hide(); + }else{ + this.collapsedEl.dom.style.left = '-2000px'; + this.collapsedEl.hide(); + } + this.visible = false; + this.fireEvent('visibilitychange', this, false); + }, + + /** + * Shows this region if it was previously hidden. + */ + show : function(){ + if(!this.collapsed){ + this.el.show(); + }else{ + this.collapsedEl.show(); + } + this.visible = true; + this.fireEvent('visibilitychange', this, true); + }, + + closeClicked : function(){ + if(this.activePanel){ + this.remove(this.activePanel); + } + }, + + collapseClick : function(e){ + if(this.isSlid){ + e.stopPropagation(); + this.slideIn(); + }else{ + e.stopPropagation(); + this.slideOut(); + } + }, + + /** + * Collapses this region. + * @param {Boolean} skipAnim (optional) true to collapse the element without animation (if animate is true) + */ + collapse : function(skipAnim){ + if(this.collapsed) return; + this.collapsed = true; + if(this.split){ + this.split.el.hide(); + } + if(this.config.animate && skipAnim !== true){ + this.fireEvent('invalidated', this); + this.animateCollapse(); + }else{ + this.el.setLocation(-20000,-20000); + this.el.hide(); + this.collapsedEl.show(); + this.fireEvent('collapsed', this); + this.fireEvent('invalidated', this); + } + }, + + animateCollapse : function(){ + // overridden + }, + + /** + * Expand this region if it was previously collapsed. + * @param {YAHOO.ext.EventObject} e The event that triggered the expand (or null if calling manually) + * @param {Boolean} skipAnim (optional) true to expand the element without animation (if animate is true) + */ + expand : function(e, skipAnim){ + if(e) e.stopPropagation(); + if(!this.collapsed) return; + if(this.isSlid){ + this.slideIn(this.expand.createDelegate(this)); + return; + } + this.collapsed = false; + this.el.show(); + if(this.config.animate && skipAnim !== true){ + this.animateExpand(); + }else{ + if(this.split){ + this.split.el.show(); + } + this.collapsedEl.setLocation(-2000,-2000); + this.collapsedEl.hide(); + this.fireEvent('invalidated', this); + this.fireEvent('expanded', this); + } + }, + + animateExpand : function(){ + // overridden + }, + + initTabs : function(){ + this.bodyEl.setStyle('overflow', 'hidden'); + var ts = new YAHOO.ext.TabPanel(this.bodyEl.dom, this.bottomTabs); + if(this.config.hideTabs){ + ts.stripWrap.setDisplayed(false); + } + this.tabs = ts; + ts.resizeTabs = this.config.resizeTabs === true; + ts.minTabWidth = this.config.minTabWidth || 40; + ts.maxTabWidth = this.config.maxTabWidth || 250; + ts.preferredTabWidth = this.config.preferredTabWidth || 150; + ts.monitorResize = false; + ts.bodyEl.setStyle('overflow', this.config.autoScroll ? 'auto' : 'hidden'); + this.panels.each(this.initPanelAsTab, this); + }, + + initPanelAsTab : function(panel){ + var ti = this.tabs.addTab(panel.getEl().id, panel.getTitle(), null, + this.config.closeOnTab && panel.isClosable()); + ti.on('activate', function(){ + this.setActivePanel(panel); + }, this, true); + if(this.config.closeOnTab){ + ti.on('beforeclose', function(t, e){ + e.cancel = true; + this.remove(panel); + }, this, true); + } + return ti; + }, + + updatePanelTitle : function(panel, title){ + if(this.activePanel == panel){ + this.updateTitle(title); + } + if(this.tabs){ + this.tabs.getTab(panel.getEl().id).setText(title); + } + }, + + updateTitle : function(title){ + if(this.titleTextEl && !this.config.title){ + this.titleTextEl.innerHTML = (typeof title != 'undefined' && title.length > 0 ? title : " "); + } + }, + + setActivePanel : function(panel){ + panel = this.getPanel(panel); + if(this.activePanel && this.activePanel != panel){ + this.activePanel.setActiveState(false); + } + this.activePanel = panel; + panel.setActiveState(true); + if(this.panelSize){ + panel.setSize(this.panelSize.width, this.panelSize.height); + } + this.closeBtn.setVisible(!this.config.closeOnTab && !this.isSlid && panel.isClosable()); + this.updateTitle(panel.getTitle()); + this.fireEvent('panelactivated', this, panel); + }, + + /** + * Show the specified panel. + * @param {Number/String/ContentPanel} panelId The panels index, id or the panel itself + * @return {YAHOO.ext.ContentPanel} The shown panel or null + */ + showPanel : function(panel){ + if(panel = this.getPanel(panel)){ + if(this.tabs){ + this.tabs.activate(panel.getEl().id); + }else{ + this.setActivePanel(panel); + } + } + return panel; + }, + + /** + * Get the active panel for this region. + * @return {YAHOO.ext.ContentPanel} The active panel or null + */ + getActivePanel : function(){ + return this.activePanel; + }, + + validateVisibility : function(){ + if(this.panels.getCount() < 1){ + this.updateTitle(' '); + this.closeBtn.hide(); + this.hide(); + }else{ + if(!this.isVisible()){ + this.show(); + } + } + }, + + /** + * Add the passed ContentPanel(s) + * @param {ContentPanel...} panel The ContentPanel(s) to add (you can pass more than one) + * @return {YAHOO.ext.ContentPanel} The panel added (if only one was added) + */ + add : function(panel){ + if(arguments.length > 1){ + for(var i = 0, len = arguments.length; i < len; i++) { + this.add(arguments[i]); + } + return null; + } + if(this.hasPanel(panel)){ + this.showPanel(panel); + return panel; + } + panel.setRegion(this); + this.panels.add(panel); + if(this.panels.getCount() == 1 && !this.config.alwaysShowTabs){ + this.bodyEl.dom.appendChild(panel.getEl().dom); + if(panel.background !== true){ + this.setActivePanel(panel); + } + this.fireEvent('paneladded', this, panel); + return panel; + } + if(!this.tabs){ + this.initTabs(); + }else{ + this.initPanelAsTab(panel); + } + if(panel.background !== true){ + this.tabs.activate(panel.getEl().id); + } + this.fireEvent('paneladded', this, panel); + return panel; + }, + + /** + * Hides the tab for the specified panel. + * @param {Number/String/ContentPanel} panel The panels index, id or the panel itself + */ + hidePanel : function(panel){ + if(this.tabs && (panel = this.getPanel(panel))){ + this.tabs.hideTab(panel.getEl().id); + } + }, + + /** + * Unhides the tab for a previously hidden panel. + * @param {Number/String/ContentPanel} panel The panels index, id or the panel itself + */ + unhidePanel : function(panel){ + if(this.tabs && (panel = this.getPanel(panel))){ + this.tabs.unhideTab(panel.getEl().id); + } + }, + + clearPanels : function(){ + while(this.panels.getCount() > 0){ + this.remove(this.panels.first()); + } + }, + + /** + * Removes the specified panel. If preservePanel is not true (either here or in the config), the panel is destroyed. + * @param {Number/String/ContentPanel} panel The panels index, id or the panel itself + * @param {Boolean} preservePanel Overrides the config preservePanel option + * @return {YAHOO.ext.ContentPanel} The panel that was removed + */ + remove : function(panel, preservePanel){ + panel = this.getPanel(panel); + if(!panel){ + return null; + } + var e = {}; + this.fireEvent('beforeremove', this, panel, e); + if(e.cancel === true){ + return null; + } + preservePanel = (typeof preservePanel != 'undefined' ? preservePanel : (this.config.preservePanels === true || panel.preserve === true)); + var panelId = panel.getId(); + this.panels.removeKey(panelId); + if(preservePanel){ + document.body.appendChild(panel.getEl().dom); + } + if(this.tabs){ + this.tabs.removeTab(panel.getEl().id); + }else if (!preservePanel){ + this.bodyEl.dom.removeChild(panel.getEl().dom); + } + if(this.panels.getCount() == 1 && this.tabs && !this.config.alwaysShowTabs){ + var p = this.panels.first(); + var tempEl = document.createElement('span'); // temp holder to keep IE from deleting the node + tempEl.appendChild(p.getEl().dom); + this.bodyEl.update(''); + this.bodyEl.dom.appendChild(p.getEl().dom); + tempEl = null; + this.updateTitle(p.getTitle()); + this.tabs = null; + this.bodyEl.setStyle('overflow', this.config.autoScroll ? 'auto' : 'hidden'); + this.setActivePanel(p); + } + panel.setRegion(null); + if(this.activePanel == panel){ + this.activePanel = null; + } + if(this.config.autoDestroy !== false && preservePanel !== true){ + try{panel.destroy();}catch(e){} + } + this.fireEvent('panelremoved', this, panel); + return panel; + }, + + /** + * Returns the TabPanel component used by this region + * @return {YAHOO.ext.TabPanel} + */ + getTabs : function(){ + return this.tabs; + }, + + createTool : function(parentEl, className){ + var btn = YAHOO.ext.DomHelper.append(parentEl, {tag: 'div', cls: 'ylayout-tools-button', + children: [{tag: 'div', cls: 'ylayout-tools-button-inner ' + className, html: ' '}]}, true); + btn.addClassOnOver('ylayout-tools-button-over'); + return btn; + } +}); diff --git a/frontend/beta/js/YUI-extensions/layout/LayoutStateManager.js b/frontend/beta/js/YUI-extensions/layout/LayoutStateManager.js new file mode 100644 index 0000000..ea22235 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/LayoutStateManager.js @@ -0,0 +1,68 @@ +/* + * Private internal class for reading and applying state + */ +YAHOO.ext.LayoutStateManager = function(layout){ + // default empty state + this.state = { + north: {}, + south: {}, + east: {}, + west: {} + }; +}; + +YAHOO.ext.LayoutStateManager.prototype = { + init : function(layout, provider){ + this.provider = provider; + var state = provider.get(layout.id+'-layout-state'); + if(state){ + var wasUpdating = layout.isUpdating(); + if(!wasUpdating){ + layout.beginUpdate(); + } + for(var key in state){ + if(typeof state[key] != 'function'){ + var rstate = state[key]; + var r = layout.getRegion(key); + if(r && rstate){ + if(rstate.size){ + r.resizeTo(rstate.size); + } + if(rstate.collapsed == true){ + r.collapse(true); + }else{ + r.expand(null, true); + } + } + } + } + if(!wasUpdating){ + layout.endUpdate(); + } + this.state = state; + } + this.layout = layout; + layout.on('regionresized', this.onRegionResized, this, true); + layout.on('regioncollapsed', this.onRegionCollapsed, this, true); + layout.on('regionexpanded', this.onRegionExpanded, this, true); + }, + + storeState : function(){ + this.provider.set(this.layout.id+'-layout-state', this.state); + }, + + onRegionResized : function(region, newSize){ + this.state[region.getPosition()].size = newSize; + this.storeState(); + }, + + onRegionCollapsed : function(region){ + this.state[region.getPosition()].collapsed = true; + this.storeState(); + }, + + onRegionExpanded : function(region){ + this.state[region.getPosition()].collapsed = false; + this.storeState(); + } +}; diff --git a/frontend/beta/js/YUI-extensions/layout/SplitLayoutRegion.js b/frontend/beta/js/YUI-extensions/layout/SplitLayoutRegion.js new file mode 100644 index 0000000..6b8ce9e --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/layout/SplitLayoutRegion.js @@ -0,0 +1,282 @@ +/** + * @class YAHOO.ext.SplitLayoutRegion + * @extends YAHOO.ext.LayoutRegion + * Adds a splitbar and other (private) useful functionality to a LayoutRegion + */ +YAHOO.ext.SplitLayoutRegion = function(mgr, config, pos, cursor){ + this.cursor = cursor; + YAHOO.ext.SplitLayoutRegion.superclass.constructor.call(this, mgr, config, pos); + if(config.split){ + this.hide(); + } +}; + +YAHOO.extendX(YAHOO.ext.SplitLayoutRegion, YAHOO.ext.LayoutRegion, { + applyConfig : function(config){ + YAHOO.ext.SplitLayoutRegion.superclass.applyConfig.call(this, config); + if(config.split){ + if(!this.split){ + var splitEl = YAHOO.ext.DomHelper.append(this.mgr.el.dom, + {tag: 'div', id: this.el.id + '-split', cls: 'ylayout-split ylayout-split-'+this.position, html: ' '}); + /** The SplitBar for this region @type YAHOO.ext.SplitBar */ + this.split = new YAHOO.ext.SplitBar(splitEl, this.el); + this.split.onMoved.subscribe(this.onSplitMove, this, true); + this.split.useShim = config.useShim === true; + YAHOO.util.Dom.setStyle([this.split.el.dom, this.split.proxy], 'cursor', this.cursor); + this.split.getMaximumSize = this.getMaxSize.createDelegate(this); + } + if(typeof config.minSize != 'undefined'){ + this.split.minSize = config.minSize; + } + if(typeof config.maxSize != 'undefined'){ + this.split.maxSize = config.maxSize; + } + } + }, + + getMaxSize : function(){ + var cmax = this.config.maxSize || 10000; + var center = this.mgr.getRegion('center'); + return Math.min(cmax, (this.el.getWidth()+center.getEl().getWidth())-center.getMinWidth()); + }, + + onSplitMove : function(split, newSize){ + this.fireEvent('resized', this, newSize); + }, + + /** + * Returns the SplitBar for this region. + * @return {YAHOO.ext.SplitBar} + */ + getSplitBar : function(){ + return this.split; + }, + + hide : function(){ + if(this.split){ + this.split.el.setLocation(-2000,-2000); + this.split.el.hide(); + } + YAHOO.ext.SplitLayoutRegion.superclass.hide.call(this); + }, + + show : function(){ + if(this.split){ + this.split.el.show(); + } + YAHOO.ext.SplitLayoutRegion.superclass.show.call(this); + }, + + beforeSlide: function(){ + if(YAHOO.ext.util.Browser.isGecko){// firefox overflow auto bug workaround + this.bodyEl.clip(); + if(this.tabs) this.tabs.bodyEl.clip(); + if(this.activePanel){ + this.activePanel.getEl().clip(); + + if(this.activePanel.beforeSlide){ + this.activePanel.beforeSlide(); + } + } + } + }, + + afterSlide : function(){ + if(YAHOO.ext.util.Browser.isGecko){// firefox overflow auto bug workaround + this.bodyEl.unclip(); + if(this.tabs) this.tabs.bodyEl.unclip(); + if(this.activePanel){ + this.activePanel.getEl().unclip(); + if(this.activePanel.afterSlide){ + this.activePanel.afterSlide(); + } + } + } + }, + + slideOut : function(){ + if(!this.slideEl){ + this.slideEl = new YAHOO.ext.Actor( + YAHOO.ext.DomHelper.append(this.mgr.el.dom, {tag: 'div', cls:'ylayout-slider'})); + if(this.config.autoHide !== false){ + var slideInTask = new YAHOO.ext.util.DelayedTask(this.slideIn, this); + this.slideEl.mon('mouseout', function(e){ + var to = e.getRelatedTarget(); + if(to && to != this.slideEl.dom && !YAHOO.util.Dom.isAncestor(this.slideEl.dom, to)){ + slideInTask.delay(500); + } + }, this, true); + this.slideEl.mon('mouseover', function(e){ + slideInTask.cancel(); + }, this, true); + } + } + var sl = this.slideEl, c = this.collapsedEl, cm = this.cmargins; + this.isSlid = true; + this.snapshot = { + 'left': this.el.getLeft(true), + 'top': this.el.getTop(true), + 'colbtn': this.collapseBtn.isVisible(), + 'closebtn': this.closeBtn.isVisible() + }; + this.collapseBtn.hide(); + this.closeBtn.hide(); + this.el.show(); + this.el.setLeftTop(0,0); + sl.startCapture(true); + var size; + switch(this.position){ + case 'west': + sl.setLeft(c.getRight(true)); + sl.setTop(c.getTop(true)); + size = this.el.getWidth(); + break; + case 'east': + sl.setRight(this.mgr.getViewSize().width-c.getLeft(true)); + sl.setTop(c.getTop(true)); + size = this.el.getWidth(); + break; + case 'north': + sl.setLeft(c.getLeft(true)); + sl.setTop(c.getBottom(true)); + size = this.el.getHeight(); + break; + case 'south': + sl.setLeft(c.getLeft(true)); + sl.setBottom(this.mgr.getViewSize().height-c.getTop(true)); + size = this.el.getHeight(); + break; + } + sl.dom.appendChild(this.el.dom); + YAHOO.util.Event.on(document.body, 'click', this.slideInIf, this, true); + sl.setSize(this.el.getWidth(), this.el.getHeight()); + this.beforeSlide(); + if(this.activePanel){ + this.activePanel.setSize(this.bodyEl.getWidth(), this.bodyEl.getHeight()); + } + sl.slideShow(this.getAnchor(), size, this.slideDuration, null, false); + sl.play(function(){ + this.afterSlide(); + }.createDelegate(this)); + }, + + slideInIf : function(e){ + var t = YAHOO.util.Event.getTarget(e); + if(!YAHOO.util.Dom.isAncestor(this.el.dom, t)){ + this.slideIn(); + } + }, + + slideIn : function(callback){ + if(this.isSlid && !this.slideEl.playlist.isPlaying()){ + YAHOO.util.Event.removeListener(document.body, 'click', this.slideInIf, this, true); + this.slideEl.startCapture(true); + this.slideEl.slideHide(this.getAnchor(), this.slideDuration, null); + this.beforeSlide(); + this.slideEl.play(function(){ + this.isSlid = false; + this.el.setPositioning(this.snapshot); + this.collapseBtn.setVisible(this.snapshot.colbtn); + this.closeBtn.setVisible(this.snapshot.closebtn); + this.afterSlide(); + this.mgr.el.dom.appendChild(this.el.dom); + if(typeof callback == 'function'){ + callback(); + } + }.createDelegate(this)); + } + }, + + animateExpand : function(){ + var em = this.margins, cm = this.cmargins; + var c = this.collapsedEl, el = this.el; + var direction, distance; + switch(this.position){ + case 'west': + direction = 'right'; + el.setLeft(-(el.getWidth() + (em.right+em.left))); + el.setTop(c.getTop(true)-cm.top+em.top); + distance = el.getWidth() + (em.right+em.left); + break; + case 'east': + direction = 'left'; + el.setLeft(this.mgr.getViewSize().width + em.left); + el.setTop(c.getTop(true)-cm.top+em.top); + distance = el.getWidth() + (em.right+em.left); + break; + case 'north': + direction = 'down'; + el.setLeft(em.left); + el.setTop(-(el.getHeight() + (em.top+em.bottom))); + distance = el.getHeight() + (em.top+em.bottom); + break; + case 'south': + direction = 'up'; + el.setLeft(em.left); + el.setTop(this.mgr.getViewSize().height + em.top); + distance = el.getHeight() + (em.top+em.bottom); + break; + } + this.beforeSlide(); + el.setStyle('z-index', '100'); + el.show(); + c.setLocation(-2000,-2000); + c.hide(); + el.move(direction, distance, true, this.duration, function(){ + this.afterSlide(); + el.setStyle('z-index', ''); + if(this.split){ + this.split.el.show(); + } + this.fireEvent('invalidated', this); + this.fireEvent('expanded', this); + }.createDelegate(this), this.config.easing || YAHOO.util.Easing.easeOut); + }, + + animateCollapse : function(){ + var em = this.margins, cm = this.cmargins; + var c = this.collapsedEl, el = this.el; + var direction, distance; + switch(this.position){ + case 'west': + direction = 'left'; + distance = el.getWidth() + (em.right+em.left); + break; + case 'east': + direction = 'right'; + distance = el.getWidth() + (em.right+em.left); + break; + case 'north': + direction = 'up'; + distance = el.getHeight() + (em.top+em.bottom); + break; + case 'south': + direction = 'down'; + distance = el.getHeight() + (em.top+em.bottom); + break; + } + this.el.setStyle('z-index', '100'); + this.beforeSlide(); + this.el.move(direction, distance, true, this.duration, function(){ + this.afterSlide(); + this.el.setStyle('z-index', ''); + this.el.setLocation(-20000,-20000); + this.el.hide(); + this.collapsedEl.show(); + this.fireEvent('collapsed', this); + }.createDelegate(this), YAHOO.util.Easing.easeIn); + }, + + getAnchor : function(){ + switch(this.position){ + case 'west': + return 'left'; + case 'east': + return 'right'; + case 'north': + return 'top'; + case 'south': + return 'bottom'; + } + } +}); -- cgit v0.9.0.2