/* ** Command & Conquer Generals(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // FILE: GameWindowManagerScript.cpp ////////////////////////////////////////// //----------------------------------------------------------------------------- // // Westwood Studios Pacific. // // Confidential Information // Copyright (C) 2001 - All Rights Reserved // //----------------------------------------------------------------------------- // // Project: RTS3 // // File name: GameWindowManagerScript.cpp // // Created: Colin Day, June 2001 // Dean Iverson, May 1998 // // Desc: Reading window definition files from disk for the window manager // //----------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////// // SYSTEM INCLUDES //////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine // USER INCLUDES ////////////////////////////////////////////////////////////// #include "Lib/BaseType.h" #include "Common/Debug.h" #include "Common/File.h" #include "Common/FileSystem.h" #include "Common/GameMemory.h" #include "Common/NameKeyGenerator.h" #include "Common/FunctionLexicon.h" #include "GameClient/Display.h" #include "GameClient/WindowLayout.h" #include "GameClient/Gadget.h" #include "GameClient/GameWindowManager.h" #include "GameClient/GameWindowGlobal.h" #include "GameClient/GadgetStaticText.h" #include "GameClient/GadgetTabControl.h" #include "GameClient/GadgetTextEntry.h" #include "GameClient/GadgetPushButton.h" #include "GameClient/GadgetRadioButton.h" #include "GameClient/GadgetCheckBox.h" #include "GameClient/GadgetListBox.h" #include "GameClient/GadgetComboBox.h" #include "GameClient/GadgetSlider.h" #include "GameClient/GameText.h" #include "GameClient/HeaderTemplate.h" // DEFINES //////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // PRIVATE TYPES ////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// enum { WIN_BUFFER_LENGTH = 2048, WIN_STACK_DEPTH = 10, }; //------------------------------------------------------------------------------------------------- /** Layout parse structure ... these data items apply to the window file itself, * they are not associated with any window, but rather just a block of data in * every file */ //------------------------------------------------------------------------------------------------- struct LayoutScriptParse { char *name; Bool (*parse)( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info ); }; // GameWindowParse ------------------------------------------------------------ /** used to match database fields to parsing functions */ //----------------------------------------------------------------------------- struct GameWindowParse { char *name; Bool (*parse)( char *token, WinInstanceData *, char *, void * ); }; /////////////////////////////////////////////////////////////////////////////// // PRIVATE DATA /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // window methods and their string representations static GameWinSystemFunc systemFunc = NULL; static GameWinInputFunc inputFunc = NULL; static GameWinTooltipFunc tooltipFunc = NULL; static GameWinDrawFunc drawFunc = NULL; static AsciiString theSystemString; static AsciiString theInputString; static AsciiString theTooltipString; static AsciiString theDrawString; // default visual properties static Color defEnabledColor = 0; static Color defDisabledColor = 0; static Color defBackgroundColor = 0; static Color defHiliteColor = 0; static Color defSelectedColor = 0; static Color defTextColor = 0; static GameFont *defFont = NULL; // // These strings must be in the same order as they are in their definitions // (see WIN_STATUS_* enums and GWS_* enums). // const char *WindowStatusNames[] = { "ACTIVE", "TOGGLE", "DRAGABLE", "ENABLED", "HIDDEN", "ABOVE", "BELOW", "IMAGE", "TABSTOP", "NOINPUT", "NOFOCUS", "DESTROYED", "BORDER", "SMOOTH_TEXT", "ONE_LINE", "NO_FLUSH", "SEE_THRU", "RIGHT_CLICK", "WRAP_CENTERED", "CHECK_LIKE","HOTKEY_TEXT", "USE_OVERLAY_STATES", "NOT_READY", "FLASHING", "ALWAYS_COLOR", NULL }; const char *WindowStyleNames[] = { "PUSHBUTTON", "RADIOBUTTON", "CHECKBOX", "VERTSLIDER", "HORZSLIDER", "SCROLLLISTBOX", "ENTRYFIELD", "STATICTEXT", "PROGRESSBAR", "USER", "MOUSETRACK", "ANIMATED", "TABSTOP", "TABCONTROL", "TABPANE", "COMBOBOX", NULL }; // Implement a stack to keep track of parent/child nested window descriptions. static GameWindow *windowStack[ WIN_STACK_DEPTH ]; static GameWindow **stackPtr; // for parsing static char *seps = " =;\n\r\t"; WinDrawData enabledDropDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData disabledDropDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData hiliteDropDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData enabledEditBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData disabledEditBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData hiliteEditBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData enabledListBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData disabledListBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData hiliteListBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes WinDrawData enabledUpButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData disabledUpButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData hiliteUpButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData enabledDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData disabledDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData hiliteDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData enabledSliderDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData disabledSliderDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData hiliteSliderDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes WinDrawData enabledSliderThumbDrawData[ MAX_DRAW_DATA ]; ///< for sliders and list boxes and combo boxes WinDrawData disabledSliderThumbDrawData[ MAX_DRAW_DATA ]; ///< for sliders and list boxes and combo boxes WinDrawData hiliteSliderThumbDrawData[ MAX_DRAW_DATA ]; ///< for sliders and list boxes and combo boxes // PUBLIC DATA //////////////////////////////////////////////////////////////// // PRIVATE PROTOTYPES ///////////////////////////////////////////////////////// static GameWindow *parseWindow( File *inFile, char *buffer ); /////////////////////////////////////////////////////////////////////////////// // PRIVATE FUNCTIONS ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // parseBitFlag =============================================================== /** Parse one of the "flags" referred to below in the header comment * for ParseBitString(). Sets the appropriate bit in the 'bits' arg, * if successful. Returns TRUE on success, else FALSE. */ //============================================================================= static Bool parseBitFlag( const char *flagString, UnsignedInt *bits, const char **flagList ) { const char **c; int i; for( i = 0, c = flagList; *c; i++, c++ ) { if( !stricmp( *c, flagString ) ) { *bits |= (1 << i); return TRUE; } } return FALSE; } // end parseBitFlag // parseBitString ============================================================= /** Given a character string of the form 'A+B+C+D', parse the * flags separated by the '+' symbols into a bitfield stored in the 'bits' * argument. * Note that this routine does not clear any bits, only sets them. */ //============================================================================= static void parseBitString( const char *inBuffer, UnsignedInt *bits, const char **flagList ) { char buffer[256]; char *tok; // do not modify the inBuffer argument strcpy( buffer, inBuffer ); if( strncmp( buffer, "NULL", 4 ) ) { for( tok = strtok( buffer, "+" ); tok; tok = strtok( NULL, "+" ) ) { if ( !parseBitFlag( tok, bits, flagList ) ) { DEBUG_LOG(( "ParseBitString: Invalid flag '%s'.\n", tok )); } } } } // end parseBitString // readUntilSemicolon ========================================================= //============================================================================= static void readUntilSemicolon( File *fp, char *buffer, int maxBufLen ) { int i = 0; Bool start = TRUE; while( i < maxBufLen ) { // get next character fp->read(buffer + i, 1); // make all whitespace characters spaces if( isspace( buffer[ i ] ) ) { if( start == FALSE ) buffer[ i++ ] = ' '; } else { start = FALSE; if( buffer[ i ] == ';' ) { // found end of data chunk buffer[ i ] = '\000'; return; } i++; } } DEBUG_LOG(( "ReadUntilSemicolon: ERROR - Read buffer overflow - input truncated.\n" )); buffer[ maxBufLen - 1 ] = '\000'; } // end readUntilSemicolon // scanBool =================================================================== //============================================================================= static Int scanBool( const char *source, Bool& val ) { Int temp = 0; Int ret = sscanf( source, "%d", &temp ); val = (Bool)temp; return ret; } // end scanBool // scanShort ================================================================== //============================================================================= static Int scanShort( const char *source, Short& val ) { Int temp = 0; Int ret = sscanf( source, "%d", &temp ); val = (Short)temp; return ret; } // end scanShort // scanInt ==================================================================== //============================================================================= static Int scanInt( const char *source, Int& val ) { Int ret = sscanf( source, "%d", &val ); // not strictly necessary to wrap this, but it's more consistent return ret; } // end scanInt // scanUnsignedInt ============================================================ //============================================================================= static Int scanUnsignedInt( const char *source, UnsignedInt& val ) { Int ret = sscanf( source, "%d", &val ); // not strictly necessary to wrap this, but it's more consistent return ret; } // end scanUnsignedInt // resetWindowStack =========================================================== //============================================================================= static void resetWindowStack( void ) { memset( windowStack, 0, sizeof( windowStack ) ); stackPtr = windowStack; } // end resetWindowStack // resetWindowDefaults ======================================================== //============================================================================= static void resetWindowDefaults( void ) { defEnabledColor = 0; defDisabledColor = 0; defBackgroundColor = 0; defHiliteColor = 0; defSelectedColor = 0; defTextColor = 0; defFont = 0; } // end resetWindowDefaults // peekWindow ================================================================= //============================================================================= static GameWindow *peekWindow( void ) { if (stackPtr == windowStack) return NULL; return *(stackPtr - 1); } // end peekWindow // popWindow ================================================================== //============================================================================= static GameWindow *popWindow( void ) { if( stackPtr == windowStack ) return NULL; stackPtr--; return *stackPtr; } // end popWindow // pushWindow ================================================================= //============================================================================= static void pushWindow( GameWindow *window ) { if( stackPtr == &windowStack[ WIN_STACK_DEPTH - 1 ] ) { DEBUG_LOG(( "pushWindow: Warning, stack overflow\n" )); return; } // end if *stackPtr++ = window; } // end pushWindow // parseColor ================================================================= /** Parse a color entry and store it in the value pointed to by the * 'color' parm. */ //============================================================================= static Bool parseColor( Color *color, char *buffer ) { char *c; Byte red, green, blue; c = strtok( buffer, " \t\n\r" ); red = atoi(c); c = strtok( NULL, " \t\n\r" ); green = atoi(c); c = strtok( NULL, " \t\n\r" ); blue = atoi(c); *color = TheWindowManager->winMakeColor( red, green, blue, 255 ); return TRUE; } // end parseColor // parseDefaultColor ========================================================== /** Parse a default color entry and store it in the value pointed to by * the 'color' parm. */ //============================================================================= static Bool parseDefaultColor( Color *color, File *inFile, char *buffer ) { // eat '=' // fscanf( inFile, "%*s" ); AsciiString str; inFile->scanString(str); // Read the rest of the color definition readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); if (!strcmp( buffer, "TRANSPARENT" )) { *color = WIN_COLOR_UNDEFINED; } // end if else parseColor( color, buffer ); return TRUE; } // end parseDefaultColor // parseDefaultFont =========================================================== /** Parse the default font */ //============================================================================= static Bool parseDefaultFont( GameFont *font, File *inFile, char *buffer ) { // eat '=' // fscanf( inFile, "%*s" ); AsciiString str; inFile->scanString(str); // Read the rest of the color definition readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); /// @todo font parsing for window files work needed here // *font = GetFont( buffer ); // if( *font == NULL ) // return FALSE; return TRUE; } // end parseDefaultFont // parseTooltip =============================================================== /** Parse the tooltip field */ //============================================================================= static Bool parseTooltip( char *token, WinInstanceData *instData, char *buffer, void *data ) { UnicodeString tooltip; tooltip.set(L"Need tooltip translation"); /// @todo need to parse the tooltip in multibyte here instData->setTooltipText( tooltip ); return TRUE; } // end parseTooltip // parseScreenRect ============================================================ /** Parse the screen rect entry which tells us the position and size * of window. Note we scale for the current resolution if needed * and adjust to make the screen rect coords relative to any parent * if present */ //============================================================================= static Bool parseScreenRect( char *token, char *buffer, Int *x, Int *y, Int *width, Int *height ) { GameWindow *parent = peekWindow(); IRegion2D screenRegion; ICoord2D createRes; // creation resolution char *seps = " ,:=\n\r\t"; char *c; c = strtok( NULL, seps ); // UPPERLEFT token c = strtok( NULL, seps ); // x position scanInt( c, screenRegion.lo.x ); c = strtok( NULL, seps ); // y posotion scanInt( c, screenRegion.lo.y ); c = strtok( NULL, seps ); // BOTTOMRIGHT token c = strtok( NULL, seps ); // x position scanInt( c, screenRegion.hi.x ); c = strtok( NULL, seps ); // y posotion scanInt( c, screenRegion.hi.y ); c = strtok( NULL, seps ); // CREATIONRESOLUTION token c = strtok( NULL, seps ); // x creation resolution scanInt( c, createRes.x ); c = strtok( NULL, seps ); // y creation resolution scanInt( c, createRes.y ); // // shrink or expand the screen region by the ratio of the current // resolution divided by the creation resolution // Real xScale = (Real)TheDisplay->getWidth() / (Real)createRes.x; Real yScale = (Real)TheDisplay->getHeight() / (Real)createRes.y; screenRegion.lo.x = (Int)((Real)screenRegion.lo.x * xScale); screenRegion.lo.y = (Int)((Real)screenRegion.lo.y * yScale); screenRegion.hi.x = (Int)((Real)screenRegion.hi.x * xScale); screenRegion.hi.y = (Int)((Real)screenRegion.hi.y * yScale); // // given the screen region upper left compute the upper left that we // will give this window, if we have a parent note that the position // is relative to the parent client area, if no parent is present // we're talking about the screen // if( parent ) { ICoord2D parentScreenPos; // get parent position on screen parent->winGetScreenPosition( &parentScreenPos.x, &parentScreenPos.y ); // save x and y with parent position as relative (0,0) location *x = screenRegion.lo.x - parentScreenPos.x; *y = screenRegion.lo.y - parentScreenPos.y; } // end if else { *x = screenRegion.lo.x; *y = screenRegion.lo.y; } // end else // save our width and height from the adjusted screen region locations *width = screenRegion.hi.x - screenRegion.lo.x; *height = screenRegion.hi.y - screenRegion.lo.y; return TRUE; } // end parseScreenRect // parseImageOffset =========================================================== /** Parse the image draw offset */ //============================================================================= static Bool parseImageOffset( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c; c = strtok( buffer, " \t\n\r" ); instData->m_imageOffset.x = atoi( c ); c = strtok( NULL, " \t\n\r" ); instData->m_imageOffset.y = atoi( c ); return TRUE; } // end parseImageOffset // parseFont ================================================================== /** Parse the font field */ //============================================================================= static Bool parseFont( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c, *ptr; char *seps = " ,\n\r\t"; char *stringSeps = ":,\n\r\t\""; char fontName[ 256 ]; Int fontSize; Int fontBold; // "NAME" c = strtok( buffer, seps ); // label // scan to the first " mark ptr = buffer; while( *ptr != '"' ) ptr++; ptr++; // skip the " c = strtok( ptr, stringSeps ); // value strcpy( fontName, c ); // "SIZE" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, fontSize ); // "BOLD" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, fontBold ); if( TheFontLibrary ) { GameFont *font; font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold ); if( font ) instData->m_font = font; } // end if return TRUE; } // end parseFont // parseName ================================================================= /** Parse the NAME field */ //============================================================================= static Bool parseName( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c, *ptr; // char *seps = " ,\n\r\t"; char *stringSeps = "\""; // scan to the first " mark ptr = buffer; while( *ptr != '"' ) ptr++; ptr++; // skip the first " c = strtok( ptr, stringSeps ); // name value instData->m_decoratedNameString = c; // given the name assign a window ID from the assert( TheNameKeyGenerator ); if( TheNameKeyGenerator ) instData->m_id = (Int)TheNameKeyGenerator->nameToKey( instData->m_decoratedNameString ); return TRUE; } // end parseName // parseStatus ================================================================ /** Parse the STATUS field */ //============================================================================= static Bool parseStatus( char *token, WinInstanceData *instData, char *buffer, void *data ) { instData->m_status = 0; parseBitString( buffer, &instData->m_status, WindowStatusNames ); return TRUE; } // end parseStatus // parseStyle ================================================================= /** Parse the STYLE field */ //============================================================================= static Bool parseStyle( char *token, WinInstanceData *instData, char *buffer, void *data ) { instData->m_style = 0; parseBitString( buffer, &instData->m_style, WindowStyleNames ); return TRUE; } // end parseStyle // parseSystemCallback ======================================================== /** Parse the system method callback for a window */ //============================================================================= static Bool parseSystemCallback( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c, *ptr; // char *seps = " ,\n\r\t"; char *stringSeps = "\""; // scan to the first " mark ptr = buffer; while( *ptr != '"' ) ptr++; ptr++; // skip the first " c = strtok( ptr, stringSeps ); // name value // save a pointer of the function address DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") ); theSystemString = c; NameKeyType key = TheNameKeyGenerator->nameToKey( theSystemString ); systemFunc = TheFunctionLexicon->gameWinSystemFunc( key ); return TRUE; } // end parseSystemCallback // parseInputCallback ========================================================= /** Parse the Input method callback for a window */ //============================================================================= static Bool parseInputCallback( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c, *ptr; // char *seps = " ,\n\r\t"; char *stringSeps = "\""; // scan to the first " mark ptr = buffer; while( *ptr != '"' ) ptr++; ptr++; // skip the first " c = strtok( ptr, stringSeps ); // name value // save a pointer of the function address DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") ); theInputString = c; NameKeyType key = TheNameKeyGenerator->nameToKey( theInputString ); inputFunc = TheFunctionLexicon->gameWinInputFunc( key ); return TRUE; } // end parseInputCallback // parseTooltipCallback ======================================================= /** Parse the Tooltip method callback for a window */ //============================================================================= static Bool parseTooltipCallback( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c, *ptr; // char *seps = " ,\n\r\t"; char *stringSeps = "\""; // scan to the first " mark ptr = buffer; while( *ptr != '"' ) ptr++; ptr++; // skip the first " c = strtok( ptr, stringSeps ); // name value // save a pointer of the function address DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") ); theTooltipString = c; NameKeyType key = TheNameKeyGenerator->nameToKey( theTooltipString ); tooltipFunc = TheFunctionLexicon->gameWinTooltipFunc( key ); return TRUE; } // end parseTooltipCallback // parseDrawCallback ========================================================== /** Parse the Draw method callback for a window */ //============================================================================= static Bool parseDrawCallback( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c, *ptr; // char *seps = " ,\n\r\t"; char *stringSeps = "\""; // scan to the first " mark ptr = buffer; while( *ptr != '"' ) ptr++; ptr++; // skip the first " c = strtok( ptr, stringSeps ); // name value // save a pointer of the function address DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") ); theDrawString = c; NameKeyType key = TheNameKeyGenerator->nameToKey( theDrawString ); drawFunc = TheFunctionLexicon->gameWinDrawFunc( key ); return TRUE; } // end parseDrawCallback // parseHeaderTemplate ========================================================== /** Parse the Draw method callback for a window */ //============================================================================= static Bool parseHeaderTemplate( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c, *ptr; // char *seps = " ,\n\r\t"; char *stringSeps = "\""; // scan to the first " mark ptr = buffer; while( *ptr != '"' ) ptr++; ptr++; // skip the first " c = strtok( ptr, stringSeps ); // name value // save a pointer of the function address DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") ); instData->m_headerTemplateName = c; return TRUE; } // end parseDrawCallback // parseListboxData =========================================================== /** Parse listbox data entry */ //============================================================================= static Bool parseListboxData( char *token, WinInstanceData *instData, char *buffer, void *data ) { ListboxData *listData = (ListboxData *)data; char *c; char *seps = " :,\n\r\t"; // "LENGTH" c = strtok( buffer, seps ); // label c = strtok( NULL, seps ); scanShort( c, listData->listLength ); // "AUTOSCROLL" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, listData->autoScroll ); // "SCROLLIFATEND" (optional) c = strtok( NULL, seps ); // label if ( !stricmp(c, "ScrollIfAtEnd") ) { c = strtok( NULL, seps ); // value scanBool( c, listData->scrollIfAtEnd ); c = strtok( NULL, seps ); // label } else { listData->scrollIfAtEnd = FALSE; } // "AUTOPURGE" c = strtok( NULL, seps ); // value scanBool( c, listData->autoPurge ); // "SCROLLBAR" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, listData->scrollBar ); // "MULTISELECT" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, listData->multiSelect ); // "COLUMNS" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanShort( c, listData->columns ); if(listData->columns > 1) { listData->columnWidthPercentage = NEW Int[listData->columns]; for(Int i = 0; i < listData->columns; i++ ) { // "COLUMNS" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, listData->columnWidthPercentage[i] ); } } else listData->columnWidthPercentage = NULL; listData->columnWidth = NULL; // "FORCESELECT" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, listData->forceSelect ); // " return TRUE; } // end parseListboxData // parseComboBoxData =========================================================== /** Parse Combo Box data entry */ //============================================================================= static Bool parseComboBoxData( char *token, WinInstanceData *instData, char *buffer, void *data ) { ComboBoxData *comboData = (ComboBoxData *)data; char *c; char *seps = " :,\n\r\t"; c = strtok( buffer, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, comboData->isEditable ); c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, comboData->maxChars ); c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, comboData->maxDisplay ); c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, comboData->asciiOnly ); c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, comboData->lettersAndNumbersOnly ); return TRUE; }//parseComboBoxData // parseSliderData ============================================================ /** Parse slider data entry */ //============================================================================= static Bool parseSliderData( char *token, WinInstanceData *instData, char *buffer, void *data ) { SliderData *sliderData = (SliderData *)data; char *c; char *seps = " :,\n\r\t"; // "MINVALUE" c = strtok( buffer, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, sliderData->minVal ); // "MAXVALUE" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, sliderData->maxVal ); return TRUE; } // end parseSliderData // parseRadioButtonData ======================================================= /** Parse radio button data entry */ //============================================================================= static Bool parseRadioButtonData( char *token, WinInstanceData *instData, char *buffer, void *data ) { RadioButtonData *radioData = (RadioButtonData *)data; char *c; char *seps = " :,\n\r\t"; // "GROUP" c = strtok( buffer, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, radioData->group ); return TRUE; } // end parseRadioButtonData // parseTooltipText =========================================================== /** Parse the TOOLTIPTEXT field */ //============================================================================= static Bool parseTooltipText( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *ptr = buffer; char *c; char *stringSeps = "\n\r\t\""; // scan to the first " mark while( *ptr != '"' ) ptr++; ptr++; // skip the " if(strlen( ptr ) == 1 ) return TRUE; c = strtok( ptr, stringSeps ); // value if( strlen( c ) >= MAX_TEXT_LABEL ) { DEBUG_LOG(( "TextTooltip label '%s' is too long, max is '%d'\n", c, MAX_TEXT_LABEL )); assert( 0 ); return FALSE; } // end if instData->m_tooltipString.set(c); instData->setTooltipText(TheGameText->fetch(c)); return TRUE; } // end parseTooltipText // parseTooltipDelay ======================================================= /** Parse the tooltip delay */ //============================================================================= static Bool parseTooltipDelay( char *token, WinInstanceData *instData, char *buffer, void *data ) { //RadioButtonData *radioData = (RadioButtonData *)data; char *c; char *seps = " :,\n\r\t"; // "getvalue" c = strtok( buffer, seps ); // value scanInt( c, instData->m_tooltipDelay ); return TRUE; } // end parseTooltipDelay // parseText ================================================================== /** Parse the TEXT field */ //============================================================================= static Bool parseText( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *ptr = buffer; char *c; char *stringSeps = "\n\r\t\""; // scan to the first " mark while( *ptr != '"' ) ptr++; ptr++; // skip the " c = strtok( ptr, stringSeps ); // value if( strlen( c ) >= MAX_TEXT_LABEL ) { DEBUG_LOG(( "Text label '%s' is too long, max is '%d'\n", c, MAX_TEXT_LABEL )); assert( 0 ); return FALSE; } // end if instData->m_textLabelString = c; return TRUE; } // end parseText // parseTextColor ============================================================= /** Parse text color entries for enabled, disabled, and hilite with * drop shadow colors */ //============================================================================= static Bool parseTextColor( char *token, WinInstanceData *instData, char *buffer, void *data ) { char *c; char *seps = " :,\n\r\t"; UnsignedInt r, g, b, a; Int i, states = 3; TextDrawData *textData; Bool first = TRUE; for( i = 0; i < states; i++ ) { if( i == 0 ) textData = &instData->m_enabledText; else if( i == 1 ) textData = &instData->m_disabledText; else if( i == 2 ) textData = &instData->m_hiliteText; else { DEBUG_LOG(( "Undefined state for text color\n" )); assert( 0 ); return FALSE; } // end else // color if( first == TRUE ) c = strtok( buffer, seps ); // label else c = strtok( NULL, seps ); // label first = FALSE; c = strtok( NULL, seps ); // value scanUnsignedInt( c, r ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, g ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, b ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, a ); textData->color = GameMakeColor( r, g, b, a ); // border color c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanUnsignedInt( c, r ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, g ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, b ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, a ); textData->borderColor = GameMakeColor( r, g, b, a ); } // end if return TRUE; } // end parseTextColor // parseStaticTextData ======================================================== /** Parse static text data entry */ //============================================================================= static Bool parseStaticTextData( char *token, WinInstanceData *instData, char *buffer, void *data ) { TextData *textData = (TextData *)data; char *c; char *seps = " :,\n\r\t"; // "CENTERED" c = strtok( buffer, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, textData->centered ); return TRUE; } // end parseStaticTextDAta // parseTextEntryData ========================================================= /** Parse text entry data entry */ //============================================================================= static Bool parseTextEntryData( char *token, WinInstanceData *instData, char *buffer, void *data ) { EntryData *entryData = (EntryData *)data; char *c; char *seps = " :,\n\r\t"; // "MAXLEN" c = strtok( buffer, seps ); // label c = strtok( NULL, seps ); // value scanShort( c, entryData->maxTextLen ); // "SECRETTEXT" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, entryData->secretText ); // "NUMERICALONLY" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, entryData->numericalOnly ); // "ALPHANUMERICALONLY" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, entryData->alphaNumericalOnly ); // "ASCIIONLY" c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanBool( c, entryData->aSCIIOnly ); return TRUE; } // end parseStaticTextDAta // parseTabControlData ========================================================= /** Parse tab control data entry */ //============================================================================= static Bool parseTabControlData( char *token, WinInstanceData *instData, char *buffer, void *data ) { TabControlData *tabControlData = (TabControlData *)data; char *c; char *seps = " :,\n\r\t"; //TABORIENTATION c = strtok( buffer, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, tabControlData->tabOrientation ); //TABEDGE c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, tabControlData->tabEdge ); //TABWIDTH c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, tabControlData->tabWidth ); //TABHEIGHT c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, tabControlData->tabHeight ); //TABCOUNT c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, tabControlData->tabCount ); //PANEBORDER c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, tabControlData->paneBorder ); //PANEDISABLED Int entryCount = 0; c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanInt( c, entryCount ); for( Int paneIndex = 0; paneIndex < entryCount; paneIndex ++ ) { c = strtok( NULL, seps ); // value scanBool( c, tabControlData->subPaneDisabled[paneIndex] ); } return TRUE; } // parseDrawData ============================================================== /** Parse set of draw data elements */ //============================================================================= static Bool parseDrawData( char *token, WinInstanceData *instData, char *buffer, void *data ) { Int i; UnsignedInt r, g, b, a; WinDrawData *drawData; Bool first = TRUE; char *c; char *seps = " :,\n\r\t"; for( i = 0; i < MAX_DRAW_DATA; i++ ) { // get the right draw data if( strcmp( token, "ENABLEDDRAWDATA" ) == 0 ) drawData = &instData->m_enabledDrawData[ i ]; else if( strcmp( token, "DISABLEDDRAWDATA" ) == 0 ) drawData = &instData->m_disabledDrawData[ i ]; else if( strcmp( token, "HILITEDRAWDATA" ) == 0 ) drawData = &instData->m_hiliteDrawData[ i ]; else if( strcmp( token, "LISTBOXENABLEDUPBUTTONDRAWDATA" ) == 0 ) drawData = &enabledUpButtonDrawData[ i ]; else if( strcmp( token, "LISTBOXDISABLEDUPBUTTONDRAWDATA" ) == 0 ) drawData = &disabledUpButtonDrawData[ i ]; else if( strcmp( token, "LISTBOXHILITEUPBUTTONDRAWDATA" ) == 0 ) drawData = &hiliteUpButtonDrawData[ i ]; else if( strcmp( token, "LISTBOXENABLEDDOWNBUTTONDRAWDATA" ) == 0 ) drawData = &enabledDownButtonDrawData[ i ]; else if( strcmp( token, "LISTBOXDISABLEDDOWNBUTTONDRAWDATA" ) == 0 ) drawData = &disabledDownButtonDrawData[ i ]; else if( strcmp( token, "LISTBOXHILITEDOWNBUTTONDRAWDATA" ) == 0 ) drawData = &hiliteDownButtonDrawData[ i ]; else if( strcmp( token, "LISTBOXENABLEDSLIDERDRAWDATA" ) == 0 ) drawData = &enabledSliderDrawData[ i ]; else if( strcmp( token, "LISTBOXDISABLEDSLIDERDRAWDATA" ) == 0 ) drawData = &disabledSliderDrawData[ i ]; else if( strcmp( token, "LISTBOXHILITESLIDERDRAWDATA" ) == 0 ) drawData = &hiliteSliderDrawData[ i ]; else if( strcmp( token, "SLIDERTHUMBENABLEDDRAWDATA" ) == 0 ) drawData = &enabledSliderThumbDrawData[ i ]; else if( strcmp( token, "SLIDERTHUMBDISABLEDDRAWDATA" ) == 0 ) drawData = &disabledSliderThumbDrawData[ i ]; else if( strcmp( token, "SLIDERTHUMBHILITEDRAWDATA" ) == 0 ) drawData = &hiliteSliderThumbDrawData[ i ]; else if( strcmp( token, "COMBOBOXDROPDOWNBUTTONENABLEDDRAWDATA" ) == 0 ) drawData = &enabledDropDownButtonDrawData[ i ]; else if( strcmp( token, "COMBOBOXDROPDOWNBUTTONDISABLEDDRAWDATA" ) == 0 ) drawData = &disabledDropDownButtonDrawData[ i ]; else if( strcmp( token, "COMBOBOXDROPDOWNBUTTONHILITEDRAWDATA" ) == 0 ) drawData = &hiliteDropDownButtonDrawData[ i ]; else if( strcmp( token, "COMBOBOXEDITBOXENABLEDDRAWDATA" ) == 0 ) drawData = &enabledEditBoxDrawData[ i ]; else if( strcmp( token, "COMBOBOXEDITBOXDISABLEDDRAWDATA" ) == 0 ) drawData = &disabledEditBoxDrawData[ i ]; else if( strcmp( token, "COMBOBOXEDITBOXHILITEDRAWDATA" ) == 0 ) drawData = &hiliteEditBoxDrawData[ i ]; else if( strcmp( token, "COMBOBOXLISTBOXENABLEDDRAWDATA" ) == 0 ) drawData = &enabledListBoxDrawData[ i ]; else if( strcmp( token, "COMBOBOXLISTBOXDISABLEDDRAWDATA" ) == 0 ) drawData = &disabledListBoxDrawData[ i ]; else if( strcmp( token, "COMBOBOXLISTBOXHILITEDRAWDATA" ) == 0 ) drawData = &hiliteListBoxDrawData[ i ]; else { DEBUG_LOG(( "ParseDrawData, undefined token '%s'\n", token )); assert( 0 ); return FALSE; } // end else // IMAGE: X if( first == TRUE ) c = strtok( buffer, seps ); // label else c = strtok( NULL, seps ); // label first = FALSE; c = strtok( NULL, seps ); // value if( strcmp( c, "NoImage" ) ) drawData->image = TheMappedImageCollection->findImageByName( AsciiString( c ) ); else drawData->image = NULL; // COLOR: R G B A c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanUnsignedInt( c, r ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, g ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, b ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, a ); drawData->color = GameMakeColor( r, g, b, a ); // BORDERCOLOR: R G B A c = strtok( NULL, seps ); // label c = strtok( NULL, seps ); // value scanUnsignedInt( c, r ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, g ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, b ); c = strtok( NULL, seps ); // value scanUnsignedInt( c, a ); drawData->borderColor = GameMakeColor( r, g, b, a ); } // end for i return TRUE; } // end parseDrawData // getDataTemplate ============================================================ /** Given a window type style string return the address of a static * gadget data type used for the generic data pointers in the * GUI gadget contorls */ //============================================================================= void *getDataTemplate( char *type ) { static EntryData eData; static SliderData sData; static ListboxData lData; static TextData tData; static RadioButtonData rData; static TabControlData tcData; static ComboBoxData cData; void *data; if( !strcmp( type, "VERTSLIDER" ) || !strcmp( type, "HORZSLIDER" ) ) { memset( &sData, 0, sizeof( SliderData ) ); data = &sData; } else if( !strcmp( type, "SCROLLLISTBOX" ) ) { memset( &lData, 0, sizeof( ListboxData ) ); data = &lData; } else if( !strcmp( type, "TABCONTROL" ) ) { memset( &tcData, 0, sizeof( TabControlData ) ); data = &tcData; } else if( !strcmp( type, "ENTRYFIELD" ) ) { memset( &eData, 0, sizeof( EntryData ) ); data = &eData; } else if( !strcmp( type, "STATICTEXT" ) ) { memset( &tData, 0, sizeof( TextData ) ); data = &tData; } else if( !strcmp( type, "RADIOBUTTON" ) ) { memset( &rData, 0, sizeof( RadioButtonData ) ); data = &rData; } else if( !strcmp( type, "COMBOBOX" ) ) { memset( &cData, 0, sizeof( ComboBoxData ) ); data = &cData; } else data = NULL; return data; } // end getDataTemplate // parseData ================================================================== // // Parse the data for gadgets. For sliders the data is in the format: // // // For listboxes the data is formatted as: // // // For Combo Boxes the data is formatted as: // // // For entry fields the data is as follows: // <1 = NumericalOnly, 2 = AlphaNumericOnly> // // For text the data is as follows: // // // 1/2/2003: THIS FUNCTION IS NEVER REACHED; IT IS OBSOLETE -MDC // //============================================================================= static Bool parseData( void **data, char *type, char *buffer ) { char *c; static EntryData eData; static SliderData sData; static ListboxData lData; static TextData tData; static RadioButtonData rData; static ComboBoxData cData; if( !strcmp( type, "VERTSLIDER" ) || !strcmp( type, "HORZSLIDER" ) ) { memset( &sData, 0, sizeof( SliderData ) ); c = strtok( buffer, " \t\n\r" ); sData.minVal = atoi(c); c = strtok( NULL, " \t\n\r" ); sData.maxVal = atoi(c); *data = &sData; } else if( !strcmp( type, "SCROLLLISTBOX" ) ) { memset( &lData, 0, sizeof( ListboxData ) ); c = strtok( buffer, " \t\n\r" ); lData.listLength = atoi(c); // c = strtok( NULL, " \t\n\r" ); // lData.entryHeight = atoi(c); c = strtok( NULL, " \t\n\r" ); lData.autoScroll = atoi(c); c = strtok( NULL, " \t\n\r" ); lData.autoPurge = atoi(c); c = strtok( NULL, " \t\n\r" ); lData.scrollBar = atoi(c); c = strtok( NULL, " \t\n\r" ); lData.multiSelect = atoi(c); c = strtok( NULL, " \t\n\r" ); lData.forceSelect = atoi(c); *data = &lData; } else if( !strcmp( type, "ENTRYFIELD" ) ) { memset( &eData, 0, sizeof( EntryData ) ); c = strtok( buffer, " \t\n\r" ); eData.maxTextLen = atoi(c); c = strtok( NULL, " \t\n\r" ); // if (c) // eData.entryWidth = atoi(c); // else // eData.entryWidth = -1; c = strtok( NULL, " \t\n\r" ); if (c) { eData.secretText = atoi(c); if( eData.secretText != FALSE ) eData.secretText = TRUE; } else eData.secretText = FALSE; c = strtok( NULL, " \t\n\r" ); if (c) { eData.numericalOnly = ( atoi(c) == 1 ); eData.alphaNumericalOnly = ( atoi(c) == 2 ); eData.aSCIIOnly = ( atoi(c) == 3 ); } else { eData.numericalOnly = FALSE; eData.alphaNumericalOnly = FALSE; eData.aSCIIOnly = FALSE; } *data = &eData; } else if( !strcmp( type, "STATICTEXT" ) ) { c = strtok( buffer, " \t\n\r" ); tData.centered = atoi(c); if( tData.centered != FALSE ) tData.centered = TRUE; c = strtok( NULL, " \t\n\r" ); /** @todo need to get a label from the translation manager, uncomment the following line and remove the WideChar assignment when we have it */ // text = StringManagerFetch( c ); // text = L"Need StrManager, Remove me!"; // TheWindowManager->winStrcpy( tData.text, text ); *data = &tData; } else if( !strcmp( type, "RADIOBUTTON" ) ) { c = strtok( buffer, " \t\n\r" ); rData.group = atoi(c); /// @todo Colin: Why was this here??? // if( tData.centered != FALSE ) // { // tData.centered = TRUE; // } *data = &rData; } else *data = NULL; return TRUE; } // end parseData // setWindowText ============================================================== /** Set the default text for a window or gadget control */ //============================================================================= static void setWindowText( GameWindow *window, AsciiString textLabel ) { // sanity if (textLabel.isEmpty()) return; UnicodeString theText, entryText; //Translate the text theText = TheGameText->fetch( (char *)textLabel.str()); // set the text in the window based on what it is if( BitTest( window->winGetStyle(), GWS_PUSH_BUTTON ) ) GadgetButtonSetText( window, theText ); else if( BitTest( window->winGetStyle(), GWS_RADIO_BUTTON ) ) GadgetRadioSetText( window, theText ); else if( BitTest( window->winGetStyle(), GWS_CHECK_BOX ) ) GadgetCheckBoxSetText( window, theText ); else if( BitTest( window->winGetStyle(), GWS_STATIC_TEXT ) ) GadgetStaticTextSetText( window, theText ); else if( BitTest( window->winGetStyle(), GWS_ENTRY_FIELD ) ) { entryText.translate(textLabel); GadgetTextEntrySetText( window, entryText ); } else window->winSetText( theText ); } // end setWindowText // createGadget =============================================================== /** Create a gadget based on the 'type' parm */ //============================================================================= static GameWindow *createGadget( char *type, GameWindow *parent, Int status, Int x, Int y, Int width, Int height, WinInstanceData *instData, void *data ) { GameWindow *window; instData->m_owner = parent; if( !strcmp( type, "PUSHBUTTON" ) ) { instData->m_style |= GWS_PUSH_BUTTON; window = TheWindowManager->gogoGadgetPushButton( parent, status, x, y, width, height, instData, instData->m_font, FALSE ); } else if( !strcmp( type, "RADIOBUTTON" ) ) { RadioButtonData *rData = (RadioButtonData *)data; char filename[ MAX_WINDOW_NAME_LEN ]; char *c; // // assign a screen identifier to the radio button based on the // filename the radio button was saved in // strcpy( filename, instData->m_decoratedNameString.str() ); c = strchr( filename, ':' ); if( c ) *c = 0; // terminate after filename (format is filename:gadgetname) assert( TheNameKeyGenerator ); if( TheNameKeyGenerator ) rData->screen = (Int)(TheNameKeyGenerator->nameToKey( AsciiString(filename) )); instData->m_style |= GWS_RADIO_BUTTON; window = TheWindowManager->gogoGadgetRadioButton( parent, status, x, y, width, height, instData, rData, instData->m_font, FALSE ); } else if( !strcmp( type, "CHECKBOX" ) ) { instData->m_style |= GWS_CHECK_BOX; window = TheWindowManager->gogoGadgetCheckbox( parent, status, x, y, width, height, instData, instData->m_font, FALSE ); } else if( !strcmp( type, "TABCONTROL" ) ) { TabControlData *tcData = (TabControlData *)data; instData->m_style |= GWS_TAB_CONTROL; window = TheWindowManager->gogoGadgetTabControl( parent, status, x, y, width, height, instData, tcData, instData->m_font, FALSE ); } else if( !strcmp( type, "VERTSLIDER" ) ) { SliderData *sData = (SliderData *)data; instData->m_style |= GWS_VERT_SLIDER; window = TheWindowManager->gogoGadgetSlider( parent, status, x, y, width, height, instData, sData, instData->m_font, FALSE ); // // we know we've read in the slider thumb data in the definition file // (it's guaranteed to be generated by the editor) so place that // draw data into the thumb of the slider // GameWindow *thumb = window->winGetChild(); if( thumb ) { WinInstanceData *instData = thumb->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ]; } // end for i } //end if } else if( !strcmp( type, "HORZSLIDER" ) ) { SliderData *sData = (SliderData *)data; instData->m_style |= GWS_HORZ_SLIDER; window = TheWindowManager->gogoGadgetSlider( parent, status, x, y, width, height, instData, sData, instData->m_font, FALSE ); // // we know we've read in the slider thumb data in the definition file // (it's guaranteed to be generated by the editor) so place that // draw data into the thumb of the slider // GameWindow *thumb = window->winGetChild(); if( thumb ) { WinInstanceData *instData = thumb->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ]; } // end for i } //end if } else if( !strcmp( type, "SCROLLLISTBOX" ) ) { ListboxData *lData = (ListboxData *)data; instData->m_style |= GWS_SCROLL_LISTBOX; window = TheWindowManager->gogoGadgetListBox( parent, status, x, y, width, height, instData, lData, instData->m_font, FALSE ); // // we know that in the file we have read the draw data for the listbox // parts (up button, down button, and slider), now that we have those // parts actually created we must assign that data to them // GameWindow *upButton = GadgetListBoxGetUpButton( window ); if( upButton ) { WinInstanceData *instData = upButton->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledUpButtonDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledUpButtonDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteUpButtonDrawData[ i ]; } // end for i } // end if GameWindow *downButton = GadgetListBoxGetDownButton( window ); if( downButton ) { WinInstanceData *instData = downButton->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledDownButtonDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledDownButtonDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteDownButtonDrawData[ i ]; } // end for i } // end if GameWindow *slider = GadgetListBoxGetSlider( window ); if( slider ) { WinInstanceData *instData = slider->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledSliderDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledSliderDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteSliderDrawData[ i ]; } // end for i // do the slider thumb GameWindow *thumb = slider->winGetChild(); if( thumb ) { WinInstanceData *instData = thumb->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ]; } // end for i } //end if } // end if } else if( !strcmp( type, "COMBOBOX" ) ) { ComboBoxData *cData = (ComboBoxData *)data; cData->entryData = NEW EntryData; memset ( cData->entryData, 0, sizeof(EntryData)); cData->listboxData = NEW ListboxData; memset ( cData->listboxData, 0, sizeof(ListboxData)); //initialize combo box data //cData->isEditable = TRUE; //cData->maxChars = 16; //cData->maxDisplay = 5; cData->entryCount = 0; //initialize entry data cData->entryData->aSCIIOnly = cData->asciiOnly; cData->entryData->alphaNumericalOnly = cData->lettersAndNumbersOnly; cData->entryData->maxTextLen = cData->maxChars; //initialize listbox data cData->listboxData->listLength = 10; cData->listboxData->autoScroll = 0; cData->listboxData->scrollIfAtEnd = FALSE; cData->listboxData->autoPurge = 0; cData->listboxData->scrollBar = 1; cData->listboxData->multiSelect = 0; cData->listboxData->forceSelect = 1; cData->listboxData->columns = 1; cData->listboxData->columnWidth = NULL; cData->listboxData->columnWidthPercentage = NULL; instData->m_style |= GWS_COMBO_BOX; window = TheWindowManager->gogoGadgetComboBox( parent, status, x, y, width, height, instData, cData, instData->m_font, FALSE ); GameWindow *dropDownButton = GadgetComboBoxGetDropDownButton( window ); if( dropDownButton ) { WinInstanceData *instData = dropDownButton->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledDropDownButtonDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledDropDownButtonDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteDropDownButtonDrawData[ i ]; } // end for i } // end if GameWindow *editBox = GadgetComboBoxGetEditBox( window ); if( editBox ) { WinInstanceData *instData = editBox->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledEditBoxDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledEditBoxDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteEditBoxDrawData[ i ]; } // end for i } // end if GameWindow *listBox = GadgetComboBoxGetListBox( window ); if( listBox ) { WinInstanceData *instData = listBox->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledListBoxDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledListBoxDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteListBoxDrawData[ i ]; } // end for i GameWindow *upButton = GadgetListBoxGetUpButton( listBox ); if( upButton ) { WinInstanceData *instData = upButton->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledUpButtonDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledUpButtonDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteUpButtonDrawData[ i ]; } // end for i } // end if GameWindow *downButton = GadgetListBoxGetDownButton( listBox ); if( downButton ) { WinInstanceData *instData = downButton->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledDownButtonDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledDownButtonDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteDownButtonDrawData[ i ]; } // end for i } // end if GameWindow *slider = GadgetListBoxGetSlider( listBox ); if( slider ) { WinInstanceData *instData = slider->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledSliderDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledSliderDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteSliderDrawData[ i ]; } // end for i // do the slider thumb GameWindow *thumb = slider->winGetChild(); if( thumb ) { WinInstanceData *instData = thumb->winGetInstanceData(); for( Int i = 0; i < MAX_DRAW_DATA; i++ ) { instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ]; instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ]; instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ]; } // end for i } //end if } // end if } } else if( !strcmp( type, "ENTRYFIELD" ) ) { EntryData *eData = (EntryData *)data; instData->m_style |= GWS_ENTRY_FIELD; window = TheWindowManager->gogoGadgetTextEntry( parent, status, x, y, width, height, instData, eData, instData->m_font, FALSE ); } else if( !strcmp( type, "STATICTEXT" ) ) { TextData *tData = (TextData *)data; instData->m_style |= GWS_STATIC_TEXT; window = TheWindowManager->gogoGadgetStaticText( parent, status, x, y, width, height, instData, tData, instData->m_font, FALSE ); } else if( !strcmp( type, "PROGRESSBAR" ) ) { instData->m_style |= GWS_PROGRESS_BAR; window = TheWindowManager->gogoGadgetProgressBar( parent, status, x, y, width, height, instData, instData->m_font, FALSE ); } return window; } // end createGadget // createWindow =============================================================== // Create a user window or a gadget depending on the 'type' parm //============================================================================= static GameWindow *createWindow( char *type, Int id, Int status, Int x, Int y, Int width, Int height, WinInstanceData *instData, void *data, GameWinSystemFunc system, GameWinInputFunc input, GameWinTooltipFunc tooltip, GameWinDrawFunc draw ) { GameWindow *window, *parent; // Check to see if this window has a parent parent = peekWindow(); // If this is a regular window just create it if( !strcmp( type, "USER" ) ) { window = TheWindowManager->winCreate( parent, status, x, y, width, height, system ); if( window ) { instData->m_style |= GWS_USER_WINDOW; window->winSetInstanceData( instData ); window->winSetWindowId( id ); } // end if } else if( !strcmp( type, "TABPANE" ) ) { window = TheWindowManager->winCreate( parent, status, x, y, width, height, system ); if( window ) { instData->m_style |= GWS_TAB_PANE; window->winSetInstanceData( instData ); window->winSetWindowId( id ); } // end if } else { // Else parse the type and create the gadget window = createGadget( type, parent, status, x, y, width, height, instData, data ); if( window ) { // set id window->winSetWindowId( id ); } // end if } // assign the callbacks if they are not empty/NULL, that means they were read // in and parsed from the window definition file if( window ) { if( system ) window->winSetSystemFunc( system ); if( input ) window->winSetInputFunc( input ); if( tooltip ) window->winSetTooltipFunc( tooltip ); if( draw ) window->winSetDrawFunc( draw ); // save strings for edit data if present GameWindowEditData *editData = window->winGetEditData(); if( editData ) { editData->systemCallbackString = theSystemString; editData->inputCallbackString = theInputString; editData->tooltipCallbackString = theTooltipString; editData->drawCallbackString = theDrawString; } // end if } // end if if( window ) { // set any text read from the textLabel setWindowText( window, instData->m_textLabelString ); } // end if // If there is a parent window, send it the SCRIPT_CREATE message if( window && parent ) TheWindowManager->winSendInputMsg( parent, GWM_SCRIPT_CREATE, id, 0 ); return window; } // end createWindow // parseChildWindows ========================================================== /** Parse window descriptions until an extra end is encountered indicating * the end of this block of child window descriptions. */ //============================================================================= static Bool parseChildWindows( GameWindow *window, File *inFile, char *buffer ) { GameWindow *lastWindow; AsciiString asciibuf; //The gadget with children needs to delete its default created children in favor //of the ones from the script file. So kill them before reading. if( BitTest( window->winGetStyle(), GWS_TAB_CONTROL ) ) { GameWindow *nextWindow = NULL; for( GameWindow *myChild = window->winGetChild(); myChild; myChild = nextWindow ) { nextWindow = myChild->winGetNext(); TheWindowManager->winDestroy( myChild ); } } // Push the current window onto the stack so we know it's the parent pushWindow( window ); while( TRUE ) { if (inFile->scanString(asciibuf) == FALSE) { break; } if (asciibuf.compare("ENDALLCHILDREN") == 0) { break; } if (asciibuf.compare("END") == 0) { break; } if (asciibuf.compare("ENABLEDCOLOR") == 0) { if( parseDefaultColor( &defEnabledColor, inFile, buffer ) == FALSE ) { return FALSE; } } else if (asciibuf.compare("DISABLEDCOLOR") == 0) { if( parseDefaultColor( &defDisabledColor, inFile, buffer ) == FALSE ) { return FALSE; } } else if (asciibuf.compare("HILITECOLOR") == 0) { if( parseDefaultColor( &defHiliteColor, inFile, buffer ) == FALSE ) { return FALSE; } } else if (asciibuf.compare("SELECTEDCOLOR") == 0) { if( parseDefaultColor( &defSelectedColor, inFile, buffer ) == FALSE ) { return FALSE; } } else if (asciibuf.compare("TEXTCOLOR") == 0) { if( parseDefaultColor( &defTextColor, inFile, buffer ) == FALSE ) { return FALSE; } } else if (asciibuf.compare("WINDOW") == 0) { // Parse window descriptions until the last END is read if( parseWindow( inFile, buffer ) == NULL ) { return FALSE; } } } // end while( TRUE ) // Pop the current window off the stack lastWindow = popWindow(); if( lastWindow != window ) { DEBUG_LOG(( "parseChildWindows: unmatched window on stack. Corrupt stack or bad source\n" )); return FALSE; } if( BitTest( window->winGetStyle(), GWS_TAB_CONTROL ) ) GadgetTabControlFixupSubPaneList( window );//all children created, so re-fill SubPane array with children return TRUE; } // end parseChildWindows // lookup table for parsing functions static GameWindowParse gameWindowFieldList[] = { { "NAME", parseName }, { "STATUS", parseStatus }, { "STYLE", parseStyle }, { "SYSTEMCALLBACK", parseSystemCallback }, { "INPUTCALLBACK", parseInputCallback }, { "TOOLTIPCALLBACK", parseTooltipCallback }, { "DRAWCALLBACK", parseDrawCallback }, { "FONT", parseFont }, { "HEADERTEMPLATE", parseHeaderTemplate }, { "LISTBOXDATA", parseListboxData }, { "COMBOBOXDATA", parseComboBoxData }, { "SLIDERDATA", parseSliderData }, { "RADIOBUTTONDATA", parseRadioButtonData }, { "TOOLTIPTEXT", parseTooltipText }, { "TOOLTIPDELAY", parseTooltipDelay }, { "TEXT", parseText }, { "TEXTCOLOR", parseTextColor }, { "STATICTEXTDATA", parseStaticTextData }, { "TEXTENTRYDATA", parseTextEntryData }, { "TABCONTROLDATA", parseTabControlData }, { "ENABLEDDRAWDATA", parseDrawData }, { "DISABLEDDRAWDATA", parseDrawData }, { "HILITEDRAWDATA", parseDrawData }, { "LISTBOXENABLEDUPBUTTONDRAWDATA", parseDrawData }, { "LISTBOXENABLEDDOWNBUTTONDRAWDATA", parseDrawData }, { "LISTBOXENABLEDSLIDERDRAWDATA", parseDrawData }, { "LISTBOXDISABLEDUPBUTTONDRAWDATA", parseDrawData }, { "LISTBOXDISABLEDDOWNBUTTONDRAWDATA", parseDrawData }, { "LISTBOXDISABLEDSLIDERDRAWDATA", parseDrawData }, { "LISTBOXHILITEUPBUTTONDRAWDATA", parseDrawData }, { "LISTBOXHILITEDOWNBUTTONDRAWDATA", parseDrawData }, { "LISTBOXHILITESLIDERDRAWDATA", parseDrawData }, { "SLIDERTHUMBENABLEDDRAWDATA", parseDrawData }, { "SLIDERTHUMBDISABLEDDRAWDATA", parseDrawData }, { "SLIDERTHUMBHILITEDRAWDATA", parseDrawData }, { "COMBOBOXDROPDOWNBUTTONENABLEDDRAWDATA", parseDrawData }, { "COMBOBOXDROPDOWNBUTTONDISABLEDDRAWDATA", parseDrawData }, { "COMBOBOXDROPDOWNBUTTONHILITEDRAWDATA", parseDrawData }, { "COMBOBOXEDITBOXENABLEDDRAWDATA", parseDrawData }, { "COMBOBOXEDITBOXDISABLEDDRAWDATA", parseDrawData }, { "COMBOBOXEDITBOXHILITEDRAWDATA", parseDrawData }, { "COMBOBOXLISTBOXENABLEDDRAWDATA", parseDrawData }, { "COMBOBOXLISTBOXDISABLEDDRAWDATA", parseDrawData }, { "COMBOBOXLISTBOXHILITEDRAWDATA", parseDrawData }, { "IMAGEOFFSET", parseImageOffset }, { "TOOLTIP", parseTooltip }, { NULL, NULL } }; // parseWindow ================================================================ /** Parse a WINDOW entry in the script. */ //============================================================================= static GameWindow *parseWindow( File *inFile, char *buffer ) { GameWindowParse *parse; GameWindow *window = NULL; GameWindow *parent = peekWindow(); WinInstanceData instData; char type[64]; char token[ 256 ]; char *c; Int x, y, width, height; void *data = NULL; ICoord2D parentSize; AsciiString asciibuf; // // reset our 'static globals' that house the current parsed window callback // definitions to empty // systemFunc = NULL; inputFunc = NULL; tooltipFunc = NULL; drawFunc = NULL; theSystemString.clear(); theInputString.clear(); theTooltipString.clear(); theDrawString.clear(); // get the size of the parent, or if no parent present the screen if( parent ) { parent->winGetSize( &parentSize.x, &parentSize.y ); } // end if else { parentSize.x = TheDisplay->getWidth(); parentSize.y = TheDisplay->getHeight(); } // end else // Initialize the instance data to the defaults /// @todo need to support enabled/disabled/hilite text colors here instData.init(); instData.m_enabledText.color = defTextColor; instData.m_enabledText.borderColor = defTextColor; instData.m_disabledText.color = defTextColor; instData.m_disabledText.borderColor = defTextColor; instData.m_hiliteText.color = defTextColor; instData.m_hiliteText.borderColor = defTextColor; /// @todo need real font support here instData.m_font = defFont; // // read the first few lines that are required to be first in a // window definition file including position, size, type, and id // // window type readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); c = strtok( buffer, seps ); assert( strcmp( c, "WINDOWTYPE" ) == 0 ); c = strtok( NULL, seps ); // get data to right of = sign strcpy( type, c ); // // based on the window type get a pointer for any specific data // for the gadget controls needed // data = getDataTemplate( type ); // position readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); c = strtok( buffer, seps ); assert( strcmp( c, "SCREENRECT" ) == 0 ); if( parseScreenRect( c, buffer, &x, &y, &width, &height ) == FALSE ) goto cleanupAndExit; // parse all the field definitions while( TRUE ) { // get token inFile->scanString(asciibuf); // parse field for( parse = gameWindowFieldList; parse->parse; parse++ ) { if (asciibuf.compare(parse->name) == 0) { strcpy( token, asciibuf.str() ); // eat '=' inFile->scanString(asciibuf); readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); if (parse->parse( token, &instData, buffer, data ) == FALSE ) { DEBUG_LOG(( "parseGameObject: Error parsing %s\n", parse->name )); goto cleanupAndExit; } break; } } // end for if( parse->parse == NULL ) { // If it's the END keyword if (asciibuf.compare("DATA") == 0) { // eat '=' inFile->scanString(asciibuf); readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); if( parseData( &data, type, buffer ) == FALSE ) { DEBUG_LOG(( "parseGameWindow: Error parsing %s\n", parse->name )); goto cleanupAndExit; } } else if (asciibuf.compare("END") == 0) { // Check to see if we have a header template, if so, set the font equal to that. if(TheHeaderTemplateManager->getFontFromTemplate(instData.m_headerTemplateName)) instData.m_font = TheHeaderTemplateManager->getFontFromTemplate(instData.m_headerTemplateName); // Create a window using the current description if( window == NULL ) window = createWindow( type, instData.m_id, instData.getStatus(), x, y, width, height, &instData, data, systemFunc, inputFunc, tooltipFunc, drawFunc ); goto cleanupAndExit; } else if (asciibuf.compare("CHILD") == 0) { // Create a window using the current description window = createWindow( type, instData.m_id, instData.getStatus(), x, y, width, height, &instData, data, systemFunc, inputFunc, tooltipFunc, drawFunc ); if (window == NULL) goto cleanupAndExit; // Parses the CHILD's window info. if( parseChildWindows( window, inFile, buffer ) == FALSE ) { TheWindowManager->winDestroy( window ); window = NULL; goto cleanupAndExit; } // end if } else { // Else it is unrecognized so eat associated data readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); } } // end if } // end while( TRUE ) cleanupAndExit: // // this should be true since we should never set the text in // display strings in a instance data that is not inside a // window ... it's for sanity checking // // I am commenting this out to get tooltips working, If for // some reason we start having displayString problems... CLH // assert( instData.m_text == NULL && instData.m_tooltip == NULL ); return window; } // end parseWindow //================================================================================================= //================================================================================================= //================================================================================================= //------------------------------------------------------------------------------------------------- /** Parse init for layout file */ //------------------------------------------------------------------------------------------------- Bool parseInit( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info ) { char *c; char *seps = " \n\r\t"; // get string c = strtok( buffer, seps ); // translate string to function address info->initNameString = c; info->init = TheFunctionLexicon->winLayoutInitFunc( TheNameKeyGenerator->nameToKey( info->initNameString ) ); return TRUE; // success } // end parseInit //------------------------------------------------------------------------------------------------- /** Parse update for layout file */ //------------------------------------------------------------------------------------------------- Bool parseUpdate( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info ) { char *c; char *seps = " \n\r\t"; // get string c = strtok( buffer, seps ); // translate string to function address info->updateNameString = c; info->update = TheFunctionLexicon->winLayoutUpdateFunc( TheNameKeyGenerator->nameToKey( info->updateNameString ) ); return TRUE; // success } // end parseUpdate //------------------------------------------------------------------------------------------------- /** Parse shutdown for layout file */ //------------------------------------------------------------------------------------------------- Bool parseShutdown( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info ) { char *c; char *seps = " \n\r\t"; // get string c = strtok( buffer, seps ); // translate string to function address info->shutdownNameString = c; info->shutdown = TheFunctionLexicon->winLayoutShutdownFunc( TheNameKeyGenerator->nameToKey( info->shutdownNameString ) ); return TRUE; // success } // end parseShutdown static LayoutScriptParse layoutScriptTable[] = { { "LAYOUTINIT", parseInit }, { "LAYOUTUPDATE", parseUpdate }, { "LAYOUTSHUTDOWN", parseShutdown }, { NULL, NULL }, }; //------------------------------------------------------------------------------------------------- /** Parse the layout block which MUST be present in every window file */ //------------------------------------------------------------------------------------------------- Bool parseLayoutBlock( File *inFile, char *buffer, UnsignedInt version, WindowLayoutInfo *info ) { LayoutScriptParse *parse; char token[ 256 ]; AsciiString asciitoken; if (inFile->scanString(asciitoken) == FALSE) { return FALSE; } // better be the layout block if (asciitoken.compare("STARTLAYOUTBLOCK") != 0) { return FALSE; } while( TRUE ) { // get next token inFile->scanString(asciitoken); // check for end if (asciitoken.compare("ENDLAYOUTBLOCK") == 0) { break; } // search for token in the table for( parse = layoutScriptTable; parse && parse->name; parse++ ) { if (asciitoken.compare(parse->name) == 0) { char *c; // read from file readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH ); // eat equals separator " = " c = strtok( buffer, " =" ); strcpy(token, asciitoken.str()); // parse it if( parse->parse( token, c, version, info ) == FALSE ) return FALSE; break; // exit for } // end if } // end for parse } // end while return TRUE; } // end parseLayoutBlock /////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // GameWindowManager::winCreateLayout ========================================= /** Load window(s) from a .wnd definition file and wrap within a * new window layout */ //============================================================================= WindowLayout *GameWindowManager::winCreateLayout( AsciiString filename ) { WindowLayout *layout; // allocate a new window layout layout = newInstance(WindowLayout); // load windows into layout if( layout->load( filename ) == FALSE ) { layout->deleteInstance(); return NULL; } // end if // return loaded layout return layout; } // end winCreateLayout /** Free up the memory used by static strings. Normally this memory is freed by the string destructor but we do it here to make the memory leak detection code happy.*/ void GameWindowManager::freeStaticStrings(void) { theSystemString.clear(); theInputString.clear(); theTooltipString.clear(); theDrawString.clear(); } WindowLayoutInfo::WindowLayoutInfo() : version(0), init(NULL), update(NULL), shutdown(NULL), initNameString(AsciiString::TheEmptyString), updateNameString(AsciiString::TheEmptyString), shutdownNameString(AsciiString::TheEmptyString) { windows.clear(); } // GameWindowManager::winCreateFromScript ===================================== /** Parse through a window .wnd file and create all the windows * within it. * * NOTE: The FIRST window created from the script is returned, this * way if you want to know ALL of the windows created from this * layout file you must iterate over info->windows, since the windows will * not be at the head of the window list if there is a modal window active. */ //============================================================================= GameWindow *GameWindowManager::winCreateFromScript( AsciiString filenameString, WindowLayoutInfo *info ) { const char* filename = filenameString.str(); static char buffer[ WIN_BUFFER_LENGTH ]; // input buffer for reading GameWindow *firstWindow = NULL; GameWindow *window; char filepath[ _MAX_PATH ] = "Window\\"; File *inFile; WindowLayoutInfo scriptInfo; AsciiString asciibuf; // zero info struct //memset( &scriptInfo, 0, sizeof( WindowLayoutInfo ) ); // it's a class - use a constructor // Reset the window stack resetWindowStack(); resetWindowDefaults(); // // get the filename from the parameter, if it doesn't contain a '\' it is // a it is assumed to be a filename only, which we will prefix a "window\" // directory to, otherwise it is assumed to be an absolute path. When using // a filename only make sure the current directory is set to the right // place for the window files subdirectory // if( strchr( filename, '\\' ) == NULL ) sprintf( filepath, "Window\\%s", filename ); else strcpy( filepath, filename ); // Open the input file inFile = TheFileSystem->openFile(filepath, File::READ); if (inFile == NULL) { DEBUG_LOG(( "WinCreateFromScript: Cannot access file '%s'.\n", filename )); return NULL; } // read the file version Int version; inFile->read(NULL, strlen("FILE_VERSION = ")); inFile->scanInt(version); inFile->nextLine(); // version 2+ have a special block called the layout block if( version >= 2 ) { if( parseLayoutBlock( inFile, buffer, version, &scriptInfo ) == FALSE ) { DEBUG_LOG(( "WinCreateFromScript: Error parsing layout block\n" )); return FALSE; } // end if } // end if else { // default none names scriptInfo.initNameString = "[None]"; scriptInfo.updateNameString = "[None]"; scriptInfo.shutdownNameString = "[None]"; } // end else while( TRUE ) { if (inFile->scanString(asciibuf) == FALSE) { break; } if (asciibuf.compare("END") == 0) { continue; } if (asciibuf.compare("ENABLEDCOLOR") == 0) { if( parseDefaultColor( &defEnabledColor, inFile, buffer ) == FALSE ) { inFile->close(); inFile = NULL; return NULL; } } else if (asciibuf.compare("DISABLEDCOLOR") == 0) { if( parseDefaultColor( &defDisabledColor, inFile, buffer ) == FALSE ) { inFile->close(); inFile = NULL; return NULL; } } else if (asciibuf.compare("HILITECOLOR") == 0) { if( parseDefaultColor( &defHiliteColor, inFile, buffer ) == FALSE ) { inFile->close(); inFile = NULL; return NULL; } } else if (asciibuf.compare("SELECTEDCOLOR") == 0) { if( parseDefaultColor( &defSelectedColor, inFile, buffer ) == FALSE ) { inFile->close(); inFile = NULL; return NULL; } } else if (asciibuf.compare("TEXTCOLOR") == 0) { if( parseDefaultColor( &defTextColor, inFile, buffer ) == FALSE ) { inFile->close(); inFile = NULL; return NULL; } } else if (asciibuf.compare("BACKGROUNDCOLOR") == 0) { if( parseDefaultColor( &defBackgroundColor, inFile, buffer ) == FALSE ) { inFile->close(); inFile = NULL; return NULL; } } else if (asciibuf.compare("FONT") == 0) { if( parseDefaultFont( defFont, inFile, buffer ) == FALSE ) { inFile->close(); inFile = NULL; return NULL; } } else if (asciibuf.compare("WINDOW") == 0) { // Parse window descriptions until the last END is read window = parseWindow( inFile, buffer ); // save first window created if( firstWindow == NULL ) firstWindow = window; scriptInfo.windows.push_back(window); } // end else if } // end while( TRUE ) // close the file inFile->close(); inFile = NULL; // if info parameter is provided, copy info to the param if( info ) *info = scriptInfo; // return the first window created return firstWindow; } // end WinCreateFromScript