From d1c25a19d7e3fc2e57d1191c58c2cc2a34827fe8 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Tue, 17 Apr 2012 22:04:32 +0400 Subject: [PATCH] TableLayout --- .../layout/CaptionStaticDecorator.java | 9 +- .../layout/TableLayoutDecorator.java | 42 +-- .../layout/TableLayoutOperation.java | 240 ++++++++++++++---- .../designer/model/table/GridInfo.java | 31 +++ .../designer/model/table/GridInsertType.java | 29 +++ .../model/table/RadCaptionTableColumn.java | 12 +- .../model/table/RadCaptionTableRow.java | 9 +- .../designer/model/table/RadTableLayout.java | 15 +- .../model/table/RadTableLayoutComponent.java | 169 ++++++++++-- .../model/table/RadTableRowLayout.java | 4 + .../feedbacks/AlphaFeedback.java | 28 ++ 11 files changed, 481 insertions(+), 107 deletions(-) create mode 100644 plugins/android-designer/src/com/intellij/android/designer/model/table/GridInfo.java create mode 100644 plugins/android-designer/src/com/intellij/android/designer/model/table/GridInsertType.java diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/CaptionStaticDecorator.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/CaptionStaticDecorator.java index 3f5770a90634..029d6c764f48 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/CaptionStaticDecorator.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/CaptionStaticDecorator.java @@ -26,14 +26,21 @@ import java.awt.*; * @author Alexander Lobas */ public class CaptionStaticDecorator extends StaticDecorator { + private final Color myColor; + public CaptionStaticDecorator(RadComponent component) { + this(component, LightColors.GREEN); + } + + public CaptionStaticDecorator(RadComponent component, Color color) { super(component); + myColor = color; } @Override protected void paint(DecorationLayer layer, Graphics2D g, RadComponent component) { Rectangle bounds = component.getBounds(layer); - g.setColor(LightColors.GREEN); + g.setColor(myColor); g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); g.setColor(Color.black); g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height); diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutDecorator.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutDecorator.java index d880e515f621..72c5dde6a686 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutDecorator.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutDecorator.java @@ -15,14 +15,13 @@ */ package com.intellij.android.designer.designSurface.layout; -import com.intellij.android.designer.model.RadViewComponent; +import com.intellij.android.designer.model.table.GridInfo; import com.intellij.android.designer.model.table.RadTableLayoutComponent; import com.intellij.designer.designSurface.DecorationLayer; import com.intellij.designer.designSurface.StaticDecorator; import com.intellij.designer.model.RadComponent; import java.awt.*; -import java.util.List; /** * @author Alexander Lobas @@ -39,42 +38,17 @@ public class TableLayoutDecorator extends StaticDecorator { g.setStroke(FlowStaticDecorator.STROKE); Rectangle bounds = component.getBounds(layer); - int[] columnWidths = ((RadTableLayoutComponent)component).getColumnWidths(); + GridInfo gridInfo = ((RadTableLayoutComponent)component).getGridInfo(); - if (columnWidths != null && columnWidths.length > 0) { - int x = bounds.x; - - for (int i = 0; i < columnWidths.length; i++) { - int width = columnWidths[i]; - - if (width > 0) { - x += width; - - if (i != columnWidths.length - 1 || x < bounds.getMinX()) { - g.drawLine(x, bounds.y, x, bounds.y + bounds.height); - } - } - else { - g.drawLine(x + 2, bounds.y, x + 2, bounds.y + bounds.height); - } - } - - bounds.width = Math.max(bounds.width, x - bounds.x); + for (int x : gridInfo.vLines) { + g.drawLine(bounds.x + x, bounds.y, bounds.x + x, bounds.y + gridInfo.height); } - - List children = component.getChildren(); - RadComponent last = children.isEmpty() ? null : children.get(children.size() - 1); - - for (RadComponent child : children) { - Rectangle childBounds = child.getBounds(layer); - int y = childBounds.y + childBounds.height + ((RadViewComponent)child).getMargins().height; - - if (child != last || y < bounds.getMaxY()) { - g.drawLine(bounds.x, y, bounds.x + bounds.width, y); - } + for (int y : gridInfo.hLines) { + g.drawLine(bounds.x, bounds.y + y, bounds.x + gridInfo.width, bounds.y + y); } g.setStroke(stroke); - g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height); + g.drawRect(bounds.x, bounds.y, gridInfo.width, gridInfo.height); + g.drawRect(bounds.x + 1, bounds.y + 1, gridInfo.width - 2, gridInfo.height - 2); } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutOperation.java index f0d700b7c228..da701526e26b 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutOperation.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/TableLayoutOperation.java @@ -16,39 +16,57 @@ package com.intellij.android.designer.designSurface.layout; import com.intellij.android.designer.designSurface.AbstractEditOperation; -import com.intellij.android.designer.model.RadViewComponent; +import com.intellij.android.designer.model.table.GridInfo; +import com.intellij.android.designer.model.table.GridInsertType; import com.intellij.android.designer.model.table.RadTableLayoutComponent; import com.intellij.designer.designSurface.FeedbackLayer; import com.intellij.designer.designSurface.OperationContext; +import com.intellij.designer.designSurface.feedbacks.AlphaFeedback; +import com.intellij.designer.designSurface.feedbacks.LineInsertFeedback; import com.intellij.designer.model.RadComponent; import javax.swing.*; import java.awt.*; -import java.util.List; /** * @author Alexander Lobas */ public class TableLayoutOperation extends AbstractEditOperation { private GridFeedback myFeedback; + private LineInsertFeedback myHInsertFeedback; + private LineInsertFeedback myVInsertFeedback; + private int myColumn; + private int myRow; + private GridInsertType myInsertType; + private boolean myExist; public TableLayoutOperation(RadComponent container, OperationContext context) { super(container, context); } - private void createFeedback() { - if (myFeedback == null) { - FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); - myFeedback = new GridFeedback(); - myFeedback.setBounds(myContainer.getBounds(layer)); - layer.add(myFeedback); - layer.repaint(); - } + private GridInfo getGridInfo() { + return ((RadTableLayoutComponent)myContainer).getVirtualGridInfo(); } @Override public void showFeedback() { - createFeedback(); + if (myFeedback == null) { + FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); + + myFeedback = new GridFeedback(); + myFeedback.setBounds(myContainer.getBounds(layer)); + + myHInsertFeedback = new LineInsertFeedback(Color.green, true); + myVInsertFeedback = new LineInsertFeedback(Color.green, false); + + layer.add(myFeedback); + layer.add(myHInsertFeedback); + layer.add(myVInsertFeedback); + layer.repaint(); + } + + calculateGridInfo(); + myFeedback.repaint(); } @Override @@ -56,64 +74,192 @@ public class TableLayoutOperation extends AbstractEditOperation { if (myFeedback != null) { FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); layer.remove(myFeedback); + layer.add(myHInsertFeedback); + layer.add(myVInsertFeedback); layer.repaint(); myFeedback = null; + myHInsertFeedback = null; + myVInsertFeedback = null; } } + private void calculateGridInfo() { + GridInfo gridInfo = getGridInfo(); + Point location = SwingUtilities.convertPoint(myContext.getArea().getFeedbackLayer(), myContext.getLocation(), myFeedback); + + myColumn = getLineIndex(gridInfo.vLines, location.x); + myRow = getLineIndex(gridInfo.hLines, location.y); + + RadComponent[][] components = gridInfo.components; + if (components == null) { + myInsertType = GridInsertType.in_cell; + myExist = false; + } + else { + myInsertType = null; + + Rectangle bounds = myContainer.getBounds(myContext.getArea().getFeedbackLayer()); + Rectangle cellRect = getInsertRect(myExist); + Rectangle inCellRect = getInsertInRect(cellRect); + + if (inCellRect.contains(location)) { + myInsertType = GridInsertType.in_cell; + + myHInsertFeedback.setVisible(false); + myVInsertFeedback.setVisible(false); + } + else if (location.x < inCellRect.x) { + myInsertType = GridInsertType.before_v_cell; + + myHInsertFeedback.setVisible(false); + + myVInsertFeedback.setLocation(bounds.x + cellRect.x, bounds.y + cellRect.y); + myVInsertFeedback.setSize(0, cellRect.height); + myVInsertFeedback.setVisible(true); + } + else if (location.x > inCellRect.x) { + myInsertType = GridInsertType.after_v_cell; + + myHInsertFeedback.setVisible(false); + + myVInsertFeedback.setLocation(bounds.x + cellRect.x + cellRect.width, bounds.y + cellRect.y); + myVInsertFeedback.setSize(0, cellRect.height); + myVInsertFeedback.setVisible(true); + } + else if (location.y < inCellRect.y) { + myInsertType = GridInsertType.before_h_cell; + + myHInsertFeedback.setVisible(true); + myHInsertFeedback.setLocation(bounds.x + cellRect.x, bounds.y + cellRect.y); + myHInsertFeedback.setSize(cellRect.width, 0); + + myVInsertFeedback.setVisible(false); + } + else if (location.y > inCellRect.y) { + myInsertType = GridInsertType.after_h_cell; + + myHInsertFeedback.setVisible(true); + myHInsertFeedback.setLocation(bounds.x + cellRect.x, bounds.y + cellRect.y + cellRect.height); + myHInsertFeedback.setSize(cellRect.width, 0); + + myVInsertFeedback.setVisible(false); + } + + if (myInsertType == GridInsertType.in_cell) { + if (myRow < components.length && myColumn < components[0].length) { + myExist = components[myRow][myColumn] != null; + } + else { + myExist = false; + } + } + } + } + + private static int getLineIndex(int[] line, int location) { + for (int i = 0; i < line.length - 1; i++) { + if (line[i] <= location && location <= line[i + 1]) { + return i; + } + } + return Math.max(0, line.length - 1); + } + + private Rectangle getInsertRect(boolean includeSpan) { + GridInfo gridInfo = getGridInfo(); + int startColumn = myColumn; + int endColumn = myColumn + 1; + + if (includeSpan) { + RadComponent[] columnComponents = gridInfo.components[myRow]; + RadComponent existComponent = columnComponents[startColumn]; + + while (startColumn > 0) { + if (columnComponents[startColumn - 1] == existComponent) { + startColumn--; + } + else { + break; + } + } + + while (endColumn < columnComponents.length) { + if (columnComponents[endColumn] == existComponent) { + endColumn++; + } + else { + break; + } + } + } + + int x1 = startColumn < gridInfo.vLines.length ? gridInfo.vLines[startColumn] : 0; + int x2 = endColumn < gridInfo.vLines.length ? gridInfo.vLines[endColumn] : gridInfo.width; + + int y1 = myRow < gridInfo.hLines.length ? gridInfo.hLines[myRow] : 0; + int y2 = myRow + 1 < gridInfo.hLines.length ? gridInfo.hLines[myRow + 1] : gridInfo.height; + + return new Rectangle(x1, y1, x2 - x1, y2 - y1); + } + + private static Rectangle getInsertInRect(Rectangle cellRect) { + int borderWidth = getInsertBorderLength(cellRect.width); + int borderHeight = getInsertBorderLength(cellRect.height); + return new Rectangle(cellRect.x + borderWidth, cellRect.y + borderHeight, cellRect.width - 2 * borderWidth, + cellRect.height - 2 * borderHeight); + } + + private static int getInsertBorderLength(int length) { + int border = 5; + if (length < 3 * border) { + border = length / 3; + } + return border; + } + + @Override + public boolean canExecute() { + return !myExist; + } + + @Override + public void execute() throws Exception { + super.execute(); // TODO: Auto-generated method stub + } + ////////////////////////////////////////////////////////////////////////////////////////// // // Feedback // ////////////////////////////////////////////////////////////////////////////////////////// - public static final Color COLOR = new Color(80, 110, 160); - private class GridFeedback extends JComponent { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); - g.setColor(COLOR); + g.setColor(BorderStaticDecorator.COLOR); - Rectangle bounds = getBounds(); - bounds.x = bounds.y = 0; + GridInfo gridInfo = getGridInfo(); - int[] columnWidths = ((RadTableLayoutComponent)myContainer).getColumnWidths(); - - if (columnWidths != null && columnWidths.length > 0) { - int x = bounds.x; - - for (int i = 0; i < columnWidths.length; i++) { - int width = columnWidths[i]; - - if (width > 0) { - x += width; - - if (i != columnWidths.length - 1 || x < bounds.getMinX()) { - g.drawLine(x, bounds.y, x, bounds.y + bounds.height); - } - } - else { - g.drawLine(x + 2, bounds.y, x + 2, bounds.y + bounds.height); - } - } - - bounds.width = Math.max(bounds.width, x - bounds.x); + for (int x : gridInfo.vLines) { + g.drawLine(x, 0, x, gridInfo.height); } + for (int y : gridInfo.hLines) { + g.drawLine(0, y, gridInfo.width, y); + } + g.drawRect(0, 0, gridInfo.width - 1, gridInfo.height - 1); + g.drawRect(1, 1, gridInfo.width - 3, gridInfo.height - 3); - List children = myContainer.getChildren(); - RadComponent last = children.isEmpty() ? null : children.get(children.size() - 1); + if (myInsertType == GridInsertType.in_cell) { + Rectangle cellRect = getInsertRect(myExist); - for (RadComponent child : children) { - Rectangle childBounds = child.getBounds(this); - int y = childBounds.y + childBounds.height + ((RadViewComponent)child).getMargins().height; - - if (child != last || y < bounds.getMaxY()) { - g.drawLine(bounds.x, y, bounds.x + bounds.width, y); + if (myExist) { + AlphaFeedback.fillRect2(g, cellRect.x, cellRect.y, cellRect.width, cellRect.height, Color.pink); + } + else { + AlphaFeedback.fillRect1(g, cellRect.x, cellRect.y, cellRect.width, cellRect.height, Color.green); } } - - g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height); } } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/table/GridInfo.java b/plugins/android-designer/src/com/intellij/android/designer/model/table/GridInfo.java new file mode 100644 index 000000000000..35158ac63641 --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/model/table/GridInfo.java @@ -0,0 +1,31 @@ +/* + * 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.table; + +import com.intellij.designer.model.RadComponent; +import com.intellij.util.ArrayUtil; + +/** + * @author Alexander Lobas + */ +public class GridInfo { + public int width; + public int height; + public int[] hLines = ArrayUtil.EMPTY_INT_ARRAY; + public int[] vLines = ArrayUtil.EMPTY_INT_ARRAY; + public boolean[] emptyColumns = ArrayUtil.EMPTY_BOOLEAN_ARRAY; + public RadComponent[][] components; +} \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/table/GridInsertType.java b/plugins/android-designer/src/com/intellij/android/designer/model/table/GridInsertType.java new file mode 100644 index 000000000000..a210473dc78d --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/model/table/GridInsertType.java @@ -0,0 +1,29 @@ +/* + * 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.table; + +/** + * @author Alexander Lobas + */ +public enum GridInsertType { + in_cell, + before_h_cell, + after_h_cell, + before_v_cell, + after_v_cell, + before_row, + after_row +} \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableColumn.java b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableColumn.java index 502cfb27c903..914e13e16c27 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableColumn.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableColumn.java @@ -30,12 +30,20 @@ public class RadCaptionTableColumn extends RadVisualComponent { private final RadTableLayoutComponent myContainer; private final int myColumnOffset; private final int myColumnWidth; - private final StaticDecorator myDecorator = new CaptionStaticDecorator(this); + private final StaticDecorator myDecorator; - public RadCaptionTableColumn(RadTableLayoutComponent container, int columnOffset, int columnWidth) { + public RadCaptionTableColumn(RadTableLayoutComponent container, int columnOffset, int columnWidth, boolean empty) { myContainer = container; myColumnOffset = columnOffset; myColumnWidth = columnWidth; + + if (empty) { + myDecorator = new CaptionStaticDecorator(this, Color.PINK); + } + else { + myDecorator = new CaptionStaticDecorator(this); + } + setNativeComponent(container.getNativeComponent()); } diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableRow.java b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableRow.java index d0d9f199eadd..d4b7c8012953 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableRow.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadCaptionTableRow.java @@ -29,10 +29,17 @@ import java.util.List; */ public class RadCaptionTableRow extends RadVisualComponent { private final RadViewComponent myComponent; - private final StaticDecorator myDecorator = new CaptionStaticDecorator(this); + private final StaticDecorator myDecorator; public RadCaptionTableRow(RadViewComponent component) { myComponent = component; + + if (RadTableRowLayout.is(component)) { + myDecorator = new CaptionStaticDecorator(this); + } else { + myDecorator = new CaptionStaticDecorator(this, Color.PINK); + } + setNativeComponent(component.getNativeComponent()); } diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayout.java index 50343c814537..a2901c650352 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayout.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayout.java @@ -97,7 +97,7 @@ public class RadTableLayout extends RadViewLayoutWithData implements ILayoutDeco @Override public ComponentDecorator getChildSelectionDecorator(RadComponent component, List selection) { - if (component.getLayout() instanceof RadTableRowLayout) { + if (RadTableRowLayout.is(component)) { return super.getChildSelectionDecorator(component, selection); } @@ -165,10 +165,15 @@ public class RadTableLayout extends RadViewLayoutWithData implements ILayoutDeco List components = new ArrayList(); if (horizontal) { - int columnOffset = 0; - for (int columnWidth : container.getColumnWidths()) { - components.add(new RadCaptionTableColumn(container, columnOffset, Math.max(columnWidth, 2))); - columnOffset += columnWidth; + GridInfo gridInfo = container.getGridInfo(); + int[] lines = gridInfo.vLines; + boolean[] emptyColumns = gridInfo.emptyColumns; + + for (int i = 0; i < lines.length - 1; i++) { + components.add(new RadCaptionTableColumn(container, + lines[i], + lines[i + 1] - lines[i], + emptyColumns[i])); } } else { diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayoutComponent.java b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayoutComponent.java index e478251c11cc..d2c691975f95 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayoutComponent.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableLayoutComponent.java @@ -16,40 +16,175 @@ package com.intellij.android.designer.model.table; import com.android.ide.common.rendering.api.ViewInfo; +import com.intellij.android.designer.model.RadViewComponent; import com.intellij.android.designer.model.RadViewContainer; +import com.intellij.designer.model.RadComponent; import com.intellij.util.ArrayUtil; -import org.jetbrains.annotations.Nullable; +import java.awt.*; import java.lang.reflect.Field; +import java.util.List; /** * @author Alexander Lobas */ public class RadTableLayoutComponent extends RadViewContainer { - private int[] myColumnWidths; + private GridInfo myGridInfo; + private GridInfo myVirtualGridInfo; @Override public void setViewInfo(ViewInfo viewInfo) { super.setViewInfo(viewInfo); - myColumnWidths = null; + myGridInfo = null; + myVirtualGridInfo = null; } - @Nullable - public int[] getColumnWidths() { - if (myColumnWidths == null) { - try { - Object viewObject = myViewInfo.getViewObject(); - Class viewClass = viewObject.getClass(); - Field maxWidths = viewClass.getDeclaredField("mMaxWidths"); - maxWidths.setAccessible(true); - myColumnWidths = (int[])maxWidths.get(viewObject); + 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; + } + } + + public GridInfo getGridInfo() { + if (myGridInfo == null) { + myGridInfo = new GridInfo(); + + 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; + } } - catch (Throwable e) { - } - if (myColumnWidths == null) { - myColumnWidths = ArrayUtil.EMPTY_INT_ARRAY; + + List 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 myColumnWidths; + return myGridInfo; + } + + public GridInfo getVirtualGridInfo() { + if (myVirtualGridInfo == null) { + myVirtualGridInfo = new GridInfo(); + GridInfo gridInfo = getGridInfo(); + Rectangle bounds = getBounds(); + + myVirtualGridInfo.width = bounds.width; + myVirtualGridInfo.height = bounds.height; + + myVirtualGridInfo.vLines = addLineInfo(gridInfo.vLines, bounds.width - (gridInfo.vLines.length == 0 ? 0 : gridInfo.width)); + myVirtualGridInfo.hLines = addLineInfo(gridInfo.hLines, bounds.height - gridInfo.height); + + List rows = getChildren(); + if (!rows.isEmpty()) { + int columnSize = Math.max(1, gridInfo.vLines.length - 1); + RadComponent[][] components = new RadComponent[rows.size()][columnSize]; + myVirtualGridInfo.components = components; + + 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 = getCellSnap(column); + for (int j = 0; j < cellSpan; j++) { + components[i][index++] = column; + } + } + } + else { + components[i][0] = row; + } + } + } + } + return myVirtualGridInfo; + } + + private static int getCellIndex(RadComponent component) { + try { + String column = ((RadViewComponent)component).getTag().getAttributeValue("android:layout_column"); + return Integer.parseInt(column); + } + catch (Throwable e) { + return -1; + } + } + + private static int getCellSnap(RadComponent component) { + try { + String span = ((RadViewComponent)component).getTag().getAttributeValue("android:layout_span"); + return Integer.parseInt(span); + } + catch (Throwable e) { + return 1; + } + } + + private static final int NEW_CELL_SIZE = 32; + + private static int[] addLineInfo(int[] oldLines, int delta) { + if (delta > 0) { + int newLength = oldLines.length + delta / NEW_CELL_SIZE; + + if (newLength > oldLines.length) { + int[] newLines = new int[newLength]; + int startIndex = oldLines.length; + + if (oldLines.length > 0) { + System.arraycopy(oldLines, 0, newLines, 0, oldLines.length); + } + else { + startIndex = 1; + } + + for (int i = startIndex; i < newLength; i++) { + newLines[i] = newLines[i - 1] + NEW_CELL_SIZE; + } + + return newLines; + } + return oldLines; + } + return oldLines; } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableRowLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableRowLayout.java index e234106de44d..0c585c90103a 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableRowLayout.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/table/RadTableRowLayout.java @@ -36,6 +36,10 @@ public class RadTableRowLayout extends RadLinearLayout { return LAYOUT_PARAMS; } + public static boolean is(RadComponent component) { + return component.getLayout() instanceof RadTableRowLayout; + } + private boolean isTableParent() { return myContainer.getParent() instanceof RadTableLayoutComponent; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/AlphaFeedback.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/AlphaFeedback.java index 55736b88bd78..42726440be34 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/AlphaFeedback.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/AlphaFeedback.java @@ -57,4 +57,32 @@ public class AlphaFeedback extends JComponent { protected void paintOther2(Graphics2D g2d) { g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1); } + + ////////////////////////////////////////////////////////////////////////////////////////// + // + // Utils + // + ////////////////////////////////////////////////////////////////////////////////////////// + + public static void fillRect1(Graphics g, int x, int y, int width, int height, Color color) { + fillRect(g, x, y, width, height, color, myComposite1); + } + + public static void fillRect2(Graphics g, int x, int y, int width, int height, Color color) { + fillRect(g, x, y, width, height, color, myComposite2); + } + + public static void fillRect(Graphics g, int x, int y, int width, int height, Color color, Composite composite) { + Graphics2D g2d = (Graphics2D)g; + Composite oldComposite = g2d.getComposite(); + Color oldColor = g.getColor(); + + g2d.setColor(color); + g2d.setComposite(composite); + + g2d.fillRect(x, y, width, height); + + g2d.setComposite(oldComposite); + g2d.setColor(oldColor); + } } \ No newline at end of file