svn merge -r 17502:18705 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / gameengine / GameLogic / SCA_MouseSensor.cpp
1 /**
2  * Sensor for mouse input
3  *
4  *
5  * $Id$
6  *
7  * ***** BEGIN GPL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): José I. Romero (cleanup and fixes)
29  *
30  * ***** END GPL LICENSE BLOCK *****
31  */
32
33 #include "SCA_MouseSensor.h"
34 #include "SCA_EventManager.h"
35 #include "SCA_MouseManager.h"
36 #include "SCA_LogicManager.h"
37 #include "SCA_IInputDevice.h"
38 #include "ConstExpr.h"
39 #include <iostream>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 /* ------------------------------------------------------------------------- */
46 /* Native functions                                                          */
47 /* ------------------------------------------------------------------------- */
48
49 SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr, 
50                                                                  int startx,int starty,
51                                                                  short int mousemode,
52                                                                  SCA_IObject* gameobj, 
53                                                                  PyTypeObject* T)
54     : SCA_ISensor(gameobj,eventmgr, T),
55         m_pMouseMgr(eventmgr),
56         m_x(startx),
57         m_y(starty)
58 {
59         m_mousemode   = mousemode;
60         m_triggermode = true;
61
62         UpdateHotkey(this, NULL);
63         Init();
64 }
65
66 void SCA_MouseSensor::Init()
67 {
68         m_val = (m_invert)?1:0; /* stores the latest attribute */
69         m_reset = true;
70 }
71
72 SCA_MouseSensor::~SCA_MouseSensor() 
73 {
74     /* Nothing to be done here. */
75 }
76
77 int SCA_MouseSensor::UpdateHotkey(void *self, const PyAttributeDef*)
78 {
79         // gosh, this function is so damn stupid
80         // its here because of a design mistake in the mouse sensor, it should only
81         // have 3 trigger modes (button, wheel, move), and let the user set the 
82         // hotkey separately, like the other sensors. but instead it has a mode for 
83         // each friggin key and i have to update the hotkey based on it... genius!
84         SCA_MouseSensor* sensor = reinterpret_cast<SCA_MouseSensor*>(self);
85
86         switch (sensor->m_mousemode) {
87         case KX_MOUSESENSORMODE_LEFTBUTTON:
88                 sensor->m_hotkey = SCA_IInputDevice::KX_LEFTMOUSE;
89                 break;
90         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
91                 sensor->m_hotkey = SCA_IInputDevice::KX_MIDDLEMOUSE;
92                 break;
93         case KX_MOUSESENSORMODE_RIGHTBUTTON:
94                 sensor->m_hotkey = SCA_IInputDevice::KX_RIGHTMOUSE;
95                 break;
96         case KX_MOUSESENSORMODE_WHEELUP:
97                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELUPMOUSE;
98                 break;
99         case KX_MOUSESENSORMODE_WHEELDOWN:
100                 sensor->m_hotkey = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
101                 break;
102         default:
103                 ; /* ignore, no hotkey */
104         }
105         // return value is used in _setattr(), 
106         // 0=attribute checked ok (see Attributes array definition)
107         return 0;
108 }
109
110 CValue* SCA_MouseSensor::GetReplica()
111 {
112         SCA_MouseSensor* replica = new SCA_MouseSensor(*this);
113         // this will copy properties and so on...
114         CValue::AddDataToReplica(replica);
115         replica->Init();
116
117         return replica;
118 }
119
120
121
122 bool SCA_MouseSensor::IsPositiveTrigger()
123 {
124         bool result = (m_val != 0);
125         if (m_invert)
126                 result = !result;
127                 
128         return result;
129 }
130
131
132
133 short int SCA_MouseSensor::GetModeKey()
134
135         return m_mousemode;
136 }
137
138
139
140 SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
141
142         return m_hotkey;
143 }
144
145
146
147 bool SCA_MouseSensor::Evaluate(CValue* event)
148 {
149         bool result = false;
150         bool reset = m_reset && m_level;
151         SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
152
153         m_reset = false;
154         switch (m_mousemode) {
155         case KX_MOUSESENSORMODE_LEFTBUTTON:
156         case KX_MOUSESENSORMODE_MIDDLEBUTTON:
157         case KX_MOUSESENSORMODE_RIGHTBUTTON:
158         case KX_MOUSESENSORMODE_WHEELUP:
159         case KX_MOUSESENSORMODE_WHEELDOWN:
160                 {
161                         const SCA_InputEvent& event = mousedev->GetEventValue(m_hotkey);
162                         switch (event.m_status){        
163                         case SCA_InputEvent::KX_JUSTACTIVATED:
164                                 m_val = 1;
165                                 result = true;
166                                 break;
167                         case SCA_InputEvent::KX_JUSTRELEASED:
168                                 m_val = 0;
169                                 result = true;
170                                 break;
171                         case SCA_InputEvent::KX_ACTIVE:
172                                 if (m_val == 0)
173                                 {
174                                         m_val = 1;
175                                         if (m_level)
176                                                 result = true;
177                                 }
178                                 break;
179                         default:
180                                 if (m_val == 1)
181                                 {
182                                         m_val = 0;
183                                         result = true;
184                                 }
185                                 break;
186                         }
187                         break;
188                 }
189         case KX_MOUSESENSORMODE_MOVEMENT:
190                 {
191                         const SCA_InputEvent& eventX = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
192                         const SCA_InputEvent& eventY = mousedev->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
193
194                         if (eventX.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
195                                 eventY.m_status == SCA_InputEvent::KX_JUSTACTIVATED ||
196                                 eventX.m_status == SCA_InputEvent::KX_ACTIVE ||
197                                 eventY.m_status == SCA_InputEvent::KX_ACTIVE)   
198                         {
199                                 m_val = 1;
200                                 result = true;
201                         } 
202                         else if (eventX.m_status == SCA_InputEvent::KX_JUSTRELEASED ||
203                                         eventY.m_status == SCA_InputEvent::KX_JUSTRELEASED )
204                         {
205                                 m_val = 0;
206                                 result = true;
207                         } 
208                         else //KX_NO_IMPUTSTATUS
209                         { 
210                                 if (m_val == 1)
211                                 {
212                                         m_val = 0;
213                                         result = true;
214                                 }
215                         }
216                         
217                         break;
218                 }
219         default:
220                 ; /* error */
221         }
222
223         if (reset)
224                 // force an event
225                 result = true;
226         return result;
227 }
228
229 void SCA_MouseSensor::setX(short x)
230 {
231         m_x = x;
232 }
233
234 void SCA_MouseSensor::setY(short y)
235 {
236         m_y = y;
237 }
238
239 bool SCA_MouseSensor::isValid(SCA_MouseSensor::KX_MOUSESENSORMODE m)
240 {
241         return ((m > KX_MOUSESENSORMODE_NODEF) && (m < KX_MOUSESENSORMODE_MAX));
242 }
243
244 /* ------------------------------------------------------------------------- */
245 /* Python functions                                                          */
246 /* ------------------------------------------------------------------------- */
247
248 //Deprecated functions ------>
249 /* get x position ---------------------------------------------------------- */
250 const char SCA_MouseSensor::GetXPosition_doc[] = 
251 "getXPosition\n"
252 "\tReturns the x-coordinate of the mouse sensor, in frame coordinates.\n"
253 "\tThe lower-left corner is the origin. The coordinate is given in\n"
254 "\tpixels\n";
255 PyObject* SCA_MouseSensor::PyGetXPosition(PyObject* self, 
256                                                                                  PyObject* args, 
257                                                                                  PyObject* kwds) {
258         ShowDeprecationWarning("getXPosition()", "the position property");
259         return PyInt_FromLong(m_x);
260 }
261
262 /* get y position ---------------------------------------------------------- */
263 const char SCA_MouseSensor::GetYPosition_doc[] = 
264 "getYPosition\n"
265 "\tReturns the y-coordinate of the mouse sensor, in frame coordinates.\n"
266 "\tThe lower-left corner is the origin. The coordinate is given in\n"
267 "\tpixels\n";
268 PyObject* SCA_MouseSensor::PyGetYPosition(PyObject* self, 
269                                                                                  PyObject* args, 
270                                                                                  PyObject* kwds) {
271         ShowDeprecationWarning("getYPosition()", "the position property");
272         return PyInt_FromLong(m_y);
273 }
274 //<----- Deprecated
275
276 KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus,
277 "getButtonStatus(button)\n"
278 "\tGet the given button's status (KX_NO_INPUTSTATUS, KX_JUSTACTIVATED, KX_ACTIVE or KX_JUSTRELEASED).\n")
279 {
280         if (PyInt_Check(value))
281         {
282                 int button = PyInt_AsLong(value);
283                 
284                 if ((button < SCA_IInputDevice::KX_LEFTMOUSE)
285                         || (button > SCA_IInputDevice::KX_MIDDLEMOUSE)){
286                         PyErr_SetString(PyExc_ValueError, "invalid button specified!");
287                         return NULL;
288                 }
289                 
290                 SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
291                 const SCA_InputEvent& event = mousedev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) button);
292                 return PyInt_FromLong(event.m_status);
293         }
294         
295         Py_Return;
296 }
297
298 /* ------------------------------------------------------------------------- */
299 /* Python Integration Hooks                                                  */
300 /* ------------------------------------------------------------------------- */
301
302 PyTypeObject SCA_MouseSensor::Type = {
303         PyObject_HEAD_INIT(&PyType_Type)
304         0,
305         "SCA_MouseSensor",
306         sizeof(SCA_MouseSensor),
307         0,
308         PyDestructor,
309         0,
310         __getattr,
311         __setattr,
312         0, //&MyPyCompare,
313         __repr,
314         0, //&cvalue_as_number,
315         0,
316         0,
317         0,
318         0
319 };
320
321 PyParentObject SCA_MouseSensor::Parents[] = {
322         &SCA_MouseSensor::Type,
323         &SCA_ISensor::Type,
324         &SCA_ILogicBrick::Type,
325         &CValue::Type,
326         NULL
327 };
328
329 PyMethodDef SCA_MouseSensor::Methods[] = {
330         //Deprecated functions ------>
331         {"getXPosition", (PyCFunction) SCA_MouseSensor::sPyGetXPosition, METH_VARARGS, (PY_METHODCHAR)GetXPosition_doc},
332         {"getYPosition", (PyCFunction) SCA_MouseSensor::sPyGetYPosition, METH_VARARGS, (PY_METHODCHAR)GetYPosition_doc},
333         //<----- Deprecated
334         KX_PYMETHODTABLE_O(SCA_MouseSensor, getButtonStatus),
335         {NULL,NULL} //Sentinel
336 };
337
338 PyAttributeDef SCA_MouseSensor::Attributes[] = {
339         KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkey),
340         KX_PYATTRIBUTE_SHORT_ARRAY_RO("position",SCA_MouseSensor,m_x,2),
341         { NULL }        //Sentinel
342 };
343
344 PyObject* SCA_MouseSensor::_getattr(const STR_String& attr) 
345 {
346         PyObject* object = _getattr_self(Attributes, this, attr);
347         if (object != NULL)
348                 return object;
349         _getattr_up(SCA_ISensor);
350 }
351
352 int SCA_MouseSensor::_setattr(const STR_String& attr, PyObject *value)
353 {
354         int ret = _setattr_self(Attributes, this, attr, value);
355         if (ret >= 0)
356                 return ret;
357         return SCA_ISensor::_setattr(attr, value);
358 }
359
360 /* eof */