update copyright
[fedora-idea.git] / plugins / ui-designer / src / com / intellij / uiDesigner / actions / AbstractMoveSelectionAction.java
bloba5591f971730a075778e11388a5837f9ab207ece
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.uiDesigner.actions;
18 import com.intellij.openapi.actionSystem.AnAction;
19 import com.intellij.openapi.actionSystem.AnActionEvent;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.util.Ref;
22 import com.intellij.uiDesigner.FormEditingUtil;
23 import com.intellij.uiDesigner.designSurface.GuiEditor;
24 import com.intellij.uiDesigner.radComponents.RadAtomicComponent;
25 import com.intellij.uiDesigner.radComponents.RadComponent;
26 import com.intellij.uiDesigner.radComponents.RadContainer;
27 import org.jetbrains.annotations.NotNull;
29 import javax.swing.*;
30 import java.awt.Point;
31 import java.util.ArrayList;
33 /**
34 * @author Anton Katilin
35 * @author Vladimir Kondratyev
37 abstract class AbstractMoveSelectionAction extends AnAction{
38 private static final Logger LOG=Logger.getInstance("#com.intellij.uiDesigner.actions.MoveSelectionToRightAction");
40 private final GuiEditor myEditor;
41 private final boolean myExtend;
42 private final boolean myMoveToLast;
44 public AbstractMoveSelectionAction(@NotNull final GuiEditor editor, boolean extend, final boolean moveToLast) {
45 myEditor = editor;
46 myExtend = extend;
47 myMoveToLast = moveToLast;
50 public final void actionPerformed(final AnActionEvent e) {
51 final ArrayList<RadComponent> selectedComponents = FormEditingUtil.getSelectedComponents(myEditor);
52 final JComponent rootContainerDelegee = myEditor.getRootContainer().getDelegee();
53 if(selectedComponents.size() == 0){
54 moveToFirstComponent(rootContainerDelegee);
55 return;
57 RadComponent selectedComponent = myEditor.getSelectionLead();
58 if (selectedComponent == null || !selectedComponents.contains(selectedComponent)) {
59 selectedComponent = selectedComponents.get(0);
62 if (moveSelectionByGrid(selectedComponent) || myMoveToLast) {
63 return;
66 // 1. We need to get coordinates of all editor's component in the same
67 // coordinate system. For example, in the RadRootContainer rootContainerDelegee's coordinate system.
69 final ArrayList<RadComponent> components = new ArrayList<RadComponent>();
70 final ArrayList<Point> points = new ArrayList<Point>();
71 final RadComponent selectedComponent1 = selectedComponent;
72 FormEditingUtil.iterate(
73 myEditor.getRootContainer(),
74 new FormEditingUtil.ComponentVisitor<RadComponent>() {
75 public boolean visit(final RadComponent component) {
76 if (component instanceof RadAtomicComponent) {
77 if(selectedComponent1.equals(component)){
78 return true;
80 if (!FormEditingUtil.isComponentSwitchedInView(component)) {
81 return true;
83 components.add(component);
84 final JComponent _delegee = component.getDelegee();
85 final Point p = SwingUtilities.convertPoint(
86 _delegee,
87 new Point(0, 0),
88 rootContainerDelegee
90 p.x += _delegee.getWidth() / 2;
91 p.y += _delegee.getHeight() / 2;
92 points.add(p);
94 return true;
98 if(components.size() == 0){
99 return;
102 // 2.
103 final Point source = SwingUtilities.convertPoint(
104 selectedComponent.getDelegee(),
105 new Point(0, 0),
106 rootContainerDelegee
108 source.x += selectedComponent.getDelegee().getWidth() / 2;
109 source.y += selectedComponent.getDelegee().getHeight() / 2;
110 int min = Integer.MAX_VALUE;
111 int nextSelectedIndex = -1;
112 for(int i = points.size() - 1; i >= 0; i--){
113 final int distance = calcDistance(source, points.get(i));
114 if(distance < min){
115 min = distance;
116 nextSelectedIndex = i;
119 if(min == Integer.MAX_VALUE){
120 return;
123 LOG.assertTrue(nextSelectedIndex != -1);
124 final RadComponent component = components.get(nextSelectedIndex);
125 selectOrExtend(component);
128 private void selectOrExtend(final RadComponent component) {
129 if (myExtend) {
130 FormEditingUtil.selectComponent(myEditor, component);
132 else {
133 FormEditingUtil.selectSingleComponent(myEditor, component);
137 private void moveToFirstComponent(final JComponent rootContainerDelegee) {
138 final int[] minX = new int[]{Integer.MAX_VALUE};
139 final int[] minY = new int[]{Integer.MAX_VALUE};
140 final Ref<RadComponent> componentToBeSelected = new Ref<RadComponent>();
141 FormEditingUtil.iterate(
142 myEditor.getRootContainer(),
143 new FormEditingUtil.ComponentVisitor<RadComponent>() {
144 public boolean visit(final RadComponent component) {
145 if (component instanceof RadAtomicComponent) {
146 final JComponent _delegee = component.getDelegee();
147 final Point p = SwingUtilities.convertPoint(
148 _delegee,
149 new Point(0, 0),
150 rootContainerDelegee
152 if(minX[0] > p.x || minY[0] > p.y){
153 minX[0] = p.x;
154 minY[0] = p.y;
155 componentToBeSelected.set(component);
158 return true;
162 if(!componentToBeSelected.isNull()){
163 FormEditingUtil.selectComponent(myEditor, componentToBeSelected.get());
167 @Override
168 public void update(AnActionEvent e) {
169 e.getPresentation().setEnabled(!myEditor.getMainProcessor().isProcessorActive());
172 private boolean moveSelectionByGrid(final RadComponent selectedComponent) {
173 final RadContainer parent = selectedComponent.getParent();
174 if (parent == null || !parent.getLayoutManager().isGrid()) {
175 return false;
178 int row = selectedComponent.getConstraints().getRow();
179 int column = selectedComponent.getConstraints().getColumn();
181 RadComponent lastComponent = null;
182 do {
183 row += getRowMoveDelta();
184 column += getColumnMoveDelta();
185 if (row < 0 || row >= parent.getGridRowCount() || column < 0 || column >= parent.getGridColumnCount()) {
186 if (myMoveToLast) {
187 break;
189 return false;
192 final RadComponent component = parent.getComponentAtGrid(row, column);
193 if (component != null && component != selectedComponent) {
194 if (myMoveToLast) {
195 if (myExtend) {
196 FormEditingUtil.selectComponent(myEditor, component);
198 lastComponent = component;
200 else {
201 selectOrExtend(component);
202 return true;
205 } while(true);
207 if (lastComponent != null) {
208 selectOrExtend(lastComponent);
209 return true;
211 return false;
214 protected abstract int calcDistance(Point source, Point point);
216 protected int getColumnMoveDelta() {
217 return 0;
220 protected int getRowMoveDelta() {
221 return 0;