From 04edc0122c15d18cf49e31d28213934bb66c7c76 Mon Sep 17 00:00:00 2001 From: Artem Bochkarev Date: Tue, 19 Jun 2018 19:19:53 +0700 Subject: [PATCH] IDEA-194199: fixed layout (width with insets) for dialog buttons --- bin/mac/libnst64.dylib | Bin 52456 -> 52952 bytes native/MacTouchBar/src/Button.m | 136 +++++++++++++----- .../openapi/keymap/impl/ui/KeymapPanel.java | 4 +- .../intellij/ui/mac/touchbar/BuildUtils.java | 31 ++-- .../intellij/ui/mac/touchbar/NSTLibrary.java | 12 +- .../ui/mac/touchbar/TBItemButton.java | 33 +++-- 6 files changed, 162 insertions(+), 54 deletions(-) diff --git a/bin/mac/libnst64.dylib b/bin/mac/libnst64.dylib index 597c2e6db6c00d0d5448d9c946d33ddf0ac45f89..c1f675e8e9f92d4eb7217f6ac79c372c01c1f4d9 100755 GIT binary patch literal 52952 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

oAAjg9wfO_dI|WG9?t+!Q>wGFT{$nzsZuF8X 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

-m7qZ;uZHn9u*rU<5oTU_qE`*$OmI;<+4ituY(#ptz|@WpABR0~ z*aL?>aM%NfJ@EfG4>Worzw`9%Yw}p`nKf2pp(oP2KhpDoC(>wpBDE7$5%(Kak=k*O z)w{nY(m3RaxVPI2t1wTDxW_zJ56;}pn*dt*CAf3(L`FQ3oySOZCda`sYX40dzw~0S8(dBT(wf(I!8HcBJS~;NG4|Hkjt+{UC@zKALy@8+PmKq!GHIZ$GXgAZSZ)ktLJ#ECB-$?WeaPp zC1up`j{XPo>f2M8(*9jPoJQqkB|XqUr&8EA?DAMwx?gb70T?_* zD&N1+ zmMT$|SJP=wx9H^BdxFEwao}_IFU_y`?grm`1%;$=^#J=%=fYX&_g@O=z~<4lx>9G%+!6Z71&`0xm*I6}g30lss1M zNlS=8T_$&?x}2E2AKgXdYDDg5mk`QqV3by%^LN%Nwjq?~4P2vW1GxOTy4*%`Fl{+TKK6b7MnshN3a&XS56E4DYh&E<9N=cS z2S|keeBI96(N}C=8zw_XNqH(-+dXll$&6@(?*`zvtpn zGMYwfq*0n|6l^(BX%lQAV=<&svsw9^{T5tPaB3KU>K~i;O;8JnVyw3E?_$-Tz)XhP z)C8)295bCUWQB~)8tjX4wQL#vCo1ea(4@TI3uQ1BJj{1tjBl9uZYREI?;u(S%}}8& zN_b>4j4V&!7(%nAq8yfk*I0jzl~)rv>Wmu8gS6(1JX{pg1!lOOnRGGJz8IP(mmr?2 z%uVYCT%uhR#Vp&DY}pr>0S#-*PO|LXg>2aX?1oi42!|pAG&geq>e+_N^(=!iORT~i zCYcHY za1BIPa}A*LFDG?V7XpkvZIFwi(s*c;+e%bVWGfS_q7B?#x8|`Yivp};M;){L3OwaUaX$}PHM ziW4rf3Zq+z36?U!DteK7&er{ew2FSfs-k7gLNS%D4k4!g?gE%#<@VQ5g8w|o6m0nf z8M=87jTIO~z6z$~`H;+lHo*ooyhE5TEn&`s&6nmMvcBmV^!4rQLJyc(6<^X zL?~ZkX0uYjEefn^QL5G}xnbn2R(A^R8Rrv;Z`E!4)%m!MLlZ&W(!8Q~*lPR$>kFv# zA*}A~q~cJUqYw_0u*ySs5tjKb=hnLo*22(jb^)@ndZ%nRHqj#Phx>XT#*}_8WZp*v z%X2GPtM=i($y?qpIA`zs1r)2y?E51~%izvP?LP7* z7LmrS+7J5PD(w3oE=|F$Pbw4l!yxnsvs)YzBF%lhg)nGoi~}vrGM6h3PvixAiOL?> zqRRkx6JofAsZ~M zyawbX)EJiggT9Fzz8AWN?Ck5EklP}@U!~0RAE%CHna?U&sxo^kukR+j0+5PTvJe zui^c>Xt@`-$*T-zLNU#?g5MI?zMN6iNJ%>q_kg`xY5z|ugVj4g)Bbv(s9Ma0qN0LS zL$h*KHap>)*<7W&b|NSlk=>SiU*7~dv8-V0^JU?8vda2&MMrZM=2@fx?csisODNwrsToLRXzi;d}z*NAFJ}|R{8KWh>X~6e}n+YevCVld(@Y9h2P5R zuO0b9?FcRk9><8ujiiqCz8=|f9jSc^(p3e|3|CoEg5A_wJ}oX$k|^>c=wI+i!80%0 zcj(-d&&*FMk{tq`Z=G(vJ?2pJ#g!~)UmYV}5ho4_v4n`0xl0tCt9frb6}&sqA9?D74%bR+f?h1J@Gs zi2Vx^vdo9L;gqgo?9(2Yr6#26YD*b4hVKw-)V!HSQi^80rj0g+mA3_ChuWL58mBA_ zk1}>+o5@uZIqnR5Xg{Xfzl-NzDEY5Y`Jb)w{|&l0mdzK&@>f?|==Q`uU*&&FEPukP z{J)1sJ}_+lR|S&j4sQO@QrdO#MDxFlOlz#%uYpz*;X8zM3;nnUqBw!fIS5hIjMRp! zFuY^VG>CKx=>tgjA>FPNOi7wd|t@w9`ej7VH>EzG!HUkU!?_4@e^OtF2c(ur*hwf;!+Sz4@#BHP5Z zMYRV1GWQKyurnWJXJfA=&x2(Y50+6pw2Xoa^hhkDc(7o>Hz@W#)ob)BeG8(9idXsn zO&tdNcFU1a{B)1oPjJ)DUtY$PYE`2LzYDTAvz%Fmc@(*-TY)o3-ohTMiq6+DmIu}i zDr@^{o%NXgS(Wv#F6FF$qBI>s)<>wke#E61vH!}Q!@Q5=Y2im@{T5?6>pjT&`J6m) zg4ru3KMM|?_T@iEoz*gb9COR4{dJ{u7ooVb@Mv>KOsV-9(XxqA`Ta`8*^DL64%=R( z;uK}qu-H`{SMh-q;3A;PIo8uQh-GU0DRI`l!g{3Ac@BGV#Qyv2_@wQ5VX=Wz)y)&| zA26CM+G)SYB=ccHanI&L{UBL@-Y!s$W61uh61Y(b3`r4giwT$kW*)JF8pXF33G0#l zs1LQXbVgRc`%hnR|4F8$=fhz@rL3=S-ZzM0jk`pocc&-PGXwz)07XYoR(=13ZCh-< z3En!v$&PU(1-H_8>4`qgLC#_vZvBbFo;(8s;!Kd|f4I|y1U`=H8It`dh_tezt)raNmf^&l>L{FAI|zrIh{L`mT~5r0ak)xzTF!Eu(*+4R?c^-B z4spWEeX%kXtDLs0oQT6NN|zJ!A*WxQuF6EC8d?ICX)k8+x=e#Ar)?^y0VJ`U3RO;o zLz#%f{x+1Qc#rvzQx}M+Dq8-|{q;qhD=*yu-Z})-rXBuD~*b9^1hBvKos1)>PDHJL~E?HDt|92-MojoB}RAW z{u=r#6)BG!HqCYL`kjSc7Rvq|!` zW&Ttt#A-!VWEY+VdB7bR#hmB?$p0JU=kJZ+rju8bhFPFz3=24DnWgu$psdx<9uIaM zBF|%Xh@`Qp8Ob?=#Ox^P=2flSQK}@XaTH=ZIGYi>Q&ADGX_c!H zW}06YQUe=BXj<+v|6QSJQK*C|x$9URmR2nD<~Z?WBBJFX@7Q`(;{G!20pr0gRotTA zv5uo=aJ5_J@k`0rm+bLV$Wn4h(SOA`AY^`;b9%{sJkIe@jKe%asN0CjGttETVhl=C zxFaB~?U3PJnU#~P!JBFR3x3|SCONtl%{MtOn)cGp9Q@rlVOPd7bMAM?^UICr_aTDI zA?NoZH76@MzgM6@6%G%EILZebRlBy-Af5WWL2`L|(&*n5)1O)%(qGLoho=AJH2P0G zi2grQB_`Rg0~Onj_M;Zb_Ht#Xdw#&#-qbR}{95S6&CrdXCjGp!@arXvLjRbsTNrJ= z!l)6uk-%sX@48V%V{?RWD}RYuiAWDBY5N={dACTOL?Aal?LT_HkslB0LBqkqBR|lH zht(|e-WoFCCHwa$QEvI`Kf}r~HX=4q1Z=0=qWL!i@18%*Q%x9Rm71IvJ!glT-X0`) z_z-apUDf_7sp5dgtCD}alE4w0o1%^#RCcp(Pa?_$gCsStP#78 z%`#7onI(bw`4hl8;@%GlV-ii9!S-fsWTr%1vaAe5}l zTD17T%YKt7&_z#F(15`YPo|DvU0EcWyZQo3sJQ!MPqyt)_vc%SX<$|xinzyisbN}8 zugrJ2DU8@%oZVJMG;P7IAZ%pIOcLpPni6>DK`y0wdd@O`cRA<(;R1Tt22qzaL`y$3 zX}~G(A4Tm|^$*+k9S^nOh?QC|mB2a=*dOH6Ol$$}(c#b|R%)3R$%(nq_`0)f^xqX3qt; zqF8XKroSolYNA`_I29VYN&r%hG&3O!3}u#vw~PZnSqM$MFgioQy3j;?uVC(QWXn-( zi|hlNH%d?V6}5P_<)I{7t`%FJ20djz-71=ktp$&Dj0)FVxtO%aWEJ(HQfsXI9Jc*w zn&490j_jbxe@)~ka4zGlC?VjXVI=l)GQu)nuckzvl;HcWOF^Kb+u)+2(^PE|o~GU~ zMnyzAN-1i{jfpTnG*jrte-8U%eA6mVLvvky8dePmsF|Oq}Bl!gSiA&oz%qp*dH#q@>Z3-(wSqW`9S{X|zie+9WS|24DiuQfIW9YwaF|GOEqn_WlC=XZ{ur!sY-16@s zyp@v&C8vs#0F>yxJVY~|hz5x*k~3eVTH;cZ)R18A1(dZa!Oz?Z z^5E0Vg?-)r%W)h!`C(6IeAm8Jn6=572stH>$D8*}k)N<@CRkBO7lpW(Nf$HiU!$!<;9jx)B?8s+?EP>MJYjxb zddp+XNsr_(IwK06$Zl|=gp|EmD3n>8b?#=B?e{9chi-BdW6dW8{0Dah^C>oJ#Qr0J zY6}44E)DspnB3L8G-p05-D)q($h^S(u3*2;7%)vQypE&*35P`$-5V%IBGXz1M7_j{Uq z-}dbKeXb|#pB$RqWA>E=tWUi?M9-n`wohgyB!N4O<{n7A1Bv&z0lG)+A0N#UrDQ$b zic`DXZQHCTRmfU46Xp(!eY+Kx4MC_kv!n@q8)%fXZ#XOBetYths$JqG33}*U-5+k= z7pC%yOK}$!sePO6i;yB#c3c@Tyl!95c@&+;_L=Wo%2gMc+SHp)6W0p@{av zkw92QM=FV@l!Sde>oI@C;D|k)K)xyIwXL4F?IN04SVfN_7U8kfZ8gzcYYt`}(R>=f zYOJCyM8J+C-uc=#;vNKY_lWxeB-k&j-Hr!chPYOET?6})w7?RfXQJswt>3<#olJKm zW{ntd8=*Gu2}1)lxRm`Va!$hgEb3(z^Js2WbgMsNS1F|v9;?m;#mAPBg|FM^5n3&8 zp<>J`X@|!%x0x&8bR|q2=LqV9dL>5_fAofjl7(2z|SLt;&1~uKXHl(P;{gcOcddcMn(+NttYe%`_`>(p4sQKJ{m21NLA(`iMxy+k9pZobIkz3OGO0xc+ zlQ#}=zW509ChOmnqCXx#Q6*D&1qseNiJWDX{4GJ3==AdqkQ zaxZ5A^D9F6%O^l-W>qd}OTQtMW!`@Y$&A>q5Qr`{;(irQM~Hv*68FA>Xk8X@VVS16 z_Ei*&MI^%=XA$@&cM?-H_e@eneabSw!fKe~Q^}g{PSSKmT+@4KmXiUciFQRr z)6%%6F>oZ<*hHieTGZU z!xHkFupc5a_Xr)||F`c~eg+ycjvt?jsh8)C@&0GV=PBMl!a07t1q`gi_z__thd0<+xAC@1XC(Zp3^P}7AeloY}K z5%(Kt!H7z4a8x=E*UE|Te{&v3N~!SewYQRW-%$m`)}$6a>x6P#UAXxoecRX z7^6iupF)==A~L#m?o1+}J)(z?jkw2wMDOO(dFY9r2+c$=ndfKLxmTY>S+eJ2{Z09g zih|~s`yiLVd^VvA=dzjHgb~qiUIhX1K8@9A2%7|kr6!1Hc zyiN}zBkn=aaQ5KY)5e{6tnx8;!FOJ%ZvLrfWEWcW$M!TB1=3UQ$SdW${&1>0>lfuO zfAn5?!8yB0AO-sZt)tMg3O`VhW`TttlGqO`(75R-i$XURX5@K`0TSK@H(t($nw1M+ zFLf66knfk_4-~5reV^pOT}Y1tj@Z45u!!maUvGx6rBmG$!S~X%Ytoe%w2lOSx-}*#Az%gX>SW7l8q)a-*z~HW18gQCF3s z?&I12oQXxu+4K?Jk7sA|-yHsX1pm$Bzn|p4NAcgI`EMcrJ%;}t$A6FKzccyor|=hH zDSC1>l$Y0kJo{p#1Fcv^GA7?aD{GxcS8vc&H(mXdu5PERQMwwWt7quy2XyrqUE#u* z{1#nZL05xx^*mjDnXcZXt2^lG1G@S=T@|2NOj4I=EvBmuy1Ig{TIgymU9G@XbGP3Y z^1He^yE@nVyIt4LE?eoE6KVyvrNlM6>}gmEa+z!OHeqq_A#YWH{s`YiR z33RyHdxD{kvqG*_epj=vtKBmldb##VW@kL)(sMF=&=x^=` z`HfZlaoUEZbFZ9xl~)0)HUwHitwuwO!YSwmrNd~r{!&J3xP4PaXLk#}I4tZjxP6l< zYMdZ&qQeqO;F{C!gJUxKHi(W?Uf4Rc)z(SWZtFAn(IS`1IgP3O&S zIqzBrY6=&-h$P0b<*t*_Oyju+~VTI)tx94Sj(KoNzZ8s zwAB0C{LP`{a?N$2$t2s3)*qAt;DXBLREdwOuI}t^mmWiXF6L+Q0yzNQZS@7wKbFp2 zX7FcN`P;5W!|8xq{NN9CaYy88*LAvVZY7ATde&4WaFEKNs^8k4kZ)C+zr4HKw<%W5 zOqRNf*>R8J-U$>Xs?2_3>yL{u@Xa%DwH2H8}VU{2PzqxV9MocKq@h0)ba|+t966| zp*Fuk!NX_?@BoO<(o*FvS#<+~MX&^|{R;o4U0FhYkPmU1*_is94f zmIhYb((T*8S0x)D#9zBD33Sl7P+|~GHG))H>HtZFtyj^rg1!ced|3fa1OlDiWK*(w zZ%hZSWK{L_gz%-Lf`L_mwm@i89VtUvV$d*Pbl?mGYtgc#2Y|VOhf=N+ zYFV8feCh6>$kc*s{=)BKcy!5XGMK3Z@`Z8+wGwInDNR>3X=YY!v_aY#1#f=~T6UsA(}oT_u5rexuy73|6h__WL_ZR<-r`OMGoztv*&?kB$iQ0zt9eX!Cch z!JI}LSJxQ~sPgF^uRKf)v4NU3aaoi%<3qNujpt|~zZ!R9rjuyQ{20J`%G&~KI@%E- z7-|gqgY}q+wfU(>sm{c0jdC)4EiLsutEiTkxyHAtvj=+7?>P_zjaA%Cj8*>6Awt#p zLao$BmJyOdQFEwd<1$}MpeI6Ne>U3B~(i3+>5(A+nq?zDO@6l z1Yfd;)gXP9j~Ws8_J+>Ife^W;!q>cZO*eT~S2YV%x359qq#7=vR)HWC2x$#}G zlQ=aABtG4|D6n7#M?GZ?WSIo1HHMlHa6mF>fF&oepJHQBN#}+R8kO(~W>mDy;-C+V z)OO%}l8NJkJZzBBZL1BL-6%^tp~Z>V0ADH(9*~yE76{gLcW&H7vBckw`DiT4qnZ$5 z+k*|AUgZ8< zQ{jVfLcPq6QE+`l4bbVH7%|-(GC>w(Phd?e`fzLFEHjy-venl?_aF$kZT@9+jX)k~ zsqo{551q;1P0g=k4b^AdJTNRq3<|a$h@;Zifk7f8N30ZW94Sg@BugnN8XNfr%?*Qa zD50?uHlc4fHY{GK`U5qZP!-0MH5^O{z&${HXHR!CO4f~H;e+qpYD`B>llsJY6Zm;f zQr^TpSS>QpN!Lz)71`dY{v zu^D5fj|`^K6-BxdpT6gdq-m8q*zD`_W6FWqVjHHhG#WUa#`E8J6~yLnB{~{Vy~cw9 zXJ2xIOw~)8v8vG7j(n;yT6;Ab0Y*>Cy{sR@qMA!4)$?i}LTs`<%6FJJbTkLLd~L}@ zgi{@UX^ae${*j15EN%9}E2IC_^%M_uWs>ihEOC-2|n^-#+?p zP7PxUX}FSb>R48$($AJ*rHOw>f!1|tJ(t#dvGDY<6OT1AIvB4m6aOAphQ)7#R;kr- zPMJzSTZVlJL$4cMu4Z*HxKgbn>1agtMuUivhyb$&ssAEIW3eZWBPXel0Hhi^5~&hB z5>SiVIyb0(t3!*SdkMJoWsG+E{ENzpOBNbslCEEHA;E$97X=m+8|wwTG?@y}Xh}u^ zG_Joi8Aq_O)Mx?0xUupws^Zd?mfi~&QVu}SB&if>U1y*pM3e-kUWl$Y*|vjomR*Pf z9J<;C#biJQ<#6ai7c3wla?^qf4e=5nqrymDrDBj~E<7!n#h{7<>Y69Kvy5itXVL(L zq`HJIRW7)sT*@wFLlp#)(JcNIVbq=0L&8_-+PeNm@0Il{Fvgd{i=_-08u zSJI0lEtB+eNgE{9g{qN@f#cOh-3cmvQ1elMPdGGxn08Ui!}aQ7O468qM-9@GAav;86Lc{Y|D)-*Ncqo3afnT&a@SUrqm;(CK-v#6#0(T%)kG@1J;R`getXb|Mkin*K|n&(1*4TA>K84D?w- z$F676q4hTk9oxxCho0w zmft7zWr;*wYx)%B)?o^14l1@ol_C7$D4xx zhu{ZzmlzNB2tKz>@imFP^vx_f_%NVztI! z1b?C6U4nOkOd)i6RPkjsskBV^h?a-5N$7b(uW-;?g05=Y#UE|c^c zN!Li)DJevZA)KRhk#OjG9Oy|v;<9UfGCVGDruIPJUH;!3RK0jI%-G$eq%M2bkVSzK%OXdGTy-+`;PutP4 zUDu1u7p`ql_@4^CSO%g6%?kf3!8Zy1P0^$KZ{bCXuUqs?Z&z@5p-T4(zm5;a#R`9& z;ERO6SnxME_`3v8U!bHz^A8H%1swICu+-meVuwrgg2eH#U+8xUeU{KkmiqC4(C-!c zdXZ8BUoy}sPUPSW$-H%wq&G_%k@QYU?~(M|4p{qB+okQ$^{(q#*Q>5aT|YYg zk@!K^gVv+{tYPg(?KchU{C^>ObV@#;L(fkY6#re8E&BDtay#ex3hy8Spm?ez}AHKEcQ0pD21Z1OBZH_-@gw(>nzIUWQbcZ{vWrT&22w zOUtPJvzbJ8Dx67dlg+ELDq3dZ(@Gg+EaSlZl-+bXaty95zeBUYbONDMa z=+tj>aXuyeaJQuYYCk3`>TovEMZ%%|9~QrB|Ihq<0uwHq1U@{DB>Uy?IHLUV|K)Ln zV&tz|RXHz{{;FF+qrk*NN8&mN!Gup2_nvday_vTWcjiOKy?=@w5y`hs)=!=G4PBvh zeM;t0I*x^F6#gF3qvP11;C~``%|9Xde{=8~wMvf*3B|TyiEAeY6yCYMFe>!Zh5i*s z+#3`6c|v#2zbP(K-2bAib8VCKaY>()^#6@GnTLE_I1>+DUmK;KbbS@xp2&sYA{Y2# znMYnGX|1F_N%eY_o^Ngv{5_IBDd{VczA5QPlIBXi>iRuh;Lk{^*Q@k8lwa^SNP3f` zdVNgK|Mk3EuY2hA41Hg9Vv{QGsgj-{X|<#)C2f|pRnm=;eo0cj-tvUNdVYPZ&*05T`Os?q_;^rAgNxzyGLNX{`Y->cT4)Zr0+=jzNE*j z5_=^*Q_}M!)$1L4-9WE5==Ft=@O@d*2PFNTql6bITD}pB|TlzQc3-i;;BqNZjn^4JLvTU9p`j> z{HE~fxcG{|7w9-AsgBEDfp3)bPD%AV;SqtKm9*goWsg_Vc1aaB&EGrI;D8#J_?e!1 z=vck(uO;-pfQI${fQI${fQB=rG5f@RtyjwriQrC2hb7%8X;{*|l8#9_E@_^mG)~Y# z<0Tz+DlwKznu%{t2EU4!Q7G%BbqC?wt_{|L8B&j9T|5Juv0U;UJXpS;%cLP0KXr)q zO^LqIgXG(FQ?mX{(8A4%GV_a>I23;8=T$mz5Wb1q53EO1iyiZ-FF591J014-->fB7 zx?SKVK~Fj8$=rs~Bl-t!5qU|Sd``GY5EBRC|98LGk{^ry@hvGNMoeYEHwk;8qdwDXIgCB*fx{j+?194`IP8JL9ysiQ z!yY*7fx{j+?194`IP8Ic%>y$|YicT}sIS!j!Y9n^%DWbbW$vbv%IoQ0#Z{Hd%DeKq zW_A@f9m9x*I70IzpqM8vmba|@5dKvxt7!Ukc~_xg)v1E6VtiL#eHE;5i47|%8(`ES zXf9tC*G=+q9kB5_XlaUMRdyA2m4&B)+E5(M>YBN%5`3=s-({6_9nOUl>fIn$z!?dD zm*QEZGB4h9!7E;PnGi3whw$Qa1wM(f)>yi(YydPbzB7%6j^iK1+=qZZS3y=J^6<#Sc!cA#d_(L8> zcqpBC>_bpS*p(`(zCsY*hA)uukw!x$zbvX>=ON!3;fa{RgG0HgTB&}F@YqM0m0m{g zeiM14dwBMrrusQ!h_idqSG6k2@N1wMYicx+(jGXr4v zdMg(rV)6HI)SH6*Hu^IEYCk^hgAWCTx9`!m4WBS`;CPBAEBxJ^^k%0K?#Ivh@)7e% z+%EMs4E~-x|H!HDIi3;wVccTpXZSXRK?b*v`S6 zD| z@%&hx`ihrvh5AyUaa$HV{92ZLu_qP`wqT*_={|3~lr_y5 zJ{ymXgsbs~-eAm@w@Hn?S^U)(V=_C(7`QD9kFbUZvOw40Tcb~T;LB6SyICRQfADeA z;d_W@;C|wXeK^3lD?4W515h;fbz++O2K^m;fR#Q-0)Bk9q1$*W8{fG>=iLp?!RV|8)#xHY>+^egr z8a&4Dm|AcAVOoQGd4uuiY1Ort8GoHtZv0~!?0}*iV-Now<-b2B)!CH|)l054?#QXB zG44WsV@!ILNI6y2_2m^c?keNCoO*YSyRre7dvhw6)GS$stCw;bmRxpOjoWw)V&g3K z2LGMlzi*R@?0Qf2;s#@1PHlPp6~=pDw3)b%iKu=WjEp;T)h8N*#+UGo-u|DFp?Bb~ zF|GQl@?|`$(JdkNhX1_euY|mntK*sR``pC%Y>XZOCw?Ux%C4+8`j60xxCK5mJyz?# zn{H%Fll^9lDVCe@Cdm5Z1Wz3ypC#B0)#Ff|V}!pd8BE4xIfEzT8T=uhLH~4ZMLdI_ zCuDH%bjjcw({qgNP>pJ#46=Dp-!a{I1^E4O%*b@(MPLT+CC*X)JH>yu-A9;V{%iB! zfv-W2ItFJ?WesHyOe-7C3TI7ajb#mFmAQ)P-&oG@QJiLnk8%y?)P=L^CUT31rcdRB zv+&|~nT!4v4`hvHhd(iq?J66bK9-GHKvq-PMD|z~Q73ZhnxJyB6Oqna-89!)<%(SIedeqWD1<4^kZdwM5*QuLpw_&+1C zevhz0VEvw6yTJPWye|l>-^+VIVEsPcZh`fCc)t=@zkm04f%W@iryZ&6(eI5d6j7OlSY-_pOf?Sig6DzQA?o zEB<8y>-VX81=jCTeMMmX{?s0U^?OtM1lI3MeKKF=uiulJE3ke)>T-egdr@ry>-T&% z3v84q`|c6AOyEZaZW8!;fd>WtwZOvye*u`31lG@Y zzpMExlzm4RD1AeV6@0S5u4)A@(sY5B39R31Un{VFPV+9!e}$5NMqvG1<|_j0=P~yQ zte?aDhrs&z%VY4s3-uTJ?NmB06j;A6f4RW=z4>N=o9Y$+EduNJi213m?@V|i4` ze_r4wfxjtmtH3V`+$He)0&f)f#AB2`{hnT>!2LpR6L>)2tpaZoc!$9HeXv&r-Y)dN z3cOR`QxO-*e*Jvxr2>x%-7Bzu{*?lH0sK87{-rQU@VLO|3H*k@l>)ylFeX#Xzfa(H zfo*|r6?jbGdjx(};70`BBk*p4e=P880*?wjDe$ns|0I}olh8H^9+&c7EU{@~Kb7kuV*3XA+6<9wfhMAX90DlgNzF!JmKbQ4)f%WrTr@*06=VAnELzF~ozu2S%S30&5o;NJ>N-x{IgJ%Q=BndrcLne`8e ze4)UFRFOE&6nLOc!50yX_An&=_6U5G^uKEa&J*|sk#~tbL4k_}zDeMzrAmKP;Idi; z4+>l-^hX6YBtAT;<J7M=z#O_fG7MDqo1MRnEh@A$Mmmp@b@_2+a2&d4)|dO!wPjg>!82n zfM0j;PdebgI^ZKQA4Yj%`e!@fiyiPX2i&3Hm_N3_%x~h{j`LeMAI3>B|GPN9hx7Y5 zAH%r==i@kkfO99#Cvg4{Cyuf{{J9n9Z8&eo*^e`V^C6s%;`|Oy(($k4d<#Nt-lfg+3Rok+TSckuCj zy#uH2{hiwY>RwjvBhwT0{j8IkdUKl0q3L{wo0-HntI6cp-L^s>^4+~+PrR+y9}G+? zU^<56LMC(Qg2eB_Q!~;$3588ml1NS{a3V{*&}xZIRvEksiZ6!=g4V?1m&r>?g4Zi$ z0%{wyn5^e&Dld=4R-FVJH)@U7vHav+gUvEpf6|LGF@#>P@pc5&LKrU8N|@KVPUsEt zM^njbdI1h7EK$mrIt_y2MyN$c?HL8dN~yqjDbw%JVHr4ecMizdIy0_yhGbUeeY!(n zRJ(MU8I$(tz!qE5Pwo%NyLBnF_!rZ8h2Kd}*vLyE@n=M1dv_^hwQrXmOqBb23|!cauq}9!R@G6*%Z-(ZP4@lJ}7SIW~}zFzP{s)W;Cg?3_7w zob*;x>K;?_-dYkQyGm(rvS*Y;Ny4SsKvK+!g!s-;%3~C8MC?~Q_`}3-L{cF4uA-+k zy!c#p=UTr3YI7$x<68Y~*a#CEVeu7p{K$fnaNf1LHOheQqVF=VG*a=fLjB@I>^DBr zap_;}SZSP_qPZCXkhf{m3Gy#cr6V9;^|K`Di0Y?5(oslE{f0?8s{B+)IuZo+FN`FT z)r5$Dn~OG+@Fi*a$&NHk2mBF_H2nHkJ<^cK>-rZ{(vbD9fTSU@q^hx!m1qFu5FVbS z5%KP-`e6`i9*HxBf3Zb5BMdhw`YgEmsSUC@|Ytk{Jl&QQ4 z9U!qTNO^MW*VNct9>1QI;TIPu^Y~|&;{rk1Qs!R*q0iW3?A5tM z?T|?-Kr`x0M5<+?!;chRJMdEi3K8!)+E4#t-_a8v?lbAX?@va?*g`VR$nY}(X?c^7 z)S9%8Bm(_lKoSC+{3(6%0iucHIe>qu+^jHW$04YiH-G*GWJcOS4a5r#+#D?FsHa~8 z;>*>m<$4VUO8j^QRVO{^$4|0Aks3qwFO76|dqeGAl)?W^JnS@O4j8**S0P%);(7WP zu6PQWk%x!5gD8^zo}NpMZSxX-T`FCMaV|BgBL2;!Boa# zX=cWG@}oMLa)e#95RjRi!Bg7mSXhH13JJ-obXS^}@EaV7S;gtP<7Sel?uUgt9RClk CIR#Vz diff --git a/native/MacTouchBar/src/Button.m b/native/MacTouchBar/src/Button.m index 06a59f54345e..9bdb04cf9556 100644 --- a/native/MacTouchBar/src/Button.m +++ b/native/MacTouchBar/src/Button.m @@ -74,6 +74,20 @@ const NSSize g_defaultMinSize = {72, 30}; // empiric value // // [NSGraphicsContext restoreGraphicsState]; //} +//- (void)drawDebugRect:(NSRect)frame color:(NSColor *)col { +// // NSLog(@"drawDebugRect: %@", NSStringFromRect(frame)); +// +// [[NSGraphicsContext currentContext] saveGraphicsState]; +// +// if (col == nil) +// col = [NSColor colorWithRed:105/255.0 green:211/255.0 blue:232/255.0 alpha:1.0]; +// [col set]; +// [col setStroke]; +// [col setFill]; +// NSFrameRect(frame); +// +// [NSGraphicsContext restoreGraphicsState]; +//} - (NSSize)cellSizeForBounds:(NSRect)rect { if (self.title == nil) { // NSLog(@"\t empty text, use default size %@", NSStringFromSize(g_defaultMinSize)); @@ -90,43 +104,56 @@ const NSSize g_defaultMinSize = {72, 30}; // empiric value } - (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView *)controlView { // NSLog(@"drawInteriorWithFrame: %@", NSStringFromRect(frame)); - if (self.image == nil) { - [super drawTitle:self.attributedTitle withFrame:frame inView:controlView]; - return; - } - - if (self.title == nil) { + if (self.title == nil || self.title.length <= 0) { [super drawImage:self.image withFrame:frame inView:controlView]; return; } - const CGFloat imgW = self.image.size.width; + const CGFloat imgW = self.image == nil ? 0 : self.image.size.width; + const CGFloat imgWithMargin = imgW > 0 ? self.myMargin + imgW : 0; + NSSize txtSize = [self.title sizeWithAttributes:@{ NSFontAttributeName:self.font }]; const CGFloat txtW = txtSize.width; - const CGFloat fullW = self.myBorder*2 + txtW + self.myMargin + imgW; + const CGFloat fullW = self.myBorder*2 + txtW + imgWithMargin; NSRect rcImg = frame; + rcImg.size.width = imgW; NSRect rcTxt = frame; if (fullW <= frame.size.width) { const CGFloat delta = frame.size.width - fullW; - rcImg.origin.x = delta/2 + self.myBorder; - rcImg.size.width = imgW; - rcTxt.origin.x = rcImg.origin.x + imgW + self.myMargin; - rcTxt.size.width = txtW + self.myBorder; + if (imgW > 0) { + rcImg.origin.x = delta/2 + self.myBorder; + rcTxt.origin.x = rcImg.origin.x + imgWithMargin; + rcTxt.size.width = txtW + 1; + } else { + rcTxt.origin.x = delta/2 + self.myBorder; + rcTxt.size.width = txtW + 1; + } } else { - rcImg.origin.x = self.myBorder; - rcImg.size.width = imgW; - rcTxt.origin.x = rcImg.origin.x + imgW + self.myMargin; - rcTxt.size.width = frame.size.width - self.myBorder - rcTxt.origin.x; + if (imgW > 0) { + rcImg.origin.x = self.myBorder; + rcTxt.origin.x = rcImg.origin.x + imgWithMargin; + rcTxt.size.width = frame.size.width - self.myBorder - rcTxt.origin.x; + } else { + rcTxt.origin.x = self.myBorder; + rcTxt.size.width = frame.size.width - self.myBorder*2; + } } - if (rcImg.size.width > 0) + if (imgW > 0) { [super drawImage:self.image withFrame:rcImg inView:controlView]; - if (rcTxt.size.width > 0) +// NSColor * col = [NSColor colorWithRed:105/255.0 green:211/255.0 blue:0/255.0 alpha:1.0]; +// [self drawDebugRect:rcImg color:col]; + } + if (rcTxt.size.width > 0) { [super drawTitle:self.attributedTitle withFrame:rcTxt inView:controlView]; +// NSColor * col = [NSColor colorWithRed:105/255.0 green:0/255.0 blue:255/255.0 alpha:1.0]; +// [self drawDebugRect:rcTxt color:col]; + } +// [self drawDebugRect:frame color:nil]; } @end -const int BUTTON_UPDATE_WIDTH = 1; +const int BUTTON_UPDATE_LAYOUT = 1; const int BUTTON_UPDATE_FLAGS = 1 << 1; const int BUTTON_UPDATE_TEXT = 1 << 2; const int BUTTON_UPDATE_IMG = 1 << 3; @@ -138,14 +165,35 @@ const int BUTTON_FLAG_SELECTED = 1 << 1; const int BUTTON_FLAG_COLORED = 1 << 2; const int BUTTON_FLAG_TOGGLE = 1 << 3; -const int BUTTON_PRIORITY_SHIFT = 3*8; -const unsigned int BUTTON_PRIORITY_MASK = 0xFF << BUTTON_PRIORITY_SHIFT; +const unsigned int LAYOUT_WIDTH_MASK = 0x0FFF; +const unsigned int LAYOUT_FLAG_MIN_WIDTH = 1 << 15; +const unsigned int LAYOUT_FLAG_MAX_WIDTH = 1 << 14; + +const unsigned int LAYOUT_MARGIN_SHIFT = 2*8; +const unsigned int LAYOUT_MARGIN_MASK = 0xFF << LAYOUT_MARGIN_SHIFT; +const unsigned int LAYOUT_BORDER_SHIFT = 3*8; +const unsigned int LAYOUT_BORDER_MASK = 0xFF << LAYOUT_BORDER_SHIFT; + +const int BUTTON_PRIORITY_SHIFT = 3*8; +const unsigned int BUTTON_PRIORITY_MASK = 0xFF << BUTTON_PRIORITY_SHIFT; static int _getPriority(int flags) { return (flags & BUTTON_PRIORITY_MASK) >> BUTTON_PRIORITY_SHIFT; } -static void _setButtonData(NSButtonJAction *button, int updateOptions, int buttonWidth, int buttonFlags, NSString *nstext, NSImage *img, execute jaction) { +static int _getWidth(int layoutBits) { + return (layoutBits & LAYOUT_WIDTH_MASK); +} + +static int _getMargin(int layoutBits) { + return (layoutBits & LAYOUT_MARGIN_MASK) >> LAYOUT_MARGIN_SHIFT; +} + +static int _getBorder(int layoutBits) { + return (layoutBits & LAYOUT_BORDER_MASK) >> LAYOUT_BORDER_SHIFT; +} + +static void _setButtonData(NSButtonJAction *button, int updateOptions, int layoutBits, int buttonFlags, NSString *nstext, NSImage *img, execute jaction) { if (updateOptions & BUTTON_UPDATE_ACTION) { button.jaction = jaction; if (jaction) { @@ -169,12 +217,36 @@ static void _setButtonData(NSButtonJAction *button, int updateOptions, int butto if (updateOptions & BUTTON_UPDATE_IMG) [button setImage:img]; - if (updateOptions & BUTTON_UPDATE_WIDTH) { - button.bwidth = buttonWidth; - if (button.bwidth > 0.1f) - [button.widthAnchor constraintEqualToConstant:button.bwidth].active = YES; - else + if (updateOptions & BUTTON_UPDATE_LAYOUT) { + const int width = _getWidth(layoutBits); + button.bwidth = width; + if (width > 0) { + bool isMinWidth = (layoutBits & LAYOUT_FLAG_MIN_WIDTH) != 0; + bool isMaxWidth = (layoutBits & LAYOUT_FLAG_MAX_WIDTH) != 0; + if (isMinWidth && isMaxWidth) { + nserror(@"invalid arguments specified: both min and max bits are 1"); + } + if (isMinWidth) { + //NSLog(@"set min width %d", width); + [button.widthAnchor constraintGreaterThanOrEqualToConstant:button.bwidth].active = YES; + } else if (isMaxWidth) { + //NSLog(@"set max width %d", width); + [button.widthAnchor constraintLessThanOrEqualToConstant:button.bwidth].active = YES; + } else { + //NSLog(@"set const width %d", width); + [button.widthAnchor constraintEqualToConstant:button.bwidth].active = YES; + } + } else [button.widthAnchor constraintEqualToAnchor:button.widthAnchor].active = NO; + + { // process margins + const int margin = _getMargin(layoutBits); + const int border = _getBorder(layoutBits); + if (margin > 0 || border > 0) { + [button setMargins:margin border:border]; + //NSLog(@"set insets: m=%d b=%d", margin, border); + } + } } if (updateOptions & BUTTON_UPDATE_FLAGS) { @@ -224,7 +296,7 @@ static void _setButtonData(NSButtonJAction *button, int updateOptions, int butto // NOTE: called from AppKit-thread (creation when TB becomes visible), uses default autorelease-pool (create before event processing) id createButton( const char *uid, - int buttonWidth, + int layoutBits, int buttonFlags, const char *text, const char *raster4ByteRGBA, int w, int h, @@ -238,7 +310,7 @@ id createButton( NSImage *img = createImgFrom4ByteRGBA((const unsigned char *) raster4ByteRGBA, w, h); NSString *nstext = createStringFromUTF8(text); - _setButtonData(button, BUTTON_UPDATE_ALL, buttonWidth, buttonFlags, nstext, img, jaction); + _setButtonData(button, BUTTON_UPDATE_ALL, layoutBits, buttonFlags, nstext, img, jaction); customItemForButton.view = button; // NOTE: view is strong const int prio = _getPriority(buttonFlags); @@ -254,7 +326,7 @@ id createButton( void updateButton( id buttObj, int updateOptions, - int buttonWidth, + int layoutBits, int buttonFlags, const char *text, const char *raster4ByteRGBA, int w, int h, @@ -269,13 +341,13 @@ void updateButton( if ([NSThread isMainThread]) { nstrace(@"sync update button [%@] (main thread: %@)", container.identifier, [NSThread currentThread]); - _setButtonData(button, updateOptions, buttonWidth, buttonFlags, nstext, img, jaction); + _setButtonData(button, updateOptions, layoutBits, buttonFlags, nstext, img, jaction); } else { nstrace(@"async update button [%@] (thread: %@)", container.identifier, [NSThread currentThread]); dispatch_async(dispatch_get_main_queue(), ^{ // NOTE: block is copied, img/text objects is automatically retained // nstrace(@"\tperform update button [%@] (thread: %@)", container.identifier, [NSThread currentThread]); - _setButtonData(button, updateOptions, buttonWidth, buttonFlags, nstext, img, jaction); + _setButtonData(button, updateOptions, layoutBits, buttonFlags, nstext, img, jaction); }); } diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java index 905514a03ce4..c9bff7c200a9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java @@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.actionSystem.ex.QuickListsManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.keymap.KeyMapBundle; import com.intellij.openapi.keymap.KeyboardSettingsExternalizable; import com.intellij.openapi.keymap.Keymap; @@ -228,7 +229,8 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi } }); panel.add(myShowFnCheckbox, BorderLayout.SOUTH); - } + } else + Logger.getInstance(KeymapPanel.class).error("can't obtain application id from NSBundle"); } return panel; diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BuildUtils.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BuildUtils.java index 1b0c76378d98..ca524b2217c2 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BuildUtils.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BuildUtils.java @@ -44,6 +44,9 @@ class BuildUtils { private static final String ourFlexibleSeparatorText = "type.flexible"; private static final int ourRunConfigurationPopoverWidth = 143; + private static final int BUTTON_MIN_WIDTH_DLG = 107; + private static final int BUTTON_BORDER = 16; + private static final int BUTTON_IMAGE_MARGIN = 2; private static final String RUNNERS_GROUP_TOUCHBAR = "RunnerActionsTouchbar"; @@ -176,12 +179,14 @@ class BuildUtils { defIndex = c; continue; } - group.addButton().setText(DialogWrapper.extractMnemonic(sb).second).setThreadSafeAction(actions[c]); + final TBItemButton tbb = group.addButton().setText(DialogWrapper.extractMnemonic(sb).second).setThreadSafeAction(actions[c]); + _setDialogLayout(tbb); } - if (defIndex >= 0) - group.addButton().setText(DialogWrapper.extractMnemonic(buttons[defIndex]).second).setThreadSafeAction(actions[defIndex]) - .setColored(true); + if (defIndex >= 0) { + final TBItemButton tbb = group.addButton().setText(DialogWrapper.extractMnemonic(buttons[defIndex]).second).setThreadSafeAction(actions[defIndex]).setColored(true); + _setDialogLayout(tbb); + } result.setPrincipal(gr); result.selectVisibleItemsToShow(); @@ -207,7 +212,8 @@ class BuildUtils { continue; // NOTE: must set different priorities for items, otherwise system can hide all items with the same priority (but some of them is able to be placed) - result.addAnActionButton(anAct, TBItemAnActionButton.SHOWMODE_TEXT_ONLY, ms).setComponent(ob).setPriority(--prio); + final TBItemButton tbb = result.addAnActionButton(anAct, TBItemAnActionButton.SHOWMODE_TEXT_ONLY, ms).setComponent(ob).setPriority(--prio); + _setDialogLayout(tbb); } } } @@ -226,13 +232,16 @@ class BuildUtils { final AnAction anAct = _createAnAction(jb.getAction(), jb, false); if (anAct == null) continue; - group.addAnActionButton(anAct, TBItemAnActionButton.SHOWMODE_TEXT_ONLY, ms).setComponent(jb); + final TBItemButton tbb = group.addAnActionButton(anAct, TBItemAnActionButton.SHOWMODE_TEXT_ONLY, ms).setComponent(jb); + _setDialogLayout(tbb); } if (jbdef != null) { final AnAction anAct = _createAnAction(jbdef.getAction(), jbdef, false); - if (anAct != null) - group.addAnActionButton(anAct, TBItemAnActionButton.SHOWMODE_TEXT_ONLY, ms).setComponent(jbdef).setColored(true); + if (anAct != null) { + final TBItemButton tbb = group.addAnActionButton(anAct, TBItemAnActionButton.SHOWMODE_TEXT_ONLY, ms).setComponent(jbdef).setColored(true); + _setDialogLayout(tbb); + } } result.selectVisibleItemsToShow(); @@ -283,6 +292,12 @@ class BuildUtils { return tb; } + private static void _setDialogLayout(TBItemButton button) { + if (button == null) + return; + button.setLayout(BUTTON_MIN_WIDTH_DLG, NSTLibrary.LAYOUT_FLAG_MIN_WIDTH, BUTTON_IMAGE_MARGIN, BUTTON_BORDER); + } + interface INodeFilter { boolean skip(String nodeId); } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NSTLibrary.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NSTLibrary.java index b570440bc5be..bdf87058ea54 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NSTLibrary.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NSTLibrary.java @@ -47,7 +47,7 @@ public interface NSTLibrary extends Library { ID createScrubber(String uid, int itemWidth, ScrubberItemData[] items, int count); ID createGroupItem(String uid, ID[] items, int count); - int BUTTON_UPDATE_WIDTH = 1; + int BUTTON_UPDATE_LAYOUT = 1; int BUTTON_UPDATE_FLAGS = 1 << 1; int BUTTON_UPDATE_TEXT = 1 << 2; int BUTTON_UPDATE_IMG = 1 << 3; @@ -59,6 +59,14 @@ public interface NSTLibrary extends Library { int BUTTON_FLAG_COLORED = 1 << 2; int BUTTON_FLAG_TOGGLE = 1 << 3; + int LAYOUT_WIDTH_MASK = 0x0FFF; + int LAYOUT_FLAG_MIN_WIDTH = 1 << 15; + int LAYOUT_FLAG_MAX_WIDTH = 1 << 14; + int LAYOUT_MARGIN_SHIFT = 2*8; + int LAYOUT_MARGIN_MASK = 0xFF << LAYOUT_MARGIN_SHIFT; + int LAYOUT_BORDER_SHIFT = 3*8; + int LAYOUT_BORDER_MASK = 0xFF << LAYOUT_BORDER_SHIFT; + int BUTTON_PRIORITY_SHIFT = 3*8; int BUTTON_PRIORITY_MASK = 0xFF << BUTTON_PRIORITY_SHIFT; @@ -69,4 +77,6 @@ public interface NSTLibrary extends Library { void updateScrubber(ID scrubObj, int itemWidth, ScrubberItemData[] items, int count); static int priority2mask(byte prio) { return (prio + 128) << BUTTON_PRIORITY_SHIFT; } + static int margin2mask(byte margin) { return ((int)margin & 0xFF) << LAYOUT_MARGIN_SHIFT; } + static int border2mask(byte border) { return ((int)border & 0xFF) << LAYOUT_BORDER_SHIFT; } } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TBItemButton.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TBItemButton.java index a87f7b8afd7a..fe5cb49044d6 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TBItemButton.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TBItemButton.java @@ -14,7 +14,7 @@ import javax.swing.*; class TBItemButton extends TBItem { protected @Nullable Icon myIcon; protected @Nullable String myText; - protected int myWidth = -1; + protected int myLayoutBits = 0; protected int myFlags = 0; private @Nullable Runnable myAction; @@ -83,12 +83,24 @@ class TBItemButton extends TBItem { return this; } + TBItemButton setWidth(int width) { return setLayout(width, 0, 2, 8); } - TBItemButton setWidth(int width) { - if (width != myWidth) { - myWidth = width; + TBItemButton setLayout(int width, int widthFlags, int margin, int border) { + if (width < 0) + width = 0; + if (margin < 0) + margin = 0; + if (border < 0) + border = 0; + + int newLayout = width & NSTLibrary.LAYOUT_WIDTH_MASK; + newLayout |= widthFlags; + newLayout |= NSTLibrary.margin2mask((byte)margin); + newLayout |= NSTLibrary.border2mask((byte)border); + if (myLayoutBits != newLayout) { + myLayoutBits = newLayout; if (myNativePeer != ID.NIL) { - myUpdateOptions |= NSTLibrary.BUTTON_UPDATE_WIDTH; + myUpdateOptions |= NSTLibrary.BUTTON_UPDATE_LAYOUT; _updateNativePeer(); } } @@ -141,7 +153,7 @@ class TBItemButton extends TBItem { int flags = _applyFlag(myFlags, isSelected, NSTLibrary.BUTTON_FLAG_SELECTED); flags = _applyFlag(flags, isDisabled, NSTLibrary.BUTTON_FLAG_DISABLED); - _update(icon, text, myAction, myWidth, flags); + _update(icon, text, myAction, flags); } private static boolean _equals(Icon ic0, Icon ic1) { @@ -150,7 +162,7 @@ class TBItemButton extends TBItem { return ic0 != null ? ic0.equals(ic1) : ic1.equals(ic0); } - synchronized private void _update(Icon icon, String text, Runnable action, int buttWidth, int buttFlags) { + synchronized private void _update(Icon icon, String text, Runnable action, int buttFlags) { if (myNativePeer != ID.NIL) { if (!_equals(icon, myIcon)) { // NOTE: some of layered buttons (like 'stop' or 'debug') can change the icon-object permanently (every second) without any visible differences @@ -161,15 +173,12 @@ class TBItemButton extends TBItem { myUpdateOptions |= NSTLibrary.BUTTON_UPDATE_TEXT; if (action != myAction) myUpdateOptions |= NSTLibrary.BUTTON_UPDATE_ACTION; - if (buttWidth != myWidth) - myUpdateOptions |= NSTLibrary.BUTTON_UPDATE_WIDTH; if (buttFlags != myFlags) myUpdateOptions |= NSTLibrary.BUTTON_UPDATE_FLAGS; } myIcon = icon; myText = text; myAction = action; - myWidth = buttWidth; myFlags = buttFlags; if (myUpdateOptions != 0) updateNativePeer(); @@ -182,14 +191,14 @@ class TBItemButton extends TBItem { final NSTLibrary.Action callback = (myUpdateOptions & NSTLibrary.BUTTON_UPDATE_ACTION) != 0 ? myNativeCallback : null; // System.out.printf("_updateNativePeer, button [%s]: updateOptions 0x%X\n", myUid, myUpdateOptions); final int validFlags = _validateFlags(); - NST.updateButton(myNativePeer, myUpdateOptions, myWidth, validFlags, text, icon, callback); + NST.updateButton(myNativePeer, myUpdateOptions, myLayoutBits, validFlags, text, icon, callback); myUpdateOptions = 0; } @Override synchronized protected ID _createNativePeer() { // System.out.printf("_createNativePeer, button [%s]\n", myUid); - return NST.createButton(myUid, myWidth, _validateFlags(), myText, myIcon, myNativeCallback); + return NST.createButton(myUid, myLayoutBits, _validateFlags(), myText, myIcon, myNativeCallback); } private int _validateFlags() {