blob: 6229ecbe1d6b382418150a118d54a3b21af24d71 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.android.designer.model.layout.table;
import com.android.SdkConstants;
import com.android.ide.common.rendering.api.ViewInfo;
import com.intellij.android.designer.model.RadComponentOperations;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.android.designer.model.RadViewContainer;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.android.designer.model.grid.IGridProvider;
import com.intellij.designer.model.RadComponent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import java.awt.*;
import java.lang.reflect.Field;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class RadTableLayoutComponent extends RadViewContainer implements IGridProvider {
private GridInfo myGridInfo;
private GridInfo myVirtualGridInfo;
@Override
public void setViewInfo(ViewInfo viewInfo) {
super.setViewInfo(viewInfo);
myGridInfo = null;
myVirtualGridInfo = null;
}
private int[] getColumnWidths() {
try {
Object viewObject = myViewInfo.getViewObject();
Class<?> viewClass = viewObject.getClass();
Field maxWidths = viewClass.getDeclaredField("mMaxWidths");
maxWidths.setAccessible(true);
int[] columnWidths = (int[])maxWidths.get(viewObject);
return columnWidths == null ? ArrayUtil.EMPTY_INT_ARRAY : columnWidths;
}
catch (Throwable e) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
}
@Override
public GridInfo getGridInfo() {
if (myGridInfo == null) {
myGridInfo = new GridInfo(this);
int[] columnWidths = getColumnWidths();
if (columnWidths.length > 0) {
myGridInfo.emptyColumns = new boolean[columnWidths.length];
myGridInfo.vLines = new int[columnWidths.length + 1];
for (int i = 0; i < columnWidths.length; i++) {
int width = Math.max(columnWidths[i], 0);
myGridInfo.emptyColumns[i] = width == 0;
if (width == 0) {
width = 2;
if (i + 1 < columnWidths.length) {
columnWidths[i + 1] -= width;
}
}
myGridInfo.width += width;
myGridInfo.vLines[i + 1] = myGridInfo.width;
}
}
List<RadComponent> rows = getChildren();
if (!rows.isEmpty()) {
Rectangle bounds = getBounds();
if (columnWidths.length == 0) {
myGridInfo.width = bounds.width;
}
myGridInfo.hLines = new int[rows.size() + 1];
int index = 1;
for (RadComponent row : rows) {
Rectangle rowBounds = row.getBounds();
myGridInfo.hLines[index++] = myGridInfo.height = rowBounds.y - bounds.y + rowBounds.height;
}
}
}
return myGridInfo;
}
@Override
public GridInfo getVirtualGridInfo() {
if (myVirtualGridInfo == null) {
myVirtualGridInfo = new GridInfo(this);
GridInfo gridInfo = getGridInfo();
Rectangle bounds = getBounds();
myVirtualGridInfo.width = bounds.width;
myVirtualGridInfo.height = bounds.height;
int deltaWidth = bounds.width - (gridInfo.vLines.length == 0 ? 0 : gridInfo.width);
myVirtualGridInfo.vLines = GridInfo.addLineInfo(gridInfo.vLines, deltaWidth);
int deltaHeight = bounds.height - gridInfo.height;
myVirtualGridInfo.hLines = GridInfo.addLineInfo(gridInfo.hLines, deltaHeight);
List<RadComponent> rows = getChildren();
if (!rows.isEmpty()) {
int columnSize = Math.max(1, gridInfo.vLines.length - 1);
if (deltaWidth < 2) {
myVirtualGridInfo.lastInsertColumn = columnSize - 1;
}
if (deltaHeight < 2) {
myVirtualGridInfo.lastInsertRow = rows.size() - 1;
}
myVirtualGridInfo.components = getGridComponents(true);
}
}
return myVirtualGridInfo;
}
public RadComponent[][] getGridComponents(boolean fillSpans) {
GridInfo gridInfo = getGridInfo();
List<RadComponent> rows = getChildren();
int columnSize = Math.max(1, gridInfo.vLines.length - 1);
RadComponent[][] components = new RadComponent[rows.size()][columnSize];
for (int i = 0; i < components.length; i++) {
RadComponent row = rows.get(i);
if (RadTableRowLayout.is(row)) {
int index = 0;
for (RadComponent column : row.getChildren()) {
int cellIndex = getCellIndex(column);
if (cellIndex > index) {
index = cellIndex;
}
int cellSpan = getCellSpan(column);
if (fillSpans) {
for (int j = 0; j < cellSpan; j++) {
components[i][index++] = column;
}
}
else {
components[i][index] = column;
index += cellSpan;
}
}
}
else {
components[i][0] = row;
}
}
return components;
}
public static int getCellIndex(RadComponent component) {
try {
String column = ((RadViewComponent)component).getTag().getAttributeValue("layout_column", SdkConstants.NS_RESOURCES);
return Integer.parseInt(column);
}
catch (Throwable e) {
return -1;
}
}
public static int getCellSpan(RadComponent component) {
try {
String span = ((RadViewComponent)component).getTag().getAttributeValue("layout_span", SdkConstants.NS_RESOURCES);
return Integer.parseInt(span);
}
catch (Throwable e) {
return 1;
}
}
public static void setCellIndex(final RadComponent component, final int column) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
XmlTag tag = ((RadViewComponent)component).getTag();
tag.setAttribute("layout_column", SdkConstants.NS_RESOURCES, Integer.toString(column));
RadComponentOperations.deleteAttribute(tag, "layout_span");
}
});
}
public static void setCellSpan(final RadComponent component, final int span) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
XmlTag tag = ((RadViewComponent)component).getTag();
tag.setAttribute("layout_span", SdkConstants.NS_RESOURCES, Integer.toString(span));
}
});
}
}