blob: fa2fb6ea69e63eb33382f0a3f44d01e722a42804 [file] [log] [blame]
/*
* Copyright 2000-2009 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.CutCopyPasteSupport;
import com.intellij.uiDesigner.FormEditingUtil;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.Util;
import com.intellij.uiDesigner.radComponents.RadComponent;
import com.intellij.uiDesigner.radComponents.RadContainer;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.List;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class ResizeProcessor extends EventProcessor {
private final RadComponent myComponent;
private final int myResizeMask;
private Point myLastPoint;
private Rectangle myBounds;
private Rectangle myOriginalBounds;
private final RadContainer myOriginalParent;
private final GuiEditor myEditor;
private final GridConstraints myOriginalConstraints;
private RadComponent myResizedCopy;
public ResizeProcessor(final GuiEditor editor, final RadComponent component, final int resizeMask){
myEditor = editor;
if (component.getParent() == null) {
throw new IllegalArgumentException("parent is null for " + component);
}
myComponent = component;
myOriginalParent = component.getParent();
myOriginalConstraints = component.getConstraints();
final List<RadComponent> copyList = CutCopyPasteSupport.copyComponents(editor, Collections.singletonList(component));
if (component.getParent().getLayoutManager().isGrid() && copyList != null) {
myComponent.setResizing(true);
Rectangle rc = SwingUtilities.convertRectangle(component.getParent().getDelegee(),
component.getBounds(),
myEditor.getDragLayer());
component.setDragging(true);
component.setSelected(false);
myResizedCopy = copyList.get(0);
myResizedCopy.setBounds(rc);
myResizedCopy.setSelected(true);
editor.getDragLayer().add(myResizedCopy.getDelegee());
}
myResizeMask = resizeMask;
setCursor(getResizeCursor());
}
protected void processKeyEvent(final KeyEvent e){}
protected void processMouseEvent(final MouseEvent e){
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
myLastPoint = e.getPoint();
myBounds = myOriginalParent.getLayoutManager().isGrid() ? myResizedCopy.getBounds() : myComponent.getBounds();
myOriginalBounds = new Rectangle(myBounds);
}
else if(e.getID()==MouseEvent.MOUSE_DRAGGED){
final int dx = e.getX() - myLastPoint.x;
final int dy = e.getY() - myLastPoint.y;
if (myOriginalParent.getLayoutManager().isGrid()) {
final Point point = SwingUtilities.convertPoint(myEditor.getDragLayer(), e.getX(), e.getY(), myOriginalParent.getDelegee());
putGridSpanFeedback(point);
}
else if (myOriginalParent.isXY()) {
myEditor.getActiveDecorationLayer().removeFeedback();
setCursor(getResizeCursor());
}
else {
return;
}
final GridConstraints constraints = myComponent.getConstraints();
if ((myResizeMask & Painter.WEST_MASK) != 0) {
myBounds.x += dx;
myBounds.width -= dx;
}
if ((myResizeMask & Painter.EAST_MASK) != 0) {
myBounds.width += dx;
}
if ((myResizeMask & Painter.NORTH_MASK) != 0) {
myBounds.y += dy;
myBounds.height -= dy;
}
if ((myResizeMask & Painter.SOUTH_MASK) != 0) {
myBounds.height += dy;
}
final Dimension minSize = myComponent.getMinimumSize();
final Rectangle newBounds = myOriginalParent.getLayoutManager().isGrid() ? myResizedCopy.getBounds() : myComponent.getBounds();
// Component's bounds cannot be less the some minimum size
if (myBounds.width >= minSize.width) {
newBounds.x = myBounds.x;
newBounds.width = myBounds.width;
}
else {
if((myResizeMask & Painter.WEST_MASK) != 0){
newBounds.x = newBounds.x+newBounds.width-minSize.width;
newBounds.width = minSize.width;
}
else if ((myResizeMask & Painter.EAST_MASK) != 0) {
newBounds.width = minSize.width;
}
}
if (myBounds.height >= minSize.height) {
newBounds.y = myBounds.y;
newBounds.height = myBounds.height;
}
else {
if ((myResizeMask & Painter.NORTH_MASK) != 0) {
newBounds.y = newBounds.y + newBounds.height - minSize.height;
newBounds.height = minSize.height;
}
else if ((myResizeMask & Painter.SOUTH_MASK) != 0) {
newBounds.height = minSize.height;
}
}
final Dimension size = newBounds.getSize();
Util.adjustSize(myComponent.getDelegee(), constraints, size);
newBounds.width = size.width;
newBounds.height = size.height;
if (myOriginalParent.getLayoutManager().isGrid()) {
myResizedCopy.setBounds(newBounds);
}
else {
if (myEditor.ensureEditable()) {
myComponent.setBounds(newBounds);
}
}
myEditor.refresh();
myLastPoint=e.getPoint();
}
else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
boolean modified = false;
myComponent.getDelegee().setVisible(true);
myComponent.setResizing(false);
myComponent.setSelected(true);
if (myResizedCopy != null) {
myEditor.getDragLayer().remove(myResizedCopy.getDelegee());
}
if (myOriginalParent.getLayoutManager().isGrid() && myEditor.ensureEditable()) {
final Point point = SwingUtilities.convertPoint(myEditor.getDragLayer(), e.getX(), e.getY(), myOriginalParent.getDelegee());
Rectangle rcGrid = getGridSpanGridRect(myOriginalParent, myOriginalConstraints, point, myResizeMask);
if (rcGrid != null && isGridSpanDropAllowed(rcGrid)) {
GridConstraints oldConstraints = (GridConstraints) myOriginalConstraints.clone();
myOriginalConstraints.setColumn(rcGrid.x);
myOriginalConstraints.setRow(rcGrid.y);
myOriginalConstraints.setColSpan(rcGrid.width);
myOriginalConstraints.setRowSpan(rcGrid.height);
myComponent.fireConstraintsChanged(oldConstraints);
modified = true;
}
}
else {
modified = true;
}
myEditor.getActiveDecorationLayer().removeFeedback();
myComponent.setDragging(false);
if (modified) {
if (myEditor.ensureEditable()) {
myEditor.refreshAndSave(true);
}
}
}
}
private Cursor getResizeCursor() {
return Cursor.getPredefinedCursor(Painter.getResizeCursor(myResizeMask));
}
private void putGridSpanFeedback(final Point point) {
Rectangle rcGrid = getGridSpanGridRect(myOriginalParent, myOriginalConstraints, point, myResizeMask);
if (rcGrid != null) {
Rectangle rc = myOriginalParent.getGridLayoutManager().getGridCellRangeRect(myOriginalParent, rcGrid.y, rcGrid.x,
rcGrid.y+rcGrid.height-1, rcGrid.x+rcGrid.width-1);
String tooltip = UIDesignerBundle.message("resize.feedback", myComponent.getDisplayName(), rcGrid.height, rcGrid.width);
myEditor.getActiveDecorationLayer().putFeedback(myOriginalParent.getDelegee(), rc, tooltip);
setCursor(isGridSpanDropAllowed(rcGrid) ? getResizeCursor() : FormEditingUtil.getMoveNoDropCursor());
}
else {
setCursor(getResizeCursor());
myEditor.getActiveDecorationLayer().removeFeedback();
}
}
@Nullable
static Rectangle getGridSpanGridRect(final RadContainer grid,
final GridConstraints originalConstraints,
final Point point,
final int resizeMask) {
int rowAtMouse = (resizeMask & (Painter.NORTH_MASK | Painter.SOUTH_MASK)) != 0
? grid.getGridRowAt(point.y)
: -1;
int colAtMouse = (resizeMask & (Painter.WEST_MASK | Painter.EAST_MASK)) != 0
? grid.getGridColumnAt(point.x)
: -1;
if (rowAtMouse != -1 || colAtMouse != -1) {
final int origStartCol = originalConstraints.getColumn();
final int origEndCol = originalConstraints.getColumn() + originalConstraints.getColSpan() - 1;
int startCol = origStartCol;
int endCol = origEndCol;
if (colAtMouse >= 0) {
if ((resizeMask & Painter.WEST_MASK) != 0 && colAtMouse <= endCol) {
// resize to left
startCol = colAtMouse;
}
else if ((resizeMask & Painter.EAST_MASK) != 0 && colAtMouse >= startCol) {
endCol = colAtMouse;
}
}
final int origStartRow = originalConstraints.getRow();
final int origEndRow = originalConstraints.getRow() + originalConstraints.getRowSpan() - 1;
int startRow = origStartRow;
int endRow = origEndRow;
if (rowAtMouse >= 0) {
if ((resizeMask & Painter.NORTH_MASK) != 0 && rowAtMouse <= endRow) {
startRow = rowAtMouse;
}
else if ((resizeMask & Painter.SOUTH_MASK) != 0 && rowAtMouse >= startRow) {
endRow = rowAtMouse;
}
}
return new Rectangle(startCol, startRow, endCol-startCol+1, endRow-startRow+1);
}
return null;
}
protected boolean cancelOperation(){
myComponent.setBounds(myOriginalBounds);
myComponent.setResizing(false);
myComponent.setDragging(false);
if (myResizedCopy != null) {
myEditor.getDragLayer().remove(myResizedCopy.getDelegee());
myResizedCopy = null;
}
myEditor.refresh();
return true;
}
private boolean isGridSpanDropAllowed(final Rectangle rcGrid) {
return myOriginalParent.findComponentInRect(rcGrid.y, rcGrid.x, rcGrid.height, rcGrid.width) == null;
}
}