Merge remote-tracking branch 'origin/master'
authorAlexander Lobas <Alexander.Lobas@jetbrains.com>
Mon, 30 Jan 2012 16:28:55 +0000 (20:28 +0400)
committerAlexander Lobas <Alexander.Lobas@jetbrains.com>
Mon, 30 Jan 2012 16:28:55 +0000 (20:28 +0400)
plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridDropLocation.java
plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridInsertLocation.java

index 90c529db3a1b03ce1aad34b6551fb5fb765a488f..0bb7d72f894e1eaab0682b5ee76d90811427b784 100644 (file)
@@ -63,11 +63,12 @@ public class GridDropLocation implements ComponentDropLocation {
       return false;
     }
 
+    int colSpan = 1; // allow drop any (NxM) component to cell (1x1)
+    int rowSpan = 1;
+
     for(int i=0; i<dragObject.getComponentCount(); i++) {
       int relativeCol = dragObject.getRelativeCol(i);
       int relativeRow = dragObject.getRelativeRow(i);
-      int colSpan = dragObject.getColSpan(i);
-      int rowSpan = dragObject.getRowSpan(i);
 
       LOG.debug("checking component: relativeRow" + relativeRow + ", relativeCol" + relativeCol + ", colSpan=" + colSpan + ", rowSpan=" + rowSpan);
 
@@ -99,7 +100,7 @@ public class GridDropLocation implements ComponentDropLocation {
   public void placeFeedback(FeedbackLayer feedbackLayer, ComponentDragObject dragObject) {
     Rectangle feedbackRect = null;
     if (getContainer().getLayoutManager().isGrid()) {
-      feedbackRect = getGridFeedbackRect(dragObject, false, false);
+      feedbackRect = getGridFeedbackRect(dragObject, false, false, true);
     }
     if (feedbackRect != null) {
       final JComponent component = getContainer().getDelegee();
@@ -115,44 +116,62 @@ public class GridDropLocation implements ComponentDropLocation {
   }
 
   @Nullable
-  protected Rectangle getGridFeedbackCellRect(ComponentDragObject dragObject, final boolean ignoreWidth, final boolean ignoreHeight) {
+  protected Rectangle getGridFeedbackCellRect(ComponentDragObject dragObject,
+                                              boolean ignoreWidth,
+                                              boolean ignoreHeight,
+                                              boolean overlapping) {
     if (dragObject.getComponentCount() == 0) {
-      LOG.debug("no feedback rect because component count=0");
       return null;
     }
 
-    Rectangle rc = getDragObjectDimensions(dragObject);
+    Rectangle rc = calculateGridFeedbackCellRect(dragObject, ignoreWidth, ignoreHeight, true);
+
+    if (rc == null) {
+      return calculateGridFeedbackCellRect(dragObject, ignoreWidth, ignoreHeight, false);
+    }
+
+    if (overlapping && findOverlappingComponent(rc.y, rc.x, rc.height + 1, rc.width + 1) != null) {
+     return calculateGridFeedbackCellRect(dragObject, ignoreWidth, ignoreHeight, false);
+    }
+
+    return rc;
+  }
+
+  @Nullable
+  private Rectangle calculateGridFeedbackCellRect(ComponentDragObject dragObject,
+                                             boolean ignoreWidth,
+                                             boolean ignoreHeight,
+                                             boolean spans) {
+    Rectangle rc = getDragObjectDimensions(dragObject, spans);
     int w = ignoreWidth ? 1 : rc.width;
     int h = ignoreHeight ? 1 : rc.height;
 
-    if (rc.x < 0 || rc.y < 0 ||
-        rc.y + h > getContainer().getGridRowCount() || rc.x + w > getContainer().getGridColumnCount()) {
-      LOG.debug("no feedback rect because insert range is outside grid: firstRow=" + rc.y +
-                ", firstCol=" + rc.x + ", lastRow=" + (rc.y+h-1) + ", lastCol=" + (rc.x+w-1));
+    if (rc.x < 0 || rc.y < 0 || rc.y + h > getContainer().getGridRowCount() || rc.x + w > getContainer().getGridColumnCount()) {
       return null;
     }
-    return new Rectangle(rc.x, rc.y, w-1, h-1);
+    
+    return new Rectangle(rc.x, rc.y, w - 1, h - 1);
   }
 
-  protected Rectangle getDragObjectDimensions(final ComponentDragObject dragObject) {
+  protected Rectangle getDragObjectDimensions(ComponentDragObject dragObject, boolean spans) {
     int firstRow = getRow();
     int lastRow = getRow();
     int firstCol = getColumn();
     int lastCol = getColumn();
-    for(int i=0; i<dragObject.getComponentCount(); i++) {
-      final int relRow = dragObject.getRelativeRow(i);
-      final int relCol = dragObject.getRelativeCol(i);
+    for (int i = 0; i < dragObject.getComponentCount(); i++) {
+      int relRow = dragObject.getRelativeRow(i);
+      int relCol = dragObject.getRelativeCol(i);
       firstRow = Math.min(firstRow, getRow() + relRow);
       firstCol = Math.min(firstCol, getColumn() + relCol);
-      lastRow = Math.max(lastRow, getRow() + relRow + dragObject.getRowSpan(i) - 1);
-      lastCol = Math.max(lastCol, getColumn() + relCol + dragObject.getColSpan(i) - 1);
+      lastRow = Math.max(lastRow, getRow() + relRow + (spans ? dragObject.getRowSpan(i) : 1) - 1);
+      lastCol = Math.max(lastCol, getColumn() + relCol + (spans ? dragObject.getColSpan(i) : 1) - 1);
     }
-    return new Rectangle(firstCol, firstRow, lastCol-firstCol+1, lastRow-firstRow+1);
+    return new Rectangle(firstCol, firstRow, lastCol - firstCol + 1, lastRow - firstRow + 1);
   }
 
   @Nullable
-  protected Rectangle getGridFeedbackRect(ComponentDragObject dragObject, final boolean ignoreWidth, final boolean ignoreHeight) {
-    Rectangle cellRect = getGridFeedbackCellRect(dragObject, ignoreWidth, ignoreHeight);
+  protected Rectangle getGridFeedbackRect(ComponentDragObject dragObject, boolean ignoreWidth, boolean ignoreHeight, boolean overlapping) {
+    Rectangle cellRect = getGridFeedbackCellRect(dragObject, ignoreWidth, ignoreHeight, overlapping);
     if (cellRect == null) return null;
     int h = ignoreHeight ? 0 : cellRect.height;
     int w = ignoreWidth ? 0 : cellRect.width;
@@ -202,6 +221,16 @@ public class GridDropLocation implements ComponentDropLocation {
 
       assert row + relativeRow >= 0;
       assert column + relativeCol >= 0;
+
+      if (rowSpan > 1 || colSpan > 1) {
+        if ((row + relativeRow + rowSpan > container.getGridRowCount() && rowSpan > 1) ||
+            (column + relativeCol + colSpan > container.getGridColumnCount() && colSpan > 1) ||
+            container.findComponentInRect(row + relativeRow, column + relativeCol, rowSpan, colSpan) != null) {
+          rowSpan = 1;
+          colSpan = 1;
+        }
+      }
+
       if (!container.getGridLayoutManager().isGridDefinedByComponents()) {
         assert relativeRow + rowSpan <= container.getGridRowCount();
         assert relativeCol + colSpan <= container.getGridColumnCount();
index 5f704f9b5f6d013a33dfa6fe42abbc5fbfaed2c4..41f0a32cfc65f2c432eabedb001a266eadb5227c 100644 (file)
@@ -107,7 +107,7 @@ public class GridInsertLocation extends GridDropLocation {
   }
 
   @Override public boolean canDrop(ComponentDragObject dragObject) {
-    Rectangle rc = getDragObjectDimensions(dragObject);
+    Rectangle rc = getDragObjectDimensions(dragObject, true);
     int size = isRowInsert() ? rc.width : rc.height;
     if (isInsertInsideComponent(size)) {
       LOG.debug("GridInsertLocation.canDrop()=false because insert inside component");
@@ -165,12 +165,12 @@ public class GridInsertLocation extends GridDropLocation {
     final int insertCol = getColumn();
     final int insertRow = getRow();
 
-    Rectangle feedbackRect = getGridFeedbackRect(dragObject, isColumnInsert(), isRowInsert());
+    Rectangle feedbackRect = getGridFeedbackRect(dragObject, isColumnInsert(), isRowInsert(), false);
     if (feedbackRect == null) {
       feedbackLayer.removeFeedback();
       return;
     }
-    Rectangle cellRect = getGridFeedbackCellRect(dragObject, isColumnInsert(), isRowInsert());
+    Rectangle cellRect = getGridFeedbackCellRect(dragObject, isColumnInsert(), isRowInsert(), false);
     assert cellRect != null;
 
     final RadAbstractGridLayoutManager layoutManager = getContainer().getGridLayoutManager();
@@ -185,15 +185,25 @@ public class GridInsertLocation extends GridDropLocation {
 
     Rectangle rcFeedback = null;
     if (dragObject.getComponentCount() == 1) {
-      int cellWidth = vGridLines [insertCol+1] - vGridLines [insertCol];
-      int cellHeight = hGridLines [insertRow+1] - hGridLines [insertRow];
+      int lastColIndex = insertCol + dragObject.getColSpan(0);
+      if (lastColIndex > vGridLines.length - 1) {
+        lastColIndex = insertCol + 1;
+      }
+      
+      int lastRowIndex = insertRow + dragObject.getRowSpan(0);
+      if (lastRowIndex > hGridLines.length - 1) {
+        lastRowIndex = insertRow + 1;
+      }
+      
+      int cellWidth = vGridLines [lastColIndex] - vGridLines [insertCol];
+      int cellHeight = hGridLines [lastRowIndex] - hGridLines [insertRow];
       RadComponent component = layoutManager.getComponentAtGrid(getContainer(), insertRow, insertCol);
       if (component != null) {
         Rectangle bounds = component.getBounds();
         bounds.translate(-vGridLines [insertCol], -hGridLines [insertRow]);
 
-        int spaceToRight = vGridLines [insertCol+1] - vGridLines [insertCol] - (bounds.x + bounds.width);
-        int spaceBelow = hGridLines [insertRow+1] - hGridLines [insertRow] - (bounds.y + bounds.height);
+        int spaceToRight = vGridLines [lastColIndex] - vGridLines [insertCol] - (bounds.x + bounds.width);
+        int spaceBelow = hGridLines [lastRowIndex] - hGridLines [insertRow] - (bounds.y + bounds.height);
         if (myMode == GridInsertMode.RowBefore && bounds.y > INSERT_RECT_MIN_SIZE) {
           rcFeedback = new Rectangle(0, 0, cellWidth, bounds.y);
         }
@@ -325,7 +335,8 @@ public class GridInsertLocation extends GridDropLocation {
 
     int cellsToInsert = 1;
     if (components.length > 0) {
-      Rectangle rc = getDragObjectDimensions(dragObject);
+      int cellSize = container.getGridCellCount(isRowInsert());
+      Rectangle rc = getDragObjectDimensions(dragObject, cell < cellSize - 1);
       int size = isRowInsert() ? rc.height : rc.width;
       if (size > 0) {
         cellsToInsert = size;