blob: 19311166481eb727612498581fd4eddea1ec1865 [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.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;
}
}