blob: 66e5bc950782a36b27e3aedc2eee573b9add4d97 [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.radComponents.RadComponent;
import com.intellij.uiDesigner.radComponents.RadContainer;
import com.intellij.uiDesigner.radComponents.RadRootContainer;
import com.intellij.uiDesigner.FormEditingUtil;
import com.intellij.uiDesigner.core.GridConstraints;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class GroupSelectionProcessor extends EventProcessor {
private final GuiEditor myEditor;
private final RadComponent myComponent;
private Point myStartPoint;
private final MyRectanglePainter myRectangePainter;
/**
* @param component group where drag is started. This group should not be selected
* after drag is complete.
*/
public GroupSelectionProcessor(final GuiEditor editor, final RadComponent component) {
myEditor = editor;
myComponent = component;
myRectangePainter=new MyRectanglePainter();
}
protected void processKeyEvent(final KeyEvent e){
}
protected void processMouseEvent(final MouseEvent e){
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
myStartPoint = e.getPoint();
myEditor.getDragLayer().add(myRectangePainter);
}
else if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
final Rectangle rectangle = getRectangle(e);
myRectangePainter.setBounds(rectangle);
myEditor.getDragLayer().repaint();
}
else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
final Rectangle rectangle = getRectangle(e);
if (e.isShiftDown() && rectangle.width <= 3 && rectangle.height <= 3) {
RadComponent component = FormEditingUtil.getRadComponentAt(myEditor.getRootContainer(), e.getX(), e.getY());
if (component != null) {
RadComponent anchor = myEditor.getSelectionAnchor();
if (anchor == null || anchor.getParent() != component.getParent() || anchor.getParent() == null || !anchor.getParent().getLayoutManager().isGrid()) {
component.setSelected(!component.isSelected());
}
else {
selectComponentsInRange(component, anchor);
myEditor.setSelectionLead(component);
}
}
}
markRectangle(myEditor.getRootContainer(), rectangle, e.getComponent());
final JComponent dragLayer = myEditor.getDragLayer();
dragLayer.remove(myRectangePainter);
dragLayer.repaint();
myStartPoint = null;
}
}
private static void selectComponentsInRange(final RadComponent component, final RadComponent anchor) {
final GridConstraints c1 = component.getConstraints();
final GridConstraints c2 = anchor.getConstraints();
int startRow = Math.min(c1.getRow(), c2.getRow());
int startCol = Math.min(c1.getColumn(), c2.getColumn());
int endRow = Math.max(c1.getRow() + c1.getRowSpan(), c2.getRow() + c2.getRowSpan());
int endCol = Math.max(c1.getColumn() + c1.getColSpan(), c2.getColumn() + c2.getColSpan());
for(int row=startRow; row<endRow; row++) {
for(int col=startCol; col<endCol; col++) {
RadComponent c = anchor.getParent().getComponentAtGrid(row, col);
if (c != null) {
c.setSelected(true);
}
}
}
}
protected boolean cancelOperation() {
final JComponent dragLayer = myEditor.getDragLayer();
dragLayer.remove(myRectangePainter);
dragLayer.repaint();
return true;
}
private Rectangle getRectangle(final MouseEvent e){
final int x = Math.min(myStartPoint.x, e.getX());
final int y = Math.min(myStartPoint.y, e.getY());
final int width = Math.abs(myStartPoint.x - e.getX());
final int height = Math.abs(myStartPoint.y - e.getY());
return new Rectangle(x, y, width, height);
}
private void markRectangle(
final RadComponent component,
final Rectangle rectangle,
final Component coordinateOriginComponent
){
if (!(component instanceof RadRootContainer) && !component.equals(myComponent)) {
final Rectangle bounds = component.getBounds();
final Point point = SwingUtilities.convertPoint(component.getDelegee().getParent(), bounds.x, bounds.y, coordinateOriginComponent);
bounds.setLocation(point);
if(rectangle.intersects(bounds)){
component.setSelected(true);
return;
}
}
if (component instanceof RadContainer){
final RadContainer container = (RadContainer)component;
// [anton] it is very important to iterate through a STORED array because setSelected can
// change order of components so iteration via getComponent(i) is incorrect
final RadComponent[] components = container.getComponents();
for (RadComponent component1 : components) {
markRectangle(component1, rectangle, coordinateOriginComponent);
}
}
}
private static final class MyRectanglePainter extends JComponent{
private final AlphaComposite myComposite1;
private final AlphaComposite myComposite2;
private final Color myColor;
public MyRectanglePainter() {
myComposite1 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3f);
myComposite2 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.6f);
myColor = new Color(47, 67, 96);
}
protected void paintComponent(final Graphics g){
final Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g);
final Composite oldComposite = g2d.getComposite();
final Color oldColor = g2d.getColor();
g2d.setColor(myColor);
g2d.setComposite(myComposite1);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setComposite(myComposite2);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.setColor(oldColor);
g2d.setComposite(oldComposite);
}
}
}