From f54ec1d9635d2600667986ab60b0314115059bd1 Mon Sep 17 00:00:00 2001 From: nmwei <254060001@qq.com> Date: Thu, 14 Dec 2023 17:20:04 +0800 Subject: [PATCH 1/8] =?UTF-8?q?REPORT-106829=20FineOne=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/images/emptydata/emptydata.png | Bin 21918 -> 6522 bytes .../design/images/emptydata/emptydata_en.png | Bin 21918 -> 6522 bytes .../design/images/emptydata/emptydata_zh.png | Bin 25842 -> 9150 bytes .../images/emptydata/emptydata_zh_TW.png | Bin 18659 -> 8916 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata.png b/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata.png index 46597ea7a146532843bfce15eadefb1f7ab12263..ddb244479c3deba6883e40f7cdebf798a0c64f87 100644 GIT binary patch literal 6522 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 diff --git a/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata_en.png b/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata_en.png index 46597ea7a146532843bfce15eadefb1f7ab12263..ddb244479c3deba6883e40f7cdebf798a0c64f87 100644 GIT binary patch literal 6522 zcmds5X;f2LwhpENk)l!xh$4eZF(@dd%mfHBh{_~E2ALHUL^2ni5@Kp@GB)%~ifS6Bb&_x`-~ver%R-RtbVzw_;H=bUrn zF4|a#?UCLC006|!pEH9300LY5YjC#^-*V%8OEdpR%Apn4=`1eZykdb+SZxjfD zT9^Q^{W4Vk!{2<*Sf2p^DpEvut_T7E2SMk}&Rhx?pc6oe?oLSM6;flcft>B$Q#G)( zvR%3X*M!$?J4KeB{q({Z;4tyVTJ=Ssxc1Lc;zt*hiiR$fxF1V)shGHMEazA0fRynv+&N5dWN&4uyLjRNz9{VB%Y(6ux^1`)=P5!DraVDOm*t#zW$ zOcY(U_fZk#_N>McKt{E+@hG`{Ok+>Pz_!sQBX`kFmJ*GzXEZMpZIP#5Tkze|pnaT8 zpQ+TFG>%pL@nkbfdp3Q%lH%NQ`h~#fSewj55`?tNs5rj%t$!JpbN89}TPqW}1#oeK z(L?u4T>QGaRXYNhS}X}bk~>+12>2y@a0eV4AHJ^c$?TjZp=K%yfzm_IgxMGH47Wpf zUzmp`1tC&RyMf5O$#`|AjrCfSC6j>tBz)5h9wdTwXvMy&bmbhK^LvIkB?5E66( z<2@Uh%mZ?A$;*+;tD76G7E+Cjm6eM-6JX*Xfdw7Q8f!7u-_nzKYxX@2-Y4{m`aC6K zV7UQIT*qcxKY>y6(>hUKHiS;SLfi0vs$Y(P!_D0g*Y6ua4(++qd+KZKjW58)o_vTzF%|^?vilF#Q|y z8Um2nnFJkt8GFu?;VD^hK)N@=4wOY-o>?LuCeg+rIn-AQ$MKVOyA;U}-buG=AlXs0h zYgao#W#um7@=0>%6$o8jwr2Ldmm&E1w9~n$Bj)vWhyiq#w}9mvMbO$qLxd4r4MPmI zR9Bu(tB+I%8X=W-p$quZ(uvQVkk8DGIQsg?5ztx^#ZfY4?VVP3OzyW2#HdH#2W-&4 zoWg2BEF5GfDt%MVz%==SZyE~hgB@?(k3Urwo?61!mCsT|m(tmj@9$MH3Y!e#oh2#7 z{XL6}ZN}s}Z&&IWzLF?$%G|D1Pj1HvUWrPAP8RHpXGb^(MnaL$St!}x1Zzp+aar6* zvJ-KK@Oa~#Lh8-s^s?dp#1qV&wR`X_(Vjp4r9rkw66nq^*{rbErkSs=4 zr^08A>kUB12bu~VRZ7@mef+#if2g8oVeYASGkvQ6(RVYJZYW5aCiaMl?ai z)85?e6bX@VJb8pSY$%S*RrxrZ<IT16e(c8H^2Tid+|gB1Q+7j0=MY~-X6b}CWafux@#P$Xwo`JI1@-e zI*QtE;l7ak)qdh=I7OlFU9w<(spg?B2K&vY zb(l5BTkyd>7@DO&P52}@zmNHug1turqw3W#s`ElDV=c*%xl1ks9?HWUJBLBlm>7a% zq^GbiYv22RQPg};;0lysB8C#%+sA;%RcgnaZp?o@nZ_+L|O`{WE1WP#0!6Z;>J^<~6sE`F7V2pzK#? zXX0+hj9pP2b_c1pe9riKVA*cEATa;=qa1cc4ny(Wz*xDfRGX=3WqIIBhM_Z#SPORU zd0Y4VS%h&2x}LcuZGH>V#ll=f^S9s#E;)F*XPteZ!OhaR80`0 zOORbATMq7qI|~qZQdNOo#XmFvqpU>WfbL(P2>FTXwuT2$_gL~BPn(h2XV2EC)f%uj{qD`!a&^(*Fty0lv`A`Vuen3JId5rw zwR=oHdEnl>y|0^17qf+fxXNLpB+9vk9 zbh_E~`3UA#>aZquwyVomIf*(p*RgYg5&_Rgrc&R`wr|=V^29ptpCjr7L=c*yjE<72 zmc1fyU8x5KoO9Obr9{Im9~r|%#tk)VcK@4aK(bl)^DI*o{FhEHZb-#aV`IcwCSuLY z*v9InWtcYaLjfb{vez-~0B0v$gtp-K(X!tfhT9AJq{e(73tS#_w+$O1-!QR8%ZR|= zU`!mVsV20y%&kIGg;CFr|_atW+SQqs?S0JqWDB~URCRAC!}eAKTe^D4=KeTp7&cFBKqX%+nKTLgcfS z=%u2b;RhK8di$6@7S?E`5pvJdC(2-dre=0~a5>7ChtPb7c#Y-`%17 z$p3Jv`ornSUrmco-#>B=JyQl3*JQ}Om1xo-pW`#Aj-<98Kwj1KItH~iLc$I!^Ar34 z5*tg&iON5xwY5fw&Xf>9E(m)=nhNYgv0~0gKITqsKe8^Ll=^J(J@3SE>rLVlg@2Q` z>5bCB1wOlw?}`0OG`}KDlOGuT1<6`)_OlEF)uar5wZBtTHuPXw?B7vDwe)9}YV!XJ z6uxs*b3y#?llh$^Il$?BC0kGEbKiV^IpuHk0FC);;rM$NaiF8sR2Y~#GY$JOtQq`7 z{0In;4t-vzUffeT#HT2wiY##0{tu4#F#%7G{S!2PXvIIV{XcW>PitE7N;EQ(ek(x* zKX3Yu!#1qbHW4QOR$_LRKN;V{hc$SMIFzzi@kzqzA*8VlAO1mUxgVX6lMdZ^Q~!HC z|D+*C#P2fZ%ca^OW2NzkMIG&TIsH)~D)x8fe6NLTzQ}(Zv|qs!VR zn3!6)DP?Y#h-8Yh5(U@xYQf)yG+?_R2=Y1BR>(SP2f?BzmA&?kFToXE0V6r>cP8Q%=EetR1}!L_j8$K~%AGdz$QoZ- z<-L1rh>GieDux4Q0nK zI$xHw6)crlhiU)yiOdmubXumKxmcp(AfENqQKDR=+svV(LdrvBgNyg1>l7MN5}!~q z&wur>xiogxE?`f$gF}*}`R$cgq$!lj^fe_i{IYx4__en3@D4#IC-bchHl+D$)HgH9 z+X1hamUyu!6^m*H{QYjY$9{q%0(`Q(`HsSetZ(l4;vXeD$lPEg&2>O1)7%7Ic^!jq z+IWV+U_UE@3UgGmE3LYRL+Z#^Za|$P?W(hNZ|APR#omiJ-#x4$G}Ow>$L{#Q)!n3X zw!3zvp6{+yE5>s}q)JgCRyIL<8K1$$p`K@#@Gl1L?1oF%vxw>*+_pm08Y3=F#GQF7 z^#`#sy$y_0qd$)>&u!sGDN675^P`ubB8OjbS0Q^>ZiSVl*mRlMX+nhnPZYoR{cp|v zzq=`pj(QX?h29<_lUJGm{g~+J)meeRuFHR7cf5W!l$U-f)3`PN zDjRfI^csLtEuPg%`}l4>Y3-#5;xGs(pf<7LUa#Frp0=jKFH7X%BB$B0``vsgoXMd9 zM@bOjPOn&=z{=^p%(oKHfronE)rLe+x9F3wBx2ZPUo6G-+B}C|G_>7c|Aa?Q-nRI7 z6szjmF^p?kW+Q;%;|ti>`O(yv63G5fB`WbHLvc3v;-Ed#*Z4cS_nOA^Iy#v5&7t+6 zq+OZVbmmXY&ld~rkp`TA>W|fUo^_bcN=NJo@a83@l@r97>7Fk>qkBzvR z4lOsfE3JE@HldJpJQ8Yl+w1N6hiDJCQEmL}MGyS(*-*O8POXu(-mS?|6!LZH#DGOb zEpLyFVG~<|LiL~7%+3yS`>;W;*DlDucG&~!;2?3WVq?T3rHVI<)zJ-iurtTZdH%w3 z20HIM0(KG?gwmB zA(vBQpHeR4#<>eaIcTk$?4k4Pq!+B`2058w*w6mk;q~}WGQJrdv*umw@quLz2lVD+ z+UAwjyJKyqe-O*GDq~6L-?X**k+@gvO_aQ!B9q$i|7!lFW@KDct30v_(9$iVQ;w=d6jIgPji%XGy>`f^3>SQ5= z)qt!{ZFLO$#_L^@R5&KTanV%1vg@BJM@- zUu$R};--X2C?xI$+GZa#d@S0K-3pposTrnw7a43_BzQlK5M@{^+Z0xfF25W<%dwcU zW4)Zp*8(NvDS~=6Wiw-kzl|=ox>rch@sn5eAJ7UGEo{UFCxf_zwwO6lovs0w_F}cS zMbQD-+)rrQ^%{2=cG*a4x_%PH6RW57v*5h|>dQs%FL&xP!u6Zd1s)fJBeypOf)jF4013JEauJ6gUX*Sh zExVmoHj>fomlMiAjA}uxaaA<-h7JX>oDnS*HbxjHOu+4aEmlMv-Ve2Uctt^x zS%C8QuFPTZ>#J$y3ArKoPc#R7q{CYGr=*Y}KQ3GI+Qv7v1m^wU0H;(XFz4T4h8{DM z68M-gv?+~&1V`HH7V(wK(7JX#aA)!5zIruDS>C3uTo!bgkv*lLAYhrX& zN)@NSN9yDrubwJ$POKx&Ca5IlIR1n0$>PcV!)af#*hDF76Z?~xP@~4AJFVjP?|!hu z?c_-*VOrHKB%ScK*|srDHnJQK+{##LZ-Aezdn{=@6p87H1lOss>otRVG6@>hq}<9=(iarg zC{{KhU4gE_3tR4FsBLRcF>R&ZNnnZ{O*_=518De_5wTF=iff{v^~;7He=8onx3^F> z9qlrCiXi9-i)n@tlfs0`GvF>`CGzndMFm2X{3jku*I?@7f%pu)t#EDtK`D%Z-$n0# z<2q;p;-7*<_30ZHLjxlj*(_w%xHNY{(|P&sGS%j#cqQvCq~VL+)MUunr2!p#w?;aN zud?|mx9jwD8wnvHA)@rRBK?j}ai2P!jR##qCsu_RYr=iI`7xnCNtuTphQhWC+*gN( zXXMZxJ70>=WPhM{RE}D^r!*g+zN;S(gz3XF^-lz4*y!~A>;y5KC7;G$N-=YiUgzd| zm)IID&T^P*zv6sHiZRLs*+H3yMm3bhOo7iUw^i~uxy_J9Wm(p-5F#+)jS|SWXH79w z!@ddai1`{!THnIqtGCh*+nz!BBJV$$e?dB+QTbIdE3N;rPIeVtzZ<2|myn%&CBkJ2 zJRbxmfR)7VzLL}8?b8_U>s;H}T4(Fv2P|m&xt$n|Q0B9O-YiCiE{CLt#5JvLON`zy zimvPP82jq&EjuHXKf5#H%UG6cTa)FWu_>#!I6GTxLnpjNt#(qCZQ5{OdW^jD-%h}F zEj={nXeP_52{>!g6Q#>w+3SafKa7aooCvNDr40pN+s<(fI#7mdR1BO|oWx$$3}nT~ z*B+@x+k%4*3*OSN*}NRw*2%u@j=b~B=@7T!;W;A+i6n(5FO4+Vr*(ze{xoW1wc|G7 z!NNSyL-9JP-VNA#!qK1$Aw-z|su{rY>LdPJ4vor&e9Ofl#jvcnjRj~>xJEXk&u2nh zfy&;o0iPWfX@QO|6Hk-}1TT4zP)u@kzT8+bYSOC&IX%)#PDLdCCwqz?Nadpx`@kQvR(eX-s;WpYfnx{~a)ccc_}^E67a8zELPE(#MnVDJk^g;` z4f?PDBHv}B{P*$1zb`tTjqD&HNg^r9N@;r`AGM-4P+DbHDF5>8%f##Y92&|XsgX+; znG2~)^qxF!`y!u6t6~=(PINR?bkev>bv#w%vL@ay|IFXf8m#@=)^kZEm?k%p;6juE z7X;=Vn;LarbE%%QwmK4+HYoj}Q&zj`lePG+^e_428hoaFO=ym@xj{)1g#S4Z%s_*T zuJ}KP|1%H&V+8-R8U9~9!D41d;3qV*d&cotaCzfSnv}7zarbPwv4}flDG(VY{FA3A z&e7o^#V^bLc-p0Umy^T2J(7Vd>;N2wxJFCiwb84rOkeY*zFH27=Ci4|HRofOg(i;! z`EnNs{28%PWuk+KuxC;rI4v@eZcR3|pyWt_Ch`ta=d@H8w_Ia4r5O5&fw0TfHjN(@ zo1y__VojFTg5#{bH%p*99Ltc;Wwpga*T}W^n%{|s6J3$!HL{%eYc}IIG_Iif<&Vn5 z7ENrme~qKqDHIr}>?rXx4%VcCECoK5OJ3?8)-5@+sfnKTjCg=cbb;T>gQERnxv}1W zX7C%%f3rozQHp$0@A*g(5K@d&A{hI;X-)F=_qPY8yjH)zTJhP8E~iP63n+n{q$Cqv zVjKk%_30!D9&EuMxI#auAChG zS#}%y%&7eRu+?hlyAs5ZgnM^ZIZ!9oiQ78@+23U(OH2gPPJiS7n&C4Na0=vN)P*)M zZUwT?n%_lMtT-$-@JOm`<*5oI0cGl1u=B|2T4+q{W|`Y(O%;S685PKtogzu5;!9vg zroY=0MIaOBPsR{lFBG?^rQT`#s?AhvH^c4wELF5PBTWzmZ~}#{Jg_|tZrV06mx<`N zG&o@k&JS8hD?;&;}2 zFc~wG!Z7X!jK4F)$DtP0;Z(mOXn(OYLM^r2Ur1Omp{-yhfZ-L-XOxXh`!`-G%YJq=jy3@|7rS}Xz?(0tqex8lu@!NMM+ic?+S68TZOjTzCEk<+Z)fp!6D^kVAoFC$1<#^z2@Tib6l%J{=*etF$yp} zeA~Q1&Y*v{;n$2XyZ&xag560TT6v;c=8tMeZt8+flcgR@!n29qHR4y6Rl`XoU_Y%j z{kQo*wf>QDd>EKJ>rpYMiWnpVf%QIemyA)K%l7&nc>~n*+GerhM(U2cN7^_Z=EE0h zJ=AvLk3LOgf|K{BxBEq~HePE~ROX;UTHG7VY&-n&oFmmhmnIwqu(|#c*Dqn_NA~>sSw?H>}}qY@fX*g7lL)iX3(?4>ai?p-IQ?pAZxnp0U<4CI|p_! z?yYMq-4n@XN-@b!Y=I!9cxh9bKV@)rkQds=RlJ^*P8VZ}<_}s|6n<$N5q!FS7#m?b zx7wI&)7vL`^6lKoeN4iOerw>={HQYmjqNQP`$$rz4=WyXs&d)Zp^Gk))^w{ww*$Ys z%)7%|4eh8rNp5d`vsJinh(jJvX&%f^IKaxQ~jWT&KK!Rq9~LV+;I$n$~-2pvWrPOJ@yJurs$AtKVdfsWYN12 z<-aI8Q_M~TlbwIGeIFdxjDUoWb+#d{mtc~(1TK^EABf|q#9qh#RkNZcZK6V@HSnEu zmk7!@!h3AlqRL>t#-sFdCVTa98z+kXTMfRtBY9nW*ZmDwKT$Ta5=|bk=&{zZ*1a<8 zqar61qc^J(a<)`k|InBQEvKnuR{8rlj-5Am zVr@#O?p#2QVMN4D!^L;^&G~O!nK6Xr{OHS+Q_ARS?XHB3rhA!Eg1xf5WzvhXhKQ@mCX9uVEgRvU0oAzD?QrEB21*949V&ni?l-_SBfn8oR_q9 zrKz>2aAmI68aqrjbXT5vCT75Xy;1ESN5MW4+-|mHTHDgYk;|{se4&Fp1c+0SDa9vU zl5IsHN#ZhcWAoOB5Bc9EGJ-XTXJwB-ifbP%dS#G4O%0L;i?Wq@ z?wcOzIm}ODyuR0ms^6Ap>@H6fLP zF(7p4+XG__@()8wd+OJ@q^L&OG*Zsl5-Q{Eqq7!8oqG?M4bu?!$dNjYpIkig1#?M| z$7Or^@;8lxypqSDZ42)A=hreCDT_$>Y$*b#%{8+kwvzX;zf>Xl1_yQog-m>MplKup z`s0WKj#I*y;guN1Olc`vJ()h*4zoW~)iFnYOw+GgB^%FGm_i|Uj&jAwr*XXEz(n}5 zW3gI+p8q0$L*VjqYFm2Jw(ID<-9l6(T=UR|4r%MH+Q%h1At3TsMoyF-mZ+=evsrVA z%RMC4g*XQrMgzX~?ZSe16gsv02IB+zbz4F`L!yrX1a(}Yg*-Q49)LWfX6y67a5bw9 zi`I)q_>OF0r1lesAraV=uRkw7D1TdKc7@$CuYKsoLSw+IGk-&a1zZ-{*Eo6|(8eDL z=;MP7#NGWT^6s-f>DTnO<%sdWGo|gJ15dA9!^u|EFb}eyqW!3<8`LXWuNT$C2d1Ws zsEC$maaJQm;#oHEPA*Tcx>%e&=!1UZX>3=2r(e`cMB-XLO`WN{_W4Q9bwN8ldy_Z& z=w0aTAEgtljwh9}X6&B#sbqkdkzlNMf2!yPD_?dSt#W;|d0UhIez)5PLf!P|yI~g^ zbeUmX8(6r)-<)w)*(>kmYj@LzwvZ-+vehN$CHe!H5XXFYUs#?+9>;LCdC5_rlE}M) zl#@AEO8$fj;JzM&c{ixFLdEqI4@Nu9DHL5DT3-e^;?M8HSkjs7zkyfjam9tJ?WPKG z=7#d>VgBr@op4$*YK9gA`N4J>;qs5VF4kYq)IF7$5oaQeW(G@0SwYFRRweLP^Q`L- z2`?Q~t&ZpP$54k=1*F0x6(BV8C1R0jMoE&`-Yhy)%+yl(>p5YW!zS5q>DhYqkHxv} zJ%?6qOb}rC1ge!zugCyo+RJp^pL%Dg(#`7a>FB1Cd!EgAJL%n$E#c3>D#G5VYr$a0 za+gjOr(Oo0@#AjDL8SducqLAuyl~vzY!Nr&XbAGK5vrNoakFR!^{Y+QEbz5Ilw+ec z=Qg2-?|O${+t{xhzhhF^#kYk39)os1u7(Ws+$${>-kNv6!MGeG8C#TqsHPa(zR|qJ zT2oAL$|GuIsq1)NOpT1;PQ%$6Y>s-ri&F({Gp+Nc4FN}g|H@}u#8k_Qyu*@^zoS$2 z^g@#)vU%bV?kbLA6cun5JFz;uP2k4_y&E#Uj{C{=LUj*TboU@cf1dk^wYa zbSF$A_DF4Hb2AemEmC5J_woy7c=s!|bug3JL?Om;GZ3R`7FONR9%ChDOpZ$4;3pN@ z=+%I0)<}311inuQ7LQBsA?jm|g{>I^kh10HfCpEvY<6iW+n0d|z&PtTHeTtIYE8d; zCX@5=HEdkV#inMpKy@sC$$+xla zp-9R6lB40D(h?DYXr8>M?%umisDcG`z=8{MylZmCIJn%(M3B+aia}axP&%u!@;OtKxTonJ_4GhzWW4Q5yo}gwOR4o+b77AsFlm6KQ za~NE~5>2*0%6oUw$nSSahtBY)DA>v?KA&*KyY&m^UP>AN1 zS8#t3+w^#UP}D<`FQt^t3Ajz;+e;&?AQvcni8}AomFj~^S)Xa&GH0rQ!>sScJ+HN1 zX-YRp$RoxNFngLtLZ%WZHc8G?V92S#A3MiK_y5oX)x=;Izb$g=Y|^U}?oWDJBu0yh z>3@~0qYl)JN3LGc`@na1>6=y>9qcGrjoc><1UTXvVr4+z0F?3#;@$2H(lz#&Ic~9i z5<#x*BBYmVJ7&)HLz)>)p~7@ZX6)J5FY zCA4g4rL|2kJScM9K!5G|b`PfTA=&KH55xro!T((%zP95FjZcWPCaCI3rj~^{=^g#Q zJ@dAPqxx)92l$=p{R9DC? z>!L25fzCdJHI7AoR$gRE;c-=gv00hy!EE03YQuL~w~v)O$8Q`+3d?PH zf6E@ zln>A~B?9M@Q^UW1`Y@L&#uy(&r#!Q4bGR?ZPMQwN?QX_S6p(qUsVx+Rm9g47fl!2M zBgv+az@lbbb-6$d^9yG(NW$5Pn1Hk1jN!DO^^x~8CybIXjKhGi4U5vXpp!f*c(K#F zJEgIGVaM=c)O|>MRmpA)W`moBa*FR|^86QXkoIHF%k-QW9frUG7yAPDv)oVP#$BYp zrG-lb9Ex5+vvkTq&J#Ztl8P)*djIGNq~QfNBJWE|9p%8ZhoPDK!C!FKtv=TCK^u)9)K7y~V_JcjdB+4Rk(MX2 z^xPlN32Czjh=Vo@<{_fwhKg9&kp}a>7piUQwQpoX5{crnMh9p)g9T1S{=qRUUkP@NAR8RV6%5x!fFllSi$J?#+6t;Hyu;NeA zbeCgOlu5TYyWa8F*6L0lHq@dn6%6q;wwHL9rj+@)4owM`t}iWA*qP+Sd1_A3hS7}c z_{`k4;JT9{%6U+#AnGm_xa)qw@07(%U`>wICA;?9_i|%&-lju&H*6;%CW-1HysnN5 zzpOYe{%BQy^%T4)N z0W+~n@|QR?Q3OOL7_MH3KMZN4qFrGx-RJ#lQv$8+wXw;bu~E^B;VX8rX7RJgXxYyP zup&9yl9Mr<%{&3i7}+C6^d2?I#01I`WFq{A%SmM+EjRDnQy&6^30w$zA%umO!DK<$ zTvC+f^Or2Gj(k=^!sl|&n@~-tKZ_fbk5sLIzd=?A#sEw?O!k3NB&f8!$sU4ox*9LG z{uQ(>cQUv8)*_P{YuPg+;C`PCuP2;;g#g+Q&dkp!i9VLH6zfKVP#jXON7eKfA;^=MTqRXyTy`;AN z>*%(d)$9R|GdHRR!-EWGigHl&^L1eg`!ju7tV zZ9shQ8hL@#Fvs(L;Pa>k5{ZDlHd@!BzA`e+KJ5(EuR7K(4*YAxz26Q z*z*VvijiZ5iA0EB_f|1Qy%eCzpt23n6J{PO*fZ1v+5WVg7+n^S7!?$Yr5 zN7G_PEOcYgOKvBRvoE?-YUeb^KIm-oeZkY`4k>&%745%XW!Hg>O24kn@qqMPSJq+U zYvB_I$;A*IO>4t2lgTDNrHR7E5Tm!6iDO=<1$I;`s>VG1LcjF;ih44fLzMrcI_-Um z4VRK*OsDhKA9X=xB9u3ptRv-p$w;2cM_oFgwSLraHES4A^uBGPh8A#ASbSn-41CdT z`2!JF&QhBC3?6<`YIkL0Wg09t$N=2ZCh79}_BYC~;f$?kSalVS zmo4LEy~&Kz0YdsWw4V}-)Z5;hHy|MCn+?D=cO?*L@dH`OwRxs4vEO*Jo!>Ps?ChEc zQj9s`2WQBpIAs|!NhnArjwPOwupyg7qNGysH@wYm;jb3`ZIW2=HOR^RX(!!zf)5BQQ9u>>M{7^;M3BEUQ$ zmWnb2*4rHaaN7Q%lhLM^s~o;}s5>USG_JbFad>unXw$ADU9>1FQnU=^g<;ELOif8# zQlP_JztU9YJ>*oH;!TqO+Q~=eSk8ddyZ))6M!TNYPl$U8winn1rB?N)uCxsi20Nd} zue!t|{f@9j9GeE$RF@5T>?ZU7@L3Pret+@YA>eBlh4-XM_0wA_^lEx{7uV;oQI90a zpFoJ#b0yP@m-O_!G3ybzsXj~$xGQLp>_(Hy^=2VAa1^R9*Q?6?BSC@xorD@IKZHVKn!ityJ$m8OEcRca*v{Wp1(YA~MN( z`P!8!98^U|&8*S=_a6+%Ib~1-wJevCg$*OM+yRQ;KBJ|?Do z)Q*CwY*q~=GWE~8p>ub96^=7R-3mnW9Aq5F{d0rS;3MlYq_bx~->$b9w`(lmx*E~& ziNTRM!uJEG`XqD zd}a}h?`vyFo?cQa8<^}vqM|*hzvjPu!|paTbbQ(tgC&|X+gKbl(T^_>+$4mYDJiZJ z$=E>xqJ`b$AvI7xOBnz9#Mcv`^t_Xass{*TG4WcFY@7C&y{^3u!e#1!RU$;46){2v zbjf+B%k(>v4|r+M=htck?nF*n+=Ts)6}lyqSExnAun9#A=^UZnYyLNg?@~TEe2QFC zc^9mg9_A-%c99ooEAM8vx4`y#{$Rh#dkrsq<{%EkI&F^g=i&wlSSNjU3T5UK`O9DF z)Q=F7!Y0y9d~BzUqB%4INE@Pl+XIQj^w(N$bJbq?8ejH)xX*4^ryP`-C(*5u-K8{Y zYh09+Y!SPTbn(_Nc>)(ukQ!ppMG0*@axQ$eI_yC$Lw&=pLQTyq9O^`w z+Z@d;0J&YXc;{%wWI|8m0IVXmAqB2Vdg+H=)oxS8@u4B6SRigBIe!YhfV zyD=BBofJ!*hTIi+j`YAJRI zu;VedI|EQlm+e6%h8}(0@Z9!(dsf$a-xS`2!DEEb`iW=k-XlHRL~qmAmmA@JP@cm` zcRkc=twZWv&sy(SUxGIe(Wt!Eck&X%eO&3Of{ikU@AtaCFOSK_yKBBP?s(IKi{kVO zRNF#hfE|n;4MP%W^!d)S68=Q&RTaP=Fhm!YVwYHi6TqdT2!C4(N`P}fjw?vCZ+-7u zy6ZvsE5%_E3;2K_LGPEo4rv03hhZf;TsKhuZn`(^e8M7>@0t$`cQn5@nxq@MC?61F z@HCW|9C-Rrme57mr<9$Q=2saKuyN<8T5FRKyb-v$jZ zo9w;ma13z-fo8YUX_C?=dNh(0wCx2mHLux9%E}o769v%ThA7Bdp}7jxcsG1qaN8ZF z9QF$1qMuKcL#r1#bsMYdr-JL1e3)vApXch%Fx<1heV!pfE?}~J{M)Rhz2oHORRtm^ zn#???StE(7fe@~a!JBIGoaGu!Ze|buIan0l)Jm7@U0t56gUgJ8F;=J=XPZ2l%Ez2k z`;sW`6*|02@mi5QxFHeoogLygYIeBbx*5eRuJZcWEMd7IWNA=^AR`r%d4yh&`Qig?4(c8qLnp1On@IQ(7}lp z_na*)YP?dhF?@vM*~1cIl&^BqDh~~`~eYJn)}+DDIdpCZ8x!t zo}#2jlw9s?`Ian%LV^5PMB*L0_EfQ56l2nd->gNU-f)SoYeh@i51uS5!~}0pNw%=S z!mf!$W~n8NewIBp8l=GJHZ%kVGvKt8gYukH(4joi+jKPrzf?T$o}Vb;%(8ysUG^OH zS|MDE{gmI^8J%`J&M%&uEpb_-l)S=ZTQXl#&y`msxQWtSnca#PRrLEy6+^~)e)axK zzz{I+Lz`#TVqh=3iqd}QC|7MsvfHi_HD1E-%Z%$WxhsbLv>&LogFiB#@mTSvWnRL+y2+#}{rse?mpg*& z9Lm(6^d1GFm5aFdckLA7oLa-`^c7XMqZLt4-&h34f4jaX^t@_NlG#orBh^85Pm-hq z{H1IqnJrDnmwez{Qejrk-9CFtE~$1uinsz$qp)BfIhr+b^~MaIa0uN9F)#>`)VB0~ z3YZ=Kcvq_Sa;IWqu4_|l-pCbO3?$0>a|4#&s-zCXtgA3;oJ{lkk~+U*&UWtfh{TZU zXEN&=J!*y{bG!Jv5Cw>O$0&u+E+@f*G9qBG@jakWhD^q*H z?}m#^I%y}YM}A)RuX*ogZs8`gnjNKDG|H0@D5+2EINA@UH+Zu7-zvx4jdTf| z!#(HqdD=_t)YX41nIA3IM&UHkQ%7Te9hRoDm2m(BdP90@zEnW2ZJ_(fM>Pwp@ZAb) z4*|*K4lU!$F{K^o?{iK5{sif%V0})=AzSr%9DSKw1MDZ%qi6 zcqFg)_>U=l6pC(z2_omg!8P-urGRJ8*~93XEFK&UBtl{|&kP*FxTEh}pMAgNtq+Bv zCn|*IMLxW--y9>h9Ga{^>+-j#@`dcS4l6^O=UaaoFZrIdQqxn)HPc}@#&wl;DF1;G z(%=(&qv9AORb;$qDh>fSCYorg4ij$mK*gWl^m*dV+k2yKIq_i|=D0kz!~&ux!sFfTsCYc9V1-OL-wdVvYgA`DRai)$7<8MWbz{2!Xrc;Y*u;q1MZr z%m5krUdPf{A~VhQYjQx)i^PC(Yb5P%g;!eD>14eI^3%jeF-4!bUzi^Xp=CL2lm>We za@g1k_{*6u|=S4K5jf z_7M$zU+1mIs^~?Ngec1;M(n0v>JuNKN(p0gAm4kMziY(5;q@g=U&}Xp%U^aUufRd^ z2VUZyb$R&;!+3~oVcj2nS{cv_ld~U(@F4;UCe|-ZC#_Hho0YuM7j}1zqYwBA=n?`? z2xz6`rpCTjblyHm=0Lriiauz&;u_|(|9mK1KQ{my7Rr7gSU?YvXLZ3+aj&A8EErH2 z#iN`Buzbb0j7K^G$@dnSKja9U@rRZLjkZa-g)nqp>{{`Ce7v$a)qmym@)3?ur+?rI zt7v_3G4*_og@H)brR^x+)hJ~y3tEiPu2)Xp7l|3(@N7q)M z(MhxkG$QfSb(O36tFm0ML8m@aZffe2$nPj}zn2#iAFr?;6W|ptJ>e$TWtXPR-U*jy zv{Zs4iC2l#eQ7SfN&TLDncd8h!^ZYQtSL#d3|K*f!F?{?pz1Mkkyx5|rz7t)&H8gS zDD5v~Jc_pjjtv7^mMa{=C2Wem6Fk`YIcqhq%8$&xdVSqFhG+`)4HCDVhS7w-XlIo) zr@?4fjH2Pff8l-pfz($ED>xRcrjQEI4I55ngR$&WUQDi9VJ-Qi8rydFGFR>or5kiO zdC_!X*2GSme|&D6mXE{snTI`7)lD^NFcDTqo?mw(x=iH)G^gZB-{g*5`dh!qoh=Bg8yF3eOzWMEmA91_o}XDW0lp-4AbeKHqAL`=iZkyw zrdSPj&&=HNse#`K0eAjnQsAv4`%ZYL7k#ubn%0E06i>Z=oBZqOLXkD=<>#YM#$(=J zrgpuYb*=v-^<8mKy0`&;Bb^?Ww)%Vgz0nUM1BXqLKwZ~qkFS;9`_`KWZu6R&`M9uS z3p?rcXd>JODl7eY3n}ZrWd7TlO%&0*#e%flwHSnbV^2Y49WCnm6~BRHQ!gwk&h-tocZvHAX-~CA zqA6^Pm-!!9gNzMO*{UkZZhDs|yFN#yy-PLlfi3XUC;uoT zq6}4BjJ}?^c{b0$JRHC>^EMF{tY^S65YZ!>^}y29Clx>^nk<GOpT*vU5zV||>22#u4imGn;%Ip4Umor$ zj8&rjdi=)qMgO@kVX`-}Aoy|f$`(&Cj!-WqotMPpX*Dr2fcx;4~6#5$?=@iwP_f zQ7kI{HzbE*mp@^xEI;5Z$3E>Src=E2^IyIh_$mHPgY0uOtt+obuLZz<%jq#C_4S}8 z%2f&xG3V#mHeI0Dv`DibToCBe(Ixo1>?|ELf+qpPFOpgi{zNCKYPX?A{P#iX=o7hb zS?%3$q^MnS!%LcAoCk@os7qBNkzsyMTznT1@H`=`(`#@g5sm4S`CMZ(u zdfyG=cLM}RVuy{o)tbNUVu1A@C61-OVdQGAeDq0T$dP4vF{w9a1;g4-EN-E}a8BEstR~6)e zw^u*wVVtwC55hw~oiuE)9!W#_Ks6+Ktf4GDoK-OEqbEz?lQAKimC7_-`EvcA5Mc$; z8DzRMz&~g$UrT7u3fQyBTY(VdNF4*Zn;$M)c8Pht*Br zlk=3Opf(&OH0Orwv#=}=1VBq64;Nz+5-CJcxg5lIvF7+gyY5LO`sz79ZH3;nA+nTd zSOFaP_B~cTUC`N9KUasQBjW3HO4l2UnaiP1&?5)am_=C=9x+#8vzJD4iOgAvIO4Zv zavL$-S@IE8W}U$(c&E`E@nOaESZAd?L+kltrAlU~5K7r5z|gJWD^tFpanTV> z(b-J9@KxVdXRI#Z=U1=iE}d@6Nb(=^QJ8}K%t>c0YuFqnlzzCP@10(rotRppso#Vgv6V$mfwc9bGc|C1@NEw!EuWoK zoATY>CT`BHy<{Ae47!f(W-O)8U4RjswcO1Jl4!5SKVFQc2^ zIFr-}hjvLTFnVg9To@U~Bw#3eMgic8K*pg%6aA-gv*566LYWIyq92dNaw_4SQW8^Z z>Vxk{g?_PqAE&sY@O|!<4xOt@AH@VW*rNn_EuGX4dFXWmGQp4 zg>QRk0VN3YK+ZT)TIx;wUL9*j)$?IoUfl-3L%&7u=9Y4fdc*44sER+N)a9h#e(f&-I{tYSgEUn*(TU$d5S5MjJ*kKZJyB3JNv z%&_d;Ibzum_>BcxYxKU@nNn2#s*ke7@>~?ZsI14Zet@7)I;&K#eF)cv4679J&rK!o zrmFIA4IITP#*2=%8cE}}P_oBQx$Mu0O6WWPIN`YfQt`&Jyt(HoqhA_eL&~O8nUhv- z82gzd6Q>dZ8k%_0)Yn0R3@dwkIwM;Tg ztw=u?*acVKM{L9eyEl2QAcerZ?20CL>ZoI|Wv+Zzwd)vA#3v-@LEXFZ%WCMa{g0yc zvr$r;j0wUqZ9=LhJ4(R*4z{g^@)_7a%UHZrqmB7uCR<_aCM1nF#9OTCSUfj!)=&N9 z+ZFkehH_|HEP!yI#Y(bla@(?`^J%ibD5fWBGajgD^PiFzX?5)D2*aGdqqZzsOGkBC4(w8 z_h#kHUs-M5y`OH7mWr577O^c%h&_SM_@ z&V7z{E}*LAPkXWzFTxpHS7F}*vf#%vZ%tXez>B3zI6`3$tNRA0l&|3HI3{sSl`%Qg z8FktaGjOA_G3uhmsOZ0ICQ2-_+F-OlBj2p)u4KR!0sw|{ZaA?>5Kx9DHWnlPysy-* z+oia+{mX8nog5X_IKCAPZ(B* z-cKdw{0S@%9)di{UMC9lT!5aX!7SWH?x+~m94XY5`$JireODaK_7|DI)RkiRy1xwi z0_GKO7#{z$oJ2%k&RFG&TB6;3nDDUJ%4-$$^cAJ{rcC*9TdQr@{_WPx4 z(QH>JXo^HHqtbrn$JQP*^qC;nb87L2D<9OlGxO95b^#HrHa>_i*(a>^6u!p4^p>mv za(Y$%!3|%L^Zh|*vAd7KZ=FBRDUH zGlaMJ?sQQ_`L}gpg_HkorYGvewuBduvX*fb`tD21^~na-BQA(de%__06nEFujU(Y_ zxmr7~UeR*?TR$Iu;m-QtP|)FeBfO?(nkG8g8YE6yE=IN1m66YVn9%dj zVQGV39kjLZ&G;{f(sZF?L&AT%xc&EKw{Im}pu4{*iO-VdYVi7$5<-8b9THc-)5i+7wpJKqvv&iK$3 zG7pyteQXsEqH}Nbd_Ht}Y`U#uoLt`Y_XjPw(g70MCEG3)kV7+gB@s%L-$XZA4JMNX z@MWXUkKIzvpYu4+$o>m0S9$A#dQxJ#(zo^C)6=>lr|dICMtNWq^(iKVb8-x za9Uho-a$G?e@#6#a_D0(xl4v$LFT0xXMX(o-SOKei5<-mf*s@a42NRdS% z*U)}N6#mVxukCqyuQ$x1>%c|4p~RedNg{Y04^t;}Qy}YO*Z;N6AHUYGI%CO;(H+`r zGQHFNr#8}OOuN-22%2%yT|dko+vN^#_Wu{>ljbha%@yj~Dyz#j&aC3GL>w=1yb8M3AEVj!ZJqQHc z92{^Gi;vvi@Gx=@x3ATwh;*g*NVaG-+)(!(>$=4;-DQ0{uB>(WiCQNS)M4WDU*qK!dz(KboPfH(2WG?0gdnJVnXwpFQJt;$kv1p zh0_R@xu-kW(;f6ne8T7Oh?E~f35yQ|Hklr?OPUXV<^OLX`v5rjaoO);1daAGDcZ}R z(`dIzHb*gq!=LrkZzGHtbtGNL1(LhCFf&toRt-ZOT8CEcAvFq{Kito?Qz_>h`8l%G zw>=(BKbV#an8-e&f&(bDa9p--4e!_2eh9E5lxSiAl)}CfEjS}b1DWyws!V9Oj_jTx zw}uT!=zkc2kusgGhu|D{Q(W;4PUVJ#HnxQ&-V1TRZvTt?@n@EB5&P$KC6d~3k;hMMZjLULa z0c|NqM%2?QEB?4z2LUpV0ix~#AIg&apqX12vFI$RyY6U*q!^(M2%%?fB*qoBprG7> zEgi)ayU!i}x;QYn&UQaCkZc&Ahr!&ocznTK{F3Kq^}Xye)6~-Wx~?r>;n1$T2;3W- z^+#}%Bj@&zS5nL!=G-YCRXuduQtlns5AByK70NUYz&!l?6M5b9CQy8K&U@p=FD5Iw ziH@3WP^UrE4k|eEG0YmyJ^4g&T}d(u)o^&?w-BrS zf@oM!Ts8GPA7sAy`9S>rSMN!rGH2s^Z^ri3WXWm(!=#I$)tZ8wWCKe)EN>5wNbL8S z=~vA;{imH+k6pa(_lqJDNcpVC!-!297=9?MC}pRj&l{}`Hx?b?+wy^8OXpR}9x&fw z_+{6Kpj?hF0Shfccq`~@yC~Wi?Uycr!~}Ft$eLaKonfAurXt!evCne}0BapxFWbQU zvCDqv#WRj?12e=lCOMKU*^Im1%^#xZu=aHza-T|a1PWnWD9ek2l5-$M@T?qL;voQZ zt@!hPqB>m25APg=7+p=!JXw#J4&dSOdn+&=Lhb%aPTD-&=Dt14X-rs-uW2o zR@;=Y_D_IME(aU@OMXW;+NUv$cY&=(Ga93;;nbR#YlOPI=m+5MBP&AXr_U8Y`Tz^F zVPvk60s0$N0#Ew6PWJXvVuVj34@+WY3{bm1{mt}TeN`UI=c1Io4>&^AWGgauWOOjd zkL}Te|1pci?s-nw`cQ)S{az(WH&95){}ni|#)CX3GWxX4dVZ3cPb}H($pLy^$B7=% zN~(b8@$wI%6;?<$41eG`vYe}F&oUAcApqf|w8i=Kb7=8DOLBmVC)N_$?`m&3Hf(+a zh3IPRu46;^wl4uzp=Fia_eK&F1}+|SDOz~MjvvA}nYmA|#5Si{Wp=o#kU)PQ22?SA z%NWN-SIo8sF=u&g?v$68Q`23OJ7DLx_gex*fR6~c>2)+XEdsbyQSX8R;GCqO|A6^6 zp{ELnfBV(nAul%Xn8gRA*@h=Nf%_HZ*XQA2UZBJgsK>I)0yE%dc4#V4UZIwsL?7qn z4t4tV9uN8LeDab@e*IYz6_6oFhY3}`1cL3EC8rQc(>qW@Ux)~t;U^CuPkQVxWmesm zD*c~E^^4>dy%=bMw9$uCc=FN{79JuMg?b2GbyYS< zV!>|#@w+H|F%tMf4f-ih`n%^D&6!^HGvuBbWuU9YTqwFMVCf2s1tP$-v7%Sft)`Pa z!aT^<;+}+cXG*6iT9s+Y00=|IYz#a*K~*I%$ZO2(k-nBGXf_avgLypt*A$9xO9+^^ z=60Me2w(AA$3KRL*>hiDPgf8n?)Uqe$^hlZxvnZj(>KX4fblZylhpyOzN8@Y9x>At zxaV^ppFtRI)M`M?iGCK@8dfHhxPNN{ynJypP_@dHV^mYq9i|o<;BSL(UPtv z%Pp=_a}rmm({h8W#4AAb*-G=# zB?)V1{QU1$1g7PI#@qK%NCNk?kbBxgxTYI*w3EYY5fPa1^}MC&$d}ATy8o}94b7gdt+6*6xB1TzVU)qg*$1!_$HWSC~aDgQ)1ssDmv*BjLBGm9l5p^fRiAw$tq-)L7Hgf;oo8=Xv*1v(40~aX8L{&1b+ei9dq}LMtV}m zL8oJnjVR*sX);4;-2Pwp{|OMx)@(LX!2wcFr?to^(ob?}Nn^NC!1FPJteMt3n*TNG zCS-O1-39G^1Lt|Tcm4|%h0w>1AD6e%c{kl^Yvj$A5ghCqw{vTtpwOQXby4Q$sX6+unr9+i(CIZY{Kgy>33EEE zsBBkBNx<7l>-tdM{&;UJ$gVCldY^?lx`ZAnK#uS_4J$g1q$wITW(jV>RJxl5JZa$uL7C+VN+yTUCgXp;>jp2?r%sdv{*tF2XSN$+$X zYgaFlsZX*>*Z-Ns=QQ&E^R3?V)2Fw64eoX@6m^F2 zzJIM_Tf;*8z34P*?NYXntjlte;>u2s=bM~)ri`%!c*SW@Cuum>yER z@pAh!p5~~ukDAE6s_)3p)Z~|`X_u*jnA^tRo}$GIee_H5=gYl&2Y$SMgB;Nr8G3=a zoH@obPdxbn2ksGiLw_yt%gv!b>(KLa{L@IQ9w56Ua6_fd#6aqzW3B-r{SLy9vHs}3 z^J*a%G4oAhz7hzwplc>G)wb4)wdrIUZr9BoHr%#x3d*$Ur;Wd*6>U!ykAEw&I5t`i zt?W;PcD-@p!#n@6Y@76o`w;iMEoYm5R*6q~tFzRd^lganK1E zu)BNuiJFzR`B?*|&VtCadDB)_C1Jt!?g@^h!3}FidUyy~h!>I%8a5tgXnYoE&(9o9 z6vm6IE5+u~9}!AOnL*(5&(ww{VeBCWYZi;ccZID7J+yTgpZ|Vw7r3AjnO15L`O5Qb z#l|@<$-AWD=7$!-^|x%P$sGAL;N9ON?HfRBI`BLdVvfqK!vSpJ>$i%RQ-?JQd( zsNi+I^B$hGQ1V4>UD-uR{|w)Zd+II{wDBqkHew2;JDAV(aUf@@pXeU9Abikj3*OoQ zX_#<5kg}aj+0_ii@(QOJZBwHm4WpZwA!lq1Hw;+wpqu_FKfOak-{y57GlMvHU8GS3 z+4|-%FqMJ;Lt_5D{9R=u*Ooz+f>j6nGHvsXLsqGnQH%*^?`j%GmQvxY2llJy|ae{7Z3-6HzxKeJAeFPpd$&ANMxF z7q@iFr03_wB8IkkS}t*WUY`qjPYdQGF>jJ?u(9>&#PNs4e-YeMkjvaIAfpwNuX#CG z!EU1E${>;Js|3Ax{Ts20DF}d;k*$3>vC;Lk?4@mIpY&ZnWDVIVQL9L_vhW3zZ%W0l zqJs;LY#c*4*R3Y&yK~~xvS(4UqPM$%G=l@eqlU`cUzW7Z*hcro5faxh3EU7#feoV% zsPmcf1*-8)@VqLY^*}mop3NK&e?*xDtO!NHzdNtAo)DREhrJ`q?V3AJhX+!VFz?}ab1UTsqRqTZ?UT6lRFbjLRNmAKb+d%nf}o< zf3_lkddZA>DW0{QCrHx74Oy`MJK1h&oX@@I%yR`vpMYZaY(Z3Gx1F0yNcOda@$8-) z-GB?s2wmKzEaKu==%i>)W*ko{aAcPaaT8_8*#a zB+1bYWr!C`E?9U)vNJZ1rf5I3Y0a_-c3MD;J;m91N(N?p^fDf z3H&8{{rqkNzoBxF2mk>mx2z{25%4@(5gVboHEIZF2^_a9<6W9_6A@81lIhCT>25t$ zJzRZe!ZvcU>s98SyN<`^aoPV9)#97BNpNKuImFHStMXV7q;GrI*eCMEg2#-8#KE@b z)Kivcdln8xX8(N||GURNEMWrnNBcEW8`T&aG*B=lq=(k%pfZd*Lf*M@Guob_;tEBI zlba@Nwcdfc!{wx=px)Nd)gX7G9R4~oXKZJeD>+DpGB@H2AylMS=@`69;!i^iabQ}L11 zFh6FOsgsgs>DcO=M?W}W^J|+KFP)?%2$CO-UV9wGm$mK^WPP!g^R>iJZ$S5UIe)8G z;w6LdrGP7@L~}4F26XBLhkrHebnIX%H;8tAXKQ|2AzdT-Irh$YMp~X}Xv9y_*Mgzk zKU{NMI6p5_3HhI(z{{SQnfU%gk)iHGDOh?+LkUrI<=;x_MZB%4G^B=w*V@6~ylOL2 zoJ+iww1`f0Cu1O*_vMtdli-TrU;O@q^=f|2)0t}SO5R8vSS7fdH0Pr^TWBNf{6^Dm zuf6Z@R+%Sb&^aZskvCe%nHwQ?qRi%X>BuT_GSSv_(z>R`l1hwy^ZVX&5XN%y2)E68 z(BAB8Yi7N2M*qc^;G-FCXFqC~h`k?D?x^dnhof~p3vX`YYr2UWA(OLT<;l+Ld1?JijJ2;^$1VJ~0ppdBk!HEULx8ba;Y=cec=OcgvsVP*J`@5 z*I!Ql8x8#PF~S9uVrDO{G z>-ZY($n;VepR^<}#69PHVam~r#w5~m%dU7ze!P=2tKiXn%iV|x zE2vIKtF)$NF2uVG+aSFo2*z*{M91Bjh-X8R^|J7MS%MnabWzlN@mNm0Ow`+n-64NH zSXHTlgp7J$!Xq>T4gB{gpAy;1zjLm$DTW;oh_*LXzq&}R+6vh>bCiE%LV?b|gvTn! z7Jq#MA6P5wc6_vovZvKlSFdW7kyqLo09184+IG)mN%M$Qg9kpC7A((;wdMOzU=3C#%VNsoU%1 yVA#DAyT5|~zXK7!(;&a2F#pde%rE9VsbWD~UH6?p&g8#rR6nm1p0yqkxBmfwckCAc diff --git a/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata_zh.png b/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata_zh.png index 5a6c3a9624f8428547454528e6ce58fe0c6d9758..cb5dfc00b489138089e3d3c0c090ffccb2feb23f 100644 GIT binary patch literal 9150 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 diff --git a/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata_zh_TW.png b/designer-chart/src/main/resources/com/fr/design/images/emptydata/emptydata_zh_TW.png index 738fa685adb223d384edfe6310251f31365a6830..e6b7b9733ab2774986a967e1a8f9851d8bef2585 100644 GIT binary patch literal 8916 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 From f70a3cea5e2f371d95a40908813f74f6e906358e Mon Sep 17 00:00:00 2001 From: "Crawford.Zhou" Date: Wed, 24 Jan 2024 16:30:23 +0800 Subject: [PATCH 2/8] =?UTF-8?q?REPORT-111299=20=E6=8E=A7=E4=BB=B6=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=A0=B7=E5=BC=8F-=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E7=BB=84=E6=89=A9=E5=B1=95=E6=A0=B7=E5=BC=8F=20feat=EF=BC=9A?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=8D=95=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E6=A0=B7=E5=BC=8F=EF=BC=9B=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CapsuleCheckboxGroupStyleProvider.java | 35 ++++ .../ImageCheckboxGroupStyleProvider.java | 35 ++++ .../UnitedCheckboxGroupStyleProvider.java | 35 ++++ .../radiogroup/CapsuleCustomDefinePane.java | 89 +++++++++-- .../mobile/ui/radiogroup/IconConfigPane.java | 150 ++++++++++++++++-- .../ui/radiogroup/ImageCustomDefinePane.java | 105 ++++++++++-- .../ui/radiogroup/UnitedCustomDefinePane.java | 15 +- .../mainframe/mobile/utils/DesignerUtils.java | 4 + .../utils/MobileStyleProviderManager.java | 6 + .../fr/design/images/buttonicon/icon_add.png | Bin 0 -> 192 bytes .../design/images/buttonicon/icon_delete.png | Bin 0 -> 162 bytes 11 files changed, 441 insertions(+), 33 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java create mode 100644 designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_add.png create mode 100644 designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_delete.png diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java new file mode 100644 index 000000000..fa2d9d905 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java @@ -0,0 +1,35 @@ +package com.fr.design.mainframe.mobile.provider.checkboxgroup; + +import com.fr.design.fun.impl.AbstractMobileWidgetStyleProvider; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; +import com.fr.design.mainframe.mobile.ui.radiogroup.CapsuleCustomDefinePane; +import com.fr.form.ui.mobile.MobileStyle; +import com.fr.form.ui.mobile.radiogroup.CapsuleMobileStyle; + +public class CapsuleCheckboxGroupStyleProvider extends AbstractMobileWidgetStyleProvider { + @Override + public Class classForMobileStyle() { + return CapsuleMobileStyle.class; + } + + @Override + public Class classForWidgetAppearance() { + return CapsuleCustomDefinePane.class; + } + + @Override + public String xTypeForWidget() { + return "checkboxgroup"; + } + + @Override + public String displayName() { + return Toolkit.i18nText("Fine-Plugin-RadioGroup_Capsule_Button"); + } + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java new file mode 100644 index 000000000..fb7224aa1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java @@ -0,0 +1,35 @@ +package com.fr.design.mainframe.mobile.provider.checkboxgroup; + +import com.fr.design.fun.impl.AbstractMobileWidgetStyleProvider; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; +import com.fr.design.mainframe.mobile.ui.radiogroup.ImageCustomDefinePane; +import com.fr.form.ui.mobile.MobileStyle; +import com.fr.form.ui.mobile.radiogroup.ImageMobileStyle; + +public class ImageCheckboxGroupStyleProvider extends AbstractMobileWidgetStyleProvider { + @Override + public Class classForMobileStyle() { + return ImageMobileStyle.class; + } + + @Override + public Class classForWidgetAppearance() { + return ImageCustomDefinePane.class; + } + + @Override + public String xTypeForWidget() { + return "checkboxgroup"; + } + + @Override + public String displayName() { + return Toolkit.i18nText("Fine-Plugin-RadioGroup_Graphic_Button"); + } + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java new file mode 100644 index 000000000..e22aa9223 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java @@ -0,0 +1,35 @@ +package com.fr.design.mainframe.mobile.provider.checkboxgroup; + +import com.fr.design.fun.impl.AbstractMobileWidgetStyleProvider; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; +import com.fr.design.mainframe.mobile.ui.radiogroup.UnitedCustomDefinePane; +import com.fr.form.ui.mobile.MobileStyle; +import com.fr.form.ui.mobile.radiogroup.UnitedMobileStyle; + +public class UnitedCheckboxGroupStyleProvider extends AbstractMobileWidgetStyleProvider { + @Override + public Class classForMobileStyle() { + return UnitedMobileStyle.class; + } + + @Override + public Class classForWidgetAppearance() { + return UnitedCustomDefinePane.class; + } + + @Override + public String xTypeForWidget() { + return "checkboxgroup"; + } + + @Override + public String displayName() { + return Toolkit.i18nText("Fine-Plugin-RadioGroup_Linkage_Button"); + } + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java index 072a7a57a..ab5b64a99 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java @@ -36,11 +36,23 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { private UIComboBox custom; private JPanel centerPane; + // 按钮排布+按钮排布下拉框panel; + private JPanel buttonAlignPane; + + // 固定列数 数字panel + private JPanel columnSizePane; private UISpinner leftSpinner; private UISpinner rightSpinner; private UISpinner topSpinner; private UISpinner bottomSpinner; + private UIComboBox layoutTypeCombo; + + private UIComboBox buttonAlignCombo; + + + private UISpinner columnSizeSpinner; + private JRadioButton leftAlignRadioButton; private JRadioButton centerAlignRadioButton; @@ -122,12 +134,12 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { } private void addPaddingPane() { + double p = TableLayout.PREFERRED; + double[] rowSize = {p, p, p}; + double[] columnSize = {p, p}; centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout"))); - UILabel paddingHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Button_Padding")); UILabel emptyHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("")); - UILabel buttonAlignHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment")); - UILabel leftLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Left")); leftSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); @@ -140,6 +152,52 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Bottom")); bottomSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + // 布局方式下拉框 + UILabel layoutTypeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Type")); + layoutTypeCombo = new UIComboBox(new String[]{ + Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Single_Line"), + Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Auto"), + Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Fixed") + }); + layoutTypeCombo.setPreferredSize(new Dimension(DesignerUtils.NORMAL_COMBO_WIDTH, 20)); + layoutTypeCombo.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (layoutTypeCombo.getSelectedIndex() == 0) { + buttonAlignPane.setVisible(true); + columnSizePane.setVisible(false); + } + if (layoutTypeCombo.getSelectedIndex() == 1) { + buttonAlignPane.setVisible(false); + columnSizePane.setVisible(false); + } + if (layoutTypeCombo.getSelectedIndex() == 2) { + buttonAlignPane.setVisible(false); + columnSizePane.setVisible(true); + } + } + }); + + // 按钮排布下拉框 + UILabel buttonAlignLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment")); + buttonAlignCombo = new UIComboBox(new String[]{ + Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Nature"), + Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Center"), + }); + buttonAlignCombo.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); + buttonAlignPane = TableLayoutHelper.createGapTableLayoutPane( + new Component[][]{new Component[]{buttonAlignLabel, buttonAlignCombo}}, + TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, + LayoutConstants.VGAP_SMALL + ); + + // 固定列数——数字输入框 + UILabel columnSizeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Fixed_Number")); + columnSizeSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, 1); + columnSizeSpinner.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); + columnSizePane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{columnSizeLabel, columnSizeSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + columnSizePane.setVisible(false); + leftAlignRadioButton = new JRadioButton(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Left"), true); centerAlignRadioButton = new JRadioButton(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Center"), false); @@ -147,26 +205,30 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { JPanel rightSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{rightLabel, rightSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); JPanel topSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topLabel, topSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); JPanel bottomSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{bottomLabel, bottomSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); - JPanel vPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topSpinnerPanel, bottomSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); JPanel hPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftSpinnerPanel, rightSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); - JPanel layoutPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftAlignRadioButton, centerAlignRadioButton}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); + JPanel layoutTypePanel = TableLayoutHelper.createGapTableLayoutPane( + new Component[][]{new Component[]{layoutTypeCombo}}, + TableLayoutHelper.FILL_LASTCOLUMN, + IntervalConstants.INTERVAL_W1, + LayoutConstants.VGAP_SMALL + ); ButtonGroup layoutRadioButtonGroup = new ButtonGroup(); layoutRadioButtonGroup.add(leftAlignRadioButton); layoutRadioButtonGroup.add(centerAlignRadioButton); - double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p}; - double[] columnSize = {p, p}; JPanel paddingPanel = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ {paddingHintLabel, vPaddingSpinnerPanel}, {emptyHintLabel, hPaddingSpinnerPanel}, - {buttonAlignHintLabel, layoutPanel}, + {layoutTypeLabel, layoutTypePanel}, }, rowSize, columnSize, 10); + centerPane.add(paddingPanel); + centerPane.add(buttonAlignPane); + centerPane.add(columnSizePane); } private void addBackgroundPane() { @@ -240,7 +302,7 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { UILabel initialFontLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Font_init")); initialFontConfPane = new FontConfigPane(); - initialFontConfPane.setFontColor(new Color(204, 204, 204)); + initialFontConfPane.setFontColor(new Color(102, 102, 102)); JPanel fontPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{initialFontLabel, initialFontConfPane}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_MEDIUM); centerPane.add(fontPanel); UILabel selectedFontLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Font_Select")); @@ -260,6 +322,9 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { rightSpinner.setValue(mobileStyle.getRightPadding()); topSpinner.setValue(mobileStyle.getTopPadding()); bottomSpinner.setValue(mobileStyle.getBottomPadding()); + layoutTypeCombo.setSelectedIndex(mobileStyle.getButtonLayoutType()); + buttonAlignCombo.setSelectedIndex(mobileStyle.getButtonAlign()); + columnSizeSpinner.setValue(mobileStyle.getButtonColumnSize()); leftAlignRadioButton.setSelected(mobileStyle.getButtonAlign() == DesignerUtils.kAlignLeft); centerAlignRadioButton.setSelected(mobileStyle.getButtonAlign() == DesignerUtils.kAlignCenter); initialColorSelectBox.setSelectObject(mobileStyle.getInitialBackgroundColor()); @@ -285,7 +350,9 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { mobileStyle.setRightPadding(rightSpinner.getValue()); mobileStyle.setTopPadding(topSpinner.getValue()); mobileStyle.setBottomPadding(bottomSpinner.getValue()); - mobileStyle.setButtonAlign(leftAlignRadioButton.isSelected() ? DesignerUtils.kAlignLeft : DesignerUtils.kAlignCenter); + mobileStyle.setButtonAlign(buttonAlignCombo.getSelectedIndex()); + mobileStyle.setButtonLayoutType(layoutTypeCombo.getSelectedIndex()); + mobileStyle.setButtonColumnSize((int)columnSizeSpinner.getValue()); mobileStyle.setInitialBackgroundColor(initialColorSelectBox.getSelectObject()); mobileStyle.setSelectedBackgroundColor(selectedColorSelectBox.getSelectObject()); mobileStyle.setBorderType(borderLineCombo.getSelectedLineStyle()); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java index 08e0ecd09..61cf28288 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java @@ -1,5 +1,6 @@ package com.fr.design.mainframe.mobile.ui.radiogroup; +import com.fr.base.BaseUtils; import com.fr.base.IconManager; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; @@ -12,11 +13,13 @@ import com.fr.design.web.CustomIconPane; import com.fr.form.ui.WidgetInfoConfig; import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; +import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.swing.event.EventListenerList; import javax.swing.plaf.basic.BasicButtonUI; import java.awt.*; import java.awt.event.ActionEvent; @@ -24,17 +27,102 @@ import java.awt.event.ActionListener; import java.util.ArrayList; public class IconConfigPane extends JPanel { + private final int northPaneWidth = 330; + private final Icon addIcon = BaseUtils.readIcon("/com/fr/design/images/buttonicon/icon_add.png"); + + private final Icon deleteIcon = BaseUtils.readIcon("/com/fr/design/images/buttonicon/icon_delete.png"); private UIButton editIconButton; private UIButton deleteIconButton; private String curIconName; private IconButton selectIconButton; private ArrayList iconButtons = new ArrayList(); - public IconConfigPane(int count) { - initComp(count); + private UIButton addCountButton; + + private UIButton deleteCountButton; + + private EventListenerList addCountListener = new EventListenerList(); + private EventListenerList deleteCountListener = new EventListenerList(); + + private JPanel northPane; + public IconConfigPane(int count, boolean canChangeCount) { + initComp(count, canChangeCount); + } + public void deleteCount() { + if (!iconButtons.isEmpty()) { + northPane.remove(iconButtons.get(iconButtons.size() - 1)); + iconButtons.remove(iconButtons.size() - 1); + adjustNorthPaneHeight(); + IconConfigPane.this.revalidate(); // 重新验证并更新布局 + IconConfigPane.this.repaint(); // 可选:刷新JPanel以更新界面显示 + deleteCountButton.setEnabled(!iconButtons.isEmpty()); + } + deleteCountButton.setEnabled(!iconButtons.isEmpty()); + } + + public void addCount() { + deleteCountButton.setEnabled(true); + IconButton iconButton = new IconButton(""); + iconButtons.add(iconButton); + int indexToInsert = northPane.getComponentCount() - 2; + deleteCountButton.setEnabled(!iconButtons.isEmpty()); + // 创建新的按钮并插入到倒数第三个组件后面 + northPane.add(iconButton, indexToInsert); + adjustNorthPaneHeight(); + IconConfigPane.this.revalidate(); // 重新验证并更新布局 + IconConfigPane.this.repaint(); // 可选:刷新JPanel以更新界面显示 + } + private void adjustNorthPaneHeight() { + northPane.setPreferredSize(new Dimension(northPaneWidth, getNorthPanelHeight(iconButtons.size()))); + } + + private int getNorthPanelHeight(int iconNum) { + return (int) Math.ceil((iconNum + 2) / 13.0) * 30; } - public void initComp(int count) { + private void initAddAndDeleteCountButton(Boolean deleteCountButtonEnabled) { + addCountButton = new UIButton(addIcon); + addCountButton.setPreferredSize(new Dimension(20, 20)); + addCountButton.setName("add"); + deleteCountButton = new UIButton(deleteIcon); + deleteCountButton.setPreferredSize(new Dimension(20, 20)); + deleteCountButton.setName("delete"); + deleteCountButton.setEnabled(deleteCountButtonEnabled); + addCountButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fireAddCountListener(); + } + }); + deleteCountButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fireDeleteCountListener(); + } + }); + northPane.add(addCountButton); + northPane.add(deleteCountButton); + } + public void refreshByIconNames(String[] names, Boolean canChangeCount) { + northPane.removeAll(); + northPane.setPreferredSize(new Dimension(northPaneWidth, getNorthPanelHeight(names.length))); + ArrayList newIconButtons = new ArrayList<>(); + for (String name : names) { + IconButton iconButton = new IconButton(name); + northPane.add(iconButton); + newIconButtons.add(iconButton); + } + iconButtons = newIconButtons; + if (canChangeCount) { + initAddAndDeleteCountButton(!ArrayUtils.isEmpty(names)); + } + IconConfigPane.this.revalidate(); + IconConfigPane.this.repaint(); + } + /* + 重载形式,默认没有增加/删减按钮 + */ + public void initComp(int count, boolean canChangeCount) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); JPanel panel = FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane(); panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); @@ -75,30 +163,73 @@ public class IconConfigPane extends JPanel { } }); deleteIconButton.setEnabled(false); - - + northPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + northPane.setPreferredSize(new Dimension(northPaneWidth, getNorthPanelHeight(count))); this.add(panel, BorderLayout.CENTER); - - JPanel northPane = new JPanel(); - northPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0)); for (int i = 0; i < count; i++) { IconButton iconButton = new IconButton(""); northPane.add(iconButton); iconButtons.add(iconButton); } + if (canChangeCount) { + initAddAndDeleteCountButton(count != 0); + } this.add(northPane, BorderLayout.NORTH); } public void setShowIconImage() { selectIconButton.setIconName(curIconName); } + /** + * 添加监听 + * + * @param changeListener 监听列表 + */ + public void addAddCountListener(ChangeListener changeListener) { + addCountListener.add(ChangeListener.class, changeListener); + } + + public void addDeleteCountListener(ChangeListener changeListener) { + deleteCountListener.add(ChangeListener.class, changeListener); + } + /** + * 点击增加按钮 + */ + public void fireAddCountListener() { + Object[] listeners = addCountListener.getListenerList(); + ChangeEvent e = null; + + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == ChangeListener.class) { + if (e == null) { + e = new ChangeEvent(this); + } + ((ChangeListener) listeners[i + 1]).stateChanged(e); + } + } + } + /** + * 点击删除按钮 + */ + public void fireDeleteCountListener() { + Object[] listeners = deleteCountListener.getListenerList(); + ChangeEvent e = null; + + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == ChangeListener.class) { + if (e == null) { + e = new ChangeEvent(this); + } + ((ChangeListener) listeners[i + 1]).stateChanged(e); + } + } + } public void populate(ArrayList iconArr) { for (int i = 0; i < iconButtons.size(); i++) { iconButtons.get(i).setIconName(iconArr.get(i)); } } - public ArrayList update() { ArrayList iconNames = new ArrayList(); for (int i = 0; i < iconButtons.size(); i++) { @@ -107,7 +238,6 @@ public class IconConfigPane extends JPanel { return iconNames; } - private class IconButton extends JToggleButton implements ActionListener { private String iconName; private Image iconImage = null; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java index 7288d3263..73a405dab 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java @@ -23,6 +23,8 @@ import com.fr.form.ui.mobile.radiogroup.ImageMobileStyle; import com.fr.general.FRFont; import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; @@ -36,12 +38,21 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { private JPanel scrollPanel; private UIComboBox custom; private JPanel centerPane; + // 按钮排布+按钮排布下拉框panel; + private JPanel buttonAlignPane; + // 固定列数 数字panel + private JPanel columnSizePane; private UISpinner leftSpinner; private UISpinner rightSpinner; private UISpinner topSpinner; private UISpinner bottomSpinner; + private UIComboBox layoutTypeCombo; + + private UIComboBox buttonAlignCombo; + + private UISpinner columnSizeSpinner; private IconConfigPane initialIconConfigPane; private IconConfigPane selectedIconConfigPane; @@ -141,27 +152,98 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { JPanel vPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topSpinnerPanel, bottomSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); JPanel hPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftSpinnerPanel, rightSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); + // 布局方式下拉框 + UILabel layoutTypeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Type")); + layoutTypeCombo = new UIComboBox(new String[]{ + Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Single_Line"), + Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Auto"), + Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Fixed") + }); + layoutTypeCombo.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); + layoutTypeCombo.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + System.out.println(layoutTypeCombo.getSelectedIndex()); + if (layoutTypeCombo.getSelectedIndex() == 0) { + buttonAlignPane.setVisible(true); + columnSizePane.setVisible(false); + } + if (layoutTypeCombo.getSelectedIndex() == 1) { + buttonAlignPane.setVisible(false); + columnSizePane.setVisible(false); + } + if (layoutTypeCombo.getSelectedIndex() == 2) { + buttonAlignPane.setVisible(false); + columnSizePane.setVisible(true); + } + } + }); + + // 按钮排布下拉框 + UILabel buttonAlignLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment")); + buttonAlignCombo = new UIComboBox(new String[]{ + Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Nature"), + Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Split"), + }); + buttonAlignCombo.setSelectedIndex(DesignerUtils.kAlignSpit); + buttonAlignCombo.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); + buttonAlignPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{buttonAlignLabel, buttonAlignCombo}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + + // 固定列数——数字输入框 + UILabel columnSizeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Fixed_Number")); + columnSizeSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + columnSizeSpinner.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); + columnSizePane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{columnSizeLabel, columnSizeSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + columnSizePane.setVisible(false); double p = TableLayout.PREFERRED; - double[] rowSize = {p, p}; + double[] rowSize = {p, p, p}; double[] columnSize = {p, p}; JPanel paddingPanel = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ {paddingHintLabel, vPaddingSpinnerPanel}, {emptyHintLabel, hPaddingSpinnerPanel}, + {layoutTypeLabel, layoutTypeCombo}, }, rowSize, columnSize, 10); centerPane.add(paddingPanel); + centerPane.add(buttonAlignPane); + centerPane.add(columnSizePane); } private void addIconPane() { - centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon"))); UILabel initialLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon_Init")); UILabel selectedLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon_Select")); - - initialIconConfigPane = new IconConfigPane(8); - selectedIconConfigPane = new IconConfigPane(8); - + initialIconConfigPane = new IconConfigPane(8, true); + selectedIconConfigPane = new IconConfigPane(8, true); + initialIconConfigPane.addAddCountListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + initialIconConfigPane.addCount(); + selectedIconConfigPane.addCount(); + } + }); + initialIconConfigPane.addDeleteCountListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + initialIconConfigPane.deleteCount(); + selectedIconConfigPane.deleteCount(); + } + }); + selectedIconConfigPane.addAddCountListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + initialIconConfigPane.addCount(); + selectedIconConfigPane.addCount(); + } + }); + selectedIconConfigPane.addDeleteCountListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + initialIconConfigPane.deleteCount(); + selectedIconConfigPane.deleteCount(); + } + }); JPanel container = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); JPanel initialPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); @@ -175,7 +257,6 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { container.add(selectedPane); centerPane.add(container); - } private void addFontPane() { @@ -205,8 +286,11 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { rightSpinner.setValue(mobileStyle.getRightPadding()); topSpinner.setValue(mobileStyle.getTopPadding()); bottomSpinner.setValue(mobileStyle.getBottomPadding()); - initialIconConfigPane.populate(new ArrayList<>(Arrays.asList(mobileStyle.getInitialIconNames()))); - selectedIconConfigPane.populate(new ArrayList<>(Arrays.asList(mobileStyle.getSelectedIconNames()))); + layoutTypeCombo.setSelectedIndex(mobileStyle.getButtonLayoutType()); + buttonAlignCombo.setSelectedIndex(mobileStyle.getButtonAlign()); + columnSizeSpinner.setValue(mobileStyle.getButtonColumnSize()); + initialIconConfigPane.refreshByIconNames(mobileStyle.getInitialIconNames(), true); + selectedIconConfigPane.refreshByIconNames(mobileStyle.getSelectedIconNames(), true); if(mobileStyle.getInitialFont() != null) { initialFontConfPane.populate(mobileStyle.getInitialFont()); } @@ -224,6 +308,9 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { mobileStyle.setRightPadding(rightSpinner.getValue()); mobileStyle.setTopPadding(topSpinner.getValue()); mobileStyle.setBottomPadding(bottomSpinner.getValue()); + mobileStyle.setButtonLayoutType(layoutTypeCombo.getSelectedIndex()); + mobileStyle.setButtonAlign(buttonAlignCombo.getSelectedIndex()); + mobileStyle.setButtonColumnSize((int)columnSizeSpinner.getValue()); ArrayList initialIconNamesList = initialIconConfigPane.update(); ArrayList selectedIconNamesList = selectedIconConfigPane.update(); mobileStyle.setInitialIconNames(initialIconNamesList.toArray(new String[initialIconNamesList.size()])); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/UnitedCustomDefinePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/UnitedCustomDefinePane.java index 8d9b42574..7d39b2ad0 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/UnitedCustomDefinePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/UnitedCustomDefinePane.java @@ -41,6 +41,7 @@ public class UnitedCustomDefinePane extends MobileStyleCustomDefinePane { private UISpinner topSpinner; private UISpinner bottomSpinner; + private UIComboBox buttonAlignCombo; private NewColorSelectBox initialColorSelectBox; private NewColorSelectBox selectedColorSelectBox; @@ -117,7 +118,7 @@ public class UnitedCustomDefinePane extends MobileStyleCustomDefinePane { private void addPaddingPane() { centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout"))); - + UILabel buttonAlignLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment")); UILabel paddingHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Button_Padding")); UILabel emptyHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("")); @@ -140,13 +141,19 @@ public class UnitedCustomDefinePane extends MobileStyleCustomDefinePane { JPanel vPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topSpinnerPanel, bottomSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); JPanel hPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftSpinnerPanel, rightSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); - + // 按钮排布下拉框 + buttonAlignCombo = new UIComboBox(new String[]{ + Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Nature"), + Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Split"), + }); + buttonAlignCombo.setPreferredSize(new Dimension(DesignerUtils.NORMAL_COMBO_WIDTH, 20)); double p = TableLayout.PREFERRED; - double[] rowSize = {p, p}; + double[] rowSize = {p, p, p}; double[] columnSize = {p, p}; JPanel paddingPanel = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ {paddingHintLabel, vPaddingSpinnerPanel}, {emptyHintLabel, hPaddingSpinnerPanel}, + {buttonAlignLabel, buttonAlignCombo} }, rowSize, columnSize, 10); centerPane.add(paddingPanel); @@ -234,6 +241,7 @@ public class UnitedCustomDefinePane extends MobileStyleCustomDefinePane { rightSpinner.setValue(mobileStyle.getRightPadding()); topSpinner.setValue(mobileStyle.getTopPadding()); bottomSpinner.setValue(mobileStyle.getBottomPadding()); + buttonAlignCombo.setSelectedIndex(mobileStyle.getButtonAlign()); initialColorSelectBox.setSelectObject(mobileStyle.getInitialBackgroundColor()); selectedColorSelectBox.setSelectObject(mobileStyle.getSelectedBackgroundColor()); borderLineCombo.setSelectedLineStyle(mobileStyle.getBorderType()); @@ -256,6 +264,7 @@ public class UnitedCustomDefinePane extends MobileStyleCustomDefinePane { mobileStyle.setRightPadding(rightSpinner.getValue()); mobileStyle.setTopPadding(topSpinner.getValue()); mobileStyle.setBottomPadding(bottomSpinner.getValue()); + mobileStyle.setButtonAlign(buttonAlignCombo.getSelectedIndex()); mobileStyle.setInitialBackgroundColor(initialColorSelectBox.getSelectObject()); mobileStyle.setSelectedBackgroundColor(selectedColorSelectBox.getSelectObject()); mobileStyle.setBorderType(borderLineCombo.getSelectedLineStyle()); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java index bcadac1c7..9bc412cef 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java @@ -16,10 +16,14 @@ import java.awt.*; public class DesignerUtils { public static final int NORMAL_COMBO_WIDTH = 152; + + public static final int LARGE_COMBO_WIDTH = 174; public static final int kDefaultHorizontalPadding = 0; public static final int kDefaultVerticalPadding = 15; public static final int kAlignLeft = 0; public static final int kAlignCenter = 1; + + public static final int kAlignSpit = 1; public static final int[] BORDER_LINE_STYLE_ARRAY = new int[]{ Constants.LINE_NONE, Constants.LINE_THIN, diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/MobileStyleProviderManager.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/MobileStyleProviderManager.java index 7c3194ba6..96113e90a 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/MobileStyleProviderManager.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/MobileStyleProviderManager.java @@ -1,5 +1,8 @@ package com.fr.design.mainframe.mobile.utils; +import com.fr.design.mainframe.mobile.provider.checkboxgroup.CapsuleCheckboxGroupStyleProvider; +import com.fr.design.mainframe.mobile.provider.checkboxgroup.ImageCheckboxGroupStyleProvider; +import com.fr.design.mainframe.mobile.provider.checkboxgroup.UnitedCheckboxGroupStyleProvider; import com.fr.design.mainframe.mobile.provider.combo.SimpleComboCheckBoxStyleProvider; import com.fr.design.mainframe.mobile.provider.combo.SimpleComboStyleProvider; import com.fr.design.mainframe.mobile.provider.date.NavigationStyleProvider; @@ -26,6 +29,9 @@ public class MobileStyleProviderManager { add(new CapsuleRadioGroupStyleProvider()); add(new UnitedRadioGroupStyleProvider()); add(new ImageRadioGroupStyleProvider()); + add(new CapsuleCheckboxGroupStyleProvider()); + add(new UnitedCheckboxGroupStyleProvider()); + add(new ImageCheckboxGroupStyleProvider()); }}; private static Set mobileParamUIProviderSet = new HashSet() {{ add(new MobileTopParamStyleProvider()); diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_add.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_add.png new file mode 100644 index 0000000000000000000000000000000000000000..170c4027dba5c6bb75ce1b6d7f7755f7a96cbb17 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBeyFF5V@L(#+sOxc8w_}uWsfMNvTgp)HnTA= zN#w`!kQMV+saxu+cL_;KaGunjQdzbn!m*jxer7_0Yo&fJYwU_$zdzW8F`f&A{H+5jk``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBzPYE1V@L(#+tZ$c3<^BX7aN2w2>cgX#5iZl zQAbO|x%-@-#WO8oI3+nLIlZ~t*K_YZlO20&E^QZcPUd20W Date: Wed, 24 Jan 2024 16:42:40 +0800 Subject: [PATCH 3/8] =?UTF-8?q?REPORT-111299=20=E6=8E=A7=E4=BB=B6=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=A0=B7=E5=BC=8F-=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E7=BB=84=E6=89=A9=E5=B1=95=E6=A0=B7=E5=BC=8F=20feat=EF=BC=9A?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=8D=95=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E6=A0=B7=E5=BC=8F=EF=BC=9B=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java | 3 --- .../com/fr/design/mainframe/mobile/utils/DesignerUtils.java | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java index 73a405dab..776ec6584 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java @@ -29,7 +29,6 @@ import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; -import java.util.Arrays; public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { @@ -163,7 +162,6 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { layoutTypeCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { - System.out.println(layoutTypeCombo.getSelectedIndex()); if (layoutTypeCombo.getSelectedIndex() == 0) { buttonAlignPane.setVisible(true); columnSizePane.setVisible(false); @@ -185,7 +183,6 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Nature"), Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Split"), }); - buttonAlignCombo.setSelectedIndex(DesignerUtils.kAlignSpit); buttonAlignCombo.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); buttonAlignPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{buttonAlignLabel, buttonAlignCombo}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java index 9bc412cef..89fa5e520 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java @@ -23,7 +23,7 @@ public class DesignerUtils { public static final int kAlignLeft = 0; public static final int kAlignCenter = 1; - public static final int kAlignSpit = 1; + public static final int kAlignSplit = 1; public static final int[] BORDER_LINE_STYLE_ARRAY = new int[]{ Constants.LINE_NONE, Constants.LINE_THIN, From e913f94dab117988babf24f2fab97cfae1d967ff Mon Sep 17 00:00:00 2001 From: "Crawford.Zhou" Date: Thu, 25 Jan 2024 10:12:32 +0800 Subject: [PATCH 4/8] =?UTF-8?q?REPORT-111299=20=E6=8E=A7=E4=BB=B6=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=A0=B7=E5=BC=8F-=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E7=BB=84=E6=89=A9=E5=B1=95=E6=A0=B7=E5=BC=8F=20feat=EF=BC=9A?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=8D=95=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E6=A0=B7=E5=BC=8F=EF=BC=9B=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CapsuleCheckboxGroupStyleProvider.java | 6 + .../ImageCheckboxGroupStyleProvider.java | 7 +- .../UnitedCheckboxGroupStyleProvider.java | 7 +- .../radiogroup/CapsuleCustomDefinePane.java | 104 +++++++++------ .../mobile/ui/radiogroup/IconConfigPane.java | 63 +++++++--- .../ui/radiogroup/ImageCustomDefinePane.java | 118 +++++++++++------- .../mainframe/mobile/utils/DesignerUtils.java | 7 +- 7 files changed, 215 insertions(+), 97 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java index fa2d9d905..3f84336c3 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/CapsuleCheckboxGroupStyleProvider.java @@ -7,6 +7,12 @@ import com.fr.design.mainframe.mobile.ui.radiogroup.CapsuleCustomDefinePane; import com.fr.form.ui.mobile.MobileStyle; import com.fr.form.ui.mobile.radiogroup.CapsuleMobileStyle; +/** + * 移动端复选框provider + * @author crawford.zhou + * @since 11.0 + * Created on 2024/1/25 + */ public class CapsuleCheckboxGroupStyleProvider extends AbstractMobileWidgetStyleProvider { @Override public Class classForMobileStyle() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java index fb7224aa1..bafb50a43 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/ImageCheckboxGroupStyleProvider.java @@ -6,7 +6,12 @@ import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; import com.fr.design.mainframe.mobile.ui.radiogroup.ImageCustomDefinePane; import com.fr.form.ui.mobile.MobileStyle; import com.fr.form.ui.mobile.radiogroup.ImageMobileStyle; - +/** + * 移动端复选框provider + * @author crawford.zhou + * @since 11.0 + * Created on 2024/1/25 + */ public class ImageCheckboxGroupStyleProvider extends AbstractMobileWidgetStyleProvider { @Override public Class classForMobileStyle() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java index e22aa9223..81249fee8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/provider/checkboxgroup/UnitedCheckboxGroupStyleProvider.java @@ -6,7 +6,12 @@ import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; import com.fr.design.mainframe.mobile.ui.radiogroup.UnitedCustomDefinePane; import com.fr.form.ui.mobile.MobileStyle; import com.fr.form.ui.mobile.radiogroup.UnitedMobileStyle; - +/** + * 移动端复选框provider + * @author crawford.zhou + * @since 11.0 + * Created on 2024/1/25 + */ public class UnitedCheckboxGroupStyleProvider extends AbstractMobileWidgetStyleProvider { @Override public Class classForMobileStyle() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java index ab5b64a99..1d6987526 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/CapsuleCustomDefinePane.java @@ -133,27 +133,10 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { return FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 10); } - private void addPaddingPane() { - double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p}; - double[] columnSize = {p, p}; - centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout"))); - UILabel paddingHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Button_Padding")); - UILabel emptyHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("")); - UILabel leftLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Left")); - leftSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); - - UILabel rightLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Right")); - rightSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); - - UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Top")); - topSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); - - UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Bottom")); - bottomSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); - - // 布局方式下拉框 - UILabel layoutTypeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Type")); + /** + * 初始化布局方式下拉框 + */ + private void initLayoutCombo() { layoutTypeCombo = new UIComboBox(new String[]{ Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Single_Line"), Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Auto"), @@ -163,22 +146,26 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { layoutTypeCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { - if (layoutTypeCombo.getSelectedIndex() == 0) { + if (layoutTypeCombo.getSelectedIndex() == DesignerUtils.K_LAYOUT_SINGLE) { buttonAlignPane.setVisible(true); columnSizePane.setVisible(false); } - if (layoutTypeCombo.getSelectedIndex() == 1) { + if (layoutTypeCombo.getSelectedIndex() == DesignerUtils.K_LAYOUT_AUTO) { buttonAlignPane.setVisible(false); columnSizePane.setVisible(false); } - if (layoutTypeCombo.getSelectedIndex() == 2) { + if (layoutTypeCombo.getSelectedIndex() == DesignerUtils.K_LAYOUT_FIXED) { buttonAlignPane.setVisible(false); columnSizePane.setVisible(true); } } }); + } - // 按钮排布下拉框 + /** + * 初始化按钮排布面板 + */ + private void initButtonAlignPane() { UILabel buttonAlignLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment")); buttonAlignCombo = new UIComboBox(new String[]{ Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Nature"), @@ -190,24 +177,70 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL ); + } - // 固定列数——数字输入框 + /** + * 初始化固定列数面板 + */ + private void initColumnSizePane() { UILabel columnSizeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Fixed_Number")); - columnSizeSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, 1); + columnSizeSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.INITIAL_COLUMN_SIZE); columnSizeSpinner.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); columnSizePane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{columnSizeLabel, columnSizeSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); columnSizePane.setVisible(false); + } - leftAlignRadioButton = new JRadioButton(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Left"), true); - centerAlignRadioButton = new JRadioButton(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Center"), false); + private JPanel initVPaddingConfig() { - JPanel leftSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftLabel, leftSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); - JPanel rightSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{rightLabel, rightSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Top")); + topSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + + UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Bottom")); + bottomSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); JPanel topSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topLabel, topSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); JPanel bottomSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{bottomLabel, bottomSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); - JPanel vPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topSpinnerPanel, bottomSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); - JPanel hPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftSpinnerPanel, rightSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); + return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topSpinnerPanel, bottomSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); + + } + private JPanel initHPaddingConfig() { + UILabel leftLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Left")); + leftSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); + + UILabel rightLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Right")); + rightSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); + JPanel leftSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftLabel, leftSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + JPanel rightSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{rightLabel, rightSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + + return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftSpinnerPanel, rightSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); + } + + private void addPaddingPane() { + double p = TableLayout.PREFERRED; + double[] rowSize = {p, p, p}; + double[] columnSize = {p, p}; + centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout"))); + UILabel paddingHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Button_Padding")); + UILabel emptyHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("")); + UILabel leftLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Left")); + leftSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); + + UILabel rightLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Right")); + rightSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); + + UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Top")); + topSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + + UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Bottom")); + bottomSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + + UILabel layoutTypeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Type")); + initLayoutCombo(); + initButtonAlignPane(); + initColumnSizePane(); + leftAlignRadioButton = new JRadioButton(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Left"), true); + centerAlignRadioButton = new JRadioButton(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Center"), false); + JPanel layoutTypePanel = TableLayoutHelper.createGapTableLayoutPane( new Component[][]{new Component[]{layoutTypeCombo}}, @@ -219,10 +252,9 @@ public class CapsuleCustomDefinePane extends MobileStyleCustomDefinePane { ButtonGroup layoutRadioButtonGroup = new ButtonGroup(); layoutRadioButtonGroup.add(leftAlignRadioButton); layoutRadioButtonGroup.add(centerAlignRadioButton); - JPanel paddingPanel = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ - {paddingHintLabel, vPaddingSpinnerPanel}, - {emptyHintLabel, hPaddingSpinnerPanel}, + {paddingHintLabel, initVPaddingConfig()}, + {emptyHintLabel, initHPaddingConfig()}, {layoutTypeLabel, layoutTypePanel}, }, rowSize, columnSize, 10); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java index 61cf28288..17d995d3c 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/IconConfigPane.java @@ -28,6 +28,7 @@ import java.util.ArrayList; public class IconConfigPane extends JPanel { private final int northPaneWidth = 330; + private final int listenerStep = 2; private final Icon addIcon = BaseUtils.readIcon("/com/fr/design/images/buttonicon/icon_add.png"); private final Icon deleteIcon = BaseUtils.readIcon("/com/fr/design/images/buttonicon/icon_delete.png"); @@ -45,9 +46,17 @@ public class IconConfigPane extends JPanel { private EventListenerList deleteCountListener = new EventListenerList(); private JPanel northPane; + + public IconConfigPane(int count) { + initComp(count, false); + } public IconConfigPane(int count, boolean canChangeCount) { initComp(count, canChangeCount); } + + /** + * 删除一个图标 + */ public void deleteCount() { if (!iconButtons.isEmpty()) { northPane.remove(iconButtons.get(iconButtons.size() - 1)); @@ -59,7 +68,9 @@ public class IconConfigPane extends JPanel { } deleteCountButton.setEnabled(!iconButtons.isEmpty()); } - + /** + * 添加一个图标 + */ public void addCount() { deleteCountButton.setEnabled(true); IconButton iconButton = new IconButton(""); @@ -103,6 +114,12 @@ public class IconConfigPane extends JPanel { northPane.add(addCountButton); northPane.add(deleteCountButton); } + + /** + * 根据图标名称刷新字体配置面板 + * @param names 字体名称 + * @param canChangeCount 是否支持改变数目 + */ public void refreshByIconNames(String[] names, Boolean canChangeCount) { northPane.removeAll(); northPane.setPreferredSize(new Dimension(northPaneWidth, getNorthPanelHeight(names.length))); @@ -119,17 +136,14 @@ public class IconConfigPane extends JPanel { IconConfigPane.this.revalidate(); IconConfigPane.this.repaint(); } - /* - 重载形式,默认没有增加/删减按钮 + + /** + * 初始化编辑按钮 */ - public void initComp(int count, boolean canChangeCount) { - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - JPanel panel = FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane(); - panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); + private void initEditIconButton() { editIconButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Edit")); editIconButton.setFont(FRFont.getInstance("Helvetica", Font.PLAIN, 12, Color.decode("#3A383A"))); editIconButton.setPreferredSize(new Dimension(62, 20)); - panel.add(editIconButton); editIconButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final CustomIconPane cip = new CustomIconPane(){ @@ -150,11 +164,14 @@ public class IconConfigPane extends JPanel { } }); editIconButton.setEnabled(false); - + } + /** + * 初始化删除按钮 + */ + private void initDeleteIconButton() { deleteIconButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Delete")); deleteIconButton.setFont(FRFont.getInstance("Helvetica", Font.PLAIN, 12, Color.decode("#3A383A"))); deleteIconButton.setPreferredSize(new Dimension(62, 20)); - panel.add(deleteIconButton); deleteIconButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -163,6 +180,20 @@ public class IconConfigPane extends JPanel { } }); deleteIconButton.setEnabled(false); + } + /** + * 重载形式 + * @param count 图标数目 + * @param canChangeCount 是否可以动态增减 + */ + public void initComp(int count, boolean canChangeCount) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + JPanel panel = FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane(); + panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); + initEditIconButton(); + initDeleteIconButton(); + panel.add(editIconButton); + panel.add(deleteIconButton); northPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); northPane.setPreferredSize(new Dimension(northPaneWidth, getNorthPanelHeight(count))); this.add(panel, BorderLayout.CENTER); @@ -181,14 +212,16 @@ public class IconConfigPane extends JPanel { selectIconButton.setIconName(curIconName); } /** - * 添加监听 - * + * 添加事件的监听 * @param changeListener 监听列表 */ public void addAddCountListener(ChangeListener changeListener) { addCountListener.add(ChangeListener.class, changeListener); } - + /** + * 删除事件的监听 + * @param changeListener 监听列表 + */ public void addDeleteCountListener(ChangeListener changeListener) { deleteCountListener.add(ChangeListener.class, changeListener); } @@ -199,7 +232,7 @@ public class IconConfigPane extends JPanel { Object[] listeners = addCountListener.getListenerList(); ChangeEvent e = null; - for (int i = listeners.length - 2; i >= 0; i -= 2) { + for (int i = listeners.length - listenerStep; i >= 0; i -= listenerStep) { if (listeners[i] == ChangeListener.class) { if (e == null) { e = new ChangeEvent(this); @@ -215,7 +248,7 @@ public class IconConfigPane extends JPanel { Object[] listeners = deleteCountListener.getListenerList(); ChangeEvent e = null; - for (int i = listeners.length - 2; i >= 0; i -= 2) { + for (int i = listeners.length - listenerStep; i >= 0; i -= listenerStep) { if (listeners[i] == ChangeListener.class) { if (e == null) { e = new ChangeEvent(this); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java index 776ec6584..0284f28c5 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/radiogroup/ImageCustomDefinePane.java @@ -125,34 +125,7 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { return FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 10); } - private void addPaddingPane() { - centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout"))); - - UILabel paddingHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Button_Padding")); - UILabel emptyHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("")); - - UILabel leftLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Left")); - leftSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); - - UILabel rightLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Right")); - rightSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); - - UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Top")); - topSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); - - UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Bottom")); - bottomSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); - - JPanel leftSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftLabel, leftSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); - JPanel rightSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{rightLabel, rightSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); - JPanel topSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topLabel, topSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); - JPanel bottomSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{bottomLabel, bottomSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); - - JPanel vPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topSpinnerPanel, bottomSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); - JPanel hPaddingSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftSpinnerPanel, rightSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); - - // 布局方式下拉框 - UILabel layoutTypeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Type")); + private void initLayoutCombo() { layoutTypeCombo = new UIComboBox(new String[]{ Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Single_Line"), Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Auto"), @@ -162,22 +135,26 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { layoutTypeCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { - if (layoutTypeCombo.getSelectedIndex() == 0) { + if (layoutTypeCombo.getSelectedIndex() == DesignerUtils.K_LAYOUT_SINGLE) { buttonAlignPane.setVisible(true); columnSizePane.setVisible(false); } - if (layoutTypeCombo.getSelectedIndex() == 1) { + if (layoutTypeCombo.getSelectedIndex() == DesignerUtils.K_LAYOUT_AUTO) { buttonAlignPane.setVisible(false); columnSizePane.setVisible(false); } - if (layoutTypeCombo.getSelectedIndex() == 2) { + if (layoutTypeCombo.getSelectedIndex() == DesignerUtils.K_LAYOUT_FIXED) { buttonAlignPane.setVisible(false); columnSizePane.setVisible(true); } } }); + } - // 按钮排布下拉框 + /** + * 初始化按钮排布面板 + */ + private void initButtonAlignPane() { UILabel buttonAlignLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment")); buttonAlignCombo = new UIComboBox(new String[]{ Toolkit.i18nText("Fine-Plugin-RadioGroup_Alignment_Nature"), @@ -185,19 +162,61 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { }); buttonAlignCombo.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); buttonAlignPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{buttonAlignLabel, buttonAlignCombo}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + } - // 固定列数——数字输入框 + /** + * 初始化固定列数面板 + */ + private void initColumnSizePane() { UILabel columnSizeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Fixed_Number")); - columnSizeSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + columnSizeSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.INITIAL_COLUMN_SIZE); columnSizeSpinner.setPreferredSize(new Dimension(DesignerUtils.LARGE_COMBO_WIDTH, 20)); columnSizePane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{columnSizeLabel, columnSizeSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); columnSizePane.setVisible(false); + } + + private JPanel initVPaddingConfig() { + + UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Top")); + topSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + + UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Bottom")); + bottomSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultVerticalPadding); + JPanel topSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topLabel, topSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + JPanel bottomSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{bottomLabel, bottomSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + + return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{topSpinnerPanel, bottomSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); + + } + private JPanel initHPaddingConfig() { + UILabel leftLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Left")); + leftSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); + + UILabel rightLabel = new UILabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Padding_Right")); + rightSpinner = new UISpinner(0, Integer.MAX_VALUE, 1, DesignerUtils.kDefaultHorizontalPadding); + JPanel leftSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftLabel, leftSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + JPanel rightSpinnerPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{rightLabel, rightSpinner}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_SMALL); + + return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{leftSpinnerPanel, rightSpinnerPanel}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, LayoutConstants.VGAP_SMALL); + } + + private void addPaddingPane() { + centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout"))); + + UILabel paddingHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Button_Padding")); + UILabel emptyHintLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("")); + + UILabel layoutTypeLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Layout_Type")); + initLayoutCombo(); + initButtonAlignPane(); + initColumnSizePane(); + double p = TableLayout.PREFERRED; double[] rowSize = {p, p, p}; double[] columnSize = {p, p}; JPanel paddingPanel = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ - {paddingHintLabel, vPaddingSpinnerPanel}, - {emptyHintLabel, hPaddingSpinnerPanel}, + {paddingHintLabel, initVPaddingConfig()}, + {emptyHintLabel, initHPaddingConfig()}, {layoutTypeLabel, layoutTypeCombo}, }, rowSize, columnSize, 10); @@ -206,13 +225,11 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { centerPane.add(columnSizePane); } - private void addIconPane() { - centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon"))); - - UILabel initialLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon_Init")); - UILabel selectedLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon_Select")); + /** + * 初始化默认字体配置面版 + */ + private void initInitialIconConfigPane() { initialIconConfigPane = new IconConfigPane(8, true); - selectedIconConfigPane = new IconConfigPane(8, true); initialIconConfigPane.addAddCountListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { @@ -227,6 +244,13 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { selectedIconConfigPane.deleteCount(); } }); + } + + /** + * 初始化选择字体配置面板 + */ + private void initSelectedIconConfigPane() { + selectedIconConfigPane = new IconConfigPane(8, true); selectedIconConfigPane.addAddCountListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { @@ -241,6 +265,14 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { selectedIconConfigPane.deleteCount(); } }); + } + private void addIconPane() { + centerPane.add(DesignerUtils.createTitleSplitLine(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon"))); + + UILabel initialLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon_Init")); + UILabel selectedLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Icon_Select")); + initInitialIconConfigPane(); + initSelectedIconConfigPane(); JPanel container = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); JPanel initialPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); @@ -261,7 +293,7 @@ public class ImageCustomDefinePane extends MobileStyleCustomDefinePane { UILabel initialFontLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Font_init")); initialFontConfPane = new FontConfigPane(); - initialFontConfPane.setFontColor(new Color(204, 204, 204)); + initialFontConfPane.setFontColor(new Color(102, 102, 102)); JPanel fontPanel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{initialFontLabel, initialFontConfPane}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_MEDIUM); centerPane.add(fontPanel); UILabel selectedFontLabel = DesignerUtils.createConfigLabel(Toolkit.i18nText("Fine-Plugin-RadioGroup_Font_Select")); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java index 89fa5e520..a2e8d0656 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java @@ -23,7 +23,12 @@ public class DesignerUtils { public static final int kAlignLeft = 0; public static final int kAlignCenter = 1; - public static final int kAlignSplit = 1; + public static final int K_LAYOUT_SINGLE = 0; + public static final int K_LAYOUT_AUTO = 1; + public static final int K_LAYOUT_FIXED = 2; + + public static final int INITIAL_COLUMN_SIZE = 1; + public static final int[] BORDER_LINE_STYLE_ARRAY = new int[]{ Constants.LINE_NONE, Constants.LINE_THIN, From 6b5a9dbee713b393c9f0e197990492a183e5aca3 Mon Sep 17 00:00:00 2001 From: obo Date: Mon, 29 Jan 2024 09:42:28 +0800 Subject: [PATCH 5/8] =?UTF-8?q?REPORT-111619=20=E6=8E=A7=E4=BB=B6=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA-=E6=9B=B4=E5=A4=9A=E7=9A=84=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E9=85=8D=E7=BD=AE--=E6=8A=A5=E8=A1=A8=E6=94=AF=E6=92=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widget/DesktopWidgetStyleEditPane.java | 110 ++++++--- .../widget/MobileWidgetStyleEditPane.java | 13 ++ .../edit/widget/WidgetStyleEditPane.java | 58 ++++- .../theme/panel/ButtonStyleDefinedPane.java | 2 - .../theme/panel/ControlPreviewCell.java | 20 +- .../panel/ControlPreviewCellWithIcon.java | 9 +- .../theme/panel/RoundControlPreviewCell.java | 3 +- .../util/ThemeTextStylePaneCreator.java | 40 ---- .../util/WidgetStyleComponentCombiner.java | 147 ++++++++++++ .../util/WidgetThemeDesignerUtils.java | 32 +++ .../DisplayEnhanceMobileStyleDefinePane.java | 84 ++++++- .../pane/FreeButtonMobileStyleDefinePane.java | 55 ----- .../pane/IconColorMobileStyleDefinePane.java | 36 +++ .../pane/LabelMobileStyleDefinePane.java | 44 ---- .../pane/TextAreaMobileStyleDefinePane.java | 33 +++ .../DisplayEnhanceMobileStyleFactory.java | 16 +- ...dgetThemeMobileStyleDefinePaneCreator.java | 55 +++-- .../widgettheme/BaseStyleSettingPane.java | 213 ++++++++++-------- .../design/widgettheme/LabelSettingPane.java | 15 +- .../widgettheme/ParaButtonSettingPane.java | 6 +- .../widgettheme/ParaEditorSettingPane.java | 13 +- .../ParaNormalButtonSettingPane.java | 3 + .../ParaSelectEditorSettingPane.java | 10 +- .../ParaTreeEditorSettingPane.java | 2 +- .../fr/design/widgettheme/StyleSetting.java | 42 +++- .../widgettheme/common/ButtonSettingPane.java | 9 +- .../widgettheme/common/EditorSettingPane.java | 17 +- .../common/NormalButtonSettingPane.java | 4 +- .../common/SelectEditorSettingPane.java | 8 +- .../common/TreeEditorSettingPane.java | 9 +- 30 files changed, 716 insertions(+), 392 deletions(-) delete mode 100644 designer-base/src/main/java/com/fr/widgettheme/util/ThemeTextStylePaneCreator.java create mode 100644 designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java create mode 100644 designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/IconColorMobileStyleDefinePane.java create mode 100644 designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/TextAreaMobileStyleDefinePane.java diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java index aca4b690d..bc21732be 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java @@ -2,20 +2,23 @@ package com.fr.widgettheme.theme.edit.widget; import com.fr.base.background.ColorBackground; import com.fr.base.theme.TemplateTheme; +import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.style.color.NewColorSelectBox; +import com.fr.design.utils.DesignUtils; +import com.fr.locale.InterProviderFactory; +import com.fr.stable.StringUtils; +import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.BorderStyle; import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle; import com.fr.widgettheme.theme.widget.style.ThemeTextStyle; import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle; -import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.FRGUIPaneFactory; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; -import com.fr.widgettheme.util.ThemeTextStylePaneCreator; +import com.fr.widgettheme.util.WidgetStyleComponentCombiner; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; -import javax.swing.ButtonGroup; -import javax.swing.JPanel; +import java.awt.Color; import java.awt.Component; @@ -27,52 +30,47 @@ import java.awt.Component; * Created on 2023/3/28 */ public class DesktopWidgetStyleEditPane extends WidgetStyleEditPane { - // 风格1 - protected UIRadioButton style1; - // 风格2 - protected UIRadioButton style2; + + /** + * 字体名选择器 + */ + protected UIComboBox fontNameSelectBox; /** * 下拉面板背景颜色 */ private NewColorSelectBox selectBackgroundColorBox; + public DesktopWidgetStyleEditPane() { super(); } @Override public Component[][] generateComponent() { - initStyleEditor(); initSelectBackgroundColorBox(); - // 容纳风格1和风格2的panel - JPanel stylePane = new JPanel(FRGUIPaneFactory.createBoxFlowLayout()); - stylePane.add(style1); - stylePane.add(style2); - + initFontNameSelectBox(); return new Component[][]{ new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")), colorSelectBox}, - new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Style")), stylePane}, + new Component[]{WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Widget_Background")), WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, colorSelectBox.getPreferredSize().width)}, new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line")), lineComboBox}, + new Component[]{null, lineComboColorSelectBox}, new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius")), borderRadiusSpinner}, - new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")), ThemeTextStylePaneCreator.create(fontSizePane, fontColorButton)}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Icon_Color")), iconColorSelectBox}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")), fontNameSelectBox}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")), WidgetStyleComponentCombiner.combineTextStyleComponent(fontSizePane, fontColorButton, bold, italic)}, new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Background_Select_Box")), selectBackgroundColorBox} }; } - - private void initStyleEditor() { - style1 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_1")); - style2 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_2")); - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(style1); - buttonGroup.add(style2); - } - private void initSelectBackgroundColorBox() { selectBackgroundColorBox = new NewColorSelectBox(140, true); selectBackgroundColorBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR); } + private void initFontNameSelectBox() { + fontNameSelectBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report()); + } + @Override public void populateBean(T t) { ThemedWidgetStyle style = (ThemedWidgetStyle) t.getWidgetStyle(); @@ -80,17 +78,12 @@ public class DesktopWidgetStyleEditPane extends WidgetS style = new ThemedWidgetStyle(); t.setWidgetStyle(style); } - if (style.getStyleType() == 1) { - style1.setSelected(true); - } else { - style2.setSelected(true); - } colorSelectBox.setSelectObject(style.getThemeColor()); - lineComboBox.setSelectedLineStyle(style.getBorderStyle().getLineType()); - borderRadiusSpinner.setValue(style.getBorderStyle().getRadius()); - fontSizePane.setValue(style.getTextStyle().getFontSize()); - fontColorButton.setColor(style.getTextStyle().getFontColor()); selectBackgroundColorBox.setSelectObject(style.getSelectBackgroundColor()); + iconColorSelectBox.setSelectObject(style.getIconColor()); + populateBorder(style); + populateTextStyle(style); + populateWidgetBackground(style); } @Override @@ -100,22 +93,65 @@ public class DesktopWidgetStyleEditPane extends WidgetS style = new ThemedWidgetStyle(); t.setWidgetStyle(style); } + updateBorderStyle(style); + updateTextStyle(style); + updateButtonBackground(style); + updateWidgetBackground(style); style.setThemeColor(colorSelectBox.getSelectObject()); + style.setSelectBackgroundColor(selectBackgroundColorBox.getSelectObject()); + style.setIconColor(iconColorSelectBox.getSelectObject()); + } + + private void updateBorderStyle(ThemedWidgetStyle style) { BorderStyle borderStyle = new BorderStyle(); borderStyle.setLineType(lineComboBox.getSelectedLineStyle()); borderStyle.setRadius((int) borderRadiusSpinner.getValue()); + borderStyle.setBorderColor(lineComboColorSelectBox.getSelectObject()); style.setBorderStyle(borderStyle); + } + + private void updateTextStyle(ThemedWidgetStyle style) { ThemeTextStyle textStyle = new ThemeTextStyle(); textStyle.setFontSize(fontSizePane.getValue()); textStyle.setFontColor(fontColorButton.getColor()); + textStyle.setName((String) fontNameSelectBox.getSelectedItem()); + textStyle.setBold(bold.isSelected()); + textStyle.setItalic(italic.isSelected()); style.setTextStyle(textStyle); + } + + private void updateButtonBackground(ThemedWidgetStyle style) { ButtonBackgroundStyle buttonBackgroundStyle = new ButtonBackgroundStyle(); ColorBackground buttonBackground = ColorBackground.getInstance(style.getThemeColor()); buttonBackgroundStyle.setInitialBackground(buttonBackground); buttonBackgroundStyle.setOverBackground(buttonBackground); buttonBackgroundStyle.setClickBackground(buttonBackground); style.setButtonBackgroundStyle(buttonBackgroundStyle); - style.setStyleType(style1.isSelected() ? 1 : 2); - style.setSelectBackgroundColor(selectBackgroundColorBox.getSelectObject()); + } + + private void updateWidgetBackground(ThemedWidgetStyle style) { + Color bgColor = widgetBgColorSelectBox.getSelectObject(); + style.setWidgetBackground(ColorUtils.createColorBackgroundWithAlpha(bgColor, widgetBgAlphaDragPane.updateBean())); + } + + private void populateTextStyle(ThemedWidgetStyle style) { + ThemeTextStyle textStyle = style.getTextStyle(); + fontSizePane.setValue(textStyle.getFontSize()); + fontColorButton.setColor(textStyle.getFontColor()); + bold.setSelected(textStyle.isBold()); + italic.setSelected(textStyle.isItalic()); + String fontName = StringUtils.isEmpty(textStyle.getName()) ? InterProviderFactory.getProvider().getLocText("Fine-Engine_Base_Song_TypeFace") : textStyle.getName(); + fontNameSelectBox.setSelectedItem(fontName); + } + + private void populateBorder(ThemedWidgetStyle style) { + lineComboBox.setSelectedLineStyle(style.getBorderStyle().getLineType()); + lineComboColorSelectBox.setSelectObject(style.getBorderStyle().getBorderColor()); + borderRadiusSpinner.setValue(style.getBorderStyle().getRadius()); + } + + private void populateWidgetBackground(ThemedWidgetStyle style) { + widgetBgColorSelectBox.setSelectObject(ColorUtils.ignoreColorAlpha(style.getWidgetBackground().getColor())); + widgetBgAlphaDragPane.populateBean(ColorUtils.roundColorAlphaDouble(style.getWidgetBackground().getColor())); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java index ec6ef9aeb..a41a3c976 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java @@ -1,16 +1,29 @@ package com.fr.widgettheme.theme.edit.widget; +import com.fr.base.background.ColorBackground; import com.fr.base.theme.TemplateTheme; import com.fr.design.gui.frpane.FontSizeComboPane; +import com.fr.design.utils.ColorUtils; import com.fr.widgettheme.theme.widget.style.BorderStyle; import com.fr.widgettheme.theme.widget.style.MobileThemedWidgetStyle; import com.fr.design.gui.icombobox.LineComboBox; +import com.fr.widgettheme.theme.widget.style.StyleType; import com.fr.widgettheme.theme.widget.style.ThemeTextStyle; +import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; +import java.awt.Color; import java.util.Arrays; import java.util.Vector; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_00000000_HEX; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_00FFFFFF_HEX; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_26000000_HEX; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_26FFFFFF_HEX; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_CC000000_HEX; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_CCFFFFFF_HEX; + /** * 移动端控件样式编辑面板 * diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java index 1c8ab2ff1..8a0062d04 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java @@ -4,8 +4,11 @@ import com.fr.base.theme.TemplateTheme; import com.fr.design.beans.BasicBeanPane; import com.fr.design.designer.IntervalConstants; import com.fr.design.gui.frpane.FontSizeComboPane; +import com.fr.design.gui.frpane.UIPercentDragPane; import com.fr.design.gui.ibutton.UIColorButton; +import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.gui.icombobox.LineComboBox; +import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.gui.style.FRFontPane; @@ -14,9 +17,11 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.style.color.NewColorSelectBox; +import com.fr.general.IOUtils; import com.fr.stable.StringUtils; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; -import com.fr.widgettheme.util.ThemeTextStylePaneCreator; +import com.fr.widgettheme.util.WidgetStyleComponentCombiner; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; import org.jetbrains.annotations.Nullable; import javax.swing.BorderFactory; @@ -39,6 +44,11 @@ public class WidgetStyleEditPane extends BasicBeanPane< // 边框线型 protected LineComboBox lineComboBox; + + /** + * 边框颜色 + */ + protected NewColorSelectBox lineComboColorSelectBox; // 圆角边框 protected UISpinner borderRadiusSpinner; /** @@ -48,6 +58,24 @@ public class WidgetStyleEditPane extends BasicBeanPane< protected UIColorButton fontColorButton; + /** + * 控件背景和透明度配置面板 + */ + protected NewColorSelectBox widgetBgColorSelectBox; + protected UIPercentDragPane widgetBgAlphaDragPane; + /** + * 图标颜色 + */ + protected NewColorSelectBox iconColorSelectBox; + + /** + * 字体粗体斜体配置 + */ + protected UIToggleButton bold; + protected UIToggleButton italic; + + protected JPanel leftPanel; + public WidgetStyleEditPane() { initComponents(); } @@ -55,15 +83,17 @@ public class WidgetStyleEditPane extends BasicBeanPane< private void initComponents() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); initCommonStyleEditor(); - double f = TableLayout.PREFERRED; + double f = TableLayout.FILL; final double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p, p, p, p}; - double[] columnSize = {p, p}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; + double[] rowSize = {p, p, p, p, p, p, p, p, p}; + double[] columnSize = {p, WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENTS_COL_WIDTH}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; Component[][] components = generateComponent(); JPanel customPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - customPane.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 10)); + customPane.setBorder(BorderFactory.createEmptyBorder(20, 10, 20, 10)); this.add(customPane, BorderLayout.NORTH); + UIScrollPane scrollPane = new UIScrollPane(customPane); + this.add(scrollPane); } /** @@ -72,21 +102,29 @@ public class WidgetStyleEditPane extends BasicBeanPane< * @return components */ public Component[][] generateComponent() { - return new Component[][]{new Component[]{ - new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")), colorSelectBox}, + return new Component[][]{ + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")), colorSelectBox}, + new Component[]{WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Widget_Background")), WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, colorSelectBox.getPreferredSize().width)}, new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line")), lineComboBox}, + new Component[]{null, lineComboColorSelectBox}, new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius")), borderRadiusSpinner}, - new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")), ThemeTextStylePaneCreator.create(fontSizePane, fontColorButton)} + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Icon_Color")), iconColorSelectBox}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")), WidgetStyleComponentCombiner.combineTextStyleComponent(fontSizePane, fontColorButton, bold, italic)} }; } private void initCommonStyleEditor() { colorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); colorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR); + widgetBgColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); + widgetBgAlphaDragPane = new UIPercentDragPane(); initLineBox(); borderRadiusSpinner = new UISpinner(0, Integer.MAX_VALUE, 1); + iconColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); initFontSizePane(); fontColorButton = new UIColorButton(); + bold = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png")); + italic = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png")); } protected void initFontSizePane() { @@ -98,6 +136,8 @@ public class WidgetStyleEditPane extends BasicBeanPane< */ public void initLineBox() { lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.BORDER_LINE_STYLE_ARRAY); + lineComboColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); + lineComboBox.addItemListener(e -> lineComboColorSelectBox.setVisible(!Integer.valueOf(0).equals(e.getItem()))); } diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ButtonStyleDefinedPane.java b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ButtonStyleDefinedPane.java index c6ec951eb..e65b372ac 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ButtonStyleDefinedPane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ButtonStyleDefinedPane.java @@ -10,7 +10,6 @@ import com.fr.widgettheme.theme.bean.ButtonBackground; import com.fr.design.mainframe.widget.accessibles.AccessibleImgBackgroundEditor; import com.fr.general.Background; -import javax.swing.BorderFactory; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; @@ -48,7 +47,6 @@ public class ButtonStyleDefinedPane extends BasicPane { new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Background_Click")), clickBackgroundPane}, }; JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 7, 7); - panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); this.add(panel, BorderLayout.CENTER); } diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java index 7dca24b7c..d9e350e9b 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java @@ -85,24 +85,16 @@ public class ControlPreviewCell extends JPanel { this.paintBgColor(g, widgetStyle, DEFAULT_ALPHA); } - public boolean isDefaultStyle() { + public Color getIconColor() { ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle(); - return widgetStyle.getStyleType() == ThemedWidgetStyle.DEFAULT_STYLE; - } - - public Color getThemeColor() { - - ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle(); - return widgetStyle.getThemeColor(); - + return widgetStyle.getIconColor(); } protected Icon setStyleTwoIcon(Icon icon, Icon defaultIcon) { - if (this.reportTheme != null && !isDefaultStyle()) { - + if (this.reportTheme != null) { if (icon instanceof ImageIcon) { ImageIcon imageIcon = (ImageIcon) icon; - BufferedImage bufferedImage = ImageUtils.colorImage(ImageUtils.imageIconToBufferedImage(imageIcon), getThemeColor()); + BufferedImage bufferedImage = ImageUtils.colorImage(ImageUtils.imageIconToBufferedImage(imageIcon), getIconColor()); return new ImageIcon(bufferedImage); } } @@ -113,9 +105,9 @@ public class ControlPreviewCell extends JPanel { * 填充圆角矩形背景色 */ public void paintBgColor(Graphics g, ThemedWidgetStyle widgetStyle, int alpha) { - Color themeColor = widgetStyle.getThemeColor(); + Color themeColor = widgetStyle.getWidgetBackground().getColor(); g.setColor(new Color(themeColor.getRed(), themeColor.getGreen(), themeColor.getBlue(), alpha)); - g.fillRoundRect(0, 0, getSize().width - 1, getSize().height - 1, widgetStyle.getBorderStyle().getRadius(), widgetStyle.getBorderStyle().getRadius()); + g.fillRoundRect(0, 0, getSize().width - 1, getSize().height - 1, (int) widgetStyle.getBorderStyle().getRadius(), (int) widgetStyle.getBorderStyle().getRadius()); //需要重新绘制一遍字体,否则会被颜色填充给遮住 Graphics2D g2d = (Graphics2D) g.create(); FRFont font = FRFont.getInstance(FRFont.DEFAULT_FONTNAME, Font.PLAIN, widgetStyle.getTextStyle().getFontSize(), textColor); diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCellWithIcon.java b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCellWithIcon.java index eb5f1eb9b..491af469f 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCellWithIcon.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCellWithIcon.java @@ -5,7 +5,6 @@ import com.fr.base.svg.IconUtils; import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle; import com.fr.design.border.UIRoundedBorder; import com.fr.stable.StringUtils; -import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; import javax.swing.Icon; import javax.swing.JLabel; @@ -64,14 +63,12 @@ public class ControlPreviewCellWithIcon extends ControlPreviewCell { super.paintComponent(g); ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle(); //风格一边框不显示主题色 - Color borderColor = isDefaultStyle() ? DEFAULT_COLOR : widgetStyle.getThemeColor(); + Color borderColor = widgetStyle.getBorderStyle().getBorderColor(); this.setBorder(new UIRoundedBorder(widgetStyle.getBorderStyle().getLineType() - , borderColor, widgetStyle.getBorderStyle().getRadius())); + , borderColor, (int) widgetStyle.getBorderStyle().getRadius())); icon = setStyleTwoIcon(icon, defaultIcon); this.jLabel.setIcon(icon); this.add(jLabel, BorderLayout.EAST); - if (widgetStyle.getStyleType() != ThemedWidgetStyle.DEFAULT_STYLE) { - paintBgColor(g, widgetStyle, CONTROL_ALPHA); - } + paintBgColor(g, widgetStyle, CONTROL_ALPHA); } } diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/RoundControlPreviewCell.java b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/RoundControlPreviewCell.java index dc98146b3..4b527dd4f 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/RoundControlPreviewCell.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/RoundControlPreviewCell.java @@ -36,8 +36,7 @@ public class RoundControlPreviewCell extends ControlPreviewCell { public void paintComponent(Graphics g) { super.paintComponent(g); ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle(); - //风格一边框不显示主题色 - Color borderColor = isDefaultStyle() ? DEFAULT_COLOR : widgetStyle.getThemeColor(); + Color borderColor = widgetStyle.getBorderStyle().getBorderColor(); Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(borderColor); g2d.drawOval(5, 9, 15, 15); diff --git a/designer-base/src/main/java/com/fr/widgettheme/util/ThemeTextStylePaneCreator.java b/designer-base/src/main/java/com/fr/widgettheme/util/ThemeTextStylePaneCreator.java deleted file mode 100644 index 133f25864..000000000 --- a/designer-base/src/main/java/com/fr/widgettheme/util/ThemeTextStylePaneCreator.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.fr.widgettheme.util; - -import com.fr.design.gui.frpane.FontSizeComboPane; -import com.fr.design.gui.ibutton.UIColorButton; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; - -import javax.swing.Box; -import javax.swing.JPanel; -import java.awt.Component; - -/** - * 创建主题文本样式的工具类 - * - * @author obo - * @since 11.0 - * Created on 2023/12/21 - */ -public class ThemeTextStylePaneCreator { - private ThemeTextStylePaneCreator() {} - - /** - * 创建主题文本样式配置面板 - * 包含字体大小下拉框和字体颜色按钮 - * 可以自适应布局 - * - * @param fontSizePane 字体大小配置 - * @param fontColorButton 字体颜色配置 - * @return 文本样式面板 - */ - public static JPanel create(FontSizeComboPane fontSizePane, UIColorButton fontColorButton) { - Component[][] components = {{fontSizePane, Box.createHorizontalStrut(5), fontColorButton}}; - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {f}; - double[] columnSize = {f, p, p}; - int[][] rowCount = {{1, 1, 1}}; - return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 0, 0); - } -} diff --git a/designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java new file mode 100644 index 000000000..b612b7027 --- /dev/null +++ b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java @@ -0,0 +1,147 @@ +package com.fr.widgettheme.util; + +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.frpane.FontSizeComboPane; +import com.fr.design.gui.frpane.UIPercentDragPane; +import com.fr.design.gui.ibutton.UIColorButton; +import com.fr.design.gui.ibutton.UIToggleButton; +import com.fr.design.gui.icombobox.LineComboBox; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane; +import com.fr.design.style.color.NewColorSelectBox; +import com.fr.design.widget.FRWidgetFactory; +import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; +import groovy.swing.factory.LayoutFactory; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JComponent; +import javax.swing.JPanel; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.LayoutManager; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * 创建控件样式组合配置面板的工具类 + * + * @author obo + * @since 11.0 + * Created on 2023/12/21 + */ +public class WidgetStyleComponentCombiner { + + private static final double F = TableLayout.FILL; + private static final double P = TableLayout.PREFERRED; + + + private WidgetStyleComponentCombiner() { + } + + /** + * 组合主题文本样式配置面板 + * 包含字体大小下拉框和字体颜色按钮 + * + * @param fontSizePane 字体大小配置 + * @param fontColorButton 字体颜色配置 + * @param bold 粗体 + * @param italic 斜体 + * @return 文本样式面板 + */ + public static JPanel combineTextStyleComponent(FontSizeComboPane fontSizePane, UIColorButton fontColorButton, UIToggleButton bold, UIToggleButton italic) { + Component[][] components = {{fontSizePane, fontColorButton, bold, italic}}; + double[] rowSize = {P}; + double[] columnSize = {F, P, P, P}; + int[][] rowCount = {{1, 1, 1, 1}}; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 5, 5); + } + + /** + * 组合主题文本样式配置面板 + * 包含字体大小下拉框和字体颜色按钮 + * + * @param fontNameSelectBox 字体名配置 + * @param fontSizePane 字体大小配置 + * @param fontColorButton 字体颜色配置 + * @param bold 粗体 + * @param italic 斜体 + * @return 文本样式面板 + */ + public static JPanel combineTextStyleComponent(UIComboBox fontNameSelectBox, FontSizeComboPane fontSizePane, UIColorButton fontColorButton, UIToggleButton bold, UIToggleButton italic) { + Component[][] components = { + {fontNameSelectBox, null, null, null}, + {fontSizePane, fontColorButton, bold, italic} + }; + double[] rowSize = {P, P}; + double[] columnSize = {F, P, P, P}; + int[][] rowCount = { + {1, 1, 1, 1}, + {1, 1, 1, 1} + }; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 5, 5); + } + + /** + * 组合控件背景配置面板 + * + * @param colorSelectBox 颜色下拉框 + * @param alphaDragPane 透明度 + * @param columnWidth 列宽 + * @return 文本样式面板 + */ + public static JPanel combineWidgetBackgroundComponent(NewColorSelectBox colorSelectBox, + UIPercentDragPane alphaDragPane, + double columnWidth) { + Component[][] components = { + {colorSelectBox}, + {FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))}, + {alphaDragPane} + }; + double[] rowSize = {P, P, P}; + double[] columnSize = {columnWidth}; + int[][] rowCount = {{1}, {1}, {1}}; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + } + + /** + * 组合控件边框配置面板 + * + * @param lineComboBox 字体大小配置 + * @param lineComboColorSelectBox 字体颜色配置 + * @return 文本样式面板 + */ + public static JPanel combineWidgetBorderComponent(LineComboBox lineComboBox, NewColorSelectBox lineComboColorSelectBox) { + return combineWidgetBorderComponent(lineComboBox, lineComboColorSelectBox, P); + } + + /** + * 组合控件边框配置面板 + * + * @param lineComboBox 字体大小配置 + * @param lineComboColorSelectBox 字体颜色配置 + * @param columnWidth 指定的列宽 + * @return 文本样式面板 + */ + public static JPanel combineWidgetBorderComponent(LineComboBox lineComboBox, + NewColorSelectBox lineComboColorSelectBox, + double columnWidth) { + Component[][] components = { + {lineComboBox}, + {lineComboColorSelectBox} + }; + double[] rowSize = {P, P}; + double[] columnSize = {columnWidth}; + int[][] rowCount = {{1}, {1}}; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + } +} diff --git a/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java index 296b5e2e5..68bceee16 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java +++ b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java @@ -2,10 +2,16 @@ package com.fr.widgettheme.util; import com.fr.base.io.AttrMark; import com.fr.base.io.IOFile; +import com.fr.base.theme.TemplateTheme; import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.mainframe.JTemplate; import com.fr.stable.StringUtils; import com.fr.widgettheme.control.attr.WidgetDisplayEnhanceMarkAttr; +import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; + +import javax.swing.SwingConstants; +import java.awt.Color; /** * 控件主题设计器部分工具类 @@ -43,4 +49,30 @@ public class WidgetThemeDesignerUtils { } return false; } + /** + * 返回当前编辑模版的主题深浅 + */ + public static boolean isCurrentTemplateThemeDark() { + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (JTemplate.isValid(jTemplate)) { + TemplateTheme theme = jTemplate.getTemplateTheme(); + if (theme != null) { + return theme.isDark(); + } + return false; + } + throw new IllegalArgumentException("The current template is not valid"); + } + + /** + * 创建垂直方向顶部对齐的label + */ + public static UILabel createTopAlignmentLabel(String labelName) { + if(StringUtils.isEmpty(labelName)) { + return null; + } + UILabel label = new UILabel(labelName); + label.setVerticalAlignment(SwingConstants.TOP); + return label; + } } diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java index a0ed4159c..66aa578c5 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java @@ -1,6 +1,8 @@ package com.fr.widgettheme.widget.mobile.pane; import com.fr.base.background.ColorBackground; +import com.fr.design.gui.frpane.UIPercentDragPane; +import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.MobileThemedWidgetStyle; import com.fr.widgettheme.theme.widget.mobile.style.WidgetThemeMobileCommonExtraStyle; import com.fr.design.beans.BasicBeanPane; @@ -16,7 +18,6 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; -import com.fr.design.style.color.ColorSelectBox; import com.fr.design.style.color.NewColorSelectBox; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.form.ui.Widget; @@ -27,8 +28,11 @@ import com.fr.invoke.Reflect; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; import com.fr.stable.Constants; import com.fr.stable.StringUtils; +import com.fr.widgettheme.util.WidgetStyleComponentCombiner; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; import javax.swing.JPanel; +import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import java.awt.BorderLayout; @@ -40,6 +44,8 @@ import java.awt.Font; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.THEME_MOBILE_WIDGET_BACKGROUND_WIDTH; + /** *

开启控件显示增强后替换原通用属性面板 *

参考{@link com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane} @@ -59,9 +65,13 @@ public class DisplayEnhanceMobileStyleDefinePane extends BasicBeanPane customBeanPaneClass, Class mobileStyleClazz) { super(widget, customBeanPaneClass, mobileStyleClazz); } - @Override - public void populateBean(MobileStyle ob) { - super.populateBean(ob); - MobileCommonExtraStyle extraStyle = ob.getMobileCommonExtraStyle(); - if (extraStyle instanceof FreeButtonStyle) { - FreeButtonStyle style = (FreeButtonStyle) extraStyle; - if (style.getBorderColor() != null) { - borderColorSelectBox.setSelectObject(style.getBorderColor()); - } - if (style.getIconColor() != null) { - iconColorSelectBox.setSelectObject(style.getIconColor()); - } - } - } - - @Override - public MobileStyle updateBean() { - mobileStyle = Reflect.on(mobileStyleClazz).create().get(); - FreeButtonStyle extraStyle = new FreeButtonStyle(); - extraStyle.setCustom(customCombo.getSelectedIndex() == 1); - extraStyle.setWidgetBackground(ColorBackground.getInstance(widgetBackgroundSelectBox.getSelectObject())); - extraStyle.setBorderType(borderType.getSelectedLineStyle()); - extraStyle.setBorderColor(borderColorSelectBox.getSelectObject()); - extraStyle.setBorderRadius(borderRadius.getValue()); - extraStyle.setNewFont(fontConfigPane.updateBean()); - extraStyle.setIconColor(iconColorSelectBox.getSelectObject()); - mobileStyle.setMobileCommonExtraStyle(extraStyle); - this.widget.setMobileStyle(mobileStyle); - this.customBeanPane.updateBean(); - return mobileStyle; - } - @Override protected void createUniversalPane() { createBackgroundPane(); createBorderLinePane(); - initBorderColor(); createBorderRadiusPane(); - initIconColor(); createFontPane(WidgetThemeDisplayConstants.DEFAULT_WHITE_COLOR); } - private void initIconColor() { - iconColorSelectBox = new NewColorSelectBox(NORMAL_COMBO_WIDTH); - iconColorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_WHITE_COLOR); - settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_Icon_Color")), iconColorSelectBox)); - } - @Override protected void initDefaultLineType() { borderType.setSelectedLineStyle(com.fr.stable.Constants.LINE_NONE); } - private void initBorderColor() { - borderColorSelectBox = new NewColorSelectBox(NORMAL_COMBO_WIDTH); - borderColorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR); - settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_BorderColor")), borderColorSelectBox)); - } - @Override protected void initBackgroundColor() { widgetBackgroundSelectBox.setSelectObject(getCurrentTemplateThemeColor()); diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/IconColorMobileStyleDefinePane.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/IconColorMobileStyleDefinePane.java new file mode 100644 index 000000000..3a7a8c45b --- /dev/null +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/IconColorMobileStyleDefinePane.java @@ -0,0 +1,36 @@ +package com.fr.widgettheme.widget.mobile.pane; + +import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; +import com.fr.form.ui.Widget; +import com.fr.form.ui.mobile.MobileStyle; +import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; + +/** + * 带有图标颜色的移动端控件通用配置面板 + * + * @author obo + * @since 11.0 + * Created on 2024/1/25 + */ +public class IconColorMobileStyleDefinePane extends DisplayEnhanceMobileStyleDefinePane{ + + public IconColorMobileStyleDefinePane(Widget widget, Class customBeanPaneClass, Class mobileStyleClazz) { + super(widget, customBeanPaneClass, mobileStyleClazz); + } + + @Override + protected void createUniversalPane() { + // 主题色 + createThemePane(); + // 组件背景 + createBackgroundPane(); + // 边框线型 + createBorderLinePane(); + // 圆角边框 + createBorderRadiusPane(); + //图标颜色 + createIconColorSelectBox(); + // 字体 + createFontPane(WidgetThemeDisplayConstants.DEFAULT_FONT_COLOR_BLACK); + } +} diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/LabelMobileStyleDefinePane.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/LabelMobileStyleDefinePane.java index 17388b859..682237f75 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/LabelMobileStyleDefinePane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/LabelMobileStyleDefinePane.java @@ -1,14 +1,8 @@ package com.fr.widgettheme.widget.mobile.pane; -import com.fr.base.background.ColorBackground; -import com.fr.widgettheme.theme.widget.mobile.style.LabelIconSettingStyle; -import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; -import com.fr.design.style.color.NewColorSelectBox; import com.fr.form.ui.Widget; -import com.fr.form.ui.mobile.MobileCommonExtraStyle; import com.fr.form.ui.mobile.MobileStyle; -import com.fr.invoke.Reflect; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; /** @@ -19,57 +13,19 @@ import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; * Created on 2023/5/15 */ public class LabelMobileStyleDefinePane extends DisplayEnhanceMobileStyleDefinePane { - private NewColorSelectBox borderColorSelectBox; - public LabelMobileStyleDefinePane(Widget widget, Class customBeanPaneClass, Class mobileStyleClazz) { super(widget, customBeanPaneClass, mobileStyleClazz); } - - @Override - public void populateBean(MobileStyle ob) { - super.populateBean(ob); - MobileCommonExtraStyle extraStyle = ob.getMobileCommonExtraStyle(); - if (extraStyle instanceof LabelIconSettingStyle) { - LabelIconSettingStyle style = (LabelIconSettingStyle) extraStyle; - if (style.getBorderColor() != null) { - borderColorSelectBox.setSelectObject(style.getBorderColor()); - } - } - } - - @Override - public MobileStyle updateBean() { - mobileStyle = Reflect.on(mobileStyleClazz).create().get(); - LabelIconSettingStyle extraStyle = new LabelIconSettingStyle(); - extraStyle.setCustom(customCombo.getSelectedIndex() == 1); - extraStyle.setWidgetBackground(ColorBackground.getInstance(widgetBackgroundSelectBox.getSelectObject())); - extraStyle.setBorderType(borderType.getSelectedLineStyle()); - extraStyle.setBorderColor(borderColorSelectBox.getSelectObject()); - extraStyle.setBorderRadius(borderRadius.getValue()); - extraStyle.setNewFont(fontConfigPane.updateBean()); - mobileStyle.setMobileCommonExtraStyle(extraStyle); - this.widget.setMobileStyle(mobileStyle); - this.customBeanPane.updateBean(); - return mobileStyle; - } - @Override protected void createUniversalPane() { createBackgroundPane(); createBorderLinePane(); - initBorderColor(); createBorderRadiusPane(); createFontPane(WidgetThemeDisplayConstants.DEFAULT_FONT_COLOR_BLACK); } - private void initBorderColor() { - borderColorSelectBox = new NewColorSelectBox(NORMAL_COMBO_WIDTH); - borderColorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_TRANSPARENT_COLOR); - settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_BorderColor")), borderColorSelectBox)); - } - @Override protected void initDefaultLineType() { borderType.setSelectedLineStyle(com.fr.stable.Constants.LINE_NONE); diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/TextAreaMobileStyleDefinePane.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/TextAreaMobileStyleDefinePane.java new file mode 100644 index 000000000..29283a7fe --- /dev/null +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/TextAreaMobileStyleDefinePane.java @@ -0,0 +1,33 @@ +package com.fr.widgettheme.widget.mobile.pane; + +import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; +import com.fr.form.ui.Widget; +import com.fr.form.ui.mobile.MobileStyle; +import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; + +/** + * 文本域控件移动端配置面板 + * + * @author obo + * @since 11.0 + * Created on 2024/1/25 + */ +public class TextAreaMobileStyleDefinePane extends DisplayEnhanceMobileStyleDefinePane{ + public TextAreaMobileStyleDefinePane(Widget widget, Class customBeanPaneClass, Class mobileStyleClazz) { + super(widget, customBeanPaneClass, mobileStyleClazz); + } + + @Override + protected void createUniversalPane() { + // 主题色 + createThemePane(); + // 组件背景 + createBackgroundPane(); + // 边框线型 + createBorderLinePane(); + // 圆角边框 + createBorderRadiusPane(); + // 字体 + createFontPane(WidgetThemeDisplayConstants.DEFAULT_FONT_COLOR_BLACK); + } +} diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/DisplayEnhanceMobileStyleFactory.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/DisplayEnhanceMobileStyleFactory.java index 53650ca5d..fea523c68 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/DisplayEnhanceMobileStyleFactory.java +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/DisplayEnhanceMobileStyleFactory.java @@ -1,11 +1,11 @@ package com.fr.widgettheme.widget.mobile.provider; +import com.fr.form.ui.TextArea; +import com.fr.widgettheme.theme.widget.mobile.style.WidgetThemeMobileCommonExtraStyle; import com.fr.widgettheme.widget.mobile.pane.FileEditorMobileStyleDefinePane; import com.fr.widgettheme.widget.mobile.pane.FreeButtonMobileStyleDefinePane; import com.fr.widgettheme.widget.mobile.pane.LabelMobileStyleDefinePane; import com.fr.widgettheme.theme.widget.mobile.style.FileEditorStyle; -import com.fr.widgettheme.theme.widget.mobile.style.FreeButtonStyle; -import com.fr.widgettheme.theme.widget.mobile.style.LabelIconSettingStyle; import com.fr.design.beans.BasicBeanPane; import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; import com.fr.form.ui.FreeButton; @@ -14,6 +14,7 @@ import com.fr.form.ui.MultiFileEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.mobile.MobileCommonExtraStyle; import com.fr.form.ui.mobile.MobileStyle; +import com.fr.widgettheme.widget.mobile.pane.TextAreaMobileStyleDefinePane; /** * 样式创建工厂 @@ -40,6 +41,9 @@ public class DisplayEnhanceMobileStyleFactory { if (widget instanceof FreeButton) { return new FreeButtonMobileStyleDefinePane(widget, customDefinePane, mobileStyle); } + if (widget instanceof TextArea) { + return new TextAreaMobileStyleDefinePane(widget, customDefinePane, mobileStyle); + } return null; } @@ -50,16 +54,10 @@ public class DisplayEnhanceMobileStyleFactory { * @return */ public static Class classForWidgetCommonExtraStyle(Widget widget) { - if (widget instanceof Label) { - return LabelIconSettingStyle.class; - } if (widget instanceof MultiFileEditor) { return FileEditorStyle.class; } - if (widget instanceof FreeButton) { - return FreeButtonStyle.class; - } - return null; + return WidgetThemeMobileCommonExtraStyle.class; } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java index a40199327..226bf64df 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java @@ -1,11 +1,18 @@ package com.fr.widgettheme.widget.mobile.provider; -import com.fr.base.io.IOFile; +import com.fr.form.ui.ComboBox; +import com.fr.form.ui.ComboCheckBox; +import com.fr.form.ui.DateEditor; +import com.fr.form.ui.NumberEditor; +import com.fr.form.ui.Password; +import com.fr.form.ui.TextArea; +import com.fr.form.ui.TextEditor; +import com.fr.form.ui.TreeEditor; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; +import com.fr.widgettheme.utils.WidgetThemeServerUtils; import com.fr.widgettheme.widget.mobile.pane.DisplayEnhanceMobileStyleDefinePane; import com.fr.widgettheme.theme.widget.mobile.style.WidgetThemeMobileCommonExtraStyle; import com.fr.design.beans.BasicBeanPane; -import com.fr.design.file.HistoryTemplateListCache; -import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; import com.fr.form.ui.FreeButton; import com.fr.form.ui.Label; @@ -14,7 +21,7 @@ import com.fr.form.ui.Widget; import com.fr.form.ui.mobile.MobileCommonExtraStyle; import com.fr.form.ui.mobile.MobileStyle; import com.fr.log.FineLoggerFactory; -import com.fr.widgettheme.control.attr.WidgetDisplayEnhanceMarkAttr; +import com.fr.widgettheme.widget.mobile.pane.IconColorMobileStyleDefinePane; import org.jetbrains.annotations.NotNull; /** @@ -39,16 +46,13 @@ public class WidgetThemeMobileStyleDefinePaneCreator { */ public static BasicBeanPane createBaseBeanPane(Widget widget, Class customDefinePane, Class mobileStyle) { try { - JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (JTemplate.isValid(jTemplate)) { - IOFile ioFile = (IOFile) jTemplate.getTarget(); - WidgetDisplayEnhanceMarkAttr mark = ioFile.getAttrMark(WidgetDisplayEnhanceMarkAttr.XML_TAG); - if (mark != null && mark.isWidgetEnhance()) { - if (commonWidget(widget)) { - return new DisplayEnhanceMobileStyleDefinePane(widget, customDefinePane, mobileStyle); - } else { - return DisplayEnhanceMobileStyleFactory.createWidgetMobileStyleDefinePane(widget, customDefinePane, mobileStyle); - } + if (WidgetThemeDesignerUtils.enableWidgetEnhance()) { + if (specialCommonWidget(widget)) { + return DisplayEnhanceMobileStyleFactory.createWidgetMobileStyleDefinePane(widget, customDefinePane, mobileStyle); + } else if (isIconWidget(widget)) { + return new IconColorMobileStyleDefinePane(widget, customDefinePane, mobileStyle); + } else { + return new DisplayEnhanceMobileStyleDefinePane(widget, customDefinePane, mobileStyle); } } } catch (Exception e) { @@ -64,10 +68,10 @@ public class WidgetThemeMobileStyleDefinePaneCreator { * @return class */ public static @NotNull Class classForCommonExtraStyle(Widget widget) { - if (commonWidget(widget)) { - return WidgetThemeMobileCommonExtraStyle.class; - } else { + if (specialCommonWidget(widget)) { return DisplayEnhanceMobileStyleFactory.classForWidgetCommonExtraStyle(widget); + } else { + return WidgetThemeMobileCommonExtraStyle.class; } } @@ -78,7 +82,20 @@ public class WidgetThemeMobileStyleDefinePaneCreator { * @param widget 控件 * @return 是/否 */ - private static boolean commonWidget(Widget widget) { - return !((widget instanceof FreeButton) || (widget instanceof Label) || (widget instanceof MultiFileEditor)); + private static boolean specialCommonWidget(Widget widget) { + return widget instanceof FreeButton || widget instanceof Label || widget instanceof MultiFileEditor || widget instanceof TextArea; + } + + /** + * 是否为带图标的控件 + * + * @param widget 控件 + * @return 是/否 + */ + private static boolean isIconWidget(Widget widget) { + return widget instanceof TextEditor || widget instanceof NumberEditor || widget instanceof Password || + widget instanceof DateEditor || widget instanceof ComboBox || widget instanceof ComboCheckBox || + widget instanceof TreeEditor || + WidgetThemeServerUtils.isNewComboBoxTreeEditor(widget); } } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java index b651b9373..93683c92e 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java @@ -1,9 +1,17 @@ package com.fr.design.widgettheme; +import com.fr.base.background.ColorBackground; import com.fr.base.theme.TemplateTheme; import com.fr.design.gui.frpane.FontSizeComboPane; +import com.fr.design.gui.frpane.UIPercentDragPane; import com.fr.design.gui.ibutton.UIColorButton; +import com.fr.design.gui.ibutton.UIToggleButton; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; +import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.BorderStyle; +import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle; import com.fr.widgettheme.theme.widget.style.ThemeTextStyle; import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle; import com.fr.widgettheme.theme.bean.ButtonBackground; @@ -11,7 +19,6 @@ import com.fr.design.beans.BasicBeanPane; import com.fr.design.designer.IntervalConstants; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.ibutton.UIButtonGroup; -import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.icombobox.LineComboBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.style.FRFontPane; @@ -26,11 +33,12 @@ import com.fr.form.ui.Widget; import com.fr.general.FRFont; import com.fr.widgettheme.theme.panel.ButtonStyleDefinedPane; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; -import com.fr.widgettheme.util.ThemeTextStylePaneCreator; +import com.fr.widgettheme.util.WidgetStyleComponentCombiner; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; import javax.swing.JPanel; +import javax.swing.SwingConstants; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; @@ -38,6 +46,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.THEME_PC_WIDGET_BACKGROUND_WIDTH; + /** * 样式设置pane抽象类 * @@ -54,12 +64,12 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa protected JPanel customPane; // 主题色 protected NewColorSelectBox colorSelectBox; - // 风格1 - protected UIRadioButton style1; - // 风格2 - protected UIRadioButton style2; // 边框线型 protected LineComboBox lineComboBox; + /** + * 边框颜色 + */ + protected NewColorSelectBox borderColorSelectBox; // 圆角边框 protected UIBoundSpinner borderRadiusSpinner; // 字体详细设置 @@ -79,6 +89,33 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa */ protected UIColorButton fontColorButton; + /** + * 字体名选择器 + */ + protected UIComboBox fontNameSelectBox; + + /** + * 字体粗体配置 + */ + protected UIToggleButton bold; + /** + * 字体斜体配置 + */ + protected UIToggleButton italic; + + /** + * 控件背景颜色配置面板 + */ + protected NewColorSelectBox widgetBgColorSelectBox; + /** + * 控件背景透明度配置面板 + */ + protected UIPercentDragPane widgetBgAlphaDragPane; + /** + * 控件图标颜色 + */ + protected NewColorSelectBox iconColorSelectBox; + private final Map labelMap = new HashMap<>(); private final Map paneMap = new HashMap<>(); public BaseStyleSettingPane(List styleSettingList) { @@ -97,34 +134,30 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa protected void initStyleEditor() { - initStyle(); - colorSelectBox = new NewColorSelectBox(160, true); + colorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, false); lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.BORDER_LINE_STYLE_ARRAY); + borderColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); borderRadiusSpinner = new UIBoundSpinner(0, Integer.MAX_VALUE, 1); frFontPane = new FRFontPane(); buttonStyleDefinedPane = new ButtonStyleDefinedPane(); - selectBgColorBox = new NewColorSelectBox(160, true); + selectBgColorBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); + iconColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); fontSizePane = new FontSizeComboPane(); fontColorButton = new UIColorButton(); - paneMap.put(StyleSetting.STYLE_TYPE, createStyleTypePane()); + bold = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png")); + italic = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png")); + widgetBgColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); + widgetBgAlphaDragPane = new UIPercentDragPane(); paneMap.put(StyleSetting.THEME_COLOR, colorSelectBox); paneMap.put(StyleSetting.LINE_TYPE, lineComboBox); - paneMap.put(StyleSetting.TEXT_STYLE, ThemeTextStylePaneCreator.create(fontSizePane, fontColorButton)); + paneMap.put(StyleSetting.LINE_COLOR, borderColorSelectBox); + paneMap.put(StyleSetting.TEXT_STYLE, WidgetStyleComponentCombiner.combineTextStyleComponent(fontNameSelectBox, fontSizePane, fontColorButton, bold, italic)); paneMap.put(StyleSetting.BORDER_RADIUS, borderRadiusSpinner); paneMap.put(StyleSetting.FONT, frFontPane); paneMap.put(StyleSetting.BTN_BACKGROUND, buttonStyleDefinedPane); paneMap.put(StyleSetting.SELECT_COLOR, selectBgColorBox); - } - - /** - * 初始化style1和style2 - */ - private void initStyle() { - style1 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_1")); - style2 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_2")); - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(style1); - buttonGroup.add(style2); + paneMap.put(StyleSetting.WIDGET_BACKGROUND, WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, THEME_PC_WIDGET_BACKGROUND_WIDTH)); + paneMap.put(StyleSetting.ICON_COLOR, iconColorSelectBox); } protected JPanel createHeadPane() { @@ -143,14 +176,6 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa return headPane; } - protected JPanel createStyleTypePane() { - // 容纳风格1和风格2的panel - JPanel stylePane = new JPanel(FRGUIPaneFactory.createBoxFlowLayout()); - stylePane.add(style1); - stylePane.add(style2); - return stylePane; - } - protected JPanel createCustomPane() { int size = styleSettingList.size(); @@ -212,92 +237,95 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa } private void setThemedStyle(ThemedWidgetStyle widgetStyle) { - setColorSelectBox(widgetStyle); - setStyle(widgetStyle); - setLineComboBox(widgetStyle); - setBorderRadiusSpinner(widgetStyle); - setTextStylePane(widgetStyle); - setFrFontPane(widgetStyle); - setButtonStyleDefinedPane(widgetStyle); - setSelectBgColor(widgetStyle); + setColorSelectBox(widgetStyle.getThemeColor()); + setLineComboBox(widgetStyle.getBorderStyle().getLineType()); + setBorderRadiusSpinner(widgetStyle.getBorderStyle().getRadius()); + setTextStylePane(widgetStyle.getTextStyle()); + setFrFontPane(widgetStyle.getFontStyle().getFont()); + setButtonStyleDefinedPane(widgetStyle.getButtonBackgroundStyle()); + setSelectBgColor(widgetStyle.getSelectBackgroundColor()); + setWidgetBackground(widgetStyle.getWidgetBackground()); + setBorderColor(widgetStyle.getBorderStyle().getBorderColor()); + setIconColor(widgetStyle.getIconColor()); } - private void setColorSelectBox(ThemedWidgetStyle widgetStyle) { + private void setColorSelectBox(Color themeColor) { if (colorSelectBox != null) { - colorSelectBox.setSelectObject(widgetStyle.getThemeColor()); - } - } - private void setStyle(ThemedWidgetStyle widgetStyle) { - if (widgetStyle.getStyleType() == ThemedWidgetStyle.DEFAULT_STYLE) { - if (style1 != null) { - style1.setSelected(true); - } - } else { - if (style2 != null) { - style2.setSelected(true); - } + colorSelectBox.setSelectObject(themeColor); } } - private void setLineComboBox(ThemedWidgetStyle widgetStyle) { + private void setLineComboBox(int lineType) { if (lineComboBox != null) { - lineComboBox.setSelectedLineStyle(widgetStyle.getBorderStyle().getLineType()); + lineComboBox.setSelectedLineStyle(lineType); } } - private void setBorderRadiusSpinner(ThemedWidgetStyle widgetStyle) { + private void setBorderRadiusSpinner(double radius) { if (borderRadiusSpinner != null) { - borderRadiusSpinner.setValue(widgetStyle.getBorderStyle().getRadius()); + borderRadiusSpinner.setValue(radius); } } - private void setTextStylePane(ThemedWidgetStyle widgetStyle) { - ThemeTextStyle textStyle = widgetStyle.getTextStyle(); - this.fontSizePane.setValue(textStyle.getFontSize()); - this.fontColorButton.setColor(textStyle.getFontColor()); + private void setTextStylePane(ThemeTextStyle textStyle) { + if (fontSizePane != null) { + this.fontSizePane.setValue(textStyle.getFontSize()); + } + if (fontColorButton != null) { + this.fontColorButton.setColor(textStyle.getFontColor()); + } } - private void setFrFontPane(ThemedWidgetStyle widgetStyle) { + private void setFrFontPane(FRFont font) { if (frFontPane != null) { - frFontPane.populateBean(widgetStyle.getFontStyle().getFont()); + frFontPane.populateBean(font); } } - private void setButtonStyleDefinedPane(ThemedWidgetStyle widgetStyle) { + private void setButtonStyleDefinedPane(ButtonBackgroundStyle backgroundStyle) { if (buttonStyleDefinedPane != null) { - buttonStyleDefinedPane.populate(ButtonBackground.create(widgetStyle.getButtonBackgroundStyle())); + buttonStyleDefinedPane.populate(ButtonBackground.create(backgroundStyle)); } } + private void setDefaultStyle() { - if (colorSelectBox != null) { - colorSelectBox.setSelectObject(ThemedWidgetStyle.DEFAULT_COLOR); - } - if (style1 != null) { - style1.setSelected(true); - } - if (lineComboBox != null) { - lineComboBox.setSelectedLineStyle(BorderStyle.DEFAULT_LINE_TYPE); - } - if (borderRadiusSpinner != null) { - borderRadiusSpinner.setValue(BorderStyle.DEFAULT_BORDER_RADIUS); - } - if (fontSizePane != null) { - fontSizePane.setValue(ThemeTextStyle.DEFAULT_FONT_SIZE); + setColorSelectBox(ThemedWidgetStyle.DEFAULT_COLOR); + setLineComboBox(BorderStyle.DEFAULT_LINE_TYPE); + setBorderRadiusSpinner(BorderStyle.DEFAULT_BORDER_RADIUS); + setTextStylePane(ThemeTextStyle.DEFAULT_WIDGET_STYLE); + setFrFontPane(FRFont.getInstance()); + setSelectBgColor(WidgetThemeDisplayConstants.DEFAULT_TRANSPARENT_COLOR); + setWidgetBackground(WidgetThemeDisplayConstants.DEFAULT_COLOR_BACKGROUND); + setBorderColor(BorderStyle.DEFAULT_WIDGET_BORDER_COLOR); + setIconColor(Color.BLACK); + } + + private void setSelectBgColor(Color selectBgColor) { + if (selectBgColorBox != null) { + selectBgColorBox.setSelectObject(selectBgColor); } - if (fontColorButton != null) { - fontColorButton.setColor(Color.BLACK); + } + + private void setWidgetBackground(ColorBackground background) { + if (widgetBgColorSelectBox != null) { + widgetBgColorSelectBox.setSelectObject(background.getColor()); } - if (frFontPane != null) { - frFontPane.populateBean(FRFont.getInstance()); + if (widgetBgAlphaDragPane != null) { + //0-255,需要转化为 + double alpha = ColorUtils.roundColorAlphaDouble(background.getColor()); + widgetBgAlphaDragPane.populateBean(alpha); } - if (selectBgColorBox != null) { - selectBgColorBox.setSelectObject(null); + } + + private void setBorderColor(Color borderColor) { + if(borderColorSelectBox != null) { + borderColorSelectBox.setSelectObject(borderColor); } } - private void setSelectBgColor(ThemedWidgetStyle widgetStyle) { - if(selectBgColorBox != null) { - selectBgColorBox.setSelectObject(widgetStyle.getSelectBackgroundColor()); + private void setIconColor(Color iconColor) { + if(iconColorSelectBox != null) { + iconColorSelectBox.setSelectObject(iconColor); } } @@ -305,13 +333,8 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa * 初始化枚举和UILabel对应的map */ private void initLabelMap() { - labelMap.put(StyleSetting.THEME_COLOR, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color"))); - labelMap.put(StyleSetting.TEXT_STYLE, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style"))); - labelMap.put(StyleSetting.FONT, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Font"))); - labelMap.put(StyleSetting.STYLE_TYPE, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Style"))); - labelMap.put(StyleSetting.LINE_TYPE, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line"))); - labelMap.put(StyleSetting.BORDER_RADIUS, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius"))); - labelMap.put(StyleSetting.BTN_BACKGROUND, new UILabel(Toolkit.i18nText("Fine-Design_Theme_Widget_Background"))); - labelMap.put(StyleSetting.SELECT_COLOR, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Background_Select_Box"))); + for (StyleSetting setting : StyleSetting.values()) { + labelMap.put(setting, WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText(setting.getLabelI18nKey()))); + } } } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/LabelSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/LabelSettingPane.java index 4146ef684..19453a6da 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/LabelSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/LabelSettingPane.java @@ -1,11 +1,15 @@ package com.fr.design.widgettheme; +import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.FontStyle; import com.fr.form.ui.Label; import com.fr.form.ui.Widget; import com.fr.general.FRFont; import com.fr.widgettheme.theme.widget.theme.LabelTheme; +import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; +import java.awt.Color; import java.util.Collections; /** @@ -37,7 +41,7 @@ public class LabelSettingPane extends BaseStyleSettingPane private LabelTheme initLabelTheme(T t) { LabelTheme widgetTheme = (LabelTheme) t.getWidgetTheme(); if (widgetTheme == null) { - widgetTheme = new LabelTheme(); + widgetTheme = initLabelTheme(); Label label = (Label) t; if (!label.getDefaultFont().equals(label.getFont())) { widgetTheme.setFollowTheme(false); @@ -48,6 +52,15 @@ public class LabelSettingPane extends BaseStyleSettingPane return widgetTheme; } + private LabelTheme initLabelTheme() { + LabelTheme labelTheme = new LabelTheme(); + Color fontColor = WidgetThemeDesignerUtils.isCurrentTemplateThemeDark() ? + ColorUtils.hexToColor(WidgetThemeDisplayConstants.COLOR_FFFFFF_HEX) : + ColorUtils.hexToColor(WidgetThemeDisplayConstants.COLOR_091E40_HEX); + labelTheme.getFontStyle().setFont(FRFont.getInstance().applyForeground(fontColor)); + return labelTheme; + } + @Override public void updateBean(T t) { LabelTheme widgetTheme = initLabelTheme(t); diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/ParaButtonSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/ParaButtonSettingPane.java index 084e183ab..620af9a80 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/ParaButtonSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/ParaButtonSettingPane.java @@ -21,7 +21,7 @@ public class ParaButtonSettingPane extends ButtonSettingPane extends ButtonSettingPane extends ButtonSettingPane extends EditorSettingPane extends EditorSettingPane extends EditorSettingPane extends NormalButtonS super(Arrays.asList( StyleSetting.BTN_BACKGROUND, StyleSetting.LINE_TYPE, + StyleSetting.LINE_COLOR, StyleSetting.BORDER_RADIUS, StyleSetting.FONT )); diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/ParaSelectEditorSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/ParaSelectEditorSettingPane.java index f7cd1eb93..b0f90a112 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/ParaSelectEditorSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/ParaSelectEditorSettingPane.java @@ -16,12 +16,14 @@ public class ParaSelectEditorSettingPane extends ParaEditorSet public ParaSelectEditorSettingPane() { super(Arrays.asList( StyleSetting.THEME_COLOR, - StyleSetting.SELECT_COLOR, - StyleSetting.STYLE_TYPE, + StyleSetting.WIDGET_BACKGROUND, StyleSetting.LINE_TYPE, + StyleSetting.LINE_COLOR, StyleSetting.BORDER_RADIUS, - StyleSetting.TEXT_STYLE - )); + StyleSetting.ICON_COLOR, + StyleSetting.TEXT_STYLE, + StyleSetting.SELECT_COLOR + )); } @Override diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/ParaTreeEditorSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/ParaTreeEditorSettingPane.java index 462bdbaf4..fbebd5863 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/ParaTreeEditorSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/ParaTreeEditorSettingPane.java @@ -21,7 +21,7 @@ public class ParaTreeEditorSettingPane extends TreeEditorS public ParaTreeEditorSettingPane() { super(Arrays.asList( StyleSetting.THEME_COLOR, - StyleSetting.STYLE_TYPE, + StyleSetting.WIDGET_BACKGROUND, StyleSetting.TEXT_STYLE )); } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/StyleSetting.java b/designer-form/src/main/java/com/fr/design/widgettheme/StyleSetting.java index bae829f03..f3b8cca75 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/StyleSetting.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/StyleSetting.java @@ -12,34 +12,56 @@ public enum StyleSetting { /** * 主题颜色 */ - THEME_COLOR, + THEME_COLOR("Fine-Design_Widget_Theme_Color"), /** - * 风格 + * 线型 */ - STYLE_TYPE, + LINE_TYPE("Fine-Design_Widget_Theme_Border_Line"), /** - * 线型 + * 线型颜色 */ - LINE_TYPE, + LINE_COLOR(""), /** * 边框圆角 */ - BORDER_RADIUS, + BORDER_RADIUS("Fine-Design_Widget_Theme_Border_Radius"), /** * 文本样式 */ - TEXT_STYLE, + TEXT_STYLE("Fine-Design_Widget_Theme_Text_Style"), /** * 字体 */ - FONT, + FONT("Fine-Design_Widget_Theme_Font"), /** * 按钮背景 */ - BTN_BACKGROUND, + BTN_BACKGROUND("Fine-Design_Theme_Widget_Background"), /** * 自定义下拉框颜色 */ - SELECT_COLOR + SELECT_COLOR("Fine-Design_Widget_Background_Select_Box"), + + /** + * 控件背景 + */ + WIDGET_BACKGROUND("Fine-Design_Widget_Theme_Widget_Background"), + + /** + * 图标颜色 + */ + ICON_COLOR("Fine-Design_Widget_Theme_Icon_Color"); + + /** + * label标签i18n key + */ + private final String labelI18nKey; + StyleSetting(String labelI18nKey) { + this.labelI18nKey = labelI18nKey; + } + + public String getLabelI18nKey() { + return labelI18nKey; + } } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/common/ButtonSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/common/ButtonSettingPane.java index 9433b9e10..acdebeb96 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/common/ButtonSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/common/ButtonSettingPane.java @@ -3,7 +3,6 @@ package com.fr.design.widgettheme.common; import com.fr.design.widgettheme.StyleSetting; import com.fr.design.widgettheme.BaseStyleSettingPane; import com.fr.form.ui.Widget; -import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; import com.fr.widgettheme.theme.widget.theme.cell.ButtonTheme; import org.jetbrains.annotations.Nullable; @@ -23,7 +22,7 @@ public class ButtonSettingPane extends BaseStyleSettingPane public ButtonSettingPane() { super(Arrays.asList( StyleSetting.THEME_COLOR, - StyleSetting.STYLE_TYPE + StyleSetting.WIDGET_BACKGROUND )); } @@ -65,11 +64,6 @@ public class ButtonSettingPane extends BaseStyleSettingPane } else { styleSettingHead.setSelectedIndex(1); colorSelectBox.setSelectObject(buttonTheme.getThemeColor()); - if (buttonTheme.getStyleType() == WidgetThemeDisplayConstants.STYLE_1) { - style1.setSelected(true); - } else { - style2.setSelected(true); - } assignFontSizePane(buttonTheme); } switchCard(); @@ -89,7 +83,6 @@ public class ButtonSettingPane extends BaseStyleSettingPane protected void updateButtonStyleBean(ButtonTheme buttonTheme) { buttonTheme.setThemeColor(colorSelectBox.getSelectObject()); - buttonTheme.setStyleType(style1.isSelected() ? WidgetThemeDisplayConstants.STYLE_1 : WidgetThemeDisplayConstants.STYLE_2); assignFontSizeStyle(buttonTheme); switchCard(); } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java index 5209a7baa..be3eb7acc 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java @@ -1,12 +1,13 @@ package com.fr.design.widgettheme.common; +import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.BorderStyle; import com.fr.design.widgettheme.BaseStyleSettingPane; import com.fr.form.ui.Widget; import com.fr.design.widgettheme.StyleSetting; -import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; import com.fr.widgettheme.theme.widget.theme.cell.EditorTheme; +import com.fr.widgettheme.util.WidgetThemeDesignerUtils; import org.jetbrains.annotations.Nullable; import java.util.Arrays; @@ -25,7 +26,7 @@ public class EditorSettingPane extends BaseStyleSettingPane public EditorSettingPane() { super(Arrays.asList( StyleSetting.THEME_COLOR, - StyleSetting.STYLE_TYPE, + StyleSetting.WIDGET_BACKGROUND, StyleSetting.LINE_TYPE, StyleSetting.BORDER_RADIUS )); @@ -74,13 +75,11 @@ public class EditorSettingPane extends BaseStyleSettingPane } else { styleSettingHead.setSelectedIndex(1); colorSelectBox.setSelectObject(editorTheme.getThemeColor()); - if (editorTheme.getStyleType() == WidgetThemeDisplayConstants.STYLE_1) { - style1.setSelected(true); - } else { - style2.setSelected(true); - } lineComboBox.setSelectedLineStyle(editorTheme.getBorderStyle().getLineType()); borderRadiusSpinner.setValue(editorTheme.getBorderStyle().getRadius()); + widgetBgColorSelectBox.setSelectObject(ColorUtils.ignoreColorAlpha(editorTheme.getWidgetBackground().getColor())); + widgetBgAlphaDragPane.populateBean(ColorUtils.roundColorAlphaDouble(editorTheme.getWidgetBackground().getColor())); + iconColorSelectBox.setSelectObject(editorTheme.getIconColor()); selectBgColorBox.setSelectObject(editorTheme.getSelectBoxBgColor()); assignFontSizePane(editorTheme); } @@ -108,8 +107,8 @@ public class EditorSettingPane extends BaseStyleSettingPane protected void updateEditorStyleBean(EditorTheme editorTheme) { editorTheme.setThemeColor(colorSelectBox.getSelectObject()); editorTheme.setSelectBoxBgColor(selectBgColorBox.getSelectObject()); - editorTheme.setStyleType(style1.isSelected() ? WidgetThemeDisplayConstants.STYLE_1 : WidgetThemeDisplayConstants.STYLE_2); - editorTheme.setBorderStyle(new BorderStyle((int) borderRadiusSpinner.getValue(), lineComboBox.getSelectedLineStyle())); + editorTheme.setBorderStyle(new BorderStyle((int) borderRadiusSpinner.getValue(), lineComboBox.getSelectedLineStyle(), borderColorSelectBox.getSelectObject())); + editorTheme.setWidgetBackground(ColorUtils.createColorBackgroundWithAlpha(widgetBgColorSelectBox.getSelectObject(), widgetBgAlphaDragPane.updateBean())); assignFontSizeStyle(editorTheme); switchCard(); } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/common/NormalButtonSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/common/NormalButtonSettingPane.java index 006df9661..2cfc721e5 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/common/NormalButtonSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/common/NormalButtonSettingPane.java @@ -27,6 +27,7 @@ public class NormalButtonSettingPane extends BaseStyleSettingP super(Arrays.asList( StyleSetting.BTN_BACKGROUND, StyleSetting.LINE_TYPE, + StyleSetting.LINE_COLOR, StyleSetting.BORDER_RADIUS )); } @@ -118,8 +119,7 @@ public class NormalButtonSettingPane extends BaseStyleSettingP protected void updateNormalButtonStyleBean(NormalButtonTheme normalButtonTheme) { assignFontStyle(normalButtonTheme); normalButtonTheme.setButtonBackgroundStyle(buttonStyleDefinedPane.update()); - normalButtonTheme.setBorderStyle(new BorderStyle((int) borderRadiusSpinner.getValue(), lineComboBox.getSelectedLineStyle())); - + normalButtonTheme.setBorderStyle(new BorderStyle((int) borderRadiusSpinner.getValue(), lineComboBox.getSelectedLineStyle(), borderColorSelectBox.getSelectObject())); switchCard(); } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/common/SelectEditorSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/common/SelectEditorSettingPane.java index c226852ba..4bc0bf1d3 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/common/SelectEditorSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/common/SelectEditorSettingPane.java @@ -18,10 +18,12 @@ public class SelectEditorSettingPane extends EditorSettingPan public SelectEditorSettingPane() { super(Arrays.asList( StyleSetting.THEME_COLOR, - StyleSetting.SELECT_COLOR, - StyleSetting.STYLE_TYPE, + StyleSetting.WIDGET_BACKGROUND, StyleSetting.LINE_TYPE, - StyleSetting.BORDER_RADIUS + StyleSetting.LINE_COLOR, + StyleSetting.BORDER_RADIUS, + StyleSetting.ICON_COLOR, + StyleSetting.SELECT_COLOR )); } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/common/TreeEditorSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/common/TreeEditorSettingPane.java index 5381909c0..6f6676071 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/common/TreeEditorSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/common/TreeEditorSettingPane.java @@ -3,7 +3,6 @@ package com.fr.design.widgettheme.common; import com.fr.design.widgettheme.StyleSetting; import com.fr.design.widgettheme.BaseStyleSettingPane; import com.fr.form.ui.TreeEditor; -import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; import com.fr.widgettheme.theme.widget.theme.cell.TreeTheme; import org.jetbrains.annotations.Nullable; @@ -23,7 +22,7 @@ public class TreeEditorSettingPane extends BaseStyleSettin public TreeEditorSettingPane() { super(Arrays.asList( StyleSetting.THEME_COLOR, - StyleSetting.STYLE_TYPE + StyleSetting.WIDGET_BACKGROUND )); } @@ -57,11 +56,6 @@ public class TreeEditorSettingPane extends BaseStyleSettin } else { styleSettingHead.setSelectedIndex(1); colorSelectBox.setSelectObject(treeTheme.getThemeColor()); - if (treeTheme.getStyleType() == WidgetThemeDisplayConstants.STYLE_1) { - style1.setSelected(true); - } else { - style2.setSelected(true); - } assignFontSizePane(treeTheme); } switchCard(); @@ -89,7 +83,6 @@ public class TreeEditorSettingPane extends BaseStyleSettin protected void updateTreeStyleBean(TreeTheme treeTheme) { treeTheme.setThemeColor(colorSelectBox.getSelectObject()); - treeTheme.setStyleType(style1.isSelected() ? WidgetThemeDisplayConstants.STYLE_1 : WidgetThemeDisplayConstants.STYLE_2); assignFontSizeStyle(treeTheme); switchCard(); } From 05d416ed9958d6bf8213c8d9718f845667e6d896 Mon Sep 17 00:00:00 2001 From: obo Date: Mon, 29 Jan 2024 16:09:31 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E8=A1=A5=E5=85=85=E4=B8=80=E4=BA=9B=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widget/MobileWidgetStyleEditPane.java | 13 ------- .../theme/panel/ControlPreviewCell.java | 2 + .../util/WidgetThemeDesignerUtils.java | 4 +- ...dgetThemeMobileStyleDefinePaneCreator.java | 38 +++++++++++++++---- .../widgettheme/BaseStyleSettingPane.java | 13 ++++--- .../widgettheme/common/EditorSettingPane.java | 1 + 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java index a41a3c976..ec6ef9aeb 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java @@ -1,29 +1,16 @@ package com.fr.widgettheme.theme.edit.widget; -import com.fr.base.background.ColorBackground; import com.fr.base.theme.TemplateTheme; import com.fr.design.gui.frpane.FontSizeComboPane; -import com.fr.design.utils.ColorUtils; import com.fr.widgettheme.theme.widget.style.BorderStyle; import com.fr.widgettheme.theme.widget.style.MobileThemedWidgetStyle; import com.fr.design.gui.icombobox.LineComboBox; -import com.fr.widgettheme.theme.widget.style.StyleType; import com.fr.widgettheme.theme.widget.style.ThemeTextStyle; -import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; -import com.fr.widgettheme.util.WidgetThemeDesignerUtils; -import java.awt.Color; import java.util.Arrays; import java.util.Vector; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_00000000_HEX; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_00FFFFFF_HEX; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_26000000_HEX; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_26FFFFFF_HEX; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_CC000000_HEX; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_CCFFFFFF_HEX; - /** * 移动端控件样式编辑面板 * diff --git a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java index d9e350e9b..b42c26fcf 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java +++ b/designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java @@ -7,6 +7,7 @@ import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.general.FRFont; import com.fr.stable.Constants; +import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -106,6 +107,7 @@ public class ControlPreviewCell extends JPanel { */ public void paintBgColor(Graphics g, ThemedWidgetStyle widgetStyle, int alpha) { Color themeColor = widgetStyle.getWidgetBackground().getColor(); + themeColor = themeColor == null ? WidgetThemeDisplayConstants.DEFAULT_TRANSPARENT_COLOR : themeColor; g.setColor(new Color(themeColor.getRed(), themeColor.getGreen(), themeColor.getBlue(), alpha)); g.fillRoundRect(0, 0, getSize().width - 1, getSize().height - 1, (int) widgetStyle.getBorderStyle().getRadius(), (int) widgetStyle.getBorderStyle().getRadius()); //需要重新绘制一遍字体,否则会被颜色填充给遮住 diff --git a/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java index 68bceee16..452fb945b 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java +++ b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java @@ -9,6 +9,7 @@ import com.fr.design.mainframe.JTemplate; import com.fr.stable.StringUtils; import com.fr.widgettheme.control.attr.WidgetDisplayEnhanceMarkAttr; import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; +import org.jetbrains.annotations.NotNull; import javax.swing.SwingConstants; import java.awt.Color; @@ -67,9 +68,10 @@ public class WidgetThemeDesignerUtils { /** * 创建垂直方向顶部对齐的label */ + @NotNull public static UILabel createTopAlignmentLabel(String labelName) { if(StringUtils.isEmpty(labelName)) { - return null; + return new UILabel(""); } UILabel label = new UILabel(labelName); label.setVerticalAlignment(SwingConstants.TOP); diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java index 226bf64df..62108a9de 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java @@ -24,6 +24,9 @@ import com.fr.log.FineLoggerFactory; import com.fr.widgettheme.widget.mobile.pane.IconColorMobileStyleDefinePane; import org.jetbrains.annotations.NotNull; +import java.util.HashSet; +import java.util.Set; + /** * 控件主题移动端样式窗口创建类 * @@ -36,6 +39,28 @@ public class WidgetThemeMobileStyleDefinePaneCreator { private WidgetThemeMobileStyleDefinePaneCreator() { } + /** + * 需要特殊处理的控件集合 + */ + private static final Set> SPECIAL_WIDGET_SET = new HashSet<>(); + /** + * 带有图标颜色的控件集合 + */ + private static final Set> ICON_WIDGET_SET = new HashSet<>(); + + static { + SPECIAL_WIDGET_SET.add(FreeButton.class); + SPECIAL_WIDGET_SET.add(Label.class); + SPECIAL_WIDGET_SET.add(MultiFileEditor.class); + SPECIAL_WIDGET_SET.add(TextArea.class); + ICON_WIDGET_SET.add(TextEditor.class); + ICON_WIDGET_SET.add(NumberEditor.class); + ICON_WIDGET_SET.add(Password.class); + ICON_WIDGET_SET.add(DateEditor.class); + ICON_WIDGET_SET.add(ComboBox.class); + ICON_WIDGET_SET.add(ComboCheckBox.class); + ICON_WIDGET_SET.add(TreeEditor.class); + } /** * 创建移动端控件样式属性窗口 * @@ -47,7 +72,7 @@ public class WidgetThemeMobileStyleDefinePaneCreator { public static BasicBeanPane createBaseBeanPane(Widget widget, Class customDefinePane, Class mobileStyle) { try { if (WidgetThemeDesignerUtils.enableWidgetEnhance()) { - if (specialCommonWidget(widget)) { + if (isSpecialWidget(widget)) { return DisplayEnhanceMobileStyleFactory.createWidgetMobileStyleDefinePane(widget, customDefinePane, mobileStyle); } else if (isIconWidget(widget)) { return new IconColorMobileStyleDefinePane(widget, customDefinePane, mobileStyle); @@ -68,7 +93,7 @@ public class WidgetThemeMobileStyleDefinePaneCreator { * @return class */ public static @NotNull Class classForCommonExtraStyle(Widget widget) { - if (specialCommonWidget(widget)) { + if (isSpecialWidget(widget)) { return DisplayEnhanceMobileStyleFactory.classForWidgetCommonExtraStyle(widget); } else { return WidgetThemeMobileCommonExtraStyle.class; @@ -82,8 +107,8 @@ public class WidgetThemeMobileStyleDefinePaneCreator { * @param widget 控件 * @return 是/否 */ - private static boolean specialCommonWidget(Widget widget) { - return widget instanceof FreeButton || widget instanceof Label || widget instanceof MultiFileEditor || widget instanceof TextArea; + private static boolean isSpecialWidget(Widget widget) { + return SPECIAL_WIDGET_SET.contains(widget.getClass()); } /** @@ -93,9 +118,6 @@ public class WidgetThemeMobileStyleDefinePaneCreator { * @return 是/否 */ private static boolean isIconWidget(Widget widget) { - return widget instanceof TextEditor || widget instanceof NumberEditor || widget instanceof Password || - widget instanceof DateEditor || widget instanceof ComboBox || widget instanceof ComboCheckBox || - widget instanceof TreeEditor || - WidgetThemeServerUtils.isNewComboBoxTreeEditor(widget); + return ICON_WIDGET_SET.contains(widget.getClass()) || WidgetThemeServerUtils.isNewComboBoxTreeEditor(widget); } } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java index 93683c92e..985d41122 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java @@ -8,7 +8,6 @@ import com.fr.design.gui.ibutton.UIColorButton; import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.general.IOUtils; -import com.fr.stable.StringUtils; import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.BorderStyle; import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle; @@ -38,7 +37,6 @@ import com.fr.widgettheme.util.WidgetThemeDesignerUtils; import javax.swing.BorderFactory; import javax.swing.JPanel; -import javax.swing.SwingConstants; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; @@ -135,9 +133,7 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa protected void initStyleEditor() { colorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, false); - lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.BORDER_LINE_STYLE_ARRAY); - borderColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); - borderRadiusSpinner = new UIBoundSpinner(0, Integer.MAX_VALUE, 1); + initBorderPane(); frFontPane = new FRFontPane(); buttonStyleDefinedPane = new ButtonStyleDefinedPane(); selectBgColorBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); @@ -337,4 +333,11 @@ public abstract class BaseStyleSettingPane extends BasicBeanPa labelMap.put(setting, WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText(setting.getLabelI18nKey()))); } } + + private void initBorderPane() { + lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.BORDER_LINE_STYLE_ARRAY); + borderColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true); + borderRadiusSpinner = new UIBoundSpinner(0, Integer.MAX_VALUE, 1); + lineComboBox.addItemListener(e -> borderColorSelectBox.setVisible(!Integer.valueOf(0).equals(e.getItem()))); + } } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java index be3eb7acc..ea547eb67 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java @@ -28,6 +28,7 @@ public class EditorSettingPane extends BaseStyleSettingPane StyleSetting.THEME_COLOR, StyleSetting.WIDGET_BACKGROUND, StyleSetting.LINE_TYPE, + StyleSetting.LINE_COLOR, StyleSetting.BORDER_RADIUS )); } From 8fe43ca30b053e3cf48b844095a439c343fd2163 Mon Sep 17 00:00:00 2001 From: obo Date: Mon, 29 Jan 2024 16:31:28 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E6=B6=88=E9=99=A4=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile/pane/DisplayEnhanceMobileStyleDefinePane.java | 4 +--- .../com/fr/design/widgettheme/BaseStyleSettingPane.java | 4 +--- .../com/fr/design/widgettheme/ParaEditorSettingPane.java | 7 ------- .../fr/design/widgettheme/ParaNormalButtonSettingPane.java | 2 -- 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java index 66aa578c5..a17f51874 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java +++ b/designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java @@ -44,8 +44,6 @@ import java.awt.Font; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.THEME_MOBILE_WIDGET_BACKGROUND_WIDTH; - /** *

开启控件显示增强后替换原通用属性面板 *

参考{@link com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane} @@ -211,7 +209,7 @@ public class DisplayEnhanceMobileStyleDefinePane extends BasicBeanPane extends BasicBeanPa paneMap.put(StyleSetting.FONT, frFontPane); paneMap.put(StyleSetting.BTN_BACKGROUND, buttonStyleDefinedPane); paneMap.put(StyleSetting.SELECT_COLOR, selectBgColorBox); - paneMap.put(StyleSetting.WIDGET_BACKGROUND, WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, THEME_PC_WIDGET_BACKGROUND_WIDTH)); + paneMap.put(StyleSetting.WIDGET_BACKGROUND, WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, WidgetThemeDisplayConstants.THEME_PC_WIDGET_BACKGROUND_WIDTH)); paneMap.put(StyleSetting.ICON_COLOR, iconColorSelectBox); } diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java index eb891a6b1..5a67090bc 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java @@ -2,20 +2,13 @@ package com.fr.design.widgettheme; import com.fr.design.widgettheme.common.EditorSettingPane; import com.fr.form.ui.Widget; -import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.ThemeTextStyle; import com.fr.widgettheme.theme.widget.theme.ParaEditorTheme; import com.fr.widgettheme.theme.widget.theme.cell.EditorTheme; -import com.fr.widgettheme.util.WidgetThemeDesignerUtils; -import java.awt.Color; import java.util.Arrays; import java.util.List; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_091E40_HEX; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_FFFFFF_HEX; - - /** * 设计器控件属性的“高级”设置增加主题样式设置项,包括: * 文本控件/数字控件/密码控件/文本域控件/下拉框控件/下拉复选框控件/下拉树控件/日期控件 diff --git a/designer-form/src/main/java/com/fr/design/widgettheme/ParaNormalButtonSettingPane.java b/designer-form/src/main/java/com/fr/design/widgettheme/ParaNormalButtonSettingPane.java index f083c7dc5..c50c6207e 100644 --- a/designer-form/src/main/java/com/fr/design/widgettheme/ParaNormalButtonSettingPane.java +++ b/designer-form/src/main/java/com/fr/design/widgettheme/ParaNormalButtonSettingPane.java @@ -1,6 +1,5 @@ package com.fr.design.widgettheme; -import com.fr.util.ColorUtils; import com.fr.widgettheme.theme.widget.style.FontStyle; import com.fr.design.widgettheme.common.NormalButtonSettingPane; import com.fr.form.ui.FreeButton; @@ -11,7 +10,6 @@ import com.fr.widgettheme.theme.widget.theme.cell.NormalButtonTheme; import java.util.Arrays; -import static com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants.COLOR_FFFFFF_HEX; /** * 参数面板常规按钮设置窗口 * From 3ee75bbb726fc9c6da7c3b90b0975bb9afd44c08 Mon Sep 17 00:00:00 2001 From: obo Date: Mon, 29 Jan 2024 17:23:34 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E6=97=A0JIRA,=E5=8E=BB=E9=99=A4=E5=A4=9A?= =?UTF-8?q?=E4=BD=99import,=E8=A7=A3=E5=86=B3=E6=89=93=E5=8C=85=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/WidgetStyleComponentCombiner.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java index b612b7027..6fd2757c9 100644 --- a/designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java +++ b/designer-base/src/main/java/com/fr/widgettheme/util/WidgetStyleComponentCombiner.java @@ -7,30 +7,14 @@ import com.fr.design.gui.ibutton.UIColorButton; import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.gui.icombobox.LineComboBox; import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane; import com.fr.design.style.color.NewColorSelectBox; import com.fr.design.widget.FRWidgetFactory; -import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants; -import groovy.swing.factory.LayoutFactory; -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.JComponent; import javax.swing.JPanel; -import java.awt.CardLayout; import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.LayoutManager; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; /** * 创建控件样式组合配置面板的工具类