GridLayout

This commit is contained in:
Alexander Lobas
2012-04-28 18:34:00 +04:00
parent faeba33bc1
commit 73f8549170
9 changed files with 527 additions and 105 deletions
@@ -0,0 +1,101 @@
/*
* 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.actions;
import com.intellij.android.designer.designSurface.layout.grid.GridSelectionDecorator;
import com.intellij.android.designer.model.layout.grid.RadGridLayoutComponent;
import com.intellij.designer.designSurface.OperationContext;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.utils.Position;
import java.awt.*;
/**
* @author Alexander Lobas
*/
public class GridLayoutSpanOperation extends LayoutSpanOperation {
public GridLayoutSpanOperation(OperationContext context, GridSelectionDecorator decorator) {
super(context, decorator);
}
@Override
public void setComponent(RadComponent component) {
super.setComponent(component);
int direction = myContext.getResizeDirection();
mySpan = RadGridLayoutComponent.getSpan(myComponent, direction == Position.NORTH || direction == Position.SOUTH);
}
@Override
protected String getColumnAttribute(boolean asName) {
return asName ? "layout:column" : "android:layout_column";
}
@Override
protected String getColumnSpanAttribute(boolean asName) {
return asName ? "layout:columnSpan" : "android:layout_columnSpan";
}
@Override
protected String getRowAttribute(boolean asName) {
return asName ? "layout:row" : "android:layout_row";
}
@Override
protected String getRowSpanAttribute(boolean asName) {
return asName ? "layout:rowSpan" : "android:layout_rowSpan";
}
@Override
protected Point getCellInfo() {
return RadGridLayoutComponent.getCellInfo(myComponent).getLocation();
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// ResizePoint
//
//////////////////////////////////////////////////////////////////////////////////////////
public static void points(GridSelectionDecorator decorator) {
decorator.addPoint(new SpanPoint(COLOR,
Color.black,
Position.WEST,
TYPE,
"Change layout:column x layout:columnSpan",
decorator)); // left
decorator.addPoint(new SpanPoint(COLOR,
Color.black,
Position.EAST,
TYPE,
"Change layout:columnSpan",
decorator).move(1, 0.75)); // right
decorator.addPoint(new SpanPoint(COLOR,
Color.black,
Position.NORTH,
TYPE,
"Change layout:row x layout:rowSpan",
decorator)); // top
decorator.addPoint(new SpanPoint(COLOR,
Color.black,
Position.SOUTH,
TYPE,
"Change layout:rowSpan",
decorator).move(0.75, 1)); // bottom
}
}
@@ -15,10 +15,12 @@
*/
package com.intellij.android.designer.designSurface.layout.actions;
import com.intellij.android.designer.designSurface.layout.grid.GridSelectionDecorator;
import com.intellij.android.designer.model.ModelParser;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.android.designer.model.layout.table.RadTableLayoutComponent;
import com.intellij.android.designer.model.grid.IGridProvider;
import com.intellij.designer.designSurface.DecorationLayer;
import com.intellij.designer.designSurface.EditOperation;
import com.intellij.designer.designSurface.FeedbackLayer;
import com.intellij.designer.designSurface.OperationContext;
@@ -26,13 +28,12 @@ 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.ResizeSelectionDecorator;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.utils.Position;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.IntArrayList;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.List;
@@ -40,38 +41,40 @@ import java.util.List;
/**
* @author Alexander Lobas
*/
public class LayoutSpanOperation implements EditOperation {
public abstract class LayoutSpanOperation implements EditOperation {
public static final String TYPE = "layout_span";
private static final Color COLOR = Color.green.darker();
protected static final Color COLOR = Color.green.darker();
private final OperationContext myContext;
private RadViewComponent myComponent;
protected final OperationContext myContext;
private final GridSelectionDecorator myDecorator;
protected RadViewComponent myComponent;
private RectangleFeedback myFeedback;
private TextFeedback myTextFeedback;
private Rectangle myBounds;
private Rectangle myTableBounds;
private int mySpan;
private Rectangle myContainerBounds;
protected int mySpan;
private int[] mySpans;
private int[] myOffsets;
private int[] myColumns;
private int[] myCells;
private int myIndex = -1;
public LayoutSpanOperation(OperationContext context) {
public LayoutSpanOperation(OperationContext context, GridSelectionDecorator decorator) {
myContext = context;
myDecorator = decorator;
}
@Override
public void setComponent(RadComponent component) {
myComponent = (RadViewComponent)component;
myBounds = myComponent.getBounds(myContext.getArea().getFeedbackLayer());
myBounds = myDecorator.getCellBounds(myContext.getArea().getFeedbackLayer(), myComponent);
}
@Override
public void setComponents(List<RadComponent> components) {
}
private void createFeedback() {
protected void createFeedback() {
if (myFeedback == null) {
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
@@ -90,11 +93,87 @@ public class LayoutSpanOperation implements EditOperation {
public void showFeedback() {
createFeedback();
Rectangle bounds = myContext.getTransformedRectangle(myBounds);
boolean right = myContext.getResizeDirection() == Position.EAST;
int direction = myContext.getResizeDirection();
if (direction == Position.WEST || direction == Position.EAST) {
handleColumns(direction == Position.EAST);
}
else {
handleRows(direction == Position.SOUTH);
}
}
@Override
public void eraseFeedback() {
if (myFeedback != null) {
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
layer.remove(myTextFeedback);
layer.remove(myFeedback);
layer.repaint();
myTextFeedback = null;
myFeedback = null;
}
}
protected abstract String getColumnAttribute(boolean asName);
protected abstract String getColumnSpanAttribute(boolean asName);
protected abstract String getRowAttribute(boolean asName);
protected abstract String getRowSpanAttribute(boolean asName);
private void handleRows(boolean bottom) {
calculateRows(bottom);
Rectangle bounds = myContext.getTransformedRectangle(myBounds);
int location = bottom ? bounds.y + bounds.height : bounds.y;
if (location < myOffsets[0]) {
myIndex = 0;
}
else {
myIndex = -1;
for (int i = 0; i < myOffsets.length - 1; i++) {
if (myOffsets[i] <= location && location <= myOffsets[i + 1]) {
int delta1 = location - myOffsets[i];
int delta2 = myOffsets[i + 1] - location;
myIndex = delta2 >= delta1 ? i : i + 1;
break;
}
}
if (myIndex == -1) {
myIndex = myOffsets.length - 1;
}
}
if (bottom) {
myFeedback.setBounds(myBounds.x, myBounds.y, myBounds.width, myOffsets[myIndex] - myBounds.y);
}
else {
myFeedback.setBounds(myBounds.x, myOffsets[myIndex], myBounds.width, myBounds.y + myBounds.height - myOffsets[myIndex]);
}
myTextFeedback.clear();
if (!bottom) {
myTextFeedback.append(getRowAttribute(true));
myTextFeedback.append(" ");
myTextFeedback.append(Integer.toString(myCells[myIndex]));
myTextFeedback.append(", ");
}
myTextFeedback.append(getRowSpanAttribute(true));
myTextFeedback.append(" ");
myTextFeedback.append(Integer.toString(mySpans[myIndex]));
myTextFeedback.centerTop(myContainerBounds);
}
private void handleColumns(boolean right) {
calculateColumns(right);
Rectangle bounds = myContext.getTransformedRectangle(myBounds);
int location = right ? bounds.x + bounds.width : bounds.x;
if (location < myOffsets[0]) {
@@ -127,14 +206,86 @@ public class LayoutSpanOperation implements EditOperation {
myTextFeedback.clear();
if (!right) {
myTextFeedback.append("layout:column ");
myTextFeedback.append(Integer.toString(myColumns[myIndex]));
myTextFeedback.append(getColumnAttribute(true));
myTextFeedback.append(" ");
myTextFeedback.append(Integer.toString(myCells[myIndex]));
myTextFeedback.append(", ");
}
myTextFeedback.append("layout:span ");
myTextFeedback.append(getColumnSpanAttribute(true));
myTextFeedback.append(" ");
myTextFeedback.append(Integer.toString(mySpans[myIndex]));
myTextFeedback.centerTop(myTableBounds);
myTextFeedback.centerTop(myContainerBounds);
}
protected RadComponent getContainer() {
return myComponent.getParent();
}
protected abstract Point getCellInfo();
private void calculateRows(boolean bottom) {
if (mySpans != null) {
return;
}
RadComponent container = getContainer();
GridInfo gridInfo = ((IGridProvider)container).getVirtualGridInfo();
RadComponent[][] components = gridInfo.components;
Point cellInfo = getCellInfo();
int row = cellInfo.y;
myContainerBounds = container.getBounds(myContext.getArea().getFeedbackLayer());
IntArrayList spans = new IntArrayList();
IntArrayList offsets = new IntArrayList();
if (bottom) {
int span = 1;
for (int i = row; i < row + mySpan; i++) {
spans.add(span++);
offsets.add(myContainerBounds.y + gridInfo.hLines[i + 1]);
}
for (int i = row + mySpan; i < components.length; i++) {
if (components[i][cellInfo.x] == null) {
spans.add(span++);
offsets.add(myContainerBounds.y + gridInfo.hLines[i + 1]);
}
else {
break;
}
}
}
else {
IntArrayList columns = new IntArrayList();
int span = mySpan;
for (int i = row; i < row + mySpan; i++) {
spans.add(span--);
offsets.add(myContainerBounds.y + gridInfo.hLines[i]);
columns.add(i);
}
span = mySpan;
for (int i = row - 1; i >= 0; i--) {
if (components[i][cellInfo.x] == null) {
spans.add(0, ++span);
offsets.add(0, myContainerBounds.y + gridInfo.hLines[i]);
columns.add(0, i);
}
else {
break;
}
}
myCells = columns.toArray();
}
mySpans = spans.toArray();
myOffsets = offsets.toArray();
}
private void calculateColumns(boolean right) {
@@ -142,13 +293,13 @@ public class LayoutSpanOperation implements EditOperation {
return;
}
RadTableLayoutComponent tableComponent = (RadTableLayoutComponent)myComponent.getParent().getParent();
GridInfo gridInfo = tableComponent.getVirtualGridInfo();
RadComponent[] rowComponents = gridInfo.components[tableComponent.getChildren().indexOf(myComponent.getParent())];
int column = ArrayUtil.indexOf(rowComponents, myComponent);
RadComponent container = getContainer();
GridInfo gridInfo = ((IGridProvider)container).getVirtualGridInfo();
Point cellInfo = getCellInfo();
RadComponent[] rowComponents = gridInfo.components[cellInfo.y];
int column = cellInfo.x;
mySpan = RadTableLayoutComponent.getCellSpan(myComponent);
myTableBounds = tableComponent.getBounds(myContext.getArea().getFeedbackLayer());
myContainerBounds = container.getBounds(myContext.getArea().getFeedbackLayer());
IntArrayList spans = new IntArrayList();
IntArrayList offsets = new IntArrayList();
@@ -158,13 +309,13 @@ public class LayoutSpanOperation implements EditOperation {
for (int i = column; i < column + mySpan; i++) {
spans.add(span++);
offsets.add(myTableBounds.x + gridInfo.vLines[i + 1]);
offsets.add(myContainerBounds.x + gridInfo.vLines[i + 1]);
}
for (int i = column + mySpan; i < rowComponents.length; i++) {
if (rowComponents[i] == null) {
spans.add(span++);
offsets.add(myTableBounds.x + gridInfo.vLines[i + 1]);
offsets.add(myContainerBounds.x + gridInfo.vLines[i + 1]);
}
else {
break;
@@ -177,7 +328,7 @@ public class LayoutSpanOperation implements EditOperation {
for (int i = column; i < column + mySpan; i++) {
spans.add(span--);
offsets.add(myTableBounds.x + gridInfo.vLines[i]);
offsets.add(myContainerBounds.x + gridInfo.vLines[i]);
columns.add(i);
}
@@ -186,7 +337,7 @@ public class LayoutSpanOperation implements EditOperation {
for (int i = column - 1; i >= 0; i--) {
if (rowComponents[i] == null) {
spans.add(0, ++span);
offsets.add(0, myTableBounds.x + gridInfo.vLines[i]);
offsets.add(0, myContainerBounds.x + gridInfo.vLines[i]);
columns.add(0, i);
}
else {
@@ -194,25 +345,13 @@ public class LayoutSpanOperation implements EditOperation {
}
}
myColumns = columns.toArray();
myCells = columns.toArray();
}
mySpans = spans.toArray();
myOffsets = offsets.toArray();
}
@Override
public void eraseFeedback() {
if (myFeedback != null) {
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
layer.remove(myTextFeedback);
layer.remove(myFeedback);
layer.repaint();
myTextFeedback = null;
myFeedback = null;
}
}
@Override
public boolean canExecute() {
return true;
@@ -227,66 +366,55 @@ public class LayoutSpanOperation implements EditOperation {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
XmlTag tag = myComponent.getTag();
if (myContext.getResizeDirection() == Position.WEST) {
tag.setAttribute("android:layout_column", Integer.toString(myColumns[myIndex]));
}
int span = mySpans[myIndex];
if (span == 1) {
ModelParser.deleteAttribute(tag, "android:layout_span");
int direction = myContext.getResizeDirection();
if (direction == Position.WEST || direction == Position.EAST) {
execute(getColumnAttribute(false), getColumnSpanAttribute(false), direction == Position.WEST);
}
else {
tag.setAttribute("android:layout_span", Integer.toString(span));
execute(getRowAttribute(false), getRowSpanAttribute(false), direction == Position.NORTH);
}
}
});
}
private void execute(String cell, String span, boolean cellFix) {
XmlTag tag = myComponent.getTag();
if (cellFix) {
tag.setAttribute(cell, Integer.toString(myCells[myIndex]));
}
int spanValue = mySpans[myIndex];
if (spanValue == 1) {
ModelParser.deleteAttribute(tag, span);
}
else {
tag.setAttribute(span, Integer.toString(spanValue));
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// ResizePoint
//
//////////////////////////////////////////////////////////////////////////////////////////
public static void tablePoints(ResizeSelectionDecorator decorator) {
decorator.addPoint(new DirectionResizePoint(COLOR,
Color.black,
Position.WEST,
TYPE,
"Change layout:column x layout:span")); // left
protected static class SpanPoint extends DirectionResizePoint {
private final GridSelectionDecorator myDecorator;
decorator.addPoint(new DirectionResizePoint(COLOR,
Color.black,
Position.EAST,
TYPE,
"Change layout:span")); // right
}
public SpanPoint(Color color,
Color border,
int direction,
Object type,
@Nullable String description,
GridSelectionDecorator decorator) {
super(color, border, direction, type, description);
myDecorator = decorator;
}
public static void gridPoints(ResizeSelectionDecorator decorator) {
decorator.addPoint(new DirectionResizePoint(COLOR,
Color.black,
Position.WEST,
TYPE,
"Change layout:column x layout:columnSpan")); // left
decorator.addPoint(new DirectionResizePoint(COLOR,
Color.black,
Position.EAST,
TYPE,
"Change layout:columnSpan").move(1, 0.25)); // right
decorator.addPoint(new DirectionResizePoint(COLOR,
Color.black,
Position.NORTH,
TYPE,
"Change layout:row x layout:rowSpan")); // top
decorator.addPoint(new DirectionResizePoint(COLOR,
Color.black,
Position.SOUTH,
TYPE,
"Change layout:rowSpan").move(0.25, 1)); // bottom
@Override
protected Rectangle getBounds(DecorationLayer layer, RadComponent component) {
return myDecorator.getCellBounds(layer, component);
}
}
}
@@ -66,11 +66,15 @@ public class ResizeOperation implements EditOperation {
}
public static void points(ResizeSelectionDecorator decorator) {
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.EAST, TYPE, "Change layout:width"));
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH, TYPE, "Change layout:height"));
width(decorator);
height(decorator);
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH_EAST, TYPE, "Change layout:width x layout:height"));
}
public static void width(ResizeSelectionDecorator decorator) {
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.EAST, TYPE, "Change layout:width"));
}
public static void height(ResizeSelectionDecorator decorator) {
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH, TYPE, "Change layout:height"));
}
@@ -0,0 +1,98 @@
/*
* 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.actions;
import com.intellij.android.designer.designSurface.layout.grid.GridSelectionDecorator;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.android.designer.model.layout.table.RadTableLayoutComponent;
import com.intellij.designer.designSurface.OperationContext;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.utils.Position;
import com.intellij.util.ArrayUtil;
import java.awt.*;
/**
* @author Alexander Lobas
*/
public class TableLayoutSpanOperation extends LayoutSpanOperation {
public TableLayoutSpanOperation(OperationContext context, GridSelectionDecorator decorator) {
super(context, decorator);
}
@Override
public void setComponent(RadComponent component) {
super.setComponent(component);
mySpan = RadTableLayoutComponent.getCellSpan(myComponent);
}
@Override
protected String getColumnAttribute(boolean asName) {
return asName ? "layout:column" : "android:layout_column";
}
@Override
protected String getColumnSpanAttribute(boolean asName) {
return asName ? "layout:span" : "android:layout_span";
}
@Override
protected String getRowAttribute(boolean asName) {
throw new UnsupportedOperationException();
}
@Override
protected String getRowSpanAttribute(boolean asName) {
throw new UnsupportedOperationException();
}
@Override
protected RadComponent getContainer() {
return myComponent.getParent().getParent();
}
@Override
protected Point getCellInfo() {
RadTableLayoutComponent tableComponent = (RadTableLayoutComponent)myComponent.getParent().getParent();
GridInfo gridInfo = tableComponent.getVirtualGridInfo();
int row = tableComponent.getChildren().indexOf(myComponent.getParent());
int column = ArrayUtil.indexOf(gridInfo.components[row], myComponent);
return new Point(column, row);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// ResizePoint
//
//////////////////////////////////////////////////////////////////////////////////////////
public static void points(GridSelectionDecorator decorator) {
decorator.addPoint(new SpanPoint(COLOR,
Color.black,
Position.WEST,
TYPE,
"Change layout:column x layout:span",
decorator)); // left
decorator.addPoint(new SpanPoint(COLOR,
Color.black,
Position.EAST,
TYPE,
"Change layout:span",
decorator)); // right
}
}
@@ -0,0 +1,48 @@
package com.intellij.android.designer.designSurface.layout.grid;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.designer.designSurface.DecorationLayer;
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
import com.intellij.designer.model.RadComponent;
import java.awt.*;
/**
* @author Alexander Lobas
*/
public abstract class GridSelectionDecorator extends ResizeSelectionDecorator {
public GridSelectionDecorator(Color color, int lineWidth) {
super(color, lineWidth);
}
@Override
protected Rectangle getBounds(DecorationLayer layer, RadComponent component) {
return getCellBounds(layer, component);
}
public abstract Rectangle getCellBounds(Component layer, RadComponent component);
public static Rectangle calculateBounds(Component layer,
GridInfo gridInfo,
RadComponent parent,
RadComponent component,
int row,
int column,
int rowSpan,
int columnSpan) {
Rectangle bounds = parent.getBounds(layer);
bounds.x += gridInfo.vLines[column];
bounds.width = gridInfo.vLines[column + columnSpan] - gridInfo.vLines[column];
bounds.y += gridInfo.hLines[row];
bounds.height = gridInfo.hLines[row + rowSpan] - gridInfo.hLines[row];
Rectangle componentBounds = component.getBounds(layer);
if (!bounds.contains(componentBounds.x, componentBounds.y)) {
return componentBounds;
}
return bounds;
}
}
@@ -17,11 +17,13 @@ package com.intellij.android.designer.model.layout.grid;
import com.intellij.android.designer.designSurface.TreeDropToOperation;
import com.intellij.android.designer.designSurface.layout.GridLayoutOperation;
import com.intellij.android.designer.designSurface.layout.actions.GridLayoutSpanOperation;
import com.intellij.android.designer.designSurface.layout.actions.LayoutSpanOperation;
import com.intellij.android.designer.designSurface.layout.actions.ResizeOperation;
import com.intellij.android.designer.designSurface.layout.caption.GridHorizontalCaptionOperation;
import com.intellij.android.designer.designSurface.layout.caption.GridVerticalCaptionOperation;
import com.intellij.android.designer.designSurface.layout.grid.GridDecorator;
import com.intellij.android.designer.designSurface.layout.grid.GridSelectionDecorator;
import com.intellij.android.designer.model.RadViewLayout;
import com.intellij.android.designer.model.RadViewLayoutWithData;
import com.intellij.android.designer.model.grid.GridInfo;
@@ -29,7 +31,6 @@ import com.intellij.android.designer.model.layout.actions.AllGravityAction;
import com.intellij.android.designer.model.layout.actions.OrientationAction;
import com.intellij.designer.componentTree.TreeEditOperation;
import com.intellij.designer.designSurface.*;
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadLayout;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -49,7 +50,7 @@ public class RadGridLayout extends RadViewLayoutWithData implements ILayoutDecor
private static final String[] LAYOUT_PARAMS = {"GridLayout_Layout", "ViewGroup_MarginLayout"};
private GridDecorator myGridDecorator;
private ResizeSelectionDecorator mySelectionDecorator;
private GridSelectionDecorator mySelectionDecorator;
@NotNull
@Override
@@ -72,7 +73,7 @@ public class RadGridLayout extends RadViewLayoutWithData implements ILayoutDecor
return new ResizeOperation(context);
}
if (context.is(LayoutSpanOperation.TYPE)) {
return new LayoutSpanOperation(context);
return new GridLayoutSpanOperation(context, mySelectionDecorator);
}
return null;
}
@@ -105,14 +106,24 @@ public class RadGridLayout extends RadViewLayoutWithData implements ILayoutDecor
@Override
public ComponentDecorator getChildSelectionDecorator(RadComponent component, List<RadComponent> selection) {
if (mySelectionDecorator == null) {
mySelectionDecorator = new ResizeSelectionDecorator(Color.red, 1);
mySelectionDecorator = new GridSelectionDecorator(Color.red, 1) {
@Override
public Rectangle getCellBounds(Component layer, RadComponent component) {
RadGridLayoutComponent parent = (RadGridLayoutComponent)component.getParent();
GridInfo gridInfo = parent.getGridInfo();
Rectangle cellInfo = RadGridLayoutComponent.getCellInfo(component);
return calculateBounds(layer, gridInfo, parent, component, cellInfo.y, cellInfo.x, cellInfo.height, cellInfo.width);
}
};
}
mySelectionDecorator.clear();
if (selection.size() == 1) {
LayoutSpanOperation.gridPoints(mySelectionDecorator);
GridLayoutSpanOperation.points(mySelectionDecorator);
}
ResizeOperation.points(mySelectionDecorator);
ResizeOperation.width(mySelectionDecorator);
ResizeOperation.height(mySelectionDecorator);
return mySelectionDecorator;
}
@@ -16,12 +16,15 @@
package com.intellij.android.designer.model.layout.table;
import com.intellij.android.designer.designSurface.layout.actions.LayoutSpanOperation;
import com.intellij.android.designer.model.layout.actions.AllGravityAction;
import com.intellij.android.designer.designSurface.layout.actions.TableLayoutSpanOperation;
import com.intellij.android.designer.designSurface.layout.grid.GridSelectionDecorator;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.android.designer.model.layout.RadLinearLayout;
import com.intellij.android.designer.model.layout.actions.AllGravityAction;
import com.intellij.designer.designSurface.*;
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
import com.intellij.designer.model.RadComponent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -34,7 +37,7 @@ import java.util.List;
public class RadTableRowLayout extends RadLinearLayout {
private static final String[] LAYOUT_PARAMS = {"TableRow_Cell", "LinearLayout_Layout", "ViewGroup_MarginLayout"};
private ResizeSelectionDecorator mySelectionDecorator;
private GridSelectionDecorator mySelectionDecorator;
@Override
@NotNull
@@ -61,7 +64,7 @@ public class RadTableRowLayout extends RadLinearLayout {
return super.processChildOperation(context);
}
if (context.is(LayoutSpanOperation.TYPE)) {
return new LayoutSpanOperation(context);
return new TableLayoutSpanOperation(context, mySelectionDecorator);
}
return null;
}
@@ -77,12 +80,33 @@ public class RadTableRowLayout extends RadLinearLayout {
public ComponentDecorator getChildSelectionDecorator(RadComponent component, List<RadComponent> selection) {
if (isTableParent()) {
if (mySelectionDecorator == null) {
mySelectionDecorator = new ResizeSelectionDecorator(Color.red, 1);
mySelectionDecorator = new GridSelectionDecorator(Color.red, 1) {
@Override
public Rectangle getCellBounds(Component layer, RadComponent component) {
RadTableLayoutComponent tableComponent = (RadTableLayoutComponent)component.getParent().getParent();
GridInfo gridInfo = tableComponent.getVirtualGridInfo();
int row = tableComponent.getChildren().indexOf(component.getParent());
RadComponent[] rowComponents = gridInfo.components[row];
int column = ArrayUtil.indexOf(rowComponents, component);
int columnSpan = 1;
for (int i = column + 1; i < rowComponents.length; i++) {
if (rowComponents[i] == component) {
columnSpan++;
}
else {
break;
}
}
return calculateBounds(layer, gridInfo, tableComponent, component, row, column, 1, columnSpan);
}
};
}
mySelectionDecorator.clear();
if (selection.size() == 1) {
LayoutSpanOperation.tablePoints(mySelectionDecorator);
TableLayoutSpanOperation.points(mySelectionDecorator);
}
return mySelectionDecorator;
}
@@ -95,11 +95,15 @@ public class DirectionResizePoint extends ResizePoint {
@Override
protected Point getLocation(DecorationLayer layer, RadComponent component) {
Rectangle bounds = component.getBounds(layer);
Rectangle bounds = getBounds(layer, component);
int size = (getSize() + 1) / 2;
int x = bounds.x + (int)(bounds.width * myXSeparator) - size;
int y = bounds.y + (int)(bounds.height * myYSeparator) - size;
return new Point(x, y);
}
protected Rectangle getBounds(DecorationLayer layer, RadComponent component) {
return component.getBounds(layer);
}
}
@@ -39,7 +39,7 @@ public class NonResizeSelectionDecorator extends ComponentDecorator {
@Override
public InputTool findTargetTool(DecorationLayer layer, RadComponent component, int x, int y) {
Rectangle bounds = component.getBounds(layer);
Rectangle bounds = getBounds(layer, component);
int lineWidth = Math.max(myLineWidth, 2);
Rectangle top = new Rectangle(bounds.x, bounds.y, bounds.width, lineWidth);
@@ -61,7 +61,11 @@ public class NonResizeSelectionDecorator extends ComponentDecorator {
g.setStroke(myStroke);
}
Rectangle bounds = component.getBounds(layer);
Rectangle bounds = getBounds(layer, component);
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
protected Rectangle getBounds(DecorationLayer layer, RadComponent component) {
return component.getBounds(layer);
}
}