Window.cpp 102 KB

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