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
;
30 import java
.awt
.Point
;
31 import java
.util
.ArrayList
;
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
) {
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
);
57 RadComponent selectedComponent
= myEditor
.getSelectionLead();
58 if (selectedComponent
== null || !selectedComponents
.contains(selectedComponent
)) {
59 selectedComponent
= selectedComponents
.get(0);
62 if (moveSelectionByGrid(selectedComponent
) || myMoveToLast
) {
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
)){
80 if (!FormEditingUtil
.isComponentSwitchedInView(component
)) {
83 components
.add(component
);
84 final JComponent _delegee
= component
.getDelegee();
85 final Point p
= SwingUtilities
.convertPoint(
90 p
.x
+= _delegee
.getWidth() / 2;
91 p
.y
+= _delegee
.getHeight() / 2;
98 if(components
.size() == 0){
103 final Point source
= SwingUtilities
.convertPoint(
104 selectedComponent
.getDelegee(),
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
));
116 nextSelectedIndex
= i
;
119 if(min
== Integer
.MAX_VALUE
){
123 LOG
.assertTrue(nextSelectedIndex
!= -1);
124 final RadComponent component
= components
.get(nextSelectedIndex
);
125 selectOrExtend(component
);
128 private void selectOrExtend(final RadComponent component
) {
130 FormEditingUtil
.selectComponent(myEditor
, component
);
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(
152 if(minX
[0] > p
.x
|| minY
[0] > p
.y
){
155 componentToBeSelected
.set(component
);
162 if(!componentToBeSelected
.isNull()){
163 FormEditingUtil
.selectComponent(myEditor
, componentToBeSelected
.get());
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()) {
178 int row
= selectedComponent
.getConstraints().getRow();
179 int column
= selectedComponent
.getConstraints().getColumn();
181 RadComponent lastComponent
= null;
183 row
+= getRowMoveDelta();
184 column
+= getColumnMoveDelta();
185 if (row
< 0 || row
>= parent
.getGridRowCount() || column
< 0 || column
>= parent
.getGridColumnCount()) {
192 final RadComponent component
= parent
.getComponentAtGrid(row
, column
);
193 if (component
!= null && component
!= selectedComponent
) {
196 FormEditingUtil
.selectComponent(myEditor
, component
);
198 lastComponent
= component
;
201 selectOrExtend(component
);
207 if (lastComponent
!= null) {
208 selectOrExtend(lastComponent
);
214 protected abstract int calcDistance(Point source
, Point point
);
216 protected int getColumnMoveDelta() {
220 protected int getRowMoveDelta() {