1 /*
2 * file mi_tool.c - toolkit for xblast menus
3 *
4 * $Id: mi_tool.c,v 1.33 2006/02/10 13:22:12 fzago Exp $
5 *
6 * Program XBLAST
7 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2; or (at your option)
12 * any later version
13 *
14 * This program is distributed in the hope that it will be entertaining,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "xblast.h"
25
26 /*
27 * local variables
28 */
29 static XBMenuItem *itemFirst = NULL;
30 static XBMenuItem *itemLast = NULL;
31 static XBMenuItem *itemFocus = NULL;
32 static XBBool execFlag = XBTrue;
33 static XBBool fadeFlag = XBFalse;
34 static XBMenuItem *defaultItem = NULL;
35 static XBMenuItem *abortItem = NULL;
36 static XBBool mapMode = 0;
37 static int setPressed = 0;
38 static XBComboEntryList yesNoTable[] = {
39 {N_("no"), 0, NULL},
40 {N_("yes"), 1, NULL},
41 {NULL, 0, NULL},
42 };
43
44 /*
45 * delete any menu item
46 */
47 static void
DeleteMenuItem(XBMenuItem * item)48 DeleteMenuItem (XBMenuItem * item)
49 {
50 assert (item != NULL);
51 switch (item->type) {
52 case MIT_Button:
53 MenuDeleteButton (item);
54 break;
55 case MIT_Color:
56 MenuDeleteColor (item);
57 break;
58 case MIT_Combo:
59 MenuDeleteCombo (item);
60 break;
61 case MIT_Cyclic:
62 MenuDeleteCyclic (item);
63 break;
64 case MIT_Keysym:
65 MenuDeleteKeysym (item);
66 break;
67 case MIT_Label:
68 MenuDeleteLabel (item);
69 break;
70 case MIT_Player:
71 MenuDeletePlayer (item);
72 break;
73 case MIT_String:
74 MenuDeleteString (item);
75 break;
76 case MIT_Toggle:
77 MenuDeleteToggle (item);
78 break;
79 case MIT_Integer:
80 MenuDeleteInteger (item);
81 break;
82 case MIT_Tag:
83 MenuDeleteTag (item);
84 break;
85 case MIT_Host:
86 MenuDeleteHost (item);
87 break;
88 case MIT_Table:
89 MenuDeleteTable (item);
90 break;
91 case MIT_Team:
92 MenuDeleteTeam (item);
93 break;
94 default:
95 break;
96 }
97 free (item);
98 } /* DeleteMenuItem */
99
100 /*****************
101 * mouse buttons *
102 *****************/
103
104 /*
105 * store press status of mouse
106 */
107 void
SetPressed(XBBool mode)108 SetPressed (XBBool mode)
109 {
110 setPressed = mode;
111 } /* SetPressed */
112
113 /*
114 * get press status of mouse
115 */
116 XBBool
GetPressed(void)117 GetPressed (void)
118 {
119 return setPressed;
120 } /* GetPressed */
121
122 /***************
123 * editor mode *
124 ***************/
125
126 /*
127 * set editor mode
128 */
129 void
SetXBEditMapMode(XBBool mode)130 SetXBEditMapMode (XBBool mode)
131 {
132 mapMode = mode;
133 } /* SetXBEditMapMode */
134
135 /*
136 * get editor mode
137 */
138 XBBool
GetXBEditMapMode(void)139 GetXBEditMapMode (void)
140 {
141 return mapMode;
142 } /* GetXBEditMapMode */
143
144 /***************
145 * local tools *
146 ***************/
147
148 /*
149 * find item by id
150 */
151 static XBMenuItem *
FindItem(MENU_ID id)152 FindItem (MENU_ID id)
153 {
154 XBMenuItem *item;
155
156 for (item = itemFirst; item != NULL; item = item->next) {
157 if (item->id == id) {
158 return item;
159 }
160 }
161 return NULL;
162 } /* FindItem */
163
164 /**************
165 * menu tools *
166 **************/
167
168 /*
169 * an menu item was selected (i.e Space was pressed)
170 */
171 static void
SelectItem(XBMenuItem * item)172 SelectItem (XBMenuItem * item)
173 {
174 if (item != NULL && item->select != NULL) {
175 (*item->select) (item);
176 }
177 } /* SelectItem */
178
179 /*
180 * clear all menu items
181 */
182 void
MenuClear(void)183 MenuClear (void)
184 {
185 XBMenuItem *item_next;
186 while (itemFirst != NULL) {
187 item_next = itemFirst->next;
188 DeleteMenuItem (itemFirst);
189 itemFirst = item_next;
190 }
191 itemLast = itemFocus = NULL;
192 fadeFlag = XBTrue;
193 defaultItem = NULL;
194 abortItem = NULL;
195 MenuResetBase ();
196 MenuClearMap ();
197 } /* MenuClear */
198
199 /*
200 * set directional links between items for arrow keys
201 */
202 void
MenuSetLinks(void)203 MenuSetLinks (void)
204 {
205 XBMenuItem *ptr;
206
207 for (ptr = itemFirst; ptr != NULL; ptr = ptr->next) {
208 if (NULL != ptr->mouse) {
209 ptr->left = MenuFindLeftItem (ptr);
210 ptr->right = MenuFindRightItem (ptr);
211 ptr->up = MenuFindUpperItem (ptr);
212 ptr->down = MenuFindLowerItem (ptr);
213 }
214 }
215 } /* MenuSetLinks */
216
217 /*
218 * select item
219 */
220 void
MenuSelect(MENU_ID id)221 MenuSelect (MENU_ID id)
222 {
223 SelectItem (FindItem (id));
224 } /* MenuSelect */
225
226 /*
227 * set default item
228 */
229 void
MenuSetDefault(MENU_ID id)230 MenuSetDefault (MENU_ID id)
231 {
232 defaultItem = FindItem (id);
233 if (NULL != defaultItem && MIT_Button == defaultItem->type) {
234 MenuSetButtonIcon (defaultItem, ISA_Default);
235 }
236 } /* MenuSetDefault */
237
238 /*
239 * set abort item
240 */
241 void
MenuSetAbort(MENU_ID id)242 MenuSetAbort (MENU_ID id)
243 {
244 abortItem = FindItem (id);
245 if (NULL != abortItem && MIT_Button == abortItem->type) {
246 MenuSetButtonIcon (abortItem, ISA_Abort);
247 }
248 } /* MenuSetDefault */
249
250 /*
251 * async execution of function
252 */
253 void
MenuExecFunc(MIC_button func,void * data)254 MenuExecFunc (MIC_button func, void *data)
255 {
256 execFlag = XBTrue;
257 MenuButtonSetNextExec (func, data);
258 } /* MenuExecFunc */
259
260 /*
261 * activate/deactivate item
262 */
263 void
MenuSetActive(MENU_ID id,XBBool active)264 MenuSetActive (MENU_ID id, XBBool active)
265 {
266 XBMenuItem *item = FindItem (id);
267 if (NULL != item) {
268 /* set flags */
269 if (active) {
270 item->flags &= ~MIF_DEACTIVATED;
271 }
272 else {
273 item->flags |= MIF_DEACTIVATED;
274 }
275 switch (item->type) {
276 case MIT_Button:
277 MenuActivateButton (item, active);
278 break;
279 case MIT_Table:
280 MenuActivateTable (item, active);
281 break;
282 default:
283 break;
284 }
285 }
286 } /* MenuSetActive */
287
288 /*
289 * get item id with focus
290 */
291 MENU_ID
MenuGetFocus(void)292 MenuGetFocus (void)
293 {
294 return (NULL != itemFocus) ? itemFocus->id : 0;
295 } /* MenuGetFocus */
296
297 /*------------------------------------------------------------------------*
298 *
299 * add items to menu
300 *
301 *------------------------------------------------------------------------*/
302
303 /*
304 * add a generic item to the menu
305 */
306 static MENU_ID
MenuAdd(XBMenuItem * item)307 MenuAdd (XBMenuItem * item)
308 {
309 if (itemLast == NULL) {
310 itemFirst = item;
311 }
312 if (itemLast != NULL) {
313 itemLast->next = item;
314 item->prev = itemLast;
315 }
316 itemLast = item;
317 itemLast->next = NULL;
318 if (itemFocus == NULL && item->focus != NULL) {
319 item->flags |= MIF_FOCUS;
320 itemFocus = item;
321 (*item->focus) (item, XBTrue);
322 }
323 return item->id;
324 } /* MenuAdd */
325
326 /*
327 * add horizontal button to menu
328 */
329 MENU_ID
MenuAddHButton(int x,int y,int w,const char * text,MIC_button func,void * funcData)330 MenuAddHButton (int x, int y, int w, const char *text, MIC_button func, void *funcData)
331 {
332 return MenuAdd (MenuCreateHButton (x, y, w, text, func, funcData));
333 } /* MenuAddHButton */
334
335 /*
336 * add vertical button to menu
337 */
338 MENU_ID
MenuAddVButton(int x,int y,int h,const char * text,MIC_button func,void * funcData)339 MenuAddVButton (int x, int y, int h, const char *text, MIC_button func, void *funcData)
340 {
341 return MenuAdd (MenuCreateVButton (x, y, h, text, func, funcData));
342 } /* MenuAddVButton */
343
344 /*
345 * add a checkbox item to menu
346 */
347 MENU_ID
MenuAddToggle(int x,int y,int w,const char * text,XBBool * pState)348 MenuAddToggle (int x, int y, int w, const char *text, XBBool * pState)
349 {
350 return MenuAdd (MenuCreateToggle (x, y, w, text, pState));
351 } /* MenuAddToggle */
352
353 /*
354 * add a label/title to menu
355 */
356 MENU_ID
MenuAddLabel(int x,int y,int w,const char * text)357 MenuAddLabel (int x, int y, int w, const char *text)
358 {
359 return MenuAdd (MenuCreateLabel (x, y, w, text));
360 } /* MenuAddLabel */
361
362 /*
363 * add label variant 1 to menu
364 */
365 MENU_ID
MenuAddLabel1(int x,int y,int w,const char * text)366 MenuAddLabel1 (int x, int y, int w, const char *text)
367 {
368 return MenuAdd (MenuCreateLabel1 (x, y, w, text));
369 } /* MenuAddLabel1 */
370
371 /*
372 * add label variant 2 to menu
373 */
374 MENU_ID
MenuAddLabel2(int x,int y,int w,const char * text)375 MenuAddLabel2 (int x, int y, int w, const char *text)
376 {
377 return MenuAdd (MenuCreateLabel2 (x, y, w, text));
378 } /* MenuAddLabel2 */
379
380 /*
381 * add a combobox to menu, check only integer keys
382 */
383 MENU_ID
MenuAddComboInt(int x,int y,int w_text,const char * text,int w,int * value,XBComboEntryList * table)384 MenuAddComboInt (int x, int y, int w_text, const char *text, int w, int *value,
385 XBComboEntryList * table)
386 {
387 return MenuAdd (MenuCreateCombo (x, y, w_text, text, w, value, NULL, NULL, table));
388 } /* MenuAddComboInt */
389
390 /*
391 * a simple yes/no combobox to menu
392 */
393 MENU_ID
MenuAddComboBool(int x,int y,int w_text,const char * text,int w,XBBool * value)394 MenuAddComboBool (int x, int y, int w_text, const char *text, int w, XBBool * value)
395 {
396 return MenuAdd (MenuCreateCombo (x, y, w_text, text, w, (int *)value, NULL, NULL, yesNoTable));
397 } /* MenuAddComboInt */
398
399 /*
400 * add a combobox to menu, check only data entry
401 */
402 MENU_ID
MenuAddComboData(int x,int y,int w_text,const char * text,int w,void ** data,XBComboEntryList * table)403 MenuAddComboData (int x, int y, int w_text, const char *text, int w, void **data,
404 XBComboEntryList * table)
405 {
406 return MenuAdd (MenuCreateCombo (x, y, w_text, text, w, NULL, data, NULL, table));
407 } /* MenuAddComboData */
408
409 /*
410 * add a combobox to menu, check only atom entry
411 */
412 MENU_ID
MenuAddComboAtom(int x,int y,int w_text,const char * text,int w,XBAtom * atom,XBComboEntryList * table)413 MenuAddComboAtom (int x, int y, int w_text, const char *text, int w, XBAtom * atom,
414 XBComboEntryList * table)
415 {
416 return MenuAdd (MenuCreateCombo (x, y, w_text, text, w, NULL, NULL, atom, table));
417 } /* MenuAddComboAtom */
418
419 /*
420 * add a combobox to menu, check all entries
421 */
422 MENU_ID
MenuAddCombo(int x,int y,int w_text,const char * text,int w,int * value,void ** data,XBAtom * atom,XBComboEntryList * table)423 MenuAddCombo (int x, int y, int w_text, const char *text, int w, int *value, void **data,
424 XBAtom * atom, XBComboEntryList * table)
425 {
426 return MenuAdd (MenuCreateCombo (x, y, w_text, text, w, value, data, atom, table));
427 } /* MenuAddCombo */
428
429 /*
430 * add a player graphics to menu
431 */
432 MENU_ID
MenuAddPlayer(int x,int y,int w,int sprite,const CFGPlayerGraphics ** cfg,int n_anime,BMSpriteAnimation * anime)433 MenuAddPlayer (int x, int y, int w, int sprite, const CFGPlayerGraphics ** cfg, int n_anime,
434 BMSpriteAnimation * anime)
435 {
436 return MenuAdd (MenuCreatePlayer (x, y, w, sprite, cfg, n_anime, anime));
437 } /* MenuAddPlayer */
438
439 /*
440 * add a player graphics to menu
441 */
442 MENU_ID
MenuAddConfigPlayer(int x,int y,int w,int sprite,const CFGPlayerGraphics ** cfg,int n_anime,BMSpriteAnimation * anime,XBRgbValue * pRgb)443 MenuAddConfigPlayer (int x, int y, int w, int sprite, const CFGPlayerGraphics ** cfg, int n_anime,
444 BMSpriteAnimation * anime, XBRgbValue * pRgb)
445 {
446 return MenuAdd (MenuCreateConfigPlayer (x, y, w, sprite, cfg, n_anime, anime, pRgb));
447 } /* MenuAddPlayer */
448
449 /*
450 * add an item for string input to menu
451 */
452 MENU_ID
MenuAddString(int x,int y,int w_text,const char * text,int w,char * buffer,size_t len)453 MenuAddString (int x, int y, int w_text, const char *text, int w, char *buffer, size_t len)
454 {
455 return MenuAdd (MenuCreateString (x, y, w_text, text, w, buffer, len));
456 } /* MenuAddString */
457
458 /*
459 * add an item for changing a color to menu
460 */
461 MENU_ID
MenuAddColor(int x,int y,int w,const char * text,XBColor * color,XBRgbValue * pRgb)462 MenuAddColor (int x, int y, int w, const char *text, XBColor * color, XBRgbValue * pRgb)
463 {
464 return MenuAdd (MenuCreateColor (x, y, w, text, color, pRgb));
465 } /* MenuAddColor */
466
467 /*
468 * add an item for assigning a key to menu
469 */
470 MENU_ID
MenuAddKeysym(int x,int y,int w,const char * text,XBAtom * pKey)471 MenuAddKeysym (int x, int y, int w, const char *text, XBAtom * pKey)
472 {
473 return MenuAdd (MenuCreateKeysym (x, y, w, text, pKey));
474 } /* MenuAddKeysym */
475
476 /*
477 * add an invisble item for a poll function
478 */
479 MENU_ID
MenuAddCyclic(MIC_cyclic func,void * par)480 MenuAddCyclic (MIC_cyclic func, void *par)
481 {
482 return MenuAdd (MenuCreateCyclic (func, par));
483 } /* MenuAddCyclic */
484
485 /*
486 * add an item for integer input to menu
487 */
488 MENU_ID
MenuAddInteger(int x,int y,int w_text,const char * text,int w,int * pValue,int min,int max)489 MenuAddInteger (int x, int y, int w_text, const char *text, int w, int *pValue, int min, int max)
490 {
491 return MenuAdd (MenuCreateInteger (x, y, w_text, text, w, pValue, min, max));
492 } /* MenuAddInteger */
493
494 /*
495 * add a name tag for players
496 */
497 MENU_ID
MenuAddTag(int x,int y,int w,const char ** pText)498 MenuAddTag (int x, int y, int w, const char **pText)
499 {
500 return MenuAdd (MenuCreateTag (x, y, w, pText));
501 } /* MenuAddTag */
502
503 /*
504 * add integer tag (counter)
505 */
506 MENU_ID
MenuAddIntTag(int x,int y,int w,int * pNr)507 MenuAddIntTag (int x, int y, int w, int *pNr)
508 {
509 return MenuAdd (MenuCreateIntTag (x, y, w, pNr));
510 } /* MenuAddIntTag */
511
512 /*******************************************
513 * host items for server/client wait menus *
514 *******************************************/
515
516 /*
517 * add a generic host button
518 */
519 MENU_ID
MenuAddHost(int x,int y,int w,unsigned client,const char ** pText,XBHSFocusFunc focusFunc,XBHSChangeFunc chgFunc,XBHSUpdateFunc upFunc)520 MenuAddHost (int x, int y, int w, unsigned client, const char **pText, XBHSFocusFunc focusFunc,
521 XBHSChangeFunc chgFunc, XBHSUpdateFunc upFunc)
522 {
523 return MenuAdd (MenuCreateHost (x, y, w, client, pText, focusFunc, chgFunc, upFunc));
524 } /* MenuAddHost */
525
526 /*
527 * host button (server)
528 */
529 MENU_ID
MenuAddServer(int x,int y,int w,const char ** pText)530 MenuAddServer (int x, int y, int w, const char **pText)
531 {
532 return MenuAdd (MenuCreateServer (x, y, w, pText));
533 } /* MenuAddServer */
534
535 /*
536 * host button (client)
537 */
538 MENU_ID
MenuAddClient(int x,int y,int w,const char ** pText,XBHostState * pState,const int * pPing)539 MenuAddClient (int x, int y, int w, const char **pText, XBHostState * pState, const int *pPing)
540 {
541 return MenuAdd (MenuCreateClient (x, y, w, pText, pState, pPing));
542 } /* MenuAddClient */
543
544 /*
545 * host button (peer)
546 */
547 MENU_ID
MenuAddPeer(int x,int y,int w,const char ** pText,XBHostState * pState,const int * pPing)548 MenuAddPeer (int x, int y, int w, const char **pText, XBHostState * pState, const int *pPing)
549 {
550 return MenuAdd (MenuCreatePeer (x, y, w, pText, pState, pPing));
551 } /* MenuAddPeer */
552
553 /*******************************************
554 * team items for server/client wait menus *
555 *******************************************/
556
557 /*
558 * team button (generic)
559 */
560 MENU_ID
MenuAddTeam(int x,int y,int w,unsigned id,unsigned player,XBTSFocusFunc focusFunc,XBTSChangeFunc chgFunc,XBTSUpdateFunc upFunc)561 MenuAddTeam (int x, int y, int w, unsigned id, unsigned player, XBTSFocusFunc focusFunc,
562 XBTSChangeFunc chgFunc, XBTSUpdateFunc upFunc)
563 {
564 return MenuAdd (MenuCreateTeam (x, y, w, id, player, focusFunc, chgFunc, upFunc));
565 } /* MenuAddTeam */
566
567 /*
568 * team button (server)
569 */
570 MENU_ID
MenuAddServerTeam(int x,int y,int w,XBTeamState * pTeam)571 MenuAddServerTeam (int x, int y, int w, XBTeamState * pTeam)
572 {
573 return MenuAdd (MenuCreateServerTeam (x, y, w, pTeam));
574 } /* MenuAddServerTeam */
575
576 /*
577 * team button (peeer)
578 */
579 MENU_ID
MenuAddPeerTeam(int x,int y,int w,XBTeamState * pTeam)580 MenuAddPeerTeam (int x, int y, int w, XBTeamState * pTeam)
581 {
582 return MenuAdd (MenuCreatePeerTeam (x, y, w, pTeam));
583 } /* MenuAddPeerTeam */
584
585 /*
586 * add statitics header to menu
587 */
588 MENU_ID
MenuAddStatHeader(int x,int y,int w,const char * title)589 MenuAddStatHeader (int x, int y, int w, const char *title)
590 {
591 return MenuAdd (MenuCreateStatHeader (x, y, w, title));
592 } /* MenuAddHButton */
593
594 /*
595 * add table entry to menu
596 */
597 MENU_ID
MenuAddStatEntry(int x,int y,int w,const XBStatData * stat,MIC_button func,void * funcData)598 MenuAddStatEntry (int x, int y, int w, const XBStatData * stat, MIC_button func, void *funcData)
599 {
600 return MenuAdd (MenuCreateStatEntry (x, y, w, stat, func, funcData));
601 } /* MenuAddHButton */
602
603 /*
604 * add table entry to menu
605 */
606 MENU_ID
MenuAddDemoEntry(int x,int y,int w,const CFGDemoEntry * demo,MIC_button func,void * funcData)607 MenuAddDemoEntry (int x, int y, int w, const CFGDemoEntry * demo, MIC_button func, void *funcData)
608 {
609 return MenuAdd (MenuCreateDemoEntry (x, y, w, demo, func, funcData));
610 } /* MenuAddHButton */
611
612 /*
613 * add statitics header to menu
614 */
615 MENU_ID
MenuAddDemoHeader(int x,int y,int w)616 MenuAddDemoHeader (int x, int y, int w)
617 {
618 return MenuAdd (MenuCreateDemoHeader (x, y, w));
619 } /* MenuAddHButton */
620
621 /*
622 * add statitics header to menu
623 */
624 MENU_ID
MenuAddGameEntry(int x,int y,int w,const XBNetworkGame ** game,MIC_button func)625 MenuAddGameEntry (int x, int y, int w, const XBNetworkGame ** game, MIC_button func)
626 {
627 return MenuAdd (MenuCreateGameEntry (x, y, w, game, func));
628 } /* MenuAddHButton */
629
630 /*
631 * add statitics header to menu
632 */
633 MENU_ID
MenuAddGameHeader(int x,int y,int w)634 MenuAddGameHeader (int x, int y, int w)
635 {
636 return MenuAdd (MenuCreateGameHeader (x, y, w));
637 } /* MenuAddHButton */
638
639 /*
640 * XBCC add statitics header to menu
641 */
642 MENU_ID
MenuAddCentralHeader(int x,int y,int w,const char * title)643 MenuAddCentralHeader (int x, int y, int w, const char *title)
644 {
645 return MenuAdd (MenuCreateCentralHeader (x, y, w, title));
646 } /* MenuAddHButton */
647
648 /*
649 * XBCC add table entry to menu
650 */
651 MENU_ID
MenuAddCentralEntry(int x,int y,int w,const XBCentralData * stat,MIC_button func,void * funcData)652 MenuAddCentralEntry (int x, int y, int w, const XBCentralData * stat, MIC_button func,
653 void *funcData)
654 {
655 return MenuAdd (MenuCreateCentralEntry (x, y, w, stat, func, funcData));
656 } /* MenuAddHButton */
657
658 /*
659 * XBCC add info header to menu
660 */
661 MENU_ID
MenuAddInfoHeader(int x,int y,int w,const char * title)662 MenuAddInfoHeader (int x, int y, int w, const char *title)
663 {
664 return MenuAdd (MenuCreateInfoHeader (x, y, w, title));
665 } /* MenuAddHButton */
666
667 /*
668 * XBCC add table entry to menu
669 */
670 MENU_ID
MenuAddInfoEntry(int x,int y,int w,const XBCentralInfo * stat,MIC_button func,void * funcData)671 MenuAddInfoEntry (int x, int y, int w, const XBCentralInfo * stat, MIC_button func, void *funcData)
672 {
673 return MenuAdd (MenuCreateInfoEntry (x, y, w, stat, func, funcData));
674 } /* MenuAddHButton */
675
676 /*------------------------------------------------------------------------
677 *
678 * Event handling
679 *
680 *------------------------------------------------------------------------*/
681
682 /*
683 * redraw routine for menu (used after timer event)
684 */
685 void
MenuUpdateWindow(void)686 MenuUpdateWindow (void)
687 {
688 XBMenuItem *item;
689 XBEventData eData;
690
691 /* call poll routines for all objects */
692 for (item = itemFirst; item != NULL; item = item->next) {
693 if (NULL != item->poll) {
694 (*item->poll) (item);
695 }
696 }
697 /* shuffle sprites and mark them */
698 ShuffleAllSprites ();
699 /* set rectangles to be redrawn */
700 SetRedrawRectangles ();
701 /* shuffle sprites and mark them */
702 MarkAllSprites ();
703 /* update maze pixmap */
704 UpdateMaze ();
705 /* draw sprites into pixmap */
706 DrawAllSprites ();
707 /* fade in if neccessary */
708 if (fadeFlag) {
709 fadeFlag = XBFalse;
710 /* inits */
711 GUI_InitFade (XBFM_IN, PIXH + SCOREH);
712 /* do it */
713 while (GUI_DoFade ()) {
714 while (XBE_TIMER != GUI_WaitEvent (&eData))
715 continue;
716 }
717 }
718 /* update window from pixmap */
719 GUI_FlushPixmap (XBTrue);
720 /* clear the redraw map */
721 ClearRedrawMap ();
722 } /* MenuUpdateWindow */
723
724 /*
725 * move focus to next item in list
726 */
727 static void
MoveFocus(XBMenuKey dir)728 MoveFocus (XBMenuKey dir)
729 {
730 if (itemFocus != NULL) {
731 XBMenuItem *newFocus;
732 switch (dir) {
733 /* arrow keys */
734 case XBMK_LEFT:
735 newFocus = itemFocus->left;
736 while (newFocus && newFocus->flags & MIF_DEACTIVATED) {
737 newFocus = newFocus->left;
738 }
739 break;
740 case XBMK_RIGHT:
741 newFocus = itemFocus->right;
742 while (newFocus && newFocus->flags & MIF_DEACTIVATED) {
743 newFocus = newFocus->right;
744 }
745 break;
746 case XBMK_UP:
747 newFocus = itemFocus->up;
748 while (newFocus && newFocus->flags & MIF_DEACTIVATED) {
749 newFocus = newFocus->up;
750 }
751 break;
752 case XBMK_DOWN:
753 newFocus = itemFocus->down;
754 while (newFocus && newFocus->flags & MIF_DEACTIVATED) {
755 newFocus = newFocus->down;
756 }
757 break;
758 /* next in list */
759 case XBMK_NEXT:
760 newFocus = itemFocus->next;
761 while (newFocus != NULL) {
762 if (newFocus->focus != NULL && !(newFocus->flags & MIF_DEACTIVATED)) {
763 break;
764 }
765 newFocus = newFocus->next;
766 }
767 break;
768 /* previous in list */
769 case XBMK_PREV:
770 newFocus = itemFocus->prev;
771 while (newFocus != NULL) {
772 if (newFocus->focus != NULL && !(newFocus->flags & MIF_DEACTIVATED)) {
773 break;
774 }
775 newFocus = newFocus->prev;
776 }
777 break;
778 default:
779 return;
780 }
781 if (NULL != newFocus) {
782 itemFocus->flags &= ~MIF_FOCUS;
783 newFocus->flags |= MIF_FOCUS;
784 (*itemFocus->focus) (itemFocus, XBFalse);
785 (*newFocus->focus) (newFocus, XBTrue);
786 itemFocus = newFocus;
787 }
788 }
789 } /* MoveFocus */
790
791 /*
792 * set mouse to position
793 */
794 static void
SetMousePosition(int x,int y)795 SetMousePosition (int x, int y)
796 {
797 XBMenuItem *newItem = MenuGetMouseItem (x, y);
798 /* set new focus if needed */
799 if (NULL != newItem && !(newItem->flags & MIF_DEACTIVATED) && newItem != itemFocus) {
800 /* take back old focus */
801 if (NULL != itemFocus) {
802 itemFocus->flags &= ~MIF_FOCUS;
803 assert (NULL != itemFocus->focus);
804 (*itemFocus->focus) (itemFocus, XBFalse);
805 }
806 /* set new focus */
807 itemFocus = newItem;
808 itemFocus->flags |= MIF_FOCUS;
809 assert (NULL != itemFocus->focus);
810 (*itemFocus->focus) (itemFocus, XBTrue);
811 }
812 } /* SetMousePosition */
813
814 /*
815 * determine item under mouse
816 */
817 static void
MouseItem(XBEventCode button,int x,int y)818 MouseItem (XBEventCode button, int x, int y)
819 {
820 if (itemFocus != NULL && itemFocus == MenuGetMouseItem (x, y) && itemFocus->mouse != NULL) {
821 (*itemFocus->mouse) (itemFocus, button);
822 }
823 } /* MouseItem */
824
825 /*
826 * edit events
827 */
828 static XBBool
EditEvent(XBEventCode event,XBEventData data)829 EditEvent (XBEventCode event, XBEventData data)
830 {
831 if (!mapMode) {
832 return XBFalse;
833 }
834 switch (event) {
835 case XBE_RMOUSE_2:
836 SetOldBlock ();
837 case XBE_RMOUSE_1:
838 case XBE_RMOUSE_3:
839 setPressed = 0;
840 break;
841 case XBE_MOUSE_2:
842 SetToBlockFree ();
843 case XBE_MOUSE_1:
844 case XBE_MOUSE_3:
845 setPressed = 1;
846 fprintf (stderr, "mouse 1/3 pressed on %i %i \n", data.pos.x, data.pos.y);
847 SetEditMapBlock (data.pos.x, data.pos.y);
848 return XBFalse; /* pass mouse buttons on to default */
849 /* mouse motion event */
850 case XBE_MOUSE_MOVE:
851 if (setPressed) {
852 SetEditMapBlock (data.pos.x, data.pos.y);
853 }
854 UpdateMaze ();
855 return XBFalse; /* pass mouse move to default */
856 default:
857 return XBFalse;
858 }
859 return XBTrue;
860 } /* EditEvent */
861
862 /*
863 * default events
864 */
865 static XBBool
DefaultEvent(XBEventCode event,XBEventData data)866 DefaultEvent (XBEventCode event, XBEventData data)
867 {
868 switch (event) {
869 /* menu keys */
870 case XBE_MENU:
871 switch (data.value) {
872 case XBMK_PREV:
873 case XBMK_NEXT:
874 case XBMK_LEFT:
875 case XBMK_RIGHT:
876 case XBMK_UP:
877 case XBMK_DOWN:
878 MoveFocus (data.value);
879 break;
880 case XBMK_SELECT:
881 SelectItem (itemFocus);
882 break;
883 case XBMK_ABORT:
884 SelectItem (abortItem);
885 break;
886 case XBMK_DEFAULT:
887 SelectItem (defaultItem);
888 break;
889 default:
890 break;
891 }
892 break;
893 /* mouse events */
894 case XBE_MOUSE_1:
895 case XBE_MOUSE_2:
896 case XBE_MOUSE_3:
897 SetMousePosition (data.pos.x, data.pos.y);
898 MouseItem (event, data.pos.x, data.pos.y);
899 break;
900 /* mouse motion event */
901 case XBE_MOUSE_MOVE:
902 SetMousePosition (data.pos.x, data.pos.y);
903 break;
904 default:
905 return XBFalse;
906 }
907 return XBTrue;
908 } /* DefaultEvent */
909
910 /*
911 * event handling for menus
912 */
913 XBBool
MenuEventLoop(void)914 MenuEventLoop (void)
915 {
916 int result;
917 XBEventCode event;
918 XBEventData data;
919
920 /* load background graphics */
921 MenuLoadTiles ();
922 /* wait for kb event */
923 GUI_SetTimer (FRAME_TIME, XBTrue);
924 GUI_SetKeyboardMode (KB_MENU);
925 GUI_SetMouseMode (XBTrue);
926 /* event loop */
927 while (1) {
928 /* update window contents */
929 MenuUpdateWindow ();
930 /* exec any delayed functions */
931 if (execFlag) {
932 execFlag = XBFalse;
933 result = MenuExecButton ();
934 /* no menu left start (or quit) game */
935 if (NULL == itemFirst) {
936 /* unload background graphics */
937 MenuUnloadTiles ();
938 return result;
939 }
940 }
941 /* get event from gui */
942 while (XBE_TIMER != (event = GUI_WaitEvent (&data))) {
943 if (!Chat_Event (event, data) &&
944 !EditEvent (event, data) && !DefaultEvent (event, data)) {
945 continue;
946 }
947 result = MenuExecButton ();
948 /* no menu left start (or quit) game */
949 if (NULL == itemFirst) {
950 /* unload background graphics */
951 MenuUnloadTiles ();
952 return result;
953 }
954 }
955 }
956 /* unload background graphics */
957 MenuUnloadTiles ();
958 return XBTrue;
959 } /* MenuEventLoop */
960
961 /*
962 * set default item
963 */
964 void
MenuDeleteItemById(MENU_ID id)965 MenuDeleteItemById (MENU_ID id)
966 {
967 XBMenuItem *itemTemp;
968 XBMenuItem *item_next;
969 itemTemp = FindItem (id);
970 if (itemTemp == NULL) {
971 return;
972 }
973 item_next = itemTemp->next;
974 DeleteMenuItem (itemTemp);
975 itemTemp = item_next;
976 } /* MenuDeleteItemById */
977
978 /*
979 * end of file mi_tool.c
980 */
981