From 5526bf6f06b67e277816f788ab4b182efa4b43ea Mon Sep 17 00:00:00 2001 From: Yoshman29 Date: Sun, 23 Oct 2022 02:17:49 +0200 Subject: [PATCH] windows xp luna theme (temporary) --- assets/images/desktop/ui.xml | 13 ++- assets/images/desktop/ui/caption.png | Bin 2600 -> 2580 bytes assets/images/desktop/ui/captionButtons.png | Bin 8592 -> 8690 bytes assets/images/desktop/ui/captionInactive.png | Bin 1896 -> 1903 bytes buildnumber.txt | 2 +- source/funkin/desktop/DesktopMain.hx | 5 + source/funkin/desktop/theme/Theme.hx | 107 ++++++++++++++++++ source/funkin/desktop/windows/Window.hx | 30 +++-- .../desktop/windows/WindowCaptionButton.hx | 65 +++++++---- 9 files changed, 184 insertions(+), 38 deletions(-) create mode 100644 source/funkin/desktop/theme/Theme.hx diff --git a/assets/images/desktop/ui.xml b/assets/images/desktop/ui.xml index 66b00bf6..4b2aac16 100644 --- a/assets/images/desktop/ui.xml +++ b/assets/images/desktop/ui.xml @@ -1,5 +1,8 @@ - - - - - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/assets/images/desktop/ui/caption.png b/assets/images/desktop/ui/caption.png index c981a60431543700bf4503b80e579921e0629c33..01cff8f638c90e88e1159ed02901b56fb182ebc1 100644 GIT binary patch delta 2549 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 LNkvXXu0mjfIX1}O delta 2570 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 diff --git a/assets/images/desktop/ui/captionButtons.png b/assets/images/desktop/ui/captionButtons.png index faadfa29c13983e6b794b2ed1a1b9258f9df3884..c0e1caefb73963a71ab8db680144abd5e67cd0a9 100644 GIT binary patch literal 8690 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

g3apoA1U;u+5@tA!x&SeFzbG%QnrX^Jl=0 zb}}9A0qvGA<;^Ben5iXPB}c}h=xE|C*a`SxWu7Lc#X)1=<9@n6e9QfNx|1rfFG zw{hdVff{+CU+82JgP_{Ryvsryf}GPT=%?dk+G0}5h{T%&riAeLFDy>B12J#sHzscGWSUqWdvz#7Mju_hHjrw>C(~RVeMVw$meu5)XRLwV`JR@I|KU-d;8vC- zXO6K|RPW)AzkZvV;gvW^;bIZO#Zh)~;ON~wbepr#Im|0E={DOi!NAVl?tq^@r%!Oo zhbA}X$b9>2(l5?!!XCS!wgtx@wsDeYqBckdy%CkqbWXdTgQ4h3!XSU$wXF1MCi!qq zSY;)8*_CWQ8jH0HZMX?wrB6)LO%4jqT?oVh zl1iV~elm9hEEu;zeirr;d^sXBv*SH`_(Af#O4i8#e*Pr50~a>-?9${)Dx-qOYz&h2 z*K;+q;39~&uGMi7M$%!7((vyzH33O;^QVD)WNn-S+yarDH_i&nYH1JkN$j&-%*+a# zzU+xpG-{i^*{^JaHU5~Uyl=;a{rj-8hHh1Wjv4~|K1I@v4;xV-x%auW`0H$1HOZi* z--Wk$q&Zi<5hgH{6~<#>jvqcw3Y+i`8kyC0lxlkqWByk{Z`+)(*6wC*emA*c zzz_fVO=Rj27j7e3)56gf;7^4u??IOxUfK{ycB|iouPz>`gc=J>RTu9QfFAJw z(ZR&xmI94`Ye#y=|4Z2N&mUUTuYzPe_D0oR>19v%eHG>f&$o(SCI!I2>n{%ha9`o; zrXrFTX}F`KqrF4de0R5`^VwGa`F=5=-BYQtwZi7<+f)wPbmS)FPxUsfS?|j(FV7Er zZ$Fy92}+F{?CnhM8ZKS_6T%`AVxD%%)0!4SNFymg0 z)wlZu_!ov6Et-wb1?+Rehs=Vp1OJci0F2vP3S0k6R1W_){GVLN_J0*p-W%J~8!J^B zTexxsNRi-o=7yp?U+0lmJd<%lb&$OuEmvr~u{uX_U=?6o zr*rp0JKFSBsw~3qBCYRQh{M{-YqE3&Z6!qi#s1Ie4vKe)cKg$@FP}J&)RlFV8WgOf F{s-;A2Z;ax literal 8592 zcmZX4WmFqXur}7>PN8_Q0L8tydvJFtS}0m1Xp2j+V8Nw$ky5NckRmSug1Z+8?!o$$8?tjD*W*7A-U%FQ-N_AHmHg4FeAF_Ko0pgs>K4v@G&!EOIUAYof7bBJKc64| zD&kg^h!^->lm}g)ZbUirN~4c+HJoCtDoprz!RtPM{nq%#7sJ3uI7pUS7A$Q$k462p z7JWVD0qi_DVBMG4xjpt;j+o3Y@YhAHFXY)x=7DPqk`Z|;AAAaJBQpH_hO>*%mknzv zraLi$rGf!-RaoQpEkRX0ef`VOT{ z7~APw$i`TgEe8<~5&p;kbYyewrAOO;1W3>kn%eNJhTMHA%G&O(&KAe7C9o)LowNo? z@*cRvz6<_96E#v;Run_ZMu;QX;w*C`;5$y(Ym{W#Bk|8IlGN%!4NNb>6C*pY>(MGW zJ-u{#lU~Ni`Ie9d+fiM1@NTz}n7`x-je&agD_LXJAuCP52?^i)$T!gLUr*QvH=-23 zzZcUnsMbe|7c6EeGn{%~7o!+n_r^s;*v}WC0K1H=-MH#{4AyACh`KD=?!kdS5gGd` zFfnNtnNP7Jg0?ED_8O6UDfs$OceR?xUh)Si!m8os;={c7h{BO?CLz~CD$-YWPR`Z0 zV#b|fjEV^3b6~P^2IjZdGQd}IZ<5MrXi}w&cCJ6(7k&DE^BV}JKl4C&Y)j2>TD)<} zz6qavi1;O;wa2HB#K|jd+AL_6Ut2BO2_deE-WfMMv#%;yuO*6!S)N!-jGLO_jPgC1m*-4HuV^Wb=ika7DxooHIdlzj zMdoIs0N#i54)DXjEYyp`YIS7=h47-cx5<-f{s@pN%ET>B!V`Mlp|;96vfxJ;z?K{0 ze}T~Yvr<6T;M!yTr~MiusY0XY&2rbfyFBzw%=lY;VQ+a;xoZO}<>yZKKJ17JVi4}q z&kdMWKplODSbL$%Bn>rDlFH|J)PEr7Px!fSTny(_#W-|h|) zzCF>316ePZsvOMXQYEnEe8>qJ*a%hVY6(45?AcrrL|HKmp=6RO>H0;kKBc48<6c+Y zdpdG&i)e3T<#MJniQ{*_g4=9G-~mQfjloH5?jze;Pk7E$TKXgx|Af;z-!Rc9-ELT9 z{n=l){s9puxBqeS`Kbf~Ts0V1j1sy!KHP<+`ek36raA5HHjE#Yj(zOIyiO^wN0PBX zzZ@MI_`Gdy)dx#ERuQh?e(}=G{!UW%1$Y<~G0Ua$P4sonBs*mW0NSLv?^j>QzysYf z^ZZwH-mgf?m${M}%R!GL7}x48OCFHAoobU|8A`BB+ddUjjt#upZKfn2tsZ`8iZ&U4 zS}*ZbkCdKlQ$+ulzzgDuauaVr4S=T!4ds6*w&lTvdFKheVMgsOnGosZ5qfBwl^|T!qZq*s&%XW$6EOfkbeokHE>Q9_O{HDon~`FOlG@vZ zXH4s=WH}o%a}b^P6(6!IoHtypocBeN@~uHqBG(l<`QR&BcE#sbVXA!B1hiO2QYm9_ z^7{NH=OuEnF*8~wiDUCG0Z*i7%U5&j1N%_w4e-lmPw{bn@;mEE|ChiG`_ryNzRa?SL0&og}OQ7#7S64suV|D zHsgBqzt$9v*V1{6gXv)#f;u?%J!s-6GFEE`9BFe34^N{HjlTl>!oNZ)v2RF@{# z2s-eBG@PV>Wp=ZA`5KiKm$4V{k#DW{xoCfoi*mz5EajQ(hJK9wC7?R&G4-Toc`0TX zZW0fH~=9y@am(o||dx-Ua3?5y-(T^W%`_%Cvb*OmdNga5O952wMu4zc!?a zK5*7D4qb>`H__zt`ad6Z>p6WQYk>LQ9{+;PY&EE7_9jKHAUbs^qLD^3*rlxk7fgXEZR)%_&{d0 z2R>AIdML=i43*Lv&Bzaa6I9F3#5Kgrn~YbGsUG8?^9k`1J4_dc+5LBx4`LQjP0HXufAW z_%^XfJ*Haz(6@%2Lh-pkC!xP(XJa!oy3bKBQ8hHzp9;TcKhyr(JDIU?)GYhhssuoR zw<@gJZl6-eKv&a!Pk=aXI6rq5mjCoNBScxJmxA{Q({jcW$ojR6*j`4)LWav3AC&F+ zY9J~gKxltU z&E>OD6@jbb9`#PlUpE3EJWmmHjzXmqmnVx>azRlQz%fWg0>PAh!`r{60E&Z6ef323 z_5;1rT)9YK4xN(wr$99hY=L?NYtN2`tC5-N0w(icDu$LbxakBn~1`%xn|0urNRAsK+Pg)v3sm@|{q7UTE(5U9$}Ih5MmN z-Y0KQmHwy28vo%K<6kT#A1+q3ey{{5?N9@PNooZP+GxxEI(Vzz=N7Kl6#puFu(` zgY~syiU?wb#bbOOoT|ED{CUCf(467r)(f(|m`Ihr>_k8yz8vETwE1S)v@ZV0@ADKV zwDePVQ^OlEgsJwNI0Bb~Yrgch$b!mAA<+r9TV3_yh*BKfus;k!6kea)s$$lYcP??t zQ_I%Swb-4VZ{7RvVI+vUKb1ZnERaVkE|hTBZoYjWrim*u`QAh*~wZCu)~5h;*@X)$1%` z#(CO*eW3}xbXYSX;Lso5rG=t2=1y~-Q%}Z7@p8aE@UI6k7GyE(pKcJDHc^rIC9;Ju;vsoxnuDQ&%^U>5t`7Ny8G(lRi;GdjXfP1Y(WjERn-PG|9V z$>s*k_J%WJDCqQL{##roX6zVCFO8^H?Ya;ZQT(b1L?YVN56^p88)s!W^`q^Dy-fR6 zoJ8=TVmIMPJhn&@e57XhJj0~^nqrk5%$Ng|GG3QuPdRDOWD$LQM*9Lo_Y!D5MX7GR zhaq@OmC>ez(9I1+5Q~hu$}U@8(r8P5g$}oa8{UJw%E|VN5;ZYU4Wt<*ACh3($Vi){ zg;5lsWQo_vf;3s+?+*_01pZpk+oBnM7q3zt?~%6|^#|2|-*BFeM@}JREkAtsyjjgX za3Toq&ehbnw<~^4m-X>e}U(G zcUX8+i#0claVD5$9z*1!mIP;UFva2n*<9WKoY?6&VZPP;*z1&DlTw&{!+lSpF;!9+ z;XLKcj%oiZ+IKMSCk$;*bzXh65=!^FAJLt|4-mn0KxmcAZ~hiaX<_f0qbVO)S4j4q z>TZijo%r%5nkyaa722<$kQ6&)eM>2_1OHZB(-6vP z$_NlpXtGm@Y7T37YujwI`TL{!@TPcENpLTP3~gjvc-H6f(0+i^Sf_zwL11;_MAAdV zV|0)QaZG$CTQL^4ZE9Zt6>E+#_CcBU7Kv)ItVw!ld3@jrc}-ed3(m&OJ?6iuBd;WL zHNKWXvq_Olj{ea=Rt9ZLfXfx03M&IiC-X?qN*e$cpR94VqA>=_QI9cnC~Br1cez62 zTv{|B=iRX+?w*hLO3u4ooBI!nsCw=kjAlQuzZABIP^ze)K9mh>mR{<@qvDl9UfJ4jFNk-gyMFd^sXtVd_BqacUic8IJ;f(|*Gv$afAWTM zv1$-h*$Z_SX>1Xho3}7Eu-^TgR9vz=oT}VrpEnXm8vEro7k?<7VQsUm{hUr(H^X4Q zRC1QgDi%F`&lYupi^m628f_;EwK^byx9(Bh5N5>9FjIr5b_65xiq5??I2&(7qXQ^9 z3IN9l*jW9V)6%8LTZt3;dEEv4>`a=~uki!LB~je@tEM(+QZZ zwW&YLdcyD?Zd!i+ZxJtg3;pI{L@Ptbr#i<{56nJ4Lx0Cu0Kk;vY!Nc>AkN`-CH8!& z+t$O3nqk`Imz1(+=OTi3Y2Vv_+oHt@Z~-I=bWnvZu`1dlHyYQdxYwLt!*y27ekf~F zA=v}$u#sS1$A*XHBcjv0{=p21OqPrWKzE3{a)zgGkX7rIJ734frDDl7FT^!yjAmNQy zDhS)ydUhjgaPoI2t6NPc^OidimOFR7>RFN>Jz1U8`c7=|WRAX3%25!n2R@S7fQD9e zv@Bw8ZUWOX@r&K4zA`A!a} z$kDx~bYu`KanLeoK+*(hF@W&$>B%TxukPbEH^YmjtSiK%(^)$n+pVkGDwzi!$RJbX zXvO1p0iyo}wi0d9M!K|6oXHmx5wfl(9`>xJI0~FFq*n!r!1k>&(lX|KUYd9mksU2`98Vi`m49@WN$dnVpk ztUSZ=A+N+qKyKImn}pyX5+G&I#^696!7c8&4z!+;efuLi(i4wG^z#beNW4cGF!Y%N zH}XG=h?%YIGh5Ts=dC&(l0GgQAbCRh8|A0(SuzK7y4obwyHz1C)%D*ZrsO2p<4K*> z`$5*fWC))}>C~=5$v6=MKz~q>wN${?p9v*0W!Q9G9uYpx;fw{hMG7mcN~Pt_&jDp7 zenSVjAAu9O(V6Jwi!b!Nq>R7; zIEi!uxnPkZ{0d=qMDoR@dZz47#CuxQC1jghi#+A zCB!Agrf}MPH;!4k3nsp-*_Gf7_DP;NcOK6B6|EeBZ|j*SZOA6b~ve zgbWUh@uq#>dVk_%ZFiDyU^BxjcVs&0VYmT>0vZXM^_S>_Tnc?MF2w)-I`kEuR+42E z_)V6-TS6wzngc-*H}KO*ZXo_?5tO zr)e>_n-*forZ9w6oS!jo5uL<@w9;QVXn9*q8i%QMF;NvISD&NDg}O=MK1r<3B}O~O zSJl5+l zK_T=H#~JM`w{y}dVZYJs89)PRKUkV9EU+Bdk51PgM#$Ki{FE?=E9$x}=B~mrw&c96 z?^XlRYr{0dpf|E8tCWBH@R}~(+TbqmmJDfVj&?`6v#{AUDy)P(8f_~9w&fCiN3_kV02YiRY{{ue1$a4t zf=1|eeQGGxcDAdDq!ub%+#422ZBDkdaI<~!YADz4gtLGtpFQsBF#$UXM$h(+ETr zes{?u>po+c-9bhq?~s^)-@T&6fy>MLu;)B+ZM623d_fu)lrA0d(LI}lY3;pwS)}hY zl!5$FXT%IC!VP?hyMyr>F;MKUjbv5sDpGXk3+*@_2ZwP=d~+jvF$~vfto?RKQ(q2+ zdy5%B9|PeU6_eN&HeLbsl73^rL%3In*JeGp_#a46sBAtwWUrmLaWtc~o|FYB04S*p z0rY^r2=WLs#EBngIIZKPW|SrFqb7ip72vP@D6E%1MpN~h8!e+6CBL+*XKO5RBw4j) zE({*F6EH7698N3|HWZ4mN|8}Ky(^1nrdJB}^{4KtsLymwHd8VG6idf-VUl>Qs4u^a zbr|v9jdYVR-X1;62_kX6Qq4m0@{F-AsSt8i^nyfk7B!QCRxQrt`i=w#G%BZRxztSK z?q)lGsH(H!0+6PP|JiI#eY$D}uwsYlRV+1@{%3h1oaI!uJolrLzmDxn)Xek>%uZ0n=Br{WLD0X=uO{k0);|3$Sa(4hb~L4@(I35rQ^YQS!9 zv`fg56=EVh&}Bi!XZxBC>khK%h2Yo^nqehO6(o}$SRWFTG~$isX-q+Ybk_s$$Ii_1?(iLD4! zUSXWo$%6OQJF)8Pw~&@MviGMPNssWwU-O*1zJp8c>SayRUU(rTU=?+)`qnu8^w6Cs z452}Vla5ZzFC>DL+g#r7e~5;SOVA)=Y-@8=5%d+nIFt4VO2t(Tgnet^X*l1;!Eq>n z>iD%Zop-j)8o>#UcRYzG~1m)MmA3q7hYFx3bHJ8BxeDW!-@1U^*_RAD%?9>#Je zyefq*Fz*O%D)H;IMA<<^#wyA6)S4gu!~dFn{qQG5N!yM}_#;sf68#{HY29+-X2$5nYuH&v#13uH=YXto$FL&xD9N z&f3J$87FcT9{=k!4eUW6Nt%1^GZnmV6O38);)_p@b!mHNgqXj!r#v>2akc&TQL00& zJ9$GV^f?}@osTePh->Eto;Wv0~A2;cftZC&yJ#@q>pVL*_GdebLx){AxaUI1L>Y@0z zBzLkg!b5vWIWn__4AtVht7UVf3-`X`JN+!n(^@o_^N81U zUTKy8Dpk~2)0Jjn>czD(t5)$|Dm?w2GQTw#E_}X)?i=Dp^_rY+okI8UM*05qdWN{< z&_>zBID*(vX^5AQs7&h#rWNASbGV=YL|!bZ%T-hh+o5{PB$=B(wfn+`eb&1q_o0B< zP{T-ibtvOg{;V`1MLsxsR#c;R`N9Xk^R_5M@UZ8r6!VUWMyB`5K>E$~^R!Ih?TY+W z7Atv4^~!yFjT8b=vK|pq>B6w~q)vp2oSdVh2b$pCQcE{|+diYZl6U{3JA3^2H7Q|O}$yUkmF&i#>V89|BrtBAJi{)pyA>|{6895 zlp8&`om0-u|4oj33cc4S=e_q!dfA1*18#XTUR?3g+Q=ZSSV}Hyx3>EzKuhv2if@O4(|?-Ie#HZL_t(|+U=V^j~z7-z-PSs-n&2KlAJCHQ38>mprZgGJ_8LB zHAplR6ck8Ed<7(GBpMnd8Y(0j_zox%q6QKokjRD0k-K}j_ulT>jJ@{m*lX{;OLGL) zm&@+kKlaRT#xrBT1eH<{wl_ccNnPHZf!LUI?oD%Hjv_~Ugnu(NS)T2A|6Misj4G?n zwE}8c<)VPYhfDbOvzIY^204f~-u*#cy|n|^uV#>6n8IY5!_3~xrZs>Kt^B0!$Fcw+ zI{l`Vk;BTwTF5{as*yvVr`m#ktCck8s}f=HXaRrhuVDYTBlzyi*BZea5O2MATU~kK z671~>$hRku34Z~TNd^;CfYu8(>3o_YV1{P~5Cfv$9|EH)H3+cJQ5+-(M8jCkS1>;~ zg}Zm=@XZ&mVgo{Z!gDX}!tRcOY%3>41qh`3q_75JlqMJ%UE^S$q^VM#`5kA`p{AAW zj92(mr36Vb&~(u-_UG{PuM7D8>(|kMc;~|()s-t7Fn_y95JamalJBGS|18f87;{d~ zhy)CoQdD7MT?K2*byfGHv?oaI8RkWI(;oTr?FZAp)!)2db!CzTdB>wAJa|~ZSD(Lv z`1bp^)ul@rY+v34nADviO^F5uDeZu0Pti>bc|;XXXh8zC!Z<-W5Crt^n?JHuh!jPM zMlmHMoqvl)!6a5ah8wrCP~3P0c}KB=>a>8r4i;cQT-&9Xur(zB*ntrPVPM#)6DlvA zWvYl!&{~o!=|CX$=`7oLk940oNT{(jR!?{#_X?}Ltm=zWRwlSqMd^c(TN9X0L=uEK z=U##Sd<+4o&?_1SzLibCh`vYAyWDyl0(7&ZXMc77y6*uFf&-zwL6r+Qcmx*2P7Z=n zrJz6w8wrm<0+88z%rnp_h)j^c?KuRj(A?v5TDv@CT?^KI$+o8mgj%ZrSnN5QS{jd7 zmBt$eKx72MLcm%`2LeG@Kp}nhAp!!W4iznkKE=)if{i=mIUL3s9w7__N|qFqln27q z4}Ts6E=UZ7a#n9aB!LA=D4nWVwy7Zn@xU{HhFsb4n2<`f<8T<{73Jv(13@t&pG*N} zGzByW?fN{=fw01;zzQ)CO4wr}pvF9<6Kg^k?vw+L6km$FEWwC^xW2amVn#KD zE~6)P4A2?G1Td{U_CQF0;BKN7MD95%cz?ioz?vYu`%b|D5aGbpvWSDoW<+3vB7hE( zS*?G-$!7J<jF<-O=)d<3ZxOw9OfygL@l9G06xGCWlVd&xn{YVQ%uoNY$c!1J?Q1&d>Lw@#I z4F!VLq*rD~#%pE@FV-UQ!@!}wbbr9~LEPM-V40aJYHT?losw868B zx4!PJ4FYRL*9U12^1MW*y`t@(k3Gnt?siF)*(8xy2LKN4IoO!D-^FV&{>nGK@h9#X~UV;}sM~k9`o?7EKN75jcew zf?jCRQ4B!fM(YG>sh}rZc7LXc1|+$1O8HPi5Gm!AN-pf=s)BMs!Se5U0>n%-F{0VB zw-CZTh^ABJHdtdy!eDDQU+T{Kfp`O_VGe;YQ{!<3%i|Nc|NC(qga%-g&cz^v7?2Rk zx-i1{(gERX)d3O>z+ncnFd7ht$HN{GPKzNJGO(Cz1njXK7m`6pf`5p7A(aHt;}sf2 zL0O|XNW=)2F^uATi%tWn_n7>6A?s^h3wM>ae+oSy zbk@LGTPq0C)@;n=b}?g>#cX(rbkdd01iiIG!pa>m5yc$Bu-HnhdlJ@ah)``oITSO(YEpmft0}<$J^~@E71sDJgnoqNtIxy+ja!Gv5>^Lu zf6?`S266Y^q1~8y_M$1T>s@LEpMLb>;Gj=)`}mVzj3H$~AdXJp-kp>41}RD#L7Wu? ztk&pl3hO=hZ*9FGp71}OJ*_PYLWwp1@zH;*c_4P5Id5^!w>2P69vq&xEa%?-0q^Og U$HnxamH+?%07*qoM6N<$g8VdFp#T5? delta 1823 zcmV+)2jKYc4(JY$Ie!{SL_t(|+U=Xaj~q1=$KUhJ?%oe_Nlv+hD1k^cbQB=O-#~*z z4Ty$dFCv`oR1qjip zH*Jg@HYQd=2C`61KlFL3EaM+Y`uyfPcv(g9$1?tAb5BpJoV{;h6!%fav#!z^FO#o*6LaoSqR0 z7&2w3!p6G_))?!mu19GlNUaR>qPuC2{Q35Sso&af-mkiSk_D;ba0!nd7x4AxuOhzl z;ca#4QU=?XHvuMfWk^G!fk8$)AX+K9h#^H(;eZy@p|&%wqZ|kV`uEKr*&0NKqC{hu z5|YkEV}D>0t8T-!TUjWsy@J$Hte`qA;LrU97!cQXDJE=92>^Cr#6TDrcIbr0OXry? z(kW;?$&GX%km_`vZPX*(XATl-Y>n3wD&(rL#>=X{C}m}WOI4IU2)Q+Z=|m(!m~*ZQ z^v7ceK!vJk82DZ`^&3>wmri90UhKt3j0u*gpgdVkZYdQ>CCl z2^$GTAOXniJ*EtF1|sW7AbSo0D>V1`nAVbqtn0zLF4@);flyl&0E<0mrA$Ngn^(Kkx!-oGa3RK zgqD5|z8ZApF%Y&hD)2%KgcA0c2&gfobYe{i!<}-#k>pEp$r6kxi0fB2K+GtI&}sCf zjsbcGF#${)k3A3)Ah=AlfykAkf(M)e)_(-y-FF5KfCw9|mPH&yHX{NX6ajRQ%xc5Y zO_4UO;1JNJ*IvStDiIhRAlzU!WYz*vB~twm2v52w@heZ4K8PFFw#_Voo1}y(wh%<1 zhR8~@1`$bZ6Vqp`ldgX*ez++%REQT(^nFLx9!wl#P$VA?9Ey$^Nf0v~ENwv4Ab+&? zg@vNiZXuh-x<>aTHBe8FO{W4Nl&q5-lB&<>@6tf2XO`|%=mpIHN~cW=#Dl?r=rxFr z6UBVdCR8_XTp$n`%^YN;RfJQ5TYI1z9`qwE6u~01tm5NR147xeN)7qhXEhWE7ExYy z8ELN(2+vU>!^Xg&x^$fILEPM-7=MwO7-6!=tW|;r;Ec~O3q%DArh3ic8^xzeRrLic`%GECrI&(n+EQ-~?^P;ArJkixP_CQy&CwB4nGni4hKhSy$;uEP8SX zufwdb+~W!Fqg%12;56}7vGYhW6~>^1;USpv$qI_2Cq9U5i-v|(1Wuuapw}046ax^r z(>j4#D(KtP3x|mYB)M@)`F~JC5Gmu8O0H+*s)BMs!Sb(p0>n%-F{0V2wh+RlcT=fy z`-(9mVX!oN4s~VyK)i<2Fo(dHq4A`G45O9 z>Hvub;BW@BFd7gC$HR&Uhs6*K8F)-K9qjQO?<9ke1QGcjCJCZP6@MB;L9<4&pNJ7| z#xRESohc2Z-dgeFg{-f2J=`@u^f)iZ=;nSrK1AX1XI zYt4Q{ZgY5REM~()q%&RFnV>g!NO-veCSsUF7$#fE{@9{7Z#@utts%B2AalE(0J{_y zZYgfPhS(;QLop-FCP($hzMKO5ZFqz*S6JgK0QwP z_irt|AfEC+o;|B23POoB{}tAMtau=HpF8jFoNsABoIE->@4lRS`5TP#gr^+fk8c0~ N002ovPDHLkV1jL(Ot}C6 diff --git a/buildnumber.txt b/buildnumber.txt index 50ae8807..c7105757 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -714 \ No newline at end of file +732 \ No newline at end of file diff --git a/source/funkin/desktop/DesktopMain.hx b/source/funkin/desktop/DesktopMain.hx index 1b1fbac0..32b5342b 100644 --- a/source/funkin/desktop/DesktopMain.hx +++ b/source/funkin/desktop/DesktopMain.hx @@ -13,6 +13,7 @@ import flixel.FlxCamera; import flixel.math.FlxPoint; import funkin.desktop.editors.HelloWorld; import funkin.desktop.windows.*; +import funkin.desktop.theme.Theme; class DesktopMain extends MusicBeatState { public var oldScaleMode:BaseScaleMode; @@ -25,8 +26,12 @@ class DesktopMain extends MusicBeatState { public var mouseInput:MouseInput = new MouseInput(); + public static var theme:Theme = null; + public override function create() { super.create(); + + theme = Theme.loadFromAssets(Paths.getPath('images/desktop/ui.xml', TEXT, null)); instance = this; FlxG.mouse.useSystemCursor = FlxG.mouse.visible = true; diff --git a/source/funkin/desktop/theme/Theme.hx b/source/funkin/desktop/theme/Theme.hx new file mode 100644 index 00000000..db41c401 --- /dev/null +++ b/source/funkin/desktop/theme/Theme.hx @@ -0,0 +1,107 @@ +package funkin.desktop.theme; + +import flixel.util.FlxDestroyUtil.IFlxDestroyable; +import flixel.util.FlxColor; +import flixel.math.FlxPoint; +import haxe.xml.Access; +import openfl.Assets; + +class Theme { + public static function loadFromAssets(path:String) { + return load(Assets.getText(path)); + } + + public static function loadFromPath(path:String) { + #if sys + return load(sys.io.File.getContent(path)); + #else + return null; + #end + } + + public static function load(content:String):Theme { + return new Theme(content); + } + + public var captionActive:ThemeData = new ThemeData(); + public var captionInactive:ThemeData = new ThemeData(); + public var captionButtons:ThemeData = new ThemeData(); + + public function new(content:String) { + try { + var access = new Access(Xml.parse(content).firstElement()); + var prefix = ''; + if (access.has.folder) prefix = access.att.folder.trim(); + for(element in access.elements) { + var name:String = element.name.trim(); + trace(name); + if (!Type.getInstanceFields(Theme).contains(name)) continue; + var field = Reflect.field(this, name); + if (!(field is ThemeData)) continue; + var data = cast(field, ThemeData); + + if (element.has.path) data.sprite = '$prefix${element.att.path.trim()}'; + if (element.has.textColor) data.textColor = element.att.textColor.getColorFromDynamic(); + if (element.has.left) data.left = Std.parseFloat(element.att.left).getDefault(0); + if (element.has.right) data.right = Std.parseFloat(element.att.right).getDefault(0); + if (element.has.top) data.top = Std.parseFloat(element.att.top).getDefault(0); + if (element.has.bottom) data.bottom = Std.parseFloat(element.att.bottom).getDefault(0); + if (element.has.size) { + var split = element.att.size.split(","); + data.size.set( + Std.parseFloat(split[0]).getDefault(data.size.x), + Std.parseFloat(split[1]).getDefault(data.size.y)); + } + if (element.has.margin) { + var split = element.att.margin.split(","); + data.margin.set( + Std.parseFloat(split[0]).getDefault(data.margin.x), + Std.parseFloat(split[1]).getDefault(data.margin.y)); + } + if (element.has.offset) { + var split = element.att.offset.split(","); + data.offset.set( + Std.parseFloat(split[0]).getDefault(data.offset.x), + Std.parseFloat(split[1]).getDefault(data.offset.y)); + } + + } + } catch(e) { + // TODO: logs system + trace(e.details()); + } + } +} + +class ThemeData implements IFlxDestroyable { + public var sprite:String = ""; + + public var textColor:FlxColor = FlxColor.WHITE; + + public var left:Float = 4; + public var bottom:Float = 4; + public var top:Float = 4; + public var right:Float = 4; + + public var margin:FlxPoint = FlxPoint.get(0, 0); + public var size:FlxPoint = FlxPoint.get(20, 20); + public var offset:FlxPoint = FlxPoint.get(5, 5); + + + public function new() {} + + public function destroy() { + if (margin != null) { + margin.put(); + margin = null; + } + if (size != null) { + size.put(); + size = null; + } + if (offset != null) { + offset.put(); + offset = null; + } + } +} \ No newline at end of file diff --git a/source/funkin/desktop/windows/Window.hx b/source/funkin/desktop/windows/Window.hx index 4db01ca0..78860997 100644 --- a/source/funkin/desktop/windows/Window.hx +++ b/source/funkin/desktop/windows/Window.hx @@ -55,19 +55,26 @@ class Window extends FlxTypedGroup { } public function new(content:WindowContent) { super(); - windowFrame = new FlxUI9SliceSprite(0, 0, Paths.image('desktop/windowFrame'), new Rectangle(10, 10), [3, 3, 6, 6]); + windowFrame = new FlxUI9SliceSprite(0, 0, + Paths.image(DesktopMain.theme.captionActive.sprite), + new Rectangle(10, 10), [ + Std.int(DesktopMain.theme.captionActive.left), + Std.int(DesktopMain.theme.captionActive.top), + Std.int(DesktopMain.theme.captionActive.right), + Std.int(DesktopMain.theme.captionActive.bottom) + ]); add(windowFrame); caption = new FlxUIText(24, 4, 0, content.title); captionButtons = new FlxTypedSpriteGroup(); for(i in 0...3) { var btn = new WindowCaptionButton(this, i); - btn.x = (i+1) * -18; + btn.x = (i+1) * -(DesktopMain.theme.captionButtons.size.x + DesktopMain.theme.captionButtons.margin.x); captionButtons.add(btn); } add(caption); - dragHitbox = new WindowDragHitbox(4, 4, 4, 18); + dragHitbox = new WindowDragHitbox(DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.top); dragHitbox.parent = this; add(dragHitbox); @@ -158,12 +165,17 @@ class Window extends FlxTypedGroup { content.winY = windowCaptionCamera.y = y; @:privateAccess content.__noParentUpdate = false; for(e in windowCameras) { - e.camera.x = x + 4; - e.camera.y = y + 23; + e.camera.x = x + Std.int(DesktopMain.theme.captionActive.left); + e.camera.y = y + Std.int(DesktopMain.theme.captionActive.top); } } public override function update(elapsed:Float) { + if (__closing) { + DesktopMain.instance.windows.remove(this, true); + destroy(); + return; + } var i = members.length; var shouldCancel = DesktopMain.instance.mouseInput.overlapsRect(this, new Rectangle(0, 0, windowCaptionCamera.width, windowCaptionCamera.height), windowCaptionCamera); @@ -184,14 +196,12 @@ class Window extends FlxTypedGroup { public function close() { __closing = true; - DesktopMain.instance.windows.remove(this, true); - destroy(); } public function updateWindowFrame() { - windowFrame.resize(windowWidth + 4 + 4, windowHeight + 23 + 4); - windowCaptionCamera.setSize(windowWidth + 4 + 4, windowHeight + 23 + 4); - captionButtons.setPosition(windowWidth + 4, 4); + windowFrame.resize(windowWidth + Std.int(DesktopMain.theme.captionActive.left * 2), windowHeight + Std.int(DesktopMain.theme.captionActive.top) + Std.int(DesktopMain.theme.captionActive.left)); + windowCaptionCamera.setSize(windowWidth + Std.int(DesktopMain.theme.captionActive.left * 2), windowHeight + Std.int(DesktopMain.theme.captionActive.top) + Std.int(DesktopMain.theme.captionActive.left)); + captionButtons.setPosition(windowWidth + Std.int((DesktopMain.theme.captionActive.left * 2) - DesktopMain.theme.captionButtons.offset.x), Std.int(DesktopMain.theme.captionButtons.offset.y)); for(e in windowCameras) { e.camera.setSize(windowWidth, windowHeight); if (e.resizeScroll) { diff --git a/source/funkin/desktop/windows/WindowCaptionButton.hx b/source/funkin/desktop/windows/WindowCaptionButton.hx index af78f15f..1ac3627a 100644 --- a/source/funkin/desktop/windows/WindowCaptionButton.hx +++ b/source/funkin/desktop/windows/WindowCaptionButton.hx @@ -1,38 +1,59 @@ package funkin.desktop.windows; -import flixel.addons.ui.FlxUIButton; import flixel.FlxSprite; -class WindowCaptionButton extends FlxUIButton { +class WindowCaptionButton extends FlxSprite { public var icon:FlxSprite; + public var window:Window; public function new(window:Window, i:Int) { - super(0, 0, "", function() { - switch(i) { - case 0: - window.close(); - } - }); + // super(0, 0, "", function() { + // switch(i) { + // case 0: + // window.close(); + // } + // }); + super(0, 0); + this.window = window; ID = i; - resize(18, 18); - color = (i > 0) ? 0xFF8888FF : 0xFFFF0000; - icon = new FlxSprite(0, 0).loadGraphic(Paths.image('desktop/captionButtons'), true, 18, 18); - icon.animation.add("button", [switch(i) { - case 0: 2; - case 1: 1; - case 2: 0; - default: i; - }]); - icon.animation.play("button"); + loadGraphic(Paths.image(DesktopMain.theme.captionButtons.sprite), true, Std.int(DesktopMain.theme.captionButtons.size.x), Std.int(DesktopMain.theme.captionButtons.size.y)); + animation.add("button", [for(l in 0...6) i+(l*3)], 0, true); + animation.play("button"); + + // resize(18, 18); + // color = (i > 0) ? 0xFF8888FF : 0xFFFF0000; } public override function draw() { super.draw(); + } - icon.setPosition(x, y); - icon.cameras = this.cameras; - icon.draw(); - icon.scrollFactor.set(scrollFactor.x, scrollFactor.y); + public override function update(elapsed:Float) { + if (animation.curAnim == null) { + super.update(elapsed); + return; + } + var mouseInput = DesktopMain.instance.mouseInput; + if (DesktopMain.instance.mouseInput.overlaps(this, camera)) { + if (mouseInput.justReleased) { + switch(ID) { + case 0: + window.close(); + } + mouseInput.cancel(); + return; + } + if (mouseInput.pressed || mouseInput.justPressed) { + animation.curAnim.curFrame = 2; + } else { + animation.curAnim.curFrame = 1; + } + mouseInput.cancel(); // prevents controls behind this one from updating input + } else + animation.curAnim.curFrame = 0; + if (!window.focused) animation.curAnim.curFrame += 3; + + super.update(elapsed); } } \ No newline at end of file