GameWindowManagerScript.cpp 82 KB

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