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