1 /*
2  * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.awt.windows;
27 
28 import java.awt.Component;
29 import java.awt.Point;
30 import java.awt.dnd.DnDConstants;
31 import java.awt.dnd.DragGestureListener;
32 import java.awt.dnd.DragSource;
33 import java.awt.dnd.MouseDragGestureRecognizer;
34 import java.awt.event.InputEvent;
35 import java.awt.event.MouseEvent;
36 
37 import sun.awt.dnd.SunDragSourceContextPeer;
38 
39 /**
40  * <p>
41  * This subclass of MouseDragGestureRecognizer defines a DragGestureRecognizer
42  * for Mouse based gestures on Win32.
43  * </p>
44  *
45  * @author Laurence P. G. Cable
46  *
47  * @see java.awt.dnd.DragGestureListener
48  * @see java.awt.dnd.DragGestureEvent
49  * @see java.awt.dnd.DragSource
50  */
51 
52 final class WMouseDragGestureRecognizer extends MouseDragGestureRecognizer {
53 
54     private static final long serialVersionUID = -3527844310018033570L;
55 
56     /*
57      * constant for number of pixels hysterisis before drag is determined
58      * to have started
59      */
60 
61     protected static int motionThreshold;
62 
63     protected static final int ButtonMask = InputEvent.BUTTON1_DOWN_MASK |
64                                             InputEvent.BUTTON2_DOWN_MASK |
65                                             InputEvent.BUTTON3_DOWN_MASK;
66 
67     /**
68      * construct a new WMouseDragGestureRecognizer
69      *
70      * @param ds  The DragSource for the Component c
71      * @param c   The Component to observe
72      * @param act The actions permitted for this Drag
73      * @param dgl The DragGestureRecognizer to notify when a gesture is detected
74      *
75      */
76 
WMouseDragGestureRecognizer(DragSource ds, Component c, int act, DragGestureListener dgl)77     protected WMouseDragGestureRecognizer(DragSource ds, Component c, int act, DragGestureListener dgl) {
78         super(ds, c, act, dgl);
79     }
80 
81     /**
82      * construct a new WMouseDragGestureRecognizer
83      *
84      * @param ds  The DragSource for the Component c
85      * @param c   The Component to observe
86      * @param act The actions permitted for this Drag
87      */
88 
WMouseDragGestureRecognizer(DragSource ds, Component c, int act)89     protected WMouseDragGestureRecognizer(DragSource ds, Component c, int act) {
90         this(ds, c, act, null);
91     }
92 
93     /**
94      * construct a new WMouseDragGestureRecognizer
95      *
96      * @param ds  The DragSource for the Component c
97      * @param c   The Component to observe
98      */
99 
WMouseDragGestureRecognizer(DragSource ds, Component c)100     protected WMouseDragGestureRecognizer(DragSource ds, Component c) {
101         this(ds, c, DnDConstants.ACTION_NONE);
102     }
103 
104     /**
105      * construct a new WMouseDragGestureRecognizer
106      *
107      * @param ds  The DragSource for the Component c
108      */
109 
WMouseDragGestureRecognizer(DragSource ds)110     protected WMouseDragGestureRecognizer(DragSource ds) {
111         this(ds, null);
112     }
113 
114     /**
115      * determine the drop action from the event
116      */
117 
mapDragOperationFromModifiers(MouseEvent e)118     protected int mapDragOperationFromModifiers(MouseEvent e) {
119         int mods = e.getModifiersEx();
120         int btns = mods & ButtonMask;
121 
122         // Prohibit multi-button drags.
123         if (!(btns == InputEvent.BUTTON1_DOWN_MASK ||
124               btns == InputEvent.BUTTON2_DOWN_MASK ||
125               btns == InputEvent.BUTTON3_DOWN_MASK)) {
126             return DnDConstants.ACTION_NONE;
127         }
128 
129         return
130             SunDragSourceContextPeer.convertModifiersToDropAction(mods,
131                                                                   getSourceActions());
132     }
133 
134     /**
135      * Invoked when the mouse has been clicked on a component.
136      */
137 
138     @Override
mouseClicked(MouseEvent e)139     public void mouseClicked(MouseEvent e) {
140         // do nothing
141     }
142 
143     /**
144      * Invoked when a mouse button has been pressed on a component.
145      */
146 
147     @Override
mousePressed(MouseEvent e)148     public void mousePressed(MouseEvent e) {
149         events.clear();
150 
151         if (mapDragOperationFromModifiers(e) != DnDConstants.ACTION_NONE) {
152             try {
153                 motionThreshold = DragSource.getDragThreshold();
154             } catch (Exception exc) {
155                 motionThreshold = 5;
156             }
157             appendEvent(e);
158         }
159     }
160 
161     /**
162      * Invoked when a mouse button has been released on a component.
163      */
164 
165     @Override
mouseReleased(MouseEvent e)166     public void mouseReleased(MouseEvent e) {
167         events.clear();
168     }
169 
170     /**
171      * Invoked when the mouse enters a component.
172      */
173 
174     @Override
mouseEntered(MouseEvent e)175     public void mouseEntered(MouseEvent e) {
176         events.clear();
177     }
178 
179     /**
180      * Invoked when the mouse exits a component.
181      */
182 
183     @Override
mouseExited(MouseEvent e)184     public void mouseExited(MouseEvent e) {
185 
186         if (!events.isEmpty()) { // gesture pending
187             int dragAction = mapDragOperationFromModifiers(e);
188 
189             if (dragAction == DnDConstants.ACTION_NONE) {
190                 events.clear();
191             }
192         }
193     }
194 
195     /**
196      * Invoked when a mouse button is pressed on a component.
197      */
198 
199     @Override
mouseDragged(MouseEvent e)200     public void mouseDragged(MouseEvent e) {
201         if (!events.isEmpty()) { // gesture pending
202             int dop = mapDragOperationFromModifiers(e);
203 
204             if (dop == DnDConstants.ACTION_NONE) {
205                 return;
206             }
207 
208             MouseEvent trigger = (MouseEvent)events.get(0);
209 
210 
211             Point      origin  = trigger.getPoint();
212             Point      current = e.getPoint();
213 
214             int        dx      = Math.abs(origin.x - current.x);
215             int        dy      = Math.abs(origin.y - current.y);
216 
217             if (dx > motionThreshold || dy > motionThreshold) {
218                 fireDragGestureRecognized(dop, ((MouseEvent)getTriggerEvent()).getPoint());
219             } else
220                 appendEvent(e);
221         }
222     }
223 
224     /**
225      * Invoked when the mouse button has been moved on a component
226      * (with no buttons no down).
227      */
228 
229     @Override
mouseMoved(MouseEvent e)230     public void mouseMoved(MouseEvent e) {
231         // do nothing
232     }
233 }
234