Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / layout / container / CheckboxGroup.js
diff --git a/src/layout/container/CheckboxGroup.js b/src/layout/container/CheckboxGroup.js
new file mode 100644 (file)
index 0000000..393c61d
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * @class Ext.layout.container.CheckboxGroup
+ * @extends Ext.layout.container.Container
+ * <p>This layout implements the column arrangement for {@link Ext.form.CheckboxGroup} and {@link Ext.form.RadioGroup}.
+ * It groups the component's sub-items into columns based on the component's
+ * {@link Ext.form.CheckboxGroup#columns columns} and {@link Ext.form.CheckboxGroup#vertical} config properties.</p>
+ *
+ */
+Ext.define('Ext.layout.container.CheckboxGroup', {
+    extend: 'Ext.layout.container.Container',
+    alias: ['layout.checkboxgroup'],
+
+
+    onLayout: function() {
+        var numCols = this.getColCount(),
+            shadowCt = this.getShadowCt(),
+            owner = this.owner,
+            items = owner.items,
+            shadowItems = shadowCt.items,
+            numItems = items.length,
+            colIndex = 0,
+            i, numRows;
+
+        // Distribute the items into the appropriate column containers. We add directly to the
+        // containers' items collection rather than calling container.add(), because we need the
+        // checkboxes to maintain their original ownerCt. The distribution is done on each layout
+        // in case items have been added, removed, or reordered.
+
+        shadowItems.each(function(col) {
+            col.items.clear();
+        });
+
+        // If columns="auto", then the number of required columns may change as checkboxes are added/removed
+        // from the CheckboxGroup; adjust to match.
+        while (shadowItems.length > numCols) {
+            shadowCt.remove(shadowItems.last());
+        }
+        while (shadowItems.length < numCols) {
+            shadowCt.add({
+                xtype: 'container',
+                cls: owner.groupCls,
+                flex: 1
+            });
+        }
+
+        if (owner.vertical) {
+            numRows = Math.ceil(numItems / numCols);
+            for (i = 0; i < numItems; i++) {
+                if (i > 0 && i % numRows === 0) {
+                    colIndex++;
+                }
+                shadowItems.getAt(colIndex).items.add(items.getAt(i));
+            }
+        } else {
+            for (i = 0; i < numItems; i++) {
+                colIndex = i % numCols;
+                shadowItems.getAt(colIndex).items.add(items.getAt(i));
+            }
+        }
+
+        if (!shadowCt.rendered) {
+            shadowCt.render(this.getRenderTarget());
+        } else {
+            // Ensure all items are rendered in the correct place in the correct column - this won't
+            // get done by the column containers themselves if their dimensions are not changing.
+            shadowItems.each(function(col) {
+                var layout = col.getLayout();
+                layout.renderItems(layout.getLayoutItems(), layout.getRenderTarget());
+            });
+        }
+
+        shadowCt.doComponentLayout();
+    },
+
+
+    // We don't want to render any items to the owner directly, that gets handled by each column's own layout
+    renderItems: Ext.emptyFn,
+
+
+    /**
+     * @private
+     * Creates and returns the shadow hbox container that will be used to arrange the owner's items
+     * into columns.
+     */
+    getShadowCt: function() {
+        var me = this,
+            shadowCt = me.shadowCt,
+            owner, items, item, columns, columnsIsArray, numCols, i;
+
+        if (!shadowCt) {
+            // Create the column containers based on the owner's 'columns' config
+            owner = me.owner;
+            columns = owner.columns;
+            columnsIsArray = Ext.isArray(columns);
+            numCols = me.getColCount();
+            items = [];
+            for(i = 0; i < numCols; i++) {
+                item = {
+                    xtype: 'container',
+                    cls: owner.groupCls
+                };
+                if (columnsIsArray) {
+                    // Array can contain mixture of whole numbers, used as fixed pixel widths, and fractional
+                    // numbers, used as relative flex values.
+                    if (columns[i] < 1) {
+                        item.flex = columns[i];
+                    } else {
+                        item.width = columns[i];
+                    }
+                }
+                else {
+                    // All columns the same width
+                    item.flex = 1;
+                }
+                items.push(item);
+            }
+
+            // Create the shadow container; delay rendering until after items are added to the columns
+            shadowCt = me.shadowCt = Ext.createWidget('container', {
+                layout: 'hbox',
+                items: items,
+                ownerCt: owner
+            });
+        }
+        
+        return shadowCt;
+    },
+
+
+    /**
+     * @private Get the number of columns in the checkbox group
+     */
+    getColCount: function() {
+        var owner = this.owner,
+            colsCfg = owner.columns;
+        return Ext.isArray(colsCfg) ? colsCfg.length : (Ext.isNumber(colsCfg) ? colsCfg : owner.items.length);
+    }
+
+});