From ac34dde28354e4b2e76a5f4a29f9389813bd2767 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Thu, 7 Sep 2023 13:28:52 -0400 Subject: [PATCH] add electron simulator slider features to wxPython simulator (#2481) --- icons/backward_command.png | Bin 0 -> 3550 bytes icons/backward_command.svg | 121 +++++++++ icons/backward_stitch.png | Bin 0 -> 3152 bytes icons/backward_stitch.svg | 99 +++++++ icons/close.png | Bin 0 -> 3806 bytes icons/close.svg | 202 ++++++++++++++ icons/color_change.png | Bin 0 -> 4207 bytes icons/color_change.svg | 89 +++++++ icons/faster.png | Bin 0 -> 4230 bytes icons/faster.svg | 192 +++++++++++++ icons/forward.png | Bin 0 -> 5145 bytes icons/forward.svg | 104 ++++++++ icons/forward_command.png | Bin 0 -> 3492 bytes icons/forward_command.svg | 121 +++++++++ icons/forward_stitch.png | Bin 0 -> 3129 bytes icons/forward_stitch.svg | 99 +++++++ icons/inkstitch_colour_logo.png | Bin 0 -> 991 bytes icons/jump.png | Bin 0 -> 5343 bytes icons/jump.svg | 1 + icons/npp.png | Bin 0 -> 3375 bytes icons/npp.svg | 253 ++++++++++++++++++ icons/pause.png | 1 + icons/play.png | Bin 0 -> 2646 bytes icons/play.svg | 116 ++++++++ icons/restart.png | Bin 0 -> 5319 bytes icons/restart.svg | 142 ++++++++++ icons/reverse.png | Bin 0 -> 5047 bytes icons/reverse.svg | 104 ++++++++ icons/slower.png | Bin 0 -> 4391 bytes icons/slower.svg | 193 ++++++++++++++ icons/stop.png | Bin 0 -> 2110 bytes icons/stop.svg | 1 + icons/trim.png | Bin 0 -> 5815 bytes icons/trim.svg | 1 + lib/gui/simulator.py | 459 ++++++++++++++++++++++++++------ 35 files changed, 2221 insertions(+), 77 deletions(-) create mode 100644 icons/backward_command.png create mode 100644 icons/backward_command.svg create mode 100644 icons/backward_stitch.png create mode 100644 icons/backward_stitch.svg create mode 100644 icons/close.png create mode 100644 icons/close.svg create mode 100644 icons/color_change.png create mode 100644 icons/color_change.svg create mode 100644 icons/faster.png create mode 100644 icons/faster.svg create mode 100644 icons/forward.png create mode 100644 icons/forward.svg create mode 100644 icons/forward_command.png create mode 100644 icons/forward_command.svg create mode 100644 icons/forward_stitch.png create mode 100644 icons/forward_stitch.svg create mode 100644 icons/inkstitch_colour_logo.png create mode 100644 icons/jump.png create mode 100644 icons/jump.svg create mode 100644 icons/npp.png create mode 100644 icons/npp.svg create mode 120000 icons/pause.png create mode 100644 icons/play.png create mode 100644 icons/play.svg create mode 100644 icons/restart.png create mode 100644 icons/restart.svg create mode 100644 icons/reverse.png create mode 100644 icons/reverse.svg create mode 100644 icons/slower.png create mode 100644 icons/slower.svg create mode 100644 icons/stop.png create mode 100644 icons/stop.svg create mode 100644 icons/trim.png create mode 100644 icons/trim.svg diff --git a/icons/backward_command.png b/icons/backward_command.png new file mode 100644 index 0000000000000000000000000000000000000000..53729a4fd60dbc65bf114e9eb65aef32e25166e9 GIT binary patch literal 3550 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 + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/backward_stitch.png b/icons/backward_stitch.png new file mode 100644 index 0000000000000000000000000000000000000000..9e97b31f5246ff9a8a6393f7230aceae4bcfb10f GIT binary patch literal 3152 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 Dp&+3@ literal 0 HcmV?d00001 diff --git a/icons/backward_stitch.svg b/icons/backward_stitch.svg new file mode 100644 index 000000000..3e64c8d91 --- /dev/null +++ b/icons/backward_stitch.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/icons/close.png b/icons/close.png new file mode 100644 index 0000000000000000000000000000000000000000..0212ad0f48f03233c278e3f77b55b09116290ac5 GIT binary patch literal 3806 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 literal 0 HcmV?d00001 diff --git a/icons/close.svg b/icons/close.svg new file mode 100644 index 000000000..394a478d9 --- /dev/null +++ b/icons/close.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/icons/color_change.png b/icons/color_change.png new file mode 100644 index 0000000000000000000000000000000000000000..bcdd71b9939d9fa69be13ee540bab9e519f75c56 GIT binary patch literal 4207 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 D^jlm{ literal 0 HcmV?d00001 diff --git a/icons/color_change.svg b/icons/color_change.svg new file mode 100644 index 000000000..a4ccb08bb --- /dev/null +++ b/icons/color_change.svg @@ -0,0 +1,89 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/icons/faster.png b/icons/faster.png new file mode 100644 index 0000000000000000000000000000000000000000..d20d2d1c1f6514dddba8d4200e302063990b784d GIT binary patch literal 4230 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 literal 0 HcmV?d00001 diff --git a/icons/faster.svg b/icons/faster.svg new file mode 100644 index 000000000..ea48b08e0 --- /dev/null +++ b/icons/faster.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/icons/forward.png b/icons/forward.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a95d116ed0b8218b0f3c4bf61c5b27318e3bc1 GIT binary patch literal 5145 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 + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/forward_command.png b/icons/forward_command.png new file mode 100644 index 0000000000000000000000000000000000000000..ee7e393ee21e2ceb27c6eec7958ee3f12d1fb66a GIT binary patch literal 3492 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 H?s5MGyXhLQ literal 0 HcmV?d00001 diff --git a/icons/forward_command.svg b/icons/forward_command.svg new file mode 100644 index 000000000..b0a79576a --- /dev/null +++ b/icons/forward_command.svg @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/forward_stitch.png b/icons/forward_stitch.png new file mode 100644 index 0000000000000000000000000000000000000000..d585dbb9e4e83dd747d8c8003b57b55d25029d8d GIT binary patch literal 3129 zcma)8X*d+@8h*z*SrXY3WBrnB!^u+2s2Q3hLZM6<+h8n%L6c?1*L+N+h$KbG(qb!1 zAtGa~K}dsBge)~CTPE4&Oy70>oFC^p=lSzI_wzpY{rq{a_kOQ9owSn_Qx*dNNMeqm zoB@FFO9+4p@e?=Ji^ESscpC>B0G_3aZ{mdc80K@#*#Uq{Isi~<0Ic&{)Hwj6i~#uN z1%Txp02GKh4W|zC4+OmJ?N9(bxvmN4BT*8@0WCTUmDwq2s3d#n6aZpBF(@0?i=&)R z1mfu-rH&=ak&1L7A;?>Iq2Otq9qNg#^pvxKgv?&oGUt$}qR}AE`~8C%$(qHj(~6qHPqg1n2%bU~8Os_^ziE>f^py5AGt|Esb+&-(+h>5uHBVdl(J7 za$9}JX1640PAx4_R11KnGz+*6{6Z(vl$Tj zquEPnn1%ITD*b2u%{Z1|#&*94&={N5LBo_RrI2l^@=l*G5xpx*`LxBoVo|oc8Y%>L z^>^v#OkARRm%aojmCqXzBrDXj_whi3yL9v_R?2z)hb)zT>AR~?>rf=nP%tz92MAw#iD|e0AZdsy97BM~tx&4@I^~ z%bR>$eK*yYtnFnzwZ7OKp<7I^Rf)FRyttwXrZ#@?BI>C!AC?Q)0$NsmtARV_+@Y#I zMZXcnQ4>h(AAUVjVV_3Y)Gr69nq^r{lI=SSwb17&1DiZy=B&E)R71+eWp(hl=7M@2 zVNH9s!9eRq92D7L0+6cXpJ!8|u*WyGv_ab2p{p$qf9<0F$f8Eqd$u1v3$^Y|2EP6x zpbKYUuQ=V1Z@#1svhPAbL|smC$_ETCxkwm@7$tZ9%3(j4Y~{~}?wET--f4g5b3@t1 zMgD9q1XQibq{927aN(bif(I#m5RkRBr$-<`2)1H^e0h!hAQfRM+Lj93nf&X&EZU*H zk!=1I4C7_h3w4+|_fKZdrQmX9P? zs`)2oSBPg;VBegpQL^*eTkV-Ok{4$#x!DyRq}c5~7-nee^x8JM!JxKzO%6Qrk<>nM z@OsOLYgHn)!k(k{N*E|V*0^_k@Mfx)4&gE5yWZUJq9GvCPpjZXERq(&<*Pjy-xoDM z`+)pRxf&w|shO(IEJ?~Ouxsf9Ejz|0V1p;rc3aVu8ar=1)%;8Vuy!%7^P63apNhwY zYu_iSKq!L1iE*YQdyI!jc|4#0Vg8BM?B-4+N}sLRPEJ}dP6>RUvDm`G$IPXBU!+S#DMNNn)TFEv2D+-M_RoHQ;W;VtrVSoyqA zD-_f$D*tj-w)HZSdta?x1Et9T^VftLqamWyGZS6B+QMIQi9`Vq;(E$a>2lB5#EFus zydHHltOy|Y>>2Jr+1_blc$M_G%n*B_tzw{PxYgFW58rcA+sA)3VA<3C7bZ`0{aSs0ARVWSY7JJorTi&0`qQVF8oS$%6Xo|{s5oy=1zeEQQ#cxD?X(dNJ6?Fv(Wvp(QqMf4Ki03 z?0di`<$QCRZi^*CGmQq2sJ*3%QFk|_xaZaVd|fy`Lg~_gy4Bcj;om26peQBo%v#KW zv>bpmsf5$6*s>&KojQ>D} zoKcyMu~~oU17iAVQ+Q&5PUU?&C3M*goehuGBSQk3gMCG(u1D`?7T=P25_bhDBM3r* z{RE3`f67k7vkMv@bJ$b**L2H_V&9$6YaZgRF2$(6wFs0=EZiLX(J>@}nUQ%{ke#K- z5Xx{2+BuuiNnzB-nYzwC{TQr1+^T@hVrBUD0g!Co6<5eoJ+k*LR$vRgn7Pz;SZsty3HKJias_zmB2HOb9%6RnzsM zQ*dwK_OvH>8PO$J;%I!!bb7^s!8Hrd`?^~~+d;7YI@X`VqsC5B*0X#s*QJV7bIl@N zOt>7^3Sp3GNBueDeH!Ik;Rll*2L6M4UH8@1=WArKNs|f}3dy~s!Vw40!dgT{l~P}`IwayBe>D+AOpAG z^@gP3DxL1$o)tBw=I9|YX?#QR1rN^Gwq10qKG*b5-jh012Ia7y@ombT`&_iE@j0`B zc9(p0@G<@DiDnOl!k9yz%`7j zIg(4vE|TKb^;XL&FYcdIC~01`Lp9>+7VZ@JDcYwvZa6o-_N_(Ss8VEPbmVQxR>Cm^ zii)4ho9Yfu>cwo#`j5`R;PddNcX}F=7yJ)hJ9c-bYM^n;(D*g~CCv`5Fhj6Y-9w+( z-YU{gJ!j!Hw#_s85LGactsx)Itox;V+vIF=!cs=N(#NpPa}-qDwVYCJ=c$7TqgMle zXn1Fj^gc*0ndnd;mu?yV)aTxN!SiIH8zvdrH!`kA|6(r+yl|dvIOfJTqh}NQTpC;S z-@i2I->a7J{pm{?vq^HOe;!)^%eO8M|3C1QiGy6}dV_b`Y64y+9rTCwdfge6LkNMi zUrPDc5fM_co>?>Zr9>06!+4nOHVtJ@1$j|xA=qH``|xdMZrtCFgxk?IFF{Pf*Im|O zq1*qGf^>aROkI|Z>Cc(hl5r z*dZV~qHt90!I-eup79R{Lvi06z;j}*^;W?*3vjOP3`fe%5i;B{ba(UUhj0?MZJf+%p3JXMm}uX6+QtSqCJ=Uj`h zxE=pwOX2YrrfPn7azeFYK7L)N`!VE^_icq2HTEL$veZoG03Jb>kIbRdhnOU*TZ?N% zquN9jktL0vRc}_ETBjJayJ%x{&0N2M#{U!PLOj9oFN9|aPBpjqzhZ3?+MVQ!Bl%hS zMELO&fE&S0^o`8*jm=$+%`J^hEKSYyjZ7_#jI1)!KK%zFB+NI^pZwnmCwlkc_yp_U z8zQ6emOf!2A%3AG06Y5kCSO=gASnQb2_;1O;D~;(eE}pA(bCW`CML!p@ZU{?un4@N VE^HfZSIt)f81zY0#SyPR{{^`}pEm#i literal 0 HcmV?d00001 diff --git a/icons/forward_stitch.svg b/icons/forward_stitch.svg new file mode 100644 index 000000000..25a2040a3 --- /dev/null +++ b/icons/forward_stitch.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/icons/inkstitch_colour_logo.png b/icons/inkstitch_colour_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9bbdcb0aaf3a4ddf770a538f281bff9a07bda0ac GIT binary patch literal 991 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?K*|-O<;Pfnj4m_n$;oAYUQb zBgmJ5p-PQ`p`nF=;TKS-;RORjsR0ASs{{rHs~HRo;stYd1=;{5n3BBRT^JZv^(q?y zdF&;gzOL-gIfVFl^(95D1A+4MJY5_^DsH{Ka?q32P{iS)OTGK8hR~Z$M}K-xx^W;y zk%#A;ZTd|2HujxoB!DJ>z=6AG-u}FE?nnK#h-6t_x!c_}YkBtj4;#5ROfw$m z*2L^JT^^Y%_n$FtTX@~NdozV|<3B&ukAGOlBB0)2!FYsI!H=PksYBRd4#T5Sp^+65 z+xZ`SeRb91;x|+I*`H14CC35NN@ZWE%?;a6GQkYyn~vR5g(NeE1H6BkD((wjZqu9i z6DXuw;u=wsl30>zm0Xkxq!^40jEr>+EOZSmLJTde42`W!%ykV+tPBinCr`MGq9Hdw zB{QuOw+5ec8i_y+wjdjd%hIiq^K)}k^GX;L{L|7hlQR=@6ms&@^A(Cxb5awFQx(9D oP%ttuw9qp!Rcr>mdKI;Vst05Uuz0{{R3 literal 0 HcmV?d00001 diff --git a/icons/jump.png b/icons/jump.png new file mode 100644 index 0000000000000000000000000000000000000000..40b4b995b4e04577efeb191f352ddd5bba0490dd GIT binary patch literal 5343 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 literal 0 HcmV?d00001 diff --git a/icons/jump.svg b/icons/jump.svg new file mode 100644 index 000000000..b2bb09e00 --- /dev/null +++ b/icons/jump.svg @@ -0,0 +1 @@ + diff --git a/icons/npp.png b/icons/npp.png new file mode 100644 index 0000000000000000000000000000000000000000..125f9020c1fa9d4c24aa34eb4bf9f73f5794ef78 GIT binary patch literal 3375 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 N@?mSU@F@vm literal 0 HcmV?d00001 diff --git a/icons/npp.svg b/icons/npp.svg new file mode 100644 index 000000000..ba0a22811 --- /dev/null +++ b/icons/npp.svg @@ -0,0 +1,253 @@ + + + + image/svg+xml diff --git a/icons/pause.png b/icons/pause.png new file mode 120000 index 000000000..6222e6f71 --- /dev/null +++ b/icons/pause.png @@ -0,0 +1 @@ +stop.png \ No newline at end of file diff --git a/icons/play.png b/icons/play.png new file mode 100644 index 0000000000000000000000000000000000000000..209c4e7eb0b16b6c73a36d71d8853c536926bbe2 GIT binary patch literal 2646 zcma)8XIPV27QRVAeTHV-7RdSLPcSM9bDJhRQpo7LlmIsPF*)fgeWtr+%mk3agTCJ6?=oaXkc|B5w*H z=k-jAn@)^e&be8O`mRrl{wi_EN>M^Z6_1@u>L&0Ys&UDK%|cG+O!;Wc3;7j=c>hh_ zR7~+F}LokU^A*slds0p?||nl=G8{L@@)xOmNv{s=sl zs}*pSn zY3MmTOX#y`wSyi4&w7+5&Pfd{#vFi-GKm%=Hf-`~_iRzdJigz!<82}>>!dmYFB@N! z#jZMyIR#h3l7W%LU*P1X9i=^NwBnMwDqtdHTtbrfx#s+Vq?Ih_^?!7gXpTnF@K5wT z#BXM3WCN^eQI+jLFUA4nq)rXnaZ>XaY^0$NTDfZ-m%pAk09BQa*n1%Zv-DwVo_(v7 zxq2ka2xL^1^(96qV#m;Pv_{H}2-%DyWgyz@rM%Kx|D_H@mDnqybx}7$lp#ZlMTGV*AUnWVA(URs{uRl7Do9kyLDoe`j`NVE*iyg3RQG2 zHPM^?!T*=>Z`vXOx^+!x5`i!Z#B8PHib8pRRF`+d7i>$om3v3g&jRLm$2hqG(S*p> zyW*q|8Mn!1Ui(6YE)-r-ExLc2XlAvKkxy2A8hTMpERb)G_IzZAz9Uh}1~nZ;8YkD& zJyByqDM6RS z?9^(acNnzeFL$?nX1h=GXB~vg!B^+y17m4aUAkZ<3x6N-ooqx4`qURftnPxwB_3P% z?0^-_`Mcf>Gt&nfq%f#{WWnoKv6b2u|EBck0t0eR(hu)?a)`YJ>8BYT-3E4BdacanSIX*W3bN_?&@fLwq_a1KxVvcXQ7fMLc?`TmUZXgiRj?gt6SwXipC*sbn$vFqV=U2Z!wi9u0T@1|jW+Xc3FapVmKj zAd*GwS$4~<=^Wmq{CMP|O31#}dW!ts6L}>kDnt>TJK5DM!O>$W*xfi*q^k~{ms@(H zVTn-sLRf6H9dHArupo17w)LVqL}~j2DHrlo{-_f|X-(}tkXCi#AoI{kZu`N>&~Wh!( zvTdpk)til==6~Ay6Jv=fu3x5NpU78XgesCETd#-CcCEXq@jEx4(F$rv+1wJY0YhW` z4O#(_@m{-T=2G6B9~!ATF-N+2Ca9Yc3gRv=NgTbQ8gR;u8JBP;2)64$_Qa59ms2?Y z{flH5&}TAOwPRL2z1yV@Ent`H%<^mZq-%jtAzA!dg2g9~6fdC)XNU7af)9Lh_aEbT zE_%}#@WP4kSyGzcIkP~ELau+tOLhaiwE*K;a>MB8MqNhAo^C~!Y6rWnoSs$80?8qi zW5YY!7AbErmS4nLN`9N4SryGE6hhdPWus|L2Y4{uFPt%&xpW5E85VeaIKf!^8Sh97 z0k!yU)VO`%@5$zX$%HhY-|^h>6M(B#S6sy=+j$L^AjB@9k2Z;WBub`$rcV@;)bX7>uYm=zip#UK zTU_F{^64;$ymO=Nd6;?nUpg!U#--&oi|#KALKUfn-`cr7q`d{W2oHPqBVE2IK3cKO zPnAyzA};9HJr>J)@3tRSJC6yx?iHRopKRxPT@4i+B<=O1LLNr76FAaz$@C?02Y19< zeXq?eYm5yzZsd0Bm%}WKIsx)D!ui$hI^U9G?7!5zkCU1=e(L~ZcI%NNFHlnzTB#qG zx^z$T7^K3Es^NZh?HWhod(GkZ<4mRVDG>QJVS2^s+F4XE*>qxUs9e5}-+45#-zQhg zMMDMRX)Q`}E-U+{p}&epkc+tOl5M@n;14ztuVW)+r6nyMz`<;o&Os>qy+FSnNZt1I-{#6#qW)}qU(RpN|GFo_qK^8#_1;A= za(?lsFPCaF0c3sprPVZw1r*Jpr+lIdQS;N%h#8$525C4}K?TXi{tuAad&r;zplQP}Ln@$O&pEDsxpMw?9 z$LSkrTOzBIrQT`d^tSig6+IU`0|y*adPR?VO@oFr7{_(bbKMi_;1DcTguXnyRa=xNBqE Q3hx9+HjXEntpcw66VR!L761SM literal 0 HcmV?d00001 diff --git a/icons/play.svg b/icons/play.svg new file mode 100644 index 000000000..4ae8c42de --- /dev/null +++ b/icons/play.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/icons/restart.png b/icons/restart.png new file mode 100644 index 0000000000000000000000000000000000000000..f146bb145bbe587da15fd2da0ede8460495f2fd8 GIT binary patch literal 5319 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 AkpKVy literal 0 HcmV?d00001 diff --git a/icons/restart.svg b/icons/restart.svg new file mode 100644 index 000000000..4fe1e327a --- /dev/null +++ b/icons/restart.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/icons/reverse.png b/icons/reverse.png new file mode 100644 index 0000000000000000000000000000000000000000..982bf3e55bf3b7fb57bfd185503e756a5a760476 GIT binary patch literal 5047 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 literal 0 HcmV?d00001 diff --git a/icons/reverse.svg b/icons/reverse.svg new file mode 100644 index 000000000..29e3d738f --- /dev/null +++ b/icons/reverse.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/slower.png b/icons/slower.png new file mode 100644 index 0000000000000000000000000000000000000000..fce47d545c8e6b0d24f0e277b3a1a84282a20f9c GIT binary patch literal 4391 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 literal 0 HcmV?d00001 diff --git a/icons/slower.svg b/icons/slower.svg new file mode 100644 index 000000000..024644159 --- /dev/null +++ b/icons/slower.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/icons/stop.png b/icons/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..7245124bbc01fe29cd6d3200b10728a3e785fdad GIT binary patch literal 2110 zcmeHIX;9Pm7X2Z}mO=YKsDPk8LI6p~KScH=pfC_1P#_jiUdonGWlJC^JE4!3$7Tv7 zEV5{eP_Zf?memx{fFhD8!Ado!|0`b) z4Rt+r0DuPG(=7l11$n9fRF&lLAw6tG4ocCk1XloBnXtX^gK~Z%(ldYnKpFx7MlJw5 z@)BbnfMf`O#V`QuD*^bDTGQ?CC~q8y@b+*6;C8W*rJSkI@dS4jv8v`F4TyEj`X&I% zU3fQFV#=G9Hwm|bHVyiuTdN;mc0FwH?)iaSb@#bx?D?NyZF(CwepVTEQH^psANvod zf<@QjxVXXy*vW61%9!!*<`0*!+zU@=wBl?yKHglq!rRWu z-pZP2UYAjwdsnyi9mEq!XwOnO{&TU2EEX#6F%2n#*P_tJ$7bFN6$K-)JM))lqO-?_ zoz|M{%^0c3=`;&b0I$BM0eeV_IU7qc?>RaIN$o-hPg%@q>bww)>gH|dzKacqIq32r zTHYerj(MM5ecMJ>_WI37>u_sCdt%<>uMdm*)qy{8paNTt6B; zJ8^X^es2A|PTP&JO5E6weW#RTs#A(KTQ!3RqJKkCTwTj1AK!a~y%jO3DZ*2i3D?edD&;iQDZRUD$rxvnV_15j~YlcyN#(v=Pdw9|p99X#?Iw5}|<&Bv~|&;u~xhw8IZpl-u?czAf!-{MVrNf^_+kp_~y_btcy z?`O355$@f2E^mNNQuydntt=OZYON{kgl}_w-T|FgvMb#JhhA>B8uE_p`@|Sc5|#{# zxj5fiI%YradJp|}Zw*1;Wmn&Sa9J~3_c@k!=HhXM)CrnZ<4#9s(b%fO9?JkRIO?;| zu{6t7b@_!1`gL8X%3stdC`JE2{ol6^;~jWX2n9ttETw_eqi0X}KkM zYuXtzMbq(;S*&E*<*is!xyWQbP>3DAU(>VQy^_>{Ee{vvjyfN>%$8ZSC;a%boo^t* z=^`d-C55Hd30fUK;%6&B>|(hS9JEs(ACWi zR$a=$T`k`|n?~`(&uIklLR8_lSw#>;Lo=}@--^(k_FKxY64V?@k(9FZQ)yh(%syOx zq$l2Wb^Ma0@kgRl_D)vZ*{x>F-vQ!?AV|UT#ua2Uzhn3aA#A&XR(64PSA9rge z#|pn8g-2Rh%%z8(lX9^stZ6+H!zi+ZfREA14u8-%Abj**4^cO?8q)*I;3jw3z&TZp z#K&dHMHL|d0xq_bnaTEZ>|bI}HY4&4hv0_sM=`HnDD;}^-)MAX&fNK(geXcuFecyf1bwEuw7J=cCnNRUc}#{2<;* zj8PYXahB~;t;joJo#TUrn?8zqr&NA`^ZGH9DpTciA6!SD2y!; zV{4DW+Ml*XL8t8@X!z~a>Awl$5~40rQa>-~{vr53azRcSF_@loIodulAuf&_PX|D? zDv(GW=9~Ldk$xy1pKy+9?nO8U39v7*0iL&sR8Pfc#%CJn+Lm5k>IHW diff --git a/icons/trim.png b/icons/trim.png new file mode 100644 index 0000000000000000000000000000000000000000..8310813adf4365e2639c0e10a7399d49b407556b GIT binary patch literal 5815 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 literal 0 HcmV?d00001 diff --git a/icons/trim.svg b/icons/trim.svg new file mode 100644 index 000000000..3d58f3dd0 --- /dev/null +++ b/icons/trim.svg @@ -0,0 +1 @@ + diff --git a/lib/gui/simulator.py b/lib/gui/simulator.py index 78138fc89..963acd451 100644 --- a/lib/gui/simulator.py +++ b/lib/gui/simulator.py @@ -2,7 +2,7 @@ # # Copyright (c) 2010 Authors # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. - +import os import sys import time from threading import Event, Thread @@ -11,6 +11,7 @@ import wx from wx.lib.intctrl import IntCtrl from lib.debug import debug +from lib.utils import get_resource_dir from lib.utils.threading import ExitThread from ..i18n import _ from ..stitch_plan import stitch_groups_to_stitch_plan, stitch_plan_from_file @@ -29,6 +30,7 @@ COLOR_CHANGE = 4 class ControlPanel(wx.Panel): """""" + @debug.time def __init__(self, parent, *args, **kwargs): """""" self.parent = parent @@ -38,44 +40,68 @@ class ControlPanel(wx.Panel): kwargs['style'] = wx.BORDER_SUNKEN wx.Panel.__init__(self, parent, *args, **kwargs) - self.statusbar = self.GetTopLevelParent().statusbar - self.drawing_panel = None self.num_stitches = 1 self.current_stitch = 1 self.speed = 1 self.direction = 1 + self._last_color_block_end = 0 + + self.icons_dir = get_resource_dir("icons") # Widgets - self.btnMinus = wx.Button(self, -1, label='-') + self.button_size = self.GetTextExtent("M").y * 2 + self.button_style = wx.BU_EXACTFIT | wx.BU_NOTEXT + self.btnMinus = wx.Button(self, -1, style=self.button_style) self.btnMinus.Bind(wx.EVT_BUTTON, self.animation_slow_down) + self.btnMinus.SetBitmap(self.load_icon('slower')) self.btnMinus.SetToolTip(_('Slow down (arrow down)')) - self.btnPlus = wx.Button(self, -1, label='+') + self.btnPlus = wx.Button(self, -1, style=self.button_style) self.btnPlus.Bind(wx.EVT_BUTTON, self.animation_speed_up) + self.btnPlus.SetBitmap(self.load_icon('faster')) self.btnPlus.SetToolTip(_('Speed up (arrow up)')) - self.btnBackwardStitch = wx.Button(self, -1, label='<|') + self.btnBackwardStitch = wx.Button(self, -1, style=self.button_style) self.btnBackwardStitch.Bind(wx.EVT_BUTTON, self.animation_one_stitch_backward) - self.btnBackwardStitch.SetToolTip(_('Go on step backward (-)')) - self.btnForwardStitch = wx.Button(self, -1, label='|>') + self.btnBackwardStitch.SetBitmap(self.load_icon('backward_stitch')) + self.btnBackwardStitch.SetToolTip(_('Go backward one stitch (-)')) + self.btnForwardStitch = wx.Button(self, -1, style=self.button_style) self.btnForwardStitch.Bind(wx.EVT_BUTTON, self.animation_one_stitch_forward) - self.btnForwardStitch.SetToolTip(_('Go on step forward (+)')) - self.directionBtn = wx.Button(self, -1, label='<<') - self.directionBtn.Bind(wx.EVT_BUTTON, self.on_direction_button) - self.directionBtn.SetToolTip(_('Switch direction (arrow left | arrow right)')) - self.pauseBtn = wx.Button(self, -1, label=_('Pause')) - self.pauseBtn.Bind(wx.EVT_BUTTON, self.on_pause_start_button) - self.pauseBtn.SetToolTip(_('Pause (P)')) - self.restartBtn = wx.Button(self, -1, label=_('Restart')) - self.restartBtn.Bind(wx.EVT_BUTTON, self.animation_restart) - self.restartBtn.SetToolTip(_('Restart (R)')) - self.nppBtn = wx.ToggleButton(self, -1, label=_('O')) - self.nppBtn.Bind(wx.EVT_TOGGLEBUTTON, self.toggle_npp) - self.nppBtn.SetToolTip(_('Display needle penetration point (O)')) - self.quitBtn = wx.Button(self, -1, label=_('Quit')) - self.quitBtn.Bind(wx.EVT_BUTTON, self.animation_quit) - self.quitBtn.SetToolTip(_('Quit (Q)')) - self.slider = wx.Slider(self, -1, value=1, minValue=1, maxValue=2, - style=wx.SL_HORIZONTAL | wx.SL_LABELS) + self.btnForwardStitch.SetBitmap(self.load_icon('forward_stitch')) + self.btnForwardStitch.SetToolTip(_('Go forward one stitch (+)')) + self.btnBackwardCommand = wx.Button(self, -1, style=self.button_style) + self.btnBackwardCommand.Bind(wx.EVT_BUTTON, self.animation_one_command_backward) + self.btnBackwardCommand.SetBitmap(self.load_icon('backward_command')) + self.btnBackwardCommand.SetToolTip(_('Go backward one command (page-down)')) + self.btnForwardCommand = wx.Button(self, -1, style=self.button_style) + self.btnForwardCommand.Bind(wx.EVT_BUTTON, self.animation_one_command_forward) + self.btnForwardCommand.SetBitmap(self.load_icon('forward_command')) + self.btnForwardCommand.SetToolTip(_('Go forward one command (page-up)')) + self.btnForward = wx.ToggleButton(self, -1, style=self.button_style) + self.btnForward.SetValue(True) + self.btnForward.Bind(wx.EVT_TOGGLEBUTTON, self.on_forward_button) + self.btnForward.SetBitmap(self.load_icon('forward')) + self.btnForward.SetToolTip(_('Animate forward (arrow right)')) + self.btnReverse = wx.ToggleButton(self, -1, style=self.button_style) + self.btnReverse.Bind(wx.EVT_TOGGLEBUTTON, self.on_reverse_button) + self.btnReverse.SetBitmap(self.load_icon('reverse')) + self.btnReverse.SetToolTip(_('Animate in reverse (arrow right)')) + self.btnPlay = wx.ToggleButton(self, -1, style=self.button_style) + self.btnPlay.Bind(wx.EVT_TOGGLEBUTTON, self.on_play_button) + self.btnPlay.SetBitmap(self.load_icon('play')) + self.btnPlay.SetToolTip(_('Play (P)')) + self.btnPause = wx.ToggleButton(self, -1, style=self.button_style) + self.btnPause.Bind(wx.EVT_TOGGLEBUTTON, self.on_pause_button) + self.btnPause.SetBitmap(self.load_icon('pause')) + self.btnPause.SetToolTip(_('Pause (P)')) + self.btnRestart = wx.Button(self, -1, style=self.button_style) + self.btnRestart.Bind(wx.EVT_BUTTON, self.animation_restart) + self.btnRestart.SetBitmap(self.load_icon('restart')) + self.btnRestart.SetToolTip(_('Restart (R)')) + self.btnNpp = wx.ToggleButton(self, -1, style=self.button_style) + self.btnNpp.Bind(wx.EVT_TOGGLEBUTTON, self.toggle_npp) + self.btnNpp.SetBitmap(self.load_icon('npp')) + self.btnNpp.SetToolTip(_('Display needle penetration point (O)')) + self.slider = SimulatorSlider(self, -1, value=1, minValue=1, maxValue=2) self.slider.Bind(wx.EVT_SLIDER, self.on_slider) self.stitchBox = IntCtrl(self, -1, value=1, min=1, max=2, limited=True, allow_none=True, style=wx.TE_PROCESS_ENTER) self.stitchBox.Bind(wx.EVT_LEFT_DOWN, self.on_stitch_box_focus) @@ -83,24 +109,89 @@ class ControlPanel(wx.Panel): self.stitchBox.Bind(wx.EVT_TEXT_ENTER, self.on_stitch_box_focusout) self.stitchBox.Bind(wx.EVT_KILL_FOCUS, self.on_stitch_box_focusout) self.Bind(wx.EVT_LEFT_DOWN, self.on_stitch_box_focusout) + self.btnJump = wx.ToggleButton(self, -1, style=self.button_style) + self.btnJump.SetToolTip(_('Show jump stitches')) + self.btnJump.SetBitmap(self.load_icon('jump')) + self.btnJump.Bind(wx.EVT_TOGGLEBUTTON, lambda event: self.on_marker_button('jump', event)) + self.btnTrim = wx.ToggleButton(self, -1, style=self.button_style) + self.btnTrim.SetToolTip(_('Show trims')) + self.btnTrim.SetBitmap(self.load_icon('trim')) + self.btnTrim.Bind(wx.EVT_TOGGLEBUTTON, lambda event: self.on_marker_button('trim', event)) + self.btnStop = wx.ToggleButton(self, -1, style=self.button_style) + self.btnStop.SetToolTip(_('Show stops')) + self.btnStop.SetBitmap(self.load_icon('stop')) + self.btnStop.Bind(wx.EVT_TOGGLEBUTTON, lambda event: self.on_marker_button('stop', event)) + self.btnColorChange = wx.ToggleButton(self, -1, style=self.button_style) + self.btnColorChange.SetToolTip(_('Show color changes')) + self.btnColorChange.SetBitmap(self.load_icon('color_change')) + self.btnColorChange.Bind(wx.EVT_TOGGLEBUTTON, lambda event: self.on_marker_button('color_change', event)) # Layout + self.hbSizer1 = wx.BoxSizer(wx.HORIZONTAL) + self.hbSizer1.Add(self.slider, 1, wx.EXPAND | wx.RIGHT, 10) + self.hbSizer1.Add(self.stitchBox, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10) + + self.command_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Command")), wx.VERTICAL) + self.command_text = wx.StaticText(self, wx.ID_ANY, label="", style=wx.ALIGN_CENTRE_HORIZONTAL | wx.ST_NO_AUTORESIZE) + self.command_text.SetFont(wx.Font(wx.FontInfo(20).Bold())) + self.command_text.SetMinSize(self.get_max_command_text_size()) + self.command_sizer.Add(self.command_text, 0, wx.EXPAND | wx.ALL, 10) + self.hbSizer1.Add(self.command_sizer, 0, wx.EXPAND) + + self.controls_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Controls")), wx.HORIZONTAL) + self.controls_inner_sizer = wx.BoxSizer(wx.HORIZONTAL) + self.controls_inner_sizer.Add(self.btnBackwardCommand, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnBackwardStitch, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnForwardStitch, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnForwardCommand, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnReverse, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnForward, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnPlay, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnPause, 0, wx.EXPAND | wx.ALL, 2) + self.controls_inner_sizer.Add(self.btnRestart, 0, wx.EXPAND | wx.ALL, 2) + self.controls_sizer.Add((1, 1), 1) + self.controls_sizer.Add(self.controls_inner_sizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10) + self.controls_sizer.Add((1, 1), 1) + + self.show_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Show")), wx.HORIZONTAL) + self.show_inner_sizer = wx.BoxSizer(wx.HORIZONTAL) + self.show_inner_sizer.Add(self.btnNpp, 0, wx.EXPAND | wx.ALL, 2) + self.show_inner_sizer.Add(self.btnJump, 0, wx.ALL, 2) + self.show_inner_sizer.Add(self.btnTrim, 0, wx.ALL, 2) + self.show_inner_sizer.Add(self.btnStop, 0, wx.ALL, 2) + self.show_inner_sizer.Add(self.btnColorChange, 0, wx.ALL, 2) + self.show_sizer.Add((1, 1), 1) + self.show_sizer.Add(self.show_inner_sizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10) + self.show_sizer.Add((1, 1), 1) + + self.speed_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Speed")), wx.VERTICAL) + + self.speed_buttons_sizer = wx.BoxSizer(wx.HORIZONTAL) + self.speed_buttons_sizer.Add((1, 1), 1) + self.speed_buttons_sizer.Add(self.btnMinus, 0, wx.ALL, 2) + self.speed_buttons_sizer.Add(self.btnPlus, 0, wx.ALL, 2) + self.speed_buttons_sizer.Add((1, 1), 1) + self.speed_sizer.Add(self.speed_buttons_sizer, 0, wx.EXPAND | wx.ALL) + self.speed_text = wx.StaticText(self, wx.ID_ANY, label="", style=wx.ALIGN_CENTRE_HORIZONTAL | wx.ST_NO_AUTORESIZE) + self.speed_text.SetFont(wx.Font(wx.FontInfo(15).Bold())) + extent = self.speed_text.GetTextExtent(self.format_speed_text(100000)) + self.speed_text.SetMinSize(extent) + self.speed_sizer.Add(self.speed_text, 0, wx.EXPAND | wx.ALL, 5) + + # A normal BoxSizer can only make child components the same or + # proportional size. A FlexGridSizer can split up the available extra + # space evenly among all growable columns. + self.control_row2_sizer = wx.FlexGridSizer(cols=3, vgap=0, hgap=5) + self.control_row2_sizer.AddGrowableCol(0) + self.control_row2_sizer.AddGrowableCol(1) + self.control_row2_sizer.AddGrowableCol(2) + self.control_row2_sizer.Add(self.controls_sizer, 0, wx.EXPAND) + self.control_row2_sizer.Add(self.speed_sizer, 0, wx.EXPAND) + self.control_row2_sizer.Add(self.show_sizer, 0, wx.EXPAND) + self.vbSizer = vbSizer = wx.BoxSizer(wx.VERTICAL) - self.hbSizer1 = hbSizer1 = wx.BoxSizer(wx.HORIZONTAL) - self.hbSizer2 = hbSizer2 = wx.BoxSizer(wx.HORIZONTAL) - hbSizer1.Add(self.slider, 1, wx.EXPAND | wx.ALL, 3) - hbSizer1.Add(self.stitchBox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) - vbSizer.Add(hbSizer1, 1, wx.EXPAND | wx.ALL, 3) - hbSizer2.Add(self.btnMinus, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.btnPlus, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.btnBackwardStitch, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.btnForwardStitch, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.directionBtn, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.pauseBtn, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.restartBtn, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.nppBtn, 0, wx.EXPAND | wx.ALL, 2) - hbSizer2.Add(self.quitBtn, 0, wx.EXPAND | wx.ALL, 2) - vbSizer.Add(hbSizer2, 0, wx.EXPAND | wx.ALL, 3) + vbSizer.Add(self.hbSizer1, 1, wx.EXPAND | wx.ALL, 10) + vbSizer.Add(self.control_row2_sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) self.SetSizerAndFit(vbSizer) # Keyboard Shortcuts @@ -125,9 +216,13 @@ class ControlPanel(wx.Panel): (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_SUBTRACT, self.animation_one_stitch_backward), (wx.ACCEL_NORMAL, ord('r'), self.animation_restart), (wx.ACCEL_NORMAL, ord('o'), self.on_toggle_npp_shortcut), - (wx.ACCEL_NORMAL, ord('p'), self.on_pause_start_button), - (wx.ACCEL_NORMAL, wx.WXK_SPACE, self.on_pause_start_button), - (wx.ACCEL_NORMAL, ord('q'), self.animation_quit)] + (wx.ACCEL_NORMAL, ord('p'), self.play_or_pause), + (wx.ACCEL_NORMAL, wx.WXK_SPACE, self.play_or_pause), + (wx.ACCEL_NORMAL, ord('q'), self.animation_quit), + (wx.ACCEL_NORMAL, wx.WXK_PAGEDOWN, self.animation_one_command_backward), + (wx.ACCEL_NORMAL, wx.WXK_PAGEUP, self.animation_one_command_forward), + + ] self.accel_entries = [] @@ -140,11 +235,14 @@ class ControlPanel(wx.Panel): self.SetAcceleratorTable(self.accel_table) self.SetFocus() + # wait for layouts so that panel size is set + wx.CallLater(50, self.load, self.stitch_plan) + def set_drawing_panel(self, drawing_panel): self.drawing_panel = drawing_panel self.drawing_panel.set_speed(self.speed) - def set_num_stitches(self, num_stitches): + def _set_num_stitches(self, num_stitches): if num_stitches < 2: # otherwise the slider and intctrl get mad num_stitches = 2 @@ -153,6 +251,41 @@ class ControlPanel(wx.Panel): self.slider.SetMax(num_stitches) self.choose_speed() + def add_color(self, color, num_stitches): + start = self._last_color_block_end + 1 + self.slider.add_color_section(ColorSection(color.rgb, start, start + num_stitches - 1)) + self._last_color_block_end = self._last_color_block_end + num_stitches + + def load(self, stitch_plan): + self.stitches = [] + self._set_num_stitches(stitch_plan.num_stitches) + + stitch_num = 0 + for color_block in stitch_plan.color_blocks: + self.stitches.extend(color_block.stitches) + + start = stitch_num + 1 + end = start + color_block.num_stitches + self.slider.add_color_section(color_block.color.rgb, start, end) + + for stitch_num, stitch in enumerate(color_block.stitches, start): + if stitch.trim: + self.slider.add_marker("trim", stitch_num) + elif stitch.stop: + self.slider.add_marker("stop", stitch_num) + elif stitch.jump: + self.slider.add_marker("jump", stitch_num) + elif stitch.color_change: + self.slider.add_marker("color_change", stitch_num) + + def load_icon(self, icon_name): + icon = wx.Image(os.path.join(self.icons_dir, f"{icon_name}.png")) + icon.Rescale(self.button_size, self.button_size, wx.IMAGE_QUALITY_HIGH) + return icon.ConvertToBitmap() + + def on_marker_button(self, marker_type, event): + self.slider.enable_marker_list(marker_type, event.GetEventObject().GetValue()) + def choose_speed(self): if self.target_duration: self.set_speed(int(self.num_stitches / float(self.target_duration))) @@ -160,22 +293,24 @@ class ControlPanel(wx.Panel): self.set_speed(self.target_stitches_per_second) def animation_forward(self, event=None): - self.directionBtn.SetLabel("<<") + self.btnForward.SetValue(True) + self.btnReverse.SetValue(False) self.drawing_panel.forward() self.direction = 1 self.update_speed_text() def animation_reverse(self, event=None): - self.directionBtn.SetLabel(">>") + self.btnForward.SetValue(False) + self.btnReverse.SetValue(True) self.drawing_panel.reverse() self.direction = -1 self.update_speed_text() - def on_direction_button(self, event): - if self.direction == 1: - self.animation_reverse() - else: - self.animation_forward() + def on_forward_button(self, event): + self.animation_forward() + + def on_reverse_button(self, event): + self.animation_reverse() def set_speed(self, speed): self.speed = int(max(speed, 1)) @@ -184,9 +319,15 @@ class ControlPanel(wx.Panel): if self.drawing_panel: self.drawing_panel.set_speed(self.speed) + def format_speed_text(self, speed): + return _('%d stitches/sec') % speed + def update_speed_text(self): - self.statusbar.SetStatusText(_('Speed: %d stitches/sec') % (self.speed * self.direction), 0) - self.hbSizer2.Layout() + self.speed_text.SetLabel(self.format_speed_text(self.speed * self.direction)) + + def get_max_command_text_size(self): + extents = [self.command_text.GetTextExtent(command) for command in COMMAND_NAMES] + return max(extents, key=lambda extent: extent.x) def on_slider(self, event): stitch = event.GetEventObject().GetValue() @@ -202,7 +343,7 @@ class ControlPanel(wx.Panel): self.current_stitch = stitch self.slider.SetValue(stitch) self.stitchBox.SetValue(stitch) - self.statusbar.SetStatusText(COMMAND_NAMES[command], 1) + self.command_text.SetLabel(COMMAND_NAMES[command]) def on_stitch_box_focus(self, event): self.animation_pause() @@ -238,14 +379,23 @@ class ControlPanel(wx.Panel): self.drawing_panel.go() def on_start(self): - self.pauseBtn.SetLabel(_('Pause')) + self.btnPause.SetValue(False) + self.btnPlay.SetValue(True) def on_stop(self): - self.pauseBtn.SetLabel(_('Start')) + self.btnPause.SetValue(True) + self.btnPlay.SetValue(False) - def on_pause_start_button(self, event): + def on_pause_button(self, event): """""" - if self.pauseBtn.GetLabel() == _('Pause'): + self.animation_pause() + + def on_play_button(self, event): + """""" + self.animation_start() + + def play_or_pause(self, event): + if self.drawing_panel.animating: self.animation_pause() else: self.animation_start() @@ -258,6 +408,28 @@ class ControlPanel(wx.Panel): self.animation_pause() self.drawing_panel.one_stitch_backward() + def animation_one_command_backward(self, event): + self.animation_pause() + stitch_number = self.current_stitch - 1 + while stitch_number >= 1: + # stitch number shown to the user starts at 1 + stitch = self.stitches[stitch_number - 1] + if stitch.jump or stitch.trim or stitch.stop or stitch.color_change: + break + stitch_number -= 1 + self.drawing_panel.set_current_stitch(stitch_number) + + def animation_one_command_forward(self, event): + self.animation_pause() + stitch_number = self.current_stitch + 1 + while stitch_number <= self.num_stitches: + # stitch number shown to the user starts at 1 + stitch = self.stitches[stitch_number - 1] + if stitch.jump or stitch.trim or stitch.stop or stitch.color_change: + break + stitch_number += 1 + self.drawing_panel.set_current_stitch(stitch_number) + def animation_quit(self, event): self.parent.quit() @@ -265,13 +437,11 @@ class ControlPanel(wx.Panel): self.drawing_panel.restart() def on_toggle_npp_shortcut(self, event): - self.nppBtn.SetValue(not self.nppBtn.GetValue()) + self.btnNpp.SetValue(not self.btnNpp.GetValue()) self.toggle_npp(event) def toggle_npp(self, event): - if self.pauseBtn.GetLabel() == _('Start'): - stitch = self.stitchBox.GetValue() - self.drawing_panel.set_current_stitch(stitch) + self.drawing_panel.Refresh() class DrawingPanel(wx.Panel): @@ -405,8 +575,8 @@ class DrawingPanel(wx.Panel): canvas.SetTransform(canvas.CreateMatrix()) crosshair_radius = 10 canvas.SetPen(self.black_pen) - canvas.DrawLines(((x - crosshair_radius, y), (x + crosshair_radius, y))) - canvas.DrawLines(((x, y - crosshair_radius), (x, y + crosshair_radius))) + canvas.StrokeLines(((x - crosshair_radius, y), (x + crosshair_radius, y))) + canvas.StrokeLines(((x, y - crosshair_radius), (x, y + crosshair_radius))) def draw_scale(self, canvas): canvas.BeginLayer(1) @@ -433,13 +603,13 @@ class DrawingPanel(wx.Panel): scale_lower_left_x = 20 scale_lower_left_y = canvas_height - 30 - canvas.DrawLines(((scale_lower_left_x, scale_lower_left_y - 6), - (scale_lower_left_x, scale_lower_left_y), - (scale_lower_left_x + scale_width / 2.0, scale_lower_left_y), - (scale_lower_left_x + scale_width / 2.0, scale_lower_left_y - 3), - (scale_lower_left_x + scale_width / 2.0, scale_lower_left_y), - (scale_lower_left_x + scale_width, scale_lower_left_y), - (scale_lower_left_x + scale_width, scale_lower_left_y - 5))) + canvas.StrokeLines(((scale_lower_left_x, scale_lower_left_y - 6), + (scale_lower_left_x, scale_lower_left_y), + (scale_lower_left_x + scale_width / 2.0, scale_lower_left_y), + (scale_lower_left_x + scale_width / 2.0, scale_lower_left_y - 3), + (scale_lower_left_x + scale_width / 2.0, scale_lower_left_y), + (scale_lower_left_x + scale_width, scale_lower_left_y), + (scale_lower_left_x + scale_width, scale_lower_left_y - 6))) canvas.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL), wx.Colour((0, 0, 0))) canvas.DrawText("%s mm" % scale_width_mm, scale_lower_left_x, scale_lower_left_y + 5) @@ -447,7 +617,7 @@ class DrawingPanel(wx.Panel): canvas.EndLayer() def draw_needle_penetration_points(self, canvas, pen, stitches): - if self.control_panel.nppBtn.GetValue(): + if self.control_panel.btnNpp.GetValue(): npp_pen = wx.Pen(pen.GetColour(), width=int(0.5 * PIXELS_PER_MM * self.PIXEL_DENSITY)) canvas.SetPen(npp_pen) canvas.StrokeLineSegments(stitches, [(stitch[0] + 0.001, stitch[1]) for stitch in stitches]) @@ -460,11 +630,10 @@ class DrawingPanel(wx.Panel): self.current_stitch = 1 self.direction = 1 self.last_frame_duration = 0 - self.num_stitches = stitch_plan.num_stitches - self.control_panel.set_num_stitches(self.num_stitches) self.minx, self.miny, self.maxx, self.maxy = stitch_plan.bounding_box self.width = self.maxx - self.minx self.height = self.maxy - self.miny + self.num_stitches = stitch_plan.num_stitches self.parse_stitch_plan(stitch_plan) self.choose_zoom_and_pan() self.set_current_stitch(0) @@ -640,6 +809,141 @@ class DrawingPanel(wx.Panel): self.Refresh() +class MarkerList(list): + def __init__(self, icon_name, stitch_numbers=()): + super().__init__(self) + icons_dir = get_resource_dir("icons") + self.icon_name = icon_name + self.icon = wx.Image(os.path.join(icons_dir, f"{icon_name}.png")).ConvertToBitmap() + self.enabled = False + self.extend(stitch_numbers) + + def __repr__(self): + return f"MarkerList({self.icon_name})" + + +class ColorSection: + def __init__(self, color, start, end): + self.color = color + self.start = start + self.end = end + self.brush = wx.Brush(wx.Colour(*color)) + + +class SimulatorSlider(wx.Panel): + PROXY_EVENTS = (wx.EVT_SLIDER,) + + def __init__(self, parent, id=wx.ID_ANY, *args, **kwargs): + super().__init__(parent, id) + + kwargs['style'] = wx.SL_HORIZONTAL | wx.SL_LABELS + + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.slider = wx.Slider(self, *args, **kwargs) + self.sizer.Add(self.slider, 0, wx.EXPAND) + + # add 33% additional vertical space for marker icons + size = self.sizer.CalcMin() + self.sizer.Add((10, size.height // 3), 1, wx.EXPAND) + self.SetSizerAndFit(self.sizer) + + self.marker_lists = { + "trim": MarkerList("trim"), + "stop": MarkerList("stop"), + "jump": MarkerList("jump"), + "color_change": MarkerList("color_change"), + } + self.marker_pen = wx.Pen(wx.Colour(0, 0, 0)) + self.color_sections = [] + self.margin = 13 + self.color_bar_start = 0.25 + self.color_bar_thickness = 0.25 + self.marker_start = 0.375 + self.marker_end = 0.75 + self.marker_icon_start = 0.75 + self.marker_icon_size = size.height // 3 + + self.Bind(wx.EVT_PAINT, self.on_paint) + self.Bind(wx.EVT_ERASE_BACKGROUND, self.on_erase_background) + + def SetMax(self, value): + self.slider.SetMax(value) + + def SetMin(self, value): + self.slider.SetMin(value) + + def SetValue(self, value): + self.slider.SetValue(value) + + def Bind(self, event, callback, *args, **kwargs): + if event in self.PROXY_EVENTS: + self.slider.Bind(event, callback, *args, **kwargs) + else: + super().Bind(event, callback, *args, **kwargs) + + def add_color_section(self, color, start, end): + self.color_sections.append(ColorSection(color, start, end)) + + def add_marker(self, name, location): + self.marker_lists[name].append(location) + self.Refresh() + + def enable_marker_list(self, name, enabled=True): + self.marker_lists[name].enabled = enabled + self.Refresh() + + def disable_marker_list(self, name): + self.marker_lists[name].enabled = False + self.Refresh() + + def toggle_marker_list(self, name): + self.marker_lists[name].enabled = not self.marker_lists[name].enabled + self.Refresh() + + def on_paint(self, event): + dc = wx.BufferedPaintDC(self) + background_brush = wx.Brush(self.GetTopLevelParent().GetBackgroundColour(), wx.SOLID) + dc.SetBackground(background_brush) + dc.Clear() + gc = wx.GraphicsContext.Create(dc) + + width, height = self.GetSize() + min_value = self.slider.GetMin() + max_value = self.slider.GetMax() + spread = max_value - min_value + + def _value_to_x(value): + return (value - min_value) * (width - 2 * self.margin) / spread + self.margin + + gc.SetPen(wx.NullPen) + for color_section in self.color_sections: + gc.SetBrush(color_section.brush) + + start_x = _value_to_x(color_section.start) + end_x = _value_to_x(color_section.end) + gc.DrawRectangle(start_x, height * self.color_bar_start, + end_x - start_x, height * self.color_bar_thickness) + + gc.SetPen(self.marker_pen) + for marker_list in self.marker_lists.values(): + if marker_list.enabled: + for value in marker_list: + x = _value_to_x(value) + gc.StrokeLine( + x, height * self.marker_start, + x, height * self.marker_end + ) + gc.DrawBitmap( + marker_list.icon, + x - self.marker_icon_size / 2, height * self.marker_icon_start, + self.marker_icon_size, self.marker_icon_size + ) + + def on_erase_background(self, event): + # supposedly this prevents flickering? + pass + + class SimulatorPanel(wx.Panel): """""" @@ -675,6 +979,7 @@ class SimulatorPanel(wx.Panel): def load(self, stitch_plan): self.dp.load(stitch_plan) + self.cp.load(stitch_plan) def clear(self): self.dp.clear() @@ -687,8 +992,6 @@ class EmbroiderySimulator(wx.Frame): stitches_per_second = kwargs.pop('stitches_per_second', 16) target_duration = kwargs.pop('target_duration', None) wx.Frame.__init__(self, *args, **kwargs) - self.statusbar = self.CreateStatusBar(2) - self.statusbar.SetStatusWidths([250, -1]) sizer = wx.BoxSizer(wx.HORIZONTAL) self.simulator_panel = SimulatorPanel(self, @@ -839,6 +1142,8 @@ class SimulatorPreview(Thread): on_close=self.simulate_window_closed, target_duration=self.target_duration) except Exception: + import traceback + print(traceback.format_exc(), file=sys.stderr) try: # a window may have been created, so we need to destroy it # or the app will never exit