2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.uiDesigner
.designSurface
;
18 import com
.intellij
.openapi
.diagnostic
.Logger
;
19 import com
.intellij
.uiDesigner
.core
.GridConstraints
;
20 import com
.intellij
.uiDesigner
.radComponents
.RadComponent
;
21 import com
.intellij
.uiDesigner
.radComponents
.RadContainer
;
22 import com
.intellij
.uiDesigner
.shared
.XYLayoutManager
;
23 import org
.jetbrains
.annotations
.NonNls
;
24 import org
.jetbrains
.annotations
.Nullable
;
25 import org
.jetbrains
.annotations
.NotNull
;
28 import java
.awt
.Rectangle
;
29 import java
.awt
.LayoutManager
;
34 public class GridDropLocation
implements ComponentDropLocation
{
35 private static final Logger LOG
= Logger
.getInstance("#com.intellij.uiDesigner.designSurface.GridDropLocation");
37 protected final RadContainer myContainer
;
39 protected int myColumn
;
41 public GridDropLocation(@NotNull final RadContainer container
, final int row
, final int column
) {
42 myContainer
= container
;
51 public int getColumn() {
55 public RadContainer
getContainer() {
59 public boolean canDrop(final ComponentDragObject dragObject
) {
60 // If target point doesn't belong to any cell and column then do not allow drop.
61 if (myRow
== -1 || myColumn
== -1) {
62 LOG
.debug("RadContainer.canDrop=false because no cell at mouse position");
66 for(int i
=0; i
<dragObject
.getComponentCount(); i
++) {
67 int relativeCol
= dragObject
.getRelativeCol(i
);
68 int relativeRow
= dragObject
.getRelativeRow(i
);
69 int colSpan
= dragObject
.getColSpan(i
);
70 int rowSpan
= dragObject
.getRowSpan(i
);
72 LOG
.debug("checking component: relativeRow" + relativeRow
+ ", relativeCol" + relativeCol
+ ", colSpan=" + colSpan
+ ", rowSpan=" + rowSpan
);
74 if (myRow
+ relativeRow
< 0 ||
75 myColumn
+ relativeCol
< 0 ||
76 myRow
+ relativeRow
+ rowSpan
> myContainer
.getGridRowCount() ||
77 myColumn
+ relativeCol
+ colSpan
> myContainer
.getGridColumnCount()) {
78 LOG
.debug("RadContainer.canDrop=false because range is outside grid: row=" + (myRow
+relativeRow
) +
79 ", col=" + (myColumn
+relativeCol
) + ", colSpan=" + colSpan
+ ", rowSpan=" + rowSpan
);
83 final RadComponent componentInRect
= findOverlappingComponent(myRow
+ relativeRow
, myColumn
+ relativeCol
, rowSpan
, colSpan
);
84 if (componentInRect
!= null) {
85 LOG
.debug("GridDropLocation.canDrop=false because found component " + componentInRect
.getId() +
86 " in rect (row=" + (myRow
+relativeRow
) + ", col=" + (myColumn
+relativeCol
) +
87 ", rowSpan=" + rowSpan
+ ", colSpan=" + colSpan
+ ")");
91 LOG
.debug("canDrop=true");
95 protected RadComponent
findOverlappingComponent(final int startRow
, final int startCol
, final int rowSpan
, final int colSpan
) {
96 return myContainer
.findComponentInRect(startRow
, startCol
, rowSpan
, colSpan
);
99 public void placeFeedback(FeedbackLayer feedbackLayer
, ComponentDragObject dragObject
) {
100 Rectangle feedbackRect
= null;
101 if (getContainer().getLayoutManager().isGrid()) {
102 feedbackRect
= getGridFeedbackRect(dragObject
, false, false);
104 if (feedbackRect
!= null) {
105 final JComponent component
= getContainer().getDelegee();
106 StringBuilder feedbackBuilder
= new StringBuilder(getContainer().getDisplayName());
107 feedbackBuilder
.append(" (").append(myRow
+ getContainer().getGridLayoutManager().getCellIndexBase());
108 feedbackBuilder
.append(", ").append(myColumn
+ getContainer().getGridLayoutManager().getCellIndexBase());
109 feedbackBuilder
.append(")");
110 feedbackLayer
.putFeedback(component
, feedbackRect
, feedbackBuilder
.toString());
113 feedbackLayer
.removeFeedback();
118 protected Rectangle
getGridFeedbackCellRect(ComponentDragObject dragObject
, final boolean ignoreWidth
, final boolean ignoreHeight
) {
119 if (dragObject
.getComponentCount() == 0) {
120 LOG
.debug("no feedback rect because component count=0");
124 Rectangle rc
= getDragObjectDimensions(dragObject
);
125 int w
= ignoreWidth ?
1 : rc
.width
;
126 int h
= ignoreHeight ?
1 : rc
.height
;
128 if (rc
.x
< 0 || rc
.y
< 0 ||
129 rc
.y
+ h
> getContainer().getGridRowCount() || rc
.x
+ w
> getContainer().getGridColumnCount()) {
130 LOG
.debug("no feedback rect because insert range is outside grid: firstRow=" + rc
.y
+
131 ", firstCol=" + rc
.x
+ ", lastRow=" + (rc
.y
+h
-1) + ", lastCol=" + (rc
.x
+w
-1));
134 return new Rectangle(rc
.x
, rc
.y
, w
-1, h
-1);
137 protected Rectangle
getDragObjectDimensions(final ComponentDragObject dragObject
) {
138 int firstRow
= getRow();
139 int lastRow
= getRow();
140 int firstCol
= getColumn();
141 int lastCol
= getColumn();
142 for(int i
=0; i
<dragObject
.getComponentCount(); i
++) {
143 final int relRow
= dragObject
.getRelativeRow(i
);
144 final int relCol
= dragObject
.getRelativeCol(i
);
145 firstRow
= Math
.min(firstRow
, getRow() + relRow
);
146 firstCol
= Math
.min(firstCol
, getColumn() + relCol
);
147 lastRow
= Math
.max(lastRow
, getRow() + relRow
+ dragObject
.getRowSpan(i
) - 1);
148 lastCol
= Math
.max(lastCol
, getColumn() + relCol
+ dragObject
.getColSpan(i
) - 1);
150 return new Rectangle(firstCol
, firstRow
, lastCol
-firstCol
+1, lastRow
-firstRow
+1);
154 protected Rectangle
getGridFeedbackRect(ComponentDragObject dragObject
, final boolean ignoreWidth
, final boolean ignoreHeight
) {
155 Rectangle cellRect
= getGridFeedbackCellRect(dragObject
, ignoreWidth
, ignoreHeight
);
156 if (cellRect
== null) return null;
157 int h
= ignoreHeight ?
0 : cellRect
.height
;
158 int w
= ignoreWidth ?
0 : cellRect
.width
;
159 return getContainer().getGridLayoutManager().getGridCellRangeRect(getContainer(), cellRect
.y
, cellRect
.x
,
160 cellRect
.y
+h
, cellRect
.x
+w
);
163 public void processDrop(final GuiEditor editor
,
164 final RadComponent
[] components
,
165 final GridConstraints
[] constraintsToAdjust
,
166 final ComponentDragObject dragObject
) {
167 dropIntoGrid(myContainer
, components
, myRow
, myColumn
, dragObject
);
171 public ComponentDropLocation
getAdjacentLocation(Direction direction
) {
173 case LEFT
: return new GridInsertLocation(myContainer
, myRow
, myColumn
, GridInsertMode
.ColumnBefore
);
174 case UP
: return new GridInsertLocation(myContainer
, myRow
, myColumn
, GridInsertMode
.RowBefore
);
175 case RIGHT
: return new GridInsertLocation(myContainer
, myRow
, myColumn
, GridInsertMode
.ColumnAfter
);
176 case DOWN
: return new GridInsertLocation(myContainer
, myRow
, myColumn
, GridInsertMode
.RowAfter
);
181 @NonNls @Override public String
toString() {
182 return "GridDropLocation(row=" + myRow
+ ",col=" + myColumn
+ ")";
185 protected static void dropIntoGrid(final RadContainer container
, final RadComponent
[] components
, int row
, int column
, final ComponentDragObject dragObject
) {
186 assert components
.length
> 0;
188 for(int i
=0; i
<components
.length
; i
++) {
189 RadComponent c
= components
[i
];
190 if (c
instanceof RadContainer
) {
191 final LayoutManager layout
= ((RadContainer
)c
).getLayout();
192 if (layout
instanceof XYLayoutManager
) {
193 ((XYLayoutManager
)layout
).setPreferredSize(c
.getSize());
197 int relativeCol
= dragObject
.getRelativeCol(i
);
198 int relativeRow
= dragObject
.getRelativeRow(i
);
199 LOG
.debug("dropIntoGrid: relativeRow=" + relativeRow
+ ", relativeCol=" + relativeCol
);
200 int colSpan
= dragObject
.getColSpan(i
);
201 int rowSpan
= dragObject
.getRowSpan(i
);
203 assert row
+ relativeRow
>= 0;
204 assert column
+ relativeCol
>= 0;
205 if (!container
.getGridLayoutManager().isGridDefinedByComponents()) {
206 assert relativeRow
+ rowSpan
<= container
.getGridRowCount();
207 assert relativeCol
+ colSpan
<= container
.getGridColumnCount();
210 RadComponent old
= container
.findComponentInRect(row
+ relativeRow
, column
+ relativeCol
, rowSpan
, colSpan
);
212 LOG
.assertTrue(false,
213 "Drop rectangle not empty: (" + (row
+ relativeRow
) + ", " + (column
+ relativeCol
)
214 + ", " + rowSpan
+ ", " + colSpan
+ "), component ID=" + old
.getId());
217 final GridConstraints constraints
= c
.getConstraints();
218 constraints
.setRow(row
+ relativeRow
);
219 constraints
.setColumn(column
+ relativeCol
);
220 constraints
.setRowSpan(rowSpan
);
221 constraints
.setColSpan(colSpan
);
222 container
.addComponent(c
);
228 container
.revalidate();