mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
TableLayout
This commit is contained in:
+178
-18
@@ -16,17 +16,26 @@
|
||||
package com.intellij.android.designer.designSurface.layout;
|
||||
|
||||
import com.intellij.android.designer.designSurface.AbstractEditOperation;
|
||||
import com.intellij.android.designer.model.ModelParser;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.android.designer.model.ViewsMetaManager;
|
||||
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.android.designer.model.table.RadTableRowLayout;
|
||||
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.InsertFeedback;
|
||||
import com.intellij.designer.designSurface.feedbacks.TextFeedback;
|
||||
import com.intellij.designer.model.MetaManager;
|
||||
import com.intellij.designer.model.MetaModel;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
@@ -36,6 +45,8 @@ public class TableLayoutOperation extends AbstractEditOperation {
|
||||
|
||||
private GridFeedback myFeedback;
|
||||
private InsertFeedback myInsertFeedback;
|
||||
private TextFeedback myTextFeedback;
|
||||
private Rectangle myBounds;
|
||||
private int myColumn;
|
||||
private int myRow;
|
||||
private GridInsertType myInsertType;
|
||||
@@ -49,34 +60,93 @@ public class TableLayoutOperation extends AbstractEditOperation {
|
||||
return ((RadTableLayoutComponent)myContainer).getVirtualGridInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFeedback() {
|
||||
private void createFeedback() {
|
||||
if (myFeedback == null) {
|
||||
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
|
||||
|
||||
myFeedback = new GridFeedback();
|
||||
myFeedback.setBounds(myContainer.getBounds(layer));
|
||||
|
||||
myInsertFeedback = new InsertFeedback(Color.green);
|
||||
|
||||
layer.add(myInsertFeedback);
|
||||
|
||||
myBounds = myContainer.getBounds(layer);
|
||||
|
||||
myFeedback = new GridFeedback();
|
||||
myFeedback.setBounds(myBounds);
|
||||
layer.add(myFeedback);
|
||||
|
||||
myTextFeedback = new TextFeedback();
|
||||
myTextFeedback.setBorder(IdeBorderFactory.createEmptyBorder(0, 3, 2, 0));
|
||||
layer.add(myTextFeedback);
|
||||
|
||||
layer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFeedback() {
|
||||
createFeedback();
|
||||
calculateGridInfo();
|
||||
configureTextFeedback();
|
||||
myFeedback.repaint();
|
||||
}
|
||||
|
||||
private void configureTextFeedback() {
|
||||
myTextFeedback.clear();
|
||||
|
||||
int row = myRow;
|
||||
int column = myColumn;
|
||||
|
||||
myTextFeedback.append("[");
|
||||
|
||||
if (myInsertType == GridInsertType.before_h_cell) {
|
||||
myTextFeedback.append("before ");
|
||||
}
|
||||
else if (myInsertType == GridInsertType.after_h_cell) {
|
||||
myTextFeedback.append("after ");
|
||||
}
|
||||
else if (myInsertType != GridInsertType.in_cell) {
|
||||
myTextFeedback.append("insert: ");
|
||||
|
||||
if (myInsertType == GridInsertType.corner_top_right) {
|
||||
column++;
|
||||
}
|
||||
else if (myInsertType == GridInsertType.corner_bottom_left) {
|
||||
row++;
|
||||
}
|
||||
else if (myInsertType == GridInsertType.corner_bottom_right) {
|
||||
row++;
|
||||
column++;
|
||||
}
|
||||
}
|
||||
|
||||
myTextFeedback.append("row ");
|
||||
myTextFeedback.bold(Integer.toString(row));
|
||||
myTextFeedback.append(", ");
|
||||
|
||||
if (myInsertType == GridInsertType.before_v_cell) {
|
||||
myTextFeedback.append("before ");
|
||||
}
|
||||
else if (myInsertType == GridInsertType.after_v_cell) {
|
||||
myTextFeedback.append("after ");
|
||||
}
|
||||
|
||||
myTextFeedback.append("column ");
|
||||
myTextFeedback.bold(Integer.toString(column));
|
||||
myTextFeedback.append("]");
|
||||
|
||||
myTextFeedback.centerTop(myBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eraseFeedback() {
|
||||
if (myFeedback != null) {
|
||||
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
|
||||
layer.remove(myInsertFeedback);
|
||||
layer.remove(myFeedback);
|
||||
layer.remove(myTextFeedback);
|
||||
layer.repaint();
|
||||
myFeedback = null;
|
||||
myInsertFeedback = null;
|
||||
myTextFeedback = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,58 +165,59 @@ public class TableLayoutOperation extends AbstractEditOperation {
|
||||
myExist = isExist(myRow, myColumn);
|
||||
myInsertType = GridInsertType.in_cell;
|
||||
|
||||
Rectangle bounds = myContainer.getBounds(myContext.getArea().getFeedbackLayer());
|
||||
Rectangle cellRect = getInsertRect(myExist);
|
||||
Rectangle inCellRect = getInsertInRect(cellRect);
|
||||
boolean isExistCell = myRow < gridInfo.components.length && myColumn < gridInfo.components[0].length;
|
||||
boolean isExistCell = gridInfo.components != null && myRow < gridInfo.components.length && myColumn < gridInfo.components[0].length;
|
||||
|
||||
if (!inCellRect.contains(location)) {
|
||||
if (location.x <= inCellRect.x) {
|
||||
if (location.y <= inCellRect.y) {
|
||||
if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_top_left;
|
||||
myInsertFeedback.cross(bounds.x + cellRect.x, bounds.y + cellRect.y, CROSS_SIZE);
|
||||
myInsertFeedback.cross(myBounds.x + cellRect.x, myBounds.y + cellRect.y, CROSS_SIZE);
|
||||
}
|
||||
}
|
||||
else if (inCellRect.y < location.y && location.y < inCellRect.getMaxY()) {
|
||||
if (myExist && (myColumn == 0 || isExist(myRow, myColumn - 1))) {
|
||||
myInsertType = GridInsertType.before_v_cell;
|
||||
myInsertFeedback.vertical(bounds.x + cellRect.x, bounds.y + cellRect.y, cellRect.height);
|
||||
myInsertFeedback.vertical(myBounds.x + cellRect.x, myBounds.y + cellRect.y, cellRect.height);
|
||||
}
|
||||
}
|
||||
else if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_bottom_left;
|
||||
myInsertFeedback.cross(bounds.x + cellRect.x, bounds.y + cellRect.y + cellRect.height, CROSS_SIZE);
|
||||
myInsertFeedback.cross(myBounds.x + cellRect.x, myBounds.y + cellRect.y + cellRect.height, CROSS_SIZE);
|
||||
}
|
||||
}
|
||||
else if (location.x >= inCellRect.getMaxX()) {
|
||||
if (location.y <= inCellRect.y) {
|
||||
if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_top_right;
|
||||
myInsertFeedback.cross(bounds.x + cellRect.x + cellRect.width, bounds.y + cellRect.y, CROSS_SIZE);
|
||||
myInsertFeedback.cross(myBounds.x + cellRect.x + cellRect.width, myBounds.y + cellRect.y, CROSS_SIZE);
|
||||
}
|
||||
}
|
||||
else if (inCellRect.y < location.y && location.y < inCellRect.getMaxY()) {
|
||||
if (myExist && (myColumn == gridInfo.lastColumn || isExist(myRow, myColumn + 1))) {
|
||||
myInsertType = GridInsertType.after_v_cell;
|
||||
myInsertFeedback.vertical(bounds.x + cellRect.x + cellRect.width, bounds.y + cellRect.y, cellRect.height);
|
||||
myInsertFeedback.vertical(myBounds.x + cellRect.x + cellRect.width, myBounds.y + cellRect.y, cellRect.height);
|
||||
}
|
||||
}
|
||||
else if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_bottom_right;
|
||||
myInsertFeedback.cross(bounds.x + cellRect.x + cellRect.width, bounds.y + cellRect.y + cellRect.height, CROSS_SIZE);
|
||||
myInsertFeedback.cross(myBounds.x + cellRect.x + cellRect.width, myBounds.y + cellRect.y + cellRect.height, CROSS_SIZE);
|
||||
}
|
||||
}
|
||||
else if (location.y <= inCellRect.y) {
|
||||
if (myExist && (myRow == 0 || isExist(myRow - 1, myColumn))) {
|
||||
myInsertType = GridInsertType.before_h_cell;
|
||||
myInsertFeedback.horizontal(bounds.x + cellRect.x, bounds.y + cellRect.y, cellRect.width);
|
||||
cellRect = getInsertRect(false);
|
||||
myInsertFeedback.horizontal(myBounds.x + cellRect.x, myBounds.y + cellRect.y, cellRect.width);
|
||||
}
|
||||
}
|
||||
else if (location.y >= inCellRect.getMaxY()) {
|
||||
if (myExist && (myRow == gridInfo.lastRow || isExist(myRow + 1, myColumn))) {
|
||||
myInsertType = GridInsertType.after_h_cell;
|
||||
myInsertFeedback.horizontal(bounds.x + cellRect.x, bounds.y + cellRect.y + cellRect.height, cellRect.width);
|
||||
cellRect = getInsertRect(false);
|
||||
myInsertFeedback.horizontal(myBounds.x + cellRect.x, myBounds.y + cellRect.y + cellRect.height, cellRect.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,12 +293,101 @@ public class TableLayoutOperation extends AbstractEditOperation {
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
return myInsertType != GridInsertType.in_cell || !myExist;
|
||||
return myComponents.size() == 1 && (myInsertType != GridInsertType.in_cell || !myExist);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
super.execute(); // TODO: Auto-generated method stub
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
|
||||
RadViewComponent container = (RadViewComponent)myContainer;
|
||||
List<RadComponent> rows = myContainer.getChildren();
|
||||
RadComponent editComponent = myComponents.get(0);
|
||||
|
||||
MetaManager metaManager = ViewsMetaManager.getInstance(container.getTag().getProject());
|
||||
MetaModel tableRowModel = metaManager.getModelByTag("TableRow");
|
||||
|
||||
if (myInsertType == GridInsertType.in_cell) {
|
||||
if (gridInfo.components != null && myRow < gridInfo.components.length) {
|
||||
RadViewComponent rowComponent = (RadViewComponent)rows.get(myRow);
|
||||
if (RadTableRowLayout.is(rowComponent)) {
|
||||
RadComponent[] rowComponents = gridInfo.components[myRow];
|
||||
RadComponent insertBefore = null;
|
||||
|
||||
for (int i = myColumn + 1; i < rowComponents.length; i++) {
|
||||
insertBefore = rowComponents[i];
|
||||
if (insertBefore != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (editComponent != insertBefore) {
|
||||
execute(myContext, rowComponent, myComponents, (RadViewComponent)insertBefore);
|
||||
}
|
||||
|
||||
RadTableLayoutComponent.setCellConstraints(editComponent, myColumn, 1);
|
||||
}
|
||||
else {
|
||||
RadViewComponent newRowComponent = ModelParser.createComponent(null, tableRowModel);
|
||||
ModelParser.addComponent(container, newRowComponent, rowComponent);
|
||||
|
||||
ModelParser.moveComponent(newRowComponent, rowComponent, null);
|
||||
|
||||
execute(myContext, newRowComponent, myComponents, null);
|
||||
|
||||
if (myColumn > 1) {
|
||||
RadTableLayoutComponent.setCellConstraints(editComponent, myColumn, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = rows.size(); i <= myRow; i++) {
|
||||
RadViewComponent rowComponent = ModelParser.createComponent(null, tableRowModel);
|
||||
ModelParser.addComponent(container, rowComponent, null);
|
||||
}
|
||||
|
||||
execute(myContext, (RadViewComponent)myContainer.getChildren().get(myRow), myComponents, null);
|
||||
RadTableLayoutComponent.setCellConstraints(editComponent, myColumn, 1);
|
||||
}
|
||||
}
|
||||
else if (myInsertType == GridInsertType.before_h_cell || myInsertType == GridInsertType.after_h_cell) {
|
||||
RadViewComponent rowComponent = ModelParser.createComponent(null, tableRowModel);
|
||||
RadComponent insertBefore = null;
|
||||
|
||||
if (myInsertType == GridInsertType.before_h_cell) {
|
||||
insertBefore = rows.get(myRow);
|
||||
}
|
||||
else if (myRow + 1 < rows.size()) {
|
||||
insertBefore = rows.get(myRow + 1);
|
||||
}
|
||||
|
||||
ModelParser.addComponent(container, rowComponent, (RadViewComponent)insertBefore);
|
||||
|
||||
execute(myContext, rowComponent, myComponents, null);
|
||||
RadTableLayoutComponent.setCellConstraints(editComponent, myColumn, 1);
|
||||
}
|
||||
else if (myInsertType == GridInsertType.before_v_cell || myInsertType == GridInsertType.after_v_cell) {
|
||||
int column = myColumn;
|
||||
if (myInsertType == GridInsertType.after_v_cell) {
|
||||
column++;
|
||||
}
|
||||
shiftColumns(column);
|
||||
}
|
||||
else {
|
||||
// XXX
|
||||
}
|
||||
}
|
||||
|
||||
private void shiftColumns(int startColumn) {
|
||||
RadComponent[][] components = getGridInfo().components;
|
||||
for (RadComponent[] rowComponents : components) {
|
||||
for (int j = startColumn; j < rowComponents.length; j++) {
|
||||
RadComponent cellComponent = rowComponents[j];
|
||||
if (cellComponent != null) {
|
||||
RadTableLayoutComponent.setCellConstraints(cellComponent, j + 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+15
@@ -19,6 +19,8 @@ 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.openapi.application.ApplicationManager;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -178,6 +180,19 @@ public class RadTableLayoutComponent extends RadViewContainer {
|
||||
return oldLines;
|
||||
}
|
||||
|
||||
public static void setCellConstraints(final RadComponent component, final int column, final int span) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
XmlTag tag = ((RadViewComponent)component).getTag();
|
||||
tag.setAttribute("android:layout_column", Integer.toString(column));
|
||||
if (span > 1) {
|
||||
tag.setAttribute("android:layout_span", Integer.toString(span));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static int getCellIndex(RadComponent component) {
|
||||
try {
|
||||
String column = ((RadViewComponent)component).getTag().getAttributeValue("android:layout_column");
|
||||
|
||||
+6
-6
@@ -31,11 +31,11 @@ public class InsertFeedback extends LineInsertFeedback {
|
||||
protected void paintLines(Graphics g) {
|
||||
if (myCross) {
|
||||
int size = getWidth();
|
||||
int size2 = size / 2;
|
||||
AlphaFeedback.fillRect1(g, 0, size2 - 1, size, 3, myColor);
|
||||
AlphaFeedback.fillRect1(g, size2 - 1, 0, 3, size, myColor);
|
||||
g.drawLine(0, size2, size, size2);
|
||||
g.drawLine(size2, 0, size2, size);
|
||||
int size2 = (size - 3) / 2;
|
||||
AlphaFeedback.fillRect2(g, 0, size2, size, 3, myColor);
|
||||
AlphaFeedback.fillRect2(g, size2, 0, 3, size, myColor);
|
||||
g.drawLine(0, size2 + 1, size, size2 + 1);
|
||||
g.drawLine(size2 + 1, 0, size2 + 1, size);
|
||||
}
|
||||
else {
|
||||
super.paintLines(g);
|
||||
@@ -44,7 +44,7 @@ public class InsertFeedback extends LineInsertFeedback {
|
||||
|
||||
public void cross(int xCenter, int yCenter, int size) {
|
||||
myCross = true;
|
||||
setBounds(xCenter - size, yCenter - size, 2 * size, 2 * size);
|
||||
setBounds(xCenter - size - 1, yCenter - size - 1, 2 * size + 3, 2 * size + 3);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user