GameWindowManagerScript.cpp 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: GameWindowManagerScript.cpp //////////////////////////////////////////
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Westwood Studios Pacific.
  27. //
  28. // Confidential Information
  29. // Copyright (C) 2001 - All Rights Reserved
  30. //
  31. //-----------------------------------------------------------------------------
  32. //
  33. // Project: RTS3
  34. //
  35. // File name: GameWindowManagerScript.cpp
  36. //
  37. // Created: Colin Day, June 2001
  38. // Dean Iverson, May 1998
  39. //
  40. // Desc: Reading window definition files from disk for the window manager
  41. //
  42. //-----------------------------------------------------------------------------
  43. ///////////////////////////////////////////////////////////////////////////////
  44. // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
  45. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  46. // USER INCLUDES //////////////////////////////////////////////////////////////
  47. #include "Lib/BaseType.h"
  48. #include "Common/Debug.h"
  49. #include "Common/File.h"
  50. #include "Common/FileSystem.h"
  51. #include "Common/GameMemory.h"
  52. #include "Common/NameKeyGenerator.h"
  53. #include "Common/FunctionLexicon.h"
  54. #include "GameClient/Display.h"
  55. #include "GameClient/WindowLayout.h"
  56. #include "GameClient/Gadget.h"
  57. #include "GameClient/GameWindowManager.h"
  58. #include "GameClient/GameWindowGlobal.h"
  59. #include "GameClient/GadgetStaticText.h"
  60. #include "GameClient/GadgetTabControl.h"
  61. #include "GameClient/GadgetTextEntry.h"
  62. #include "GameClient/GadgetPushButton.h"
  63. #include "GameClient/GadgetRadioButton.h"
  64. #include "GameClient/GadgetCheckBox.h"
  65. #include "GameClient/GadgetListBox.h"
  66. #include "GameClient/GadgetComboBox.h"
  67. #include "GameClient/GadgetSlider.h"
  68. #include "GameClient/GameText.h"
  69. #include "GameClient/HeaderTemplate.h"
  70. // DEFINES ////////////////////////////////////////////////////////////////////
  71. ///////////////////////////////////////////////////////////////////////////////
  72. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  73. ///////////////////////////////////////////////////////////////////////////////
  74. enum
  75. {
  76. WIN_BUFFER_LENGTH = 2048,
  77. WIN_STACK_DEPTH = 10,
  78. };
  79. //-------------------------------------------------------------------------------------------------
  80. /** Layout parse structure ... these data items apply to the window file itself,
  81. * they are not associated with any window, but rather just a block of data in
  82. * every file */
  83. //-------------------------------------------------------------------------------------------------
  84. struct LayoutScriptParse
  85. {
  86. char *name;
  87. Bool (*parse)( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info );
  88. };
  89. // GameWindowParse ------------------------------------------------------------
  90. /** used to match database fields to parsing functions */
  91. //-----------------------------------------------------------------------------
  92. struct GameWindowParse
  93. {
  94. char *name;
  95. Bool (*parse)( char *token, WinInstanceData *, char *, void * );
  96. };
  97. ///////////////////////////////////////////////////////////////////////////////
  98. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  99. ///////////////////////////////////////////////////////////////////////////////
  100. // window methods and their string representations
  101. static GameWinSystemFunc systemFunc = NULL;
  102. static GameWinInputFunc inputFunc = NULL;
  103. static GameWinTooltipFunc tooltipFunc = NULL;
  104. static GameWinDrawFunc drawFunc = NULL;
  105. static AsciiString theSystemString;
  106. static AsciiString theInputString;
  107. static AsciiString theTooltipString;
  108. static AsciiString theDrawString;
  109. // default visual properties
  110. static Color defEnabledColor = 0;
  111. static Color defDisabledColor = 0;
  112. static Color defBackgroundColor = 0;
  113. static Color defHiliteColor = 0;
  114. static Color defSelectedColor = 0;
  115. static Color defTextColor = 0;
  116. static GameFont *defFont = NULL;
  117. //
  118. // These strings must be in the same order as they are in their definitions
  119. // (see WIN_STATUS_* enums and GWS_* enums).
  120. //
  121. const char *WindowStatusNames[] = { "ACTIVE", "TOGGLE", "DRAGABLE", "ENABLED", "HIDDEN",
  122. "ABOVE", "BELOW", "IMAGE", "TABSTOP", "NOINPUT",
  123. "NOFOCUS", "DESTROYED", "BORDER",
  124. "SMOOTH_TEXT", "ONE_LINE", "NO_FLUSH", "SEE_THRU",
  125. "RIGHT_CLICK", "WRAP_CENTERED", "CHECK_LIKE","HOTKEY_TEXT",
  126. "USE_OVERLAY_STATES", "NOT_READY", "FLASHING", "ALWAYS_COLOR",
  127. NULL };
  128. const char *WindowStyleNames[] = { "PUSHBUTTON", "RADIOBUTTON", "CHECKBOX",
  129. "VERTSLIDER", "HORZSLIDER", "SCROLLLISTBOX",
  130. "ENTRYFIELD", "STATICTEXT", "PROGRESSBAR",
  131. "USER", "MOUSETRACK", "ANIMATED",
  132. "TABSTOP", "TABCONTROL", "TABPANE",
  133. "COMBOBOX",
  134. NULL };
  135. // Implement a stack to keep track of parent/child nested window descriptions.
  136. static GameWindow *windowStack[ WIN_STACK_DEPTH ];
  137. static GameWindow **stackPtr;
  138. // for parsing
  139. static char *seps = " =;\n\r\t";
  140. WinDrawData enabledDropDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  141. WinDrawData disabledDropDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  142. WinDrawData hiliteDropDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  143. WinDrawData enabledEditBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  144. WinDrawData disabledEditBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  145. WinDrawData hiliteEditBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  146. WinDrawData enabledListBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  147. WinDrawData disabledListBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  148. WinDrawData hiliteListBoxDrawData[ MAX_DRAW_DATA ]; ///< for combo boxes
  149. WinDrawData enabledUpButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  150. WinDrawData disabledUpButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  151. WinDrawData hiliteUpButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  152. WinDrawData enabledDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  153. WinDrawData disabledDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  154. WinDrawData hiliteDownButtonDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  155. WinDrawData enabledSliderDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  156. WinDrawData disabledSliderDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  157. WinDrawData hiliteSliderDrawData[ MAX_DRAW_DATA ]; ///< for list boxes and combo boxes
  158. WinDrawData enabledSliderThumbDrawData[ MAX_DRAW_DATA ]; ///< for sliders and list boxes and combo boxes
  159. WinDrawData disabledSliderThumbDrawData[ MAX_DRAW_DATA ]; ///< for sliders and list boxes and combo boxes
  160. WinDrawData hiliteSliderThumbDrawData[ MAX_DRAW_DATA ]; ///< for sliders and list boxes and combo boxes
  161. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  162. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  163. static GameWindow *parseWindow( File *inFile, char *buffer );
  164. ///////////////////////////////////////////////////////////////////////////////
  165. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  166. ///////////////////////////////////////////////////////////////////////////////
  167. // parseBitFlag ===============================================================
  168. /** Parse one of the "flags" referred to below in the header comment
  169. * for ParseBitString(). Sets the appropriate bit in the 'bits' arg,
  170. * if successful. Returns TRUE on success, else FALSE. */
  171. //=============================================================================
  172. static Bool parseBitFlag( const char *flagString, UnsignedInt *bits,
  173. const char **flagList )
  174. {
  175. const char **c;
  176. int i;
  177. for( i = 0, c = flagList; *c; i++, c++ )
  178. {
  179. if( !stricmp( *c, flagString ) )
  180. {
  181. *bits |= (1 << i);
  182. return TRUE;
  183. }
  184. }
  185. return FALSE;
  186. } // end parseBitFlag
  187. // parseBitString =============================================================
  188. /** Given a character string of the form 'A+B+C+D', parse the
  189. * flags separated by the '+' symbols into a bitfield stored in the 'bits'
  190. * argument.
  191. * Note that this routine does not clear any bits, only sets them. */
  192. //=============================================================================
  193. static void parseBitString( const char *inBuffer, UnsignedInt *bits, const char **flagList )
  194. {
  195. char buffer[256];
  196. char *tok;
  197. // do not modify the inBuffer argument
  198. strcpy( buffer, inBuffer );
  199. if( strncmp( buffer, "NULL", 4 ) )
  200. {
  201. for( tok = strtok( buffer, "+" ); tok; tok = strtok( NULL, "+" ) )
  202. {
  203. if ( !parseBitFlag( tok, bits, flagList ) )
  204. {
  205. DEBUG_LOG(( "ParseBitString: Invalid flag '%s'.\n", tok ));
  206. }
  207. }
  208. }
  209. } // end parseBitString
  210. // readUntilSemicolon =========================================================
  211. //=============================================================================
  212. static void readUntilSemicolon( File *fp, char *buffer, int maxBufLen )
  213. {
  214. int i = 0;
  215. Bool start = TRUE;
  216. while( i < maxBufLen )
  217. {
  218. // get next character
  219. fp->read(buffer + i, 1);
  220. // make all whitespace characters spaces
  221. if( isspace( buffer[ i ] ) )
  222. {
  223. if( start == FALSE )
  224. buffer[ i++ ] = ' ';
  225. }
  226. else
  227. {
  228. start = FALSE;
  229. if( buffer[ i ] == ';' )
  230. {
  231. // found end of data chunk
  232. buffer[ i ] = '\000';
  233. return;
  234. }
  235. i++;
  236. }
  237. }
  238. DEBUG_LOG(( "ReadUntilSemicolon: ERROR - Read buffer overflow - input truncated.\n" ));
  239. buffer[ maxBufLen - 1 ] = '\000';
  240. } // end readUntilSemicolon
  241. // scanBool ===================================================================
  242. //=============================================================================
  243. static Int scanBool( const char *source, Bool& val )
  244. {
  245. Int temp = 0;
  246. Int ret = sscanf( source, "%d", &temp );
  247. val = (Bool)temp;
  248. return ret;
  249. } // end scanBool
  250. // scanShort ==================================================================
  251. //=============================================================================
  252. static Int scanShort( const char *source, Short& val )
  253. {
  254. Int temp = 0;
  255. Int ret = sscanf( source, "%d", &temp );
  256. val = (Short)temp;
  257. return ret;
  258. } // end scanShort
  259. // scanInt ====================================================================
  260. //=============================================================================
  261. static Int scanInt( const char *source, Int& val )
  262. {
  263. Int ret = sscanf( source, "%d", &val ); // not strictly necessary to wrap this, but it's more consistent
  264. return ret;
  265. } // end scanInt
  266. // scanUnsignedInt ============================================================
  267. //=============================================================================
  268. static Int scanUnsignedInt( const char *source, UnsignedInt& val )
  269. {
  270. Int ret = sscanf( source, "%d", &val ); // not strictly necessary to wrap this, but it's more consistent
  271. return ret;
  272. } // end scanUnsignedInt
  273. // resetWindowStack ===========================================================
  274. //=============================================================================
  275. static void resetWindowStack( void )
  276. {
  277. memset( windowStack, 0, sizeof( windowStack ) );
  278. stackPtr = windowStack;
  279. } // end resetWindowStack
  280. // resetWindowDefaults ========================================================
  281. //=============================================================================
  282. static void resetWindowDefaults( void )
  283. {
  284. defEnabledColor = 0;
  285. defDisabledColor = 0;
  286. defBackgroundColor = 0;
  287. defHiliteColor = 0;
  288. defSelectedColor = 0;
  289. defTextColor = 0;
  290. defFont = 0;
  291. } // end resetWindowDefaults
  292. // peekWindow =================================================================
  293. //=============================================================================
  294. static GameWindow *peekWindow( void )
  295. {
  296. if (stackPtr == windowStack)
  297. return NULL;
  298. return *(stackPtr - 1);
  299. } // end peekWindow
  300. // popWindow ==================================================================
  301. //=============================================================================
  302. static GameWindow *popWindow( void )
  303. {
  304. if( stackPtr == windowStack )
  305. return NULL;
  306. stackPtr--;
  307. return *stackPtr;
  308. } // end popWindow
  309. // pushWindow =================================================================
  310. //=============================================================================
  311. static void pushWindow( GameWindow *window )
  312. {
  313. if( stackPtr == &windowStack[ WIN_STACK_DEPTH - 1 ] )
  314. {
  315. DEBUG_LOG(( "pushWindow: Warning, stack overflow\n" ));
  316. return;
  317. } // end if
  318. *stackPtr++ = window;
  319. } // end pushWindow
  320. // parseColor =================================================================
  321. /** Parse a color entry and store it in the value pointed to by the
  322. * 'color' parm. */
  323. //=============================================================================
  324. static Bool parseColor( Color *color, char *buffer )
  325. {
  326. char *c;
  327. Byte red, green, blue;
  328. c = strtok( buffer, " \t\n\r" );
  329. red = atoi(c);
  330. c = strtok( NULL, " \t\n\r" );
  331. green = atoi(c);
  332. c = strtok( NULL, " \t\n\r" );
  333. blue = atoi(c);
  334. *color = TheWindowManager->winMakeColor( red, green, blue, 255 );
  335. return TRUE;
  336. } // end parseColor
  337. // parseDefaultColor ==========================================================
  338. /** Parse a default color entry and store it in the value pointed to by
  339. * the 'color' parm. */
  340. //=============================================================================
  341. static Bool parseDefaultColor( Color *color, File *inFile, char *buffer )
  342. {
  343. // eat '='
  344. // fscanf( inFile, "%*s" );
  345. AsciiString str;
  346. inFile->scanString(str);
  347. // Read the rest of the color definition
  348. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  349. if (!strcmp( buffer, "TRANSPARENT" ))
  350. {
  351. *color = WIN_COLOR_UNDEFINED;
  352. } // end if
  353. else
  354. parseColor( color, buffer );
  355. return TRUE;
  356. } // end parseDefaultColor
  357. // parseDefaultFont ===========================================================
  358. /** Parse the default font */
  359. //=============================================================================
  360. static Bool parseDefaultFont( GameFont *font, File *inFile, char *buffer )
  361. {
  362. // eat '='
  363. // fscanf( inFile, "%*s" );
  364. AsciiString str;
  365. inFile->scanString(str);
  366. // Read the rest of the color definition
  367. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  368. /// @todo font parsing for window files work needed here
  369. // *font = GetFont( buffer );
  370. // if( *font == NULL )
  371. // return FALSE;
  372. return TRUE;
  373. } // end parseDefaultFont
  374. // parseTooltip ===============================================================
  375. /** Parse the tooltip field */
  376. //=============================================================================
  377. static Bool parseTooltip( char *token, WinInstanceData *instData,
  378. char *buffer, void *data )
  379. {
  380. UnicodeString tooltip;
  381. tooltip.set(L"Need tooltip translation");
  382. /// @todo need to parse the tooltip in multibyte here
  383. instData->setTooltipText( tooltip );
  384. return TRUE;
  385. } // end parseTooltip
  386. // parseScreenRect ============================================================
  387. /** Parse the screen rect entry which tells us the position and size
  388. * of window. Note we scale for the current resolution if needed
  389. * and adjust to make the screen rect coords relative to any parent
  390. * if present */
  391. //=============================================================================
  392. static Bool parseScreenRect( char *token, char *buffer,
  393. Int *x, Int *y, Int *width, Int *height )
  394. {
  395. GameWindow *parent = peekWindow();
  396. IRegion2D screenRegion;
  397. ICoord2D createRes; // creation resolution
  398. char *seps = " ,:=\n\r\t";
  399. char *c;
  400. c = strtok( NULL, seps ); // UPPERLEFT token
  401. c = strtok( NULL, seps ); // x position
  402. scanInt( c, screenRegion.lo.x );
  403. c = strtok( NULL, seps ); // y posotion
  404. scanInt( c, screenRegion.lo.y );
  405. c = strtok( NULL, seps ); // BOTTOMRIGHT token
  406. c = strtok( NULL, seps ); // x position
  407. scanInt( c, screenRegion.hi.x );
  408. c = strtok( NULL, seps ); // y posotion
  409. scanInt( c, screenRegion.hi.y );
  410. c = strtok( NULL, seps ); // CREATIONRESOLUTION token
  411. c = strtok( NULL, seps ); // x creation resolution
  412. scanInt( c, createRes.x );
  413. c = strtok( NULL, seps ); // y creation resolution
  414. scanInt( c, createRes.y );
  415. //
  416. // shrink or expand the screen region by the ratio of the current
  417. // resolution divided by the creation resolution
  418. //
  419. Real xScale = (Real)TheDisplay->getWidth() / (Real)createRes.x;
  420. Real yScale = (Real)TheDisplay->getHeight() / (Real)createRes.y;
  421. screenRegion.lo.x = (Int)((Real)screenRegion.lo.x * xScale);
  422. screenRegion.lo.y = (Int)((Real)screenRegion.lo.y * yScale);
  423. screenRegion.hi.x = (Int)((Real)screenRegion.hi.x * xScale);
  424. screenRegion.hi.y = (Int)((Real)screenRegion.hi.y * yScale);
  425. //
  426. // given the screen region upper left compute the upper left that we
  427. // will give this window, if we have a parent note that the position
  428. // is relative to the parent client area, if no parent is present
  429. // we're talking about the screen
  430. //
  431. if( parent )
  432. {
  433. ICoord2D parentScreenPos;
  434. // get parent position on screen
  435. parent->winGetScreenPosition( &parentScreenPos.x, &parentScreenPos.y );
  436. // save x and y with parent position as relative (0,0) location
  437. *x = screenRegion.lo.x - parentScreenPos.x;
  438. *y = screenRegion.lo.y - parentScreenPos.y;
  439. } // end if
  440. else
  441. {
  442. *x = screenRegion.lo.x;
  443. *y = screenRegion.lo.y;
  444. } // end else
  445. // save our width and height from the adjusted screen region locations
  446. *width = screenRegion.hi.x - screenRegion.lo.x;
  447. *height = screenRegion.hi.y - screenRegion.lo.y;
  448. return TRUE;
  449. } // end parseScreenRect
  450. // parseImageOffset ===========================================================
  451. /** Parse the image draw offset */
  452. //=============================================================================
  453. static Bool parseImageOffset( char *token, WinInstanceData *instData,
  454. char *buffer, void *data )
  455. {
  456. char *c;
  457. c = strtok( buffer, " \t\n\r" );
  458. instData->m_imageOffset.x = atoi( c );
  459. c = strtok( NULL, " \t\n\r" );
  460. instData->m_imageOffset.y = atoi( c );
  461. return TRUE;
  462. } // end parseImageOffset
  463. // parseFont ==================================================================
  464. /** Parse the font field */
  465. //=============================================================================
  466. static Bool parseFont( char *token, WinInstanceData *instData,
  467. char *buffer, void *data )
  468. {
  469. char *c, *ptr;
  470. char *seps = " ,\n\r\t";
  471. char *stringSeps = ":,\n\r\t\"";
  472. char fontName[ 256 ];
  473. Int fontSize;
  474. Int fontBold;
  475. // "NAME"
  476. c = strtok( buffer, seps ); // label
  477. // scan to the first " mark
  478. ptr = buffer;
  479. while( *ptr != '"' )
  480. ptr++;
  481. ptr++; // skip the "
  482. c = strtok( ptr, stringSeps ); // value
  483. strcpy( fontName, c );
  484. // "SIZE"
  485. c = strtok( NULL, seps ); // label
  486. c = strtok( NULL, seps ); // value
  487. scanInt( c, fontSize );
  488. // "BOLD"
  489. c = strtok( NULL, seps ); // label
  490. c = strtok( NULL, seps ); // value
  491. scanInt( c, fontBold );
  492. if( TheFontLibrary )
  493. {
  494. GameFont *font;
  495. font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold );
  496. if( font )
  497. instData->m_font = font;
  498. } // end if
  499. return TRUE;
  500. } // end parseFont
  501. // parseName =================================================================
  502. /** Parse the NAME field */
  503. //=============================================================================
  504. static Bool parseName( char *token, WinInstanceData *instData,
  505. char *buffer, void *data )
  506. {
  507. char *c, *ptr;
  508. // char *seps = " ,\n\r\t";
  509. char *stringSeps = "\"";
  510. // scan to the first " mark
  511. ptr = buffer;
  512. while( *ptr != '"' )
  513. ptr++;
  514. ptr++; // skip the first "
  515. c = strtok( ptr, stringSeps ); // name value
  516. instData->m_decoratedNameString = c;
  517. // given the name assign a window ID from the
  518. assert( TheNameKeyGenerator );
  519. if( TheNameKeyGenerator )
  520. instData->m_id = (Int)TheNameKeyGenerator->nameToKey( instData->m_decoratedNameString );
  521. return TRUE;
  522. } // end parseName
  523. // parseStatus ================================================================
  524. /** Parse the STATUS field */
  525. //=============================================================================
  526. static Bool parseStatus( char *token, WinInstanceData *instData,
  527. char *buffer, void *data )
  528. {
  529. instData->m_status = 0;
  530. parseBitString( buffer, &instData->m_status, WindowStatusNames );
  531. return TRUE;
  532. } // end parseStatus
  533. // parseStyle =================================================================
  534. /** Parse the STYLE field */
  535. //=============================================================================
  536. static Bool parseStyle( char *token, WinInstanceData *instData,
  537. char *buffer, void *data )
  538. {
  539. instData->m_style = 0;
  540. parseBitString( buffer, &instData->m_style, WindowStyleNames );
  541. return TRUE;
  542. } // end parseStyle
  543. // parseSystemCallback ========================================================
  544. /** Parse the system method callback for a window */
  545. //=============================================================================
  546. static Bool parseSystemCallback( char *token, WinInstanceData *instData,
  547. char *buffer, void *data )
  548. {
  549. char *c, *ptr;
  550. // char *seps = " ,\n\r\t";
  551. char *stringSeps = "\"";
  552. // scan to the first " mark
  553. ptr = buffer;
  554. while( *ptr != '"' )
  555. ptr++;
  556. ptr++; // skip the first "
  557. c = strtok( ptr, stringSeps ); // name value
  558. // save a pointer of the function address
  559. DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") );
  560. theSystemString = c;
  561. NameKeyType key = TheNameKeyGenerator->nameToKey( theSystemString );
  562. systemFunc = TheFunctionLexicon->gameWinSystemFunc( key );
  563. return TRUE;
  564. } // end parseSystemCallback
  565. // parseInputCallback =========================================================
  566. /** Parse the Input method callback for a window */
  567. //=============================================================================
  568. static Bool parseInputCallback( char *token, WinInstanceData *instData,
  569. char *buffer, void *data )
  570. {
  571. char *c, *ptr;
  572. // char *seps = " ,\n\r\t";
  573. char *stringSeps = "\"";
  574. // scan to the first " mark
  575. ptr = buffer;
  576. while( *ptr != '"' )
  577. ptr++;
  578. ptr++; // skip the first "
  579. c = strtok( ptr, stringSeps ); // name value
  580. // save a pointer of the function address
  581. DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") );
  582. theInputString = c;
  583. NameKeyType key = TheNameKeyGenerator->nameToKey( theInputString );
  584. inputFunc = TheFunctionLexicon->gameWinInputFunc( key );
  585. return TRUE;
  586. } // end parseInputCallback
  587. // parseTooltipCallback =======================================================
  588. /** Parse the Tooltip method callback for a window */
  589. //=============================================================================
  590. static Bool parseTooltipCallback( char *token, WinInstanceData *instData,
  591. char *buffer, void *data )
  592. {
  593. char *c, *ptr;
  594. // char *seps = " ,\n\r\t";
  595. char *stringSeps = "\"";
  596. // scan to the first " mark
  597. ptr = buffer;
  598. while( *ptr != '"' )
  599. ptr++;
  600. ptr++; // skip the first "
  601. c = strtok( ptr, stringSeps ); // name value
  602. // save a pointer of the function address
  603. DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") );
  604. theTooltipString = c;
  605. NameKeyType key = TheNameKeyGenerator->nameToKey( theTooltipString );
  606. tooltipFunc = TheFunctionLexicon->gameWinTooltipFunc( key );
  607. return TRUE;
  608. } // end parseTooltipCallback
  609. // parseDrawCallback ==========================================================
  610. /** Parse the Draw method callback for a window */
  611. //=============================================================================
  612. static Bool parseDrawCallback( char *token, WinInstanceData *instData,
  613. char *buffer, void *data )
  614. {
  615. char *c, *ptr;
  616. // char *seps = " ,\n\r\t";
  617. char *stringSeps = "\"";
  618. // scan to the first " mark
  619. ptr = buffer;
  620. while( *ptr != '"' )
  621. ptr++;
  622. ptr++; // skip the first "
  623. c = strtok( ptr, stringSeps ); // name value
  624. // save a pointer of the function address
  625. DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") );
  626. theDrawString = c;
  627. NameKeyType key = TheNameKeyGenerator->nameToKey( theDrawString );
  628. drawFunc = TheFunctionLexicon->gameWinDrawFunc( key );
  629. return TRUE;
  630. } // end parseDrawCallback
  631. // parseHeaderTemplate ==========================================================
  632. /** Parse the Draw method callback for a window */
  633. //=============================================================================
  634. static Bool parseHeaderTemplate( char *token, WinInstanceData *instData,
  635. char *buffer, void *data )
  636. {
  637. char *c, *ptr;
  638. // char *seps = " ,\n\r\t";
  639. char *stringSeps = "\"";
  640. // scan to the first " mark
  641. ptr = buffer;
  642. while( *ptr != '"' )
  643. ptr++;
  644. ptr++; // skip the first "
  645. c = strtok( ptr, stringSeps ); // name value
  646. // save a pointer of the function address
  647. DEBUG_ASSERTCRASH( TheNameKeyGenerator && TheFunctionLexicon, ("Invalid singletons") );
  648. instData->m_headerTemplateName = c;
  649. return TRUE;
  650. } // end parseDrawCallback
  651. // parseListboxData ===========================================================
  652. /** Parse listbox data entry */
  653. //=============================================================================
  654. static Bool parseListboxData( char *token, WinInstanceData *instData,
  655. char *buffer, void *data )
  656. {
  657. ListboxData *listData = (ListboxData *)data;
  658. char *c;
  659. char *seps = " :,\n\r\t";
  660. // "LENGTH"
  661. c = strtok( buffer, seps ); // label
  662. c = strtok( NULL, seps );
  663. scanShort( c, listData->listLength );
  664. // "AUTOSCROLL"
  665. c = strtok( NULL, seps ); // label
  666. c = strtok( NULL, seps ); // value
  667. scanBool( c, listData->autoScroll );
  668. // "SCROLLIFATEND" (optional)
  669. c = strtok( NULL, seps ); // label
  670. if ( !stricmp(c, "ScrollIfAtEnd") )
  671. {
  672. c = strtok( NULL, seps ); // value
  673. scanBool( c, listData->scrollIfAtEnd );
  674. c = strtok( NULL, seps ); // label
  675. }
  676. else
  677. {
  678. listData->scrollIfAtEnd = FALSE;
  679. }
  680. // "AUTOPURGE"
  681. c = strtok( NULL, seps ); // value
  682. scanBool( c, listData->autoPurge );
  683. // "SCROLLBAR"
  684. c = strtok( NULL, seps ); // label
  685. c = strtok( NULL, seps ); // value
  686. scanBool( c, listData->scrollBar );
  687. // "MULTISELECT"
  688. c = strtok( NULL, seps ); // label
  689. c = strtok( NULL, seps ); // value
  690. scanBool( c, listData->multiSelect );
  691. // "COLUMNS"
  692. c = strtok( NULL, seps ); // label
  693. c = strtok( NULL, seps ); // value
  694. scanShort( c, listData->columns );
  695. if(listData->columns > 1)
  696. {
  697. listData->columnWidthPercentage = NEW Int[listData->columns];
  698. for(Int i = 0; i < listData->columns; i++ )
  699. {
  700. // "COLUMNS"
  701. c = strtok( NULL, seps ); // label
  702. c = strtok( NULL, seps ); // value
  703. scanInt( c, listData->columnWidthPercentage[i] );
  704. }
  705. }
  706. else
  707. listData->columnWidthPercentage = NULL;
  708. listData->columnWidth = NULL;
  709. // "FORCESELECT"
  710. c = strtok( NULL, seps ); // label
  711. c = strtok( NULL, seps ); // value
  712. scanBool( c, listData->forceSelect );
  713. // "
  714. return TRUE;
  715. } // end parseListboxData
  716. // parseComboBoxData ===========================================================
  717. /** Parse Combo Box data entry */
  718. //=============================================================================
  719. static Bool parseComboBoxData( char *token, WinInstanceData *instData,
  720. char *buffer, void *data )
  721. {
  722. ComboBoxData *comboData = (ComboBoxData *)data;
  723. char *c;
  724. char *seps = " :,\n\r\t";
  725. c = strtok( buffer, seps ); // label
  726. c = strtok( NULL, seps ); // value
  727. scanBool( c, comboData->isEditable );
  728. c = strtok( NULL, seps ); // label
  729. c = strtok( NULL, seps ); // value
  730. scanInt( c, comboData->maxChars );
  731. c = strtok( NULL, seps ); // label
  732. c = strtok( NULL, seps ); // value
  733. scanInt( c, comboData->maxDisplay );
  734. c = strtok( NULL, seps ); // label
  735. c = strtok( NULL, seps ); // value
  736. scanBool( c, comboData->asciiOnly );
  737. c = strtok( NULL, seps ); // label
  738. c = strtok( NULL, seps ); // value
  739. scanBool( c, comboData->lettersAndNumbersOnly );
  740. return TRUE;
  741. }//parseComboBoxData
  742. // parseSliderData ============================================================
  743. /** Parse slider data entry */
  744. //=============================================================================
  745. static Bool parseSliderData( char *token, WinInstanceData *instData,
  746. char *buffer, void *data )
  747. {
  748. SliderData *sliderData = (SliderData *)data;
  749. char *c;
  750. char *seps = " :,\n\r\t";
  751. // "MINVALUE"
  752. c = strtok( buffer, seps ); // label
  753. c = strtok( NULL, seps ); // value
  754. scanInt( c, sliderData->minVal );
  755. // "MAXVALUE"
  756. c = strtok( NULL, seps ); // label
  757. c = strtok( NULL, seps ); // value
  758. scanInt( c, sliderData->maxVal );
  759. return TRUE;
  760. } // end parseSliderData
  761. // parseRadioButtonData =======================================================
  762. /** Parse radio button data entry */
  763. //=============================================================================
  764. static Bool parseRadioButtonData( char *token, WinInstanceData *instData,
  765. char *buffer, void *data )
  766. {
  767. RadioButtonData *radioData = (RadioButtonData *)data;
  768. char *c;
  769. char *seps = " :,\n\r\t";
  770. // "GROUP"
  771. c = strtok( buffer, seps ); // label
  772. c = strtok( NULL, seps ); // value
  773. scanInt( c, radioData->group );
  774. return TRUE;
  775. } // end parseRadioButtonData
  776. // parseTooltipText ===========================================================
  777. /** Parse the TOOLTIPTEXT field */
  778. //=============================================================================
  779. static Bool parseTooltipText( char *token, WinInstanceData *instData,
  780. char *buffer, void *data )
  781. {
  782. char *ptr = buffer;
  783. char *c;
  784. char *stringSeps = "\n\r\t\"";
  785. // scan to the first " mark
  786. while( *ptr != '"' )
  787. ptr++;
  788. ptr++; // skip the "
  789. if(strlen( ptr ) == 1 )
  790. return TRUE;
  791. c = strtok( ptr, stringSeps ); // value
  792. if( strlen( c ) >= MAX_TEXT_LABEL )
  793. {
  794. DEBUG_LOG(( "TextTooltip label '%s' is too long, max is '%d'\n", c, MAX_TEXT_LABEL ));
  795. assert( 0 );
  796. return FALSE;
  797. } // end if
  798. instData->m_tooltipString.set(c);
  799. instData->setTooltipText(TheGameText->fetch(c));
  800. return TRUE;
  801. } // end parseTooltipText
  802. // parseTooltipDelay =======================================================
  803. /** Parse the tooltip delay */
  804. //=============================================================================
  805. static Bool parseTooltipDelay( char *token, WinInstanceData *instData,
  806. char *buffer, void *data )
  807. {
  808. //RadioButtonData *radioData = (RadioButtonData *)data;
  809. char *c;
  810. char *seps = " :,\n\r\t";
  811. // "getvalue"
  812. c = strtok( buffer, seps ); // value
  813. scanInt( c, instData->m_tooltipDelay );
  814. return TRUE;
  815. } // end parseTooltipDelay
  816. // parseText ==================================================================
  817. /** Parse the TEXT field */
  818. //=============================================================================
  819. static Bool parseText( char *token, WinInstanceData *instData,
  820. char *buffer, void *data )
  821. {
  822. char *ptr = buffer;
  823. char *c;
  824. char *stringSeps = "\n\r\t\"";
  825. // scan to the first " mark
  826. while( *ptr != '"' )
  827. ptr++;
  828. ptr++; // skip the "
  829. c = strtok( ptr, stringSeps ); // value
  830. if( strlen( c ) >= MAX_TEXT_LABEL )
  831. {
  832. DEBUG_LOG(( "Text label '%s' is too long, max is '%d'\n", c, MAX_TEXT_LABEL ));
  833. assert( 0 );
  834. return FALSE;
  835. } // end if
  836. instData->m_textLabelString = c;
  837. return TRUE;
  838. } // end parseText
  839. // parseTextColor =============================================================
  840. /** Parse text color entries for enabled, disabled, and hilite with
  841. * drop shadow colors */
  842. //=============================================================================
  843. static Bool parseTextColor( char *token, WinInstanceData *instData,
  844. char *buffer, void *data )
  845. {
  846. char *c;
  847. char *seps = " :,\n\r\t";
  848. UnsignedInt r, g, b, a;
  849. Int i, states = 3;
  850. TextDrawData *textData;
  851. Bool first = TRUE;
  852. for( i = 0; i < states; i++ )
  853. {
  854. if( i == 0 )
  855. textData = &instData->m_enabledText;
  856. else if( i == 1 )
  857. textData = &instData->m_disabledText;
  858. else if( i == 2 )
  859. textData = &instData->m_hiliteText;
  860. else
  861. {
  862. DEBUG_LOG(( "Undefined state for text color\n" ));
  863. assert( 0 );
  864. return FALSE;
  865. } // end else
  866. // color
  867. if( first == TRUE )
  868. c = strtok( buffer, seps ); // label
  869. else
  870. c = strtok( NULL, seps ); // label
  871. first = FALSE;
  872. c = strtok( NULL, seps ); // value
  873. scanUnsignedInt( c, r );
  874. c = strtok( NULL, seps ); // value
  875. scanUnsignedInt( c, g );
  876. c = strtok( NULL, seps ); // value
  877. scanUnsignedInt( c, b );
  878. c = strtok( NULL, seps ); // value
  879. scanUnsignedInt( c, a );
  880. textData->color = GameMakeColor( r, g, b, a );
  881. // border color
  882. c = strtok( NULL, seps ); // label
  883. c = strtok( NULL, seps ); // value
  884. scanUnsignedInt( c, r );
  885. c = strtok( NULL, seps ); // value
  886. scanUnsignedInt( c, g );
  887. c = strtok( NULL, seps ); // value
  888. scanUnsignedInt( c, b );
  889. c = strtok( NULL, seps ); // value
  890. scanUnsignedInt( c, a );
  891. textData->borderColor = GameMakeColor( r, g, b, a );
  892. } // end if
  893. return TRUE;
  894. } // end parseTextColor
  895. // parseStaticTextData ========================================================
  896. /** Parse static text data entry */
  897. //=============================================================================
  898. static Bool parseStaticTextData( char *token, WinInstanceData *instData,
  899. char *buffer, void *data )
  900. {
  901. TextData *textData = (TextData *)data;
  902. char *c;
  903. char *seps = " :,\n\r\t";
  904. // "CENTERED"
  905. c = strtok( buffer, seps ); // label
  906. c = strtok( NULL, seps ); // value
  907. scanBool( c, textData->centered );
  908. return TRUE;
  909. } // end parseStaticTextDAta
  910. // parseTextEntryData =========================================================
  911. /** Parse text entry data entry */
  912. //=============================================================================
  913. static Bool parseTextEntryData( char *token, WinInstanceData *instData,
  914. char *buffer, void *data )
  915. {
  916. EntryData *entryData = (EntryData *)data;
  917. char *c;
  918. char *seps = " :,\n\r\t";
  919. // "MAXLEN"
  920. c = strtok( buffer, seps ); // label
  921. c = strtok( NULL, seps ); // value
  922. scanShort( c, entryData->maxTextLen );
  923. // "SECRETTEXT"
  924. c = strtok( NULL, seps ); // label
  925. c = strtok( NULL, seps ); // value
  926. scanBool( c, entryData->secretText );
  927. // "NUMERICALONLY"
  928. c = strtok( NULL, seps ); // label
  929. c = strtok( NULL, seps ); // value
  930. scanBool( c, entryData->numericalOnly );
  931. // "ALPHANUMERICALONLY"
  932. c = strtok( NULL, seps ); // label
  933. c = strtok( NULL, seps ); // value
  934. scanBool( c, entryData->alphaNumericalOnly );
  935. // "ASCIIONLY"
  936. c = strtok( NULL, seps ); // label
  937. c = strtok( NULL, seps ); // value
  938. scanBool( c, entryData->aSCIIOnly );
  939. return TRUE;
  940. } // end parseStaticTextDAta
  941. // parseTabControlData =========================================================
  942. /** Parse tab control data entry */
  943. //=============================================================================
  944. static Bool parseTabControlData( char *token, WinInstanceData *instData,
  945. char *buffer, void *data )
  946. {
  947. TabControlData *tabControlData = (TabControlData *)data;
  948. char *c;
  949. char *seps = " :,\n\r\t";
  950. //TABORIENTATION
  951. c = strtok( buffer, seps ); // label
  952. c = strtok( NULL, seps ); // value
  953. scanInt( c, tabControlData->tabOrientation );
  954. //TABEDGE
  955. c = strtok( NULL, seps ); // label
  956. c = strtok( NULL, seps ); // value
  957. scanInt( c, tabControlData->tabEdge );
  958. //TABWIDTH
  959. c = strtok( NULL, seps ); // label
  960. c = strtok( NULL, seps ); // value
  961. scanInt( c, tabControlData->tabWidth );
  962. //TABHEIGHT
  963. c = strtok( NULL, seps ); // label
  964. c = strtok( NULL, seps ); // value
  965. scanInt( c, tabControlData->tabHeight );
  966. //TABCOUNT
  967. c = strtok( NULL, seps ); // label
  968. c = strtok( NULL, seps ); // value
  969. scanInt( c, tabControlData->tabCount );
  970. //PANEBORDER
  971. c = strtok( NULL, seps ); // label
  972. c = strtok( NULL, seps ); // value
  973. scanInt( c, tabControlData->paneBorder );
  974. //PANEDISABLED
  975. Int entryCount = 0;
  976. c = strtok( NULL, seps ); // label
  977. c = strtok( NULL, seps ); // value
  978. scanInt( c, entryCount );
  979. for( Int paneIndex = 0; paneIndex < entryCount; paneIndex ++ )
  980. {
  981. c = strtok( NULL, seps ); // value
  982. scanBool( c, tabControlData->subPaneDisabled[paneIndex] );
  983. }
  984. return TRUE;
  985. }
  986. // parseDrawData ==============================================================
  987. /** Parse set of draw data elements */
  988. //=============================================================================
  989. static Bool parseDrawData( char *token, WinInstanceData *instData,
  990. char *buffer, void *data )
  991. {
  992. Int i;
  993. UnsignedInt r, g, b, a;
  994. WinDrawData *drawData;
  995. Bool first = TRUE;
  996. char *c;
  997. char *seps = " :,\n\r\t";
  998. for( i = 0; i < MAX_DRAW_DATA; i++ )
  999. {
  1000. // get the right draw data
  1001. if( strcmp( token, "ENABLEDDRAWDATA" ) == 0 )
  1002. drawData = &instData->m_enabledDrawData[ i ];
  1003. else if( strcmp( token, "DISABLEDDRAWDATA" ) == 0 )
  1004. drawData = &instData->m_disabledDrawData[ i ];
  1005. else if( strcmp( token, "HILITEDRAWDATA" ) == 0 )
  1006. drawData = &instData->m_hiliteDrawData[ i ];
  1007. else if( strcmp( token, "LISTBOXENABLEDUPBUTTONDRAWDATA" ) == 0 )
  1008. drawData = &enabledUpButtonDrawData[ i ];
  1009. else if( strcmp( token, "LISTBOXDISABLEDUPBUTTONDRAWDATA" ) == 0 )
  1010. drawData = &disabledUpButtonDrawData[ i ];
  1011. else if( strcmp( token, "LISTBOXHILITEUPBUTTONDRAWDATA" ) == 0 )
  1012. drawData = &hiliteUpButtonDrawData[ i ];
  1013. else if( strcmp( token, "LISTBOXENABLEDDOWNBUTTONDRAWDATA" ) == 0 )
  1014. drawData = &enabledDownButtonDrawData[ i ];
  1015. else if( strcmp( token, "LISTBOXDISABLEDDOWNBUTTONDRAWDATA" ) == 0 )
  1016. drawData = &disabledDownButtonDrawData[ i ];
  1017. else if( strcmp( token, "LISTBOXHILITEDOWNBUTTONDRAWDATA" ) == 0 )
  1018. drawData = &hiliteDownButtonDrawData[ i ];
  1019. else if( strcmp( token, "LISTBOXENABLEDSLIDERDRAWDATA" ) == 0 )
  1020. drawData = &enabledSliderDrawData[ i ];
  1021. else if( strcmp( token, "LISTBOXDISABLEDSLIDERDRAWDATA" ) == 0 )
  1022. drawData = &disabledSliderDrawData[ i ];
  1023. else if( strcmp( token, "LISTBOXHILITESLIDERDRAWDATA" ) == 0 )
  1024. drawData = &hiliteSliderDrawData[ i ];
  1025. else if( strcmp( token, "SLIDERTHUMBENABLEDDRAWDATA" ) == 0 )
  1026. drawData = &enabledSliderThumbDrawData[ i ];
  1027. else if( strcmp( token, "SLIDERTHUMBDISABLEDDRAWDATA" ) == 0 )
  1028. drawData = &disabledSliderThumbDrawData[ i ];
  1029. else if( strcmp( token, "SLIDERTHUMBHILITEDRAWDATA" ) == 0 )
  1030. drawData = &hiliteSliderThumbDrawData[ i ];
  1031. else if( strcmp( token, "COMBOBOXDROPDOWNBUTTONENABLEDDRAWDATA" ) == 0 )
  1032. drawData = &enabledDropDownButtonDrawData[ i ];
  1033. else if( strcmp( token, "COMBOBOXDROPDOWNBUTTONDISABLEDDRAWDATA" ) == 0 )
  1034. drawData = &disabledDropDownButtonDrawData[ i ];
  1035. else if( strcmp( token, "COMBOBOXDROPDOWNBUTTONHILITEDRAWDATA" ) == 0 )
  1036. drawData = &hiliteDropDownButtonDrawData[ i ];
  1037. else if( strcmp( token, "COMBOBOXEDITBOXENABLEDDRAWDATA" ) == 0 )
  1038. drawData = &enabledEditBoxDrawData[ i ];
  1039. else if( strcmp( token, "COMBOBOXEDITBOXDISABLEDDRAWDATA" ) == 0 )
  1040. drawData = &disabledEditBoxDrawData[ i ];
  1041. else if( strcmp( token, "COMBOBOXEDITBOXHILITEDRAWDATA" ) == 0 )
  1042. drawData = &hiliteEditBoxDrawData[ i ];
  1043. else if( strcmp( token, "COMBOBOXLISTBOXENABLEDDRAWDATA" ) == 0 )
  1044. drawData = &enabledListBoxDrawData[ i ];
  1045. else if( strcmp( token, "COMBOBOXLISTBOXDISABLEDDRAWDATA" ) == 0 )
  1046. drawData = &disabledListBoxDrawData[ i ];
  1047. else if( strcmp( token, "COMBOBOXLISTBOXHILITEDRAWDATA" ) == 0 )
  1048. drawData = &hiliteListBoxDrawData[ i ];
  1049. else
  1050. {
  1051. DEBUG_LOG(( "ParseDrawData, undefined token '%s'\n", token ));
  1052. assert( 0 );
  1053. return FALSE;
  1054. } // end else
  1055. // IMAGE: X
  1056. if( first == TRUE )
  1057. c = strtok( buffer, seps ); // label
  1058. else
  1059. c = strtok( NULL, seps ); // label
  1060. first = FALSE;
  1061. c = strtok( NULL, seps ); // value
  1062. if( strcmp( c, "NoImage" ) )
  1063. drawData->image = TheMappedImageCollection->findImageByName( AsciiString( c ) );
  1064. else
  1065. drawData->image = NULL;
  1066. // COLOR: R G B A
  1067. c = strtok( NULL, seps ); // label
  1068. c = strtok( NULL, seps ); // value
  1069. scanUnsignedInt( c, r );
  1070. c = strtok( NULL, seps ); // value
  1071. scanUnsignedInt( c, g );
  1072. c = strtok( NULL, seps ); // value
  1073. scanUnsignedInt( c, b );
  1074. c = strtok( NULL, seps ); // value
  1075. scanUnsignedInt( c, a );
  1076. drawData->color = GameMakeColor( r, g, b, a );
  1077. // BORDERCOLOR: R G B A
  1078. c = strtok( NULL, seps ); // label
  1079. c = strtok( NULL, seps ); // value
  1080. scanUnsignedInt( c, r );
  1081. c = strtok( NULL, seps ); // value
  1082. scanUnsignedInt( c, g );
  1083. c = strtok( NULL, seps ); // value
  1084. scanUnsignedInt( c, b );
  1085. c = strtok( NULL, seps ); // value
  1086. scanUnsignedInt( c, a );
  1087. drawData->borderColor = GameMakeColor( r, g, b, a );
  1088. } // end for i
  1089. return TRUE;
  1090. } // end parseDrawData
  1091. // getDataTemplate ============================================================
  1092. /** Given a window type style string return the address of a static
  1093. * gadget data type used for the generic data pointers in the
  1094. * GUI gadget contorls */
  1095. //=============================================================================
  1096. void *getDataTemplate( char *type )
  1097. {
  1098. static EntryData eData;
  1099. static SliderData sData;
  1100. static ListboxData lData;
  1101. static TextData tData;
  1102. static RadioButtonData rData;
  1103. static TabControlData tcData;
  1104. static ComboBoxData cData;
  1105. void *data;
  1106. if( !strcmp( type, "VERTSLIDER" ) || !strcmp( type, "HORZSLIDER" ) )
  1107. {
  1108. memset( &sData, 0, sizeof( SliderData ) );
  1109. data = &sData;
  1110. }
  1111. else if( !strcmp( type, "SCROLLLISTBOX" ) )
  1112. {
  1113. memset( &lData, 0, sizeof( ListboxData ) );
  1114. data = &lData;
  1115. }
  1116. else if( !strcmp( type, "TABCONTROL" ) )
  1117. {
  1118. memset( &tcData, 0, sizeof( TabControlData ) );
  1119. data = &tcData;
  1120. }
  1121. else if( !strcmp( type, "ENTRYFIELD" ) )
  1122. {
  1123. memset( &eData, 0, sizeof( EntryData ) );
  1124. data = &eData;
  1125. }
  1126. else if( !strcmp( type, "STATICTEXT" ) )
  1127. {
  1128. memset( &tData, 0, sizeof( TextData ) );
  1129. data = &tData;
  1130. }
  1131. else if( !strcmp( type, "RADIOBUTTON" ) )
  1132. {
  1133. memset( &rData, 0, sizeof( RadioButtonData ) );
  1134. data = &rData;
  1135. }
  1136. else if( !strcmp( type, "COMBOBOX" ) )
  1137. {
  1138. memset( &cData, 0, sizeof( ComboBoxData ) );
  1139. data = &cData;
  1140. }
  1141. else
  1142. data = NULL;
  1143. return data;
  1144. } // end getDataTemplate
  1145. // parseData ==================================================================
  1146. //
  1147. // Parse the data for gadgets. For sliders the data is in the format:
  1148. // <Minimum Value> <Maximum Value>
  1149. //
  1150. // For listboxes the data is formatted as:
  1151. // <Max number of entries> <Height of an entry> <AutoScroll> <AutoPurge> <ScrollBar> <MultiSelect> <ForceSelect>
  1152. //
  1153. // For Combo Boxes the data is formatted as:
  1154. // <is Editable> <Max Characters> <Max Entries before scroll appaears>
  1155. //
  1156. // For entry fields the data is as follows:
  1157. // <Max text length> <entry box width> <SecretText> <1 = NumericalOnly, 2 = AlphaNumericOnly>
  1158. //
  1159. // For text the data is as follows:
  1160. // <Centered> <Outlined> <StringManagerLabel>
  1161. //
  1162. // 1/2/2003: THIS FUNCTION IS NEVER REACHED; IT IS OBSOLETE -MDC
  1163. //
  1164. //=============================================================================
  1165. static Bool parseData( void **data, char *type, char *buffer )
  1166. {
  1167. char *c;
  1168. static EntryData eData;
  1169. static SliderData sData;
  1170. static ListboxData lData;
  1171. static TextData tData;
  1172. static RadioButtonData rData;
  1173. static ComboBoxData cData;
  1174. if( !strcmp( type, "VERTSLIDER" ) || !strcmp( type, "HORZSLIDER" ) )
  1175. {
  1176. memset( &sData, 0, sizeof( SliderData ) );
  1177. c = strtok( buffer, " \t\n\r" );
  1178. sData.minVal = atoi(c);
  1179. c = strtok( NULL, " \t\n\r" );
  1180. sData.maxVal = atoi(c);
  1181. *data = &sData;
  1182. }
  1183. else if( !strcmp( type, "SCROLLLISTBOX" ) )
  1184. {
  1185. memset( &lData, 0, sizeof( ListboxData ) );
  1186. c = strtok( buffer, " \t\n\r" );
  1187. lData.listLength = atoi(c);
  1188. // c = strtok( NULL, " \t\n\r" );
  1189. // lData.entryHeight = atoi(c);
  1190. c = strtok( NULL, " \t\n\r" );
  1191. lData.autoScroll = atoi(c);
  1192. c = strtok( NULL, " \t\n\r" );
  1193. lData.autoPurge = atoi(c);
  1194. c = strtok( NULL, " \t\n\r" );
  1195. lData.scrollBar = atoi(c);
  1196. c = strtok( NULL, " \t\n\r" );
  1197. lData.multiSelect = atoi(c);
  1198. c = strtok( NULL, " \t\n\r" );
  1199. lData.forceSelect = atoi(c);
  1200. *data = &lData;
  1201. }
  1202. else if( !strcmp( type, "ENTRYFIELD" ) )
  1203. {
  1204. memset( &eData, 0, sizeof( EntryData ) );
  1205. c = strtok( buffer, " \t\n\r" );
  1206. eData.maxTextLen = atoi(c);
  1207. c = strtok( NULL, " \t\n\r" );
  1208. // if (c)
  1209. // eData.entryWidth = atoi(c);
  1210. // else
  1211. // eData.entryWidth = -1;
  1212. c = strtok( NULL, " \t\n\r" );
  1213. if (c)
  1214. {
  1215. eData.secretText = atoi(c);
  1216. if( eData.secretText != FALSE )
  1217. eData.secretText = TRUE;
  1218. }
  1219. else
  1220. eData.secretText = FALSE;
  1221. c = strtok( NULL, " \t\n\r" );
  1222. if (c)
  1223. {
  1224. eData.numericalOnly = ( atoi(c) == 1 );
  1225. eData.alphaNumericalOnly = ( atoi(c) == 2 );
  1226. eData.aSCIIOnly = ( atoi(c) == 3 );
  1227. }
  1228. else
  1229. {
  1230. eData.numericalOnly = FALSE;
  1231. eData.alphaNumericalOnly = FALSE;
  1232. eData.aSCIIOnly = FALSE;
  1233. }
  1234. *data = &eData;
  1235. }
  1236. else if( !strcmp( type, "STATICTEXT" ) )
  1237. {
  1238. c = strtok( buffer, " \t\n\r" );
  1239. tData.centered = atoi(c);
  1240. if( tData.centered != FALSE )
  1241. tData.centered = TRUE;
  1242. c = strtok( NULL, " \t\n\r" );
  1243. /** @todo need to get a label from the translation manager, uncomment
  1244. the following line and remove the WideChar assignment when
  1245. we have it */
  1246. // text = StringManagerFetch( c );
  1247. // text = L"Need StrManager, Remove me!";
  1248. // TheWindowManager->winStrcpy( tData.text, text );
  1249. *data = &tData;
  1250. }
  1251. else if( !strcmp( type, "RADIOBUTTON" ) )
  1252. {
  1253. c = strtok( buffer, " \t\n\r" );
  1254. rData.group = atoi(c);
  1255. /// @todo Colin: Why was this here???
  1256. // if( tData.centered != FALSE )
  1257. // {
  1258. // tData.centered = TRUE;
  1259. // }
  1260. *data = &rData;
  1261. }
  1262. else
  1263. *data = NULL;
  1264. return TRUE;
  1265. } // end parseData
  1266. // setWindowText ==============================================================
  1267. /** Set the default text for a window or gadget control */
  1268. //=============================================================================
  1269. static void setWindowText( GameWindow *window, AsciiString textLabel )
  1270. {
  1271. // sanity
  1272. if (textLabel.isEmpty())
  1273. return;
  1274. UnicodeString theText, entryText;
  1275. //Translate the text
  1276. theText = TheGameText->fetch( (char *)textLabel.str());
  1277. // set the text in the window based on what it is
  1278. if( BitTest( window->winGetStyle(), GWS_PUSH_BUTTON ) )
  1279. GadgetButtonSetText( window, theText );
  1280. else if( BitTest( window->winGetStyle(), GWS_RADIO_BUTTON ) )
  1281. GadgetRadioSetText( window, theText );
  1282. else if( BitTest( window->winGetStyle(), GWS_CHECK_BOX ) )
  1283. GadgetCheckBoxSetText( window, theText );
  1284. else if( BitTest( window->winGetStyle(), GWS_STATIC_TEXT ) )
  1285. GadgetStaticTextSetText( window, theText );
  1286. else if( BitTest( window->winGetStyle(), GWS_ENTRY_FIELD ) )
  1287. {
  1288. entryText.translate(textLabel);
  1289. GadgetTextEntrySetText( window, entryText );
  1290. }
  1291. else
  1292. window->winSetText( theText );
  1293. } // end setWindowText
  1294. // createGadget ===============================================================
  1295. /** Create a gadget based on the 'type' parm */
  1296. //=============================================================================
  1297. static GameWindow *createGadget( char *type,
  1298. GameWindow *parent,
  1299. Int status,
  1300. Int x, Int y,
  1301. Int width, Int height,
  1302. WinInstanceData *instData,
  1303. void *data )
  1304. {
  1305. GameWindow *window;
  1306. instData->m_owner = parent;
  1307. if( !strcmp( type, "PUSHBUTTON" ) )
  1308. {
  1309. instData->m_style |= GWS_PUSH_BUTTON;
  1310. window = TheWindowManager->gogoGadgetPushButton( parent, status, x, y,
  1311. width, height,
  1312. instData,
  1313. instData->m_font, FALSE );
  1314. }
  1315. else if( !strcmp( type, "RADIOBUTTON" ) )
  1316. {
  1317. RadioButtonData *rData = (RadioButtonData *)data;
  1318. char filename[ MAX_WINDOW_NAME_LEN ];
  1319. char *c;
  1320. //
  1321. // assign a screen identifier to the radio button based on the
  1322. // filename the radio button was saved in
  1323. //
  1324. strcpy( filename, instData->m_decoratedNameString.str() );
  1325. c = strchr( filename, ':' );
  1326. if( c )
  1327. *c = 0; // terminate after filename (format is filename:gadgetname)
  1328. assert( TheNameKeyGenerator );
  1329. if( TheNameKeyGenerator )
  1330. rData->screen = (Int)(TheNameKeyGenerator->nameToKey( AsciiString(filename) ));
  1331. instData->m_style |= GWS_RADIO_BUTTON;
  1332. window = TheWindowManager->gogoGadgetRadioButton( parent, status, x, y,
  1333. width, height,
  1334. instData, rData,
  1335. instData->m_font, FALSE );
  1336. }
  1337. else if( !strcmp( type, "CHECKBOX" ) )
  1338. {
  1339. instData->m_style |= GWS_CHECK_BOX;
  1340. window = TheWindowManager->gogoGadgetCheckbox( parent, status, x, y,
  1341. width, height,
  1342. instData,
  1343. instData->m_font, FALSE );
  1344. }
  1345. else if( !strcmp( type, "TABCONTROL" ) )
  1346. {
  1347. TabControlData *tcData = (TabControlData *)data;
  1348. instData->m_style |= GWS_TAB_CONTROL;
  1349. window = TheWindowManager->gogoGadgetTabControl( parent, status, x, y,
  1350. width, height,
  1351. instData, tcData,
  1352. instData->m_font, FALSE );
  1353. }
  1354. else if( !strcmp( type, "VERTSLIDER" ) )
  1355. {
  1356. SliderData *sData = (SliderData *)data;
  1357. instData->m_style |= GWS_VERT_SLIDER;
  1358. window = TheWindowManager->gogoGadgetSlider( parent, status, x, y,
  1359. width, height,
  1360. instData, sData,
  1361. instData->m_font, FALSE );
  1362. //
  1363. // we know we've read in the slider thumb data in the definition file
  1364. // (it's guaranteed to be generated by the editor) so place that
  1365. // draw data into the thumb of the slider
  1366. //
  1367. GameWindow *thumb = window->winGetChild();
  1368. if( thumb )
  1369. {
  1370. WinInstanceData *instData = thumb->winGetInstanceData();
  1371. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1372. {
  1373. instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ];
  1374. instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ];
  1375. instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ];
  1376. } // end for i
  1377. } //end if
  1378. }
  1379. else if( !strcmp( type, "HORZSLIDER" ) )
  1380. {
  1381. SliderData *sData = (SliderData *)data;
  1382. instData->m_style |= GWS_HORZ_SLIDER;
  1383. window = TheWindowManager->gogoGadgetSlider( parent, status, x, y,
  1384. width, height,
  1385. instData, sData,
  1386. instData->m_font, FALSE );
  1387. //
  1388. // we know we've read in the slider thumb data in the definition file
  1389. // (it's guaranteed to be generated by the editor) so place that
  1390. // draw data into the thumb of the slider
  1391. //
  1392. GameWindow *thumb = window->winGetChild();
  1393. if( thumb )
  1394. {
  1395. WinInstanceData *instData = thumb->winGetInstanceData();
  1396. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1397. {
  1398. instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ];
  1399. instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ];
  1400. instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ];
  1401. } // end for i
  1402. } //end if
  1403. }
  1404. else if( !strcmp( type, "SCROLLLISTBOX" ) )
  1405. {
  1406. ListboxData *lData = (ListboxData *)data;
  1407. instData->m_style |= GWS_SCROLL_LISTBOX;
  1408. window = TheWindowManager->gogoGadgetListBox( parent, status, x, y,
  1409. width, height,
  1410. instData, lData,
  1411. instData->m_font, FALSE );
  1412. //
  1413. // we know that in the file we have read the draw data for the listbox
  1414. // parts (up button, down button, and slider), now that we have those
  1415. // parts actually created we must assign that data to them
  1416. //
  1417. GameWindow *upButton = GadgetListBoxGetUpButton( window );
  1418. if( upButton )
  1419. {
  1420. WinInstanceData *instData = upButton->winGetInstanceData();
  1421. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1422. {
  1423. instData->m_enabledDrawData[ i ] = enabledUpButtonDrawData[ i ];
  1424. instData->m_disabledDrawData[ i ] = disabledUpButtonDrawData[ i ];
  1425. instData->m_hiliteDrawData[ i ] = hiliteUpButtonDrawData[ i ];
  1426. } // end for i
  1427. } // end if
  1428. GameWindow *downButton = GadgetListBoxGetDownButton( window );
  1429. if( downButton )
  1430. {
  1431. WinInstanceData *instData = downButton->winGetInstanceData();
  1432. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1433. {
  1434. instData->m_enabledDrawData[ i ] = enabledDownButtonDrawData[ i ];
  1435. instData->m_disabledDrawData[ i ] = disabledDownButtonDrawData[ i ];
  1436. instData->m_hiliteDrawData[ i ] = hiliteDownButtonDrawData[ i ];
  1437. } // end for i
  1438. } // end if
  1439. GameWindow *slider = GadgetListBoxGetSlider( window );
  1440. if( slider )
  1441. {
  1442. WinInstanceData *instData = slider->winGetInstanceData();
  1443. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1444. {
  1445. instData->m_enabledDrawData[ i ] = enabledSliderDrawData[ i ];
  1446. instData->m_disabledDrawData[ i ] = disabledSliderDrawData[ i ];
  1447. instData->m_hiliteDrawData[ i ] = hiliteSliderDrawData[ i ];
  1448. } // end for i
  1449. // do the slider thumb
  1450. GameWindow *thumb = slider->winGetChild();
  1451. if( thumb )
  1452. {
  1453. WinInstanceData *instData = thumb->winGetInstanceData();
  1454. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1455. {
  1456. instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ];
  1457. instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ];
  1458. instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ];
  1459. } // end for i
  1460. } //end if
  1461. } // end if
  1462. }
  1463. else if( !strcmp( type, "COMBOBOX" ) )
  1464. {
  1465. ComboBoxData *cData = (ComboBoxData *)data;
  1466. cData->entryData = NEW EntryData;
  1467. memset ( cData->entryData, 0, sizeof(EntryData));
  1468. cData->listboxData = NEW ListboxData;
  1469. memset ( cData->listboxData, 0, sizeof(ListboxData));
  1470. //initialize combo box data
  1471. //cData->isEditable = TRUE;
  1472. //cData->maxChars = 16;
  1473. //cData->maxDisplay = 5;
  1474. cData->entryCount = 0;
  1475. //initialize entry data
  1476. cData->entryData->aSCIIOnly = cData->asciiOnly;
  1477. cData->entryData->alphaNumericalOnly = cData->lettersAndNumbersOnly;
  1478. cData->entryData->maxTextLen = cData->maxChars;
  1479. //initialize listbox data
  1480. cData->listboxData->listLength = 10;
  1481. cData->listboxData->autoScroll = 0;
  1482. cData->listboxData->scrollIfAtEnd = FALSE;
  1483. cData->listboxData->autoPurge = 0;
  1484. cData->listboxData->scrollBar = 1;
  1485. cData->listboxData->multiSelect = 0;
  1486. cData->listboxData->forceSelect = 1;
  1487. cData->listboxData->columns = 1;
  1488. cData->listboxData->columnWidth = NULL;
  1489. cData->listboxData->columnWidthPercentage = NULL;
  1490. instData->m_style |= GWS_COMBO_BOX;
  1491. window = TheWindowManager->gogoGadgetComboBox( parent, status, x, y,
  1492. width, height,
  1493. instData, cData,
  1494. instData->m_font, FALSE );
  1495. GameWindow *dropDownButton = GadgetComboBoxGetDropDownButton( window );
  1496. if( dropDownButton )
  1497. {
  1498. WinInstanceData *instData = dropDownButton->winGetInstanceData();
  1499. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1500. {
  1501. instData->m_enabledDrawData[ i ] = enabledDropDownButtonDrawData[ i ];
  1502. instData->m_disabledDrawData[ i ] = disabledDropDownButtonDrawData[ i ];
  1503. instData->m_hiliteDrawData[ i ] = hiliteDropDownButtonDrawData[ i ];
  1504. } // end for i
  1505. } // end if
  1506. GameWindow *editBox = GadgetComboBoxGetEditBox( window );
  1507. if( editBox )
  1508. {
  1509. WinInstanceData *instData = editBox->winGetInstanceData();
  1510. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1511. {
  1512. instData->m_enabledDrawData[ i ] = enabledEditBoxDrawData[ i ];
  1513. instData->m_disabledDrawData[ i ] = disabledEditBoxDrawData[ i ];
  1514. instData->m_hiliteDrawData[ i ] = hiliteEditBoxDrawData[ i ];
  1515. } // end for i
  1516. } // end if
  1517. GameWindow *listBox = GadgetComboBoxGetListBox( window );
  1518. if( listBox )
  1519. {
  1520. WinInstanceData *instData = listBox->winGetInstanceData();
  1521. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1522. {
  1523. instData->m_enabledDrawData[ i ] = enabledListBoxDrawData[ i ];
  1524. instData->m_disabledDrawData[ i ] = disabledListBoxDrawData[ i ];
  1525. instData->m_hiliteDrawData[ i ] = hiliteListBoxDrawData[ i ];
  1526. } // end for i
  1527. GameWindow *upButton = GadgetListBoxGetUpButton( listBox );
  1528. if( upButton )
  1529. {
  1530. WinInstanceData *instData = upButton->winGetInstanceData();
  1531. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1532. {
  1533. instData->m_enabledDrawData[ i ] = enabledUpButtonDrawData[ i ];
  1534. instData->m_disabledDrawData[ i ] = disabledUpButtonDrawData[ i ];
  1535. instData->m_hiliteDrawData[ i ] = hiliteUpButtonDrawData[ i ];
  1536. } // end for i
  1537. } // end if
  1538. GameWindow *downButton = GadgetListBoxGetDownButton( listBox );
  1539. if( downButton )
  1540. {
  1541. WinInstanceData *instData = downButton->winGetInstanceData();
  1542. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1543. {
  1544. instData->m_enabledDrawData[ i ] = enabledDownButtonDrawData[ i ];
  1545. instData->m_disabledDrawData[ i ] = disabledDownButtonDrawData[ i ];
  1546. instData->m_hiliteDrawData[ i ] = hiliteDownButtonDrawData[ i ];
  1547. } // end for i
  1548. } // end if
  1549. GameWindow *slider = GadgetListBoxGetSlider( listBox );
  1550. if( slider )
  1551. {
  1552. WinInstanceData *instData = slider->winGetInstanceData();
  1553. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1554. {
  1555. instData->m_enabledDrawData[ i ] = enabledSliderDrawData[ i ];
  1556. instData->m_disabledDrawData[ i ] = disabledSliderDrawData[ i ];
  1557. instData->m_hiliteDrawData[ i ] = hiliteSliderDrawData[ i ];
  1558. } // end for i
  1559. // do the slider thumb
  1560. GameWindow *thumb = slider->winGetChild();
  1561. if( thumb )
  1562. {
  1563. WinInstanceData *instData = thumb->winGetInstanceData();
  1564. for( Int i = 0; i < MAX_DRAW_DATA; i++ )
  1565. {
  1566. instData->m_enabledDrawData[ i ] = enabledSliderThumbDrawData[ i ];
  1567. instData->m_disabledDrawData[ i ] = disabledSliderThumbDrawData[ i ];
  1568. instData->m_hiliteDrawData[ i ] = hiliteSliderThumbDrawData[ i ];
  1569. } // end for i
  1570. } //end if
  1571. } // end if
  1572. }
  1573. }
  1574. else if( !strcmp( type, "ENTRYFIELD" ) )
  1575. {
  1576. EntryData *eData = (EntryData *)data;
  1577. instData->m_style |= GWS_ENTRY_FIELD;
  1578. window = TheWindowManager->gogoGadgetTextEntry( parent, status, x, y,
  1579. width, height,
  1580. instData, eData,
  1581. instData->m_font, FALSE );
  1582. }
  1583. else if( !strcmp( type, "STATICTEXT" ) )
  1584. {
  1585. TextData *tData = (TextData *)data;
  1586. instData->m_style |= GWS_STATIC_TEXT;
  1587. window = TheWindowManager->gogoGadgetStaticText( parent, status, x, y,
  1588. width, height,
  1589. instData, tData,
  1590. instData->m_font, FALSE );
  1591. }
  1592. else if( !strcmp( type, "PROGRESSBAR" ) )
  1593. {
  1594. instData->m_style |= GWS_PROGRESS_BAR;
  1595. window = TheWindowManager->gogoGadgetProgressBar( parent, status, x, y,
  1596. width, height,
  1597. instData,
  1598. instData->m_font, FALSE );
  1599. }
  1600. return window;
  1601. } // end createGadget
  1602. // createWindow ===============================================================
  1603. // Create a user window or a gadget depending on the 'type' parm
  1604. //=============================================================================
  1605. static GameWindow *createWindow( char *type,
  1606. Int id,
  1607. Int status,
  1608. Int x, Int y,
  1609. Int width, Int height,
  1610. WinInstanceData *instData,
  1611. void *data,
  1612. GameWinSystemFunc system,
  1613. GameWinInputFunc input,
  1614. GameWinTooltipFunc tooltip,
  1615. GameWinDrawFunc draw )
  1616. {
  1617. GameWindow *window, *parent;
  1618. // Check to see if this window has a parent
  1619. parent = peekWindow();
  1620. // If this is a regular window just create it
  1621. if( !strcmp( type, "USER" ) )
  1622. {
  1623. window = TheWindowManager->winCreate( parent,
  1624. status, x, y,
  1625. width, height,
  1626. system );
  1627. if( window )
  1628. {
  1629. instData->m_style |= GWS_USER_WINDOW;
  1630. window->winSetInstanceData( instData );
  1631. window->winSetWindowId( id );
  1632. } // end if
  1633. }
  1634. else if( !strcmp( type, "TABPANE" ) )
  1635. {
  1636. window = TheWindowManager->winCreate( parent,
  1637. status, x, y,
  1638. width, height,
  1639. system );
  1640. if( window )
  1641. {
  1642. instData->m_style |= GWS_TAB_PANE;
  1643. window->winSetInstanceData( instData );
  1644. window->winSetWindowId( id );
  1645. } // end if
  1646. }
  1647. else
  1648. {
  1649. // Else parse the type and create the gadget
  1650. window = createGadget( type,
  1651. parent,
  1652. status,
  1653. x, y,
  1654. width, height,
  1655. instData,
  1656. data );
  1657. if( window )
  1658. {
  1659. // set id
  1660. window->winSetWindowId( id );
  1661. } // end if
  1662. }
  1663. // assign the callbacks if they are not empty/NULL, that means they were read
  1664. // in and parsed from the window definition file
  1665. if( window )
  1666. {
  1667. if( system )
  1668. window->winSetSystemFunc( system );
  1669. if( input )
  1670. window->winSetInputFunc( input );
  1671. if( tooltip )
  1672. window->winSetTooltipFunc( tooltip );
  1673. if( draw )
  1674. window->winSetDrawFunc( draw );
  1675. // save strings for edit data if present
  1676. GameWindowEditData *editData = window->winGetEditData();
  1677. if( editData )
  1678. {
  1679. editData->systemCallbackString = theSystemString;
  1680. editData->inputCallbackString = theInputString;
  1681. editData->tooltipCallbackString = theTooltipString;
  1682. editData->drawCallbackString = theDrawString;
  1683. } // end if
  1684. } // end if
  1685. if( window )
  1686. {
  1687. // set any text read from the textLabel
  1688. setWindowText( window, instData->m_textLabelString );
  1689. } // end if
  1690. // If there is a parent window, send it the SCRIPT_CREATE message
  1691. if( window && parent )
  1692. TheWindowManager->winSendInputMsg( parent, GWM_SCRIPT_CREATE, id, 0 );
  1693. return window;
  1694. } // end createWindow
  1695. // parseChildWindows ==========================================================
  1696. /** Parse window descriptions until an extra end is encountered indicating
  1697. * the end of this block of child window descriptions. */
  1698. //=============================================================================
  1699. static Bool parseChildWindows( GameWindow *window,
  1700. File *inFile,
  1701. char *buffer )
  1702. {
  1703. GameWindow *lastWindow;
  1704. AsciiString asciibuf;
  1705. //The gadget with children needs to delete its default created children in favor
  1706. //of the ones from the script file. So kill them before reading.
  1707. if( BitTest( window->winGetStyle(), GWS_TAB_CONTROL ) )
  1708. {
  1709. GameWindow *nextWindow = NULL;
  1710. for( GameWindow *myChild = window->winGetChild(); myChild; myChild = nextWindow )
  1711. {
  1712. nextWindow = myChild->winGetNext();
  1713. TheWindowManager->winDestroy( myChild );
  1714. }
  1715. }
  1716. // Push the current window onto the stack so we know it's the parent
  1717. pushWindow( window );
  1718. while( TRUE )
  1719. {
  1720. if (inFile->scanString(asciibuf) == FALSE) {
  1721. break;
  1722. }
  1723. if (asciibuf.compare("ENDALLCHILDREN") == 0) {
  1724. break;
  1725. }
  1726. if (asciibuf.compare("END") == 0) {
  1727. break;
  1728. }
  1729. if (asciibuf.compare("ENABLEDCOLOR") == 0)
  1730. {
  1731. if( parseDefaultColor( &defEnabledColor, inFile, buffer ) == FALSE )
  1732. {
  1733. return FALSE;
  1734. }
  1735. }
  1736. else if (asciibuf.compare("DISABLEDCOLOR") == 0)
  1737. {
  1738. if( parseDefaultColor( &defDisabledColor, inFile, buffer ) == FALSE )
  1739. {
  1740. return FALSE;
  1741. }
  1742. }
  1743. else if (asciibuf.compare("HILITECOLOR") == 0)
  1744. {
  1745. if( parseDefaultColor( &defHiliteColor, inFile, buffer ) == FALSE )
  1746. {
  1747. return FALSE;
  1748. }
  1749. }
  1750. else if (asciibuf.compare("SELECTEDCOLOR") == 0)
  1751. {
  1752. if( parseDefaultColor( &defSelectedColor, inFile, buffer ) == FALSE )
  1753. {
  1754. return FALSE;
  1755. }
  1756. }
  1757. else if (asciibuf.compare("TEXTCOLOR") == 0)
  1758. {
  1759. if( parseDefaultColor( &defTextColor, inFile, buffer ) == FALSE )
  1760. {
  1761. return FALSE;
  1762. }
  1763. }
  1764. else if (asciibuf.compare("WINDOW") == 0)
  1765. {
  1766. // Parse window descriptions until the last END is read
  1767. if( parseWindow( inFile, buffer ) == NULL )
  1768. {
  1769. return FALSE;
  1770. }
  1771. }
  1772. } // end while( TRUE )
  1773. // Pop the current window off the stack
  1774. lastWindow = popWindow();
  1775. if( lastWindow != window )
  1776. {
  1777. DEBUG_LOG(( "parseChildWindows: unmatched window on stack. Corrupt stack or bad source\n" ));
  1778. return FALSE;
  1779. }
  1780. if( BitTest( window->winGetStyle(), GWS_TAB_CONTROL ) )
  1781. GadgetTabControlFixupSubPaneList( window );//all children created, so re-fill SubPane array with children
  1782. return TRUE;
  1783. } // end parseChildWindows
  1784. // lookup table for parsing functions
  1785. static GameWindowParse gameWindowFieldList[] =
  1786. {
  1787. { "NAME", parseName },
  1788. { "STATUS", parseStatus },
  1789. { "STYLE", parseStyle },
  1790. { "SYSTEMCALLBACK", parseSystemCallback },
  1791. { "INPUTCALLBACK", parseInputCallback },
  1792. { "TOOLTIPCALLBACK", parseTooltipCallback },
  1793. { "DRAWCALLBACK", parseDrawCallback },
  1794. { "FONT", parseFont },
  1795. { "HEADERTEMPLATE", parseHeaderTemplate },
  1796. { "LISTBOXDATA", parseListboxData },
  1797. { "COMBOBOXDATA", parseComboBoxData },
  1798. { "SLIDERDATA", parseSliderData },
  1799. { "RADIOBUTTONDATA", parseRadioButtonData },
  1800. { "TOOLTIPTEXT", parseTooltipText },
  1801. { "TOOLTIPDELAY", parseTooltipDelay },
  1802. { "TEXT", parseText },
  1803. { "TEXTCOLOR", parseTextColor },
  1804. { "STATICTEXTDATA", parseStaticTextData },
  1805. { "TEXTENTRYDATA", parseTextEntryData },
  1806. { "TABCONTROLDATA", parseTabControlData },
  1807. { "ENABLEDDRAWDATA", parseDrawData },
  1808. { "DISABLEDDRAWDATA", parseDrawData },
  1809. { "HILITEDRAWDATA", parseDrawData },
  1810. { "LISTBOXENABLEDUPBUTTONDRAWDATA", parseDrawData },
  1811. { "LISTBOXENABLEDDOWNBUTTONDRAWDATA", parseDrawData },
  1812. { "LISTBOXENABLEDSLIDERDRAWDATA", parseDrawData },
  1813. { "LISTBOXDISABLEDUPBUTTONDRAWDATA", parseDrawData },
  1814. { "LISTBOXDISABLEDDOWNBUTTONDRAWDATA", parseDrawData },
  1815. { "LISTBOXDISABLEDSLIDERDRAWDATA", parseDrawData },
  1816. { "LISTBOXHILITEUPBUTTONDRAWDATA", parseDrawData },
  1817. { "LISTBOXHILITEDOWNBUTTONDRAWDATA", parseDrawData },
  1818. { "LISTBOXHILITESLIDERDRAWDATA", parseDrawData },
  1819. { "SLIDERTHUMBENABLEDDRAWDATA", parseDrawData },
  1820. { "SLIDERTHUMBDISABLEDDRAWDATA", parseDrawData },
  1821. { "SLIDERTHUMBHILITEDRAWDATA", parseDrawData },
  1822. { "COMBOBOXDROPDOWNBUTTONENABLEDDRAWDATA", parseDrawData },
  1823. { "COMBOBOXDROPDOWNBUTTONDISABLEDDRAWDATA", parseDrawData },
  1824. { "COMBOBOXDROPDOWNBUTTONHILITEDRAWDATA", parseDrawData },
  1825. { "COMBOBOXEDITBOXENABLEDDRAWDATA", parseDrawData },
  1826. { "COMBOBOXEDITBOXDISABLEDDRAWDATA", parseDrawData },
  1827. { "COMBOBOXEDITBOXHILITEDRAWDATA", parseDrawData },
  1828. { "COMBOBOXLISTBOXENABLEDDRAWDATA", parseDrawData },
  1829. { "COMBOBOXLISTBOXDISABLEDDRAWDATA", parseDrawData },
  1830. { "COMBOBOXLISTBOXHILITEDRAWDATA", parseDrawData },
  1831. { "IMAGEOFFSET", parseImageOffset },
  1832. { "TOOLTIP", parseTooltip },
  1833. { NULL, NULL }
  1834. };
  1835. // parseWindow ================================================================
  1836. /** Parse a WINDOW entry in the script. */
  1837. //=============================================================================
  1838. static GameWindow *parseWindow( File *inFile, char *buffer )
  1839. {
  1840. GameWindowParse *parse;
  1841. GameWindow *window = NULL;
  1842. GameWindow *parent = peekWindow();
  1843. WinInstanceData instData;
  1844. char type[64];
  1845. char token[ 256 ];
  1846. char *c;
  1847. Int x, y, width, height;
  1848. void *data = NULL;
  1849. ICoord2D parentSize;
  1850. AsciiString asciibuf;
  1851. //
  1852. // reset our 'static globals' that house the current parsed window callback
  1853. // definitions to empty
  1854. //
  1855. systemFunc = NULL;
  1856. inputFunc = NULL;
  1857. tooltipFunc = NULL;
  1858. drawFunc = NULL;
  1859. theSystemString.clear();
  1860. theInputString.clear();
  1861. theTooltipString.clear();
  1862. theDrawString.clear();
  1863. // get the size of the parent, or if no parent present the screen
  1864. if( parent )
  1865. {
  1866. parent->winGetSize( &parentSize.x, &parentSize.y );
  1867. } // end if
  1868. else
  1869. {
  1870. parentSize.x = TheDisplay->getWidth();
  1871. parentSize.y = TheDisplay->getHeight();
  1872. } // end else
  1873. // Initialize the instance data to the defaults
  1874. /// @todo need to support enabled/disabled/hilite text colors here
  1875. instData.init();
  1876. instData.m_enabledText.color = defTextColor;
  1877. instData.m_enabledText.borderColor = defTextColor;
  1878. instData.m_disabledText.color = defTextColor;
  1879. instData.m_disabledText.borderColor = defTextColor;
  1880. instData.m_hiliteText.color = defTextColor;
  1881. instData.m_hiliteText.borderColor = defTextColor;
  1882. /// @todo need real font support here
  1883. instData.m_font = defFont;
  1884. //
  1885. // read the first few lines that are required to be first in a
  1886. // window definition file including position, size, type, and id
  1887. //
  1888. // window type
  1889. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  1890. c = strtok( buffer, seps );
  1891. assert( strcmp( c, "WINDOWTYPE" ) == 0 );
  1892. c = strtok( NULL, seps ); // get data to right of = sign
  1893. strcpy( type, c );
  1894. //
  1895. // based on the window type get a pointer for any specific data
  1896. // for the gadget controls needed
  1897. //
  1898. data = getDataTemplate( type );
  1899. // position
  1900. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  1901. c = strtok( buffer, seps );
  1902. assert( strcmp( c, "SCREENRECT" ) == 0 );
  1903. if( parseScreenRect( c, buffer, &x, &y, &width, &height ) == FALSE )
  1904. goto cleanupAndExit;
  1905. // parse all the field definitions
  1906. while( TRUE )
  1907. {
  1908. // get token
  1909. inFile->scanString(asciibuf);
  1910. // parse field
  1911. for( parse = gameWindowFieldList; parse->parse; parse++ )
  1912. {
  1913. if (asciibuf.compare(parse->name) == 0)
  1914. {
  1915. strcpy( token, asciibuf.str() );
  1916. // eat '='
  1917. inFile->scanString(asciibuf);
  1918. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  1919. if (parse->parse( token, &instData, buffer, data ) == FALSE )
  1920. {
  1921. DEBUG_LOG(( "parseGameObject: Error parsing %s\n", parse->name ));
  1922. goto cleanupAndExit;
  1923. }
  1924. break;
  1925. }
  1926. } // end for
  1927. if( parse->parse == NULL )
  1928. {
  1929. // If it's the END keyword
  1930. if (asciibuf.compare("DATA") == 0)
  1931. {
  1932. // eat '='
  1933. inFile->scanString(asciibuf);
  1934. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  1935. if( parseData( &data, type, buffer ) == FALSE )
  1936. {
  1937. DEBUG_LOG(( "parseGameWindow: Error parsing %s\n", parse->name ));
  1938. goto cleanupAndExit;
  1939. }
  1940. }
  1941. else if (asciibuf.compare("END") == 0)
  1942. {
  1943. // Check to see if we have a header template, if so, set the font equal to that.
  1944. if(TheHeaderTemplateManager->getFontFromTemplate(instData.m_headerTemplateName))
  1945. instData.m_font = TheHeaderTemplateManager->getFontFromTemplate(instData.m_headerTemplateName);
  1946. // Create a window using the current description
  1947. if( window == NULL )
  1948. window = createWindow( type, instData.m_id, instData.getStatus(), x, y,
  1949. width, height, &instData, data,
  1950. systemFunc, inputFunc, tooltipFunc, drawFunc );
  1951. goto cleanupAndExit;
  1952. }
  1953. else if (asciibuf.compare("CHILD") == 0)
  1954. {
  1955. // Create a window using the current description
  1956. window = createWindow( type, instData.m_id, instData.getStatus(), x, y,
  1957. width, height, &instData, data,
  1958. systemFunc, inputFunc, tooltipFunc, drawFunc );
  1959. if (window == NULL)
  1960. goto cleanupAndExit;
  1961. // Parses the CHILD's window info.
  1962. if( parseChildWindows( window, inFile, buffer ) == FALSE )
  1963. {
  1964. TheWindowManager->winDestroy( window );
  1965. window = NULL;
  1966. goto cleanupAndExit;
  1967. } // end if
  1968. }
  1969. else
  1970. {
  1971. // Else it is unrecognized so eat associated data
  1972. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  1973. }
  1974. } // end if
  1975. } // end while( TRUE )
  1976. cleanupAndExit:
  1977. //
  1978. // this should be true since we should never set the text in
  1979. // display strings in a instance data that is not inside a
  1980. // window ... it's for sanity checking
  1981. //
  1982. // I am commenting this out to get tooltips working, If for
  1983. // some reason we start having displayString problems... CLH
  1984. // assert( instData.m_text == NULL && instData.m_tooltip == NULL );
  1985. return window;
  1986. } // end parseWindow
  1987. //=================================================================================================
  1988. //=================================================================================================
  1989. //=================================================================================================
  1990. //-------------------------------------------------------------------------------------------------
  1991. /** Parse init for layout file */
  1992. //-------------------------------------------------------------------------------------------------
  1993. Bool parseInit( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info )
  1994. {
  1995. char *c;
  1996. char *seps = " \n\r\t";
  1997. // get string
  1998. c = strtok( buffer, seps );
  1999. // translate string to function address
  2000. info->initNameString = c;
  2001. info->init = TheFunctionLexicon->winLayoutInitFunc( TheNameKeyGenerator->nameToKey( info->initNameString ) );
  2002. return TRUE; // success
  2003. } // end parseInit
  2004. //-------------------------------------------------------------------------------------------------
  2005. /** Parse update for layout file */
  2006. //-------------------------------------------------------------------------------------------------
  2007. Bool parseUpdate( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info )
  2008. {
  2009. char *c;
  2010. char *seps = " \n\r\t";
  2011. // get string
  2012. c = strtok( buffer, seps );
  2013. // translate string to function address
  2014. info->updateNameString = c;
  2015. info->update = TheFunctionLexicon->winLayoutUpdateFunc( TheNameKeyGenerator->nameToKey( info->updateNameString ) );
  2016. return TRUE; // success
  2017. } // end parseUpdate
  2018. //-------------------------------------------------------------------------------------------------
  2019. /** Parse shutdown for layout file */
  2020. //-------------------------------------------------------------------------------------------------
  2021. Bool parseShutdown( char *token, char *buffer, UnsignedInt version, WindowLayoutInfo *info )
  2022. {
  2023. char *c;
  2024. char *seps = " \n\r\t";
  2025. // get string
  2026. c = strtok( buffer, seps );
  2027. // translate string to function address
  2028. info->shutdownNameString = c;
  2029. info->shutdown = TheFunctionLexicon->winLayoutShutdownFunc( TheNameKeyGenerator->nameToKey( info->shutdownNameString ) );
  2030. return TRUE; // success
  2031. } // end parseShutdown
  2032. static LayoutScriptParse layoutScriptTable[] =
  2033. {
  2034. { "LAYOUTINIT", parseInit },
  2035. { "LAYOUTUPDATE", parseUpdate },
  2036. { "LAYOUTSHUTDOWN", parseShutdown },
  2037. { NULL, NULL },
  2038. };
  2039. //-------------------------------------------------------------------------------------------------
  2040. /** Parse the layout block which MUST be present in every window file */
  2041. //-------------------------------------------------------------------------------------------------
  2042. Bool parseLayoutBlock( File *inFile, char *buffer, UnsignedInt version, WindowLayoutInfo *info )
  2043. {
  2044. LayoutScriptParse *parse;
  2045. char token[ 256 ];
  2046. AsciiString asciitoken;
  2047. if (inFile->scanString(asciitoken) == FALSE) {
  2048. return FALSE;
  2049. }
  2050. // better be the layout block
  2051. if (asciitoken.compare("STARTLAYOUTBLOCK") != 0) {
  2052. return FALSE;
  2053. }
  2054. while( TRUE )
  2055. {
  2056. // get next token
  2057. inFile->scanString(asciitoken);
  2058. // check for end
  2059. if (asciitoken.compare("ENDLAYOUTBLOCK") == 0) {
  2060. break;
  2061. }
  2062. // search for token in the table
  2063. for( parse = layoutScriptTable; parse && parse->name; parse++ )
  2064. {
  2065. if (asciitoken.compare(parse->name) == 0)
  2066. {
  2067. char *c;
  2068. // read from file
  2069. readUntilSemicolon( inFile, buffer, WIN_BUFFER_LENGTH );
  2070. // eat equals separator " = "
  2071. c = strtok( buffer, " =" );
  2072. strcpy(token, asciitoken.str());
  2073. // parse it
  2074. if( parse->parse( token, c, version, info ) == FALSE )
  2075. return FALSE;
  2076. break; // exit for
  2077. } // end if
  2078. } // end for parse
  2079. } // end while
  2080. return TRUE;
  2081. } // end parseLayoutBlock
  2082. ///////////////////////////////////////////////////////////////////////////////
  2083. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  2084. ///////////////////////////////////////////////////////////////////////////////
  2085. // GameWindowManager::winCreateLayout =========================================
  2086. /** Load window(s) from a .wnd definition file and wrap within a
  2087. * new window layout */
  2088. //=============================================================================
  2089. WindowLayout *GameWindowManager::winCreateLayout( AsciiString filename )
  2090. {
  2091. WindowLayout *layout;
  2092. // allocate a new window layout
  2093. layout = newInstance(WindowLayout);
  2094. // load windows into layout
  2095. if( layout->load( filename ) == FALSE )
  2096. {
  2097. layout->deleteInstance();
  2098. return NULL;
  2099. } // end if
  2100. // return loaded layout
  2101. return layout;
  2102. } // end winCreateLayout
  2103. /** Free up the memory used by static strings. Normally this memory
  2104. is freed by the string destructor but we do it here to make the
  2105. memory leak detection code happy.*/
  2106. void GameWindowManager::freeStaticStrings(void)
  2107. {
  2108. theSystemString.clear();
  2109. theInputString.clear();
  2110. theTooltipString.clear();
  2111. theDrawString.clear();
  2112. }
  2113. WindowLayoutInfo::WindowLayoutInfo() :
  2114. version(0),
  2115. init(NULL),
  2116. update(NULL),
  2117. shutdown(NULL),
  2118. initNameString(AsciiString::TheEmptyString),
  2119. updateNameString(AsciiString::TheEmptyString),
  2120. shutdownNameString(AsciiString::TheEmptyString)
  2121. {
  2122. windows.clear();
  2123. }
  2124. // GameWindowManager::winCreateFromScript =====================================
  2125. /** Parse through a window .wnd file and create all the windows
  2126. * within it.
  2127. *
  2128. * NOTE: The FIRST window created from the script is returned, this
  2129. * way if you want to know ALL of the windows created from this
  2130. * layout file you must iterate over info->windows, since the windows will
  2131. * not be at the head of the window list if there is a modal window active.
  2132. */
  2133. //=============================================================================
  2134. GameWindow *GameWindowManager::winCreateFromScript( AsciiString filenameString,
  2135. WindowLayoutInfo *info )
  2136. {
  2137. const char* filename = filenameString.str();
  2138. static char buffer[ WIN_BUFFER_LENGTH ]; // input buffer for reading
  2139. GameWindow *firstWindow = NULL;
  2140. GameWindow *window;
  2141. char filepath[ _MAX_PATH ] = "Window\\";
  2142. File *inFile;
  2143. WindowLayoutInfo scriptInfo;
  2144. AsciiString asciibuf;
  2145. // zero info struct
  2146. //memset( &scriptInfo, 0, sizeof( WindowLayoutInfo ) ); // it's a class - use a constructor
  2147. // Reset the window stack
  2148. resetWindowStack();
  2149. resetWindowDefaults();
  2150. //
  2151. // get the filename from the parameter, if it doesn't contain a '\' it is
  2152. // a it is assumed to be a filename only, which we will prefix a "window\"
  2153. // directory to, otherwise it is assumed to be an absolute path. When using
  2154. // a filename only make sure the current directory is set to the right
  2155. // place for the window files subdirectory
  2156. //
  2157. if( strchr( filename, '\\' ) == NULL )
  2158. sprintf( filepath, "Window\\%s", filename );
  2159. else
  2160. strcpy( filepath, filename );
  2161. // Open the input file
  2162. inFile = TheFileSystem->openFile(filepath, File::READ);
  2163. if (inFile == NULL)
  2164. {
  2165. DEBUG_LOG(( "WinCreateFromScript: Cannot access file '%s'.\n", filename ));
  2166. return NULL;
  2167. }
  2168. // read the file version
  2169. Int version;
  2170. inFile->read(NULL, strlen("FILE_VERSION = "));
  2171. inFile->scanInt(version);
  2172. inFile->nextLine();
  2173. // version 2+ have a special block called the layout block
  2174. if( version >= 2 )
  2175. {
  2176. if( parseLayoutBlock( inFile, buffer, version, &scriptInfo ) == FALSE )
  2177. {
  2178. DEBUG_LOG(( "WinCreateFromScript: Error parsing layout block\n" ));
  2179. return FALSE;
  2180. } // end if
  2181. } // end if
  2182. else
  2183. {
  2184. // default none names
  2185. scriptInfo.initNameString = "[None]";
  2186. scriptInfo.updateNameString = "[None]";
  2187. scriptInfo.shutdownNameString = "[None]";
  2188. } // end else
  2189. while( TRUE )
  2190. {
  2191. if (inFile->scanString(asciibuf) == FALSE) {
  2192. break;
  2193. }
  2194. if (asciibuf.compare("END") == 0) {
  2195. continue;
  2196. }
  2197. if (asciibuf.compare("ENABLEDCOLOR") == 0)
  2198. {
  2199. if( parseDefaultColor( &defEnabledColor, inFile, buffer ) == FALSE )
  2200. {
  2201. inFile->close();
  2202. inFile = NULL;
  2203. return NULL;
  2204. }
  2205. }
  2206. else if (asciibuf.compare("DISABLEDCOLOR") == 0)
  2207. {
  2208. if( parseDefaultColor( &defDisabledColor, inFile, buffer ) == FALSE )
  2209. {
  2210. inFile->close();
  2211. inFile = NULL;
  2212. return NULL;
  2213. }
  2214. }
  2215. else if (asciibuf.compare("HILITECOLOR") == 0)
  2216. {
  2217. if( parseDefaultColor( &defHiliteColor, inFile, buffer ) == FALSE )
  2218. {
  2219. inFile->close();
  2220. inFile = NULL;
  2221. return NULL;
  2222. }
  2223. }
  2224. else if (asciibuf.compare("SELECTEDCOLOR") == 0)
  2225. {
  2226. if( parseDefaultColor( &defSelectedColor, inFile, buffer ) == FALSE )
  2227. {
  2228. inFile->close();
  2229. inFile = NULL;
  2230. return NULL;
  2231. }
  2232. }
  2233. else if (asciibuf.compare("TEXTCOLOR") == 0)
  2234. {
  2235. if( parseDefaultColor( &defTextColor, inFile, buffer ) == FALSE )
  2236. {
  2237. inFile->close();
  2238. inFile = NULL;
  2239. return NULL;
  2240. }
  2241. }
  2242. else if (asciibuf.compare("BACKGROUNDCOLOR") == 0)
  2243. {
  2244. if( parseDefaultColor( &defBackgroundColor, inFile, buffer ) == FALSE )
  2245. {
  2246. inFile->close();
  2247. inFile = NULL;
  2248. return NULL;
  2249. }
  2250. }
  2251. else if (asciibuf.compare("FONT") == 0)
  2252. {
  2253. if( parseDefaultFont( defFont, inFile, buffer ) == FALSE )
  2254. {
  2255. inFile->close();
  2256. inFile = NULL;
  2257. return NULL;
  2258. }
  2259. }
  2260. else if (asciibuf.compare("WINDOW") == 0)
  2261. {
  2262. // Parse window descriptions until the last END is read
  2263. window = parseWindow( inFile, buffer );
  2264. // save first window created
  2265. if( firstWindow == NULL )
  2266. firstWindow = window;
  2267. scriptInfo.windows.push_back(window);
  2268. } // end else if
  2269. } // end while( TRUE )
  2270. // close the file
  2271. inFile->close();
  2272. inFile = NULL;
  2273. // if info parameter is provided, copy info to the param
  2274. if( info )
  2275. *info = scriptInfo;
  2276. // return the first window created
  2277. return firstWindow;
  2278. } // end WinCreateFromScript