/* * 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.radComponents; import com.intellij.uiDesigner.core.GridConstraints; import com.intellij.uiDesigner.designSurface.*; import org.intellij.lang.annotations.JdkConstants; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; /** * @author yole */ public class FlowDropLocation implements ComponentDropLocation { private int myInsertIndex; private final String myInsertBeforeId; private final RadContainer myContainer; private final int myAlignment; private final int myHGap; private final int myVGap; public FlowDropLocation(RadContainer container, Point location, @JdkConstants.FlowLayoutAlignment int alignment, int hGap, int vGap) { myContainer = container; myAlignment = alignment; myHGap = hGap; myVGap = vGap; myInsertIndex = myContainer.getComponentCount(); if (location != null) { for(int i=0; i<myContainer.getComponentCount(); i++) { Rectangle bounds = myContainer.getComponent(i).getBounds(); bounds.grow(myHGap, vGap); if (bounds.contains(location)) { if (location.x < bounds.getCenterX()) { myInsertIndex = i; } else { myInsertIndex = i+1; } break; } else if (i == 0 && location.x < bounds.x) { myInsertIndex = 0; } } } if (myInsertIndex < myContainer.getComponentCount()) { myInsertBeforeId = myContainer.getComponent(myInsertIndex).getId(); } else { myInsertBeforeId = null; } } public RadContainer getContainer() { return myContainer; } public boolean canDrop(ComponentDragObject dragObject) { return true; } public void placeFeedback(FeedbackLayer feedbackLayer, ComponentDragObject dragObject) { if (myContainer.getComponentCount() == 0) { Dimension initialSize = dragObject.getInitialSize(getContainer()); int originX; if (myAlignment == FlowLayout.CENTER) { originX = myContainer.getSize().width / 2 - initialSize.width / 2 - myHGap; } else if (isRightAlign()) { originX = myContainer.getSize().width - initialSize.width - 2 * myHGap; } else { originX = 2 * myHGap; } int height = Math.min(initialSize.height, myContainer.getBounds().height); Rectangle rc = new Rectangle(originX, 2 * myVGap, initialSize.width, height); feedbackLayer.putFeedback(myContainer.getDelegee(), rc, myContainer.getDisplayName()); } else if ((myInsertIndex == myContainer.getComponentCount() && !isRightAlign()) || (myInsertIndex == 0 && !isLeftAlign())) { Dimension initialSize = dragObject.getInitialSize(getContainer()); JComponent component = myContainer.getDelegee(); int minX = component.getComponent(0).getBounds().x; int maxX = 0; int maxSize = 0; int lastTop = myContainer.getDelegee().getInsets().top; for(Component child: component.getComponents()) { int childX = child.getBounds().x + child.getBounds().width; if (childX > maxX) maxX = childX; maxSize = Math.max(maxSize, child.getBounds().height); lastTop = child.getBounds().y; } maxSize = Math.max(maxSize, initialSize.height); maxSize = Math.min(maxSize, myContainer.getBounds().height); final Rectangle rc; if (myInsertIndex == 0) { rc = new Rectangle(minX - myHGap - initialSize.width, lastTop, initialSize.width, maxSize); } else { int initialWidth = Math.max(8, Math.min(initialSize.width, myContainer.getBounds().width - maxX)); rc = new Rectangle(maxX, lastTop, initialWidth, maxSize); } feedbackLayer.putFeedback(myContainer.getDelegee(), rc, myContainer.getDisplayName()); } else if (myInsertIndex == myContainer.getComponentCount() && isRightAlign()) { Rectangle bounds = myContainer.getComponent(myInsertIndex-1).getBounds(); Rectangle rc = new Rectangle(bounds.x+bounds.width, bounds.y, 8, bounds.height); feedbackLayer.putFeedback(myContainer.getDelegee(), rc, VertInsertFeedbackPainter.INSTANCE, myContainer.getDisplayName()); } else { Rectangle bounds = myContainer.getComponent(myInsertIndex).getBounds(); Rectangle rc = new Rectangle(bounds.x-4-myHGap, bounds.y, 8, bounds.height); feedbackLayer.putFeedback(myContainer.getDelegee(), rc, VertInsertFeedbackPainter.INSTANCE, myContainer.getDisplayName()); } } private boolean isLeftAlign() { return myAlignment == FlowLayout.LEFT || myAlignment == FlowLayout.LEADING; } private boolean isRightAlign() { return myAlignment == FlowLayout.RIGHT || myAlignment == FlowLayout.TRAILING; } public void processDrop(GuiEditor editor, RadComponent[] components, GridConstraints[] constraintsToAdjust, ComponentDragObject dragObject) { for(int i=0; i<myContainer.getComponentCount(); i++) { if (myContainer.getComponent(i).getId().equals(myInsertBeforeId)) { myInsertIndex = i; break; } } if (myInsertIndex > myContainer.getComponentCount()) { myInsertIndex = myContainer.getComponentCount(); } for(RadComponent component: components) { myContainer.addComponent(component, myInsertIndex); myInsertIndex++; } } @Nullable public ComponentDropLocation getAdjacentLocation(Direction direction) { return null; } }