]> icculus.org git repositories - divverent/nexuiz.git/blob - data/scmenu/source/system/events.qc
restructure
[divverent/nexuiz.git] / data / scmenu / source / system / events.qc
1 // DP/Nex menu
2 // system/events.qc
3
4 // debug process output functions
5 bool _menu_process_filtered;
6 void( float pMode, float pSelectState ) _Menu_Process_Debug_Filter =
7 {
8         if( !sys_debug_process )
9                 _menu_process_filtered = false;
10         else if( sys_debug_process_filter )
11                 _menu_process_filtered = (pMode & sys_debug_process_filter);
12         else
13                 _menu_process_filtered = true;
14         if( _menu_process_filtered == MENU_PROCESS_MOUSE && pSelectState == MENU_SELECT_NEVER )
15                 _menu_process_filtered = false;
16 };
17
18 #ifdef USEFUNCTIONS
19 void( string pText ) _Menu_Process_Debug_Print =
20 {
21         if( _menu_process_filtered )
22                 print( pText );
23 };
24 #else
25 #define _Menu_Process_Debug_Print(pText)   if( _menu_process_filtered ) print( pText )
26 #endif
27
28 // process stacks
29
30 void() Menu_Process_Setup =
31 {
32         Menu_Origin = '0 0 0';
33         Menu_Clip_Position = '0 0 0';
34         Menu_Clip_Size = '0 0 0';
35 };
36
37 void( entity pItem ) _Menu_Env_LoadClipArea
38 {
39         Menu_Clip_Position = pItem._cache_clip_pos;
40         Menu_Clip_Size = pItem._cache_clip_size;
41
42         if( sys_debug_mgfx && _menu_process_filtered )
43                 print( "MGFX Loaded clip area = (", vtos( Menu_Clip_Position ), "; ", vtos( Menu_Clip_Size ), ")\n" );
44 };
45
46 void( entity pItem ) _Menu_Env_LoadOrigin =
47 {
48         Menu_Origin = pItem._cache_origin;
49         Menu_Cursor_Position = Cursor_Position - Menu_Origin;
50
51         if( sys_debug_mgfx && _menu_process_filtered )
52                 print( "MGFX Loaded org = ", vtos( Menu_Origin ), "\n" );
53 };
54
55 void( entity pItem ) _Menu_Env_Reload =
56 {
57         Menu_Origin = pItem._cache_origin;
58         Menu_Cursor_Position = Cursor_Position - Menu_Origin;
59         Menu_Clip_Position = pItem._cache_clip_pos;
60         Menu_Clip_Size = pItem._cache_clip_size;
61
62         if( sys_debug_mgfx && _menu_process_filtered )
63                 print( "MGFX Reloaded env for: org = ", vtos( Menu_Origin ), "; clip area = (", vtos( Menu_Clip_Position ), "; ", vtos( Menu_Clip_Size ), ")\n" );
64 };
65
66 void() _MGX_SetClipArea =
67 {
68         if( Menu_Clip_Position == '0 0 0' && Menu_Clip_Size == '0 0 0' )
69                 Gfx_ResetClipArea();
70         else
71                 Gfx_SetClipArea( Menu_Clip_Position_x, Menu_Clip_Position_y, Menu_Clip_Size_x, Menu_Clip_Size_y );
72 };
73
74 void( entity pItem ) _Menu_Env_SetupClipArea
75 {
76         local vector lDelta, lPos, lSize;
77
78         lPos = pItem.pos;
79         lSize = pItem.size;
80         if( lPos != '0 0 0' || lSize != '0 0 0' ) {
81                 if( (Menu_Clip_Position != '0 0 0' || Menu_Clip_Size != '0 0 0') ) {
82                         lPos = Menu_Origin + lPos;
83                         lDelta = Util_GetClipDelta( lPos, Menu_Clip_Position, Menu_Clip_Size );
84                         lPos = lPos + lDelta;
85                         lSize = Util_ClipRect( lPos, lSize - lDelta, Menu_Clip_Position, Menu_Clip_Size );
86                 }
87
88                 Menu_Clip_Position = lPos;
89                 Menu_Clip_Size = lSize;
90         }
91         pItem._cache_clip_pos = Menu_Clip_Position;
92         pItem._cache_clip_size = Menu_Clip_Size;
93
94         if( sys_debug_mgfx && _menu_process_filtered ) {
95                 print( "MGFX Setup clip area: (", vtos( pItem.pos ), "; ", vtos( pItem.size ) );
96                 print( ") clipped to (", vtos( Menu_Clip_Position ), "; ", vtos( Menu_Clip_Size ), ")\n" );
97         }
98 };
99
100 void( entity pItem ) _Menu_Env_SetupOrigin =
101 {
102         Menu_Origin = Menu_Origin + pItem.origin + pItem.pos;
103         pItem._cache_origin = Menu_Origin;
104
105         if( sys_debug_mgfx && _menu_process_filtered )
106                 print( "MGFX Setup org = ", vtos( Menu_Origin ), "\n" );
107 };
108
109 void( entity pItem ) _Menu_ProcessRunFlag =
110 {
111         local entity lChild;
112         local bool lWasHidden;
113         local float lOldRunFlag;
114
115         _Menu_Process_Debug_Print( strcat( "R ", pItem.name, "\n" ) );
116
117         // setup the cache and the Menu_* variables
118         _Menu_Env_SetupClipArea( pItem );
119
120         lWasHidden = Menu_HasRunFlag( pItem, RUNFLAG_HIDDEN );
121
122         lOldRunFlag = pItem._runFlag;
123         Menu_SetRunFlag( pItem );
124
125         // AK LATE: This should speed up things a bit
126         if( /*lOldRunFlag == pItem._runFlag &&*/ lWasHidden && Menu_HasRunFlag( pItem, RUNFLAG_HIDDEN ) ) {
127                 _Menu_Process_Debug_Print( "Aborted branching (RUNFLAG_HIDDEN)\n" );
128                 return;
129         }
130
131         // we adjust the origin for the children
132         _Menu_Env_SetupOrigin( pItem );
133
134         for( lChild = pItem._child ; lChild ; lChild = lChild._next ) {
135                         Menu_InheritRunFlag( pItem, lChild );
136                         _Menu_ProcessRunFlag( lChild );
137                         // reload the cached state
138                         _Menu_Env_Reload( pItem );
139         }
140 };
141
142 void( entity pItem ) _Menu_ProcessDraw =
143 {
144         local entity lChild;
145
146         _Menu_Process_Debug_Print( strcat( "D ", pItem.name, " " ) );
147
148         if( !Menu_IsVisible( pItem ) ) {
149                 _Menu_Process_Debug_Print( "Failed (Not visible)\n" );
150                 return;
151         }
152         _Menu_Process_Debug_Print( "\n" );
153
154         _Menu_Env_LoadClipArea( pItem );
155         _MGX_SetClipArea();
156
157         Raise_Draw( pItem );
158
159         _Menu_Env_LoadOrigin( pItem );
160         for( lChild = pItem._child ; lChild ; lChild = lChild._next ) {
161                 _Menu_ProcessDraw( lChild );
162                 // reload old state
163                 _Menu_Env_Reload( pItem );
164                 _MGX_SetClipArea();
165         }
166 };
167
168 void( entity pItem ) _Menu_ProcessUpdate =
169 {
170         local entity lChild;
171
172         _Menu_Process_Debug_Print( strcat( "U ", pItem.name, " " ) );
173
174         if( Menu_HasRunFlag( pItem, RUNFLAG_CHILDDRAWONLY ) ) {
175                 _Menu_Process_Debug_Print( "Failed (RUNFLAG_CHILDDRAWONLY)\n" );
176                 return;
177         }
178
179         _Menu_Env_LoadClipArea( pItem );
180         Raise_Update( pItem );
181
182         if( Menu_HasRunFlag( pItem, RUNFLAG_HIDDEN ) ) {
183                 _Menu_Process_Debug_Print( "Aborted branching (RUNFLAG_HIDDEN)\n" );
184                 return;
185         }
186         _Menu_Process_Debug_Print( "\n" );
187
188         _Menu_Env_LoadOrigin( pItem );
189         for( lChild = pItem._child ; lChild ; lChild = lChild._next ) {
190                 _Menu_ProcessUpdate( lChild );
191                 _Menu_Env_Reload( lChild );
192         }
193 };
194
195 void( entity pItem, float pSelectMode ) _Menu_ProcessMouse =
196 {
197         local entity lChild;
198
199         if( _menu_process_filtered ) {
200                 print( "M " );
201                 switch( pSelectMode ) {
202                         case MENU_SELECT_SELECTABLE:
203                                 print( "S " );
204                                 break;
205                         case MENU_SELECT_ALWAYS:
206                                 print( "A " );
207                                 break;
208                         case MENU_SELECT_NEVER:
209                                 print( "N " );
210                                 break;
211                 }
212                 print( pItem.name, " " );
213         }
214
215         if( !Menu_IsVisible( pItem ) ) {
216                 _Menu_Process_Debug_Print( "Failed (Not visible)\n" );
217                 return;
218         }
219
220         _Menu_Env_LoadClipArea( pItem );
221         // check if the mouse is even in the clip area
222         if( Util_InRect( Cursor_Position, Menu_Clip_Position, Menu_Clip_Size ) ||
223         ( Menu_Clip_Position == '0 0 0' && Menu_Clip_Size == '0 0 0' ) ) {
224                 pItem._runFlag = pItem._runFlag | RUNFLAG_MOUSEINAREA;
225
226                 if( !Menu_HasRunFlag( pItem, RUNFLAG_HADMOUSE ) && Menu_HasEvents( pItem ) )
227                         Raise_MouseEnter( pItem );
228                 if( pSelectMode != MENU_SELECT_NEVER && Menu_HasFlag( pItem, FLAG_SEALOFFMOUSE ) )
229                         Menu_ActiveItem = null_entity;
230                 if( ( pSelectMode == MENU_SELECT_ALWAYS ) ||
231                     ( Menu_IsSelectable( pItem ) && pSelectMode == MENU_SELECT_SELECTABLE ) )
232                         Menu_ActiveItem = pItem;
233         } else { // if the mouse isnt in the clip area, neither the children will be!
234                 if( Menu_HasRunFlag( pItem, RUNFLAG_HADMOUSE ) && Menu_HasEvents( pItem ) )
235                         Raise_MouseLeave( pItem );
236                 _Menu_Process_Debug_Print( "Aborted branching (Outside the clip area)\n" );
237                 return;
238         }
239         _Menu_Process_Debug_Print( "\n" );
240
241         _Menu_Env_LoadOrigin( pItem );
242         for( lChild = pItem._child ; lChild ; lChild = lChild._next ) {
243                 if( !Menu_HasRunFlag( pItem, RUNFLAG_CHILDDRAWUPDATEONLY ) || !Menu_HasRunFlag( pItem, RUNFLAG_CHILDDRAWONLY ) )
244                         _Menu_ProcessMouse( lChild, pSelectMode );
245                 else
246                         _Menu_ProcessMouse( lChild, MENU_SELECT_NEVER );
247                 _Menu_Env_Reload( pItem );
248         }
249 };
250
251 float( float pRetValue ) _Menu_Process_Debug_Return =
252 {
253         if( _menu_process_filtered )
254                 switch( pRetValue ) {
255                 case MENU_EVENT_NORMAL:
256                 case MENU_EVENT_CONTINUE:
257                         print( "MENU_EVENT_CONTINUE\n" );
258                         break;
259                 case MENU_EVENT_RAISEPARENT:
260                         print( "MENU_EVENT_RAISEPARENT\n" );
261                         break;
262                 case MENU_EVENT_PROCESSED:
263                         print( "MENU_EVENT_PROCESSED\n" );
264                         break;
265                 }
266
267         return pRetValue;
268 };
269
270 float( entity pItem, float pKey, float pAscii ) _Menu_ProcessKey =
271 {
272         local entity lChild;
273         local float lResult;
274
275         _Menu_Process_Debug_Print( strcat( "K ", ftos( pKey ), " ", pItem.name, " " ) );
276         if( Menu_HasRunFlag( pItem, RUNFLAG_CHILDDRAWUPDATEONLY ) || Menu_HasRunFlag( pItem, RUNFLAG_CHILDDRAWONLY ) )
277                 return _Menu_Process_Debug_Return( MENU_EVENT_CONTINUE );
278
279         _Menu_Env_LoadClipArea( pItem );
280
281         if( Menu_ActiveItem == pItem ) {
282                 if( Raise_Key( pItem, pKey, pAscii ) )
283                         lResult = MENU_EVENT_PROCESSED;
284                 else
285                         lResult = MENU_EVENT_RAISEPARENT;
286
287                 return _Menu_Process_Debug_Return( lResult );
288         }
289
290         _Menu_Env_LoadOrigin( pItem );
291         for( lChild = pItem._child ; lChild ; lChild = lChild._next ) {
292                 lResult = _Menu_ProcessKey( lChild, pKey, pAscii );
293                 _Menu_Env_Reload( pItem );
294
295                 if( lResult == MENU_EVENT_PROCESSED )
296                         return _Menu_Process_Debug_Return( MENU_EVENT_PROCESSED );
297                 else if( lResult == MENU_EVENT_RAISEPARENT )
298                         if( Raise_Key( pItem, pKey, pAscii ) )
299                                 return _Menu_Process_Debug_Return( MENU_EVENT_PROCESSED );
300                         else
301                                 return _Menu_Process_Debug_Return( MENU_EVENT_RAISEPARENT );
302         }
303
304         return _Menu_Process_Debug_Return( MENU_EVENT_CONTINUE );
305 };
306
307 float( entity pItem, float pMode, float pSelectMode, float pKey, float pAscii ) Menu_Process =
308 {
309         local vector lSize, lPos, lOrigin;
310         local float lResult;
311
312         lSize = Menu_Clip_Size;
313         lPos = Menu_Clip_Position;
314         lOrigin = Menu_Origin;
315
316         _Menu_Process_Debug_Filter( pMode, pSelectMode );
317
318         lResult = 0;
319         switch( pMode ) {
320                 case MENU_PROCESS_RUNFLAG:
321                         _Menu_ProcessRunFlag( pItem );
322                         break;
323                 case MENU_PROCESS_UPDATE:
324                         _Menu_ProcessUpdate( pItem );
325                         break;
326                 case MENU_PROCESS_DRAW:
327                         _Menu_ProcessDraw( pItem );
328                         break;
329                 case MENU_PROCESS_MOUSE:
330                         _Menu_ProcessMouse( pItem, pSelectMode );
331                         break;
332                 case MENU_PROCESS_KEY:
333                         lResult = _Menu_ProcessKey( pItem, pKey, pAscii );
334                         break;
335         }
336
337         Menu_Clip_Size = lSize;
338         Menu_Clip_Position = lPos;
339         Menu_Origin = lOrigin;
340         Menu_Cursor_Position = Cursor_Position - Menu_Origin;
341         if( pMode == MENU_PROCESS_DRAW )
342                 _MGX_SetClipArea();
343
344         return lResult;
345 };
346
347 void() Menu_Frame =
348 {
349         Sys_Debug_Frame();
350         if( sys_debug_halt ) {
351                 return;
352         }
353
354         Menu_UpdateRunFlags();
355
356         Menu_Process_Setup();
357         // if mouse was moved, select an item
358         if( Cursor_Relative != '0 0 0' ) {
359                 local entity lOld;
360
361                 lOld = Menu_ActiveItem;
362                 Menu_ProcessMouse( Menu_ActiveWindow, MENU_SELECT_SELECTABLE );
363
364                 if( !Menu_ActiveItem )
365                         Menu_ActiveItem = lOld;
366                 else if( lOld != Menu_ActiveItem ) {
367                         Raise_Select( lOld, false, true );
368                         Raise_Select( Menu_ActiveItem, true, true );
369                 }
370         } else // just update mouseinarea
371                 Menu_ProcessMouse( Menu_ActiveWindow, MENU_SELECT_NEVER );
372
373         // process the update event
374         Menu_Process_Setup();
375         Menu_ProcessUpdate( Menu_ActiveWindow, MENU_PROCESS_UPDATE );
376
377
378         Menu_CollectGarbage( false );
379 }
380
381 void() Menu_Draw =
382 {
383         if( sys_debug_halt ) {
384                 return;
385         }
386         // if Menu_ActiveWindow is visible loop though it
387         if( Menu_IsVisible( Menu_ActiveWindow ) )
388         {
389                 Menu_Process_Setup();
390                 Menu_ProcessDraw( Menu_ActiveWindow );
391         }
392
393         Sys_Debug_Draw();
394 };
395
396 void( float pKey, float pAscii) Menu_Key =
397 {
398         if( sys_debug_halt ) {
399                 return;
400         }
401
402         // is a keyhook set ?
403         if( Menu_KeyHook != Util_NullFunction ) {
404                 // call it
405                 Menu_KeyHook( pKey, pAscii );
406                 return;
407         }
408         // before calling the current keydown functions, process the mouse again
409         // to make sure the correct item is called
410         // (except mouse wheel up and down)
411         // if the mouse doesnt point to an item, there wont be a reaction on the clicking
412         if(K_MOUSE1 <= pKey && pKey <= K_MOUSE10) {
413                 local entity lOld;
414
415                 lOld = Menu_ActiveItem;
416                 Menu_ActiveItem = null_entity;
417                 Menu_ProcessMouse( Menu_ActiveWindow, MENU_SELECT_SELECTABLE );
418
419                 if( !Menu_ActiveItem ) {
420                         Menu_ActiveItem = lOld;
421                         return;
422                 } else if( lOld != Menu_ActiveItem ) {
423                         Raise_Select( lOld, false, true );
424                         Raise_Select( Menu_ActiveItem, true, true );
425                 }
426         }
427
428         // call current selected keydown function
429         // if nothing is selected -> window has no items -> call window key
430         if(Menu_ActiveItem == null_entity)
431                 Menu_Reselect( false );
432
433         if( ( !Menu_IsSelectable( Menu_ActiveItem ) && Menu_ActiveItem != Menu_ActiveWindow ) ||
434              Menu_ProcessKey( Menu_ActiveWindow, pKey, pAscii ) != MENU_EVENT_PROCESSED )
435                 // If it goes really wrong:
436                 if( pKey == K_ESCAPE )
437                         if( gamestatus & GAME_DEVELOPER )
438                                 error( " K_ESCAPE wasnt processed!\n" );
439                         else {
440                                 Menu_Toggle();
441                                 cmd( "menu_restart\n" );
442                         }
443                 else if( gamestatus & GAME_DEVELOPER ) {
444                         print( " Key ", ftos( pKey ), " ('" );
445                         print( chr( pAscii ), "') wasn't processed!\n" );
446                 }
447 };
448
449 bool() Menu_Toggle =
450 {
451         // only let the qc toggle the menu if we are ingame or a developer
452         if( gamestatus & GAME_CONNECTED || gamestatus & GAME_DEVELOPER ) {
453                 // then allow toggling
454                 m_hide();
455                 return true;
456         } else
457                 return false;
458 };