]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu/system/isframe.qc
Add a gecko control to the scmenu, too.
[divverent/nexuiz.git] / data / qcsrc / menu / system / isframe.qc
1 // DP/Nex Menu
2 // system/isframe.qc
3
4 void() Menu_Init =
5 {
6         //registercvar("menu_reloadlist","0");
7
8         Sys_Debug_Init();
9         // do one frame to make it possible to debug the parser
10         Sys_Debug_Frame();
11
12         Campaign_Init();
13
14         Menu_InitGarbageStats();
15         Menu_Load();
16 };
17
18 void() Menu_Load =
19 {
20         Parser_ParseMenu( MENU_MAINFILE, MENU_PLUGINDIR );
21
22         Menu_LinkWindows();
23 };
24
25 // the good thing is, finddef doesnt fuck up any chain lists
26 entity(entity pStart, .string pFind1, string pMatch, .float pFind2, float pMatch2) finddef =
27 {
28         while( 1 ) {
29                 pStart = findstring( pStart, pFind1, pMatch );
30                 if( pStart == null_entity )
31                         break;
32                 if( pStart.pFind2 == pMatch2 )
33                         break;
34         }
35
36         return pStart;
37 };
38
39 void( entity pParent ) Menu_LinkChildren =
40 {
41         local entity lChild;
42         local float  lOrder;
43         local entity lPrevious;
44
45         // build a list of all children
46         lChild = findchainstring( parent, pParent.name );
47         if( lChild == null_entity )
48                 return;
49
50         // inverse the chain
51         lPrevious = null_entity;
52         while( lChild ) {
53                 local entity lNext;
54
55                 lNext = lChild.chain;
56                 lChild.chain = lPrevious;
57                 lPrevious = lChild;
58                 lChild = lNext;
59         }
60         lChild = lPrevious;
61
62         lOrder = 1; // we start with orderPos 1 (0 is auto-set)
63         lPrevious = null_entity;
64         while( lChild ) {
65                 local entity lOverwrite;
66                 // try to find an item that has the current orderPos set
67                 lOverwrite = finddef( null_entity, parent, pParent.name, orderPos, lOrder );
68                 if( lOverwrite == lChild )
69                         lChild.orderPos = lOrder;
70                 else if( lOverwrite ) {
71                         // insert lOverwrite in front of lChild
72                         local entity lOPrevious;
73
74                         lOPrevious = findentity( null_entity, chain, lOverwrite );
75                         lOPrevious.chain = lOverwrite.chain;
76                         lOverwrite.chain = lChild;
77                         lChild = lOverwrite;
78                 } else
79                         lChild.orderPos = 0 - lOrder; //INFO: HACK: tell Spike
80
81                 // link it
82                 if( lPrevious )
83                         lPrevious._next = lChild;
84                 else
85                         pParent._child = lChild;
86                 lChild._prev = lPrevious;
87                 lChild._parent = pParent;
88
89                 lPrevious = lChild;
90                 lChild = lChild.chain;
91                 lOrder++;
92         }
93         lPrevious._next = null_entity;
94 };
95
96 void() Menu_LinkWindows =
97 {
98         // first verify that MENU_NORMAL_NAME and MENU_INGAME_NAME exist
99         // if not add the default strings
100         local entity lEntity;
101
102         dprint( "Loading defaults if necessary\n" );
103
104         lEntity = findstring( null_entity, name, MENU_NORMAL_NAME );
105         if( lEntity == null_entity )
106                 loadfromdata( MENU_NORMAL_DEFAULT );
107
108         // verify again if MENU_NORMAL_NAME is there now
109         lEntity = findstring( null_entity, name, MENU_NORMAL_NAME );
110         if( lEntity == null_entity )
111                 error( "Bad MENU_NORMAL_DEFAULT!\n" );
112
113         lEntity = findstring( null_entity, name, MENU_INGAME_NAME );
114         if( lEntity == null_entity )
115                 loadfromdata( MENU_INGAME_DEFAULT );
116
117         // verify again if MENU_INGAME_NAME is there now
118         lEntity = findstring( null_entity, name, MENU_INGAME_NAME );
119         if( lEntity == null_entity )
120                 error( "Bad MENU_INGAME_DEFAULT!\n" );
121
122         dprint( "Verifying that every name is used only once\n" );
123
124         // verify that every name is only used *once*
125         lEntity = null_entity;
126         while( ( lEntity = nextent( lEntity ) ) != null_entity ) {
127                 self = lEntity;
128                 while( ( self = findstring( self, name, lEntity.name ) ) != null_entity )
129                         if( self != null_entity )
130                                 objerror( "Name ", lEntity.name, " already used!\n" );
131         }
132
133         dprint( "Verification of: name, type and parent fields\n" );
134
135         // now we have to :
136         // set the parent field with parent_name
137         // check the type field
138         self = null_entity;
139         while( ( self = nextent( self ) ) != null_entity ) {
140                 if( self.name == "" ) {
141                         objerror( "Name is missing!\n" );
142                         continue;
143                 }
144
145                 if( self.type == "" ) {
146                         objerror( "Type is missing!\n" );
147                         continue;
148                 }
149
150                 if( !isfunction( strcat( self.type, "_Spawn" ) ) ) {
151                         objerror( "Control ", self.type, " not found!\n" );
152                         continue;
153                 }
154
155                 // find parent
156                 // if parent_name is "" do nothing else check whether the parent exists
157                 if( self.parent != "" ) {
158                         lEntity = findstring( null_entity, name, self.parent );
159
160                         if( lEntity == null_entity ) {
161                                 objerror( "Item ", self.parent, " not found!\n" );
162                                 continue;
163                         }
164                 }
165                 else
166                         self._parent = null_entity;
167         }
168
169         dprint( "Building the child lists\n" );
170         // call LinkChildren for all entities
171         lEntity = null_entity;
172         while( ( lEntity = nextent( lEntity ) ) != null_entity )
173                 Menu_LinkChildren( lEntity );
174
175         dprint( "Calling the type functions\n" );
176
177         // call the type functions (former classname functions)
178         lEntity = null_entity;
179         while( ( lEntity = nextent( lEntity ) ) != null_entity ) {
180                 self = lEntity;
181                 //dprint("Calling ",self.type," (", etos(self),")\n");
182                 if( !Menu_HasFlag( self, FLAG_TEMPLATE ) && !Menu_HasRunFlag( self, RUNFLAG_SPAWNED ) ) {
183                         //print( lEntity.name, "\n" );
184                         callfunction( strcat( self.type, "_Spawn" ) );
185                         self._runFlag = self._runFlag | RUNFLAG_SPAWNED;
186                 } //else
187                         //print( "X ", lEntity.name, "\n" );
188         }
189
190         dprint( "Linking windows finished.\n" );
191 };
192
193 void( entity pItem ) Menu_LinkItem =
194 {
195         local entity lEntity;
196         local entity lOldSelf;
197
198         if( Menu_HasRunFlag( pItem, RUNFLAG_SPAWNED ) )
199                 return;
200
201         // verify the type
202         if( pItem.type == "" )
203                 error( "LinkItem: Type is missing (", etos( pItem ), ")!\n" );
204
205         if( !isfunction( strcat( pItem.type, "_Spawn" ) ) )
206                 error( "LinkItem: Control ", pItem.type, " not found (", etos( pItem ), ")!\n" );
207
208         // verify name and parent
209         lEntity = null_entity;
210         while( (lEntity = findstring( lEntity, name, pItem.name )) != null_entity )
211                 if( lEntity != pItem )
212                         error( "LinkItem: Name '", pItem.name, "' already in use (", etos( pItem ), ", ", etos( lEntity ), ")!" );
213
214         if( pItem.parent != "" ) {
215                 pItem._parent = findstring( null_entity, name, pItem.parent );
216
217                 if( !pItem._parent  )
218                         error( "LinkItem: Couldnt find parent '", pItem.parent, "' (", etos( pItem ), ")!" );
219         } else
220                 pItem._parent = null_entity;
221
222         // Add the children
223         Menu_LinkChildren( pItem );
224
225         // link children
226         for( lEntity = pItem._child ; lEntity ; lEntity = lEntity._next )
227                 Menu_LinkItem( lEntity );
228
229         // call the spawn function
230         lOldSelf = self;
231         self = pItem;
232         if( !Menu_HasFlag( self, FLAG_TEMPLATE ) ) {
233                 callfunction( strcat( self.type, "_Spawn" ) );
234                 self._runFlag = self._runFlag | RUNFLAG_SPAWNED;
235         }
236         self = lOldSelf;
237 };
238
239 void() Menu_Hide =
240 {
241         Raise_Select( Menu_ActiveItem, false, false );
242         Menu_CollectGarbage( true );
243         Menu_ResetGarbageStats();
244 };
245
246 void() Menu_PerformReinit =
247 {
248         // clear history
249         Menu_History_Clear();
250
251         // reset the key hook (if necessary at all)
252         Menu_KeyHook = Util_NullFunction;
253
254         // choose which menu to display
255         // AK 05: added support for scmenu_directmenu
256         if( cvar_string( "scmenu_directmenu" ) != "" ) {
257                 Menu_ActiveWindow = findstring( null_entity, name, cvar_string( "scmenu_directmenu" ) );
258                 cvar_set( "scmenu_directmenu", "" );
259         } else if( MENU_ALLOWINGAME && ( gamestatus & GAME_CONNECTED ) )
260                 Menu_ActiveWindow = findstring( null_entity, name, MENU_INGAME_NAME );
261         else
262                 Menu_ActiveWindow = findstring( null_entity, name, MENU_NORMAL_NAME );
263
264         // and reinit all menu items
265         self = null_entity;
266         while( (self = nextent( self ) ) != null_entity ) {
267                 if( self.parent == "" )
268                         self._parent = null_entity;
269                 //else actually this shouldnt happen
270                 else if( self._parent.name != self.parent )
271                         objerror( "Parent (should be ", self.parent, ") of menu item ", self.name, " changed to ", self._parent.name, " !\n" );
272
273                 Raise_Reinit( self ); // always call reinit
274         }
275
276         // run one runflag frame to (re)init the runflags
277         Menu_UpdateRunFlags();
278
279         Menu_Reselect( false );
280 };
281
282 void() Menu_Shutdown =
283 {
284         // call the terminate event for each object
285         self = null_entity;
286         while( ( self = nextent( self ) ) != null_entity )
287                 Raise_Destroy( self );
288         Campaign_Shutdown();
289 };
290
291 entity( string pType, string pName, string pParent ) Menu_CreateItem =
292 {
293         local entity lItem;
294
295         if( !pType )
296                 error( "Bad pType '", pType, "'!" );
297         if( !pName )
298                 error( "Bad pName '", pName, "'!" );
299
300         lItem = spawn();
301         parseentitydata( lItem, strcat( "{ type \"", pType, "\" name \"", strcat( pParent, "::", pName ), "\" parent \"", pParent, "\" }" ) );
302         return lItem;
303 };
304
305 entity( entity pTemplate, string pName, string pParent, bool pTree ) Menu_DeriveItem =
306 {
307         local entity lItem;
308         local entity lChild;
309
310         if( !pTemplate )
311                 error( "Null pTemplate!" );
312         if( !pName )
313                 error( "Bad pName '", pName, "'!" );
314
315         lItem = spawn();
316         copyentity( pTemplate, lItem );
317         if( lItem.flag & FLAG_TEMPLATE )
318                 lItem.flag = lItem.flag - FLAG_TEMPLATE;
319         if( lItem._runFlag & RUNFLAG_SPAWNED )
320                 lItem._runFlag = lItem._runFlag - RUNFLAG_SPAWNED;
321         parseentitydata( lItem, strcat( "{ name \"", strcat( pParent, "::", pName ), "\" parent \"", pParent, "\" }" ) );
322
323         if( pTree )
324                 for( lChild = pTemplate._child ; lChild ; lChild = lChild._next ) {
325                         local string lName;
326                         lName = String_Zone( substring( lChild.name, strlen( lChild.parent ) + 2, 100000 ) );
327                         Menu_DeriveItem( lChild, lName, lItem.name, true );
328                         String_Free( lName );
329                 }
330
331         return lItem;
332 };
333
334 void( entity pItem, string pData ) Menu_AddEntityData =
335 {
336         parseentitydata( pItem, pData );
337 };
338
339 void( entity pWindow ) Menu_LinkWindow =
340 {
341         Menu_LinkItem( pWindow );
342 };