mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
GridLayout
This commit is contained in:
+2
-8
@@ -15,25 +15,19 @@
|
||||
*/
|
||||
package com.intellij.android.designer.designSurface.layout;
|
||||
|
||||
import com.intellij.android.designer.designSurface.AbstractEditOperation;
|
||||
import com.intellij.designer.designSurface.OperationContext;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class GridLayoutOperation extends AbstractEditOperation {
|
||||
public class GridLayoutOperation extends GridOperation {
|
||||
public GridLayoutOperation(RadComponent container, OperationContext context) {
|
||||
super(container, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFeedback() {
|
||||
// TODO: Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eraseFeedback() {
|
||||
public void execute() throws Exception {
|
||||
// TODO: Auto-generated method stub
|
||||
}
|
||||
}
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* 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.designSurface.layout;
|
||||
|
||||
import com.intellij.android.designer.designSurface.AbstractEditOperation;
|
||||
import com.intellij.android.designer.model.agrid.GridInfo;
|
||||
import com.intellij.android.designer.model.agrid.GridInsertType;
|
||||
import com.intellij.android.designer.model.agrid.IGridProvider;
|
||||
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.RadComponent;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public abstract class GridOperation extends AbstractEditOperation {
|
||||
private GridFeedback myFeedback;
|
||||
private InsertFeedback myInsertFeedback;
|
||||
private TextFeedback myTextFeedback;
|
||||
private Rectangle myBounds;
|
||||
protected int myColumn;
|
||||
protected int myRow;
|
||||
protected GridInsertType myInsertType;
|
||||
protected boolean myExist;
|
||||
|
||||
public GridOperation(RadComponent container, OperationContext context) {
|
||||
super(container, context);
|
||||
}
|
||||
|
||||
protected final GridInfo getGridInfo() {
|
||||
return ((IGridProvider)myContainer).getVirtualGridInfo();
|
||||
}
|
||||
|
||||
private void createFeedback() {
|
||||
if (myFeedback == null) {
|
||||
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
return myComponents.size() == 1 && (myInsertType != GridInsertType.in_cell || !myExist);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void execute() throws Exception;
|
||||
|
||||
private static final int CROSS_SIZE = 10;
|
||||
|
||||
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);
|
||||
|
||||
if (gridInfo.components == null) {
|
||||
myInsertType = GridInsertType.in_cell;
|
||||
myExist = false;
|
||||
}
|
||||
else {
|
||||
myExist = isExist(myRow, myColumn);
|
||||
myInsertType = GridInsertType.in_cell;
|
||||
|
||||
Rectangle cellRect = getInsertRect(myExist);
|
||||
Rectangle inCellRect = getInsertInRect(cellRect);
|
||||
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(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(myBounds.x + cellRect.x, myBounds.y + cellRect.y, cellRect.height);
|
||||
}
|
||||
}
|
||||
else if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_bottom_left;
|
||||
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(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(myBounds.x + cellRect.x + cellRect.width, myBounds.y + cellRect.y, cellRect.height);
|
||||
}
|
||||
}
|
||||
else if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_bottom_right;
|
||||
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;
|
||||
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;
|
||||
cellRect = getInsertRect(false);
|
||||
myInsertFeedback.horizontal(myBounds.x + cellRect.x, myBounds.y + cellRect.y + cellRect.height, cellRect.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (myInsertType == GridInsertType.in_cell) {
|
||||
myInsertFeedback.setVisible(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 boolean isExist(int row, int column) {
|
||||
RadComponent[][] components = getGridInfo().components;
|
||||
if (components != null &&
|
||||
0 <= row && row < components.length &&
|
||||
0 <= column && column < components[0].length) {
|
||||
return components[row][column] != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Rectangle getInsertRect(boolean includeSpans) {
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
int startColumn = myColumn;
|
||||
int endColumn = myColumn + 1;
|
||||
int startRow = myRow;
|
||||
int endRow = myRow + 1;
|
||||
|
||||
if (includeSpans) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
while (startRow > 0) {
|
||||
if (gridInfo.components[startRow - 1][startColumn] == existComponent) {
|
||||
startRow--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (endRow < gridInfo.components.length) {
|
||||
if (gridInfo.components[endRow][startColumn] == existComponent) {
|
||||
endRow++;
|
||||
}
|
||||
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 = startRow < gridInfo.hLines.length ? gridInfo.hLines[startRow] : 0;
|
||||
int y2 = endRow < gridInfo.hLines.length ? gridInfo.hLines[endRow] : gridInfo.height;
|
||||
|
||||
return new Rectangle(x1, y1, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
private static Rectangle getInsertInRect(Rectangle cellRect) {
|
||||
int borderWidth = Math.min(cellRect.width / 3, 10);
|
||||
int borderHeight = Math.min(cellRect.height / 3, 10);
|
||||
return new Rectangle(cellRect.x + borderWidth, cellRect.y + borderHeight, cellRect.width - 2 * borderWidth,
|
||||
cellRect.height - 2 * borderHeight);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Feedback
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private class GridFeedback extends JComponent {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.setColor(BorderStaticDecorator.COLOR);
|
||||
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
|
||||
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);
|
||||
|
||||
if (myInsertType == GridInsertType.in_cell) {
|
||||
Rectangle cellRect = getInsertRect(myExist);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-13
@@ -19,7 +19,6 @@ import com.intellij.android.designer.model.ModelParser;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.android.designer.model.agrid.GridInfo;
|
||||
import com.intellij.android.designer.model.table.RadTableLayoutComponent;
|
||||
import com.intellij.designer.designSurface.DecorationLayer;
|
||||
import com.intellij.designer.designSurface.EditOperation;
|
||||
import com.intellij.designer.designSurface.FeedbackLayer;
|
||||
import com.intellij.designer.designSurface.OperationContext;
|
||||
@@ -27,7 +26,6 @@ import com.intellij.designer.designSurface.feedbacks.LineMarginBorder;
|
||||
import com.intellij.designer.designSurface.feedbacks.RectangleFeedback;
|
||||
import com.intellij.designer.designSurface.feedbacks.TextFeedback;
|
||||
import com.intellij.designer.designSurface.selection.DirectionResizePoint;
|
||||
import com.intellij.designer.designSurface.selection.EmptyPoint;
|
||||
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.designer.utils.Position;
|
||||
@@ -267,17 +265,6 @@ public class LayoutSpanOperation implements EditOperation {
|
||||
}
|
||||
|
||||
public static void gridPoints(ResizeSelectionDecorator decorator) {
|
||||
decorator.addPoint(new EmptyPoint() {
|
||||
@Override
|
||||
protected void paint(DecorationLayer layer, Graphics2D g, RadComponent component) {
|
||||
Rectangle bounds = component.getBounds(layer);
|
||||
|
||||
g.setStroke(LayoutMarginOperation.STROKE);
|
||||
g.setColor(COLOR);
|
||||
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
});
|
||||
|
||||
decorator.addPoint(new DirectionResizePoint(COLOR,
|
||||
Color.black,
|
||||
Position.WEST,
|
||||
|
||||
+1
-296
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
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;
|
||||
@@ -23,280 +22,22 @@ import com.intellij.android.designer.model.agrid.GridInfo;
|
||||
import com.intellij.android.designer.model.agrid.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 org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class TableLayoutOperation extends AbstractEditOperation {
|
||||
private static final int CROSS_SIZE = 10;
|
||||
|
||||
private GridFeedback myFeedback;
|
||||
private InsertFeedback myInsertFeedback;
|
||||
private TextFeedback myTextFeedback;
|
||||
private Rectangle myBounds;
|
||||
private int myColumn;
|
||||
private int myRow;
|
||||
private GridInsertType myInsertType;
|
||||
private boolean myExist;
|
||||
|
||||
public class TableLayoutOperation extends GridOperation {
|
||||
public TableLayoutOperation(RadComponent container, OperationContext context) {
|
||||
super(container, context);
|
||||
}
|
||||
|
||||
private GridInfo getGridInfo() {
|
||||
return ((RadTableLayoutComponent)myContainer).getVirtualGridInfo();
|
||||
}
|
||||
|
||||
private void createFeedback() {
|
||||
if (myFeedback == null) {
|
||||
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (gridInfo.components == null) {
|
||||
myInsertType = GridInsertType.in_cell;
|
||||
myExist = false;
|
||||
}
|
||||
else {
|
||||
myExist = isExist(myRow, myColumn);
|
||||
myInsertType = GridInsertType.in_cell;
|
||||
|
||||
Rectangle cellRect = getInsertRect(myExist);
|
||||
Rectangle inCellRect = getInsertInRect(cellRect);
|
||||
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(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(myBounds.x + cellRect.x, myBounds.y + cellRect.y, cellRect.height);
|
||||
}
|
||||
}
|
||||
else if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_bottom_left;
|
||||
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(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(myBounds.x + cellRect.x + cellRect.width, myBounds.y + cellRect.y, cellRect.height);
|
||||
}
|
||||
}
|
||||
else if (isExistCell) {
|
||||
myInsertType = GridInsertType.corner_bottom_right;
|
||||
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;
|
||||
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;
|
||||
cellRect = getInsertRect(false);
|
||||
myInsertFeedback.horizontal(myBounds.x + cellRect.x, myBounds.y + cellRect.y + cellRect.height, cellRect.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (myInsertType == GridInsertType.in_cell) {
|
||||
myInsertFeedback.setVisible(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 boolean isExist(int row, int column) {
|
||||
RadComponent[][] components = getGridInfo().components;
|
||||
if (components != null &&
|
||||
0 <= row && row < components.length &&
|
||||
0 <= column && column < components[0].length) {
|
||||
return components[row][column] != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 = Math.min(cellRect.width / 3, 10);
|
||||
int borderHeight = Math.min(cellRect.height / 3, 10);
|
||||
return new Rectangle(cellRect.x + borderWidth, cellRect.y + borderHeight, cellRect.width - 2 * borderWidth,
|
||||
cellRect.height - 2 * borderHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
return myComponents.size() == 1 && (myInsertType != GridInsertType.in_cell || !myExist);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
@@ -448,40 +189,4 @@ public class TableLayoutOperation extends AbstractEditOperation {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Feedback
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private class GridFeedback extends JComponent {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.setColor(BorderStaticDecorator.COLOR);
|
||||
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
|
||||
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);
|
||||
|
||||
if (myInsertType == GridInsertType.in_cell) {
|
||||
Rectangle cellRect = getInsertRect(myExist);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,4 +32,32 @@ public class GridInfo {
|
||||
public RadComponent[][] components;
|
||||
public int lastRow = -1;
|
||||
public int lastColumn = -1;
|
||||
|
||||
private static final int NEW_CELL_SIZE = 32;
|
||||
|
||||
public 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;
|
||||
}
|
||||
}
|
||||
+2
@@ -20,4 +20,6 @@ package com.intellij.android.designer.model.agrid;
|
||||
*/
|
||||
public interface IGridProvider {
|
||||
GridInfo getGridInfo();
|
||||
|
||||
GridInfo getVirtualGridInfo();
|
||||
}
|
||||
+81
@@ -16,6 +16,7 @@
|
||||
package com.intellij.android.designer.model.grid;
|
||||
|
||||
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.android.designer.model.agrid.GridInfo;
|
||||
import com.intellij.android.designer.model.agrid.IGridProvider;
|
||||
@@ -30,11 +31,13 @@ import java.lang.reflect.Method;
|
||||
*/
|
||||
public class RadGridLayoutComponent extends RadViewContainer implements IGridProvider {
|
||||
private GridInfo myGridInfo;
|
||||
private GridInfo myVirtualGridInfo;
|
||||
|
||||
@Override
|
||||
public void setViewInfo(ViewInfo viewInfo) {
|
||||
super.setViewInfo(viewInfo);
|
||||
myGridInfo = null;
|
||||
myVirtualGridInfo = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,4 +92,82 @@ public class RadGridLayoutComponent extends RadViewContainer implements IGridPro
|
||||
}
|
||||
return myGridInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GridInfo getVirtualGridInfo() {
|
||||
if (myVirtualGridInfo == null) {
|
||||
myVirtualGridInfo = new GridInfo();
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
Rectangle bounds = getBounds();
|
||||
|
||||
myVirtualGridInfo.lastColumn = gridInfo.lastColumn;
|
||||
myVirtualGridInfo.lastRow = gridInfo.lastRow;
|
||||
|
||||
myVirtualGridInfo.width = bounds.width;
|
||||
myVirtualGridInfo.height = bounds.height;
|
||||
|
||||
myVirtualGridInfo.vLines = GridInfo.addLineInfo(gridInfo.vLines, bounds.width - gridInfo.width);
|
||||
myVirtualGridInfo.hLines = GridInfo.addLineInfo(gridInfo.hLines, bounds.height - gridInfo.height);
|
||||
|
||||
myVirtualGridInfo.components = getGridComponents(true);
|
||||
}
|
||||
|
||||
return myVirtualGridInfo;
|
||||
}
|
||||
|
||||
public RadComponent[][] getGridComponents(boolean fillSpans) {
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
RadComponent[][] components = new RadComponent[gridInfo.lastRow + 1][gridInfo.lastColumn + 1];
|
||||
|
||||
for (RadComponent child : getChildren()) {
|
||||
Rectangle cellInfo = getCellInfo(child);
|
||||
|
||||
if (fillSpans) {
|
||||
for (int row = 0; row < cellInfo.height; row++) {
|
||||
for (int column = 0; column < cellInfo.width; column++) {
|
||||
components[cellInfo.y + row][cellInfo.x + column] = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
components[cellInfo.y][cellInfo.x] = child;
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
public static Rectangle getCellInfo(RadComponent component) {
|
||||
Rectangle cellInfo = new Rectangle();
|
||||
|
||||
try {
|
||||
Object layoutParams = ((RadViewComponent)component).getViewInfo().getLayoutParamsObject();
|
||||
Class<?> layoutParamsClass = layoutParams.getClass();
|
||||
|
||||
Object columnSpec = layoutParamsClass.getField("columnSpec").get(layoutParams);
|
||||
Object rowSpec = layoutParamsClass.getField("rowSpec").get(layoutParams);
|
||||
|
||||
Class<?> class_Spec = columnSpec.getClass();
|
||||
Field field_span = class_Spec.getDeclaredField("span");
|
||||
field_span.setAccessible(true);
|
||||
|
||||
Object columnSpan = field_span.get(columnSpec);
|
||||
Object rowSpan = field_span.get(rowSpec);
|
||||
|
||||
Class<?> class_Interval = columnSpan.getClass();
|
||||
Field field_min = class_Interval.getField("min");
|
||||
field_min.setAccessible(true);
|
||||
Field field_max = class_Interval.getField("max");
|
||||
field_max.setAccessible(true);
|
||||
|
||||
cellInfo.x = field_min.getInt(columnSpan);
|
||||
cellInfo.y = field_min.getInt(rowSpan);
|
||||
cellInfo.width = field_max.getInt(columnSpan) - cellInfo.x;
|
||||
cellInfo.height = field_max.getInt(rowSpan) - cellInfo.y;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
}
|
||||
|
||||
return cellInfo;
|
||||
}
|
||||
}
|
||||
+4
-32
@@ -111,10 +111,10 @@ public class RadTableLayoutComponent extends RadViewContainer implements IGridPr
|
||||
myVirtualGridInfo.height = bounds.height;
|
||||
|
||||
int deltaWidth = bounds.width - (gridInfo.vLines.length == 0 ? 0 : gridInfo.width);
|
||||
myVirtualGridInfo.vLines = addLineInfo(gridInfo.vLines, deltaWidth);
|
||||
myVirtualGridInfo.vLines = GridInfo.addLineInfo(gridInfo.vLines, deltaWidth);
|
||||
|
||||
int deltaHeight = bounds.height - gridInfo.height;
|
||||
myVirtualGridInfo.hLines = addLineInfo(gridInfo.hLines, deltaHeight);
|
||||
myVirtualGridInfo.hLines = GridInfo.addLineInfo(gridInfo.hLines, deltaHeight);
|
||||
|
||||
List<RadComponent> rows = getChildren();
|
||||
if (!rows.isEmpty()) {
|
||||
@@ -132,7 +132,7 @@ public class RadTableLayoutComponent extends RadViewContainer implements IGridPr
|
||||
return myVirtualGridInfo;
|
||||
}
|
||||
|
||||
public RadComponent[][] getGridComponents(boolean useSpan) {
|
||||
public RadComponent[][] getGridComponents(boolean fillSpans) {
|
||||
GridInfo gridInfo = getGridInfo();
|
||||
List<RadComponent> rows = getChildren();
|
||||
int columnSize = Math.max(1, gridInfo.vLines.length - 1);
|
||||
@@ -150,7 +150,7 @@ public class RadTableLayoutComponent extends RadViewContainer implements IGridPr
|
||||
}
|
||||
|
||||
int cellSpan = getCellSpan(column);
|
||||
if (useSpan) {
|
||||
if (fillSpans) {
|
||||
for (int j = 0; j < cellSpan; j++) {
|
||||
components[i][index++] = column;
|
||||
}
|
||||
@@ -169,34 +169,6 @@ public class RadTableLayoutComponent extends RadViewContainer implements IGridPr
|
||||
return components;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static void setCellIndex(final RadComponent component, final int column) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user