1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include "GameControl.h"
26 #include "Interface.h"
29 EventMgr::EventMgr(void)
31 last_win_focused
= NULL
;
32 // Last window focused for mouse events (eg, with a click). Used to determine MouseUp events
33 last_win_mousefocused
= NULL
;
34 // Last window we were over. Used to determine MouseEnter and MouseLeave events
42 rk_flags
= GEM_RK_DISABLE
;
45 EventMgr::~EventMgr(void)
49 void EventMgr::SetOnTop(int Index
)
51 std::vector
< int>::iterator t
;
52 for (t
= topwin
.begin(); t
!= topwin
.end(); ++t
) {
53 if (( *t
) == Index
) {
58 if (topwin
.size() != 0) {
59 topwin
.insert( topwin
.begin(), Index
);
61 topwin
.push_back( Index
);
65 void EventMgr::SetDefaultFocus(Window
*win
)
67 if (!last_win_focused
) {
68 last_win_focused
= win
;
69 last_win_focused
->SetFocused(last_win_focused
->GetControl(0));
74 /** Adds a Window to the Event Manager */
75 void EventMgr::AddWindow(Window
* win
)
83 for (i
= 0; i
< windows
.size(); i
++) {
84 if (windows
[i
] == win
) {
87 if(windows
[i
]==NULL
) {
96 windows
.push_back( win
);
97 if (windows
.size() == 1)
98 topwin
.push_back( 0 );
100 SetOnTop( ( int ) windows
.size() - 1 );
102 SetDefaultFocus(win
);
104 /** Frees and Removes all the Windows in the Array */
105 void EventMgr::Clear()
109 last_win_focused
= NULL
;
110 last_win_mousefocused
= NULL
;
111 last_win_over
= NULL
;
114 /** Remove a Window from the array */
115 void EventMgr::DelWindow(Window
*win
)
116 //unsigned short WindowID, const char *WindowPack)
118 if (last_win_focused
== win
) {
119 last_win_focused
= NULL
;
121 if (last_win_mousefocused
== win
) {
122 last_win_mousefocused
= NULL
;
124 if (last_win_over
== win
) {
125 last_win_over
= NULL
;
128 if (windows
.size() == 0) {
132 std::vector
< Window
*>::iterator m
;
133 for (m
= windows
.begin(); m
!= windows
.end(); ++m
) {
137 std::vector
< int>::iterator t
;
138 for (t
= topwin
.begin(); t
!= topwin
.end(); ++t
) {
144 printMessage("EventManager","Couldn't find window",YELLOW
);
149 /** BroadCast Mouse Move Event */
150 void EventMgr::MouseMove(unsigned short x
, unsigned short y
)
152 if (windows
.size() == 0) {
155 if (!last_win_focused
) {
158 GameControl
*gc
= core
->GetGameControl();
161 gc
->OnGlobalMouseMove(x
, y
);
163 std::vector
< int>::iterator t
;
164 std::vector
< Window
*>::iterator m
;
165 for (t
= topwin
.begin(); t
!= topwin
.end(); ++t
) {
173 if (( win
->XPos
<= x
) && ( win
->YPos
<= y
)) {
174 //Maybe we are on the window, let's check
175 if (( win
->XPos
+ win
->Width
>= x
) &&
176 ( win
->YPos
+ win
->Height
>= y
)) {
177 //Yes, we are on the Window
178 //Let's check if we have a Control under the Mouse Pointer
179 Control
* ctrl
= win
->GetControl( x
, y
, true );
180 //look for the low priority flagged controls (mostly static labels)
182 ctrl
= win
->GetControl( x
, y
, false );
184 if (win
!= last_win_over
|| ctrl
!= win
->GetOver()) {
185 // Remove tooltip if mouse moved to different control
186 core
->DisplayTooltip( 0, 0, NULL
);
188 last_win_over
->OnMouseLeave( x
, y
);
191 win
->OnMouseEnter( x
, y
, ctrl
);
194 win
->OnMouseOver( x
, y
);
196 RefreshCursor(win
->Cursor
);
201 if (( *m
)->Visible
== WINDOW_FRONT
)
204 core
->DisplayTooltip( 0, 0, NULL
);
207 void EventMgr::RefreshCursor(int idx
)
209 Video
*video
= core
->GetVideoDriver();
210 if (idx
&IE_CURSOR_GRAY
) {
211 video
->SetMouseGrayed(true);
213 video
->SetMouseGrayed(false);
215 idx
&= IE_CURSOR_MASK
;
216 video
->SetCursor( core
->Cursors
[idx
], core
->Cursors
[idx
^ 1] );
219 bool EventMgr::ClickMatch(unsigned short x
, unsigned short y
, unsigned long thisTime
)
221 if (dc_x
+10<x
) return false;
222 if (dc_x
>x
+10) return false;
223 if (dc_y
+10<y
) return false;
224 if (dc_y
>y
+10) return false;
225 if (dc_time
<thisTime
) return false;
229 /** BroadCast Mouse Move Event */
230 void EventMgr::MouseDown(unsigned short x
, unsigned short y
, unsigned short Button
,
233 std::vector
< int>::iterator t
;
234 std::vector
< Window
*>::iterator m
;
236 unsigned long thisTime
;
239 if (ClickMatch(x
, y
, thisTime
)) {
240 Button
|= GEM_MB_DOUBLECLICK
;
247 dc_time
= thisTime
+dc_delay
;
250 for (t
= topwin
.begin(); t
!= topwin
.end(); ++t
) {
255 if (!( *m
)->Visible
)
257 if (( ( *m
)->XPos
<= x
) && ( ( *m
)->YPos
<= y
)) {
258 //Maybe we are on the window, let's check
259 if (( ( *m
)->XPos
+ ( *m
)->Width
>= x
) &&
260 ( ( *m
)->YPos
+ ( *m
)->Height
>= y
)) {
261 //Yes, we are on the Window
262 //Let's check if we have a Control under the Mouse Pointer
263 ctrl
= ( *m
)->GetControl( x
, y
, true );
265 ctrl
= ( *m
)->GetControl( x
, y
, false);
267 last_win_mousefocused
= *m
;
269 last_win_mousefocused
->SetMouseFocused( ctrl
);
270 ctrl
->OnMouseDown( x
- last_win_mousefocused
->XPos
- ctrl
->XPos
, y
- last_win_mousefocused
->YPos
- ctrl
->YPos
, Button
, Mod
);
275 if (( *m
)->Visible
== WINDOW_FRONT
) //stop looking further
279 if ((Button
== GEM_MB_SCRLUP
|| Button
== GEM_MB_SCRLDOWN
) && last_win_mousefocused
) {
280 ctrl
= last_win_mousefocused
->GetScrollControl();
282 ctrl
->OnMouseDown( x
- last_win_mousefocused
->XPos
- ctrl
->XPos
, y
- last_win_mousefocused
->YPos
- ctrl
->YPos
, Button
, Mod
);
286 if (last_win_mousefocused
) {
287 last_win_mousefocused
->SetMouseFocused(NULL
);
290 /** BroadCast Mouse Up Event */
291 void EventMgr::MouseUp(unsigned short x
, unsigned short y
, unsigned short Button
,
295 if (last_win_mousefocused
== NULL
) return;
296 Control
*last_ctrl_mousefocused
= last_win_mousefocused
->GetMouseFocus();
297 if (last_ctrl_mousefocused
== NULL
) return;
298 last_ctrl_mousefocused
->OnMouseUp( x
- last_win_mousefocused
->XPos
- last_ctrl_mousefocused
->XPos
,
299 y
- last_win_mousefocused
->YPos
- last_ctrl_mousefocused
->YPos
, Button
, Mod
);
302 /** BroadCast Mouse Idle Event */
303 void EventMgr::MouseIdle(unsigned long /*time*/)
305 if (last_win_over
== NULL
) return;
306 Control
*ctrl
= last_win_over
->GetOver();
307 if (ctrl
== NULL
) return;
308 ctrl
->DisplayTooltip();
311 /** BroadCast Key Press Event */
312 void EventMgr::KeyPress(unsigned char Key
, unsigned short Mod
)
314 if (last_win_focused
== NULL
) return;
315 Control
*ctrl
= last_win_focused
->GetFocus();
316 if (ctrl
== NULL
) return;
317 ctrl
->OnKeyPress( Key
, Mod
);
319 /** BroadCast Key Release Event */
320 void EventMgr::KeyRelease(unsigned char Key
, unsigned short Mod
)
322 if (last_win_focused
== NULL
) return;
323 Control
*ctrl
= last_win_focused
->GetFocus();
324 if (Key
== GEM_GRAB
) {
325 core
->GetVideoDriver()->ToggleGrabInput();
328 if (ctrl
== NULL
) return;
329 ctrl
->OnKeyRelease( Key
, Mod
);
332 /** Special Key Press Event */
333 void EventMgr::OnSpecialKeyPress(unsigned char Key
)
335 if (!last_win_focused
) {
338 Control
*ctrl
= NULL
;
340 // tab shows tooltips
341 if (Key
== GEM_TAB
) {
342 if (last_win_over
!= NULL
) {
343 Control
*ctrl
= last_win_over
->GetOver();
345 ctrl
->DisplayTooltip();
349 //the default control will get only GEM_RETURN
350 else if (Key
== GEM_RETURN
) {
351 ctrl
= last_win_focused
->GetDefaultControl(0);
353 //the default cancel control will get only GEM_ESCAPE
354 else if (Key
== GEM_ESCAPE
) {
355 ctrl
= last_win_focused
->GetDefaultControl(1);
358 //if there was no default button set, then the current focus will get it
360 ctrl
= last_win_focused
->GetFocus();
362 //if one is under focus, use the default scroll focus
364 if (Key
== GEM_UP
|| Key
== GEM_DOWN
) {
365 ctrl
= last_win_focused
->GetScrollControl();
369 switch (ctrl
->ControlType
) {
370 //scrollbars will receive only mousewheel events
371 case IE_GUI_SCROLLBAR
:
372 if (Key
!= GEM_UP
&& Key
!= GEM_DOWN
) {
376 //buttons will receive only GEM_RETURN
378 if (Key
!= GEM_RETURN
&& Key
!=GEM_ESCAPE
) {
382 case IE_GUI_GAMECONTROL
:
383 //gamecontrols will receive all special keys
386 case IE_GUI_TEXTAREA
:
387 //editboxes and textareas will receive all special keys
390 //other controls don't receive any
393 ctrl
->OnSpecialKeyPress( Key
);
397 void EventMgr::SetFocused(Window
*win
, Control
*ctrl
)
399 last_win_focused
= win
;
400 last_win_focused
->SetFocused(ctrl
);
401 //this is to refresh changing mouse cursors should the focus change)
403 core
->GetVideoDriver()->GetMousePos(x
,y
);
404 MouseMove((unsigned short) x
, (unsigned short) y
);
407 void EventMgr::SetDCDelay(unsigned long t
)
412 void EventMgr::SetRKDelay(unsigned long t
)
417 unsigned long EventMgr::GetRKDelay()
419 if (rk_flags
&GEM_RK_DISABLE
) return (unsigned long) ~0;
420 if (rk_flags
&GEM_RK_DOUBLESPEED
) return rk_delay
/2;
421 if (rk_flags
&GEM_RK_QUADRUPLESPEED
) return rk_delay
/4;
425 unsigned long EventMgr::SetRKFlags(unsigned long arg
, unsigned int op
)
427 unsigned long tmp
= rk_flags
;
429 case BM_SET
: tmp
= arg
; break;
430 case BM_OR
: tmp
|= arg
; break;
431 case BM_NAND
: tmp
&= ~arg
; break;
432 case BM_XOR
: tmp
^= arg
; break;
433 case BM_AND
: tmp
&= arg
; break;
434 default: tmp
= 0; break;