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
26package sun.awt.windows;
27
28import java.awt.Component;
29import java.awt.Point;
30import java.awt.dnd.DnDConstants;
31import java.awt.dnd.DragGestureListener;
32import java.awt.dnd.DragSource;
33import java.awt.dnd.MouseDragGestureRecognizer;
34import java.awt.event.InputEvent;
35import java.awt.event.MouseEvent;
36
37import 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
52final 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
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
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
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
110    protected WMouseDragGestureRecognizer(DragSource ds) {
111        this(ds, null);
112    }
113
114    /**
115     * determine the drop action from the event
116     */
117
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
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
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
166    public void mouseReleased(MouseEvent e) {
167        events.clear();
168    }
169
170    /**
171     * Invoked when the mouse enters a component.
172     */
173
174    @Override
175    public void mouseEntered(MouseEvent e) {
176        events.clear();
177    }
178
179    /**
180     * Invoked when the mouse exits a component.
181     */
182
183    @Override
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
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
230    public void mouseMoved(MouseEvent e) {
231        // do nothing
232    }
233}
234