From 1278cf22a25cbd2a85f463dd9697a066cc9b089c Mon Sep 17 00:00:00 2001 From: Areloch Date: Sun, 28 Jan 2018 15:30:17 -0600 Subject: [PATCH] Initial implementation of the Asset Browser tool. --- .../tools/assetBrowser/art/animationIcon.png | Bin 0 -> 8177 bytes .../assetBrowser/art/clientScriptIcon.png | Bin 0 -> 14572 bytes .../tools/assetBrowser/art/componentIcon.png | Bin 0 -> 9050 bytes .../tools/assetBrowser/art/gameObjectIcon.png | Bin 0 -> 14773 bytes .../game/tools/assetBrowser/art/guiIcon.png | Bin 0 -> 5789 bytes .../game/tools/assetBrowser/art/levelIcon.png | Bin 0 -> 6797 bytes .../tools/assetBrowser/art/materialIcon.png | Bin 0 -> 7889 bytes .../tools/assetBrowser/art/postEffectIcon.png | Bin 0 -> 8615 bytes .../tools/assetBrowser/art/scriptIcon.png | Bin 0 -> 10044 bytes .../assetBrowser/art/serverScriptIcon.png | Bin 0 -> 14897 bytes .../game/tools/assetBrowser/art/soundIcon.png | Bin 0 -> 10582 bytes .../assetBrowser/art/stateMachineIcon.png | Bin 0 -> 13506 bytes .../tools/assetBrowser/assetImportConfigs.xml | 18 + .../assetBrowser/guis/GameObjectCreator.gui | 217 +++ .../assetBrowser/guis/addModuleWindow.gui | 142 ++ .../assetBrowser/guis/addPackageWindow.gui | 142 ++ .../tools/assetBrowser/guis/assetBrowser.gui | 934 ++++++++++ .../tools/assetBrowser/guis/assetImport.gui | 613 +++++++ .../tools/assetBrowser/guis/editAsset.gui | 147 ++ .../tools/assetBrowser/guis/editModule.gui | 147 ++ .../game/tools/assetBrowser/guis/newAsset.gui | 237 +++ .../assetBrowser/guis/newComponentAsset.gui | 434 +++++ .../tools/assetBrowser/guis/selectModule.gui | 144 ++ .../tools/assetBrowser/guis/selectPackage.gui | 144 ++ .../BaseGame/game/tools/assetBrowser/main.cs | 70 + .../assetBrowser/scripts/addModuleWindow.cs | 112 ++ .../assetBrowser/scripts/addPackageWindow.cs | 110 ++ .../assetBrowser/scripts/assetBrowser.cs | 1304 ++++++++++++++ .../tools/assetBrowser/scripts/assetImport.cs | 1525 +++++++++++++++++ .../assetBrowser/scripts/assetImportConfig.cs | 472 +++++ .../tools/assetBrowser/scripts/editAsset.cs | 371 ++++ .../tools/assetBrowser/scripts/editModule.cs | 127 ++ .../tools/assetBrowser/scripts/fieldTypes.cs | 127 ++ .../assetBrowser/scripts/gameObjectCreator.cs | 130 ++ .../tools/assetBrowser/scripts/newAsset.cs | 663 +++++++ .../tools/assetBrowser/scripts/popupMenus.cs | 154 ++ .../assetBrowser/scripts/selectModule.cs | 17 + .../assetBrowser/scripts/selectPackage.cs | 17 + 38 files changed, 8518 insertions(+) create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/componentIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/gameObjectIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/postEffectIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/soundIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png create mode 100644 Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/GameObjectCreator.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/addModuleWindow.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/addPackageWindow.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/assetImport.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/editAsset.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/editModule.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/newAsset.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/newComponentAsset.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/selectModule.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/guis/selectPackage.gui create mode 100644 Templates/BaseGame/game/tools/assetBrowser/main.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/addPackageWindow.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfig.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/editModule.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/fieldTypes.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/gameObjectCreator.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/selectModule.cs create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/selectPackage.cs diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/animationIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..381dcee849583825fed664f50d9314fda2d8eb3d GIT binary patch literal 8177 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 G;NJk(1STH< literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/clientScriptIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f83a2ff3189fae48971c2975fb3e26b2696da03 GIT binary patch literal 14572 zcmeHu^;=X?*Y;rqr9%k?q(eX$N>N|{>FyK;kQ9_IVJJ~T=@x;ZyQDi5q@@R?L3)50 zY8aYteBSpj_^$7|zF(dn=A3=@>}#JLYp->$d#&?HTT_XQn4TB_05TP2d0hYi;ff%D z@HXyt{BG(Tcf<40RgwiNM;Nzp5BT;kG+qEebu7u{D+1gzk*l(a2LO=w{QKc0^N};) zDsNk`PF&SP2Yq8tITt4?Qot4yf9 z_;U88>>E>laq2f^F&Nv881dCH9s9>e?_d?y_Kavm+5s~2z1y+*n2rS4P$Dl^GpFGM zD(jR(07{CZysOH(@`Tle`+Z#N^hhBA{c?H0h?IR+ZAX^W=D;F1@yc38d*GYB`fEOo z28a|d0Ce$gql^H+lIq_o(X!z#maP9R{&yYzFNGjSbmru=7)FY3{Jy-rJpLk*B>!m= zTFR#*(19$n?znEiNL->|Jb)GulmY<>GVjYPE!eQ3^OJnr4heN9npk{5kjWX3g^0Sp zT$v$=pWA|dUJmFwCB(_4aRlxX97+htP}9p2Y(nO_aqR?&1b;sH$ZKo<$YLX9ZKym0 zR5Gbmdh~L$)dfM1^66+G#SAQ>*lQ%_xp$`6t9fm^f1K6KLt1lP(;qu6ZceHOgG@}? zWl-Rb<2R3xPv-j_@c}#~Kv}5eduLINnc z=jVV*d5+Edx+!qt`1zTe(`EgvcIdoOy}TlwKw=6qtwwkq9b`1P5Ek8OXlnL7K^}N7 z4=BrOc306aY8VJHZD5NVniQu?SrR5*WampBQbinv9@@fTgun|~K$$B?btaqsWzmXH z7IA{u2N}-xMKS7rGs8OoAqz-GcT8lIAtUE{U1jXc6zyoL1_^_Wm&*GK^~1@bOMoSr z5(pXD#(?AN-8%Z1+x_ihWYjpxxB+}BJeK|pmB4}VozA4$&r^hW(L`0DK#z$sx~rt> z1=)zrQlsS55kH1R*D-(eDSmLUW3fJSOYq{3n1N}Iz}@M^JLtrPS6E7AdQ`u4DEzhm zr*S2y_Ar#JE~h7eTqP8slxaCw(qB1>3o=G$1&w!K8SbtR1tce<+!BydYzzx>><}fJ zOc)^t8KOzTK#skxjblK1DJ7RuyX$n~G`!U&&oN@!2Rkt0Y9UYHew^Rv%eyejUlK=? z$_Ha8DgJ!K;li37{ZOm_;R1>%?y;;$K|u%C;b?$XVt&0(3%4?D6o9WX5c22AHEuU2 zt4&gzgJdVZ`t(1{%+%DlQD#sG7==NxQYMJSM_waY;~a1Na_@60zsKzF%%zCG8sYa#w^;LXXAefmDAez>0 zmO({Yeah$<%}7~ZbhgHlm&|pTp!T+XvK}ZkS$MaE1HnD)0Eh1DLP_eM`O@}fGhL*u zn1PlP#m(!}raU~kE7E~mGQpI<-Pg7S-ysc=_+DAQ0j4ssx67Mfhs^gnqbNW!ak#$= zY~CMyJrp|@C8#+F(#t9r7ZZ~iO)-*28yS<|0p8=}GXi7+U2z-8g72qt)H-E0z2p?JAj;@>{a+e4-%x z5~u-$#}d=#j2TL)!6ODrzu2_CxDL)vA)6 z?w2$IrlovWu+fi)w-!&|oY`dw$>UBgHyNjS81cpW_%rl=ICZX{KZCy9uIMF7??99m zpWa5UAU66XV-!I#XU%kM*bQ6#&m-H(AGb~Rl^Agg{0&7`MN8#*SzoaPO*Qp)}5leSW(4|XbF3Qr|dva z=*n1iS$z@Tm&ATbOY0-*zvHG){*t;~Ox9u)igllI9DC`1FL5*(mIGX+Kr)g^NlH@h z_sB?Zy5pSdX#LV&(}S%cb6w$pea-wO5CxAQ#;b<4d$*`Pd+&i0u;sl))2v;)Q|5Sg zzw+CBoOijFS!I^c6jSQHSAP6)$tV+1`ow&5xk!u`=ihLE@(vu;j$wRtBF#pf-rM

V>)K)rm&t6~*^h8PO|YKnWM1Pt?;8sE&q|$0o`qBH*FV~}!^DA(qlW9Oko%jF{u+(ljpD$Iv*#n5^&KD8==QfA6AgMB(~0wQ^0``C zKph=Yw>$ZuRXMHm9;;O!Ci8f|p$)56G_lW}%!_3%V{8Ubg z-rJ6GsqU4k`91-MukSFxf8N9Ea$$;e(Y`|a;|HtZ45RuqZ7VmIq}Zj)I`#d-*>~r( zo@9YWE$UU<^uCyznLqV%9l7S65rLi6k65Tjf9U=@FpU7H#Ns3&#Er9b1v7ElSQ?3$ zutQ9K9_N_sMLpDQ45%$X*oRkC6sufT0C~L@Pc9#xHz?;3Z&BgYSCgJ$z1ZMH%u{4~N}T6521j%Y< zA5QL74&6cVy{G`)-}7q+=KdY!k8+gBt-^t25iLI8#}(bY8ot1^w#mJ-3c}QzBh_;o zXzQ7>42vROrA(){!!M!PC6;*}A5jl7ZR^sPvT)XVw@Ay-D=iiz-vDEEwZ#WmKHbM&!)EW+RnE4#k&FnqwrnyNLAKkY zK=?N44jj^;;How!kUWoi)TpPC3LhNn<-25@c8HUw z-ki&eHwwev*=2F9_nuQ^7x4(KHzM9l{bf?*TAJ)kPx!spYW05rj-=dIP4m$?#iXkmPQ2x+fWXsiem-Y241QUPCP)_ zHL3>xVF3V@uH)+S_agdXuvc`2VS_%lDiR;I#c@D&J%fV$1^IQ)02MtdpM; z-g1*I4^G(3t>&SGtSV&;e}m&MNKaQ1Byk8eyoNs#<`?T9qCSH=H#)vc8t4@P7g9CpQ9J;oDaD zz$6gYMhH-`0xY+i2mt)dZJZAp0pN8R1=PU$A)?>ym;oS*3h>`>2mp)ZxJh9GBQBZ5 z0r@b1Qu*x(o+)O)*-#L0!*!X~2x7+7s9_l6y-=(`5EXDqixQhhdXUxwmRSPLscCC6 z^OV4)T^nNaK5xKxCSDG#=)lCD#MadA&kk%}PA&@6^-hoH zX%fhl06+NIp&vuA4)6ud^Wq^9kg5bk6rrA)tX7LND%;_`x5yk|f02DhbCxjGzqj zo4Y2a8E7dt^4f{KO9$t zus~QSgE^&Bj&wc+KcAzeO|Wx>FF|-Z`#l;OvU^APsUmrgHS)(OG;%O9Zv5#LSc!0 z$sA`jW&}S|noio5NTdB?`UBJ{HHbIXi)idSKJ^8chzmUCi~@sXSdIru?W*XG)pY3m zHm8Hl!*8LOQ&!)0q&M$j(W{e z)8F>{e1uzy7NcaJI7EftKaP_`St9X=BQ`m=u>;Mn#f#h|56C_j{g00uB~S88pZOzw ziI*w&WElcRzE>z!PGLR}%i6%gnl1{FBt zdks@GSd)*$a#tPs^i&T#+|48P@z0ke~2vo=zmcb_jgwQX_A{&{i zA0QcmAn!EaPi zfXQSz%sbyV=!^#RH}s74d%>b9bX=cbA&v?Fm1#}?v+U#)$xEQ@`XUwFdc_%-{aLkn zjL%{FTK~lX)gt%zpO0h)*#LaAe_qNP=Y%H%?yrpKj$j5=ot5n(ZdkpFnXu@KM4x+2fT932GjI%r8}&Oz2kyJ!}vCsG2gi6?NCi#U|+yPm@RD zyohxDJCjh579pULUk%GTr<9^9W*I{spZ3vT8_e%ekc){H5;)5`biUo4Ad}9MSK$`8 zm(*$lxfiw?2E=_FA$Tu}g}cm$!!TbDJm}nt`p`bzE=@uM+MQZtYTAM1w?-69JB{u> zV{=7aRy*@Vn883+eUZ5o9y?Qy#U=%z4j_a6!;`h z9c}y~R;jghjS4ZO)gO8o9c1yo_Hwu4xCJBSu>G9P;-L2Zr>#v&j7Qzsg@^o$RIiSr znqIx{aOFB=`x@fHHlRsun$unX(F_is%{N@Pul1iwSNTCr4Ziu-mGQIWIkkMYh?dl+ z+IymOr)N3PT=xMUi@|nemftX0^3Y>Uy(Uz@?g0GJ`Z(0|&4Y>dBK8_nsEsE9SSqRH zZTaz$B&MUORlZ$}jdx#U+SSpe&1mYP$G7UsaZ9|c=l$Y1*c9w_s2@c%BL4ox$XRct z5N|OBX2=hb^CzvCoPZG@0D#9mjQ_6xXw)v*|5W_9`2S-alDOuWn7v}DWK57cS&85y zIRarLNTJ<&KQ-n{Ia9%dw1o5&)|_KcqJn~Gx61(gn%UtNT$oC%wj;}jPo!iglNRt%{<4Z$i8VQ zy4{+WvQ798AGoY<`nz6@*K$%_CVA@;0r1cD1@cSGFPuuNZ(chTv~@O_sfyGtpgDSX zx?lM=pz|dsgJj_-2v0@Podq;-O%H7vh6pD%ToGXjW%6+}M^b8vK-L#Qg=_!6o@oyT zeX_{lDXyK8e#kF=jLG&FT7wQ)UzTYcBEQ5D6*3e@LEe8weY5?;l59B}8eNcUX|K*q zMs?0~e2OGzV6r2H%}an)FaY#W;IWLL1Tr2ieG%pxgIp_n;iep}$(T^zM4PfR_>``dev&$*wd*rwxkX<*23Q_Y0)Lka z+pHW)E!dcOGIymCUrtO;+M0~ZV@ZKHQbIuL!g#>u%6E^l0f~?%Mfmd_ePTy(F&&95%E&Xdu`m zRi#`x#Fx^znfk0C+*-%^3xzagO}NW9&Ho9!nb9eLZw7O_WCa7bTenO@!m7f zr_fS6RX^%HO$?2>h9bEJKmYh7{9Ix!u#c44Og<8b^CJYlD*zEWX!T6?tjFm{cp9t) z+vI<~%rqk+xh!=rXdAh(U-^UR@PNo@0A|3_|Eu4#)5F%^70)aRpfpnlMaA#Ph8~6& z=*^3W$g#5@&U~mEl$bTwe7#z=J<$=1$&905ew{GTnw2=(c2ZgwwkmQL4~Sp}$wc|v zx>x8?_UU8OCf#9khG!cGA5bFS$348|I|BY@PoW)>DC%8O`L7@-9{?DL!I4uQHAia; zOuQ?Y=#2O|tW)w5DSqoKL>?&im@$6G)FKI6-_GVF_vv8)0LaJU+GoL^{elP|9o&+z zebe+CqDH<0iyg>-L?6rtMNQwMeM)+DolPF5v^pO!&c% z77{FwObV###nl>Vg_BX~JSGay235t$L~AXaABLm4RFB+AaIdRCKmW^w2gKc{27T6D z9p153dGQHGn-&VAw^hn0y$Rf!dEs7E)WAE?_TUe7(1KElA5a)a2;^F=TQ(~@uM2>%29#d`2Q2__L93%+x^SyvyUWa zk)ng>Uw$w@6!rKkhYyWbLi(YqRSi!9{9-I$pi2vrnZ)fEJ5+TML-K~*QWng9{pTak zp+u-{jbK%Oz_eMdAMO=X(A{n&yj&%t0d6dmFej>M;?q zjb**&V1&Qcxcq?FBd6V;pC-ExYxR^eG%`FN?eAb2(UFciFT>^ywRs~AZWX`^G0)F* z3;oJMN0e2|graM_=|4%J{c6y5>r1 zOLd>pYLqiRhj84K_}T2}$G*ML&boN}wkIz>BM#2fX(4Wc(ji049e(DVlq(qWP`|#` zCkGsOIRf(QbUXBg^z2Gl){7?XmDWs=?by`JiU~2~67NHh%%Rm?%cNt7m0m&G^@*&L zm>9Pfyu{?ObX7CgD_n>Ip1c|*`8K^>9{$CxqOH|3EOw5nb}_Jz z#uL>@7rr;^G+y6Z3j~d$_x2QQ5C07RoX8Jsh%GbsqTCJ(3P8wmfAcrKihBOQj@|UW zg@R(rr8YsSy<=7CS#v0=_8_mj*JZ~!4ojCt_gK!69gr`vm#_LL=3yOJjeA2guZSr; z-M3v*TS%^k%w?cwQW639TRge_Lbues$_4tw6hpnl<&&J$I?6`tnb)d^IhRgY9!pJ) z=aH^_$->NA>6(RyJ9(38Khzi2a^6u2XlNZywqMJWW4X&>lhso;X4EoGX&#Us^{FdQ ztikj)2es@TCwwybe*a*y(d}9zbQCLe7of{JeN<18ekXW6)K)iTL^9a;G&6+g(D>IA zVICH`85V|Q!V?*=*M?GVmPNG(<1Xi#gRXZCZzhEtFi9qdlMf=dFc*&= zn9rr<_@A}-fxDci@FEgAe*3&#tbh{_i@^{$n z^@EO8O^0phN}vM+Q=DGQ8oEEirl{a~`^h#kplZkvY|z>5LzAKcO;RKBq8XYyaZ292 zojW&?E)EPt;#9M=9%Q^#t?gIkRe@u$)ciQdEh$>0GG{ZAzwGyu(SvV9iG?t9mQnka zVl2DZ>i8=ex}mfAeBNg9AGYQPGJKXWq@&K=+{>W?#43#lgI~{HrK5 zurYrkpm$z?=GlgrONtJS@a5gQCGN!@{^0wkuY8JNHmH%m?nPoSr$^U29}>rxG)j)9 zPAQ5Pr%FG-);6Y7t!7W(T=BLASU`I=OGvgeoxnpRSL2xCOUk6Qt@{jTFqb(#T@3Q* zFco?snYyzeI>yedpBbKRYMwOxt?}1SPfJ8H(JO96z)FVVn(2#2t@_AGpq9mNbl}z+ z>zU*4z!~N-X!~6aFc#*wVWlEwRyqBgF+~FFlF0w+h$!8B8#5gw(roDHemHM0K#isX zz{ir|8oa}Ak!UyXjJXP?K1EFlxydUe>_O@8F9iauGf1pX2Arqhfr+q?h+1il2ZEi$ zL+(siTA!tU#y4T+IRB!^+@v%H*s?qg?dCs>qQKM9+JZGXcFgO%?dWl-BBt;-5iK0< zpow6_V^O@m=-EERlpz;H(2DcXl7X&&1%OV-tb{6!V~nco!y^26=HW*UOgsk#MbV9UJt|{V@E8 z{l{lD?mrB4tNaXv9bN99vSaAKJiR{ez}7TW5Y2Hz!yCa~^#d4~MUv5N&F0bDli5f_ z)$>`_df3x}!>g)(Eqy`_`PD2{&o34M`Er%ci@Pu!Mj7Z~M*d-~BLC_liRpW+)^Ha$ z|FEf_*IE`!tMH$SI(8}k-|BRyHPiWE8}l688w)i|evtK6+j|~y>6B0Zx z<-W>Bs-%xWW@4HC@cil?53hN>oe3;WADW&iA-ZlyFAAaNc-xR+L5Q68`M}TdPZ2wv zB^b`Lqi)!$_;;gGrDmm2;0pHS0QEySt(S>&nic371LNQdHntN5|7q@E*U(n>I`>jR zA^LJNN@3zD)@~c_lP)QCB!0G$HVWa@)cE_WG_6PrE+>wBzRo1Def+X9T{l1cmaXB*M?v zvtk~4jduSv_B^km?~wW>|hRdv?W zbT;|OsSH@mmf#mxy|5!zsKMFPqb?#385MJ;U%mupZ%)B+VX;d)5S_d)t1U|7ma z=-G4hQ{U2!m-a*Rt;F1_wqfw6)NlRdyFEz|V9$np&sFAVC0NWL;#c&0r%NgZ?h$xA zI`i2YT%quV*URIPxNmpxy6!-6URKIo5v4?~uh8>Vn(uxk36*4X)cA-+Mv>A|<79+a}^w=@Y3|S2wQHJn6bK z5hQu?waVaE0-~bAbp3`=Vj2GZwuanQ&7^B>4JY1W4`HjI^s0CbQ(%&uVv}S4 zz9gxL1)O;wB?o1QE173qc-!}V^Py2!{-gR~2l2CbK0726wSK*$Qu|8Fw5R2qHK7|! zD#0Rl7bus-5#XrkK+Nmb$IfRJdLU7gEy3(f%1g%$EBl>46m&+>WGd*J`dy8 z9pcb*Nu+G6h51_Xv6-t;TlkBVH5o`IW0xM8T5!?Of9J#{5rUV_;L6!ze%g&7v6(C9 zbXQ|E5}W_}4-G4#cke7~v?SFEh%lARN2!+#2${M^uHhVy+AO#@uSYsV=0v)meTz*E zOO-afq}{wj%&U_69Qwx6Q=j(1$aN6cfVozei=V;7B5UohFl0^NQYWY+9EbzX8-goa z1CBcQg*Oozhd$5?YhA@>=2AM|$-BiCe|N~kyq^1Na`q@cgg`i8VRsvk?-G_eh26um zhg#j@%Vz?~gzPg|#(s)7&R8>bl6s)`#mdwm81hT~Ka>C?2;yL|QtVMg@dJyxT zYsmN9lqJ;;;@d{(84hOWCDx#ze5g4REwsos^>MLeUt)5j#eTeXFdK-Q_WHW88+`EP zcChXTvX61|gaD5thlUMyEEs16)TDfx6r5iN=%{*2u{Sn4$Af)PiTu2jJzp0~Pf@b9 ze<7(>epE;+2~$fmNLVA0hwfVmH#7Q9he*;WcrrJRaIo;fDSTc^^#x4%<;-`Zf&tgG zv339EnrX;q&B~QZn|Awq5_BNK(pTNYaC`u^pWg6ir}X!wRv*P+2u}SuRe%Sov>y6& zu4W3*Qb#(zZw{l&Vg2A}AFL5(urKxk_;#n$;Te1zonm`o;jK!eWSX=^!TrT)MFKwW z*$u>HlSKw+OIV-I^ykCFo)7{}!2$+t@6aTNbE=qVTA1KLyV+GH&JL?2C;_;}2zA0^3{t4*$Rfb~tKV zGmuWCop7DOd<`&7vi)LkvSW|mMUM}dO;czxx_i%xJP{d${Jf+1OF(uCe5cp`d}b@Z z@IO;{+@5tBwrGtqSySgbgO*QztFa)!1MV9sq|DfVsF^)s0hT{Mg%#636Jl?^cbfoUtu_9r;kSjqn%wdaDvJV#F*=3WT-ZVe_Q| zTosfc^Y@~>P2dh-8*g%4|D*F6AnYSyiQ5Daq}(o-7-OwDg`l*dmgSV{9OOn?n=Qf>yw4A@gc*TLKt0_gt>!R zd}?W+h7cjpi4vKMT!s?Z>URCS<@$J-CvGMTdlN+Sf&V-B>Dy<_k7jA)BN(eZsTDUm z^{y*x425<5M+OgbKcRHio??7jl@=j>gXLm(2m9le_%e6lc-|MoJr1~09q->9)Q}xLJI8Tt&n(R)x2(cP zNQZ{Pf=2AQHGN_Mn1=eO{;Q@5NaV0qOY3~zAK`_WTH~wT2nvu4>0_Qp@kVwFkC@fJ z!^T=(@DGd5soQ)&Hplk9W*gONjcrnjPfIst@nN`4%YyLtb+1^nm0yfQzB&(j?)wK4 zS+QzAoI<4~+_u;yfg^d6?Cgfv5hUy5NClo+MvWT@DGT#GxB@Cms}04ZfQE6C4>)wg zA}rE{)wbli42?F|hM2X!{DmuQbn3sB{+qL?#L+@(gl}N4)EIxC4HulOmiWv)P#(EV%a&HeswmlLi6UFF&xlFO`3J>AgIdj%Ir z(*+Thh8o1?N%-U@L&eqa4v))h7&R<>^vm8(^|PveNXQb792`p=zb5txxa~d=o)LaIoD_I5zB@(;tgJiW5^)+#58r;yC#0-fRW{~ zi?}CsHa#^{!!r67F*1G460oweel^o&)h?#Dv=lQ+V5ZzC13&O@H78DN@j%r8b^oOdMuC$i;Ub8S<*A+ zl0dq63JlJaziAi*m(mSZFga)W{&UbfGu)y*ph5*CH~!}sqXm(hHt{L2l2-b!Tc=kO zswMWq*|?KUKT(x`9(d+fq?1Z#+Xhnu??Xue@{)c-Mla=)A3Uc^ErcrcGZt=Uoel}|{Qv_-2@=zH3@);ez%H52({JCN{Q{cy0o$yqg7tQ~b16yYPXM&Jh zu)rzk2jsB#xSeiqiB9XqMWe#SbBfrg{@z9FL*@nO;XCv}ap|6hE+lY4;<^qgI8|!7 zg9!A3nvAuXod2ym$|7H)Fao=dvSITQ!`C|>{^6;v(jtroC<&xNT|YH5n7mImogdOC z1$5u4(F$;#Gl(^HX`Cw(zy&d{0x|vCtS?-0sdQtBkZd|BX`FgB?)h92MvfkbYxIae zU{V@!K5DD&)rS)6InF`E5oUw2g`=qy4-B76WHFszo|WVsw%@B7vM!1liU{{F=$?|m zF_?FzLiYp^x5@;|@l}API(-sga}o_{*9u#Ftfmz+*}ZxZey8B~nPlv@6R2;JxQCa}aT%gCm!2W|BMiGDeIp3rvp!<9H&a@92iYP4k4R&ET-=`@w{ z+BfieD0<_I+0$598OOWw!TA)Zk)nCD435!aWx^%rGCiv^>hP}XhD0($^OgtFA`4h= z4~2Sm`I$p4;b>_d*woJ^1A_8AdrgTPWE66Su8bswT)!YKO_-0{f_9U(L@DQ9u{s|I zJQi?uC}9LbmML&H-J(@uq4xA_+MsrQGVJ1BhE^5+L@P~)sH>`1$nAoo;cuj+G6m8_ z3Z>S1rBX%Wg4?4T^+*ptYx4usr*f)=qc3o$F4yu6a6etLPHFn*x4&6DklM~_)a{}z zEnzmmj2^E`+G6i*;+@u$X8VID?0g(BdvNkFzCb7^U>2bgESSr^(%u;WlVu3fSW;?t zTB4nK5UZjtLu?$7&yFJ>8*V&}JGOI*=`Q7fh#wy9*9N1+xxF2UHLuZjXQ87zVeADy zByG(Y&Ka9$-S@x!T4Hucm6mS9aqStM$hXPf-GjmVxbO~fW1Um-8H|4YrbK^EETQE{ z|ISqB-gi0v!;@+LiC0bV-!2O{Ui2gY=lM+30*kU$6K9FPy@xg>sV5FUn0xJaoa{|x z{rEj(Ba0(uM{)wsrgmU9gO&D~6tf#0&RB_(7j&m-d9ou$u??`V{LB=u9(ZkV%p*=d zGm;p~H2=Yg)IdcAxY<59h@6ycuyxivrJkq*>LUb6zk#1T9640xpvC$9eg-uN=DM%| zu*x0|CJ$v^}=&%SpGPjmpM!DClArC81(4U9-_2vp~>Wa0^TRVTh@3%3T(DQI`yxO+wY)x zzj8d6`Z!*T6uGonA~Fd$4xX&lRAkn9aTR1Rl9VPDq(}tN;Zl6!7PB{6+N?}6j5vNH z{|e{Grp2wJPwM^1Iv2BGwT>A~JCKbeF2udYcnda@;F^|@tlD%@JSl}InD3| z`@~d%l7J#VCr{&`R3wLQ3H>{%tC?Nxs-Z}vm*Xzlo5}RYV+JW^JQho?Vx}^ICDX)2 zK9MOS=!lP%VuRjn<70L;uHq_Rhi%Q7rCrafCmOdrmNg4&&5lx zClS535j%eR?eMCy--l1UbjEGXd`M3QhmdY;z1r1c6uA>3M$bwNo%x zce@yU8#}dl$5T(9Wp&KVwC#HsVm1FsqS#nUzMoKYG9lNCpJl&BhAyzK|OsWOB0 zU$v_SJS{2>uN+P*tAuSMFV5@7W0^2#lfRpOA6q}$O;TSfkjiS+7epInnc~z300^)r zyEJw=mxKPlW)wKo>>cP}@8iBu38DILg2R8aJN}=iwv@9U-rzm>x%ZCRfDrd(A}$A3 MK~ug`)-vS(0P0TN6#xJL literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/componentIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/componentIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..cbaf5699025862b2147fd972708158f0bb255e5b GIT binary patch literal 9050 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 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/gameObjectIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/gameObjectIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..6b285daae9fb35e85d132522a3ec28b00f8364b2 GIT binary patch literal 14773 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 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/guiIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..ffeb015f1fa198083840d9870738f5f59766abd5 GIT binary patch literal 5789 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 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/levelIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..7fdb61d1b1cfd9e2af585bcded85a68824021509 GIT binary patch literal 6797 zcmd^DXIPWjwvOe9=%7-hD~bpRii5N$O+iGYN|7Fv-Z9c45S$ql5QxecK$?ia(1LUV zfuNFLsDiXmC7~07p(YTL`(?_Tj{Ci*;w zL=S;LARdF8*Udqoy+C&_=->gMSr6;q2ATuThWgim_7kYVDY}0g=yBh_X&VRv9p>je zdq6KUg@Hk?AOmAPuBii}f0I1!mw1&444v?@vwLU$YDwSsssk`zAR23$3uRXE!=aOsTWw$FcrBB=FmVP~0o2 z)1vvOAl%1feL_`=+F#ofZw*if?z?9DI<+omVQsl?a%;<-L?{>92Lhv9m-m8> zfj}|9tL_JZP65px5a=KXbQS0U!2IjKzH@pEVDpbnt^&QkwEk`Sw|DwyWB;C|@A#~L z++=Ty!gqo4KUV)0hW|MI8}i?O8h={)X5wET-v8S8JEva-{r4H30#W{NNz@{0?jZy+ zIPx#^m$_ag_Q58PPpMx7i35ZG4BCG-_Sb+!-^g-ou}eKC zNKP{LgPH_JW{wT>$*3u}Z9bZvFY$>(`l{Mhp*_21B_*9vW^rg8E%(C=VFyTJYN`-v zCZ91}2Nptfn&8(u)CJ>1VXE11hy-KY0t8g zXb(|IG~{4+B|Az!R)>-$@&qe#`Iu9dX#7W4xlIQNO}9|WEt+@_eDhhDXLRu_Wc0Az z6>^4ph|HvERZ7JUVu`ur$uHhk<&l-AP`$Q!aVGVN=p@RU5)(7 zi3)X=?}yEgNLoh?+WEAvk16zVG}f4?tJ}iss)w`u3|YMycE1 zyCgoUJ}>w3#K>S)SmREiJ~=)A@}GtXO@&PtPmWZmn=sC%UbCu75wj;fTn>m|-k4#y zrfth!U6~bStmkY_WA`YbZz;utVxFThfsU|yquo}Txr;WL!^7f{bt?(1OX3l`?^~yY zZ6QXOajr(y>w%VA=~G1K))(ixt-;mR$3l%yDyEbur}Q65-D5tW)n9YkpSb$yw~mwc zB?_}^w0WkbhO(N7X{Rx+!|*WlZn#zfJ2)uqZ~pDMzw?M-1bZvvASl0sJ2J;yGo3U3)5X|q(! zS@fv(sDygy!GBlt|sI~kdr1>Ln6{5 z^9TB1Efw69n=j|YZuWI_80k$7Ym6+^Z{O^gG?E0p>TIY&(^m~V^gSF`S7f+S1xcY0 zn1;eQ+f}3DM~l_A%}-2AN;LHuJ>{Lp87EmOHdksFzECYk#P}?W6=m9fdY=@JALbTOU5Wsluhr=YRvf$A$FG=b%35AX zE*PYfS!HLVj6zM1w0-K+AuXdQ6T&=JbUZvbp^CkAu^Xptj7THMr5o%ANv$>~v*=A! zp7^>(7nrOkr-fTUVJ1wuv-lRjPdW_wYL+>|vC z%(H_k*c>K4hb@eV>2tldd8D$^CAAmSUMgcR#P(PdiLcwiy6Dn!Q?U{ZEBdL($xa&w zZMrXMIbunSbacn${DKSGE9lg~=`Y?pqF-JLAUqUvOpjl6uf%XzpSL=x>WkRmww7&# zM<}DBXSm!L)1lR@q4}#Yw+CQah{Vz;ADR#H^IChmGt(kLw<{oEIXR`+^>!NmW9yE^ z7<~>^bjFSG#!s3TWae(aB*tHUTf4scm^FnBIdA=r%%;Ed;Dc{9ROFshSeU=CK)xAx z>8@%<0q;_h9tZX(+(7`mI5(SsX%~el1a;*o8Y~x8pEv zq2gx%zlK(|S#+qk6aa@`%7$z$P3;p$JB^7$pM2QY=)8>Zirt&w2tAa}D_2+O`=wf0o%^gFXZpjR);PuW4)}Wz5Ek<`} z02jWfI1W`^?j^~6mhYg&znd$jhW}7{9vAi5CBD|HbB5&CR{wnTVnaCPZgEvhx#Nu3 ze#h}h9n!!L9&7T@QTo&L(p4a!wUkUJ@LJ1YCUQ+L{z*#z0&eyTj3)o)X3c0 z#zL>G6h>g>grDYFxVV=;ze8$QLGv!PqT#nPnOYTTCuF_23_G2$+6gcvx_icvAZWvA z@4qRI>NB>3nc>40|mN{4P1AL+#B;d8%S+4PzNj8~-(PYzA+{I}>ABE-c4D?4 zKlofbx#ImT=7;HLKyGNv)7}nzp$^KN{mL$L`6D^GaJU{9M_0Q*pk8Br9CJ0+D9;tx z%A5T4KAM>KVs^8hhv?ui&{QP3v&fTF#>xKEJtaRpW_P)|akd83N~L;pRH%QkboNm0 z%wl-e?k3X}7NEe0fAC@(aI5U;Tqt|plVbl;Ek)%@%0WKFo( z+@bDE?VDjh?oCWrmf434H;$QHm`4P2!wKScc5#j7nL~G_OMIk@jzI3+!EFjWX*Qx_ zJiDlfSzm@7tidKu9e)%T97RBGHn=uSv6c!gYo9DwG`{J==3*k2V*mF$&okH@IG> z5z-8ff%;(}@HB*|YHk{NMV%t2(x-~VueLy<%Gf9hSN zPmvrne#~OdstmoDcWvoVAJUI>tkhi&H9iqPb!g0g==W418Z}~v%L5Ti3nC4DJSgYi zb=~VbziUrTVRM{L&J%4@&3}iWZFDkuO2FrX(@>I=oJqMi2ILu1h6PP{Z?#XI`+b_$>0RxXtX2tgh$r)T`a$_=0@ z@3MRMC~+r)-WKeA^%Ul}icGAkHk`rtK9rS$@iZ)nl2%b0MXY9DMN<1OC5O6atx2^N zryUnDoh|3jvy1OzE7-0V9S=i~4A!bD(bEYd>llSik~@0ibQMyY!4i z4LWgo(&mNv%MVLJwZUy(-0)}mZyIT)`6etSfaAZtvPPy%-U#+daMHlkUIbF%JAt~Y zCe^9iG1={EsQ8K)>GZqSl^F-ewKYX|%wc?LoRy~$`SjLcz4lnoFh87; zw3g;erfW+{q^jPgwRjOcV6I`lDB$M0Qh-hDpH!htp$V;{4ijjtOM|`_(HU(=@aFGh z@0)mfCQMT2BfHqy>v-+QNI?>caK@c)Kgeg?TIMl-KoyWuX(}_A<}-|$dUf0qblInL z1&cdVh$U@8yu}5_oaeSBz%(=wUQ%+iRaOm>8jbn4onDTEJC8v*u~k# z&kWxh`2(UZ;|}91mZQV-T`$pQil$RvWsQy;7m{HH5tbU^AsU+(I;BPm6f%-Z8sSrB z@Csq;U>S8Ld}aM6rn1sg`WomyhR(d+@HZz`#AmPgJ9*^!u{4qeU1B}^7)@#NA$zoz zIy}+;a^Ax-0`PT!kXD-)tN3ZV0v?c@-Z88vQpSthzwcV(}uBc;Vs&)P_X zB}oN;{&KylNoWUVbWcI+V>VVfSnAPQhdU<^f+4#bA0LKA-%}l^^-!+E z?T&`xkPY}^csAO(6+S;MzGI@TjWVh?GtooreFGNxy3HzsLVT==2-P$KIS}xV(%T)p zG(zs2c>w%IpuI-OA{u(_1*!ug#A_WKkQh~%BLQz@B+i$VQ=NW*t7!>*mM3VX2Y7nk zTA$0w&PnE)mF|249P)ikqmMVZSs4o6*j!o^b6MF`YlAysHAP=vF_BwppCxTK^OJF( zFUIv`)A6mTZDq)G=hIrLs}JfQoOJs!rELZH7#lJwYGwiaHjU+fe}m}2TzHg1F0$x( zvQ@oRHnIk;L!Z&AVk8QK*M`XO%=>n}UcM;w(CbX>tKU`9@Y8hVlu}8L2+LfOtx$RV z+_Uh-=GM_fp;cP$zDdLmaQ|xX-PY0sF1J)IMkbv~ab@;QrIHO(^qm#kBR?RslFFcZ zLyv&VP!z>xUruqhLt4DPy9{aUm&qlGBz5T{I7>w*{+)N6fUR>fGb0gk0w%rbdwDGl zKA2&zP7W+ncY(Q`)6#~5slfHVNy$ag;=K4;4=9<3(uK-zn|lm0e^9IVNLWlea%??*6JE3?&d|=a~?p?BUZY4T2l^xru8#}C{8aC z4`*<~c92A%rXiRR`%&nOT@}%@XF$(hRVWJmXt;NH^)owbU@XJ|gPyn?Evr?t&_B;Q ztHv}~QV0Bl{=OOj>L7?d!*ULT2hA*!QqDGiw$oJ=YP3^#u`W423hB`iAlK4z>3OWO z{GD~}D|Z3PTD2I&Sk|zE<{5MZ*Op$h*;}PM2ItBLB%Ev$)Z31x1DWybwwB6+QwpPO z%T8&G0Z%@yv(JIqv2J4!JqSpr3bR@M$xcp)eHvMyPr}SK^P5ULyhie!_?v9+y&X-U zECJYf+Idva!(}TF(VBB2Lh;Vvr>UWb`HW(CqEn`ZxIR({vEV_;I++xu^3?%QIY4rZ zA$LBw&Rm!ha^@^jE4bma8QwW(O-iQa)=$T-;N!KK?#7g@o|9z9oz4EQz{TKs%||Ox z{~H-WcM>V}B;tu(Be_Q{+Z^dL&@nZtM22?I?=pAkQ*7)p6KM;6#4eBu>DSqV9}8@L zm;-KSV=CdTMlS)?@+*FVNCU4h^vUm$-E_|tWIZ5?lxH4Tt)CT9eu&>nLwk%0U~9?#l^UNf{- zM!gqXnQngo^NUbsLA^PwN~Y;VcTwiVZa@sgK@6SK{&snQtdy!b&u<#t5#NRBH4BQR`jmwHSe;J;wMtfY0xU@$}8H>-FFtI3h*vnf#4RV!vpB zxBru}jjoFP+;gf!YIyFAq~7$hC$qi^F9C9OPrp8$5})s^DEK7SMpn>S4$Jr08tLpA zuK4JVAUPJtp!bq|nV$Eg58Odg95|8%^joyTzWv{-$NyfX_**IPKPpjkHu+}aJFBtZ zIsMe%tDJvbtNa)5^q<$p{~uJhWB!iuRiO8sl=x$Mi`@nrRCJXjvtVg-2QUIM&@;J? J(z*N7e*q&EOz;2z literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/materialIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..0e6c456a644cf50a23d8fd1abf5609681bcda256 GIT binary patch literal 7889 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 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/scriptIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..1a2433dea6c67e3abe4e89db66fac55c32c7db5b GIT binary patch literal 10044 zcmeHtcTiJNw{JiNlqMpeARwZERHYNDg7n^d=slqH4vG+^_ZB)r=)FkjBB0VC5Q=~Z z2uTQt5RiTk_s#w9&G)|h?swNXr!FU4%0#T|c zE9ini#K0*rh>Qd{?E9mRfdh$+nvw!=90wsGp{PaR?D|V(6E6^moc6L2fwFV%0DqEt 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 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/serverScriptIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..f65bccb3980c63b93a36c873f539048e41e3558f GIT binary patch literal 14897 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 YMz1{4xS6F|;CzzmDmuz_Pi?~g7vXvhjsO4v literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png b/Templates/BaseGame/game/tools/assetBrowser/art/stateMachineIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..95ef798eec2267de8e28636ebd4b9ba740244bcc GIT binary patch literal 13506 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 BQEUJJ literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml new file mode 100644 index 000000000..a442ab0a8 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/GameObjectCreator.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/GameObjectCreator.gui new file mode 100644 index 000000000..eb2bf15e6 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/GameObjectCreator.gui @@ -0,0 +1,217 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GameObjectCreator) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + selectedEntity = "20054"; + + new GuiWindowCtrl(CreateGameObjectWindow) { + text = "Create GameObject"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(GameObjectCreator);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "328 322"; + extent = "368 123"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(GameObjectCreateBtn) { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "224 92"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_importAssetWindow.ImportAssets();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "292 92"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(GameObjectCreator);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(GameObjectCreatorObjectName) { + text = "Game Object Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 60"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GameObjectCreatorPkgBtn) { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_addModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(GameObjectModuleList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + text = "Characters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(GameObjectCreatorName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "116 60"; + extent = "234 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/addModuleWindow.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/addModuleWindow.gui new file mode 100644 index 000000000..e8f35a13a --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/addModuleWindow.gui @@ -0,0 +1,142 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_AddModule) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_addModuleWindow) { + text = "Create New Module"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "88 35"; + extent = "196 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ModuleName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Module Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 35"; + extent = "72 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addModuleWindow.CreateNewModule();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addModuleWindow.Close();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/addPackageWindow.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/addPackageWindow.gui new file mode 100644 index 000000000..48a48f5be --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/addPackageWindow.gui @@ -0,0 +1,142 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_AddPackage) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_addPackageWindow) { + text = "Create New Package"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "88 35"; + extent = "196 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "PackageName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Package Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 35"; + extent = "72 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addPackageWindow.CreateNewPackage();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addPackageWindow.Close();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui new file mode 100644 index 000000000..fd06f7561 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui @@ -0,0 +1,934 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + AddNewArtAssetPopup = "18801"; + AddNewAssetPopup = "18802"; + AddNewScriptAssetPopup = "18800"; + currentPreviewPage = "0"; + enabled = "1"; + importAssetFinalListArray = "20465"; + importAssetNewListArray = "20463"; + importAssetUnprocessedListArray = "20464"; + totalPages = "1"; + + new GuiWindowCtrl(AssetBrowser_addFilterWindow) { + text = "Create New Tag"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "321 334"; + extent = "381 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "64 35"; + extent = "196 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "tagName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Tag Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 35"; + extent = "52 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "64 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.createFilter( AssetBrowser_addFilterWindow-->tagName.getText() );AssetBrowser_addFilterWindow.setVisible(0);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "196 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_addFilterWindow.setVisible(0);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiWindowCtrl(AssetBrowserWindow) { + text = "Asset Browser"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "AssetBrowser::hideDialog();"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "256 107"; + extent = "512 554"; + minExtent = "383 274"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(CreateAssetButton) { + text = "New"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "3 22"; + extent = "45 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ImportAssetButton) { + text = "Import"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "50 22"; + extent = "45 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiWindowCtrl(TagFilterWindow) { + text = "New Window"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + docking = "None"; + margin = "4 4 4 4"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "129 62"; + extent = "161 250"; + minExtent = "161 86"; + horizSizing = "windowRelative"; + vertSizing = "windowRelative"; + profile = "ToolsGuiToolbarWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "VisibilityLayerWindow"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "2 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 9"; + extent = "159 238"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl(TagFilterList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "-2"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "3 1"; + extent = "153 16"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "theVisOptionsList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiSplitContainer() { + orientation = "Vertical"; + splitterSize = "2"; + splitPoint = "149 100"; + fixedPanel = "None"; + fixedSize = "356"; + docking = "None"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "3 42"; + extent = "505 509"; + minExtent = "64 64"; + horizSizing = "relative"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "147 509"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "Panel1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "147 31"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "inspectorStyleRolloutDarkProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Filters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 0"; + extent = "30 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconNew.png"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "113 1"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.viewTagsFilter();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Show assets grouped and filtered via tags."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconList.png"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "130 1"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.viewListFilter();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Views assets via module-oriented list tree."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 17"; + extent = "147 493"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "147 493"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiEditorScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(AssetBrowserFilterTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + mouseDragging = "1"; + multipleSelections = "1"; + deleteObjectAllowed = "1"; + dragToItemAllowed = "1"; + clearAllOnSingleSelection = "1"; + showRoot = "1"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + showObjectIds = "1"; + showClassNames = "1"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + position = "1 1"; + extent = "145 294"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTreeViewProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "filterTree"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "151 0"; + extent = "354 509"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "panel2"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 0"; + extent = "354 41"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "inspectorStyleRolloutDarkProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/new"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "42 22"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.createNewAsset();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Create New Asset"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "23 22"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.showDeleteDialog();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Delete Asset"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(AssetBrowserSearchFilter) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "\c2Filter..."; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "62 19"; + extent = "273 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserSearchFilterText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(TagFilterButton) { + bitmap = "tools/gui/images/visible"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "4 19"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.toggleTagFilterPopup();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Assets"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 0"; + extent = "53 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "337 22"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.showDeleteDialog();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Delete Asset"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "1"; + position = "1 40"; + extent = "354 468"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl(AssetListPanel) { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "354 448"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiEditorScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "0"; + position = "1 1"; + extent = "352 254"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiModelessDialogProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "352 4"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiDynamicCtrlArrayControl() { + colCount = "3"; + colSize = "100"; + rowCount = "2"; + rowSize = "124"; + rowSpacing = "2"; + colSpacing = "2"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "1"; + dynamicSize = "1"; + padding = "0 0 0 0"; + position = "3 4"; + extent = "352 250"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "materialSelection"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiContainer() { + docking = "Bottom"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 448"; + extent = "354 20"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "materialPreviewControlContainer"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "242 491"; + extent = "53 19"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "SelectButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "300 491"; + extent = "52 19"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser.hideDialog();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetImport.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetImport.gui new file mode 100644 index 000000000..199ad91b8 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetImport.gui @@ -0,0 +1,613 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetImportCtrl) { + position = "0 0"; + extent = "1440 900"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(ImportAssetOptionsWindow) { + text = "Import Options"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "633 358"; + extent = "346 409"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "271 377"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetOptionsWindow.saveAssetOptions();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 26"; + extent = "326 344"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiVariableInspector(ImportOptionsList) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "309 64"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiWindowCtrl(ImportAssetConfigEditorWindow) { + text = "Import Options Config"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "562 251"; + extent = "376 503"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Configuration Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 26"; + extent = "100 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(AssetImportConfigName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "113 25"; + extent = "250 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "301 471"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.saveAssetOptionsConfig();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 50"; + extent = "356 414"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiVariableInspector(ImportOptionsConfigList) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "339 64"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiWindowCtrl(ImportAssetWindow) { + text = "Import Assets"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "536 205"; + extent = "368 502"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "224 470"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetWindow.ImportAssets();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "292 470"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(ImportAssetModuleList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_addModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "New Module"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Import Options Config:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 56"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(ImportAssetConfigList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "126 53"; + extent = "175 22"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "305 53"; + extent = "15 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.addNewConfig();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "New Config"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconInformation.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "325 53"; + extent = "15 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.editConfig();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Edit Config"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconDelete.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "346 53"; + extent = "15 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "ImportAssetConfigEditorWindow.deleteConfig();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Delete Config"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 82"; + extent = "348 381"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl(ImportingAssetList) { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "0"; + changeChildPosition = "1"; + position = "1 1"; + extent = "345 20"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/editAsset.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/editAsset.gui new file mode 100644 index 000000000..45d411f20 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/editAsset.gui @@ -0,0 +1,147 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_editAsset) { + position = "0 0"; + extent = "1920 1080"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_editAssetWindow) { + text = "Asset Properties"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_editAsset);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "710 375"; + extent = "500 329"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 21"; + extent = "498 283"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiInspector(AssetEditInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "481 101"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "402 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_editAsset.saveAsset();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "450 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_editAsset);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/editModule.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/editModule.gui new file mode 100644 index 000000000..90ff639dd --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/editModule.gui @@ -0,0 +1,147 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_editModule) { + position = "0 0"; + extent = "1920 1080"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_editModuleWindow) { + text = "Module Properties"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_editModule);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "710 375"; + extent = "500 329"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "1 21"; + extent = "498 283"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiInspector(ModuleEditInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "481 101"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "402 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_editModule.saveModule();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "450 305"; + extent = "45 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_editModule);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/newAsset.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/newAsset.gui new file mode 100644 index 000000000..09fcb997d --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/newAsset.gui @@ -0,0 +1,237 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_newAsset) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(AssetBrowser_newAssetWindow) { + text = "Create Asset"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_newAsset);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "328 140"; + extent = "368 450"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(NewAssetCreateBtn) { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "227 419"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "CreateNewAsset();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "295 419"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "AssetBrowser_newAssetWindow.onClose();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(NewAssetModuleList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserModuleList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(NewAssetModuleBtn) { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_AddModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl(NewComponentAssetSettings) { + position = "12 120"; + extent = "344 107"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOn"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 56"; + extent = "354 357"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiVariableInspector(NewAssetPropertiesInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "337 338"; + minExtent = "16 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/newComponentAsset.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/newComponentAsset.gui new file mode 100644 index 000000000..65896dccc --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/newComponentAsset.gui @@ -0,0 +1,434 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_newComponentAsset) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(AssetBrowser_newComponentAssetWindow) { + text = "Create Component"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(AssetBrowser_newComponentAsset);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "328 250"; + extent = "368 268"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Target Module:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 27"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "NewComponentModuleList"; + class = "AssetBrowserModuleList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "342 27"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(AssetBrowser_AddModule);\nAssetBrowser_addModuleWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "NewComponentModuleBtn"; + class = "NewAssetModuleBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Component Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 83"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NewComponentName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 83"; + extent = "203 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Parent Component:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 57"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx(ParentComponentList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 54"; + extent = "204 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "NewAssetTypeList.onSelected();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NewComponentFriendlyName) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 109"; + extent = "203 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Friendly Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 109"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NewComponentGroup) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 134"; + extent = "203 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Component Group:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 134"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "134 159"; + extent = "203 64"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiMLTextEditCtrl(NewComponentDescription) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + position = "1 0"; + extent = "201 64"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Description:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 159"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "224 240"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "createNewComponentAsset();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "292 240"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_newComponentAsset);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/selectModule.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/selectModule.gui new file mode 100644 index 000000000..a1c4293ab --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/selectModule.gui @@ -0,0 +1,144 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_SelectModule) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_SelectModuleWindow) { + text = "Select Module"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiPopUpMenuCtrlEx() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "39 34"; + extent = "217 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserModuleList"; + internalName = "ModuleList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "260 32"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "SelectPackage_NewAssetModuleBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_SelectModule);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_addModule);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/selectPackage.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/selectPackage.gui new file mode 100644 index 000000000..055763d35 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/selectPackage.gui @@ -0,0 +1,144 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AssetBrowser_SelectPackage) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultNonModalProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl(AssetBrowser_SelectPackageWindow) { + text = "Select Package"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "362 334"; + extent = "299 99"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiPopUpMenuCtrlEx() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "39 34"; + extent = "217 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AssetBrowserPackageList"; + internalName = "PackageList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/iconAdd.png"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "260 32"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "SelectPackage_NewAssetPackageBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "88 68"; + extent = "126 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_SelectPackage);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "220 68"; + extent = "64 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(AssetBrowser_addPackage);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/assetBrowser/main.cs b/Templates/BaseGame/game/tools/assetBrowser/main.cs new file mode 100644 index 000000000..32ae4682f --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/main.cs @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +if( !isObject( ToolsGuiDefaultNonModalProfile ) ) +new GuiControlProfile (ToolsGuiDefaultNonModalProfile : ToolsGuiDefaultProfile) +{ + modal = false; +}; + +function initializeAssetBrowser() +{ + echo(" % - Initializing Asset Browser"); + + exec("./guis/assetBrowser.gui"); + exec("./guis/addModuleWindow.gui"); + exec("./guis/gameObjectCreator.gui"); + exec("./guis/newAsset.gui"); + exec("./guis/newComponentAsset.gui"); + exec("./guis/editAsset.gui"); + exec("./guis/assetImport.gui"); + exec("./guis/selectModule.gui"); + exec("./guis/editModule.gui"); + + exec("./scripts/assetBrowser.cs"); + exec("./scripts/popupMenus.cs"); + exec("./scripts/addModuleWindow.cs"); + exec("./scripts/assetImport.cs"); + exec("./scripts/assetImportConfig.cs"); + exec("./scripts/gameObjectCreator.cs"); + exec("./scripts/newAsset.cs"); + exec("./scripts/editAsset.cs"); + exec("./scripts/editModule.cs"); + + exec("./scripts/fieldTypes.cs"); + + new ScriptObject( AssetBrowserPlugin ) + { + superClass = "EditorPlugin"; + }; + + Input::GetEventManager().subscribe( AssetBrowser, "BeginDropFiles" ); + Input::GetEventManager().subscribe( AssetBrowser, "DropFile" ); + Input::GetEventManager().subscribe( AssetBrowser, "EndDropFiles" ); + + AssetBrowser.buildPopupMenus(); +} + +function AssetBrowserPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the toolbar. + AssetBrowser.addToolbarButton(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.cs new file mode 100644 index 000000000..784ed7d63 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/addModuleWindow.cs @@ -0,0 +1,112 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +function AssetBrowser_addModuleWindow::onGainFirstResponder(%this) +{ + %this-->moduleName.setFirstResponder(); +} + +function AssetBrowser_addModuleWindow::close() +{ + Canvas.popDialog(AssetBrowser_addModule); + eval(AssetBrowser_addModuleWindow.callbackFunction); +} + +function AssetBrowser_addModuleWindow::CreateNewModule(%this) +{ + %newModuleName = %this-->moduleName.getText(); + + if(%newModuleName $= "") + return; + + echo("Creating a new Module named: " @ %newModuleName); + + %moduleFilePath = "data/" @ %newModuleName; + %moduleDefinitionFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".module"; + %moduleScriptFilePath = %moduleFilePath @ "/" @ %newModuleName @ ".cs"; + + %newModule = new ModuleDefinition() + { + ModuleId = %newModuleName; + versionId = 1; + ScriptFile = %newModuleName @ ".cs"; + CreateFunction="onCreate"; + DestroyFunction="onDestroy"; + Group = "Game"; + + new DeclaredAssets() + { + Extension = "asset.taml"; + Recurse = true; + }; + }; + + TAMLWrite(%newModule, %moduleDefinitionFilePath); + + //Now generate the script file for it + %file = new FileObject(); + + if(%file.openForWrite(%moduleScriptFilePath)) + { + %file.writeline("function " @ %newModuleName @ "::onCreate(%this)\n{\n\n}\n"); + %file.writeline("function " @ %newModuleName @ "::onDestroy(%this)\n{\n\n}\n"); + + //todo, pre-write any event functions of interest + + %file.close(); + } + + //force a refresh of our modules list + ModuleDatabase.ignoreLoadedGroups(true); + ModuleDatabase.scanModules(); + %success = ModuleDatabase.loadExplicit(%newModuleName, 1); + ModuleDatabase.ignoreLoadedGroups(false); + + //force a reload of the Module lists + NewAssetModuleList.refresh(); + GameObjectModuleList.refresh(); + ImportAssetModuleList.refresh(); + + AssetBrowser.newModuleId = %newModuleName; + + Canvas.popDialog(AssetBrowser_addModule); + eval(AssetBrowser_addModuleWindow.callbackFunction); +} + +function AssetBrowserModuleList::onWake(%this) +{ + %this.refresh(); +} + +function AssetBrowserModuleList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/addPackageWindow.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/addPackageWindow.cs new file mode 100644 index 000000000..90d999b8e --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/addPackageWindow.cs @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +function AssetBrowser_addPackageWindow::onGainFirstResponder(%this) +{ + %this-->packageName.setFirstResponder(); +} + +function AssetBrowser_addPackageWindow::close() +{ + Canvas.popDialog(AssetBrowser_addPackage); + eval(AssetBrowser_addPackageWindow.callbackFunction); +} + +function AssetBrowser_addPackageWindow::CreateNewPackage(%this) +{ + %newPackageName = %this-->packageName.getText(); + + if(%newPackageName $= "") + return; + + echo("Creating a new package named: " @ %newPackageName); + + %moduleFilePath = "data/" @ %newPackageName; + %moduleDefinitionFilePath = %moduleFilePath @ "/" @ %newPackageName @ ".module"; + %moduleScriptFilePath = %moduleFilePath @ "/" @ %newPackageName @ ".cs"; + + %newPackage = new ModuleDefinition() + { + ModuleId = %newPackageName; + versionId = 1; + ScriptFile = %newPackageName @ ".cs"; + CreateFunction="onCreate"; + DestroyFunction="onDestroy"; + Group = "Game"; + + new DeclaredAssets() + { + Extension = "asset.taml"; + Recurse = true; + }; + }; + + TAMLWrite(%newPackage, %moduleDefinitionFilePath); + + //Now generate the script file for it + %file = new FileObject(); + + if(%file.openForWrite(%moduleScriptFilePath)) + { + %file.writeline("function " @ %newPackageName @ "::onCreate(%this)\n{\n\n}\n"); + %file.writeline("function " @ %newPackageName @ "::onDestroy(%this)\n{\n\n}\n"); + + //todo, pre-write any event functions of interest + + %file.close(); + } + + //force a refresh of our modules list + ModuleDatabase.ignoreLoadedGroups(true); + ModuleDatabase.scanModules(); + %success = ModuleDatabase.loadExplicit(%newPackageName, 1); + ModuleDatabase.ignoreLoadedGroups(false); + + //force a reload of the package lists + NewAssetPackageList.refresh(); + GameObjectPackageList.refresh(); + ImportAssetPackageList.refresh(); + + Canvas.popDialog(AssetBrowser_addPackage); + eval(AssetBrowser_addPackageWindow.callbackFunction); +} + +function AssetBrowserPackageList::onWake(%this) +{ + %this.refresh(); +} + +function AssetBrowserPackageList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs new file mode 100644 index 000000000..0979f219e --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs @@ -0,0 +1,1304 @@ + +new SimGroup(AssetBrowserPreviewCache); + +//AssetBrowser.addToolbarButton +function AssetBrowser::addToolbarButton(%this) +{ + %filename = expandFilename("tools/gui/images/iconOpen"); + %button = new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = AssetBrowserBtn; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "180 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "AssetBrowser.ShowDialog();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Asset Browser"; + hovertime = "750"; + bitmap = %filename; + bitmapMode = "Centered"; + buttonType = "PushButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + ToolsToolbarArray.add(%button); + EWToolsToolbar.setExtent((25 + 8) * (ToolsToolbarArray.getCount()) + 12 SPC "33"); +} +// +function AssetBrowser::onAdd(%this) +{ + %this.isReImportingAsset = false; +} + +function AssetBrowser::onWake(%this) +{ + %this.importAssetNewListArray = new ArrayObject(); + %this.importAssetUnprocessedListArray = new ArrayObject(); + %this.importAssetFinalListArray = new ArrayObject(); +} + +//Drag-Drop functionality +function AssetBrowser::selectAsset( %this, %asset ) +{ + if(AssetBrowser.selectCallback !$= "") + { + // The callback function should be ready to intake the returned material + //eval("materialEd_previewMaterial." @ %propertyField @ " = " @ %value @ ";"); + if( AssetBrowser.returnType $= "name" ) + { + eval( "" @ AssetBrowser.selectCallback @ "(" @ %name @ ");"); + } + else + { + %command = "" @ AssetBrowser.selectCallback @ "(\"" @ %asset @ "\");"; + eval(%command); + } + } + else + { + //try just setting the asset + %this.changeAsset(); + } + + Inspector.refresh(); + + AssetBrowser.hideDialog(); +} + +function AssetBrowser::showDialog( %this, %AssetTypeFilter, %selectCallback, %targetObj, %fieldName, %returnType) +{ + // Set the select callback + AssetBrowser.selectCallback = %selectCallback; + AssetBrowser.returnType = %returnType; + AssetBrowser.assetTypeFilter = %AssetTypeFilter; + AssetBrowser.fieldTargetObject = %targetObj; + AssetBrowser.fieldTargetName = %fieldName; + + Canvas.add(AssetBrowser); + AssetBrowser.setVisible(1); + AssetBrowserWindow.setVisible(1); + AssetBrowserWindow.selectWindow(); + + if(%selectCallback $= "") + { + //we're not in selection mode, so just hide the select button + %this-->SelectButton.setHidden(true); + } + else + { + %this-->SelectButton.setHidden(false); + } + + //AssetBrowser_importAssetWindow.setVisible(0); + //AssetBrowser_importAssetConfigWindow.setVisible(0); + AssetBrowser.loadFilters(); +} + +function AssetBrowser::hideDialog( %this ) +{ + AssetBrowser.setVisible(1); + AssetBrowserWindow.setVisible(1); + Canvas.popDialog(AssetBrowser_addModule); + Canvas.popDialog(ImportAssetWindow); + + Canvas.popDialog(AssetBrowser); +} + +function AssetBrowser::buildPreviewArray( %this, %asset, %moduleName ) +{ + %assetDesc = AssetDatabase.acquireAsset(%asset); + %assetName = AssetDatabase.getAssetName(%asset); + %previewImage = "core/art/warnmat"; + + AssetPreviewArray.empty(); + + // it may seem goofy why the checkbox can't be instanciated inside the container + // reason being its because we need to store the checkbox ctrl in order to make changes + // on it later in the function. + + %previewSize = "80 80"; + %previewBounds = 20; + + %assetType = AssetDatabase.getAssetType(%asset); + + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = %previewSize.x + %previewBounds SPC %previewSize.y + %previewBounds + 24; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + assetName = %assetName; + moduleName = %moduleName; + assetType = %assetType; + }; + + %tooltip = %assetName; + + if(%assetType $= "ShapeAsset") + { + %previewButton = new GuiObjectView() + { + className = "AssetPreviewControl"; + internalName = %matName; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + position = "7 4"; + extent = %previewSize; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + renderMissionArea = "0"; + GizmoProfile = "GlobalGizmoProfile"; + cameraZRot = "0"; + forceFOV = "0"; + gridColor = "0 0 0 0"; + renderNodes = "0"; + renderObjBox = "0"; + renderMounts = "0"; + renderColMeshes = "0"; + selectedNode = "-1"; + sunDiffuse = "255 255 255 255"; + sunAmbient = "180 180 180 255"; + timeScale = "1.0"; + fixedDetail = "0"; + orbitNode = "0"; + + new GuiBitmapButtonCtrl() + { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "0 0"; + extent = %previewSize; + Variable = ""; + buttonType = "ToggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + %name = AssetDatabase.getAssetName(%assetId); + + if(%name $= %assetName) + { + %asset = AssetDatabase.acquireAsset(%assetId); + + %previewButton.setModel(%asset.fileName); + //%previewButton.refreshShape(); + //%previewButton.currentDL = 0; + //%previewButton.fitToShape(); + + break; + } + } + } + else + { + if(%assetType $= "ComponentAsset") + { + %assetPath = "data/" @ %moduleName @ "/components/" @ %assetName @ ".cs"; + %doubleClickCommand = "EditorOpenFileInTorsion( "@%assetPath@", 0 );"; + + %previewImage = "tools/assetBrowser/art/componentIcon"; + + %assetFriendlyName = %assetDesc.friendlyName; + %assetDesc = %assetDesc.description; + %tooltip = %assetFriendlyName @ "\n" @ %assetDesc; + } + else if(%assetType $= "GameObjectAsset") + { + %assetPath = "data/" @ %moduleName @ "/gameObjects/" @ %assetName @ ".cs"; + %doubleClickCommand = "EditorOpenFileInTorsion( "@%assetPath@", 0 );"; + + %previewImage = "tools/assetBrowser/art/gameObjectIcon"; + + %tooltip = %assetDesc.gameObjectName; + } + else if(%assetType $= "ImageAsset") + { + //nab the image and use it for the preview + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + %name = AssetDatabase.getAssetName(%assetId); + + if(%name $= %assetName) + { + %asset = AssetDatabase.acquireAsset(%assetId); + %previewImage = %asset.imageFile; + break; + } + } + } + else if(%assetType $= "StateMachineAsset") + { + %previewImage = "tools/assetBrowser/art/stateMachineIcon"; + } + else if(%assetType $= "SoundAsset") + { + %previewImage = "tools/assetBrowser/art/soundIcon"; + } + else if(%assetType $= "LevelAsset") + { + %previewImage = "tools/assetBrowser/art/levelIcon"; + } + else if(%assetType $= "PostEffectAsset") + { + %previewImage = "tools/assetBrowser/art/postEffectIcon"; + } + else if(%assetType $= "GUIAsset") + { + %previewImage = "tools/assetBrowser/art/guiIcon"; + } + else if(%assetType $= "ScriptAsset") + { + if(%assetDesc.isServerSide) + %previewImage = "tools/assetBrowser/art/serverScriptIcon"; + else + %previewImage = "tools/assetBrowser/art/clientScriptIcon"; + } + else if(%assetType $= "MaterialAsset") + { + %previewImage = ""; + //nab the image and use it for the preview + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + %name = AssetDatabase.getAssetName(%assetId); + + if(%name $= %assetName) + { + %asset = AssetDatabase.acquireAsset(%assetId); + %previewImage = %asset.materialDefinitionName.diffuseMap[0]; + break; + } + } + + if(%previewImage $= "") + %previewImage = "tools/assetBrowser/art/materialIcon"; + } + if(%assetType $= "ShapeAnimationAsset") + { + %previewImage = "tools/assetBrowser/art/animationIcon"; + } + + %previewButton = new GuiBitmapButtonCtrl() + { + className = "AssetPreviewControl"; + internalName = %assetName; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "10 4"; + extent = %previewSize; + buttonType = "PushButton"; + bitmap = %previewImage; + Command = ""; + text = ""; + useStates = false; + + new GuiBitmapButtonCtrl() + { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "0 0"; + extent = %previewSize; + Variable = ""; + buttonType = "toggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + } + + %previewBorder = new GuiButtonCtrl(){ + class = "AssetPreviewButton"; + internalName = %assetName@"Border"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiThumbHighlightButtonProfile"; + position = "0 0"; + extent = %previewSize.x + %previewBounds SPC %previewSize.y + 24; + Variable = ""; + buttonType = "radioButton"; + tooltip = %tooltip; + Command = "AssetBrowser.updateSelection( $ThisControl.getParent().assetName, $ThisControl.getParent().moduleName );"; + altCommand = %doubleClickCommand; + groupNum = "0"; + useMouseEvents = true; + text = ""; + icon = %previewImage; + }; + + %previewNameCtrl = new GuiTextEditCtrl(){ + position = 0 SPC %previewSize.y + %previewBounds - 16; + profile = ToolsGuiTextEditCenterProfile; + extent = %previewSize.x + %previewBounds SPC 16; + text = %assetName; + originalAssetName = %assetName; //special internal field used in renaming assets + internalName = "AssetNameLabel"; + class = "AssetNameField"; + active = false; + }; + + %container.add(%previewButton); + %container.add(%previewBorder); + %container.add(%previewNameCtrl); + + // add to the gui control array + AssetBrowser-->materialSelection.add(%container); + + // add to the array object for reference later + AssetPreviewArray.add( %previewButton, %previewImage ); +} + +function AssetBrowser::loadImages( %this, %materialNum ) +{ + // this will save us from spinning our wheels in case we don't exist + /*if( !AssetBrowser.visible ) + return; + + // this schedule is here to dynamically load images + %previewButton = AssetPreviewArray.getKey(%materialNum); + %previewImage = AssetPreviewArray.getValue(%materialNum); + + if(%previewButton.getClassName() !$= "GuiObjectView") + { + %previewButton.setBitmap(%previewImage); + %previewButton.setText(""); + } + + %materialNum++; + + /*if( %materialNum < AssetPreviewArray.count() ) + { + %tempSchedule = %this.schedule(64, "loadImages", %materialNum); + MatEdScheduleArray.add( %tempSchedule, %materialNum ); + }*/ +} + +function AssetBrowser::loadFilters( %this ) +{ + AssetBrowser-->filterTree.clear(); + + AssetBrowser-->filterTree.buildIconTable(":tools/classIcons/prefab"); + + AssetBrowser-->filterTree.insertItem(0, "Assets"); + + //First, build our our list of active modules + %modulesList = ModuleDatabase.findModules(true); + + for(%i=0; %i < getWordCount(%modulesList); %i++) + { + %moduleName = getWord(%modulesList, %i).ModuleId; + + %moduleItemId = AssetBrowser-->filterTree.findItemByName(%moduleName); + + if(%moduleItemId == 0) + %moduleItemId = AssetBrowser-->filterTree.insertItem(1, %moduleName, "", "", 1, 1); + } + + //Next, go through and list the asset categories + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %moduleName = %module.moduleId; + + //These are core, native-level components, so we're not going to be messing with this module at all, skip it + if(%moduleName $= "CoreComponentsModule") + continue; + + //first, see if this module Module is listed already + %moduleItemId = AssetBrowser-->filterTree.findItemByName(%moduleName); + + if(%moduleItemId == 0) + %moduleItemId = AssetBrowser-->filterTree.insertItem(1, %moduleName, "", "", 1, 1); + + %assetType = AssetDatabase.getAssetCategory(%assetId); + + if(%assetType $= "") + { + %assetType = AssetDatabase.getAssetType(%assetId); + if(%assetType $= "") + %assetType = "Misc"; + } + + if(AssetBrowser.assetTypeFilter !$= "" && AssetBrowser.assetTypeFilter !$= %assetType) + continue; + + %assetTypeId = AssetBrowser-->filterTree.findChildItemByName(%moduleItemId, %assetType); + + if(%assetTypeId == 0) + %assetTypeId = AssetBrowser-->filterTree.insertItem(%moduleItemId, %assetType); + } + + AssetBrowser-->filterTree.buildVisibleTree(true); + + //special handling for selections + if(AssetBrowser.newModuleId !$= "") + { + AssetBrowser-->filterTree.clearSelection(); + %newModuleItem = AssetBrowser-->filterTree.findItemByName(AssetBrowser.newModuleId); + AssetBrowser-->filterTree.selectItem(%newModuleItem); + AssetBrowser.newModuleId = ""; + } + + %selectedItem = AssetBrowser-->filterTree.getSelectedItem(); + AssetBrowser-->filterTree.scrollVisibleByObjectId(%selectedItem); +} + +// create category and update current material if there is one +function AssetBrowser::createFilter( %this, %filter ) +{ + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create blank filter."); + return; + } + + for( %i = AssetBrowser.staticFilterObjects; %i < AssetBrowser-->filterArray.getCount() ; %i++ ) + { + %existingFilters = AssetBrowser-->filterArray.getObject(%i).getObject(0).filter; + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create two filters of the same name."); + return; + } + } + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiCheckBoxCtrl(){ + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 1"; + Extent = "118 18"; + Command = ""; + groupNum = "0"; + buttonType = "ToggleButton"; + text = %filter @ " ( " @ MaterialFilterAllArray.countKey(%filter) @ " )"; + filter = %filter; + Command = "AssetBrowser.preloadFilter();"; + }; + }; + + AssetBrowser-->filterArray.add( %container ); + + // if selection exists, lets reselect it to refresh it + if( isObject(AssetBrowser.selectedMaterial) ) + AssetBrowser.updateSelection( AssetBrowser.selectedMaterial, AssetBrowser.selectedPreviewImagePath ); + + // material category text field to blank + AssetBrowser_addFilterWindow-->tagName.setText(""); +} + +function AssetBrowser::updateSelection( %this, %asset, %moduleName ) +{ + // the material selector will visually update per material information + // after we move away from the material. eg: if we remove a field from the material, + // the empty checkbox will still be there until you move fro and to the material again + + %isAssetBorder = 0; + eval("%isAssetBorder = isObject(AssetBrowser-->"@%asset@"Border);"); + if( %isAssetBorder ) + { + eval( "AssetBrowser-->"@%asset@"Border.setStateOn(1);"); + } + + %isAssetBorderPrevious = 0; + eval("%isAssetBorderPrevious = isObject(AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border);"); + if( %isAssetBorderPrevious ) + { + eval( "AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border.setStateOn(0);"); + } + + AssetBrowser.selectedMaterial = %asset; + AssetBrowser.selectedAsset = %moduleName@":"@%asset; + AssetBrowser.selectedAssetDef = AssetDatabase.acquireAsset(AssetBrowser.selectedAsset); + //AssetBrowser.selectedPreviewImagePath = %previewImagePath; + + %this.prevSelectedMaterialHL = %asset; +} + +// +//needs to be deleted with the persistence manager and needs to be blanked out of the matmanager +//also need to update instances... i guess which is the tricky part.... +function AssetBrowser::showDeleteDialog( %this ) +{ + %material = AssetBrowser.selectedMaterial; + %secondFilter = "MaterialFilterMappedArray"; + %secondFilterName = "Mapped"; + + for( %i = 0; %i < MaterialFilterUnmappedArray.count(); %i++ ) + { + if( MaterialFilterUnmappedArray.getValue(%i) $= %material ) + { + %secondFilter = "MaterialFilterUnmappedArray"; + %secondFilterName = "Unmapped"; + break; + } + } + + if( isObject( %material ) ) + { + MessageBoxYesNoCancel("Delete Material?", + "Are you sure you want to delete

" @ %material.getName() @ "

Material deletion won't take affect until the engine is quit.", + "AssetBrowser.deleteMaterial( " @ %material @ ", " @ %secondFilter @ ", " @ %secondFilterName @" );", + "", + "" ); + } +} + +function AssetBrowser::deleteMaterial( %this, %materialName, %secondFilter, %secondFilterName ) +{ + if( !isObject( %materialName ) ) + return; + + for( %i = 0; %i <= MaterialFilterAllArray.countValue( %materialName ); %i++) + { + %index = MaterialFilterAllArray.getIndexFromValue( %materialName ); + MaterialFilterAllArray.erase( %index ); + } + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() - 1 @ " ) "); + + %checkbox = %secondFilter @ "Checkbox"; + for( %k = 0; %k <= %secondFilter.countValue( %materialName ); %k++) + { + %index = %secondFilter.getIndexFromValue( %materialName ); + %secondFilter.erase( %index ); + } + %checkbox.setText( %secondFilterName @ " ( " @ %secondFilter.count() - 1 @ " ) "); + + for( %i = 0; %materialName.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %materialTag = %materialName.getFieldValue("materialTag" @ %i); + + for( %j = AssetBrowser.staticFilterObjects; %j < AssetBrowser-->filterArray.getCount() ; %j++ ) + { + if( %materialTag $= AssetBrowser-->filterArray.getObject(%j).getObject(0).filter ) + { + %count = getWord( AssetBrowser-->filterArray.getObject(%j).getObject(0).getText(), 2 ); + %count--; + AssetBrowser-->filterArray.getObject(%j).getObject(0).setText( %materialTag @ " ( "@ %count @ " )"); + } + } + + } + + UnlistedMaterials.add( "unlistedMaterials", %materialName ); + + if( %materialName.getFilename() !$= "" && + %materialName.getFilename() !$= "tools/gui/AssetBrowser.ed.gui" && + %materialName.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs" ) + { + AssetBrowserPerMan.removeObjectFromFile(%materialName); + AssetBrowserPerMan.saveDirty(); + } + + AssetBrowser.preloadFilter(); +} + +function AssetBrowser::thumbnailCountUpdate(%this) +{ + $Pref::AssetBrowser::ThumbnailCountIndex = AssetBrowser-->materialPreviewCountPopup.getSelected(); + AssetBrowser.LoadFilter( AssetBrowser.currentFilter, AssetBrowser.currentStaticFilter ); +} + +function AssetBrowser::toggleTagFilterPopup(%this) +{ + if(TagFilterWindow.visible) + TagFilterWindow.visible = false; + else + TagFilterWindow.visible = true; + + return; + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %moduleName = %module.moduleId; + + //check that we don't re-add it + %moduleItemId = AssetBrowser-->filterTree.findItemByName(%moduleName); + + if(%moduleItemId == -1 || %moduleItemId == 0) + %moduleItemId = AssetBrowser-->filterTree.insertItem(1, %module.moduleId, "", "", 1, 1); + + //now, add the asset's category + %assetType = AssetDatabase.getAssetCategory(%assetId); + + %checkBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %var; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + Command = %cmd; + }; + + TagFilterList.add(%checkBox); + } +} + +function AssetBrowser::changeAsset(%this) +{ + //alright, we've selectd an asset for a field, so time to set it! + %cmd = %this.fieldTargetObject @ "." @ %this.fieldTargetName @ "=\"" @ %this.selectedAsset @ "\";"; + echo("Changing asset via the " @ %cmd @ " command"); + eval(%cmd); +} + +function AssetBrowser::reImportAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %assetType = AssetDatabase.getAssetType(EditAssetPopup.assetId); + + if(%assetType $= "ShapeAsset" || %assetType $= "ImageAsset" || %assetType $= "SoundAsset") + { + AssetBrowser.isAssetReImport = true; + AssetBrowser.reImportingAssetId = EditAssetPopup.assetId; + + AssetBrowser.onBeginDropFiles(); + AssetBrowser.onDropFile(%assetDef.originalFilePath); + AssetBrowser.onEndDropFiles(); + + %module = AssetDatabase.getAssetModule(EditAssetPopup.assetId); + + //get the selected module data + ImportAssetModuleList.setText(%module.ModuleId); + } +} + +//------------------------------------------------------------------------------ +function AssetPreviewButton::onRightClick(%this) +{ + AssetBrowser.selectedAssetPreview = %this.getParent(); + EditAssetPopup.assetId = %this.getParent().moduleName @ ":" @ %this.getParent().assetName; + %assetType = %this.getParent().assetType; + + //Do some enabling/disabling of options depending on asset type + EditAssetPopup.enableItem(0, true); + EditAssetPopup.enableItem(7, true); + + //Is it an editable type? + if(%assetType $= "ImageAsset" || %assetType $= "GameObjectAsset" || %assetType $= "SoundAsset") + { + EditAssetPopup.enableItem(0, false); + } + + //Is it an importable type? + if(%assetType $= "GameObjectAsset" || %assetType $= "ComponentAsset" || %assetType $= "GUIAsset" || %assetType $= "LevelAsset" + || %assetType $= "MaterialAsset" || %assetType $= "ParticleAsset" || %assetType $= "PostEffectAsset" || %assetType $= "ScriptAsset" + || %assetType $= "StateMachineAsset") + { + EditAssetPopup.enableItem(7, false); + } + + EditAssetPopup.showPopup(Canvas); +} + +function AssetListPanel::onRightMouseDown(%this) +{ + AddNewAssetPopup.showPopup(Canvas); +} + +//------------------------------------------------------------------------------ +function AssetBrowser::refreshPreviews(%this) +{ + AssetBrowserFilterTree.onSelect(AssetBrowser.selectedItem); +} + +function AssetBrowserFilterTree::onSelect(%this, %itemId) +{ + if(%itemId == 1) + //can't select root + return; + + //Make sure we have an actual module selected! + %parentId = %this.getParentItem(%itemId); + + if(%parentId != 1) + AssetBrowser.selectedModule = %this.getItemText(%parentId);//looks like we have one of the categories selected, not the module. Nab the parent so we have the correct thing! + else + AssetBrowser.selectedModule = %this.getItemText(%itemId); + + AssetBrowser.selectedItem = %itemId; + + //alright, we have a module or sub-filter selected, so now build our asset list based on that filter! + echo("Asset Browser Filter Tree selected filter #:" @ %itemId); + + // manage schedule array properly + if(!isObject(MatEdScheduleArray)) + new ArrayObject(MatEdScheduleArray); + + // if we select another list... delete all schedules that were created by + // previous load + for( %i = 0; %i < MatEdScheduleArray.count(); %i++ ) + cancel(MatEdScheduleArray.getKey(%i)); + + // we have to empty out the list; so when we create new schedules, these dont linger + MatEdScheduleArray.empty(); + + // manage preview array + if(!isObject(AssetPreviewArray)) + new ArrayObject(AssetPreviewArray); + + // we have to empty out the list; so when we create new guicontrols, these dont linger + AssetPreviewArray.empty(); + AssetBrowser-->materialSelection.deleteAllObjects(); + //AssetBrowser-->materialPreviewPagesStack.deleteAllObjects(); + + %assetArray = new ArrayObject(); + + //First, Query for our assets + %assetQuery = new AssetQuery(); + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + //module name per our selected filter: + %moduleItemId = %this.getParentItem(%itemId); + + //check if we've selected a Module + if(%moduleItemId == 1) + { + %FilterModuleName = %this.getItemText(%itemId); + } + else + { + %FilterModuleName = %this.getItemText(%moduleItemId); + } + + //now, we'll iterate through, and find the assets that are in this module, and this category + for( %i=0; %i < %numAssetsFound; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %moduleName = %module.moduleId; + + if(%FilterModuleName $= %moduleName) + { + //it's good, so test that the category is right! + %assetType = AssetDatabase.getAssetCategory(%assetId); + if(%assetType $= "") + { + %assetType = AssetDatabase.getAssetType(%assetId); + } + + if(%this.getItemText(%itemId) $= %assetType || (%assetType $= "" && %this.getItemText(%itemId) $= "Misc") + || %moduleItemId == 1) + { + //stop adding after previewsPerPage is hit + %assetName = AssetDatabase.getAssetName(%assetId); + + %searchText = AssetBrowserSearchFilter.getText(); + if(%searchText !$= "\c2Filter...") + { + if(strstr(strlwr(%assetName), strlwr(%searchText)) != -1) + %assetArray.add( %moduleName, %assetId); + } + else + { + //got it. + %assetArray.add( %moduleName, %assetId ); + } + } + } + } + + AssetBrowser.currentPreviewPage = 0; + AssetBrowser.totalPages = 1; + + for(%i=0; %i < %assetArray.count(); %i++) + AssetBrowser.buildPreviewArray( %assetArray.getValue(%i), %assetArray.getKey(%i) ); + + AssetBrowser.loadImages( 0 ); +} + +function AssetBrowserFilterTree::onRightMouseDown(%this, %itemId) +{ + if( %this.getSelectedItemsCount() > 0 && %itemId != 1) + { + //AddNewAssetPopup.showPopup(Canvas); + + //We have something clicked, so figure out if it's a sub-filter or a module filter, then push the correct + //popup menu + if(%this.getParentItem(%itemId) == 1) + { + //yep, module, push the all-inclusive popup + EditModulePopup.showPopup(Canvas); + //also set the module value for creation info + AssetBrowser.selectedModule = %this.getItemText(%itemId); + } + else + { + //get the parent, and thus our module + %moduleId = %this.getParentItem(%itemId); + + //set the module value for creation info + AssetBrowser.selectedModule = %this.getItemText(%moduleId); + + if(%this.getItemText(%itemId) $= "ComponentAsset") + { + AddNewComponentAssetPopup.showPopup(Canvas); + //Canvas.popDialog(AssetBrowser_newComponentAsset); + //AssetBrowser_newComponentAsset-->AssetBrowserModuleList.setText(AssetBrowser.selectedModule); + } + else + { + + } + } + } + else if( %this.getSelectedItemsCount() > 0 && %itemId == 1) + { + AddNewModulePopup.showPopup(Canvas); + } +} + +// +// +function AssetBrowserSearchFilterText::onWake( %this ) +{ + /*%filter = %this.treeView.getFilterText(); + if( %filter $= "" ) + %this.setText( "\c2Filter..." ); + else + %this.setText( %filter );*/ +} + +//------------------------------------------------------------------------------ + +function AssetBrowserSearchFilterText::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +//--------------------------------------------------------------------------------------------- + +// When Enter is pressed in the filter text control, pass along the text of the control +// as the treeview's filter. +function AssetBrowserSearchFilterText::onReturn( %this ) +{ + %text = %this.getText(); + if( %text $= "" ) + %this.reset(); + else + { + //%this.treeView.setFilterText( %text ); + %curItem = AssetBrowserFilterTree.getSelectedItem(); + AssetBrowserFilterTree.onSelect(%curItem); + } +} + +//--------------------------------------------------------------------------------------------- + +function AssetBrowserSearchFilterText::reset( %this ) +{ + %this.setText( "\c2Filter..." ); + //%this.treeView.clearFilterText(); + %curItem = AssetBrowserFilterTree.getSelectedItem(); + AssetBrowserFilterTree.onSelect(%curItem); +} + +//--------------------------------------------------------------------------------------------- + +function AssetBrowserSearchFilterText::onClick( %this ) +{ + %this.textCtrl.reset(); +} + +// +// +// +function AssetBrowser::reloadModules(%this) +{ + ModuleDatabase.unloadGroup("Game"); + + %modulesList = ModuleDatabase.findModules(); + + %count = getWordCount(%modulesList); + + for(%i=0; %i < %count; %i++) + { + %moduleId = getWord(%modulesList, %i).ModuleId; + ModuleDatabase.unloadExplicit(%moduleId); + } + + ModuleDatabase.scanModules(); + + %modulesList = ModuleDatabase.findModules(); + + %count = getWordCount(%modulesList); + + for(%i=0; %i < %count; %i++) + { + %moduleId = getWord(%modulesList, %i).ModuleId; + ModuleDatabase.loadExplicit(%moduleId); + } + + //ModuleDatabase.loadGroup("Game"); +} +// + +function AssetPreviewButton::onMouseDragged(%this) +{ + %payload = new GuiBitmapButtonCtrl(); + %payload.assignFieldsFrom( %this ); + %payload.className = "AssetPreviewControl"; + %payload.position = "0 0"; + %payload.dragSourceControl = %this; + %payload.bitmap = %this.icon; + %payload.extent.x /= 2; + %payload.extent.y /= 2; + + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + + // Compute the initial position of the GuiDragAndDrop control on the cavas based on the current + // mouse cursor position. + + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + if(!isObject(EditorDragAndDropLayer)) + { + new GuiControl(EditorDragAndDropLayer) + { + position = "0 0"; + extent = Canvas.extent; + }; + } + + // Create the drag control. + %ctrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = "GuiSolidDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "4 4"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + // Let the GuiDragAndDropControl delete itself on mouse-up. When the drag is aborted, + // this not only deletes the drag control but also our payload. + deleteOnMouseUp = true; + + useWholeCanvas = true; + + // To differentiate drags, use the namespace hierarchy to classify them. + // This will allow a color swatch drag to tell itself apart from a file drag, for example. + class = "AssetPreviewControlType_AssetDrop"; + }; + + // Add the temporary color swatch to the drag control as the payload. + %ctrl.add( %payload ); + + // Start drag by adding the drag control to the canvas and then calling startDragging(). + //Canvas.getContent().add( %ctrl ); + EditorDragAndDropLayer.add(%ctrl); + Canvas.pushDialog(EditorDragAndDropLayer); + + %ctrl.startDragging( %xOffset, %yOffset ); +} + +function AssetPreviewButton::onControlDragCancelled(%this) +{ + Canvas.popDialog(EditorDragAndDropLayer); +} + +function AssetPreviewButton::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + // If dropped on same button whence we came from, + // do nothing. + + if( %payload.dragSourceControl == %this ) + return; + + // If a swatch button control is dropped onto this control, + // copy it's color. + + if( %payload.isMemberOfClass( "AssetPreviewButton" ) ) + { + // If the swatch button is part of a color-type inspector field, + // remember the inspector field so we can later set the color + // through it. + + if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorI" ) ) + %this.parentGroup.apply( ColorFloatToInt( %payload.color ) ); + else if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorF" ) ) + %this.parentGroup.apply( %payload.color ); + else + %this.setColor( %payload.color ); + } +} + +function EWorldEditor::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + // If dropped on same button whence we came from, + // do nothing. + + if( %payload.dragSourceControl == %this ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + %pos = EWCreatorWindow.getCreateObjectPosition(); //LocalClientConnection.camera.position; + %module = %payload.dragSourceControl.parentGroup.moduleName; + %asset = %payload.dragSourceControl.parentGroup.assetName; + + if(%assetType $= "ImageAsset") + { + echo("DROPPED AN IMAGE ON THE EDITOR WINDOW!"); + } + else if(%assetType $= "ShapeAsset") + { + echo("DROPPED A SHAPE ON THE EDITOR WINDOW!"); + + %newEntity = new Entity() + { + position = %pos; + + new MeshComponent() + { + MeshAsset = %module @ ":" @ %asset; + }; + + //new CollisionComponent(){}; + }; + + MissionGroup.add(%newEntity); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newEntity); + } + else if(%assetType $= "MaterialAsset") + { + echo("DROPPED A MATERIAL ON THE EDITOR WINDOW!"); + } + else if(%assetType $= "GameObjectAsset") + { + echo("DROPPED A GAME OBJECT ON THE EDITOR WINDOW!"); + + %GO = spawnGameObject(%asset, true); + + %pos = EWCreatorWindow.getCreateObjectPosition(); //LocalClientConnection.camera.position; + + %GO.position = %pos; + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%GO); + } + else if(%assetType $= "ComponentAsset") + { + %newEntity = new Entity() + { + position = %pos; + }; + + %assetDef = AssetDatabase.acquireAsset(%module @ ":" @ %asset); + + if(%assetDef.componentClass $= "Component") + eval("$tmpVar = new " @ %assetDef.componentClass @ "() { class = " @ %assetDef.componentName @ "; }; %newEntity.add($tmpVar);"); + else + eval("$tmpVar = new " @ %assetDef.componentClass @ "() {}; %newEntity.add($tmpVar);"); + + MissionGroup.add(%newEntity); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newEntity); + } + else if(%assetType $= "ScriptAsset") //do we want to do it this way? + { + %newEntity = new Entity() + { + position = %pos; + class = %asset; + }; + + MissionGroup.add(%newEntity); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newEntity); + } + + EWorldEditor.isDirty = true; +} + +function GuiInspectorTypeShapeAssetPtr::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + if(%assetType $= "ShapeAsset") + { + echo("DROPPED A SHAPE ON A SHAPE ASSET COMPONENT FIELD!"); + + %module = %payload.dragSourceControl.parentGroup.moduleName; + %asset = %payload.dragSourceControl.parentGroup.assetName; + + %targetComponent = %this.ComponentOwner; + %targetComponent.MeshAsset = %module @ ":" @ %asset; + + //Inspector.refresh(); + } + + EWorldEditor.isDirty= true; +} + +function GuiInspectorTypeImageAssetPtr::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + if(%assetType $= "ImageAsset") + { + echo("DROPPED A IMAGE ON AN IMAGE ASSET COMPONENT FIELD!"); + } + + EWorldEditor.isDirty = true; +} + +function GuiInspectorTypeMaterialAssetPtr::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + // Make sure this is a color swatch drag operation. + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + + if(%assetType $= "MaterialAsset") + { + echo("DROPPED A MATERIAL ON A MATERIAL ASSET COMPONENT FIELD!"); + } + + EWorldEditor.isDirty = true; +} + +function AssetBrowserFilterTree::onControlDropped( %this, %payload, %position ) +{ + Canvas.popDialog(EditorDragAndDropLayer); + + if( !%payload.parentGroup.isInNamespaceHierarchy( "AssetPreviewControlType_AssetDrop" ) ) + return; + + %assetType = %payload.dragSourceControl.parentGroup.assetType; + %assetName = %payload.dragSourceControl.parentGroup.assetName; + %moduleName = %payload.dragSourceControl.parentGroup.moduleName; + + echo("DROPPED A " @ %assetType @ " ON THE ASSET BROWSER NAVIGATION TREE!"); + + %item = %this.getItemAtPosition(%position); + + echo("DROPPED IT ON ITEM " @ %item); + + %parent = %this.getParentItem(%item); + + if(%parent == 1) + { + //we're a module entry, cool + %targetModuleName = %this.getItemText(%item); + echo("DROPPED IT ON MODULE " @ %targetModuleName); + + if(%moduleName !$= %targetModuleName) + { + //we're trying to move the asset to a different module! + MessageBoxYesNo( "Move Asset", "Do you wish to move asset " @ %assetName @ " to module " @ %targetModuleName @ "?", + "AssetBrowser.moveAsset("@%assetName@", "@%targetModuleName@");", ""); + } + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs new file mode 100644 index 000000000..8732ac8a5 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs @@ -0,0 +1,1525 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// +// +function isImageFormat(%fileExt) +{ + if( (%fileExt $= ".png") || (%fileExt $= ".jpg") || (%fileExt $= ".bmp") || (%fileExt $= ".dds") || (%fileExt $= ".tif")) + return true; + + return false; +} + +function isShapeFormat(%fileExt) +{ + if( (%fileExt $= ".dae") || (%fileExt $= ".dts") || (%fileExt $= ".fbx") || (%fileExt $= ".obj") || (%fileExt $= ".blend")) + return true; + + return false; +} + +function isSoundFormat(%fileExt) +{ + if( (%fileExt $= ".ogg") || (%fileExt $= ".wav") || (%fileExt $= ".mp3")) + return true; + + return false; +} + +function getImageInfo(%file) +{ + //we're going to populate a GuiTreeCtrl with info of the inbound image file +} + +//This lets us go and look for a image at the importing directory as long as it matches the material name +function findImageFile(%path, %materialName, %type) +{ + + if(isFile(%path @ "/" @ %materialName @ ".jpg")) + return %path @ "/" @ %materialName @ ".jpg"; + else if(isFile(%path @ "/" @ %materialName @ ".png")) + return %path @ "/" @ %materialName @ ".png"; + else if(isFile(%path @ "/" @ %materialName @ ".dds")) + return %path @ "/" @ %materialName @ ".dds"; + else if(isFile(%path @ "/" @ %materialName @ ".tif")) + return %path @ "/" @ %materialName @ ".tif"; +} + +function AssetBrowser::onBeginDropFiles( %this ) +{ + error("% DragDrop - Beginning files dropping."); + %this.importAssetNewListArray.empty(); + %this.importAssetUnprocessedListArray.empty(); + %this.importAssetFinalListArray.empty(); +} + +function AssetBrowser::onDropFile( %this, %filePath ) +{ + if(!%this.isVisible()) + return; + + %fileExt = fileExt( %filePath ); + //add it to our array! + if(isImageFormat(%fileExt)) + %this.addImportingAsset("Image", %filePath); + else if( isShapeFormat(%fileExt)) + %this.addImportingAsset("Model", %filePath); + else if( isSoundFormat(%fileExt)) + %this.addImportingAsset("Sound", %filePath); + else if (%fileExt $= ".zip") + %this.onDropZipFile(%filePath); +} + +function AssetBrowser::onDropZipFile(%this, %filePath) +{ + if(!%this.isVisible()) + return; + + %zip = new ZipObject(); + %zip.openArchive(%filePath); + %count = %zip.getFileEntryCount(); + + echo("Dropped in a zip file with" SPC %count SPC "files inside!"); + + return; + for (%i = 0; %i < %count; %i++) + { + %fileEntry = %zip.getFileEntry(%i); + %fileFrom = getField(%fileEntry, 0); + + //First, we wanna scan to see if we have modules to contend with. If we do, we'll just plunk them in wholesale + //and not process their contents. + + //If not modules, it's likely an art pack or other mixed files, so we'll import them as normal + if( (%fileExt $= ".png") || (%fileExt $= ".jpg") || (%fileExt $= ".bmp") || (%fileExt $= ".dds") ) + %this.importAssetListArray.add("Image", %filePath); + else if( (%fileExt $= ".dae") || (%fileExt $= ".dts")) + %this.importAssetListArray.add("Model", %filePath); + else if( (%fileExt $= ".ogg") || (%fileExt $= ".wav") || (%fileExt $= ".mp3")) + %this.importAssetListArray.add("Sound", %filePath); + else if( (%fileExt $= ".gui") || (%fileExt $= ".gui.dso")) + %this.importAssetListArray.add("GUI", %filePath); + //else if( (%fileExt $= ".cs") || (%fileExt $= ".dso")) + // %this.importAssetListArray.add("Script", %filePath); + else if( (%fileExt $= ".mis")) + %this.importAssetListArray.add("Level", %filePath); + + // For now, if it's a .cs file, we'll assume it's a behavior. + if (fileExt(%fileFrom) !$= ".cs") + continue; + + %fileTo = expandFilename("^game/behaviors/") @ fileName(%fileFrom); + %zip.extractFile(%fileFrom, %fileTo); + exec(%fileTo); + } +} + +function AssetBrowser::onDropImageFile(%this, %filePath) +{ + if(!%this.isVisible()) + return; + + // File Information madness + %fileName = %filePath; + %fileOnlyName = fileName( %fileName ); + %fileBase = validateDatablockName(fileBase( %fileName ) @ "ImageMap"); + + // [neo, 5/17/2007 - #3117] + // Check if the file being dropped is already in data/images or a sub dir by checking if + // the file path up to length of check path is the same as check path. + %defaultPath = EditorSettings.value( "WorldEditor/defaultMaterialsPath" ); + + %checkPath = expandFilename( "^"@%defaultPath ); + %fileOnlyPath = expandFileName( %filePath ); //filePath( expandFileName( %filePath ) ); + %fileBasePath = getSubStr( %fileOnlyPath, 0, strlen( %checkPath ) ); + + if( %checkPath !$= %fileBasePath ) + { + // No match so file is from outside images directory and we need to copy it in + %fileNewLocation = expandFilename("^"@%defaultPath) @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + + // Move to final location + if( !pathCopy( %filePath, %fileNewLocation ) ) + return; + } + else + { + // Already in images path somewhere so just link to it + %fileNewLocation = %filePath; + } + + addResPath( filePath( %fileNewLocation ) ); + + %matName = fileBase( %fileName ); + + // Create Material + %imap = new Material(%matName) + { + mapTo = fileBase( %matName ); + diffuseMap[0] = %defaultPath @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + }; + //%imap.setName( %fileBase ); + //%imap.imageName = %fileNewLocation; + //%imap.imageMode = "FULL"; + //%imap.filterPad = false; + //%imap.compile(); + + %diffusecheck = %imap.diffuseMap[0]; + + // Bad Creation! + if( !isObject( %imap ) ) + return; + + %this.addDatablock( %fileBase, false ); +} + +function AssetBrowser::onDropSoundFile(%this, %filePath) +{ + if(!%this.isVisible()) + return; + + // File Information madness + %fileName = %filePath; + %fileOnlyName = fileName( %fileName ); + %fileBase = validateDatablockName(fileBase( %fileName ) @ "ImageMap"); + + // [neo, 5/17/2007 - #3117] + // Check if the file being dropped is already in data/images or a sub dir by checking if + // the file path up to length of check path is the same as check path. + %defaultPath = EditorSettings.value( "WorldEditor/defaultMaterialsPath" ); + + %checkPath = expandFilename( "^"@%defaultPath ); + %fileOnlyPath = expandFileName( %filePath ); //filePath( expandFileName( %filePath ) ); + %fileBasePath = getSubStr( %fileOnlyPath, 0, strlen( %checkPath ) ); + + if( %checkPath !$= %fileBasePath ) + { + // No match so file is from outside images directory and we need to copy it in + %fileNewLocation = expandFilename("^"@%defaultPath) @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + + // Move to final location + if( !pathCopy( %filePath, %fileNewLocation ) ) + return; + } + else + { + // Already in images path somewhere so just link to it + %fileNewLocation = %filePath; + } + + addResPath( filePath( %fileNewLocation ) ); + + %matName = fileBase( %fileName ); + + // Create Material + %imap = new Material(%matName) + { + mapTo = fileBase( %matName ); + diffuseMap[0] = %defaultPath @ "/" @ fileBase( %fileName ) @ fileExt( %fileName ); + }; + //%imap.setName( %fileBase ); + //%imap.imageName = %fileNewLocation; + //%imap.imageMode = "FULL"; + //%imap.filterPad = false; + //%imap.compile(); + + %diffusecheck = %imap.diffuseMap[0]; + + // Bad Creation! + if( !isObject( %imap ) ) + return; + + %this.addDatablock( %fileBase, false ); +} + +function AssetBrowser::onEndDropFiles( %this ) +{ + if(!%this.isVisible()) + return; + + //we have assets to import, so go ahead and display the window for that now + Canvas.pushDialog(AssetImportCtrl); + ImportAssetWindow.visible = true; + //ImportAssetWindow.validateAssets(); + ImportAssetWindow.refresh(); + ImportAssetWindow.selectWindow(); + + // Update object library + GuiFormManager::SendContentMessage($LBCreateSiderBar, %this, "refreshAll 1"); + + if(ImportAssetWindow.importConfigsList.count() == 0) + { + MessageBoxOK( "Warning", "No base import config. Please create an import configuration set to simplify asset importing."); + } +} +// +// +// + +function AssetBrowser::addImportingAsset( %this, %assetType, %filePath, %parentAssetItem ) +{ + %assetName = fileBase(%filePath); + %filePath = filePath(%filePath) @ "/" @ fileBase(%filePath) @ fileExt(%filePath); //sanitize the file path + + %moduleName = AssetBrowser.SelectedModule; + ImportAssetModuleList.text = %moduleName; + + //Add to our main list + %assetItem = new ScriptObject() + { + assetType = %assetType; + filePath = %filePath; + assetName = %assetName; + moduleName = %moduleName; + dirty = true; + parentAssetItem = %parentAssetItem; + status = ""; + statusType = ""; + statusInfo = ""; + skip = false; + }; + + //little bit of interception here + if(%assetItem.assetType $= "Model") + { + %fileExt = fileExt(%assetItem.filePath); + if(%fileExt $= ".dae") + { + %shapeInfo = new GuiTreeViewCtrl(); + enumColladaForImport(%assetItem.filePath, %shapeInfo); + } + else + { + %shapeInfo = GetShapeInfo(%assetItem.filePath); + } + + %assetItem.shapeInfo = %shapeInfo; + + %shapeItem = %assetItem.shapeInfo.findItemByName("Shape"); + %shapeCount = %assetItem.shapeInfo.getItemValue(%shapeItem); + + %animItem = %assetItem.shapeInfo.findItemByName("Animations"); + %animCount = %assetItem.shapeInfo.getItemValue(%animItem); + + //If the model has shapes AND animations, then it's a normal shape with embedded animations + //if it has shapes and no animations it's a regular static mesh + //if it has no shapes and animations, it's a special case. This means it's a shape animation only file so it gets flagged as special + if(%shapeCount == 0 && %animCount != 0) + { + %assetItem.assetType = "Animation"; + } + else if(%shapeCount == 0 && %animCount == 0) + { + //either it imported wrong or it's a bad file we can't read. Either way, don't try importing it + error("Error - attempted to import a model file with no shapes or animations! Model in question was: " @ %filePath); + + %assetItem.delete(); + return 0; + } + } + + if(%parentAssetItem $= "") + { + %assetItem.parentDepth = 0; + %this.importAssetNewListArray.add(%assetItem); + %this.importAssetUnprocessedListArray.add(%assetItem); + } + else + { + %assetItem.parentDepth = %parentAssetItem.parentDepth + 1; + %parentIndex = %this.importAssetUnprocessedListArray.getIndexFromKey(%parentAssetItem); + + %parentAssetItem.dependencies = %parentAssetItem.dependencies SPC %assetItem; + trim(%parentAssetItem.dependencies); + + %this.importAssetUnprocessedListArray.insert(%assetItem, "", %parentIndex + 1); + } + + return %assetItem; +} + +// +function ImportAssetButton::onClick(%this) +{ + %dlg = new OpenFileDialog() + { + Filters = "Shape Files(*.dae, *.cached.dts)|*.dae;*.cached.dts|Images Files(*.jpg,*.png,*.tga,*.bmp,*.dds)|*.jpg;*.png;*.tga;*.bmp;*.dds|Any Files (*.*)|*.*|"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + //MultipleFiles = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = makeRelativePath( %dlg.FileName, getMainDotCSDir() ); + %file = fileBase( %fullPath ); + } + + %dlg.delete(); + + if ( !%ret ) + return; + + AssetBrowser.importAssetListArray.empty(); + + %fileExt = fileExt( %fullPath ); + //add it to our array! + if( (%fileExt $= ".png") || (%fileExt $= ".jpg") || (%fileExt $= ".bmp") || (%fileExt $= ".dds") ) + AssetBrowser.importAssetListArray.add("Image", %fullPath); + else if( (%fileExt $= ".dae") || (%fileExt $= ".dts")) + AssetBrowser.importAssetListArray.add("Model", %fullPath); + else if( (%fileExt $= ".ogg") || (%fileExt $= ".wav") || (%fileExt $= ".mp3")) + AssetBrowser.importAssetListArray.add("Sound", %fullPath); + else if (%fileExt $= ".zip") + AssetBrowser.onDropZipFile(%fullPath); + + ImportAssetConfigWindow.visible = true; + ImportAssetConfigWindow.refresh(); + ImportAssetConfigWindow.selectWindow(); +} +// + +// +function ImportAssetWindow::onWake(%this) +{ + //We've woken, meaning we're trying to import assets + //Lets refresh our list + if(!ImportAssetWindow.isVisible()) + return; + + $AssetBrowser::importConfigsFile = "tools/assetBrowser/assetImportConfigs.xml"; + + %this.reloadImportOptionConfigs(); +} + +function ImportAssetWindow::reloadImportOptionConfigs(%this) +{ + ImportAssetWindow.importConfigsList = new ArrayObject(); + ImportAssetConfigList.clear(); + + %xmlDoc = new SimXMLDocument(); + if(%xmlDoc.loadFile($AssetBrowser::importConfigsFile)) + { + //StateMachine element + %xmlDoc.pushFirstChildElement("AssetImportConfigs"); + + //Configs + %configCount = 0; + while(%xmlDoc.pushChildElement(%configCount)) + { + %configObj = new ScriptObject(){}; + + %configObj.Name = %xmlDoc.attribute("Name"); + + %xmlDoc.pushFirstChildElement("Mesh"); + %configObj.ImportMesh = %xmlDoc.attribute("ImportMesh"); + %configObj.DoUpAxisOverride = %xmlDoc.attribute("DoUpAxisOverride"); + %configObj.UpAxisOverride = %xmlDoc.attribute("UpAxisOverride"); + %configObj.DoScaleOverride = %xmlDoc.attribute("DoScaleOverride"); + %configObj.ScaleOverride = %xmlDoc.attribute("ScaleOverride"); + %configObj.IgnoreNodeScale = %xmlDoc.attribute("IgnoreNodeScale"); + %configObj.AdjustCenter = %xmlDoc.attribute("AdjustCenter"); + %configObj.AdjustFloor = %xmlDoc.attribute("AdjustFloor"); + %configObj.CollapseSubmeshes = %xmlDoc.attribute("CollapseSubmeshes"); + %configObj.LODType = %xmlDoc.attribute("LODType"); + %configObj.ImportedNodes = %xmlDoc.attribute("ImportedNodes"); + %configObj.IgnoreNodes = %xmlDoc.attribute("IgnoreNodes"); + %configObj.ImportMeshes = %xmlDoc.attribute("ImportMeshes"); + %configObj.IgnoreMeshes = %xmlDoc.attribute("IgnoreMeshes"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Materials"); + %configObj.ImportMaterials = %xmlDoc.attribute("ImportMaterials"); + %configObj.CreateComposites = %xmlDoc.attribute("CreateComposites"); + %configObj.UseDiffuseSuffixOnOriginImg = %xmlDoc.attribute("UseDiffuseSuffixOnOriginImg"); + %configObj.UseExistingMaterials = %xmlDoc.attribute("UseExistingMaterials"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Animations"); + %configObj.ImportAnimations = %xmlDoc.attribute("ImportAnimations"); + %configObj.SeparateAnimations = %xmlDoc.attribute("SeparateAnimations"); + %configObj.SeparateAnimationPrefix = %xmlDoc.attribute("SeparateAnimationPrefix"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Collisions"); + %configObj.GenerateCollisions = %xmlDoc.attribute("GenerateCollisions"); + %configObj.GenCollisionType = %xmlDoc.attribute("GenCollisionType"); + %configObj.CollisionMeshPrefix = %xmlDoc.attribute("CollisionMeshPrefix"); + %configObj.GenerateLOSCollisions = %xmlDoc.attribute("GenerateLOSCollisions"); + %configObj.GenLOSCollisionType = %xmlDoc.attribute("GenLOSCollisionType"); + %configObj.LOSCollisionMeshPrefix = %xmlDoc.attribute("LOSCollisionMeshPrefix"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Images"); + %configObj.ImageType = %xmlDoc.attribute("ImageType"); + %configObj.DiffuseTypeSuffixes = %xmlDoc.attribute("DiffuseTypeSuffixes"); + %configObj.NormalTypeSuffixes = %xmlDoc.attribute("NormalTypeSuffixes"); + %configObj.SpecularTypeSuffixes = %xmlDoc.attribute("SpecularTypeSuffixes"); + %configObj.MetalnessTypeSuffixes = %xmlDoc.attribute("MetalnessTypeSuffixes"); + %configObj.RoughnessTypeSuffixes = %xmlDoc.attribute("RoughnessTypeSuffixes"); + %configObj.SmoothnessTypeSuffixes = %xmlDoc.attribute("SmoothnessTypeSuffixes"); + %configObj.AOTypeSuffixes = %xmlDoc.attribute("AOTypeSuffixes"); + %configObj.CompositeTypeSuffixes = %xmlDoc.attribute("CompositeTypeSuffixes"); + %configObj.TextureFilteringMode = %xmlDoc.attribute("TextureFilteringMode"); + %configObj.UseMips = %xmlDoc.attribute("UseMips"); + %configObj.IsHDR = %xmlDoc.attribute("IsHDR"); + %configObj.Scaling = %xmlDoc.attribute("Scaling"); + %configObj.Compressed = %xmlDoc.attribute("Compressed"); + %configObj.GenerateMaterialOnImport = %xmlDoc.attribute("GenerateMaterialOnImport"); + %configObj.PopulateMaterialMaps = %xmlDoc.attribute("PopulateMaterialMaps"); + %xmlDoc.popElement(); + + %xmlDoc.pushFirstChildElement("Sounds"); + %configObj.VolumeAdjust = %xmlDoc.attribute("VolumeAdjust"); + %configObj.PitchAdjust = %xmlDoc.attribute("PitchAdjust"); + %configObj.Compressed = %xmlDoc.attribute("Compressed"); + %xmlDoc.popElement(); + + %xmlDoc.popElement(); + %configCount++; + + ImportAssetWindow.importConfigsList.add(%configObj); + } + + %xmlDoc.popElement(); + } + + for(%i = 0; %i < ImportAssetWindow.importConfigsList.count(); %i++) + { + %configObj = ImportAssetWindow.importConfigsList.getKey(%i); + ImportAssetConfigList.add(%configObj.Name); + } + + ImportAssetConfigList.setSelected(0); +} + +function ImportAssetWindow::setImportOptions(%this, %optionsObj) +{ + //Todo, editor + load from files for preconfigs + + //Meshes + %optionsObj.ImportMesh = true; + %optionsObj.UpAxisOverride = "Z_AXIS"; + %optionsObj.OverrideScale = 1.0; + %optionsObj.IgnoreNodeScale = false; + %optionsObj.AdjustCenter = false; + %optionsObj.AdjustFloor = false; + %optionsObj.CollapseSubmeshes = false; + %optionsObj.LODType = "TrailingNumber"; + %optionsObj.TrailingNumber = 2; + %optionsObj.ImportedNodes = ""; + %optionsObj.IgnoreNodes = ""; + %optionsObj.ImportMeshes = ""; + %optionsObj.IgnoreMeshes = ""; + + //Materials + %optionsObj.ImportMaterials = true; + %optionsObj.CreateComposites = true; + + //Animations + %optionsObj.ImportAnimations = true; + %optionsObj.SeparateAnimations = true; + %optionsObj.SeparateAnimationPrefix = ""; + + //Collision + %optionsObj.GenerateCollisions = true; + %optionsObj.GenCollisionType = "CollisionMesh"; + %optionsObj.CollisionMeshPrefix = "Collision"; + %optionsObj.GenerateLOSCollisions = true; + %optionsObj.GenLOSCollisionType = "CollisionMesh"; + %optionsObj.LOSCollisionMeshPrefix = "LOS"; + + //Images + %optionsObj.ImageType = "Diffuse"; + %optionsObj.DiffuseTypeSuffixes = "_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL"; + %optionsObj.NormalTypeSuffixes = "_NORMAL,_NORM"; + %optionsObj.SpecularTypeSuffixes = "_SPECULAR,_SPEC"; + %optionsObj.MetalnessTypeSuffixes = "_METAL,_MET,_METALNESS,_METALLIC"; + %optionsObj.RoughnessTypeSuffixes = "_ROUGH,_ROUGHNESS"; + %optionsObj.SmoothnessTypeSuffixes = "_SMOOTH,_SMOOTHNESS"; + %optionsObj.AOTypeSuffixes = "_AO,_AMBIENT,_AMBIENTOCCLUSION"; + %optionsObj.CompositeTypeSuffixes = "_COMP,_COMPOSITE"; + %optionsObj.TextureFilteringMode = "Bilinear"; + %optionsObj.UseMips = true; + %optionsObj.IsHDR = false; + %optionsObj.Scaling = 1.0; + %optionsObj.Compressed = true; + + //Sounds + %optionsObj.VolumeAdjust = 1.0; + %optionsObj.PitchAdjust = 1.0; + %optionsObj.Compressed = false; +} + +// +function ImportAssetWindow::processNewImportAssets(%this) +{ + %unprocessedCount = AssetBrowser.importAssetUnprocessedListArray.count(); + while(AssetBrowser.importAssetUnprocessedListArray.count() > 0) + { + %assetItem = AssetBrowser.importAssetUnprocessedListArray.getKey(0); + + %assetConfigObj = ImportAssetWindow.activeImportConfig.clone(); + %assetConfigObj.assetIndex = %i; + %assetConfigObj.assetName = %assetItem.assetName; + %assetItem.importConfig = %assetConfigObj; + + if(%assetItem.assetType $= "Model") + { + %fileExt = fileExt(%assetItem.filePath); + if(%fileExt $= ".dae") + { + %shapeInfo = new GuiTreeViewCtrl(); + enumColladaForImport(%assetItem.filePath, %shapeInfo); + } + else + { + %shapeInfo = GetShapeInfo(%assetItem.filePath); + } + + %assetItem.shapeInfo = %shapeInfo; + + %shapeItem = %assetItem.shapeInfo.findItemByName("Shape"); + %shapeCount = %assetItem.shapeInfo.getItemValue(%shapeItem); + + if(%assetConfigObj.ImportMesh == 1 && %shapeCount > 0) + { + + } + + %animItem = %assetItem.shapeInfo.findItemByName("Animations"); + %animCount = %assetItem.shapeInfo.getItemValue(%animItem); + + if(%assetConfigObj.ImportAnimations == 1 && %animCount > 0) + { + %animationItem = %assetItem.shapeInfo.getChild(%animItem); + + %animName = %assetItem.shapeInfo.getItemText(%animationItem); + //%animName = %assetItem.shapeInfo.getItemValue(%animationItem); + + AssetBrowser.addImportingAsset("Animation", %animName, %assetItem); + + %animationItem = %assetItem.shapeInfo.getNextSibling(%animationItem); + while(%animationItem != 0) + { + %animName = %assetItem.shapeInfo.getItemText(%animationItem); + //%animName = %assetItem.shapeInfo.getItemValue(%animationItem); + + AssetBrowser.addImportingAsset("Animation", %animName, %assetItem); + + %animationItem = %shapeInfo.getNextSibling(%animationItem); + } + } + + %matItem = %assetItem.shapeInfo.findItemByName("Materials"); + %matCount = %assetItem.shapeInfo.getItemValue(%matItem); + + if(%assetConfigObj.importMaterials == 1 && %matCount > 0) + { + %materialItem = %assetItem.shapeInfo.getChild(%matItem); + + %matName = %assetItem.shapeInfo.getItemText(%materialItem); + + %filePath = %assetItem.shapeInfo.getItemValue(%materialItem); + if(%filePath !$= "") + { + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + } + else + { + //we need to try and find our material, since the shapeInfo wasn't able to find it automatically + %filePath = findImageFile(filePath(%assetItem.filePath), %matName); + if(%filePath !$= "") + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + else + AssetBrowser.addImportingAsset("Material", %matName, %assetItem); + } + + %materialItem = %assetItem.shapeInfo.getNextSibling(%materialItem); + while(%materialItem != 0) + { + %matName = %assetItem.shapeInfo.getItemText(%materialItem); + %filePath = %assetItem.shapeInfo.getItemValue(%materialItem); + if(%filePath !$= "") + { + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + } + else + { + //we need to try and find our material, since the shapeInfo wasn't able to find it automatically + %filePath = findImageFile(filePath(%assetItem.filePath), %matName); + if(%filePath !$= "") + AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + else + AssetBrowser.addImportingAsset("Material", %matName, %assetItem); + } + + %materialItem = %shapeInfo.getNextSibling(%materialItem); + } + } + } + else if(%assetItem.assetType $= "Animation") + { + //if we don't have our own file, that means we're gunna be using our parent shape's file so reference that + if(!isFile(%assetItem.filePath)) + { + %assetItem.filePath = %assetItem.parentAssetItem.filePath; + } + } + else if(%assetItem.assetType $= "Material") + { + //Iterate over to find appropriate images for + + //Fetch just the fileBase name + %fileDir = filePath(%assetItem.filePath); + %filename = fileBase(%assetItem.filePath); + %fileExt = fileExt(%assetItem.filePath); + + if(%assetItem.importConfig.PopulateMaterialMaps == 1) + { + if(%assetItem.diffuseImageAsset $= "") + { + //First, load our diffuse map, as set to the material in the shape + %diffuseAsset = AssetBrowser.addImportingAsset("Image", %fileDir @ "/" @ %filename @ %fileExt, %assetItem); + %assetItem.diffuseImageAsset = %diffuseAsset; + + if(%assetItem.importConfig.UseDiffuseSuffixOnOriginImg == 1) + { + %diffuseToken = getToken(%assetItem.importConfig.DiffuseTypeSuffixes, ",", 0); + %diffuseAsset.AssetName = %diffuseAsset.AssetName @ %diffuseToken; + } + } + + if(%assetItem.normalImageAsset $= "") + { + //Now, iterate over our comma-delimited suffixes to see if we have any matches. We'll use the first match in each case, if any. + //First, normal map + %listCount = getTokenCount(%assetItem.importConfig.NormalTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.NormalTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %normalAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.normalImageAsset = %normalAsset; + break; + } + } + } + if(%assetItem.specularImageAsset $= "") + { + //Specular + %listCount = getTokenCount(%assetItem.importConfig.SpecularTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.SpecularTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %specularAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.specularImageAsset = %specularAsset; + break; + } + } + } + + if(%assetItem.metalImageAsset $= "") + { + //Metal + %listCount = getTokenCount(%assetItem.importConfig.MetalnessTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.MetalnessTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %metalAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.metalImageAsset = %metalAsset; + break; + } + } + } + + if(%assetItem.roughnessImageAsset $= "") + { + //Roughness + %listCount = getTokenCount(%assetItem.importConfig.RoughnessTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.RoughnessTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %roughnessAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.roughnessImageAsset = %roughnessAsset; + break; + } + } + } + + if(%assetItem.smoothnessImageAsset $= "") + { + //Smoothness + %listCount = getTokenCount(%assetItem.importConfig.SmoothnessTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.SmoothnessTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %smoothnessAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.SmoothnessImageAsset = %smoothnessAsset; + break; + } + } + } + + if(%assetItem.AOImageAsset $= "") + { + //AO + %listCount = getTokenCount(%assetItem.importConfig.AOTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.AOTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %AOAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.AOImageAsset = %AOAsset; + break; + } + } + } + + if(%assetItem.compositeImageAsset $= "") + { + //Composite + %listCount = getTokenCount(%assetItem.importConfig.CompositeTypeSuffixes, ","); + + %foundFile = 0; + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%assetItem.importConfig.CompositeTypeSuffixes, ",", %i); + + %targetFilePath = %fileDir @ "/" @ %filename @ %entryText @ %fileExt; + %foundFile = isFile(%targetFilePath); + + if(%foundFile) + { + %compositeAsset = AssetBrowser.addImportingAsset("Image", %targetFilePath, %assetItem); + %assetItem.compositeImageAsset = %compositeAsset; + break; + } + } + } + } + } + else if(%assetItem.assetType $= "Image") + { + if(%assetConfigObj.GenerateMaterialOnImport == 1 && %assetItem.parentAssetItem $= "") + { + %filePath = %assetItem.filePath; + if(%filePath !$= "") + %materialAsset = AssetBrowser.addImportingAsset("Material", %filePath, %assetItem); + + %materialAsset.diffuseImageAsset = %assetItem; + + if(%assetConfigObj.UseDiffuseSuffixOnOriginImg == 1) + { + %diffuseToken = getToken(%assetItem.importConfig.DiffuseTypeSuffixes, ",", 0); + %assetItem.AssetName = %assetItem.AssetName @ %diffuseToken; + } + } + } + + AssetBrowser.importAssetUnprocessedListArray.erase(0); + //Been processed, so add it to our final list + AssetBrowser.importAssetFinalListArray.add(%assetItem); + } +} + +function ImportAssetWindow::refresh(%this) +{ + ImportingAssetList.clear(); + + //Go through and process any newly, unprocessed assets + %this.processNewImportAssets(); + + if(AssetBrowser.importAssetUnprocessedListArray.count() == 0) + { + //We've processed them all, prep the assets for actual importing + //Initial set of assets + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + + for(%i=0; %i < %assetCount; %i++) + { + %assetItem = AssetBrowser.importAssetFinalListArray.getKey(%i); + %assetType = %assetItem.assetType; + %filePath = %assetItem.filePath; + %assetName = %assetItem.assetName; + + //validate + %this.validateAsset(%assetItem); + + //Once validated, attempt any fixes for issues + %this.resolveIssue(%assetItem); + + //Make sure we size correctly + ImportingAssetList.extent.x = ImportingAssetList.getParent().extent.x - 15; + + //create! + %width = mRound(mRound(ImportingAssetList.extent.x) / 2); + %height = 20; + %indent = %assetItem.parentDepth * 16; + %toolTip = ""; + + %iconPath = "tools/gui/images/iconInformation"; + %configCommand = "ImportAssetOptionsWindow.editImportSettings(" @ %assetItem @ ");"; + + if(%assetType $= "Model" || %assetType $= "Animation" || %assetType $= "Image" || %assetType $= "Sound") + { + if(%assetItem.status $= "Error") + { + %iconPath = "tools/gui/images/iconError"; + %configCommand = "ImportAssetOptionsWindow.findMissingFile(" @ %assetItem @ ");"; + } + else if(%assetItem.status $= "Warning") + { + %iconPath = "tools/gui/images/iconWarn"; + %configCommand = "ImportAssetOptionsWindow.fixIssues(" @ %assetItem @ ");"; + + if(%assetItem.statusType $= "DuplicateAsset" || %assetItem.statusType $= "DuplicateImportAsset") + %assetName = %assetItem.assetName @ " "; + } + + %toolTip = %assetItem.statusInfo; + } + else + { + if(%assetItem.status $= "Error") + { + %iconPath = "tools/gui/images/iconError"; + %configCommand = "";//"ImportAssetOptionsWindow.findMissingFile(" @ %assetItem @ ");"; + } + else if(%assetItem.status $= "Warning") + { + %iconPath = "tools/gui/images/iconWarn"; + %configCommand = "";//"ImportAssetOptionsWindow.fixIssues(" @ %assetItem @ ");"; + + if(%assetItem.statusType $= "DuplicateAsset" || %assetItem.statusType $= "DuplicateImportAsset") + %assetName = %assetItem.assetName @ " "; + } + } + + %importEntry = new GuiControl() + { + position = "0 0"; + extent = ImportingAssetList.extent.x SPC %height; + + new GuiTextCtrl() + { + Text = %assetName; + position = %indent SPC "0"; + extent = %width - %indent SPC %height; + internalName = "AssetName"; + }; + + new GuiTextCtrl() + { + Text = %assetType; + position = %width SPC "0"; + extent = %width - %height - %height SPC %height; + internalName = "AssetType"; + }; + + new GuiBitmapButtonCtrl() + { + position = ImportingAssetList.extent.x - %height - %height SPC "0"; + extent = %height SPC %height; + command = %configCommand; + bitmap = %iconPath; + tooltip = %toolTip; + }; + new GuiBitmapButtonCtrl() + { + position = ImportingAssetList.extent.x - %height SPC "0"; + extent = %height SPC %height; + command = "ImportAssetOptionsWindow.deleteImportingAsset(" @ %assetItem @ ");"; + bitmap = "tools/gui/images/iconDelete"; + }; + }; + + ImportingAssetList.add(%importEntry); + } + } + else + { + //Continue processing + %this.refresh(); + } +} +// + +function ImportAssetWindow::validateAssets(%this) +{ + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + %moduleName = ImportAssetModuleList.getText(); + %assetQuery = new AssetQuery(); + + %hasIssues = false; + + //First, check the obvious: name collisions. We should have no asset that shares a similar name. + //If we do, prompt for it be renamed first before continuing + + for(%i=0; %i < %assetCount; %i++) + { + %assetItemA = AssetBrowser.importAssetFinalListArray.getKey(%i); + + //First, check our importing assets for name collisions + for(%j=0; %j < %assetCount; %j++) + { + %assetItemB = AssetBrowser.importAssetFinalListArray.getKey(%j); + if( (%assetItemA.assetName $= %assetItemB.assetName) && (%i != %j) ) + { + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItemB.assetName @ "\" of type \"" @ %assetItemB.assetType @ "\" have matching names.\nPlease rename one of them and try again!");*/ + + %assetItemA.status = "Warning"; + %assetItemA.statusType = "DuplicateImportAsset"; + %assetItemA.statusInfo = "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItemB.assetName @ "\" of type \"" @ %assetItemB.assetType @ "\" have matching names.\nPlease rename one of them and try again!"; + + %hasIssues = true; + } + } + + //No collisions of for this name in the importing assets. Now, check against the existing assets in the target module + if(!AssetBrowser.isAssetReImport) + { + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + %foundCollision = false; + for( %f=0; %f < %numAssetsFound; %f++) + { + %assetId = %assetQuery.getAsset(%f); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %testModuleName = %module.moduleId; + + //These are core, native-level components, so we're not going to be messing with this module at all, skip it + if(%moduleName !$= %testModuleName) + continue; + + %testAssetName = AssetDatabase.getAssetName(%assetId); + + if(%testAssetName $= %assetItemA.assetName) + { + %foundCollision = true; + + %assetItemA.status = "Warning"; + %assetItemA.statusType = "DuplicateAsset"; + %assetItemA.statusInfo = "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" has a matching name.\nPlease rename it and try again!"; + + break; + } + } + + if(%foundCollision == true) + { + %hasIssues = true; + + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" has a matching name.\nPlease rename it and try again!");*/ + + //%assetQuery.delete(); + //return false; + } + } + + if(!isFile(%assetItemA.filePath)) + { + %hasIssues = true; + %assetItemA.status = "error"; + %assetItemA.statusType = "MissingFile"; + %assetItemA.statusInfo = "Unable to find file to be imported. Please select asset file."; + } + } + + //Clean up our queries + %assetQuery.delete(); + + if(%hasIssues) + return false; + else + return true; +} + +function ImportAssetWindow::ImportAssets(%this) +{ + //do the actual importing, now! + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + + //get the selected module data + %moduleName = ImportAssetModuleList.getText(); + + %module = ModuleDatabase.findModule(%moduleName, 1); + + if(!isObject(%module)) + { + MessageBoxOK( "Error!", "No module selected. You must select or create a module for the assets to be added to."); + return; + } + + /*if(!%this.validateAssets()) + { + //Force a refresh, as some things may have changed, such as errors and failure info! + refresh(); + + return; + }*/ + + for(%i=0; %i < %assetCount; %i++) + { + %assetItem = AssetBrowser.importAssetFinalListArray.getKey(%i); + %assetType = %assetItem.AssetType; + %filePath = %assetItem.filePath; + %assetName = %assetItem.assetName; + %assetImportSuccessful = false; + %assetId = %moduleName@":"@%assetName; + + if(%assetType $= "Image") + { + %assetPath = "data/" @ %moduleName @ "/Images"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new ImageAsset() + { + assetName = %assetName; + versionId = 1; + imageFile = %assetFullPath; + originalFilePath = %filePath; + }; + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + } + else if(%assetType $= "Model") + { + %assetPath = "data/" @ %moduleName @ "/Shapes"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new ShapeAsset() + { + assetName = %assetName; + versionId = 1; + fileName = %assetFullPath; + originalFilePath = %filePath; + isNewShape = true; + }; + + %dependencyCount = getWordCount(%assetItem.dependencies); + for(%d=0; %d < %dependencyCount; %d++) + { + %dependencyAssetItem = getWord(%assetItem.dependencies, %d); + + %depAssetType = %dependencyAssetItem.assetType; + if(%depAssetType $= "Material") + { + %matSet = "%newAsset.materialSlot"@%d@"=\"@Asset="@%moduleName@":"@%dependencyAssetItem.assetName@"\";"; + eval(%matSet); + } + if(%depAssetType $= "Animation") + { + %matSet = "%newAsset.animationSequence"@%d@"=\"@Asset="@%moduleName@":"@%dependencyAssetItem.assetName@"\";"; + eval(%matSet); + } + } + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + + //now, force-load the file if it's collada + %fileExt = fileExt(%assetFullPath); + if(isSupportedFormat(getSubStr(%fileExt,1))) + { + %tempShape = new TSStatic() + { + shapeName = %assetFullPath; + }; + + %tempShape.delete(); + } + } + else if(%assetType $= "Animation") + { + %assetPath = "data/" @ %moduleName @ "/ShapeAnimations"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new ShapeAnimationAsset() + { + assetName = %assetName; + versionId = 1; + fileName = %assetFullPath; + originalFilePath = %filePath; + animationFile = %assetFullPath; + animationName = %assetName; + startFrame = 0; + endFrame = -1; + padRotation = false; + padTransforms = false; + }; + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + } + else if(%assetType $= "Sound") + { + %assetPath = "data/" @ %moduleName @ "/Sounds"; + %assetFullPath = %assetPath @ "/" @ fileName(%filePath); + + %newAsset = new SoundAsset() + { + assetName = %assetName; + versionId = 1; + fileName = %assetFullPath; + originalFilePath = %filePath; + }; + + %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); + + //and copy the file into the relevent directory + %doOverwrite = !AssetBrowser.isAssetReImport; + if(!pathCopy(%filePath, %assetFullPath, %doOverwrite)) + { + error("Unable to import asset: " @ %filePath); + } + } + else if(%assetType $= "Material") + { + %assetPath = "data/" @ %moduleName @ "/materials"; + %tamlpath = %assetPath @ "/" @ %assetName @ ".asset.taml"; + %sgfPath = %assetPath @ "/" @ %assetName @ ".sgf"; + %scriptPath = %assetPath @ "/" @ %assetName @ ".cs"; + + %newAsset = new MaterialAsset() + { + assetName = %assetName; + versionId = 1; + shaderGraph = %sgfPath; + scriptFile = %scriptPath; + originalFilePath = %filePath; + materialDefinitionName = %assetName; + }; + + %dependencyCount = getWordCount(%assetItem.dependencies); + for(%d=0; %d < %dependencyCount; %d++) + { + %dependencyAssetItem = getWord(%assetItem.dependencies, %d); + + %depAssetType = %dependencyAssetItem.assetType; + if(%depAssetType $= "Image") + { + %matSet = "%newAsset.imageMap"@%d@"=\"@Asset="@%moduleName@":"@%dependencyAssetItem.assetName@"\";"; + eval(%matSet); + } + } + + %assetImportSuccessful = TamlWrite(%newAsset, %tamlpath); + + %file = new FileObject(); + + if(%file.openForWrite(%scriptPath)) + { + %file.writeline("//--- OBJECT WRITE BEGIN ---"); + %file.writeline("singleton Material(" @ %assetName @ ") {"); + + //TODO: pass along the shape's target material for this just to be sure + %file.writeLine(" mapTo = \"" @ %assetName @ "\";"); + + if(%assetItem.diffuseImageAsset !$= "") + { + %diffuseAssetPath = "data/" @ %moduleName @ "/Images/" @ fileName(%assetItem.diffuseImageAsset.filePath); + %file.writeline(" DiffuseMap[0] = \"" @ %diffuseAssetPath @"\";"); + %file.writeline(" DiffuseMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.diffuseImageAsset.assetName @"\";"); + } + if(%assetItem.normalImageAsset) + { + %normalAssetPath = "data/" @ %moduleName @ "/Images/" @ fileName(%assetItem.normalImageAsset.filePath); + %file.writeline(" NormalMap[0] = \"" @ %normalAssetPath @"\";"); + %file.writeline(" NormalMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.normalImageAsset.assetName @"\";"); + } + /*if(%assetItem.specularImageAsset) + { + %file.writeline(" SpecularMap[0] = \"" @ %assetItem.specularImageAsset.filePath @"\";"); + %file.writeline(" SpecularMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.specularImageAsset.assetName @"\";"); + }*/ + if(%assetItem.roughnessImageAsset) + { + %file.writeline(" RoughMap[0] = \"" @ %assetItem.roughnessImageAsset.filePath @"\";"); + %file.writeline(" RoughMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.roughnessImageAsset.assetName @"\";"); + } + if(%assetItem.smoothnessImageAsset) + { + %file.writeline(" SmoothnessMap[0] = \"" @ %assetItem.smoothnessImageAsset.filePath @"\";"); + %file.writeline(" SmoothnessMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.smoothnessImageAsset.assetName @"\";"); + } + if(%assetItem.metalnessImageAsset) + { + %file.writeline(" MetalMap[0] = \"" @ %assetItem.metalnessImageAsset.filePath @"\";"); + %file.writeline(" MetalMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.metalnessImageAsset.assetName @"\";"); + } + if(%assetItem.AOImageAsset) + { + %file.writeline(" AOMap[0] = \"" @ %assetItem.AOImageAsset.filePath @"\";"); + %file.writeline(" AOMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.AOImageAsset.assetName @"\";"); + } + if(%assetItem.compositeImageAsset) + { + %file.writeline(" CompositeMap[0] = \"" @ %assetItem.compositeImageAsset.filePath @"\";"); + %file.writeline(" CompositeMapAsset[0] = \"" @ %moduleName @ ":" @ %assetItem.compositeImageAsset.assetName @"\";"); + } + %file.writeline("};"); + %file.writeline("//--- OBJECT WRITE END ---"); + + %file.close(); + } + } + + if(%assetImportSuccessful) + { + %moduleDef = ModuleDatabase.findModule(%moduleName,1); + + if(!AssetBrowser.isAssetReImport) + AssetDatabase.addDeclaredAsset(%moduleDef, %assetPath @ "/" @ %assetName @ ".asset.taml"); + else + AssetDatabase.refreshAsset(%assetId); + } + } + + //force an update of any and all modules so we have an up-to-date asset list + AssetBrowser.loadFilters(); + AssetBrowser.refreshPreviews(); + Canvas.popDialog(AssetImportCtrl); + AssetBrowser.isAssetReImport = false; +} + +// +function ImportAssetWindow::validateAsset(%this, %assetItem) +{ + %assetCount = AssetBrowser.importAssetFinalListArray.count(); + %moduleName = ImportAssetModuleList.getText(); + + %hasIssues = false; + + //First, check the obvious: name collisions. We should have no asset that shares a similar name. + //If we do, prompt for it be renamed first before continuing + + for(%i=0; %i < %assetCount; %i++) + { + %assetItemA = AssetBrowser.importAssetFinalListArray.getKey(%i); + + if( (%assetItemA.assetName $= %assetItem.assetName) && (%assetItemA.getId() != %assetItem.getId()) ) + { + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItemB.assetName @ "\" of type \"" @ %assetItemB.assetType @ "\" have matching names.\nPlease rename one of them and try again!");*/ + + %assetItem.status = "Warning"; + %assetItem.statusType = "DuplicateImportAsset"; + %assetItem.statusInfo = "Duplicate asset names found with importing assets!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" and \"" @ + %assetItem.assetName @ "\" of type \"" @ %assetItem.assetType @ "\" have matching names.\nPlease rename one of them and try again!"; + + %hasIssues = true; + return false; + } + } + + //No collisions of for this name in the importing assets. Now, check against the existing assets in the target module + if(!AssetBrowser.isAssetReImport) + { + %assetQuery = new AssetQuery(); + + %numAssetsFound = AssetDatabase.findAllAssets(%assetQuery); + + %foundCollision = false; + for( %f=0; %f < %numAssetsFound; %f++) + { + %assetId = %assetQuery.getAsset(%f); + + //first, get the asset's module, as our major categories + %module = AssetDatabase.getAssetModule(%assetId); + + %testModuleName = %module.moduleId; + + //These are core, native-level components, so we're not going to be messing with this module at all, skip it + if(%moduleName !$= %testModuleName) + continue; + + %testAssetName = AssetDatabase.getAssetName(%assetId); + + if(%testAssetName $= %assetItem.assetName) + { + %foundCollision = true; + + %assetItem.status = "Warning"; + %assetItem.statusType = "DuplicateAsset"; + %assetItem.statusInfo = "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItem.assetName @ "\" of type \"" @ %assetItem.assetType @ "\" has a matching name.\nPlease rename it and try again!"; + + //Clean up our queries + %assetQuery.delete(); + + return false; + } + } + + if(%foundCollision == true) + { + %hasIssues = true; + + //yup, a collision, prompt for the change and bail out + /*MessageBoxOK( "Error!", "Duplicate asset names found with the target module!\nAsset \"" @ + %assetItemA.assetName @ "\" of type \"" @ %assetItemA.assetType @ "\" has a matching name.\nPlease rename it and try again!");*/ + + //%assetQuery.delete(); + //return false; + } + + //Clean up our queries + %assetQuery.delete(); + } + + if(!isFile(%assetItem.filePath)) + { + %hasIssues = true; + %assetItem.status = "error"; + %assetItem.statusType = "MissingFile"; + %assetItem.statusInfo = "Unable to find file to be imported. Please select asset file."; + + return false; + } + + return true; +} + +function ImportAssetWindow::resolveIssue(%this, %assetItem) +{ + if(%assetItem.status !$= "Warning") + return; + + //Ok, we actually have a warning, so lets resolve + if(%assetItem.statusType $= "DuplicateImportAsset" || %assetItem.statusType $= "DuplicateAsset") + { + + } + else if(%assetItem.statusType $= "MissingFile") + { + %this.findMissingFile(%assetItem); + } +} +// + +// +function ImportAssetModuleList::onWake(%this) +{ + %this.refresh(); +} + +function ImportAssetModuleList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} +// diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfig.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfig.cs new file mode 100644 index 000000000..bdd4c2851 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfig.cs @@ -0,0 +1,472 @@ +function ImportAssetConfigList::onSelect( %this, %id, %text ) +{ + //Apply our settings to the assets + echo("Changed our import config!"); + AssetBrowser.importAssetUnprocessedListArray.empty(); + AssetBrowser.importAssetUnprocessedListArray.duplicate(AssetBrowser.importAssetNewListArray); + AssetBrowser.importAssetFinalListArray.empty(); + + ImportAssetWindow.activeImportConfigIndex = %id; + ImportAssetWindow.activeImportConfig = ImportAssetWindow.importConfigsList.getKey(%id); + ImportAssetWindow.refresh(); +} + +function ImportAssetOptionsWindow::findMissingFile(%this, %assetItem) +{ + if(%assetItem.assetType $= "Model") + %filters = "Shape Files(*.dae, *.cached.dts)|*.dae;*.cached.dts"; + else if(%assetItem.assetType $= "Image") + %filters = "Images Files(*.jpg,*.png,*.tga,*.bmp,*.dds)|*.jpg;*.png;*.tga;*.bmp;*.dds"; + + %dlg = new OpenFileDialog() + { + Filters = %filters; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = true; + OverwritePrompt = true; + forceRelativePath = false; + //MultipleFiles = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = %dlg.FileName;//makeRelativePath( %dlg.FileName, getMainDotCSDir() ); + } + + %dlg.delete(); + + if ( !%ret ) + return; + + %assetItem.filePath = %fullPath; + + ImportAssetWindow.refresh(); +} + +// +function ImportAssetOptionsWindow::editImportSettings(%this, %assetItem) +{ + ImportAssetOptionsWindow.setVisible(1); + ImportAssetOptionsWindow.selectWindow(); + + ImportOptionsList.clearFields(); + + %assetType = %assetItem.assetType; + %filePath = %assetItem.filePath; + %assetName = %assetItem.assetName; + %assetConfigObj = %assetItem.importConfig; + + ImportOptionsList.startGroup("Asset"); + ImportOptionsList.addField("AssetName", "Asset Name", "string", "", "NewAsset", "", %assetItem); + ImportOptionsList.endGroup(); + + if(%assetType $= "Model") + { + //Get the shape info, so we know what we're doing with the mesh + %shapeInfo = GetShapeInfo(%filePath); + %meshItem = %shapeInfo.findItemByName("Meshes"); + %matItem = %shapeInfo.findItemByName("Materials"); + + %meshCount = %shapeInfo.getItemValue(%meshItem); + %matCount = %shapeInfo.getItemValue(%matItem); + + %firstMat = %shapeInfo.getChild(%matItem); + echo("Mesh's first material texture path is: " @ %shapeInfo.getItemValue(%firstMat)); + + if(%meshCount > 0) + { + ImportOptionsList.startGroup("Mesh"); + ImportOptionsList.addField("AutogenCollisions", "Auto-gen Collisions", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("CollapseSubmeshes", "Collapse Submeshes", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("UpAxisOverride", "Up-Axis Override", "list", "", "Z_AXIS", "Z_AXIS,Y_AXIS,X_AXIS", %assetConfigObj); + ImportOptionsList.addField("OverrideScale", "Override Scale", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.addField("IgnoreNodeScale", "IgnoreNodeScaling", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("AdjustCenter", "Adjust Center", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("CollapseSubmeshes", "Collapse Submeshes", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("AdjustFloor", "Adjust Floor", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.addField("LODType", "LOD Type", "list", "", "TrailingNumber", "TrailingNumber,DetectDTS", %assetConfigObj); + ImportOptionsList.endGroup(); + } + + if(%matItem > 0) + { + ImportOptionsList.startGroup("Material"); + ImportOptionsList.addCallbackField("ImportMaterials", "Import Materials", "bool", "", "1", "", "ImportMaterialsChanged", %assetConfigObj); + ImportOptionsList.addField("UseExistingMaterials", "Use Existing Materials", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + } + } + else if(%assetType $= "Material") + { + ImportOptionsList.startGroup("Material"); + ImportOptionsList.addField("CreateComposites", "Create Composite Textures", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + } + else if(%assetType $= "Image") + { + ImportOptionsList.startGroup("Formatting"); + ImportOptionsList.addField("ImageType", "Image Type", "string", "", "Diffuse", "", %assetConfigObj); + ImportOptionsList.addField("TextureFiltering", "Texture Filtering", "list", "", "Bilinear", "None,Bilinear,Trilinear", %assetConfigObj); + ImportOptionsList.addField("UseMips", "Use Mips", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.addField("IsHDR", "Is HDR", "bool", "", "0", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Scaling"); + ImportOptionsList.addField("Scaling", "Scaling", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Compression"); + ImportOptionsList.addField("IsCompressed", "Is Compressed", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Material"); + ImportOptionsList.addField("GenerateMaterialOnImport", "Generate Material On Import", "bool", "", "1", "", %optionsObj); + ImportOptionsList.addField("PopulateMaterialMaps", "Populate Material Maps", "bool", "", "1", "", %optionsObj); + ImportOptionsList.addField("UseDiffuseSuffixOnOriginImg", "Use Diffuse Suffix for Origin Image", "bool", "", "1", "", %optionsObj); + ImportOptionsList.addField("UseExistingMaterials", "Use Existing Materials", "bool", "", "1", "", %optionsObj); + ImportOptionsList.endGroup(); + } + else if(%assetType $= "Sound") + { + ImportOptionsList.startGroup("Adjustment"); + ImportOptionsList.addField("VolumeAdjust", "VolumeAdjustment", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.addField("PitchAdjust", "PitchAdjustment", "float", "", "1.0", "", %assetConfigObj); + ImportOptionsList.endGroup(); + + ImportOptionsList.startGroup("Compression"); + ImportOptionsList.addField("IsCompressed", "Is Compressed", "bool", "", "1", "", %assetConfigObj); + ImportOptionsList.endGroup(); + } +} + +function ImportAssetOptionsWindow::deleteImportingAsset(%this, %assetItem) +{ + %assetIndex = AssetBrowser.importAssetNewListArray.getIndexFromKey(%assetItem); + AssetBrowser.importAssetNewListArray.erase(%assetIndex); + + //check if we have any child assets and remove them as well + for(%i=0; %i < AssetBrowser.importAssetNewListArray.count(); %i++) + { + %asset = AssetBrowser.importAssetNewListArray.getKey(%i); + if(%asset.ParentAssetItem == %assetItem) + { + AssetBrowser.importAssetNewListArray.erase(%i); + %i--; + } + } + + %assetIndex = AssetBrowser.importAssetFinalListArray.getIndexFromKey(%assetItem); + AssetBrowser.importAssetFinalListArray.erase(%assetIndex); + + //check if we have any child assets and remove them as well + for(%i=0; %i < AssetBrowser.importAssetFinalListArray.count(); %i++) + { + %asset = AssetBrowser.importAssetFinalListArray.getKey(%i); + if(%asset.ParentAssetItem == %assetItem) + { + AssetBrowser.importAssetFinalListArray.erase(%i); + %i--; + } + } + + ImportAssetWindow.refresh(); + ImportAssetOptionsWindow.setVisible(0); +} + +function ImportAssetOptionsWindow::saveAssetOptions(%this) +{ + ImportAssetWindow.refresh(); + ImportAssetOptionsWindow.setVisible(0); +} + +function ImportOptionsList::ImportMaterialsChanged(%this, %fieldName, %newValue, %ownerObject) +{ + echo("CHANGED IF OUR IMPORTED MATERIALS WERE HAPPENING!"); +} + +function ImportAssetConfigEditorWindow::populateConfigList(%this, %optionsObj) +{ + AssetImportConfigName.setText(%optionsObj.Name); + + ImportOptionsConfigList.clear(); + + ImportOptionsConfigList.startGroup("Mesh"); + ImportOptionsConfigList.addCallbackField("ImportMesh", "Import Mesh", "bool", "", "1", "", "ToggleImportMesh", %optionsObj); + ImportOptionsConfigList.addField("DoUpAxisOverride", "Do Up-axis Override", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("UpAxisOverride", "Up-axis Override", "list", "", "Z_AXIS", "X_AXIS,Y_AXIS,Z_AXIS", %optionsObj); + ImportOptionsConfigList.addField("DoScaleOverride", "Do Scale Override", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("ScaleOverride", "Scale Override", "float", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreNodeScale", "Ignore Node Scale", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("AdjustCenter", "Adjust Center", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("AdjustFloor", "Adjust Floor", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("CollapseSubmeshes", "Collapse Submeshes", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("LODType", "LOD Type", "list", "", "TrailingNumber", "TrailingNumber,DetectDTS", %optionsObj); + //ImportOptionsConfigList.addField("TrailingNumber", "Trailing Number", "float", "", "2", "", %optionsObj, "Mesh"); + ImportOptionsConfigList.addField("ImportedNodes", "Imported Nodes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreNodes", "Ignore Nodes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.addField("ImportMeshes", "Import Meshes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreMeshes", "Imported Meshes", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Materials + ImportOptionsConfigList.startGroup("Material"); + ImportOptionsConfigList.addField("ImportMaterials", "Import Materials", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("CreateComposites", "Create Composites", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("UseDiffuseSuffixOnOriginImg", "Use Diffuse Suffix for Origin Image", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("UseExistingMaterials", "Use Existing Materials", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("IgnoreMaterials", "Ignore Materials", "command", "", "", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Animations + ImportOptionsConfigList.startGroup("Animations"); + ImportOptionsConfigList.addField("ImportAnimations", "Import Animations", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("SeparateAnimations", "Separate Animations", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("SeparateAnimationPrefix", "Separate Animation Prefix", "string", "", "", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Collision + ImportOptionsConfigList.startGroup("Collision"); + ImportOptionsConfigList.addField("GenerateCollisions", "Generate Collisions", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("GenCollisionType", "Generate Collision Type", "list", "", "CollisionMesh", "CollisionMesh,ConvexHull", %optionsObj); + ImportOptionsConfigList.addField("CollisionMeshPrefix", "CollisionMesh Prefix", "string", "", "Col", "", %optionsObj); + ImportOptionsConfigList.addField("GenerateLOSCollisions", "Generate LOS Collisions", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("GenLOSCollisionType", "Generate LOS Collision Type", "list", "", "CollisionMesh", "CollisionMesh,ConvexHull", %optionsObj); + ImportOptionsConfigList.addField("LOSCollisionMeshPrefix", "LOS CollisionMesh Prefix", "string", "", "LOS", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Images + ImportOptionsConfigList.startGroup("Image"); + ImportOptionsConfigList.addField("ImageType", "Image Type", "list", "", "N/A", "N/A,Diffuse,Normal,Specular,Metalness,Roughness,AO,Composite,GUI", %optionsObj); + ImportOptionsConfigList.addField("DiffuseTypeSuffixes", "Diffuse Type Suffixes", "command", "", "_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL", "", %optionsObj); + ImportOptionsConfigList.addField("NormalTypeSuffixes", "Normal Type Suffixes", "command", "", "_NORMAL,_NORM", "", %optionsObj); + + if(EditorSettings.lightingModel $= "Legacy") + { + ImportOptionsConfigList.addField("SpecularTypeSuffixes", "Specular Type Suffixes", "command", "", "_SPECULAR,_SPEC", "", %optionsObj); + } + else + { + ImportOptionsConfigList.addField("MetalnessTypeSuffixes", "Metalness Type Suffixes", "command", "", "_METAL,_MET,_METALNESS,_METALLIC", "", %optionsObj); + ImportOptionsConfigList.addField("RoughnessTypeSuffixes", "Roughness Type Suffixes", "command", "", "_ROUGH,_ROUGHNESS", "", %optionsObj); + ImportOptionsConfigList.addField("SmoothnessTypeSuffixes", "Smoothness Type Suffixes", "command", "", "_SMOOTH,_SMOOTHNESS", "", %optionsObj); + ImportOptionsConfigList.addField("AOTypeSuffixes", "AO Type Suffixes", "command", "", "_AO,_AMBIENT,_AMBIENTOCCLUSION", "", %optionsObj); + ImportOptionsConfigList.addField("CompositeTypeSuffixes", "Composite Type Suffixes", "command", "", "_COMP,_COMPOSITE", "", %optionsObj); + } + + ImportOptionsConfigList.addField("TextureFilteringMode", "Texture Filtering Mode", "list", "", "Bilinear", "None,Bilinear,Trilinear", %optionsObj); + ImportOptionsConfigList.addField("UseMips", "Use Mipmaps", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("IsHDR", "Is HDR", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.addField("Scaling", "Scaling", "float", "", "1.0", "", %optionsObj); + ImportOptionsConfigList.addField("Compressed", "Is Compressed", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("GenerateMaterialOnImport", "Generate Material On Import", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.addField("PopulateMaterialMaps", "Populate Material Maps", "bool", "", "1", "", %optionsObj); + ImportOptionsConfigList.endGroup(); + + //Sounds + ImportOptionsConfigList.startGroup("Sound"); + ImportOptionsConfigList.addField("VolumeAdjust", "Volume Adjustment", "float", "", "1.0", "", %optionsObj); + ImportOptionsConfigList.addField("PitchAdjust", "Pitch Adjustment", "float", "", "1.0", "", %optionsObj); + ImportOptionsConfigList.addField("Compressed", "Is Compressed", "bool", "", "0", "", %optionsObj); + ImportOptionsConfigList.endGroup(); +} + +function ImportAssetConfigEditorWindow::addNewConfig(%this) +{ + ImportAssetConfigEditorWindow.setVisible(1); + ImportAssetConfigEditorWindow.selectWindow(); + + %optionsObj = new ScriptObject(){}; + + ImportAssetWindow.importConfigsList.add(%optionsObj); + + //Initial, blank configuration + %optionsObj.ImportMesh = true; + %optionsObj.DoUpAxisOverride = false; + %optionsObj.UpAxisOverride = "Z_AXIS"; + %optionsObj.DoScaleOverride = false; + %optionsObj.ScaleOverride = 1.0; + %optionsObj.IgnoreNodeScale = false; + %optionsObj.AdjustCenter = false; + %optionsObj.AdjustFloor = false; + %optionsObj.CollapseSubmeshes = false; + %optionsObj.LODType = "TrailingNumber"; + //%optionsObj.TrailingNumber = 2; + %optionsObj.ImportedNodes = ""; + %optionsObj.IgnoreNodes = ""; + %optionsObj.ImportMeshes = ""; + %optionsObj.IgnoreMeshes = ""; + + //Materials + %optionsObj.ImportMaterials = true; + %optionsObj.CreateComposites = true; + %optionsObj.UseDiffuseSuffixOnOriginImg = true; + %optionsObj.UseExistingMaterials = true; + + //Animations + %optionsObj.ImportAnimations = true; + %optionsObj.SeparateAnimations = true; + %optionsObj.SeparateAnimationPrefix = ""; + + //Collision + %optionsObj.GenerateCollisions = true; + %optionsObj.GenCollisionType = "CollisionMesh"; + %optionsObj.CollisionMeshPrefix = "Col"; + %optionsObj.GenerateLOSCollisions = true; + %optionsObj.GenLOSCollisionType = "CollisionMesh"; + %optionsObj.LOSCollisionMeshPrefix = "LOS"; + + //Images + %optionsObj.ImageType = "N/A"; + %optionsObj.DiffuseTypeSuffixes = "_ALBEDO;_DIFFUSE;_ALB;_DIF;_COLOR;_COL;_BASECOLOR;_BASE_COLOR"; + %optionsObj.NormalTypeSuffixes = "_NORMAL;_NORM"; + %optionsObj.SpecularTypeSuffixes = "_SPECULAR;_SPEC"; + %optionsObj.MetalnessTypeSuffixes = "_METAL;_MET;_METALNESS;_METALLIC"; + %optionsObj.RoughnessTypeSuffixes = "_ROUGH;_ROUGHNESS"; + %optionsObj.SmoothnessTypeSuffixes = "_SMOOTH;_SMOOTHNESS"; + %optionsObj.AOTypeSuffixes = "_AO;_AMBIENT;_AMBIENTOCCLUSION"; + %optionsObj.CompositeTypeSuffixes = "_COMP;_COMPOSITE"; + %optionsObj.TextureFilteringMode = "Bilinear"; + %optionsObj.UseMips = true; + %optionsObj.IsHDR = false; + %optionsObj.Scaling = 1.0; + %optionsObj.Compressed = true; + %optionsObj.GenerateMaterialOnImport = true; + %optionsObj.PopulateMaterialMaps = true; + + //Sounds + %optionsObj.VolumeAdjust = 1.0; + %optionsObj.PitchAdjust = 1.0; + %optionsObj.Compressed = false; + + //Hook in the UI + %this.populateConfigList(%optionsObj); +} + +function ImportAssetConfigEditorWindow::editConfig(%this) +{ + ImportAssetConfigEditorWindow.setVisible(1); + ImportAssetConfigEditorWindow.selectWindow(); + + %this.populateConfigList(ImportAssetWindow.activeImportConfig); +} + +function ImportAssetConfigEditorWindow::deleteConfig(%this) +{ + ImportAssetWindow.importConfigsList.erase(ImportAssetWindow.activeImportConfigIndex); + ImportAssetConfigList.setSelected(0); //update it + + ImportAssetConfigEditorWindow.saveAssetOptionsConfig(); +} + +function ImportAssetConfigEditorWindow::saveAssetOptionsConfig(%this) +{ + %xmlDoc = new SimXMLDocument(); + + %xmlDoc.pushNewElement("AssetImportConfigs"); + + for(%i = 0; %i < ImportAssetWindow.importConfigsList.count(); %i++) + { + %configObj = ImportAssetWindow.importConfigsList.getKey(%i); + + %xmlDoc.pushNewElement("Config"); + + if(%configObj.Name $= "") + %configObj.Name = AssetImportConfigName.getText(); + + %xmlDoc.setAttribute("Name", %configObj.Name); + + %xmlDoc.pushNewElement("Mesh"); + %xmlDoc.setAttribute("ImportMesh", %configObj.ImportMesh); + %xmlDoc.setAttribute("DoUpAxisOverride", %configObj.DoUpAxisOverride); + %xmlDoc.setAttribute("UpAxisOverride", %configObj.UpAxisOverride); + %xmlDoc.setAttribute("DoScaleOverride", %configObj.DoScaleOverride); + %xmlDoc.setAttribute("ScaleOverride", %configObj.ScaleOverride); + %xmlDoc.setAttribute("IgnoreNodeScale", %configObj.IgnoreNodeScale); + %xmlDoc.setAttribute("AdjustCenter", %configObj.AdjustCenter); + %xmlDoc.setAttribute("AdjustFloor", %configObj.AdjustFloor); + %xmlDoc.setAttribute("CollapseSubmeshes", %configObj.CollapseSubmeshes); + %xmlDoc.setAttribute("LODType", %configObj.LODType); + %xmlDoc.setAttribute("ImportedNodes", %configObj.ImportedNodes); + %xmlDoc.setAttribute("IgnoreNodes", %configObj.IgnoreNodes); + %xmlDoc.setAttribute("ImportMeshes", %configObj.ImportMeshes); + %xmlDoc.setAttribute("IgnoreMeshes", %configObj.IgnoreMeshes); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Materials"); + %xmlDoc.setAttribute("ImportMaterials", %configObj.ImportMaterials); + %xmlDoc.setAttribute("CreateComposites", %configObj.CreateComposites); + %xmlDoc.setAttribute("UseDiffuseSuffixOnOriginImg", %configObj.UseDiffuseSuffixOnOriginImg); + %xmlDoc.setAttribute("UseExistingMaterials", %configObj.UseExistingMaterials); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Animations"); + %xmlDoc.setAttribute("ImportAnimations", %configObj.ImportAnimations); + %xmlDoc.setAttribute("SeparateAnimations", %configObj.SeparateAnimations); + %xmlDoc.setAttribute("SeparateAnimationPrefix", %configObj.SeparateAnimationPrefix); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Collisions"); + %xmlDoc.setAttribute("GenerateCollisions", %configObj.GenerateCollisions); + %xmlDoc.setAttribute("GenCollisionType", %configObj.GenCollisionType); + %xmlDoc.setAttribute("CollisionMeshPrefix", %configObj.CollisionMeshPrefix); + %xmlDoc.setAttribute("GenerateLOSCollisions", %configObj.GenerateLOSCollisions); + %xmlDoc.setAttribute("GenLOSCollisionType", %configObj.GenLOSCollisionType); + %xmlDoc.setAttribute("LOSCollisionMeshPrefix", %configObj.LOSCollisionMeshPrefix); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Images"); + %xmlDoc.setAttribute("ImageType", %configObj.ImageType); + %xmlDoc.setAttribute("DiffuseTypeSuffixes", %configObj.DiffuseTypeSuffixes); + %xmlDoc.setAttribute("NormalTypeSuffixes", %configObj.NormalTypeSuffixes); + %xmlDoc.setAttribute("SpecularTypeSuffixes", %configObj.SpecularTypeSuffixes); + %xmlDoc.setAttribute("MetalnessTypeSuffixes", %configObj.MetalnessTypeSuffixes); + %xmlDoc.setAttribute("RoughnessTypeSuffixes", %configObj.RoughnessTypeSuffixes); + %xmlDoc.setAttribute("SmoothnessTypeSuffixes", %configObj.SmoothnessTypeSuffixes); + %xmlDoc.setAttribute("AOTypeSuffixes", %configObj.AOTypeSuffixes); + %xmlDoc.setAttribute("CompositeTypeSuffixes", %configObj.CompositeTypeSuffixes); + %xmlDoc.setAttribute("TextureFilteringMode", %configObj.TextureFilteringMode); + %xmlDoc.setAttribute("UseMips", %configObj.UseMips); + %xmlDoc.setAttribute("IsHDR", %configObj.IsHDR); + %xmlDoc.setAttribute("Scaling", %configObj.Scaling); + %xmlDoc.setAttribute("Compressed", %configObj.Compressed); + %xmlDoc.setAttribute("GenerateMaterialOnImport", %configObj.GenerateMaterialOnImport); + %xmlDoc.setAttribute("PopulateMaterialMaps", %configObj.PopulateMaterialMaps); + %xmlDoc.popElement(); + + %xmlDoc.pushNewElement("Sounds"); + %xmlDoc.setAttribute("VolumeAdjust", %configObj.VolumeAdjust); + %xmlDoc.setAttribute("PitchAdjust", %configObj.PitchAdjust); + %xmlDoc.setAttribute("Compressed", %configObj.Compressed); + %xmlDoc.popElement(); + + %xmlDoc.popElement(); + } + + %xmlDoc.popElement(); + + %xmlDoc.saveFile($AssetBrowser::importConfigsFile); + + ImportAssetConfigEditorWindow.setVisible(0); + ImportAssetWindow.reloadImportOptionConfigs(); +} + +function ImportOptionsConfigList::ToggleImportMesh(%this, %fieldName, %newValue, %ownerObject) +{ + %this.setFieldEnabled("DoUpAxisOverride", %newValue); + %this.setFieldEnabled("UpAxisOverride", %newValue); + %this.setFieldEnabled("DoScaleOverride", %newValue); + %this.setFieldEnabled("ScaleOverride", %newValue); + %this.setFieldEnabled("IgnoreNodeScale", %newValue); + %this.setFieldEnabled("AdjustCenter", %newValue); + %this.setFieldEnabled("AdjustFloor", %newValue); + %this.setFieldEnabled("CollapseSubmeshes", %newValue); + %this.setFieldEnabled("LODType", %newValue); + %this.setFieldEnabled("ImportedNodes", %newValue); + %this.setFieldEnabled("IgnoreNodes", %newValue); + %this.setFieldEnabled("ImportMeshes", %newValue); + %this.setFieldEnabled("IgnoreMeshes", %newValue); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.cs new file mode 100644 index 000000000..bc80f8977 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.cs @@ -0,0 +1,371 @@ +function AssetBrowser_editAsset::saveAsset(%this) +{ + %file = AssetDatabase.getAssetFilePath(%this.editedAssetId); + %success = TamlWrite(AssetBrowser_editAsset.editedAsset, %file); + + AssetBrowser.loadFilters(); + + Canvas.popDialog(AssetBrowser_editAsset); +} + +function AssetBrowser::editAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %assetType = %assetDef.getClassName(); + + if(%assetType $= "MaterialAsset") + { + //if(EditorSettings.materialEditMode $= "MaterialEditor") + //{ + %assetDef.materialDefinitionName.reload(); + + EditorGui.setEditor(MaterialEditorPlugin); + + MaterialEditorGui.currentMaterial = %assetDef.materialDefinitionName; + MaterialEditorGui.setActiveMaterial( %assetDef.materialDefinitionName ); + + AssetBrowser.hideDialog(); + /*} + else + { + Canvas.pushDialog(ShaderEditor); + ShaderEditorGraph.loadGraph(%assetDef.shaderGraph); + $ShaderGen::targetShaderFile = filePath(%assetDef.shaderGraph) @"/"@fileBase(%assetDef.shaderGraph); + }*/ + } + else if(%assetType $= "StateMachineAsset") + { + eval("AssetBrowser.tempAsset = new " @ %assetDef.getClassName() @ "();"); + AssetBrowser.tempAsset.assignFieldsFrom(%assetDef); + + SMAssetEditInspector.inspect(AssetBrowser.tempAsset); + AssetBrowser_editAsset.editedAssetId = EditAssetPopup.assetId; + AssetBrowser_editAsset.editedAsset = AssetBrowser.tempAsset; + + //remove some of the groups we don't need: + for(%i=0; %i < SMAssetEditInspector.getCount(); %i++) + { + %caption = SMAssetEditInspector.getObject(%i).caption; + + if(%caption $= "Ungrouped" || %caption $= "Object" || %caption $= "Editing" + || %caption $= "Persistence" || %caption $= "Dynamic Fields") + { + SMAssetEditInspector.remove(SMAssetEditInspector.getObject(%i)); + %i--; + } + } + + Canvas.pushDialog(StateMachineEditor); + StateMachineEditor.loadStateMachineAsset(EditAssetPopup.assetId); + StateMachineEditor-->Window.text = "State Machine Editor ("@EditAssetPopup.assetId@")"; + } + else if(%assetType $= "ComponentAsset") + { + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %scriptFile = %assetDef.scriptFile; + + EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); + } + else if(%assetType $= "GameObjectAsset") + { + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %scriptFile = %assetDef.scriptFilePath; + + EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); + } + else if(%assetType $= "ScriptAsset") + { + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %scriptFile = %assetDef.scriptFilePath; + + EditorOpenFileInTorsion(makeFullPath(%scriptFile), 0); + } + else if(%assetType $= "ShapeAsset") + { + %this.hideDialog(); + ShapeEditorPlugin.openShapeAsset(EditAssetPopup.assetId); + } + else if(%assetType $= "ShapeAnimationAsset") + { + %this.hideDialog(); + ShapeEditorPlugin.openShapeAsset(EditAssetPopup.assetId); + } + else if(%assetType $= "LevelAsset") + { + schedule( 1, 0, "EditorOpenMission", %assetDef.LevelFile); + } + else if(%assetType $= "GUIAsset") + { + if(!isObject(%assetDef.assetName)) + { + exec(%assetDef.GUIFilePath); + exec(%assetDef.mScriptFilePath); + } + + GuiEditContent(%assetDef.assetName); + } +} + +function AssetBrowser::editAssetInfo(%this) +{ + Canvas.pushDialog(AssetBrowser_editAsset); + + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + + eval("AssetBrowser.tempAsset = new " @ %assetDef.getClassName() @ "();"); + AssetBrowser.tempAsset.assignFieldsFrom(%assetDef); + + AssetEditInspector.inspect(AssetBrowser.tempAsset); + AssetBrowser_editAsset.editedAssetId = EditAssetPopup.assetId; + AssetBrowser_editAsset.editedAsset = AssetBrowser.tempAsset; + + //remove some of the groups we don't need: + for(%i=0; %i < AssetEditInspector.getCount(); %i++) + { + %caption = AssetEditInspector.getObject(%i).caption; + + if(%caption $= "Ungrouped" || %caption $= "Object" || %caption $= "Editing" + || %caption $= "Persistence" || %caption $= "Dynamic Fields") + { + AssetEditInspector.remove(AssetEditInspector.getObject(%i)); + %i--; + } + } +} + +//------------------------------------------------------------ + +function AssetBrowser::refreshAsset(%this, %assetId) +{ + if(%assetId $= "") + { + //if we have no passed-in asset ID, we're probably going through the popup menu, so get our edit popup id + %assetId = EditAssetPopup.assetId; + } + + AssetDatabase.refreshAsset(%assetId); + AssetBrowser.refreshPreviews(); +} + +//------------------------------------------------------------ + +function AssetBrowser::renameAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + + %curFirstResponder = AssetBrowser.getFirstResponder(); + + if(%curFirstResponder != 0) + %curFirstResponder.clearFirstResponder(); + + AssetBrowser.selectedAssetPreview-->AssetNameLabel.setActive(true); + AssetBrowser.selectedAssetPreview-->AssetNameLabel.setFirstResponder(); +} + +function AssetNameField::onReturn(%this) +{ + //if the name is different to the asset's original name, rename it! + %newName = %this.getText(); + if(%this.originalAssetName !$= %this.getText()) + { + %moduleName = AssetBrowser.selectedModule; + + //do a rename! + %success = AssetDatabase.renameDeclaredAsset(%moduleName @ ":" @ %this.originalAssetName, %moduleName @ ":" @ %this.getText()); + + if(%success) + { + %newAssetId = %moduleName @ ":" @ %this.getText(); + %assetPath = AssetDatabase.getAssetFilePath(%newAssetId); + + //Rename any associated files as well + %assetDef = AssetDatabase.acquireAsset(%newAssetId); + %assetType = %assetDef.getClassName(); + + //rename the file to match + %path = filePath(%assetPath); + + if(%assetType $= "ComponentAsset") + { + %oldScriptFilePath = %assetDef.scriptFile; + %scriptFilePath = filePath(%assetDef.scriptFile); + %scriptExt = fileExt(%assetDef.scriptFile); + + %newScriptFileName = %scriptFilePath @ "/" @ %newName @ %scriptExt; + %newAssetFile = %path @ "/" @ %this.getText() @ ".asset.taml"; + + %assetDef.componentName = %newName; + %assetDef.scriptFile = %newScriptFileName; + + TamlWrite(%assetDef, %newAssetFile); + fileDelete(%assetPath); + + pathCopy(%oldScriptFilePath, %newScriptFileName); + fileDelete(%oldScriptFilePath); + + //Go through our scriptfile and replace the old namespace with the new + %editedFileContents = ""; + + %file = new FileObject(); + if ( %file.openForRead( %newScriptFileName ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %this.originalAssetName, %newName) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newScriptFileName); + + %file.writeline(%editedFileContents); + + %file.close(); + } + + exec(%newScriptFileName); + } + else if(%assetType $= "StateMachineAsset") + { + %oldScriptFilePath = %assetDef.stateMachineFile; + %scriptFilePath = filePath(%assetDef.stateMachineFile); + %scriptExt = fileExt(%assetDef.stateMachineFile); + + %newScriptFileName = %scriptFilePath @ "/" @ %newName @ %scriptExt; + %newAssetFile = %path @ "/" @ %this.getText() @ ".asset.taml"; + + %assetDef.stateMachineFile = %newScriptFileName; + + TamlWrite(%assetDef, %newAssetFile); + fileDelete(%assetPath); + + pathCopy(%oldScriptFilePath, %newScriptFileName); + fileDelete(%oldScriptFilePath); + } + else if(%assetType $= "GameObjectAsset") + { + %oldScriptFilePath = %assetDef.scriptFilePath; + %scriptFilePath = filePath(%assetDef.scriptFilePath); + %scriptExt = fileExt(%assetDef.scriptFilePath); + + %oldGOFilePath = %assetDef.TAMLFilePath; + + %newScriptFileName = %scriptFilePath @ "/" @ %newName @ %scriptExt; + %newAssetFile = %path @ "/" @ %this.getText() @ ".asset.taml"; + %newGOFile = %path @ "/" @ %this.getText() @ ".taml"; + + %assetDef.gameObjectName = %newName; + %assetDef.scriptFilePath = %newScriptFileName; + %assetDef.TAMLFilePath = %newGOFile; + + TamlWrite(%assetDef, %newAssetFile); + fileDelete(%assetPath); + + pathCopy(%oldScriptFilePath, %newScriptFileName); + fileDelete(%oldScriptFilePath); + + pathCopy(%oldGOFilePath, %newGOFile); + fileDelete(%oldGOFilePath); + + //Go through our scriptfile and replace the old namespace with the new + %editedFileContents = ""; + + %file = new FileObject(); + if ( %file.openForRead( %newScriptFileName ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %this.originalAssetName, %newName) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newScriptFileName); + + %file.writeline(%editedFileContents); + + %file.close(); + } + + exec(%newScriptFileName); + + //Rename in the TAML file as well + %file = new FileObject(); + if ( %file.openForRead( %newGOFile ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %this.originalAssetName, %newName) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newGOFile); + + %file.writeline(%editedFileContents); + + %file.close(); + } + } + } + } + + %this.clearFirstResponder(); + %this.setActive(false); +} + +//------------------------------------------------------------ + +function AssetBrowser::duplicateAsset(%this) +{ + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + + %this.setupCreateNewAsset(%assetDef.getClassName(), AssetBrowser.selectedModule); +} + +function AssetBrowser::deleteAsset(%this) +{ + //Find out what type it is + %assetDef = AssetDatabase.acquireAsset(EditAssetPopup.assetId); + %assetType = %assetDef.getClassName(); + + MessageBoxOKCancel("Warning!", "This will delete the selected asset and the files associated to it, do you wish to continue?", + "AssetBrowser.confirmDeleteAsset();", ""); +} + +function AssetBrowser::confirmDeleteAsset(%this) +{ + %currentSelectedItem = AssetBrowserFilterTree.getSelectedItem(); + %currentItemParent = AssetBrowserFilterTree.getParentItem(%currentSelectedItem); + + AssetDatabase.deleteAsset(EditAssetPopup.assetId, false); + + %this.loadFilters(); + + if(!AssetBrowserFilterTree.selectItem(%currentSelectedItem)) + { + //if it failed, that means we deleted the last item in that category, and we need to do the parent + AssetBrowserFilterTree.selectItem(%currentItemParent); + AssetBrowserFilterTree.expandItem(%currentItemParent); + } +} diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/editModule.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/editModule.cs new file mode 100644 index 000000000..996bec6f0 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/editModule.cs @@ -0,0 +1,127 @@ +// +function AssetBrowser::CreateNewModule(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); + + AssetBrowser_addModuleWindow.callbackFunction = "AssetBrowser.loadFilters();"; +} + +function AssetBrowser_editModule::saveModule(%this) +{ + //Check what special actions we may need to do, such as renames + %moduleDef = ModuleDatabase.findModule(AssetBrowser.selectedModule, 1); + + %oldModuleName = %moduleDef.ModuleID; + + if(%oldModuleName !$= AssetBrowser.tempModule.ModuleID) + { + //rename the script file and script namespaces + %oldScriptFilePath = "data/" @ %oldModuleName @ "/" @ %moduleDef.scriptFile; + %newscriptFilePath = "data/" @ AssetBrowser.tempModule.ModuleID @ "/"; + %scriptExt = fileExt(%moduleDef.scriptFile); + + %newScriptFileName = %newscriptFilePath @ "/" @ AssetBrowser.tempModule.ModuleID @ %scriptExt; + %newScriptFileOldName = %newscriptFilePath @ "/" @ %oldModuleName @ %scriptExt; + + %moduleDef.ModuleId = AssetBrowser.tempModule.ModuleID; + %moduleDef.scriptFile = AssetBrowser.tempModule.ModuleID @ %scriptExt; + + ModuleDatabase.copyModule(%moduleDef, AssetBrowser.tempModule.ModuleID, "data/" @ AssetBrowser.tempModule.ModuleID); + + //Go through our scriptfile and replace the old namespace with the new + %editedFileContents = ""; + + %file = new FileObject(); + if ( %file.openForRead( %newScriptFileOldName ) ) + { + while ( !%file.isEOF() ) + { + %line = %file.readLine(); + %line = trim( %line ); + + %editedFileContents = %editedFileContents @ strreplace(%line, %oldModuleName, AssetBrowser.tempModule.ModuleID) @ "\n"; + } + + %file.close(); + } + + if(%editedFileContents !$= "") + { + %file.openForWrite(%newScriptFileName); + + %file.writeline(%editedFileContents); + + %file.close(); + } + + %success = fileDelete(%newScriptFileOldName); + + ModuleDatabase.unloadExplicit(%oldModuleName); + + %success = fileDelete("data/" @ %oldModuleName); + + ModuleDatabase.loadExplicit(AssetBrowser.tempModule.ModuleID); + } + + //Now, update the module file itself + //%file = ModuleDatabase.getAssetFilePath(%moduleDef.ModuleID); + //%success = TamlWrite(AssetBrowser_editAsset.editedAsset, %file); + + AssetBrowser.loadFilters(); + + Canvas.popDialog(AssetBrowser_editModule); +} + +function AssetBrowser::editModuleInfo(%this) +{ + Canvas.pushDialog(AssetBrowser_editModule); + + %moduleDef = ModuleDatabase.findModule(AssetBrowser.selectedModule, 1); + + AssetBrowser.tempModule = new ModuleDefinition(); + AssetBrowser.tempModule.assignFieldsFrom(%moduleDef); + + ModuleEditInspector.inspect(AssetBrowser.tempModule); + AssetBrowser_editModule.editedModuleId = AssetBrowser.selectedModule; + AssetBrowser_editModule.editedModule = AssetBrowser.tempModule; + + //remove some of the groups we don't need: + for(%i=0; %i < ModuleEditInspector.getCount(); %i++) + { + %caption = ModuleEditInspector.getObject(%i).caption; + + if(%caption $= "BuildId" || %caption $= "type" || %caption $= "Dependencies" || %caption $= "scriptFile" + || %caption $= "AssetTagsManifest" || %caption $= "ScopeSet" || %caption $= "ModulePath" + || %caption $= "ModuleFile" || %caption $= "ModuleFilePath" || %caption $= "ModuleScriptFilePath" ) + { + ModuleEditInspector.remove(ModuleEditInspector.getObject(%i)); + %i--; + } + } +} + +function AssetBrowser::renameModule(%this) +{ + +} + +function AssetBrowser::reloadModule(%this) +{ + ModuleDatabase.unregisterModule(AssetBrowser.SelectedModule, 1); + ModuleDatabase.loadExplicit(AssetBrowser.SelectedModule); +} + +function AssetBrowser::deleteModule(%this) +{ + +} + +function AssetBrowser::RefreshModuleDependencies(%this) +{ + //Iterate through all our modules + + //then, iterate through the module's assets + + //if an asset has a module that isn't us, queue that into the dependencies list +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/fieldTypes.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/fieldTypes.cs new file mode 100644 index 000000000..fe524ce65 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/fieldTypes.cs @@ -0,0 +1,127 @@ +function GuiVariableInspector::onInspectorFieldModified(%this, %targetObj, %fieldName, %index, %oldValue, %newValue) +{ + echo("FIELD CHANGED: " @ %fieldName @ " from " @ %oldValue @ " to " @ %newValue); +} + +function GuiInspectorVariableGroup::onConstructField(%this, %fieldName, %fieldLabel, %fieldTypeName, %fieldDesc, %fieldDefaultVal, %fieldDataVals, %ownerObj) +{ + %makeCommand = %this @ ".build" @ %fieldTypeName @ "Field(\""@ %fieldName @ "\",\"" @ %fieldLabel @ "\",\"" @ %fieldDesc @ "\",\"" @ + %fieldDefaultVal @ "\",\"" @ %fieldDataVals @ "\",\"" @ %ownerObj @"\");"; + eval(%makeCommand); +} + +function GuiInspectorVariableGroup::buildListField(%this, %fieldName, %fieldLabel, %fieldDesc, %fieldDefaultVal, %fieldDataVals, %ownerObj) +{ + %extent = 200; + + %fieldCtrl = %this.createInspectorField(); + + %extent = %this.stack.getExtent(); + + %width = mRound(%extent/2); + %height = 20; + %inset = 10; + + /*%container = new GuiControl() { + canSaveDynamicFields = "0"; + Profile = "EditorContainerProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %extent.x SPC %height; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "100"; + tooltip = %tooltip; + tooltipProfile = "EditorToolTipProfile"; + }; + + %labelControl = new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorFontHLBold"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %inset SPC "0"; + Extent = %width + %inset SPC %height; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "100"; + tooltip = %tooltip; + tooltipProfile = "EditorToolTipProfile"; + text = %fieldLabel; + maxLength = "1024"; + };*/ + + %editControl = new GuiPopUpMenuCtrl() { + class = "guiInspectorListField"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %fieldCtrl.edit.position; + Extent = %fieldCtrl.edit.extent; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = %tooltip; + text = %fieldDefaultVal; + hovertime = "1000"; + ownerObject = %ownerObj; + fieldName = %fieldName; + }; + + //set the field value + if(getSubStr(%this.fieldName, 0, 1) $= "$") + { + if(%fieldName $= "") + %editControl.setText(%fieldName); + } + else + { + //regular variable + %setCommand = %editControl @ ".setText(" @ %ownerObj @ "." @ %fieldName @ ");"; + eval(%setCommand); + } + + %listCount = getTokenCount(%fieldDataVals, ","); + + for(%i=0; %i < %listCount; %i++) + { + %entryText = getToken(%fieldDataVals, ",", %i); + %editControl.add(%entryText); + } + + %fieldCtrl.setCaption(%fieldLabel); + %fieldCtrl.setEditControl(%editControl); + + %this.addInspectorField(%fieldCtrl); +} + +function guiInspectorListField::onSelect( %this, %id, %text ) +{ + if(getSubStr(%this.fieldName, 0, 1) $= "$") + { + //ah, a global var, just do it straight, then + %setCommand = %this.fieldName @ " = \"" @ %text @ "\";"; + } + else + { + //regular variable + %setCommand = %this.ownerObject @ "." @ %this.fieldName @ " = \"" @ %text @ "\";"; + } + eval(%setCommand); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/gameObjectCreator.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/gameObjectCreator.cs new file mode 100644 index 000000000..a2c526251 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/gameObjectCreator.cs @@ -0,0 +1,130 @@ +function GameObjectModuleList::onWake(%this) +{ + %this.refresh(); +} + +function GameObjectModuleList::refresh(%this) +{ + %this.clear(); + + //First, get our list of modules + %moduleList = ModuleDatabase.findModules(); + + %count = getWordCount(%moduleList); + for(%i=0; %i < %count; %i++) + { + %moduleName = getWord(%moduleList, %i); + %this.add(%moduleName.ModuleId, %i); + } +} + +function GameObjectCreatorPkgBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); +} + +function GameObjectCreateBtn::onClick(%this) +{ + %className = GameObjectCreatorName.getText(); + + if(%className $= "") + { + error("Attempted to make a new Game Object with no name!"); + Canvas.popDialog(GameObjectCreator); + return; + } + + //First, find out if this one already exists. If so, we're obviously merely updating it + //also, exec any components that may exist + //find all GameObjectAssets + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "GameObjectAsset")) + return; //if we didn't find ANY, just exit + + %count = %assetQuery.getCount(); + + %createNew = true; + + for(%i=0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); + + if(%gameObjectAsset.gameObjectName $= %className) + { + %createNew = false; + break; + } + } + + %selectedEntity = GameObjectCreator.selectedEntity; + + %selectedEntity.class = %className; + Inspector.inspect(%selectedEntity); + + if(%createNew) + { + //get the selected module data + %moduleName = GameObjectModuleList.getText(); + + %selectedEntity.gameObjectAsset = %moduleName @ ":" @ %className; + + %path = "data/" @ %moduleName @ "/gameObjects/"; + + %file = new FileObject(); + + if(%file.openForWrite(%path @ "\\" @ %className @ ".cs")) + { + %file.writeline("function " @ %className @ "::onAdd(%this)\n{\n\n}\n"); + %file.writeline("function " @ %className @ "::onRemove(%this)\n{\n\n}\n"); + + //todo, pre-write any event functions of interest + + %file.close(); + } + + //set up the paths + %tamlPath = %path @ %className @ ".taml"; + %scriptPath = %path @ %className @ ".cs"; + saveGameObject(%className, %tamlPath, %scriptPath); + + %asset = new GameObjectAsset() + { + AssetName = %className; + VersionId = 1; + gameObjectName=%className; + TAMLFilePath = %tamlPath; + scriptFilePath = %scriptPath; + }; + %assetPath = %path @ %className @ ".asset.taml"; + + //now, add the script file and a ref to the taml into our SGO manifest so we can readily spawn it later. + TamlWrite(%selectedEntity, %tamlpath); + TamlWrite(%asset, %assetPath); + + GameObjectCreator.selectedEntity = ""; + + Canvas.popDialog(GameObjectCreator); + + //Load it + %moduleDef = ModuleDatabase.findModule(%moduleName,1); + AssetDatabase.addDeclaredAsset(%moduleDef, %assetPath); + } + else + { + %moduleDef = AssetDatabase.getAssetModule(%assetId); + %moduleName = %moduleDef.ModuleId; + %path = "data/" @ %moduleName @ "/gameObjects/"; + + %selectedEntity.gameObjectAsset = %moduleName @ ":" @ %className; + + %tamlPath = %path @ %className @ ".taml"; + TamlWrite(%selectedEntity, %tamlpath); + + GameObjectCreator.selectedEntity = ""; + + Canvas.popDialog(GameObjectCreator); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.cs new file mode 100644 index 000000000..ee351a192 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/newAsset.cs @@ -0,0 +1,663 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +function CreateAssetButton::onClick(%this) +{ + AddNewAssetPopup.showPopup(Canvas); +} + +function AssetBrowser_newAsset::onWake(%this) +{ + NewAssetModuleList.refresh(); + //NewComponentParentClass.setText("Component"); +} + +function AssetBrowser_newAssetWindow::onClose(%this) +{ + NewAssetPropertiesInspector.clearFields(); + Canvas.popDialog(AssetBrowser_newAsset); +} + +function NewAssetTypeList::onWake(%this) +{ + %this.refresh(); +} + +function NewAssetTypeList::refresh(%this) +{ + %this.clear(); + + //TODO: make this more automated + //%this.add("GameObject", 0); + %this.add("Component", 0); + %this.add("Image", 1); + %this.add("Material", 2); + %this.add("Shape", 3); + %this.add("Sound", 4); + %this.add("State Machine", 5); +} + +function NewAssetTypeList::onSelected(%this) +{ + %assetType = %this.getText(); + + if(%assetType $= "Component") + { + NewComponentAssetSettings.hidden = false; + } +} + +function NewAssetModuleBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); +} + +function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName) +{ + Canvas.pushDialog(AssetBrowser_newAsset); + + AssetBrowser_newAssetWindow.text = "New" SPC %assetType SPC "Asset"; + + NewAssetPropertiesInspector.clear(); + + NewAssetModuleList.setText(%moduleName); + + //get rid of the old one if we had one. + if(isObject(%this.newAssetSettings)) + %this.newAssetSettings.delete(); + + %this.newAssetSettings = new ScriptObject(); + + %this.newAssetSettings.assetType = %assetType; + %this.newAssetSettings.moduleName = %moduleName; + + %shortAssetTypeName = strreplace(%assetType, "Asset", ""); + + NewAssetPropertiesInspector.startGroup("General"); + NewAssetPropertiesInspector.addField("assetName", "New Asset Name", "String", "Name of the new asset", "New" @ %shortAssetTypeName, "", %this.newAssetSettings); + //NewAssetPropertiesInspector.addField("AssetType", "New Asset Type", "List", "Type of the new asset", %assetType, "Component,Image,Material,Shape,Sound,State Machine", %newAssetSettings); + + NewAssetPropertiesInspector.addField("friendlyName", "Friendly Name", "String", "Human-readable name of new asset", "", "", %this.newAssetSettings); + + NewAssetPropertiesInspector.addField("description", "Description", "Command", "Description of the new asset", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + + if(%assetType $= "ComponentAsset") + { + NewAssetPropertiesInspector.startGroup("Components"); + NewAssetPropertiesInspector.addField("parentClass", "New Asset Parent Class", "String", "Name of the new asset's parent class", "Component", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("componentGroup", "Component Group", "String", "Name of the group of components this component asset belongs to", "", "", %this.newAssetSettings); + //NewAssetPropertiesInspector.addField("componentName", "Component Name", "String", "Name of the new component", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + } + else if(%assetType $= "LevelAsset") + { + NewAssetPropertiesInspector.startGroup("Level"); + NewAssetPropertiesInspector.addField("levelPreviewImage", "LevePreviewImage", "Image", "Preview Image for the level", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + } + else if(%assetType $= "ScriptAsset") + { + NewAssetPropertiesInspector.startGroup("Script"); + NewAssetPropertiesInspector.addField("isServerScript", "Is Server Script", "bool", "Is this script used on the server?", "1", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + } + /*else if(%assetType $= "ShapeAnimationAsset") + { + NewAssetPropertiesInspector.startGroup("Animation"); + NewAssetPropertiesInspector.addField("sourceFile", "Source File", "filename", "Source file this animation will pull from", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("animationName", "Animation Name", "string", "Name of the animation clip when used in a shape", "", "", %this.newAssetSettings); + + NewAssetPropertiesInspector.addField("startFrame", "Starting Frame", "int", "Source file this animation will pull from", "", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("endFrame", "Ending Frame", "int", "Source file this animation will pull from", "", "", %this.newAssetSettings); + + NewAssetPropertiesInspector.addField("padRotation", "Pad Rotations", "bool", "Source file this animation will pull from", "0", "", %this.newAssetSettings); + NewAssetPropertiesInspector.addField("padTransforms", "Pad Transforms", "bool", "Source file this animation will pull from", "0", "", %this.newAssetSettings); + NewAssetPropertiesInspector.endGroup(); + }*/ + + return; + + if(%moduleName $= "") + { + Canvas.pushDialog(AssetBrowser_selectModule); + } + else + { + AssetBrowser.SelectedModule = %moduleName; + + if(%assetType $= "MaterialAsset") + { + createNewMaterialAsset("NewMaterial", %moduleName); + } + else if(%assetType $= "StateMachineAsset") + { + createNewStateMachineAsset("NewStateMachine", %moduleName); + } + else if(%assetType $= "ScriptAsset") + { + createNewScriptAsset("NewScriptAsset", %moduleName); + } + } +} + +//We do a quick validation that mandatory fields are filled in before passing along to the asset-type specific function +function CreateNewAsset() +{ + %assetName = AssetBrowser.newAssetSettings.assetName; + + if(%assetName $= "") + { + MessageBoxOK( "Error", "Attempted to make a new asset with no name!"); + return; + } + + //get the selected module data + %moduleName = NewAssetModuleList.getText(); + + if(%moduleName $= "") + { + MessageBoxOK( "Error", "Attempted to make a new asset with no module!"); + return; + } + + AssetBrowser.newAssetSettings.moduleName = %moduleName; + + %assetType = AssetBrowser.newAssetSettings.assetType; + if(%assetType $= "") + { + MessageBoxOK( "Error", "Attempted to make a new asset with no type!"); + return; + } + + if(%assetType $= "ComponentAsset") + { + //Canvas.popDialog(AssetBrowser_newComponentAsset); + //AssetBrowser_newComponentAsset-->AssetBrowserModuleList.setText(AssetBrowser.selectedModule); + %assetFilePath = createNewComponentAsset(%assetName, %path); + } + else if(%assetType $= "MaterialAsset") + { + %assetFilePath = createNewMaterialAsset(); + } + else if(%assetType $= "StateMachineAsset") + { + %assetFilePath = createNewStateMachineAsset(); + } + else if(%assetType $= "GUIAsset") + { + %assetFilePath = createNewGUIAsset(); + } + else if(%assetType $= "LevelAsset") + { + %assetFilePath = createNewLevelAsset(); + } + else if(%assetType $= "ScriptAsset") + { + %assetFilePath = createNewScriptAsset(); + } + else if(%assetType $= "ShapeAnimationAsset") + { + %assetFilePath = createShapeAnimationAsset(); + } + + Canvas.popDialog(AssetBrowser_newAsset); + + //Load it + %moduleDef = ModuleDatabase.findModule(%moduleName,1); + AssetDatabase.addDeclaredAsset(%moduleDef, %assetFilePath); + + AssetBrowser.loadFilters(); +} + +function createNewComponentAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/components/" @ %assetName @ ".asset.taml"; + %scriptPath = %modulePath @ "/components/" @ %assetName @ ".cs"; + + %asset = new ComponentAsset() + { + AssetName = %assetName; + versionId = 1; + componentName = %assetName; + componentClass = AssetBrowser.newAssetSettings.parentClass; + friendlyName = AssetBrowser.newAssetSettings.friendlyName; + componentType = AssetBrowser.newAssetSettings.componentGroup; + description = AssetBrowser.newAssetSettings.description; + scriptFile = %scriptPath; + }; + + TamlWrite(%asset, %tamlpath); + + %file = new FileObject(); + + if(%file.openForWrite(%scriptPath)) + { + //TODO: enable ability to auto-embed a header for copyright or whatnot + %file.writeline("//onAdd is called when the component is created and then added to it's owner entity.\n"); + %file.writeline("//You would also add any script-defined component fields via addComponentField().\n"); + %file.writeline("function " @ %assetName @ "::onAdd(%this)\n{\n\n}\n"); + %file.writeline("//onAdd is called when the component is removed and deleted from it's owner entity."); + %file.writeline("function " @ %assetName @ "::onRemove(%this)\n{\n\n}\n"); + %file.writeline("//onClientConnect is called any time a new client connects to the server."); + %file.writeline("function " @ %assetName @ "::onClientConnect(%this, %client)\n{\n\n}\n"); + %file.writeline("//onClientDisconnect is called any time a client disconnects from the server."); + %file.writeline("function " @ %assetName @ "::onClientDisonnect(%this, %client)\n{\n\n}\n"); + %file.writeline("//update is called when the component does an update tick.\n"); + %file.writeline("function " @ %assetName @ "::Update(%this)\n{\n\n}\n"); + + %file.close(); + } + + Canvas.popDialog(AssetBrowser_newComponentAsset); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Components"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewMaterialAsset() +{ + %assetName = AssetBrowser.newAssetSettings.assetName; + + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %tamlpath = %modulePath @ "/materials/" @ %assetName @ ".asset.taml"; + %sgfPath = %modulePath @ "/materials/" @ %assetName @ ".sgf"; + + %asset = new MaterialAsset() + { + AssetName = %assetName; + versionId = 1; + shaderData = ""; + shaderGraph = %sgfPath; + }; + + TamlWrite(%asset, %tamlpath); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Materials"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewScriptAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/scripts/" @ %assetName @ ".asset.taml"; + %scriptPath = %modulePath @ "/scripts/" @ %assetName @ ".cs"; + + %asset = new ScriptAsset() + { + AssetName = %assetName; + versionId = 1; + scriptFilePath = %scriptPath; + }; + + TamlWrite(%asset, %tamlpath); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Scripts"); + + AssetBrowserFilterTree.onSelect(%smItem); + + %file = new FileObject(); + + if(%file.openForWrite(%scriptPath)) + { + %file.close(); + } + + return %tamlpath; +} + +function createNewStateMachineAsset() +{ + %assetName = AssetBrowser.newAssetSettings.assetName; + + %assetQuery = new AssetQuery(); + + %matchingAssetCount = AssetDatabase.findAssetName(%assetQuery, %assetName); + + %i=1; + while(%matchingAssetCount > 0) + { + %newAssetName = %assetName @ %i; + %i++; + + %matchingAssetCount = AssetDatabase.findAssetName(%assetQuery, %newAssetName); + } + + %assetName = %newAssetName; + + %assetQuery.delete(); + + %tamlpath = "data/" @ %moduleName @ "/stateMachines/" @ %assetName @ ".asset.taml"; + %smFilePath = "data/" @ %moduleName @ "/stateMachines/" @ %assetName @ ".xml"; + + %asset = new StateMachineAsset() + { + AssetName = %assetName; + versionId = 1; + stateMachineFile = %smFilePath; + }; + + %xmlDoc = new SimXMLDocument(); + %xmlDoc.saveFile(%smFilePath); + %xmlDoc.delete(); + + TamlWrite(%asset, %tamlpath); + + //Now write our XML file + %xmlFile = new FileObject(); + %xmlFile.openForWrite(%smFilePath); + %xmlFile.writeLine(""); + %xmlFile.writeLine(""); + %xmlFile.close(); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "StateMachines"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewGUIAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/GUIs/" @ %assetName @ ".asset.taml"; + %guipath = %modulePath @ "/GUIs/" @ %assetName @ ".gui"; + %scriptPath = %modulePath @ "/GUIs/" @ %assetName @ ".cs"; + + %asset = new GUIAsset() + { + AssetName = %assetName; + versionId = 1; + scriptFilePath = %scriptPath; + guiFilePath = %guipath; + }; + + TamlWrite(%asset, %tamlpath); + + %file = new FileObject(); + + if(%file.openForWrite(%guipath)) + { + %file.writeline("//--- OBJECT WRITE BEGIN ---"); + %file.writeline("%guiContent = new GuiControl(" @ %assetName @ ") {"); + %file.writeline(" position = \"0 0\";"); + %file.writeline(" extent = \"100 100\";"); + %file.writeline("};"); + %file.writeline("//--- OBJECT WRITE END ---"); + + %file.close(); + } + + if(%file.openForWrite(%scriptPath)) + { + %file.writeline("function " @ %assetName @ "::onWake(%this)\n{\n\n}\n"); + %file.writeline("function " @ %assetName @ "::onSleep(%this)\n{\n\n}\n"); + + %file.close(); + } + + //load the gui + exec(%guipath); + exec(%scriptPath); + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "GUIs"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewLevelAsset() +{ + %moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/levels/" @ %assetName @ ".asset.taml"; + %levelPath = %modulePath @ "/levels/" @ %assetName @ ".mis"; + + %asset = new LevelAsset() + { + AssetName = %assetName; + versionId = 1; + LevelFile = %levelPath; + LevelDescription = AssetBrowser.newAssetSettings.levelDescription; + PreviewImage = AssetBrowser.newAssetSettings.levelPreviewImage; + }; + + TamlWrite(%asset, %tamlpath); + + if(!pathCopy("tools/levels/BlankRoom.mis", %levelPath, false)) + { + echo("Unable to copy template level file!"); + } + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Levels"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath; +} + +function createNewShapeAnimationAsset() +{ + %dlg = new OpenFileDialog() + { + Filters = "Animation Files(*.dae, *.cached.dts)|*.dae;*.cached.dts"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + forceRelativePath = false; + //MultipleFiles = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = %dlg.FileName; + } + + %dlg.delete(); + + if ( !%ret ) + return; + + /*%moduleName = AssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = AssetBrowser.newAssetSettings.assetName; + + %tamlpath = %modulePath @ "/levels/" @ %assetName @ ".asset.taml"; + %levelPath = %modulePath @ "/levels/" @ %assetName @ ".mis"; + + %asset = new ShapeAnimationAsset() + { + AssetName = %assetName; + versionId = 1; + LevelFile = %levelPath; + LevelDescription = AssetBrowser.newAssetSettings.levelDescription; + PreviewImage = AssetBrowser.newAssetSettings.levelPreviewImage; + }; + + TamlWrite(%asset, %tamlpath); + + if(!pathCopy("tools/levels/BlankRoom.mis", %levelPath, false)) + { + echo("Unable to copy template level file!"); + } + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + AssetBrowser.loadFilters(); + + %treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName); + %smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "Levels"); + + AssetBrowserFilterTree.onSelect(%smItem); + + return %tamlpath;*/ +} + +function ParentComponentList::onWake(%this) +{ + %this.refresh(); +} + +function ParentComponentList::refresh(%this) +{ + %this.clear(); + + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "ComponentAsset")) + return; //if we didn't find ANY, just exit + + // Find all the types. + %count = %assetQuery.getCount(); + + /*%categories = ""; + for (%i = 0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentName = %componentAsset.componentName; + + if(%componentName $= "") + %componentName = %componentAsset.componentClass; + + %this.add(%componentName, %i); + }*/ + + %categories = ""; + for (%i = 0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentClass = %componentAsset.componentClass; + if (!isInList(%componentClass, %categories)) + %categories = %categories TAB %componentClass; + } + + %categories = trim(%categories); + + %index = 0; + %categoryCount = getFieldCount(%categories); + for (%i = 0; %i < %categoryCount; %i++) + { + %category = getField(%categories, %i); + %this.addCategory(%category); + + for (%j = 0; %j < %count; %j++) + { + %assetId = %assetQuery.getAsset(%j); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentName = %componentAsset.componentName; + %componentClass = %componentAsset.componentClass; + + if (%componentClass $= %category) + { + if(%componentName !$= "") + %this.add(" "@%componentName, %i); + } + } + } +} + +//---------------------------------------------------------- +// Game Object creation +//---------------------------------------------------------- +function EWorldEditor::createGameObject( %this ) +{ + GameObjectCreatorObjectName.text = ""; + + %activeSelection = %this.getActiveSelection(); + if( %activeSelection.getCount() == 0 ) + return; + + GameObjectCreator.selectedEntity = %activeSelection.getObject( 0 ); + + Canvas.pushDialog(GameObjectCreator); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs new file mode 100644 index 000000000..12f422485 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/popupMenus.cs @@ -0,0 +1,154 @@ +function AssetBrowser::buildPopupMenus(%this) +{ + if( !isObject( AddNewModulePopup ) ) + { + new PopupMenu( AddNewModulePopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + isPopup = true; + + item[ 0 ] = "Create New Module" TAB "" TAB "AssetBrowser.CreateNewModule();"; + item[ 1 ] = "Refresh Module Dependencies" TAB "" TAB "AssetBrowser.RefreshModuleDependencies();"; + }; + } + + if( !isObject( EditAssetPopup ) ) + { + new PopupMenu( EditAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Edit Asset" TAB "" TAB "AssetBrowser.editAsset();"; + item[ 1 ] = "Rename Asset" TAB "" TAB "AssetBrowser.renameAsset();"; + item[ 2 ] = "Refresh Asset" TAB "" TAB "AssetBrowser.refreshAsset();"; + item[ 3 ] = "Asset Properties" TAB "" TAB "AssetBrowser.editAssetInfo();"; + item[ 4 ] = "-"; + Item[ 5 ] = "Duplicate Asset" TAB "" TAB "AssetBrowser.duplicateAsset();"; + item[ 6 ] = "-"; + item[ 7 ] = "Re-Import Asset" TAB "" TAB "AssetBrowser.reImportAsset();"; + item[ 8 ] = "-"; + item[ 9 ] = "Delete Asset" TAB "" TAB "AssetBrowser.deleteAsset();"; + + jumpFileName = ""; + jumpLineNumber = ""; + }; + } + + if( !isObject( AddNewComponentAssetPopup ) ) + { + new PopupMenu( AddNewComponentAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + //item[ 0 ] = "Create Component" TAB "" TAB "Canvas.pushDialog(AssetBrowser_newComponentAsset); AssetBrowser_newComponentAsset-->NewComponentPackageList.setText(AssetBrowser.selectedModule);"; + item[ 0 ] = "Component" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ComponentAsset\", AssetBrowser.selectedModule);"; + + //list other common component types here to shortcut the creation process + }; + } + + if( !isObject( AddNewScriptAssetPopup ) ) + { + %this.AddNewScriptAssetPopup = new PopupMenu( AddNewScriptAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Create Component" TAB AddNewComponentAssetPopup; + item[ 1 ] = "Create Script" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ScriptAsset\", AssetBrowser.selectedModule);"; + item[ 2 ] = "Create State Machine" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"StateMachineAsset\", AssetBrowser.selectedModule);"; + //item[ 3 ] = "-"; + //item[ 3 ] = "Create Game Object" TAB "" TAB "AssetBrowser.createNewGameObjectAsset(\"NewGameObject\", AssetBrowser.selectedModule);"; + }; + //%this.AddNewScriptAssetPopup.insertSubMenu(0, "Create Component", AddNewComponentAssetPopup); + } + + if( !isObject( AddNewArtAssetPopup ) ) + { + %this.AddNewArtAssetPopup = new PopupMenu( AddNewArtAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Create Material" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"MaterialAsset\", AssetBrowser.selectedModule);";//"createNewMaterialAsset(\"NewMaterial\", AssetBrowser.selectedModule);"; + item[ 1 ] = "Create Image" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ImageAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewImageAsset(\"NewImage\", AssetBrowser.selectedModule);"; + item[ 2 ] = "-"; + item[ 3 ] = "Create Shape" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"Shape\", AssetBrowser.selectedModule);"; + item[ 4 ] = "Create Shape Animation" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ShapeAnimationAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewShapeAnimationAsset(\"NewShapeAnimation\", AssetBrowser.selectedModule);"; + item[ 5 ] = "-"; + item[ 6 ] = "Create GUI" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"GUIAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewGUIAsset(\"NewGUI\", AssetBrowser.selectedModule);"; + item[ 7 ] = "-"; + item[ 8 ] = "Create Post Effect" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"PostEffectAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewPostEffectAsset(\"NewPostEffect\", AssetBrowser.selectedModule);"; + item[ 9 ] = "-"; + item[ 10 ] = "Create Sound" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"SoundAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewSoundAsset(\"NewSound\", AssetBrowser.selectedModule);"; + item[ 11 ] = "-"; + item[ 12 ] = "Create Particle Effect" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ParticleEffectAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewParticleEffectAsset(\"NewParticleEffect\", AssetBrowser.selectedModule);"; + }; + } + + if( !isObject( AddNewAssetPopup ) ) + { + %this.AddNewAssetPopup = new PopupMenu( AddNewAssetPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + + item[0] = "Create Code Asset" TAB AddNewScriptAssetPopup; + item[1] = "-"; + item[2] = "Create Art Asset" TAB AddNewArtAssetPopup; + item[3] = "-"; + item[4] = "Create Level" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule);";//"AssetBrowser.createNewLevelAsset(\"NewLevel\", AssetBrowser.selectedModule);"; + }; + } + + if( !isObject( EditModulePopup ) ) + { + new PopupMenu( EditModulePopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + //isPopup = true; + + item[ 0 ] = "Create New Asset" TAB AddNewAssetPopup; + item[ 1 ] = "Reload Module" TAB "" TAB "AssetBrowser.reloadModule();"; + Item[ 2 ] = "-"; + Item[ 3 ] = "Edit Module" TAB "" TAB "AssetBrowser.editModuleInfo();"; + Item[ 4 ] = "-"; + Item[ 5 ] = "Duplicate Module" TAB "" TAB "AssetBrowser.copyModule();"; + Item[ 6 ] = "-"; + Item[ 7 ] = "Delete Module" TAB "" TAB "AssetBrowser.deleteModule();"; + }; + } + + //Some assets are not yet ready/implemented, so disable their creation here + AddNewArtAssetPopup.enableItem(3, false); //shape + AddNewArtAssetPopup.enableItem(4, false); //shape animation + AddNewArtAssetPopup.enableItem(8, false); //post effect + AddNewArtAssetPopup.enableItem(10, false); //sound asset + AddNewArtAssetPopup.enableItem(12, false); //particle effect + + AddNewScriptAssetPopup.enableItem(2, false); //state machine +} + +function AddNewScriptAssetPopupMenu::onSelectItem(%this, %id, %text) +{ + return true; +} +function AddNewScriptAssetPopupMenu::setupDefaultState(%this) +{ + // Setup camera speed gui's. Both menu and editorgui + %this.setupGuiControls(); + + Parent::setupDefaultState(%this); +} + +function AddNewScriptAssetPopupMenu::setupGuiControls(%this) +{ +} diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/selectModule.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectModule.cs new file mode 100644 index 000000000..3c2c7c1ea --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectModule.cs @@ -0,0 +1,17 @@ +function AssetBrowser_selectModule::onWake(%this) +{ + AssetBrowser_SelectModuleWindow-->ModuleList.refresh(); +} + +function SelectModule_NewAssetModuleBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddModule); + AssetBrowser_addModuleWindow.selectWindow(); + + AssetBrowser_AddModule.callback = "AssetBrowser_selectModule.newModuleAdded();"; +} + +function AssetBrowser_selectModule::newModuleAdded(%this) +{ + AssetBrowser_SelectModuleWindow-->ModuleList.refresh(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/selectPackage.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectPackage.cs new file mode 100644 index 000000000..42f66ddb1 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/selectPackage.cs @@ -0,0 +1,17 @@ +function AssetBrowser_selectPackage::onWake(%this) +{ + AssetBrowser_SelectPackageWindow-->packageList.refresh(); +} + +function SelectPackage_NewAssetPackageBtn::onClick(%this) +{ + Canvas.pushDialog(AssetBrowser_AddPackage); + AssetBrowser_addPackageWindow.selectWindow(); + + AssetBrowser_AddPackage.callback = "AssetBrowser_selectPackage.newPackageAdded();"; +} + +function AssetBrowser_selectPackage::newPackageAdded(%this) +{ + AssetBrowser_SelectPackageWindow-->packageList.refresh(); +} \ No newline at end of file