update copyright
[fedora-idea.git] / plugins / ui-designer / src / com / intellij / uiDesigner / designSurface / ResizeProcessor.java
blobfa2fb6ea69e63eb33382f0a3f44d01e722a42804
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.uiDesigner.CutCopyPasteSupport;
19 import com.intellij.uiDesigner.FormEditingUtil;
20 import com.intellij.uiDesigner.UIDesignerBundle;
21 import com.intellij.uiDesigner.core.GridConstraints;
22 import com.intellij.uiDesigner.core.Util;
23 import com.intellij.uiDesigner.radComponents.RadComponent;
24 import com.intellij.uiDesigner.radComponents.RadContainer;
25 import org.jetbrains.annotations.Nullable;
27 import javax.swing.*;
28 import java.awt.Cursor;
29 import java.awt.Dimension;
30 import java.awt.Point;
31 import java.awt.Rectangle;
32 import java.awt.event.KeyEvent;
33 import java.awt.event.MouseEvent;
34 import java.util.Collections;
35 import java.util.List;
37 /**
38 * @author Anton Katilin
39 * @author Vladimir Kondratyev
41 public final class ResizeProcessor extends EventProcessor {
42 private final RadComponent myComponent;
43 private final int myResizeMask;
44 private Point myLastPoint;
45 private Rectangle myBounds;
46 private Rectangle myOriginalBounds;
47 private final RadContainer myOriginalParent;
48 private final GuiEditor myEditor;
49 private final GridConstraints myOriginalConstraints;
50 private RadComponent myResizedCopy;
52 public ResizeProcessor(final GuiEditor editor, final RadComponent component, final int resizeMask){
53 myEditor = editor;
54 if (component.getParent() == null) {
55 throw new IllegalArgumentException("parent is null for " + component);
58 myComponent = component;
59 myOriginalParent = component.getParent();
60 myOriginalConstraints = component.getConstraints();
62 final List<RadComponent> copyList = CutCopyPasteSupport.copyComponents(editor, Collections.singletonList(component));
63 if (component.getParent().getLayoutManager().isGrid() && copyList != null) {
64 myComponent.setResizing(true);
65 Rectangle rc = SwingUtilities.convertRectangle(component.getParent().getDelegee(),
66 component.getBounds(),
67 myEditor.getDragLayer());
68 component.setDragging(true);
69 component.setSelected(false);
71 myResizedCopy = copyList.get(0);
72 myResizedCopy.setBounds(rc);
73 myResizedCopy.setSelected(true);
74 editor.getDragLayer().add(myResizedCopy.getDelegee());
76 myResizeMask = resizeMask;
78 setCursor(getResizeCursor());
81 protected void processKeyEvent(final KeyEvent e){}
83 protected void processMouseEvent(final MouseEvent e){
84 if (e.getID() == MouseEvent.MOUSE_PRESSED) {
85 myLastPoint = e.getPoint();
86 myBounds = myOriginalParent.getLayoutManager().isGrid() ? myResizedCopy.getBounds() : myComponent.getBounds();
87 myOriginalBounds = new Rectangle(myBounds);
89 else if(e.getID()==MouseEvent.MOUSE_DRAGGED){
90 final int dx = e.getX() - myLastPoint.x;
91 final int dy = e.getY() - myLastPoint.y;
93 if (myOriginalParent.getLayoutManager().isGrid()) {
94 final Point point = SwingUtilities.convertPoint(myEditor.getDragLayer(), e.getX(), e.getY(), myOriginalParent.getDelegee());
95 putGridSpanFeedback(point);
97 else if (myOriginalParent.isXY()) {
98 myEditor.getActiveDecorationLayer().removeFeedback();
99 setCursor(getResizeCursor());
101 else {
102 return;
105 final GridConstraints constraints = myComponent.getConstraints();
107 if ((myResizeMask & Painter.WEST_MASK) != 0) {
108 myBounds.x += dx;
109 myBounds.width -= dx;
111 if ((myResizeMask & Painter.EAST_MASK) != 0) {
112 myBounds.width += dx;
114 if ((myResizeMask & Painter.NORTH_MASK) != 0) {
115 myBounds.y += dy;
116 myBounds.height -= dy;
118 if ((myResizeMask & Painter.SOUTH_MASK) != 0) {
119 myBounds.height += dy;
122 final Dimension minSize = myComponent.getMinimumSize();
124 final Rectangle newBounds = myOriginalParent.getLayoutManager().isGrid() ? myResizedCopy.getBounds() : myComponent.getBounds();
126 // Component's bounds cannot be less the some minimum size
127 if (myBounds.width >= minSize.width) {
128 newBounds.x = myBounds.x;
129 newBounds.width = myBounds.width;
131 else {
132 if((myResizeMask & Painter.WEST_MASK) != 0){
133 newBounds.x = newBounds.x+newBounds.width-minSize.width;
134 newBounds.width = minSize.width;
136 else if ((myResizeMask & Painter.EAST_MASK) != 0) {
137 newBounds.width = minSize.width;
141 if (myBounds.height >= minSize.height) {
142 newBounds.y = myBounds.y;
143 newBounds.height = myBounds.height;
145 else {
146 if ((myResizeMask & Painter.NORTH_MASK) != 0) {
147 newBounds.y = newBounds.y + newBounds.height - minSize.height;
148 newBounds.height = minSize.height;
150 else if ((myResizeMask & Painter.SOUTH_MASK) != 0) {
151 newBounds.height = minSize.height;
155 final Dimension size = newBounds.getSize();
156 Util.adjustSize(myComponent.getDelegee(), constraints, size);
157 newBounds.width = size.width;
158 newBounds.height = size.height;
160 if (myOriginalParent.getLayoutManager().isGrid()) {
161 myResizedCopy.setBounds(newBounds);
163 else {
164 if (myEditor.ensureEditable()) {
165 myComponent.setBounds(newBounds);
169 myEditor.refresh();
171 myLastPoint=e.getPoint();
173 else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
174 boolean modified = false;
175 myComponent.getDelegee().setVisible(true);
176 myComponent.setResizing(false);
177 myComponent.setSelected(true);
178 if (myResizedCopy != null) {
179 myEditor.getDragLayer().remove(myResizedCopy.getDelegee());
181 if (myOriginalParent.getLayoutManager().isGrid() && myEditor.ensureEditable()) {
182 final Point point = SwingUtilities.convertPoint(myEditor.getDragLayer(), e.getX(), e.getY(), myOriginalParent.getDelegee());
183 Rectangle rcGrid = getGridSpanGridRect(myOriginalParent, myOriginalConstraints, point, myResizeMask);
184 if (rcGrid != null && isGridSpanDropAllowed(rcGrid)) {
185 GridConstraints oldConstraints = (GridConstraints) myOriginalConstraints.clone();
186 myOriginalConstraints.setColumn(rcGrid.x);
187 myOriginalConstraints.setRow(rcGrid.y);
188 myOriginalConstraints.setColSpan(rcGrid.width);
189 myOriginalConstraints.setRowSpan(rcGrid.height);
190 myComponent.fireConstraintsChanged(oldConstraints);
191 modified = true;
194 else {
195 modified = true;
197 myEditor.getActiveDecorationLayer().removeFeedback();
198 myComponent.setDragging(false);
199 if (modified) {
200 if (myEditor.ensureEditable()) {
201 myEditor.refreshAndSave(true);
207 private Cursor getResizeCursor() {
208 return Cursor.getPredefinedCursor(Painter.getResizeCursor(myResizeMask));
211 private void putGridSpanFeedback(final Point point) {
212 Rectangle rcGrid = getGridSpanGridRect(myOriginalParent, myOriginalConstraints, point, myResizeMask);
213 if (rcGrid != null) {
214 Rectangle rc = myOriginalParent.getGridLayoutManager().getGridCellRangeRect(myOriginalParent, rcGrid.y, rcGrid.x,
215 rcGrid.y+rcGrid.height-1, rcGrid.x+rcGrid.width-1);
216 String tooltip = UIDesignerBundle.message("resize.feedback", myComponent.getDisplayName(), rcGrid.height, rcGrid.width);
217 myEditor.getActiveDecorationLayer().putFeedback(myOriginalParent.getDelegee(), rc, tooltip);
218 setCursor(isGridSpanDropAllowed(rcGrid) ? getResizeCursor() : FormEditingUtil.getMoveNoDropCursor());
220 else {
221 setCursor(getResizeCursor());
222 myEditor.getActiveDecorationLayer().removeFeedback();
226 @Nullable
227 static Rectangle getGridSpanGridRect(final RadContainer grid,
228 final GridConstraints originalConstraints,
229 final Point point,
230 final int resizeMask) {
231 int rowAtMouse = (resizeMask & (Painter.NORTH_MASK | Painter.SOUTH_MASK)) != 0
232 ? grid.getGridRowAt(point.y)
233 : -1;
234 int colAtMouse = (resizeMask & (Painter.WEST_MASK | Painter.EAST_MASK)) != 0
235 ? grid.getGridColumnAt(point.x)
236 : -1;
237 if (rowAtMouse != -1 || colAtMouse != -1) {
238 final int origStartCol = originalConstraints.getColumn();
239 final int origEndCol = originalConstraints.getColumn() + originalConstraints.getColSpan() - 1;
240 int startCol = origStartCol;
241 int endCol = origEndCol;
242 if (colAtMouse >= 0) {
243 if ((resizeMask & Painter.WEST_MASK) != 0 && colAtMouse <= endCol) {
244 // resize to left
245 startCol = colAtMouse;
247 else if ((resizeMask & Painter.EAST_MASK) != 0 && colAtMouse >= startCol) {
248 endCol = colAtMouse;
252 final int origStartRow = originalConstraints.getRow();
253 final int origEndRow = originalConstraints.getRow() + originalConstraints.getRowSpan() - 1;
254 int startRow = origStartRow;
255 int endRow = origEndRow;
256 if (rowAtMouse >= 0) {
257 if ((resizeMask & Painter.NORTH_MASK) != 0 && rowAtMouse <= endRow) {
258 startRow = rowAtMouse;
260 else if ((resizeMask & Painter.SOUTH_MASK) != 0 && rowAtMouse >= startRow) {
261 endRow = rowAtMouse;
265 return new Rectangle(startCol, startRow, endCol-startCol+1, endRow-startRow+1);
267 return null;
270 protected boolean cancelOperation(){
271 myComponent.setBounds(myOriginalBounds);
272 myComponent.setResizing(false);
273 myComponent.setDragging(false);
274 if (myResizedCopy != null) {
275 myEditor.getDragLayer().remove(myResizedCopy.getDelegee());
276 myResizedCopy = null;
278 myEditor.refresh();
279 return true;
282 private boolean isGridSpanDropAllowed(final Rectangle rcGrid) {
283 return myOriginalParent.findComponentInRect(rcGrid.y, rcGrid.x, rcGrid.height, rcGrid.width) == null;