IDEA-40712
authorAlexander Lobas <Alexander.Lobas@jetbrains.com>
Wed, 1 Feb 2012 16:52:36 +0000 (20:52 +0400)
committerAlexander Lobas <Alexander.Lobas@jetbrains.com>
Wed, 1 Feb 2012 16:52:36 +0000 (20:52 +0400)
plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridInsertLocation.java
plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridSpanInsertProcessor.java [new file with mode: 0644]
plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadAbstractGridLayoutManager.java

index 41f0a32cfc65f2c432eabedb001a266eadb5227c..364d5879a664a9c060c5a1fb0876f53838bf6970 100644 (file)
@@ -41,6 +41,8 @@ public class GridInsertLocation extends GridDropLocation {
 
   private GridInsertMode myMode;
 
+  private boolean mySpanInsertMode;
+
   public GridInsertLocation(@NotNull final RadContainer container,
                             final int row,
                             final int column,
@@ -82,6 +84,10 @@ public class GridInsertLocation extends GridDropLocation {
     return myMode;
   }
 
+  public void setSpanInsertMode(boolean spanInsertMode) {
+    mySpanInsertMode = spanInsertMode;
+  }
+
   private boolean isColumnInsert() {
     return myMode == GridInsertMode.ColumnAfter || myMode == GridInsertMode.ColumnBefore;
   }
@@ -198,7 +204,7 @@ public class GridInsertLocation extends GridDropLocation {
       int cellWidth = vGridLines [lastColIndex] - vGridLines [insertCol];
       int cellHeight = hGridLines [lastRowIndex] - hGridLines [insertRow];
       RadComponent component = layoutManager.getComponentAtGrid(getContainer(), insertRow, insertCol);
-      if (component != null) {
+      if (component != null && mySpanInsertMode) {
         Rectangle bounds = component.getBounds();
         bounds.translate(-vGridLines [insertCol], -hGridLines [insertRow]);
 
@@ -218,6 +224,32 @@ public class GridInsertLocation extends GridDropLocation {
         }
 
         if (rcFeedback != null) {
+          boolean spanInsertMode = false;
+          
+          if (isRowInsert()) {
+            int columns = layoutManager.getGridColumnCount(getContainer());
+            for (int i = 0; i < columns; i++) {
+              if (i != insertCol && RadAbstractGridLayoutManager.getComponentAtGrid(getContainer(), insertRow, i) != null) {
+                spanInsertMode = true;
+                break;
+              }
+            }
+          } else {
+            int rows = layoutManager.getGridRowCount(getContainer());
+            for (int i = 0; i < rows; i++) {
+              if (i != insertRow && RadAbstractGridLayoutManager.getComponentAtGrid(getContainer(), i, insertCol) != null) {
+                spanInsertMode = true;
+                break;
+              }
+            }
+          }
+
+          if (!spanInsertMode) {
+            rcFeedback = null;
+          }
+        }
+
+        if (rcFeedback != null) {
           rcFeedback.translate(vGridLines [insertCol], hGridLines [insertRow]);
         }
       }
@@ -336,13 +368,17 @@ public class GridInsertLocation extends GridDropLocation {
     int cellsToInsert = 1;
     if (components.length > 0) {
       int cellSize = container.getGridCellCount(isRowInsert());
-      Rectangle rc = getDragObjectDimensions(dragObject, cell < cellSize - 1);
-      int size = isRowInsert() ? rc.height : rc.width;
-      if (size > 0) {
-        cellsToInsert = size;
+        Rectangle rc = getDragObjectDimensions(dragObject, cell < cellSize - 1);
+        int size = isRowInsert() ? rc.height : rc.width;
+        if (size > 0) {
+          cellsToInsert = size;
       }
     }
 
+    GridSpanInsertProcessor spanInsertProcessor =
+      mySpanInsertMode && dragObject.getComponentCount() == 1 ? new GridSpanInsertProcessor(container, getRow(), getColumn(), myMode,
+                                                                                            dragObject) : null;
+
     int newCell = insertGridCells(container, cell, cellsToInsert, canGrow, isRowInsert(), !isInsertAfter(), constraintsToAdjust);
     if (isRowInsert()) {
       row = newCell;
@@ -352,7 +388,15 @@ public class GridInsertLocation extends GridDropLocation {
     }
 
     if (components.length > 0) {
+      if (spanInsertProcessor != null) {
+        spanInsertProcessor.doBefore(newCell);
+      }
+
       dropIntoGrid(container, components, row, col, dragObject);
+
+      if (spanInsertProcessor != null) {
+        spanInsertProcessor.doAfter(newCell);
+      }
     }
   }
 
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridSpanInsertProcessor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridSpanInsertProcessor.java
new file mode 100644 (file)
index 0000000..79ee09e
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * 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.uiDesigner.designSurface;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.radComponents.RadAbstractGridLayoutManager;
+import com.intellij.uiDesigner.radComponents.RadComponent;
+import com.intellij.uiDesigner.radComponents.RadContainer;
+
+import java.awt.*;
+
+/**
+ * @author Alexander Lobas
+ */
+public class GridSpanInsertProcessor {
+  private final RadContainer myContainer;
+  private final RadAbstractGridLayoutManager myLayoutManager;
+  private final int myRow;
+  private final int myColumn;
+  private GridInsertMode myMode;
+  private RadComponent myInsertCellComponent;
+
+  public GridSpanInsertProcessor(RadContainer container,
+                                 int insertRow,
+                                 int insertColumn,
+                                 GridInsertMode mode,
+                                 ComponentDragObject dragObject) {
+    myContainer = container;
+    myLayoutManager = container.getGridLayoutManager();
+    myRow = insertRow;
+    myColumn = insertColumn;
+
+    int[] vGridLines = myLayoutManager.getVerticalGridLines(container);
+    int[] hGridLines = myLayoutManager.getHorizontalGridLines(container);
+
+    RadComponent component = RadAbstractGridLayoutManager.getComponentAtGrid(container, insertRow, insertColumn);
+
+    if (component != null) {
+      int lastColIndex = insertColumn + dragObject.getColSpan(0);
+      if (lastColIndex > vGridLines.length - 1) {
+        lastColIndex = insertColumn + 1;
+      }
+
+      int lastRowIndex = insertRow + dragObject.getRowSpan(0);
+      if (lastRowIndex > hGridLines.length - 1) {
+        lastRowIndex = insertRow + 1;
+      }
+
+      Rectangle bounds = component.getBounds();
+      bounds.translate(-vGridLines[insertColumn], -hGridLines[insertRow]);
+
+      int spaceToRight = vGridLines[lastColIndex] - vGridLines[insertColumn] - (bounds.x + bounds.width);
+      int spaceBelow = hGridLines[lastRowIndex] - hGridLines[insertRow] - (bounds.y + bounds.height);
+
+      if (mode == GridInsertMode.RowBefore && bounds.y > GridInsertLocation.INSERT_RECT_MIN_SIZE) {
+        myMode = GridInsertMode.RowBefore;
+        myInsertCellComponent = component;
+      }
+      else if (mode == GridInsertMode.RowAfter && spaceBelow > GridInsertLocation.INSERT_RECT_MIN_SIZE) {
+        myMode = GridInsertMode.RowAfter;
+      }
+      else if (mode == GridInsertMode.ColumnBefore && bounds.x > GridInsertLocation.INSERT_RECT_MIN_SIZE) {
+        myMode = GridInsertMode.ColumnBefore;
+        myInsertCellComponent = component;
+      }
+      else if (mode == GridInsertMode.ColumnAfter && spaceToRight > GridInsertLocation.INSERT_RECT_MIN_SIZE) {
+        myMode = GridInsertMode.ColumnAfter;
+      }
+    }
+  }
+
+  public void doBefore(int newCell) {
+    if (myMode == GridInsertMode.RowBefore) {
+      int oldRow = myInsertCellComponent.getConstraints().getRow();
+      int columns = myLayoutManager.getGridColumnCount(myContainer);
+      for (int i = 0; i < columns; i++) {
+        if (i != myColumn) {
+          RadComponent component = RadAbstractGridLayoutManager.getComponentAtGrid(myContainer, oldRow, i);
+          if (component != null) {
+            GridConstraints constraints = component.getConstraints();
+
+            if (constraints.getRow() == oldRow) {
+              GridConstraints oldConstraints = (GridConstraints)constraints.clone();
+              constraints.setRow(newCell);
+              constraints.setRowSpan(constraints.getRowSpan() + oldRow - newCell);
+              component.fireConstraintsChanged(oldConstraints);
+            }
+
+            i = constraints.getColumn() + constraints.getColSpan() - 1;
+          }
+        }
+      }
+    }
+    else if (myMode == GridInsertMode.ColumnBefore) {
+      int oldColumn = myInsertCellComponent.getConstraints().getColumn();
+      int rows = myLayoutManager.getGridRowCount(myContainer);
+      for (int i = 0; i < rows; i++) {
+        if (i != myRow) {
+          RadComponent component = RadAbstractGridLayoutManager.getComponentAtGrid(myContainer, i, oldColumn);
+          if (component != null) {
+            GridConstraints constraints = component.getConstraints();
+
+            if (constraints.getColumn() == oldColumn) {
+              GridConstraints oldConstraints = (GridConstraints)constraints.clone();
+              constraints.setColumn(newCell);
+              constraints.setColSpan(constraints.getColSpan() + oldColumn - newCell);
+              component.fireConstraintsChanged(oldConstraints);
+            }
+
+            i = constraints.getRow() + constraints.getRowSpan() - 1;
+          }
+        }
+      }
+    }
+  }
+
+  public void doAfter(int newCell) {
+    if (myMode == GridInsertMode.RowAfter) {
+      int columns = myLayoutManager.getGridColumnCount(myContainer);
+      for (int i = 0; i < columns; i++) {
+        if (i != myColumn) {
+          RadComponent component = RadAbstractGridLayoutManager.getComponentAtGrid(myContainer, myRow, i);
+          if (component != null) {
+            GridConstraints constraints = component.getConstraints();
+            int endRow = constraints.getRow() + constraints.getRowSpan() - 1;
+
+            if (endRow == myRow) {
+              GridConstraints oldConstraints = (GridConstraints)constraints.clone();
+              constraints.setRowSpan(constraints.getRowSpan() + newCell - myRow);
+              component.fireConstraintsChanged(oldConstraints);
+            }
+
+            i = constraints.getColumn() + constraints.getColSpan() - 1;
+          }
+        }
+      }
+    }
+    else if (myMode == GridInsertMode.ColumnAfter) {
+      int rows = myLayoutManager.getGridRowCount(myContainer);
+      for (int i = 0; i < rows; i++) {
+        if (i != myRow) {
+          RadComponent component = RadAbstractGridLayoutManager.getComponentAtGrid(myContainer, i, myColumn);
+          if (component != null) {
+            GridConstraints constraints = component.getConstraints();
+            int endColumn = constraints.getColumn() + constraints.getColSpan() - 1;
+
+            if (endColumn == myColumn) {
+              GridConstraints oldConstraints = (GridConstraints)constraints.clone();
+              constraints.setColSpan(constraints.getColSpan() + newCell - myColumn);
+              component.fireConstraintsChanged(oldConstraints);
+            }
+
+            i = constraints.getRow() + constraints.getRowSpan() - 1;
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
index ccc7b57141966b3b4fab855c0c47fcfa7539ff06..2f76d26fa057cb2249214a9cee26c5ad377596c4 100644 (file)
@@ -190,6 +190,10 @@ public abstract class RadAbstractGridLayoutManager extends RadLayoutManager {
     return 0;
   }
 
+  public boolean canSpanningAllowed() {
+    return true;
+  }
+
   public boolean canResizeCells() {
     return true;
   }
@@ -301,6 +305,8 @@ public abstract class RadAbstractGridLayoutManager extends RadLayoutManager {
       mode = GridInsertMode.ColumnAfter;
     }
 
+    boolean spanInsertMode = canSpanningAllowed() && mode == null;
+    boolean normalize = true;
     final int cellWidth = vertGridLines[col + 1] - vertGridLines[col];
     final int cellHeight = horzGridLines[row + 1] - horzGridLines[row];
     if (mode == null) {
@@ -324,11 +330,15 @@ public abstract class RadAbstractGridLayoutManager extends RadLayoutManager {
         else if (dx > right && dx < cellWidth) {
           mode = GridInsertMode.ColumnAfter;
         }
+
+        normalize = false;
       }
     }
 
     if (mode != null) {
-      return new GridInsertLocation(container, row, col, mode).normalize();
+      GridInsertLocation dropLocation = new GridInsertLocation(container, row, col, mode);
+      dropLocation.setSpanInsertMode(spanInsertMode);
+      return normalize ? dropLocation.normalize() : dropLocation;
     }
     if (getComponentAtGrid(container, row, col) instanceof RadVSpacer ||
         getComponentAtGrid(container, row, col) instanceof RadHSpacer) {