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
.designSurface
;
18 import com
.intellij
.openapi
.diagnostic
.Logger
;
19 import com
.intellij
.uiDesigner
.FormEditingUtil
;
20 import com
.intellij
.uiDesigner
.core
.GridConstraints
;
21 import com
.intellij
.uiDesigner
.radComponents
.RadComponent
;
22 import com
.intellij
.uiDesigner
.radComponents
.RadContainer
;
23 import org
.jetbrains
.annotations
.NotNull
;
24 import org
.jetbrains
.annotations
.Nullable
;
28 import java
.awt
.datatransfer
.DataFlavor
;
29 import java
.awt
.datatransfer
.Transferable
;
30 import java
.awt
.datatransfer
.UnsupportedFlavorException
;
31 import java
.io
.IOException
;
32 import java
.util
.ArrayList
;
33 import java
.util
.Collection
;
34 import java
.util
.Collections
;
35 import java
.util
.Comparator
;
40 public class DraggedComponentList
implements Transferable
, ComponentDragObject
{
41 private static final Logger LOG
= Logger
.getInstance("#com.intellij.uiDesigner.DraggedComponentList");
43 private static DataFlavor ourDataFlavor
;
47 ourDataFlavor
= new DataFlavor(DataFlavor
.javaJVMLocalObjectMimeType
);
48 } catch (ClassNotFoundException e
) {
53 private final ArrayList
<RadComponent
> mySelection
;
54 private GridConstraints
[] myOriginalConstraints
;
55 private Rectangle
[] myOriginalBounds
;
56 private RadContainer
[] myOriginalParents
;
57 private int myDragRelativeColumn
= 0;
58 private int myComponentUnderMouseColumn
;
59 private int myComponentUnderMouseRow
;
60 private int myDragDeltaX
= 0;
61 private int myDragDeltaY
= 0;
62 private boolean myHasDragDelta
= false;
64 private DraggedComponentList(Collection
<RadComponent
> selection
) {
65 mySelection
= new ArrayList
<RadComponent
>(selection
);
66 fillOriginalConstraints();
69 private DraggedComponentList(final GuiEditor editor
, final Point pnt
) {
70 // Store selected components
71 mySelection
= FormEditingUtil
.getSelectedComponents(editor
);
73 // sort selection in correct grid order
74 Collections
.sort(mySelection
, new Comparator
<RadComponent
>() {
75 public int compare(final RadComponent o1
, final RadComponent o2
) {
76 if (o1
.getParent() == o2
.getParent()) {
77 int result
= o1
.getConstraints().getRow() - o2
.getConstraints().getRow();
79 result
= o1
.getConstraints().getColumn() - o2
.getConstraints().getColumn();
87 RadComponent componentUnderMouse
= null;
88 int componentUnderMouseIndex
= mySelection
.size() == 0 ?
-1 : 0;
90 for(int i
=0; i
<mySelection
.size(); i
++) {
91 RadComponent c
= mySelection
.get(i
);
92 Point aPoint
= SwingUtilities
.convertPoint(editor
.getRootContainer().getDelegee(), pnt
,
93 c
.getParent().getDelegee());
94 if (c
.getBounds().contains(aPoint
)) {
95 aPoint
= SwingUtilities
.convertPoint(editor
.getRootContainer().getDelegee(), pnt
,
97 mySelection
.set(i
, c
.getComponentToDrag(aPoint
));
98 componentUnderMouseIndex
= i
;
102 fillOriginalConstraints();
104 if (componentUnderMouseIndex
>= 0) {
105 componentUnderMouse
= mySelection
.get(componentUnderMouseIndex
);
106 myComponentUnderMouseColumn
= myOriginalConstraints
[componentUnderMouseIndex
].getColumn();
107 myComponentUnderMouseRow
= myOriginalConstraints
[componentUnderMouseIndex
].getRow();
110 LOG
.debug("myComponentUnderMouseColumn=" + myComponentUnderMouseColumn
+
111 ", myComponentUnderMouseRow=" + myComponentUnderMouseRow
);
113 if (mySelection
.size() > 1 && componentUnderMouse
!= null) {
114 for(GridConstraints constraints
: myOriginalConstraints
) {
115 myDragRelativeColumn
= Math
.max(myDragRelativeColumn
,
116 componentUnderMouse
.getConstraints().getColumn() - constraints
.getColumn());
120 for(RadComponent c
: mySelection
) {
121 JComponent delegee
= c
.getDelegee();
122 if (c
== componentUnderMouse
&& pnt
!= null) {
123 if (delegee
.getX() > pnt
.x
&& delegee
.getX() + delegee
.getWidth() < pnt
.x
) {
124 myDragDeltaX
= pnt
.x
- (delegee
.getX() + delegee
.getWidth() / 2);
126 if (delegee
.getY() > pnt
.y
&& delegee
.getY() + delegee
.getHeight() < pnt
.y
) {
127 myDragDeltaY
= pnt
.y
- (delegee
.getY() + delegee
.getHeight() / 2);
129 myHasDragDelta
= true;
134 private void fillOriginalConstraints() {
135 // Store original constraints and parents. This information is required
136 // to restore initial state if drag is canceled.
137 myOriginalConstraints
= new GridConstraints
[mySelection
.size()];
138 myOriginalBounds
= new Rectangle
[mySelection
.size()];
139 myOriginalParents
= new RadContainer
[mySelection
.size()];
140 for (int i1
= 0; i1
< mySelection
.size(); i1
++) {
141 final RadComponent component
= mySelection
.get(i1
);
142 myOriginalConstraints
[i1
] = component
.getConstraints().store();
143 myOriginalBounds
[i1
] = component
.getBounds();
144 myOriginalParents
[i1
] = component
.getParent();
148 public static DraggedComponentList
pickupSelection(final GuiEditor editor
, @Nullable Point pnt
) {
149 return new DraggedComponentList(editor
, pnt
);
152 public static DraggedComponentList
withComponents(RadComponent
... c
) {
153 ArrayList
<RadComponent
> list
= new ArrayList
<RadComponent
>();
154 Collections
.addAll(list
, c
);
155 return new DraggedComponentList(list
);
159 public static DraggedComponentList
fromTransferable(final Transferable transferable
) {
160 if (transferable
.isDataFlavorSupported(ourDataFlavor
)) {
163 data
= transferable
.getTransferData(ourDataFlavor
);
165 catch (Exception e
) {
168 if (data
instanceof DraggedComponentList
) {
169 return (DraggedComponentList
) data
;
175 public int getDragDeltaX() {
179 public int getDragDeltaY() {
183 public ArrayList
<RadComponent
> getComponents() {
187 public int getComponentCount() {
188 return mySelection
.size();
191 public RadContainer
getOriginalParent(final RadComponent c
) {
192 return myOriginalParents
[mySelection
.indexOf(c
)];
196 * Returns a copy of the original constraints array.
198 public GridConstraints
[] getOriginalConstraints() {
199 GridConstraints
[] result
= new GridConstraints
[myOriginalConstraints
.length
];
200 for(int i
=0; i
<myOriginalConstraints
.length
; i
++) {
201 result
[i
] = myOriginalConstraints
[i
].store();
206 public Rectangle
[] getOriginalBounds() {
207 return myOriginalBounds
;
210 public Rectangle
getOriginalBounds(final RadComponent c
) {
211 return myOriginalBounds
[mySelection
.indexOf(c
)];
214 public DataFlavor
[] getTransferDataFlavors() {
215 return new DataFlavor
[] { ourDataFlavor
};
218 public boolean isDataFlavorSupported(DataFlavor flavor
) {
219 return flavor
.equals(ourDataFlavor
);
222 public Object
getTransferData(DataFlavor flavor
) throws UnsupportedFlavorException
, IOException
{
226 public boolean isHGrow() {
227 for(GridConstraints c
: myOriginalConstraints
) {
228 if ((c
.getHSizePolicy() & GridConstraints
.SIZEPOLICY_WANT_GROW
) != 0) return true;
233 public boolean isVGrow() {
234 for(GridConstraints c
: myOriginalConstraints
) {
235 if ((c
.getVSizePolicy() & GridConstraints
.SIZEPOLICY_WANT_GROW
) != 0) return true;
240 public int getRelativeRow(int componentIndex
) {
241 return myOriginalConstraints
[componentIndex
].getRow() - myComponentUnderMouseRow
;
244 public int getRelativeCol(int componentIndex
) {
245 return myOriginalConstraints
[componentIndex
].getColumn() - myComponentUnderMouseColumn
;
248 public int getRowSpan(int componentIndex
) {
249 return myOriginalConstraints
[componentIndex
].getRowSpan();
252 public int getColSpan(int componentIndex
) {
253 return myOriginalConstraints
[componentIndex
].getColSpan();
256 public Point
getDelta(int componentIndex
) {
261 public Dimension
getInitialSize(final RadContainer targetContainer
) {
262 if (myOriginalBounds
.length
== 1) {
263 return myOriginalBounds
[0].getSize();
265 return new Dimension(-1, -1);
268 public RadContainer
[] getOriginalParents() {
269 return myOriginalParents
;
272 public boolean hasDragDelta() {
273 return myHasDragDelta
;