123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- #define BUILDING_OPENDOORS
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include "OpenDoor.h"
- #include "ODCore.h"
- #include "ODGen.h"
- #include "ODPlat.h"
- #include "ODKrnl.h"
- #include "ODStat.h"
- #define MENU_LEVELS 11
- #define MAX_MENU_ITEMS 21
- #define MAX_ITEM_WIDTH 76
- #define NO_COMMAND -10
- typedef struct
- {
- char szItemText[MAX_ITEM_WIDTH + 1];
- BYTE btKeyIndex;
- } tMenuItem;
- typedef struct
- {
- tMenuItem *paMenuItems;
- BYTE btNumMenuItems;
- BYTE btWidth;
- BYTE btRight;
- BYTE btBottom;
- BYTE btCursor;
- BYTE btLeft;
- BYTE btTop;
- WORD wFlags;
- void *pWindow;
- } tMenuLevelInfo;
- tMenuLevelInfo MenuLevelInfo[MENU_LEVELS];
- static BYTE btCorrectItem;
- static INT nCommand;
- static WORD wCurrentFlags;
- static BYTE btCurrentNumMenuItems;
- static INT nCurrentLevel;
- static void ODPopupCheckForKey(BOOL bWaitForInput);
- static void ODPopupDisplayMenuItem(BYTE btLeft, BYTE btTop,
- tMenuItem *paMenuItems, BYTE btItemIndex, BOOL bHighlighted, BYTE btWidth,
- BOOL bPositionCursor);
- ODAPIDEF INT ODCALL od_popup_menu(char *pszTitle, char *pszText, INT nLeft,
- INT nTop, INT nLevel, WORD uFlags)
- {
- tMenuItem *paMenuItems = NULL;
- BYTE btCount;
- BYTE btWidth;
- BYTE btRight;
- BYTE btBottom;
- BYTE btCursor;
- BYTE btLeft;
- BYTE btTop;
- void *pWindow;
- BYTE btBetweenSize;
- BYTE btTitleSize;
- BYTE btRemaining;
- BYTE btLineCount;
- INT16 nOriginalAttrib;
-
- TRACE(TRACE_API, "od_popup_menu()");
-
- if(!bODInitialized) od_init();
- OD_API_ENTRY();
-
- if(od_control.od_box_chars[BOX_BOTTOM] == 0)
- {
- od_control.od_box_chars[BOX_BOTTOM] = od_control.od_box_chars[BOX_TOP];
- }
- if(od_control.od_box_chars[BOX_RIGHT] == 0)
- {
- od_control.od_box_chars[BOX_RIGHT] = od_control.od_box_chars[BOX_LEFT];
- }
-
- nOriginalAttrib = od_control.od_cur_attrib;
-
- if(nLevel < 0 || nLevel > MENU_LEVELS)
- {
- od_control.od_error = ERR_LIMIT;
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
-
- nCurrentLevel = nLevel;
- if(MenuLevelInfo[nLevel].pWindow == NULL)
- {
- btLeft = nLeft;
- btTop = nTop;
- wCurrentFlags = uFlags;
- if(pszText == NULL)
- {
- od_control.od_error = ERR_PARAMETER;
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
- if(paMenuItems == NULL)
- {
- if((paMenuItems = malloc(sizeof(tMenuItem) * MAX_MENU_ITEMS)) == NULL)
- {
- od_control.od_error = ERR_PARAMETER;
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
- }
- MenuLevelInfo[nLevel].paMenuItems = paMenuItems;
- btCurrentNumMenuItems = 0;
- btWidth = 0;
- btCount = 0;
- nCommand = NO_COMMAND;
- paMenuItems[0].btKeyIndex = 0;
- while(*pszText && btCurrentNumMenuItems < MAX_MENU_ITEMS)
- {
- switch(*pszText)
- {
- case '|':
- paMenuItems[btCurrentNumMenuItems++].szItemText[btCount]
- = '\0';
- if(btCount > btWidth) btWidth = btCount;
- btCount = 0;
- paMenuItems[btCurrentNumMenuItems].btKeyIndex = 0;
- break;
- case '^':
- if(btCount < MAX_ITEM_WIDTH)
- {
- paMenuItems[btCurrentNumMenuItems].btKeyIndex = btCount;
- }
- break;
- default:
- if(btCount < MAX_ITEM_WIDTH)
- {
- paMenuItems[btCurrentNumMenuItems].szItemText[btCount++] =
- *pszText;
- }
- }
- ++pszText;
- }
-
-
-
-
- if(btCount != 0)
- {
-
- paMenuItems[btCurrentNumMenuItems++].szItemText[btCount] = '\0';
-
- if(btCount > btWidth) btWidth = btCount;
- }
-
- if(btCurrentNumMenuItems == 0)
- {
-
- od_control.od_error = ERR_PARAMETER;
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
-
-
-
- if(pszTitle != NULL && strlen(pszTitle) + 2 > btWidth)
- {
-
-
- btWidth = strlen(pszTitle) + 2 > MAX_ITEM_WIDTH
- ? MAX_ITEM_WIDTH : strlen(pszTitle) + 2;
- }
-
-
- btBottom = btTop + btCurrentNumMenuItems + 1;
- btRight = btLeft + btWidth + 3;
- btBetweenSize = (btRight - btLeft) - 1;
-
- if(!(od_control.user_ansi || od_control.user_avatar))
- {
- od_control.od_error = ERR_NOGRAPHICS;
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
-
- if(btLeft < 1 || btTop < 1 || btRight > OD_SCREEN_WIDTH
- || btBottom > OD_SCREEN_HEIGHT || btRight - btLeft < 2
- || btBottom - btTop < 2)
- {
- od_control.od_error = ERR_PARAMETER;
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
-
-
- if((pWindow = malloc((btRight - btLeft + 1) * 2
- + (btBottom - btTop + 1) * 160)) == NULL)
- {
- od_control.od_error = ERR_MEMORY;
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
-
-
- if(!od_gettext(btLeft, btTop, btRight, btBottom, pWindow))
- {
- free(pWindow);
- pWindow = NULL;
-
- OD_API_EXIT();
- return(POPUP_ERROR);
- }
-
- if(pszTitle == NULL)
- {
- btTitleSize = 0;
- }
- else
- {
- if((btTitleSize = strlen(pszTitle)) > (btBetweenSize - 4))
- {
- btTitleSize = btBetweenSize - 4;
- }
- }
- od_set_cursor(btTop,btLeft);
- od_set_attrib(od_control.od_menu_border_col);
- od_putch(od_control.od_box_chars[BOX_UPPERLEFT]);
- if(btTitleSize == 0)
- {
- od_repeat(od_control.od_box_chars[BOX_TOP], btBetweenSize);
- }
- else
- {
- od_repeat(od_control.od_box_chars[BOX_TOP],
- btRemaining = ((btBetweenSize - btTitleSize - 2) / 2));
- od_set_attrib(od_control.od_menu_title_col);
- od_putch(' ');
- od_disp(pszTitle,btTitleSize, TRUE);
- od_putch(' ');
- od_set_attrib(od_control.od_menu_border_col);
- od_repeat(od_control.od_box_chars[BOX_TOP],
- (BYTE)(btBetweenSize - btRemaining - btTitleSize - 2));
- }
- od_putch(od_control.od_box_chars[BOX_UPPERRIGHT]);
- btLineCount = btTop + 1;
- btCorrectItem = 0;
- ODPopupCheckForKey(FALSE);
- btCursor = btCorrectItem;
- for(btCount = 0; btCount < btCurrentNumMenuItems
- && btLineCount < btBottom; ++btCount)
- {
- ODPopupCheckForKey(FALSE);
- if(nCommand != NO_COMMAND && !(wCurrentFlags & MENU_KEEP))
- {
- goto exit_now;
- }
- od_set_cursor(btLineCount,btLeft);
- od_putch(od_control.od_box_chars[BOX_LEFT]);
- od_set_attrib(od_control.od_menu_text_col);
- if(btCount == btCursor)
- {
- ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCount,
- TRUE, btWidth, FALSE);
- }
- else
- {
- ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCount,
- FALSE, btWidth, FALSE);
- }
- od_set_attrib(od_control.od_menu_border_col);
- od_putch(od_control.od_box_chars[BOX_RIGHT]);
- ++btLineCount;
- }
- od_set_cursor(btBottom, btLeft);
- od_putch(od_control.od_box_chars[BOX_LOWERLEFT]);
- od_repeat(od_control.od_box_chars[BOX_BOTTOM], btBetweenSize);
- od_putch(od_control.od_box_chars[BOX_LOWERRIGHT]);
- od_set_cursor(btTop + 1, btLeft + 1);
- }
- else
- {
- paMenuItems = MenuLevelInfo[nLevel].paMenuItems;
- btCurrentNumMenuItems = MenuLevelInfo[nLevel].btNumMenuItems;
- btWidth = MenuLevelInfo[nLevel].btWidth;
- btRight = MenuLevelInfo[nLevel].btRight;
- btBottom = MenuLevelInfo[nLevel].btBottom;
- btLeft = MenuLevelInfo[nLevel].btLeft;
- btTop = MenuLevelInfo[nLevel].btTop;
- wCurrentFlags = MenuLevelInfo[nLevel].wFlags;
- pWindow = MenuLevelInfo[nLevel].pWindow;
- btCorrectItem = btCursor = MenuLevelInfo[nLevel].btCursor;
- nCommand = NO_COMMAND;
- if(uFlags & MENU_DESTROY)
- {
- nCommand = POPUP_ESCAPE;
- goto destroy;
- }
-
- od_set_cursor(btTop + btCursor + 1, btLeft + 1);
- }
-
- ODStatStartArrowUse();
- for(;;)
- {
- ODPopupCheckForKey(TRUE);
- if(btCorrectItem != btCursor)
- {
- ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCursor,
- FALSE, btWidth, TRUE);
- btCursor = btCorrectItem;
- ODWaitDrain(25);
- ODPopupCheckForKey(FALSE);
- ODPopupDisplayMenuItem(btLeft, btTop, paMenuItems, btCursor,
- TRUE, btWidth, TRUE);
- }
- if(nCommand != NO_COMMAND)
- {
- goto exit_now;
- }
- }
- exit_now:
- if((!(wCurrentFlags & MENU_KEEP)) || nCommand <= 0)
- {
- destroy:
- od_puttext(btLeft, btTop, btRight, btBottom, pWindow);
- free(pWindow);
- MenuLevelInfo[nLevel].pWindow = NULL;
- if(paMenuItems != NULL)
- {
- free(paMenuItems);
- MenuLevelInfo[nLevel].paMenuItems = NULL;
- }
- }
- else if(wCurrentFlags & MENU_KEEP)
- {
- MenuLevelInfo[nLevel].paMenuItems = paMenuItems;
- MenuLevelInfo[nLevel].btNumMenuItems = btCurrentNumMenuItems;
- MenuLevelInfo[nLevel].btWidth = btWidth;
- MenuLevelInfo[nLevel].btRight = btRight;
- MenuLevelInfo[nLevel].btBottom = btBottom;
- MenuLevelInfo[nLevel].btCursor = btCursor;
- MenuLevelInfo[nLevel].btLeft = btLeft;
- MenuLevelInfo[nLevel].btTop = btTop;
- MenuLevelInfo[nLevel].wFlags = wCurrentFlags;
- MenuLevelInfo[nLevel].pWindow = pWindow;
- }
-
- od_set_attrib(nOriginalAttrib);
-
- ODStatEndArrowUse();
- OD_API_EXIT();
- return(nCommand);
- }
- static void ODPopupCheckForKey(BOOL bWaitForInput)
- {
- BYTE btCount;
- tODInputEvent InputEvent;
- BOOL bDoneAnythingYet = FALSE;
-
-
- while(nCommand == NO_COMMAND)
- {
- CALL_KERNEL_IF_NEEDED();
- if(!od_get_input(&InputEvent, bWaitForInput && !bDoneAnythingYet
- ? OD_NO_TIMEOUT : 0, GETIN_NORMAL))
- {
-
- return;
- }
- bDoneAnythingYet = TRUE;
- if(InputEvent.EventType == EVENT_EXTENDED_KEY)
- {
- switch(InputEvent.chKeyPress)
- {
- case OD_KEY_UP:
- up_arrow:
- if(btCorrectItem == 0)
- {
- btCorrectItem = btCurrentNumMenuItems - 1;
- }
- else
- {
- --btCorrectItem;
- }
- break;
- case OD_KEY_DOWN:
- down_arrow:
- if(++btCorrectItem >= btCurrentNumMenuItems)
- {
- btCorrectItem = 0;
- }
- break;
- case OD_KEY_LEFT:
- left_arrow:
- if(wCurrentFlags & MENU_PULLDOWN)
- {
- nCommand = POPUP_LEFT;
- return;
- }
- break;
- case OD_KEY_RIGHT:
- right_arrow:
- if(wCurrentFlags & MENU_PULLDOWN)
- {
- nCommand = POPUP_RIGHT;
- return;
- }
- break;
- }
- }
- else if(InputEvent.EventType == EVENT_CHARACTER)
- {
- if(InputEvent.chKeyPress == '\n' || InputEvent.chKeyPress == '\r')
- {
- nCommand = btCorrectItem + 1;
- return;
- }
- else if(InputEvent.chKeyPress == 27)
- {
- if(wCurrentFlags & MENU_ALLOW_CANCEL)
- {
- nCommand = POPUP_ESCAPE;
- return;
- }
- }
- else
- {
-
- for(btCount = 0; btCount < btCurrentNumMenuItems; ++btCount)
- {
- if(toupper(MenuLevelInfo[nCurrentLevel].paMenuItems[btCount]
- .szItemText[MenuLevelInfo[nCurrentLevel].paMenuItems[btCount]
- .btKeyIndex]) == toupper(InputEvent.chKeyPress))
- {
- btCorrectItem = btCount;
- nCommand = btCorrectItem + 1;
- return;
- }
- }
-
-
- if(InputEvent.chKeyPress == '4')
- {
- goto left_arrow;
- }
- else if(InputEvent.chKeyPress == '6')
- {
- goto right_arrow;
- }
- else if(InputEvent.chKeyPress == '8')
- {
- goto up_arrow;
- }
- else if(InputEvent.chKeyPress == '2')
- {
- goto down_arrow;
- }
- }
- }
- }
- }
- static void ODPopupDisplayMenuItem(BYTE btLeft, BYTE btTop,
- tMenuItem *paMenuItems, BYTE btItemIndex, BOOL bHighlighted, BYTE btWidth,
- BOOL bPositionCursor)
- {
- BYTE btCount;
- char *pchItemText;
- BYTE btKeyPosition;
- BYTE btTextColor;
- BYTE btKeyColor;
-
- ASSERT(paMenuItems != NULL);
- ASSERT(btItemIndex < MAX_MENU_ITEMS);
- ASSERT(btWidth < OD_SCREEN_WIDTH);
- ++btLeft;
- ++btTop;
- btTextColor = bHighlighted ? od_control.od_menu_highlight_col
- : od_control.od_menu_text_col;
- btKeyColor = bHighlighted ? od_control.od_menu_highkey_col
- : od_control.od_menu_key_col;
- pchItemText = (char *)(paMenuItems[btItemIndex].szItemText);
- btKeyPosition = paMenuItems[btItemIndex].btKeyIndex;
- if(bPositionCursor) od_set_cursor(btTop + btItemIndex, btLeft);
- od_set_attrib(btTextColor);
- od_putch(' ');
- for(btCount = 0; btCount < btWidth && *pchItemText; ++btCount)
- {
- if(btCount == btKeyPosition)
- {
- od_set_attrib(btKeyColor);
- od_putch(*pchItemText++);
- od_set_attrib(btTextColor);
- }
- else
- {
- od_putch(*pchItemText++);
- }
- }
- od_repeat(' ', (BYTE)((btWidth - btCount) + 1));
- if(bPositionCursor) od_set_cursor(btTop + btItemIndex, btLeft);
- }
|