1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 /*!
34 \class SoEvent SoEvent.h Inventor/events/SoEvent.h
35 \brief The SoEvent class is the base class for all Coin events.
36
37 \ingroup events
38
39 Coin contains its own set of event classes, independent of the underlying
40 window system.
41
42 Upon system specific events, a translation is done by the window
43 specific device classes into one of the Coin event object classes
44 listed below. The event is then typically sent by the render area
45 to an SoSceneManager which will apply it to the scenegraph through
46 an SoHandleEventAction.
47
48 Events may be caught by the user by attaching an SoEventCallback
49 node to the scenegraph, or it can automatically be handled by a
50 dragger or manipulator in the graph.
51
52 \sa SoButtonEvent, SoKeyboardEvent, SoLocation2Event, SoMotion3Event
53 \sa SoMouseButtonEvent, SoSpaceballButtonEvent
54 \sa SoEventCallback, SoHandleEventAction */
55
56 #include <Inventor/events/SoEvent.h>
57
58 #include <cassert>
59
60 #include <Inventor/events/SoMouseButtonEvent.h>
61 #include <Inventor/events/SoKeyboardEvent.h>
62 #include <Inventor/events/SoSpaceballButtonEvent.h>
63 #include <Inventor/events/SoLocation2Event.h>
64 #include <Inventor/events/SoMotion3Event.h>
65 #include <Inventor/SbViewportRegion.h>
66 #include <Inventor/SbName.h>
67
68 #include "tidbitsp.h"
69
70 SO_EVENT_ABSTRACT_SOURCE(SoEvent);
71
72 /*!
73 \fn SoType SoEvent::getClassTypeId(void)
74
75 This static method returns the SoType object associated with objects
76 of this class.
77 */
78
79
80 // FIXME: grab better version of getTypeId() doc from SoBase, SoAction
81 // and / or SoDetail. 20010913 mortene.
82 /*!
83 \fn SoType SoEvent::getTypeId(void) const
84
85 Returns the actual type id of an instantiated object.
86 */
87
88
89 /*!
90 Initialize SoEvent and all it's known subclasses (i.e. all subclasses
91 which are part of the standard classes in the Coin library).
92
93 This method is called from SoDB::init(), so it's very unlikely that
94 you will have to call it explicitly.
95 */
96 void
initClass(void)97 SoEvent::initClass(void)
98 {
99 // Make sure we only initialize once.
100 assert(SoEvent::classTypeId == SoType::badType());
101
102 SoEvent::classTypeId = SoType::createType(SoType::badType(), "SoEvent");
103 coin_atexit(reinterpret_cast<coin_atexit_f *>(cleanupClass), CC_ATEXIT_NORMAL);
104
105 SoEvent::initEvents();
106 }
107
108 /*!
109 \COININTERNAL
110
111 Initialize all known subclasses.
112 */
113 void
initEvents(void)114 SoEvent::initEvents(void)
115 {
116 SoButtonEvent::initClass();
117 SoMouseButtonEvent::initClass();
118 SoKeyboardEvent::initClass();
119 SoSpaceballButtonEvent::initClass();
120 SoLocation2Event::initClass();
121 SoMotion3Event::initClass();
122 }
123
124 /*!
125 Constructor, will set all modifiers to "off" state.
126 */
SoEvent(void)127 SoEvent::SoEvent(void)
128 {
129 this->modifiers.shiftdown = 0;
130 this->modifiers.ctrldown = 0;
131 this->modifiers.altdown = 0;
132 }
133
134 /*!
135 Destructor.
136 */
~SoEvent()137 SoEvent::~SoEvent()
138 {
139 }
140
141 /*!
142 Returns TRUE if this object either has the same type as the given
143 \c type parameter, or if \c type belongs to a superclass of ourselves.
144 */
145 SbBool
isOfType(SoType type) const146 SoEvent::isOfType(SoType type) const
147 {
148 const SoType myType = this->getTypeId();
149 if (myType == type) return TRUE;
150 if (myType.isDerivedFrom(type)) return TRUE;
151 return FALSE;
152 }
153
154 /*!
155 From a system specific device object, set the time the event occurred.
156
157 \sa getTime()
158 */
159 void
setTime(const SbTime t)160 SoEvent::setTime(const SbTime t)
161 {
162 this->timeofevent = t;
163 }
164
165 /*!
166 Returns the time the event occurred.
167
168 \sa getPosition(), wasShiftDown(), wasCtrlDown(), wasAltDown()
169 */
170 SbTime
getTime(void) const171 SoEvent::getTime(void) const
172 {
173 return this->timeofevent;
174 }
175
176 /*!
177 From a system specific device object, set the mouse pointer position
178 when the event occurred.
179
180 \sa getPosition(), getNormalizedPosition()
181 */
182 void
setPosition(const SbVec2s & p)183 SoEvent::setPosition(const SbVec2s & p)
184 {
185 this->positionofevent = p;
186 }
187
188 // FIXME: "window" below is ambiguous, replace with something less
189 // generic, like e.g. "the rendering canvas" or some such. Should also
190 // scan API docs for other references to "window" (and "widget"?) and
191 // do likewise. 20040728 mortene.
192 /*!
193 Returns the mouse pointer position when the event occurred. The
194 coordinates are given relative to the window coordinates.
195
196 \sa getNormalizedPosition(), getTime(), wasShiftDown(), wasCtrlDown(),
197 \sa wasAltDown()
198 */
199 const SbVec2s &
getPosition(void) const200 SoEvent::getPosition(void) const
201 {
202 return this->positionofevent;
203 }
204
205 /*!
206 Returns the mouse pointer position when the event occurred. The
207 coordinates are given relative to the viewport coordinates.
208
209 \sa getNormalizedPosition(), getTime(), wasShiftDown(), wasCtrlDown(),
210 \sa wasAltDown()
211 */
212 const SbVec2s &
getPosition(const SbViewportRegion & vpRgn) const213 SoEvent::getPosition(const SbViewportRegion & vpRgn) const
214 {
215 positionVP = SbVec2s(this->positionofevent - vpRgn.getViewportOriginPixels());
216
217 return positionVP;
218 }
219
220 /*!
221 Returns the mouse pointer position when the event occurred. The
222 coordinates are given relative to the viewport coordinates,
223 normalized according to the size of the viewport.
224
225 \sa getPosition(), getTime(), wasShiftDown(), wasCtrlDown(), wasAltDown()
226 */
227 const SbVec2f &
getNormalizedPosition(const SbViewportRegion & vpRgn) const228 SoEvent::getNormalizedPosition(const SbViewportRegion & vpRgn) const
229 {
230 SbVec2s p = this->positionofevent - vpRgn.getViewportOriginPixels();
231 SbVec2s s = vpRgn.getViewportSizePixels();
232
233 positionVPNorm = SbVec2f(
234 static_cast<float>(p[0])/static_cast<float>(s[0]),
235 static_cast<float>(p[1])/static_cast<float>(s[1])
236 );
237
238 return positionVPNorm;
239 }
240
241 /*!
242 From a system specific device object, set the state of the Shift key(s)
243 when the event occurred.
244
245 \sa wasShiftDown(), setCtrlDown(), setAltDown()
246 */
247 void
setShiftDown(SbBool isDown)248 SoEvent::setShiftDown(SbBool isDown)
249 {
250 this->modifiers.shiftdown = isDown ? TRUE : FALSE;
251 }
252
253 /*!
254 Returns state of Shift key(s) when the event occurred.
255
256 \sa wasCtrlDown(), wasAltDown(), getPosition(), getTime()
257 */
258 SbBool
wasShiftDown(void) const259 SoEvent::wasShiftDown(void) const
260 {
261 return this->modifiers.shiftdown;
262 }
263
264 /*!
265 From a system specific device object, set the state of the Ctrl key(s)
266 when the event occurred.
267
268 \sa wasCtrlDown(), setShiftDown(), setAltDown()
269 */
270 void
setCtrlDown(SbBool isDown)271 SoEvent::setCtrlDown(SbBool isDown)
272 {
273 this->modifiers.ctrldown = isDown ? TRUE : FALSE;
274 }
275
276 /*!
277 Returns state of Ctrl key(s) when the event occurred.
278
279 \sa wasShiftDown(), wasAltDown(), getPosition(), getTime()
280 */
281 SbBool
wasCtrlDown(void) const282 SoEvent::wasCtrlDown(void) const
283 {
284 return this->modifiers.ctrldown;
285 }
286
287 /*!
288 From a system specific device object, set the state of the Alt key(s)
289 when the event occurred.
290
291 \sa wasAltDown(), setCtrlDown(), setShiftDown()
292 */
293 void
setAltDown(SbBool isDown)294 SoEvent::setAltDown(SbBool isDown)
295 {
296 this->modifiers.altdown = isDown ? TRUE : FALSE;
297 }
298
299 /*!
300 Returns state of Alt key(s) when the event occurred.
301
302 \sa wasShiftDown(), wasCtrlDown(), getPosition(), getTime()
303 */
304 SbBool
wasAltDown(void) const305 SoEvent::wasAltDown(void) const
306 {
307 return this->modifiers.altdown;
308 }
309