| /* |
| * 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); |
| } |
| } |
| } |