update copyright
[fedora-idea.git] / plugins / ui-designer / src / com / intellij / uiDesigner / designSurface / GridDropLocation.java
blobc66cae060f30fee06742f538fc300f4bbc6cc973
1 /*
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;
27 import javax.swing.*;
28 import java.awt.Rectangle;
29 import java.awt.LayoutManager;
31 /**
32 * @author yole
34 public class GridDropLocation implements ComponentDropLocation {
35 private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.designSurface.GridDropLocation");
37 protected final RadContainer myContainer;
38 protected int myRow;
39 protected int myColumn;
41 public GridDropLocation(@NotNull final RadContainer container, final int row, final int column) {
42 myContainer = container;
43 myRow = row;
44 myColumn = column;
47 public int getRow() {
48 return myRow;
51 public int getColumn() {
52 return myColumn;
55 public RadContainer getContainer() {
56 return myContainer;
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");
63 return false;
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);
80 return false;
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 + ")");
88 return false;
91 LOG.debug("canDrop=true");
92 return 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());
112 else {
113 feedbackLayer.removeFeedback();
117 @Nullable
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");
121 return null;
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));
132 return null;
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);
153 @Nullable
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);
170 @Nullable
171 public ComponentDropLocation getAdjacentLocation(Direction direction) {
172 switch(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);
178 return null;
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);
211 if (old != null) {
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);
224 // Fill DropInfo
225 c.revalidate();
228 container.revalidate();