package org.ovirt.engine.ui.common.widget.form; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.gwtbootstrap3.client.ui.Column; import org.gwtbootstrap3.client.ui.Container; import org.gwtbootstrap3.client.ui.Row; import org.ovirt.engine.ui.common.idhandler.HasElementId; import org.ovirt.engine.ui.common.utils.ElementIdUtils; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; /** * Represents a form panel that renders name/value items organized in columns. */ public abstract class AbstractFormPanel extends Composite implements HasElementId { interface Style extends CssResource { String formPanelLabel(); String formPanelValue(); } //There can be a max of 12 columns private static final int BOOTSTRAP_GRID_SIZE = 12; private static final String COL_PREFIX = "md_"; //$NON-NLS-1$ /** * Stores the label width and item width so we can look them up based on the {@code FormItem}. * Index 0 is the label, index 1 is the item width. */ private Map<FormItem, List<Integer>> formSizeMap = new HashMap<>(); protected String elementId = DOM.createUniqueId(); @UiField public Container container; @UiField public Style style; // Used with form item auto placement feature private final Map<Integer, Integer> nextAvailableRowForColumn = new HashMap<>(); public int getNextAvailableRow(int column) { if(!nextAvailableRowForColumn.containsKey(column)) { nextAvailableRowForColumn.put(column, 0); } return nextAvailableRowForColumn.get(column); } void incNextAvailableRow(int column) { int curRow = getNextAvailableRow(column); nextAvailableRowForColumn.put(column, curRow + 1); } /** * Adds new detail view (column) to the form panel. */ public void addFormDetailView(int numOfRows, int numOfColumns) { container.clear(); for (int i = 0; i < numOfRows; i++) { Row row = createRow(numOfColumns); container.add(row); } } public void setRelativeColumnWidth(int columnNum, int widthInGridColumns) { for(int i = 0; i < container.getWidgetCount(); i++) { Row row = (Row) container.getWidget(i); Column column = (Column) row.getWidget(columnNum); column.setSize(COL_PREFIX + widthInGridColumns); } } private Row createRow(int numOfColumns) { Row row = new Row(); //Evenly distribute by default. String columnSize = COL_PREFIX + (BOOTSTRAP_GRID_SIZE / numOfColumns); for (int i = 0; i < numOfColumns; i++) { Column column = new Column(columnSize); row.add(column); } return row; } public void addFormItem(FormItem item) { addFormItem(item, 6, 6); } /** * Adds new item to the form panel. */ public void addFormItem(FormItem item, int labelWidth, int valueWidth) { updateItemSizes(item, labelWidth, valueWidth); // Create item label Label itemLabel = new Label(item.getName()); itemLabel.getElement().setId(ElementIdUtils.createFormGridElementId(elementId, item.getColumn(), item.getRow(), "_label")); //$NON-NLS-1$ itemLabel.setStyleName(style.formPanelLabel()); Row itemRow = new Row(); Column labelColumn = new Column(COL_PREFIX + labelWidth); labelColumn.add(itemLabel); itemRow.add(labelColumn); Column itemColumn = findColumn(item.getRow(), item.getColumn()); if (itemColumn != null) { itemColumn.add(itemRow); } // Update the item updateFormItem(item, valueWidth); // Update auto placement data incNextAvailableRow(item.getColumn()); } private void updateItemSizes(FormItem item, int labelWidth, int valueWidth) { List<Integer> sizesList = formSizeMap.get(item); if (sizesList == null) { sizesList = new ArrayList<>(); formSizeMap.put(item, sizesList); } sizesList.clear(); sizesList.add(labelWidth); sizesList.add(valueWidth); } private Column findColumn(int row, int column) { Column result = null; IsWidget rowWidget = container.getWidget(row); if (rowWidget instanceof Row) { IsWidget columnWidget = ((Row) rowWidget).getWidget(column); if (columnWidget instanceof Column) { result = (Column) columnWidget; } } return result; } public void updateFormItem(FormItem item) { updateFormItem(item, null); } /** * Updates the value and visibility of the given item. */ public void updateFormItem(FormItem item, Integer labelWidth) { Widget valueWidget = item.resolveValueWidget(); valueWidget.getElement().setId( ElementIdUtils.createFormGridElementId(elementId, item.getColumn(), item.getRow(), "_value")); //$NON-NLS-1$ valueWidget.setStyleName(style.formPanelValue()); boolean visible = item.getIsAvailable(); Column widgetColumn = findColumn(item.getRow(), item.getColumn()); if (widgetColumn != null) { IsWidget itemCell = widgetColumn.getWidget(0); if (itemCell instanceof Row) { Row itemCellRow = (Row)itemCell; // Update item visibility itemCellRow.setVisible(visible); if(itemCellRow.getWidgetCount() > 1) { itemCellRow.remove(1); //Clear out old value. } Column valueColumn = new Column(COL_PREFIX + determineRealLabelWidth(item, labelWidth)); valueColumn.add(valueWidget); itemCellRow.add(valueColumn); } } } /** * Determine the real width the label should be. * @param item The item to determine the width for. * @param labelWidth If not null store the label width and return the value. If null look up the value. * @return The actual width the label should be, even if not supplied. */ int determineRealLabelWidth(FormItem item, Integer labelWidth) { List<Integer> sizesList = formSizeMap.get(item); if (labelWidth != null) { sizesList.set(1, labelWidth); } return sizesList.get(1); } @Override public void setElementId(String elementId) { this.elementId = elementId; } }