| /* |
| * 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.layout.grid.GridOperation; |
| import com.intellij.android.designer.model.RadViewComponent; |
| import com.intellij.android.designer.model.grid.GridInfo; |
| import com.intellij.android.designer.model.grid.GridInsertType; |
| import com.intellij.android.designer.model.layout.grid.RadGridLayoutComponent; |
| import com.intellij.designer.designSurface.OperationContext; |
| import com.intellij.designer.model.RadComponent; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.awt.*; |
| |
| /** |
| * @author Alexander Lobas |
| */ |
| public class GridLayoutOperation extends GridOperation { |
| public GridLayoutOperation(RadComponent container, OperationContext context) { |
| super(container, context); |
| } |
| |
| @Override |
| protected int getMovedIndex(boolean row) { |
| RadComponent movedComponent = myContext.getComponents().get(0); |
| Rectangle movedCellInfo = RadGridLayoutComponent.getCellInfo(movedComponent); |
| |
| return row ? movedCellInfo.y : movedCellInfo.x; |
| } |
| |
| @Override |
| protected boolean isSingleMovedAxis(boolean row) { |
| RadComponent movedComponent = myContext.getComponents().get(0); |
| Rectangle movedCellInfo = RadGridLayoutComponent.getCellInfo(movedComponent); |
| |
| if (row) { |
| for (int i = 0; i < movedCellInfo.height; i++) { |
| if (getSizeInRow(movedCellInfo.y + i, movedComponent) > 0) { |
| return false; |
| } |
| } |
| } |
| else { |
| GridInfo gridInfo = getGridInfo(); |
| for (int i = 0; i < movedCellInfo.width; i++) { |
| if (getSizeInColumn(movedCellInfo.x + i, gridInfo.columnCount, movedComponent) > 0) { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| @Override |
| public void execute() throws Exception { |
| GridInfo gridInfo = getGridInfo(); |
| |
| RadGridLayoutComponent container = (RadGridLayoutComponent)myContainer; |
| RadComponent[][] components = container.getGridComponents(false); |
| RadComponent editComponent = myComponents.get(0); |
| |
| if (myInsertType == GridInsertType.in_cell && (myRow >= gridInfo.rowCount || myColumn >= gridInfo.columnCount)) { |
| execute(myContext, container, myComponents, null); |
| RadGridLayoutComponent.setCellIndex(editComponent, myRow, myColumn, true, true); |
| return; |
| } |
| |
| RadViewComponent nextComponent = getNextComponent(components, myRow, myColumn); |
| switch (myInsertType) { |
| case in_cell: |
| if (!myContext.isMove()) { |
| execute(myContext, container, myComponents, nextComponent); |
| RadGridLayoutComponent.setCellIndex(editComponent, myRow, myColumn, true, true); |
| return; |
| } |
| |
| components = insertComponent(components, nextComponent, false, false, false, false); |
| break; |
| |
| case before_h_cell: |
| case after_h_cell: |
| components = insertComponent(components, nextComponent, |
| true, myInsertType == GridInsertType.after_h_cell, |
| false, false); |
| break; |
| |
| case before_v_cell: |
| case after_v_cell: |
| components = insertComponent(components, nextComponent, false, false, |
| true, myInsertType == GridInsertType.after_v_cell); |
| break; |
| |
| default: |
| components = insertComponent(components, nextComponent, |
| true, |
| myInsertType == GridInsertType.corner_bottom_left || myInsertType == GridInsertType.corner_bottom_right, |
| true, |
| myInsertType == GridInsertType.corner_top_right || myInsertType == GridInsertType.corner_bottom_right); |
| } |
| |
| validateLayoutParams(components); |
| } |
| |
| public static void validateLayoutParams(@NotNull RadComponent[][] components) throws Exception { |
| for (int i = 0; i < components.length; i++) { |
| RadComponent[] rowComponents = components[i]; |
| for (int j = 0; j < rowComponents.length; j++) { |
| RadComponent cellComponent = rowComponents[j]; |
| if (cellComponent != null) { |
| RadGridLayoutComponent.setCellIndex(cellComponent, i, j, false, false); |
| } |
| } |
| } |
| } |
| |
| private RadComponent[][] insertComponent(@NotNull RadComponent[][] components, |
| @Nullable RadViewComponent nextComponent, |
| boolean insertRow, |
| boolean afterRow, |
| boolean insertColumn, |
| boolean afterColumn) throws Exception { |
| RadComponent editComponent = myComponents.get(0); |
| |
| if (myContext.isMove()) { |
| Rectangle cellInfo = RadGridLayoutComponent.getCellInfo(editComponent); |
| if (cellInfo.y < components.length && cellInfo.x < components[cellInfo.y].length) { |
| components[cellInfo.y][cellInfo.x] = null; |
| } |
| RadGridLayoutComponent.clearCellSpans(editComponent); |
| } |
| |
| int row = myRow; |
| if (insertRow && afterRow) { |
| row++; |
| } |
| |
| int column = myColumn; |
| if (insertColumn && afterColumn) { |
| column++; |
| } |
| |
| GridInfo gridInfo = getGridInfo(); |
| |
| if (insertRow) { |
| shiftRowSpan(gridInfo, row, 1); |
| } |
| if (insertColumn) { |
| shiftColumnSpan(gridInfo, column, 1); |
| } |
| if (insertRow) { |
| components = insertRow(components, row); |
| } |
| if (insertColumn) { |
| insertColumn(components, column); |
| } |
| |
| components[row][column] = editComponent; |
| |
| if (editComponent != nextComponent) { |
| execute(myContext, (RadGridLayoutComponent)myContainer, myComponents, nextComponent); |
| } |
| |
| return components; |
| } |
| |
| public static void shiftRowSpan(@NotNull GridInfo gridInfo, int row, int inc) { |
| if (row >= gridInfo.rowCount - 1) { |
| return; |
| } |
| |
| RadComponent[] rowComponents = gridInfo.components[row]; |
| RadComponent[] rowComponents1 = gridInfo.components[row + 1]; |
| |
| for (int i = 0; i < rowComponents.length; i++) { |
| RadComponent cellComponent = rowComponents[i]; |
| if (cellComponent != null) { |
| if (cellComponent == rowComponents1[i]) { |
| RadGridLayoutComponent.setSpan(cellComponent, RadGridLayoutComponent.getSpan(cellComponent, true) + inc, true); |
| } |
| |
| while (i + 1 < rowComponents.length && cellComponent == rowComponents[i + 1]) { |
| i++; |
| } |
| } |
| } |
| } |
| |
| private static RadComponent[][] insertRow(@NotNull RadComponent[][] components, int row) { |
| RadComponent[][] newComponents = new RadComponent[components.length + 1][]; |
| |
| System.arraycopy(components, 0, newComponents, 0, row); |
| System.arraycopy(components, row, newComponents, row + 1, components.length - row); |
| |
| newComponents[row] = new RadComponent[components[0].length]; |
| |
| return newComponents; |
| } |
| |
| public static void shiftColumnSpan(@NotNull GridInfo gridInfo, int column, int inc) { |
| if (column >= gridInfo.columnCount - 1) { |
| return; |
| } |
| |
| RadComponent[][] components = gridInfo.components; |
| for (int i = 0; i < components.length; i++) { |
| RadComponent[] rowComponents = components[i]; |
| RadComponent cellComponent = rowComponents[column]; |
| |
| if (cellComponent != null) { |
| if (cellComponent == rowComponents[column + 1]) { |
| RadGridLayoutComponent.setSpan(cellComponent, RadGridLayoutComponent.getSpan(cellComponent, false) + inc, false); |
| } |
| |
| while (i + 1 < components.length && cellComponent == components[i + 1][column]) { |
| i++; |
| } |
| } |
| } |
| } |
| |
| private static void insertColumn(@NotNull RadComponent[][] components, int column) { |
| for (int i = 0; i < components.length; i++) { |
| RadComponent[] rowComponents = components[i]; |
| RadComponent[] newRowComponents = new RadComponent[rowComponents.length + 1]; |
| |
| System.arraycopy(rowComponents, 0, newRowComponents, 0, column); |
| System.arraycopy(rowComponents, column, newRowComponents, column + 1, rowComponents.length - column); |
| |
| components[i] = newRowComponents; |
| } |
| } |
| |
| @Nullable |
| public static RadViewComponent getNextComponent(@NotNull RadComponent[][] components, int row, int column) { |
| RadComponent[] rowComponents = components[row]; |
| |
| for (int i = column + 1; i < rowComponents.length; i++) { |
| RadComponent component = rowComponents[i]; |
| if (component != null) { |
| return (RadViewComponent)component; |
| } |
| } |
| |
| for (int i = row + 1; i < components.length; i++) { |
| for (RadComponent component : components[i]) { |
| if (component != null) { |
| return (RadViewComponent)component; |
| } |
| } |
| } |
| |
| return null; |
| } |
| } |