Sort include order.
[gemrb.git] / gemrb / core / EventMgr.cpp
blob4cf59b67e315c261060852ec00e655a9e3f08172
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.
21 #include "EventMgr.h"
23 #include "win32def.h"
25 #include "GameControl.h"
26 #include "Interface.h"
27 #include "Video.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
35 last_win_over = NULL;
36 MButtons = 0;
37 dc_x = 0;
38 dc_y = 0;
39 dc_time = 0;
40 dc_delay = 250;
41 rk_delay = 250;
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) {
54 topwin.erase( t );
55 break;
58 if (topwin.size() != 0) {
59 topwin.insert( topwin.begin(), Index );
60 } else {
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));
71 last_win_over = NULL;
74 /** Adds a Window to the Event Manager */
75 void EventMgr::AddWindow(Window* win)
77 unsigned int i;
79 if (win == NULL) {
80 return;
82 bool found = false;
83 for (i = 0; i < windows.size(); i++) {
84 if (windows[i] == win) {
85 goto ok;
87 if(windows[i]==NULL) {
88 windows[i] = win;
89 ok:
90 SetOnTop( i );
91 found = true;
92 break;
95 if (!found) {
96 windows.push_back( win );
97 if (windows.size() == 1)
98 topwin.push_back( 0 );
99 else
100 SetOnTop( ( int ) windows.size() - 1 );
102 SetDefaultFocus(win);
104 /** Frees and Removes all the Windows in the Array */
105 void EventMgr::Clear()
107 topwin.clear();
108 windows.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) {
129 return;
131 int pos = -1;
132 std::vector< Window*>::iterator m;
133 for (m = windows.begin(); m != windows.end(); ++m) {
134 pos++;
135 if ( (*m) == win) {
136 (*m) = NULL;
137 std::vector< int>::iterator t;
138 for (t = topwin.begin(); t != topwin.end(); ++t) {
139 if ( (*t) == pos) {
140 topwin.erase( t );
141 return;
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) {
153 return;
155 if (!last_win_focused) {
156 return;
158 GameControl *gc = core->GetGameControl();
159 if (gc) {
160 // for scrolling
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) {
166 m = windows.begin();
167 m += ( *t );
168 Window *win = *m;
169 if (win == NULL)
170 continue;
171 if (!win->Visible)
172 continue;
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)
181 if (ctrl == NULL) {
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 );
187 if (last_win_over) {
188 last_win_over->OnMouseLeave( x, y );
190 last_win_over = win;
191 win->OnMouseEnter( x, y, ctrl );
193 if (ctrl != NULL) {
194 win->OnMouseOver( x, y );
196 RefreshCursor(win->Cursor);
197 return;
200 //stop going further
201 if (( *m )->Visible == WINDOW_FRONT)
202 break;
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);
212 } else {
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;
226 return true;
229 /** BroadCast Mouse Move Event */
230 void EventMgr::MouseDown(unsigned short x, unsigned short y, unsigned short Button,
231 unsigned short Mod)
233 std::vector< int>::iterator t;
234 std::vector< Window*>::iterator m;
235 Control *ctrl;
236 unsigned long thisTime;
238 GetTime( thisTime );
239 if (ClickMatch(x, y, thisTime)) {
240 Button |= GEM_MB_DOUBLECLICK;
241 dc_x = 0;
242 dc_y = 0;
243 dc_time = 0;
244 } else {
245 dc_x = x;
246 dc_y = y;
247 dc_time = thisTime+dc_delay;
249 MButtons |= Button;
250 for (t = topwin.begin(); t != topwin.end(); ++t) {
251 m = windows.begin();
252 m += ( *t );
253 if (( *m ) == NULL)
254 continue;
255 if (!( *m )->Visible)
256 continue;
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 );
264 if (!ctrl) {
265 ctrl = ( *m )->GetControl( x, y, false);
267 last_win_mousefocused = *m;
268 if (ctrl != NULL) {
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 );
271 return;
275 if (( *m )->Visible == WINDOW_FRONT) //stop looking further
276 break;
279 if ((Button == GEM_MB_SCRLUP || Button == GEM_MB_SCRLDOWN) && last_win_mousefocused) {
280 ctrl = last_win_mousefocused->GetScrollControl();
281 if (ctrl) {
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,
292 unsigned short Mod)
294 MButtons &= ~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();
326 return;
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) {
336 return;
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();
344 if (ctrl != NULL) {
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
359 if (!ctrl) {
360 ctrl = last_win_focused->GetFocus();
362 //if one is under focus, use the default scroll focus
363 if (!ctrl) {
364 if (Key == GEM_UP || Key == GEM_DOWN) {
365 ctrl = last_win_focused->GetScrollControl();
368 if (ctrl) {
369 switch (ctrl->ControlType) {
370 //scrollbars will receive only mousewheel events
371 case IE_GUI_SCROLLBAR:
372 if (Key != GEM_UP && Key != GEM_DOWN) {
373 return;
375 break;
376 //buttons will receive only GEM_RETURN
377 case IE_GUI_BUTTON:
378 if (Key != GEM_RETURN && Key!=GEM_ESCAPE) {
379 return;
381 break;
382 case IE_GUI_GAMECONTROL:
383 //gamecontrols will receive all special keys
384 break;
385 case IE_GUI_EDIT:
386 case IE_GUI_TEXTAREA:
387 //editboxes and textareas will receive all special keys
388 break;
389 default:
390 //other controls don't receive any
391 return;
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)
402 int x,y;
403 core->GetVideoDriver()->GetMousePos(x,y);
404 MouseMove((unsigned short) x, (unsigned short) y);
407 void EventMgr::SetDCDelay(unsigned long t)
409 dc_delay = t;
412 void EventMgr::SetRKDelay(unsigned long t)
414 rk_delay = 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;
422 return rk_delay;
425 unsigned long EventMgr::SetRKFlags(unsigned long arg, unsigned int op)
427 unsigned long tmp = rk_flags;
428 switch (op) {
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;
436 rk_flags=tmp;
437 return rk_flags;