001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.uif.layout;
017
018import org.kuali.rice.krad.datadictionary.parse.BeanTag;
019import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
020import org.kuali.rice.krad.uif.component.Component;
021import org.kuali.rice.krad.uif.container.Container;
022import org.kuali.rice.krad.uif.util.LifecycleElement;
023
024import java.util.ArrayList;
025import java.util.List;
026
027/**
028 * Css Grid Layout manager is a layout manager which creates div "rows" and "cells" to replicate a
029 * table look by using div elements for its items.
030 *
031 * <p>
032 * Items are added into rows based on their colSpan
033 * setting, while each row has a max size of 12 columns. By default, if colSpan is not set on an
034 * item, that item will take a full row.
035 * </p>
036 *
037 * @author Kuali Rice Team (rice.collab@kuali.org)
038 */
039@BeanTag(name = "cssGridLayout", parent = "Uif-CssGridLayout")
040public class CssGridLayoutManager extends CssGridLayoutManagerBase {
041    private static final long serialVersionUID = 1830635073147703757L;
042
043    private int defaultItemSize;
044
045    private CssGridSizes defaultItemSizes;
046
047    public CssGridLayoutManager() {
048        super();
049
050        defaultItemSizes = new CssGridSizes();
051    }
052
053    /**
054     * CssGridLayoutManager's performFinalize method calculates and separates the items into rows
055     * based on their colSpan settings and the defaultItemSize setting
056     *
057     * {@inheritDoc}
058     */
059    @Override
060    public void performFinalize(Object model, LifecycleElement component) {
061        super.performFinalize(model, component);
062
063        Container container = (Container) component;
064        cellItems = new ArrayList<Component>();
065        processNormalLayout(container);
066
067    }
068
069    /**
070     * Separates the container's items into the appropriate number of rows and div "cells" based on
071     * the defaultColSpan property settings and colSpan settings of the items
072     *
073     * @param container the container using this layout manager
074     */
075    private void processNormalLayout(Container container) {
076        for (Component item : container.getItems()) {
077            if (item == null) {
078                continue;
079            }
080
081            // set colSpan to default setting (12 is the default)
082            int colSpan = this.defaultItemSize;
083
084            // if the item's mdSize is set, use that as the col span for calculations below
085            if (item.getColSpan() > 1 && item.getColSpan() <= NUMBER_OF_COLUMNS) {
086                colSpan = item.getColSpan();
087            }
088
089            List<String> cellCssClasses = item.getWrapperCssClasses();
090            if (cellCssClasses == null) {
091                item.setWrapperCssClasses(new ArrayList<String>());
092                cellCssClasses = item.getWrapperCssClasses();
093            }
094
095            // Determine "cell" div css
096            calculateCssClassAndSize(item, cellCssClasses, defaultItemSizes, colSpan);
097
098            // Add dynamic left clear classes for potential wrapping content at each screen size
099            addLeftClearCssClass(cellCssClasses);
100
101            cellCssClassAttributes.add(getCellStyleClassesAsString(cellCssClasses));
102            cellItems.add(item);
103        }
104    }
105
106    /**
107     * The default "cell" size to use for this layout - this converts to medium size
108     * (max setting, and the default, is 12)
109     *
110     * <p>
111     * This is a quick and easy setter for default mdSize for this layout, as a common use case is to have
112     * a different layout for medium devices and up, while small and extra small will consume the full screen.
113     * For customizations at every screen size, use defaultItemSizes.
114     * </p>
115     *
116     * @return int representing the default colSpan for cells in this layout
117     */
118    @BeanTagAttribute
119    public int getDefaultItemSize() {
120        return defaultItemSize;
121    }
122
123    /**
124     * Set the default colSpan for this layout's items
125     *
126     * @param defaultItemSize
127     */
128    public void setDefaultItemSize(int defaultItemSize) {
129        this.defaultItemSize = defaultItemSize;
130    }
131
132    /**
133     * Default sizes for each item in this css grid layout, these settings will override the setting in
134     * defaultItemSize,
135     * but will not override item specific cssGridSizes.
136     *
137     * @return cssGridSizes containing the sizes of items in this group to use as default
138     */
139    public CssGridSizes getDefaultItemSizes() {
140        return defaultItemSizes;
141    }
142
143    /**
144     * @see org.kuali.rice.krad.uif.layout.CssGridLayoutManager#getDefaultItemSizes()
145     */
146    public void setDefaultItemSizes(CssGridSizes defaultItemSizes) {
147        this.defaultItemSizes = defaultItemSizes;
148    }
149}