SExtContentBrowser.cpp 154 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604
  1. // Copyright 2017-2021 marynate. All Rights Reserved.
  2. #include "SExtContentBrowser.h"
  3. #include "ExtContentBrowser.h"
  4. #include "ExtContentBrowserSingleton.h"
  5. #include "SExtAssetView.h"
  6. #include "SExtPathView.h"
  7. #include "SExtFilterList.h"
  8. #include "SExtDependencyViewer.h"
  9. #include "AssetContextMenu.h"
  10. #include "PathContextMenu.h"
  11. #include "ExtContentBrowserCommands.h"
  12. #include "ExtContentBrowserUtils.h"
  13. #include "DesktopPlatformModule.h"
  14. #include "IDesktopPlatform.h"
  15. #include "Widgets/Input/SDirectoryPicker.h"
  16. #include "Factories/Factory.h"
  17. #include "Framework/Commands/UIAction.h"
  18. #include "Textures/SlateIcon.h"
  19. #include "Framework/Commands/UICommandList.h"
  20. #include "Misc/ConfigCacheIni.h"
  21. #include "Misc/FeedbackContext.h"
  22. #include "Misc/ScopedSlowTask.h"
  23. #include "Widgets/SBoxPanel.h"
  24. #include "Layout/WidgetPath.h"
  25. #include "SlateOptMacros.h"
  26. #include "Framework/Application/SlateApplication.h"
  27. #include "Widgets/Layout/SBorder.h"
  28. #include "Widgets/Layout/SSeparator.h"
  29. #include "Widgets/Layout/SWrapBox.h"
  30. #include "Widgets/Images/SImage.h"
  31. #include "Widgets/Text/STextBlock.h"
  32. #include "Widgets/Input/SEditableTextBox.h"
  33. #include "Widgets/Layout/SBox.h"
  34. #include "Framework/MultiBox/MultiBoxBuilder.h"
  35. #include "Widgets/Input/SButton.h"
  36. #include "Widgets/Input/SComboButton.h"
  37. #include "Widgets/Layout/SSplitter.h"
  38. #include "Framework/Docking/TabManager.h"
  39. #include "EditorStyleSet.h"
  40. #include "EditorFontGlyphs.h"
  41. #include "Settings/ContentBrowserSettings.h"
  42. #include "Settings/EditorSettings.h"
  43. #include "Editor.h"
  44. #include "FileHelpers.h"
  45. #include "AssetRegistry/AssetRegistryModule.h"
  46. #include "AssetToolsModule.h"
  47. #include "Widgets/Navigation/SBreadcrumbTrail.h"
  48. #include "Widgets/Docking/SDockTab.h"
  49. #include "Widgets/Colors/SColorPicker.h"
  50. #include "Widgets/Colors/SColorBlock.h"
  51. #include "Widgets/Input/SSpinBox.h"
  52. #include "Framework/Commands/GenericCommands.h"
  53. #include "Engine/Selection.h"
  54. #include "Toolkits/GlobalEditorCommonCommands.h"
  55. #include "SAssetSearchBox.h"
  56. #include "ExtFrontendFilters.h"
  57. //#include "SCollectionView.h"
  58. //#include "AddToProjectConfig.h"
  59. //#include "GameProjectGenerationModule.h"
  60. #include "Widgets/Input/SFilePathPicker.h"
  61. #include "ExtDocumentation.h"
  62. #define LOCTEXT_NAMESPACE "ExtContentBrowser"
  63. /////////////////////////////////////////////////////////////
  64. // SExtContentBrowser implementation
  65. //
  66. const FString SExtContentBrowser::SettingsIniSection = TEXT("UAssetBrowser");
  67. TSharedRef<SWidget> SExtContentBrowser::CreateChangeLogWidget()
  68. {
  69. FString AboutLinkRoot(TEXT("Shared/About"));
  70. FDocumentationStyle DocumentationStyle = FExtContentBrowserStyle::GetChangLogDocumentationStyle();
  71. const IDocumentationProvider* Provider = FDocumentationProvider::Get().GetProvider(FName(*DocumentationHostPluginName));
  72. if (Provider == nullptr)
  73. {
  74. return SNullWidget::NullWidget;
  75. }
  76. AboutPage = Provider->GetDocumentation()->GetPage(AboutLinkRoot, /*TSharedPtr<FParserConfiguration>()*/NULL, DocumentationStyle);
  77. if (!AboutPage.IsValid())
  78. {
  79. return SNullWidget::NullWidget;
  80. }
  81. FExcerpt ChangeLogExcerpt;
  82. AboutPage->GetExcerpt(TEXT("ChangeLog"), ChangeLogExcerpt);
  83. AboutPage->GetExcerptContent(ChangeLogExcerpt);
  84. TSharedRef<SWidget> ChangeLogContentWidget = ChangeLogExcerpt.Content.IsValid() ? ChangeLogExcerpt.Content.ToSharedRef() : SNew(SSpacer);
  85. return SNew(SBorder)
  86. .BorderBackgroundColor(FLinearColor(0.5f, 0.5f, 0.5f))
  87. .BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
  88. .Padding(6.f)
  89. .Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateLambda([this] { return bShowChangelog ? EVisibility::Visible : EVisibility::Collapsed; })))
  90. [
  91. SNew(SVerticalBox)
  92. // Header
  93. + SVerticalBox::Slot().AutoHeight().Padding(0, 4, 0, 8).HAlign(HAlign_Center)
  94. [
  95. SNew(STextBlock)
  96. .TextStyle(FExtContentBrowserStyle::Get(), "UAssetBrowser.ChangeLogHeaderText")
  97. .Text(LOCTEXT("UAssetBrowserChangeLog", "UAsset Browser Change Log"))
  98. ]
  99. // Change Log
  100. + SVerticalBox::Slot().Padding(0, 2, 0, 2).FillHeight(1.0f).HAlign(HAlign_Center)
  101. [
  102. SNew(SBorder)
  103. .BorderBackgroundColor(FLinearColor(0.3f, 0.3f, 0.3f))
  104. .BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
  105. .Padding(1.f)
  106. [
  107. SNew(SScrollBox)
  108. + SScrollBox::Slot().Padding(5, 5)
  109. [
  110. ChangeLogContentWidget
  111. ]
  112. ]
  113. ]
  114. // Close Button
  115. + SVerticalBox::Slot().AutoHeight().Padding(0, 8, 0, 4).HAlign(HAlign_Center)
  116. [
  117. SNew(SButton)
  118. //.ButtonStyle(FMeshToolStyle::GetButtonStyleByTheme())
  119. //.TextStyle(FMeshToolStyle::GetButtonTextStyleByTheme(FMeshToolStyle::EMeshToolTextSize::Normal))
  120. .Text(LOCTEXT("Close", "Close"))
  121. .HAlign(HAlign_Center)
  122. .OnClicked(FOnClicked::CreateLambda([this] { this->bShowChangelog = false; return FReply::Handled(); }))
  123. ]
  124. ];
  125. }
  126. SExtContentBrowser::~SExtContentBrowser()
  127. {
  128. // Remove the listener for when view settings are changed
  129. UExtContentBrowserSettings::OnSettingChanged().RemoveAll( this );
  130. #if ECB_WIP_CACHEDB
  131. if (GetDefault<UExtContentBrowserSettings>()->bCacheMode && GetDefault<UExtContentBrowserSettings>()->bAutoSaveCacheOnExit)
  132. {
  133. FExtContentBrowserSingleton::GetAssetRegistry().SaveCacheDB(/*bSilent =*/ false);
  134. }
  135. #endif
  136. // // Remove listeners for when collections/paths are renamed/deleted
  137. // if (FCollectionManagerModule::IsModuleAvailable())
  138. // {
  139. // FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
  140. //
  141. // CollectionManagerModule.Get().OnCollectionRenamed().RemoveAll(this);
  142. // CollectionManagerModule.Get().OnCollectionDestroyed().RemoveAll(this);
  143. // }
  144. //
  145. // FAssetRegistryModule* AssetRegistryModule = FModuleManager::GetModulePtr<FAssetRegistryModule>(TEXT("AssetRegistry"));
  146. // if (AssetRegistryModule != nullptr)
  147. // {
  148. // AssetRegistryModule->Get().OnPathRemoved().RemoveAll(this);
  149. // }
  150. }
  151. BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
  152. void SExtContentBrowser::Construct(const FArguments& InArgs, const FName& InInstanceName)
  153. {
  154. const UExtContentBrowserSettings* ExtContentBrowserSettings = GetDefault<UExtContentBrowserSettings>();
  155. if (InArgs._ContainingTab.IsValid())
  156. {
  157. // For content browsers that are placed in tabs, save settings when the tab is closing.
  158. ContainingTab = InArgs._ContainingTab;
  159. InArgs._ContainingTab->SetOnPersistVisualState(SDockTab::FOnPersistVisualState::CreateSP(this, &SExtContentBrowser::OnContainingTabSavingVisualState));
  160. InArgs._ContainingTab->SetOnTabClosed(SDockTab::FOnTabClosedCallback::CreateSP(this, &SExtContentBrowser::OnContainingTabClosed));
  161. InArgs._ContainingTab->SetOnTabActivated(SDockTab::FOnTabActivatedCallback::CreateSP(this, &SExtContentBrowser::OnContainingTabActivated));
  162. }
  163. bIsLocked = InArgs._InitiallyLocked;
  164. bAlwaysShowCollections = false;
  165. bCanSetAsPrimaryBrowser = true;
  166. #if ECB_WIP_HISTORY
  167. HistoryManager.SetOnApplyHistoryData(FOnApplyHistoryData::CreateSP(this, &SExtContentBrowser::OnApplyHistoryData));
  168. HistoryManager.SetOnUpdateHistoryData(FOnUpdateHistoryData::CreateSP(this, &SExtContentBrowser::OnUpdateHistoryData));
  169. #endif
  170. PathContextMenu = MakeShareable(new FPathContextMenu(AsShared()));
  171. #if ECB_LEGACY
  172. PathContextMenu->SetOnImportAssetRequested(FNewAssetOrClassContextMenu::FOnImportAssetRequested::CreateSP(this, &SExtContentBrowser::ImportAsset));
  173. PathContextMenu->SetOnRenameFolderRequested(FPathContextMenu::FOnRenameFolderRequested::CreateSP(this, &SExtContentBrowser::OnRenameFolderRequested));
  174. PathContextMenu->SetOnFolderDeleted(FPathContextMenu::FOnFolderDeleted::CreateSP(this, &SExtContentBrowser::OnOpenedFolderDeleted));
  175. PathContextMenu->SetOnFolderFavoriteToggled(FPathContextMenu::FOnFolderFavoriteToggled::CreateSP(this, &SExtContentBrowser::ToggleFolderFavorite));
  176. #endif
  177. FrontendFilters = MakeShareable(new FExtAssetFilterCollectionType());
  178. #if ECB_FEA_SEARCH
  179. TextFilter = MakeShareable(new FFrontendFilter_Text());
  180. #endif
  181. static const FName DefaultForegroundName("DefaultForeground");
  182. BindCommands();
  183. TSharedRef<SOverlay> MainOverlay = SNew(SOverlay);
  184. ChildSlot
  185. [
  186. SNew(SBorder)
  187. .Padding(FMargin(1))
  188. .BorderImage(FAppStyle::GetBrush("WhiteBrush"))
  189. .BorderBackgroundColor(this, &SExtContentBrowser::GetContentBrowserBorderBackgroundColor)
  190. [
  191. MainOverlay
  192. ]
  193. ];
  194. const float WrapButtonGroupsSize = 60.f;
  195. const float ButtonBoxPadding = 3.f;
  196. const float ButtonPadding = 4.f;
  197. const float ButtonAutoHidePadding = 130.f;
  198. MainOverlay->AddSlot()
  199. [
  200. SNew(SBorder)
  201. .Padding(FMargin(0))
  202. .BorderImage(FAppStyle::GetBrush("WhiteBrush"))
  203. //.BorderBackgroundColor(this, & SExtContentBrowser::GetContentBrowserBorderBackgroundColor)
  204. .BorderBackgroundColor(FExtContentBrowserStyle::CustomContentBrowserBorderBackgroundColor)
  205. [
  206. SNew(SVerticalBox)
  207. // Top Bar (Buttons and History) >>
  208. #if ECB_FOLD
  209. + SVerticalBox::Slot()
  210. .AutoHeight()
  211. .Padding(0, 0, 0, 0)
  212. [
  213. SNew(SHorizontalBox)
  214. + SHorizontalBox::Slot()
  215. .FillWidth(1.0f)
  216. [
  217. SNew(SBorder)
  218. .Padding(FMargin(3))
  219. .BorderImage(FAppStyle::GetBrush("WhiteBrush"))
  220. .BorderBackgroundColor(this, &SExtContentBrowser::GetToolbarBackgroundColor)
  221. [
  222. SNew(SHorizontalBox)
  223. // Button Group (Add/Remote Root Folder)
  224. + SHorizontalBox::Slot()
  225. .AutoWidth()
  226. [
  227. SNew(SHorizontalBox)
  228. // Add Root Folder Button >>
  229. #if ECB_FOLD
  230. + SHorizontalBox::Slot()
  231. .AutoWidth()
  232. .VAlign(VAlign_Center)
  233. .HAlign(HAlign_Left)
  234. .Padding(ButtonBoxPadding, 0)
  235. [
  236. SNew(SButton)
  237. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  238. .ContentPadding(FMargin(ButtonPadding, 1))
  239. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 300.f)
  240. .ToolTipText(LOCTEXT("AddContentFolderTooltip", "Add a root content folder to path view"))
  241. .OnClicked(this, &SExtContentBrowser::HandleAddContentFolderClicked)
  242. [
  243. SNew(SHorizontalBox)
  244. // Add Icon
  245. + SHorizontalBox::Slot()
  246. .VAlign(VAlign_Center)
  247. .AutoWidth()
  248. [
  249. SNew(STextBlock)
  250. .TextStyle(FExtContentBrowserStyle::Get(), "UAssetBrowser.TopBar.Font")
  251. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  252. .Text(FEditorFontGlyphs::Plus_Circle)
  253. ]
  254. // Add Text
  255. + SHorizontalBox::Slot().AutoWidth().VAlign(VAlign_Center).Padding(4, 0, 0, 0)
  256. [
  257. SNew(STextBlock)
  258. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 349.f + ButtonAutoHidePadding)
  259. .TextStyle(FExtContentBrowserStyle::Get(), "UAssetBrowser.TopBar.Font")
  260. .Text(LOCTEXT("Add", "Add"))
  261. ]
  262. ]
  263. ]
  264. #endif // Add Root Folder Button <<
  265. // Remove Root Folder Button >>
  266. #if ECB_FOLD
  267. + SHorizontalBox::Slot()
  268. .AutoWidth()
  269. .VAlign(VAlign_Center)
  270. .HAlign(HAlign_Left)
  271. .Padding(ButtonBoxPadding, 0)
  272. [
  273. SNew(SButton)
  274. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 230.f + ButtonAutoHidePadding)
  275. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  276. .ContentPadding(FMargin(ButtonPadding, 1))
  277. .ToolTipText(LOCTEXT("RemoveContentFolderTooltip", "Remove selected root content folder from path view"))
  278. .OnClicked(this, &SExtContentBrowser::HandleRemoveContentFoldersClicked)
  279. .IsEnabled(this, &SExtContentBrowser::CanRemoveContentFolders)
  280. [
  281. SNew(SHorizontalBox)
  282. // Remove Icon
  283. + SHorizontalBox::Slot()
  284. .VAlign(VAlign_Center)
  285. .AutoWidth()
  286. [
  287. SNew(STextBlock)
  288. .TextStyle(FExtContentBrowserStyle::Get(), "UAssetBrowser.TopBar.Font")
  289. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  290. .Text(FEditorFontGlyphs::Minus_Circle)
  291. ]
  292. // Remove Text
  293. + SHorizontalBox::Slot()
  294. .AutoWidth()
  295. .VAlign(VAlign_Center)
  296. .Padding(4, 0, 0, 0)
  297. [
  298. SNew(STextBlock)
  299. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 405.f + ButtonAutoHidePadding)
  300. .TextStyle(FExtContentBrowserStyle::Get(), "UAssetBrowser.TopBar.Font")
  301. .Text(LOCTEXT("Remove", "Remove"))
  302. ]
  303. ]
  304. ]
  305. #endif // Remove Root Folder Button <<
  306. ] // SWrapBox::Slot()
  307. // Button Group Save CacheDB >>
  308. #if ECB_FOLD
  309. + SHorizontalBox::Slot()
  310. .AutoWidth()
  311. [
  312. SNew(SHorizontalBox)
  313. #if ECB_WIP_CACHEDB
  314. // Save and Switch
  315. + SHorizontalBox::Slot()
  316. .AutoWidth()
  317. .VAlign(VAlign_Center)
  318. .HAlign(HAlign_Left)
  319. .Padding(ButtonBoxPadding, 0)
  320. [
  321. SNew(SButton)
  322. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 247.f)
  323. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  324. .ToolTipText(LOCTEXT("SaveCacheUAssetTooltip", "Save Cache and Switch to Cache Mode"))
  325. .IsEnabled(true)
  326. .OnClicked(this, &SExtContentBrowser::HandleSaveAndSwitchToCacheModeClicked)
  327. .ContentPadding(FMargin(ButtonPadding, 1))
  328. [
  329. SNew(SHorizontalBox)
  330. // Icon
  331. + SHorizontalBox::Slot()
  332. .VAlign(VAlign_Center)
  333. .AutoWidth()
  334. [
  335. SNew(STextBlock)
  336. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  337. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.10"))
  338. .Text(FEditorFontGlyphs::Database)
  339. ]
  340. // Text
  341. + SHorizontalBox::Slot()
  342. .AutoWidth()
  343. .VAlign(VAlign_Center)
  344. .Padding(4, 0, 0, 0)
  345. [
  346. SNew(STextBlock)
  347. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 276.f + ButtonAutoHidePadding)
  348. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  349. //.Text(GetSaveAndSwitchToCacheModeText())
  350. .Text_Lambda([this, ExtContentBrowserSettings]()
  351. {
  352. return GetSaveAndSwitchToCacheModeText();
  353. })
  354. ]
  355. ]
  356. ]
  357. #endif
  358. ]
  359. #endif
  360. // Button Group Load/Save CacheDB <<
  361. // Button Group Validate Asset Button >>
  362. #if ECB_FOLD
  363. + SHorizontalBox::Slot()
  364. .AutoWidth()
  365. [
  366. SNew(SHorizontalBox)
  367. #if ECB_FEA_VALIDATE
  368. + SHorizontalBox::Slot()
  369. .AutoWidth()
  370. .VAlign(VAlign_Center)
  371. .HAlign(HAlign_Left)
  372. .Padding(ButtonBoxPadding, 0)
  373. [
  374. SNew(SButton)
  375. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 200.f)
  376. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  377. .ToolTipText(LOCTEXT("ValidateUAssetTooltip", "Validate selected uasset files before import"))
  378. .IsEnabled(this, &SExtContentBrowser::IsValidateEnabled)
  379. .OnClicked(this, &SExtContentBrowser::HandleValidateclicked)
  380. .ContentPadding(FMargin(ButtonPadding, 1))
  381. [
  382. SNew(SHorizontalBox)
  383. // Validate Icon
  384. + SHorizontalBox::Slot()
  385. .VAlign(VAlign_Center)
  386. .AutoWidth()
  387. [
  388. SNew(STextBlock)
  389. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  390. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  391. .Text(FEditorFontGlyphs::Check)
  392. ]
  393. // Validate Text
  394. + SHorizontalBox::Slot()
  395. .AutoWidth()
  396. .VAlign(VAlign_Center)
  397. .Padding(4, 0, 0, 0)
  398. [
  399. SNew(STextBlock)
  400. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 340.f + ButtonAutoHidePadding)
  401. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  402. .Text(LOCTEXT("Validate", "Validate"))
  403. ]
  404. ]
  405. ]
  406. #endif
  407. ]
  408. #endif
  409. // Button Group Validate Asset Button <<
  410. // Button Group Export Button >>
  411. #if ECB_WIP
  412. + SHorizontalBox::Slot()
  413. .AutoWidth()
  414. [
  415. SNew(SHorizontalBox)
  416. // Export >>
  417. #if ECB_WIP_EXPORT
  418. + SHorizontalBox::Slot()
  419. .AutoWidth()
  420. .VAlign(VAlign_Center)
  421. .HAlign(HAlign_Left)
  422. [
  423. SNew(SButton)
  424. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  425. .ToolTipText(LOCTEXT("ExportTooltip", "Export uasset with dependencies"))
  426. .IsEnabled(this, &SExtContentBrowser::IsExportAssetEnabled)
  427. .OnClicked(this, &SExtContentBrowser::HandleExportAssetClicked)
  428. .ContentPadding(FMargin(1, 2))
  429. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserExport")))
  430. [
  431. SNew(SHorizontalBox)
  432. // Export Icon
  433. + SHorizontalBox::Slot()
  434. .VAlign(VAlign_Center)
  435. .AutoWidth()
  436. [
  437. SNew(STextBlock)
  438. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  439. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  440. .Text(FEditorFontGlyphs::Archive)
  441. ]
  442. // Export Text
  443. + SHorizontalBox::Slot()
  444. .AutoWidth()
  445. .VAlign(VAlign_Center)
  446. .Padding(4, 0, 0, 0)
  447. [
  448. SNew(STextBlock)
  449. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  450. .Text(LOCTEXT("Export", "Export"))
  451. ]
  452. ]
  453. ]
  454. #endif // Export <<
  455. // Zip >>
  456. #if ECB_WIP_EXPORT_ZIP
  457. + SHorizontalBox::Slot()
  458. .AutoWidth()
  459. .VAlign(VAlign_Center)
  460. .HAlign(HAlign_Left)
  461. [
  462. SNew(SButton)
  463. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  464. .ToolTipText(LOCTEXT("ZipExportTooltip", "Zip uasset with dependencies"))
  465. .IsEnabled(this, &SExtContentBrowser::IsExportAssetEnabled)
  466. .OnClicked(this, &SExtContentBrowser::HandleZipExportClicked)
  467. .ContentPadding(FMargin(1, 2))
  468. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserZipExport")))
  469. [
  470. SNew(SHorizontalBox)
  471. // Zip Icon
  472. + SHorizontalBox::Slot()
  473. .VAlign(VAlign_Center)
  474. .AutoWidth()
  475. [
  476. SNew(STextBlock)
  477. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  478. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  479. .Text(FEditorFontGlyphs::Archive)
  480. ]
  481. // Zip Text
  482. + SHorizontalBox::Slot()
  483. .AutoWidth()
  484. .VAlign(VAlign_Center)
  485. .Padding(4, 0, 0, 0)
  486. [
  487. SNew(STextBlock)
  488. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  489. .Text(LOCTEXT("ZipExport", "Zip"))
  490. ]
  491. ]
  492. ]
  493. #endif // Zip <<
  494. // Import to Sandbox Button >>
  495. #if ECB_WIP_IMPORT_SANDBOX
  496. + SHorizontalBox::Slot()
  497. .AutoWidth()
  498. .VAlign(VAlign_Center)
  499. .HAlign(HAlign_Left)
  500. [
  501. SNew(SButton)
  502. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  503. .IsEnabled(this, &SExtContentBrowser::IsImportEnabled)
  504. .OnClicked(this, &SExtContentBrowser::HandleImportToSandboxClicked)
  505. .ContentPadding(FMargin(1, 2))
  506. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserImportAsset")))
  507. [
  508. SNew(SHorizontalBox)
  509. // Import Icon
  510. + SHorizontalBox::Slot()
  511. .VAlign(VAlign_Center)
  512. .AutoWidth()
  513. [
  514. SNew(STextBlock)
  515. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  516. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  517. .Text(FEditorFontGlyphs::Download)
  518. ]
  519. // Import Text
  520. + SHorizontalBox::Slot()
  521. .AutoWidth()
  522. .VAlign(VAlign_Center)
  523. .Padding(4, 0, 0, 0)
  524. [
  525. SNew(STextBlock)
  526. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  527. .Text(LOCTEXT("Sandbox", "Sandbox"))
  528. ]
  529. ]
  530. ]
  531. #endif // Import to Sandbox Button <<
  532. ]
  533. #endif
  534. // Button Group Export Button <<
  535. // Button Group Import Button >>
  536. #if ECB_FOLD
  537. + SHorizontalBox::Slot()
  538. .AutoWidth()
  539. [
  540. SNew(SHorizontalBox)
  541. // Flat Import Button >>
  542. #if ECB_FEA_IMPORT_FLATMODE
  543. + SHorizontalBox::Slot()
  544. .AutoWidth()
  545. .VAlign(VAlign_Center)
  546. .HAlign(HAlign_Left)
  547. .Padding(ButtonBoxPadding, 0)
  548. [
  549. SNew(SButton)
  550. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 142.f)
  551. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  552. .ToolTipText(LOCTEXT("FlatImportTooltip", "Collect dependencies and import all into one selected folder"))
  553. .IsEnabled(this, &SExtContentBrowser::IsImportEnabled)
  554. .OnClicked(this, &SExtContentBrowser::HandleFlatImportClicked)
  555. .ContentPadding(FMargin(ButtonPadding, 1))
  556. //.AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserImportAsset")))
  557. [
  558. SNew(SHorizontalBox)
  559. // Import Icon
  560. + SHorizontalBox::Slot()
  561. .VAlign(VAlign_Center)
  562. .AutoWidth()
  563. [
  564. SNew(STextBlock)
  565. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  566. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  567. .Text(FEditorFontGlyphs::Long_Arrow_Down)
  568. ]
  569. // Import Text
  570. + SHorizontalBox::Slot()
  571. .AutoWidth()
  572. .VAlign(VAlign_Center)
  573. .Padding(4, 0, 0, 0)
  574. [
  575. SNew(STextBlock)
  576. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 468.f + ButtonAutoHidePadding)
  577. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  578. .Text(LOCTEXT("FlatImport", "Flat Import"))
  579. ]
  580. ]
  581. ]
  582. #endif // Flat Import Button <<
  583. ]
  584. + SHorizontalBox::Slot()
  585. .AutoWidth()
  586. [
  587. SNew(SHorizontalBox)
  588. // Import Asset Button >>
  589. #if ECB_FOLD
  590. + SHorizontalBox::Slot()
  591. .AutoWidth()
  592. .VAlign(VAlign_Center)
  593. .HAlign(HAlign_Left)
  594. .Padding(ButtonBoxPadding, 0)
  595. [
  596. SNew(SButton)
  597. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 100.f)
  598. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  599. .ToolTipText(this, &SExtContentBrowser::GetImportTooltipText)
  600. .IsEnabled(this, &SExtContentBrowser::IsImportEnabled)
  601. .OnClicked(this, &SExtContentBrowser::HandleImportClicked)
  602. .ContentPadding(FMargin(ButtonPadding, 1))
  603. //.AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserImportAsset")))
  604. [
  605. SNew(SHorizontalBox)
  606. // Import Icon
  607. + SHorizontalBox::Slot()
  608. .VAlign(VAlign_Center)
  609. .AutoWidth()
  610. [
  611. SNew(STextBlock)
  612. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  613. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  614. .Text(FEditorFontGlyphs::Download)
  615. ]
  616. // Import Text
  617. + SHorizontalBox::Slot()
  618. .AutoWidth()
  619. .VAlign(VAlign_Center)
  620. .Padding(4, 0, 0, 0)
  621. [
  622. SNew(STextBlock)
  623. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 550.f + ButtonAutoHidePadding)
  624. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  625. .Text(LOCTEXT("Import", "Import"))
  626. ]
  627. ]
  628. ]
  629. #endif // Import Asset Button <<
  630. ]
  631. #endif
  632. // Button Group Import Button <<
  633. // History - BreadcrumbTrail - Import - Lock >>
  634. #if ECB_TODO
  635. + SWrapBox::Slot()
  636. .FillEmptySpace(true)
  637. [
  638. SNew(SHorizontalBox)
  639. // History Back Button >>
  640. #if ECB_WIP_HISTORY
  641. + SHorizontalBox::Slot()
  642. .AutoWidth()
  643. [
  644. SNew(SVerticalBox)
  645. + SVerticalBox::Slot()
  646. .FillHeight(1.0f)
  647. [
  648. SNew(SButton)
  649. .VAlign(EVerticalAlignment::VAlign_Center)
  650. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  651. .ForegroundColor(FAppStyle::GetSlateColor(DefaultForegroundName))
  652. .ToolTipText(this, &SExtContentBrowser::GetHistoryBackTooltip)
  653. .ContentPadding(FMargin(1, 0))
  654. .OnClicked(this, &SExtContentBrowser::BackClicked)
  655. .IsEnabled(this, &SExtContentBrowser::IsBackEnabled)
  656. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserHistoryBack")))
  657. [
  658. SNew(STextBlock)
  659. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  660. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  661. .Text(FText::FromString(FString(TEXT("\xf060"))) /*fa-arrow-left*/)
  662. ]
  663. ]
  664. ]
  665. #endif // History Back Button <<
  666. // History Forward Button >>
  667. #if ECB_WIP_HISTORY
  668. + SHorizontalBox::Slot()
  669. .AutoWidth()
  670. [
  671. SNew(SVerticalBox)
  672. + SVerticalBox::Slot()
  673. .FillHeight(1.0f)
  674. [
  675. SNew(SButton)
  676. .VAlign(EVerticalAlignment::VAlign_Center)
  677. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  678. .ForegroundColor(FAppStyle::GetSlateColor(DefaultForegroundName))
  679. .ToolTipText(this, &SExtContentBrowser::GetHistoryForwardTooltip)
  680. .ContentPadding(FMargin(1, 0))
  681. .OnClicked(this, &SExtContentBrowser::ForwardClicked)
  682. .IsEnabled(this, &SExtContentBrowser::IsForwardEnabled)
  683. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserHistoryForward")))
  684. [
  685. SNew(STextBlock)
  686. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  687. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  688. .Text(FText::FromString(FString(TEXT("\xf061"))) /*fa-arrow-right*/)
  689. ]
  690. ]
  691. ]
  692. #endif // History Forward Button <<
  693. // Separator >>
  694. #if ECB_FOLD
  695. + SHorizontalBox::Slot()
  696. .AutoWidth()
  697. .Padding(3, 0)
  698. [
  699. SNew(SSeparator)
  700. .Orientation(Orient_Vertical)
  701. ]
  702. #endif // Separator <<
  703. // Path picker >>
  704. #if ECB_WIP_PATHPICKER
  705. + SHorizontalBox::Slot()
  706. .AutoWidth()
  707. .VAlign(VAlign_Fill)
  708. [
  709. SAssignNew(PathPickerButton, SComboButton)
  710. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  711. .ForegroundColor(FLinearColor::White)
  712. .ToolTipText(LOCTEXT("PathPickerTooltip", "Choose a path"))
  713. .OnGetMenuContent(this, &SExtContentBrowser::GetPathPickerContent)
  714. .HasDownArrow(false)
  715. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserPathPicker")))
  716. .ContentPadding(FMargin(3, 3))
  717. .ButtonContent()
  718. [
  719. SNew(STextBlock)
  720. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  721. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  722. .Text(FText::FromString(FString(TEXT("\xf07c"))) /*fa-folder-open*/)
  723. ]
  724. ]
  725. #endif // Patch picker <<
  726. // BreadcrumbTrail >>
  727. #if ECB_WIP_BREADCRUMB
  728. + SHorizontalBox::Slot()
  729. .VAlign(VAlign_Center)
  730. .HAlign(HAlign_Left)
  731. .FillWidth(1.0f)
  732. .Padding(FMargin(0))
  733. [
  734. SAssignNew(PathBreadcrumbTrail, SBreadcrumbTrail<FString>)
  735. .ButtonContentPadding(FMargin(2, 2))
  736. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  737. .DelimiterImage(FAppStyle::GetBrush("ContentBrowser.PathDelimiter"))
  738. .TextStyle(FAppStyle::Get(), "ContentBrowser.PathText")
  739. .ShowLeadingDelimiter(false)
  740. .InvertTextColorOnHover(false)
  741. .OnCrumbClicked(this, &SExtContentBrowser::OnPathClicked)
  742. .GetCrumbMenuContent(this, &SExtContentBrowser::OnGetCrumbDelimiterContent)
  743. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserPath")))
  744. ]
  745. #endif // BreadcrumbTrail <<
  746. // Import Asset Button >>
  747. #if ECB_FOLD
  748. + SHorizontalBox::Slot()
  749. .AutoWidth()
  750. .VAlign(VAlign_Center)
  751. .HAlign(HAlign_Left)
  752. .Padding(6, 0)
  753. [
  754. SNew(SButton)
  755. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  756. .ToolTipText(this, &SExtContentBrowser::GetImportTooltipText)
  757. .IsEnabled(this, &SExtContentBrowser::IsImportEnabled)
  758. .OnClicked(this, &SExtContentBrowser::HandleImportClicked)
  759. .ContentPadding(FMargin(6, 2))
  760. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserImportAsset")))
  761. [
  762. SNew(SHorizontalBox)
  763. // Import Icon
  764. + SHorizontalBox::Slot()
  765. .VAlign(VAlign_Center)
  766. .AutoWidth()
  767. [
  768. SNew(STextBlock)
  769. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  770. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  771. .Text(FEditorFontGlyphs::Download)
  772. ]
  773. // Import Text
  774. + SHorizontalBox::Slot()
  775. .AutoWidth()
  776. .VAlign(VAlign_Center)
  777. .Padding(4, 0, 0, 0)
  778. [
  779. SNew(STextBlock)
  780. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  781. .Text(LOCTEXT("Import", "Import"))
  782. ]
  783. ]
  784. ]
  785. #endif // Import Asset Button <<
  786. // Lock button >>
  787. #if ECB_WIP_LOCK
  788. + SHorizontalBox::Slot()
  789. .AutoWidth()
  790. .VAlign(VAlign_Center)
  791. [
  792. SNew(SVerticalBox)
  793. .Visibility(EVisibility::SelfHitTestInvisible)
  794. + SVerticalBox::Slot()
  795. .FillHeight(1.0f)
  796. [
  797. SNew(SButton)
  798. .VAlign(EVerticalAlignment::VAlign_Center)
  799. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  800. .ToolTipText(LOCTEXT("LockToggleTooltip", "Toggle lock. If locked, this browser will ignore Find in Content Browser requests."))
  801. .ContentPadding(FMargin(1, 0))
  802. .OnClicked(this, &SExtContentBrowser::ToggleLockClicked)
  803. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserLock")))
  804. [
  805. SNew(SImage)
  806. .Image(this, &SExtContentBrowser::GetToggleLockImage)
  807. ]
  808. ]
  809. ]
  810. #endif // Lock button <<
  811. ]
  812. ]
  813. #endif // History - BreadcrumbTrail - Import - Lock <<
  814. ]
  815. ]
  816. // Import Asset Options >>
  817. #if ECB_FEA_IMPORT_OPTIONS
  818. + SHorizontalBox::Slot().AutoWidth()
  819. [
  820. SAssignNew(ImportOptionsComboButton, SComboButton)
  821. .ContentPadding(1)
  822. .ForegroundColor(this, &SExtContentBrowser::GetImportOptionsButtonForegroundColor)
  823. .ButtonStyle(FAppStyle::Get(), "ToggleButton")
  824. .OnGetMenuContent(this, &SExtContentBrowser::GetImportOptionsButtonContent)
  825. .ButtonContent()
  826. [
  827. SNew(SHorizontalBox)
  828. #if ECB_FOLD
  829. + SHorizontalBox::Slot()
  830. .AutoWidth()
  831. .VAlign(VAlign_Center)
  832. [
  833. //SNew(SImage).Image(FAppStyle::GetBrush("LevelEditor.GameSettings.Small"))
  834. SNew(STextBlock)
  835. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  836. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.11"))
  837. .Text(FEditorFontGlyphs::Info)
  838. ]
  839. #endif
  840. + SHorizontalBox::Slot()
  841. .AutoWidth()
  842. .Padding(3, 0, 0, 0)
  843. .VAlign(VAlign_Center)
  844. [
  845. //SNew(STextBlock).Text(LOCTEXT("ImportButton", "Import Options"))
  846. SNew(STextBlock)
  847. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  848. .Text(LOCTEXT(" ", " "))
  849. ]
  850. ]
  851. ]
  852. #endif // Import Asset Options <<
  853. ]
  854. #endif // Top Bar (Buttons and History) <<
  855. // Paths and Assets View >>
  856. #if ECB_FOLD
  857. + SVerticalBox::Slot()
  858. .FillHeight(1.0f)
  859. .Padding(0,2,0,0)
  860. [
  861. // The tree/assets splitter
  862. SAssignNew(PathAssetSplitterPtr, SSplitter)
  863. // Sources View >>
  864. #if ECB_FOLD
  865. + SSplitter::Slot()
  866. .Value(0.25f)
  867. [
  868. SNew(SBorder)
  869. .Padding(FMargin(0))
  870. .BorderImage(FAppStyle::GetBrush("WhiteBrush"))
  871. .BorderBackgroundColor(this, &SExtContentBrowser::GetSourceViewBackgroundColor)
  872. .Visibility(this, &SExtContentBrowser::GetSourcesViewVisibility)
  873. [
  874. SAssignNew(PathFavoriteSplitterPtr, SSplitter)
  875. .Orientation(EOrientation::Orient_Vertical)
  876. .MinimumSlotHeight(70.0f)
  877. .Visibility( this, &SExtContentBrowser::GetSourcesViewVisibility )
  878. // Favorite View >>
  879. #if ECB_FOLD
  880. + SSplitter::Slot()
  881. .Value(.2f)
  882. [
  883. SNew(SBorder)
  884. .Visibility(this, &SExtContentBrowser::GetFavoriteFolderVisibility)
  885. .Padding(FMargin(3))
  886. .BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
  887. [
  888. #if ECB_WIP_FAVORITE
  889. SAssignNew(FavoritePathViewPtr, SFavoritePathView)
  890. .OnPathSelected(this, &SExtContentBrowser::FavoritePathSelected)
  891. .OnGetFolderContextMenu(this, &SExtContentBrowser::GetFolderContextMenu, /*bPathView*/true)
  892. .OnGetPathContextMenuExtender(this, &SExtContentBrowser::GetPathContextMenuExtender)
  893. .FocusSearchBoxWhenOpened(false)
  894. .ShowTreeTitle(true)
  895. .ShowSeparator(false)
  896. .AllowClassesFolder(true)
  897. .SearchContent()
  898. [
  899. SNew(SVerticalBox)
  900. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserSourcesToggle1")))
  901. + SVerticalBox::Slot()
  902. .FillHeight(1.0f)
  903. .Padding(0, 0, 2, 0)
  904. [
  905. SNew(SButton)
  906. .VAlign(EVerticalAlignment::VAlign_Center)
  907. .ButtonStyle(FAppStyle::Get(), "ToggleButton")
  908. .ToolTipText(LOCTEXT("SourcesTreeToggleTooltip", "Show or hide the sources panel"))
  909. .ContentPadding(FMargin(1, 0))
  910. .ForegroundColor(FAppStyle::GetSlateColor(DefaultForegroundName))
  911. .OnClicked(this, &SExtContentBrowser::SourcesViewExpandClicked)
  912. [
  913. SNew(SImage)
  914. .Image(this, &SExtContentBrowser::GetSourcesToggleImage)
  915. ]
  916. ]
  917. ]
  918. #endif
  919. SNew(STextBlock)
  920. .Text(LOCTEXT("SFavoritePathView","SFavoritePathView"))
  921. ] // end of Favorite View Border
  922. ] // end of Favorite View Splitter
  923. #endif // Favorite View <<
  924. + SSplitter::Slot()
  925. .Value(0.8f)
  926. [
  927. SAssignNew(PathCollectionSplitterPtr, SSplitter)
  928. .Orientation( Orient_Vertical )
  929. // Path View
  930. #if ECB_FOLD
  931. + SSplitter::Slot()
  932. .Value(0.9f)
  933. [
  934. SNew(SBorder)
  935. .Padding(FMargin(3))
  936. .BorderImage(FAppStyle::GetBrush("NoBrush"))
  937. //.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
  938. //.BorderImage(FAppStyle::GetBrush("WhiteBrush"))
  939. //.BorderBackgroundColor(FLinearColor(1.0f, 0.f, 0.f, 1.f))
  940. [
  941. SAssignNew( PathViewPtr, SExtPathView )
  942. .OnPathSelected( this, &SExtContentBrowser::PathSelected )
  943. .OnGetFolderContextMenu( this, &SExtContentBrowser::GetFolderContextMenu, /*bPathView*/true )
  944. .OnGetPathContextMenuExtender( this, &SExtContentBrowser::GetPathContextMenuExtender )
  945. //.SearchBarVisibility(this, &SExtContentBrowser::GetAlternateSearchBarVisibility)
  946. .FocusSearchBoxWhenOpened(false)
  947. .ShowTreeTitle(false)
  948. .ShowSeparator(false)
  949. .AllowClassesFolder(true)
  950. .AllowContextMenu(true)
  951. .SearchContent()
  952. [
  953. SNew(SVerticalBox)
  954. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserSourcesToggle1")))
  955. //.Visibility(this, &SExtContentBrowser::GetAlternateSearchBarVisibility)
  956. + SVerticalBox::Slot().FillHeight(1.0f).Padding(0, 0, 2, 0)
  957. [
  958. SNew(SButton)
  959. .VAlign(EVerticalAlignment::VAlign_Center)
  960. .ContentPadding(FMargin(1, 0))
  961. .ForegroundColor(FAppStyle::GetSlateColor(DefaultForegroundName))
  962. .ButtonStyle(FAppStyle::Get(), "ToggleButton")
  963. .ToolTipText(LOCTEXT("SourcesTreeToggleTooltip", "Show or hide the sources panel"))
  964. .OnClicked(this, &SExtContentBrowser::SourcesViewExpandClicked)
  965. [
  966. SNew(SImage)
  967. .Image(this, &SExtContentBrowser::GetSourcesToggleImage)
  968. ]
  969. ]
  970. ] // end of SExtPathView
  971. ] // end of PathView Border
  972. ]
  973. #endif
  974. // Collection View
  975. #if ECB_FOLD
  976. + SSplitter::Slot()
  977. .Value(0.9f)
  978. [
  979. SNew(SBorder)
  980. .Visibility( this, &SExtContentBrowser::GetCollectionViewVisibility )
  981. .Padding(FMargin(3))
  982. .BorderImage( FAppStyle::GetBrush("ToolPanel.GroupBorder") )
  983. [
  984. SNew(STextBlock).Text(LOCTEXT("SCollectionView", "SCollectionView"))
  985. #if ECB_WIP_COLLECTION
  986. SAssignNew(CollectionViewPtr, SCollectionView)
  987. .OnCollectionSelected(this, &SExtContentBrowser::CollectionSelected)
  988. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserCollections")))
  989. .AllowCollectionDrag(true)
  990. .AllowQuickAssetManagement(true)
  991. #endif
  992. ] // end of CollectionView Border
  993. ] // end of CollectionView Splitter
  994. #endif
  995. ]
  996. ] // endo fo source view sborder
  997. ] // end of Source View
  998. #endif // Sources View <<
  999. // Asset and Dependency View >>
  1000. #if ECB_FOLD
  1001. + SSplitter::Slot()
  1002. .Value(0.75f)
  1003. [
  1004. // The assets/dependency splitter
  1005. SAssignNew(AssetReferenceSplitterPtr, SSplitter)
  1006. .Orientation(Orient_Horizontal)
  1007. // Asset View >>
  1008. #if ECB_FOLD
  1009. + SSplitter::Slot()
  1010. .Value(0.5f)
  1011. [
  1012. SNew(SBorder)
  1013. //.Padding(FMargin(3))
  1014. //.BorderImage( FAppStyle::GetBrush("ToolPanel.GroupBorder") )
  1015. .Padding(FMargin(0))
  1016. .BorderImage(FAppStyle::GetBrush("WhiteBrush"))
  1017. .BorderBackgroundColor(this, &SExtContentBrowser::GetAssetViewBackgroundColor)
  1018. [
  1019. SNew(SVerticalBox)
  1020. // Expand Tree - Filter - Search - Save Search - Expand RefViewer >>
  1021. #if ECB_FOLD
  1022. + SVerticalBox::Slot().AutoHeight().Padding(0, 0, 0, 2)
  1023. [
  1024. SNew(SHorizontalBox)
  1025. // Expand Tree >>
  1026. #if ECB_FOLD
  1027. + SHorizontalBox::Slot().AutoWidth().Padding( 0, 0, 4, 0 )
  1028. [
  1029. SNew( SVerticalBox )
  1030. .Visibility(EVisibility::SelfHitTestInvisible)
  1031. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserSourcesToggle2")))
  1032. + SVerticalBox::Slot().FillHeight( 1.0f )
  1033. [
  1034. SNew( SButton ).VAlign( EVerticalAlignment::VAlign_Center ).ButtonStyle( FAppStyle::Get(), "ToggleButton" ).ContentPadding(FMargin(1, 0))
  1035. .ToolTipText( LOCTEXT( "SourcesTreeToggleTooltip", "Show or hide the sources panel" ) )
  1036. .ForegroundColor( FAppStyle::GetSlateColor(DefaultForegroundName) )
  1037. .OnClicked( this, &SExtContentBrowser::SourcesViewExpandClicked )
  1038. .Visibility( this, &SExtContentBrowser::GetPathExpanderVisibility )
  1039. [
  1040. SNew( SImage ).Image( this, &SExtContentBrowser::GetSourcesToggleImage )
  1041. ]
  1042. ]
  1043. ]
  1044. #endif // Expand Tree <<
  1045. // Filter >>
  1046. #if ECB_FOLD
  1047. + SHorizontalBox::Slot()
  1048. .AutoWidth()
  1049. [
  1050. SNew( SComboButton )
  1051. .ComboButtonStyle( FAppStyle::Get(), "GenericFilters.ComboButtonStyle" )
  1052. .ForegroundColor(FLinearColor::White)
  1053. .ContentPadding(0)
  1054. .ToolTipText( LOCTEXT( "AddFilterToolTip", "Add an asset filter." ) )
  1055. .OnGetMenuContent( this, &SExtContentBrowser::MakeAddFilterMenu )
  1056. .HasDownArrow( true )
  1057. .ContentPadding( FMargin( 1, 0 ) )
  1058. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserFiltersCombo")))
  1059. #if ECB_FEA_FILTER
  1060. .Visibility(EVisibility::Visible)
  1061. #else
  1062. .Visibility(EVisibility::Collapsed)
  1063. #endif
  1064. .ButtonContent()
  1065. [
  1066. SNew(SHorizontalBox)
  1067. + SHorizontalBox::Slot()
  1068. .AutoWidth()
  1069. [
  1070. SNew(STextBlock)
  1071. .TextStyle(FAppStyle::Get(), "GenericFilters.TextStyle")
  1072. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.9"))
  1073. .Text(FText::FromString(FString(TEXT("\xf0b0"))) /*fa-filter*/)
  1074. ]
  1075. + SHorizontalBox::Slot()
  1076. .AutoWidth()
  1077. .Padding(2,0,0,0)
  1078. [
  1079. SNew(STextBlock)
  1080. .TextStyle(FAppStyle::Get(), "GenericFilters.TextStyle")
  1081. .Text(LOCTEXT("Filters", "Filters"))
  1082. ]
  1083. ]
  1084. ]
  1085. #endif // Filter <<
  1086. // Search >>
  1087. #if ECB_FEA_SEARCH
  1088. +SHorizontalBox::Slot()
  1089. .Padding(4, 1, 0, 0)
  1090. .FillWidth(1.0f)
  1091. [
  1092. SAssignNew(SearchBoxPtr, SAssetSearchBox)
  1093. .HintText( this, &SExtContentBrowser::GetSearchAssetsHintText )
  1094. .OnTextChanged( this, &SExtContentBrowser::OnSearchBoxChanged )
  1095. .OnTextCommitted( this, &SExtContentBrowser::OnSearchBoxCommitted )
  1096. //.PossibleSuggestions( this, &SExtContentBrowser::GetAssetSearchSuggestions )
  1097. .OnAssetSearchBoxSuggestionFilter(this, &SExtContentBrowser::OnAssetSearchSuggestionFilter)
  1098. .OnAssetSearchBoxSuggestionChosen(this, &SExtContentBrowser::OnAssetSearchSuggestionChosen)
  1099. .DelayChangeNotificationsWhileTyping( true )
  1100. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserSearchAssets")))
  1101. ]
  1102. #endif // Search <<
  1103. // Save Search >>
  1104. #if ECB_TODO
  1105. +SHorizontalBox::Slot()
  1106. .AutoWidth()
  1107. .VAlign(VAlign_Center)
  1108. .Padding(2.0f, 0.0f, 0.0f, 0.0f)
  1109. [
  1110. SNew(SButton)
  1111. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  1112. .ToolTipText(LOCTEXT("SaveSearchButtonTooltip", "Save the current search as a dynamic collection."))
  1113. .IsEnabled(this, &SExtContentBrowser::IsSaveSearchButtonEnabled)
  1114. .OnClicked(this, &SExtContentBrowser::OnSaveSearchButtonClicked)
  1115. .ContentPadding( FMargin(1, 1) )
  1116. [
  1117. SNew(STextBlock)
  1118. .TextStyle(FAppStyle::Get(), "GenericFilters.TextStyle")
  1119. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.10"))
  1120. .Text(FEditorFontGlyphs::Floppy_O)
  1121. ]
  1122. ]
  1123. #endif // Save Search <<
  1124. // Expand RefViewer >>
  1125. #if ECB_FEA_REF_VIEWER
  1126. + SHorizontalBox::Slot().AutoWidth().Padding(4, 0, 4, 0)
  1127. [
  1128. SNew(SVerticalBox)
  1129. .Visibility(EVisibility::SelfHitTestInvisible)
  1130. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserRefViewerToggle")))
  1131. + SVerticalBox::Slot().FillHeight(1.0f)
  1132. [
  1133. SNew(SButton).VAlign(EVerticalAlignment::VAlign_Center).ButtonStyle(FAppStyle::Get(), "ToggleButton").ContentPadding(FMargin(1, 0))
  1134. .ToolTipText(LOCTEXT("RefViewerToggleTooltip", "Show or hide the dependencies viewer"))
  1135. .ForegroundColor(FAppStyle::GetSlateColor(DefaultForegroundName))
  1136. .OnClicked(this, &SExtContentBrowser::ReferenceViewerExpandClicked)
  1137. //.Visibility(this, &SExtContentBrowser::GetPathExpanderVisibility)
  1138. [
  1139. SNew(SImage).Image(this, &SExtContentBrowser::GetDependencyViewerToggleImage)
  1140. ]
  1141. ]
  1142. ]
  1143. #endif // Expand RefViewer <<
  1144. ]
  1145. #endif // Expand Tree - Filter - Search - Save Search - Expand RefViewer <<
  1146. // FilterList >>
  1147. #if ECB_FOLD
  1148. + SVerticalBox::Slot()
  1149. .AutoHeight()
  1150. [
  1151. SAssignNew(FilterListPtr, SExtFilterList)
  1152. .OnFilterChanged(this, &SExtContentBrowser::OnFilterChanged)
  1153. .OnGetContextMenu(this, &SExtContentBrowser::GetFilterContextMenu)
  1154. #if ECB_FEA_FILTER
  1155. .Visibility(EVisibility::Visible)
  1156. #else
  1157. .Visibility(EVisibility::Collapsed)
  1158. #endif
  1159. .FrontendFilters(FrontendFilters)
  1160. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserFilters")))
  1161. ]
  1162. #endif // FilterList <<
  1163. // Asset Tile View >>
  1164. #if ECB_FOLD
  1165. + SVerticalBox::Slot()
  1166. .FillHeight( 1.0f )
  1167. .Padding( 0 )
  1168. [
  1169. SAssignNew(AssetViewPtr, SExtAssetView)
  1170. .ThumbnailLabel(EThumbnailLabel::ClassName)
  1171. .ThumbnailScale(0.18f)
  1172. .InitialViewType(EAssetViewType::Tile)
  1173. .ShowBottomToolbar(true)
  1174. .OnPathSelected(this, &SExtContentBrowser::FolderEntered)
  1175. .OnAssetSelected(this, &SExtContentBrowser::OnAssetSelectionChanged)
  1176. #if ECB_LEGACY
  1177. .OnAssetsActivated(this, &SExtContentBrowser::OnAssetsActivated)
  1178. #endif
  1179. .OnGetAssetContextMenu(this, &SExtContentBrowser::OnGetAssetContextMenu)
  1180. #if ECB_TODO
  1181. .OnGetFolderContextMenu(this, &SExtContentBrowser::GetFolderContextMenu, /*bPathView*/false)
  1182. .OnGetPathContextMenuExtender(this, &SExtContentBrowser::GetPathContextMenuExtender)
  1183. #endif
  1184. #if ECB_WIP_SYNC_ASSET
  1185. .OnFindInAssetTreeRequested(this, &SExtContentBrowser::OnFindInAssetTreeRequested)
  1186. #endif
  1187. .FrontendFilters(FrontendFilters)
  1188. .HighlightedText(this, &SExtContentBrowser::GetHighlightedText)
  1189. .AllowThumbnailHintLabel(false)
  1190. .CanShowFolders(true)
  1191. .CanShowCollections(true)
  1192. .CanShowFavorites(true)
  1193. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtContentBrowserAssets")))
  1194. .OnRequestShowChangeLog(this, &SExtContentBrowser::HandleRequestShowChangeLog)
  1195. #if ECB_FEA_SEARCH
  1196. .OnSearchOptionsChanged(this, &SExtContentBrowser::HandleAssetViewSearchOptionsChanged)
  1197. #endif
  1198. ]
  1199. #endif // Asset Tile View <<
  1200. ]
  1201. ]
  1202. #endif // Asset View <<
  1203. // Reference Viewer >>
  1204. #if ECB_FEA_REF_VIEWER
  1205. + SSplitter::Slot()
  1206. .Value(0.5f)
  1207. [
  1208. SAssignNew(ReferenceViewerPtr, SExtDependencyViewer)
  1209. .Visibility(this, &SExtContentBrowser::GetReferencesViewerVisibility)
  1210. .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ExtDependencyViewer")))
  1211. ]
  1212. #endif // Reference Viewer <<
  1213. ]
  1214. #endif // Asset and Dependency View <<
  1215. ]
  1216. #endif // Paths and Assets View <<
  1217. // Bottom Bar (Cache Status) >>
  1218. #if ECB_WIP_CACHEDB
  1219. + SVerticalBox::Slot()
  1220. .AutoHeight()
  1221. .Padding(0, 0, 0, 0)
  1222. [
  1223. SNew(SBorder)
  1224. .Padding(FMargin(1))
  1225. .BorderImage(FAppStyle::GetBrush("WhiteBrush"))
  1226. .BorderBackgroundColor(FLinearColor(.03f, 0.03f, 0.03f, 1.f))
  1227. .Visibility(this, &SExtContentBrowser::GetCacheStatusBarVisibility)
  1228. [
  1229. SNew(SHorizontalBox)
  1230. // Asset count
  1231. + SHorizontalBox::Slot().FillWidth(1.f).HAlign(HAlign_Right).VAlign(VAlign_Center).Padding(8, 2)
  1232. [
  1233. SNew(SHorizontalBox)
  1234. + SHorizontalBox::Slot().AutoWidth().VAlign(VAlign_Center).Padding(0, 0)
  1235. [
  1236. SNew(STextBlock).Text(this, &SExtContentBrowser::GetCacheStatusText)
  1237. ]
  1238. #if ECB_WIP_CACHEDB_SWITCH
  1239. // Switch DB
  1240. + SHorizontalBox::Slot().AutoWidth().VAlign(VAlign_Center).Padding(0, 0)
  1241. [
  1242. SNew(SFilePathPicker)
  1243. .BrowseButtonImage(FAppStyle::GetBrush("PropertyWindow.Button_Ellipsis"))
  1244. .BrowseButtonStyle(FAppStyle::Get(), "HoverHintOnly")
  1245. .BrowseButtonToolTip(LOCTEXT("CacheDBPathBrowseButtonToolTip", "Choose a file from this computer"))
  1246. .BrowseDirectory_Lambda([this, ExtContentBrowserSettings]() -> FString
  1247. {
  1248. return FPaths::GetPath(ExtContentBrowserSettings->CacheFilePath.FilePath);
  1249. })
  1250. .FilePath_Lambda([this, ExtContentBrowserSettings]() -> FString
  1251. {
  1252. return ExtContentBrowserSettings->CacheFilePath.FilePath;
  1253. })
  1254. .FileTypeFilter_Lambda([]() -> FString
  1255. {
  1256. return TEXT("All files (*.*)|*.*|Cache Database files (*.cachedb)|*.cachedb");
  1257. })
  1258. .OnPathPicked(this, &SExtContentBrowser::HandleSwitchAndLoadCacheDBClicked)
  1259. .ToolTipText(LOCTEXT("CacheDBPathToolTip", "The file use as cache dababase to store parsed uasset meta data."))
  1260. ]
  1261. #if 0 // Move to Import Options Menu
  1262. // Purge DB
  1263. + SHorizontalBox::Slot().AutoWidth().VAlign(VAlign_Bottom).Padding(2, 0)
  1264. [
  1265. SNew(SButton)
  1266. .Visibility(this, &SExtContentBrowser::GetVisibilityByLastFrameWidth, 132.f)
  1267. .ButtonStyle(FAppStyle::Get(), "FlatButton")
  1268. .ToolTipText(LOCTEXT("PurgeCacheDBTooltip", "Purge unused assets data in the cache db."))
  1269. .IsEnabled(true)
  1270. .OnClicked(this, &SExtContentBrowser::HandlePurgeCacheDBClicked)
  1271. .ContentPadding(FMargin(1, 1))
  1272. [
  1273. SNew(SHorizontalBox)
  1274. // Icon
  1275. + SHorizontalBox::Slot()
  1276. .VAlign(VAlign_Bottom)
  1277. .AutoWidth()
  1278. [
  1279. SNew(STextBlock)
  1280. .TextStyle(FAppStyle::Get(), "ContentBrowser.TopBar.Font")
  1281. .Font(FAppStyle::Get().GetFontStyle("FontAwesome.9"))
  1282. .Text(FEditorFontGlyphs::Trash)
  1283. ]
  1284. ]
  1285. ]
  1286. #endif
  1287. #endif
  1288. ]
  1289. ]
  1290. ]
  1291. #endif
  1292. ]];
  1293. WidthLastFrame = 1000.f; // width enough to show all buttons
  1294. bShowChangelog = false;
  1295. MainOverlay->AddSlot()[CreateChangeLogWidget()];
  1296. UpdateAssetReferenceSplitterOrientation();
  1297. AssetContextMenu = MakeShareable(new FAssetContextMenu(AssetViewPtr));
  1298. #if ECB_LEGACY
  1299. AssetContextMenu->BindCommands(Commands);
  1300. AssetContextMenu->SetOnFindInAssetTreeRequested( FOnFindInAssetTreeRequested::CreateSP(this, &SExtContentBrowser::OnFindInAssetTreeRequested) );
  1301. AssetContextMenu->SetOnRenameRequested( FAssetContextMenu::FOnRenameRequested::CreateSP(this, &SExtContentBrowser::OnRenameRequested) );
  1302. AssetContextMenu->SetOnRenameFolderRequested( FAssetContextMenu::FOnRenameFolderRequested::CreateSP(this, &SExtContentBrowser::OnRenameFolderRequested) );
  1303. AssetContextMenu->SetOnAssetViewRefreshRequested( FAssetContextMenu::FOnAssetViewRefreshRequested::CreateSP( this, &SExtContentBrowser::OnAssetViewRefreshRequested) );
  1304. FavoritePathViewPtr->SetTreeTitle(LOCTEXT("Favorites", "Favorites"));
  1305. if( Config != nullptr && Config->SelectedCollectionName.Name != NAME_None )
  1306. {
  1307. // Select the specified collection by default
  1308. FSourcesData DefaultSourcesData( Config->SelectedCollectionName );
  1309. TArray<FString> SelectedPaths;
  1310. AssetViewPtr->SetSourcesData( DefaultSourcesData );
  1311. }
  1312. else
  1313. {
  1314. // Select /Game by default
  1315. FSourcesData DefaultSourcesData(FName("/Game"));
  1316. TArray<FString> SelectedPaths;
  1317. TArray<FString> SelectedFavoritePaths;
  1318. SelectedPaths.Add(TEXT("/Game"));
  1319. PathViewPtr->SetSelectedPaths(SelectedPaths);
  1320. AssetViewPtr->SetSourcesData(DefaultSourcesData);
  1321. FavoritePathViewPtr->SetSelectedPaths(SelectedFavoritePaths);
  1322. }
  1323. #endif
  1324. #if ECB_WIP_FAVORITE
  1325. //Bind the path view filtering to the favorite path view search bar
  1326. FavoritePathViewPtr->OnFavoriteSearchChanged.BindSP(PathViewPtr.Get(), &SExtPathView::OnAssetTreeSearchBoxChanged);
  1327. FavoritePathViewPtr->OnFavoriteSearchCommitted.BindSP(PathViewPtr.Get(), &SExtPathView::OnAssetTreeSearchBoxCommitted);
  1328. // Bind the favorites menu to update after folder changes in the path or asset view
  1329. PathViewPtr->OnFolderPathChanged.BindSP(FavoritePathViewPtr.Get(), &SFavoritePathView::FixupFavoritesFromExternalChange);
  1330. AssetViewPtr->OnFolderPathChanged.BindSP(FavoritePathViewPtr.Get(), &SFavoritePathView::FixupFavoritesFromExternalChange);
  1331. #endif
  1332. #if ECB_WIP_HISTORY
  1333. // Set the initial history data
  1334. HistoryManager.AddHistoryData();
  1335. #endif
  1336. // Load settings if they were specified
  1337. this->InstanceName = InInstanceName;
  1338. LoadSettings(InInstanceName);
  1339. // Expand Source View?
  1340. {
  1341. // in case we do not have a config, see what the global default settings are for the Sources Panel
  1342. if (!bSourcesViewExpanded && ExtContentBrowserSettings->bOpenSourcesPanelByDefault)
  1343. {
  1344. SourcesViewExpandClicked();
  1345. }
  1346. }
  1347. #if ECB_WIP_COLLECTION
  1348. // Bindings to manage history when items are deleted
  1349. FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
  1350. CollectionManagerModule.Get().OnCollectionRenamed().AddSP(this, &SExtContentBrowser::HandleCollectionRenamed);
  1351. CollectionManagerModule.Get().OnCollectionDestroyed().AddSP(this, &SExtContentBrowser::HandleCollectionRemoved);
  1352. CollectionManagerModule.Get().OnCollectionUpdated().AddSP(this, &SExtContentBrowser::HandleCollectionUpdated);
  1353. #endif
  1354. // Listen for when view settings are changed
  1355. UExtContentBrowserSettings::OnSettingChanged().AddSP(this, &SExtContentBrowser::HandleSettingChanged);
  1356. #if ECB_WIP_BREADCRUMB
  1357. // Update the breadcrumb trail path
  1358. UpdatePath();
  1359. #endif
  1360. }
  1361. void SExtContentBrowser::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
  1362. {
  1363. if (WidthLastFrame != AllottedGeometry.Size.X)
  1364. {
  1365. WidthLastFrame = AllottedGeometry.Size.X;
  1366. ECB_LOG(Display, TEXT("[SExtContentBrowser]WidthLastFrame: %.2f"), WidthLastFrame);
  1367. }
  1368. }
  1369. END_SLATE_FUNCTION_BUILD_OPTIMIZATION
  1370. void SExtContentBrowser::BindCommands()
  1371. {
  1372. Commands = TSharedPtr< FUICommandList >(new FUICommandList);
  1373. #if ECB_LEGACY
  1374. Commands->MapAction(FGenericCommands::Get().Delete, FUIAction(
  1375. FExecuteAction::CreateSP(this, &SExtContentBrowser::HandleDeleteCommandExecute),
  1376. FCanExecuteAction::CreateSP(this, &SExtContentBrowser::HandleDeleteCommandCanExecute)
  1377. ));
  1378. Commands->MapAction(FContentBrowserCommands::Get().OpenAssetsOrFolders, FUIAction(
  1379. FExecuteAction::CreateSP(this, &SExtContentBrowser::HandleOpenAssetsOrFoldersCommandExecute)
  1380. ));
  1381. Commands->MapAction(FContentBrowserCommands::Get().DirectoryUp, FUIAction(
  1382. FExecuteAction::CreateSP(this, &SExtContentBrowser::HandleDirectoryUpCommandExecute)
  1383. ));
  1384. #endif
  1385. Commands->MapAction(FExtContentBrowserCommands::Get().ImportSelectedUAsset, FUIAction(
  1386. FExecuteAction::CreateSP(this, &SExtContentBrowser::HandleImportSelectedCommandExecute)));
  1387. Commands->MapAction(FExtContentBrowserCommands::Get().ToggleDependencyViewer, FUIAction(
  1388. FExecuteAction::CreateSP(this, &SExtContentBrowser::HandleToggleDependencyViewerCommandExecute)));
  1389. #if ECB_WIP_DELEGATES
  1390. // Allow extenders to add commands
  1391. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
  1392. TArray<FContentBrowserCommandExtender> CommmandExtenderDelegates = ContentBrowserModule.GetAllContentBrowserCommandExtenders();
  1393. for (int32 i = 0; i < CommmandExtenderDelegates.Num(); ++i)
  1394. {
  1395. if (CommmandExtenderDelegates[i].IsBound())
  1396. {
  1397. CommmandExtenderDelegates[i].Execute(Commands.ToSharedRef(), FOnContentBrowserGetSelection::CreateSP(this, &SExtContentBrowser::GetSelectionState));
  1398. }
  1399. }
  1400. #endif
  1401. }
  1402. EVisibility SExtContentBrowser::GetCollectionViewVisibility() const
  1403. {
  1404. return bAlwaysShowCollections ? EVisibility::Visible : ( GetDefault<UExtContentBrowserSettings>()->GetDisplayCollections() ? EVisibility::Visible : EVisibility::Collapsed );
  1405. }
  1406. EVisibility SExtContentBrowser::GetFavoriteFolderVisibility() const
  1407. {
  1408. return GetDefault<UExtContentBrowserSettings>()->GetDisplayFavorites() ? EVisibility::Visible : EVisibility::Collapsed;
  1409. }
  1410. #if ECB_DEBUG
  1411. FReply SExtContentBrowser::HandlePrintCacheClicked()
  1412. {
  1413. FExtContentBrowserSingleton::GetAssetRegistry().PrintCacheStatus();
  1414. return FReply::Handled();
  1415. }
  1416. FReply SExtContentBrowser::HandleClearCacheClicked()
  1417. {
  1418. FExtContentBrowserSingleton::GetAssetRegistry().ClearCache();
  1419. CollectGarbage(RF_NoFlags);
  1420. return FReply::Handled();
  1421. }
  1422. FReply SExtContentBrowser::HandlePrintAssetDataClicked()
  1423. {
  1424. const TArray<FExtAssetData>& SelectedAssets = AssetViewPtr->GetSelectedAssets();
  1425. for (const FExtAssetData& AssetData : SelectedAssets)
  1426. {
  1427. AssetData.PrintAssetData();
  1428. }
  1429. return FReply::Handled();
  1430. }
  1431. #endif
  1432. void SExtContentBrowser::ShowPluginVersionChangeLog()
  1433. {
  1434. }
  1435. void SExtContentBrowser::HandleSettingChanged(FName PropertyName)
  1436. {
  1437. if ((PropertyName == GET_MEMBER_NAME_CHECKED(UExtContentBrowserSettings, ShowDependencyViewerUnderAssetView)) ||
  1438. (PropertyName == NAME_None))
  1439. {
  1440. UpdateAssetReferenceSplitterOrientation();
  1441. }
  1442. }
  1443. void SExtContentBrowser::UpdateAssetReferenceSplitterOrientation()
  1444. {
  1445. bool bVertical = GetDefault<UExtContentBrowserSettings>()->ShowDependencyViewerUnderAssetView;
  1446. if (bVertical)
  1447. {
  1448. AssetReferenceSplitterPtr->SetOrientation(Orient_Vertical);
  1449. }
  1450. else
  1451. {
  1452. AssetReferenceSplitterPtr->SetOrientation(Orient_Horizontal);
  1453. }
  1454. }
  1455. FSlateColor SExtContentBrowser::GetContentBrowserBorderBackgroundColor() const
  1456. {
  1457. const UExtContentBrowserSettings* Settings = GetDefault<UExtContentBrowserSettings>();
  1458. #if ECB_WIP_CACHEDB
  1459. if (Settings->bCacheMode)
  1460. {
  1461. return Settings->CacheModeBorderColor;
  1462. }
  1463. else
  1464. #endif
  1465. {
  1466. return FExtContentBrowserStyle::CustomContentBrowserBorderBackgroundColor;
  1467. }
  1468. }
  1469. FSlateColor SExtContentBrowser::GetToolbarBackgroundColor() const
  1470. {
  1471. return FExtContentBrowserStyle::CustomToolbarBackgroundColor;
  1472. }
  1473. FSlateColor SExtContentBrowser::GetSourceViewBackgroundColor() const
  1474. {
  1475. return FExtContentBrowserStyle::CustomSourceViewBackgroundColor;
  1476. }
  1477. FSlateColor SExtContentBrowser::GetAssetViewBackgroundColor() const
  1478. {
  1479. return FExtContentBrowserStyle::CustomAssetViewBackgroundColor;
  1480. }
  1481. #if ECB_WIP_FAVORITE
  1482. void SExtContentBrowser::ToggleFolderFavorite(const TArray<FString>& FolderPaths)
  1483. {
  1484. bool bAddedFavorite = false;
  1485. for (FString FolderPath : FolderPaths)
  1486. {
  1487. if (ContentBrowserUtils::IsFavoriteFolder(FolderPath))
  1488. {
  1489. ContentBrowserUtils::RemoveFavoriteFolder(FolderPath, false);
  1490. }
  1491. else
  1492. {
  1493. ContentBrowserUtils::AddFavoriteFolder(FolderPath, false);
  1494. bAddedFavorite = true;
  1495. }
  1496. }
  1497. GConfig->Flush(false, GEditorPerProjectIni);
  1498. FavoritePathViewPtr->Populate();
  1499. if(bAddedFavorite)
  1500. {
  1501. FavoritePathViewPtr->SetSelectedPaths(FolderPaths);
  1502. if (GetFavoriteFolderVisibility() == EVisibility::Collapsed)
  1503. {
  1504. UExtContentBrowserSettings* Settings = GetMutableDefault<UExtContentBrowserSettings>();
  1505. Settings->SetDisplayFavorites(true);
  1506. Settings->SaveConfig();
  1507. }
  1508. }
  1509. }
  1510. #endif
  1511. #if ECB_FEA_SEARCH
  1512. EVisibility SExtContentBrowser::GetAlternateSearchBarVisibility() const
  1513. {
  1514. return GetDefault<UExtContentBrowserSettings>()->GetDisplayFavorites() ? EVisibility::Collapsed : EVisibility::Visible;
  1515. }
  1516. void SExtContentBrowser::HandleAssetViewSearchOptionsChanged()
  1517. {
  1518. #if ECB_LEGACY
  1519. TextFilter->SetIncludeClassName(AssetViewPtr->IsIncludingClassNames());
  1520. TextFilter->SetIncludeAssetPath(AssetViewPtr->IsIncludingAssetPaths());
  1521. TextFilter->SetIncludeCollectionNames(AssetViewPtr->IsIncludingCollectionNames());
  1522. #endif
  1523. }
  1524. void SExtContentBrowser::HandleRequestShowChangeLog()
  1525. {
  1526. bShowChangelog = true;
  1527. }
  1528. #endif
  1529. FText SExtContentBrowser::GetHighlightedText() const
  1530. {
  1531. return TextFilter->GetRawFilterText();
  1532. }
  1533. bool SExtContentBrowser::IsImportEnabled() const
  1534. {
  1535. // Todo: enable import bulk aseets and folders
  1536. const TArray<FExtAssetData>& SelectedAssets = AssetViewPtr->GetSelectedAssets();
  1537. #if ECB_WIP_MULTI_IMPORT
  1538. for (const auto& Asset : SelectedAssets)
  1539. {
  1540. if (Asset.CanImportFast())
  1541. {
  1542. return true;
  1543. }
  1544. }
  1545. return false;
  1546. #else
  1547. return SelectedAssets.Num() == 1 && SelectedAssets[0].CanImportFast();// || AssetViewPtr->GetSelectedFolders().Num() > 0;
  1548. #endif
  1549. }
  1550. FText SExtContentBrowser::GetImportTooltipText() const
  1551. {
  1552. // const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  1553. //
  1554. // if ( SourcesData.PackagePaths.Num() == 1 )
  1555. // {
  1556. // const FString CurrentPath = SourcesData.PackagePaths[0].ToString();
  1557. // if ( ContentBrowserUtils::IsClassPath( CurrentPath ) )
  1558. // {
  1559. // return LOCTEXT( "ImportAssetToolTip_InvalidClassPath", "Cannot import assets to class paths." );
  1560. // }
  1561. // else
  1562. // {
  1563. // return FText::Format( LOCTEXT( "ImportAssetToolTip", "Import to {0}..." ), FText::FromString( CurrentPath ) );
  1564. // }
  1565. // }
  1566. // else if ( SourcesData.PackagePaths.Num() > 1 )
  1567. // {
  1568. // return LOCTEXT( "ImportAssetToolTip_MultiplePaths", "Cannot import assets to multiple paths." );
  1569. // }
  1570. //
  1571. // return LOCTEXT( "ImportAssetToolTip_NoPath", "No path is selected as an import target." );
  1572. return LOCTEXT("ImportAssetToolTip", "Import .uasset files...");
  1573. }
  1574. FReply SExtContentBrowser::HandleAddContentFolderClicked()
  1575. {
  1576. AddContentFolder();
  1577. return FReply::Handled();
  1578. }
  1579. void SExtContentBrowser::AddContentFolder()
  1580. {
  1581. PathContextMenu->ExecuteAddRootFolder();
  1582. }
  1583. FReply SExtContentBrowser::HandleRemoveContentFoldersClicked()
  1584. {
  1585. RemoveContentFolders();
  1586. return FReply::Handled();
  1587. }
  1588. #if ECB_WIP_SYNC_ASSET
  1589. void SExtContentBrowser::PrepareToSync( const TArray<FExtAssetData>& AssetDataList, const TArray<FString>& FolderPaths, const bool bDisableFiltersThatHideAssets )
  1590. {
  1591. // Check to see if any of the assets require certain folders to be visible
  1592. bool bDisplayDev = GetDefault<UExtContentBrowserSettings>()->GetDisplayDevelopersFolder();
  1593. bool bDisplayEngine = GetDefault<UExtContentBrowserSettings>()->GetDisplayEngineFolder();
  1594. bool bDisplayPlugins = GetDefault<UExtContentBrowserSettings>()->GetDisplayPluginFolders();
  1595. bool bDisplayLocalized = GetDefault<UExtContentBrowserSettings>()->GetDisplayL10NFolder();
  1596. if ( !bDisplayDev || !bDisplayEngine || !bDisplayPlugins || !bDisplayLocalized )
  1597. {
  1598. TSet<FString> PackagePaths = TSet<FString>(FolderPaths);
  1599. for (const FExtAssetData& AssetData : AssetDataList)
  1600. {
  1601. FString PackagePath = AssetData.PackageFilePath.PackagePath.ToString();
  1602. PackagePaths.Add(PackagePath);
  1603. }
  1604. bool bRepopulate = false;
  1605. #if ECB_LEGACY
  1606. for (const FString& PackagePath : PackagePaths)
  1607. {
  1608. const ExtContentBrowserUtils::ECBFolderCategory FolderCategory = ExtContentBrowserUtils::GetFolderCategory( PackagePath );
  1609. if ( !bDisplayDev && FolderCategory == ExtContentBrowserUtils::ECBFolderCategory::DeveloperContent )
  1610. {
  1611. bDisplayDev = true;
  1612. GetMutableDefault<UExtContentBrowserSettings>()->SetDisplayDevelopersFolder(true, true);
  1613. bRepopulate = true;
  1614. }
  1615. else if ( !bDisplayEngine && (FolderCategory == ExtContentBrowserUtils::ECBFolderCategory::EngineContent || FolderCategory == ExtContentBrowserUtils::ECBFolderCategory::EngineClasses) )
  1616. {
  1617. bDisplayEngine = true;
  1618. GetMutableDefault<UExtContentBrowserSettings>()->SetDisplayEngineFolder(true, true);
  1619. bRepopulate = true;
  1620. }
  1621. else if ( !bDisplayPlugins && (FolderCategory == ExtContentBrowserUtils::ECBFolderCategory::PluginContent || FolderCategory == ExtContentBrowserUtils::ECBFolderCategory::PluginClasses) )
  1622. {
  1623. bDisplayPlugins = true;
  1624. GetMutableDefault<UExtContentBrowserSettings>()->SetDisplayPluginFolders(true, true);
  1625. bRepopulate = true;
  1626. }
  1627. if (!bDisplayLocalized && ExtContentBrowserUtils::IsLocalizationFolder(PackagePath))
  1628. {
  1629. bDisplayLocalized = true;
  1630. GetMutableDefault<UExtContentBrowserSettings>()->SetDisplayL10NFolder(true);
  1631. bRepopulate = true;
  1632. }
  1633. if (bDisplayDev && bDisplayEngine && bDisplayPlugins && bDisplayLocalized)
  1634. {
  1635. break;
  1636. }
  1637. }
  1638. #endif
  1639. // If we have auto-enabled any flags, force a refresh
  1640. if ( bRepopulate )
  1641. {
  1642. PathViewPtr->Populate();
  1643. #if ECB_WIP_FAVORITE
  1644. FavoritePathViewPtr->Populate();
  1645. #endif
  1646. }
  1647. }
  1648. if ( bDisableFiltersThatHideAssets )
  1649. {
  1650. // Disable the filter categories
  1651. FilterListPtr->DisableFiltersThatHideAssets(AssetDataList);
  1652. }
  1653. // Disable the filter search (reset the filter, then clear the search text)
  1654. // Note: we have to remove the filter immediately, we can't wait for OnSearchBoxChanged to hit
  1655. SetSearchBoxText(FText::GetEmpty());
  1656. SearchBoxPtr->SetText(FText::GetEmpty());
  1657. SearchBoxPtr->SetError(FText::GetEmpty());
  1658. }
  1659. void SExtContentBrowser::SyncToAssets( const TArray<FExtAssetData>& AssetDataList, const bool bAllowImplicitSync, const bool bDisableFiltersThatHideAssets )
  1660. {
  1661. PrepareToSync(AssetDataList, TArray<FString>(), bDisableFiltersThatHideAssets);
  1662. // Tell the sources view first so the asset view will be up to date by the time we request the sync
  1663. PathViewPtr->SyncToAssets(AssetDataList, bAllowImplicitSync);
  1664. #if ECB_WIP_FAVORITE
  1665. FavoritePathViewPtr->SyncToAssets(AssetDataList, bAllowImplicitSync);
  1666. #endif
  1667. AssetViewPtr->SyncToAssets(AssetDataList);
  1668. }
  1669. void SExtContentBrowser::SyncToFolders( const TArray<FString>& FolderList, const bool bAllowImplicitSync )
  1670. {
  1671. PrepareToSync(TArray<FAssetData>(), FolderList, false);
  1672. // Tell the sources view first so the asset view will be up to date by the time we request the sync
  1673. PathViewPtr->SyncToFolders(FolderList, bAllowImplicitSync);
  1674. #if ECB_WIP_FAVORITE
  1675. FavoritePathViewPtr->SyncToFolders(FolderList, bAllowImplicitSync);
  1676. #endif
  1677. AssetViewPtr->SyncToFolders(FolderList);
  1678. }
  1679. void SExtContentBrowser::SyncTo( const FExtContentBrowserSelection& ItemSelection, const bool bAllowImplicitSync, const bool bDisableFiltersThatHideAssets )
  1680. {
  1681. PrepareToSync(ItemSelection.SelectedAssets, ItemSelection.SelectedFolders, bDisableFiltersThatHideAssets);
  1682. // Tell the sources view first so the asset view will be up to date by the time we request the sync
  1683. PathViewPtr->SyncTo(ItemSelection, bAllowImplicitSync);
  1684. #if ECB_WIP_FAVORITE
  1685. FavoritePathViewPtr->SyncTo(ItemSelection, bAllowImplicitSync);
  1686. #endif
  1687. AssetViewPtr->SyncTo(ItemSelection);
  1688. }
  1689. #endif
  1690. void SExtContentBrowser::SetIsPrimaryContentBrowser(bool NewIsPrimary)
  1691. {
  1692. if (!CanSetAsPrimaryContentBrowser())
  1693. {
  1694. return;
  1695. }
  1696. bIsPrimaryBrowser = NewIsPrimary;
  1697. }
  1698. bool SExtContentBrowser::CanSetAsPrimaryContentBrowser() const
  1699. {
  1700. return bCanSetAsPrimaryBrowser;
  1701. }
  1702. #if ECB_WIP_MULTI_INSTANCES
  1703. const FName SExtContentBrowser::GetInstanceName() const
  1704. {
  1705. return InstanceName;
  1706. }
  1707. TSharedPtr<FTabManager> SExtContentBrowser::GetTabManager() const
  1708. {
  1709. if (ContainingTab.IsValid())
  1710. {
  1711. return ContainingTab.Pin()->GetTabManager();
  1712. }
  1713. return NULL;
  1714. }
  1715. void SExtContentBrowser::OpenNewContentBrowser()
  1716. {
  1717. //FContentBrowserSingleton::Get().SyncBrowserToFolders(PathContextMenu->GetSelectedPaths(), false, true, NAME_None, true);
  1718. }
  1719. #endif
  1720. #if ECB_LEGACY
  1721. void SExtContentBrowser::LoadSelectedObjectsIfNeeded()
  1722. {
  1723. // Get the selected assets in the asset view
  1724. const TArray<FAssetData>& SelectedAssets = AssetViewPtr->GetSelectedAssets();
  1725. // Load every asset that isn't already in memory
  1726. for ( auto AssetIt = SelectedAssets.CreateConstIterator(); AssetIt; ++AssetIt )
  1727. {
  1728. const FAssetData& AssetData = *AssetIt;
  1729. const bool bShowProgressDialog = (!AssetData.IsAssetLoaded() && FEditorFileUtils::IsMapPackageAsset(AssetData.ObjectPath.ToString()));
  1730. GWarn->BeginSlowTask(LOCTEXT("LoadingObjects", "Loading Objects..."), bShowProgressDialog);
  1731. (*AssetIt).GetAsset();
  1732. GWarn->EndSlowTask();
  1733. }
  1734. }
  1735. #endif
  1736. void SExtContentBrowser::GetSelectedAssets(TArray<FExtAssetData>& SelectedAssets)
  1737. {
  1738. // Make sure the asset data is up to date
  1739. AssetViewPtr->ProcessRecentlyLoadedOrChangedAssets();
  1740. SelectedAssets = AssetViewPtr->GetSelectedAssets();
  1741. }
  1742. #if ECB_LEGACY
  1743. void SExtContentBrowser::GetSelectedFolders(TArray<FString>& SelectedFolders)
  1744. {
  1745. // Make sure the asset data is up to date
  1746. AssetViewPtr->ProcessRecentlyLoadedOrChangedAssets();
  1747. SelectedFolders = AssetViewPtr->GetSelectedFolders();
  1748. }
  1749. TArray<FString> SExtContentBrowser::GetSelectedPathViewFolders()
  1750. {
  1751. check(PathViewPtr.IsValid());
  1752. return PathViewPtr->GetSelectedPaths();
  1753. }
  1754. #endif
  1755. void SExtContentBrowser::SaveSettings() const
  1756. {
  1757. const FString& SettingsString = InstanceName.ToString();
  1758. GConfig->SetBool(*SettingsIniSection, *(SettingsString + TEXT(".SourcesExpanded")), bSourcesViewExpanded, GEditorPerProjectIni);
  1759. #if ECB_WIP_LOCK
  1760. GConfig->SetBool(*SettingsIniSection, *(SettingsString + TEXT(".Locked")), bIsLocked, GEditorPerProjectIni);
  1761. #endif
  1762. #if ECB_TODO // Save splitter position
  1763. for(int32 SlotIndex = 0; SlotIndex < PathAssetSplitterPtr->GetChildren()->Num(); SlotIndex++)
  1764. {
  1765. float SplitterSize = PathAssetSplitterPtr->SlotAt(SlotIndex).SizeValue.Get();
  1766. GConfig->SetFloat(*SettingsIniSection, *(SettingsString + FString::Printf(TEXT(".VerticalSplitter.SlotSize%d"), SlotIndex)), SplitterSize, GEditorPerProjectIni);
  1767. }
  1768. for(int32 SlotIndex = 0; SlotIndex < PathCollectionSplitterPtr->GetChildren()->Num(); SlotIndex++)
  1769. {
  1770. float SplitterSize = PathCollectionSplitterPtr->SlotAt(SlotIndex).SizeValue.Get();
  1771. GConfig->SetFloat(*SettingsIniSection, *(SettingsString + FString::Printf(TEXT(".HorizontalSplitter.SlotSize%d"), SlotIndex)), SplitterSize, GEditorPerProjectIni);
  1772. }
  1773. for (int32 SlotIndex = 0; SlotIndex < PathFavoriteSplitterPtr->GetChildren()->Num(); SlotIndex++)
  1774. {
  1775. float SplitterSize = PathFavoriteSplitterPtr->SlotAt(SlotIndex).SizeValue.Get();
  1776. GConfig->SetFloat(*SettingsIniSection, *(SettingsString + FString::Printf(TEXT(".FavoriteSplitter.SlotSize%d"), SlotIndex)), SplitterSize, GEditorPerProjectIni);
  1777. }
  1778. #endif
  1779. // Save all our data using the settings string as a key in the user settings ini
  1780. FilterListPtr->SaveSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1781. #if ECB_TODO // save filter and path view settings
  1782. PathViewPtr->SaveSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1783. #endif
  1784. #if ECB_WIP_FAVORITE
  1785. FavoritePathViewPtr->SaveSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString + TEXT(".Favorites"));
  1786. #endif
  1787. #if ECB_WIP_COLLECTION
  1788. CollectionViewPtr->SaveSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1789. #endif
  1790. AssetViewPtr->SaveSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1791. ReferenceViewerPtr->SaveSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1792. }
  1793. void SExtContentBrowser::LoadSettings(const FName& InInstanceName)
  1794. {
  1795. FString SettingsString = InInstanceName.ToString();
  1796. // Now that we have determined the appropriate settings string, actually load the settings
  1797. GConfig->GetBool(*SettingsIniSection, *(SettingsString + TEXT(".SourcesExpanded")), bSourcesViewExpanded, GEditorPerProjectIni);
  1798. #if ECB_WIP_LOCK
  1799. GConfig->GetBool(*SettingsIniSection, *(SettingsString + TEXT(".Locked")), bIsLocked, GEditorPerProjectIni);
  1800. #endif
  1801. #if ECB_TODO // load filter and path view settings
  1802. for (int32 SlotIndex = 0; SlotIndex < PathAssetSplitterPtr->GetChildren()->Num(); SlotIndex++)
  1803. {
  1804. float SplitterSize = PathAssetSplitterPtr->SlotAt(SlotIndex).SizeValue.Get();
  1805. GConfig->GetFloat(*SettingsIniSection, *(SettingsString + FString::Printf(TEXT(".VerticalSplitter.SlotSize%d"), SlotIndex)), SplitterSize, GEditorPerProjectIni);
  1806. PathAssetSplitterPtr->SlotAt(SlotIndex).SizeValue = SplitterSize;
  1807. }
  1808. for (int32 SlotIndex = 0; SlotIndex < PathCollectionSplitterPtr->GetChildren()->Num(); SlotIndex++)
  1809. {
  1810. float SplitterSize = PathCollectionSplitterPtr->SlotAt(SlotIndex).SizeValue.Get();
  1811. GConfig->GetFloat(*SettingsIniSection, *(SettingsString + FString::Printf(TEXT(".HorizontalSplitter.SlotSize%d"), SlotIndex)), SplitterSize, GEditorPerProjectIni);
  1812. PathCollectionSplitterPtr->SlotAt(SlotIndex).SizeValue = SplitterSize;
  1813. }
  1814. for (int32 SlotIndex = 0; SlotIndex < PathFavoriteSplitterPtr->GetChildren()->Num(); SlotIndex++)
  1815. {
  1816. float SplitterSize = PathFavoriteSplitterPtr->SlotAt(SlotIndex).SizeValue.Get();
  1817. GConfig->GetFloat(*SettingsIniSection, *(SettingsString + FString::Printf(TEXT(".FavoriteSplitter.SlotSize%d"), SlotIndex)), SplitterSize, GEditorPerProjectIni);
  1818. PathFavoriteSplitterPtr->SlotAt(SlotIndex).SizeValue = SplitterSize;
  1819. }
  1820. #endif
  1821. // Load all our data using the settings string as a key in the user settings ini
  1822. FilterListPtr->LoadSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1823. #if ECB_TODO // load filter and path view settings
  1824. PathViewPtr->LoadSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1825. #endif
  1826. #if ECB_WIP_FAVORITE
  1827. FavoritePathViewPtr->LoadSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString + TEXT(".Favorites"));
  1828. #endif
  1829. #if ECB_WIP_COLLECTION
  1830. CollectionViewPtr->LoadSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1831. #endif
  1832. AssetViewPtr->LoadSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1833. ReferenceViewerPtr->LoadSettings(GEditorPerProjectIni, SettingsIniSection, SettingsString);
  1834. }
  1835. #if ECB_WIP_LOCK
  1836. bool SExtContentBrowser::IsLocked() const
  1837. {
  1838. return bIsLocked;
  1839. }
  1840. #endif
  1841. #if ECB_FEA_SEARCH
  1842. void SExtContentBrowser::SetKeyboardFocusOnSearch() const
  1843. {
  1844. // Focus on the search box
  1845. FSlateApplication::Get().SetKeyboardFocus( SearchBoxPtr, EFocusCause::SetDirectly );
  1846. }
  1847. #endif
  1848. FReply SExtContentBrowser::OnKeyDown( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent )
  1849. {
  1850. if( Commands->ProcessCommandBindings( InKeyEvent ) )
  1851. {
  1852. return FReply::Handled();
  1853. }
  1854. return FReply::Unhandled();
  1855. }
  1856. #if ECB_LEGACY
  1857. FReply SExtContentBrowser::OnPreviewMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
  1858. {
  1859. // Clicking in a content browser will shift it to be the primary browser
  1860. FContentBrowserSingleton::Get().SetPrimaryContentBrowser(SharedThis(this));
  1861. return FReply::Unhandled();
  1862. }
  1863. FReply SExtContentBrowser::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent )
  1864. {
  1865. // Mouse back and forward buttons traverse history
  1866. if ( MouseEvent.GetEffectingButton() == EKeys::ThumbMouseButton)
  1867. {
  1868. HistoryManager.GoBack();
  1869. return FReply::Handled();
  1870. }
  1871. else if ( MouseEvent.GetEffectingButton() == EKeys::ThumbMouseButton2)
  1872. {
  1873. HistoryManager.GoForward();
  1874. return FReply::Handled();
  1875. }
  1876. return FReply::Unhandled();
  1877. }
  1878. FReply SExtContentBrowser::OnMouseButtonDoubleClick( const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent )
  1879. {
  1880. // Mouse back and forward buttons traverse history
  1881. if ( InMouseEvent.GetEffectingButton() == EKeys::ThumbMouseButton)
  1882. {
  1883. HistoryManager.GoBack();
  1884. return FReply::Handled();
  1885. }
  1886. else if ( InMouseEvent.GetEffectingButton() == EKeys::ThumbMouseButton2)
  1887. {
  1888. HistoryManager.GoForward();
  1889. return FReply::Handled();
  1890. }
  1891. return FReply::Unhandled();
  1892. }
  1893. #endif
  1894. void SExtContentBrowser::OnContainingTabSavingVisualState() const
  1895. {
  1896. SaveSettings();
  1897. }
  1898. void SExtContentBrowser::OnContainingTabClosed(TSharedRef<SDockTab> DockTab)
  1899. {
  1900. //FExtContentBrowserSingleton::Get().ContentBrowserClosed( SharedThis(this) );
  1901. }
  1902. void SExtContentBrowser::OnContainingTabActivated(TSharedRef<SDockTab> DockTab, ETabActivationCause InActivationCause)
  1903. {
  1904. if(InActivationCause == ETabActivationCause::UserClickedOnTab)
  1905. {
  1906. //FExtContentBrowserSingleton::Get().SetPrimaryContentBrowser(SharedThis(this));
  1907. }
  1908. }
  1909. void SExtContentBrowser::SourcesChanged(const TArray<FString>& SelectedPaths, const TArray<FCollectionNameType>& SelectedCollections)
  1910. {
  1911. FString NewSource = SelectedPaths.Num() > 0 ? SelectedPaths[0] : (SelectedCollections.Num() > 0 ? SelectedCollections[0].Name.ToString() : TEXT("None"));
  1912. ECB_LOG(Display, TEXT("The content browser source was changed by the sources view to '%s'"), *NewSource);
  1913. FSourcesData SourcesData;
  1914. {
  1915. TArray<FName> SelectedPathNames;
  1916. SelectedPathNames.Reserve(SelectedPaths.Num());
  1917. for (const FString& SelectedPath : SelectedPaths)
  1918. {
  1919. // exclude loading path as source
  1920. if (ExtContentBrowserUtils::IsFolderBackgroundGathering(SelectedPath))
  1921. {
  1922. continue;
  1923. }
  1924. SelectedPathNames.Add(FName(*SelectedPath));
  1925. }
  1926. SourcesData = FSourcesData(MoveTemp(SelectedPathNames), SelectedCollections);
  1927. }
  1928. #if ECB_WIP_COLLECTION
  1929. // A dynamic collection should apply its search query to the CB search, so we need to stash the current search so that we can restore it again later
  1930. if (SourcesData.IsDynamicCollection())
  1931. {
  1932. // Only stash the user search term once in case we're switching between dynamic collections
  1933. if (!StashedSearchBoxText.IsSet())
  1934. {
  1935. StashedSearchBoxText = TextFilter->GetRawFilterText();
  1936. }
  1937. FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
  1938. const FCollectionNameType& DynamicCollection = SourcesData.Collections[0];
  1939. FString DynamicQueryString;
  1940. CollectionManagerModule.Get().GetDynamicQueryText(DynamicCollection.Name, DynamicCollection.Type, DynamicQueryString);
  1941. const FText DynamicQueryText = FText::FromString(DynamicQueryString);
  1942. SetSearchBoxText(DynamicQueryText);
  1943. SearchBoxPtr->SetText(DynamicQueryText);
  1944. }
  1945. else if (StashedSearchBoxText.IsSet())
  1946. {
  1947. // Restore the stashed search term
  1948. const FText StashedText = StashedSearchBoxText.GetValue();
  1949. StashedSearchBoxText.Reset();
  1950. SetSearchBoxText(StashedText);
  1951. SearchBoxPtr->SetText(StashedText);
  1952. }
  1953. if (!AssetViewPtr->GetSourcesData().IsEmpty())
  1954. {
  1955. // Update the current history data to preserve selection if there is a valid SourcesData
  1956. HistoryManager.UpdateHistoryData();
  1957. }
  1958. #endif
  1959. // Change the filter for the asset view
  1960. AssetViewPtr->SetSourcesData(SourcesData);
  1961. #if ECB_WIP_HISTORY
  1962. // Add a new history data now that the source has changed
  1963. HistoryManager.AddHistoryData();
  1964. #endif
  1965. #if ECB_WIP_BREADCRUMB
  1966. // Update the breadcrumb trail path
  1967. UpdatePath();
  1968. #endif
  1969. }
  1970. void SExtContentBrowser::FolderEntered(const FString& FolderPath)
  1971. {
  1972. #if ECB_WIP_COLLECTION
  1973. // Have we entered a sub-collection folder?
  1974. FName CollectionName;
  1975. ECollectionShareType::Type CollectionFolderShareType = ECollectionShareType::CST_All;
  1976. if (ContentBrowserUtils::IsCollectionPath(FolderPath, &CollectionName, &CollectionFolderShareType))
  1977. {
  1978. const FCollectionNameType SelectedCollection(CollectionName, CollectionFolderShareType);
  1979. TArray<FCollectionNameType> Collections;
  1980. Collections.Add(SelectedCollection);
  1981. CollectionViewPtr->SetSelectedCollections(Collections);
  1982. CollectionSelected(SelectedCollection);
  1983. }
  1984. else
  1985. #endif
  1986. {
  1987. // set the path view to the incoming path
  1988. TArray<FString> SelectedPaths;
  1989. SelectedPaths.Add(FolderPath);
  1990. PathViewPtr->SetSelectedPaths(SelectedPaths);
  1991. PathSelected(SelectedPaths[0]);
  1992. }
  1993. }
  1994. void SExtContentBrowser::PathSelected(const FString& FolderPath)
  1995. {
  1996. // You may not select both collections and paths
  1997. #if ECB_WIP_COLLECTION
  1998. CollectionViewPtr->ClearSelection();
  1999. #endif
  2000. TArray<FString> SelectedPaths = PathViewPtr->GetSelectedPaths();
  2001. #if ECB_WIP_COLLECTION
  2002. // Selecting a folder shows it in the favorite list also
  2003. FavoritePathViewPtr->SetSelectedPaths(SelectedPaths);
  2004. #endif
  2005. TArray<FCollectionNameType> SelectedCollections;
  2006. SourcesChanged(SelectedPaths, SelectedCollections);
  2007. #if ECB_LEGACY
  2008. // Notify 'asset path changed' delegate
  2009. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>( TEXT("ContentBrowser") );
  2010. FContentBrowserModule::FOnAssetPathChanged& PathChangedDelegate = ContentBrowserModule.GetOnAssetPathChanged();
  2011. if(PathChangedDelegate.IsBound())
  2012. {
  2013. PathChangedDelegate.Broadcast(FolderPath);
  2014. }
  2015. #endif
  2016. // Update the context menu's selected paths list
  2017. PathContextMenu->SetSelectedPaths(SelectedPaths);
  2018. bCanRemoveContentFolders = FExtContentBrowserSingleton::GetAssetRegistry().IsRootFolders(SelectedPaths);
  2019. }
  2020. #if ECB_WIP_FAVORITE
  2021. void SExtContentBrowser::FavoritePathSelected(const FString& FolderPath)
  2022. {
  2023. // You may not select both collections and paths
  2024. CollectionViewPtr->ClearSelection();
  2025. TArray<FString> SelectedPaths = FavoritePathViewPtr->GetSelectedPaths();
  2026. // Selecting a favorite shows it in the main list also
  2027. PathViewPtr->SetSelectedPaths(SelectedPaths);
  2028. TArray<FCollectionNameType> SelectedCollections;
  2029. SourcesChanged(SelectedPaths, SelectedCollections);
  2030. // Notify 'asset path changed' delegate
  2031. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
  2032. FContentBrowserModule::FOnAssetPathChanged& PathChangedDelegate = ContentBrowserModule.GetOnAssetPathChanged();
  2033. if (PathChangedDelegate.IsBound())
  2034. {
  2035. PathChangedDelegate.Broadcast(FolderPath);
  2036. }
  2037. // Update the context menu's selected paths list
  2038. PathContextMenu->SetSelectedPaths(SelectedPaths);
  2039. }
  2040. #endif
  2041. TSharedRef<FExtender> SExtContentBrowser::GetPathContextMenuExtender(const TArray<FString>& InSelectedPaths) const
  2042. {
  2043. return PathContextMenu->MakePathViewContextMenuExtender(InSelectedPaths);
  2044. }
  2045. #if ECB_WIP_COLLECTION
  2046. void SExtContentBrowser::CollectionSelected(const FCollectionNameType& SelectedCollection)
  2047. {
  2048. // You may not select both collections and paths
  2049. PathViewPtr->ClearSelection();
  2050. FavoritePathViewPtr->ClearSelection();
  2051. TArray<FCollectionNameType> SelectedCollections = CollectionViewPtr->GetSelectedCollections();
  2052. TArray<FString> SelectedPaths;
  2053. if( SelectedCollections.Num() == 0 )
  2054. {
  2055. // just select the game folder
  2056. SelectedPaths.Add(TEXT("/Game"));
  2057. SourcesChanged(SelectedPaths, SelectedCollections);
  2058. }
  2059. else
  2060. {
  2061. SourcesChanged(SelectedPaths, SelectedCollections);
  2062. }
  2063. }
  2064. void SExtContentBrowser::PathPickerPathSelected(const FString& FolderPath)
  2065. {
  2066. PathPickerButton->SetIsOpen(false);
  2067. if ( !FolderPath.IsEmpty() )
  2068. {
  2069. TArray<FString> Paths;
  2070. Paths.Add(FolderPath);
  2071. PathViewPtr->SetSelectedPaths(Paths);
  2072. FavoritePathViewPtr->SetSelectedPaths(Paths);
  2073. }
  2074. PathSelected(FolderPath);
  2075. }
  2076. void SExtContentBrowser::SetSelectedPaths(const TArray<FString>& FolderPaths, bool bNeedsRefresh/* = false */)
  2077. {
  2078. if (FolderPaths.Num() > 0)
  2079. {
  2080. if (bNeedsRefresh)
  2081. {
  2082. PathViewPtr->Populate();
  2083. FavoritePathViewPtr->Populate();
  2084. }
  2085. PathViewPtr->SetSelectedPaths(FolderPaths);
  2086. FavoritePathViewPtr->SetSelectedPaths(FolderPaths);
  2087. PathSelected(FolderPaths[0]);
  2088. }
  2089. }
  2090. void SExtContentBrowser::PathPickerCollectionSelected(const FCollectionNameType& SelectedCollection)
  2091. {
  2092. PathPickerButton->SetIsOpen(false);
  2093. TArray<FCollectionNameType> Collections;
  2094. Collections.Add(SelectedCollection);
  2095. CollectionViewPtr->SetSelectedCollections(Collections);
  2096. CollectionSelected(SelectedCollection);
  2097. }
  2098. void SExtContentBrowser::OnApplyHistoryData( const FHistoryData& History )
  2099. {
  2100. PathViewPtr->ApplyHistoryData(History);
  2101. FavoritePathViewPtr->ApplyHistoryData(History);
  2102. CollectionViewPtr->ApplyHistoryData(History);
  2103. AssetViewPtr->ApplyHistoryData(History);
  2104. // Update the breadcrumb trail path
  2105. UpdatePath();
  2106. if (History.SourcesData.HasPackagePaths())
  2107. {
  2108. // Notify 'asset path changed' delegate
  2109. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
  2110. FContentBrowserModule::FOnAssetPathChanged& PathChangedDelegate = ContentBrowserModule.GetOnAssetPathChanged();
  2111. if (PathChangedDelegate.IsBound())
  2112. {
  2113. PathChangedDelegate.Broadcast(History.SourcesData.PackagePaths[0].ToString());
  2114. }
  2115. }
  2116. }
  2117. void SExtContentBrowser::OnUpdateHistoryData(FHistoryData& HistoryData) const
  2118. {
  2119. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  2120. const TArray<FAssetData>& SelectedAssets = AssetViewPtr->GetSelectedAssets();
  2121. const FText NewSource = SourcesData.HasPackagePaths() ? FText::FromName(SourcesData.PackagePaths[0]) : (SourcesData.HasCollections() ? FText::FromName(SourcesData.Collections[0].Name) : LOCTEXT("AllAssets", "All Assets"));
  2122. HistoryData.HistoryDesc = NewSource;
  2123. HistoryData.SourcesData = SourcesData;
  2124. HistoryData.SelectionData.Reset();
  2125. HistoryData.SelectionData.SelectedFolders = TSet<FString>(AssetViewPtr->GetSelectedFolders());
  2126. for (const FAssetData& SelectedAsset : SelectedAssets)
  2127. {
  2128. HistoryData.SelectionData.SelectedAssets.Add(SelectedAsset.ObjectPath);
  2129. }
  2130. }
  2131. #endif
  2132. #if ECB_FEA_SEARCH
  2133. void SExtContentBrowser::SetSearchBoxText(const FText& InSearchText)
  2134. {
  2135. // Has anything changed? (need to test case as the operators are case-sensitive)
  2136. if (!InSearchText.ToString().Equals(TextFilter->GetRawFilterText().ToString(), ESearchCase::CaseSensitive))
  2137. {
  2138. TextFilter->SetRawFilterText( InSearchText );
  2139. SearchBoxPtr->SetError( TextFilter->GetFilterErrorText() );
  2140. if(InSearchText.IsEmpty())
  2141. {
  2142. FrontendFilters->Remove(TextFilter);
  2143. AssetViewPtr->SetUserSearching(false);
  2144. }
  2145. else
  2146. {
  2147. FrontendFilters->Add(TextFilter);
  2148. AssetViewPtr->SetUserSearching(true);
  2149. }
  2150. }
  2151. }
  2152. void SExtContentBrowser::OnSearchBoxChanged(const FText& InSearchText)
  2153. {
  2154. SetSearchBoxText(InSearchText);
  2155. #if ECB_LEGACY
  2156. // Broadcast 'search box changed' delegate
  2157. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>( TEXT("ContentBrowser") );
  2158. ContentBrowserModule.GetOnSearchBoxChanged().Broadcast(InSearchText, bIsPrimaryBrowser);
  2159. #endif
  2160. }
  2161. void SExtContentBrowser::OnSearchBoxCommitted(const FText& InSearchText, ETextCommit::Type CommitInfo)
  2162. {
  2163. SetSearchBoxText(InSearchText);
  2164. }
  2165. #endif
  2166. #if ECB_TODO // todo: Save search?
  2167. bool SExtContentBrowser::IsSaveSearchButtonEnabled() const
  2168. {
  2169. return !TextFilter->GetRawFilterText().IsEmptyOrWhitespace();
  2170. }
  2171. FReply SExtContentBrowser::OnSaveSearchButtonClicked()
  2172. {
  2173. // Need to make sure we can see the collections view
  2174. if (!bSourcesViewExpanded)
  2175. {
  2176. SourcesViewExpandClicked();
  2177. }
  2178. // We want to add any currently selected paths to the final saved query so that you get back roughly the same list of objects as what you're currently seeing
  2179. FString SelectedPathsQuery;
  2180. {
  2181. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  2182. for (int32 SelectedPathIndex = 0; SelectedPathIndex < SourcesData.PackagePaths.Num(); ++SelectedPathIndex)
  2183. {
  2184. SelectedPathsQuery.Append(TEXT("Path:'"));
  2185. SelectedPathsQuery.Append(SourcesData.PackagePaths[SelectedPathIndex].ToString());
  2186. SelectedPathsQuery.Append(TEXT("'..."));
  2187. if (SelectedPathIndex + 1 < SourcesData.PackagePaths.Num())
  2188. {
  2189. SelectedPathsQuery.Append(TEXT(" OR "));
  2190. }
  2191. }
  2192. }
  2193. // todo: should we automatically append any type filters too?
  2194. // Produce the final query
  2195. FText FinalQueryText;
  2196. if (SelectedPathsQuery.IsEmpty())
  2197. {
  2198. FinalQueryText = TextFilter->GetRawFilterText();
  2199. }
  2200. else
  2201. {
  2202. FinalQueryText = FText::FromString(FString::Printf(TEXT("(%s) AND (%s)"), *TextFilter->GetRawFilterText().ToString(), *SelectedPathsQuery));
  2203. }
  2204. CollectionViewPtr->MakeSaveDynamicCollectionMenu(FinalQueryText);
  2205. return FReply::Handled();
  2206. }
  2207. void SExtContentBrowser::OnPathClicked( const FString& CrumbData )
  2208. {
  2209. FSourcesData SourcesData = AssetViewPtr->GetSourcesData();
  2210. if ( SourcesData.HasCollections() )
  2211. {
  2212. // Collection crumb was clicked. See if we've clicked on a different collection in the hierarchy, and change the path if required.
  2213. TOptional<FCollectionNameType> CollectionClicked;
  2214. {
  2215. FString CollectionName;
  2216. FString CollectionTypeString;
  2217. if (CrumbData.Split(TEXT("?"), &CollectionName, &CollectionTypeString))
  2218. {
  2219. const int32 CollectionType = FCString::Atoi(*CollectionTypeString);
  2220. if (CollectionType >= 0 && CollectionType < ECollectionShareType::CST_All)
  2221. {
  2222. CollectionClicked = FCollectionNameType(FName(*CollectionName), ECollectionShareType::Type(CollectionType));
  2223. }
  2224. }
  2225. }
  2226. if ( CollectionClicked.IsSet() && SourcesData.Collections[0] != CollectionClicked.GetValue() )
  2227. {
  2228. TArray<FCollectionNameType> Collections;
  2229. Collections.Add(CollectionClicked.GetValue());
  2230. CollectionViewPtr->SetSelectedCollections(Collections);
  2231. CollectionSelected(CollectionClicked.GetValue());
  2232. }
  2233. }
  2234. else if ( !SourcesData.HasPackagePaths() )
  2235. {
  2236. // No collections or paths are selected. This is "All Assets". Don't change the path when this is clicked.
  2237. }
  2238. else if ( SourcesData.PackagePaths.Num() > 1 || SourcesData.PackagePaths[0].ToString() != CrumbData )
  2239. {
  2240. // More than one path is selected or the crumb that was clicked is not the same path as the current one. Change the path.
  2241. TArray<FString> SelectedPaths;
  2242. SelectedPaths.Add(CrumbData);
  2243. PathViewPtr->SetSelectedPaths(SelectedPaths);
  2244. FavoritePathViewPtr->SetSelectedPaths(SelectedPaths);
  2245. PathSelected(SelectedPaths[0]);
  2246. }
  2247. }
  2248. void SExtContentBrowser::OnPathMenuItemClicked(FString ClickedPath)
  2249. {
  2250. OnPathClicked( ClickedPath );
  2251. }
  2252. TSharedPtr<SWidget> SExtContentBrowser::OnGetCrumbDelimiterContent(const FString& CrumbData) const
  2253. {
  2254. FSourcesData SourcesData = AssetViewPtr->GetSourcesData();
  2255. TSharedPtr<SWidget> Widget = SNullWidget::NullWidget;
  2256. TSharedPtr<SWidget> MenuWidget;
  2257. if( SourcesData.HasCollections() )
  2258. {
  2259. TOptional<FCollectionNameType> CollectionClicked;
  2260. {
  2261. FString CollectionName;
  2262. FString CollectionTypeString;
  2263. if (CrumbData.Split(TEXT("?"), &CollectionName, &CollectionTypeString))
  2264. {
  2265. const int32 CollectionType = FCString::Atoi(*CollectionTypeString);
  2266. if (CollectionType >= 0 && CollectionType < ECollectionShareType::CST_All)
  2267. {
  2268. CollectionClicked = FCollectionNameType(FName(*CollectionName), ECollectionShareType::Type(CollectionType));
  2269. }
  2270. }
  2271. }
  2272. if( CollectionClicked.IsSet() )
  2273. {
  2274. FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
  2275. TArray<FCollectionNameType> ChildCollections;
  2276. CollectionManagerModule.Get().GetChildCollections(CollectionClicked->Name, CollectionClicked->Type, ChildCollections);
  2277. if( ChildCollections.Num() > 0 )
  2278. {
  2279. FMenuBuilder MenuBuilder( true, nullptr );
  2280. for( const FCollectionNameType& ChildCollection : ChildCollections )
  2281. {
  2282. const FString ChildCollectionCrumbData = FString::Printf(TEXT("%s?%s"), *ChildCollection.Name.ToString(), *FString::FromInt(ChildCollection.Type));
  2283. MenuBuilder.AddMenuEntry(
  2284. FText::FromName(ChildCollection.Name),
  2285. FText::GetEmpty(),
  2286. FSlateIcon(FAppStyle::GetStyleSetName(), ECollectionShareType::GetIconStyleName(ChildCollection.Type)),
  2287. FUIAction(FExecuteAction::CreateSP(const_cast<SExtContentBrowser*>(this), &SExtContentBrowser::OnPathMenuItemClicked, ChildCollectionCrumbData))
  2288. );
  2289. }
  2290. MenuWidget = MenuBuilder.MakeWidget();
  2291. }
  2292. }
  2293. }
  2294. else if( SourcesData.HasPackagePaths() )
  2295. {
  2296. TArray<FString> SubPaths;
  2297. const bool bRecurse = false;
  2298. if( ContentBrowserUtils::IsClassPath(CrumbData) )
  2299. {
  2300. TSharedRef<FNativeClassHierarchy> NativeClassHierarchy = FContentBrowserSingleton::Get().GetNativeClassHierarchy();
  2301. FNativeClassHierarchyFilter ClassFilter;
  2302. ClassFilter.ClassPaths.Add(FName(*CrumbData));
  2303. ClassFilter.bRecursivePaths = bRecurse;
  2304. NativeClassHierarchy->GetMatchingFolders(ClassFilter, SubPaths);
  2305. }
  2306. else
  2307. {
  2308. FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
  2309. IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();
  2310. AssetRegistry.GetSubPaths( CrumbData, SubPaths, bRecurse );
  2311. }
  2312. if( SubPaths.Num() > 0 )
  2313. {
  2314. FMenuBuilder MenuBuilder( true, nullptr );
  2315. for( int32 PathIndex = 0; PathIndex < SubPaths.Num(); ++PathIndex )
  2316. {
  2317. const FString& SubPath = SubPaths[PathIndex];
  2318. // For displaying in the menu cut off the parent path since it is redundant
  2319. FString PathWithoutParent = SubPath.RightChop( CrumbData.Len() + 1 );
  2320. MenuBuilder.AddMenuEntry(
  2321. FText::FromString(PathWithoutParent),
  2322. FText::GetEmpty(),
  2323. FSlateIcon(FAppStyle::GetStyleSetName(), "ContentBrowser.BreadcrumbPathPickerFolder"),
  2324. FUIAction(FExecuteAction::CreateSP(const_cast<SExtContentBrowser*>(this), &SExtContentBrowser::OnPathMenuItemClicked, SubPath))
  2325. );
  2326. }
  2327. MenuWidget = MenuBuilder.MakeWidget();
  2328. }
  2329. }
  2330. if( MenuWidget.IsValid() )
  2331. {
  2332. // Do not allow the menu to become too large if there are many directories
  2333. Widget =
  2334. SNew( SVerticalBox )
  2335. +SVerticalBox::Slot()
  2336. .MaxHeight( 400.0f )
  2337. [
  2338. MenuWidget.ToSharedRef()
  2339. ];
  2340. }
  2341. return Widget;
  2342. }
  2343. TSharedRef<SWidget> SExtContentBrowser::GetPathPickerContent()
  2344. {
  2345. FPathPickerConfig PathPickerConfig;
  2346. FSourcesData SourcesData = AssetViewPtr->GetSourcesData();
  2347. if ( SourcesData.HasPackagePaths() )
  2348. {
  2349. PathPickerConfig.DefaultPath = SourcesData.PackagePaths[0].ToString();
  2350. }
  2351. PathPickerConfig.OnPathSelected = FOnPathSelected::CreateSP(this, &SExtContentBrowser::PathPickerPathSelected);
  2352. PathPickerConfig.bAllowContextMenu = false;
  2353. PathPickerConfig.bAllowClassesFolder = true;
  2354. return SNew(SBox)
  2355. .WidthOverride(300)
  2356. .HeightOverride(500)
  2357. .Padding(4)
  2358. [
  2359. SNew(SVerticalBox)
  2360. // Path Picker
  2361. +SVerticalBox::Slot()
  2362. .FillHeight(1.f)
  2363. [
  2364. FContentBrowserSingleton::Get().CreatePathPicker(PathPickerConfig)
  2365. ]
  2366. // Collection View
  2367. +SVerticalBox::Slot()
  2368. .AutoHeight()
  2369. .Padding(0, 6, 0, 0)
  2370. [
  2371. SNew(SCollectionView)
  2372. .AllowCollectionButtons(false)
  2373. .OnCollectionSelected(this, &SExtContentBrowser::PathPickerCollectionSelected)
  2374. .AllowContextMenu(false)
  2375. ]
  2376. ];
  2377. }
  2378. FString SExtContentBrowser::GetCurrentPath() const
  2379. {
  2380. FString CurrentPath;
  2381. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  2382. if ( SourcesData.HasPackagePaths() && SourcesData.PackagePaths[0] != NAME_None )
  2383. {
  2384. CurrentPath = SourcesData.PackagePaths[0].ToString();
  2385. }
  2386. return CurrentPath;
  2387. }
  2388. #endif
  2389. TSharedRef<SWidget> SExtContentBrowser::MakeAddNewContextMenu(bool bShowGetContent, bool bShowImport)
  2390. {
  2391. #if ECB_LEGACY
  2392. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  2393. int32 NumAssetPaths, NumClassPaths;
  2394. ContentBrowserUtils::CountPathTypes(SourcesData.PackagePaths, NumAssetPaths, NumClassPaths);
  2395. // Get all menu extenders for this context menu from the content browser module
  2396. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>( TEXT("ContentBrowser") );
  2397. TArray<FContentBrowserMenuExtender_SelectedPaths> MenuExtenderDelegates = ContentBrowserModule.GetAllAssetContextMenuExtenders();
  2398. // Delegate wants paths as FStrings
  2399. TArray<FString> SelectPaths;
  2400. for (FName PathName: SourcesData.PackagePaths)
  2401. {
  2402. SelectPaths.Add(PathName.ToString());
  2403. }
  2404. TArray<TSharedPtr<FExtender>> Extenders;
  2405. for (int32 i = 0; i < MenuExtenderDelegates.Num(); ++i)
  2406. {
  2407. if (MenuExtenderDelegates[i].IsBound())
  2408. {
  2409. Extenders.Add(MenuExtenderDelegates[i].Execute(SelectPaths));
  2410. }
  2411. }
  2412. TSharedPtr<FExtender> MenuExtender = FExtender::Combine(Extenders);
  2413. FMenuBuilder MenuBuilder(/*bInShouldCloseWindowAfterMenuSelection=*/true, NULL, MenuExtender);
  2414. // Only add "New Folder" item if we do not have a collection selected
  2415. FNewAssetOrClassContextMenu::FOnNewFolderRequested OnNewFolderRequested;
  2416. if (CollectionViewPtr->GetSelectedCollections().Num() == 0)
  2417. {
  2418. OnNewFolderRequested = FNewAssetOrClassContextMenu::FOnNewFolderRequested::CreateSP(this, &SExtContentBrowser::NewFolderRequested);
  2419. }
  2420. // New feature packs don't depend on the current paths, so we always add this item if it was requested
  2421. FNewAssetOrClassContextMenu::FOnGetContentRequested OnGetContentRequested;
  2422. if(bShowGetContent)
  2423. {
  2424. OnGetContentRequested = FNewAssetOrClassContextMenu::FOnGetContentRequested::CreateSP(this, &SExtContentBrowser::OnAddContentRequested);
  2425. }
  2426. // Only the asset items if we have an asset path selected
  2427. FNewAssetOrClassContextMenu::FOnNewAssetRequested OnNewAssetRequested;
  2428. FNewAssetOrClassContextMenu::FOnImportAssetRequested OnImportAssetRequested;
  2429. if(NumAssetPaths > 0)
  2430. {
  2431. OnNewAssetRequested = FNewAssetOrClassContextMenu::FOnNewAssetRequested::CreateSP(this, &SExtContentBrowser::NewAssetRequested);
  2432. if(bShowImport)
  2433. {
  2434. OnImportAssetRequested = FNewAssetOrClassContextMenu::FOnImportAssetRequested::CreateSP(this, &SExtContentBrowser::ImportAsset);
  2435. }
  2436. }
  2437. // This menu always lets you create classes, but uses your default project source folder if the selected path is invalid for creating classes
  2438. FNewAssetOrClassContextMenu::FOnNewClassRequested OnNewClassRequested = FNewAssetOrClassContextMenu::FOnNewClassRequested::CreateSP(this, &SExtContentBrowser::NewClassRequested);
  2439. FNewAssetOrClassContextMenu::MakeContextMenu(
  2440. MenuBuilder,
  2441. SourcesData.PackagePaths,
  2442. OnNewAssetRequested,
  2443. OnNewClassRequested,
  2444. OnNewFolderRequested,
  2445. OnImportAssetRequested,
  2446. OnGetContentRequested
  2447. );
  2448. FDisplayMetrics DisplayMetrics;
  2449. FSlateApplication::Get().GetCachedDisplayMetrics( DisplayMetrics );
  2450. const FVector2D DisplaySize(
  2451. DisplayMetrics.PrimaryDisplayWorkAreaRect.Right - DisplayMetrics.PrimaryDisplayWorkAreaRect.Left,
  2452. DisplayMetrics.PrimaryDisplayWorkAreaRect.Bottom - DisplayMetrics.PrimaryDisplayWorkAreaRect.Top );
  2453. return
  2454. SNew(SVerticalBox)
  2455. +SVerticalBox::Slot()
  2456. .MaxHeight(DisplaySize.Y * 0.9)
  2457. [
  2458. MenuBuilder.MakeWidget()
  2459. ];
  2460. #endif
  2461. return SNullWidget::NullWidget;
  2462. }
  2463. #if ECB_LEGACY
  2464. bool SExtContentBrowser::IsAddNewEnabled() const
  2465. {
  2466. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  2467. return SourcesData.PackagePaths.Num() == 1;
  2468. }
  2469. FText SExtContentBrowser::GetAddNewToolTipText() const
  2470. {
  2471. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  2472. if ( SourcesData.PackagePaths.Num() == 1 )
  2473. {
  2474. const FString CurrentPath = SourcesData.PackagePaths[0].ToString();
  2475. if ( ContentBrowserUtils::IsClassPath( CurrentPath ) )
  2476. {
  2477. return FText::Format( LOCTEXT("AddNewToolTip_AddNewClass", "Create a new class in {0}..."), FText::FromString(CurrentPath) );
  2478. }
  2479. else
  2480. {
  2481. return FText::Format( LOCTEXT("AddNewToolTip_AddNewAsset", "Create a new asset in {0}..."), FText::FromString(CurrentPath) );
  2482. }
  2483. }
  2484. else if ( SourcesData.PackagePaths.Num() > 1 )
  2485. {
  2486. return LOCTEXT( "AddNewToolTip_MultiplePaths", "Cannot add assets or classes to multiple paths." );
  2487. }
  2488. return LOCTEXT( "AddNewToolTip_NoPath", "No path is selected as an add target." );
  2489. }
  2490. #endif
  2491. TSharedRef<SWidget> SExtContentBrowser::MakeAddFilterMenu()
  2492. {
  2493. return FilterListPtr->ExternalMakeAddFilterMenu();
  2494. }
  2495. TSharedPtr<SWidget> SExtContentBrowser::GetFilterContextMenu()
  2496. {
  2497. return FilterListPtr->ExternalMakeAddFilterMenu();
  2498. }
  2499. FReply SExtContentBrowser::HandleImportClicked()
  2500. {
  2501. const int32 NumSelected = AssetViewPtr->GetNumSelectedAssets();
  2502. #if ECB_WIP_MULTI_IMPORT
  2503. if (NumSelected > 0)
  2504. #else
  2505. if (NumSelected == 1)
  2506. #endif
  2507. {
  2508. const TArray<FExtAssetData> SelectedAssets = AssetViewPtr->GetSelectedAssets();
  2509. ImportAsset(SelectedAssets);
  2510. }
  2511. return FReply::Handled();
  2512. }
  2513. FReply SExtContentBrowser::HandleFlatImportClicked()
  2514. {
  2515. const TArray<FExtAssetData> SelectedAssets = AssetViewPtr->GetSelectedAssets();
  2516. ImportAssetFlatMode(SelectedAssets);
  2517. return FReply::Handled();
  2518. }
  2519. FReply SExtContentBrowser::HandleImportToSandboxClicked()
  2520. {
  2521. const TArray<FExtAssetData> SelectedAssets = AssetViewPtr->GetSelectedAssets();
  2522. ImportAssetToSandbox(SelectedAssets);
  2523. return FReply::Handled();
  2524. }
  2525. FReply SExtContentBrowser::HandleExportAssetClicked()
  2526. {
  2527. const TArray<FExtAssetData> SelectedAssets = AssetViewPtr->GetSelectedAssets();
  2528. FExtAssetImporter::ExportAssets(SelectedAssets);
  2529. return FReply::Handled();
  2530. }
  2531. bool SExtContentBrowser::IsExportAssetEnabled() const
  2532. {
  2533. return IsImportEnabled();
  2534. }
  2535. FReply SExtContentBrowser::HandleZipExportClicked()
  2536. {
  2537. const TArray<FExtAssetData> SelectedAssets = AssetViewPtr->GetSelectedAssets();
  2538. FExtAssetImporter::ZipUpSourceAssets(SelectedAssets);
  2539. return FReply::Handled();
  2540. }
  2541. void SExtContentBrowser::ImportAsset(const TArray<FExtAssetData>& InAssetDatas)
  2542. {
  2543. FExtAssetImporter::ImportAssets(InAssetDatas, FUAssetImportSetting::GetSavedImportSetting());
  2544. }
  2545. void SExtContentBrowser::ImportAssetToSandbox(const TArray<FExtAssetData>& InAssetDatas)
  2546. {
  2547. FUAssetImportSetting ImportSetting = FUAssetImportSetting::GetSandboxImportSetting();
  2548. FExtAssetImporter::ImportAssets(InAssetDatas, ImportSetting);
  2549. }
  2550. void SExtContentBrowser::ImportAssetFlatMode(const TArray<FExtAssetData>& InAssetDatas)
  2551. {
  2552. #if ECB_TODO // todo: double check flat import a level
  2553. // Map is not supported
  2554. for (const FExtAssetData& AssetData : InAssetDatas)
  2555. {
  2556. if (AssetData.AssetClass == UWorld::StaticClass()->GetFName())
  2557. {
  2558. ExtContentBrowserUtils::DisplayMessagePopup(FText::FromString(TEXT("Map is not supporting Flat Import.")));
  2559. return;
  2560. }
  2561. }
  2562. #endif
  2563. FUAssetImportSetting ImportSetting = FUAssetImportSetting::GetFlatModeImportSetting();
  2564. FExtAssetImporter::ImportAssetsWithPathPicker(InAssetDatas, ImportSetting);
  2565. }
  2566. bool SExtContentBrowser::IsValidateEnabled() const
  2567. {
  2568. return IsImportEnabled();
  2569. }
  2570. FReply SExtContentBrowser::HandleValidateclicked()
  2571. {
  2572. const TArray<FExtAssetData> SelectedAssets = AssetViewPtr->GetSelectedAssets();
  2573. if (SelectedAssets.Num() > 0)
  2574. {
  2575. FString ResultMessage;
  2576. FExtAssetValidator::ValidateDependency(SelectedAssets, &ResultMessage, /*bShowProgess*/ true);
  2577. if (SelectedAssets.Num() == 1)
  2578. {
  2579. ExtContentBrowserUtils::DisplayMessagePopup(FText::FromString(ResultMessage));
  2580. }
  2581. else
  2582. {
  2583. ExtContentBrowserUtils::NotifyMessage(FText::FromString(ResultMessage));
  2584. }
  2585. }
  2586. return FReply::Handled();
  2587. }
  2588. #if ECB_WIP_CACHEDB
  2589. FReply SExtContentBrowser::HandleLoadCacheDBclicked()
  2590. {
  2591. FExtContentBrowserSingleton::GetAssetRegistry().LoadCacheDB();
  2592. return FReply::Handled();
  2593. }
  2594. FReply SExtContentBrowser::HandleSaveCacheDBClicked()
  2595. {
  2596. FExtContentBrowserSingleton::GetAssetRegistry().SaveCacheDB(/*bSilent =*/ false);
  2597. return FReply::Handled();
  2598. }
  2599. FReply SExtContentBrowser::HandleSaveAndSwitchToCacheModeClicked()
  2600. {
  2601. FExtContentBrowserSingleton::GetAssetRegistry().SaveCacheDB(/*bSilent =*/ false);
  2602. UExtContentBrowserSettings* ExtContentBrowserSetting = GetMutableDefault<UExtContentBrowserSettings>();
  2603. if (!ExtContentBrowserSetting->bCacheMode)
  2604. {
  2605. ExtContentBrowserSetting->bCacheMode = true;
  2606. FExtContentBrowserSingleton::GetAssetRegistry().SwitchCacheMode();
  2607. }
  2608. return FReply::Handled();
  2609. }
  2610. FReply SExtContentBrowser::HandlePurgeCacheDBClicked()
  2611. {
  2612. int32 NumPurged = FExtContentBrowserSingleton::GetAssetRegistry().PurgeCacheDB(/*bSilent*/false);
  2613. return FReply::Handled();
  2614. }
  2615. void SExtContentBrowser::HandleSwitchAndLoadCacheDBClicked(const FString& PickedPath)
  2616. {
  2617. FString CleanPath = PickedPath.TrimStartAndEnd();
  2618. CleanPath = FPaths::ConvertRelativePathToFull(CleanPath);
  2619. FPaths::NormalizeDirectoryName(CleanPath);
  2620. UExtContentBrowserSettings* ExtContentBrowserSettings = GetMutableDefault<UExtContentBrowserSettings>();
  2621. if (ExtContentBrowserSettings->CacheFilePath.FilePath.Equals(CleanPath, ESearchCase::IgnoreCase))
  2622. {
  2623. return;
  2624. }
  2625. const bool bCacheMode = ExtContentBrowserSettings->bCacheMode;
  2626. FString OrigFilePath = ExtContentBrowserSettings->CacheFilePath.FilePath;
  2627. ExtContentBrowserSettings->CacheFilePath.FilePath = CleanPath;
  2628. if (!FPaths::FileExists(CleanPath))
  2629. {
  2630. FExtContentBrowserSingleton::GetAssetRegistry().SaveCacheDB(/*bSilent =*/ true);
  2631. FString Message = FString::Printf(TEXT("Cache file path: %s does not exist, new file created."), *CleanPath);
  2632. ExtContentBrowserUtils::NotifyMessage(Message);
  2633. }
  2634. else
  2635. {
  2636. FString Message;
  2637. if (bCacheMode)
  2638. {
  2639. if (FExtContentBrowserSingleton::GetAssetRegistry().LoadCacheDB(/*bSilent =*/ true))
  2640. {
  2641. Message = FString::Printf(TEXT("Use cache file path: %s."), *CleanPath);
  2642. FExtContentBrowserSingleton::GetAssetRegistry().LoadRootContentPaths();
  2643. }
  2644. else
  2645. {
  2646. Message = FString::Printf(TEXT("Can't use cache file: %s."), *CleanPath);
  2647. ExtContentBrowserSettings->CacheFilePath.FilePath = OrigFilePath;
  2648. }
  2649. }
  2650. ExtContentBrowserUtils::NotifyMessage(Message);
  2651. }
  2652. ExtContentBrowserSettings->PostEditChange();
  2653. }
  2654. FText SExtContentBrowser::GetSaveAndSwitchToCacheModeText() const
  2655. {
  2656. const UExtContentBrowserSettings* ExtContentBrowserSettings = GetDefault<UExtContentBrowserSettings>();
  2657. const bool bCacheMode = ExtContentBrowserSettings->bCacheMode;
  2658. return bCacheMode ? LOCTEXT("Save", "Save") : LOCTEXT("Cache", "Cache");
  2659. }
  2660. FText SExtContentBrowser::GetCacheStatusText() const
  2661. {
  2662. int32 NumFoldersCached = FExtContentBrowserSingleton::GetAssetRegistry().GetNumFoldersInCache();
  2663. int32 NumAssetsCached = FExtContentBrowserSingleton::GetAssetRegistry().GetNumAssetsInCache();
  2664. int32 NumFoldersMem = FExtContentBrowserSingleton::GetAssetRegistry().GetNumFoldersInMem();
  2665. int32 NumAssetsMem = FExtContentBrowserSingleton::GetAssetRegistry().GetNumAssetsInMem();
  2666. FText CacheStatus = FText::Format(LOCTEXT("CacheStatusText", "{0} folders {1} assets cached, {2} assets in memory. ")
  2667. , FText::AsNumber(NumFoldersCached)
  2668. , FText::AsNumber(NumAssetsCached)
  2669. , FText::AsNumber(NumAssetsMem));
  2670. FText CacheStatusNonCacheMode = FText::Format(LOCTEXT("CacheStatusNonCacheModeText", "{0} folders {1} assets in memory. ")
  2671. , FText::AsNumber(NumFoldersMem)
  2672. , FText::AsNumber(NumAssetsMem));
  2673. const UExtContentBrowserSettings* ExtContentBrowserSettings = GetDefault<UExtContentBrowserSettings>();
  2674. const bool bCacheMode = ExtContentBrowserSettings->bCacheMode;
  2675. return bCacheMode ? CacheStatus : CacheStatusNonCacheMode;
  2676. }
  2677. EVisibility SExtContentBrowser::GetCacheStatusBarVisibility() const
  2678. {
  2679. const UExtContentBrowserSettings* ExtContentBrowserSettings = GetDefault<UExtContentBrowserSettings>();
  2680. return (ExtContentBrowserSettings->bCacheMode || ExtContentBrowserSettings->bShowCacheStatusBarInLiveMode)
  2681. ? EVisibility::Visible : EVisibility::Collapsed;
  2682. }
  2683. #endif
  2684. #if ECB_FEA_IMPORT_OPTIONS
  2685. FSlateColor SExtContentBrowser::GetImportOptionsButtonForegroundColor() const
  2686. {
  2687. static const FName InvertedForegroundName("InvertedForeground");
  2688. static const FName DefaultForegroundName("DefaultForeground");
  2689. return ImportOptionsComboButton->IsHovered() ? FAppStyle::GetSlateColor(InvertedForegroundName) : FAppStyle::GetSlateColor(DefaultForegroundName);
  2690. }
  2691. DECLARE_DELEGATE(FOnColorPicked);
  2692. DECLARE_DELEGATE(FOnSpintBoxVauleComitted);
  2693. namespace LocalWidgetHelpers
  2694. {
  2695. TSharedRef<SWidget> CreateColorWidget(FLinearColor* Color, FOnColorPicked OnColorPicked = FOnColorPicked())
  2696. {
  2697. auto GetValue = [=] {
  2698. return *Color;
  2699. };
  2700. auto SetValue = [=](FLinearColor NewColor) {
  2701. *Color = NewColor;
  2702. OnColorPicked.ExecuteIfBound();
  2703. };
  2704. auto OnGetMenuContent = [=]() -> TSharedRef<SWidget> {
  2705. // Open a color picker
  2706. return SNew(SColorPicker)
  2707. .TargetColorAttribute_Lambda(GetValue)
  2708. .UseAlpha(true)
  2709. .DisplayInlineVersion(true)
  2710. .OnColorCommitted_Lambda(SetValue);
  2711. };
  2712. return SNew(SComboButton)
  2713. .ContentPadding(0)
  2714. .HasDownArrow(false)
  2715. .ButtonStyle(FAppStyle::Get(), "Sequencer.AnimationOutliner.ColorStrip")
  2716. .OnGetMenuContent_Lambda(OnGetMenuContent)
  2717. .CollapseMenuOnParentFocus(true)
  2718. .ButtonContent()
  2719. [
  2720. SNew(SColorBlock)
  2721. .Color_Lambda(GetValue)
  2722. .ShowBackgroundForAlpha(true)
  2723. .AlphaDisplayMode(EColorBlockAlphaDisplayMode::Ignore)
  2724. .Size(FVector2D(10.0f, 10.0f))
  2725. ];
  2726. }
  2727. template<typename T>
  2728. TSharedRef<SWidget> CreateSpinBox(T* Value, T Min, T Max, FOnSpintBoxVauleComitted OnSpintBoxVauleComitted = FOnSpintBoxVauleComitted(), TSharedPtr<INumericTypeInterface<T>> TypeInterface = nullptr)
  2729. {
  2730. auto GetValue = [=] { return *Value; };
  2731. auto SetValue = [=](T NewValue) { *Value = NewValue; };
  2732. auto SetValueCommitted = [=](T NewValue, ETextCommit::Type) { *Value = NewValue; OnSpintBoxVauleComitted.ExecuteIfBound(); };
  2733. return SNew(SSpinBox<T>)
  2734. .MinValue(Min)
  2735. .MaxValue(Max)
  2736. .Value_Lambda(GetValue)
  2737. .OnValueChanged_Lambda(SetValue)
  2738. .OnValueCommitted_Lambda(SetValueCommitted)
  2739. .TypeInterface(TypeInterface);
  2740. }
  2741. }
  2742. TSharedRef<SWidget> SExtContentBrowser::GetImportOptionsButtonContent()
  2743. {
  2744. UExtContentBrowserSettings* ExtContentBrowserSetting = GetMutableDefault<UExtContentBrowserSettings>();
  2745. FMenuBuilder MenuBuilder(/*bInShouldCloseWindowAfterMenuSelection=*/true, NULL, TSharedPtr<FExtender>(), /*bCloseSelfOnly=*/ true);
  2746. #if ECB_WIP_CACHEDB
  2747. MenuBuilder.BeginSection("CacheDB", LOCTEXT("CacheHeading", "Cache"));
  2748. {
  2749. // Enable CacheMode
  2750. MenuBuilder.AddMenuEntry(
  2751. LOCTEXT("CacheMode", "Cache Mode"),
  2752. LOCTEXT("CacheModeTooltip", "Use Cache for uasset files information. Please note that cache info might not in sync with uasset files on disk."),
  2753. FSlateIcon(),
  2754. FUIAction(
  2755. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting]
  2756. {
  2757. bool bWasCacheMode = ExtContentBrowserSetting->bCacheMode;
  2758. ExtContentBrowserSetting->bCacheMode = !ExtContentBrowserSetting->bCacheMode;
  2759. ExtContentBrowserSetting->PostEditChange();
  2760. if (bWasCacheMode && ExtContentBrowserSetting->bAutoSaveCacheOnSwitchToCacheMode)
  2761. {
  2762. FExtContentBrowserSingleton::GetAssetRegistry().SaveCacheDB();
  2763. }
  2764. FExtContentBrowserSingleton::GetAssetRegistry().SwitchCacheMode();
  2765. }),
  2766. FCanExecuteAction(),
  2767. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bCacheMode; })
  2768. ),
  2769. NAME_None,
  2770. EUserInterfaceActionType::ToggleButton
  2771. );
  2772. // Cache Mode Auto Save on Exit
  2773. #if ECB_FOLD
  2774. MenuBuilder.AddMenuEntry(
  2775. LOCTEXT("AutoSaveCacheOnExit", "Auto Save Cache on Exit"),
  2776. LOCTEXT("AutoSaveCacheOnExitTooltip", "Auto save cache on close uasset browser or leaving cache mode"),
  2777. FSlateIcon(),
  2778. FUIAction(
  2779. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bAutoSaveCacheOnExit = !ExtContentBrowserSetting->bAutoSaveCacheOnExit; ExtContentBrowserSetting->PostEditChange(); }),
  2780. FCanExecuteAction(),
  2781. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bAutoSaveCacheOnExit; })
  2782. ),
  2783. NAME_None,
  2784. EUserInterfaceActionType::ToggleButton
  2785. );
  2786. MenuBuilder.AddMenuEntry(
  2787. LOCTEXT("AutoSaveCacheOnSwitchToCacheMode", "Auto Save Cache When Switch To Cache Mode"),
  2788. LOCTEXT("AutoSaveCacheOnSwitchToCacheModeTooltip", "Auto save cache when switching to cache mode"),
  2789. FSlateIcon(),
  2790. FUIAction(
  2791. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bAutoSaveCacheOnSwitchToCacheMode = !ExtContentBrowserSetting->bAutoSaveCacheOnSwitchToCacheMode; ExtContentBrowserSetting->PostEditChange(); }),
  2792. FCanExecuteAction(),
  2793. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bAutoSaveCacheOnSwitchToCacheMode; })
  2794. ),
  2795. NAME_None,
  2796. EUserInterfaceActionType::ToggleButton
  2797. );
  2798. // Cache Mode Auto Save on Close
  2799. MenuBuilder.AddMenuEntry(
  2800. LOCTEXT("KeepCachedAssetsWhenRootRemoved", "Keep Cached Assets When Folder Removed"),
  2801. LOCTEXT("KeepCachedAssetsWhenRootRemovedTooltip", "Keep cached assets when root content folder removed."),
  2802. FSlateIcon(),
  2803. FUIAction(
  2804. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bKeepCachedAssetsWhenRootRemoved = !ExtContentBrowserSetting->bKeepCachedAssetsWhenRootRemoved; ExtContentBrowserSetting->PostEditChange(); }),
  2805. FCanExecuteAction(),
  2806. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bKeepCachedAssetsWhenRootRemoved; })
  2807. ),
  2808. NAME_None,
  2809. EUserInterfaceActionType::ToggleButton
  2810. );
  2811. #endif
  2812. // Always Show Cache Status Bar
  2813. #if ECB_FOLD
  2814. MenuBuilder.AddMenuEntry(
  2815. LOCTEXT("ShowCacheStatusBarOnLiveMode", "Show Cache StatusBar in Live Mode"),
  2816. LOCTEXT("ShowCacheStatusBarOnLiveModeTooltip", "Show Cache StatusBar in both Live Mode and Cache Mode"),
  2817. FSlateIcon(),
  2818. FUIAction(
  2819. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bShowCacheStatusBarInLiveMode = !ExtContentBrowserSetting->bShowCacheStatusBarInLiveMode; ExtContentBrowserSetting->PostEditChange(); }),
  2820. FCanExecuteAction(),
  2821. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bShowCacheStatusBarInLiveMode; })
  2822. ),
  2823. NAME_None,
  2824. EUserInterfaceActionType::ToggleButton
  2825. );
  2826. #endif
  2827. // Cache Mode Border Color
  2828. MenuBuilder.AddWidget(
  2829. LocalWidgetHelpers::CreateColorWidget(&ExtContentBrowserSetting->CacheModeBorderColor, FOnColorPicked::CreateLambda([this, ExtContentBrowserSetting] {
  2830. ExtContentBrowserSetting->PostEditChange();
  2831. }))
  2832. , LOCTEXT("CacheModeBorderColor", "Cache Mode Border Color"));
  2833. MenuBuilder.AddSeparator();
  2834. // Purge Cache DB
  2835. #if ECB_FOLD
  2836. MenuBuilder.AddMenuEntry(
  2837. LOCTEXT("PurgeCacheDB", "Purge and Save Cache"),
  2838. LOCTEXT("PurgeCacheDBTooltip", "Purge unused assets data in the cache db."),
  2839. FSlateIcon(),
  2840. FUIAction(
  2841. FExecuteAction::CreateLambda([this] { SExtContentBrowser::HandlePurgeCacheDBClicked(); })
  2842. ),
  2843. NAME_None,
  2844. EUserInterfaceActionType::Button
  2845. );
  2846. #endif
  2847. #if 0
  2848. TSharedRef<SWidget> CacheDBFilePathPicker = SNew(SFilePathPicker)
  2849. .BrowseButtonImage(FAppStyle::GetBrush("PropertyWindow.Button_Ellipsis"))
  2850. .BrowseButtonStyle(FAppStyle::Get(), "HoverHintOnly")
  2851. .BrowseButtonToolTip(LOCTEXT("FilePathBrowseButtonToolTip", "Choose a file to uase as UAsset Browser Cache Database"))
  2852. .BrowseDirectory(FPaths::ProjectSavedDir() )
  2853. .FilePath_Lambda([this, ExtContentBrowserSetting]() -> FString
  2854. {
  2855. return ExtContentBrowserSetting->CacheDBFilePath.FilePath;
  2856. })
  2857. .FileTypeFilter_Lambda([]() -> FString
  2858. {
  2859. return TEXT("All files (*.*)|*.*|CacheDB files (*.cachedb)|*.cachedb");
  2860. })
  2861. .OnPathPicked(this, &SExtContentBrowser::HandleCacheDBFilePathPicked)
  2862. .ToolTipText(LOCTEXT("FilePathToolTip", "The path to Uasset Browser Cache Database file"));
  2863. MenuBuilder.AddWidget(CacheDBFilePathPicker, LOCTEXT("CacheDBFilePath", "CacheDB File"));
  2864. #endif
  2865. }
  2866. MenuBuilder.EndSection();
  2867. #endif
  2868. #if ECB_WIP_OBJECT_THUMB_POOL
  2869. MenuBuilder.BeginSection("CacheDB", LOCTEXT("ThumbnailPoolHeading", "Thumbnail Pool"));
  2870. {
  2871. // Use Thumbnail Pool
  2872. MenuBuilder.AddMenuEntry(
  2873. LOCTEXT("UseThumbnailPool", "Use Thumbnail Pool"),
  2874. LOCTEXT("UseThumbnailPoolTooltip", "Use thumbnial pool in memeory to store thumbnail data."),
  2875. FSlateIcon(),
  2876. FUIAction(
  2877. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting]
  2878. {
  2879. bool bWasUseThumbnailPool = ExtContentBrowserSetting->bUseThumbnailPool;
  2880. ExtContentBrowserSetting->bUseThumbnailPool = !ExtContentBrowserSetting->bUseThumbnailPool;
  2881. ExtContentBrowserSetting->PostEditChange();
  2882. if (ExtContentBrowserSetting->bUseThumbnailPool) // now use thumbnail pool
  2883. {
  2884. FExtContentBrowserSingleton::GetThumbnailPool().Resize(ExtContentBrowserSetting->NumThumbnailsInPool);
  2885. }
  2886. else // turn off thumbnail pool
  2887. {
  2888. FExtContentBrowserSingleton::GetThumbnailPool().Free();
  2889. }
  2890. }),
  2891. FCanExecuteAction(),
  2892. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bUseThumbnailPool; })
  2893. ),
  2894. NAME_None,
  2895. EUserInterfaceActionType::ToggleButton
  2896. );
  2897. // Cache Mode Border Color
  2898. MenuBuilder.AddWidget(
  2899. LocalWidgetHelpers::CreateSpinBox<int32>(&ExtContentBrowserSetting->NumThumbnailsInPool, 1, 1024 * 1024, FOnSpintBoxVauleComitted::CreateLambda([this, ExtContentBrowserSetting] {
  2900. if (ExtContentBrowserSetting->bUseThumbnailPool) // now use thumbnail pool
  2901. {
  2902. FExtContentBrowserSingleton::GetThumbnailPool().Resize(ExtContentBrowserSetting->NumThumbnailsInPool);
  2903. }
  2904. ExtContentBrowserSetting->PostEditChange();
  2905. }))
  2906. , LOCTEXT("NumThumbnailsInPool", "Max Num Thumbnails in Pool"));
  2907. }
  2908. MenuBuilder.EndSection();
  2909. #endif
  2910. MenuBuilder.BeginSection("Import", LOCTEXT("ImportHeading", "Import"));
  2911. {
  2912. MenuBuilder.AddMenuEntry(
  2913. LOCTEXT("SkipImportIfAnyDependencyMissing", "Abort If Dependency Missing"),
  2914. LOCTEXT("SkipImportIfAnyDependencyMissingTooltip", "Abort importing if any dependency of selected uasset file is missing"),
  2915. FSlateIcon(),
  2916. FUIAction(
  2917. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bSkipImportIfAnyDependencyMissing = !ExtContentBrowserSetting->bSkipImportIfAnyDependencyMissing; ExtContentBrowserSetting->PostEditChange(); }),
  2918. FCanExecuteAction(),
  2919. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bSkipImportIfAnyDependencyMissing; })
  2920. ),
  2921. NAME_None,
  2922. EUserInterfaceActionType::ToggleButton
  2923. );
  2924. #if ECB_FEA_IMPORT_IGNORE_SOFT_ERROR
  2925. MenuBuilder.AddMenuEntry(
  2926. LOCTEXT("IgnoreSoftReferencesError", "Ignore Soft References Error"),
  2927. LOCTEXT("IgnoreSoftReferencesErrorTooltip", "Always ignore missing or invalid soft references when importing"),
  2928. FSlateIcon(),
  2929. FUIAction(
  2930. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bImportIgnoreSoftReferencesError = !ExtContentBrowserSetting->bImportIgnoreSoftReferencesError; ExtContentBrowserSetting->PostEditChange(); }),
  2931. FCanExecuteAction(),
  2932. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportIgnoreSoftReferencesError; })
  2933. ),
  2934. NAME_None,
  2935. EUserInterfaceActionType::ToggleButton
  2936. );
  2937. #endif
  2938. MenuBuilder.AddMenuEntry(
  2939. LOCTEXT("OverwriteExistingFiles", "Overwrite Existing Assets"),
  2940. LOCTEXT("OverwriteExistingFilesTooltip", "Overwrite existing files when importing uasset and its dependencies or use existing files instead"),
  2941. FSlateIcon(),
  2942. FUIAction(
  2943. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bImportOverwriteExistingFiles = !ExtContentBrowserSetting->bImportOverwriteExistingFiles; ExtContentBrowserSetting->PostEditChange(); }),
  2944. FCanExecuteAction(),
  2945. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportOverwriteExistingFiles; })
  2946. ),
  2947. NAME_None,
  2948. EUserInterfaceActionType::ToggleButton
  2949. );
  2950. MenuBuilder.AddMenuEntry(
  2951. LOCTEXT("RollbackIfFailed", "Rollback If Failed"),
  2952. LOCTEXT("RollbackIfFailedTooltip", "Delete imported uasset and dependencies and restore any replaced files if import failed"),
  2953. FSlateIcon(),
  2954. FUIAction(
  2955. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bRollbackImportIfFailed = !ExtContentBrowserSetting->bRollbackImportIfFailed; ExtContentBrowserSetting->PostEditChange(); }),
  2956. FCanExecuteAction(),
  2957. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bRollbackImportIfFailed; })
  2958. ),
  2959. NAME_None,
  2960. EUserInterfaceActionType::ToggleButton
  2961. );
  2962. MenuBuilder.AddSeparator();
  2963. #if ECB_WIP_IMPORT_FOLDER_COLOR
  2964. MenuBuilder.AddMenuEntry(
  2965. LOCTEXT("ImportFolderColor", "Import Folder Color"),
  2966. LOCTEXT("ImportFolderColorTooltip", "Import folder color definiation to current project"),
  2967. FSlateIcon(),
  2968. FUIAction(
  2969. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bImportFolderColor = !ExtContentBrowserSetting->bImportFolderColor; ExtContentBrowserSetting->PostEditChange(); }),
  2970. FCanExecuteAction(),
  2971. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportFolderColor; })
  2972. ),
  2973. NAME_None,
  2974. EUserInterfaceActionType::ToggleButton
  2975. );
  2976. #if ECB_WIP_IMPORT_FOLDER_COLOR_OVERRIDE
  2977. MenuBuilder.AddMenuEntry(
  2978. LOCTEXT("OverrideExistingFolderColor", "Override Existing Folder Color"),
  2979. LOCTEXT("OverrideExistingFolderColorTooltip", "Wheter override existing folder color or skip import folder color when exist"),
  2980. FSlateIcon(),
  2981. FUIAction(
  2982. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bOverrideExistingFolderColor = !ExtContentBrowserSetting->bOverrideExistingFolderColor; ExtContentBrowserSetting->PostEditChange(); }),
  2983. FCanExecuteAction(),
  2984. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bOverrideExistingFolderColor; })
  2985. ),
  2986. NAME_None,
  2987. EUserInterfaceActionType::ToggleButton
  2988. );
  2989. #endif
  2990. #endif
  2991. MenuBuilder.AddSeparator();
  2992. #if ECB_WIP_IMPORT_TO_PLUGIN_FOLDER
  2993. MenuBuilder.AddMenuEntry(
  2994. LOCTEXT("ImportToPlugin", "Import to Plugin"),
  2995. LOCTEXT("ImportToPluginTooltip", "Import to project's plugin content folder"),
  2996. FSlateIcon(),
  2997. FUIAction(
  2998. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bImportToPluginFolder = !ExtContentBrowserSetting->bImportToPluginFolder; ExtContentBrowserSetting->PostEditChange(); }),
  2999. FCanExecuteAction(),
  3000. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportToPluginFolder; })
  3001. ),
  3002. NAME_None,
  3003. EUserInterfaceActionType::ToggleButton
  3004. );
  3005. MenuBuilder.AddMenuEntry(
  3006. LOCTEXT("WarnBeforeImportToPluginFolder", "Ask Before Import to Plugin"),
  3007. LOCTEXT("WarnBeforeImportToPluginFolderTooltip", "Always show confirmation dialog before importing to a plugin"),
  3008. FSlateIcon(),
  3009. FUIAction(
  3010. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bWarnBeforeImportToPluginFolder = !ExtContentBrowserSetting->bWarnBeforeImportToPluginFolder; ExtContentBrowserSetting->PostEditChange(); }),
  3011. FCanExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportToPluginFolder; }),
  3012. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bWarnBeforeImportToPluginFolder; })
  3013. ),
  3014. NAME_None,
  3015. EUserInterfaceActionType::ToggleButton
  3016. );
  3017. TSharedRef<SWidget> ImportToPluginName = SNew(SEditableTextBox)
  3018. .Text_Lambda([this, ExtContentBrowserSetting]()
  3019. {
  3020. return FText::FromName(ExtContentBrowserSetting->ImportToPluginName);
  3021. })
  3022. .IsEnabled_Lambda([this, ExtContentBrowserSetting]()
  3023. {
  3024. return ExtContentBrowserSetting->bImportToPluginFolder;
  3025. })
  3026. .OnTextCommitted_Lambda([this, ExtContentBrowserSetting](const FText& InText, ETextCommit::Type)
  3027. {
  3028. if (!InText.IsEmpty())
  3029. {
  3030. ExtContentBrowserSetting->ImportToPluginName = *InText.ToString();
  3031. }
  3032. });
  3033. MenuBuilder.AddWidget(ImportToPluginName, LOCTEXT("PluginName", "Plugin Name"));
  3034. #endif
  3035. }
  3036. MenuBuilder.EndSection();
  3037. MenuBuilder.BeginSection("PostImport", LOCTEXT("PostImportHeading", "Post Import"));
  3038. {
  3039. MenuBuilder.AddMenuEntry(
  3040. LOCTEXT("SyncAssetsInContentBrowser", "Sync Improted Assets In Content Browser"),
  3041. LOCTEXT("SyncAssetsInContentBrowserTooltip", "Find imported assets in Content Browser"),
  3042. FSlateIcon(),
  3043. FUIAction(
  3044. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bImportSyncAssetsInContentBrowser = !ExtContentBrowserSetting->bImportSyncAssetsInContentBrowser; ExtContentBrowserSetting->PostEditChange(); }),
  3045. FCanExecuteAction(),
  3046. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportSyncAssetsInContentBrowser; })
  3047. ),
  3048. NAME_None,
  3049. EUserInterfaceActionType::ToggleButton
  3050. );
  3051. MenuBuilder.AddMenuEntry(
  3052. LOCTEXT("SyncExistingAssets", "Sync Skipped Existing Assets"),
  3053. LOCTEXT("SyncExistingAssetsTooltip", "Find existing assets skipped for import in Content Browser, by default only find new imported assets"),
  3054. FSlateIcon(),
  3055. FUIAction(
  3056. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bImportSyncExistingAssets = !ExtContentBrowserSetting->bImportSyncExistingAssets; ExtContentBrowserSetting->PostEditChange(); }),
  3057. FCanExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportSyncAssetsInContentBrowser; }),
  3058. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bImportSyncExistingAssets; })
  3059. ),
  3060. NAME_None,
  3061. EUserInterfaceActionType::ToggleButton
  3062. );
  3063. MenuBuilder.AddMenuEntry(
  3064. LOCTEXT("LoadAssetAfterImport", "Load/Reload Assets After Import"),
  3065. LOCTEXT("LoadAssetAfterImportTooltip", "Load or reload import assets into memory immediately after import"),
  3066. FSlateIcon(),
  3067. FUIAction(
  3068. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bLoadAssetAfterImport = !ExtContentBrowserSetting->bLoadAssetAfterImport; ExtContentBrowserSetting->PostEditChange(); }),
  3069. FCanExecuteAction(),
  3070. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bLoadAssetAfterImport; })
  3071. ),
  3072. NAME_None,
  3073. EUserInterfaceActionType::ToggleButton
  3074. );
  3075. #if ECB_WIP_IMPORT_ADD_TO_COLLECTION
  3076. MenuBuilder.AddMenuEntry(
  3077. LOCTEXT("AddImportedToCollection", "Add to Collection"),
  3078. LOCTEXT("AddImportedToCollectionTooltip", "Add imported assets and dependencies into collection"),
  3079. FSlateIcon(),
  3080. FUIAction(
  3081. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bAddImportedAssetsToCollection = !ExtContentBrowserSetting->bAddImportedAssetsToCollection; ExtContentBrowserSetting->PostEditChange(); }),
  3082. FCanExecuteAction(),
  3083. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bAddImportedAssetsToCollection; })
  3084. ),
  3085. NAME_None,
  3086. EUserInterfaceActionType::ToggleButton
  3087. );
  3088. MenuBuilder.AddMenuEntry(
  3089. LOCTEXT("UniqueCollectionForEachImport", "Unique Collection for Each Import"),
  3090. LOCTEXT("UniqueCollectionForEachImportTooltip", "Make a unique collection for each import session"),
  3091. FSlateIcon(),
  3092. FUIAction(
  3093. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bUniqueCollectionNameForEachImportSession = !ExtContentBrowserSetting->bUniqueCollectionNameForEachImportSession; ExtContentBrowserSetting->PostEditChange(); }),
  3094. FCanExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bAddImportedAssetsToCollection; }),
  3095. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bUniqueCollectionNameForEachImportSession; })
  3096. ),
  3097. NAME_None,
  3098. EUserInterfaceActionType::ToggleButton
  3099. );
  3100. TSharedRef<SWidget> ImportedCollectionName = SNew(SEditableTextBox)
  3101. .Text_Lambda([this, ExtContentBrowserSetting]()
  3102. {
  3103. return FText::FromName(ExtContentBrowserSetting->DefaultImportedUAssetCollectionName);
  3104. })
  3105. .IsEnabled_Lambda([this, ExtContentBrowserSetting]()
  3106. {
  3107. return ExtContentBrowserSetting->bAddImportedAssetsToCollection;
  3108. })
  3109. .OnTextCommitted_Lambda([this, ExtContentBrowserSetting](const FText& InText, ETextCommit::Type)
  3110. {
  3111. if (!InText.IsEmpty())
  3112. {
  3113. ExtContentBrowserSetting->DefaultImportedUAssetCollectionName = *InText.ToString();
  3114. }
  3115. });
  3116. MenuBuilder.AddWidget(ImportedCollectionName, LOCTEXT("Collection", "Collection"));
  3117. #endif
  3118. }
  3119. MenuBuilder.EndSection();
  3120. #if ECB_WIP_EXPORT
  3121. MenuBuilder.BeginSection("Export", LOCTEXT("ExportHeading", "Export"));
  3122. {
  3123. MenuBuilder.AddMenuEntry(
  3124. LOCTEXT("SkipExportIfAnyDependencyMissing", "Abort If Dependency Missing"),
  3125. LOCTEXT("SkipExportIfAnyDependencyMissingTooltip", "Abort exporting if any dependency of selected uasset file is missing"),
  3126. FSlateIcon(),
  3127. FUIAction(
  3128. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bSkipExportIfAnyDependencyMissing = !ExtContentBrowserSetting->bSkipExportIfAnyDependencyMissing; ExtContentBrowserSetting->PostEditChange(); }),
  3129. FCanExecuteAction(),
  3130. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bSkipExportIfAnyDependencyMissing; })
  3131. ),
  3132. NAME_None,
  3133. EUserInterfaceActionType::ToggleButton
  3134. );
  3135. MenuBuilder.AddMenuEntry(
  3136. LOCTEXT("IgnoreSoftReferencesError", "Ignore Soft References Error"),
  3137. LOCTEXT("ExportIgnoreSoftReferencesErrorTooltip", "Always ignore missing or invalid soft references when exporting"),
  3138. FSlateIcon(),
  3139. FUIAction(
  3140. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bExportIgnoreSoftReferencesError = !ExtContentBrowserSetting->bExportIgnoreSoftReferencesError; ExtContentBrowserSetting->PostEditChange(); }),
  3141. FCanExecuteAction(),
  3142. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bExportIgnoreSoftReferencesError; })
  3143. ),
  3144. NAME_None,
  3145. EUserInterfaceActionType::ToggleButton
  3146. );
  3147. MenuBuilder.AddMenuEntry(
  3148. LOCTEXT("OverwriteExistingFiles", "Overwrite Existing Assets"),
  3149. LOCTEXT("ExportOverwriteExistingFilesTooltip", "Overwrite existing files when exporting uasset and its dependencies or use existing files instead"),
  3150. FSlateIcon(),
  3151. FUIAction(
  3152. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bExportOverwriteExistingFiles = !ExtContentBrowserSetting->bExportOverwriteExistingFiles; ExtContentBrowserSetting->PostEditChange(); }),
  3153. FCanExecuteAction(),
  3154. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bExportOverwriteExistingFiles; })
  3155. ),
  3156. NAME_None,
  3157. EUserInterfaceActionType::ToggleButton
  3158. );
  3159. MenuBuilder.AddMenuEntry(
  3160. LOCTEXT("RollbackIfFailed", "Rollback If Failed"),
  3161. LOCTEXT("ExportRollbackIfFailedTooltip", "Delete exported uasset and dependencies and restore any replaced files if export failed"),
  3162. FSlateIcon(),
  3163. FUIAction(
  3164. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bRollbackExportIfFailed = !ExtContentBrowserSetting->bRollbackExportIfFailed; ExtContentBrowserSetting->PostEditChange(); }),
  3165. FCanExecuteAction(),
  3166. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bRollbackExportIfFailed; })
  3167. ),
  3168. NAME_None,
  3169. EUserInterfaceActionType::ToggleButton
  3170. );
  3171. MenuBuilder.AddMenuEntry(
  3172. LOCTEXT("OpenFolderAfterExport", "Open Folder After Export"),
  3173. LOCTEXT("OpenFolderAfterExportTooltip", "Open selected folder after export"),
  3174. FSlateIcon(),
  3175. FUIAction(
  3176. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->bOpenFolderAfterExport = !ExtContentBrowserSetting->bOpenFolderAfterExport; ExtContentBrowserSetting->PostEditChange(); }),
  3177. FCanExecuteAction(),
  3178. FIsActionChecked::CreateLambda([this, ExtContentBrowserSetting] { return ExtContentBrowserSetting->bOpenFolderAfterExport; })
  3179. ),
  3180. NAME_None,
  3181. EUserInterfaceActionType::ToggleButton
  3182. );
  3183. }
  3184. MenuBuilder.EndSection();
  3185. #endif
  3186. #if ECB_DEBUG
  3187. MenuBuilder.BeginSection("Debug", LOCTEXT("DebugHeading", "Debug"));
  3188. {
  3189. // Print Cache
  3190. MenuBuilder.AddMenuEntry(
  3191. LOCTEXT("Print Cache", "Print Cache"),
  3192. LOCTEXT("Print Cache", "Print Cache"),
  3193. FSlateIcon(),
  3194. FUIAction(
  3195. FExecuteAction::CreateLambda([this] { HandlePrintCacheClicked(); })
  3196. ),
  3197. NAME_None,
  3198. EUserInterfaceActionType::Button
  3199. );
  3200. // Clear Cache
  3201. MenuBuilder.AddMenuEntry(
  3202. LOCTEXT("Clear Cache", "Clear Cache"),
  3203. LOCTEXT("Clear Cache", "Clear Cache"),
  3204. FSlateIcon(),
  3205. FUIAction(
  3206. FExecuteAction::CreateLambda([this] { HandleClearCacheClicked(); })
  3207. ),
  3208. NAME_None,
  3209. EUserInterfaceActionType::Button
  3210. );
  3211. // Print AssetData
  3212. MenuBuilder.AddMenuEntry(
  3213. LOCTEXT("Print AssetData", "Print AssetData"),
  3214. LOCTEXT("Print AssetData", "Print AssetData"),
  3215. FSlateIcon(),
  3216. FUIAction(
  3217. FExecuteAction::CreateLambda([this] { HandlePrintAssetDataClicked(); })
  3218. ),
  3219. NAME_None,
  3220. EUserInterfaceActionType::Button
  3221. );
  3222. }
  3223. MenuBuilder.EndSection();
  3224. #endif
  3225. MenuBuilder.BeginSection("Reset", LOCTEXT("ResetHeading", "Reset"));
  3226. {
  3227. MenuBuilder.AddMenuEntry(
  3228. #if ECB_WIP_EXPORT
  3229. LOCTEXT("ResetImportExportOptions", "Reset Import/Export Options"),
  3230. LOCTEXT("ResetImportExportOptionsTooltip", "Reset import and export options to default"),
  3231. #else
  3232. LOCTEXT("ResetImportOptions", "Reset Import Options"),
  3233. LOCTEXT("ResetImportOptionsTooltip", "Reset import options to default"),
  3234. #endif
  3235. FSlateIcon(),
  3236. FUIAction(
  3237. FExecuteAction::CreateLambda([this, ExtContentBrowserSetting] { ExtContentBrowserSetting->ResetImportSettings(); ExtContentBrowserSetting->PostEditChange(); })
  3238. //FCanExecuteAction(),
  3239. //FIsActionChecked::CreateLambda([this] { return false; })
  3240. ),
  3241. NAME_None,
  3242. EUserInterfaceActionType::Button
  3243. );
  3244. }
  3245. MenuBuilder.EndSection();
  3246. return MenuBuilder.MakeWidget();
  3247. }
  3248. #endif
  3249. #if ECB_LEGACY
  3250. void SExtContentBrowser::OnAddContentRequested()
  3251. {
  3252. IAddContentDialogModule& AddContentDialogModule = FModuleManager::LoadModuleChecked<IAddContentDialogModule>("AddContentDialog");
  3253. FWidgetPath WidgetPath;
  3254. FSlateApplication::Get().GeneratePathToWidgetChecked(AsShared(), WidgetPath);
  3255. AddContentDialogModule.ShowDialog(WidgetPath.GetWindow());
  3256. }
  3257. #endif
  3258. void SExtContentBrowser::RemoveContentFolders()
  3259. {
  3260. PathContextMenu->ExecuteRemoveRootFolder();
  3261. }
  3262. bool SExtContentBrowser::CanRemoveContentFolders() const
  3263. {
  3264. return bCanRemoveContentFolders && PathViewPtr->GetNumPathsSelected() > 0;
  3265. }
  3266. void SExtContentBrowser::OnAssetSelectionChanged(const FExtAssetData& SelectedAsset)
  3267. {
  3268. // Notify 'asset selection changed' delegate
  3269. FExtContentBrowserModule& ExtContentBrowserModule = FModuleManager::GetModuleChecked<FExtContentBrowserModule>( TEXT("ExtContentBrowser") );
  3270. FOnExtAssetSelectionChanged& AssetSelectionChangedDelegate = ExtContentBrowserModule.GetOnAssetSelectionChanged();
  3271. const TArray<FExtAssetData>& SelectedAssets = AssetViewPtr->GetSelectedAssets();
  3272. AssetContextMenu->SetSelectedAssets(SelectedAssets);
  3273. //CollectionViewPtr->SetSelectedAssets(SelectedAssets);
  3274. const bool bReferenceViewerLocked = false;
  3275. if (bReferenceViewerExpanded && !bReferenceViewerLocked)
  3276. {
  3277. TArray<FExtAssetIdentifier> AssetIdentifiers;
  3278. FExtAssetRegistry::ExtractAssetIdentifiersFromAssetDataList(SelectedAssets, AssetIdentifiers);
  3279. // Validate to cache dependency asset data info
  3280. // for (const FExtAssetData& AssetData : SelectedAssets)
  3281. // {
  3282. // FExtAssetValidator::ValidateDependency(AssetData);
  3283. // }
  3284. EDependencyNodeStatus Status;
  3285. FExtAssetValidator::ValidateDependency(SelectedAssets, nullptr, /*bShowProgess*/ true, &Status);
  3286. if (Status != EDependencyNodeStatus::AbortGathering)
  3287. {
  3288. ReferenceViewerPtr->SetGraphRootIdentifiers(AssetIdentifiers);
  3289. }
  3290. }
  3291. if(AssetSelectionChangedDelegate.IsBound())
  3292. {
  3293. AssetSelectionChangedDelegate.Broadcast(SelectedAssets, bIsPrimaryBrowser);
  3294. }
  3295. }
  3296. #if ECB_LEGACY
  3297. void SExtContentBrowser::OnAssetsActivated(const TArray<FAssetData>& ActivatedAssets, EAssetTypeActivationMethod::Type ActivationMethod)
  3298. {
  3299. TMap< TSharedRef<IAssetTypeActions>, TArray<UObject*> > TypeActionsToObjects;
  3300. TArray<UObject*> ObjectsWithoutTypeActions;
  3301. const FText LoadingTemplate = LOCTEXT("LoadingAssetName", "Loading {0}...");
  3302. const FText DefaultText = ActivatedAssets.Num() == 1 ? FText::Format(LoadingTemplate, FText::FromName(ActivatedAssets[0].AssetName)) : LOCTEXT("LoadingObjects", "Loading Objects...");
  3303. FScopedSlowTask SlowTask(100, DefaultText);
  3304. // Iterate over all activated assets to map them to AssetTypeActions.
  3305. // This way individual asset type actions will get a batched list of assets to operate on
  3306. for ( auto AssetIt = ActivatedAssets.CreateConstIterator(); AssetIt; ++AssetIt )
  3307. {
  3308. const FAssetData& AssetData = *AssetIt;
  3309. if (!AssetData.IsAssetLoaded() && FEditorFileUtils::IsMapPackageAsset(AssetData.ObjectPath.ToString()))
  3310. {
  3311. SlowTask.MakeDialog();
  3312. }
  3313. SlowTask.EnterProgressFrame(75.f/ActivatedAssets.Num(), FText::Format(LoadingTemplate, FText::FromName(AssetData.AssetName)));
  3314. UObject* Asset = (*AssetIt).GetAsset();
  3315. if ( Asset != NULL )
  3316. {
  3317. FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");
  3318. TWeakPtr<IAssetTypeActions> AssetTypeActions = AssetToolsModule.Get().GetAssetTypeActionsForClass(Asset->GetClass());
  3319. if ( AssetTypeActions.IsValid() )
  3320. {
  3321. // Add this asset to the list associated with the asset type action object
  3322. TArray<UObject*>& ObjList = TypeActionsToObjects.FindOrAdd(AssetTypeActions.Pin().ToSharedRef());
  3323. ObjList.AddUnique(Asset);
  3324. }
  3325. else
  3326. {
  3327. ObjectsWithoutTypeActions.AddUnique(Asset);
  3328. }
  3329. }
  3330. }
  3331. // Now that we have created our map, activate all the lists of objects for each asset type action.
  3332. for ( auto TypeActionsIt = TypeActionsToObjects.CreateConstIterator(); TypeActionsIt; ++TypeActionsIt )
  3333. {
  3334. SlowTask.EnterProgressFrame(25.f/TypeActionsToObjects.Num());
  3335. const TSharedRef<IAssetTypeActions>& TypeActions = TypeActionsIt.Key();
  3336. const TArray<UObject*>& ObjList = TypeActionsIt.Value();
  3337. TypeActions->AssetsActivated(ObjList, ActivationMethod);
  3338. }
  3339. // Finally, open a simple asset editor for all assets which do not have asset type actions if activating with enter or double click
  3340. if ( ActivationMethod == EAssetTypeActivationMethod::DoubleClicked || ActivationMethod == EAssetTypeActivationMethod::Opened )
  3341. {
  3342. ContentBrowserUtils::OpenEditorForAsset(ObjectsWithoutTypeActions);
  3343. }
  3344. }
  3345. #endif
  3346. TSharedPtr<SWidget> SExtContentBrowser::OnGetAssetContextMenu(const TArray<FExtAssetData>& SelectedAssets)
  3347. {
  3348. if ( SelectedAssets.Num() == 0 )
  3349. {
  3350. return MakeAddNewContextMenu( false, true );
  3351. }
  3352. else
  3353. {
  3354. return AssetContextMenu->MakeContextMenu(SelectedAssets, AssetViewPtr->GetSourcesData(), Commands);
  3355. }
  3356. }
  3357. #if ECB_WIP_LOCK
  3358. FReply SExtContentBrowser::ToggleLockClicked()
  3359. {
  3360. bIsLocked = !bIsLocked;
  3361. return FReply::Handled();
  3362. }
  3363. const FSlateBrush* SExtContentBrowser::GetToggleLockImage() const
  3364. {
  3365. if ( bIsLocked )
  3366. {
  3367. return FAppStyle::GetBrush("ContentBrowser.LockButton_Locked");
  3368. }
  3369. else
  3370. {
  3371. return FAppStyle::GetBrush("ContentBrowser.LockButton_Unlocked");
  3372. }
  3373. }
  3374. #endif
  3375. EVisibility SExtContentBrowser::GetVisibilityByLastFrameWidth(float MinWidthToShow) const
  3376. {
  3377. #if ECB_FEA_TOOLBAR_BUTTON_AUTOHIDE
  3378. return (WidthLastFrame < MinWidthToShow) ? EVisibility::Collapsed : EVisibility::Visible;
  3379. #else
  3380. return EVisibility::Visible;
  3381. #endif
  3382. }
  3383. EVisibility SExtContentBrowser::GetSourcesViewVisibility() const
  3384. {
  3385. return bSourcesViewExpanded ? EVisibility::Visible : EVisibility::Collapsed;
  3386. }
  3387. const FSlateBrush* SExtContentBrowser::GetSourcesToggleImage() const
  3388. {
  3389. if ( bSourcesViewExpanded )
  3390. {
  3391. return FExtContentBrowserStyle::Get().GetBrush("UAssetBrowser.HideSourcesView");
  3392. }
  3393. else
  3394. {
  3395. return FExtContentBrowserStyle::Get().GetBrush("UAssetBrowser.ShowSourcesView");
  3396. }
  3397. }
  3398. FReply SExtContentBrowser::SourcesViewExpandClicked()
  3399. {
  3400. bSourcesViewExpanded = !bSourcesViewExpanded;
  3401. #if ECB_LEGACY
  3402. // Notify 'Sources View Expanded' delegate
  3403. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>( TEXT("ContentBrowser") );
  3404. FContentBrowserModule::FOnSourcesViewChanged& SourcesViewChangedDelegate = ContentBrowserModule.GetOnSourcesViewChanged();
  3405. if(SourcesViewChangedDelegate.IsBound())
  3406. {
  3407. SourcesViewChangedDelegate.Broadcast(bSourcesViewExpanded);
  3408. }
  3409. #endif
  3410. return FReply::Handled();
  3411. }
  3412. EVisibility SExtContentBrowser::GetPathExpanderVisibility() const
  3413. {
  3414. return bSourcesViewExpanded ? EVisibility::Collapsed : EVisibility::Visible;
  3415. }
  3416. #if ECB_FEA_REF_VIEWER
  3417. EVisibility SExtContentBrowser::GetReferencesViewerVisibility() const
  3418. {
  3419. return bReferenceViewerExpanded ? EVisibility::Visible : EVisibility::Collapsed;
  3420. }
  3421. const FSlateBrush* SExtContentBrowser::GetDependencyViewerToggleImage() const
  3422. {
  3423. if (bReferenceViewerExpanded)
  3424. {
  3425. return FExtContentBrowserStyle::Get().GetBrush("UAssetBrowser.ShowDependencyViewer");
  3426. }
  3427. else
  3428. {
  3429. return FExtContentBrowserStyle::Get().GetBrush("UAssetBrowser.HideDependencyViewer");
  3430. }
  3431. }
  3432. FReply SExtContentBrowser::ReferenceViewerExpandClicked()
  3433. {
  3434. bReferenceViewerExpanded = !bReferenceViewerExpanded;
  3435. if (bReferenceViewerExpanded)
  3436. {
  3437. const TArray<FExtAssetData>& SelectedAssets = AssetViewPtr->GetSelectedAssets();
  3438. TArray<FExtAssetIdentifier> AssetIdentifiers;
  3439. FExtAssetRegistry::ExtractAssetIdentifiersFromAssetDataList(SelectedAssets, AssetIdentifiers);
  3440. EDependencyNodeStatus Status;
  3441. FExtAssetValidator::ValidateDependency(SelectedAssets, nullptr, /*bShowProgess*/ true, &Status);
  3442. if (Status != EDependencyNodeStatus::AbortGathering)
  3443. {
  3444. ReferenceViewerPtr->SetGraphRootIdentifiers(AssetIdentifiers);
  3445. }
  3446. }
  3447. return FReply::Handled();
  3448. }
  3449. #endif
  3450. #if ECB_WIP_HISTORY
  3451. FReply SExtContentBrowser::BackClicked()
  3452. {
  3453. HistoryManager.GoBack();
  3454. return FReply::Handled();
  3455. }
  3456. FReply SExtContentBrowser::ForwardClicked()
  3457. {
  3458. HistoryManager.GoForward();
  3459. return FReply::Handled();
  3460. }
  3461. bool SExtContentBrowser::IsBackEnabled() const
  3462. {
  3463. return HistoryManager.CanGoBack();
  3464. }
  3465. bool SExtContentBrowser::IsForwardEnabled() const
  3466. {
  3467. return HistoryManager.CanGoForward();
  3468. }
  3469. FText SExtContentBrowser::GetHistoryBackTooltip() const
  3470. {
  3471. if (HistoryManager.CanGoBack())
  3472. {
  3473. return FText::Format(LOCTEXT("HistoryBackTooltipFmt", "Back to {0}"), HistoryManager.GetBackDesc());
  3474. }
  3475. return FText::GetEmpty();
  3476. }
  3477. FText SExtContentBrowser::GetHistoryForwardTooltip() const
  3478. {
  3479. if (HistoryManager.CanGoForward())
  3480. {
  3481. return FText::Format(LOCTEXT("HistoryForwardTooltipFmt", "Forward to {0}"), HistoryManager.GetForwardDesc());
  3482. }
  3483. return FText::GetEmpty();
  3484. }
  3485. #endif
  3486. #if ECB_LEGACY
  3487. void SExtContentBrowser::HandleSaveAssetCommand()
  3488. {
  3489. const TArray<TSharedPtr<FExtAssetViewItem>>& SelectedItems = AssetViewPtr->GetSelectedItems();
  3490. if (SelectedItems.Num() > 0)
  3491. {
  3492. AssetContextMenu->ExecuteSaveAsset();
  3493. }
  3494. }
  3495. void SExtContentBrowser::HandleOpenAssetsOrFoldersCommandExecute()
  3496. {
  3497. AssetViewPtr->OnOpenAssetsOrFolders();
  3498. }
  3499. void SExtContentBrowser::HandlePreviewAssetsCommandExecute()
  3500. {
  3501. AssetViewPtr->OnPreviewAssets();
  3502. }
  3503. void SExtContentBrowser::HandleDirectoryUpCommandExecute()
  3504. {
  3505. TArray<FString> SelectedPaths = PathViewPtr->GetSelectedPaths();
  3506. if(SelectedPaths.Num() == 1 && !ContentBrowserUtils::IsRootDir(SelectedPaths[0]))
  3507. {
  3508. FString ParentDir = SelectedPaths[0] / TEXT("..");
  3509. FPaths::CollapseRelativeDirectories(ParentDir);
  3510. FolderEntered(ParentDir);
  3511. }
  3512. }
  3513. void SExtContentBrowser::GetSelectionState(TArray<FAssetData>& SelectedAssets, TArray<FString>& SelectedPaths)
  3514. {
  3515. SelectedAssets.Reset();
  3516. SelectedPaths.Reset();
  3517. if (AssetViewPtr->HasAnyUserFocusOrFocusedDescendants())
  3518. {
  3519. SelectedAssets = AssetViewPtr->GetSelectedAssets();
  3520. SelectedPaths = AssetViewPtr->GetSelectedFolders();
  3521. }
  3522. else if (PathViewPtr->HasAnyUserFocusOrFocusedDescendants())
  3523. {
  3524. SelectedPaths = PathViewPtr->GetSelectedPaths();
  3525. }
  3526. }
  3527. bool SExtContentBrowser::CanExecuteDirectoryUp() const
  3528. {
  3529. TArray<FString> SelectedPaths = PathViewPtr->GetSelectedPaths();
  3530. return (SelectedPaths.Num() == 1 && !ContentBrowserUtils::IsRootDir(SelectedPaths[0]));
  3531. }
  3532. FText SExtContentBrowser::GetDirectoryUpTooltip() const
  3533. {
  3534. TArray<FString> SelectedPaths = PathViewPtr->GetSelectedPaths();
  3535. if(SelectedPaths.Num() == 1 && !ContentBrowserUtils::IsRootDir(SelectedPaths[0]))
  3536. {
  3537. FString ParentDir = SelectedPaths[0] / TEXT("..");
  3538. FPaths::CollapseRelativeDirectories(ParentDir);
  3539. return FText::Format(LOCTEXT("DirectoryUpTooltip", "Up to {0}"), FText::FromString(ParentDir) );
  3540. }
  3541. return FText();
  3542. }
  3543. EVisibility SExtContentBrowser::GetDirectoryUpToolTipVisibility() const
  3544. {
  3545. EVisibility ToolTipVisibility = EVisibility::Collapsed;
  3546. // if we have text in our tooltip, make it visible.
  3547. if(GetDirectoryUpTooltip().IsEmpty() == false)
  3548. {
  3549. ToolTipVisibility = EVisibility::Visible;
  3550. }
  3551. return ToolTipVisibility;
  3552. }
  3553. #endif
  3554. void SExtContentBrowser::HandleImportSelectedCommandExecute()
  3555. {
  3556. if (IsImportEnabled())
  3557. {
  3558. HandleImportClicked();
  3559. }
  3560. }
  3561. void SExtContentBrowser::HandleToggleDependencyViewerCommandExecute()
  3562. {
  3563. ReferenceViewerExpandClicked();
  3564. }
  3565. #if ECB_WIP_BREADCRUMB
  3566. void SExtContentBrowser::UpdatePath()
  3567. {
  3568. FSourcesData SourcesData = AssetViewPtr->GetSourcesData();
  3569. PathBreadcrumbTrail->ClearCrumbs();
  3570. if ( SourcesData.HasPackagePaths() )
  3571. {
  3572. TArray<FString> Crumbs;
  3573. SourcesData.PackagePaths[0].ToString().ParseIntoArray(Crumbs, TEXT("/"), true);
  3574. FString CrumbPath = TEXT("/");
  3575. for ( auto CrumbIt = Crumbs.CreateConstIterator(); CrumbIt; ++CrumbIt )
  3576. {
  3577. // If this is the root part of the path, try and get the localized display name to stay in sync with what we see in SExtPathView
  3578. const FText DisplayName = (CrumbIt.GetIndex() == 0) ? ExtContentBrowserUtils::GetRootDirDisplayName(*CrumbIt) : FText::FromString(*CrumbIt);
  3579. CrumbPath += *CrumbIt;
  3580. PathBreadcrumbTrail->PushCrumb(DisplayName, CrumbPath);
  3581. CrumbPath += TEXT("/");
  3582. }
  3583. }
  3584. else if ( SourcesData.HasCollections() )
  3585. {
  3586. FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
  3587. TArray<FCollectionNameType> CollectionPathItems;
  3588. // Walk up the parents of this collection so that we can generate a complete path (this loop also adds the child collection to the array)
  3589. for (TOptional<FCollectionNameType> CurrentCollection = SourcesData.Collections[0];
  3590. CurrentCollection.IsSet();
  3591. CurrentCollection = CollectionManagerModule.Get().GetParentCollection(CurrentCollection->Name, CurrentCollection->Type)
  3592. )
  3593. {
  3594. CollectionPathItems.Insert(CurrentCollection.GetValue(), 0);
  3595. }
  3596. // Now add each part of the path to the breadcrumb trail
  3597. for (const FCollectionNameType& CollectionPathItem : CollectionPathItems)
  3598. {
  3599. const FString CrumbData = FString::Printf(TEXT("%s?%s"), *CollectionPathItem.Name.ToString(), *FString::FromInt(CollectionPathItem.Type));
  3600. FFormatNamedArguments Args;
  3601. Args.Add(TEXT("CollectionName"), FText::FromName(CollectionPathItem.Name));
  3602. const FText DisplayName = FText::Format(LOCTEXT("CollectionPathIndicator", "{CollectionName} (Collection)"), Args);
  3603. PathBreadcrumbTrail->PushCrumb(DisplayName, CrumbData);
  3604. }
  3605. }
  3606. else
  3607. {
  3608. PathBreadcrumbTrail->PushCrumb(LOCTEXT("AllAssets", "All Assets"), TEXT(""));
  3609. }
  3610. }
  3611. #endif
  3612. void SExtContentBrowser::OnFilterChanged()
  3613. {
  3614. FARFilter Filter = FilterListPtr->GetCombinedBackendFilter();
  3615. AssetViewPtr->SetBackendFilter(Filter);
  3616. #if ECB_LEGACY
  3617. // Notify 'filter changed' delegate
  3618. FContentBrowserModule& ContentBrowserModule = FModuleManager::GetModuleChecked<FContentBrowserModule>( TEXT("ContentBrowser") );
  3619. ContentBrowserModule.GetOnFilterChanged().Broadcast(Filter, bIsPrimaryBrowser);
  3620. #endif
  3621. }
  3622. #if ECB_LEGACY
  3623. FText SExtContentBrowser::GetPathText() const
  3624. {
  3625. FText PathLabelText;
  3626. if ( IsFilteredBySource() )
  3627. {
  3628. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  3629. // At least one source is selected
  3630. const int32 NumSources = SourcesData.PackagePaths.Num() + SourcesData.Collections.Num();
  3631. if (NumSources > 0)
  3632. {
  3633. PathLabelText = FText::FromName(SourcesData.HasPackagePaths() ? SourcesData.PackagePaths[0] : SourcesData.Collections[0].Name);
  3634. if (NumSources > 1)
  3635. {
  3636. PathLabelText = FText::Format(LOCTEXT("PathTextFmt", "{0} and {1} {1}|plural(one=other,other=others)..."), PathLabelText, NumSources - 1);
  3637. }
  3638. }
  3639. }
  3640. else
  3641. {
  3642. PathLabelText = LOCTEXT("AllAssets", "All Assets");
  3643. }
  3644. return PathLabelText;
  3645. }
  3646. bool SExtContentBrowser::IsFilteredBySource() const
  3647. {
  3648. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  3649. return !SourcesData.IsEmpty();
  3650. }
  3651. void SExtContentBrowser::OnAssetRenameCommitted(const TArray<FAssetData>& Assets)
  3652. {
  3653. // After a rename is committed we allow an implicit sync so as not to
  3654. // disorientate the user if they are looking at a parent folder
  3655. const bool bAllowImplicitSync = true;
  3656. const bool bDisableFiltersThatHideAssets = false;
  3657. SyncToAssets(Assets, bAllowImplicitSync, bDisableFiltersThatHideAssets);
  3658. }
  3659. #endif
  3660. #if ECB_WIP_SYNC_ASSET
  3661. void SExtContentBrowser::OnFindInAssetTreeRequested(const TArray<FAssetData>& AssetsToFind)
  3662. {
  3663. SyncToAssets(AssetsToFind);
  3664. }
  3665. #endif
  3666. #if ECB_LEGACY
  3667. void SExtContentBrowser::OnRenameRequested(const FAssetData& AssetData)
  3668. {
  3669. AssetViewPtr->RenameAsset(AssetData);
  3670. }
  3671. void SExtContentBrowser::OnRenameFolderRequested(const FString& FolderToRename)
  3672. {
  3673. const TArray<FString>& SelectedFolders = AssetViewPtr->GetSelectedFolders();
  3674. if (SelectedFolders.Num() > 0)
  3675. {
  3676. AssetViewPtr->RenameFolder(FolderToRename);
  3677. }
  3678. else
  3679. {
  3680. const TArray<FString>& SelectedPaths = PathViewPtr->GetSelectedPaths();
  3681. if (SelectedPaths.Num() > 0)
  3682. {
  3683. PathViewPtr->RenameFolder(FolderToRename);
  3684. }
  3685. }
  3686. }
  3687. void SExtContentBrowser::OnOpenedFolderDeleted()
  3688. {
  3689. // Since the contents of the asset view have just been deleted, set the selected path to the default "/Game"
  3690. TArray<FString> DefaultSelectedPaths;
  3691. DefaultSelectedPaths.Add(TEXT("/Game"));
  3692. PathViewPtr->SetSelectedPaths(DefaultSelectedPaths);
  3693. FavoritePathViewPtr->SetSelectedPaths(DefaultSelectedPaths);
  3694. FSourcesData DefaultSourcesData(FName("/Game"));
  3695. AssetViewPtr->SetSourcesData(DefaultSourcesData);
  3696. UpdatePath();
  3697. }
  3698. void SExtContentBrowser::OnAssetViewRefreshRequested()
  3699. {
  3700. AssetViewPtr->RequestSlowFullListRefresh();
  3701. }
  3702. void SExtContentBrowser::HandleCollectionRemoved(const FCollectionNameType& Collection)
  3703. {
  3704. AssetViewPtr->SetSourcesData(FSourcesData());
  3705. auto RemoveHistoryDelegate = [&](const FHistoryData& HistoryData)
  3706. {
  3707. return (HistoryData.SourcesData.Collections.Num() == 1 &&
  3708. HistoryData.SourcesData.PackagePaths.Num() == 0 &&
  3709. HistoryData.SourcesData.Collections.Contains(Collection));
  3710. };
  3711. HistoryManager.RemoveHistoryData(RemoveHistoryDelegate);
  3712. }
  3713. void SExtContentBrowser::HandleCollectionRenamed(const FCollectionNameType& OriginalCollection, const FCollectionNameType& NewCollection)
  3714. {
  3715. return HandleCollectionRemoved(OriginalCollection);
  3716. }
  3717. void SExtContentBrowser::HandleCollectionUpdated(const FCollectionNameType& Collection)
  3718. {
  3719. const FSourcesData& SourcesData = AssetViewPtr->GetSourcesData();
  3720. // If we're currently viewing the dynamic collection that was updated, make sure our active filter text is up-to-date
  3721. if (SourcesData.IsDynamicCollection() && SourcesData.Collections[0] == Collection)
  3722. {
  3723. FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
  3724. const FCollectionNameType& DynamicCollection = SourcesData.Collections[0];
  3725. FString DynamicQueryString;
  3726. CollectionManagerModule.Get().GetDynamicQueryText(DynamicCollection.Name, DynamicCollection.Type, DynamicQueryString);
  3727. const FText DynamicQueryText = FText::FromString(DynamicQueryString);
  3728. SetSearchBoxText(DynamicQueryText);
  3729. SearchBoxPtr->SetText(DynamicQueryText);
  3730. }
  3731. }
  3732. void SExtContentBrowser::HandlePathRemoved(const FString& Path)
  3733. {
  3734. const FName PathName(*Path);
  3735. auto RemoveHistoryDelegate = [&](const FHistoryData& HistoryData)
  3736. {
  3737. return (HistoryData.SourcesData.PackagePaths.Num() == 1 &&
  3738. HistoryData.SourcesData.Collections.Num() == 0 &&
  3739. HistoryData.SourcesData.PackagePaths.Contains(PathName));
  3740. };
  3741. HistoryManager.RemoveHistoryData(RemoveHistoryDelegate);
  3742. }
  3743. #endif
  3744. #if ECB_FEA_SEARCH
  3745. FText SExtContentBrowser::GetSearchAssetsHintText() const
  3746. {
  3747. if (PathViewPtr.IsValid())
  3748. {
  3749. TArray<FString> Paths = PathViewPtr->GetSelectedPaths();
  3750. if (Paths.Num() != 0)
  3751. {
  3752. FString SearchHint = NSLOCTEXT( "ContentBrowser", "SearchBoxPartialHint", "Search" ).ToString();
  3753. SearchHint += TEXT(" ");
  3754. for(int32 i = 0; i < Paths.Num(); i++)
  3755. {
  3756. const FString& Path = Paths[i];
  3757. #if ECB_LEGACY
  3758. if (ContentBrowserUtils::IsRootDir(Path))
  3759. {
  3760. SearchHint += ContentBrowserUtils::GetRootDirDisplayName(Path).ToString();
  3761. }
  3762. else
  3763. #endif
  3764. {
  3765. SearchHint += FPaths::GetCleanFilename(Path);
  3766. }
  3767. if (i + 1 < Paths.Num())
  3768. {
  3769. SearchHint += ", ";
  3770. }
  3771. }
  3772. return FText::FromString(SearchHint);
  3773. }
  3774. }
  3775. return NSLOCTEXT( "ContentBrowser", "SearchBoxHint", "Search Assets" );
  3776. }
  3777. void ExtractAssetSearchFilterTerms(const FText& SearchText, FString* OutFilterKey, FString* OutFilterValue, int32* OutSuggestionInsertionIndex)
  3778. {
  3779. const FString SearchString = SearchText.ToString();
  3780. if (OutFilterKey)
  3781. {
  3782. OutFilterKey->Reset();
  3783. }
  3784. if (OutFilterValue)
  3785. {
  3786. OutFilterValue->Reset();
  3787. }
  3788. if (OutSuggestionInsertionIndex)
  3789. {
  3790. *OutSuggestionInsertionIndex = SearchString.Len();
  3791. }
  3792. // Build the search filter terms so that we can inspect the tokens
  3793. FTextFilterExpressionEvaluator LocalFilter(ETextFilterExpressionEvaluatorMode::Complex);
  3794. LocalFilter.SetFilterText(SearchText);
  3795. // Inspect the tokens to see what the last part of the search term was
  3796. // If it was a key->value pair then we'll use that to control what kinds of results we show
  3797. // For anything else we just use the text from the last token as our filter term to allow incremental auto-complete
  3798. const TArray<FExpressionToken>& FilterTokens = LocalFilter.GetFilterExpressionTokens();
  3799. if (FilterTokens.Num() > 0)
  3800. {
  3801. const FExpressionToken& LastToken = FilterTokens.Last();
  3802. // If the last token is a text token, then consider it as a value and walk back to see if we also have a key
  3803. if (LastToken.Node.Cast<TextFilterExpressionParser::FTextToken>())
  3804. {
  3805. if (OutFilterValue)
  3806. {
  3807. *OutFilterValue = LastToken.Context.GetString();
  3808. }
  3809. if (OutSuggestionInsertionIndex)
  3810. {
  3811. *OutSuggestionInsertionIndex = FMath::Min(*OutSuggestionInsertionIndex, LastToken.Context.GetCharacterIndex());
  3812. }
  3813. if (FilterTokens.IsValidIndex(FilterTokens.Num() - 2))
  3814. {
  3815. const FExpressionToken& ComparisonToken = FilterTokens[FilterTokens.Num() - 2];
  3816. if (ComparisonToken.Node.Cast<TextFilterExpressionParser::FEqual>())
  3817. {
  3818. if (FilterTokens.IsValidIndex(FilterTokens.Num() - 3))
  3819. {
  3820. const FExpressionToken& KeyToken = FilterTokens[FilterTokens.Num() - 3];
  3821. if (KeyToken.Node.Cast<TextFilterExpressionParser::FTextToken>())
  3822. {
  3823. if (OutFilterKey)
  3824. {
  3825. *OutFilterKey = KeyToken.Context.GetString();
  3826. }
  3827. if (OutSuggestionInsertionIndex)
  3828. {
  3829. *OutSuggestionInsertionIndex = FMath::Min(*OutSuggestionInsertionIndex, KeyToken.Context.GetCharacterIndex());
  3830. }
  3831. }
  3832. }
  3833. }
  3834. }
  3835. }
  3836. // If the last token is a comparison operator, then walk back and see if we have a key
  3837. else if (LastToken.Node.Cast<TextFilterExpressionParser::FEqual>())
  3838. {
  3839. if (FilterTokens.IsValidIndex(FilterTokens.Num() - 2))
  3840. {
  3841. const FExpressionToken& KeyToken = FilterTokens[FilterTokens.Num() - 2];
  3842. if (KeyToken.Node.Cast<TextFilterExpressionParser::FTextToken>())
  3843. {
  3844. if (OutFilterKey)
  3845. {
  3846. *OutFilterKey = KeyToken.Context.GetString();
  3847. }
  3848. if (OutSuggestionInsertionIndex)
  3849. {
  3850. *OutSuggestionInsertionIndex = FMath::Min(*OutSuggestionInsertionIndex, KeyToken.Context.GetCharacterIndex());
  3851. }
  3852. }
  3853. }
  3854. }
  3855. }
  3856. }
  3857. void SExtContentBrowser::OnAssetSearchSuggestionFilter(const FText& SearchText, TArray<FAssetSearchBoxSuggestion>& PossibleSuggestions, FText& SuggestionHighlightText) const
  3858. {
  3859. // We don't bind the suggestion list, so this list should be empty as we populate it here based on the search term
  3860. check(PossibleSuggestions.Num() == 0);
  3861. FString FilterKey;
  3862. FString FilterValue;
  3863. ExtractAssetSearchFilterTerms(SearchText, &FilterKey, &FilterValue, nullptr);
  3864. auto PassesValueFilter = [&FilterValue](const FString& InOther)
  3865. {
  3866. return FilterValue.IsEmpty() || InOther.Contains(FilterValue);
  3867. };
  3868. if (FilterKey.IsEmpty() || (FilterKey == TEXT("Type") || FilterKey == TEXT("Class")))
  3869. {
  3870. FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
  3871. TArray< TWeakPtr<IAssetTypeActions> > AssetTypeActionsList;
  3872. AssetToolsModule.Get().GetAssetTypeActionsList(AssetTypeActionsList);
  3873. const FText TypesCategoryName = NSLOCTEXT("ContentBrowser", "TypesCategoryName", "Types");
  3874. for (auto TypeActionsIt = AssetTypeActionsList.CreateConstIterator(); TypeActionsIt; ++TypeActionsIt)
  3875. {
  3876. if ((*TypeActionsIt).IsValid())
  3877. {
  3878. const TSharedPtr<IAssetTypeActions> TypeActions = (*TypeActionsIt).Pin();
  3879. if (TypeActions->GetSupportedClass())
  3880. {
  3881. const FString TypeName = TypeActions->GetSupportedClass()->GetName();
  3882. const FText TypeDisplayName = TypeActions->GetSupportedClass()->GetDisplayNameText();
  3883. FString TypeSuggestion = FString::Printf(TEXT("Type=%s"), *TypeName);
  3884. if (PassesValueFilter(TypeSuggestion))
  3885. {
  3886. PossibleSuggestions.Add(FAssetSearchBoxSuggestion{ MoveTemp(TypeSuggestion), TypeDisplayName, TypesCategoryName });
  3887. }
  3888. }
  3889. }
  3890. }
  3891. }
  3892. #if ECB_WIP_COLLECTION
  3893. if (FilterKey.IsEmpty() || (FilterKey == TEXT("Collection") || FilterKey == TEXT("Tag")))
  3894. {
  3895. ICollectionManager& CollectionManager = FCollectionManagerModule::GetModule().Get();
  3896. TArray<FCollectionNameType> AllCollections;
  3897. CollectionManager.GetCollections(AllCollections);
  3898. const FText CollectionsCategoryName = NSLOCTEXT("ContentBrowser", "CollectionsCategoryName", "Collections");
  3899. for (const FCollectionNameType& Collection : AllCollections)
  3900. {
  3901. FString CollectionName = Collection.Name.ToString();
  3902. FString CollectionSuggestion = FString::Printf(TEXT("Collection=%s"), *CollectionName);
  3903. if (PassesValueFilter(CollectionSuggestion))
  3904. {
  3905. PossibleSuggestions.Add(FAssetSearchBoxSuggestion{ MoveTemp(CollectionSuggestion), FText::FromString(MoveTemp(CollectionName)), CollectionsCategoryName });
  3906. }
  3907. }
  3908. }
  3909. #endif
  3910. #if ECB_TODO
  3911. if (FilterKey.IsEmpty())
  3912. {
  3913. IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(AssetRegistryConstants::ModuleName).Get();
  3914. if (const FAssetRegistryState* StatePtr = AssetRegistry.GetAssetRegistryState())
  3915. {
  3916. const FText MetaDataCategoryName = NSLOCTEXT("ContentBrowser", "MetaDataCategoryName", "Meta-Data");
  3917. for (const auto& TagAndArrayPair : StatePtr->GetTagToAssetDatasMap())
  3918. {
  3919. const FString TagNameStr = TagAndArrayPair.Key.ToString();
  3920. if (PassesValueFilter(TagNameStr))
  3921. {
  3922. PossibleSuggestions.Add(FAssetSearchBoxSuggestion{ TagNameStr, FText::FromString(TagNameStr), MetaDataCategoryName });
  3923. }
  3924. }
  3925. }
  3926. }
  3927. #endif
  3928. SuggestionHighlightText = FText::FromString(FilterValue);
  3929. }
  3930. FText SExtContentBrowser::OnAssetSearchSuggestionChosen(const FText& SearchText, const FString& Suggestion) const
  3931. {
  3932. int32 SuggestionInsertionIndex = 0;
  3933. ExtractAssetSearchFilterTerms(SearchText, nullptr, nullptr, &SuggestionInsertionIndex);
  3934. FString SearchString = SearchText.ToString();
  3935. SearchString.RemoveAt(SuggestionInsertionIndex, SearchString.Len() - SuggestionInsertionIndex, false);
  3936. SearchString.Append(Suggestion);
  3937. return FText::FromString(SearchString);
  3938. }
  3939. #endif
  3940. TSharedPtr<SWidget> SExtContentBrowser::GetFolderContextMenu(const TArray<FString>& SelectedPaths, FContentBrowserMenuExtender_SelectedPaths InMenuExtender, FOnCreateNewFolder InOnCreateNewFolder, bool bPathView)
  3941. {
  3942. // Clear any selection in the asset view, as it'll conflict with other view info
  3943. // This is important for determining which context menu may be open based on the asset selection for rename/delete operations
  3944. if (bPathView)
  3945. {
  3946. AssetViewPtr->ClearSelection();
  3947. }
  3948. // Ensure the path context menu has the up-to-date list of paths being worked on
  3949. PathContextMenu->SetSelectedPaths(SelectedPaths);
  3950. TSharedPtr<FExtender> Extender;
  3951. if(InMenuExtender.IsBound())
  3952. {
  3953. Extender = InMenuExtender.Execute(SelectedPaths);
  3954. }
  3955. const bool bInShouldCloseWindowAfterSelection = true;
  3956. FMenuBuilder MenuBuilder(bInShouldCloseWindowAfterSelection, Commands, Extender, true);
  3957. // MenuBuilder.AddMenuEntry(
  3958. // LOCTEXT("AddContentFolder", "Add Content Folder"),
  3959. // LOCTEXT("ShowInNewContentBrowserTooltip", "Opens a new Content Browser at this folder location (at least 1 Content Browser window needs to be locked)"),
  3960. // FSlateIcon(),
  3961. // FUIAction()
  3962. // );
  3963. if (SelectedPaths.Num() > 0)
  3964. {
  3965. MenuBuilder.AddMenuEntry(
  3966. LOCTEXT("ClearFolderSelection", "Clear Folder Selection"),
  3967. LOCTEXT("ClearFolderSelectionTooltip", "Clear all folder selection."),
  3968. FSlateIcon(),
  3969. FUIAction(FExecuteAction::CreateSP(this, &SExtContentBrowser::ClearFolderSelection)),
  3970. "FolderContext"
  3971. );
  3972. }
  3973. else
  3974. {
  3975. MenuBuilder.BeginSection("FolderContext", LOCTEXT("FolderOptionsMenuHeading", "Folder Options"));
  3976. {
  3977. MenuBuilder.AddMenuEntry(
  3978. LOCTEXT("AddContentFolder", "Add Content Folder"),
  3979. LOCTEXT("AddContentFolderTooltip", "Add root content folder"),
  3980. FSlateIcon(),
  3981. FUIAction(FExecuteAction::CreateSP(this, &SExtContentBrowser::AddContentFolder))
  3982. //,"FolderContext"
  3983. );
  3984. }
  3985. MenuBuilder.EndSection();
  3986. }
  3987. //MenuBuilder.AddMenuSeparator("FolderContext");
  3988. #if ECB_WIP_MULTI_INSTANCES
  3989. MenuBuilder.AddMenuEntry(
  3990. LOCTEXT("ShowInNewContentBrowser", "Show in New Content Browser"),
  3991. LOCTEXT("ShowInNewContentBrowserTooltip", "Opens a new Content Browser at this folder location (at least 1 Content Browser window needs to be locked)"),
  3992. FSlateIcon(),
  3993. FUIAction(FExecuteAction::CreateSP(this, &SExtContentBrowser::OpenNewContentBrowser)),
  3994. "FolderContext"
  3995. );
  3996. #endif
  3997. return MenuBuilder.MakeWidget();
  3998. //return SNullWidget::NullWidget;
  3999. }
  4000. void SExtContentBrowser::ClearFolderSelection()
  4001. {
  4002. PathViewPtr->ClearSelection();
  4003. AssetViewPtr->SetSourcesData(FSourcesData());
  4004. bCanRemoveContentFolders = false;
  4005. }
  4006. #if ECB_WIP_CACHEDB
  4007. void SExtContentBrowser::HandleCacheDBFilePathPicked(const FString& PickedPath)
  4008. {
  4009. FString FinalPath = PickedPath;
  4010. UExtContentBrowserSettings* ExtContentBrowserSetting = GetMutableDefault<UExtContentBrowserSettings>();
  4011. ECB_LOG(Display, TEXT("HandleCacheDBFilePathPicked: was: %s, now: %s"), *ExtContentBrowserSetting->CacheFilePath.FilePath, *FinalPath);
  4012. }
  4013. #endif
  4014. #undef LOCTEXT_NAMESPACE
  4015. #ifdef EXT_DOC_NAMESPACE
  4016. #undef EXT_DOC_NAMESPACE
  4017. #endif