////////////////////////////////////////////////////////// // CUIToolkit.cpp // // // // Curses-based UI toolkit. Encapsulates and builds // // curses into a limited but useful dialog box-based // // text-mode GUI. Provides functions for displaying // // informational dialog boxes, string-prompt dialog // // boxes, and list selection dialog boxes. // // // // AUTHOR: Lucas Scharf, 3/20/1998 - 3/30/1998 // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 2.00 // ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // Compiler Directives // ////////////////////////////////////////////////////////// #include //Used to read file in CUIDisplayFile #include //used for strcpy & strcat in CUIDisplayFile #include //Used for system call in CUIShutdown #include "cborders.h" //Curses Borders #include "CUIToolkit.h" //Self ////////////////////////////////////////////////////////// // Local Constants Declarations // ////////////////////////////////////////////////////////// //-- String Stuff -- const LineLength = 255; //The maximum line length that will //be displayed by CUIDisplayFile ////////////////////////////////////////////////////////// // File-Scoped Variables // ////////////////////////////////////////////////////////// WindowStackItem *WindowStackTop; //Pointer to the head of the stack ////////////////////////////////////////////////////////// // Local Function Prototypes // ////////////////////////////////////////////////////////// int CUIListCount(CUIListItemPtr ListHeadPtr); void DrawBorder(WINDOW *wThisWindow, char Title[]); void DrawText(WINDOW *wThisWindow, char Text[]); ////////////////////////////////////////////////////////// // CUIInit // // // // Initialize Curses & CUIToolkit // // // // CALLED BY: // // main // // // // CALLS: // // Curses // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: x.xx // ////////////////////////////////////////////////////////// void CUIInit(){ //-- Init Curses -- initscr(); noecho(); //Do not echo input raw(); //turn off buffering //-- Initialize Window Stack -- WindowStackTop = null; //-- Clear screen -- attrset(B_CYAN|F_GRAY|A_HIGH); cursoff(); erase(); //-- Update physical screen -- refresh(); }//end CUIInit ////////////////////////////////////////////////////////// // CUIShutdown // // // // Shutdown Curses & the CUIToolkit // // // // CALLED BY: // // main // // // // CALLS: // // Curses // // CUIDestroyWindow() // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: x.xx // ////////////////////////////////////////////////////////// void CUIShutdown(){ //-- Destroy Window Stack -- while (CUIDestroyWindow()); //CUIDestroyWindow() returns true iff //"pop" was successful. This line //keeps "poping" until the window //"Stack" is empty //-- Shutdown Curses -- endwin(); //-- Clear Screen -- system("cls"); }//end Shutdown ////////////////////////////////////////////////////////// // CUIRedrawScreen // // // // Goes through the "stack" backwards and redraws all // // windows // // // // CALLED BY: // // // // CALLS: // // Curses // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: x.xx // ////////////////////////////////////////////////////////// void CUIRedrawScreen(){ //-- Variable Declaration -- WindowStackItem *CurrentItemPtr; //Pointer to the current item //-- Refresh main screen -- refresh(); //-- Null Stack check -- if (WindowStackTop) CurrentItemPtr = WindowStackTop->LinkPrevious; else return; //-- Travel around stack backwards -- while (CurrentItemPtr != WindowStackTop){ touchwin(CurrentItemPtr->WindowPtr); wrefresh(CurrentItemPtr->WindowPtr); CurrentItemPtr = CurrentItemPtr->LinkPrevious; }//end while touchwin(WindowStackTop->WindowPtr); wrefresh(WindowStackTop->WindowPtr); //Refresh top window }//end CUIRedrawScreen() ////////////////////////////////////////////////////////// // CUICreateWindow // // // // Dynamically allocates the space for a new window, // // sets some properties, and adds it into the // // stack-metaphor circular linked list. // // // // Circular Linked List add // // // // CALLED BY: // // Yet To Be Documented (YTBD) // // CALLS: // // Curses // // // // Parameters: // // int Xpos: In - upper left hand corner of the window // // int Ypos: In - upper right hand corner of the window// // int Xsize: In - horizontal size of the window // // int Ysize: In - Vertical size of the window // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: x.xx // ////////////////////////////////////////////////////////// void CUICreateWindow(int Xpos, int Ypos, int Xsize, int Ysize){ //-- Variable Declarations -- WindowStackItem *NewItemPtr; //Pointer to the new item to be added to the stack WINDOW *NewWindowPtr; //Pointer to the new window //-- Create New Element -- NewItemPtr = new WindowStackItem; //-- Create Window -- NewWindowPtr = newwin(Ysize, Xsize, Ypos, Xpos); //-- Assign Data to new element -- NewItemPtr->WindowPtr = NewWindowPtr; //-- Set links -- if (WindowStackTop){ //-- Items in the list -- NewItemPtr->LinkNext = WindowStackTop; NewItemPtr->LinkPrevious = WindowStackTop->LinkPrevious; WindowStackTop->LinkPrevious->LinkNext = NewItemPtr; WindowStackTop->LinkPrevious = NewItemPtr; } else { //-- No items in the list -- NewItemPtr->LinkNext = NewItemPtr; NewItemPtr->LinkPrevious = NewItemPtr; }//end if //-- Move Head -- WindowStackTop = NewItemPtr; }//end CUICreateWindow ////////////////////////////////////////////////////////// // CUIDestroyWindow // // // // Dynamically deallocates the space for a window. // // and removes it from the stack-metaphor circular // // linked list. // // // // Circular Linked List Delete // // // // CALLED BY: // // Yet To Be Documented (YTBD) // // CALLS: // // Curses // // // // Returns: True if window was removed, false if there // // was no window to remove // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: x.xx // ////////////////////////////////////////////////////////// bool CUIDestroyWindow(){ //-- Variable Declarations -- WindowStackItem *ItemToDeletePtr; //-- Empty List check -- if (!WindowStackTop) return false; //-- Pick Item To Delete -- ItemToDeletePtr = WindowStackTop; //-- Delete Item -- if (ItemToDeletePtr->LinkNext == ItemToDeletePtr && ItemToDeletePtr->LinkPrevious==ItemToDeletePtr){ //-- Delete the only item in the list -- //-- Delete Item -- delete ItemToDeletePtr; //-- fix list head pointer -- WindowStackTop = null; } else { //-- Delete any other item in the list -- //-- Move head if this item is the head -- if (ItemToDeletePtr == WindowStackTop) WindowStackTop = ItemToDeletePtr->LinkNext; //-- Re-arrange links -- ItemToDeletePtr->LinkPrevious->LinkNext = ItemToDeletePtr->LinkNext; ItemToDeletePtr->LinkNext->LinkPrevious = ItemToDeletePtr->LinkPrevious; //-- Return item to heap -- delete ItemToDeletePtr; }//end if //-- Refresh Screen -- CUIRedrawScreen(); //-- Return True -- return true; }//end CUIDestroyWindow ////////////////////////////////////////////////////////// // CUIWriteText // // // // Writes text to the current window // // // // CALLED BY: // // main // // // // CALLS: // // Curses // // // // Parameters: // // int Xpos: In - Upper left corner horizontal string // // position. // // int Ypos: In - Upper left corner vertial string // // position // // const char Text[]: In - Text to place on the // // background // ////////////////////////////////////////////////////////// void CUIWriteText(int Xpos, int Ypos, char Text[]){ //-- Set Colors -- wattrset(WindowStackTop->WindowPtr, B_RED|F_GRAY|A_BOLD); //-- Add Text -- mvwaddstr(WindowStackTop->WindowPtr, Ypos, Xpos, Text); //-- Update Screen -- wrefresh(WindowStackTop->WindowPtr); }//end CUIModifyBackgound ////////////////////////////////////////////////////////// // CUIDialogOk // // // // Displays an informational dialog box. Does not // // return any input from the user, but does pause // // until the user presses a key. // // // // CALLED BY: // // CUIDisplayFile // // // // CALLS: // // Curses // // DrawBorder // // DrawText // // // // Parameters: // // const char Text[]: In - the text of the dialog box // // const char Title[]: In - the title of the dialog box// ////////////////////////////////////////////////////////// void CUIDialogOk(char Text[], char Title[]){ //-- Set colors and erase -- wattrset(WindowStackTop->WindowPtr, B_RED|F_GRAY|A_BOLD); //set colors werase(WindowStackTop->WindowPtr); //Empty box //-- Window Dressing -- DrawBorder(WindowStackTop->WindowPtr, Title); wattrset(WindowStackTop->WindowPtr, B_GRAY|F_BLACK); //set colors mvwaddstr(WindowStackTop->WindowPtr, WindowStackTop->WindowPtr->_maxy-2, 1, " Ok "); //OK Button //-- Window Contents -- wattrset(WindowStackTop->WindowPtr, B_RED|F_GRAY|A_BOLD); //set colors DrawText(WindowStackTop->WindowPtr, Text); //insert text into window //-- Update physical screen -- wrefresh(WindowStackTop->WindowPtr); //-- Wait for user input -- wgetch(WindowStackTop->WindowPtr); }//end CUIDialogOk ////////////////////////////////////////////////////////// // CUIDisplayFile // // // // Displays the contents of a file in a nice little // // window. Allows the user to scroll up and down by // // way of arrow keys, page up, page down, and home. // // The user can exit this screen by pressing Enter, // // Esc, Q, or q. // // // // CALLED BY: // // main // // // // CALLS // // Curses // // ios // // // // Parameters: // // char FileName[]: In - The filename of the text to // // display. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: x.xx // ////////////////////////////////////////////////////////// void CUIDisplayFile(char FileName[]){ //-- Variable Declarations -- int CurRow; //Position(row) while writing Text[] into box int InKey=-1; //The input key from Curses int DisplayOffset=0; //The number of lines from the beginning of the file to //where the file will begin to be displayed + 1. int Counter; //for-loop counter char CurLine[LineLength+1]; //The line to be displayed char ErrorText[LineLength+1]; //Used in createing the error message ifstream InFile; //The file to be displayed //-- Open File -- InFile.open(FileName, ios::nocreate); //-- If file cold not be opened, inform user and exit -- if (InFile.fail()){ //-- Create Error String -- strcpy(ErrorText, "Error"); strcpy(ErrorText, "Could not open:\n"); strcat(ErrorText, FileName); strcat(ErrorText, "\nFile not displayed."); //-- Show dialog box -- CUICreateWindow(20,10,21,6); CUIDialogOk(ErrorText, "Error"); CUIDestroyWindow(); //-- Return -- return; }//end if-nofile //-- Initialize Keyboard -- raw(); //Turn off keyboard buffering keypad(WindowStackTop->WindowPtr, TRUE); //Recognize Arrow keys //-- Main input loop -- while (InKey!=KEY_ASCII_ENTER && InKey!=KEY_ASCII_ESC && InKey!='q' && InKey!='Q'){ //-- Keyboard Input -- switch (InKey){ case KEY_DOWN: if (!InFile.fail()) DisplayOffset++; break; case KEY_UP: if (DisplayOffset>0) DisplayOffset--; break; case KEY_NPAGE: if (!InFile.fail()) DisplayOffset+=WindowStackTop->WindowPtr->_maxy-2; break; case KEY_PPAGE: if (DisplayOffset-WindowStackTop->WindowPtr->_maxy>2) DisplayOffset-=WindowStackTop->WindowPtr->_maxy-2; else DisplayOffset=0; break; case KEY_HOME: DisplayOffset=0; break; }//end switch //-- Set colors and clear box -- wattrset(WindowStackTop->WindowPtr, B_BLUE|F_GRAY|A_BOLD); //set colors werase(WindowStackTop->WindowPtr); //Empty Box //-- Move to beginning of file, clear .fail() flag -- InFile.seekg(ios::beg); InFile.clear(); //-- Move to Offset and do Priming read -- for(Counter = 0; Counter <= DisplayOffset; Counter++){ InFile.get(CurLine, WindowStackTop->WindowPtr->_maxx-2,'\n'); if (InFile.peek()=='\n') InFile.ignore(1); } //-- Move lines into window -- CurRow = 1; //-- Priming Read -- InFile.get(CurLine, WindowStackTop->WindowPtr->_maxx,'\n'); if (InFile.peek()=='\n') InFile.ignore(1); while (InFile && CurRow < WindowStackTop->WindowPtr->_maxy){ //-- Write Line -- mvwaddstr(WindowStackTop->WindowPtr, CurRow, 1, CurLine); CurRow++; //-- Read next line -- InFile.get(CurLine, WindowStackTop->WindowPtr->_maxx,'\n'); if (InFile.peek()=='\n') InFile.ignore(1); }//end while //-- Window Dressing -- wattrset(WindowStackTop->WindowPtr, B_BLUE|F_GRAY|A_BOLD); //set colors DrawBorder(WindowStackTop->WindowPtr, FileName); //-- Update physical screen -- wrefresh(WindowStackTop->WindowPtr); //-- get user input -- InKey = wgetch(WindowStackTop->WindowPtr); }//End while //-- Close files -- InFile.close(); }//end CUIDisplayFile ////////////////////////////////////////////////////////// // CUIDialogStringPrompt // // // // Displays a dialog box and prompts the userto enter a // // string. Returns string by way ot UserResponse[]. // // // // CALLED BY: (LIST OF FUNCTIONS) // // CALLS: (LIST OF FUNCTIONS) // // // // Parameters: // // const char Text[]: In - the text of the dialog box // // const char Title[]: In - the title of the dialog box// // char UserResponse[]: Out - The user's response to // // the prompt // // int NumChars: In - the number of chars to retrieve // // from the user, not incl null terminator. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: x.xx // ////////////////////////////////////////////////////////// void CUIDialogStringPrompt(char Text[], char Title[], char UserResponse[], int NumChars){ //-- Variable Declarations -- int CurIdx = 0, //Holds position in user-input string InKey = -1; //Used for processing of keys when retrieving the prompt //-- Set colors and erase -- wattrset(WindowStackTop->WindowPtr, B_RED|F_GRAY|A_BOLD); //set colors werase(WindowStackTop->WindowPtr); //Empty box //-- Window Contents -- DrawText(WindowStackTop->WindowPtr, Text); //-- Window Border -- DrawBorder(WindowStackTop->WindowPtr, Title); //-- Input Area -- wattrset(WindowStackTop->WindowPtr, B_GRAY|F_BLACK); //set colors wmove(WindowStackTop->WindowPtr, WindowStackTop->WindowPtr->_maxy-2, 1); for(int Cnt = 0; Cnt < NumChars; Cnt++) waddch(WindowStackTop->WindowPtr, ' '); //-- Update physical screen -- wrefresh(WindowStackTop->WindowPtr); //-- Get user input -- //The curses getstr() set of functions is inadaquate for a prompt like this. //The user can easily overrun the end of the string, causing this library //and the program it to crash or become unstable. //-- Cursers setup -- curson(); raw(); //-- Input Loop -- while (InKey!=KEY_ASCII_ENTER && InKey!=KEY_ASCII_ESC){ //-- Update Window on screen -- wmove(WindowStackTop->WindowPtr, WindowStackTop->WindowPtr->_maxy-2, CurIdx+1); wrefresh(WindowStackTop->WindowPtr); //-- Get Input -- InKey = wgetch(WindowStackTop->WindowPtr); //-- Process Input -- switch(InKey){ case KEY_ASCII_BACKSPACE: if (CurIdx>0){ mvwaddch(WindowStackTop->WindowPtr, WindowStackTop->WindowPtr->_maxy-2, CurIdx, ' '); CurIdx--; }//end if break; case KEY_ASCII_ENTER: break; case KEY_ASCII_ESC: CurIdx=0; break; default: //-- If if (CurIdx < NumChars){ UserResponse[CurIdx]=InKey; //char to string mvwaddch(WindowStackTop->WindowPtr, WindowStackTop->WindowPtr->_maxy-2, CurIdx+1, InKey); //Echo char to the screen CurIdx++; } break; }//end switch } //-- Add Null Terminator -- UserResponse[CurIdx] = null; //-- Hide Curser -- cursoff(); }//end CUIDialogStringPrompt ////////////////////////////////////////////////////////// // CUIListPrompt // // // // Displays a list of items for the user to select // // from. Information is stored in a circular // // double-linked list passed by way of ListHeadPtr. // // This function passes back a pointer to the item // // currently selected and an integer containing the // // ascii value of the last non-arrow key pressed. // // This function terminates when any non-arrow key is // // pressed. This allows the user of the toolkit more // // flexibility when interpreting keys. When the // // function is restarted, the item in the circular // // linked list referenced by ItemSelected is show as // // selected. // // // // CALLED BY: // // main // // ProgramMenu // // SearchMenu // // FileMenu // // EditMenu // // WAMMenu // // // // CALLS: none // // // // CALLS: // // Curses // // // // Parameters: // // CUIListItemPtr ListHead: In - pointer to the // // listhead of list // // CUIListItemPtr ItemSelected: Out - a pointer to // // the item selected by the user // // char Title[]: In - The text of the window title // // int LastKey: Out - Last key pressed // ////////////////////////////////////////////////////////// void CUIListPrompt(CUIListItemPtr ListHeadPtr, CUIListItemPtr &ItemSelected, char Title[], int &LastKey){ //-- Variable Declarations -- int OffSet, //Holds distance from WindowStackTop->HlVertPos NumItems, //The number of items in the circular linked list Counter, //For-loop counter HlVertPos; //The vertical position of thei highlight CUIListItemPtr CI; //Current Item After the item selected //-- Set colors and erase -- wattrset(WindowStackTop->WindowPtr, B_BLUE|F_GRAY|A_BOLD); //set colors werase(WindowStackTop->WindowPtr); //Empty box //-- Draw Border -- DrawBorder(WindowStackTop->WindowPtr, Title); //-- Update display -- wrefresh(WindowStackTop->WindowPtr); //-- Setup Ketboard -- raw(); noecho(); keypad(WindowStackTop->WindowPtr, TRUE); //-- Handle Empty List -- if (!ListHeadPtr){ HlVertPos = 1; ItemSelected = null; LastKey = getch(); return; }//End if-Empty List //-- Initialize Variables -- LastKey = -1; //Last key pressed NumItems = CUIListCount(ListHeadPtr); //Count number of items in the list ItemSelected = ListHeadPtr; HlVertPos = 1; //-- Display Items & Prompt User -- if (!ItemSelected) ItemSelected = ListHeadPtr; //Take care of no-item selected //-- Display List -- while(!(LastKey > 'a' && LastKey < 'z') && !(LastKey > 'A' && LastKey < 'Z') && !(LastKey == KEY_ASCII_ENTER) && !(LastKey == KEY_ASCII_ESC) ){ //-- Set colors and erase -- wattrset(WindowStackTop->WindowPtr, B_BLUE|F_GRAY|A_BOLD); //set colors werase(WindowStackTop->WindowPtr); //Empty box //-- Display items before highlight -- OffSet = 1; CI = ItemSelected->LinkNext; while (CI != ListHeadPtr){ if (HlVertPos+OffSet < WindowStackTop->WindowPtr->_maxy - 1){ for(Counter = 1; Counter < WindowStackTop->WindowPtr->_maxx-1; Counter ++){ mvwaddch(WindowStackTop->WindowPtr, HlVertPos+OffSet, Counter, ' '); }//end for mvwaddstr(WindowStackTop->WindowPtr, HlVertPos+OffSet, 1, CI->Title); }//end if CI = CI->LinkNext; OffSet++; }//end while //-- Display items after highlight -- OffSet = - 1; CI = ItemSelected->LinkPrevious; while (CI != ListHeadPtr){ if (HlVertPos+OffSet > 0){ for(Counter = 1; Counter < WindowStackTop->WindowPtr->_maxx-1; Counter ++){ mvwaddch(WindowStackTop->WindowPtr, HlVertPos+OffSet, Counter, ' '); }//end for mvwaddstr(WindowStackTop->WindowPtr, HlVertPos+OffSet, 1, CI->Title); }//end if CI = CI->LinkPrevious; OffSet--; }//end while if (HlVertPos+OffSet > 0) mvwaddstr(WindowStackTop->WindowPtr, HlVertPos+OffSet, 1, CI->Title); //-- Display Highlight -- wattrset(WindowStackTop->WindowPtr, B_BLUE|F_GRAY|A_BOLD); for(Counter = 1; Counter < WindowStackTop->WindowPtr->_maxx-1; Counter ++){ mvwaddch(WindowStackTop->WindowPtr, HlVertPos, Counter, ' '); }//end for wattrset(WindowStackTop->WindowPtr, B_RED|F_GRAY|A_BOLD); mvwaddstr(WindowStackTop->WindowPtr, HlVertPos, 1, ItemSelected->Title); wattrset(WindowStackTop->WindowPtr, B_BLUE|F_GRAY|A_BOLD); //-- Draw Border -- DrawBorder(WindowStackTop->WindowPtr, Title); //-- Update display -- wrefresh(WindowStackTop->WindowPtr); //-- Get & Process keys -- LastKey = wgetch(WindowStackTop->WindowPtr); switch(LastKey){ case KEY_UP: if (HlVertPos>1) HlVertPos--; else if (NumItems < WindowStackTop->WindowPtr->_maxy-2) HlVertPos = NumItems; else HlVertPos = WindowStackTop->WindowPtr->_maxy-2; ItemSelected = ItemSelected->LinkPrevious; break; case KEY_DOWN: if (ItemSelected->LinkNext != ListHeadPtr){ if (HlVertPos < WindowStackTop->WindowPtr->_maxy-2) HlVertPos++; } else { HlVertPos = 1; }//end if ItemSelected = ItemSelected->LinkNext; break; case KEY_HOME: HlVertPos = 1; ItemSelected = ListHeadPtr; break; case KEY_LL: if (HlVertPos>2) HlVertPos--; else if (NumItems < WindowStackTop->WindowPtr->_maxy-2) HlVertPos = NumItems; else HlVertPos = WindowStackTop->WindowPtr->_maxy-2; ItemSelected = ListHeadPtr -> LinkPrevious; break; }//end switch }//End while }//end CUIListPrompt ////////////////////////////////////////////////////////// // CUICreateList // // // // Initialize list head pointer to null // // // // CALLED BY: // // main // // ProgramMenu // // SearchMenu // // FileMenu // // EditMenu // // WAMMenu // // // // CALLS: none // // // // Parameters: // // CUIListItemPtr ListHeadPtr: Out - pointer to the // // head of the list. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// void CUICreateList(CUIListItemPtr &ListHeadPtr){ ListHeadPtr=null; }//End CUICreateList ////////////////////////////////////////////////////////// // CUIAddItem // // // // Add item to circular double-linked list containing // // menu item information. // // // // CALLED BY: // // main // // ProgramMenu // // SearchMenu // // FileMenu // // EditMenu // // WAMMenu // // // // CALLS: none // // // // Parameters: // // CUIListItemPtr ListHeadPtr: In & Out - pointer to // // the head of the list. // // CUIListItem NewItem: In - the info to be added to // // the list // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// void CUIAddItem(CUIListItemPtr &ListHeadPtr, CUIListItem NewItem){ //-- Variable Declarations -- CUIListItemPtr NewItemPtr; //-- Create New Element -- NewItemPtr = new CUIListItem; //-- Assign Data to new element -- *NewItemPtr = NewItem; //-- Set links -- if (ListHeadPtr){ //-- Items in the list -- NewItemPtr->LinkNext = ListHeadPtr; NewItemPtr->LinkPrevious = ListHeadPtr->LinkPrevious; ListHeadPtr->LinkPrevious->LinkNext = NewItemPtr; ListHeadPtr->LinkPrevious = NewItemPtr; } else { //-- No items in the list -- NewItemPtr->LinkNext = NewItemPtr; NewItemPtr->LinkPrevious = NewItemPtr; ListHeadPtr = NewItemPtr; }//end if }//End CUIAddItem ////////////////////////////////////////////////////////// // CUIRemoveItem // // // // Remove an item from the circular double-linked list // // containing menu item information. // // // // CALLED BY: // // WebAddressManager // // ProgramMenu // // SearchMenu // // FileMenu // // EditMenu // // WAMMenu // // // // CALLS: none // // // // Parameters: // // CUIListItemPtr ListHeadPtr: In & Out - pointer to // // the head of the list. // // CUIListItemPtr ItemToDeletePtr: In - pointer to the // // item that will be deleted. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// void CUIRemoveItem(CUIListItemPtr &ListHeadPtr, CUIListItemPtr ItemToDeletePtr){ if (ItemToDeletePtr->LinkNext == ItemToDeletePtr && ItemToDeletePtr->LinkPrevious == ItemToDeletePtr){ //-- Delete the only item in the list -- //-- Delete Item -- delete ItemToDeletePtr; //-- fix list head pointer -- ListHeadPtr = null; } else { //-- Delete any other item in the list -- //-- Move head if this item is the head -- if (ItemToDeletePtr == ListHeadPtr) ListHeadPtr = ItemToDeletePtr->LinkNext; //-- Re-arrange links -- ItemToDeletePtr->LinkPrevious->LinkNext = ItemToDeletePtr->LinkNext; ItemToDeletePtr->LinkNext->LinkPrevious = ItemToDeletePtr->LinkPrevious; //-- Return item to heap -- delete ItemToDeletePtr; }//end if }//End CUIRemoveItem; ////////////////////////////////////////////////////////// // CUIDestroyList // // // // Removes all items from the circular double-linked // // list containing menu item information. // // // // CALLED BY: // // main // // ProgramMenu // // SearchMenu // // FileMenu // // EditMenu // // WAMMenu // // // // CALLS: none // // // // Parameters: // // CUIListItemPtr ListHeadPtr: In & Out - pointer to // // the head of the list. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// void CUIDestroyList(CUIListItemPtr &ListHeadPtr){ //-- Nuke until null list -- while (ListHeadPtr) CUIRemoveItem(ListHeadPtr, ListHeadPtr); }//end CUIDestroyList ////////////////////////////////////////////////////////// // LenLongestLine // // // // Returns the length of the longest run of chars not // // containing a newline charictar. Function just // // steps through the array. Null terminator required. // // // // CALLED BY: // // CUIDialogOk // // CUIDialogStringPrompt // // // // CALLS: none // // // // Parameters: // // char Astring[]: In - string in which to find the // // longest line. // // // // Returns: // // int: The length of the longest line in the string // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// int LenLongestLine(const char AString[]){ //-- Variable Declarations -- int CurIdx = 0; //used to step through AString[] int LongestLine = 0; //The length of the longest line int LenCurLine = 0; //The length of the current line //-- Count Runs -- while (AString[CurIdx]){ //-- If current char is a newline -- if (AString[CurIdx]=='\n'){ if (LenCurLine>LongestLine) //if this line is the longest so far, record it LongestLine = LenCurLine; LenCurLine=0; //Reset the length of this line } else { LenCurLine++; //Count one more char in this line }//end if CurIdx++; }//End while //-- Check to see if the last line is the longes -- if (LenCurLine>LongestLine) LongestLine = LenCurLine; //-- Return Value -- return LongestLine; }//end LenLongestLine ////////////////////////////////////////////////////////// // NumLines // // // // Returns the number of lines in the in the string. // // Function just steps through the array and counts. // // Null terminator required. // // // // CALLED BY: // // CUIDialogOk // // CUIDialogStringPrompt // // // // CALLS: none // // // // Parameters: // // char Astring[]: In - string contianing the endlines // // to be counted. // // // // Returns: // // int: The number of lines contained in the string. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// int NumLines(const char AString[]){ //-- Variable Declaration -- int CurIdx = 0; //Current Indext -- used for stepping through AString int Lines = 1; //The number of lines encountered so far //-- Step through AString -- while (AString[CurIdx]){ if (AString[CurIdx]=='\n') //check to see if current element is NewLine Lines++; CurIdx++; //Move to next element }//end while //-- Return Value -- return Lines; }//end NumLines ////////////////////////////////////////////////////////// // CUIListCount // // // // Counts the number of elements in the circular linked // // list used by CUIListPrompt. // // // // CALLED BY: CUIListPrompt // // // // CALLS: None // // // // Parameters: // // CUIListItemPtr ListHeadPtr: In - pointer to the // // head of the circular-linked list being examined // // // // Returns; // // The number of items in the list pointed to by // // ListHeadPtr. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// int CUIListCount(CUIListItemPtr ListHeadPtr){ //-- Variable Declarations -- int ItemCount=0; //The number of items in the list CUIListItemPtr CurrentItem = ListHeadPtr; //The current item //-- Empty List bomb-shelter -- if (!ListHeadPtr) return 0; //-- Count Items -- do{ ItemCount++; CurrentItem = CurrentItem->LinkNext; }while (CurrentItem!=ListHeadPtr); //-- Return Count -- return ItemCount; }//end ////////////////////////////////////////////////////////// // DrawBorder // // // // Uses Curses to draw a border around the window, than // // inserts a title. Does not check to see if the title // // is wider than the box. // // // // CALLED BY: // // CUIDialogStringPrompt // // CUIDisplayFile // // CUIListPrompt // // CUIDialogOk // // // // CALLS: // // Curses // // // // Parameters: // // WINDOW *wThisWindow: In - pointer to the window // // char Title[]: In - the string containing the title // // to be placed in the border. // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// void DrawBorder(WINDOW *wThisWindow, char Title[]){ //-- Draw Border -- box(wThisWindow, C_V, C_HD); //-- Draw Title -- if (Title[0]){ mvwaddch(wThisWindow, 0, 1, 181); //Move to position, put in =| waddstr(wThisWindow, Title); //Write Title waddch(wThisWindow, 198); //Put in |= }//end if }//end DrawBorder ////////////////////////////////////////////////////////// // DrawText // // // // Writes a string into a dialog box. Handles // // newlines. // // // // CALLED BY: // // CUIDialogStringPrompt // // CUIDialogOk // // // // CALLS: // // Curses // // // // Parameters: // // WINDOW *ThisWindow: In - pointer to the window // // char Text[]: In - the string containing the text // // to be placed in the dialog box // // // // REVISIONS: DATE, REASON // // AUTHOR FOR EACH (if different) // // VERSION: 1.00 // ////////////////////////////////////////////////////////// void DrawText(WINDOW *wThisWindow, char Text[]){ //-- Variable Declarations -- int CurRow=1, //Position(row) while writing Text[] into box CurCol=1, //Position(col) while writing Text[] into box CurIdx = 0; //Used for stepping though Text[] //-- Write text -- while (Text[CurIdx]){ if (Text[CurIdx] != '\n'){ //If the current char is a regular charictar, mvwaddch(wThisWindow, CurRow, CurCol, Text[CurIdx]); //Wwite it CurCol++; //and move to the next col } else { //If current char is a newline, CurCol = 1; //carriage return CurRow++; //and line feed }//end if CurIdx++; //Move to next char }//end while }//end DrawText