~seh999/jcog/proto3

« back to all changes in this revision

Viewing changes to spacetime/src/opencog/spacetime/control/raw/DeviceMouse.java

  • Committer: SeH
  • Date: 2009-09-19 22:59:48 UTC
  • Revision ID: seh999@gmail.com-20090919225948-q3ab80xa57i74mm6
start of major jReality refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 *
 
3
 * This file is part of jReality. jReality is open source software, made
 
4
 * available under a BSD license:
 
5
 *
 
6
 * Copyright (c) 2003-2006, jReality Group: Charles Gunn, Tim Hoffmann, Markus
 
7
 * Schmies, Steffen Weissmann.
 
8
 *
 
9
 * All rights reserved.
 
10
 *
 
11
 * Redistribution and use in source and binary forms, with or without
 
12
 * modification, are permitted provided that the following conditions are met:
 
13
 *
 
14
 * - Redistributions of source code must retain the above copyright notice, this
 
15
 *   list of conditions and the following disclaimer.
 
16
 *
 
17
 * - Redistributions in binary form must reproduce the above copyright notice,
 
18
 *   this list of conditions and the following disclaimer in the documentation
 
19
 *   and/or other materials provided with the distribution.
 
20
 *
 
21
 * - Neither the name of jReality nor the names of its contributors nor the
 
22
 *   names of their associated organizations may be used to endorse or promote
 
23
 *   products derived from this software without specific prior written
 
24
 *   permission.
 
25
 *
 
26
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
27
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
28
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
29
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
30
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
31
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
32
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
33
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
34
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
35
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
36
 * POSSIBILITY OF SUCH DAMAGE.
 
37
 *
 
38
 */
 
39
 
 
40
 
 
41
package opencog.spacetime.control.raw;
 
42
 
 
43
import java.awt.Component;
 
44
import java.awt.Container;
 
45
import java.awt.Cursor;
 
46
import java.awt.Insets;
 
47
import java.awt.KeyboardFocusManager;
 
48
import java.awt.Point;
 
49
import java.awt.event.ComponentAdapter;
 
50
import java.awt.event.ComponentEvent;
 
51
import java.awt.event.ComponentListener;
 
52
import java.awt.event.InputEvent;
 
53
import java.awt.event.KeyEvent;
 
54
import java.awt.event.KeyListener;
 
55
import java.awt.event.MouseEvent;
 
56
import java.awt.event.MouseListener;
 
57
import java.awt.event.MouseMotionListener;
 
58
import java.awt.event.MouseWheelEvent;
 
59
import java.awt.event.MouseWheelListener;
 
60
import java.util.Map;
 
61
import java.util.logging.Level;
 
62
 
 
63
import javax.swing.ImageIcon;
 
64
 
 
65
import opencog.math.Matrix;
 
66
import opencog.spacetime.control.AxisState;
 
67
import opencog.spacetime.control.InputSlot;
 
68
import opencog.spacetime.control.ToolEvent;
 
69
import opencog.spacetime.space.Viewer;
 
70
import opencog.spacetime.space.data.DoubleArray;
 
71
import opencog.spacetime.util.LoggingSystem;
 
72
 
 
73
 
 
74
/**
 
75
 * @author weissman
 
76
 *
 
77
 **/
 
78
public class DeviceMouse extends AbstractDeviceMouse implements RawDevice, MouseListener,
 
79
    MouseMotionListener, MouseWheelListener {
 
80
 
 
81
          private static int MOUSE_GRAB_TOGGLE = KeyEvent.VK_F10;
 
82
          private static int MOUSE_GRAB_TOGGLE_ALTERNATIVE = KeyEvent.VK_C;
 
83
  
 
84
  private Component component;
 
85
  
 
86
  public void mouseClicked(MouseEvent e) {
 
87
  }
 
88
 
 
89
  public void mouseEntered(MouseEvent e) {
 
90
  }
 
91
 
 
92
  public void mouseExited(MouseEvent e) {
 
93
  }
 
94
 
 
95
  public void mousePressed(MouseEvent e) {
 
96
    InputSlot button = findButton(e);
 
97
    if (button != null)
 
98
        queue.addEvent(new ToolEvent(DeviceMouse.this, System.currentTimeMillis(), button, AxisState.PRESSED));
 
99
  }
 
100
 
 
101
  public void mouseReleased(MouseEvent e) {
 
102
    InputSlot button = findButton(e);
 
103
    if (button != null)
 
104
        queue.addEvent(new ToolEvent(DeviceMouse.this, System.currentTimeMillis(), button, AxisState.ORIGIN));
 
105
  }
 
106
 
 
107
  public void mouseDragged(MouseEvent e) {
 
108
    mouseMoved(e);
 
109
  }
 
110
 
 
111
  Cursor emptyCursor;
 
112
  public void mouseMoved(MouseEvent e) {
 
113
    mouseMoved(e.getX(), e.getY());
 
114
  }
 
115
  public void mouseWheelMoved(MouseWheelEvent e) {
 
116
    int count = e.getWheelRotation();
 
117
    if (count > 0) {
 
118
      InputSlot slot = (InputSlot) usedSources.get("wheel_up");
 
119
      if (slot == null) return;
 
120
      for (int i = 0; i < count; i++) {
 
121
        queue.addEvent(new ToolEvent(DeviceMouse.this, System.currentTimeMillis(), slot, AxisState.PRESSED));
 
122
        queue.addEvent(new ToolEvent(DeviceMouse.this, System.currentTimeMillis(), slot, AxisState.ORIGIN));
 
123
      }
 
124
    }
 
125
    if (count < 0) {
 
126
      InputSlot slot = (InputSlot) usedSources.get("wheel_down");
 
127
      if (slot == null) return;
 
128
      for (int i = 0; i > count; i--) {
 
129
        queue.addEvent(new ToolEvent(DeviceMouse.this, System.currentTimeMillis(), slot, AxisState.PRESSED));
 
130
        queue.addEvent(new ToolEvent(DeviceMouse.this, System.currentTimeMillis(), slot, AxisState.ORIGIN));
 
131
      }
 
132
    }
 
133
  }
 
134
 
 
135
  // e.getButton() doesn't work properly on 1-button mouse, such as MacOS laptops
 
136
  public static int getRealButton(MouseEvent e) {
 
137
    int button = e.getButton();
 
138
    if (button == 0)  {   // Linux!
 
139
      int mods = e.getModifiersEx();
 
140
      if ((mods & InputEvent.BUTTON1_DOWN_MASK) != 0)   button = 1;
 
141
      else if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)  button = 2;
 
142
      else button = 3;
 
143
    } else {          // Mac OS X Laptop (no 3-mouse button)!!
 
144
      int mods = e.getModifiers();
 
145
      if (e.isAltDown() && ((mods & InputEvent.BUTTON2_MASK) != 0) ) button = 2;
 
146
      else if (button == 1 &&  ((mods & InputEvent.BUTTON3_MASK) != 0) ) button = 3;
 
147
    }
 
148
    return button;
 
149
  }
 
150
 
 
151
  private InputSlot findButton(MouseEvent e) {
 
152
    int button = getRealButton(e); //e.getButton();
 
153
    if (button == MouseEvent.BUTTON1)
 
154
        return (InputSlot) usedSources.get("left");
 
155
    if (button == MouseEvent.BUTTON3)
 
156
        return (InputSlot) usedSources.get("right");
 
157
    if (button == MouseEvent.BUTTON2)
 
158
        return (InputSlot) usedSources.get("center");
 
159
    return null;
 
160
  }
 
161
 
 
162
  private ComponentListener componentListener = new ComponentAdapter() {
 
163
          public void componentResized(ComponentEvent e) {
 
164
                  if (isCenter()) {
 
165
                          setCenter(false);
 
166
                          queue.addEvent(new ToolEvent(this, System.currentTimeMillis(), InputSlot.getDevice("LookSwitch"), AxisState.PRESSED, null));
 
167
                          queue.addEvent(new ToolEvent(this, System.currentTimeMillis(), InputSlot.getDevice("LookSwitch"), AxisState.ORIGIN, null));
 
168
                  }
 
169
                  requestFocus();
 
170
          }
 
171
  };
 
172
  
 
173
  private KeyListener keyListener = new KeyListener() {
 
174
      public void keyTyped(KeyEvent e) {
 
175
      }
 
176
      public void keyPressed(KeyEvent e) {
 
177
        if (e.getKeyCode() == MOUSE_GRAB_TOGGLE ||
 
178
                        (e.getKeyCode() == MOUSE_GRAB_TOGGLE_ALTERNATIVE
 
179
                && e.isShiftDown() && e.isControlDown())
 
180
                        ) {
 
181
          setCenter(!isCenter());
 
182
          // XXX: HACK
 
183
          queue.addEvent(new ToolEvent(this, System.currentTimeMillis(), InputSlot.getDevice("LookSwitch"), AxisState.PRESSED, null));
 
184
          queue.addEvent(new ToolEvent(this, System.currentTimeMillis(), InputSlot.getDevice("LookSwitch"), AxisState.ORIGIN, null));
 
185
        }
 
186
      }
 
187
      public void keyReleased(KeyEvent e) {
 
188
      }
 
189
    };
 
190
    
 
191
  public void setComponent(final Component component) {
 
192
    this.component = component;
 
193
    component.addMouseListener(this);
 
194
    component.addMouseMotionListener(this);
 
195
    component.addMouseWheelListener(this);
 
196
    component.addComponentListener(componentListener);
 
197
    component.addKeyListener(keyListener);
 
198
  }
 
199
 
 
200
  public ToolEvent mapRawDevice(String rawDeviceName, InputSlot inputDevice) {
 
201
    if (!knownSources.contains(rawDeviceName))
 
202
        throw new IllegalArgumentException("no such raw device");
 
203
    usedSources.put(rawDeviceName, inputDevice);
 
204
    if (rawDeviceName.equals("axes")) return new ToolEvent(this, System.currentTimeMillis(), inputDevice, new DoubleArray(new Matrix().getArray()));
 
205
    if (rawDeviceName.equals("axesEvolution")) {
 
206
      Matrix initM = new Matrix();
 
207
      initM.setEntry(2, 3, -1);
 
208
      return new ToolEvent(this, System.currentTimeMillis(), inputDevice, new DoubleArray(initM.getArray()));
 
209
    }
 
210
    return new ToolEvent(this, System.currentTimeMillis(), inputDevice, AxisState.ORIGIN);
 
211
  }
 
212
 
 
213
  public void dispose() {
 
214
    component.removeMouseListener(this);
 
215
    component.removeMouseMotionListener(this);
 
216
    component.removeMouseWheelListener(this);
 
217
    component.removeComponentListener(componentListener);
 
218
    component.removeKeyListener(keyListener);
 
219
  }
 
220
 
 
221
  public void initialize(Viewer viewer, Map<String, Object> config) {
 
222
    if (!viewer.hasViewingComponent() || !(viewer.getViewingComponent() instanceof Component) ) throw new UnsupportedOperationException("need AWT component");
 
223
    setComponent((Component) viewer.getViewingComponent());
 
224
  }
 
225
 
 
226
  public String getName() {
 
227
    return "Mouse";
 
228
  }
 
229
 
 
230
  public String toString() {
 
231
    return "RawDevice: Mouse AWT";
 
232
  }
 
233
 
 
234
  public void installGrabs() {
 
235
    try {
 
236
      if (emptyCursor == null) {
 
237
        ImageIcon emptyIcon = new ImageIcon(new byte[0]);
 
238
        emptyCursor = component.getToolkit().createCustomCursor(emptyIcon.getImage(), new Point(0, 0), "emptyCursor");
 
239
      }
 
240
      component.setCursor(emptyCursor);
 
241
      requestFocus();
 
242
    } catch (Exception e) {
 
243
      LoggingSystem.getLogger(this).log(Level.WARNING, "cannot grab mouse", e);
 
244
    }
 
245
  }
 
246
 
 
247
  public void uninstallGrabs() {
 
248
    try {
 
249
      component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
 
250
      requestFocus();
 
251
    } catch (Exception e) {
 
252
      LoggingSystem.getLogger(this).log(Level.WARNING, "cannot grab mouse", e);
 
253
    }
 
254
  }
 
255
 
 
256
  // XXX: howto do that?
 
257
  private void requestFocus() {
 
258
        KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
 
259
        boolean fow = component.requestFocusInWindow();
 
260
        //component.requestFocus();
 
261
        }
 
262
 
 
263
        protected int getWidth() {
 
264
    return component.getWidth();
 
265
  }
 
266
 
 
267
  protected int getHeight() {
 
268
    return component.getHeight();
 
269
  }
 
270
 
 
271
  protected void calculateCenter() {
 
272
    Component currentCmp = component;
 
273
    winCenterX=getWidth() / 2;
 
274
    winCenterY=getHeight() / 2;
 
275
    while (currentCmp != null) {
 
276
      if (currentCmp instanceof Container) {
 
277
        Insets insets = ((Container)currentCmp).getInsets();
 
278
        winCenterX += insets.left;
 
279
        winCenterY += insets.top;
 
280
      }
 
281
      winCenterX += currentCmp.getX();
 
282
      winCenterY += currentCmp.getY();
 
283
      currentCmp = currentCmp.getParent();
 
284
    }
 
285
  }
 
286
 
 
287
 
 
288
}