Bug 4677 fixed: xclick did not return correct mouse position on keyboard event
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / events / Jxgetmouse.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Bruno Jofret
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 package org.scilab.modules.gui.events;
14
15 import java.awt.AWTEvent;
16 import java.awt.event.KeyEvent;
17 import java.awt.event.MouseEvent;
18
19 import org.scilab.modules.gui.bridge.canvas.SwingScilabCanvas;
20 import org.scilab.modules.gui.utils.SciTranslator;
21
22
23 /**
24  * This class implements the xgetmouse Scilab method
25  * by updating the ClickInfos attributes
26  * @author Bruno Jofret
27  */
28 public final class Jxgetmouse {
29
30     private static int keyChar;
31     private static boolean isControlDown;
32     private static boolean watchMotion;
33     private static boolean watchRelease;
34     private static final int MOVED = -1;
35
36     /**
37      * Tool Class, constructor is private.
38      */
39     private Jxgetmouse() { }
40
41     /**
42      * Default call for xgetmouse.
43      */
44     public static void xgetmouse() {
45         xgetmouse(true, false);
46     }
47
48     /**
49      * Scilab call point for xgetmouse.
50      *
51      * @param withMotion : Means xgetmouse is mouse motion sensitive.
52      * @param withRelease : Means xgetmouse is release sensitive.
53      */
54     public static void xgetmouse(boolean withMotion, boolean withRelease) {
55         watchMotion = withMotion;
56         watchRelease = withRelease;
57         /*
58          *  Enable the local keyActionFilter function
59          *  to be called when a keyEvent is caught.
60          */
61         GlobalEventWatcher.enable(new GlobalKeyEventWatcher() {
62             public void keyEventFilter(KeyEvent keyEvent) {
63                 keyActionFilter(keyEvent);
64             }
65         });
66         long eventMask = AWTEvent.MOUSE_EVENT_MASK;
67         if (watchMotion) {
68             eventMask += AWTEvent.MOUSE_MOTION_EVENT_MASK;
69         }
70         /*
71          *  Enable the local mouseActionFilter function
72          *  to be called when a mouseEvent is caught.
73          */
74         GlobalEventWatcher.enable(new GlobalMouseEventWatcher(eventMask) {
75             public void mouseEventFilter(MouseEvent mouseEvent,
76                                          Integer axesUID, int scilabMouseAction, boolean isControlDown) {
77                 mouseActionFilter(mouseEvent, axesUID, scilabMouseAction, isControlDown);
78             }
79         });
80
81         /*
82          *  Force xgetmouse not to catch/disable callback execution.
83          */
84         GlobalEventWatcher.disableCatchingCallback();
85
86         synchronized (ClickInfos.getInstance()) {
87             try {
88                 ClickInfos.getInstance().init();
89                 ClickInfos.getInstance().wait();
90             } catch (InterruptedException e) {
91                 e.printStackTrace();
92             }
93         }
94         GlobalEventWatcher.disable();
95     }
96
97     /**
98      * @return the mouseButtonNumber
99      */
100     public static int getMouseButtonNumber() {
101         return ClickInfos.getInstance().getMouseButtonNumber();
102     }
103     /**
104      * @return the xCoordinate
105      */
106     public static double getXCoordinate() {
107         return ClickInfos.getInstance().getXCoordinate();
108     }
109     /**
110      * @return the yCoordinate
111      */
112     public static double getYCoordinate() {
113         return ClickInfos.getInstance().getYCoordinate();
114     }
115     /**
116      * @return the WindowsID
117      */
118     public static Integer getWindowsID() {
119         return ClickInfos.getInstance().getWindowID();
120     }
121
122     /**
123      * Manage xgetmouse behaviour for keyboard entry.
124      * 1 - Key has been pressed.
125      * 2 - CTRL + Key has been pressed.
126      * 3 - Key has been released
127      *
128      * @param keyEvent : the Key Event caught
129      */
130     private static void keyActionFilter(KeyEvent keyEvent) {
131         /*
132          * If a key is pressed, only remember the key and if CTRL is pressed either.
133          */
134         if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
135             if (!Character.isJavaIdentifierStart(keyEvent.getKeyChar())) {
136                 keyChar = keyEvent.getKeyChar();
137             } else {
138                 if (keyEvent.isShiftDown()) {
139                     keyChar = keyEvent.getKeyCode();
140                 } else {
141                     keyChar = Character.toLowerCase(keyEvent.getKeyCode());
142                 }
143             }
144             isControlDown = keyEvent.isControlDown();
145         } else if (keyEvent.getSource() instanceof SwingScilabCanvas) {
146             /* Now we have have to be sure we are in a Canvas. */
147             /*
148              * If a RELEASED is seen use -keyChar
149              */
150             if (keyEvent.getID() == KeyEvent.KEY_RELEASED) {
151                 GlobalEventFilter.filterKey(-keyChar, GlobalEventWatcher.getAxesUID(), isControlDown, (SwingScilabCanvas) keyEvent.getSource());
152             } else if (keyEvent.getID() == KeyEvent.KEY_TYPED) {
153                 /*
154                  * Or If a TYPED is seen use keyChar
155                  */
156                 GlobalEventFilter.filterKey(keyChar, GlobalEventWatcher.getAxesUID(), isControlDown, (SwingScilabCanvas) keyEvent.getSource());
157             }
158         }
159     }
160
161     /**
162      * Manage xgetmouse behaviour for mouse entry.
163      *
164      * @param mouseEvent : the Mouse Event caught
165      * @param scilabMouseAction : the integer scilab code for mouse action.
166      * @param axes : the axes where action occurs.
167      * @param isControlDown true if the CTRL key has been pressed
168      */
169     private static void mouseActionFilter(MouseEvent mouseEvent, Integer axesUID, int scilabMouseAction, boolean isControlDown) {
170         if (scilabMouseAction != SciTranslator.MOVED
171                 && scilabMouseAction != SciTranslator.RELEASED) {
172             GlobalEventFilter.filterMouse(mouseEvent, axesUID, scilabMouseAction, isControlDown);
173         } else if (watchMotion && scilabMouseAction == SciTranslator.MOVED) {
174             // Force false value to isControlDown
175             // MOVED do not care about CTRL Key...
176             GlobalEventFilter.filterMouse(mouseEvent, axesUID, MOVED, false);
177         } else if (watchRelease && scilabMouseAction == SciTranslator.RELEASED) {
178             // Force false value to isControlDown
179             // RELEASED do not care about CTRL Key...
180             GlobalEventFilter.filterMouse(mouseEvent, axesUID, scilabMouseAction, false);
181         }
182     }
183 }