source: trunk/src/testing/dim/devices/joystick.py @ 4

Revision 4, 6.4 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1############################################################################
2#
3# DIM - A Direct Interaction Manager for SAGE
4# Copyright (C) 2007 Electronic Visualization Laboratory,
5# University of Illinois at Chicago
6#
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are met:
11#
12#  * Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14#  * Redistributions in binary form must reproduce the above
15#    copyright notice, this list of conditions and the following disclaimer
16#    in the documentation and/or other materials provided with the distribution.
17#  * Neither the name of the University of Illinois at Chicago nor
18#    the names of its contributors may be used to endorse or promote
19#    products derived from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# Direct questions, comments etc about SAGE UI to www.evl.uic.edu/cavern/forum
34#
35# Author: Ratko Jagodic
36#       
37############################################################################
38
39
40
41
42import device
43from globals import *
44
45
46def makeNew(deviceId):
47    """ this is how we instantiate the device object from
48        the main program that loads this plugin """
49    return Joystick(deviceId)
50
51UP_ARROW = 1
52DOWN_ARROW = 2
53LEFT_ARROW = 3
54RIGHT_ARROW = 4
55
56
57class Joystick(device.Device):
58   
59    def __init__(self, deviceId):
60        device.Device.__init__(self, "joystick", deviceId, True, displayId=0)
61        isFake = deviceId.split("_")[1].startswith('fake')
62        self.isWiimote = deviceId.split("_")[1].startswith('wiimote')
63       
64        if isFake:
65            self.joyToMouseRatio = 600
66        else:
67            self.joyToMouseRatio = 40
68        self.displayFactor = 1
69       
70        # current state of the device
71        self.buttons = [False, False, False]   # left, right, middle
72        self.x = 100   # position in SAGE coords
73        self.y = 100   # position in SAGE coords
74        self.clickX = 0  # where the click happened
75        self.clickY = 0  # where the click happened
76
77       
78
79    def onMessage(self, data, firstMsg=False):
80        tokens = data.strip().split()
81        msgCode = tokens[0]
82           
83        # move
84        if msgCode == "1":
85           
86            # the axis information
87            xAxis = float(tokens[1])
88            yAxis = float(tokens[2])
89
90            # determine x, y, dX, dY
91            (dX, dY) = self.__toSAGEPos(xAxis, yAxis)
92                   
93            # fire the appropriate event
94            if self.buttons[0]:     # analog1, pan
95                self.postEvtAnalog1(self.clickX, self.clickY, dX, dY, 0)
96
97            elif self.buttons[1]:   # analog2, rotate
98                self.postEvtAnalog3(self.clickX, self.clickY, dX, dY, 0)
99               
100            elif self.buttons[2]:   # analog3, zoom
101                self.postEvtAnalog2(self.clickX, self.clickY, dX, dY, 0)
102
103            else:                   # move
104                self.postEvtMove(self.x, self.y, dX, dY)
105               
106
107            # move the pointer
108            if self.pointer: self.pointer.movePointer(self.x, self.y)
109           
110
111        # button press
112        elif msgCode == "2":  # button press
113            btnId = int(tokens[1])
114            isDown = bool(int(tokens[2]))
115           
116            # apply the state change if it's a valid buttonId
117            if btnId <= len(self.buttons):
118                forEvt = 0
119                if btnId == 0:  forEvt = 31000+EVT_PAN
120                elif btnId == 1:  forEvt = 31000+EVT_ROTATE
121                elif btnId == 2:  forEvt = 31000+EVT_ZOOM
122                self.buttons[btnId-1] = isDown
123                self.postEvtClick(self.x, self.y, btnId, isDown, forEvt)
124                self.clickX, self.clickY = self.x, self.y
125               
126
127        elif msgCode == "3":  # arrow
128            pov = int(tokens[1])
129
130            arrow = -1
131            if pov == 0:
132                arrow = UP_ARROW
133            elif pov == 9000:
134                arrow = RIGHT_ARROW
135            elif pov == 18000:
136                arrow = DOWN_ARROW
137            elif pov == 27000:
138                arrow = LEFT_ARROW
139               
140            if arrow > -1:
141                self.postEvtArrow(arrow, self.x, self.y)
142               
143
144    def __toSAGEPos(self, xAxis, yAxis):
145       
146        if self.isWiimote:
147            # wiimote is directly mapped to the whole display
148            halfWidth = self.bounds.getWidth()/2.0
149            halfHeight = self.bounds.getHeight()/2.0
150            newX = int( halfWidth + halfWidth*xAxis)
151            newY = int( halfHeight + halfHeight*yAxis)
152            dX = newX - self.x
153            dY = newY - self.y
154        else:
155            dX = int(xAxis * self.joyToMouseRatio * self.displayFactor)
156            dY = int(yAxis * self.joyToMouseRatio * self.displayFactor) * (-1)  # -1 for reverse
157
158        # make sure the pointer is within display bounds
159        # check left and right (x)
160        if (self.x + dX) > self.bounds.right:
161            dX = self.bounds.right - self.x
162        elif (self.x + dX) < self.bounds.left:
163            dX = -self.x
164
165        # check top and bottom (y)
166        if (self.y + dY) > self.bounds.top:
167            dY = self.bounds.top - self.y
168        elif (self.y + dY) < self.bounds.bottom:
169            dY = -self.y
170
171        # update the position
172        self.x += dX
173        self.y += dY
174
175        return dX, dY
176       
177       
Note: See TracBrowser for help on using the repository browser.