editor_node.cpp 191 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954
  1. /*************************************************************************/
  2. /* editor_node.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "editor_node.h"
  31. #include "core/bind/core_bind.h"
  32. #include "core/class_db.h"
  33. #include "core/io/config_file.h"
  34. #include "core/io/resource_loader.h"
  35. #include "core/io/resource_saver.h"
  36. #include "core/io/stream_peer_ssl.h"
  37. #include "core/message_queue.h"
  38. #include "core/os/file_access.h"
  39. #include "core/os/input.h"
  40. #include "core/os/keyboard.h"
  41. #include "core/os/os.h"
  42. #include "core/path_remap.h"
  43. #include "core/print_string.h"
  44. #include "core/project_settings.h"
  45. #include "core/translation.h"
  46. #include "core/version.h"
  47. #include "main/input_default.h"
  48. #include "scene/resources/packed_scene.h"
  49. #include "servers/physics_2d_server.h"
  50. #include "editor/editor_audio_buses.h"
  51. #include "editor/editor_file_system.h"
  52. #include "editor/editor_help.h"
  53. #include "editor/editor_properties.h"
  54. #include "editor/editor_settings.h"
  55. #include "editor/editor_themes.h"
  56. #include "editor/import/editor_import_collada.h"
  57. #include "editor/import/editor_scene_importer_gltf.h"
  58. #include "editor/import/resource_importer_bitmask.h"
  59. #include "editor/import/resource_importer_csv_translation.h"
  60. #include "editor/import/resource_importer_image.h"
  61. #include "editor/import/resource_importer_layered_texture.h"
  62. #include "editor/import/resource_importer_obj.h"
  63. #include "editor/import/resource_importer_scene.h"
  64. #include "editor/import/resource_importer_texture.h"
  65. #include "editor/import/resource_importer_wav.h"
  66. #include "editor/plugins/animation_blend_space_1d_editor.h"
  67. #include "editor/plugins/animation_blend_space_2d_editor.h"
  68. #include "editor/plugins/animation_blend_tree_editor_plugin.h"
  69. #include "editor/plugins/animation_player_editor_plugin.h"
  70. #include "editor/plugins/animation_state_machine_editor.h"
  71. #include "editor/plugins/animation_tree_editor_plugin.h"
  72. #include "editor/plugins/animation_tree_player_editor_plugin.h"
  73. #include "editor/plugins/asset_library_editor_plugin.h"
  74. #include "editor/plugins/audio_stream_editor_plugin.h"
  75. #include "editor/plugins/baked_lightmap_editor_plugin.h"
  76. #include "editor/plugins/camera_editor_plugin.h"
  77. #include "editor/plugins/canvas_item_editor_plugin.h"
  78. #include "editor/plugins/collision_polygon_2d_editor_plugin.h"
  79. #include "editor/plugins/collision_polygon_editor_plugin.h"
  80. #include "editor/plugins/collision_shape_2d_editor_plugin.h"
  81. #include "editor/plugins/cpu_particles_editor_plugin.h"
  82. #include "editor/plugins/curve_editor_plugin.h"
  83. #include "editor/plugins/editor_preview_plugins.h"
  84. #include "editor/plugins/gi_probe_editor_plugin.h"
  85. #include "editor/plugins/gradient_editor_plugin.h"
  86. #include "editor/plugins/item_list_editor_plugin.h"
  87. #include "editor/plugins/light_occluder_2d_editor_plugin.h"
  88. #include "editor/plugins/line_2d_editor_plugin.h"
  89. #include "editor/plugins/material_editor_plugin.h"
  90. #include "editor/plugins/mesh_editor_plugin.h"
  91. #include "editor/plugins/mesh_instance_editor_plugin.h"
  92. #include "editor/plugins/mesh_library_editor_plugin.h"
  93. #include "editor/plugins/multimesh_editor_plugin.h"
  94. #include "editor/plugins/navigation_polygon_editor_plugin.h"
  95. #include "editor/plugins/particles_2d_editor_plugin.h"
  96. #include "editor/plugins/particles_editor_plugin.h"
  97. #include "editor/plugins/path_2d_editor_plugin.h"
  98. #include "editor/plugins/path_editor_plugin.h"
  99. #include "editor/plugins/physical_bone_plugin.h"
  100. #include "editor/plugins/polygon_2d_editor_plugin.h"
  101. #include "editor/plugins/resource_preloader_editor_plugin.h"
  102. #include "editor/plugins/root_motion_editor_plugin.h"
  103. #include "editor/plugins/script_editor_plugin.h"
  104. #include "editor/plugins/script_text_editor.h"
  105. #include "editor/plugins/shader_editor_plugin.h"
  106. #include "editor/plugins/skeleton_2d_editor_plugin.h"
  107. #include "editor/plugins/skeleton_editor_plugin.h"
  108. #include "editor/plugins/skeleton_ik_editor_plugin.h"
  109. #include "editor/plugins/spatial_editor_plugin.h"
  110. #include "editor/plugins/sprite_editor_plugin.h"
  111. #include "editor/plugins/sprite_frames_editor_plugin.h"
  112. #include "editor/plugins/style_box_editor_plugin.h"
  113. #include "editor/plugins/text_editor.h"
  114. #include "editor/plugins/texture_editor_plugin.h"
  115. #include "editor/plugins/texture_region_editor_plugin.h"
  116. #include "editor/plugins/theme_editor_plugin.h"
  117. #include "editor/plugins/tile_map_editor_plugin.h"
  118. #include "editor/plugins/tile_set_editor_plugin.h"
  119. #include "editor/plugins/visual_shader_editor_plugin.h"
  120. #include "editor/pvrtc_compress.h"
  121. #include "editor/register_exporters.h"
  122. #include "editor/script_editor_debugger.h"
  123. #include <stdio.h>
  124. EditorNode *EditorNode::singleton = NULL;
  125. void EditorNode::_update_scene_tabs() {
  126. bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button");
  127. scene_tabs->clear_tabs();
  128. Ref<Texture> script_icon = gui_base->get_icon("Script", "EditorIcons");
  129. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  130. String type = editor_data.get_scene_type(i);
  131. Ref<Texture> icon;
  132. if (type != String()) {
  133. icon = get_class_icon(type, "Node");
  134. }
  135. int current = editor_data.get_edited_scene();
  136. bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
  137. scene_tabs->add_tab(editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), icon);
  138. if (show_rb && editor_data.get_scene_root_script(i).is_valid()) {
  139. scene_tabs->set_tab_right_button(i, script_icon);
  140. }
  141. }
  142. scene_tabs->set_current_tab(editor_data.get_edited_scene());
  143. if (scene_tabs->get_offset_buttons_visible()) {
  144. // move add button to fixed position on the tabbar
  145. if (scene_tab_add->get_parent() == scene_tabs) {
  146. scene_tab_add->set_position(Point2(0, 0));
  147. scene_tabs->remove_child(scene_tab_add);
  148. tabbar_container->add_child(scene_tab_add);
  149. tabbar_container->move_child(scene_tab_add, 1);
  150. }
  151. } else {
  152. // move add button to after last tab
  153. if (scene_tab_add->get_parent() == tabbar_container) {
  154. tabbar_container->remove_child(scene_tab_add);
  155. scene_tabs->add_child(scene_tab_add);
  156. }
  157. Rect2 last_tab = Rect2();
  158. if (scene_tabs->get_tab_count() != 0)
  159. last_tab = scene_tabs->get_tab_rect(scene_tabs->get_tab_count() - 1);
  160. scene_tab_add->set_position(Point2(last_tab.get_position().x + last_tab.get_size().x + 3, last_tab.get_position().y));
  161. }
  162. }
  163. void EditorNode::_update_title() {
  164. String appname = ProjectSettings::get_singleton()->get("application/config/name");
  165. String title = appname.empty() ? String(VERSION_FULL_NAME) : String(VERSION_NAME + String(" - ") + appname);
  166. String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String();
  167. if (!edited.empty())
  168. title += " - " + String(edited.get_file());
  169. if (unsaved_cache)
  170. title += " (*)";
  171. OS::get_singleton()->set_window_title(title);
  172. }
  173. void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
  174. if (Node::get_viewport()->get_modal_stack_top())
  175. return; //ignore because of modal window
  176. Ref<InputEventKey> k = p_event;
  177. if (k.is_valid() && k->is_pressed() && !k->is_echo() && !gui_base->get_viewport()->gui_has_modal_stack()) {
  178. EditorPlugin *old_editor = editor_plugin_screen;
  179. if (ED_IS_SHORTCUT("editor/next_tab", p_event)) {
  180. int next_tab = editor_data.get_edited_scene() + 1;
  181. next_tab %= editor_data.get_edited_scene_count();
  182. _scene_tab_changed(next_tab);
  183. }
  184. if (ED_IS_SHORTCUT("editor/prev_tab", p_event)) {
  185. int next_tab = editor_data.get_edited_scene() - 1;
  186. next_tab = next_tab >= 0 ? next_tab : editor_data.get_edited_scene_count() - 1;
  187. _scene_tab_changed(next_tab);
  188. }
  189. if (ED_IS_SHORTCUT("editor/filter_files", p_event)) {
  190. filesystem_dock->focus_on_filter();
  191. }
  192. if (ED_IS_SHORTCUT("editor/editor_2d", p_event)) {
  193. _editor_select(EDITOR_2D);
  194. } else if (ED_IS_SHORTCUT("editor/editor_3d", p_event)) {
  195. _editor_select(EDITOR_3D);
  196. } else if (ED_IS_SHORTCUT("editor/editor_script", p_event)) {
  197. _editor_select(EDITOR_SCRIPT);
  198. } else if (ED_IS_SHORTCUT("editor/editor_help", p_event)) {
  199. emit_signal("request_help_search", "");
  200. } else if (ED_IS_SHORTCUT("editor/editor_assetlib", p_event)) {
  201. _editor_select(EDITOR_ASSETLIB);
  202. } else if (ED_IS_SHORTCUT("editor/editor_next", p_event)) {
  203. _editor_select_next();
  204. } else if (ED_IS_SHORTCUT("editor/editor_prev", p_event)) {
  205. _editor_select_prev();
  206. }
  207. if (old_editor != editor_plugin_screen) {
  208. get_tree()->set_input_as_handled();
  209. }
  210. }
  211. }
  212. void EditorNode::_notification(int p_what) {
  213. if (p_what == NOTIFICATION_EXIT_TREE) {
  214. editor_data.save_editor_external_data();
  215. FileAccess::set_file_close_fail_notify_callback(NULL);
  216. log->deinit(); // do not get messages anymore
  217. }
  218. if (p_what == NOTIFICATION_PROCESS) {
  219. if (opening_prev && !confirmation->is_visible())
  220. opening_prev = false;
  221. if (unsaved_cache != (saved_version != editor_data.get_undo_redo().get_version())) {
  222. unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version());
  223. _update_title();
  224. }
  225. if (last_checked_version != editor_data.get_undo_redo().get_version()) {
  226. _update_scene_tabs();
  227. last_checked_version = editor_data.get_undo_redo().get_version();
  228. }
  229. //update the circle
  230. uint64_t frame = Engine::get_singleton()->get_frames_drawn();
  231. uint32_t tick = OS::get_singleton()->get_ticks_msec();
  232. if (frame != circle_step_frame && (tick - circle_step_msec) > (1000 / 8)) {
  233. circle_step++;
  234. if (circle_step >= 8)
  235. circle_step = 0;
  236. circle_step_msec = tick;
  237. circle_step_frame = frame + 1;
  238. // update the circle itself only when its enabled
  239. if (!update_menu->get_popup()->is_item_checked(3)) {
  240. update_menu->set_icon(gui_base->get_icon("Progress" + itos(circle_step + 1), "EditorIcons"));
  241. }
  242. }
  243. editor_selection->update();
  244. scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")));
  245. ResourceImporterTexture::get_singleton()->update_imports();
  246. }
  247. if (p_what == NOTIFICATION_ENTER_TREE) {
  248. Engine::get_singleton()->set_editor_hint(true);
  249. get_tree()->get_root()->set_usage(Viewport::USAGE_2D_NO_SAMPLING); //reduce memory usage
  250. get_tree()->get_root()->set_disable_3d(true);
  251. get_tree()->get_root()->set_as_audio_listener(false);
  252. get_tree()->get_root()->set_as_audio_listener_2d(false);
  253. get_tree()->set_auto_accept_quit(false);
  254. get_tree()->connect("files_dropped", this, "_dropped_files");
  255. }
  256. if (p_what == NOTIFICATION_EXIT_TREE) {
  257. editor_data.clear_edited_scenes();
  258. }
  259. if (p_what == NOTIFICATION_READY) {
  260. VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport_rid(), true);
  261. VisualServer::get_singleton()->viewport_set_hide_canvas(get_scene_root()->get_viewport_rid(), true);
  262. VisualServer::get_singleton()->viewport_set_disable_environment(get_viewport()->get_viewport_rid(), true);
  263. _editor_select(EDITOR_3D);
  264. _update_debug_options();
  265. _load_docks();
  266. }
  267. if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
  268. EditorFileSystem::get_singleton()->scan_changes();
  269. }
  270. if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) {
  271. _menu_option_confirm(FILE_QUIT, false);
  272. }
  273. if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
  274. scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
  275. Ref<Theme> theme = create_editor_theme(theme_base->get_theme());
  276. theme_base->set_theme(theme);
  277. gui_base->set_theme(theme);
  278. gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles"));
  279. play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles"));
  280. scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
  281. bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
  282. scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
  283. scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
  284. file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  285. project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  286. debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  287. settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  288. help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  289. if (EDITOR_GET("interface/scene_tabs/resize_if_many_tabs")) {
  290. scene_tabs->set_min_width(int(EDITOR_GET("interface/scene_tabs/minimum_width")) * EDSCALE);
  291. } else {
  292. scene_tabs->set_min_width(0);
  293. }
  294. _update_scene_tabs();
  295. recent_scenes->set_as_minsize();
  296. // debugger area
  297. if (ScriptEditor::get_singleton()->get_debugger()->is_visible())
  298. bottom_panel->add_style_override("panel", gui_base->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles"));
  299. // update_icons
  300. for (int i = 0; i < singleton->main_editor_buttons.size(); i++) {
  301. ToolButton *tb = singleton->main_editor_buttons[i];
  302. EditorPlugin *p_editor = singleton->editor_table[i];
  303. Ref<Texture> icon = p_editor->get_icon();
  304. if (icon.is_valid()) {
  305. tb->set_icon(icon);
  306. } else if (singleton->gui_base->has_icon(p_editor->get_name(), "EditorIcons")) {
  307. tb->set_icon(singleton->gui_base->get_icon(p_editor->get_name(), "EditorIcons"));
  308. }
  309. }
  310. _build_icon_type_cache();
  311. play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons"));
  312. play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
  313. play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
  314. pause_button->set_icon(gui_base->get_icon("Pause", "EditorIcons"));
  315. stop_button->set_icon(gui_base->get_icon("Stop", "EditorIcons"));
  316. prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons"));
  317. distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
  318. scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons"));
  319. // clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); don't have access to that node. needs to become a class property
  320. update_menu->set_icon(gui_base->get_icon("Collapse", "EditorIcons"));
  321. dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons"));
  322. dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons"));
  323. update_menu->set_icon(gui_base->get_icon("Progress1", "EditorIcons"));
  324. PopupMenu *p = help_menu->get_popup();
  325. p->set_item_icon(p->get_item_index(HELP_CLASSES), gui_base->get_icon("ClassList", "EditorIcons"));
  326. p->set_item_icon(p->get_item_index(HELP_SEARCH), gui_base->get_icon("HelpSearch", "EditorIcons"));
  327. p->set_item_icon(p->get_item_index(HELP_DOCS), gui_base->get_icon("Instance", "EditorIcons"));
  328. p->set_item_icon(p->get_item_index(HELP_QA), gui_base->get_icon("Instance", "EditorIcons"));
  329. p->set_item_icon(p->get_item_index(HELP_ISSUES), gui_base->get_icon("Instance", "EditorIcons"));
  330. p->set_item_icon(p->get_item_index(HELP_COMMUNITY), gui_base->get_icon("Instance", "EditorIcons"));
  331. p->set_item_icon(p->get_item_index(HELP_ABOUT), gui_base->get_icon("Godot", "EditorIcons"));
  332. }
  333. if (p_what == Control::NOTIFICATION_RESIZED) {
  334. _update_scene_tabs();
  335. }
  336. }
  337. void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_name) {
  338. Ref<Script> script = Object::cast_to<Script>(p_script);
  339. if (script.is_null())
  340. return;
  341. if (p_activate_name.length()) {
  342. set_addon_plugin_enabled(p_activate_name, true);
  343. }
  344. project_settings->update_plugins();
  345. project_settings->hide();
  346. push_item(script.operator->());
  347. }
  348. void EditorNode::_fs_changed() {
  349. for (Set<FileDialog *>::Element *E = file_dialogs.front(); E; E = E->next()) {
  350. E->get()->invalidate();
  351. }
  352. for (Set<EditorFileDialog *>::Element *E = editor_file_dialogs.front(); E; E = E->next()) {
  353. E->get()->invalidate();
  354. }
  355. {
  356. //reload changed resources
  357. List<Ref<Resource> > changed;
  358. List<Ref<Resource> > cached;
  359. ResourceCache::get_cached_resources(&cached);
  360. // FIXME: This should be done in a thread.
  361. for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) {
  362. if (!E->get()->editor_can_reload_from_file())
  363. continue;
  364. if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path())
  365. continue;
  366. if (!FileAccess::exists(E->get()->get_path()))
  367. continue;
  368. if (E->get()->get_import_path() != String()) {
  369. //this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback
  370. continue;
  371. }
  372. uint64_t mt = FileAccess::get_modified_time(E->get()->get_path());
  373. if (mt != E->get()->get_last_modified_time()) {
  374. changed.push_back(E->get());
  375. }
  376. }
  377. if (changed.size()) {
  378. for (List<Ref<Resource> >::Element *E = changed.front(); E; E = E->next()) {
  379. E->get()->reload_from_file();
  380. }
  381. }
  382. }
  383. _mark_unsaved_scenes();
  384. if (export_defer.preset != "" && !EditorFileSystem::get_singleton()->is_scanning()) {
  385. Ref<EditorExportPreset> preset;
  386. for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); ++i) {
  387. preset = EditorExport::get_singleton()->get_export_preset(i);
  388. if (preset->get_name() == export_defer.preset) {
  389. break;
  390. }
  391. preset.unref();
  392. }
  393. if (preset.is_null()) {
  394. String errstr = "Unknown export preset: " + export_defer.preset;
  395. ERR_PRINTS(errstr);
  396. } else {
  397. Ref<EditorExportPlatform> platform = preset->get_platform();
  398. if (platform.is_null()) {
  399. String errstr = "Preset \"" + export_defer.preset + "\" doesn't have a platform.";
  400. ERR_PRINTS(errstr);
  401. } else {
  402. // ensures export_project does not loop infinitely, because notifications may
  403. // come during the export
  404. export_defer.preset = "";
  405. Error err = OK;
  406. if (export_defer.path.ends_with(".pck") || export_defer.path.ends_with(".zip")) {
  407. if (export_defer.path.ends_with(".zip")) {
  408. err = platform->export_zip(preset, export_defer.debug, export_defer.path);
  409. } else if (export_defer.path.ends_with(".pck")) {
  410. err = platform->export_pack(preset, export_defer.debug, export_defer.path);
  411. }
  412. } else {
  413. err = platform->export_project(preset, export_defer.debug, export_defer.path);
  414. }
  415. if (err != OK) {
  416. ERR_PRINTS(vformat(TTR("Project export failed with error code %d."), (int)err));
  417. }
  418. }
  419. }
  420. get_tree()->quit();
  421. }
  422. }
  423. void EditorNode::_resources_reimported(const Vector<String> &p_resources) {
  424. List<String> scenes; //will load later
  425. for (int i = 0; i < p_resources.size(); i++) {
  426. String file_type = ResourceLoader::get_resource_type(p_resources[i]);
  427. if (file_type == "PackedScene") {
  428. scenes.push_back(p_resources[i]);
  429. //reload later if needed, first go with normal resources
  430. continue;
  431. }
  432. if (!ResourceCache::has(p_resources[i])) {
  433. continue; //not loaded, no need to reload
  434. }
  435. //reload normally
  436. Resource *resource = ResourceCache::get(p_resources[i]);
  437. if (resource) {
  438. resource->reload_from_file();
  439. }
  440. }
  441. for (List<String>::Element *E = scenes.front(); E; E = E->next()) {
  442. reload_scene(E->get());
  443. }
  444. }
  445. void EditorNode::_sources_changed(bool p_exist) {
  446. if (waiting_for_first_scan) {
  447. if (defer_load_scene != "") {
  448. load_scene(defer_load_scene);
  449. defer_load_scene = "";
  450. }
  451. waiting_for_first_scan = false;
  452. }
  453. }
  454. void EditorNode::_vp_resized() {
  455. }
  456. void EditorNode::_node_renamed() {
  457. if (get_inspector())
  458. get_inspector()->update_tree();
  459. }
  460. void EditorNode::_editor_select_next() {
  461. int editor = _get_current_main_editor();
  462. if (editor == editor_table.size() - 1) {
  463. editor = 0;
  464. } else {
  465. editor++;
  466. }
  467. _editor_select(editor);
  468. }
  469. void EditorNode::_editor_select_prev() {
  470. int editor = _get_current_main_editor();
  471. if (editor == 0) {
  472. editor = editor_table.size() - 1;
  473. } else {
  474. editor--;
  475. }
  476. _editor_select(editor);
  477. }
  478. Error EditorNode::load_resource(const String &p_scene) {
  479. RES res = ResourceLoader::load(p_scene);
  480. ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN);
  481. inspector_dock->edit_resource(res);
  482. return OK;
  483. }
  484. void EditorNode::edit_node(Node *p_node) {
  485. push_item(p_node);
  486. }
  487. void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) {
  488. editor_data.apply_changes_in_editors();
  489. int flg = 0;
  490. if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
  491. flg |= ResourceSaver::FLAG_COMPRESS;
  492. String path = ProjectSettings::get_singleton()->localize_path(p_path);
  493. Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
  494. if (err != OK) {
  495. show_accept(TTR("Error saving resource!"), TTR("OK"));
  496. return;
  497. }
  498. ((Resource *)p_resource.ptr())->set_path(path);
  499. emit_signal("resource_saved", p_resource);
  500. editor_data.notify_resource_saved(p_resource);
  501. }
  502. void EditorNode::save_resource(const Ref<Resource> &p_resource) {
  503. if (p_resource->get_path().is_resource_file()) {
  504. save_resource_in_path(p_resource, p_resource->get_path());
  505. } else {
  506. save_resource_as(p_resource);
  507. }
  508. }
  509. void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String &p_at_path) {
  510. file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
  511. current_option = RESOURCE_SAVE_AS;
  512. List<String> extensions;
  513. Ref<PackedScene> sd = memnew(PackedScene);
  514. ResourceSaver::get_recognized_extensions(p_resource, &extensions);
  515. file->clear_filters();
  516. List<String> preferred;
  517. for (int i = 0; i < extensions.size(); i++) {
  518. if (p_resource->is_class("Script") && (extensions[i] == "tres" || extensions[i] == "res" || extensions[i] == "xml")) {
  519. //this serves no purpose and confused people
  520. continue;
  521. }
  522. file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
  523. preferred.push_back(extensions[i]);
  524. }
  525. if (p_at_path != String()) {
  526. file->set_current_dir(p_at_path);
  527. if (p_resource->get_path().is_resource_file()) {
  528. file->set_current_file(p_resource->get_path().get_file());
  529. } else {
  530. if (extensions.size()) {
  531. file->set_current_file("new_" + p_resource->get_class().to_lower() + "." + preferred.front()->get().to_lower());
  532. } else {
  533. file->set_current_file(String());
  534. }
  535. }
  536. } else if (p_resource->get_path() != "") {
  537. file->set_current_path(p_resource->get_path());
  538. if (extensions.size()) {
  539. String ext = p_resource->get_path().get_extension().to_lower();
  540. if (extensions.find(ext) == NULL) {
  541. file->set_current_path(p_resource->get_path().replacen("." + ext, "." + extensions.front()->get()));
  542. }
  543. }
  544. } else if (preferred.size()) {
  545. String existing;
  546. if (extensions.size()) {
  547. existing = "new_" + p_resource->get_class().to_lower() + "." + preferred.front()->get().to_lower();
  548. }
  549. file->set_current_path(existing);
  550. }
  551. file->popup_centered_ratio();
  552. file->set_title(TTR("Save Resource As..."));
  553. }
  554. void EditorNode::_menu_option(int p_option) {
  555. _menu_option_confirm(p_option, false);
  556. }
  557. void EditorNode::_menu_confirm_current() {
  558. _menu_option_confirm(current_option, true);
  559. }
  560. void EditorNode::_dialog_display_save_error(String p_file, Error p_error) {
  561. if (p_error) {
  562. switch (p_error) {
  563. case ERR_FILE_CANT_WRITE: {
  564. show_accept(TTR("Can't open file for writing:") + " " + p_file.get_extension(), TTR("OK"));
  565. } break;
  566. case ERR_FILE_UNRECOGNIZED: {
  567. show_accept(TTR("Requested file format unknown:") + " " + p_file.get_extension(), TTR("OK"));
  568. } break;
  569. default: {
  570. show_accept(TTR("Error while saving."), TTR("OK"));
  571. } break;
  572. }
  573. }
  574. }
  575. void EditorNode::_dialog_display_load_error(String p_file, Error p_error) {
  576. if (p_error) {
  577. switch (p_error) {
  578. case ERR_CANT_OPEN: {
  579. show_accept(vformat(TTR("Can't open '%s'. The file could have been moved or deleted."), p_file.get_file()), TTR("OK"));
  580. } break;
  581. case ERR_PARSE_ERROR: {
  582. show_accept(vformat(TTR("Error while parsing '%s'."), p_file.get_file()), TTR("OK"));
  583. } break;
  584. case ERR_FILE_CORRUPT: {
  585. show_accept(vformat(TTR("Unexpected end of file '%s'."), p_file.get_file()), TTR("OK"));
  586. } break;
  587. case ERR_FILE_NOT_FOUND: {
  588. show_accept(vformat(TTR("Missing '%s' or its dependencies."), p_file.get_file()), TTR("OK"));
  589. } break;
  590. default: {
  591. show_accept(vformat(TTR("Error while loading '%s'."), p_file.get_file()), TTR("OK"));
  592. } break;
  593. }
  594. }
  595. }
  596. void EditorNode::_get_scene_metadata(const String &p_file) {
  597. Node *scene = editor_data.get_edited_scene_root();
  598. if (!scene)
  599. return;
  600. String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg");
  601. Ref<ConfigFile> cf;
  602. cf.instance();
  603. Error err = cf->load(path);
  604. if (err != OK || !cf->has_section("editor_states"))
  605. return; //must not exist
  606. List<String> esl;
  607. cf->get_section_keys("editor_states", &esl);
  608. Dictionary md;
  609. for (List<String>::Element *E = esl.front(); E; E = E->next()) {
  610. Variant st = cf->get_value("editor_states", E->get());
  611. if (st.get_type()) {
  612. md[E->get()] = st;
  613. }
  614. }
  615. editor_data.set_editor_states(md);
  616. }
  617. void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) {
  618. Node *scene = editor_data.get_edited_scene_root(p_idx);
  619. if (!scene)
  620. return;
  621. scene->set_meta("__editor_run_settings__", Variant()); //clear it (no point in keeping it)
  622. scene->set_meta("__editor_plugin_states__", Variant());
  623. String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg");
  624. Ref<ConfigFile> cf;
  625. cf.instance();
  626. Dictionary md;
  627. if (p_idx < 0 || editor_data.get_edited_scene() == p_idx) {
  628. md = editor_data.get_editor_states();
  629. } else {
  630. md = editor_data.get_scene_editor_states(p_idx);
  631. }
  632. List<Variant> keys;
  633. md.get_key_list(&keys);
  634. for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
  635. cf->set_value("editor_states", E->get(), md[E->get()]);
  636. }
  637. Error err = cf->save(path);
  638. ERR_FAIL_COND(err != OK);
  639. }
  640. bool EditorNode::_find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags) {
  641. if (p_res.is_null())
  642. return false;
  643. if (processed.has(p_res)) {
  644. return processed[p_res];
  645. }
  646. bool changed = p_res->is_edited();
  647. p_res->set_edited(false);
  648. bool subchanged = _find_and_save_edited_subresources(p_res.ptr(), processed, flags);
  649. if (p_res->get_path().is_resource_file()) {
  650. if (changed || subchanged) {
  651. //save
  652. ResourceSaver::save(p_res->get_path(), p_res, flags);
  653. }
  654. processed[p_res] = false; //because it's a file
  655. return false;
  656. } else {
  657. processed[p_res] = changed;
  658. return changed;
  659. }
  660. }
  661. bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> &processed, int32_t flags) {
  662. bool ret_changed = false;
  663. List<PropertyInfo> pi;
  664. obj->get_property_list(&pi);
  665. for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
  666. if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
  667. continue;
  668. switch (E->get().type) {
  669. case Variant::OBJECT: {
  670. RES res = obj->get(E->get().name);
  671. if (_find_and_save_resource(res, processed, flags))
  672. ret_changed = true;
  673. } break;
  674. case Variant::ARRAY: {
  675. Array varray = obj->get(E->get().name);
  676. int len = varray.size();
  677. for (int i = 0; i < len; i++) {
  678. Variant v = varray.get(i);
  679. RES res = v;
  680. if (_find_and_save_resource(res, processed, flags))
  681. ret_changed = true;
  682. }
  683. } break;
  684. case Variant::DICTIONARY: {
  685. Dictionary d = obj->get(E->get().name);
  686. List<Variant> keys;
  687. d.get_key_list(&keys);
  688. for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
  689. Variant v = d[E->get()];
  690. RES res = v;
  691. if (_find_and_save_resource(res, processed, flags))
  692. ret_changed = true;
  693. }
  694. } break;
  695. default: {}
  696. }
  697. }
  698. return ret_changed;
  699. }
  700. void EditorNode::_save_edited_subresources(Node *scene, Map<RES, bool> &processed, int32_t flags) {
  701. _find_and_save_edited_subresources(scene, processed, flags);
  702. for (int i = 0; i < scene->get_child_count(); i++) {
  703. Node *n = scene->get_child(i);
  704. if (n->get_owner() != editor_data.get_edited_scene_root())
  705. continue;
  706. _save_edited_subresources(n, processed, flags);
  707. }
  708. }
  709. void EditorNode::_find_node_types(Node *p_node, int &count_2d, int &count_3d) {
  710. if (p_node->is_class("Viewport") || (p_node != editor_data.get_edited_scene_root() && p_node->get_owner() != editor_data.get_edited_scene_root()))
  711. return;
  712. if (p_node->is_class("CanvasItem"))
  713. count_2d++;
  714. else if (p_node->is_class("Spatial"))
  715. count_3d++;
  716. for (int i = 0; i < p_node->get_child_count(); i++)
  717. _find_node_types(p_node->get_child(i), count_2d, count_3d);
  718. }
  719. void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
  720. EditorProgress save("save", TTR("Saving Scene"), 4);
  721. save.step(TTR("Analyzing"), 0);
  722. int c2d = 0;
  723. int c3d = 0;
  724. _find_node_types(editor_data.get_edited_scene_root(), c2d, c3d);
  725. RID viewport;
  726. bool is2d;
  727. if (c3d < c2d) {
  728. viewport = scene_root->get_viewport_rid();
  729. is2d = true;
  730. } else {
  731. viewport = SpatialEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_viewport_rid();
  732. is2d = false;
  733. }
  734. save.step(TTR("Creating Thumbnail"), 1);
  735. //current view?
  736. Ref<Image> img;
  737. if (is2d) {
  738. img = scene_root->get_texture()->get_data();
  739. } else {
  740. img = SpatialEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_texture()->get_data();
  741. }
  742. if (img.is_valid()) {
  743. save.step(TTR("Creating Thumbnail"), 2);
  744. save.step(TTR("Creating Thumbnail"), 3);
  745. int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
  746. preview_size *= EDSCALE;
  747. // consider a square region
  748. int vp_size = MIN(img->get_width(), img->get_height());
  749. int x = (img->get_width() - vp_size) / 2;
  750. int y = (img->get_height() - vp_size) / 2;
  751. if (vp_size < preview_size) {
  752. // just square it.
  753. img->crop_from_point(x, y, vp_size, vp_size);
  754. } else {
  755. int ratio = vp_size / preview_size;
  756. int size = preview_size * (ratio / 2);
  757. x = (img->get_width() - size) / 2;
  758. y = (img->get_height() - size) / 2;
  759. img->crop_from_point(x, y, size, size);
  760. // We could get better pictures with better filters
  761. img->resize(preview_size, preview_size, Image::INTERPOLATE_CUBIC);
  762. }
  763. img->convert(Image::FORMAT_RGB8);
  764. img->flip_y();
  765. //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5
  766. String temp_path = EditorSettings::get_singleton()->get_cache_dir();
  767. String cache_base = ProjectSettings::get_singleton()->globalize_path(p_file).md5_text();
  768. cache_base = temp_path.plus_file("resthumb-" + cache_base);
  769. //does not have it, try to load a cached thumbnail
  770. String file = cache_base + ".png";
  771. post_process_preview(img);
  772. img->save_png(file);
  773. }
  774. save.step(TTR("Saving Scene"), 4);
  775. _save_scene(p_file, p_idx);
  776. EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
  777. }
  778. void EditorNode::_save_scene(String p_file, int idx) {
  779. Node *scene = editor_data.get_edited_scene_root(idx);
  780. if (!scene) {
  781. show_accept(TTR("This operation can't be done without a tree root."), TTR("OK"));
  782. return;
  783. }
  784. editor_data.apply_changes_in_editors();
  785. _save_default_environment();
  786. _set_scene_metadata(p_file, idx);
  787. Ref<PackedScene> sdata;
  788. if (ResourceCache::has(p_file)) {
  789. // something may be referencing this resource and we are good with that.
  790. // we must update it, but also let the previous scene state go, as
  791. // old version still work for referencing changes in instanced or inherited scenes
  792. sdata = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(p_file)));
  793. if (sdata.is_valid())
  794. sdata->recreate_state();
  795. else
  796. sdata.instance();
  797. } else {
  798. sdata.instance();
  799. }
  800. Error err = sdata->pack(scene);
  801. if (err != OK) {
  802. show_accept(TTR("Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied."), TTR("OK"));
  803. return;
  804. }
  805. // force creation of node path cache
  806. // (hacky but needed for the tree to update properly)
  807. Node *dummy_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
  808. if (!dummy_scene) {
  809. show_accept(TTR("Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied."), TTR("OK"));
  810. return;
  811. }
  812. memdelete(dummy_scene);
  813. int flg = 0;
  814. if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
  815. flg |= ResourceSaver::FLAG_COMPRESS;
  816. flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
  817. err = ResourceSaver::save(p_file, sdata, flg);
  818. //Map<RES, bool> processed;
  819. //this method is slow and not always works, deprecating
  820. //_save_edited_subresources(scene, processed, flg);
  821. { //instead, just find globally unsaved subresources and save them
  822. List<Ref<Resource> > cached;
  823. ResourceCache::get_cached_resources(&cached);
  824. for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) {
  825. Ref<Resource> res = E->get();
  826. if (res->is_edited() && res->get_path().is_resource_file()) {
  827. ResourceSaver::save(res->get_path(), res, flg);
  828. res->set_edited(false);
  829. }
  830. }
  831. }
  832. editor_data.save_editor_external_data();
  833. if (err == OK) {
  834. scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_file));
  835. if (idx < 0 || idx == editor_data.get_edited_scene())
  836. set_current_version(editor_data.get_undo_redo().get_version());
  837. else
  838. editor_data.set_edited_scene_version(0, idx);
  839. _update_title();
  840. _update_scene_tabs();
  841. } else {
  842. _dialog_display_save_error(p_file, err);
  843. }
  844. }
  845. void EditorNode::save_all_scenes_and_restart() {
  846. _menu_option_confirm(RUN_STOP, true);
  847. exiting = true;
  848. _save_all_scenes();
  849. String to_reopen;
  850. if (get_tree()->get_edited_scene_root()) {
  851. to_reopen = get_tree()->get_edited_scene_root()->get_filename();
  852. }
  853. get_tree()->quit();
  854. String exec = OS::get_singleton()->get_executable_path();
  855. List<String> args;
  856. args.push_back("--path");
  857. args.push_back(ProjectSettings::get_singleton()->get_resource_path());
  858. args.push_back("-e");
  859. if (to_reopen != String()) {
  860. args.push_back(to_reopen);
  861. }
  862. OS::get_singleton()->set_restart_on_exit(true, args);
  863. }
  864. void EditorNode::_save_all_scenes() {
  865. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  866. Node *scene = editor_data.get_edited_scene_root(i);
  867. if (scene && scene->get_filename() != "") {
  868. if (i != editor_data.get_edited_scene())
  869. _save_scene(scene->get_filename(), i);
  870. else
  871. _save_scene_with_preview(scene->get_filename());
  872. } // else: ignore new scenes
  873. }
  874. _save_default_environment();
  875. }
  876. void EditorNode::_mark_unsaved_scenes() {
  877. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  878. Node *node = editor_data.get_edited_scene_root(i);
  879. if (!node)
  880. continue;
  881. String path = node->get_filename();
  882. if (!(path == String() || FileAccess::exists(path))) {
  883. node->set_filename("");
  884. if (i == editor_data.get_edited_scene())
  885. set_current_version(-1);
  886. else
  887. editor_data.set_edited_scene_version(-1, i);
  888. }
  889. }
  890. _update_title();
  891. _update_scene_tabs();
  892. }
  893. void EditorNode::_dialog_action(String p_file) {
  894. switch (current_option) {
  895. case FILE_NEW_INHERITED_SCENE: {
  896. load_scene(p_file, false, true);
  897. } break;
  898. case FILE_OPEN_SCENE: {
  899. load_scene(p_file);
  900. } break;
  901. case SETTINGS_PICK_MAIN_SCENE: {
  902. ProjectSettings::get_singleton()->set("application/run/main_scene", p_file);
  903. ProjectSettings::get_singleton()->save();
  904. //would be nice to show the project manager opened with the highlighted field..
  905. _run(false, ""); // automatically run the project
  906. } break;
  907. case FILE_CLOSE:
  908. case FILE_CLOSE_ALL_AND_QUIT:
  909. case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
  910. case SCENE_TAB_CLOSE:
  911. case FILE_SAVE_SCENE:
  912. case FILE_SAVE_AS_SCENE: {
  913. int scene_idx = (current_option == FILE_SAVE_SCENE || current_option == FILE_SAVE_AS_SCENE) ? -1 : tab_closing;
  914. if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
  915. bool same_open_scene = false;
  916. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  917. if (editor_data.get_scene_path(i) == p_file && i != scene_idx)
  918. same_open_scene = true;
  919. }
  920. if (same_open_scene) {
  921. show_warning(TTR("Can't overwrite scene that is still open!"));
  922. return;
  923. }
  924. _save_default_environment();
  925. _save_scene_with_preview(p_file, scene_idx);
  926. _add_to_recent_scenes(p_file);
  927. if (scene_idx != -1)
  928. _discard_changes();
  929. }
  930. } break;
  931. case FILE_SAVE_AND_RUN: {
  932. if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
  933. _save_default_environment();
  934. _save_scene_with_preview(p_file);
  935. _run(false, p_file);
  936. }
  937. } break;
  938. case FILE_EXPORT_MESH_LIBRARY: {
  939. Ref<MeshLibrary> ml;
  940. if (file_export_lib_merge->is_pressed() && FileAccess::exists(p_file)) {
  941. ml = ResourceLoader::load(p_file, "MeshLibrary");
  942. if (ml.is_null()) {
  943. show_accept(TTR("Can't load MeshLibrary for merging!"), TTR("OK"));
  944. return;
  945. }
  946. }
  947. if (ml.is_null()) {
  948. ml = Ref<MeshLibrary>(memnew(MeshLibrary));
  949. }
  950. MeshLibraryEditor::update_library_file(editor_data.get_edited_scene_root(), ml, true);
  951. Error err = ResourceSaver::save(p_file, ml);
  952. if (err) {
  953. show_accept(TTR("Error saving MeshLibrary!"), TTR("OK"));
  954. return;
  955. }
  956. } break;
  957. case FILE_EXPORT_TILESET: {
  958. Ref<TileSet> tileset;
  959. if (FileAccess::exists(p_file) && file_export_lib_merge->is_pressed()) {
  960. tileset = ResourceLoader::load(p_file, "TileSet");
  961. if (tileset.is_null()) {
  962. show_accept(TTR("Can't load TileSet for merging!"), TTR("OK"));
  963. return;
  964. }
  965. } else {
  966. tileset = Ref<TileSet>(memnew(TileSet));
  967. }
  968. TileSetEditor::update_library_file(editor_data.get_edited_scene_root(), tileset, true);
  969. Error err = ResourceSaver::save(p_file, tileset);
  970. if (err) {
  971. show_accept(TTR("Error saving TileSet!"), TTR("OK"));
  972. return;
  973. }
  974. } break;
  975. case RESOURCE_SAVE:
  976. case RESOURCE_SAVE_AS: {
  977. uint32_t current = editor_history.get_current();
  978. Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
  979. ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj))
  980. RES current_res = RES(Object::cast_to<Resource>(current_obj));
  981. save_resource_in_path(current_res, p_file);
  982. } break;
  983. case SETTINGS_LAYOUT_SAVE: {
  984. if (p_file.empty())
  985. return;
  986. Ref<ConfigFile> config;
  987. config.instance();
  988. Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config());
  989. if (err == ERR_CANT_OPEN) {
  990. config.instance(); // new config
  991. } else if (err != OK) {
  992. show_warning(TTR("Error trying to save layout!"));
  993. return;
  994. }
  995. _save_docks_to_config(config, p_file);
  996. config->save(EditorSettings::get_singleton()->get_editor_layouts_config());
  997. layout_dialog->hide();
  998. _update_layouts_menu();
  999. if (p_file == "Default") {
  1000. show_warning(TTR("Default editor layout overridden."));
  1001. }
  1002. } break;
  1003. case SETTINGS_LAYOUT_DELETE: {
  1004. if (p_file.empty())
  1005. return;
  1006. Ref<ConfigFile> config;
  1007. config.instance();
  1008. Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config());
  1009. if (err != OK || !config->has_section(p_file)) {
  1010. show_warning(TTR("Layout name not found!"));
  1011. return;
  1012. }
  1013. // erase
  1014. List<String> keys;
  1015. config->get_section_keys(p_file, &keys);
  1016. for (List<String>::Element *E = keys.front(); E; E = E->next()) {
  1017. config->set_value(p_file, E->get(), Variant());
  1018. }
  1019. config->save(EditorSettings::get_singleton()->get_editor_layouts_config());
  1020. layout_dialog->hide();
  1021. _update_layouts_menu();
  1022. if (p_file == "Default") {
  1023. show_warning(TTR("Restored default layout to base settings."));
  1024. }
  1025. } break;
  1026. default: { //save scene?
  1027. if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
  1028. _save_scene_with_preview(p_file);
  1029. }
  1030. } break;
  1031. }
  1032. }
  1033. bool EditorNode::item_has_editor(Object *p_object) {
  1034. return editor_data.get_subeditors(p_object).size() > 0;
  1035. }
  1036. void EditorNode::edit_item(Object *p_object) {
  1037. Vector<EditorPlugin *> sub_plugins;
  1038. if (p_object) {
  1039. sub_plugins = editor_data.get_subeditors(p_object);
  1040. }
  1041. if (!sub_plugins.empty()) {
  1042. _display_top_editors(false);
  1043. _set_top_editors(sub_plugins);
  1044. _set_editing_top_editors(p_object);
  1045. _display_top_editors(true);
  1046. } else {
  1047. _hide_top_editors();
  1048. }
  1049. }
  1050. void EditorNode::push_item(Object *p_object, const String &p_property, bool p_inspector_only) {
  1051. if (!p_object) {
  1052. get_inspector()->edit(NULL);
  1053. node_dock->set_node(NULL);
  1054. scene_tree_dock->set_selected(NULL);
  1055. return;
  1056. }
  1057. uint32_t id = p_object->get_instance_id();
  1058. if (id != editor_history.get_current()) {
  1059. if (p_inspector_only) {
  1060. editor_history.add_object_inspector_only(id);
  1061. } else if (p_property == "")
  1062. editor_history.add_object(id);
  1063. else
  1064. editor_history.add_object(id, p_property);
  1065. }
  1066. _edit_current();
  1067. }
  1068. void EditorNode::_save_default_environment() {
  1069. Ref<Environment> fallback = get_tree()->get_root()->get_world()->get_fallback_environment();
  1070. if (fallback.is_valid() && fallback->get_path().is_resource_file()) {
  1071. Map<RES, bool> processed;
  1072. _find_and_save_edited_subresources(fallback.ptr(), processed, 0);
  1073. save_resource_in_path(fallback, fallback->get_path());
  1074. }
  1075. }
  1076. void EditorNode::_hide_top_editors() {
  1077. _display_top_editors(false);
  1078. editor_plugins_over->clear();
  1079. }
  1080. void EditorNode::_display_top_editors(bool p_display) {
  1081. editor_plugins_over->make_visible(p_display);
  1082. }
  1083. void EditorNode::_set_top_editors(Vector<EditorPlugin *> p_editor_plugins_over) {
  1084. editor_plugins_over->set_plugins_list(p_editor_plugins_over);
  1085. }
  1086. void EditorNode::_set_editing_top_editors(Object *p_current_object) {
  1087. editor_plugins_over->edit(p_current_object);
  1088. }
  1089. static bool overrides_external_editor(Object *p_object) {
  1090. Script *script = Object::cast_to<Script>(p_object);
  1091. if (!script)
  1092. return false;
  1093. return script->get_language()->overrides_external_editor();
  1094. }
  1095. void EditorNode::_edit_current() {
  1096. uint32_t current = editor_history.get_current();
  1097. Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
  1098. bool inspector_only = editor_history.is_current_inspector_only();
  1099. this->current = current_obj;
  1100. if (!current_obj) {
  1101. scene_tree_dock->set_selected(NULL);
  1102. get_inspector()->edit(NULL);
  1103. node_dock->set_node(NULL);
  1104. inspector_dock->update(NULL);
  1105. _display_top_editors(false);
  1106. return;
  1107. }
  1108. bool capitalize = bool(EDITOR_GET("interface/inspector/capitalize_properties"));
  1109. bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding"));
  1110. bool is_resource = current_obj->is_class("Resource");
  1111. bool is_node = current_obj->is_class("Node");
  1112. String editable_warning; //none by default
  1113. if (is_resource) {
  1114. Resource *current_res = Object::cast_to<Resource>(current_obj);
  1115. ERR_FAIL_COND(!current_res);
  1116. scene_tree_dock->set_selected(NULL);
  1117. get_inspector()->edit(current_res);
  1118. node_dock->set_node(NULL);
  1119. EditorNode::get_singleton()->get_import_dock()->set_edit_path(current_res->get_path());
  1120. int subr_idx = current_res->get_path().find("::");
  1121. if (subr_idx != -1) {
  1122. String base_path = current_res->get_path().substr(0, subr_idx);
  1123. if (FileAccess::exists(base_path + ".import")) {
  1124. editable_warning = TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow.");
  1125. } else {
  1126. if ((!get_edited_scene() || get_edited_scene()->get_filename() != base_path) && ResourceLoader::get_resource_type(base_path) == "PackedScene") {
  1127. editable_warning = TTR("This resource belongs to a scene that was instanced or inherited.\nChanges to it will not be kept when saving the current scene.");
  1128. }
  1129. }
  1130. } else if (current_res->get_path().is_resource_file()) {
  1131. if (FileAccess::exists(current_res->get_path() + ".import")) {
  1132. editable_warning = TTR("This resource was imported, so it's not editable. Change its settings in the import panel and then re-import.");
  1133. }
  1134. }
  1135. } else if (is_node) {
  1136. Node *current_node = Object::cast_to<Node>(current_obj);
  1137. ERR_FAIL_COND(!current_node);
  1138. get_inspector()->edit(current_node);
  1139. if (current_node->is_inside_tree()) {
  1140. node_dock->set_node(current_node);
  1141. scene_tree_dock->set_selected(current_node);
  1142. } else {
  1143. node_dock->set_node(NULL);
  1144. scene_tree_dock->set_selected(NULL);
  1145. }
  1146. if (get_edited_scene() && get_edited_scene()->get_filename() != String()) {
  1147. String source_scene = get_edited_scene()->get_filename();
  1148. if (FileAccess::exists(source_scene + ".import")) {
  1149. editable_warning = TTR("This scene was imported, so changes to it will not be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow.");
  1150. }
  1151. }
  1152. } else {
  1153. if (current_obj->is_class("ScriptEditorDebuggerInspectedObject")) {
  1154. editable_warning = TTR("This is a remote object so changes to it will not be kept.\nPlease read the documentation relevant to debugging to better understand this workflow.");
  1155. capitalize = false;
  1156. disable_folding = true;
  1157. }
  1158. get_inspector()->edit(current_obj);
  1159. node_dock->set_node(NULL);
  1160. }
  1161. inspector_dock->set_warning(editable_warning);
  1162. if (get_inspector()->is_capitalize_paths_enabled() != capitalize) {
  1163. get_inspector()->set_enable_capitalize_paths(capitalize);
  1164. }
  1165. if (get_inspector()->is_using_folding() == disable_folding) {
  1166. get_inspector()->set_use_folding(!disable_folding);
  1167. }
  1168. /* Take care of PLUGIN EDITOR */
  1169. if (!inspector_only) {
  1170. EditorPlugin *main_plugin = editor_data.get_editor(current_obj);
  1171. if (main_plugin) {
  1172. // special case if use of external editor is true
  1173. if (main_plugin->get_name() == "Script" && current_obj->get_class_name() != StringName("VisualScript") && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
  1174. if (!changing_scene)
  1175. main_plugin->edit(current_obj);
  1176. }
  1177. else if (main_plugin != editor_plugin_screen && (!ScriptEditor::get_singleton() || !ScriptEditor::get_singleton()->is_visible_in_tree() || ScriptEditor::get_singleton()->can_take_away_focus())) {
  1178. // update screen main_plugin
  1179. if (!changing_scene) {
  1180. if (editor_plugin_screen)
  1181. editor_plugin_screen->make_visible(false);
  1182. editor_plugin_screen = main_plugin;
  1183. editor_plugin_screen->edit(current_obj);
  1184. editor_plugin_screen->make_visible(true);
  1185. int plugin_count = editor_data.get_editor_plugin_count();
  1186. for (int i = 0; i < plugin_count; i++) {
  1187. editor_data.get_editor_plugin(i)->notify_main_screen_changed(editor_plugin_screen->get_name());
  1188. }
  1189. for (int i = 0; i < editor_table.size(); i++) {
  1190. main_editor_buttons[i]->set_pressed(editor_table[i] == main_plugin);
  1191. }
  1192. }
  1193. } else {
  1194. editor_plugin_screen->edit(current_obj);
  1195. }
  1196. }
  1197. Vector<EditorPlugin *> sub_plugins = editor_data.get_subeditors(current_obj);
  1198. if (!sub_plugins.empty()) {
  1199. _display_top_editors(false);
  1200. _set_top_editors(sub_plugins);
  1201. _set_editing_top_editors(current_obj);
  1202. _display_top_editors(true);
  1203. } else if (!editor_plugins_over->get_plugins_list().empty()) {
  1204. _hide_top_editors();
  1205. }
  1206. }
  1207. inspector_dock->update(current_obj);
  1208. inspector_dock->update_keying();
  1209. }
  1210. void EditorNode::_run(bool p_current, const String &p_custom) {
  1211. if (editor_run.get_status() == EditorRun::STATUS_PLAY) {
  1212. play_button->set_pressed(!_playing_edited);
  1213. play_scene_button->set_pressed(_playing_edited);
  1214. return;
  1215. }
  1216. play_button->set_pressed(false);
  1217. play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons"));
  1218. play_scene_button->set_pressed(false);
  1219. play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
  1220. play_custom_scene_button->set_pressed(false);
  1221. play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
  1222. String main_scene;
  1223. String run_filename;
  1224. String args;
  1225. if (p_current || (editor_data.get_edited_scene_root() && p_custom == editor_data.get_edited_scene_root()->get_filename())) {
  1226. Node *scene = editor_data.get_edited_scene_root();
  1227. if (!scene) {
  1228. show_accept(TTR("There is no defined scene to run."), TTR("OK"));
  1229. return;
  1230. }
  1231. if (scene->get_filename() == "") {
  1232. current_option = -1;
  1233. _menu_option_confirm(FILE_SAVE_BEFORE_RUN, false);
  1234. return;
  1235. }
  1236. run_filename = scene->get_filename();
  1237. } else if (p_custom != "") {
  1238. run_filename = p_custom;
  1239. }
  1240. if (run_filename == "") {
  1241. //evidently, run the scene
  1242. main_scene = GLOBAL_DEF("application/run/main_scene", "");
  1243. if (main_scene == "") {
  1244. current_option = -1;
  1245. pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in \"Project Settings\" under the 'application' category."));
  1246. pick_main_scene->popup_centered_minsize();
  1247. return;
  1248. }
  1249. if (!FileAccess::exists(main_scene)) {
  1250. current_option = -1;
  1251. pick_main_scene->set_text(vformat(TTR("Selected scene '%s' does not exist, select a valid one?\nYou can change it later in \"Project Settings\" under the 'application' category."), main_scene));
  1252. pick_main_scene->popup_centered_minsize();
  1253. return;
  1254. }
  1255. if (ResourceLoader::get_resource_type(main_scene) != "PackedScene") {
  1256. current_option = -1;
  1257. pick_main_scene->set_text(vformat(TTR("Selected scene '%s' is not a scene file, select a valid one?\nYou can change it later in \"Project Settings\" under the 'application' category."), main_scene));
  1258. pick_main_scene->popup_centered_minsize();
  1259. return;
  1260. }
  1261. }
  1262. if (bool(EDITOR_GET("run/auto_save/save_before_running"))) {
  1263. if (unsaved_cache) {
  1264. Node *scene = editor_data.get_edited_scene_root();
  1265. if (scene) { //only autosave if there is a scene obviously
  1266. if (scene->get_filename() == "") {
  1267. show_accept(TTR("Current scene was never saved, please save it prior to running."), TTR("OK"));
  1268. return;
  1269. }
  1270. _save_scene_with_preview(scene->get_filename());
  1271. }
  1272. }
  1273. _menu_option(FILE_SAVE_ALL_SCENES);
  1274. editor_data.save_editor_external_data();
  1275. }
  1276. if (!call_build())
  1277. return;
  1278. if (bool(EDITOR_GET("run/output/always_clear_output_on_play"))) {
  1279. log->clear();
  1280. }
  1281. if (bool(EDITOR_GET("run/output/always_open_output_on_play"))) {
  1282. make_bottom_panel_item_visible(log);
  1283. }
  1284. List<String> breakpoints;
  1285. editor_data.get_editor_breakpoints(&breakpoints);
  1286. args = ProjectSettings::get_singleton()->get("editor/main_run_args");
  1287. Error error = editor_run.run(run_filename, args, breakpoints);
  1288. if (error != OK) {
  1289. show_accept(TTR("Could not start subprocess!"), TTR("OK"));
  1290. return;
  1291. }
  1292. emit_signal("play_pressed");
  1293. if (p_current) {
  1294. play_scene_button->set_pressed(true);
  1295. play_scene_button->set_icon(gui_base->get_icon("Reload", "EditorIcons"));
  1296. } else if (p_custom != "") {
  1297. run_custom_filename = p_custom;
  1298. play_custom_scene_button->set_pressed(true);
  1299. play_custom_scene_button->set_icon(gui_base->get_icon("Reload", "EditorIcons"));
  1300. } else {
  1301. play_button->set_pressed(true);
  1302. play_button->set_icon(gui_base->get_icon("Reload", "EditorIcons"));
  1303. }
  1304. stop_button->set_disabled(false);
  1305. _playing_edited = p_current;
  1306. }
  1307. void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
  1308. if (!p_confirmed) //this may be a hack..
  1309. current_option = (MenuOptions)p_option;
  1310. switch (p_option) {
  1311. case FILE_NEW_SCENE: {
  1312. int idx = editor_data.add_edited_scene(-1);
  1313. _scene_tab_changed(idx);
  1314. editor_data.clear_editor_states();
  1315. _update_scene_tabs();
  1316. } break;
  1317. case FILE_NEW_INHERITED_SCENE:
  1318. case FILE_OPEN_SCENE: {
  1319. file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
  1320. List<String> extensions;
  1321. ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
  1322. file->clear_filters();
  1323. for (int i = 0; i < extensions.size(); i++) {
  1324. file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
  1325. }
  1326. Node *scene = editor_data.get_edited_scene_root();
  1327. if (scene) {
  1328. file->set_current_path(scene->get_filename());
  1329. };
  1330. file->set_title(p_option == FILE_OPEN_SCENE ? TTR("Open Scene") : TTR("Open Base Scene"));
  1331. file->popup_centered_ratio();
  1332. } break;
  1333. case FILE_QUICK_OPEN_SCENE: {
  1334. quick_open->popup_dialog("PackedScene", true);
  1335. quick_open->set_title(TTR("Quick Open Scene..."));
  1336. } break;
  1337. case FILE_QUICK_OPEN_SCRIPT: {
  1338. quick_open->popup_dialog("Script", true);
  1339. quick_open->set_title(TTR("Quick Open Script..."));
  1340. } break;
  1341. case FILE_OPEN_PREV: {
  1342. if (previous_scenes.empty())
  1343. break;
  1344. opening_prev = true;
  1345. open_request(previous_scenes.back()->get());
  1346. } break;
  1347. case FILE_CLOSE_ALL_AND_QUIT:
  1348. case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
  1349. case FILE_CLOSE: {
  1350. if (!p_confirmed && (unsaved_cache || p_option == FILE_CLOSE_ALL_AND_QUIT || p_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER)) {
  1351. tab_closing = p_option == FILE_CLOSE ? editor_data.get_edited_scene() : _next_unsaved_scene(false);
  1352. String scene_filename = editor_data.get_edited_scene_root(tab_closing)->get_filename();
  1353. save_confirmation->get_ok()->set_text(TTR("Save & Close"));
  1354. save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene_filename != "" ? scene_filename : "unsaved scene"));
  1355. save_confirmation->popup_centered_minsize();
  1356. break;
  1357. } else {
  1358. tab_closing = editor_data.get_edited_scene();
  1359. }
  1360. if (!editor_data.get_edited_scene_root(tab_closing)) {
  1361. // empty tab
  1362. _scene_tab_closed(tab_closing);
  1363. break;
  1364. }
  1365. } // fallthrough
  1366. case SCENE_TAB_CLOSE:
  1367. case FILE_SAVE_SCENE: {
  1368. int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing;
  1369. Node *scene = editor_data.get_edited_scene_root(scene_idx);
  1370. if (scene && scene->get_filename() != "") {
  1371. if (scene_idx != editor_data.get_edited_scene())
  1372. _save_scene_with_preview(scene->get_filename(), scene_idx);
  1373. else
  1374. _save_scene_with_preview(scene->get_filename());
  1375. if (scene_idx != -1)
  1376. _discard_changes();
  1377. break;
  1378. }
  1379. // fallthrough to save_as
  1380. };
  1381. case FILE_SAVE_AS_SCENE: {
  1382. int scene_idx = (p_option == FILE_SAVE_SCENE || p_option == FILE_SAVE_AS_SCENE) ? -1 : tab_closing;
  1383. Node *scene = editor_data.get_edited_scene_root(scene_idx);
  1384. if (!scene) {
  1385. show_accept(TTR("This operation can't be done without a tree root."), TTR("OK"));
  1386. break;
  1387. }
  1388. file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
  1389. List<String> extensions;
  1390. Ref<PackedScene> sd = memnew(PackedScene);
  1391. ResourceSaver::get_recognized_extensions(sd, &extensions);
  1392. file->clear_filters();
  1393. for (int i = 0; i < extensions.size(); i++) {
  1394. file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
  1395. }
  1396. if (scene->get_filename() != "") {
  1397. file->set_current_path(scene->get_filename());
  1398. if (extensions.size()) {
  1399. String ext = scene->get_filename().get_extension().to_lower();
  1400. if (extensions.find(ext) == NULL) {
  1401. file->set_current_path(scene->get_filename().replacen("." + ext, "." + extensions.front()->get()));
  1402. }
  1403. }
  1404. } else {
  1405. String existing;
  1406. if (extensions.size()) {
  1407. String root_name(scene->get_name());
  1408. existing = root_name + "." + extensions.front()->get().to_lower();
  1409. }
  1410. file->set_current_path(existing);
  1411. }
  1412. file->popup_centered_ratio();
  1413. file->set_title(TTR("Save Scene As..."));
  1414. } break;
  1415. case FILE_SAVE_ALL_SCENES: {
  1416. _save_all_scenes();
  1417. } break;
  1418. case FILE_SAVE_BEFORE_RUN: {
  1419. if (!p_confirmed) {
  1420. confirmation->get_cancel()->set_text(TTR("No"));
  1421. confirmation->get_ok()->set_text(TTR("Yes"));
  1422. confirmation->set_text(TTR("This scene has never been saved. Save before running?"));
  1423. confirmation->popup_centered_minsize();
  1424. break;
  1425. }
  1426. _menu_option(FILE_SAVE_AS_SCENE);
  1427. _menu_option_confirm(FILE_SAVE_AND_RUN, false);
  1428. } break;
  1429. case FILE_EXPORT_PROJECT: {
  1430. project_export->popup_export();
  1431. } break;
  1432. case FILE_EXPORT_MESH_LIBRARY: {
  1433. if (!editor_data.get_edited_scene_root()) {
  1434. show_accept(TTR("This operation can't be done without a scene."), TTR("OK"));
  1435. break;
  1436. }
  1437. List<String> extensions;
  1438. Ref<MeshLibrary> ml(memnew(MeshLibrary));
  1439. ResourceSaver::get_recognized_extensions(ml, &extensions);
  1440. file_export_lib->clear_filters();
  1441. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  1442. file_export_lib->add_filter("*." + E->get());
  1443. }
  1444. file_export_lib->popup_centered_ratio();
  1445. file_export_lib->set_title(TTR("Export Mesh Library"));
  1446. } break;
  1447. case FILE_EXPORT_TILESET: {
  1448. //Make sure that the scene has a root before trying to convert to tileset
  1449. if (!editor_data.get_edited_scene_root()) {
  1450. show_accept(TTR("This operation can't be done without a root node."), TTR("OK"));
  1451. break;
  1452. }
  1453. List<String> extensions;
  1454. Ref<TileSet> ml(memnew(TileSet));
  1455. ResourceSaver::get_recognized_extensions(ml, &extensions);
  1456. file_export_lib->clear_filters();
  1457. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  1458. file_export_lib->add_filter("*." + E->get());
  1459. }
  1460. file_export_lib->popup_centered_ratio();
  1461. file_export_lib->set_title(TTR("Export Tile Set"));
  1462. } break;
  1463. case FILE_IMPORT_SUBSCENE: {
  1464. if (!editor_data.get_edited_scene_root()) {
  1465. show_accept(TTR("This operation can't be done without a selected node."), TTR("OK"));
  1466. break;
  1467. }
  1468. scene_tree_dock->import_subscene();
  1469. } break;
  1470. case FILE_EXTERNAL_OPEN_SCENE: {
  1471. if (unsaved_cache && !p_confirmed) {
  1472. confirmation->get_ok()->set_text(TTR("Open"));
  1473. confirmation->set_text(TTR("Current scene not saved. Open anyway?"));
  1474. confirmation->popup_centered_minsize();
  1475. break;
  1476. }
  1477. bool oprev = opening_prev;
  1478. Error err = load_scene(external_file);
  1479. if (err == OK && oprev) {
  1480. previous_scenes.pop_back();
  1481. opening_prev = false;
  1482. }
  1483. } break;
  1484. case EDIT_UNDO: {
  1485. if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
  1486. log->add_message("Can't UNDO while mouse buttons are pressed.");
  1487. } else {
  1488. String action = editor_data.get_undo_redo().get_current_action_name();
  1489. if (!editor_data.get_undo_redo().undo()) {
  1490. log->add_message("There is nothing to UNDO.");
  1491. } else if (action != "") {
  1492. log->add_message("UNDO: " + action);
  1493. }
  1494. }
  1495. } break;
  1496. case EDIT_REDO: {
  1497. if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
  1498. log->add_message("Can't REDO while mouse buttons are pressed.");
  1499. } else {
  1500. if (!editor_data.get_undo_redo().redo()) {
  1501. log->add_message("There is nothing to REDO.");
  1502. } else {
  1503. String action = editor_data.get_undo_redo().get_current_action_name();
  1504. log->add_message("REDO: " + action);
  1505. }
  1506. }
  1507. } break;
  1508. case EDIT_REVERT: {
  1509. Node *scene = get_edited_scene();
  1510. if (!scene)
  1511. break;
  1512. String filename = scene->get_filename();
  1513. if (filename == String()) {
  1514. show_warning(TTR("Can't reload a scene that was never saved."));
  1515. break;
  1516. }
  1517. if (unsaved_cache && !p_confirmed) {
  1518. confirmation->get_ok()->set_text(TTR("Revert"));
  1519. confirmation->set_text(TTR("This action cannot be undone. Revert anyway?"));
  1520. confirmation->popup_centered_minsize();
  1521. break;
  1522. }
  1523. int cur_idx = editor_data.get_edited_scene();
  1524. _remove_edited_scene();
  1525. Error err = load_scene(filename);
  1526. if (err != OK)
  1527. ERR_PRINT("Failed to load scene");
  1528. editor_data.move_edited_scene_to_index(cur_idx);
  1529. get_undo_redo()->clear_history();
  1530. scene_tabs->set_current_tab(cur_idx);
  1531. } break;
  1532. case RUN_PLAY: {
  1533. _menu_option_confirm(RUN_STOP, true);
  1534. _run(false);
  1535. } break;
  1536. case RUN_PLAY_CUSTOM_SCENE: {
  1537. if (run_custom_filename.empty() || editor_run.get_status() == EditorRun::STATUS_STOP) {
  1538. _menu_option_confirm(RUN_STOP, true);
  1539. quick_run->popup_dialog("PackedScene", true);
  1540. quick_run->set_title(TTR("Quick Run Scene..."));
  1541. play_custom_scene_button->set_pressed(false);
  1542. } else {
  1543. String last_custom_scene = run_custom_filename;
  1544. _menu_option_confirm(RUN_STOP, true);
  1545. _run(false, last_custom_scene);
  1546. }
  1547. } break;
  1548. case RUN_STOP: {
  1549. if (editor_run.get_status() == EditorRun::STATUS_STOP)
  1550. break;
  1551. editor_run.stop();
  1552. run_custom_filename.clear();
  1553. play_button->set_pressed(false);
  1554. play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons"));
  1555. play_scene_button->set_pressed(false);
  1556. play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
  1557. play_custom_scene_button->set_pressed(false);
  1558. play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
  1559. stop_button->set_disabled(true);
  1560. if (bool(EDITOR_GET("run/output/always_close_output_on_stop"))) {
  1561. for (int i = 0; i < bottom_panel_items.size(); i++) {
  1562. if (bottom_panel_items[i].control == log) {
  1563. _bottom_panel_switch(false, i);
  1564. break;
  1565. }
  1566. }
  1567. }
  1568. emit_signal("stop_pressed");
  1569. } break;
  1570. case FILE_SHOW_IN_FILESYSTEM: {
  1571. String path = editor_data.get_scene_path(editor_data.get_edited_scene());
  1572. if (path != String()) {
  1573. filesystem_dock->navigate_to_path(path);
  1574. }
  1575. } break;
  1576. case RUN_PLAY_SCENE: {
  1577. _save_default_environment();
  1578. _menu_option_confirm(RUN_STOP, true);
  1579. _run(true);
  1580. } break;
  1581. case RUN_PLAY_NATIVE: {
  1582. bool autosave = EDITOR_GET("run/auto_save/save_before_running");
  1583. if (autosave) {
  1584. _menu_option_confirm(FILE_SAVE_ALL_SCENES, false);
  1585. }
  1586. if (run_native->is_deploy_debug_remote_enabled()) {
  1587. _menu_option_confirm(RUN_STOP, true);
  1588. if (!call_build())
  1589. break; // build failed
  1590. emit_signal("play_pressed");
  1591. editor_run.run_native_notify();
  1592. }
  1593. } break;
  1594. case RUN_SCENE_SETTINGS: {
  1595. run_settings_dialog->popup_run_settings();
  1596. } break;
  1597. case RUN_SETTINGS: {
  1598. project_settings->popup_project_settings();
  1599. } break;
  1600. case RUN_PROJECT_DATA_FOLDER: {
  1601. OS::get_singleton()->shell_open(String("file://") + OS::get_singleton()->get_user_data_dir());
  1602. } break;
  1603. case FILE_QUIT:
  1604. case RUN_PROJECT_MANAGER: {
  1605. if (!p_confirmed) {
  1606. bool save_each = EDITOR_GET("interface/editor/save_each_scene_on_quit");
  1607. if (_next_unsaved_scene(!save_each) == -1) {
  1608. bool confirm = EDITOR_GET("interface/editor/quit_confirmation");
  1609. if (confirm) {
  1610. confirmation->get_ok()->set_text(p_option == FILE_QUIT ? TTR("Quit") : TTR("Yes"));
  1611. confirmation->set_text(p_option == FILE_QUIT ? TTR("Exit the editor?") : TTR("Open Project Manager?"));
  1612. confirmation->popup_centered_minsize();
  1613. } else {
  1614. _discard_changes();
  1615. break;
  1616. }
  1617. } else {
  1618. if (save_each) {
  1619. _menu_option_confirm(p_option == FILE_QUIT ? FILE_CLOSE_ALL_AND_QUIT : FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER, false);
  1620. } else {
  1621. String unsaved_scenes;
  1622. int i = _next_unsaved_scene(true, 0);
  1623. while (i != -1) {
  1624. unsaved_scenes += "\n " + editor_data.get_edited_scene_root(i)->get_filename();
  1625. i = _next_unsaved_scene(true, ++i);
  1626. }
  1627. save_confirmation->get_ok()->set_text(TTR("Save & Quit"));
  1628. save_confirmation->set_text((p_option == FILE_QUIT ? TTR("Save changes to the following scene(s) before quitting?") : TTR("Save changes the following scene(s) before opening Project Manager?")) + unsaved_scenes);
  1629. save_confirmation->popup_centered_minsize();
  1630. }
  1631. }
  1632. OS::get_singleton()->request_attention();
  1633. break;
  1634. }
  1635. if (_next_unsaved_scene(true) != -1) {
  1636. _save_all_scenes();
  1637. }
  1638. _discard_changes();
  1639. } break;
  1640. case RUN_FILE_SERVER: {
  1641. bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER));
  1642. if (ischecked) {
  1643. file_server->stop();
  1644. run_native->set_deploy_dumb(false);
  1645. } else {
  1646. file_server->start();
  1647. run_native->set_deploy_dumb(true);
  1648. }
  1649. debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER), !ischecked);
  1650. EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_file_server", !ischecked);
  1651. } break;
  1652. case RUN_LIVE_DEBUG: {
  1653. bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG));
  1654. debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG), !ischecked);
  1655. ScriptEditor::get_singleton()->get_debugger()->set_live_debugging(!ischecked);
  1656. EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_live_debug", !ischecked);
  1657. } break;
  1658. case RUN_DEPLOY_REMOTE_DEBUG: {
  1659. bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG));
  1660. debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG), !ischecked);
  1661. run_native->set_deploy_debug_remote(!ischecked);
  1662. EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_deploy_remote_debug", !ischecked);
  1663. } break;
  1664. case RUN_DEBUG_COLLISONS: {
  1665. bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS));
  1666. debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS), !ischecked);
  1667. run_native->set_debug_collisions(!ischecked);
  1668. editor_run.set_debug_collisions(!ischecked);
  1669. EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisons", !ischecked);
  1670. } break;
  1671. case RUN_DEBUG_NAVIGATION: {
  1672. bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION));
  1673. debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION), !ischecked);
  1674. run_native->set_debug_navigation(!ischecked);
  1675. editor_run.set_debug_navigation(!ischecked);
  1676. EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_navigation", !ischecked);
  1677. } break;
  1678. case RUN_RELOAD_SCRIPTS: {
  1679. bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS));
  1680. debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS), !ischecked);
  1681. ScriptEditor::get_singleton()->set_live_auto_reload_running_scripts(!ischecked);
  1682. EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_reload_scripts", !ischecked);
  1683. } break;
  1684. case SETTINGS_UPDATE_ALWAYS: {
  1685. update_menu->get_popup()->set_item_checked(0, true);
  1686. update_menu->get_popup()->set_item_checked(1, false);
  1687. OS::get_singleton()->set_low_processor_usage_mode(false);
  1688. EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_always", true);
  1689. show_accept(TTR("This option is deprecated. Situations where refresh must be forced are now considered a bug. Please report."), TTR("OK"));
  1690. } break;
  1691. case SETTINGS_UPDATE_CHANGES: {
  1692. update_menu->get_popup()->set_item_checked(0, false);
  1693. update_menu->get_popup()->set_item_checked(1, true);
  1694. OS::get_singleton()->set_low_processor_usage_mode(true);
  1695. EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_always", false);
  1696. } break;
  1697. case SETTINGS_UPDATE_SPINNER_HIDE: {
  1698. update_menu->set_icon(gui_base->get_icon("Collapse", "EditorIcons"));
  1699. update_menu->get_popup()->toggle_item_checked(3);
  1700. bool checked = update_menu->get_popup()->is_item_checked(3);
  1701. EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_spinner_hide", checked);
  1702. } break;
  1703. case SETTINGS_PREFERENCES: {
  1704. settings_config_dialog->popup_edit_settings();
  1705. } break;
  1706. case SETTINGS_EDITOR_DATA_FOLDER: {
  1707. OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_data_dir());
  1708. } break;
  1709. case SETTINGS_EDITOR_CONFIG_FOLDER: {
  1710. OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_settings_dir());
  1711. } break;
  1712. case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
  1713. export_template_manager->popup_manager();
  1714. } break;
  1715. case SETTINGS_TOGGLE_FULLSCREEN: {
  1716. OS::get_singleton()->set_window_fullscreen(!OS::get_singleton()->is_window_fullscreen());
  1717. } break;
  1718. case SETTINGS_PICK_MAIN_SCENE: {
  1719. file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
  1720. List<String> extensions;
  1721. ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
  1722. file->clear_filters();
  1723. for (int i = 0; i < extensions.size(); i++) {
  1724. file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
  1725. }
  1726. Node *scene = editor_data.get_edited_scene_root();
  1727. if (scene) {
  1728. file->set_current_path(scene->get_filename());
  1729. };
  1730. file->set_title(TTR("Pick a Main Scene"));
  1731. file->popup_centered_ratio();
  1732. } break;
  1733. case HELP_CLASSES: {
  1734. emit_signal("request_help_index", "");
  1735. } break;
  1736. case HELP_SEARCH: {
  1737. emit_signal("request_help_search", "");
  1738. } break;
  1739. case HELP_DOCS: {
  1740. OS::get_singleton()->shell_open("http://docs.godotengine.org/");
  1741. } break;
  1742. case HELP_QA: {
  1743. OS::get_singleton()->shell_open("https://godotengine.org/qa/");
  1744. } break;
  1745. case HELP_ISSUES: {
  1746. OS::get_singleton()->shell_open("https://github.com/godotengine/godot/issues");
  1747. } break;
  1748. case HELP_COMMUNITY: {
  1749. OS::get_singleton()->shell_open("https://godotengine.org/community");
  1750. } break;
  1751. case HELP_ABOUT: {
  1752. about->popup_centered_minsize(Size2(780, 500) * EDSCALE);
  1753. } break;
  1754. case SET_VIDEO_DRIVER_SAVE_AND_RESTART: {
  1755. ProjectSettings::get_singleton()->set("rendering/quality/driver/driver_name", video_driver_request);
  1756. ProjectSettings::get_singleton()->save();
  1757. save_all_scenes_and_restart();
  1758. } break;
  1759. default: {
  1760. if (p_option >= IMPORT_PLUGIN_BASE) {
  1761. }
  1762. }
  1763. }
  1764. }
  1765. void EditorNode::_tool_menu_option(int p_idx) {
  1766. switch (tool_menu->get_item_id(p_idx)) {
  1767. case TOOLS_ORPHAN_RESOURCES: {
  1768. orphan_resources->show();
  1769. } break;
  1770. case TOOLS_CUSTOM: {
  1771. if (tool_menu->get_item_submenu(p_idx) == "") {
  1772. Array params = tool_menu->get_item_metadata(p_idx);
  1773. Object *handler = ObjectDB::get_instance(params[0]);
  1774. String callback = params[1];
  1775. Variant *ud = &params[2];
  1776. Variant::CallError ce;
  1777. handler->call(callback, (const Variant **)&ud, 1, ce);
  1778. if (ce.error != Variant::CallError::CALL_OK) {
  1779. String err = Variant::get_call_error_text(handler, callback, (const Variant **)&ud, 1, ce);
  1780. ERR_PRINTS("Error calling function from tool menu: " + err);
  1781. }
  1782. } // else it's a submenu so don't do anything.
  1783. } break;
  1784. }
  1785. }
  1786. int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) {
  1787. for (int i = p_start; i < editor_data.get_edited_scene_count(); i++) {
  1788. if (!editor_data.get_edited_scene_root(i))
  1789. continue;
  1790. int current = editor_data.get_edited_scene();
  1791. bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
  1792. if (unsaved) {
  1793. String scene_filename = editor_data.get_edited_scene_root(i)->get_filename();
  1794. if (p_valid_filename && scene_filename.length() == 0)
  1795. continue;
  1796. return i;
  1797. }
  1798. }
  1799. return -1;
  1800. }
  1801. void EditorNode::_discard_changes(const String &p_str) {
  1802. switch (current_option) {
  1803. case FILE_CLOSE_ALL_AND_QUIT:
  1804. case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
  1805. case FILE_CLOSE:
  1806. case SCENE_TAB_CLOSE: {
  1807. _remove_scene(tab_closing);
  1808. _update_scene_tabs();
  1809. if (current_option == FILE_CLOSE_ALL_AND_QUIT || current_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) {
  1810. if (_next_unsaved_scene(false) == -1) {
  1811. current_option = current_option == FILE_CLOSE_ALL_AND_QUIT ? FILE_QUIT : RUN_PROJECT_MANAGER;
  1812. _discard_changes();
  1813. } else {
  1814. _menu_option_confirm(current_option, false);
  1815. }
  1816. } else {
  1817. current_option = -1;
  1818. save_confirmation->hide();
  1819. }
  1820. } break;
  1821. case FILE_QUIT: {
  1822. _menu_option_confirm(RUN_STOP, true);
  1823. exiting = true;
  1824. get_tree()->quit();
  1825. } break;
  1826. case RUN_PROJECT_MANAGER: {
  1827. _menu_option_confirm(RUN_STOP, true);
  1828. exiting = true;
  1829. get_tree()->quit();
  1830. String exec = OS::get_singleton()->get_executable_path();
  1831. List<String> args;
  1832. args.push_back("--path");
  1833. args.push_back(exec.get_base_dir());
  1834. args.push_back("--project-manager");
  1835. OS::ProcessID pid = 0;
  1836. Error err = OS::get_singleton()->execute(exec, args, false, &pid);
  1837. ERR_FAIL_COND(err);
  1838. } break;
  1839. }
  1840. }
  1841. void EditorNode::_update_debug_options() {
  1842. bool check_deploy_remote = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_deploy_remote_debug", false);
  1843. bool check_file_server = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_file_server", false);
  1844. bool check_debug_collisons = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false);
  1845. bool check_debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
  1846. bool check_live_debug = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_live_debug", false);
  1847. bool check_reload_scripts = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_reload_scripts", false);
  1848. if (check_deploy_remote) _menu_option_confirm(RUN_DEPLOY_REMOTE_DEBUG, true);
  1849. if (check_file_server) _menu_option_confirm(RUN_FILE_SERVER, true);
  1850. if (check_debug_collisons) _menu_option_confirm(RUN_DEBUG_COLLISONS, true);
  1851. if (check_debug_navigation) _menu_option_confirm(RUN_DEBUG_NAVIGATION, true);
  1852. if (check_live_debug) _menu_option_confirm(RUN_LIVE_DEBUG, true);
  1853. if (check_reload_scripts) _menu_option_confirm(RUN_RELOAD_SCRIPTS, true);
  1854. }
  1855. Control *EditorNode::get_viewport() {
  1856. return viewport;
  1857. }
  1858. void EditorNode::_editor_select(int p_which) {
  1859. static bool selecting = false;
  1860. if (selecting || changing_scene)
  1861. return;
  1862. selecting = true;
  1863. ERR_FAIL_INDEX(p_which, editor_table.size());
  1864. for (int i = 0; i < main_editor_buttons.size(); i++) {
  1865. main_editor_buttons[i]->set_pressed(i == p_which);
  1866. }
  1867. selecting = false;
  1868. EditorPlugin *new_editor = editor_table[p_which];
  1869. ERR_FAIL_COND(!new_editor);
  1870. if (editor_plugin_screen == new_editor)
  1871. return;
  1872. if (editor_plugin_screen) {
  1873. editor_plugin_screen->make_visible(false);
  1874. }
  1875. editor_plugin_screen = new_editor;
  1876. editor_plugin_screen->make_visible(true);
  1877. editor_plugin_screen->selected_notify();
  1878. int plugin_count = editor_data.get_editor_plugin_count();
  1879. for (int i = 0; i < plugin_count; i++) {
  1880. editor_data.get_editor_plugin(i)->notify_main_screen_changed(editor_plugin_screen->get_name());
  1881. }
  1882. if (EditorSettings::get_singleton()->get("interface/editor/separate_distraction_mode")) {
  1883. if (p_which == EDITOR_SCRIPT) {
  1884. set_distraction_free_mode(script_distraction);
  1885. } else {
  1886. set_distraction_free_mode(scene_distraction);
  1887. }
  1888. }
  1889. }
  1890. void EditorNode::add_editor_plugin(EditorPlugin *p_editor) {
  1891. if (p_editor->has_main_screen()) {
  1892. ToolButton *tb = memnew(ToolButton);
  1893. tb->set_toggle_mode(true);
  1894. tb->connect("pressed", singleton, "_editor_select", varray(singleton->main_editor_buttons.size()));
  1895. tb->set_text(p_editor->get_name());
  1896. Ref<Texture> icon = p_editor->get_icon();
  1897. if (icon.is_valid()) {
  1898. tb->set_icon(icon);
  1899. } else if (singleton->gui_base->has_icon(p_editor->get_name(), "EditorIcons")) {
  1900. tb->set_icon(singleton->gui_base->get_icon(p_editor->get_name(), "EditorIcons"));
  1901. }
  1902. tb->set_name(p_editor->get_name());
  1903. singleton->main_editor_buttons.push_back(tb);
  1904. singleton->main_editor_button_vb->add_child(tb);
  1905. singleton->editor_table.push_back(p_editor);
  1906. singleton->distraction_free->raise();
  1907. }
  1908. singleton->editor_data.add_editor_plugin(p_editor);
  1909. singleton->add_child(p_editor);
  1910. }
  1911. void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) {
  1912. if (p_editor->has_main_screen()) {
  1913. for (int i = 0; i < singleton->main_editor_buttons.size(); i++) {
  1914. if (p_editor->get_name() == singleton->main_editor_buttons[i]->get_text()) {
  1915. if (singleton->main_editor_buttons[i]->is_pressed()) {
  1916. singleton->_editor_select(EDITOR_SCRIPT);
  1917. }
  1918. memdelete(singleton->main_editor_buttons[i]);
  1919. singleton->main_editor_buttons.remove(i);
  1920. break;
  1921. }
  1922. }
  1923. singleton->editor_table.erase(p_editor);
  1924. }
  1925. p_editor->make_visible(false);
  1926. p_editor->clear();
  1927. singleton->editor_plugins_over->get_plugins_list().erase(p_editor);
  1928. singleton->remove_child(p_editor);
  1929. singleton->editor_data.remove_editor_plugin(p_editor);
  1930. }
  1931. void EditorNode::_update_addon_config() {
  1932. if (_initializing_addons)
  1933. return;
  1934. Vector<String> enabled_addons;
  1935. for (Map<String, EditorPlugin *>::Element *E = plugin_addons.front(); E; E = E->next()) {
  1936. enabled_addons.push_back(E->key());
  1937. }
  1938. if (enabled_addons.size() == 0) {
  1939. ProjectSettings::get_singleton()->set("editor_plugins/enabled", Variant());
  1940. } else {
  1941. ProjectSettings::get_singleton()->set("editor_plugins/enabled", enabled_addons);
  1942. }
  1943. project_settings->queue_save();
  1944. }
  1945. void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled) {
  1946. ERR_FAIL_COND(p_enabled && plugin_addons.has(p_addon));
  1947. ERR_FAIL_COND(!p_enabled && !plugin_addons.has(p_addon));
  1948. if (!p_enabled) {
  1949. EditorPlugin *addon = plugin_addons[p_addon];
  1950. remove_editor_plugin(addon);
  1951. memdelete(addon); //bye
  1952. plugin_addons.erase(p_addon);
  1953. _update_addon_config();
  1954. return;
  1955. }
  1956. Ref<ConfigFile> cf;
  1957. cf.instance();
  1958. String addon_path = "res://addons/" + p_addon + "/plugin.cfg";
  1959. Error err = cf->load(addon_path);
  1960. if (err != OK) {
  1961. show_warning(vformat(TTR("Unable to enable addon plugin at: '%s' parsing of config failed."), addon_path));
  1962. return;
  1963. }
  1964. if (!cf->has_section_key("plugin", "script")) {
  1965. show_warning(vformat(TTR("Unable to find script field for addon plugin at: 'res://addons/%s'."), p_addon));
  1966. return;
  1967. }
  1968. String path = cf->get_value("plugin", "script");
  1969. path = "res://addons/" + p_addon + "/" + path;
  1970. Ref<Script> script = ResourceLoader::load(path);
  1971. if (script.is_null()) {
  1972. show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), path));
  1973. return;
  1974. }
  1975. //could check inheritance..
  1976. if (String(script->get_instance_base_type()) != "EditorPlugin") {
  1977. show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), path));
  1978. return;
  1979. }
  1980. if (!script->is_tool()) {
  1981. show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), path));
  1982. return;
  1983. }
  1984. EditorPlugin *ep = memnew(EditorPlugin);
  1985. ep->set_script(script.get_ref_ptr());
  1986. ep->set_dir_cache(p_addon);
  1987. plugin_addons[p_addon] = ep;
  1988. add_editor_plugin(ep);
  1989. _update_addon_config();
  1990. }
  1991. bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const {
  1992. return plugin_addons.has(p_addon);
  1993. }
  1994. void EditorNode::_remove_edited_scene() {
  1995. int new_index = editor_data.get_edited_scene();
  1996. int old_index = new_index;
  1997. if (new_index > 0) {
  1998. new_index = new_index - 1;
  1999. } else if (editor_data.get_edited_scene_count() > 1) {
  2000. new_index = 1;
  2001. } else {
  2002. editor_data.add_edited_scene(-1);
  2003. new_index = 1;
  2004. }
  2005. if (editor_data.get_scene_path(old_index) != String()) {
  2006. ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(editor_data.get_scene_path(old_index));
  2007. }
  2008. _scene_tab_changed(new_index);
  2009. editor_data.remove_scene(old_index);
  2010. editor_data.get_undo_redo().clear_history();
  2011. _update_title();
  2012. _update_scene_tabs();
  2013. }
  2014. void EditorNode::_remove_scene(int index) {
  2015. if (editor_data.get_edited_scene() == index) {
  2016. //Scene to remove is current scene
  2017. _remove_edited_scene();
  2018. } else {
  2019. //Scene to remove is not active scene
  2020. editor_data.remove_scene(index);
  2021. }
  2022. }
  2023. void EditorNode::set_edited_scene(Node *p_scene) {
  2024. if (get_editor_data().get_edited_scene_root()) {
  2025. if (get_editor_data().get_edited_scene_root()->get_parent() == scene_root)
  2026. scene_root->remove_child(get_editor_data().get_edited_scene_root());
  2027. }
  2028. get_editor_data().set_edited_scene_root(p_scene);
  2029. if (Object::cast_to<Popup>(p_scene))
  2030. Object::cast_to<Popup>(p_scene)->show(); //show popups
  2031. scene_tree_dock->set_edited_scene(p_scene);
  2032. if (get_tree())
  2033. get_tree()->set_edited_scene_root(p_scene);
  2034. if (p_scene) {
  2035. if (p_scene->get_parent() != scene_root)
  2036. scene_root->add_child(p_scene);
  2037. }
  2038. }
  2039. int EditorNode::_get_current_main_editor() {
  2040. for (int i = 0; i < editor_table.size(); i++) {
  2041. if (editor_table[i] == editor_plugin_screen)
  2042. return i;
  2043. }
  2044. return 0;
  2045. }
  2046. Dictionary EditorNode::_get_main_scene_state() {
  2047. Dictionary state;
  2048. state["main_tab"] = _get_current_main_editor();
  2049. state["scene_tree_offset"] = scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_value();
  2050. state["property_edit_offset"] = get_inspector()->get_scroll_offset();
  2051. state["saved_version"] = saved_version;
  2052. state["node_filter"] = scene_tree_dock->get_filter();
  2053. return state;
  2054. }
  2055. void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
  2056. if (get_edited_scene() != p_for_scene && p_for_scene != NULL)
  2057. return; //not for this scene
  2058. changing_scene = false;
  2059. int current = -1;
  2060. for (int i = 0; i < editor_table.size(); i++) {
  2061. if (editor_plugin_screen == editor_table[i]) {
  2062. current = i;
  2063. break;
  2064. }
  2065. }
  2066. if (p_state.has("editor_index")) {
  2067. int index = p_state["editor_index"];
  2068. if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if currently in script, stay there
  2069. if (index < 2 || !get_edited_scene()) {
  2070. _editor_select(index);
  2071. }
  2072. }
  2073. }
  2074. if (get_edited_scene()) {
  2075. if (current < 2) {
  2076. //use heuristic instead
  2077. int n2d = 0, n3d = 0;
  2078. _find_node_types(get_edited_scene(), n2d, n3d);
  2079. if (n2d > n3d) {
  2080. _editor_select(EDITOR_2D);
  2081. } else if (n3d > n2d) {
  2082. _editor_select(EDITOR_3D);
  2083. }
  2084. }
  2085. }
  2086. if (p_state.has("scene_tree_offset"))
  2087. scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->set_value(p_state["scene_tree_offset"]);
  2088. if (p_state.has("property_edit_offset"))
  2089. get_inspector()->set_scroll_offset(p_state["property_edit_offset"]);
  2090. if (p_state.has("node_filter"))
  2091. scene_tree_dock->set_filter(p_state["node_filter"]);
  2092. //this should only happen at the very end
  2093. ScriptEditor::get_singleton()->get_debugger()->update_live_edit_root();
  2094. ScriptEditor::get_singleton()->set_scene_root_script(editor_data.get_scene_root_script(editor_data.get_edited_scene()));
  2095. editor_data.notify_edited_scene_changed();
  2096. }
  2097. void EditorNode::set_current_version(uint64_t p_version) {
  2098. saved_version = p_version;
  2099. editor_data.set_edited_scene_version(p_version);
  2100. }
  2101. bool EditorNode::is_changing_scene() const {
  2102. return changing_scene;
  2103. }
  2104. void EditorNode::_clear_undo_history() {
  2105. get_undo_redo()->clear_history();
  2106. }
  2107. void EditorNode::set_current_scene(int p_idx) {
  2108. if (editor_data.check_and_update_scene(p_idx)) {
  2109. call_deferred("_clear_undo_history");
  2110. }
  2111. changing_scene = true;
  2112. editor_data.save_edited_scene_state(editor_selection, &editor_history, _get_main_scene_state());
  2113. if (get_editor_data().get_edited_scene_root()) {
  2114. if (get_editor_data().get_edited_scene_root()->get_parent() == scene_root)
  2115. scene_root->remove_child(get_editor_data().get_edited_scene_root());
  2116. }
  2117. editor_selection->clear();
  2118. editor_data.set_edited_scene(p_idx);
  2119. Node *new_scene = editor_data.get_edited_scene_root();
  2120. if (Object::cast_to<Popup>(new_scene))
  2121. Object::cast_to<Popup>(new_scene)->show(); //show popups
  2122. scene_tree_dock->set_edited_scene(new_scene);
  2123. if (get_tree())
  2124. get_tree()->set_edited_scene_root(new_scene);
  2125. if (new_scene) {
  2126. if (new_scene->get_parent() != scene_root)
  2127. scene_root->add_child(new_scene);
  2128. }
  2129. Dictionary state = editor_data.restore_edited_scene_state(editor_selection, &editor_history);
  2130. _edit_current();
  2131. _update_title();
  2132. call_deferred("_set_main_scene_state", state, get_edited_scene()); //do after everything else is done setting up
  2133. }
  2134. bool EditorNode::is_scene_open(const String &p_path) {
  2135. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  2136. if (editor_data.get_scene_path(i) == p_path)
  2137. return true;
  2138. }
  2139. return false;
  2140. }
  2141. void EditorNode::fix_dependencies(const String &p_for_file) {
  2142. dependency_fixer->edit(p_for_file);
  2143. }
  2144. Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) {
  2145. if (!is_inside_tree()) {
  2146. defer_load_scene = p_scene;
  2147. return OK;
  2148. }
  2149. if (!p_set_inherited) {
  2150. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  2151. if (editor_data.get_scene_path(i) == p_scene) {
  2152. _scene_tab_changed(i);
  2153. return OK;
  2154. }
  2155. }
  2156. if (!p_force_open_imported && FileAccess::exists(p_scene + ".import")) {
  2157. open_imported->set_text(vformat(TTR("Scene '%s' was automatically imported, so it can't be modified.\nTo make changes to it, a new inherited scene can be created."), p_scene.get_file()));
  2158. open_imported->popup_centered_minsize();
  2159. new_inherited_button->grab_focus();
  2160. open_import_request = p_scene;
  2161. return OK;
  2162. }
  2163. }
  2164. if (p_clear_errors)
  2165. load_errors->clear();
  2166. String lpath = ProjectSettings::get_singleton()->localize_path(p_scene);
  2167. if (!lpath.begins_with("res://")) {
  2168. show_accept(TTR("Error loading scene, it must be inside the project path. Use 'Import' to open the scene, then save it inside the project path."), TTR("OK"));
  2169. opening_prev = false;
  2170. return ERR_FILE_NOT_FOUND;
  2171. }
  2172. int prev = editor_data.get_edited_scene();
  2173. int idx = editor_data.add_edited_scene(-1);
  2174. if (!editor_data.get_edited_scene_root() && editor_data.get_edited_scene_count() == 2) {
  2175. _remove_edited_scene();
  2176. } else {
  2177. _scene_tab_changed(idx);
  2178. }
  2179. dependency_errors.clear();
  2180. Error err;
  2181. Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err);
  2182. if (!sdata.is_valid()) {
  2183. _dialog_display_load_error(lpath, err);
  2184. opening_prev = false;
  2185. if (prev != -1) {
  2186. set_current_scene(prev);
  2187. editor_data.remove_scene(idx);
  2188. }
  2189. return ERR_FILE_NOT_FOUND;
  2190. }
  2191. if (!p_ignore_broken_deps && dependency_errors.has(lpath)) {
  2192. current_option = -1;
  2193. Vector<String> errors;
  2194. for (Set<String>::Element *E = dependency_errors[lpath].front(); E; E = E->next()) {
  2195. errors.push_back(E->get());
  2196. }
  2197. dependency_error->show(lpath, errors);
  2198. opening_prev = false;
  2199. if (prev != -1) {
  2200. set_current_scene(prev);
  2201. editor_data.remove_scene(idx);
  2202. }
  2203. return ERR_FILE_MISSING_DEPENDENCIES;
  2204. }
  2205. dependency_errors.erase(lpath); //at least not self path
  2206. for (Map<String, Set<String> >::Element *E = dependency_errors.front(); E; E = E->next()) {
  2207. String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E->key()) + "\n";
  2208. for (Set<String>::Element *F = E->get().front(); F; F = F->next()) {
  2209. txt += "\t" + F->get() + "\n";
  2210. }
  2211. add_io_error(txt);
  2212. }
  2213. if (ResourceCache::has(lpath)) {
  2214. //used from somewhere else? no problem! update state and replace sdata
  2215. Ref<PackedScene> ps = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(lpath)));
  2216. if (ps.is_valid()) {
  2217. ps->replace_state(sdata->get_state());
  2218. ps->set_last_modified_time(sdata->get_last_modified_time());
  2219. sdata = ps;
  2220. }
  2221. } else {
  2222. sdata->set_path(lpath, true); //take over path
  2223. }
  2224. Node *new_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_MAIN);
  2225. if (!new_scene) {
  2226. sdata.unref();
  2227. _dialog_display_load_error(lpath, ERR_FILE_NOT_FOUND);
  2228. opening_prev = false;
  2229. if (prev != -1) {
  2230. set_current_scene(prev);
  2231. editor_data.remove_scene(idx);
  2232. }
  2233. return ERR_FILE_NOT_FOUND;
  2234. }
  2235. if (p_set_inherited) {
  2236. Ref<SceneState> state = sdata->get_state();
  2237. state->set_path(lpath);
  2238. new_scene->set_scene_inherited_state(state);
  2239. new_scene->set_filename(String());
  2240. }
  2241. new_scene->set_scene_instance_state(Ref<SceneState>());
  2242. set_edited_scene(new_scene);
  2243. _get_scene_metadata(p_scene);
  2244. saved_version = editor_data.get_undo_redo().get_version();
  2245. _update_title();
  2246. _update_scene_tabs();
  2247. _add_to_recent_scenes(lpath);
  2248. prev_scene->set_disabled(previous_scenes.size() == 0);
  2249. opening_prev = false;
  2250. ScriptEditor::get_singleton()->get_debugger()->update_live_edit_root();
  2251. push_item(new_scene);
  2252. if (!restoring_scenes) {
  2253. save_layout();
  2254. }
  2255. return OK;
  2256. }
  2257. void EditorNode::open_request(const String &p_path) {
  2258. load_scene(p_path); // as it will be opened in separate tab
  2259. }
  2260. void EditorNode::request_instance_scene(const String &p_path) {
  2261. scene_tree_dock->instance(p_path);
  2262. }
  2263. void EditorNode::request_instance_scenes(const Vector<String> &p_files) {
  2264. scene_tree_dock->instance_scenes(p_files);
  2265. }
  2266. ImportDock *EditorNode::get_import_dock() {
  2267. return import_dock;
  2268. }
  2269. FileSystemDock *EditorNode::get_filesystem_dock() {
  2270. return filesystem_dock;
  2271. }
  2272. SceneTreeDock *EditorNode::get_scene_tree_dock() {
  2273. return scene_tree_dock;
  2274. }
  2275. InspectorDock *EditorNode::get_inspector_dock() {
  2276. return inspector_dock;
  2277. }
  2278. void EditorNode::_instance_request(const Vector<String> &p_files) {
  2279. request_instance_scenes(p_files);
  2280. }
  2281. void EditorNode::_close_messages() {
  2282. old_split_ofs = center_split->get_split_offset();
  2283. center_split->set_split_offset(0);
  2284. }
  2285. void EditorNode::_show_messages() {
  2286. center_split->set_split_offset(old_split_ofs);
  2287. }
  2288. void EditorNode::_add_to_recent_scenes(const String &p_scene) {
  2289. Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scenes", Array());
  2290. if (rc.find(p_scene) != -1)
  2291. rc.erase(p_scene);
  2292. rc.push_front(p_scene);
  2293. if (rc.size() > 10)
  2294. rc.resize(10);
  2295. EditorSettings::get_singleton()->set_project_metadata("recent_files", "scenes", rc);
  2296. _update_recent_scenes();
  2297. }
  2298. void EditorNode::_open_recent_scene(int p_idx) {
  2299. if (p_idx == recent_scenes->get_item_count() - 1) {
  2300. EditorSettings::get_singleton()->set_project_metadata("recent_files", "scenes", Array());
  2301. call_deferred("_update_recent_scenes");
  2302. } else {
  2303. Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scenes", Array());
  2304. ERR_FAIL_INDEX(p_idx, rc.size());
  2305. if (load_scene(rc[p_idx]) != OK) {
  2306. rc.remove(p_idx);
  2307. EditorSettings::get_singleton()->set_project_metadata("recent_files", "scenes", rc);
  2308. _update_recent_scenes();
  2309. }
  2310. }
  2311. }
  2312. void EditorNode::_update_recent_scenes() {
  2313. Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scenes", Array());
  2314. recent_scenes->clear();
  2315. String path;
  2316. for (int i = 0; i < rc.size(); i++) {
  2317. path = rc[i];
  2318. recent_scenes->add_item(path.replace("res://", ""), i);
  2319. }
  2320. recent_scenes->add_separator();
  2321. recent_scenes->add_shortcut(ED_SHORTCUT("editor/clear_recent", TTR("Clear Recent Scenes")));
  2322. recent_scenes->set_as_minsize();
  2323. }
  2324. void EditorNode::_quick_opened() {
  2325. Vector<String> files = quick_open->get_selected_files();
  2326. for (int i = 0; i < files.size(); i++) {
  2327. String res_path = files[i];
  2328. if (quick_open->get_base_type() == "PackedScene") {
  2329. open_request(res_path);
  2330. } else {
  2331. load_resource(res_path);
  2332. }
  2333. }
  2334. }
  2335. void EditorNode::_quick_run() {
  2336. _run(false, quick_run->get_selected());
  2337. }
  2338. void EditorNode::notify_child_process_exited() {
  2339. _menu_option_confirm(RUN_STOP, false);
  2340. stop_button->set_pressed(false);
  2341. editor_run.stop();
  2342. }
  2343. void EditorNode::add_io_error(const String &p_error) {
  2344. _load_error_notify(singleton, p_error);
  2345. }
  2346. void EditorNode::_load_error_notify(void *p_ud, const String &p_text) {
  2347. EditorNode *en = (EditorNode *)p_ud;
  2348. en->load_errors->add_image(en->gui_base->get_icon("Error", "EditorIcons"));
  2349. en->load_errors->add_text(p_text + "\n");
  2350. en->load_error_dialog->popup_centered_ratio(0.5);
  2351. }
  2352. bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
  2353. if (p_node->get_filename() == p_path) {
  2354. return true;
  2355. }
  2356. for (int i = 0; i < p_node->get_child_count(); i++) {
  2357. if (_find_scene_in_use(p_node->get_child(i), p_path)) {
  2358. return true;
  2359. }
  2360. }
  2361. return false;
  2362. }
  2363. bool EditorNode::is_scene_in_use(const String &p_path) {
  2364. Node *es = get_edited_scene();
  2365. if (es)
  2366. return _find_scene_in_use(es, p_path);
  2367. return false;
  2368. }
  2369. void EditorNode::register_editor_types() {
  2370. ClassDB::register_class<EditorPlugin>();
  2371. ClassDB::register_class<EditorImportPlugin>();
  2372. ClassDB::register_class<EditorScript>();
  2373. ClassDB::register_class<EditorSelection>();
  2374. ClassDB::register_class<EditorFileDialog>();
  2375. ClassDB::register_virtual_class<EditorSettings>();
  2376. ClassDB::register_class<EditorSpatialGizmo>();
  2377. ClassDB::register_virtual_class<EditorResourcePreview>();
  2378. ClassDB::register_class<EditorResourcePreviewGenerator>();
  2379. ClassDB::register_virtual_class<EditorFileSystem>();
  2380. ClassDB::register_class<EditorFileSystemDirectory>();
  2381. ClassDB::register_virtual_class<ScriptEditor>();
  2382. ClassDB::register_virtual_class<EditorInterface>();
  2383. ClassDB::register_class<EditorExportPlugin>();
  2384. ClassDB::register_class<EditorResourceConversionPlugin>();
  2385. ClassDB::register_class<EditorSceneImporter>();
  2386. ClassDB::register_class<EditorInspector>();
  2387. ClassDB::register_class<EditorInspectorPlugin>();
  2388. ClassDB::register_class<EditorProperty>();
  2389. ClassDB::register_class<AnimationTrackEditPlugin>();
  2390. ClassDB::register_class<ScriptCreateDialog>();
  2391. // FIXME: Is this stuff obsolete, or should it be ported to new APIs?
  2392. ClassDB::register_class<EditorScenePostImport>();
  2393. //ClassDB::register_type<EditorImportExport>();
  2394. }
  2395. void EditorNode::unregister_editor_types() {
  2396. _init_callbacks.clear();
  2397. }
  2398. void EditorNode::stop_child_process() {
  2399. _menu_option_confirm(RUN_STOP, false);
  2400. }
  2401. Ref<Texture> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) const {
  2402. ERR_FAIL_COND_V(!p_object || !gui_base, NULL);
  2403. Ref<Script> script = p_object->get_script();
  2404. if (script.is_null() && p_object->is_class("Script")) {
  2405. script = p_object;
  2406. }
  2407. StringName name;
  2408. String icon_path;
  2409. if (script.is_valid()) {
  2410. name = EditorNode::get_editor_data().script_class_get_name(script->get_path());
  2411. icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name);
  2412. name = script->get_instance_base_type();
  2413. }
  2414. if (gui_base->has_icon(p_object->get_class(), "EditorIcons"))
  2415. return gui_base->get_icon(p_object->get_class(), "EditorIcons");
  2416. if (icon_path.length())
  2417. return ResourceLoader::load(icon_path);
  2418. if (p_object->has_meta("_editor_icon"))
  2419. return p_object->get_meta("_editor_icon");
  2420. if (name != StringName()) {
  2421. const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types();
  2422. for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) {
  2423. const Vector<EditorData::CustomType> &ct = E->value();
  2424. for (int i = 0; i < ct.size(); ++i) {
  2425. if (ct[i].name == name && ct[i].icon.is_valid()) {
  2426. return ct[i].icon;
  2427. }
  2428. }
  2429. }
  2430. }
  2431. if (p_fallback.length())
  2432. return gui_base->get_icon(p_fallback, "EditorIcons");
  2433. return NULL;
  2434. }
  2435. Ref<Texture> EditorNode::get_class_icon(const String &p_class, const String &p_fallback) const {
  2436. ERR_FAIL_COND_V(p_class.empty(), NULL);
  2437. if (gui_base->has_icon(p_class, "EditorIcons")) {
  2438. return gui_base->get_icon(p_class, "EditorIcons");
  2439. }
  2440. if (ScriptServer::is_global_class(p_class)) {
  2441. String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(p_class);
  2442. RES icon;
  2443. if (FileAccess::exists(icon_path)) {
  2444. icon = ResourceLoader::load(icon_path);
  2445. }
  2446. if (!icon.is_valid()) {
  2447. icon = gui_base->get_icon(ScriptServer::get_global_class_base(p_class), "EditorIcons");
  2448. }
  2449. return icon;
  2450. }
  2451. const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types();
  2452. for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) {
  2453. const Vector<EditorData::CustomType> &ct = E->value();
  2454. for (int i = 0; i < ct.size(); ++i) {
  2455. if (ct[i].name == p_class) {
  2456. if (ct[i].icon.is_valid()) {
  2457. return ct[i].icon;
  2458. }
  2459. }
  2460. }
  2461. }
  2462. if (p_fallback.length() && gui_base->has_icon(p_fallback, "EditorIcons"))
  2463. return gui_base->get_icon(p_fallback, "EditorIcons");
  2464. return NULL;
  2465. }
  2466. void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
  2467. singleton->progress_dialog->add_task(p_task, p_label, p_steps, p_can_cancel);
  2468. }
  2469. bool EditorNode::progress_task_step(const String &p_task, const String &p_state, int p_step, bool p_force_refresh) {
  2470. return singleton->progress_dialog->task_step(p_task, p_state, p_step, p_force_refresh);
  2471. }
  2472. void EditorNode::progress_end_task(const String &p_task) {
  2473. singleton->progress_dialog->end_task(p_task);
  2474. }
  2475. void EditorNode::progress_add_task_bg(const String &p_task, const String &p_label, int p_steps) {
  2476. singleton->progress_hb->add_task(p_task, p_label, p_steps);
  2477. }
  2478. void EditorNode::progress_task_step_bg(const String &p_task, int p_step) {
  2479. singleton->progress_hb->task_step(p_task, p_step);
  2480. }
  2481. void EditorNode::progress_end_task_bg(const String &p_task) {
  2482. singleton->progress_hb->end_task(p_task);
  2483. }
  2484. Ref<Texture> EditorNode::_file_dialog_get_icon(const String &p_path) {
  2485. EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem_path(p_path.get_base_dir());
  2486. if (efsd) {
  2487. String file = p_path.get_file();
  2488. for (int i = 0; i < efsd->get_file_count(); i++) {
  2489. if (efsd->get_file(i) == file) {
  2490. String type = efsd->get_file_type(i);
  2491. if (singleton->icon_type_cache.has(type)) {
  2492. return singleton->icon_type_cache[type];
  2493. } else {
  2494. return singleton->icon_type_cache["Object"];
  2495. }
  2496. }
  2497. }
  2498. }
  2499. return singleton->icon_type_cache["Object"];
  2500. }
  2501. void EditorNode::_build_icon_type_cache() {
  2502. List<StringName> tl;
  2503. StringName ei = "EditorIcons";
  2504. theme_base->get_theme()->get_icon_list(ei, &tl);
  2505. for (List<StringName>::Element *E = tl.front(); E; E = E->next()) {
  2506. if (!ClassDB::class_exists(E->get()))
  2507. continue;
  2508. icon_type_cache[E->get()] = theme_base->get_theme()->get_icon(E->get(), ei);
  2509. }
  2510. }
  2511. void EditorNode::_file_dialog_register(FileDialog *p_dialog) {
  2512. singleton->file_dialogs.insert(p_dialog);
  2513. }
  2514. void EditorNode::_file_dialog_unregister(FileDialog *p_dialog) {
  2515. singleton->file_dialogs.erase(p_dialog);
  2516. }
  2517. void EditorNode::_editor_file_dialog_register(EditorFileDialog *p_dialog) {
  2518. singleton->editor_file_dialogs.insert(p_dialog);
  2519. }
  2520. void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) {
  2521. singleton->editor_file_dialogs.erase(p_dialog);
  2522. }
  2523. Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
  2524. Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after) {
  2525. export_defer.preset = p_preset;
  2526. export_defer.path = p_path;
  2527. export_defer.debug = p_debug;
  2528. export_defer.password = p_password;
  2529. return OK;
  2530. }
  2531. void EditorNode::show_accept(const String &p_text, const String &p_title) {
  2532. current_option = -1;
  2533. accept->get_ok()->set_text(p_title);
  2534. accept->set_text(p_text);
  2535. accept->popup_centered_minsize();
  2536. }
  2537. void EditorNode::show_warning(const String &p_text, const String &p_title) {
  2538. warning->set_text(p_text);
  2539. warning->set_title(p_title);
  2540. warning->popup_centered_minsize();
  2541. }
  2542. void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
  2543. Ref<InputEventMouse> me = p_input;
  2544. if (me.is_valid()) {
  2545. Vector2 point = me->get_position();
  2546. int nrect = -1;
  2547. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2548. if (dock_select_rect[i].has_point(point)) {
  2549. nrect = i;
  2550. break;
  2551. }
  2552. }
  2553. if (nrect != dock_select_rect_over) {
  2554. dock_select->update();
  2555. dock_select_rect_over = nrect;
  2556. }
  2557. if (nrect == -1)
  2558. return;
  2559. Ref<InputEventMouseButton> mb = me;
  2560. if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && dock_popup_selected != nrect) {
  2561. Control *dock = dock_slot[dock_popup_selected]->get_current_tab_control();
  2562. if (dock) {
  2563. dock_slot[dock_popup_selected]->remove_child(dock);
  2564. }
  2565. if (dock_slot[dock_popup_selected]->get_tab_count() == 0) {
  2566. dock_slot[dock_popup_selected]->hide();
  2567. } else {
  2568. dock_slot[dock_popup_selected]->set_current_tab(0);
  2569. }
  2570. dock_slot[nrect]->add_child(dock);
  2571. dock_popup_selected = nrect;
  2572. dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count() - 1);
  2573. dock_slot[nrect]->show();
  2574. dock_select->update();
  2575. for (int i = 0; i < vsplits.size(); i++) {
  2576. bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
  2577. if (in_use)
  2578. vsplits[i]->show();
  2579. else
  2580. vsplits[i]->hide();
  2581. }
  2582. if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
  2583. right_hsplit->show();
  2584. else
  2585. right_hsplit->hide();
  2586. _edit_current();
  2587. _save_docks();
  2588. }
  2589. }
  2590. }
  2591. void EditorNode::_dock_popup_exit() {
  2592. dock_select_rect_over = -1;
  2593. dock_select->update();
  2594. }
  2595. void EditorNode::_dock_pre_popup(int p_which) {
  2596. dock_popup_selected = p_which;
  2597. }
  2598. void EditorNode::_dock_move_left() {
  2599. if (dock_popup_selected < 0 || dock_popup_selected >= DOCK_SLOT_MAX)
  2600. return;
  2601. Control *current = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab());
  2602. Control *prev = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab() - 1);
  2603. if (!current || !prev)
  2604. return;
  2605. dock_slot[dock_popup_selected]->move_child(current, prev->get_index());
  2606. dock_slot[dock_popup_selected]->set_current_tab(dock_slot[dock_popup_selected]->get_current_tab() - 1);
  2607. dock_select->update();
  2608. _edit_current();
  2609. _save_docks();
  2610. }
  2611. void EditorNode::_dock_move_right() {
  2612. Control *current = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab());
  2613. Control *next = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab() + 1);
  2614. if (!current || !next)
  2615. return;
  2616. dock_slot[dock_popup_selected]->move_child(next, current->get_index());
  2617. dock_slot[dock_popup_selected]->set_current_tab(dock_slot[dock_popup_selected]->get_current_tab() + 1);
  2618. dock_select->update();
  2619. _edit_current();
  2620. _save_docks();
  2621. }
  2622. void EditorNode::_dock_select_draw() {
  2623. Size2 s = dock_select->get_size();
  2624. s.y /= 2.0;
  2625. s.x /= 6.0;
  2626. Color used = Color(0.6, 0.6, 0.6, 0.8);
  2627. Color used_selected = Color(0.8, 0.8, 0.8, 0.8);
  2628. Color tab_selected = theme_base->get_color("mono_color", "Editor");
  2629. Color unused = used;
  2630. unused.a = 0.4;
  2631. Color unusable = unused;
  2632. unusable.a = 0.1;
  2633. Rect2 unr(s.x * 2, 0, s.x * 2, s.y * 2);
  2634. unr.position += Vector2(2, 5);
  2635. unr.size -= Vector2(4, 7);
  2636. dock_select->draw_rect(unr, unusable);
  2637. dock_tab_move_left->set_disabled(true);
  2638. dock_tab_move_right->set_disabled(true);
  2639. if (dock_popup_selected != -1 && dock_slot[dock_popup_selected]->get_tab_count()) {
  2640. dock_tab_move_left->set_disabled(dock_slot[dock_popup_selected]->get_current_tab() == 0);
  2641. dock_tab_move_right->set_disabled(dock_slot[dock_popup_selected]->get_current_tab() >= dock_slot[dock_popup_selected]->get_tab_count() - 1);
  2642. }
  2643. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2644. Vector2 ofs;
  2645. switch (i) {
  2646. case DOCK_SLOT_LEFT_UL: {
  2647. } break;
  2648. case DOCK_SLOT_LEFT_BL: {
  2649. ofs.y += s.y;
  2650. } break;
  2651. case DOCK_SLOT_LEFT_UR: {
  2652. ofs.x += s.x;
  2653. } break;
  2654. case DOCK_SLOT_LEFT_BR: {
  2655. ofs += s;
  2656. } break;
  2657. case DOCK_SLOT_RIGHT_UL: {
  2658. ofs.x += s.x * 4;
  2659. } break;
  2660. case DOCK_SLOT_RIGHT_BL: {
  2661. ofs.x += s.x * 4;
  2662. ofs.y += s.y;
  2663. } break;
  2664. case DOCK_SLOT_RIGHT_UR: {
  2665. ofs.x += s.x * 4;
  2666. ofs.x += s.x;
  2667. } break;
  2668. case DOCK_SLOT_RIGHT_BR: {
  2669. ofs.x += s.x * 4;
  2670. ofs += s;
  2671. } break;
  2672. }
  2673. Rect2 r(ofs, s);
  2674. dock_select_rect[i] = r;
  2675. r.position += Vector2(2, 5);
  2676. r.size -= Vector2(4, 7);
  2677. if (i == dock_select_rect_over) {
  2678. dock_select->draw_rect(r, used_selected);
  2679. } else if (dock_slot[i]->get_child_count() == 0) {
  2680. dock_select->draw_rect(r, unused);
  2681. } else {
  2682. dock_select->draw_rect(r, used);
  2683. }
  2684. for (int j = 0; j < MIN(3, dock_slot[i]->get_child_count()); j++) {
  2685. int xofs = (r.size.width / 3) * j;
  2686. Color c = used;
  2687. if (i == dock_popup_selected && (dock_slot[i]->get_current_tab() > 3 || dock_slot[i]->get_current_tab() == j))
  2688. c = tab_selected;
  2689. dock_select->draw_rect(Rect2(2 + ofs.x + xofs, ofs.y, r.size.width / 3 - 1, 3), c);
  2690. }
  2691. }
  2692. }
  2693. void EditorNode::_save_docks() {
  2694. Ref<ConfigFile> config;
  2695. config.instance();
  2696. _save_docks_to_config(config, "docks");
  2697. _save_open_scenes_to_config(config, "EditorNode");
  2698. editor_data.get_plugin_window_layout(config);
  2699. config->save(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg"));
  2700. }
  2701. void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section) {
  2702. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2703. String names;
  2704. for (int j = 0; j < dock_slot[i]->get_tab_count(); j++) {
  2705. String name = dock_slot[i]->get_tab_control(j)->get_name();
  2706. if (names != "")
  2707. names += ",";
  2708. names += name;
  2709. }
  2710. if (names != "") {
  2711. p_layout->set_value(p_section, "dock_" + itos(i + 1), names);
  2712. }
  2713. }
  2714. p_layout->set_value(p_section, "dock_filesystem_split", filesystem_dock->get_split_offset());
  2715. for (int i = 0; i < vsplits.size(); i++) {
  2716. if (vsplits[i]->is_visible_in_tree()) {
  2717. p_layout->set_value(p_section, "dock_split_" + itos(i + 1), vsplits[i]->get_split_offset());
  2718. }
  2719. }
  2720. for (int i = 0; i < hsplits.size(); i++) {
  2721. p_layout->set_value(p_section, "dock_hsplit_" + itos(i + 1), hsplits[i]->get_split_offset());
  2722. }
  2723. }
  2724. void EditorNode::_save_open_scenes_to_config(Ref<ConfigFile> p_layout, const String &p_section) {
  2725. Array scenes;
  2726. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  2727. String path = editor_data.get_scene_path(i);
  2728. if (path == "") {
  2729. continue;
  2730. }
  2731. scenes.push_back(path);
  2732. }
  2733. p_layout->set_value(p_section, "open_scenes", scenes);
  2734. }
  2735. void EditorNode::save_layout() {
  2736. dock_drag_timer->start();
  2737. }
  2738. void EditorNode::_dock_split_dragged(int ofs) {
  2739. dock_drag_timer->start();
  2740. }
  2741. void EditorNode::_load_docks() {
  2742. Ref<ConfigFile> config;
  2743. config.instance();
  2744. Error err = config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg"));
  2745. if (err != OK) {
  2746. //no config
  2747. if (overridden_default_layout >= 0) {
  2748. _layout_menu_option(overridden_default_layout);
  2749. }
  2750. return;
  2751. }
  2752. _load_docks_from_config(config, "docks");
  2753. _load_open_scenes_from_config(config, "EditorNode");
  2754. editor_data.set_plugin_window_layout(config);
  2755. }
  2756. void EditorNode::_update_dock_slots_visibility() {
  2757. if (!docks_visible) {
  2758. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2759. dock_slot[i]->hide();
  2760. }
  2761. for (int i = 0; i < vsplits.size(); i++) {
  2762. vsplits[i]->hide();
  2763. }
  2764. right_hsplit->hide();
  2765. bottom_panel->hide();
  2766. } else {
  2767. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2768. if (dock_slot[i]->get_tab_count())
  2769. dock_slot[i]->show();
  2770. else
  2771. dock_slot[i]->hide();
  2772. }
  2773. for (int i = 0; i < vsplits.size(); i++) {
  2774. bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
  2775. if (in_use)
  2776. vsplits[i]->show();
  2777. else
  2778. vsplits[i]->hide();
  2779. }
  2780. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2781. if (dock_slot[i]->is_visible() && dock_slot[i]->get_tab_count()) {
  2782. dock_slot[i]->set_current_tab(0);
  2783. }
  2784. }
  2785. bottom_panel->show();
  2786. if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
  2787. right_hsplit->show();
  2788. else
  2789. right_hsplit->hide();
  2790. }
  2791. }
  2792. void EditorNode::_dock_tab_changed(int p_tab) {
  2793. // update visibility but don't set current tab
  2794. if (!docks_visible) {
  2795. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2796. dock_slot[i]->hide();
  2797. }
  2798. for (int i = 0; i < vsplits.size(); i++) {
  2799. vsplits[i]->hide();
  2800. }
  2801. right_hsplit->hide();
  2802. bottom_panel->hide();
  2803. } else {
  2804. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2805. if (dock_slot[i]->get_tab_count())
  2806. dock_slot[i]->show();
  2807. else
  2808. dock_slot[i]->hide();
  2809. }
  2810. for (int i = 0; i < vsplits.size(); i++) {
  2811. bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
  2812. if (in_use)
  2813. vsplits[i]->show();
  2814. else
  2815. vsplits[i]->hide();
  2816. }
  2817. bottom_panel->show();
  2818. if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
  2819. right_hsplit->show();
  2820. else
  2821. right_hsplit->hide();
  2822. }
  2823. }
  2824. void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String &p_section) {
  2825. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2826. if (!p_layout->has_section_key(p_section, "dock_" + itos(i + 1)))
  2827. continue;
  2828. Vector<String> names = String(p_layout->get_value(p_section, "dock_" + itos(i + 1))).split(",");
  2829. for (int j = 0; j < names.size(); j++) {
  2830. String name = names[j];
  2831. //find it, in a horribly inefficient way
  2832. int atidx = -1;
  2833. Control *node = NULL;
  2834. for (int k = 0; k < DOCK_SLOT_MAX; k++) {
  2835. if (!dock_slot[k]->has_node(name))
  2836. continue;
  2837. node = Object::cast_to<Control>(dock_slot[k]->get_node(name));
  2838. if (!node)
  2839. continue;
  2840. atidx = k;
  2841. break;
  2842. }
  2843. if (atidx == -1) //well, it's not anywhere
  2844. continue;
  2845. if (atidx == i) {
  2846. node->raise();
  2847. continue;
  2848. }
  2849. dock_slot[atidx]->remove_child(node);
  2850. if (dock_slot[atidx]->get_tab_count() == 0) {
  2851. dock_slot[atidx]->hide();
  2852. }
  2853. dock_slot[i]->add_child(node);
  2854. dock_slot[i]->show();
  2855. }
  2856. }
  2857. int fs_split_ofs = 0;
  2858. if (p_layout->has_section_key(p_section, "dock_filesystem_split")) {
  2859. fs_split_ofs = p_layout->get_value(p_section, "dock_filesystem_split");
  2860. }
  2861. filesystem_dock->set_split_offset(fs_split_ofs);
  2862. for (int i = 0; i < vsplits.size(); i++) {
  2863. if (!p_layout->has_section_key(p_section, "dock_split_" + itos(i + 1)))
  2864. continue;
  2865. int ofs = p_layout->get_value(p_section, "dock_split_" + itos(i + 1));
  2866. vsplits[i]->set_split_offset(ofs);
  2867. }
  2868. for (int i = 0; i < hsplits.size(); i++) {
  2869. if (!p_layout->has_section_key(p_section, "dock_hsplit_" + itos(i + 1)))
  2870. continue;
  2871. int ofs = p_layout->get_value(p_section, "dock_hsplit_" + itos(i + 1));
  2872. hsplits[i]->set_split_offset(ofs);
  2873. }
  2874. for (int i = 0; i < vsplits.size(); i++) {
  2875. bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
  2876. if (in_use)
  2877. vsplits[i]->show();
  2878. else
  2879. vsplits[i]->hide();
  2880. }
  2881. if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
  2882. right_hsplit->show();
  2883. else
  2884. right_hsplit->hide();
  2885. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  2886. if (dock_slot[i]->is_visible() && dock_slot[i]->get_tab_count()) {
  2887. dock_slot[i]->set_current_tab(0);
  2888. }
  2889. }
  2890. }
  2891. void EditorNode::_load_open_scenes_from_config(Ref<ConfigFile> p_layout, const String &p_section) {
  2892. if (!bool(EDITOR_GET("interface/scene_tabs/restore_scenes_on_load"))) {
  2893. return;
  2894. }
  2895. if (!p_layout->has_section(p_section) || !p_layout->has_section_key(p_section, "open_scenes")) {
  2896. return;
  2897. }
  2898. restoring_scenes = true;
  2899. Array scenes = p_layout->get_value(p_section, "open_scenes");
  2900. for (int i = 0; i < scenes.size(); i++) {
  2901. load_scene(scenes[i]);
  2902. }
  2903. restoring_scenes = false;
  2904. }
  2905. void EditorNode::_update_layouts_menu() {
  2906. editor_layouts->clear();
  2907. overridden_default_layout = -1;
  2908. editor_layouts->set_size(Vector2());
  2909. editor_layouts->add_shortcut(ED_SHORTCUT("layout/save", TTR("Save Layout")), SETTINGS_LAYOUT_SAVE);
  2910. editor_layouts->add_shortcut(ED_SHORTCUT("layout/delete", TTR("Delete Layout")), SETTINGS_LAYOUT_DELETE);
  2911. editor_layouts->add_separator();
  2912. editor_layouts->add_shortcut(ED_SHORTCUT("layout/default", TTR("Default")), SETTINGS_LAYOUT_DEFAULT);
  2913. Ref<ConfigFile> config;
  2914. config.instance();
  2915. Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config());
  2916. if (err != OK) {
  2917. return; //no config
  2918. }
  2919. List<String> layouts;
  2920. config.ptr()->get_sections(&layouts);
  2921. for (List<String>::Element *E = layouts.front(); E; E = E->next()) {
  2922. String layout = E->get();
  2923. if (layout == TTR("Default")) {
  2924. editor_layouts->remove_item(editor_layouts->get_item_index(SETTINGS_LAYOUT_DEFAULT));
  2925. overridden_default_layout = editor_layouts->get_item_count();
  2926. }
  2927. editor_layouts->add_item(layout);
  2928. }
  2929. }
  2930. void EditorNode::_layout_menu_option(int p_id) {
  2931. switch (p_id) {
  2932. case SETTINGS_LAYOUT_SAVE: {
  2933. current_option = p_id;
  2934. layout_dialog->set_title(TTR("Save Layout"));
  2935. layout_dialog->get_ok()->set_text(TTR("Save"));
  2936. layout_dialog->popup_centered();
  2937. } break;
  2938. case SETTINGS_LAYOUT_DELETE: {
  2939. current_option = p_id;
  2940. layout_dialog->set_title(TTR("Delete Layout"));
  2941. layout_dialog->get_ok()->set_text(TTR("Delete"));
  2942. layout_dialog->popup_centered();
  2943. } break;
  2944. case SETTINGS_LAYOUT_DEFAULT: {
  2945. _load_docks_from_config(default_layout, "docks");
  2946. _save_docks();
  2947. } break;
  2948. default: {
  2949. Ref<ConfigFile> config;
  2950. config.instance();
  2951. Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config());
  2952. if (err != OK) {
  2953. return; //no config
  2954. }
  2955. _load_docks_from_config(config, editor_layouts->get_item_text(p_id));
  2956. _save_docks();
  2957. }
  2958. }
  2959. }
  2960. void EditorNode::_scene_tab_script_edited(int p_tab) {
  2961. Ref<Script> script = editor_data.get_scene_root_script(p_tab);
  2962. if (script.is_valid())
  2963. inspector_dock->edit_resource(script);
  2964. }
  2965. void EditorNode::_scene_tab_closed(int p_tab) {
  2966. current_option = SCENE_TAB_CLOSE;
  2967. tab_closing = p_tab;
  2968. Node *scene = editor_data.get_edited_scene_root(p_tab);
  2969. if (!scene) {
  2970. _discard_changes();
  2971. return;
  2972. }
  2973. bool unsaved = (p_tab == editor_data.get_edited_scene()) ?
  2974. saved_version != editor_data.get_undo_redo().get_version() :
  2975. editor_data.get_scene_version(p_tab) != 0;
  2976. if (unsaved) {
  2977. save_confirmation->get_ok()->set_text(TTR("Save & Close"));
  2978. save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_filename() != "" ? scene->get_filename() : "unsaved scene"));
  2979. save_confirmation->popup_centered_minsize();
  2980. } else {
  2981. _discard_changes();
  2982. }
  2983. save_layout();
  2984. _update_scene_tabs();
  2985. }
  2986. void EditorNode::_scene_tab_hover(int p_tab) {
  2987. if (!bool(EDITOR_GET("interface/scene_tabs/show_thumbnail_on_hover"))) {
  2988. return;
  2989. }
  2990. int current_tab = scene_tabs->get_current_tab();
  2991. if (p_tab == current_tab || p_tab < 0) {
  2992. tab_preview_panel->hide();
  2993. } else {
  2994. String path = editor_data.get_scene_path(p_tab);
  2995. if (path != String()) {
  2996. EditorResourcePreview::get_singleton()->queue_resource_preview(path, this, "_thumbnail_done", p_tab);
  2997. }
  2998. }
  2999. }
  3000. void EditorNode::_scene_tab_exit() {
  3001. tab_preview_panel->hide();
  3002. }
  3003. void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
  3004. Ref<InputEventMouseButton> mb = p_input;
  3005. if (mb.is_valid()) {
  3006. if (scene_tabs->get_hovered_tab() >= 0) {
  3007. if (mb->get_button_index() == BUTTON_MIDDLE && mb->is_pressed()) {
  3008. _scene_tab_closed(scene_tabs->get_hovered_tab());
  3009. }
  3010. } else {
  3011. if ((mb->get_button_index() == BUTTON_LEFT && mb->is_doubleclick()) || (mb->get_button_index() == BUTTON_MIDDLE && mb->is_pressed())) {
  3012. _menu_option_confirm(FILE_NEW_SCENE, true);
  3013. }
  3014. }
  3015. if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
  3016. // context menu
  3017. scene_tabs_context_menu->clear();
  3018. scene_tabs_context_menu->set_size(Size2(1, 1));
  3019. scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/new_scene"), FILE_NEW_SCENE);
  3020. if (scene_tabs->get_hovered_tab() >= 0) {
  3021. scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene"), FILE_SAVE_SCENE);
  3022. scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene_as"), FILE_SAVE_AS_SCENE);
  3023. }
  3024. scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), FILE_SAVE_ALL_SCENES);
  3025. if (scene_tabs->get_hovered_tab() >= 0) {
  3026. scene_tabs_context_menu->add_separator();
  3027. scene_tabs_context_menu->add_item(TTR("Show in filesystem"), FILE_SHOW_IN_FILESYSTEM);
  3028. scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
  3029. scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE);
  3030. }
  3031. scene_tabs_context_menu->set_position(mb->get_global_position());
  3032. scene_tabs_context_menu->popup();
  3033. }
  3034. }
  3035. }
  3036. void EditorNode::_reposition_active_tab(int idx_to) {
  3037. editor_data.move_edited_scene_to_index(idx_to);
  3038. _update_scene_tabs();
  3039. }
  3040. void EditorNode::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) {
  3041. int p_tab = p_udata.operator signed int();
  3042. if (p_preview.is_valid()) {
  3043. Rect2 rect = scene_tabs->get_tab_rect(p_tab);
  3044. rect.position += scene_tabs->get_global_position();
  3045. tab_preview->set_texture(p_preview);
  3046. tab_preview_panel->set_position(rect.position + Vector2(0, rect.size.height));
  3047. tab_preview_panel->show();
  3048. }
  3049. }
  3050. void EditorNode::_scene_tab_changed(int p_tab) {
  3051. tab_preview_panel->hide();
  3052. bool unsaved = (saved_version != editor_data.get_undo_redo().get_version());
  3053. if (p_tab == editor_data.get_edited_scene())
  3054. return; //pointless
  3055. uint64_t next_scene_version = editor_data.get_scene_version(p_tab);
  3056. editor_data.get_undo_redo().create_action(TTR("Switch Scene Tab"));
  3057. editor_data.get_undo_redo().add_do_method(this, "set_current_version", unsaved ? saved_version : 0);
  3058. editor_data.get_undo_redo().add_do_method(this, "set_current_scene", p_tab);
  3059. editor_data.get_undo_redo().add_do_method(this, "set_current_version", next_scene_version == 0 ? editor_data.get_undo_redo().get_version() + 1 : next_scene_version);
  3060. editor_data.get_undo_redo().add_undo_method(this, "set_current_version", next_scene_version);
  3061. editor_data.get_undo_redo().add_undo_method(this, "set_current_scene", editor_data.get_edited_scene());
  3062. editor_data.get_undo_redo().add_undo_method(this, "set_current_version", saved_version);
  3063. editor_data.get_undo_redo().commit_action();
  3064. }
  3065. ToolButton *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) {
  3066. ToolButton *tb = memnew(ToolButton);
  3067. tb->connect("toggled", this, "_bottom_panel_switch", varray(bottom_panel_items.size()));
  3068. tb->set_text(p_text);
  3069. tb->set_toggle_mode(true);
  3070. tb->set_focus_mode(Control::FOCUS_NONE);
  3071. bottom_panel_vb->add_child(p_item);
  3072. bottom_panel_hb->raise();
  3073. bottom_panel_hb_editors->add_child(tb);
  3074. p_item->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3075. p_item->hide();
  3076. BottomPanelItem bpi;
  3077. bpi.button = tb;
  3078. bpi.control = p_item;
  3079. bpi.name = p_text;
  3080. bottom_panel_items.push_back(bpi);
  3081. return tb;
  3082. }
  3083. bool EditorNode::are_bottom_panels_hidden() const {
  3084. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3085. if (bottom_panel_items[i].button->is_pressed())
  3086. return false;
  3087. }
  3088. return true;
  3089. }
  3090. void EditorNode::hide_bottom_panel() {
  3091. _bottom_panel_switch(false, 0);
  3092. }
  3093. void EditorNode::make_bottom_panel_item_visible(Control *p_item) {
  3094. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3095. if (bottom_panel_items[i].control == p_item) {
  3096. _bottom_panel_switch(true, i);
  3097. break;
  3098. }
  3099. }
  3100. }
  3101. void EditorNode::raise_bottom_panel_item(Control *p_item) {
  3102. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3103. if (bottom_panel_items[i].control == p_item) {
  3104. bottom_panel_items[i].button->raise();
  3105. SWAP(bottom_panel_items.write[i], bottom_panel_items.write[bottom_panel_items.size() - 1]);
  3106. break;
  3107. }
  3108. }
  3109. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3110. bottom_panel_items[i].button->disconnect("toggled", this, "_bottom_panel_switch");
  3111. bottom_panel_items[i].button->connect("toggled", this, "_bottom_panel_switch", varray(i));
  3112. }
  3113. }
  3114. void EditorNode::remove_bottom_panel_item(Control *p_item) {
  3115. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3116. if (bottom_panel_items[i].control == p_item) {
  3117. if (p_item->is_visible_in_tree()) {
  3118. _bottom_panel_switch(false, 0);
  3119. }
  3120. bottom_panel_vb->remove_child(bottom_panel_items[i].control);
  3121. bottom_panel_hb_editors->remove_child(bottom_panel_items[i].button);
  3122. memdelete(bottom_panel_items[i].button);
  3123. bottom_panel_items.remove(i);
  3124. break;
  3125. }
  3126. }
  3127. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3128. bottom_panel_items[i].button->disconnect("toggled", this, "_bottom_panel_switch");
  3129. bottom_panel_items[i].button->connect("toggled", this, "_bottom_panel_switch", varray(i));
  3130. }
  3131. }
  3132. void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) {
  3133. ERR_FAIL_INDEX(p_idx, bottom_panel_items.size());
  3134. if (p_enable) {
  3135. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3136. bottom_panel_items[i].button->set_pressed(i == p_idx);
  3137. bottom_panel_items[i].control->set_visible(i == p_idx);
  3138. }
  3139. if (ScriptEditor::get_singleton()->get_debugger() == bottom_panel_items[p_idx].control) { // this is the debug panel which uses tabs, so the top section should be smaller
  3140. bottom_panel->add_style_override("panel", gui_base->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles"));
  3141. } else {
  3142. bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
  3143. }
  3144. center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE);
  3145. center_split->set_collapsed(false);
  3146. if (bottom_panel_raise->is_pressed()) {
  3147. top_split->hide();
  3148. }
  3149. bottom_panel_raise->show();
  3150. } else {
  3151. bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
  3152. for (int i = 0; i < bottom_panel_items.size(); i++) {
  3153. bottom_panel_items[i].button->set_pressed(false);
  3154. bottom_panel_items[i].control->set_visible(false);
  3155. }
  3156. center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
  3157. center_split->set_collapsed(true);
  3158. bottom_panel_raise->hide();
  3159. if (bottom_panel_raise->is_pressed()) {
  3160. top_split->show();
  3161. }
  3162. }
  3163. }
  3164. void EditorNode::set_docks_visible(bool p_show) {
  3165. docks_visible = p_show;
  3166. _update_dock_slots_visibility();
  3167. }
  3168. bool EditorNode::get_docks_visible() const {
  3169. return docks_visible;
  3170. }
  3171. void EditorNode::_toggle_distraction_free_mode() {
  3172. if (EditorSettings::get_singleton()->get("interface/editor/separate_distraction_mode")) {
  3173. int screen = -1;
  3174. for (int i = 0; i < editor_table.size(); i++) {
  3175. if (editor_plugin_screen == editor_table[i]) {
  3176. screen = i;
  3177. break;
  3178. }
  3179. }
  3180. if (screen == EDITOR_SCRIPT) {
  3181. script_distraction = !script_distraction;
  3182. set_distraction_free_mode(script_distraction);
  3183. } else {
  3184. scene_distraction = !scene_distraction;
  3185. set_distraction_free_mode(scene_distraction);
  3186. }
  3187. } else {
  3188. set_distraction_free_mode(distraction_free->is_pressed());
  3189. }
  3190. }
  3191. void EditorNode::set_distraction_free_mode(bool p_enter) {
  3192. distraction_free->set_pressed(p_enter);
  3193. if (p_enter) {
  3194. if (docks_visible) {
  3195. set_docks_visible(false);
  3196. }
  3197. } else {
  3198. set_docks_visible(true);
  3199. }
  3200. }
  3201. bool EditorNode::get_distraction_free_mode() const {
  3202. return distraction_free->is_pressed();
  3203. }
  3204. void EditorNode::add_control_to_dock(DockSlot p_slot, Control *p_control) {
  3205. ERR_FAIL_INDEX(p_slot, DOCK_SLOT_MAX);
  3206. dock_slot[p_slot]->add_child(p_control);
  3207. _update_dock_slots_visibility();
  3208. }
  3209. void EditorNode::remove_control_from_dock(Control *p_control) {
  3210. Control *dock = NULL;
  3211. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  3212. if (p_control->get_parent() == dock_slot[i]) {
  3213. dock = dock_slot[i];
  3214. break;
  3215. }
  3216. }
  3217. ERR_EXPLAIN("Control was not in dock");
  3218. ERR_FAIL_COND(!dock);
  3219. dock->remove_child(p_control);
  3220. _update_dock_slots_visibility();
  3221. }
  3222. Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
  3223. Control *drag_control = memnew(Control);
  3224. TextureRect *drag_preview = memnew(TextureRect);
  3225. Label *label = memnew(Label);
  3226. Ref<Texture> preview;
  3227. {
  3228. //todo make proper previews
  3229. Ref<ImageTexture> pic = gui_base->get_icon("FileBigThumb", "EditorIcons");
  3230. Ref<Image> img = pic->get_data();
  3231. img = img->duplicate();
  3232. img->resize(48, 48); //meh
  3233. Ref<ImageTexture> resized_pic = Ref<ImageTexture>(memnew(ImageTexture));
  3234. resized_pic->create_from_image(img);
  3235. preview = resized_pic;
  3236. }
  3237. drag_preview->set_texture(preview);
  3238. drag_control->add_child(drag_preview);
  3239. if (p_res->get_path().is_resource_file()) {
  3240. label->set_text(p_res->get_path().get_file());
  3241. } else if (p_res->get_name() != "") {
  3242. label->set_text(p_res->get_name());
  3243. } else {
  3244. label->set_text(p_res->get_class());
  3245. }
  3246. drag_control->add_child(label);
  3247. p_from->set_drag_preview(drag_control); //wait until it enters scene
  3248. label->set_position(Point2((preview->get_width() - label->get_minimum_size().width) / 2, preview->get_height()));
  3249. Dictionary drag_data;
  3250. drag_data["type"] = "resource";
  3251. drag_data["resource"] = p_res;
  3252. drag_data["from"] = p_from;
  3253. return drag_data;
  3254. }
  3255. Variant EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Control *p_from) {
  3256. bool has_folder = false;
  3257. bool has_file = false;
  3258. for (int i = 0; i < p_paths.size(); i++) {
  3259. bool is_folder = p_paths[i].ends_with("/");
  3260. has_folder |= is_folder;
  3261. has_file |= !is_folder;
  3262. }
  3263. int max_rows = 6;
  3264. int num_rows = p_paths.size() > max_rows ? max_rows - 1 : p_paths.size(); //Don't waste a row to say "1 more file" - list it instead.
  3265. VBoxContainer *vbox = memnew(VBoxContainer);
  3266. for (int i = 0; i < num_rows; i++) {
  3267. HBoxContainer *hbox = memnew(HBoxContainer);
  3268. TextureRect *icon = memnew(TextureRect);
  3269. Label *label = memnew(Label);
  3270. if (p_paths[i].ends_with("/")) {
  3271. label->set_text(p_paths[i].substr(0, p_paths[i].length() - 1).get_file());
  3272. icon->set_texture(gui_base->get_icon("Folder", "EditorIcons"));
  3273. } else {
  3274. label->set_text(p_paths[i].get_file());
  3275. icon->set_texture(gui_base->get_icon("File", "EditorIcons"));
  3276. }
  3277. icon->set_size(Size2(16, 16));
  3278. hbox->add_child(icon);
  3279. hbox->add_child(label);
  3280. vbox->add_child(hbox);
  3281. }
  3282. if (p_paths.size() > num_rows) {
  3283. Label *label = memnew(Label);
  3284. if (has_file && has_folder) {
  3285. label->set_text(vformat(TTR("%d more files or folders"), p_paths.size() - num_rows));
  3286. } else if (has_folder) {
  3287. label->set_text(vformat(TTR("%d more folders"), p_paths.size() - num_rows));
  3288. } else {
  3289. label->set_text(vformat(TTR("%d more files"), p_paths.size() - num_rows));
  3290. }
  3291. vbox->add_child(label);
  3292. }
  3293. p_from->set_drag_preview(vbox); //wait until it enters scene
  3294. Dictionary drag_data;
  3295. drag_data["type"] = has_folder ? "files_and_dirs" : "files";
  3296. drag_data["files"] = p_paths;
  3297. drag_data["from"] = p_from;
  3298. return drag_data;
  3299. }
  3300. void EditorNode::add_tool_menu_item(const String &p_name, Object *p_handler, const String &p_callback, const Variant &p_ud) {
  3301. ERR_FAIL_NULL(p_handler);
  3302. int idx = tool_menu->get_item_count();
  3303. tool_menu->add_item(p_name, TOOLS_CUSTOM);
  3304. Array parameters;
  3305. parameters.push_back(p_handler->get_instance_id());
  3306. parameters.push_back(p_callback);
  3307. parameters.push_back(p_ud);
  3308. tool_menu->set_item_metadata(idx, parameters);
  3309. }
  3310. void EditorNode::add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu) {
  3311. ERR_FAIL_NULL(p_submenu);
  3312. ERR_FAIL_COND(p_submenu->get_parent() != NULL);
  3313. tool_menu->add_child(p_submenu);
  3314. tool_menu->add_submenu_item(p_name, p_submenu->get_name(), TOOLS_CUSTOM);
  3315. }
  3316. void EditorNode::remove_tool_menu_item(const String &p_name) {
  3317. for (int i = 0; i < tool_menu->get_item_count(); i++) {
  3318. if (tool_menu->get_item_id(i) != TOOLS_CUSTOM)
  3319. continue;
  3320. if (tool_menu->get_item_text(i) == p_name) {
  3321. if (tool_menu->get_item_submenu(i) != "") {
  3322. Node *n = tool_menu->get_node(tool_menu->get_item_submenu(i));
  3323. tool_menu->remove_child(n);
  3324. memdelete(n);
  3325. }
  3326. tool_menu->remove_item(i);
  3327. tool_menu->set_as_minsize();
  3328. return;
  3329. }
  3330. }
  3331. }
  3332. void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
  3333. String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_current_path());
  3334. DirAccessRef dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
  3335. Vector<String> just_copy = String("ttf,otf").split(",");
  3336. for (int i = 0; i < p_files.size(); i++) {
  3337. String from = p_files[i];
  3338. if (!ResourceFormatImporter::get_singleton()->can_be_imported(from) && (just_copy.find(from.get_extension().to_lower()) == -1)) {
  3339. continue;
  3340. }
  3341. String to = to_path.plus_file(from.get_file());
  3342. dir->copy(from, to);
  3343. }
  3344. EditorFileSystem::get_singleton()->scan_changes();
  3345. }
  3346. void EditorNode::_file_access_close_error_notify(const String &p_str) {
  3347. add_io_error("Unable to write to file '" + p_str + "', file in use, locked or lacking permissions.");
  3348. }
  3349. void EditorNode::reload_scene(const String &p_path) {
  3350. //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk
  3351. List<Ref<Resource> > cached;
  3352. ResourceCache::get_cached_resources(&cached);
  3353. List<Ref<Resource> > to_clear; //clear internal resources from previous scene from being used
  3354. for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) {
  3355. if (E->get()->get_path().begins_with(p_path + "::")) { //subresources of existing scene
  3356. to_clear.push_back(E->get());
  3357. }
  3358. }
  3359. //so reload reloads everything, clear subresources of previous scene
  3360. while (to_clear.front()) {
  3361. to_clear.front()->get()->set_path("");
  3362. to_clear.pop_front();
  3363. }
  3364. int scene_idx = -1;
  3365. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
  3366. if (editor_data.get_scene_path(i) == p_path) {
  3367. scene_idx = i;
  3368. break;
  3369. }
  3370. }
  3371. int current_tab = editor_data.get_edited_scene();
  3372. if (scene_idx == -1) {
  3373. if (get_edited_scene()) {
  3374. //scene is not open, so at it might be instanced, just refresh, set tab to itself and it will reload
  3375. set_current_scene(current_tab);
  3376. editor_data.get_undo_redo().clear_history();
  3377. }
  3378. return;
  3379. }
  3380. if (current_tab == scene_idx) {
  3381. editor_data.apply_changes_in_editors();
  3382. _set_scene_metadata(p_path);
  3383. }
  3384. //remove scene
  3385. _remove_scene(scene_idx);
  3386. //reload scene
  3387. load_scene(p_path, true, false, true, true);
  3388. //adjust index so tab is back a the previous position
  3389. editor_data.move_edited_scene_to_index(scene_idx);
  3390. get_undo_redo()->clear_history();
  3391. //recover the tab
  3392. scene_tabs->set_current_tab(current_tab);
  3393. _scene_tab_changed(current_tab);
  3394. }
  3395. int EditorNode::plugin_init_callback_count = 0;
  3396. void EditorNode::add_plugin_init_callback(EditorPluginInitializeCallback p_callback) {
  3397. ERR_FAIL_COND(plugin_init_callback_count == MAX_INIT_CALLBACKS);
  3398. plugin_init_callbacks[plugin_init_callback_count++] = p_callback;
  3399. }
  3400. EditorPluginInitializeCallback EditorNode::plugin_init_callbacks[EditorNode::MAX_INIT_CALLBACKS];
  3401. int EditorNode::build_callback_count = 0;
  3402. void EditorNode::add_build_callback(EditorBuildCallback p_callback) {
  3403. ERR_FAIL_COND(build_callback_count == MAX_INIT_CALLBACKS);
  3404. build_callbacks[build_callback_count++] = p_callback;
  3405. }
  3406. EditorBuildCallback EditorNode::build_callbacks[EditorNode::MAX_BUILD_CALLBACKS];
  3407. bool EditorNode::call_build() {
  3408. bool builds_successful = true;
  3409. for (int i = 0; i < build_callback_count && builds_successful; i++) {
  3410. if (!build_callbacks[i]()) {
  3411. ERR_PRINT("A Godot Engine build callback failed.");
  3412. builds_successful = false;
  3413. }
  3414. }
  3415. if (builds_successful && !editor_data.call_build()) {
  3416. ERR_PRINT("An EditorPlugin build callback failed.");
  3417. builds_successful = false;
  3418. }
  3419. return builds_successful;
  3420. }
  3421. void EditorNode::_inherit_imported(const String &p_action) {
  3422. open_imported->hide();
  3423. load_scene(open_import_request, true, true);
  3424. }
  3425. void EditorNode::_open_imported() {
  3426. load_scene(open_import_request, true, false, true, true);
  3427. }
  3428. void EditorNode::dim_editor(bool p_dimming) {
  3429. static int dim_count = 0;
  3430. bool dim_ui = EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup");
  3431. if (p_dimming) {
  3432. if (dim_ui) {
  3433. if (dim_count == 0) {
  3434. _start_dimming(true);
  3435. }
  3436. dim_count++;
  3437. }
  3438. } else {
  3439. if (dim_count == 1) {
  3440. _start_dimming(false);
  3441. dim_count = 0;
  3442. } else if (dim_ui && dim_count > 0) {
  3443. dim_count--;
  3444. }
  3445. }
  3446. }
  3447. void EditorNode::_start_dimming(bool p_dimming) {
  3448. _dimming = p_dimming;
  3449. _dim_time = 0.0f;
  3450. _dim_timer->start();
  3451. }
  3452. void EditorNode::_dim_timeout() {
  3453. _dim_time += _dim_timer->get_wait_time();
  3454. float wait_time = EditorSettings::get_singleton()->get("interface/editor/dim_transition_time");
  3455. float c = 1.0f - (float)EditorSettings::get_singleton()->get("interface/editor/dim_amount");
  3456. Color base = _dimming ? Color(1, 1, 1) : Color(c, c, c);
  3457. Color final = _dimming ? Color(c, c, c) : Color(1, 1, 1);
  3458. if (_dim_time + _dim_timer->get_wait_time() >= wait_time) {
  3459. gui_base->set_modulate(final);
  3460. _dim_timer->stop();
  3461. } else {
  3462. gui_base->set_modulate(base.linear_interpolate(final, _dim_time / wait_time));
  3463. }
  3464. }
  3465. void EditorNode::open_export_template_manager() {
  3466. export_template_manager->popup_manager();
  3467. }
  3468. void EditorNode::add_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin) {
  3469. resource_conversion_plugins.push_back(p_plugin);
  3470. }
  3471. void EditorNode::remove_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin) {
  3472. resource_conversion_plugins.erase(p_plugin);
  3473. }
  3474. Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversion_plugin(const Ref<Resource> &p_for_resource) {
  3475. Vector<Ref<EditorResourceConversionPlugin> > ret;
  3476. for (int i = 0; i < resource_conversion_plugins.size(); i++) {
  3477. if (resource_conversion_plugins[i].is_valid() && resource_conversion_plugins[i]->handles(p_for_resource)) {
  3478. ret.push_back(resource_conversion_plugins[i]);
  3479. }
  3480. }
  3481. return ret;
  3482. }
  3483. void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) {
  3484. if (p_pressed) {
  3485. top_split->hide();
  3486. bottom_panel_raise->set_icon(gui_base->get_icon("ShrinkBottomDock", "EditorIcons"));
  3487. } else {
  3488. top_split->show();
  3489. bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons"));
  3490. }
  3491. }
  3492. void EditorNode::_update_video_driver_color() {
  3493. //todo probably should de-harcode this and add to editor settings
  3494. if (video_driver->get_text() == "GLES2") {
  3495. video_driver->add_color_override("font_color", Color::hex(0x5586a4ff));
  3496. } else if (video_driver->get_text() == "GLES3") {
  3497. video_driver->add_color_override("font_color", Color::hex(0xa5557dff));
  3498. }
  3499. }
  3500. void EditorNode::_video_driver_selected(int p_which) {
  3501. String driver = video_driver->get_item_metadata(p_which);
  3502. String current = OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver());
  3503. if (driver == current) {
  3504. return;
  3505. }
  3506. video_driver_request = driver;
  3507. video_restart_dialog->popup_centered_minsize();
  3508. video_driver->select(video_driver_current);
  3509. _update_video_driver_color();
  3510. }
  3511. void EditorNode::_bind_methods() {
  3512. ClassDB::bind_method("_menu_option", &EditorNode::_menu_option);
  3513. ClassDB::bind_method("_tool_menu_option", &EditorNode::_tool_menu_option);
  3514. ClassDB::bind_method("_menu_confirm_current", &EditorNode::_menu_confirm_current);
  3515. ClassDB::bind_method("_dialog_action", &EditorNode::_dialog_action);
  3516. ClassDB::bind_method("_editor_select", &EditorNode::_editor_select);
  3517. ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed);
  3518. ClassDB::bind_method("edit_node", &EditorNode::edit_node);
  3519. ClassDB::bind_method("_unhandled_input", &EditorNode::_unhandled_input);
  3520. ClassDB::bind_method("_get_scene_metadata", &EditorNode::_get_scene_metadata);
  3521. ClassDB::bind_method("set_edited_scene", &EditorNode::set_edited_scene);
  3522. ClassDB::bind_method("open_request", &EditorNode::open_request);
  3523. ClassDB::bind_method("_instance_request", &EditorNode::_instance_request);
  3524. ClassDB::bind_method("_close_messages", &EditorNode::_close_messages);
  3525. ClassDB::bind_method("_show_messages", &EditorNode::_show_messages);
  3526. ClassDB::bind_method("_vp_resized", &EditorNode::_vp_resized);
  3527. ClassDB::bind_method("_quick_opened", &EditorNode::_quick_opened);
  3528. ClassDB::bind_method("_quick_run", &EditorNode::_quick_run);
  3529. ClassDB::bind_method("_open_recent_scene", &EditorNode::_open_recent_scene);
  3530. ClassDB::bind_method("stop_child_process", &EditorNode::stop_child_process);
  3531. ClassDB::bind_method("get_script_create_dialog", &EditorNode::get_script_create_dialog);
  3532. ClassDB::bind_method("_sources_changed", &EditorNode::_sources_changed);
  3533. ClassDB::bind_method("_fs_changed", &EditorNode::_fs_changed);
  3534. ClassDB::bind_method("_dock_select_draw", &EditorNode::_dock_select_draw);
  3535. ClassDB::bind_method("_dock_select_input", &EditorNode::_dock_select_input);
  3536. ClassDB::bind_method("_dock_pre_popup", &EditorNode::_dock_pre_popup);
  3537. ClassDB::bind_method("_dock_split_dragged", &EditorNode::_dock_split_dragged);
  3538. ClassDB::bind_method("_save_docks", &EditorNode::_save_docks);
  3539. ClassDB::bind_method("_dock_popup_exit", &EditorNode::_dock_popup_exit);
  3540. ClassDB::bind_method("_dock_move_left", &EditorNode::_dock_move_left);
  3541. ClassDB::bind_method("_dock_move_right", &EditorNode::_dock_move_right);
  3542. ClassDB::bind_method("_dock_tab_changed", &EditorNode::_dock_tab_changed);
  3543. ClassDB::bind_method("_layout_menu_option", &EditorNode::_layout_menu_option);
  3544. ClassDB::bind_method("set_current_scene", &EditorNode::set_current_scene);
  3545. ClassDB::bind_method("set_current_version", &EditorNode::set_current_version);
  3546. ClassDB::bind_method("_scene_tab_changed", &EditorNode::_scene_tab_changed);
  3547. ClassDB::bind_method("_scene_tab_closed", &EditorNode::_scene_tab_closed);
  3548. ClassDB::bind_method("_scene_tab_hover", &EditorNode::_scene_tab_hover);
  3549. ClassDB::bind_method("_scene_tab_exit", &EditorNode::_scene_tab_exit);
  3550. ClassDB::bind_method("_scene_tab_input", &EditorNode::_scene_tab_input);
  3551. ClassDB::bind_method("_reposition_active_tab", &EditorNode::_reposition_active_tab);
  3552. ClassDB::bind_method("_thumbnail_done", &EditorNode::_thumbnail_done);
  3553. ClassDB::bind_method("_scene_tab_script_edited", &EditorNode::_scene_tab_script_edited);
  3554. ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state);
  3555. ClassDB::bind_method("_update_scene_tabs", &EditorNode::_update_scene_tabs);
  3556. ClassDB::bind_method("_discard_changes", &EditorNode::_discard_changes);
  3557. ClassDB::bind_method("_update_recent_scenes", &EditorNode::_update_recent_scenes);
  3558. ClassDB::bind_method("_clear_undo_history", &EditorNode::_clear_undo_history);
  3559. ClassDB::bind_method("_dropped_files", &EditorNode::_dropped_files);
  3560. ClassDB::bind_method("_toggle_distraction_free_mode", &EditorNode::_toggle_distraction_free_mode);
  3561. ClassDB::bind_method(D_METHOD("get_gui_base"), &EditorNode::get_gui_base);
  3562. ClassDB::bind_method(D_METHOD("_bottom_panel_switch"), &EditorNode::_bottom_panel_switch);
  3563. ClassDB::bind_method(D_METHOD("_open_imported"), &EditorNode::_open_imported);
  3564. ClassDB::bind_method(D_METHOD("_inherit_imported"), &EditorNode::_inherit_imported);
  3565. ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout);
  3566. ClassDB::bind_method(D_METHOD("_resources_reimported"), &EditorNode::_resources_reimported);
  3567. ClassDB::bind_method(D_METHOD("_bottom_panel_raise_toggled"), &EditorNode::_bottom_panel_raise_toggled);
  3568. ClassDB::bind_method(D_METHOD("_on_plugin_ready"), &EditorNode::_on_plugin_ready);
  3569. ClassDB::bind_method(D_METHOD("_video_driver_selected"), &EditorNode::_video_driver_selected);
  3570. ADD_SIGNAL(MethodInfo("play_pressed"));
  3571. ADD_SIGNAL(MethodInfo("pause_pressed"));
  3572. ADD_SIGNAL(MethodInfo("stop_pressed"));
  3573. ADD_SIGNAL(MethodInfo("request_help_search"));
  3574. ADD_SIGNAL(MethodInfo("request_help_index"));
  3575. ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::POOL_STRING_ARRAY, "args")));
  3576. ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj")));
  3577. }
  3578. static Node *_resource_get_edited_scene() {
  3579. return EditorNode::get_singleton()->get_edited_scene();
  3580. }
  3581. void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_error) {
  3582. EditorNode *en = (EditorNode *)p_this;
  3583. en->log->add_message(p_string, p_error ? EditorLog::MSG_TYPE_ERROR : EditorLog::MSG_TYPE_STD);
  3584. }
  3585. EditorNode::EditorNode() {
  3586. Resource::_get_local_scene_func = _resource_get_edited_scene;
  3587. VisualServer::get_singleton()->textures_keep_original(true);
  3588. VisualServer::get_singleton()->set_debug_generate_wireframes(true);
  3589. PhysicsServer::get_singleton()->set_active(false); // no physics by default if editor
  3590. Physics2DServer::get_singleton()->set_active(false); // no physics by default if editor
  3591. ScriptServer::set_scripting_enabled(false); // no scripting by default if editor
  3592. EditorHelp::generate_doc(); //before any editor classes are created
  3593. SceneState::set_disable_placeholders(true);
  3594. ResourceLoader::clear_translation_remaps(); //no remaps using during editor
  3595. ResourceLoader::clear_path_remaps();
  3596. InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
  3597. if (id) {
  3598. if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) {
  3599. //only if no touchscreen ui hint, set emulation
  3600. id->set_emulate_touch_from_mouse(false); //just disable just in case
  3601. }
  3602. id->set_custom_mouse_cursor(RES());
  3603. }
  3604. singleton = this;
  3605. exiting = false;
  3606. last_checked_version = 0;
  3607. changing_scene = false;
  3608. _initializing_addons = false;
  3609. docks_visible = true;
  3610. restoring_scenes = false;
  3611. scene_distraction = false;
  3612. script_distraction = false;
  3613. TranslationServer::get_singleton()->set_enabled(false);
  3614. // load settings
  3615. if (!EditorSettings::get_singleton())
  3616. EditorSettings::create();
  3617. FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename"));
  3618. {
  3619. int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale");
  3620. float custom_display_scale = EditorSettings::get_singleton()->get("interface/editor/custom_display_scale");
  3621. switch (display_scale) {
  3622. case 0: {
  3623. // Try applying a suitable display scale automatically
  3624. const int screen = OS::get_singleton()->get_current_screen();
  3625. editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
  3626. } break;
  3627. case 1: {
  3628. editor_set_scale(0.75);
  3629. } break;
  3630. case 2: {
  3631. editor_set_scale(1.0);
  3632. } break;
  3633. case 3: {
  3634. editor_set_scale(1.25);
  3635. } break;
  3636. case 4: {
  3637. editor_set_scale(1.5);
  3638. } break;
  3639. case 5: {
  3640. editor_set_scale(1.75);
  3641. } break;
  3642. case 6: {
  3643. editor_set_scale(2.0);
  3644. } break;
  3645. default: {
  3646. editor_set_scale(custom_display_scale);
  3647. } break;
  3648. }
  3649. }
  3650. ResourceLoader::set_abort_on_missing_resources(false);
  3651. FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
  3652. EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
  3653. EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int());
  3654. ResourceLoader::set_error_notify_func(this, _load_error_notify);
  3655. ResourceLoader::set_dependency_error_notify_func(this, _dependency_error_report);
  3656. ResourceLoader::set_timestamp_on_load(true);
  3657. ResourceSaver::set_timestamp_on_save(true);
  3658. { //register importers at the beginning, so dialogs are created with the right extensions
  3659. Ref<ResourceImporterTexture> import_texture;
  3660. import_texture.instance();
  3661. ResourceFormatImporter::get_singleton()->add_importer(import_texture);
  3662. Ref<ResourceImporterLayeredTexture> import_3d;
  3663. import_3d.instance();
  3664. import_3d->set_3d(true);
  3665. ResourceFormatImporter::get_singleton()->add_importer(import_3d);
  3666. Ref<ResourceImporterLayeredTexture> import_array;
  3667. import_array.instance();
  3668. import_array->set_3d(false);
  3669. ResourceFormatImporter::get_singleton()->add_importer(import_array);
  3670. Ref<ResourceImporterImage> import_image;
  3671. import_image.instance();
  3672. ResourceFormatImporter::get_singleton()->add_importer(import_image);
  3673. Ref<ResourceImporterCSVTranslation> import_csv_translation;
  3674. import_csv_translation.instance();
  3675. ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation);
  3676. Ref<ResourceImporterWAV> import_wav;
  3677. import_wav.instance();
  3678. ResourceFormatImporter::get_singleton()->add_importer(import_wav);
  3679. Ref<ResourceImporterOBJ> import_obj;
  3680. import_obj.instance();
  3681. ResourceFormatImporter::get_singleton()->add_importer(import_obj);
  3682. Ref<ResourceImporterScene> import_scene;
  3683. import_scene.instance();
  3684. ResourceFormatImporter::get_singleton()->add_importer(import_scene);
  3685. {
  3686. Ref<EditorSceneImporterCollada> import_collada;
  3687. import_collada.instance();
  3688. import_scene->add_importer(import_collada);
  3689. Ref<EditorOBJImporter> import_obj;
  3690. import_obj.instance();
  3691. import_scene->add_importer(import_obj);
  3692. Ref<EditorSceneImporterGLTF> import_gltf;
  3693. import_gltf.instance();
  3694. import_scene->add_importer(import_gltf);
  3695. Ref<EditorSceneImporterESCN> import_escn;
  3696. import_escn.instance();
  3697. import_scene->add_importer(import_escn);
  3698. }
  3699. Ref<ResourceImporterBitMap> import_bitmap;
  3700. import_bitmap.instance();
  3701. ResourceFormatImporter::get_singleton()->add_importer(import_bitmap);
  3702. }
  3703. {
  3704. Ref<EditorInspectorDefaultPlugin> eidp;
  3705. eidp.instance();
  3706. EditorInspector::add_inspector_plugin(eidp);
  3707. Ref<EditorInspectorRootMotionPlugin> rmp;
  3708. rmp.instance();
  3709. EditorInspector::add_inspector_plugin(rmp);
  3710. Ref<EditorInspectorShaderModePlugin> smp;
  3711. smp.instance();
  3712. EditorInspector::add_inspector_plugin(smp);
  3713. }
  3714. _pvrtc_register_compressors();
  3715. editor_selection = memnew(EditorSelection);
  3716. EditorFileSystem *efs = memnew(EditorFileSystem);
  3717. add_child(efs);
  3718. //used for previews
  3719. FileDialog::get_icon_func = _file_dialog_get_icon;
  3720. FileDialog::register_func = _file_dialog_register;
  3721. FileDialog::unregister_func = _file_dialog_unregister;
  3722. EditorFileDialog::get_icon_func = _file_dialog_get_icon;
  3723. EditorFileDialog::register_func = _editor_file_dialog_register;
  3724. EditorFileDialog::unregister_func = _editor_file_dialog_unregister;
  3725. editor_export = memnew(EditorExport);
  3726. add_child(editor_export);
  3727. register_exporters();
  3728. GLOBAL_DEF("editor/main_run_args", "");
  3729. ClassDB::set_class_enabled("RootMotionView", true);
  3730. //defs here, use EDITOR_GET in logic
  3731. EDITOR_DEF_RST("interface/scene_tabs/always_show_close_button", false);
  3732. EDITOR_DEF_RST("interface/scene_tabs/resize_if_many_tabs", true);
  3733. EDITOR_DEF_RST("interface/scene_tabs/minimum_width", 50);
  3734. EDITOR_DEF("run/output/always_clear_output_on_play", true);
  3735. EDITOR_DEF("run/output/always_open_output_on_play", true);
  3736. EDITOR_DEF("run/output/always_close_output_on_stop", true);
  3737. EDITOR_DEF("run/auto_save/save_before_running", true);
  3738. EDITOR_DEF_RST("interface/editor/save_each_scene_on_quit", true);
  3739. EDITOR_DEF("interface/editor/quit_confirmation", true);
  3740. EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", false);
  3741. EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true);
  3742. EDITOR_DEF_RST("interface/inspector/capitalize_properties", true);
  3743. EDITOR_DEF_RST("interface/inspector/disable_folding", false);
  3744. EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
  3745. EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true);
  3746. EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
  3747. EDITOR_DEF("interface/inspector/resources_types_to_open_in_new_inspector", "SpatialMaterial,Script");
  3748. EDITOR_DEF("run/auto_save/save_before_running", true);
  3749. theme_base = memnew(Control);
  3750. add_child(theme_base);
  3751. theme_base->set_anchors_and_margins_preset(Control::PRESET_WIDE);
  3752. gui_base = memnew(Panel);
  3753. theme_base->add_child(gui_base);
  3754. gui_base->set_anchors_and_margins_preset(Control::PRESET_WIDE);
  3755. Ref<Theme> theme = create_custom_theme();
  3756. theme_base->set_theme(theme);
  3757. gui_base->set_theme(theme);
  3758. gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles"));
  3759. resource_preview = memnew(EditorResourcePreview);
  3760. add_child(resource_preview);
  3761. progress_dialog = memnew(ProgressDialog);
  3762. gui_base->add_child(progress_dialog);
  3763. // take up all screen
  3764. gui_base->set_anchor(MARGIN_RIGHT, Control::ANCHOR_END);
  3765. gui_base->set_anchor(MARGIN_BOTTOM, Control::ANCHOR_END);
  3766. gui_base->set_end(Point2(0, 0));
  3767. main_vbox = memnew(VBoxContainer);
  3768. gui_base->add_child(main_vbox);
  3769. main_vbox->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8);
  3770. main_vbox->set_margin(MARGIN_TOP, 5 * EDSCALE);
  3771. menu_hb = memnew(HBoxContainer);
  3772. main_vbox->add_child(menu_hb);
  3773. left_l_hsplit = memnew(HSplitContainer);
  3774. main_vbox->add_child(left_l_hsplit);
  3775. left_l_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3776. left_l_vsplit = memnew(VSplitContainer);
  3777. left_l_hsplit->add_child(left_l_vsplit);
  3778. dock_slot[DOCK_SLOT_LEFT_UL] = memnew(TabContainer);
  3779. left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UL]);
  3780. dock_slot[DOCK_SLOT_LEFT_BL] = memnew(TabContainer);
  3781. left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BL]);
  3782. left_r_hsplit = memnew(HSplitContainer);
  3783. left_l_hsplit->add_child(left_r_hsplit);
  3784. left_r_vsplit = memnew(VSplitContainer);
  3785. left_r_hsplit->add_child(left_r_vsplit);
  3786. dock_slot[DOCK_SLOT_LEFT_UR] = memnew(TabContainer);
  3787. left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UR]);
  3788. dock_slot[DOCK_SLOT_LEFT_BR] = memnew(TabContainer);
  3789. left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BR]);
  3790. main_hsplit = memnew(HSplitContainer);
  3791. left_r_hsplit->add_child(main_hsplit);
  3792. VBoxContainer *center_vb = memnew(VBoxContainer);
  3793. main_hsplit->add_child(center_vb);
  3794. center_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  3795. center_split = memnew(VSplitContainer);
  3796. center_split->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3797. center_split->set_collapsed(false);
  3798. center_vb->add_child(center_split);
  3799. right_hsplit = memnew(HSplitContainer);
  3800. main_hsplit->add_child(right_hsplit);
  3801. right_l_vsplit = memnew(VSplitContainer);
  3802. right_hsplit->add_child(right_l_vsplit);
  3803. dock_slot[DOCK_SLOT_RIGHT_UL] = memnew(TabContainer);
  3804. right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UL]);
  3805. dock_slot[DOCK_SLOT_RIGHT_BL] = memnew(TabContainer);
  3806. right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BL]);
  3807. right_r_vsplit = memnew(VSplitContainer);
  3808. right_hsplit->add_child(right_r_vsplit);
  3809. dock_slot[DOCK_SLOT_RIGHT_UR] = memnew(TabContainer);
  3810. right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UR]);
  3811. dock_slot[DOCK_SLOT_RIGHT_BR] = memnew(TabContainer);
  3812. right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BR]);
  3813. // Store them for easier access
  3814. vsplits.push_back(left_l_vsplit);
  3815. vsplits.push_back(left_r_vsplit);
  3816. vsplits.push_back(right_l_vsplit);
  3817. vsplits.push_back(right_r_vsplit);
  3818. hsplits.push_back(left_l_hsplit);
  3819. hsplits.push_back(left_r_hsplit);
  3820. hsplits.push_back(main_hsplit);
  3821. hsplits.push_back(right_hsplit);
  3822. for (int i = 0; i < vsplits.size(); i++) {
  3823. vsplits[i]->connect("dragged", this, "_dock_split_dragged");
  3824. hsplits[i]->connect("dragged", this, "_dock_split_dragged");
  3825. }
  3826. dock_select_popup = memnew(PopupPanel);
  3827. gui_base->add_child(dock_select_popup);
  3828. VBoxContainer *dock_vb = memnew(VBoxContainer);
  3829. dock_select_popup->add_child(dock_vb);
  3830. HBoxContainer *dock_hb = memnew(HBoxContainer);
  3831. dock_tab_move_left = memnew(ToolButton);
  3832. dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons"));
  3833. dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE);
  3834. dock_tab_move_left->connect("pressed", this, "_dock_move_left");
  3835. dock_hb->add_child(dock_tab_move_left);
  3836. Label *dock_label = memnew(Label);
  3837. dock_label->set_text(TTR("Dock Position"));
  3838. dock_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  3839. dock_hb->add_child(dock_label);
  3840. dock_tab_move_right = memnew(ToolButton);
  3841. dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons"));
  3842. dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE);
  3843. dock_tab_move_right->connect("pressed", this, "_dock_move_right");
  3844. dock_hb->add_child(dock_tab_move_right);
  3845. dock_vb->add_child(dock_hb);
  3846. dock_select = memnew(Control);
  3847. dock_select->set_custom_minimum_size(Size2(128, 64) * EDSCALE);
  3848. dock_select->connect("gui_input", this, "_dock_select_input");
  3849. dock_select->connect("draw", this, "_dock_select_draw");
  3850. dock_select->connect("mouse_exited", this, "_dock_popup_exit");
  3851. dock_select->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3852. dock_vb->add_child(dock_select);
  3853. dock_select_popup->set_as_minsize();
  3854. dock_select_rect_over = -1;
  3855. dock_popup_selected = -1;
  3856. for (int i = 0; i < DOCK_SLOT_MAX; i++) {
  3857. dock_slot[i]->set_custom_minimum_size(Size2(170, 0) * EDSCALE);
  3858. dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3859. dock_slot[i]->set_popup(dock_select_popup);
  3860. dock_slot[i]->connect("pre_popup_pressed", this, "_dock_pre_popup", varray(i));
  3861. dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT);
  3862. dock_slot[i]->set_drag_to_rearrange_enabled(true);
  3863. dock_slot[i]->set_tabs_rearrange_group(1);
  3864. dock_slot[i]->connect("tab_changed", this, "_dock_tab_changed");
  3865. }
  3866. dock_drag_timer = memnew(Timer);
  3867. add_child(dock_drag_timer);
  3868. dock_drag_timer->set_wait_time(0.5);
  3869. dock_drag_timer->set_one_shot(true);
  3870. dock_drag_timer->connect("timeout", this, "_save_docks");
  3871. top_split = memnew(VSplitContainer);
  3872. center_split->add_child(top_split);
  3873. top_split->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3874. top_split->set_collapsed(true);
  3875. VBoxContainer *srt = memnew(VBoxContainer);
  3876. srt->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3877. top_split->add_child(srt);
  3878. srt->add_constant_override("separation", 0);
  3879. tab_preview_panel = memnew(Panel);
  3880. tab_preview_panel->set_size(Size2(100, 100) * EDSCALE);
  3881. tab_preview_panel->hide();
  3882. tab_preview_panel->set_self_modulate(Color(1, 1, 1, 0.7));
  3883. gui_base->add_child(tab_preview_panel);
  3884. tab_preview = memnew(TextureRect);
  3885. tab_preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
  3886. tab_preview->set_size(Size2(96, 96) * EDSCALE);
  3887. tab_preview->set_position(Point2(2, 2) * EDSCALE);
  3888. tab_preview_panel->add_child(tab_preview);
  3889. scene_tabs = memnew(Tabs);
  3890. scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
  3891. scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
  3892. scene_tabs->set_select_with_rmb(true);
  3893. scene_tabs->add_tab("unsaved");
  3894. scene_tabs->set_tab_align(Tabs::ALIGN_LEFT);
  3895. scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/scene_tabs/always_show_close_button", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
  3896. scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE);
  3897. scene_tabs->set_drag_to_rearrange_enabled(true);
  3898. scene_tabs->connect("tab_changed", this, "_scene_tab_changed");
  3899. scene_tabs->connect("right_button_pressed", this, "_scene_tab_script_edited");
  3900. scene_tabs->connect("tab_close", this, "_scene_tab_closed");
  3901. scene_tabs->connect("tab_hover", this, "_scene_tab_hover");
  3902. scene_tabs->connect("mouse_exited", this, "_scene_tab_exit");
  3903. scene_tabs->connect("gui_input", this, "_scene_tab_input");
  3904. scene_tabs->connect("reposition_active_tab_request", this, "_reposition_active_tab");
  3905. scene_tabs->connect("resized", this, "_update_scene_tabs");
  3906. tabbar_container = memnew(HBoxContainer);
  3907. scene_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  3908. scene_tabs_context_menu = memnew(PopupMenu);
  3909. tabbar_container->add_child(scene_tabs_context_menu);
  3910. scene_tabs_context_menu->connect("id_pressed", this, "_menu_option");
  3911. scene_tabs_context_menu->set_hide_on_window_lose_focus(true);
  3912. srt->add_child(tabbar_container);
  3913. tabbar_container->add_child(scene_tabs);
  3914. distraction_free = memnew(ToolButton);
  3915. #ifdef OSX_ENABLED
  3916. distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_D));
  3917. #else
  3918. distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11));
  3919. #endif
  3920. distraction_free->set_tooltip(TTR("Toggle distraction-free mode."));
  3921. distraction_free->connect("pressed", this, "_toggle_distraction_free_mode");
  3922. distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
  3923. distraction_free->set_toggle_mode(true);
  3924. scene_tab_add = memnew(ToolButton);
  3925. tabbar_container->add_child(scene_tab_add);
  3926. tabbar_container->add_child(distraction_free);
  3927. scene_tab_add->set_tooltip(TTR("Add a new scene."));
  3928. scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons"));
  3929. scene_tab_add->add_color_override("icon_color_normal", Color(0.6f, 0.6f, 0.6f, 0.8f));
  3930. scene_tab_add->connect("pressed", this, "_menu_option", make_binds(FILE_NEW_SCENE));
  3931. scene_root_parent = memnew(PanelContainer);
  3932. scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
  3933. scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
  3934. scene_root_parent->set_draw_behind_parent(true);
  3935. srt->add_child(scene_root_parent);
  3936. scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3937. scene_root = memnew(Viewport);
  3938. //scene_root->set_usage(Viewport::USAGE_2D); canvas BG mode prevents usage of this as 2D
  3939. scene_root->set_disable_3d(true);
  3940. VisualServer::get_singleton()->viewport_set_hide_scenario(scene_root->get_viewport_rid(), true);
  3941. scene_root->set_disable_input(true);
  3942. scene_root->set_as_audio_listener_2d(true);
  3943. viewport = memnew(VBoxContainer);
  3944. viewport->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3945. viewport->add_constant_override("separation", 0);
  3946. scene_root_parent->add_child(viewport);
  3947. PanelContainer *top_region = memnew(PanelContainer);
  3948. top_region->add_style_override("panel", gui_base->get_stylebox("MenuPanel", "EditorStyles"));
  3949. HBoxContainer *left_menu_hb = memnew(HBoxContainer);
  3950. top_region->add_child(left_menu_hb);
  3951. menu_hb->add_child(top_region);
  3952. {
  3953. Control *sp = memnew(Control);
  3954. sp->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
  3955. menu_hb->add_child(sp);
  3956. }
  3957. file_menu = memnew(MenuButton);
  3958. file_menu->set_flat(false);
  3959. file_menu->set_text(TTR("Scene"));
  3960. file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  3961. left_menu_hb->add_child(file_menu);
  3962. prev_scene = memnew(ToolButton);
  3963. prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons"));
  3964. prev_scene->set_tooltip(TTR("Go to previously opened scene."));
  3965. prev_scene->set_disabled(true);
  3966. prev_scene->connect("pressed", this, "_menu_option", make_binds(FILE_OPEN_PREV));
  3967. gui_base->add_child(prev_scene);
  3968. prev_scene->set_position(Point2(3, 24));
  3969. prev_scene->hide();
  3970. accept = memnew(AcceptDialog);
  3971. gui_base->add_child(accept);
  3972. accept->connect("confirmed", this, "_menu_confirm_current");
  3973. project_export = memnew(ProjectExportDialog);
  3974. gui_base->add_child(project_export);
  3975. dependency_error = memnew(DependencyErrorDialog);
  3976. gui_base->add_child(dependency_error);
  3977. dependency_fixer = memnew(DependencyEditor);
  3978. gui_base->add_child(dependency_fixer);
  3979. settings_config_dialog = memnew(EditorSettingsDialog);
  3980. gui_base->add_child(settings_config_dialog);
  3981. project_settings = memnew(ProjectSettingsEditor(&editor_data));
  3982. gui_base->add_child(project_settings);
  3983. run_settings_dialog = memnew(RunSettingsDialog);
  3984. gui_base->add_child(run_settings_dialog);
  3985. export_template_manager = memnew(ExportTemplateManager);
  3986. gui_base->add_child(export_template_manager);
  3987. about = memnew(EditorAbout);
  3988. gui_base->add_child(about);
  3989. warning = memnew(AcceptDialog);
  3990. gui_base->add_child(warning);
  3991. ED_SHORTCUT("editor/next_tab", TTR("Next tab"), KEY_MASK_CMD + KEY_TAB);
  3992. ED_SHORTCUT("editor/prev_tab", TTR("Previous tab"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_TAB);
  3993. ED_SHORTCUT("editor/filter_files", TTR("Filter Files..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_P);
  3994. PopupMenu *p;
  3995. file_menu->set_tooltip(TTR("Operations with scene files."));
  3996. p = file_menu->get_popup();
  3997. p->set_hide_on_window_lose_focus(true);
  3998. p->add_shortcut(ED_SHORTCUT("editor/new_scene", TTR("New Scene")), FILE_NEW_SCENE);
  3999. p->add_shortcut(ED_SHORTCUT("editor/new_inherited_scene", TTR("New Inherited Scene...")), FILE_NEW_INHERITED_SCENE);
  4000. p->add_shortcut(ED_SHORTCUT("editor/open_scene", TTR("Open Scene..."), KEY_MASK_CMD + KEY_O), FILE_OPEN_SCENE);
  4001. p->add_separator();
  4002. p->add_shortcut(ED_SHORTCUT("editor/save_scene", TTR("Save Scene"), KEY_MASK_CMD + KEY_S), FILE_SAVE_SCENE);
  4003. p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE);
  4004. p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save all Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES);
  4005. p->add_separator();
  4006. p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
  4007. p->add_separator();
  4008. p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
  4009. p->add_separator();
  4010. p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCENE);
  4011. p->add_shortcut(ED_SHORTCUT("editor/quick_open_script", TTR("Quick Open Script..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCRIPT);
  4012. p->add_separator();
  4013. PopupMenu *pm_export = memnew(PopupMenu);
  4014. pm_export->set_name("Export");
  4015. p->add_child(pm_export);
  4016. p->add_submenu_item(TTR("Convert To..."), "Export");
  4017. pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_MeshLibrary", TTR("MeshLibrary...")), FILE_EXPORT_MESH_LIBRARY);
  4018. pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_TileSet", TTR("TileSet...")), FILE_EXPORT_TILESET);
  4019. pm_export->connect("id_pressed", this, "_menu_option");
  4020. p->add_separator();
  4021. p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
  4022. p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true);
  4023. p->add_separator();
  4024. p->add_item(TTR("Revert Scene"), EDIT_REVERT);
  4025. recent_scenes = memnew(PopupMenu);
  4026. recent_scenes->set_name("RecentScenes");
  4027. p->add_child(recent_scenes);
  4028. recent_scenes->connect("id_pressed", this, "_open_recent_scene");
  4029. p->add_separator();
  4030. p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q);
  4031. project_menu = memnew(MenuButton);
  4032. project_menu->set_flat(false);
  4033. project_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools."));
  4034. project_menu->set_text(TTR("Project"));
  4035. project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  4036. left_menu_hb->add_child(project_menu);
  4037. p = project_menu->get_popup();
  4038. p->set_hide_on_window_lose_focus(true);
  4039. p->add_item(TTR("Project Settings"), RUN_SETTINGS);
  4040. p->add_separator();
  4041. p->connect("id_pressed", this, "_menu_option");
  4042. p->add_item(TTR("Export"), FILE_EXPORT_PROJECT);
  4043. plugin_config_dialog = memnew(PluginConfigDialog);
  4044. plugin_config_dialog->connect("plugin_ready", this, "_on_plugin_ready");
  4045. gui_base->add_child(plugin_config_dialog);
  4046. tool_menu = memnew(PopupMenu);
  4047. tool_menu->set_name("Tools");
  4048. tool_menu->connect("index_pressed", this, "_tool_menu_option");
  4049. p->add_child(tool_menu);
  4050. p->add_submenu_item(TTR("Tools"), "Tools");
  4051. tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
  4052. p->add_separator();
  4053. p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
  4054. p->add_separator();
  4055. #ifdef OSX_ENABLED
  4056. p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
  4057. #else
  4058. p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q);
  4059. #endif
  4060. PanelContainer *editor_region = memnew(PanelContainer);
  4061. main_editor_button_vb = memnew(HBoxContainer);
  4062. editor_region->add_child(main_editor_button_vb);
  4063. menu_hb->add_spacer();
  4064. menu_hb->add_child(editor_region);
  4065. debug_menu = memnew(MenuButton);
  4066. debug_menu->set_flat(false);
  4067. debug_menu->set_text(TTR("Debug"));
  4068. debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  4069. left_menu_hb->add_child(debug_menu);
  4070. p = debug_menu->get_popup();
  4071. p->set_hide_on_window_lose_focus(true);
  4072. p->set_hide_on_item_selection(false);
  4073. p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG);
  4074. p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
  4075. p->add_check_item(TTR("Small Deploy with Network FS"), RUN_FILE_SERVER);
  4076. p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is enabled, export or deploy will produce a minimal executable.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploy will use the USB cable for faster performance. This option speeds up testing for games with a large footprint."));
  4077. p->add_separator();
  4078. p->add_check_item(TTR("Visible Collision Shapes"), RUN_DEBUG_COLLISONS);
  4079. p->set_item_tooltip(p->get_item_count() - 1, TTR("Collision shapes and raycast nodes (for 2D and 3D) will be visible on the running game if this option is turned on."));
  4080. p->add_check_item(TTR("Visible Navigation"), RUN_DEBUG_NAVIGATION);
  4081. p->set_item_tooltip(p->get_item_count() - 1, TTR("Navigation meshes and polygons will be visible on the running game if this option is turned on."));
  4082. p->add_separator();
  4083. p->add_check_item(TTR("Sync Scene Changes"), RUN_LIVE_DEBUG);
  4084. p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any changes made to the scene in the editor will be replicated in the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
  4085. p->add_check_item(TTR("Sync Script Changes"), RUN_RELOAD_SCRIPTS);
  4086. p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
  4087. p->connect("id_pressed", this, "_menu_option");
  4088. menu_hb->add_spacer();
  4089. settings_menu = memnew(MenuButton);
  4090. settings_menu->set_flat(false);
  4091. settings_menu->set_text(TTR("Editor"));
  4092. settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  4093. left_menu_hb->add_child(settings_menu);
  4094. p = settings_menu->get_popup();
  4095. p->set_hide_on_window_lose_focus(true);
  4096. p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES);
  4097. p->add_separator();
  4098. editor_layouts = memnew(PopupMenu);
  4099. editor_layouts->set_name("Layouts");
  4100. p->add_child(editor_layouts);
  4101. editor_layouts->connect("id_pressed", this, "_layout_menu_option");
  4102. p->add_submenu_item(TTR("Editor Layout"), "Layouts");
  4103. #ifdef OSX_ENABLED
  4104. p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_F), SETTINGS_TOGGLE_FULLSCREEN);
  4105. #else
  4106. p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREEN);
  4107. #endif
  4108. p->add_separator();
  4109. if (OS::get_singleton()->get_data_path() == OS::get_singleton()->get_config_path()) {
  4110. // Configuration and data folders are located in the same place (Windows/macOS)
  4111. p->add_item(TTR("Open Editor Data/Settings Folder"), SETTINGS_EDITOR_DATA_FOLDER);
  4112. } else {
  4113. // Separate configuration and data folders (Linux)
  4114. p->add_item(TTR("Open Editor Data Folder"), SETTINGS_EDITOR_DATA_FOLDER);
  4115. p->add_item(TTR("Open Editor Settings Folder"), SETTINGS_EDITOR_CONFIG_FOLDER);
  4116. }
  4117. p->add_separator();
  4118. p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
  4119. // Help Menu
  4120. help_menu = memnew(MenuButton);
  4121. help_menu->set_flat(false);
  4122. help_menu->set_text(TTR("Help"));
  4123. help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
  4124. left_menu_hb->add_child(help_menu);
  4125. p = help_menu->get_popup();
  4126. p->set_hide_on_window_lose_focus(true);
  4127. p->connect("id_pressed", this, "_menu_option");
  4128. p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES);
  4129. p->add_icon_item(gui_base->get_icon("HelpSearch", "EditorIcons"), TTR("Search"), HELP_SEARCH);
  4130. p->add_separator();
  4131. p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS);
  4132. p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Q&A"), HELP_QA);
  4133. p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Issue Tracker"), HELP_ISSUES);
  4134. p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Community"), HELP_COMMUNITY);
  4135. p->add_separator();
  4136. p->add_icon_item(gui_base->get_icon("Godot", "EditorIcons"), TTR("About"), HELP_ABOUT);
  4137. play_cc = memnew(CenterContainer);
  4138. play_cc->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
  4139. menu_hb->add_child(play_cc);
  4140. play_button_panel = memnew(PanelContainer);
  4141. play_cc->add_child(play_button_panel);
  4142. HBoxContainer *play_hb = memnew(HBoxContainer);
  4143. play_button_panel->add_child(play_hb);
  4144. play_button = memnew(ToolButton);
  4145. play_hb->add_child(play_button);
  4146. play_button->set_toggle_mode(true);
  4147. play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons"));
  4148. play_button->set_focus_mode(Control::FOCUS_NONE);
  4149. play_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY));
  4150. play_button->set_tooltip(TTR("Play the project."));
  4151. #ifdef OSX_ENABLED
  4152. play_button->set_shortcut(ED_SHORTCUT("editor/play", TTR("Play"), KEY_MASK_CMD | KEY_B));
  4153. #else
  4154. play_button->set_shortcut(ED_SHORTCUT("editor/play", TTR("Play"), KEY_F5));
  4155. #endif
  4156. pause_button = memnew(ToolButton);
  4157. pause_button->set_toggle_mode(true);
  4158. pause_button->set_icon(gui_base->get_icon("Pause", "EditorIcons"));
  4159. pause_button->set_focus_mode(Control::FOCUS_NONE);
  4160. pause_button->set_tooltip(TTR("Pause the scene"));
  4161. pause_button->set_disabled(true);
  4162. play_hb->add_child(pause_button);
  4163. #ifdef OSX_ENABLED
  4164. pause_button->set_shortcut(ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_Y));
  4165. #else
  4166. pause_button->set_shortcut(ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), KEY_F7));
  4167. #endif
  4168. stop_button = memnew(ToolButton);
  4169. play_hb->add_child(stop_button);
  4170. stop_button->set_focus_mode(Control::FOCUS_NONE);
  4171. stop_button->set_icon(gui_base->get_icon("Stop", "EditorIcons"));
  4172. stop_button->connect("pressed", this, "_menu_option", make_binds(RUN_STOP));
  4173. stop_button->set_tooltip(TTR("Stop the scene."));
  4174. stop_button->set_disabled(true);
  4175. #ifdef OSX_ENABLED
  4176. stop_button->set_shortcut(ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_MASK_CMD | KEY_PERIOD));
  4177. #else
  4178. stop_button->set_shortcut(ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_F8));
  4179. #endif
  4180. run_native = memnew(EditorRunNative);
  4181. play_hb->add_child(run_native);
  4182. native_play_button = memnew(MenuButton);
  4183. native_play_button->set_text("NTV");
  4184. menu_hb->add_child(native_play_button);
  4185. native_play_button->hide();
  4186. native_play_button->get_popup()->connect("id_pressed", this, "_run_in_device");
  4187. run_native->connect("native_run", this, "_menu_option", varray(RUN_PLAY_NATIVE));
  4188. play_scene_button = memnew(ToolButton);
  4189. play_hb->add_child(play_scene_button);
  4190. play_scene_button->set_toggle_mode(true);
  4191. play_scene_button->set_focus_mode(Control::FOCUS_NONE);
  4192. play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
  4193. play_scene_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY_SCENE));
  4194. play_scene_button->set_tooltip(TTR("Play the edited scene."));
  4195. #ifdef OSX_ENABLED
  4196. play_scene_button->set_shortcut(ED_SHORTCUT("editor/play_scene", TTR("Play Scene"), KEY_MASK_CMD | KEY_R));
  4197. #else
  4198. play_scene_button->set_shortcut(ED_SHORTCUT("editor/play_scene", TTR("Play Scene"), KEY_F6));
  4199. #endif
  4200. play_custom_scene_button = memnew(ToolButton);
  4201. play_hb->add_child(play_custom_scene_button);
  4202. play_custom_scene_button->set_toggle_mode(true);
  4203. play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE);
  4204. play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
  4205. play_custom_scene_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY_CUSTOM_SCENE));
  4206. play_custom_scene_button->set_tooltip(TTR("Play custom scene"));
  4207. #ifdef OSX_ENABLED
  4208. play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R));
  4209. #else
  4210. play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F5));
  4211. #endif
  4212. // Toggle for video driver
  4213. video_driver = memnew(OptionButton);
  4214. video_driver->set_flat(true);
  4215. video_driver->set_focus_mode(Control::FOCUS_NONE);
  4216. video_driver->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
  4217. video_driver->connect("item_selected", this, "_video_driver_selected");
  4218. video_driver->add_font_override("font", gui_base->get_font("bold", "EditorFonts"));
  4219. menu_hb->add_child(video_driver);
  4220. String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/quality/driver/driver_name"].hint_string;
  4221. String current_video_driver = OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver());
  4222. video_driver_current = 0;
  4223. for (int i = 0; i < video_drivers.get_slice_count(","); i++) {
  4224. String driver = video_drivers.get_slice(",", i);
  4225. video_driver->add_item(driver);
  4226. video_driver->set_item_metadata(i, driver);
  4227. if (current_video_driver == driver) {
  4228. video_driver->select(i);
  4229. video_driver_current = i;
  4230. }
  4231. }
  4232. _update_video_driver_color();
  4233. video_restart_dialog = memnew(ConfirmationDialog);
  4234. video_restart_dialog->set_text(TTR("Changing the video driver requires restarting the editor."));
  4235. video_restart_dialog->get_ok()->set_text(TTR("Save & Restart"));
  4236. video_restart_dialog->connect("confirmed", this, "_menu_option", varray(SET_VIDEO_DRIVER_SAVE_AND_RESTART));
  4237. gui_base->add_child(video_restart_dialog);
  4238. progress_hb = memnew(BackgroundProgress);
  4239. HBoxContainer *right_menu_hb = memnew(HBoxContainer);
  4240. menu_hb->add_child(right_menu_hb);
  4241. layout_dialog = memnew(EditorNameDialog);
  4242. gui_base->add_child(layout_dialog);
  4243. layout_dialog->set_hide_on_ok(false);
  4244. layout_dialog->set_size(Size2(175, 70) * EDSCALE);
  4245. layout_dialog->connect("name_confirmed", this, "_dialog_action");
  4246. update_menu = memnew(MenuButton);
  4247. update_menu->set_tooltip(TTR("Spins when the editor window repaints!"));
  4248. right_menu_hb->add_child(update_menu);
  4249. update_menu->set_icon(gui_base->get_icon("Progress1", "EditorIcons"));
  4250. update_menu->get_popup()->connect("id_pressed", this, "_menu_option");
  4251. p = update_menu->get_popup();
  4252. p->add_radio_check_item(TTR("Update Always"), SETTINGS_UPDATE_ALWAYS);
  4253. p->add_radio_check_item(TTR("Update Changes"), SETTINGS_UPDATE_CHANGES);
  4254. p->add_separator();
  4255. p->add_check_item(TTR("Disable Update Spinner"), SETTINGS_UPDATE_SPINNER_HIDE);
  4256. int update_always = EditorSettings::get_singleton()->get_project_metadata("editor_options", "update_always", false);
  4257. int hide_spinner = EditorSettings::get_singleton()->get_project_metadata("editor_options", "update_spinner_hide", false);
  4258. _menu_option(update_always ? SETTINGS_UPDATE_ALWAYS : SETTINGS_UPDATE_CHANGES);
  4259. if (hide_spinner) {
  4260. _menu_option(SETTINGS_UPDATE_SPINNER_HIDE);
  4261. }
  4262. // Instantiate and place editor docks
  4263. scene_tree_dock = memnew(SceneTreeDock(this, scene_root, editor_selection, editor_data));
  4264. inspector_dock = memnew(InspectorDock(this, editor_data));
  4265. import_dock = memnew(ImportDock);
  4266. node_dock = memnew(NodeDock);
  4267. filesystem_dock = memnew(FileSystemDock(this));
  4268. filesystem_dock->set_file_list_display_mode(int(EditorSettings::get_singleton()->get("docks/filesystem/files_display_mode")));
  4269. filesystem_dock->connect("open", this, "open_request");
  4270. filesystem_dock->connect("instance", this, "_instance_request");
  4271. // Scene: Top left
  4272. dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock);
  4273. dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(scene_tree_dock->get_index(), TTR("Scene"));
  4274. // Import: Top left, behind Scene
  4275. dock_slot[DOCK_SLOT_LEFT_UR]->add_child(import_dock);
  4276. dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(import_dock->get_index(), TTR("Import"));
  4277. // FileSystem: Bottom left
  4278. dock_slot[DOCK_SLOT_LEFT_BR]->add_child(filesystem_dock);
  4279. dock_slot[DOCK_SLOT_LEFT_BR]->set_tab_title(filesystem_dock->get_index(), TTR("FileSystem"));
  4280. // Inspector: Full height right
  4281. dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(inspector_dock);
  4282. dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(inspector_dock->get_index(), TTR("Inspector"));
  4283. // Node: Full height right, behind Inspector
  4284. dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(node_dock);
  4285. dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(node_dock->get_index(), TTR("Node"));
  4286. // Hide unused dock slots and vsplits
  4287. dock_slot[DOCK_SLOT_LEFT_UL]->hide();
  4288. dock_slot[DOCK_SLOT_LEFT_BL]->hide();
  4289. dock_slot[DOCK_SLOT_RIGHT_BL]->hide();
  4290. dock_slot[DOCK_SLOT_RIGHT_UR]->hide();
  4291. dock_slot[DOCK_SLOT_RIGHT_BR]->hide();
  4292. left_l_vsplit->hide();
  4293. right_r_vsplit->hide();
  4294. // Add some offsets to left_r and main hsplits to make LEFT_R and RIGHT_L docks wider than minsize
  4295. left_r_hsplit->set_split_offset(70 * EDSCALE);
  4296. main_hsplit->set_split_offset(-70 * EDSCALE);
  4297. // Define corresponding default layout
  4298. const String docks_section = "docks";
  4299. overridden_default_layout = -1;
  4300. default_layout.instance();
  4301. // Dock numbers are based on DockSlot enum value + 1
  4302. default_layout->set_value(docks_section, "dock_3", "Scene,Import");
  4303. default_layout->set_value(docks_section, "dock_4", "FileSystem");
  4304. default_layout->set_value(docks_section, "dock_5", "Inspector,Node");
  4305. for (int i = 0; i < vsplits.size(); i++)
  4306. default_layout->set_value(docks_section, "dock_split_" + itos(i + 1), 0);
  4307. default_layout->set_value(docks_section, "dock_hsplit_1", 0);
  4308. default_layout->set_value(docks_section, "dock_hsplit_2", 70 * EDSCALE);
  4309. default_layout->set_value(docks_section, "dock_hsplit_3", -70 * EDSCALE);
  4310. default_layout->set_value(docks_section, "dock_hsplit_4", 0);
  4311. _update_layouts_menu();
  4312. // Bottom panels
  4313. bottom_panel = memnew(PanelContainer);
  4314. bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
  4315. center_split->add_child(bottom_panel);
  4316. center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
  4317. bottom_panel_vb = memnew(VBoxContainer);
  4318. bottom_panel->add_child(bottom_panel_vb);
  4319. bottom_panel_hb = memnew(HBoxContainer);
  4320. bottom_panel_hb->set_custom_minimum_size(Size2(0, 24)); // Adjust for the height of the "Expand Bottom Dock" icon.
  4321. bottom_panel_vb->add_child(bottom_panel_hb);
  4322. bottom_panel_hb_editors = memnew(HBoxContainer);
  4323. bottom_panel_hb_editors->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  4324. bottom_panel_hb->add_child(bottom_panel_hb_editors);
  4325. bottom_panel_raise = memnew(ToolButton);
  4326. bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons"));
  4327. bottom_panel_raise->set_shortcut(ED_SHORTCUT("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KEY_MASK_SHIFT | KEY_F12));
  4328. bottom_panel_hb->add_child(bottom_panel_raise);
  4329. bottom_panel_raise->hide();
  4330. bottom_panel_raise->set_toggle_mode(true);
  4331. bottom_panel_raise->connect("toggled", this, "_bottom_panel_raise_toggled");
  4332. log = memnew(EditorLog);
  4333. ToolButton *output_button = add_bottom_panel_item(TTR("Output"), log);
  4334. log->set_tool_button(output_button);
  4335. old_split_ofs = 0;
  4336. center_split->connect("resized", this, "_vp_resized");
  4337. orphan_resources = memnew(OrphanResourcesDialog);
  4338. gui_base->add_child(orphan_resources);
  4339. confirmation = memnew(ConfirmationDialog);
  4340. gui_base->add_child(confirmation);
  4341. confirmation->connect("confirmed", this, "_menu_confirm_current");
  4342. save_confirmation = memnew(ConfirmationDialog);
  4343. save_confirmation->add_button(TTR("Don't Save"), OS::get_singleton()->get_swap_ok_cancel(), "discard");
  4344. gui_base->add_child(save_confirmation);
  4345. save_confirmation->connect("confirmed", this, "_menu_confirm_current");
  4346. save_confirmation->connect("custom_action", this, "_discard_changes");
  4347. file_templates = memnew(EditorFileDialog);
  4348. file_templates->set_title(TTR("Import Templates From ZIP File"));
  4349. gui_base->add_child(file_templates);
  4350. file_templates->set_mode(EditorFileDialog::MODE_OPEN_FILE);
  4351. file_templates->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
  4352. file_templates->clear_filters();
  4353. file_templates->add_filter("*.tpz ; Template Package");
  4354. file = memnew(EditorFileDialog);
  4355. gui_base->add_child(file);
  4356. file->set_current_dir("res://");
  4357. file_export = memnew(EditorFileDialog);
  4358. file_export->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
  4359. gui_base->add_child(file_export);
  4360. file_export->set_title(TTR("Export Project"));
  4361. file_export->connect("file_selected", this, "_dialog_action");
  4362. file_export_lib = memnew(EditorFileDialog);
  4363. file_export_lib->set_title(TTR("Export Library"));
  4364. file_export_lib->set_mode(EditorFileDialog::MODE_SAVE_FILE);
  4365. file_export_lib->connect("file_selected", this, "_dialog_action");
  4366. file_export_lib_merge = memnew(CheckButton);
  4367. file_export_lib_merge->set_text(TTR("Merge With Existing"));
  4368. file_export_lib_merge->set_pressed(true);
  4369. file_export_lib->get_vbox()->add_child(file_export_lib_merge);
  4370. gui_base->add_child(file_export_lib);
  4371. file_export_password = memnew(LineEdit);
  4372. file_export_password->set_secret(true);
  4373. file_export_password->set_editable(false);
  4374. file_export->get_vbox()->add_margin_child(TTR("Password:"), file_export_password);
  4375. file_script = memnew(EditorFileDialog);
  4376. file_script->set_title(TTR("Open & Run a Script"));
  4377. file_script->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
  4378. file_script->set_mode(EditorFileDialog::MODE_OPEN_FILE);
  4379. List<String> sexts;
  4380. ResourceLoader::get_recognized_extensions_for_type("Script", &sexts);
  4381. for (List<String>::Element *E = sexts.front(); E; E = E->next()) {
  4382. file_script->add_filter("*." + E->get());
  4383. }
  4384. gui_base->add_child(file_script);
  4385. file_script->connect("file_selected", this, "_dialog_action");
  4386. file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
  4387. settings_menu->get_popup()->connect("id_pressed", this, "_menu_option");
  4388. file->connect("file_selected", this, "_dialog_action");
  4389. file_templates->connect("file_selected", this, "_dialog_action");
  4390. preview_gen = memnew(AudioStreamPreviewGenerator);
  4391. add_child(preview_gen);
  4392. //plugin stuff
  4393. file_server = memnew(EditorFileServer);
  4394. add_editor_plugin(memnew(AnimationPlayerEditorPlugin(this)));
  4395. add_editor_plugin(memnew(CanvasItemEditorPlugin(this)));
  4396. add_editor_plugin(memnew(SpatialEditorPlugin(this)));
  4397. add_editor_plugin(memnew(ScriptEditorPlugin(this)));
  4398. EditorAudioBuses *audio_bus_editor = EditorAudioBuses::register_editor();
  4399. ScriptTextEditor::register_editor(); //register one for text scripts
  4400. TextEditor::register_editor();
  4401. if (StreamPeerSSL::is_available()) {
  4402. add_editor_plugin(memnew(AssetLibraryEditorPlugin(this)));
  4403. } else {
  4404. WARN_PRINT("Asset Library not available, as it requires SSL to work.");
  4405. }
  4406. //add interface before adding plugins
  4407. editor_interface = memnew(EditorInterface);
  4408. add_child(editor_interface);
  4409. //more visually meaningful to have this later
  4410. raise_bottom_panel_item(AnimationPlayerEditor::singleton);
  4411. add_editor_plugin(memnew(ShaderEditorPlugin(this)));
  4412. add_editor_plugin(memnew(VisualShaderEditorPlugin(this)));
  4413. add_editor_plugin(memnew(CameraEditorPlugin(this)));
  4414. add_editor_plugin(memnew(ThemeEditorPlugin(this)));
  4415. add_editor_plugin(memnew(MultiMeshEditorPlugin(this)));
  4416. add_editor_plugin(memnew(MeshInstanceEditorPlugin(this)));
  4417. add_editor_plugin(memnew(AnimationTreeEditorPlugin(this)));
  4418. add_editor_plugin(memnew(AnimationTreePlayerEditorPlugin(this)));
  4419. add_editor_plugin(memnew(MeshLibraryEditorPlugin(this)));
  4420. add_editor_plugin(memnew(StyleBoxEditorPlugin(this)));
  4421. add_editor_plugin(memnew(SpriteEditorPlugin(this)));
  4422. add_editor_plugin(memnew(Skeleton2DEditorPlugin(this)));
  4423. add_editor_plugin(memnew(ParticlesEditorPlugin(this)));
  4424. add_editor_plugin(memnew(CPUParticlesEditorPlugin(this)));
  4425. add_editor_plugin(memnew(ResourcePreloaderEditorPlugin(this)));
  4426. add_editor_plugin(memnew(ItemListEditorPlugin(this)));
  4427. add_editor_plugin(memnew(Polygon3DEditorPlugin(this)));
  4428. add_editor_plugin(memnew(CollisionPolygon2DEditorPlugin(this)));
  4429. add_editor_plugin(memnew(TileSetEditorPlugin(this)));
  4430. add_editor_plugin(memnew(TileMapEditorPlugin(this)));
  4431. add_editor_plugin(memnew(SpriteFramesEditorPlugin(this)));
  4432. add_editor_plugin(memnew(TextureRegionEditorPlugin(this)));
  4433. add_editor_plugin(memnew(Particles2DEditorPlugin(this)));
  4434. add_editor_plugin(memnew(GIProbeEditorPlugin(this)));
  4435. add_editor_plugin(memnew(BakedLightmapEditorPlugin(this)));
  4436. add_editor_plugin(memnew(Path2DEditorPlugin(this)));
  4437. add_editor_plugin(memnew(PathEditorPlugin(this)));
  4438. add_editor_plugin(memnew(Line2DEditorPlugin(this)));
  4439. add_editor_plugin(memnew(Polygon2DEditorPlugin(this)));
  4440. add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this)));
  4441. add_editor_plugin(memnew(NavigationPolygonEditorPlugin(this)));
  4442. add_editor_plugin(memnew(GradientEditorPlugin(this)));
  4443. add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this)));
  4444. add_editor_plugin(memnew(CurveEditorPlugin(this)));
  4445. add_editor_plugin(memnew(TextureEditorPlugin(this)));
  4446. add_editor_plugin(memnew(AudioStreamEditorPlugin(this)));
  4447. add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
  4448. add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
  4449. add_editor_plugin(memnew(SkeletonEditorPlugin(this)));
  4450. add_editor_plugin(memnew(SkeletonIKEditorPlugin(this)));
  4451. add_editor_plugin(memnew(PhysicalBonePlugin(this)));
  4452. for (int i = 0; i < EditorPlugins::get_plugin_count(); i++)
  4453. add_editor_plugin(EditorPlugins::create(i, this));
  4454. for (int i = 0; i < plugin_init_callback_count; i++) {
  4455. plugin_init_callbacks[i]();
  4456. }
  4457. resource_preview->add_preview_generator(Ref<EditorTexturePreviewPlugin>(memnew(EditorTexturePreviewPlugin)));
  4458. resource_preview->add_preview_generator(Ref<EditorPackedScenePreviewPlugin>(memnew(EditorPackedScenePreviewPlugin)));
  4459. resource_preview->add_preview_generator(Ref<EditorMaterialPreviewPlugin>(memnew(EditorMaterialPreviewPlugin)));
  4460. resource_preview->add_preview_generator(Ref<EditorScriptPreviewPlugin>(memnew(EditorScriptPreviewPlugin)));
  4461. resource_preview->add_preview_generator(Ref<EditorAudioStreamPreviewPlugin>(memnew(EditorAudioStreamPreviewPlugin)));
  4462. resource_preview->add_preview_generator(Ref<EditorMeshPreviewPlugin>(memnew(EditorMeshPreviewPlugin)));
  4463. resource_preview->add_preview_generator(Ref<EditorBitmapPreviewPlugin>(memnew(EditorBitmapPreviewPlugin)));
  4464. resource_preview->add_preview_generator(Ref<EditorFontPreviewPlugin>(memnew(EditorFontPreviewPlugin)));
  4465. {
  4466. Ref<SpatialMaterialConversionPlugin> spatial_mat_convert;
  4467. spatial_mat_convert.instance();
  4468. resource_conversion_plugins.push_back(spatial_mat_convert);
  4469. Ref<CanvasItemMaterialConversionPlugin> canvas_item_mat_convert;
  4470. canvas_item_mat_convert.instance();
  4471. resource_conversion_plugins.push_back(canvas_item_mat_convert);
  4472. Ref<ParticlesMaterialConversionPlugin> particles_mat_convert;
  4473. particles_mat_convert.instance();
  4474. resource_conversion_plugins.push_back(particles_mat_convert);
  4475. }
  4476. circle_step_msec = OS::get_singleton()->get_ticks_msec();
  4477. circle_step_frame = Engine::get_singleton()->get_frames_drawn();
  4478. circle_step = 0;
  4479. editor_plugin_screen = NULL;
  4480. editor_plugins_over = memnew(EditorPluginList);
  4481. editor_plugins_force_over = memnew(EditorPluginList);
  4482. editor_plugins_force_input_forwarding = memnew(EditorPluginList);
  4483. Ref<EditorExportTextSceneToBinaryPlugin> export_text_to_binary_plugin;
  4484. export_text_to_binary_plugin.instance();
  4485. EditorExport::get_singleton()->add_export_plugin(export_text_to_binary_plugin);
  4486. _edit_current();
  4487. current = NULL;
  4488. reference_resource_mem = true;
  4489. save_external_resources_mem = true;
  4490. set_process(true);
  4491. open_imported = memnew(ConfirmationDialog);
  4492. open_imported->get_ok()->set_text(TTR("Open Anyway"));
  4493. new_inherited_button = open_imported->add_button(TTR("New Inherited"), !OS::get_singleton()->get_swap_ok_cancel(), "inherit");
  4494. open_imported->connect("confirmed", this, "_open_imported");
  4495. open_imported->connect("custom_action", this, "_inherit_imported");
  4496. gui_base->add_child(open_imported);
  4497. saved_version = 1;
  4498. unsaved_cache = true;
  4499. _last_instanced_scene = NULL;
  4500. quick_open = memnew(EditorQuickOpen);
  4501. gui_base->add_child(quick_open);
  4502. quick_open->connect("quick_open", this, "_quick_opened");
  4503. quick_run = memnew(EditorQuickOpen);
  4504. gui_base->add_child(quick_run);
  4505. quick_run->connect("quick_open", this, "_quick_run");
  4506. _update_recent_scenes();
  4507. editor_data.restore_editor_global_states();
  4508. convert_old = false;
  4509. opening_prev = false;
  4510. set_process_unhandled_input(true);
  4511. _playing_edited = false;
  4512. load_errors = memnew(RichTextLabel);
  4513. load_error_dialog = memnew(AcceptDialog);
  4514. load_error_dialog->add_child(load_errors);
  4515. load_error_dialog->set_title(TTR("Load Errors"));
  4516. gui_base->add_child(load_error_dialog);
  4517. EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed");
  4518. EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed");
  4519. EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported");
  4520. _build_icon_type_cache();
  4521. Node::set_human_readable_collision_renaming(true);
  4522. pick_main_scene = memnew(ConfirmationDialog);
  4523. gui_base->add_child(pick_main_scene);
  4524. pick_main_scene->get_ok()->set_text(TTR("Select"));
  4525. pick_main_scene->connect("confirmed", this, "_menu_option", varray(SETTINGS_PICK_MAIN_SCENE));
  4526. for (int i = 0; i < _init_callbacks.size(); i++)
  4527. _init_callbacks[i]();
  4528. editor_data.add_edited_scene(-1);
  4529. editor_data.set_edited_scene(0);
  4530. _update_scene_tabs();
  4531. import_dock->initialize_import_options();
  4532. {
  4533. _initializing_addons = true;
  4534. Vector<String> addons;
  4535. if (ProjectSettings::get_singleton()->has_setting("editor_plugins/enabled")) {
  4536. addons = ProjectSettings::get_singleton()->get("editor_plugins/enabled");
  4537. }
  4538. for (int i = 0; i < addons.size(); i++) {
  4539. set_addon_plugin_enabled(addons[i], true);
  4540. }
  4541. _initializing_addons = false;
  4542. }
  4543. FileAccess::set_file_close_fail_notify_callback(_file_access_close_error_notify);
  4544. waiting_for_first_scan = true;
  4545. _dimming = false;
  4546. _dim_time = 0.0f;
  4547. _dim_timer = memnew(Timer);
  4548. _dim_timer->set_wait_time(0.01666f);
  4549. _dim_timer->connect("timeout", this, "_dim_timeout");
  4550. add_child(_dim_timer);
  4551. print_handler.printfunc = _print_handler;
  4552. print_handler.userdata = this;
  4553. add_print_handler(&print_handler);
  4554. #ifdef OSX_ENABLED
  4555. ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_ALT | KEY_1);
  4556. ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2);
  4557. ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_ALT | KEY_3);
  4558. ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_MASK_ALT | KEY_SPACE);
  4559. #else
  4560. ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_F1);
  4561. ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_F2);
  4562. ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F3); //hack needed for script editor F3 search to work :) Assign like this or don't use F3
  4563. ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F4);
  4564. #endif
  4565. ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"));
  4566. ED_SHORTCUT("editor/editor_next", TTR("Open the next Editor"));
  4567. ED_SHORTCUT("editor/editor_prev", TTR("Open the previous Editor"));
  4568. }
  4569. EditorNode::~EditorNode() {
  4570. EditorInspector::cleanup_plugins();
  4571. remove_print_handler(&print_handler);
  4572. memdelete(EditorHelp::get_doc_data());
  4573. memdelete(editor_selection);
  4574. memdelete(editor_plugins_over);
  4575. memdelete(editor_plugins_force_over);
  4576. memdelete(editor_plugins_force_input_forwarding);
  4577. memdelete(file_server);
  4578. memdelete(progress_hb);
  4579. EditorSettings::destroy();
  4580. }
  4581. /*
  4582. * EDITOR PLUGIN LIST
  4583. */
  4584. void EditorPluginList::make_visible(bool p_visible) {
  4585. for (int i = 0; i < plugins_list.size(); i++) {
  4586. plugins_list[i]->make_visible(p_visible);
  4587. }
  4588. }
  4589. void EditorPluginList::edit(Object *p_object) {
  4590. for (int i = 0; i < plugins_list.size(); i++) {
  4591. plugins_list[i]->edit(p_object);
  4592. }
  4593. }
  4594. bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) {
  4595. bool discard = false;
  4596. for (int i = 0; i < plugins_list.size(); i++) {
  4597. if (plugins_list[i]->forward_canvas_gui_input(p_event)) {
  4598. discard = true;
  4599. }
  4600. }
  4601. return discard;
  4602. }
  4603. bool EditorPluginList::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) {
  4604. bool discard = false;
  4605. for (int i = 0; i < plugins_list.size(); i++) {
  4606. if ((!serve_when_force_input_enabled) && plugins_list[i]->is_input_event_forwarding_always_enabled()) {
  4607. continue;
  4608. }
  4609. if (plugins_list[i]->forward_spatial_gui_input(p_camera, p_event)) {
  4610. discard = true;
  4611. }
  4612. }
  4613. return discard;
  4614. }
  4615. void EditorPluginList::forward_canvas_draw_over_viewport(Control *p_overlay) {
  4616. for (int i = 0; i < plugins_list.size(); i++) {
  4617. plugins_list[i]->forward_canvas_draw_over_viewport(p_overlay);
  4618. }
  4619. }
  4620. void EditorPluginList::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
  4621. for (int i = 0; i < plugins_list.size(); i++) {
  4622. plugins_list[i]->forward_canvas_force_draw_over_viewport(p_overlay);
  4623. }
  4624. }
  4625. void EditorPluginList::forward_spatial_draw_over_viewport(Control *p_overlay) {
  4626. for (int i = 0; i < plugins_list.size(); i++) {
  4627. plugins_list[i]->forward_spatial_draw_over_viewport(p_overlay);
  4628. }
  4629. }
  4630. void EditorPluginList::forward_spatial_force_draw_over_viewport(Control *p_overlay) {
  4631. for (int i = 0; i < plugins_list.size(); i++) {
  4632. plugins_list[i]->forward_spatial_force_draw_over_viewport(p_overlay);
  4633. }
  4634. }
  4635. void EditorPluginList::add_plugin(EditorPlugin *p_plugin) {
  4636. plugins_list.push_back(p_plugin);
  4637. }
  4638. bool EditorPluginList::empty() {
  4639. return plugins_list.empty();
  4640. }
  4641. void EditorPluginList::clear() {
  4642. plugins_list.clear();
  4643. }
  4644. EditorPluginList::EditorPluginList() {
  4645. }
  4646. EditorPluginList::~EditorPluginList() {
  4647. }