]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/dnd/DropInteractor.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / dnd / DropInteractor.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 /*
13  *
14  * @author Toni Kalajainen
15  */
16 package org.simantics.g2d.dnd;
17
18 import java.awt.Component;
19 import java.awt.Point;
20 import java.awt.dnd.DropTarget;
21 import java.awt.dnd.DropTargetDragEvent;
22 import java.awt.dnd.DropTargetDropEvent;
23 import java.awt.dnd.DropTargetEvent;
24 import java.awt.dnd.DropTargetListener;
25 import java.awt.geom.Point2D;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.Comparator;
30
31 import org.simantics.g2d.canvas.ICanvasContext;
32 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
33
34
35 /**
36  * This participant handles drop operations of a canvas.
37  * 
38  * To implement a drop operation add an implementation of {@link IDropTargetParticipant} to the canvas.
39  * 
40  * Intantiates DragPainter for the duration of drag operations.
41  * 
42  * DropInteractor is added by chassis.
43  */
44 public class DropInteractor extends AbstractCanvasParticipant implements DropTargetListener {
45
46     private final Component component;
47     @SuppressWarnings("unused")
48     private DropTarget dropTarget;
49     private DnDContext dropCtx;
50     int allowedOps;
51
52     /**
53      * Create new abstract drop interactor
54      * @param context
55      * @param component
56      * @param ops  see DnDConstants
57      */
58     public DropInteractor(Component component) {
59         super();
60         this.component = component;
61     }
62
63     @Override
64     public void addedToContext(ICanvasContext ctx) {
65         super.addedToContext(ctx);
66         installDropTarget();
67     }
68
69     @Override
70     public void removedFromContext(ICanvasContext ctx) {
71         super.removedFromContext(ctx);
72         component.setDropTarget(null);
73     }
74
75     private int getAllowedOps() {
76         int result = 0;
77         for (IDropTargetParticipant p : getDropParticipants())
78             result |= p.getAllowedOps();
79         return result;
80     }
81
82     void installDropTarget() {
83         allowedOps = getAllowedOps();
84         dropTarget = new DropTarget(component, allowedOps, this);
85     }
86
87     protected Collection<IDropTargetParticipant> getDropParticipants() {
88         ArrayList<IDropTargetParticipant> participants = new ArrayList<IDropTargetParticipant>(getContext().getItemsByClass(IDropTargetParticipant.class));
89         Collections.sort(participants, new Comparator<IDropTargetParticipant>() {
90                         @Override
91                         public int compare(IDropTargetParticipant o1, IDropTargetParticipant o2) {
92                                 return Double.compare(o2.getPriority(), o1.getPriority());
93                         }
94                 });
95         return participants;
96     }
97
98     IDropTargetParticipant dropAccepter = null;
99     private DragPainter currentDragPainter;
100
101     public Collection<DragPainter> getDragPainters() {
102         return getContext().getItemsByClass(DragPainter.class);
103     }
104
105     @Override
106     public void dragEnter(final DropTargetDragEvent dtde) {
107         dropAccepter = null;
108         final Collection<IDropTargetParticipant> participants = getDropParticipants();
109         if (participants.isEmpty()) {
110             dtde.rejectDrag();
111             return;
112         }
113         dropCtx = new DnDContext();
114         syncExec(new Runnable() {
115             @Override
116             public void run() {
117                 for (IDropTargetParticipant p : participants) {
118                     p.dragEnter(dtde, dropCtx);
119                     if (dropCtx.toArray().length > 0) {
120                         dropAccepter = p;
121                         break;
122                     }
123
124                 }
125             }});
126
127         if (dropCtx.toArray().length==0)
128             dtde.rejectDrag();
129         else
130             dtde.acceptDrag(dtde.getDropAction());
131
132         // if drag is accepted, start drag interactor
133         Point mouseLocation = dtde.getLocation();
134         Point2D mouseControlPos = new Point2D.Double(mouseLocation.getX(), mouseLocation.getY());
135         currentDragPainter = new DragPainter(dropCtx, mouseControlPos);
136         getContext().add(currentDragPainter);
137
138         setDirty();
139     }
140
141     @Override
142     public void dragExit(final DropTargetEvent dte) {
143         syncExec(new Runnable() {
144             @Override
145             public void run() {
146                 if (dropAccepter != null)
147                     dropAccepter.dragExit(dte, dropCtx);
148 //                final Collection<IDropTargetParticipant> participants = getDropParticipants();
149 //                for (IDropTargetParticipant p : participants)
150 //                    p.dragExit(dte, dropCtx);
151
152                 endDrag();
153             }
154         });
155     }
156
157
158
159     @Override
160     public void dragOver(final DropTargetDragEvent dtde) {
161         final Collection<DragPainter> interactors = getDragPainters();
162         if (interactors.isEmpty()) {
163             dtde.rejectDrag();
164             return;
165         }
166
167         syncExec(new Runnable() {
168             @Override
169             public void run() {
170                 Point mouseLocation = dtde.getLocation();
171                 Point2D mouseControlPos = new Point2D.Double(mouseLocation.getX(), mouseLocation.getY());
172                 for (DragPainter interactor : interactors)
173                     interactor.setMousePos( mouseControlPos );
174
175                 if (dropAccepter != null)
176                     dropAccepter.dragOver(dtde, dropCtx);
177 //                final Collection<IDropTargetParticipant> participants = getDropParticipants();
178 //                for (IDropTargetParticipant p : participants)
179 //                    p.dragOver(dtde, dropCtx);
180
181             }
182         });
183     }
184
185     @Override
186     public void drop(final DropTargetDropEvent dtde) {
187 //        ITask task = ThreadLogger.getInstance().begin("Drop");
188         final Collection<DragPainter> interactors = getDragPainters();
189         if (interactors.isEmpty()) {
190             dtde.rejectDrop();
191             return;
192         }
193
194         // Try to make sure that all DragItems have a position
195         // before invoking IDropTargetParticipant.drop.
196         Point mouseLocation = dtde.getLocation();
197         Point2D mouseControlPos = new Point2D.Double(mouseLocation.getX(), mouseLocation.getY());
198         for (DragPainter interactor : interactors)
199             interactor.setMousePos( mouseControlPos, true );
200
201         // Remove drag painter before dropping just to prevent it from
202         // doing anything with the DNDContext after this point.
203         if (currentDragPainter != null) {
204             getContext().remove(currentDragPainter);
205             currentDragPainter = null;
206         }
207
208         syncExec(new Runnable() {
209             @Override
210             public void run() {
211 //                DragPainter painter = getDragPainter();
212                 if (dropAccepter != null)
213                     dropAccepter.drop(dtde, dropCtx);
214 //                final Collection<IDropTargetParticipant> participants = getDropParticipants();
215 //                for (IDropTargetParticipant p : participants)
216 //                    p.drop(dtde, dropCtx);
217
218                 endDrag();
219             }
220         });
221         //dtde.acceptDrop(dtde.getDropAction());
222 //        task.finish();
223     }
224
225     @Override
226     public void dropActionChanged(DropTargetDragEvent dtde) {
227         //System.out.println("dropActionChanged: "+dtde.getDropAction());
228         // remove interactor when action is canceled
229     }
230
231     public void endDrag()
232     {
233         Collection<DragPainter> dragPainters = getContext().getItemsByClass(DragPainter.class);
234         if (dragPainters.isEmpty()) return;
235         for (DragPainter dp : dragPainters)
236             dp.remove();
237         dropAccepter = null;
238         setDirty();
239     }
240
241 }