Window.cpp 93 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code 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. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #pragma hdrstop
  21. #include "../idlib/precompiled.h"
  22. #include "DeviceContext.h"
  23. #include "Window.h"
  24. #include "UserInterfaceLocal.h"
  25. #include "EditWindow.h"
  26. #include "ChoiceWindow.h"
  27. #include "SliderWindow.h"
  28. #include "BindWindow.h"
  29. #include "ListWindow.h"
  30. #include "RenderWindow.h"
  31. #include "FieldWindow.h"
  32. #include "GameSSDWindow.h"
  33. #include "GameBearShootWindow.h"
  34. #include "GameBustOutWindow.h"
  35. bool idWindow::registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to assist during parsing
  36. //float idWindow::shaderRegisters[MAX_EXPRESSION_REGISTERS];
  37. //wexpOp_t idWindow::shaderOps[MAX_EXPRESSION_OPS];
  38. idCVar idWindow::gui_debug( "gui_debug", "0", CVAR_GUI | CVAR_BOOL, "" );
  39. idCVar idWindow::gui_edit( "gui_edit", "0", CVAR_GUI | CVAR_BOOL, "" );
  40. idCVar hud_titlesafe( "hud_titlesafe", "0.0", CVAR_GUI | CVAR_FLOAT, "fraction of the screen to leave around hud for titlesafe area" );
  41. extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces
  42. // made RegisterVars a member of idWindow
  43. const idRegEntry idWindow::RegisterVars[] = {
  44. { "forecolor", idRegister::VEC4 },
  45. { "hovercolor", idRegister::VEC4 },
  46. { "backcolor", idRegister::VEC4 },
  47. { "bordercolor", idRegister::VEC4 },
  48. { "rect", idRegister::RECTANGLE },
  49. { "matcolor", idRegister::VEC4 },
  50. { "scale", idRegister::VEC2 },
  51. { "translate", idRegister::VEC2 },
  52. { "rotate", idRegister::FLOAT },
  53. { "textscale", idRegister::FLOAT },
  54. { "visible", idRegister::BOOL },
  55. { "noevents", idRegister::BOOL },
  56. { "text", idRegister::STRING },
  57. { "background", idRegister::STRING },
  58. { "runscript", idRegister::STRING },
  59. { "varbackground", idRegister::STRING },
  60. { "cvar", idRegister::STRING },
  61. { "choices", idRegister::STRING },
  62. { "choiceVar", idRegister::STRING },
  63. { "bind", idRegister::STRING },
  64. { "modelRotate", idRegister::VEC4 },
  65. { "modelOrigin", idRegister::VEC4 },
  66. { "lightOrigin", idRegister::VEC4 },
  67. { "lightColor", idRegister::VEC4 },
  68. { "viewOffset", idRegister::VEC4 },
  69. { "hideCursor", idRegister::BOOL}
  70. };
  71. const int idWindow::NumRegisterVars = sizeof(RegisterVars) / sizeof(idRegEntry);
  72. const char *idWindow::ScriptNames[] = {
  73. "onMouseEnter",
  74. "onMouseExit",
  75. "onAction",
  76. "onActivate",
  77. "onDeactivate",
  78. "onESC",
  79. "onEvent",
  80. "onTrigger",
  81. "onActionRelease",
  82. "onEnter",
  83. "onEnterRelease"
  84. };
  85. /*
  86. ================
  87. idWindow::CommonInit
  88. ================
  89. */
  90. void idWindow::CommonInit() {
  91. childID = 0;
  92. flags = 0;
  93. lastTimeRun = 0;
  94. origin.Zero();
  95. font = renderSystem->RegisterFont( "" );
  96. timeLine = -1;
  97. xOffset = yOffset = 0.0;
  98. cursor = 0;
  99. forceAspectWidth = 640;
  100. forceAspectHeight = 480;
  101. matScalex = 1;
  102. matScaley = 1;
  103. borderSize = 0;
  104. noTime = false;
  105. visible = true;
  106. textAlign = 0;
  107. textAlignx = 0;
  108. textAligny = 0;
  109. noEvents = false;
  110. rotate = 0;
  111. shear.Zero();
  112. textScale = 0.35f;
  113. backColor.Zero();
  114. foreColor = idVec4(1, 1, 1, 1);
  115. hoverColor = idVec4(1, 1, 1, 1);
  116. matColor = idVec4(1, 1, 1, 1);
  117. borderColor.Zero();
  118. background = NULL;
  119. backGroundName = "";
  120. focusedChild = NULL;
  121. captureChild = NULL;
  122. overChild = NULL;
  123. parent = NULL;
  124. saveOps = NULL;
  125. saveRegs = NULL;
  126. timeLine = -1;
  127. textShadow = 0;
  128. hover = false;
  129. for (int i = 0; i < SCRIPT_COUNT; i++) {
  130. scripts[i] = NULL;
  131. }
  132. hideCursor = false;
  133. }
  134. /*
  135. ================
  136. idWindow::Size
  137. ================
  138. */
  139. size_t idWindow::Size() {
  140. int c = children.Num();
  141. int sz = 0;
  142. for (int i = 0; i < c; i++) {
  143. sz += children[i]->Size();
  144. }
  145. sz += sizeof(*this) + Allocated();
  146. return sz;
  147. }
  148. /*
  149. ================
  150. idWindow::Allocated
  151. ================
  152. */
  153. size_t idWindow::Allocated() {
  154. int i, c;
  155. int sz = name.Allocated();
  156. sz += text.Size();
  157. sz += backGroundName.Size();
  158. c = definedVars.Num();
  159. for (i = 0; i < c; i++) {
  160. sz += definedVars[i]->Size();
  161. }
  162. for (i = 0; i < SCRIPT_COUNT; i++) {
  163. if (scripts[i]) {
  164. sz += scripts[i]->Size();
  165. }
  166. }
  167. c = timeLineEvents.Num();
  168. for (i = 0; i < c; i++) {
  169. sz += timeLineEvents[i]->Size();
  170. }
  171. c = namedEvents.Num();
  172. for (i = 0; i < c; i++) {
  173. sz += namedEvents[i]->Size();
  174. }
  175. c = drawWindows.Num();
  176. for (i = 0; i < c; i++) {
  177. if (drawWindows[i].simp) {
  178. sz += drawWindows[i].simp->Size();
  179. }
  180. }
  181. return sz;
  182. }
  183. /*
  184. ================
  185. idWindow::idWindow
  186. ================
  187. */
  188. idWindow::idWindow(idUserInterfaceLocal *ui) {
  189. gui = ui;
  190. CommonInit();
  191. }
  192. /*
  193. ================
  194. idWindow::CleanUp
  195. ================
  196. */
  197. void idWindow::CleanUp() {
  198. int i, c = drawWindows.Num();
  199. for (i = 0; i < c; i++) {
  200. delete drawWindows[i].simp;
  201. }
  202. // ensure the register list gets cleaned up
  203. regList.Reset ( );
  204. // Cleanup the named events
  205. namedEvents.DeleteContents(true);
  206. drawWindows.Clear();
  207. children.DeleteContents(true);
  208. definedVars.DeleteContents(true);
  209. timeLineEvents.DeleteContents(true);
  210. for (i = 0; i < SCRIPT_COUNT; i++) {
  211. delete scripts[i];
  212. }
  213. CommonInit();
  214. }
  215. /*
  216. ================
  217. idWindow::~idWindow
  218. ================
  219. */
  220. idWindow::~idWindow() {
  221. CleanUp();
  222. }
  223. /*
  224. ================
  225. idWindow::Move
  226. ================
  227. */
  228. void idWindow::Move(float x, float y) {
  229. idRectangle rct = rect;
  230. rct.x = x;
  231. rct.y = y;
  232. idRegister *reg = RegList()->FindReg("rect");
  233. if (reg) {
  234. reg->Enable(false);
  235. }
  236. rect = rct;
  237. }
  238. /*
  239. ================
  240. idWindow::SetFont
  241. ================
  242. */
  243. void idWindow::SetFont() {
  244. dc->SetFont( font );
  245. }
  246. /*
  247. ================
  248. idWindow::GetMaxCharHeight
  249. ================
  250. */
  251. float idWindow::GetMaxCharHeight() {
  252. SetFont();
  253. return dc->MaxCharHeight(textScale);
  254. }
  255. /*
  256. ================
  257. idWindow::GetMaxCharWidth
  258. ================
  259. */
  260. float idWindow::GetMaxCharWidth() {
  261. SetFont();
  262. return dc->MaxCharWidth(textScale);
  263. }
  264. /*
  265. ================
  266. idWindow::Draw
  267. ================
  268. */
  269. void idWindow::Draw( int time, float x, float y ) {
  270. if ( text.Length() == 0 ) {
  271. return;
  272. }
  273. if ( textShadow ) {
  274. idStr shadowText = text;
  275. idRectangle shadowRect = textRect;
  276. shadowText.RemoveColors();
  277. shadowRect.x += textShadow;
  278. shadowRect.y += textShadow;
  279. dc->DrawText( shadowText, textScale, textAlign, colorBlack, shadowRect, !( flags & WIN_NOWRAP ), -1 );
  280. }
  281. dc->DrawText( text, textScale, textAlign, foreColor, textRect, !( flags & WIN_NOWRAP ), -1 );
  282. if ( gui_edit.GetBool() ) {
  283. dc->EnableClipping( false );
  284. dc->DrawText( va( "x: %i y: %i", ( int )rect.x(), ( int )rect.y() ), 0.25, 0, dc->colorWhite, idRectangle( rect.x(), rect.y() - 15, 100, 20 ), false );
  285. dc->DrawText( va( "w: %i h: %i", ( int )rect.w(), ( int )rect.h() ), 0.25, 0, dc->colorWhite, idRectangle( rect.x() + rect.w(), rect.w() + rect.h() + 5, 100, 20 ), false );
  286. dc->EnableClipping( true );
  287. }
  288. }
  289. /*
  290. ================
  291. idWindow::BringToTop
  292. ================
  293. */
  294. void idWindow::BringToTop(idWindow *w) {
  295. if (w && !(w->flags & WIN_MODAL)) {
  296. return;
  297. }
  298. int c = children.Num();
  299. for (int i = 0; i < c; i++) {
  300. if (children[i] == w) {
  301. // this is it move from i - 1 to 0 to i to 1 then shove this one into 0
  302. for (int j = i+1; j < c; j++) {
  303. children[j-1] = children[j];
  304. }
  305. children[c-1] = w;
  306. break;
  307. }
  308. }
  309. }
  310. /*
  311. ================
  312. idWindow::Size
  313. ================
  314. */
  315. void idWindow::Size(float x, float y, float w, float h) {
  316. idRectangle rct = rect;
  317. rct.x = x;
  318. rct.y = y;
  319. rct.w = w;
  320. rct.h = h;
  321. rect = rct;
  322. CalcClientRect(0,0);
  323. }
  324. /*
  325. ================
  326. idWindow::MouseEnter
  327. ================
  328. */
  329. void idWindow::MouseEnter() {
  330. if (noEvents) {
  331. return;
  332. }
  333. RunScript(ON_MOUSEENTER);
  334. }
  335. /*
  336. ================
  337. idWindow::MouseExit
  338. ================
  339. */
  340. void idWindow::MouseExit() {
  341. if (noEvents) {
  342. return;
  343. }
  344. RunScript(ON_MOUSEEXIT);
  345. }
  346. /*
  347. ================
  348. idWindow::GetChildWithOnAction
  349. ================
  350. */
  351. idWindow * idWindow::GetChildWithOnAction( float xd, float yd ) {
  352. int c = children.Num();
  353. while ( c > 0 ) {
  354. idWindow *child = children[--c];
  355. if ( child->visible && child->Contains(child->drawRect, gui->CursorX(), gui->CursorY() ) && !child->noEvents ) {
  356. child->hover = true;
  357. if ( child->cursor > 0 ) {
  358. return child;
  359. }
  360. }
  361. idWindow * check = child->GetChildWithOnAction( xd, yd );
  362. if ( check != NULL && check != child ) {
  363. return check;
  364. }
  365. }
  366. return this;
  367. }
  368. /*
  369. ================
  370. idWindow::RouteMouseCoords
  371. ================
  372. */
  373. const char *idWindow::RouteMouseCoords(float xd, float yd) {
  374. idStr str;
  375. if (GetCaptureChild()) {
  376. //FIXME: unkludge this whole mechanism
  377. return GetCaptureChild()->RouteMouseCoords(xd, yd);
  378. }
  379. if (xd == -2000 || yd == -2000) {
  380. return "";
  381. }
  382. idWindow * child = GetChildWithOnAction( xd, yd );
  383. if ( overChild != child ) {
  384. if ( overChild ) {
  385. overChild->MouseExit();
  386. str = overChild->cmd;
  387. if (str.Length()) {
  388. gui->GetDesktop()->AddCommand(str);
  389. overChild->cmd = "";
  390. }
  391. }
  392. overChild = child;
  393. if ( overChild ) {
  394. overChild->MouseEnter();
  395. str = overChild->cmd;
  396. if (str.Length()) {
  397. gui->GetDesktop()->AddCommand(str);
  398. overChild->cmd = "";
  399. }
  400. dc->SetCursor( overChild->cursor );
  401. }
  402. }
  403. return "";
  404. }
  405. /*
  406. ================
  407. idWindow::Activate
  408. ================
  409. */
  410. void idWindow::Activate( bool activate, idStr &act ) {
  411. int n = (activate) ? ON_ACTIVATE : ON_DEACTIVATE;
  412. // make sure win vars are updated before activation
  413. UpdateWinVars ( );
  414. RunScript(n);
  415. int c = children.Num();
  416. for (int i = 0; i < c; i++) {
  417. children[i]->Activate( activate, act );
  418. }
  419. if ( act.Length() ) {
  420. act += " ; ";
  421. }
  422. }
  423. /*
  424. ================
  425. idWindow::Trigger
  426. ================
  427. */
  428. void idWindow::Trigger() {
  429. RunScript( ON_TRIGGER );
  430. int c = children.Num();
  431. for ( int i = 0; i < c; i++ ) {
  432. children[i]->Trigger();
  433. }
  434. StateChanged( true );
  435. }
  436. /*
  437. ================
  438. idWindow::StateChanged
  439. ================
  440. */
  441. void idWindow::StateChanged( bool redraw ) {
  442. UpdateWinVars();
  443. if (expressionRegisters.Num() && ops.Num()) {
  444. EvalRegs();
  445. }
  446. int c = drawWindows.Num();
  447. for ( int i = 0; i < c; i++ ) {
  448. if ( drawWindows[i].win ) {
  449. drawWindows[i].win->StateChanged( redraw );
  450. } else {
  451. drawWindows[i].simp->StateChanged( redraw );
  452. }
  453. }
  454. }
  455. /*
  456. ================
  457. idWindow::SetCapture
  458. ================
  459. */
  460. idWindow *idWindow::SetCapture(idWindow *w) {
  461. // only one child can have the focus
  462. idWindow *last = NULL;
  463. int c = children.Num();
  464. for (int i = 0; i < c; i++) {
  465. if ( children[i]->flags & WIN_CAPTURE ) {
  466. last = children[i];
  467. //last->flags &= ~WIN_CAPTURE;
  468. last->LoseCapture();
  469. break;
  470. }
  471. }
  472. w->flags |= WIN_CAPTURE;
  473. w->GainCapture();
  474. gui->GetDesktop()->captureChild = w;
  475. return last;
  476. }
  477. /*
  478. ================
  479. idWindow::AddUpdateVar
  480. ================
  481. */
  482. void idWindow::AddUpdateVar(idWinVar *var) {
  483. updateVars.AddUnique(var);
  484. }
  485. /*
  486. ================
  487. idWindow::UpdateWinVars
  488. ================
  489. */
  490. void idWindow::UpdateWinVars() {
  491. int c = updateVars.Num();
  492. for (int i = 0; i < c; i++) {
  493. updateVars[i]->Update();
  494. }
  495. }
  496. /*
  497. ================
  498. idWindow::RunTimeEvents
  499. ================
  500. */
  501. bool idWindow::RunTimeEvents(int time) {
  502. if ( time == lastTimeRun ) {
  503. return false;
  504. }
  505. lastTimeRun = time;
  506. UpdateWinVars();
  507. if (expressionRegisters.Num() && ops.Num()) {
  508. EvalRegs();
  509. }
  510. if ( flags & WIN_INTRANSITION ) {
  511. Transition();
  512. }
  513. Time();
  514. // renamed ON_EVENT to ON_FRAME
  515. RunScript(ON_FRAME);
  516. int c = children.Num();
  517. for (int i = 0; i < c; i++) {
  518. children[i]->RunTimeEvents(time);
  519. }
  520. return true;
  521. }
  522. /*
  523. ================
  524. idWindow::RunNamedEvent
  525. ================
  526. */
  527. void idWindow::RunNamedEvent ( const char* eventName )
  528. {
  529. int i;
  530. int c;
  531. // Find and run the event
  532. c = namedEvents.Num( );
  533. for ( i = 0; i < c; i ++ ) {
  534. if ( namedEvents[i]->mName.Icmp( eventName ) ) {
  535. continue;
  536. }
  537. UpdateWinVars();
  538. // Make sure we got all the current values for stuff
  539. if (expressionRegisters.Num() && ops.Num()) {
  540. EvalRegs(-1, true);
  541. }
  542. RunScriptList( namedEvents[i]->mEvent );
  543. break;
  544. }
  545. // Run the event in all the children as well
  546. c = children.Num();
  547. for ( i = 0; i < c; i++ ) {
  548. children[i]->RunNamedEvent ( eventName );
  549. }
  550. }
  551. /*
  552. ================
  553. idWindow::Contains
  554. ================
  555. */
  556. bool idWindow::Contains(const idRectangle &sr, float x, float y) {
  557. idRectangle r = sr;
  558. r.x += actualX - drawRect.x;
  559. r.y += actualY - drawRect.y;
  560. return r.Contains(x, y);
  561. }
  562. /*
  563. ================
  564. idWindow::Contains
  565. ================
  566. */
  567. bool idWindow::Contains(float x, float y) {
  568. idRectangle r = drawRect;
  569. r.x = actualX;
  570. r.y = actualY;
  571. return r.Contains(x, y);
  572. }
  573. /*
  574. ================
  575. idWindow::AddCommand
  576. ================
  577. */
  578. void idWindow::AddCommand(const char *_cmd) {
  579. idStr str = cmd;
  580. if (str.Length()) {
  581. str += " ; ";
  582. str += _cmd;
  583. } else {
  584. str = _cmd;
  585. }
  586. cmd = str;
  587. }
  588. /*
  589. ================
  590. idWindow::HandleEvent
  591. ================
  592. */
  593. const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) {
  594. static bool actionDownRun;
  595. static bool actionUpRun;
  596. cmd = "";
  597. if ( flags & WIN_DESKTOP ) {
  598. actionDownRun = false;
  599. actionUpRun = false;
  600. if (expressionRegisters.Num() && ops.Num()) {
  601. EvalRegs();
  602. }
  603. RunTimeEvents(gui->GetTime());
  604. CalcRects(0,0);
  605. if ( overChild != NULL ) {
  606. dc->SetCursor( overChild->cursor );
  607. } else {
  608. dc->SetCursor( idDeviceContext::CURSOR_ARROW );
  609. }
  610. }
  611. if (visible && !noEvents) {
  612. if (event->evType == SE_KEY) {
  613. EvalRegs(-1, true);
  614. if (updateVisuals) {
  615. *updateVisuals = true;
  616. }
  617. if (event->evValue == K_MOUSE1) {
  618. if (!event->evValue2 && GetCaptureChild()) {
  619. GetCaptureChild()->LoseCapture();
  620. gui->GetDesktop()->captureChild = NULL;
  621. return "";
  622. }
  623. int c = children.Num();
  624. while (--c >= 0) {
  625. if (children[c]->visible && children[c]->Contains(children[c]->drawRect, gui->CursorX(), gui->CursorY()) && !(children[c]->noEvents)) {
  626. idWindow *child = children[c];
  627. if (event->evValue2) {
  628. BringToTop(child);
  629. SetFocus(child);
  630. if (child->flags & WIN_HOLDCAPTURE) {
  631. SetCapture(child);
  632. }
  633. }
  634. if (child->Contains(child->clientRect, gui->CursorX(), gui->CursorY())) {
  635. //if ((gui_edit.GetBool() && (child->flags & WIN_SELECTED)) || (!gui_edit.GetBool() && (child->flags & WIN_MOVABLE))) {
  636. // SetCapture(child);
  637. //}
  638. SetFocus(child);
  639. const char *childRet = child->HandleEvent(event, updateVisuals);
  640. if (childRet != NULL && *childRet != NULL) {
  641. return childRet;
  642. }
  643. if (child->flags & WIN_MODAL) {
  644. return "";
  645. }
  646. } else {
  647. if (event->evValue2) {
  648. SetFocus(child);
  649. bool capture = true;
  650. if (capture && ((child->flags & WIN_MOVABLE) || gui_edit.GetBool())) {
  651. SetCapture(child);
  652. }
  653. return "";
  654. } else {
  655. }
  656. }
  657. }
  658. }
  659. if (event->evValue2 && !actionDownRun) {
  660. actionDownRun = RunScript( ON_ACTION );
  661. } else if (!actionUpRun) {
  662. actionUpRun = RunScript( ON_ACTIONRELEASE );
  663. }
  664. } else if (event->evValue == K_MOUSE2) {
  665. if (!event->evValue2 && GetCaptureChild()) {
  666. GetCaptureChild()->LoseCapture();
  667. gui->GetDesktop()->captureChild = NULL;
  668. return "";
  669. }
  670. int c = children.Num();
  671. while (--c >= 0) {
  672. if (children[c]->visible && children[c]->Contains(children[c]->drawRect, gui->CursorX(), gui->CursorY()) && !(children[c]->noEvents)) {
  673. idWindow *child = children[c];
  674. if (event->evValue2) {
  675. BringToTop(child);
  676. SetFocus(child);
  677. }
  678. if (child->Contains(child->clientRect,gui->CursorX(), gui->CursorY()) || GetCaptureChild() == child) {
  679. if ((gui_edit.GetBool() && (child->flags & WIN_SELECTED)) || (!gui_edit.GetBool() && (child->flags & WIN_MOVABLE))) {
  680. SetCapture(child);
  681. }
  682. const char *childRet = child->HandleEvent(event, updateVisuals);
  683. if (childRet && *childRet) {
  684. return childRet;
  685. }
  686. if (child->flags & WIN_MODAL) {
  687. return "";
  688. }
  689. }
  690. }
  691. }
  692. } else if (event->evValue == K_MOUSE3) {
  693. if (gui_edit.GetBool()) {
  694. int c = children.Num();
  695. for (int i = 0; i < c; i++) {
  696. if (children[i]->drawRect.Contains(gui->CursorX(), gui->CursorY())) {
  697. if (event->evValue2) {
  698. children[i]->flags ^= WIN_SELECTED;
  699. if (children[i]->flags & WIN_SELECTED) {
  700. flags &= ~WIN_SELECTED;
  701. return "childsel";
  702. }
  703. }
  704. }
  705. }
  706. }
  707. } else if (event->evValue == K_TAB && event->evValue2) {
  708. if (GetFocusedChild()) {
  709. const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals);
  710. if (childRet && *childRet) {
  711. return childRet;
  712. }
  713. // If the window didn't handle the tab, then move the focus to the next window
  714. // or the previous window if shift is held down
  715. int direction = 1;
  716. if ( idKeyInput::IsDown( K_LSHIFT ) || idKeyInput::IsDown( K_RSHIFT ) ) {
  717. direction = -1;
  718. }
  719. idWindow *currentFocus = GetFocusedChild();
  720. idWindow *child = GetFocusedChild();
  721. idWindow *parent = child->GetParent();
  722. while ( parent ) {
  723. bool foundFocus = false;
  724. bool recurse = false;
  725. int index = 0;
  726. if ( child ) {
  727. index = parent->GetChildIndex( child ) + direction;
  728. } else if ( direction < 0 ) {
  729. index = parent->GetChildCount() - 1;
  730. }
  731. while ( index < parent->GetChildCount() && index >= 0) {
  732. idWindow *testWindow = parent->GetChild( index );
  733. if ( testWindow == currentFocus ) {
  734. // we managed to wrap around and get back to our starting window
  735. foundFocus = true;
  736. break;
  737. }
  738. if ( testWindow && !testWindow->noEvents && testWindow->visible ) {
  739. if ( testWindow->flags & WIN_CANFOCUS ) {
  740. SetFocus( testWindow );
  741. foundFocus = true;
  742. break;
  743. } else if ( testWindow->GetChildCount() > 0 ) {
  744. parent = testWindow;
  745. child = NULL;
  746. recurse = true;
  747. break;
  748. }
  749. }
  750. index += direction;
  751. }
  752. if ( foundFocus ) {
  753. // We found a child to focus on
  754. break;
  755. } else if ( recurse ) {
  756. // We found a child with children
  757. continue;
  758. } else {
  759. // We didn't find anything, so go back up to our parent
  760. child = parent;
  761. parent = child->GetParent();
  762. if ( parent == gui->GetDesktop() ) {
  763. // We got back to the desktop, so wrap around but don't actually go to the desktop
  764. parent = NULL;
  765. child = NULL;
  766. }
  767. }
  768. }
  769. }
  770. } else if ( ( event->evValue == K_ESCAPE || event->evValue == K_JOY9 ) && event->evValue2) {
  771. if (GetFocusedChild()) {
  772. const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals);
  773. if (childRet && *childRet) {
  774. return childRet;
  775. }
  776. }
  777. RunScript( ON_ESC );
  778. } else if (event->evValue == K_ENTER ) {
  779. if (GetFocusedChild()) {
  780. const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals);
  781. if (childRet && *childRet) {
  782. return childRet;
  783. }
  784. }
  785. if ( flags & WIN_WANTENTER ) {
  786. if ( event->evValue2 ) {
  787. RunScript( ON_ACTION );
  788. } else {
  789. RunScript( ON_ACTIONRELEASE );
  790. }
  791. }
  792. } else {
  793. if (GetFocusedChild()) {
  794. const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals);
  795. if (childRet && *childRet) {
  796. return childRet;
  797. }
  798. }
  799. }
  800. } else if (event->evType == SE_MOUSE) {
  801. if (updateVisuals) {
  802. *updateVisuals = true;
  803. }
  804. const char *mouseRet = RouteMouseCoords(event->evValue, event->evValue2);
  805. if (mouseRet != NULL && *mouseRet != NULL) {
  806. return mouseRet;
  807. }
  808. } else if (event->evType == SE_NONE) {
  809. } else if (event->evType == SE_CHAR) {
  810. if (GetFocusedChild()) {
  811. const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals);
  812. if (childRet && *childRet) {
  813. return childRet;
  814. }
  815. }
  816. }
  817. }
  818. gui->GetReturnCmd() = cmd;
  819. if ( gui->GetPendingCmd().Length() ) {
  820. gui->GetReturnCmd() += " ; ";
  821. gui->GetReturnCmd() += gui->GetPendingCmd();
  822. gui->GetPendingCmd().Clear();
  823. }
  824. cmd = "";
  825. return gui->GetReturnCmd();
  826. }
  827. /*
  828. ================
  829. idWindow::DebugDraw
  830. ================
  831. */
  832. void idWindow::DebugDraw(int time, float x, float y) {
  833. static char buff[16384] = { 0 };
  834. if (dc) {
  835. dc->EnableClipping(false);
  836. if (gui_debug.GetInteger() == 1) {
  837. dc->DrawRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, 1, idDeviceContext::colorRed);
  838. } else if (gui_debug.GetInteger() == 2) {
  839. char out[1024];
  840. idStr str;
  841. str = text.c_str();
  842. if (str.Length()) {
  843. sprintf(buff, "%s\n", str.c_str());
  844. }
  845. sprintf(out, "Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", rect.x(), rect.y(), rect.w(), rect.h());
  846. strcat(buff, out);
  847. sprintf(out, "Draw Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", drawRect.x, drawRect.y, drawRect.w, drawRect.h);
  848. strcat(buff, out);
  849. sprintf(out, "Client Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", clientRect.x, clientRect.y, clientRect.w, clientRect.h);
  850. strcat(buff, out);
  851. sprintf(out, "Cursor: %0.1f : %0.1f\n", gui->CursorX(), gui->CursorY());
  852. strcat(buff, out);
  853. //idRectangle tempRect = textRect;
  854. //tempRect.x += offsetX;
  855. //drawRect.y += offsetY;
  856. dc->DrawText(buff, textScale, textAlign, foreColor, textRect, true);
  857. }
  858. dc->EnableClipping(true);
  859. }
  860. }
  861. /*
  862. ================
  863. idWindow::Transition
  864. ================
  865. */
  866. void idWindow::Transition() {
  867. int i, c = transitions.Num();
  868. bool clear = true;
  869. for ( i = 0; i < c; i++ ) {
  870. idTransitionData *data = &transitions[i];
  871. idWinRectangle *r = NULL;
  872. idWinVec4 *v4 = dynamic_cast<idWinVec4*>(data->data);
  873. idWinFloat* val = NULL;
  874. if (v4 == NULL) {
  875. r = dynamic_cast<idWinRectangle*>(data->data);
  876. if ( r == NULL ) {
  877. val = dynamic_cast<idWinFloat*>(data->data);
  878. }
  879. }
  880. if ( data->interp.IsDone( gui->GetTime() ) && data->data) {
  881. if (v4) {
  882. *v4 = data->interp.GetEndValue();
  883. } else if ( val ) {
  884. *val = data->interp.GetEndValue()[0];
  885. } else if ( r != NULL ) {
  886. *r = data->interp.GetEndValue();
  887. }
  888. } else {
  889. clear = false;
  890. if (data->data) {
  891. if (v4) {
  892. *v4 = data->interp.GetCurrentValue( gui->GetTime() );
  893. } else if ( val ) {
  894. *val = data->interp.GetCurrentValue( gui->GetTime() )[0];
  895. } else if ( r != NULL ) {
  896. *r = data->interp.GetCurrentValue( gui->GetTime() );
  897. }
  898. } else {
  899. common->Warning("Invalid transitional data for window %s in gui %s", GetName(), gui->GetSourceFile());
  900. }
  901. }
  902. }
  903. if ( clear ) {
  904. transitions.SetNum( 0 );
  905. flags &= ~WIN_INTRANSITION;
  906. }
  907. }
  908. /*
  909. ================
  910. idWindow::Time
  911. ================
  912. */
  913. void idWindow::Time() {
  914. if ( noTime ) {
  915. return;
  916. }
  917. if ( timeLine == -1 ) {
  918. timeLine = gui->GetTime();
  919. }
  920. cmd = "";
  921. int c = timeLineEvents.Num();
  922. if ( c > 0 ) {
  923. for (int i = 0; i < c; i++) {
  924. if ( timeLineEvents[i]->pending && gui->GetTime() - timeLine >= timeLineEvents[i]->time ) {
  925. timeLineEvents[i]->pending = false;
  926. RunScriptList( timeLineEvents[i]->event );
  927. }
  928. }
  929. }
  930. if ( gui->Active() ) {
  931. if ( gui->GetPendingCmd().Length() > 0 ) {
  932. gui->GetPendingCmd() += ";";
  933. }
  934. gui->GetPendingCmd() += cmd;
  935. }
  936. }
  937. /*
  938. ================
  939. idWindow::EvalRegs
  940. ================
  941. */
  942. float idWindow::EvalRegs(int test, bool force) {
  943. static float regs[MAX_EXPRESSION_REGISTERS];
  944. static idWindow *lastEval = NULL;
  945. if (!force && test >= 0 && test < MAX_EXPRESSION_REGISTERS && lastEval == this) {
  946. return regs[test];
  947. }
  948. lastEval = this;
  949. if (expressionRegisters.Num()) {
  950. regList.SetToRegs(regs);
  951. EvaluateRegisters(regs);
  952. regList.GetFromRegs(regs);
  953. }
  954. if (test >= 0 && test < MAX_EXPRESSION_REGISTERS) {
  955. return regs[test];
  956. }
  957. return 0.0;
  958. }
  959. /*
  960. ================
  961. idWindow::DrawBackground
  962. ================
  963. */
  964. void idWindow::DrawBackground(const idRectangle &drawRect) {
  965. if ( backColor.w() ) {
  966. dc->DrawFilledRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, backColor);
  967. }
  968. if ( background && matColor.w() ) {
  969. float scalex, scaley;
  970. if ( flags & WIN_NATURALMAT ) {
  971. scalex = drawRect.w / background->GetImageWidth();
  972. scaley = drawRect.h / background->GetImageHeight();
  973. } else {
  974. scalex = matScalex;
  975. scaley = matScaley;
  976. }
  977. dc->DrawMaterial(drawRect.x, drawRect.y, drawRect.w, drawRect.h, background, matColor, scalex, scaley);
  978. }
  979. }
  980. /*
  981. ================
  982. idWindow::DrawBorderAndCaption
  983. ================
  984. */
  985. void idWindow::DrawBorderAndCaption(const idRectangle &drawRect) {
  986. if ( flags & WIN_BORDER && borderSize && borderColor.w() ) {
  987. dc->DrawRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, borderSize, borderColor);
  988. }
  989. }
  990. /*
  991. ================
  992. idWindow::SetupTransforms
  993. ================
  994. */
  995. void idWindow::SetupTransforms(float x, float y) {
  996. static idMat3 trans;
  997. static idVec3 org;
  998. trans.Identity();
  999. org.Set( origin.x + x, origin.y + y, 0 );
  1000. if ( rotate ) {
  1001. static idRotation rot;
  1002. static idVec3 vec(0, 0, 1);
  1003. rot.Set( org, vec, rotate );
  1004. trans = rot.ToMat3();
  1005. }
  1006. if ( shear.x || shear.y ) {
  1007. static idMat3 smat;
  1008. smat.Identity();
  1009. smat[0][1] = shear.x;
  1010. smat[1][0] = shear.y;
  1011. trans *= smat;
  1012. }
  1013. if ( !trans.IsIdentity() ) {
  1014. dc->SetTransformInfo( org, trans );
  1015. }
  1016. }
  1017. /*
  1018. ================
  1019. idWindow::CalcRects
  1020. ================
  1021. */
  1022. void idWindow::CalcRects(float x, float y) {
  1023. CalcClientRect(0, 0);
  1024. drawRect.Offset(x, y);
  1025. clientRect.Offset(x, y);
  1026. actualX = drawRect.x;
  1027. actualY = drawRect.y;
  1028. int c = drawWindows.Num();
  1029. for (int i = 0; i < c; i++) {
  1030. if (drawWindows[i].win) {
  1031. drawWindows[i].win->CalcRects(clientRect.x + xOffset, clientRect.y + yOffset);
  1032. }
  1033. }
  1034. drawRect.Offset(-x, -y);
  1035. clientRect.Offset(-x, -y);
  1036. }
  1037. /*
  1038. ================
  1039. idWindow::Redraw
  1040. ================
  1041. */
  1042. void idWindow::Redraw(float x, float y, bool hud) {
  1043. idStr str;
  1044. if (r_skipGuiShaders.GetInteger() == 1 || dc == NULL ) {
  1045. return;
  1046. }
  1047. int time = gui->GetTime();
  1048. if ( flags & WIN_DESKTOP && r_skipGuiShaders.GetInteger() != 3 ) {
  1049. RunTimeEvents( time );
  1050. }
  1051. if ( r_skipGuiShaders.GetInteger() == 2 ) {
  1052. return;
  1053. }
  1054. if ( flags & WIN_SHOWTIME ) {
  1055. dc->DrawText(va(" %0.1f seconds\n%s", (float)(time - timeLine) / 1000, gui->State().GetString("name")), 0.35f, 0, dc->colorWhite, idRectangle(100, 0, 80, 80), false);
  1056. }
  1057. if ( flags & WIN_SHOWCOORDS ) {
  1058. dc->EnableClipping(false);
  1059. sprintf(str, "x: %i y: %i cursorx: %i cursory: %i", (int)rect.x(), (int)rect.y(), (int)gui->CursorX(), (int)gui->CursorY());
  1060. dc->DrawText(str, 0.25f, 0, dc->colorWhite, idRectangle(0, 0, 100, 20), false);
  1061. dc->EnableClipping(true);
  1062. }
  1063. if (!visible) {
  1064. return;
  1065. }
  1066. CalcClientRect(0, 0);
  1067. SetFont();
  1068. if ( hud ) {
  1069. float tileSafeOffset = hud_titlesafe.GetFloat();
  1070. float tileSafeScale = 1.0f / ( 1.0f - hud_titlesafe.GetFloat() * 2.0f );
  1071. dc->SetSize( forceAspectWidth * tileSafeScale, forceAspectHeight * tileSafeScale );
  1072. dc->SetOffset( forceAspectWidth * tileSafeOffset, forceAspectHeight * tileSafeOffset );
  1073. } else {
  1074. dc->SetSize( forceAspectWidth, forceAspectHeight );
  1075. dc->SetOffset( 0.0f, 0.0f );
  1076. }
  1077. //FIXME: go to screen coord tracking
  1078. drawRect.Offset(x, y);
  1079. clientRect.Offset(x, y);
  1080. textRect.Offset(x, y);
  1081. actualX = drawRect.x;
  1082. actualY = drawRect.y;
  1083. idVec3 oldOrg;
  1084. idMat3 oldTrans;
  1085. dc->GetTransformInfo( oldOrg, oldTrans );
  1086. SetupTransforms(x, y);
  1087. DrawBackground(drawRect);
  1088. DrawBorderAndCaption(drawRect);
  1089. if ( !( flags & WIN_NOCLIP) ) {
  1090. dc->PushClipRect(clientRect);
  1091. }
  1092. if ( r_skipGuiShaders.GetInteger() < 5 ) {
  1093. Draw(time, x, y);
  1094. }
  1095. if ( gui_debug.GetInteger() ) {
  1096. DebugDraw(time, x, y);
  1097. }
  1098. int c = drawWindows.Num();
  1099. for ( int i = 0; i < c; i++ ) {
  1100. if ( drawWindows[i].win ) {
  1101. drawWindows[i].win->Redraw( clientRect.x + xOffset, clientRect.y + yOffset, hud );
  1102. } else {
  1103. drawWindows[i].simp->Redraw( clientRect.x + xOffset, clientRect.y + yOffset );
  1104. }
  1105. }
  1106. // Put transforms back to what they were before the children were processed
  1107. dc->SetTransformInfo(oldOrg, oldTrans);
  1108. if ( ! ( flags & WIN_NOCLIP ) ) {
  1109. dc->PopClipRect();
  1110. }
  1111. if (gui_edit.GetBool() || (flags & WIN_DESKTOP && !( flags & WIN_NOCURSOR ) && !hideCursor && (gui->Active() || ( flags & WIN_MENUGUI ) ))) {
  1112. dc->SetTransformInfo(vec3_origin, mat3_identity);
  1113. gui->DrawCursor();
  1114. }
  1115. if (gui_debug.GetInteger() && flags & WIN_DESKTOP) {
  1116. dc->EnableClipping(false);
  1117. sprintf(str, "x: %1.f y: %1.f", gui->CursorX(), gui->CursorY());
  1118. dc->DrawText(str, 0.25, 0, dc->colorWhite, idRectangle(0, 0, 100, 20), false);
  1119. dc->DrawText(gui->GetSourceFile(), 0.25, 0, dc->colorWhite, idRectangle(0, 20, 300, 20), false);
  1120. dc->EnableClipping(true);
  1121. }
  1122. drawRect.Offset(-x, -y);
  1123. clientRect.Offset(-x, -y);
  1124. textRect.Offset(-x, -y);
  1125. }
  1126. /*
  1127. ================
  1128. idWindow::ArchiveToDictionary
  1129. ================
  1130. */
  1131. void idWindow::ArchiveToDictionary(idDict *dict, bool useNames) {
  1132. //FIXME: rewrite without state
  1133. int c = children.Num();
  1134. for (int i = 0; i < c; i++) {
  1135. children[i]->ArchiveToDictionary(dict);
  1136. }
  1137. }
  1138. /*
  1139. ================
  1140. idWindow::InitFromDictionary
  1141. ================
  1142. */
  1143. void idWindow::InitFromDictionary(idDict *dict, bool byName) {
  1144. //FIXME: rewrite without state
  1145. int c = children.Num();
  1146. for (int i = 0; i < c; i++) {
  1147. children[i]->InitFromDictionary(dict);
  1148. }
  1149. }
  1150. /*
  1151. ================
  1152. idWindow::CalcClientRect
  1153. ================
  1154. */
  1155. void idWindow::CalcClientRect(float xofs, float yofs) {
  1156. drawRect = rect;
  1157. if ( flags & WIN_INVERTRECT ) {
  1158. drawRect.x = rect.x() - rect.w();
  1159. drawRect.y = rect.y() - rect.h();
  1160. }
  1161. if (flags & (WIN_HCENTER | WIN_VCENTER) && parent) {
  1162. // in this case treat xofs and yofs as absolute top left coords
  1163. // and ignore the original positioning
  1164. if (flags & WIN_HCENTER) {
  1165. drawRect.x = (parent->rect.w() - rect.w()) / 2;
  1166. } else {
  1167. drawRect.y = (parent->rect.h() - rect.h()) / 2;
  1168. }
  1169. }
  1170. drawRect.x += xofs;
  1171. drawRect.y += yofs;
  1172. clientRect = drawRect;
  1173. if (rect.h() > 0.0 && rect.w() > 0.0) {
  1174. if (flags & WIN_BORDER && borderSize != 0.0) {
  1175. clientRect.x += borderSize;
  1176. clientRect.y += borderSize;
  1177. clientRect.w -= borderSize;
  1178. clientRect.h -= borderSize;
  1179. }
  1180. textRect = clientRect;
  1181. textRect.x += 2.0;
  1182. textRect.w -= 2.0;
  1183. textRect.y += 2.0;
  1184. textRect.h -= 2.0;
  1185. textRect.x += textAlignx;
  1186. textRect.y += textAligny;
  1187. }
  1188. origin.Set( rect.x() + (rect.w() / 2 ), rect.y() + ( rect.h() / 2 ) );
  1189. }
  1190. /*
  1191. ================
  1192. idWindow::SetupBackground
  1193. ================
  1194. */
  1195. void idWindow::SetupBackground() {
  1196. if (backGroundName.Length()) {
  1197. background = declManager->FindMaterial(backGroundName);
  1198. if ( background != NULL && !background->TestMaterialFlag( MF_DEFAULTED ) ) {
  1199. background->SetSort(SS_GUI );
  1200. }
  1201. }
  1202. backGroundName.SetMaterialPtr(&background);
  1203. }
  1204. /*
  1205. ================
  1206. idWindow::SetupFromState
  1207. ================
  1208. */
  1209. void idWindow::SetupFromState() {
  1210. idStr str;
  1211. background = NULL;
  1212. SetupBackground();
  1213. if (borderSize) {
  1214. flags |= WIN_BORDER;
  1215. }
  1216. if (regList.FindReg("rotate") || regList.FindReg("shear")) {
  1217. flags |= WIN_TRANSFORM;
  1218. }
  1219. CalcClientRect(0,0);
  1220. if ( scripts[ ON_ACTION ] ) {
  1221. cursor = idDeviceContext::CURSOR_HAND;
  1222. flags |= WIN_CANFOCUS;
  1223. }
  1224. }
  1225. /*
  1226. ================
  1227. idWindow::Moved
  1228. ================
  1229. */
  1230. void idWindow::Moved() {
  1231. }
  1232. /*
  1233. ================
  1234. idWindow::Sized
  1235. ================
  1236. */
  1237. void idWindow::Sized() {
  1238. }
  1239. /*
  1240. ================
  1241. idWindow::GainFocus
  1242. ================
  1243. */
  1244. void idWindow::GainFocus() {
  1245. }
  1246. /*
  1247. ================
  1248. idWindow::LoseFocus
  1249. ================
  1250. */
  1251. void idWindow::LoseFocus() {
  1252. }
  1253. /*
  1254. ================
  1255. idWindow::GainCapture
  1256. ================
  1257. */
  1258. void idWindow::GainCapture() {
  1259. }
  1260. /*
  1261. ================
  1262. idWindow::LoseCapture
  1263. ================
  1264. */
  1265. void idWindow::LoseCapture() {
  1266. flags &= ~WIN_CAPTURE;
  1267. }
  1268. /*
  1269. ================
  1270. idWindow::SetFlag
  1271. ================
  1272. */
  1273. void idWindow::SetFlag(unsigned int f) {
  1274. flags |= f;
  1275. }
  1276. /*
  1277. ================
  1278. idWindow::ClearFlag
  1279. ================
  1280. */
  1281. void idWindow::ClearFlag(unsigned int f) {
  1282. flags &= ~f;
  1283. }
  1284. /*
  1285. ================
  1286. idWindow::SetParent
  1287. ================
  1288. */
  1289. void idWindow::SetParent(idWindow *w) {
  1290. parent = w;
  1291. }
  1292. /*
  1293. ================
  1294. idWindow::GetCaptureChild
  1295. ================
  1296. */
  1297. idWindow *idWindow::GetCaptureChild() {
  1298. if (flags & WIN_DESKTOP) {
  1299. return gui->GetDesktop()->captureChild;
  1300. }
  1301. return NULL;
  1302. }
  1303. /*
  1304. ================
  1305. idWindow::GetFocusedChild
  1306. ================
  1307. */
  1308. idWindow *idWindow::GetFocusedChild() {
  1309. if (flags & WIN_DESKTOP) {
  1310. return gui->GetDesktop()->focusedChild;
  1311. }
  1312. return NULL;
  1313. }
  1314. /*
  1315. ================
  1316. idWindow::SetFocus
  1317. ================
  1318. */
  1319. idWindow *idWindow::SetFocus(idWindow *w, bool scripts) {
  1320. // only one child can have the focus
  1321. idWindow *lastFocus = NULL;
  1322. if (w->flags & WIN_CANFOCUS) {
  1323. lastFocus = gui->GetDesktop()->focusedChild;
  1324. if ( lastFocus ) {
  1325. lastFocus->flags &= ~WIN_FOCUS;
  1326. lastFocus->LoseFocus();
  1327. }
  1328. // call on lose focus
  1329. if ( scripts && lastFocus ) {
  1330. // calling this broke all sorts of guis
  1331. // lastFocus->RunScript(ON_MOUSEEXIT);
  1332. }
  1333. // call on gain focus
  1334. if ( scripts && w ) {
  1335. // calling this broke all sorts of guis
  1336. // w->RunScript(ON_MOUSEENTER);
  1337. }
  1338. w->flags |= WIN_FOCUS;
  1339. w->GainFocus();
  1340. gui->GetDesktop()->focusedChild = w;
  1341. }
  1342. return lastFocus;
  1343. }
  1344. /*
  1345. ================
  1346. idWindow::ParseScript
  1347. ================
  1348. */
  1349. bool idWindow::ParseScript(idTokenParser *src, idGuiScriptList &list, int *timeParm, bool elseBlock ) {
  1350. bool ifElseBlock = false;
  1351. idToken token;
  1352. // scripts start with { ( unless parm is true ) and have ; separated command lists.. commands are command,
  1353. // arg.. basically we want everything between the { } as it will be interpreted at
  1354. // run time
  1355. if ( elseBlock ) {
  1356. src->ReadToken ( &token );
  1357. if ( !token.Icmp ( "if" ) ) {
  1358. ifElseBlock = true;
  1359. }
  1360. src->UnreadToken ( &token );
  1361. if ( !ifElseBlock && !src->ExpectTokenString( "{" ) ) {
  1362. return false;
  1363. }
  1364. }
  1365. else if ( !src->ExpectTokenString( "{" ) ) {
  1366. return false;
  1367. }
  1368. int nest = 0;
  1369. while (1) {
  1370. if ( !src->ReadToken(&token) ) {
  1371. src->Error( "Unexpected end of file" );
  1372. return false;
  1373. }
  1374. if ( token == "{" ) {
  1375. nest++;
  1376. }
  1377. if ( token == "}" ) {
  1378. if (nest-- <= 0) {
  1379. return true;
  1380. }
  1381. }
  1382. idGuiScript *gs = new (TAG_OLD_UI) idGuiScript();
  1383. if (token.Icmp("if") == 0) {
  1384. gs->conditionReg = ParseExpression(src);
  1385. gs->ifList = new (TAG_OLD_UI) idGuiScriptList();
  1386. ParseScript(src, *gs->ifList, NULL);
  1387. if (src->ReadToken(&token)) {
  1388. if (token == "else") {
  1389. gs->elseList = new (TAG_OLD_UI) idGuiScriptList();
  1390. // pass true to indicate we are parsing an else condition
  1391. ParseScript(src, *gs->elseList, NULL, true );
  1392. } else {
  1393. src->UnreadToken(&token);
  1394. }
  1395. }
  1396. list.Append(gs);
  1397. // if we are parsing an else if then return out so
  1398. // the initial "if" parser can handle the rest of the tokens
  1399. if ( ifElseBlock ) {
  1400. return true;
  1401. }
  1402. continue;
  1403. } else {
  1404. src->UnreadToken(&token);
  1405. }
  1406. // empty { } is not allowed
  1407. if ( token == "{" ) {
  1408. src->Error ( "Unexpected {" );
  1409. delete gs;
  1410. return false;
  1411. }
  1412. gs->Parse(src);
  1413. list.Append(gs);
  1414. }
  1415. }
  1416. /*
  1417. ================
  1418. idWindow::SaveExpressionParseState
  1419. ================
  1420. */
  1421. void idWindow::SaveExpressionParseState() {
  1422. saveTemps = (bool*)Mem_Alloc(MAX_EXPRESSION_REGISTERS * sizeof(bool), TAG_CRAP);
  1423. memcpy(saveTemps, registerIsTemporary, MAX_EXPRESSION_REGISTERS * sizeof(bool));
  1424. }
  1425. /*
  1426. ================
  1427. idWindow::RestoreExpressionParseState
  1428. ================
  1429. */
  1430. void idWindow::RestoreExpressionParseState() {
  1431. memcpy(registerIsTemporary, saveTemps, MAX_EXPRESSION_REGISTERS * sizeof(bool));
  1432. Mem_Free(saveTemps);
  1433. }
  1434. /*
  1435. ================
  1436. idWindow::ParseScriptEntry
  1437. ================
  1438. */
  1439. bool idWindow::ParseScriptEntry(const char *name, idTokenParser *src) {
  1440. for (int i = 0; i < SCRIPT_COUNT; i++) {
  1441. if (idStr::Icmp(name, ScriptNames[i]) == 0) {
  1442. delete scripts[i];
  1443. scripts[i] = new (TAG_OLD_UI) idGuiScriptList;
  1444. return ParseScript(src, *scripts[i]);
  1445. }
  1446. }
  1447. return false;
  1448. }
  1449. /*
  1450. ================
  1451. idWindow::DisableRegister
  1452. ================
  1453. */
  1454. void idWindow::DisableRegister(const char *_name) {
  1455. idRegister *reg = RegList()->FindReg(_name);
  1456. if (reg) {
  1457. reg->Enable(false);
  1458. }
  1459. }
  1460. /*
  1461. ================================
  1462. idSort_TimeLine
  1463. ================================
  1464. */
  1465. class idSort_TimeLine : public idSort_Quick< idTimeLineEvent *, idSort_TimeLine > {
  1466. public:
  1467. int Compare( idTimeLineEvent * const & a, idTimeLineEvent * const & b ) const {
  1468. return a->time - b->time;
  1469. }
  1470. };
  1471. /*
  1472. ================
  1473. idWindow::PostParse
  1474. ================
  1475. */
  1476. void idWindow::PostParse() {
  1477. // Sort timeline events
  1478. idSort_TimeLine sorter;
  1479. timeLineEvents.SortWithTemplate( sorter );
  1480. }
  1481. /*
  1482. ================
  1483. idWindow::GetWinVarOffset
  1484. ================
  1485. */
  1486. int idWindow::GetWinVarOffset( idWinVar *wv, drawWin_t* owner) {
  1487. int ret = -1;
  1488. if ( wv == &rect ) {
  1489. ret = (int)&( ( idWindow * ) 0 )->rect;
  1490. }
  1491. if ( wv == &backColor ) {
  1492. ret = (int)&( ( idWindow * ) 0 )->backColor;
  1493. }
  1494. if ( wv == &matColor ) {
  1495. ret = (int)&( ( idWindow * ) 0 )->matColor;
  1496. }
  1497. if ( wv == &foreColor ) {
  1498. ret = (int)&( ( idWindow * ) 0 )->foreColor;
  1499. }
  1500. if ( wv == &hoverColor ) {
  1501. ret = (int)&( ( idWindow * ) 0 )->hoverColor;
  1502. }
  1503. if ( wv == &borderColor ) {
  1504. ret = (int)&( ( idWindow * ) 0 )->borderColor;
  1505. }
  1506. if ( wv == &textScale ) {
  1507. ret = (int)&( ( idWindow * ) 0 )->textScale;
  1508. }
  1509. if ( wv == &rotate ) {
  1510. ret = (int)&( ( idWindow * ) 0 )->rotate;
  1511. }
  1512. if ( ret != -1 ) {
  1513. owner->win = this;
  1514. return ret;
  1515. }
  1516. for ( int i = 0; i < drawWindows.Num(); i++ ) {
  1517. if ( drawWindows[i].win ) {
  1518. ret = drawWindows[i].win->GetWinVarOffset( wv, owner );
  1519. } else {
  1520. ret = drawWindows[i].simp->GetWinVarOffset( wv, owner );
  1521. }
  1522. if ( ret != -1 ) {
  1523. break;
  1524. }
  1525. }
  1526. return ret;
  1527. }
  1528. /*
  1529. ================
  1530. idWindow::GetWinVarByName
  1531. ================
  1532. */
  1533. idWinVar *idWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) {
  1534. idWinVar *retVar = NULL;
  1535. if ( owner ) {
  1536. *owner = NULL;
  1537. }
  1538. if (idStr::Icmp(_name, "notime") == 0) {
  1539. retVar = &noTime;
  1540. }
  1541. if (idStr::Icmp(_name, "background") == 0) {
  1542. retVar = &backGroundName;
  1543. }
  1544. if (idStr::Icmp(_name, "visible") == 0) {
  1545. retVar = &visible;
  1546. }
  1547. if (idStr::Icmp(_name, "rect") == 0) {
  1548. retVar = &rect;
  1549. }
  1550. if (idStr::Icmp(_name, "backColor") == 0) {
  1551. retVar = &backColor;
  1552. }
  1553. if (idStr::Icmp(_name, "matColor") == 0) {
  1554. retVar = &matColor;
  1555. }
  1556. if (idStr::Icmp(_name, "foreColor") == 0) {
  1557. retVar = &foreColor;
  1558. }
  1559. if (idStr::Icmp(_name, "hoverColor") == 0) {
  1560. retVar = &hoverColor;
  1561. }
  1562. if (idStr::Icmp(_name, "borderColor") == 0) {
  1563. retVar = &borderColor;
  1564. }
  1565. if (idStr::Icmp(_name, "textScale") == 0) {
  1566. retVar = &textScale;
  1567. }
  1568. if (idStr::Icmp(_name, "rotate") == 0) {
  1569. retVar = &rotate;
  1570. }
  1571. if (idStr::Icmp(_name, "noEvents") == 0) {
  1572. retVar = &noEvents;
  1573. }
  1574. if (idStr::Icmp(_name, "text") == 0) {
  1575. retVar = &text;
  1576. }
  1577. if (idStr::Icmp(_name, "backGroundName") == 0) {
  1578. retVar = &backGroundName;
  1579. }
  1580. if (idStr::Icmp(_name, "hidecursor") == 0) {
  1581. retVar = &hideCursor;
  1582. }
  1583. idStr key = _name;
  1584. bool guiVar = (key.Find(VAR_GUIPREFIX) >= 0);
  1585. int c = definedVars.Num();
  1586. for (int i = 0; i < c; i++) {
  1587. if (idStr::Icmp(_name, (guiVar) ? va("%s",definedVars[i]->GetName()) : definedVars[i]->GetName()) == 0) {
  1588. retVar = definedVars[i];
  1589. break;
  1590. }
  1591. }
  1592. if (retVar) {
  1593. if (fixup && *_name != '$') {
  1594. DisableRegister(_name);
  1595. }
  1596. if ( owner && parent ) {
  1597. *owner = parent->FindChildByName ( name );
  1598. }
  1599. return retVar;
  1600. }
  1601. int len = key.Length();
  1602. if ( len > 5 && guiVar ) {
  1603. idWinVar *var = new (TAG_OLD_UI) idWinStr;
  1604. var->Init(_name, this);
  1605. definedVars.Append(var);
  1606. return var;
  1607. } else if (fixup) {
  1608. int n = key.Find("::");
  1609. if (n > 0) {
  1610. idStr winName = key.Left(n);
  1611. idStr var = key.Right(key.Length() - n - 2);
  1612. drawWin_t *win = GetGui()->GetDesktop()->FindChildByName(winName);
  1613. if (win) {
  1614. if (win->win) {
  1615. return win->win->GetWinVarByName(var, false, owner);
  1616. } else {
  1617. if ( owner ) {
  1618. *owner = win;
  1619. }
  1620. return win->simp->GetWinVarByName(var);
  1621. }
  1622. }
  1623. }
  1624. }
  1625. return NULL;
  1626. }
  1627. /*
  1628. ================
  1629. idWindow::ParseString
  1630. ================
  1631. */
  1632. void idWindow::ParseString(idTokenParser *src, idStr &out) {
  1633. idToken tok;
  1634. if (src->ReadToken(&tok)) {
  1635. out = tok;
  1636. }
  1637. }
  1638. /*
  1639. ================
  1640. idWindow::ParseVec4
  1641. ================
  1642. */
  1643. void idWindow::ParseVec4(idTokenParser *src, idVec4 &out) {
  1644. idToken tok;
  1645. src->ReadToken(&tok);
  1646. out.x = atof(tok);
  1647. src->ExpectTokenString(",");
  1648. src->ReadToken(&tok);
  1649. out.y = atof(tok);
  1650. src->ExpectTokenString(",");
  1651. src->ReadToken(&tok);
  1652. out.z = atof(tok);
  1653. src->ExpectTokenString(",");
  1654. src->ReadToken(&tok);
  1655. out.w = atof(tok);
  1656. }
  1657. /*
  1658. ================
  1659. idWindow::ParseInternalVar
  1660. ================
  1661. */
  1662. bool idWindow::ParseInternalVar(const char *_name, idTokenParser *src) {
  1663. if (idStr::Icmp(_name, "showtime") == 0) {
  1664. if ( src->ParseBool() ) {
  1665. flags |= WIN_SHOWTIME;
  1666. }
  1667. return true;
  1668. }
  1669. if (idStr::Icmp(_name, "showcoords") == 0) {
  1670. if ( src->ParseBool() ) {
  1671. flags |= WIN_SHOWCOORDS;
  1672. }
  1673. return true;
  1674. }
  1675. if (idStr::Icmp(_name, "forceaspectwidth") == 0) {
  1676. forceAspectWidth = src->ParseFloat();
  1677. return true;
  1678. }
  1679. if (idStr::Icmp(_name, "forceaspectheight") == 0) {
  1680. forceAspectHeight = src->ParseFloat();
  1681. return true;
  1682. }
  1683. if (idStr::Icmp(_name, "matscalex") == 0) {
  1684. matScalex = src->ParseFloat();
  1685. return true;
  1686. }
  1687. if (idStr::Icmp(_name, "matscaley") == 0) {
  1688. matScaley = src->ParseFloat();
  1689. return true;
  1690. }
  1691. if (idStr::Icmp(_name, "bordersize") == 0) {
  1692. borderSize = src->ParseFloat();
  1693. return true;
  1694. }
  1695. if (idStr::Icmp(_name, "nowrap") == 0) {
  1696. if ( src->ParseBool() ) {
  1697. flags |= WIN_NOWRAP;
  1698. }
  1699. return true;
  1700. }
  1701. if (idStr::Icmp(_name, "shadow") == 0) {
  1702. textShadow = src->ParseInt();
  1703. return true;
  1704. }
  1705. if (idStr::Icmp(_name, "textalign") == 0) {
  1706. textAlign = src->ParseInt();
  1707. return true;
  1708. }
  1709. if (idStr::Icmp(_name, "textalignx") == 0) {
  1710. textAlignx = src->ParseFloat();
  1711. return true;
  1712. }
  1713. if (idStr::Icmp(_name, "textaligny") == 0) {
  1714. textAligny = src->ParseFloat();
  1715. return true;
  1716. }
  1717. if (idStr::Icmp(_name, "shear") == 0) {
  1718. shear.x = src->ParseFloat();
  1719. idToken tok;
  1720. src->ReadToken( &tok );
  1721. if ( tok.Icmp( "," ) ) {
  1722. src->Error( "Expected comma in shear definiation" );
  1723. return false;
  1724. }
  1725. shear.y = src->ParseFloat();
  1726. return true;
  1727. }
  1728. if (idStr::Icmp(_name, "wantenter") == 0) {
  1729. if ( src->ParseBool() ) {
  1730. flags |= WIN_WANTENTER;
  1731. }
  1732. return true;
  1733. }
  1734. if (idStr::Icmp(_name, "naturalmatscale") == 0) {
  1735. if ( src->ParseBool() ) {
  1736. flags |= WIN_NATURALMAT;
  1737. }
  1738. return true;
  1739. }
  1740. if (idStr::Icmp(_name, "noclip") == 0) {
  1741. if ( src->ParseBool() ) {
  1742. flags |= WIN_NOCLIP;
  1743. }
  1744. return true;
  1745. }
  1746. if (idStr::Icmp(_name, "nocursor") == 0) {
  1747. if ( src->ParseBool() ) {
  1748. flags |= WIN_NOCURSOR;
  1749. }
  1750. return true;
  1751. }
  1752. if (idStr::Icmp(_name, "menugui") == 0) {
  1753. if ( src->ParseBool() ) {
  1754. flags |= WIN_MENUGUI;
  1755. }
  1756. return true;
  1757. }
  1758. if (idStr::Icmp(_name, "modal") == 0) {
  1759. if ( src->ParseBool() ) {
  1760. flags |= WIN_MODAL;
  1761. }
  1762. return true;
  1763. }
  1764. if (idStr::Icmp(_name, "invertrect") == 0) {
  1765. if ( src->ParseBool() ) {
  1766. flags |= WIN_INVERTRECT;
  1767. }
  1768. return true;
  1769. }
  1770. if (idStr::Icmp(_name, "name") == 0) {
  1771. ParseString(src, name);
  1772. return true;
  1773. }
  1774. if (idStr::Icmp(_name, "play") == 0) {
  1775. common->Warning( "play encountered during gui parse.. see Robert\n" );
  1776. idStr playStr;
  1777. ParseString(src, playStr);
  1778. return true;
  1779. }
  1780. if (idStr::Icmp(_name, "comment") == 0) {
  1781. ParseString(src, comment);
  1782. return true;
  1783. }
  1784. if ( idStr::Icmp( _name, "font" ) == 0 ) {
  1785. idStr fontName;
  1786. ParseString( src, fontName );
  1787. font = renderSystem->RegisterFont( fontName );
  1788. return true;
  1789. }
  1790. return false;
  1791. }
  1792. /*
  1793. ================
  1794. idWindow::ParseRegEntry
  1795. ================
  1796. */
  1797. bool idWindow::ParseRegEntry(const char *name, idTokenParser *src) {
  1798. idStr work;
  1799. work = name;
  1800. work.ToLower();
  1801. idWinVar *var = GetWinVarByName(work, NULL);
  1802. if ( var ) {
  1803. for (int i = 0; i < NumRegisterVars; i++) {
  1804. if (idStr::Icmp(work, RegisterVars[i].name) == 0) {
  1805. regList.AddReg(work, RegisterVars[i].type, src, this, var);
  1806. return true;
  1807. }
  1808. }
  1809. }
  1810. // not predefined so just read the next token and add it to the state
  1811. idToken tok;
  1812. idVec4 v;
  1813. idWinInt *vari;
  1814. idWinFloat *varf;
  1815. idWinStr *vars;
  1816. if (src->ReadToken(&tok)) {
  1817. if (var) {
  1818. var->Set(tok);
  1819. return true;
  1820. }
  1821. switch (tok.type) {
  1822. case TT_NUMBER :
  1823. if (tok.subtype & TT_INTEGER) {
  1824. vari = new (TAG_OLD_UI) idWinInt();
  1825. *vari = atoi(tok);
  1826. vari->SetName(work);
  1827. definedVars.Append(vari);
  1828. } else if (tok.subtype & TT_FLOAT) {
  1829. varf = new (TAG_OLD_UI) idWinFloat();
  1830. *varf = atof(tok);
  1831. varf->SetName(work);
  1832. definedVars.Append(varf);
  1833. } else {
  1834. vars = new (TAG_OLD_UI) idWinStr();
  1835. *vars = tok;
  1836. vars->SetName(work);
  1837. definedVars.Append(vars);
  1838. }
  1839. break;
  1840. default :
  1841. vars = new (TAG_OLD_UI) idWinStr();
  1842. *vars = tok;
  1843. vars->SetName(work);
  1844. definedVars.Append(vars);
  1845. break;
  1846. }
  1847. }
  1848. return true;
  1849. }
  1850. /*
  1851. ================
  1852. idWindow::SetInitialState
  1853. ================
  1854. */
  1855. void idWindow::SetInitialState(const char *_name) {
  1856. name = _name;
  1857. matScalex = 1.0;
  1858. matScaley = 1.0;
  1859. forceAspectWidth = 640.0;
  1860. forceAspectHeight = 480.0;
  1861. noTime = false;
  1862. visible = true;
  1863. flags = 0;
  1864. }
  1865. /*
  1866. ================
  1867. idWindow::Parse
  1868. ================
  1869. */
  1870. bool idWindow::Parse( idTokenParser *src, bool rebuild) {
  1871. idToken token, token2, token3, token4, token5, token6, token7;
  1872. idStr work;
  1873. if (rebuild) {
  1874. CleanUp();
  1875. }
  1876. drawWin_t dwt;
  1877. timeLineEvents.Clear();
  1878. transitions.Clear();
  1879. namedEvents.DeleteContents( true );
  1880. src->ExpectTokenType( TT_NAME, 0, &token );
  1881. SetInitialState(token);
  1882. src->ExpectTokenString( "{" );
  1883. src->ExpectAnyToken( &token );
  1884. bool ret = true;
  1885. while( token != "}" ) {
  1886. // track what was parsed so we can maintain it for the guieditor
  1887. src->SetMarker ( );
  1888. if ( token == "windowDef" || token == "animationDef" ) {
  1889. if (token == "animationDef") {
  1890. visible = false;
  1891. rect = idRectangle(0,0,0,0);
  1892. }
  1893. src->ExpectTokenType( TT_NAME, 0, &token );
  1894. token2 = token;
  1895. src->UnreadToken(&token);
  1896. drawWin_t *dw = FindChildByName(token2.c_str());
  1897. if (dw != NULL && dw->win != NULL) {
  1898. SaveExpressionParseState();
  1899. dw->win->Parse(src, rebuild);
  1900. RestoreExpressionParseState();
  1901. } else {
  1902. idWindow *win = new (TAG_OLD_UI) idWindow(gui);
  1903. SaveExpressionParseState();
  1904. win->Parse(src, rebuild);
  1905. RestoreExpressionParseState();
  1906. win->SetParent(this);
  1907. dwt.simp = NULL;
  1908. dwt.win = NULL;
  1909. if (win->IsSimple()) {
  1910. idSimpleWindow *simple = new (TAG_OLD_UI) idSimpleWindow(win);
  1911. dwt.simp = simple;
  1912. drawWindows.Append(dwt);
  1913. delete win;
  1914. } else {
  1915. AddChild(win);
  1916. SetFocus(win,false);
  1917. dwt.win = win;
  1918. drawWindows.Append(dwt);
  1919. }
  1920. }
  1921. }
  1922. else if ( token == "editDef" ) {
  1923. idEditWindow *win = new (TAG_OLD_UI) idEditWindow(gui);
  1924. SaveExpressionParseState();
  1925. win->Parse(src, rebuild);
  1926. RestoreExpressionParseState();
  1927. AddChild(win);
  1928. win->SetParent(this);
  1929. dwt.simp = NULL;
  1930. dwt.win = win;
  1931. drawWindows.Append(dwt);
  1932. }
  1933. else if ( token == "choiceDef" ) {
  1934. idChoiceWindow *win = new (TAG_OLD_UI) idChoiceWindow(gui);
  1935. SaveExpressionParseState();
  1936. win->Parse(src, rebuild);
  1937. RestoreExpressionParseState();
  1938. AddChild(win);
  1939. win->SetParent(this);
  1940. dwt.simp = NULL;
  1941. dwt.win = win;
  1942. drawWindows.Append(dwt);
  1943. }
  1944. else if ( token == "sliderDef" ) {
  1945. idSliderWindow *win = new (TAG_OLD_UI) idSliderWindow(gui);
  1946. SaveExpressionParseState();
  1947. win->Parse(src, rebuild);
  1948. RestoreExpressionParseState();
  1949. AddChild(win);
  1950. win->SetParent(this);
  1951. dwt.simp = NULL;
  1952. dwt.win = win;
  1953. drawWindows.Append(dwt);
  1954. }
  1955. else if ( token == "bindDef" ) {
  1956. idBindWindow *win = new (TAG_OLD_UI) idBindWindow(gui);
  1957. SaveExpressionParseState();
  1958. win->Parse(src, rebuild);
  1959. RestoreExpressionParseState();
  1960. AddChild(win);
  1961. win->SetParent(this);
  1962. dwt.simp = NULL;
  1963. dwt.win = win;
  1964. drawWindows.Append(dwt);
  1965. }
  1966. else if ( token == "listDef" ) {
  1967. idListWindow *win = new (TAG_OLD_UI) idListWindow(gui);
  1968. SaveExpressionParseState();
  1969. win->Parse(src, rebuild);
  1970. RestoreExpressionParseState();
  1971. AddChild(win);
  1972. win->SetParent(this);
  1973. dwt.simp = NULL;
  1974. dwt.win = win;
  1975. drawWindows.Append(dwt);
  1976. }
  1977. else if ( token == "fieldDef" ) {
  1978. idFieldWindow *win = new (TAG_OLD_UI) idFieldWindow(gui);
  1979. SaveExpressionParseState();
  1980. win->Parse(src, rebuild);
  1981. RestoreExpressionParseState();
  1982. AddChild(win);
  1983. win->SetParent(this);
  1984. dwt.simp = NULL;
  1985. dwt.win = win;
  1986. drawWindows.Append(dwt);
  1987. }
  1988. else if ( token == "renderDef" ) {
  1989. // D3 could render a 3D model in a subrect of a full screen
  1990. // GUI for the main menus, but we have cut that ability so
  1991. // we don't need to deal with offset viewports on all platforms.
  1992. idRenderWindow *win = new (TAG_OLD_UI) idRenderWindow(gui);
  1993. SaveExpressionParseState();
  1994. win->Parse(src, rebuild);
  1995. RestoreExpressionParseState();
  1996. AddChild(win);
  1997. win->SetParent(this);
  1998. dwt.simp = NULL;
  1999. dwt.win = win;
  2000. drawWindows.Append(dwt);
  2001. }
  2002. else if ( token == "gameSSDDef" ) {
  2003. idGameSSDWindow *win = new (TAG_OLD_UI) idGameSSDWindow(gui);
  2004. SaveExpressionParseState();
  2005. win->Parse(src, rebuild);
  2006. RestoreExpressionParseState();
  2007. AddChild(win);
  2008. win->SetParent(this);
  2009. dwt.simp = NULL;
  2010. dwt.win = win;
  2011. drawWindows.Append(dwt);
  2012. }
  2013. else if ( token == "gameBearShootDef" ) {
  2014. idGameBearShootWindow *win = new (TAG_OLD_UI) idGameBearShootWindow(gui);
  2015. SaveExpressionParseState();
  2016. win->Parse(src, rebuild);
  2017. RestoreExpressionParseState();
  2018. AddChild(win);
  2019. win->SetParent(this);
  2020. dwt.simp = NULL;
  2021. dwt.win = win;
  2022. drawWindows.Append(dwt);
  2023. }
  2024. else if ( token == "gameBustOutDef" ) {
  2025. idGameBustOutWindow *win = new (TAG_OLD_UI) idGameBustOutWindow(gui);
  2026. SaveExpressionParseState();
  2027. win->Parse(src, rebuild);
  2028. RestoreExpressionParseState();
  2029. AddChild(win);
  2030. win->SetParent(this);
  2031. dwt.simp = NULL;
  2032. dwt.win = win;
  2033. drawWindows.Append(dwt);
  2034. }
  2035. //
  2036. // added new onEvent
  2037. else if ( token == "onNamedEvent" ) {
  2038. // Read the event name
  2039. if ( !src->ReadToken(&token) ) {
  2040. src->Error( "Expected event name" );
  2041. return false;
  2042. }
  2043. rvNamedEvent* ev = new (TAG_OLD_UI) rvNamedEvent ( token );
  2044. src->SetMarker ( );
  2045. if ( !ParseScript ( src, *ev->mEvent ) ) {
  2046. ret = false;
  2047. break;
  2048. }
  2049. namedEvents.Append(ev);
  2050. }
  2051. else if ( token == "onTime" ) {
  2052. idTimeLineEvent *ev = new (TAG_OLD_UI) idTimeLineEvent;
  2053. if ( !src->ReadToken(&token) ) {
  2054. src->Error( "Unexpected end of file" );
  2055. return false;
  2056. }
  2057. ev->time = atoi(token.c_str());
  2058. // reset the mark since we dont want it to include the time
  2059. src->SetMarker ( );
  2060. if (!ParseScript(src, *ev->event, &ev->time)) {
  2061. ret = false;
  2062. break;
  2063. }
  2064. // this is a timeline event
  2065. ev->pending = true;
  2066. timeLineEvents.Append(ev);
  2067. }
  2068. else if ( token == "definefloat" ) {
  2069. src->ReadToken(&token);
  2070. work = token;
  2071. work.ToLower();
  2072. idWinFloat *varf = new (TAG_OLD_UI) idWinFloat();
  2073. varf->SetName(work);
  2074. definedVars.Append(varf);
  2075. // add the float to the editors wrapper dict
  2076. // Set the marker after the float name
  2077. src->SetMarker ( );
  2078. // Read in the float
  2079. regList.AddReg(work, idRegister::FLOAT, src, this, varf);
  2080. }
  2081. else if ( token == "definevec4" ) {
  2082. src->ReadToken(&token);
  2083. work = token;
  2084. work.ToLower();
  2085. idWinVec4 *var = new (TAG_OLD_UI) idWinVec4();
  2086. var->SetName(work);
  2087. // set the marker so we can determine what was parsed
  2088. // set the marker after the vec4 name
  2089. src->SetMarker ( );
  2090. // FIXME: how about we add the var to the desktop instead of this window so it won't get deleted
  2091. // when this window is destoyed which even happens during parsing with simple windows ?
  2092. //definedVars.Append(var);
  2093. gui->GetDesktop()->definedVars.Append( var );
  2094. gui->GetDesktop()->regList.AddReg( work, idRegister::VEC4, src, gui->GetDesktop(), var );
  2095. }
  2096. else if ( token == "float" ) {
  2097. src->ReadToken(&token);
  2098. work = token;
  2099. work.ToLower();
  2100. idWinFloat *varf = new (TAG_OLD_UI) idWinFloat();
  2101. varf->SetName(work);
  2102. definedVars.Append(varf);
  2103. // add the float to the editors wrapper dict
  2104. // set the marker to after the float name
  2105. src->SetMarker ( );
  2106. // Parse the float
  2107. regList.AddReg(work, idRegister::FLOAT, src, this, varf);
  2108. }
  2109. else if (ParseScriptEntry(token, src)) {
  2110. } else if (ParseInternalVar(token, src)) {
  2111. }
  2112. else {
  2113. ParseRegEntry(token, src);
  2114. }
  2115. if ( !src->ReadToken( &token ) ) {
  2116. src->Error( "Unexpected end of file" );
  2117. ret = false;
  2118. break;
  2119. }
  2120. }
  2121. if (ret) {
  2122. EvalRegs(-1, true);
  2123. }
  2124. SetupFromState();
  2125. PostParse();
  2126. return ret;
  2127. }
  2128. /*
  2129. ================
  2130. idWindow::FindSimpleWinByName
  2131. ================
  2132. */
  2133. idSimpleWindow *idWindow::FindSimpleWinByName(const char *_name) {
  2134. int c = drawWindows.Num();
  2135. for (int i = 0; i < c; i++) {
  2136. if (drawWindows[i].simp == NULL) {
  2137. continue;
  2138. }
  2139. if ( idStr::Icmp(drawWindows[i].simp->name, _name) == 0 ) {
  2140. return drawWindows[i].simp;
  2141. }
  2142. }
  2143. return NULL;
  2144. }
  2145. /*
  2146. ================
  2147. idWindow::FindChildByName
  2148. ================
  2149. */
  2150. drawWin_t *idWindow::FindChildByName(const char *_name) {
  2151. static drawWin_t dw;
  2152. if (idStr::Icmp(name,_name) == 0) {
  2153. dw.simp = NULL;
  2154. dw.win = this;
  2155. return &dw;
  2156. }
  2157. int c = drawWindows.Num();
  2158. for (int i = 0; i < c; i++) {
  2159. if (drawWindows[i].win) {
  2160. if (idStr::Icmp(drawWindows[i].win->name, _name) == 0) {
  2161. return &drawWindows[i];
  2162. }
  2163. drawWin_t *win = drawWindows[i].win->FindChildByName(_name);
  2164. if (win) {
  2165. return win;
  2166. }
  2167. } else {
  2168. if (idStr::Icmp(drawWindows[i].simp->name, _name) == 0) {
  2169. return &drawWindows[i];
  2170. }
  2171. }
  2172. }
  2173. return NULL;
  2174. }
  2175. /*
  2176. ================
  2177. idWindow::GetStrPtrByName
  2178. ================
  2179. */
  2180. idStr* idWindow::GetStrPtrByName(const char *_name) {
  2181. return NULL;
  2182. }
  2183. /*
  2184. ================
  2185. idWindow::AddTransition
  2186. ================
  2187. */
  2188. void idWindow::AddTransition(idWinVar *dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime) {
  2189. idTransitionData data;
  2190. data.data = dest;
  2191. data.interp.Init(gui->GetTime(), accelTime * time, decelTime * time, time, from, to);
  2192. transitions.Append(data);
  2193. }
  2194. /*
  2195. ================
  2196. idWindow::StartTransition
  2197. ================
  2198. */
  2199. void idWindow::StartTransition() {
  2200. flags |= WIN_INTRANSITION;
  2201. }
  2202. /*
  2203. ================
  2204. idWindow::ResetCinematics
  2205. ================
  2206. */
  2207. void idWindow::ResetCinematics() {
  2208. if ( background ) {
  2209. background->ResetCinematicTime( gui->GetTime() );
  2210. }
  2211. }
  2212. /*
  2213. ================
  2214. idWindow::ResetTime
  2215. ================
  2216. */
  2217. void idWindow::ResetTime(int t) {
  2218. timeLine = gui->GetTime() - t;
  2219. int i, c = timeLineEvents.Num();
  2220. for ( i = 0; i < c; i++ ) {
  2221. if ( timeLineEvents[i]->time >= t ) {
  2222. timeLineEvents[i]->pending = true;
  2223. }
  2224. }
  2225. noTime = false;
  2226. c = transitions.Num();
  2227. for ( i = 0; i < c; i++ ) {
  2228. idTransitionData *data = &transitions[i];
  2229. if ( data->interp.IsDone( gui->GetTime() ) && data->data ) {
  2230. transitions.RemoveIndex( i );
  2231. i--;
  2232. c--;
  2233. }
  2234. }
  2235. }
  2236. /*
  2237. ================
  2238. idWindow::RunScriptList
  2239. ================
  2240. */
  2241. bool idWindow::RunScriptList(idGuiScriptList *src) {
  2242. if (src == NULL) {
  2243. return false;
  2244. }
  2245. src->Execute(this);
  2246. return true;
  2247. }
  2248. /*
  2249. ================
  2250. idWindow::RunScript
  2251. ================
  2252. */
  2253. bool idWindow::RunScript(int n) {
  2254. if (n >= ON_MOUSEENTER && n < SCRIPT_COUNT) {
  2255. return RunScriptList(scripts[n]);
  2256. }
  2257. return false;
  2258. }
  2259. /*
  2260. ================
  2261. idWindow::ExpressionConstant
  2262. ================
  2263. */
  2264. int idWindow::ExpressionConstant(float f) {
  2265. int i;
  2266. for ( i = WEXP_REG_NUM_PREDEFINED ; i < expressionRegisters.Num() ; i++ ) {
  2267. if ( !registerIsTemporary[i] && expressionRegisters[i] == f ) {
  2268. return i;
  2269. }
  2270. }
  2271. if ( expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS ) {
  2272. common->Warning( "expressionConstant: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile() );
  2273. return 0;
  2274. }
  2275. int c = expressionRegisters.Num();
  2276. if (i > c) {
  2277. while (i > c) {
  2278. expressionRegisters.Append(-9999999);
  2279. i--;
  2280. }
  2281. }
  2282. i = expressionRegisters.Append(f);
  2283. registerIsTemporary[i] = false;
  2284. return i;
  2285. }
  2286. /*
  2287. ================
  2288. idWindow::ExpressionTemporary
  2289. ================
  2290. */
  2291. int idWindow::ExpressionTemporary() {
  2292. if ( expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS ) {
  2293. common->Warning( "expressionTemporary: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile());
  2294. return 0;
  2295. }
  2296. int i = expressionRegisters.Num();
  2297. registerIsTemporary[i] = true;
  2298. i = expressionRegisters.Append(0);
  2299. return i;
  2300. }
  2301. /*
  2302. ================
  2303. idWindow::ExpressionOp
  2304. ================
  2305. */
  2306. wexpOp_t *idWindow::ExpressionOp() {
  2307. if ( ops.Num() == MAX_EXPRESSION_OPS ) {
  2308. common->Warning( "expressionOp: gui %s hit MAX_EXPRESSION_OPS", gui->GetSourceFile());
  2309. return &ops[0];
  2310. }
  2311. wexpOp_t wop;
  2312. memset(&wop, 0, sizeof(wexpOp_t));
  2313. int i = ops.Append(wop);
  2314. return &ops[i];
  2315. }
  2316. /*
  2317. ================
  2318. idWindow::EmitOp
  2319. ================
  2320. */
  2321. int idWindow::EmitOp( int a, int b, wexpOpType_t opType, wexpOp_t **opp ) {
  2322. wexpOp_t *op;
  2323. /*
  2324. // optimize away identity operations
  2325. if ( opType == WOP_TYPE_ADD ) {
  2326. if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) {
  2327. return b;
  2328. }
  2329. if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) {
  2330. return a;
  2331. }
  2332. if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) {
  2333. return ExpressionConstant( shaderRegisters[a] + shaderRegisters[b] );
  2334. }
  2335. }
  2336. if ( opType == WOP_TYPE_MULTIPLY ) {
  2337. if ( !registerIsTemporary[a] && shaderRegisters[a] == 1 ) {
  2338. return b;
  2339. }
  2340. if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) {
  2341. return a;
  2342. }
  2343. if ( !registerIsTemporary[b] && shaderRegisters[b] == 1 ) {
  2344. return a;
  2345. }
  2346. if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) {
  2347. return b;
  2348. }
  2349. if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) {
  2350. return ExpressionConstant( shaderRegisters[a] * shaderRegisters[b] );
  2351. }
  2352. }
  2353. */
  2354. op = ExpressionOp();
  2355. op->opType = opType;
  2356. op->a = a;
  2357. op->b = b;
  2358. op->c = ExpressionTemporary();
  2359. if (opp) {
  2360. *opp = op;
  2361. }
  2362. return op->c;
  2363. }
  2364. /*
  2365. ================
  2366. idWindow::ParseEmitOp
  2367. ================
  2368. */
  2369. int idWindow::ParseEmitOp( idTokenParser *src, int a, wexpOpType_t opType, int priority, wexpOp_t **opp ) {
  2370. int b = ParseExpressionPriority( src, priority );
  2371. return EmitOp( a, b, opType, opp );
  2372. }
  2373. /*
  2374. ================
  2375. idWindow::ParseTerm
  2376. Returns a register index
  2377. =================
  2378. */
  2379. int idWindow::ParseTerm( idTokenParser *src, idWinVar *var, int component ) {
  2380. idToken token;
  2381. int a, b;
  2382. src->ReadToken( &token );
  2383. if ( token == "(" ) {
  2384. a = ParseExpression( src );
  2385. src->ExpectTokenString(")");
  2386. return a;
  2387. }
  2388. if ( !token.Icmp( "time" ) ) {
  2389. return WEXP_REG_TIME;
  2390. }
  2391. // parse negative numbers
  2392. if ( token == "-" ) {
  2393. src->ReadToken( &token );
  2394. if ( token.type == TT_NUMBER || token == "." ) {
  2395. return ExpressionConstant( -(float) token.GetFloatValue() );
  2396. }
  2397. src->Warning( "Bad negative number '%s'", token.c_str() );
  2398. return 0;
  2399. }
  2400. if ( token.type == TT_NUMBER || token == "." || token == "-" ) {
  2401. return ExpressionConstant( (float) token.GetFloatValue() );
  2402. }
  2403. // see if it is a table name
  2404. const idDeclTable *table = static_cast<const idDeclTable *>( declManager->FindType( DECL_TABLE, token.c_str(), false ) );
  2405. if ( table ) {
  2406. a = table->Index();
  2407. // parse a table expression
  2408. src->ExpectTokenString("[");
  2409. b = ParseExpression(src);
  2410. src->ExpectTokenString("]");
  2411. return EmitOp( a, b, WOP_TYPE_TABLE );
  2412. }
  2413. if (var == NULL) {
  2414. var = GetWinVarByName(token, true);
  2415. }
  2416. if (var) {
  2417. a = (int)var;
  2418. //assert(dynamic_cast<idWinVec4*>(var));
  2419. var->Init(token, this);
  2420. b = component;
  2421. if (dynamic_cast<idWinVec4*>(var)) {
  2422. if (src->ReadToken(&token)) {
  2423. if (token == "[") {
  2424. b = ParseExpression(src);
  2425. src->ExpectTokenString("]");
  2426. } else {
  2427. src->UnreadToken(&token);
  2428. }
  2429. }
  2430. return EmitOp(a, b, WOP_TYPE_VAR);
  2431. } else if (dynamic_cast<idWinFloat*>(var)) {
  2432. return EmitOp(a, b, WOP_TYPE_VARF);
  2433. } else if (dynamic_cast<idWinInt*>(var)) {
  2434. return EmitOp(a, b, WOP_TYPE_VARI);
  2435. } else if (dynamic_cast<idWinBool*>(var)) {
  2436. return EmitOp(a, b, WOP_TYPE_VARB);
  2437. } else if (dynamic_cast<idWinStr*>(var)) {
  2438. return EmitOp(a, b, WOP_TYPE_VARS);
  2439. } else {
  2440. src->Warning("Var expression not vec4, float or int '%s'", token.c_str());
  2441. }
  2442. return 0;
  2443. } else {
  2444. // ugly but used for post parsing to fixup named vars
  2445. char *p = new (TAG_OLD_UI) char[token.Length()+1];
  2446. strcpy(p, token);
  2447. a = (int)p;
  2448. b = -2;
  2449. return EmitOp(a, b, WOP_TYPE_VAR);
  2450. }
  2451. }
  2452. /*
  2453. =================
  2454. idWindow::ParseExpressionPriority
  2455. Returns a register index
  2456. =================
  2457. */
  2458. #define TOP_PRIORITY 4
  2459. int idWindow::ParseExpressionPriority( idTokenParser *src, int priority, idWinVar *var, int component ) {
  2460. idToken token;
  2461. int a;
  2462. if ( priority == 0 ) {
  2463. return ParseTerm( src, var, component );
  2464. }
  2465. a = ParseExpressionPriority( src, priority - 1, var, component );
  2466. if ( !src->ReadToken( &token ) ) {
  2467. // we won't get EOF in a real file, but we can
  2468. // when parsing from generated strings
  2469. return a;
  2470. }
  2471. if ( priority == 1 && token == "*" ) {
  2472. return ParseEmitOp( src, a, WOP_TYPE_MULTIPLY, priority );
  2473. }
  2474. if ( priority == 1 && token == "/" ) {
  2475. return ParseEmitOp( src, a, WOP_TYPE_DIVIDE, priority );
  2476. }
  2477. if ( priority == 1 && token == "%" ) { // implied truncate both to integer
  2478. return ParseEmitOp( src, a, WOP_TYPE_MOD, priority );
  2479. }
  2480. if ( priority == 2 && token == "+" ) {
  2481. return ParseEmitOp( src, a, WOP_TYPE_ADD, priority );
  2482. }
  2483. if ( priority == 2 && token == "-" ) {
  2484. return ParseEmitOp( src, a, WOP_TYPE_SUBTRACT, priority );
  2485. }
  2486. if ( priority == 3 && token == ">" ) {
  2487. return ParseEmitOp( src, a, WOP_TYPE_GT, priority );
  2488. }
  2489. if ( priority == 3 && token == ">=" ) {
  2490. return ParseEmitOp( src, a, WOP_TYPE_GE, priority );
  2491. }
  2492. if ( priority == 3 && token == "<" ) {
  2493. return ParseEmitOp( src, a, WOP_TYPE_LT, priority );
  2494. }
  2495. if ( priority == 3 && token == "<=" ) {
  2496. return ParseEmitOp( src, a, WOP_TYPE_LE, priority );
  2497. }
  2498. if ( priority == 3 && token == "==" ) {
  2499. return ParseEmitOp( src, a, WOP_TYPE_EQ, priority );
  2500. }
  2501. if ( priority == 3 && token == "!=" ) {
  2502. return ParseEmitOp( src, a, WOP_TYPE_NE, priority );
  2503. }
  2504. if ( priority == 4 && token == "&&" ) {
  2505. return ParseEmitOp( src, a, WOP_TYPE_AND, priority );
  2506. }
  2507. if ( priority == 4 && token == "||" ) {
  2508. return ParseEmitOp( src, a, WOP_TYPE_OR, priority );
  2509. }
  2510. if ( priority == 4 && token == "?" ) {
  2511. wexpOp_t *oop = NULL;
  2512. int o = ParseEmitOp( src, a, WOP_TYPE_COND, priority, &oop );
  2513. if ( !src->ReadToken( &token ) ) {
  2514. return o;
  2515. }
  2516. if (token == ":") {
  2517. a = ParseExpressionPriority( src, priority - 1, var );
  2518. oop->d = a;
  2519. }
  2520. return o;
  2521. }
  2522. // assume that anything else terminates the expression
  2523. // not too robust error checking...
  2524. src->UnreadToken( &token );
  2525. return a;
  2526. }
  2527. /*
  2528. ================
  2529. idWindow::ParseExpression
  2530. Returns a register index
  2531. ================
  2532. */
  2533. int idWindow::ParseExpression(idTokenParser *src, idWinVar *var, int component) {
  2534. return ParseExpressionPriority( src, TOP_PRIORITY, var );
  2535. }
  2536. /*
  2537. ================
  2538. idWindow::ParseBracedExpression
  2539. ================
  2540. */
  2541. void idWindow::ParseBracedExpression(idTokenParser *src) {
  2542. src->ExpectTokenString("{");
  2543. ParseExpression(src);
  2544. src->ExpectTokenString("}");
  2545. }
  2546. /*
  2547. ===============
  2548. idWindow::EvaluateRegisters
  2549. Parameters are taken from the localSpace and the renderView,
  2550. then all expressions are evaluated, leaving the shader registers
  2551. set to their apropriate values.
  2552. ===============
  2553. */
  2554. void idWindow::EvaluateRegisters(float *registers) {
  2555. int i, b;
  2556. wexpOp_t *op;
  2557. idVec4 v;
  2558. int erc = expressionRegisters.Num();
  2559. int oc = ops.Num();
  2560. // copy the constants
  2561. for ( i = WEXP_REG_NUM_PREDEFINED ; i < erc ; i++ ) {
  2562. registers[i] = expressionRegisters[i];
  2563. }
  2564. // copy the local and global parameters
  2565. registers[WEXP_REG_TIME] = gui->GetTime();
  2566. for ( i = 0 ; i < oc ; i++ ) {
  2567. op = &ops[i];
  2568. if (op->b == -2) {
  2569. continue;
  2570. }
  2571. switch( op->opType ) {
  2572. case WOP_TYPE_ADD:
  2573. registers[op->c] = registers[op->a] + registers[op->b];
  2574. break;
  2575. case WOP_TYPE_SUBTRACT:
  2576. registers[op->c] = registers[op->a] - registers[op->b];
  2577. break;
  2578. case WOP_TYPE_MULTIPLY:
  2579. registers[op->c] = registers[op->a] * registers[op->b];
  2580. break;
  2581. case WOP_TYPE_DIVIDE:
  2582. if ( registers[op->b] == 0.0f ) {
  2583. common->Warning( "Divide by zero in window '%s' in %s", GetName(), gui->GetSourceFile() );
  2584. registers[op->c] = registers[op->a];
  2585. } else {
  2586. registers[op->c] = registers[op->a] / registers[op->b];
  2587. }
  2588. break;
  2589. case WOP_TYPE_MOD:
  2590. b = (int)registers[op->b];
  2591. b = b != 0 ? b : 1;
  2592. registers[op->c] = (int)registers[op->a] % b;
  2593. break;
  2594. case WOP_TYPE_TABLE:
  2595. {
  2596. const idDeclTable *table = static_cast<const idDeclTable *>( declManager->DeclByIndex( DECL_TABLE, op->a ) );
  2597. registers[op->c] = table->TableLookup( registers[op->b] );
  2598. }
  2599. break;
  2600. case WOP_TYPE_GT:
  2601. registers[op->c] = registers[ op->a ] > registers[op->b];
  2602. break;
  2603. case WOP_TYPE_GE:
  2604. registers[op->c] = registers[ op->a ] >= registers[op->b];
  2605. break;
  2606. case WOP_TYPE_LT:
  2607. registers[op->c] = registers[ op->a ] < registers[op->b];
  2608. break;
  2609. case WOP_TYPE_LE:
  2610. registers[op->c] = registers[ op->a ] <= registers[op->b];
  2611. break;
  2612. case WOP_TYPE_EQ:
  2613. registers[op->c] = registers[ op->a ] == registers[op->b];
  2614. break;
  2615. case WOP_TYPE_NE:
  2616. registers[op->c] = registers[ op->a ] != registers[op->b];
  2617. break;
  2618. case WOP_TYPE_COND:
  2619. registers[op->c] = (registers[ op->a ]) ? registers[op->b] : registers[op->d];
  2620. break;
  2621. case WOP_TYPE_AND:
  2622. registers[op->c] = registers[ op->a ] && registers[op->b];
  2623. break;
  2624. case WOP_TYPE_OR:
  2625. registers[op->c] = registers[ op->a ] || registers[op->b];
  2626. break;
  2627. case WOP_TYPE_VAR:
  2628. if ( !op->a ) {
  2629. registers[op->c] = 0.0f;
  2630. break;
  2631. }
  2632. if ( op->b >= 0 && registers[op->b] >= 0 && registers[op->b] < 4 ) {
  2633. // grabs vector components
  2634. idWinVec4 *var = (idWinVec4 *)( op->a );
  2635. registers[op->c] = ((idVec4&)var)[registers[op->b]];
  2636. } else {
  2637. registers[op->c] = ((idWinVar*)(op->a))->x();
  2638. }
  2639. break;
  2640. case WOP_TYPE_VARS:
  2641. if (op->a) {
  2642. idWinStr *var = (idWinStr*)(op->a);
  2643. registers[op->c] = atof(var->c_str());
  2644. } else {
  2645. registers[op->c] = 0;
  2646. }
  2647. break;
  2648. case WOP_TYPE_VARF:
  2649. if (op->a) {
  2650. idWinFloat *var = (idWinFloat*)(op->a);
  2651. registers[op->c] = *var;
  2652. } else {
  2653. registers[op->c] = 0;
  2654. }
  2655. break;
  2656. case WOP_TYPE_VARI:
  2657. if (op->a) {
  2658. idWinInt *var = (idWinInt*)(op->a);
  2659. registers[op->c] = *var;
  2660. } else {
  2661. registers[op->c] = 0;
  2662. }
  2663. break;
  2664. case WOP_TYPE_VARB:
  2665. if (op->a) {
  2666. idWinBool *var = (idWinBool*)(op->a);
  2667. registers[op->c] = *var;
  2668. } else {
  2669. registers[op->c] = 0;
  2670. }
  2671. break;
  2672. default:
  2673. common->FatalError( "R_EvaluateExpression: bad opcode" );
  2674. }
  2675. }
  2676. }
  2677. /*
  2678. ================
  2679. idWindow::ReadFromDemoFile
  2680. ================
  2681. */
  2682. void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) {
  2683. // should never hit unless we re-enable WRITE_GUIS
  2684. #ifndef WRITE_GUIS
  2685. assert( false );
  2686. #else
  2687. if (rebuild) {
  2688. CommonInit();
  2689. }
  2690. f->SetLog(true, "window1");
  2691. backGroundName = f->ReadHashString();
  2692. f->SetLog(true, backGroundName);
  2693. if ( backGroundName[0] ) {
  2694. background = declManager->FindMaterial(backGroundName);
  2695. } else {
  2696. background = NULL;
  2697. }
  2698. f->ReadUnsignedChar( cursor );
  2699. f->ReadUnsignedInt( flags );
  2700. f->ReadInt( timeLine );
  2701. f->ReadInt( lastTimeRun );
  2702. idRectangle rct = rect;
  2703. f->ReadFloat( rct.x );
  2704. f->ReadFloat( rct.y );
  2705. f->ReadFloat( rct.w );
  2706. f->ReadFloat( rct.h );
  2707. f->ReadFloat( drawRect.x );
  2708. f->ReadFloat( drawRect.y );
  2709. f->ReadFloat( drawRect.w );
  2710. f->ReadFloat( drawRect.h );
  2711. f->ReadFloat( clientRect.x );
  2712. f->ReadFloat( clientRect.y );
  2713. f->ReadFloat( clientRect.w );
  2714. f->ReadFloat( clientRect.h );
  2715. f->ReadFloat( textRect.x );
  2716. f->ReadFloat( textRect.y );
  2717. f->ReadFloat( textRect.w );
  2718. f->ReadFloat( textRect.h );
  2719. f->ReadFloat( xOffset);
  2720. f->ReadFloat( yOffset);
  2721. int i, c;
  2722. idStr work;
  2723. if (rebuild) {
  2724. f->SetLog(true, (work + "-scripts"));
  2725. for (i = 0; i < SCRIPT_COUNT; i++) {
  2726. bool b;
  2727. f->ReadBool( b );
  2728. if (b) {
  2729. delete scripts[i];
  2730. scripts[i] = new (TAG_OLD_UI) idGuiScriptList;
  2731. scripts[i]->ReadFromDemoFile(f);
  2732. }
  2733. }
  2734. f->SetLog(true, (work + "-timelines"));
  2735. f->ReadInt( c );
  2736. for (i = 0; i < c; i++) {
  2737. idTimeLineEvent *tl = new (TAG_OLD_UI) idTimeLineEvent;
  2738. f->ReadInt( tl->time );
  2739. f->ReadBool( tl->pending );
  2740. tl->event->ReadFromDemoFile(f);
  2741. if (rebuild) {
  2742. timeLineEvents.Append(tl);
  2743. } else {
  2744. assert(i < timeLineEvents.Num());
  2745. timeLineEvents[i]->time = tl->time;
  2746. timeLineEvents[i]->pending = tl->pending;
  2747. }
  2748. }
  2749. }
  2750. f->SetLog(true, (work + "-transitions"));
  2751. f->ReadInt( c );
  2752. for (i = 0; i < c; i++) {
  2753. idTransitionData td;
  2754. td.data = NULL;
  2755. f->ReadInt ( td.offset );
  2756. float startTime, accelTime, linearTime, decelTime;
  2757. idVec4 startValue, endValue;
  2758. f->ReadFloat( startTime );
  2759. f->ReadFloat( accelTime );
  2760. f->ReadFloat( linearTime );
  2761. f->ReadFloat( decelTime );
  2762. f->ReadVec4( startValue );
  2763. f->ReadVec4( endValue );
  2764. td.interp.Init( startTime, accelTime, decelTime, accelTime + linearTime + decelTime, startValue, endValue );
  2765. // read this for correct data padding with the win32 savegames
  2766. // the extrapolate is correctly initialized through the above Init call
  2767. int extrapolationType;
  2768. float duration;
  2769. idVec4 baseSpeed, speed;
  2770. float currentTime;
  2771. idVec4 currentValue;
  2772. f->ReadInt( extrapolationType );
  2773. f->ReadFloat( startTime );
  2774. f->ReadFloat( duration );
  2775. f->ReadVec4( startValue );
  2776. f->ReadVec4( baseSpeed );
  2777. f->ReadVec4( speed );
  2778. f->ReadFloat( currentTime );
  2779. f->ReadVec4( currentValue );
  2780. transitions.Append(td);
  2781. }
  2782. f->SetLog(true, (work + "-regstuff"));
  2783. if (rebuild) {
  2784. f->ReadInt( c );
  2785. for (i = 0; i < c; i++) {
  2786. wexpOp_t w;
  2787. f->ReadInt( (int&)w.opType );
  2788. f->ReadInt( w.a );
  2789. f->ReadInt( w.b );
  2790. f->ReadInt( w.c );
  2791. f->ReadInt( w.d );
  2792. ops.Append(w);
  2793. }
  2794. f->ReadInt( c );
  2795. for (i = 0; i < c; i++) {
  2796. float ff;
  2797. f->ReadFloat( ff );
  2798. expressionRegisters.Append(ff);
  2799. }
  2800. regList.ReadFromDemoFile(f);
  2801. }
  2802. f->SetLog(true, (work + "-children"));
  2803. f->ReadInt( c );
  2804. for (i = 0; i < c; i++) {
  2805. if (rebuild) {
  2806. idWindow *win = new (TAG_OLD_UI) idWindow(dc, gui);
  2807. win->ReadFromDemoFile(f);
  2808. AddChild(win);
  2809. } else {
  2810. for (int j = 0; j < c; j++) {
  2811. if (children[j]->childID == i) {
  2812. children[j]->ReadFromDemoFile(f,rebuild);
  2813. break;
  2814. } else {
  2815. continue;
  2816. }
  2817. }
  2818. }
  2819. }
  2820. #endif /* WRITE_GUIS */
  2821. }
  2822. /*
  2823. ================
  2824. idWindow::WriteToDemoFile
  2825. ================
  2826. */
  2827. void idWindow::WriteToDemoFile( class idDemoFile *f ) {
  2828. // should never hit unless we re-enable WRITE_GUIS
  2829. #ifndef WRITE_GUIS
  2830. assert( false );
  2831. #else
  2832. f->SetLog(true, "window");
  2833. f->WriteHashString(backGroundName);
  2834. f->SetLog(true, backGroundName);
  2835. f->WriteUnsignedChar( cursor );
  2836. f->WriteUnsignedInt( flags );
  2837. f->WriteInt( timeLine );
  2838. f->WriteInt( lastTimeRun );
  2839. idRectangle rct = rect;
  2840. f->WriteFloat( rct.x );
  2841. f->WriteFloat( rct.y );
  2842. f->WriteFloat( rct.w );
  2843. f->WriteFloat( rct.h );
  2844. f->WriteFloat( drawRect.x );
  2845. f->WriteFloat( drawRect.y );
  2846. f->WriteFloat( drawRect.w );
  2847. f->WriteFloat( drawRect.h );
  2848. f->WriteFloat( clientRect.x );
  2849. f->WriteFloat( clientRect.y );
  2850. f->WriteFloat( clientRect.w );
  2851. f->WriteFloat( clientRect.h );
  2852. f->WriteFloat( textRect.x );
  2853. f->WriteFloat( textRect.y );
  2854. f->WriteFloat( textRect.w );
  2855. f->WriteFloat( textRect.h );
  2856. f->WriteFloat( xOffset );
  2857. f->WriteFloat( yOffset );
  2858. idStr work;
  2859. f->SetLog(true, work);
  2860. int i, c;
  2861. f->SetLog(true, (work + "-transitions"));
  2862. c = transitions.Num();
  2863. f->WriteInt( c );
  2864. for (i = 0; i < c; i++) {
  2865. f->WriteInt( 0 );
  2866. f->WriteInt( transitions[i].offset );
  2867. f->WriteFloat( transitions[i].interp.GetStartTime() );
  2868. f->WriteFloat( transitions[i].interp.GetAccelTime() );
  2869. f->WriteFloat( transitions[i].interp.GetLinearTime() );
  2870. f->WriteFloat( transitions[i].interp.GetDecelTime() );
  2871. f->WriteVec4( transitions[i].interp.GetStartValue() );
  2872. f->WriteVec4( transitions[i].interp.GetEndValue() );
  2873. // write to keep win32 render demo format compatiblity - we don't actually read them back anymore
  2874. f->WriteInt( transitions[i].interp.GetExtrapolate()->GetExtrapolationType() );
  2875. f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetStartTime() );
  2876. f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetDuration() );
  2877. f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetStartValue() );
  2878. f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetBaseSpeed() );
  2879. f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetSpeed() );
  2880. f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetCurrentTime() );
  2881. f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetCurrentValue() );
  2882. }
  2883. f->SetLog(true, (work + "-regstuff"));
  2884. f->SetLog(true, (work + "-children"));
  2885. c = children.Num();
  2886. f->WriteInt( c );
  2887. for (i = 0; i < c; i++) {
  2888. for (int j = 0; j < c; j++) {
  2889. if (children[j]->childID == i) {
  2890. children[j]->WriteToDemoFile(f);
  2891. break;
  2892. } else {
  2893. continue;
  2894. }
  2895. }
  2896. }
  2897. #endif /* WRITE_GUIS */
  2898. }
  2899. /*
  2900. ===============
  2901. idWindow::WriteString
  2902. ===============
  2903. */
  2904. void idWindow::WriteSaveGameString( const char *string, idFile *savefile ) {
  2905. int len = strlen( string );
  2906. savefile->Write( &len, sizeof( len ) );
  2907. savefile->Write( string, len );
  2908. }
  2909. /*
  2910. ===============
  2911. idWindow::WriteSaveGameTransition
  2912. ===============
  2913. */
  2914. void idWindow::WriteSaveGameTransition( idTransitionData &trans, idFile *savefile ) {
  2915. drawWin_t dw, *fdw;
  2916. idStr winName("");
  2917. dw.simp = NULL;
  2918. dw.win = NULL;
  2919. int offset = gui->GetDesktop()->GetWinVarOffset( trans.data, &dw );
  2920. if ( dw.win || dw.simp ) {
  2921. winName = ( dw.win ) ? dw.win->GetName() : dw.simp->name.c_str();
  2922. }
  2923. fdw = gui->GetDesktop()->FindChildByName( winName );
  2924. if ( offset != -1 && fdw != NULL && ( fdw->win != NULL || fdw->simp != NULL ) ) {
  2925. savefile->Write( &offset, sizeof( offset ) );
  2926. WriteSaveGameString( winName, savefile );
  2927. savefile->Write( &trans.interp, sizeof( trans.interp ) );
  2928. } else {
  2929. offset = -1;
  2930. savefile->Write( &offset, sizeof( offset ) );
  2931. }
  2932. }
  2933. /*
  2934. ===============
  2935. idWindow::ReadSaveGameTransition
  2936. ===============
  2937. */
  2938. void idWindow::ReadSaveGameTransition( idTransitionData &trans, idFile *savefile ) {
  2939. int offset;
  2940. savefile->Read( &offset, sizeof( offset ) );
  2941. if ( offset != -1 ) {
  2942. idStr winName;
  2943. ReadSaveGameString( winName, savefile );
  2944. savefile->Read( &trans.interp, sizeof( trans.interp ) );
  2945. trans.data = NULL;
  2946. trans.offset = offset;
  2947. if ( winName.Length() ) {
  2948. idWinStr *strVar = new (TAG_OLD_UI) idWinStr();
  2949. strVar->Set( winName );
  2950. trans.data = dynamic_cast< idWinVar* >( strVar );
  2951. }
  2952. }
  2953. }
  2954. /*
  2955. ===============
  2956. idWindow::WriteToSaveGame
  2957. ===============
  2958. */
  2959. void idWindow::WriteToSaveGame( idFile *savefile ) {
  2960. int i;
  2961. WriteSaveGameString( cmd, savefile );
  2962. savefile->Write( &actualX, sizeof( actualX ) );
  2963. savefile->Write( &actualY, sizeof( actualY ) );
  2964. savefile->Write( &childID, sizeof( childID ) );
  2965. savefile->Write( &flags, sizeof( flags ) );
  2966. savefile->Write( &lastTimeRun, sizeof( lastTimeRun ) );
  2967. savefile->Write( &drawRect, sizeof( drawRect ) );
  2968. savefile->Write( &clientRect, sizeof( clientRect ) );
  2969. savefile->Write( &origin, sizeof( origin ) );
  2970. savefile->Write( &timeLine, sizeof( timeLine ) );
  2971. savefile->Write( &xOffset, sizeof( xOffset ) );
  2972. savefile->Write( &yOffset, sizeof( yOffset ) );
  2973. savefile->Write( &cursor, sizeof( cursor ) );
  2974. savefile->Write( &forceAspectWidth, sizeof( forceAspectWidth ) );
  2975. savefile->Write( &forceAspectHeight, sizeof( forceAspectHeight ) );
  2976. savefile->Write( &matScalex, sizeof( matScalex ) );
  2977. savefile->Write( &matScaley, sizeof( matScaley ) );
  2978. savefile->Write( &borderSize, sizeof( borderSize ) );
  2979. savefile->Write( &textAlign, sizeof( textAlign ) );
  2980. savefile->Write( &textAlignx, sizeof( textAlignx ) );
  2981. savefile->Write( &textAligny, sizeof( textAligny ) );
  2982. savefile->Write( &textShadow, sizeof( textShadow ) );
  2983. savefile->Write( &shear, sizeof( shear ) );
  2984. savefile->WriteString( font->GetName() );
  2985. WriteSaveGameString( name, savefile );
  2986. WriteSaveGameString( comment, savefile );
  2987. // WinVars
  2988. noTime.WriteToSaveGame( savefile );
  2989. visible.WriteToSaveGame( savefile );
  2990. rect.WriteToSaveGame( savefile );
  2991. backColor.WriteToSaveGame( savefile );
  2992. matColor.WriteToSaveGame( savefile );
  2993. foreColor.WriteToSaveGame( savefile );
  2994. hoverColor.WriteToSaveGame( savefile );
  2995. borderColor.WriteToSaveGame( savefile );
  2996. textScale.WriteToSaveGame( savefile );
  2997. noEvents.WriteToSaveGame( savefile );
  2998. rotate.WriteToSaveGame( savefile );
  2999. text.WriteToSaveGame( savefile );
  3000. backGroundName.WriteToSaveGame( savefile );
  3001. hideCursor.WriteToSaveGame(savefile);
  3002. // Defined Vars
  3003. for ( i = 0; i < definedVars.Num(); i++ ) {
  3004. definedVars[i]->WriteToSaveGame( savefile );
  3005. }
  3006. savefile->Write( &textRect, sizeof( textRect ) );
  3007. // Window pointers saved as the child ID of the window
  3008. int winID;
  3009. winID = focusedChild ? focusedChild->childID : -1 ;
  3010. savefile->Write( &winID, sizeof( winID ) );
  3011. winID = captureChild ? captureChild->childID : -1 ;
  3012. savefile->Write( &winID, sizeof( winID ) );
  3013. winID = overChild ? overChild->childID : -1 ;
  3014. savefile->Write( &winID, sizeof( winID ) );
  3015. // Scripts
  3016. for ( i = 0; i < SCRIPT_COUNT; i++ ) {
  3017. if ( scripts[i] ) {
  3018. scripts[i]->WriteToSaveGame( savefile );
  3019. }
  3020. }
  3021. // TimeLine Events
  3022. for ( i = 0; i < timeLineEvents.Num(); i++ ) {
  3023. if ( timeLineEvents[i] ) {
  3024. savefile->Write( &timeLineEvents[i]->pending, sizeof( timeLineEvents[i]->pending ) );
  3025. savefile->Write( &timeLineEvents[i]->time, sizeof( timeLineEvents[i]->time ) );
  3026. if ( timeLineEvents[i]->event ) {
  3027. timeLineEvents[i]->event->WriteToSaveGame( savefile );
  3028. }
  3029. }
  3030. }
  3031. // Transitions
  3032. int num = transitions.Num();
  3033. savefile->Write( &num, sizeof( num ) );
  3034. for ( i = 0; i < transitions.Num(); i++ ) {
  3035. WriteSaveGameTransition( transitions[ i ], savefile );
  3036. }
  3037. // Named Events
  3038. for ( i = 0; i < namedEvents.Num(); i++ ) {
  3039. if ( namedEvents[i] ) {
  3040. WriteSaveGameString( namedEvents[i]->mName, savefile );
  3041. if ( namedEvents[i]->mEvent ) {
  3042. namedEvents[i]->mEvent->WriteToSaveGame( savefile );
  3043. }
  3044. }
  3045. }
  3046. // regList
  3047. regList.WriteToSaveGame( savefile );
  3048. if ( background ) {
  3049. savefile->WriteInt( background->GetCinematicStartTime() );
  3050. } else {
  3051. savefile->WriteInt( -1 );
  3052. }
  3053. // Save children
  3054. for ( i = 0; i < drawWindows.Num(); i++ ) {
  3055. drawWin_t window = drawWindows[i];
  3056. if ( window.simp ) {
  3057. window.simp->WriteToSaveGame( savefile );
  3058. } else if ( window.win ) {
  3059. window.win->WriteToSaveGame( savefile );
  3060. }
  3061. }
  3062. }
  3063. /*
  3064. ===============
  3065. idWindow::ReadSaveGameString
  3066. ===============
  3067. */
  3068. void idWindow::ReadSaveGameString( idStr &string, idFile *savefile ) {
  3069. int len;
  3070. savefile->Read( &len, sizeof( len ) );
  3071. if ( len < 0 ) {
  3072. common->Warning( "idWindow::ReadSaveGameString: invalid length" );
  3073. }
  3074. string.Fill( ' ', len );
  3075. savefile->Read( &string[0], len );
  3076. }
  3077. /*
  3078. ===============
  3079. idWindow::ReadFromSaveGame
  3080. ===============
  3081. */
  3082. void idWindow::ReadFromSaveGame( idFile *savefile ) {
  3083. int i;
  3084. transitions.Clear();
  3085. ReadSaveGameString( cmd, savefile );
  3086. savefile->Read( &actualX, sizeof( actualX ) );
  3087. savefile->Read( &actualY, sizeof( actualY ) );
  3088. savefile->Read( &childID, sizeof( childID ) );
  3089. savefile->Read( &flags, sizeof( flags ) );
  3090. savefile->Read( &lastTimeRun, sizeof( lastTimeRun ) );
  3091. savefile->Read( &drawRect, sizeof( drawRect ) );
  3092. savefile->Read( &clientRect, sizeof( clientRect ) );
  3093. savefile->Read( &origin, sizeof( origin ) );
  3094. /* if ( savefile->GetFileVersion() < BUILD_NUMBER_8TH_ANNIVERSARY_1 ) {
  3095. unsigned char fontNum;
  3096. savefile->Read( &fontNum, sizeof( fontNum ) );
  3097. font = renderSystem->RegisterFont( "" );
  3098. }*/
  3099. savefile->Read( &timeLine, sizeof( timeLine ) );
  3100. savefile->Read( &xOffset, sizeof( xOffset ) );
  3101. savefile->Read( &yOffset, sizeof( yOffset ) );
  3102. savefile->Read( &cursor, sizeof( cursor ) );
  3103. savefile->Read( &forceAspectWidth, sizeof( forceAspectWidth ) );
  3104. savefile->Read( &forceAspectHeight, sizeof( forceAspectHeight ) );
  3105. savefile->Read( &matScalex, sizeof( matScalex ) );
  3106. savefile->Read( &matScaley, sizeof( matScaley ) );
  3107. savefile->Read( &borderSize, sizeof( borderSize ) );
  3108. savefile->Read( &textAlign, sizeof( textAlign ) );
  3109. savefile->Read( &textAlignx, sizeof( textAlignx ) );
  3110. savefile->Read( &textAligny, sizeof( textAligny ) );
  3111. savefile->Read( &textShadow, sizeof( textShadow ) );
  3112. savefile->Read( &shear, sizeof( shear ) );
  3113. // if ( savefile->GetFileVersion() >= BUILD_NUMBER_8TH_ANNIVERSARY_1 ) {
  3114. idStr fontName;
  3115. savefile->ReadString( fontName );
  3116. font = renderSystem->RegisterFont( fontName );
  3117. // }
  3118. ReadSaveGameString( name, savefile );
  3119. ReadSaveGameString( comment, savefile );
  3120. // WinVars
  3121. noTime.ReadFromSaveGame( savefile );
  3122. visible.ReadFromSaveGame( savefile );
  3123. rect.ReadFromSaveGame( savefile );
  3124. backColor.ReadFromSaveGame( savefile );
  3125. matColor.ReadFromSaveGame( savefile );
  3126. foreColor.ReadFromSaveGame( savefile );
  3127. hoverColor.ReadFromSaveGame( savefile );
  3128. borderColor.ReadFromSaveGame( savefile );
  3129. textScale.ReadFromSaveGame( savefile );
  3130. noEvents.ReadFromSaveGame( savefile );
  3131. rotate.ReadFromSaveGame( savefile );
  3132. text.ReadFromSaveGame( savefile );
  3133. backGroundName.ReadFromSaveGame( savefile );
  3134. hideCursor.ReadFromSaveGame(savefile);
  3135. // Defined Vars
  3136. for ( i = 0; i < definedVars.Num(); i++ ) {
  3137. definedVars[i]->ReadFromSaveGame( savefile );
  3138. }
  3139. savefile->Read( &textRect, sizeof( textRect ) );
  3140. // Window pointers saved as the child ID of the window
  3141. int winID = -1;
  3142. savefile->Read( &winID, sizeof( winID ) );
  3143. for ( i = 0; i < children.Num(); i++ ) {
  3144. if ( children[i]->childID == winID ) {
  3145. focusedChild = children[i];
  3146. }
  3147. }
  3148. savefile->Read( &winID, sizeof( winID ) );
  3149. for ( i = 0; i < children.Num(); i++ ) {
  3150. if ( children[i]->childID == winID ) {
  3151. captureChild = children[i];
  3152. }
  3153. }
  3154. savefile->Read( &winID, sizeof( winID ) );
  3155. for ( i = 0; i < children.Num(); i++ ) {
  3156. if ( children[i]->childID == winID ) {
  3157. overChild = children[i];
  3158. }
  3159. }
  3160. // Scripts
  3161. for ( i = 0; i < SCRIPT_COUNT; i++ ) {
  3162. if ( scripts[i] ) {
  3163. scripts[i]->ReadFromSaveGame( savefile );
  3164. }
  3165. }
  3166. // TimeLine Events
  3167. for ( i = 0; i < timeLineEvents.Num(); i++ ) {
  3168. if ( timeLineEvents[i] ) {
  3169. savefile->Read( &timeLineEvents[i]->pending, sizeof( timeLineEvents[i]->pending ) );
  3170. savefile->Read( &timeLineEvents[i]->time, sizeof( timeLineEvents[i]->time ) );
  3171. if ( timeLineEvents[i]->event ) {
  3172. timeLineEvents[i]->event->ReadFromSaveGame( savefile );
  3173. }
  3174. }
  3175. }
  3176. // Transitions
  3177. int num;
  3178. savefile->Read( &num, sizeof( num ) );
  3179. for ( i = 0; i < num; i++ ) {
  3180. idTransitionData trans;
  3181. trans.data = NULL;
  3182. ReadSaveGameTransition( trans, savefile );
  3183. if ( trans.data ) {
  3184. transitions.Append( trans );
  3185. }
  3186. }
  3187. // Named Events
  3188. for ( i = 0; i < namedEvents.Num(); i++ ) {
  3189. if ( namedEvents[i] ) {
  3190. ReadSaveGameString( namedEvents[i]->mName, savefile );
  3191. if ( namedEvents[i]->mEvent ) {
  3192. namedEvents[i]->mEvent->ReadFromSaveGame( savefile );
  3193. }
  3194. }
  3195. }
  3196. // regList
  3197. regList.ReadFromSaveGame( savefile );
  3198. int cinematicStartTime = 0;
  3199. savefile->ReadInt( cinematicStartTime );
  3200. if ( background ) {
  3201. background->ResetCinematicTime( cinematicStartTime );
  3202. }
  3203. // Read children
  3204. for ( i = 0; i < drawWindows.Num(); i++ ) {
  3205. drawWin_t window = drawWindows[i];
  3206. if ( window.simp ) {
  3207. window.simp->ReadFromSaveGame( savefile );
  3208. } else if ( window.win ) {
  3209. window.win->ReadFromSaveGame( savefile );
  3210. }
  3211. }
  3212. if ( flags & WIN_DESKTOP ) {
  3213. FixupTransitions();
  3214. }
  3215. }
  3216. /*
  3217. ===============
  3218. idWindow::NumTransitions
  3219. ===============
  3220. */
  3221. int idWindow::NumTransitions() {
  3222. int c = transitions.Num();
  3223. for ( int i = 0; i < children.Num(); i++ ) {
  3224. c += children[i]->NumTransitions();
  3225. }
  3226. return c;
  3227. }
  3228. /*
  3229. ===============
  3230. idWindow::FixupTransitions
  3231. ===============
  3232. */
  3233. void idWindow::FixupTransitions() {
  3234. int i, c = transitions.Num();
  3235. for ( i = 0; i < c; i++ ) {
  3236. drawWin_t *dw = gui->GetDesktop()->FindChildByName( ( ( idWinStr* )transitions[i].data )->c_str() );
  3237. delete transitions[i].data;
  3238. transitions[i].data = NULL;
  3239. if ( dw != NULL && ( dw->win != NULL || dw->simp != NULL ) ){
  3240. if ( dw->win != NULL ) {
  3241. if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->rect ) {
  3242. transitions[i].data = &dw->win->rect;
  3243. } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->backColor ) {
  3244. transitions[i].data = &dw->win->backColor;
  3245. } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->matColor ) {
  3246. transitions[i].data = &dw->win->matColor;
  3247. } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->foreColor ) {
  3248. transitions[i].data = &dw->win->foreColor;
  3249. } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->borderColor ) {
  3250. transitions[i].data = &dw->win->borderColor;
  3251. } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->textScale ) {
  3252. transitions[i].data = &dw->win->textScale;
  3253. } else if ( transitions[i].offset == (int)&( ( idWindow * ) 0 )->rotate ) {
  3254. transitions[i].data = &dw->win->rotate;
  3255. }
  3256. } else {
  3257. if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->rect ) {
  3258. transitions[i].data = &dw->simp->rect;
  3259. } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->backColor ) {
  3260. transitions[i].data = &dw->simp->backColor;
  3261. } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->matColor ) {
  3262. transitions[i].data = &dw->simp->matColor;
  3263. } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->foreColor ) {
  3264. transitions[i].data = &dw->simp->foreColor;
  3265. } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->borderColor ) {
  3266. transitions[i].data = &dw->simp->borderColor;
  3267. } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->textScale ) {
  3268. transitions[i].data = &dw->simp->textScale;
  3269. } else if ( transitions[i].offset == (int)&( ( idSimpleWindow * ) 0 )->rotate ) {
  3270. transitions[i].data = &dw->simp->rotate;
  3271. }
  3272. }
  3273. }
  3274. if ( transitions[i].data == NULL ) {
  3275. transitions.RemoveIndex( i );
  3276. i--;
  3277. c--;
  3278. }
  3279. }
  3280. for ( c = 0; c < children.Num(); c++ ) {
  3281. children[c]->FixupTransitions();
  3282. }
  3283. }
  3284. /*
  3285. ===============
  3286. idWindow::AddChild
  3287. ===============
  3288. */
  3289. void idWindow::AddChild(idWindow *win) {
  3290. win->childID = children.Append(win);
  3291. }
  3292. /*
  3293. ================
  3294. idWindow::FixupParms
  3295. ================
  3296. */
  3297. void idWindow::FixupParms() {
  3298. int i;
  3299. int c = children.Num();
  3300. for (i = 0; i < c; i++) {
  3301. children[i]->FixupParms();
  3302. }
  3303. for (i = 0; i < SCRIPT_COUNT; i++) {
  3304. if (scripts[i]) {
  3305. scripts[i]->FixupParms(this);
  3306. }
  3307. }
  3308. c = timeLineEvents.Num();
  3309. for (i = 0; i < c; i++) {
  3310. timeLineEvents[i]->event->FixupParms(this);
  3311. }
  3312. c = namedEvents.Num();
  3313. for (i = 0; i < c; i++) {
  3314. namedEvents[i]->mEvent->FixupParms(this);
  3315. }
  3316. c = ops.Num();
  3317. for (i = 0; i < c; i++) {
  3318. if (ops[i].b == -2) {
  3319. // need to fix this up
  3320. const char *p = (const char*)(ops[i].a);
  3321. idWinVar *var = GetWinVarByName(p, true);
  3322. delete []p;
  3323. ops[i].a = (int)var;
  3324. ops[i].b = -1;
  3325. }
  3326. }
  3327. if (flags & WIN_DESKTOP) {
  3328. CalcRects(0,0);
  3329. }
  3330. }
  3331. /*
  3332. ================
  3333. idWindow::IsSimple
  3334. ================
  3335. */
  3336. bool idWindow::IsSimple() {
  3337. if (ops.Num()) {
  3338. return false;
  3339. }
  3340. if (flags & (WIN_HCENTER | WIN_VCENTER)) {
  3341. return false;
  3342. }
  3343. if (children.Num() || drawWindows.Num()) {
  3344. return false;
  3345. }
  3346. for (int i = 0; i < SCRIPT_COUNT; i++) {
  3347. if (scripts[i]) {
  3348. return false;
  3349. }
  3350. }
  3351. if (timeLineEvents.Num()) {
  3352. return false;
  3353. }
  3354. if ( namedEvents.Num() ) {
  3355. return false;
  3356. }
  3357. return true;
  3358. }
  3359. /*
  3360. ================
  3361. idWindow::ContainsStateVars
  3362. ================
  3363. */
  3364. bool idWindow::ContainsStateVars() {
  3365. if ( updateVars.Num() ) {
  3366. return true;
  3367. }
  3368. int c = children.Num();
  3369. for (int i = 0; i < c; i++) {
  3370. if ( children[i]->ContainsStateVars() ) {
  3371. return true;
  3372. }
  3373. }
  3374. return false;
  3375. }
  3376. /*
  3377. ================
  3378. idWindow::Interactive
  3379. ================
  3380. */
  3381. bool idWindow::Interactive() {
  3382. if ( scripts[ ON_ACTION ] ) {
  3383. return true;
  3384. }
  3385. int c = children.Num();
  3386. for (int i = 0; i < c; i++) {
  3387. if (children[i]->Interactive()) {
  3388. return true;
  3389. }
  3390. }
  3391. return false;
  3392. }
  3393. /*
  3394. ================
  3395. idWindow::SetChildWinVarVal
  3396. ================
  3397. */
  3398. void idWindow::SetChildWinVarVal(const char *name, const char *var, const char *val) {
  3399. drawWin_t *dw = FindChildByName(name);
  3400. idWinVar *wv = NULL;
  3401. if (dw != NULL && dw->simp != NULL) {
  3402. wv = dw->simp->GetWinVarByName(var);
  3403. } else if (dw != NULL && dw->win != NULL) {
  3404. wv = dw->win->GetWinVarByName(var);
  3405. }
  3406. if (wv) {
  3407. wv->Set(val);
  3408. wv->SetEval(false);
  3409. }
  3410. }
  3411. /*
  3412. ================
  3413. idWindow::FindChildByPoint
  3414. Finds the window under the given point
  3415. ================
  3416. */
  3417. idWindow* idWindow::FindChildByPoint ( float x, float y, idWindow** below ) {
  3418. int c = children.Num();
  3419. // If we are looking for a window below this one then
  3420. // the next window should be good, but this one wasnt it
  3421. if ( *below == this ) {
  3422. *below = NULL;
  3423. return NULL;
  3424. }
  3425. if ( !Contains ( drawRect, x, y ) ) {
  3426. return NULL;
  3427. }
  3428. for (int i = c - 1; i >= 0 ; i-- ) {
  3429. idWindow* found = children[i]->FindChildByPoint ( x, y, below );
  3430. if ( found ) {
  3431. if ( *below ) {
  3432. continue;
  3433. }
  3434. return found;
  3435. }
  3436. }
  3437. return this;
  3438. }
  3439. /*
  3440. ================
  3441. idWindow::FindChildByPoint
  3442. ================
  3443. */
  3444. idWindow* idWindow::FindChildByPoint ( float x, float y, idWindow* below )
  3445. {
  3446. return FindChildByPoint ( x, y, &below );
  3447. }
  3448. /*
  3449. ================
  3450. idWindow::GetChildCount
  3451. Returns the number of children
  3452. ================
  3453. */
  3454. int idWindow::GetChildCount ()
  3455. {
  3456. return drawWindows.Num ( );
  3457. }
  3458. /*
  3459. ================
  3460. idWindow::GetChild
  3461. Returns the child window at the given index
  3462. ================
  3463. */
  3464. idWindow* idWindow::GetChild ( int index )
  3465. {
  3466. return drawWindows[index].win;
  3467. }
  3468. /*
  3469. ================
  3470. idWindow::GetChildIndex
  3471. Returns the index of the given child window
  3472. ================
  3473. */
  3474. int idWindow::GetChildIndex ( idWindow* window ) {
  3475. int find;
  3476. for ( find = 0; find < drawWindows.Num(); find ++ ) {
  3477. if ( drawWindows[find].win == window ) {
  3478. return find;
  3479. }
  3480. }
  3481. return -1;
  3482. }
  3483. /*
  3484. ================
  3485. idWindow::RemoveChild
  3486. Removes the child from the list of children. Note that the child window being
  3487. removed must still be deallocated by the caller
  3488. ================
  3489. */
  3490. void idWindow::RemoveChild ( idWindow *win ) {
  3491. int find;
  3492. // Remove the child window
  3493. children.Remove ( win );
  3494. for ( find = 0; find < drawWindows.Num(); find ++ )
  3495. {
  3496. if ( drawWindows[find].win == win )
  3497. {
  3498. drawWindows.RemoveIndex ( find );
  3499. break;
  3500. }
  3501. }
  3502. }
  3503. /*
  3504. ================
  3505. idWindow::InsertChild
  3506. Inserts the given window as a child into the given location in the zorder.
  3507. ================
  3508. */
  3509. bool idWindow::InsertChild ( idWindow *win, idWindow* before )
  3510. {
  3511. AddChild ( win );
  3512. win->parent = this;
  3513. drawWin_t dwt;
  3514. dwt.simp = NULL;
  3515. dwt.win = win;
  3516. // If not inserting before anything then just add it at the end
  3517. if ( before ) {
  3518. int index;
  3519. index = GetChildIndex ( before );
  3520. if ( index != -1 ) {
  3521. drawWindows.Insert ( dwt, index );
  3522. return true;
  3523. }
  3524. }
  3525. drawWindows.Append ( dwt );
  3526. return true;
  3527. }
  3528. /*
  3529. ================
  3530. idWindow::ScreenToClient
  3531. ================
  3532. */
  3533. void idWindow::ScreenToClient ( idRectangle* r ) {
  3534. int x;
  3535. int y;
  3536. idWindow* p;
  3537. for ( p = this, x = 0, y = 0; p; p = p->parent ) {
  3538. x += p->rect.x();
  3539. y += p->rect.y();
  3540. }
  3541. r->x -= x;
  3542. r->y -= y;
  3543. }
  3544. /*
  3545. ================
  3546. idWindow::ClientToScreen
  3547. ================
  3548. */
  3549. void idWindow::ClientToScreen ( idRectangle* r ) {
  3550. int x;
  3551. int y;
  3552. idWindow* p;
  3553. for ( p = this, x = 0, y = 0; p; p = p->parent ) {
  3554. x += p->rect.x();
  3555. y += p->rect.y();
  3556. }
  3557. r->x += x;
  3558. r->y += y;
  3559. }
  3560. /*
  3561. ================
  3562. idWindow::SetDefaults
  3563. Set the window do a default window with no text, no background and
  3564. default colors, etc..
  3565. ================
  3566. */
  3567. void idWindow::SetDefaults () {
  3568. forceAspectWidth = 640.0f;
  3569. forceAspectHeight = 480.0f;
  3570. matScalex = 1;
  3571. matScaley = 1;
  3572. borderSize = 0;
  3573. noTime = false;
  3574. visible = true;
  3575. textAlign = 0;
  3576. textAlignx = 0;
  3577. textAligny = 0;
  3578. noEvents = false;
  3579. rotate = 0;
  3580. shear.Zero();
  3581. textScale = 0.35f;
  3582. backColor.Zero();
  3583. foreColor = idVec4(1, 1, 1, 1);
  3584. hoverColor = idVec4(1, 1, 1, 1);
  3585. matColor = idVec4(1, 1, 1, 1);
  3586. borderColor.Zero();
  3587. text = "";
  3588. background = NULL;
  3589. backGroundName = "";
  3590. }
  3591. /*
  3592. ================
  3593. idWindow::UpdateFromDictionary
  3594. The editor only has a dictionary to work with so the easiest way to push the
  3595. values of the dictionary onto the window is for the window to interpret the
  3596. dictionary as if were a file being parsed.
  3597. ================
  3598. */
  3599. bool idWindow::UpdateFromDictionary ( idDict& dict ) {
  3600. const idKeyValue* kv;
  3601. int i;
  3602. SetDefaults ( );
  3603. // Clear all registers since they will get recreated
  3604. regList.Reset ( );
  3605. expressionRegisters.Clear ( );
  3606. ops.Clear ( );
  3607. for ( i = 0; i < dict.GetNumKeyVals(); i ++ ) {
  3608. kv = dict.GetKeyVal ( i );
  3609. // Special case name
  3610. if ( !kv->GetKey().Icmp ( "name" ) ) {
  3611. name = kv->GetValue();
  3612. continue;
  3613. }
  3614. idParser src( kv->GetValue().c_str(), kv->GetValue().Length(), "",
  3615. LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
  3616. idTokenParser src2;
  3617. src2.LoadFromParser( src, "temp" );
  3618. src2.StartParsing( "temp" );
  3619. if ( !ParseInternalVar ( kv->GetKey(), &src2 ) ) {
  3620. // Kill the old register since the parse reg entry will add a new one
  3621. if ( !ParseRegEntry ( kv->GetKey(), &src2 ) ) {
  3622. continue;
  3623. }
  3624. }
  3625. }
  3626. EvalRegs(-1, true);
  3627. SetupFromState();
  3628. PostParse();
  3629. return true;
  3630. }