From fb8d50ea411b20f9b5042a5ce63e1a3445f187b6 Mon Sep 17 00:00:00 2001 From: cmorley Date: Wed, 15 Feb 2012 17:13:34 -0800 Subject: [PATCH 1/6] gremlin/axis -change the offsets display for gremlin Signed-off-by: cmorley --- lib/python/rs274/glcanon.py | 72 +++++++++++++++++++++++++++++++------------ 1 files changed, 52 insertions(+), 20 deletions(-) diff --git a/lib/python/rs274/glcanon.py b/lib/python/rs274/glcanon.py index 75322bb..0daf8c4 100644 --- a/lib/python/rs274/glcanon.py +++ b/lib/python/rs274/glcanon.py @@ -748,7 +748,6 @@ class GlCanonDraw: g92_offset = self.to_internal_units(s.g92_offset)[:3] glPushMatrix() - if self.get_show_offsets() and (g5x_offset[0] or g5x_offset[1] or g5x_offset[2]): glBegin(GL_LINES) glVertex3f(0,0,0) @@ -953,18 +952,34 @@ class GlCanonDraw: ypos -= linespace+5 i=0 glColor3f(*self.colors['overlay_foreground']) - for string in posstrs: - maxlen = max(maxlen, len(string)) - glRasterPos2i(5, ypos) - for char in string: - glCallList(base + ord(char)) - if i < len(homed) and homed[i]: - glRasterPos2i(pixel_width + 8, ypos) - glBitmap(13, 16, 0, 3, 17, 0, homeicon) - if i < len(homed) and limit[i]: - glBitmap(13, 16, 0, 1, 17, 0, limiticon) - ypos -= linespace - i = i + 1 + if not self.get_show_offsets(): + for string in posstrs: + maxlen = max(maxlen, len(string)) + glRasterPos2i(5, ypos) + for char in string: + glCallList(base + ord(char)) + if i < len(homed) and homed[i]: + glRasterPos2i(pixel_width + 8, ypos) + glBitmap(13, 16, 0, 3, 17, 0, homeicon) + if i < len(homed) and limit[i]: + glBitmap(13, 16, 0, 1, 17, 0, limiticon) + ypos -= linespace + i = i + 1 + if self.get_show_offsets(): + if self.is_lathe(): + homed.insert(0,homed[0]) + i=0 + for string in droposstrs: + maxlen = max(maxlen, len(string)) + glRasterPos2i(5, ypos) + for char in string: + glCallList(base + ord(char)) + if i < len(homed) and homed[i]: + glRasterPos2i(charwidth *3, ypos) + glBitmap(13, 16, 0, 3, 17, 0, homeicon) + ypos -= linespace + i = i + 1 + glDepthFunc(GL_LESS) glDepthMask(GL_TRUE) @@ -1059,12 +1074,18 @@ class GlCanonDraw: g92_offset = self.from_internal_units(g92_offset, 1) tlo_offset = self.from_internal_units(tlo_offset, 1) format = "% 6s:% 9.3f" - droformat = " " + format + " DTG %1s:% 9.3f" + if self.get_show_distance_to_go(): + droformat = " " + format + " DTG %1s:% 9.3f" + else: + droformat = " " + format offsetformat = "% 5s %1s:% 9.3f G92 %1s:% 9.3f" rotformat = "% 5s %1s:% 9.3f" else: format = "% 6s:% 9.4f" - droformat = " " + format + " DTG %1s:% 9.4f" + if self.get_show_distance_to_go(): + droformat = " " + format + " DTG %1s:% 9.4f" + else: + droformat = " " + format offsetformat = "% 5s %1s:% 9.4f G92 %1s:% 9.4f" rotformat = "% 5s %1s:% 9.4f" diaformat = " " + format @@ -1075,8 +1096,10 @@ class GlCanonDraw: a = "XYZABCUVW"[i] if s.axis_mask & (1< Date: Wed, 15 Feb 2012 17:17:02 -0800 Subject: [PATCH 2/6] gscreen -add gscreen gui to linuxcnc source Signed-off-by: cmorley --- share/gscreen/images/coolant_flood.xcf | Bin 0 -> 4455 bytes share/gscreen/images/coolant_flood_plain.gif | Bin 0 -> 1330 bytes share/gscreen/images/coolant_flood_plain.xcf | Bin 0 -> 2947 bytes share/gscreen/images/coolant_mist.xcf | Bin 0 -> 4644 bytes share/gscreen/images/coolant_mist_plain.gif | Bin 0 -> 1317 bytes share/gscreen/images/coolant_mist_plain.xcf | Bin 0 -> 2994 bytes share/gscreen/images/linuxcnc-wizard.gif | Bin 0 -> 6971 bytes share/gscreen/images/spindle_ccw.gif | Bin 0 -> 209 bytes share/gscreen/images/spindle_cw.gif | Bin 0 -> 209 bytes share/gscreen/images/tool_clear.gif | Bin 0 -> 1458 bytes share/gscreen/images/tool_reload.gif | Bin 0 -> 1458 bytes src/Makefile | 10 +- src/emc/usr_intf/gscreen/Submakefile | 35 + src/emc/usr_intf/gscreen/emc_interface.py | 660 ++++++++ src/emc/usr_intf/gscreen/gscreen.glade | 2229 ++++++++++++++++++++++++++ src/emc/usr_intf/gscreen/gscreen.py | 1098 +++++++++++++ src/emc/usr_intf/gscreen/gscreen2.glade | 79 + src/emc/usr_intf/gscreen/mdi.py | 329 ++++ src/emc/usr_intf/gscreen/preferences.py | 45 + 19 files changed, 4483 insertions(+), 2 deletions(-) create mode 100755 share/gscreen/images/coolant_flood.xcf create mode 100644 share/gscreen/images/coolant_flood_plain.gif create mode 100644 share/gscreen/images/coolant_flood_plain.xcf create mode 100755 share/gscreen/images/coolant_mist.xcf create mode 100644 share/gscreen/images/coolant_mist_plain.gif create mode 100644 share/gscreen/images/coolant_mist_plain.xcf create mode 100644 share/gscreen/images/linuxcnc-wizard.gif create mode 100644 share/gscreen/images/spindle_ccw.gif create mode 100644 share/gscreen/images/spindle_cw.gif create mode 100644 share/gscreen/images/tool_clear.gif create mode 100644 share/gscreen/images/tool_reload.gif create mode 100644 src/emc/usr_intf/gscreen/Submakefile create mode 100644 src/emc/usr_intf/gscreen/emc_interface.py create mode 100644 src/emc/usr_intf/gscreen/gscreen.glade create mode 100755 src/emc/usr_intf/gscreen/gscreen.py create mode 100644 src/emc/usr_intf/gscreen/gscreen2.glade create mode 100644 src/emc/usr_intf/gscreen/mdi.py create mode 100644 src/emc/usr_intf/gscreen/preferences.py diff --git a/share/gscreen/images/coolant_flood.xcf b/share/gscreen/images/coolant_flood.xcf new file mode 100755 index 0000000000000000000000000000000000000000..0d613cf5f43dae6548b73e638f0dc5e88dbe895e GIT binary patch literal 4455 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 OQ(vV1BzF66TK@~P=HaIR literal 0 HcmV?d00001 diff --git a/share/gscreen/images/coolant_flood_plain.gif b/share/gscreen/images/coolant_flood_plain.gif new file mode 100644 index 0000000000000000000000000000000000000000..aa4c316f42433939e5cdad4fe51c0cb8c1ac62db GIT binary patch literal 1330 zcmd_p2{W4s0D$2ygbmr_U3?YQTQD3V5;p<v22apZPq47S zT3J1?w)VEM@v^rMh(gO_v0-j*@g5#YK0XOPK8e1*Fa7+|GX3EG{^@~%nZdzvK|#dQ z0L74ySD~R0b z#TCZK7bPV8k(5xBm{|Pc1tmF|l9E!Eky_fGf=W-XBoL}IGpmWj+E=frSy{B~>^c&O zo|i|@&u;`tW(5U}Wb$8yh0V;8Yb7PE6iOS1qE%MbR$l(LqT+33Wyf5(R#g?FrlwO+ ztyWvxMWel|ukWVQyBiz(nwt8Xn+IB22F0yEw6%e|ZQ7e1h)sqzgTd-ybar;K4j5Wp zUBd@m>f(2r@86GfcaQbx+x)OG_Ke%m1vb{JXZY zvAQZ;TNAFYZ+`x~wXv}!6z*(p?rv@EZf}crc0_x7Vv*=TB$Dj!OT^+Y2M31|$)QZb zmq?C|j*gFyPo&b*i_Xr@&i}{h$W$@0VL|a>p~$4i@sUVpS9cFU=L8B-2F?M~Z+mdk{wjbB6K|0e|okjR)0#}d3dsj{wdd=i4ZN+lSwwao!iPjO(V(M4s2b)aCnLnxY<2_R8gbjb;@q4d zhib~xxLxN$u#z_MUH^oK01m}8c_qU-%Xv9_ zu8KSy6}b;6=surBV=#CE3wB>>G%aT|xo@wiVcDJm{ch5UQhfIYh*m~ELfS(Wc2MZz zz@ktPP*e#710b{P@JjC-x>t4Ta*m;As^BD|5`YSX)L%4lkwBWRbgJ%mYg|no`EITe ioosH>e%0Ef%z`fcy8!|LZ2ki>H7kAq literal 0 HcmV?d00001 diff --git a/share/gscreen/images/coolant_flood_plain.xcf b/share/gscreen/images/coolant_flood_plain.xcf new file mode 100644 index 0000000000000000000000000000000000000000..8670d0d002807f95b1b6e67242babd9a67fe879b GIT binary patch literal 2947 zcmcImeNa@_6~Awn1$N&e_!bZp&0@f4Q!_DXY$E9YKXCjX|<$@!30dgmllE_EW!psAV82nh=78?e!zaccl*1`Vu_)Dv@^ZC zXWu!$bI!fz-TQmzZED(%o!Z?=DcY2@3?0GP2+=YHV=;u|@FPGJkcVaX(Le&9DI|mm zMkvG&@(?84r?aFmBuC*Il8QCfrtL^f)vZm?*(7Q*&0C?Qdw zqf6FqO3c$`!zSzi*zkw2O{b7RpUx7LJ{=dLny2&gboD$vXr3Mnoz2CLos9qpTZ4`H zhdhfA+0#B{u3*H<`jh4=n2Y*h~Wa_44@*8u_KdxIlPyT893)qG6w&971{`wCuPFX82T&k}4;P^h= z+t|g?{{AlpEYlP1wW8a4_uI;*3~cLId1p&Y{hi*a)~0&5b!@25^yPlQxBqgby1I6_ zwY#jkZ17H3!|CQD1~A-@+G+{{Mh`2PC$cZy{ z*ZrbFUB+CoUgl9e*8vxbMx7F zcpW)S<+`o$@r*cU|F6WU?_ZEObqf=x=D#P7;dlQVaa0QtN3CVVLF3j0%l=KARpE;P z@f`0YA!@Z!0Sfqd6QdQ-BzQURA!=U5sbu$P6Qxn3mB7Oh884~kShIYoCWzq*;2gsl zYnDfZh5!X?c#w-%5HU!N)xa8v#52|)T;vHKz>9=utl{0b5?%@18zAFd0PsgX;3ES9&MIMc*f_duPgZe-${*2=CA-ooR6ep7U< zrlz!|=*;nS4$u{PdCZiV+F=joE(;4^lZ}f1<4NhX*U3lsgJf6p% zd}2Mf-tpu!TX$e}_|R~2jeFi;)cFbbxZ|mxy^w(=3<@|r24g;>&bkfHZb{0_Vbn2z zl)1Z6ohx(aF1-OzARx(zFwVf`x>zbP1QbF`HyS5D*r?5EcRk!6U-v zy*3ND-6b7JQ1q$qKc$8(i}-)>qr?SYB6 zA~5@23Ld#>@w7z!smFOf7!w2#8+~}vBT)%oiZG}6U2j(j#a-K|ahjn%hl6RNiQ;B$ zv_!n$Be|K!L;ogH6^rDk$3y+FRW|xZ6nk%)8R~}Np?E9_M@6ed1L@2R)}{=@sZ*zG zHky;{&K}CDn)8VLE>!5C;!Fdj4^TfUDNrXz$4xeeV`}&`4d?N8ppz8m835dVr4ca%HA+|U<0k$x4olxw1cgO}hlWRE4%*iGPwaJ+N{$t7 z%L7#EVEpT(wE0FyYYiOBl+59l`K!FIKibgN^L3ZG7JrMa#}WT91GG+n>Z qZf?5VP{mNuUxS$^>EA!9_`JHNrs}hbkLhW4UbBuxlqZX@*uMbkty)6> literal 0 HcmV?d00001 diff --git a/share/gscreen/images/coolant_mist.xcf b/share/gscreen/images/coolant_mist.xcf new file mode 100755 index 0000000000000000000000000000000000000000..ecaa0b461c4459e739552725f327294c0e10d879 GIT binary patch literal 4644 zcmc&%eRNYr7QZiPQ<~Rq;iXLrMNCVJMQw#vbQSb~a#U1yIR{+z2ri*b(@03M$?Jy| zt1Nm}Eeg6&75UnggCA_wg1da_wl<(G&_#h_;a~+(z*0(^q|MiRv-iH2uq}4~*gd;v z-^t|7{O-Lozs&sR&cte4veZ;rSZpe`*)4$2G%O~n;4=yf$KjWNB^JvK8vHU~8FAMt z04n$-V~N2s8jCSfr=S!J9*gghRvaVOw#00;GBlLtA@Xo<;QW^2v|frL_)f=S!a{Qy zKilSXney`TunsybG~o=(h)7*=iq!E1`ayMmP(5K#J#kPy3G39?I4tzUVWBbTi7qfL zJT2;ce5;G=8TlaxZh8)3rcB~H-|^Tzw=T%U87VGxAU4po((Tbj;KbPh)@@O|lDp4WedT2ix zifQ*zyGFb4N|_51vw#MIvrrxkwIVazx?y%ei|Zr(jX}JMbhBDq#|P>ZFPL>S_+1gx zuo&oK8Amv1%~A2LxpCv(#%^Mvhr!2lXaAK%ho3X{vDlr`br*w~ZHMlS7^XB_JT+Sh z@SeXN@ zNHh0Ec`IGw7lKW{9t4h3JL1?#{2ev$5-nCV!P1V6rENkWK0c{_Ygu)06Z>Oc#%d5c6UJuQV}RVgo;VJ@JgxIX&`>n#joMkteUZB2S)p zD!#}w0`tUEjgRy~JflXA57Q9HlVULjc)gzIiKjloQ$OmSO)Eg0kv>M5!0OKdM1ak& ze?-kDrGf3HX5xtz{J1$c@?0A+sQ~g6$tD8w6p5$OK%Nm;B%TVUx`CT`Mva^phG(jY zC&gk6h;Fwi5>Gerd>-X|Gx$S(i4(Z}Few2e6y zf)TtH2kMPejr6V6#6TX}0!pS}iZ7-MHFgpj2GkUSt~V*&_|zmpp~#S9o`_w`SR4m8 zAfkbO^5HlQI^7HbU7SX%;UI%V8&x%JKmIOr;bLo9spu#o)BkJpMK?cEh+jiQ@QKpI z%@_Zk3PrK_UDRF%{y^{f6K#zj;SzhpvLtuQzNXf-i*c5`eID=mcDe5o>s^fV+3$tw zW4o3uU%VLC#s6EV|NiSeZ{fPiBe31St1EbBLm?#Ua9zA-&!0ZlcB-RsmHmEP6wmp- z6JPvg%a?ua8&=*+%l57R@^@`}-uueazTx+a9>clr{`y=`PiNBypY?ine(K)6{rxv< zAO|jfcA>NL^V5C(JxBIRA=_eJ?D60UGplZYM8Tm&6-y# zo^?IH_`&iQir~$?uRMvjlnKx^r*3&oRawcS=2H8^0B`K5T?!)+@0;UVvBYYAWX{4F zIG>cD6Nt~8hjHZ>F1Q^gBxc-U#eBijustQE3t(!&)Z3=Qb!o=YcY;9a#b|&m2wCPo zoQ<*zWM`%dsUT>DAfyN>MwHg&`M;TU{rIe`@fp{o3dR)GW)utt$b`Q8@+M|xn8u~2 z8d8!$h{Y((P6ikczRb}n>1ip+*t-y?z!;DP{$zuI84QGYAw;eS1@J`(uOLQ@13wweUg+TPYy@7cGe z?(yj)pdF0|8s0qGaPZ)^=_H^7;A(BKJUV?k31}v4iwa0PNI=TQ{%;DXsdHEXH4ZPJ zJ^#Ld#Har=0qKVkP=aaZQcUE$VW@y67)KfI2A=Z%NSgR70?IN82?@Y!`5@@=3>YGy zv4#Xh&?cdcPv?L%yM&8)b*3nZYBx*@Od0^kUeGacB!T4k0&lgU%e2AI3e}7Nt{PyP|k)z~u zq5Iso9cNFsy<2OcMhjQ2!)TgcaQ z;q0-FjR;E(M_Ra+o{Jr)8(SLB_k4GF=kfPnhifVO)E(HfXX~N5Ej!-WUcdg8mp?xI z?rQvdgocVwwr$(`+S=DP)w=$$`33l}W$P+5VD_n~U%#$y^^4D}c(t}1px(XZRY;@k zQ}Noyl`pPXREi38AoewiW#|mJ8J=omw*1Qi^;??0M=wmIiUmB2u-5xid-MI)n>**ipmO}v+ zPyh|{0b4Ii$M=1TZM^5OCxfyaU>wT>Et95QU|Q_Q&tC2sxO7>PIXN8ug5fn32b8F#U3l^{-x6 z%h-(uVIpo`S&QP6V{n>66UL-v;qDxWO-xBMCL1$w9|yE?`h=vhc+(4Mbovyi;f}&T E0Cb4f`Tzg` literal 0 HcmV?d00001 diff --git a/share/gscreen/images/coolant_mist_plain.gif b/share/gscreen/images/coolant_mist_plain.gif new file mode 100644 index 0000000000000000000000000000000000000000..403cf1270bfd078c0587f9b9e269da892f2d2698 GIT binary patch literal 1317 zcmd_pi8tE^0KoAdaR#fSb9CW3TF*6OrgOBbR7(Y0m{EPxqB2_QOlVmrBC@6p5~Fd% zE#jJ1M4!4|BF;2YR}h{fp^dDFNb9LpO#hC3-{)WW`uh2}xkp_9%mHyLaFV_j%Ebld z?*6lf$1k3qAyDYecrOqPh6o5i!r>WVVW_aM^y}9jhKK)w3D=5<$c~J}L`SDZMPZ-b zRJ(mUFD3@}5CM;k#mB|r@7{e9A5Ta~c$|3 zpHD3)pfL%~g@rUCv57=#VU?Jbl(dn_?Hsa6X=!^|*|YNUXB8D4b7dwJ3caeTbFost zx|&g2+ttv}O{I3zXuZwNeJw5ht*ryHHl6l%=5{+|v*W8xI)qMVzod6|cCz>ACJe^V z9>YM^W%%O7NO$*GPtSO7?+H#{?|5I|iC6vo+<^hEoN2*iPB57~7IT8d;tjHRZ1&{P z(A0-v|B;cI(b1V5uIu|(j-NQ^#>QsH$N3x%|Cnpd;mq+l-A6n-1<#htou8Ok;PC{n zUkfHDPb^MNElp1^DdxVNnORoM#`5_qb91Zn^J@ZuaB)$zv?N+y-dI_Av%30LxVo{n zCKd|CBGKmhx@2QRA{K9LZf;8?+wa~QvBqGK<;|?;;+}AG<4p@9tQ33686nYZxB57~O#LRaZ%x3MKd%*$d0duDBMh zQ}L!jkBMug_RepGb-Js{Xe4;{tXFiEuHBacoC-TCcG@-Tv}NN@)s`LjRO{KMZ+=@r zk1HcI2u!DZLp6Vt`ISJDWf$ozrU=zGehPyJS)L$MHR;Mu?$)PXV3D!R_- z8mM04ZX_m0{S1|=#(05D(y(zYiOb3g{zNhOeu zX2-CO<(ON23Yg-Qt8N@HiB{G#CeC{Mn1z#+wQ6>ARQ0^PfWYDKm!^QK2Am0~MjE0^ zO@r@*08w;XYam_$qES+(Z6_=5-)N>)riTi|6=*e&xC)dZM_gI;NrqvfX-gq@b0VGr@yM4#ca@dsr0*z$Yq(0gpfJ$4w{^elf1MuT!t^OxA4A0f$a z1kX=`L9S%O&oN0hjkkl-H8FhM*zyUafz88vc@uAM?KqqdOTlKb+J<|0%N;h6k6ve4 z_vhPp=I6t5n5zB$+oreRm*Dz*bZX#OHl%`WaQIfY@kVdUKHXYa0@h*6^{@Ya;)12; z*zPru0u$dk$8Q>&KKRDkbL=mhpMphT`gX`{?r;6*+=R8^YF@vY zmSxg>x!LQs-ub?vLkA0Btgff4t97(*;!;Pe+d4LQ!|;!CgnxYdd}Cwt(52qm#@d0= zt8MRf?$@KV6XC~~nrmwIw!BnPU3RSUPX&KC+P1G)bYvbsbZAfMD61Xlgo zryqnQMLfQ}DLpOyfpl1)h@SoHSWw3NLLP}MJ`to~Nlb`}m?>=2sK{t~#rx*Zzb}5y zOeO9|+`D+GR0zA`)pKKKMuG%fK9o}}1as`H=qTFN0!Ca;l}Zd@oCdrS_o`bMEC+`V zR>Cr{2$(+sR>0|Za!L;qVdzyRfj6dNDv)8Mq{n@t3#E~ ztRg|2X}MT;hp(+i^MzZZo5kN=w>WYY*D zRQ;16l0w6yej5$)*f1H%Mij(+b+{ZiI_~>Wx$LeW;vz%wR6r0f8Nn!sIWdt65`+)s zWGIMPQQ-$KS~bbe!KJA3LVtyZV$_HE;!-D$aT(d)KPj9ln`9hY{jt^eA! zF7trxdXLd?@% zwN-oGIDP5;{VUCE)@wM)^^4~0bZuTc}_iwpFxJ- zM4q8&E$kKRq{GC!UCbqrJnW(r6L`O1c(w`@39|#M;=NbDIx8?ttm5|o>nerEz@t~D zZsuUVP;jy5r+D7QI2Hz@EdDYF9myhRbVKmmw=w4okTUN>BTUL7z|7$EhV`G(HyN)1 zT^uIGbRpnmZi~L9Sm;PGU-7Yej<@;-%eZ` zKCGvQ6S?@Z+}a_ugOFP_$+IBlah(an87e4O08EJ4YwizPHwxwjh}hVoaSzXUycj;! z<^7@WYBj^HEbzxg{*%|-SJpt8m7!8>taOstz5pj#UIRnb+E}&sUp>5=JRbHpFOw0I zV;&C+fcZ%NGcMlU$2gc92ObuPE{=JvJPTnC2hNER76E)b-Z*Pv`iA$ORSYOY~U1G~8H6puTAV^*JE%2+Tb Yyn+NKiNkRcB;gqs6fBWSIEaUT0)TICP5=M^ literal 0 HcmV?d00001 diff --git a/share/gscreen/images/linuxcnc-wizard.gif b/share/gscreen/images/linuxcnc-wizard.gif new file mode 100644 index 0000000000000000000000000000000000000000..ac9adc469de2a3ada1f55c4daa17fff77ad062b8 GIT binary patch literal 6971 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 Pdpp_cMAc;+60rV1C1M-S literal 0 HcmV?d00001 diff --git a/share/gscreen/images/spindle_ccw.gif b/share/gscreen/images/spindle_ccw.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2357d85333342d3d8570a99398ad16bd9fc75aa GIT binary patch literal 209 zcmYjLF%AMT3^Qtmj`szm8ySkafLJnEaQvVvKdE$m0^*@;OeN_t;Kj1zIJw=gr}JaN zgtx$;Kq;l7_TF6&>_4&t1P521MR+Y_BRNPA;cAXKRH&J0RU#@|3XGIWCZk5tnDeR@ n0c#F(gjVJ8H(RKUHnTme-uA`?@lG=Z+gb5yi~K*~>WRx2^5ZW@ literal 0 HcmV?d00001 diff --git a/share/gscreen/images/spindle_cw.gif b/share/gscreen/images/spindle_cw.gif new file mode 100644 index 0000000000000000000000000000000000000000..cecc1d87dae85487fa1bd2b6b1fefb5898a9c25c GIT binary patch literal 209 zcmYL@F$w}P6hucdMal(FU}s?=q*<}~$e{5CX}w8c_Xy%a?X0p%Saq7u`!k>UxBGQG zJq8ST6IBMJlrnNDrE%Bp!wo7@dxVU(MfPqzjl}DOaNM1^SL0X7GN|aYhj8{llN<>sz zOk7G@TAEK(gHhO8Oj<`yUc*wG!CIfe#)v^tNlimT!_3T#Pc>RVJx1Hm!_dsz*e1rt zF2L44P~Em%%eFAqf+5bDAXowEKYd+X-jd+#4KYPqVvDxKmu$-~ zo|0EOC%Jq_ZvEb>`bBvSdkY%(RWxs^>^NNAb)-Fvp)-nMMmocS1cogY4BP4%7S`LI zsAM=*!?~`7VSO9J)&L?&C1QdU=FfuUAX3zmC2jvL{ zj(-g1xwp1>9%2%mZ3bjyUS8&l!Z2~Typ&f9tCWi4<)w;(SfxO^6pajWuoyUn>BLe+ zD>-aZTTUJZN;xdJf$5AbCl5|kv`Q1fCY34N4wOpq*ofiyEt!*>Wv$ZoC~U|K=3-+C zLbH_5D(&B%h5|>XZW$>CR5>+nv$Q=Nf=AqW8Vq6>0#J?C{H4>Gfh=v8hp*|`Dkpw5F`p3^2tbcU!-m}Sr?^fK^K0xY0UHZAj+p)pmGWyOSf zHo0PF8B$XGP`XXJX2zYsU8O52H#F$uxSs5f5xMa9^C3*QI_=Kc{M5INerKK5E z85mU<8Pph<^;p<6*x0q$xfOXh)wuZ7_&78;7>pUXjd?gtxTMvkWp!mm?Zh;Iz*fV| z%#6W-fx(A?A(DYLo=wnMNXA`;DVd2Oje#$LpP`t6v6zvoh?}Q?*V@lowM<>RM#sg) zB``2BK0cnIfq|iifng>C-#mW)8G=GBLK5>O7?v?GZe(QG#K5qbfpr(F{6cwwT>`q@ zx|V&G_EYT@S1Rf5)zjZ^V6xVf;Q#}}83u;442)+O8P77ZoMT}<$I5e*R9J#qFM(=Y3DVoBol< zq9U(F20jc7dKeV;C@kV}MC9Yhn8z_OPhv9eXBOTqD!EmX@H8R$X>!Wbl&t4jIWKZ@ zU*wj)DlL0eR{pBI`gL{RslLXyjZJTx+TOLbziaP)*fZ(lq$wY#O!+ir>ZhsGK24kb zdG@?7^HzRex$66>HQ(24`nl=<|Np?)90eqWfZ|UUMo>c20qFwe2?maT492Oarf3E) z^OZA{vQyc< zDHR(TSlSV`8??-Md4Or6ic`gjKN<&>k9Q-ae)>LFGCRv+{$2gJm%j zUqkRL9iU|{Fm1w&N_I*IK>ktV7pnkDEpdQJUGA{RKXPZm1aN4IwOAZF>GG_cxI!FXZx243pcf}bMT?Y0jIOFcMrqXgPWdobTXq#y=+nS>iRO_ zU{eyRe^O69Imoftw)s`ZOs8g`T{1dIv0{>NT0k`6L_*{y7q@196Ni*j6XDTf@}RMu z)pP?e@KR1rQne97(gs$;TLttgP)eB>H3 $@.tmp && chmod +x $@.tmp && mv -f $@.tmp $@ diff --git a/src/emc/usr_intf/gscreen/emc_interface.py b/src/emc/usr_intf/gscreen/emc_interface.py new file mode 100644 index 0000000..988081b --- /dev/null +++ b/src/emc/usr_intf/gscreen/emc_interface.py @@ -0,0 +1,660 @@ +# Touchy is Copyright (c) 2009 Chris Radek +# +# Touchy is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Touchy is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +import math + +from __main__ import set_active, set_text + +class emc_control: + def __init__(self, emc, error): + self.emc = emc + self.emcstat = emc.stat() + self.emccommand = emc.command() + self.masked = 0; + self.sb = 0; + self.jog_velocity = 100.0/60.0 + self.mdi = 0 + #self.listing = listing + self.error = error + self.isjogging = [0,0,0,0,0,0,0,0,0] + + def mask(self): + # updating toggle button active states dumbly causes spurious events + self.masked = 1 + + def mdi_active(self, m): + self.mdi = m + + def unmask(self): + self.masked = 0 + + def mist_on(self, b): + if self.masked: return + self.emccommand.mist(1) + + def mist_off(self, b): + if self.masked: return + self.emccommand.mist(0) + + def flood_on(self, b): + if self.masked: return + self.emccommand.flood(1) + + def flood_off(self, b): + if self.masked: return + self.emccommand.flood(0) + + def estop(self, b): + if self.masked: return + self.emccommand.state(self.emc.STATE_ESTOP) + + def estop_reset(self, b): + if self.masked: return + self.emccommand.state(self.emc.STATE_ESTOP_RESET) + + def machine_off(self, b): + if self.masked: return + self.emccommand.state(self.emc.STATE_OFF) + + def machine_on(self, b): + if self.masked: return + self.emccommand.state(self.emc.STATE_ON) + + def home_all(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.home(-1) + + def unhome_all(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.unhome(-1) + + def home_selected(self, axis): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.home(axis) + + def unhome_selected(self, axis): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.unhome(axis) + + def jogging(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + + def override_limits(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.override_limits() + + def spindle_forward(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.spindle(1); + + def spindle_off(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.spindle(0); + + def spindle_reverse(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.spindle(-1); + + def spindle_faster(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.spindle(self.emc.SPINDLE_INCREASE) + + def spindle_slower(self, b): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.spindle(self.emc.SPINDLE_DECREASE) + + def continuous_jog_velocity(self, velocity): + self.jog_velocity = velocity / 60.0 + for i in range(9): + if self.isjogging[i]: + self.emccommand.jog(self.emc.JOG_CONTINUOUS, i, self.isjogging[i] * self.jog_velocity) + + def continuous_jog(self, axis, direction): + if self.masked: return + if direction == 0: + self.isjogging[axis] = 0 + self.emccommand.jog(self.emc.JOG_STOP, axis) + else: + self.isjogging[axis] = direction + self.emccommand.jog(self.emc.JOG_CONTINUOUS, axis, direction * self.jog_velocity) + + def quill_up(self): + if self.masked: return + self.emccommand.mode(self.emc.MODE_MANUAL) + self.emccommand.wait_complete() + self.emccommand.jog(self.emc.JOG_CONTINUOUS, 2, 100) + + def feed_hold(self, data): + if self.masked: return + self.emccommand.set_feed_hold(data) + + def feed_override(self, f): + if self.masked: return + self.emccommand.feedrate(f/100.0) + + def spindle_override(self, s): + if self.masked: return + self.emccommand.spindleoverride(s/100.0) + + def max_velocity(self, m): + if self.masked: return + self.emccommand.maxvel(m/60.0) + + def reload_tooltable(self, b): + if self.masked: return + self.emccommand.load_tool_table() + + def opstop_on(self, b): + if self.masked: return + self.emccommand.set_optional_stop(1) + + def opstop_off(self, b): + if self.masked: return + self.emccommand.set_optional_stop(0) + + def blockdel_on(self, b): + if self.masked: return + self.emccommand.set_block_delete(1) + + def blockdel_off(self, b): + if self.masked: return + self.emccommand.set_block_delete(0) + + def abort(self): + self.emccommand.abort() + set_text(self.error, "") + + def single_block(self, s): + self.sb = s + self.emcstat.poll() + if self.emcstat.queue > 0 or self.emcstat.paused: + # program or mdi is running + if s: + self.emccommand.auto(self.emc.AUTO_PAUSE) + else: + self.emccommand.auto(self.emc.AUTO_RESUME) + + def cycle_start(self): + self.emcstat.poll() + if self.emcstat.paused: + if self.sb: + self.emccommand.auto(self.emc.AUTO_STEP) + else: + self.emccommand.auto(self.emc.AUTO_RESUME) + return + + if self.emcstat.interp_state == self.emc.INTERP_IDLE: + self.emccommand.mode(self.emc.MODE_AUTO) + self.emccommand.wait_complete() + if self.sb: + self.emccommand.auto(self.emc.AUTO_STEP) + #else: + # self.emccommand.auto(self.emc.AUTO_RUN, self.listing.get_startline()) + # self.listing.clear_startline() + +class emc_status: + def __init__(self, data, emc): + self.data = data + self.emc = emc + self.resized_dro = 0 + self.mm = 0 + self.machine_units_mm=0 + self.unit_convert=[1]*9 + self.actual = 1 + self.emcstat = emc.stat() + self.emcerror = emc.error_channel() + + def get_feedrate(self): + return self.emcstat.feedrate + + def get_spindlerate(self): + return self.emcstat.spindlerate + + def get_maxvelocity(self): + return self.emcstat.maxvelocity + + def dro_inch(self, b): + self.mm = self.data.dro_units = 0 + + def dro_mm(self, b): + self.mm = self.data.dro_units = 1 + + def set_machine_units(self,u,c): + self.machine_units_mm = self.data.machine_units = u + self.unit_convert = c + + def convert_units(self,v): + c = self.unit_convert + return map(lambda x,y: x*y, v, c) + + def dro_commanded(self, b): + self.actual = 0 + + def dro_actual(self, b): + self.actual = 1 + + def get_current_tool(self): + self.emcstat.poll() + return self.emcstat.tool_in_spindle + + def get_current_system(self): + self.emcstat.poll() + g = self.emcstat.gcodes + for i in g: + if i >= 540 and i <= 590: + return i/10 - 53 + elif i >= 590 and i <= 593: + return i - 584 + return 1 + + def periodic(self): + self.emcstat.poll() + am = self.emcstat.axis_mask + lathe = not (self.emcstat.axis_mask & 2) + dtg = self.emcstat.dtg + + if self.actual: + p = self.emcstat.actual_position + else: + p = self.emcstat.position + + x = p[0] - self.emcstat.g5x_offset[0] - self.emcstat.tool_offset[0] + y = p[1] - self.emcstat.g5x_offset[1] - self.emcstat.tool_offset[1] + z = p[2] - self.emcstat.g5x_offset[2] - self.emcstat.tool_offset[2] + a = p[3] - self.emcstat.g5x_offset[3] - self.emcstat.tool_offset[3] + b = p[4] - self.emcstat.g5x_offset[4] - self.emcstat.tool_offset[4] + c = p[5] - self.emcstat.g5x_offset[5] - self.emcstat.tool_offset[5] + u = p[6] - self.emcstat.g5x_offset[6] - self.emcstat.tool_offset[6] + v = p[7] - self.emcstat.g5x_offset[7] - self.emcstat.tool_offset[7] + w = p[8] - self.emcstat.g5x_offset[8] - self.emcstat.tool_offset[8] + + if self.emcstat.rotation_xy != 0: + t = math.radians(-self.emcstat.rotation_xy) + xr = x * math.cos(t) - y * math.sin(t) + yr = x * math.sin(t) + y * math.cos(t) + x = xr + y = yr + + x -= self.emcstat.g92_offset[0] + y -= self.emcstat.g92_offset[1] + z -= self.emcstat.g92_offset[2] + a -= self.emcstat.g92_offset[3] + b -= self.emcstat.g92_offset[4] + c -= self.emcstat.g92_offset[5] + u -= self.emcstat.g92_offset[6] + v -= self.emcstat.g92_offset[7] + w -= self.emcstat.g92_offset[8] + + relp = [x, y, z, a, b, c, u, v, w] + + if self.mm != self.machine_units_mm: + p = self.convert_units(p) + relp = self.convert_units(relp) + dtg = self.convert_units(dtg) + for count,letter in enumerate(self.data.axis_list): + if not count == len(self.data.axis_list): + self.data["%s_is_homed"% letter] = self.emcstat.homed[count] + self.data["%s_abs"% letter] = p[count] + self.data["%s_rel"% letter] = relp[count] + self.data["%s_dtg"% letter] = dtg[count] + # active G codes + temp = []; active_codes = [] + for i in sorted(self.emcstat.gcodes[1:]): + if i == -1: continue + if i % 10 == 0: + temp.append("%d" % (i/10)) + else: + temp.append("%d.%d" % (i/10, i%10)) + for i in (temp): + active_codes.append("G"+i) + self.data.active_gcodes = active_codes + temp = []; active_codes = [] + for i in sorted(self.emcstat.mcodes[1:]): + if i == -1: continue + temp.append("%d" % i) + for i in (temp): + active_codes.append("M"+i) + self.data.active_mcodes = active_codes + feed_str = "%.1f" % self.emcstat.settings[1] + if feed_str.endswith(".0"): feed_str = feed_str[:-2] + self.data.active_feed_command = feed_str + self.data.active_spindle_command = "%.0f" % self.emcstat.settings[2] + + # estop status + self.data.estopped = self.emcstat.task_state == self.emc.STATE_ESTOP + # spindle + self.data.spindle_dir = self.emcstat.spindle_direction + self.data.spindle_speed = abs(self.emcstat.spindle_speed) + self.data.spindle_override = self.emcstat.spindlerate + # other + self.data.tool_in_spindle = self.emcstat.tool_in_spindle + self.data.flood = self.emcstat.flood + self.data.mist = self.emcstat.mist + self.data.machine_on = self.emcstat.task_state == self.emc.STATE_ON + self.data.or_limits = self.emcstat.axis[0]['override_limits'] + self.data.feed_hold = self.emcstat.feed_hold_enabled + self.data.feed_override = self.emcstat.feedrate + self.data.max_velocity = self.emcstat.max_velocity + self.data.file = self.emcstat.file + #self.data.file_lines = len(self.listing.program) + self.data.line = self.emcstat.current_line + self.data.id = self.emcstat.id + self.data.dtg = self.emcstat.distance_to_go + self.data.velocity = (self.emcstat.current_vel * 60.0) + self.data.delay = self.emcstat.delay_left + if self.emcstat.pocket_prepped == -1: + self.data.preppedtool = None + else: + self.data.preppedtool = self.emcstat.tool_table[self.emcstat.pocket_prepped].id + + + + + + + +class emc_status2: + def __init__(self, gtk, emc, listing, relative, absolute, distance, + dro_table, + error, + estops, machines, override_limit, status, + floods, mists, spindles, prefs, opstop, blockdel): + self.gtk = gtk + self.emc = emc + self.listing = listing + self.relative = relative + self.absolute = absolute + self.distance = distance + self.dro_table = dro_table + self.error = error + self.estops = estops + self.machines = machines + self.override_limit = override_limit + self.status = status + self.floods = floods + self.mists = mists + self.spindles = spindles + self.prefs = prefs + self.opstop = opstop + self.blockdel = blockdel + self.resized_dro = 0 + + self.mm = 0 + self.machine_units_mm=0 + self.unit_convert=[1]*9 + self.actual = 0 + self.emcstat = emc.stat() + self.emcerror = emc.error_channel() + + def dro_inch(self, b): + self.mm = 0 + + def dro_mm(self, b): + self.mm = 1 + + def set_machine_units(self,u,c): + self.machine_units_mm = self.data.machine_units = u + self.unit_convert = c + + def convert_units(self,v,c): + return map(lambda x,y: x*y, v, c) + + def dro_commanded(self, b): + self.actual = 0 + + def dro_actual(self, b): + self.actual = 1 + + def get_current_tool(self): + self.emcstat.poll() + return self.emcstat.tool_in_spindle + + def get_current_system(self): + self.emcstat.poll() + g = self.emcstat.gcodes + for i in g: + if i >= 540 and i <= 590: + return i/10 - 53 + elif i >= 590 and i <= 593: + return i - 584 + return 1 + + def periodic(self): + self.emcstat.poll() + am = self.emcstat.axis_mask + lathe = not (self.emcstat.axis_mask & 2) + dtg = self.emcstat.dtg + + if not self.resized_dro: + height = 9 + for i in range(9): + if i == 1 and lathe: + continue + if not (am & (1<' + cslabel + '' + ' Offset:'); + + g5x = "" + g92 = "" + for i in range(len(self.emcstat.g5x_offset)): + letter = "XYZABCUVW"[i] + if self.emcstat.g5x_offset[i] != 0: g5x += "%s%.4f " % (letter, self.emcstat.g5x_offset[i]) + if self.emcstat.g92_offset[i] != 0: g92 += "%s%.4f " % (letter, self.emcstat.g92_offset[i]) + + set_text(self.status['g5xoffset'], g5x); + set_text(self.status['g92offset'], g92); + + active_codes = [] + for i in self.emcstat.gcodes[1:]: + if i == -1: continue + if i % 10 == 0: + active_codes.append("G%d" % (i/10)) + else: + active_codes.append("G%d.%d" % (i/10, i%10)) + + for i in self.emcstat.mcodes[1:]: + if i == -1: continue + active_codes.append("M%d" % i) + + feed_str = "F%.1f" % self.emcstat.settings[1] + if feed_str.endswith(".0"): feed_str = feed_str[:-2] + active_codes.append(feed_str) + active_codes.append("S%.0f" % self.emcstat.settings[2]) + + set_text(self.status['activecodes'], " ".join(active_codes)) + + set_active(self.prefs['inch'], self.mm == 0) + set_active(self.prefs['mm'], self.mm == 1) + set_active(self.prefs['actual'], self.actual == 1) + set_active(self.prefs['commanded'], self.actual == 0) + + set_active(self.opstop['on'], self.emcstat.optional_stop) + set_active(self.opstop['off'], not self.emcstat.optional_stop) + + set_active(self.blockdel['on'], self.emcstat.block_delete) + set_active(self.blockdel['off'], not self.emcstat.block_delete) + + + if self.emcstat.id == 0 and (self.emcstat.interp_state == self.emc.INTERP_PAUSED or self.emcstat.exec_state == self.emc.EXEC_WAITING_FOR_DELAY): + self.listing.highlight_line(self.emcstat.current_line) + elif self.emcstat.id == 0: + self.listing.highlight_line(self.emcstat.motion_line) + else: + self.listing.highlight_line(self.emcstat.id or self.emcstat.motion_line) + + e = self.emcerror.poll() + if e: + kind, text = e + set_text(self.error, text) + + diff --git a/src/emc/usr_intf/gscreen/gscreen.glade b/src/emc/usr_intf/gscreen/gscreen.glade new file mode 100644 index 0000000..09acad3 --- /dev/null +++ b/src/emc/usr_intf/gscreen/gscreen.glade @@ -0,0 +1,2229 @@ + + + + + + + 800 + + + + True + 11 + 7 + + + True + True + + + True + 5 + 3 + + + True + 0 + etched-out + + + 300 + True + + + True + 0 + etched-out + + + True + 1 + + + True + 3 + 3 + + + True + 0000.0000 + + + 1 + 2 + + + + + + True + 0000.0000 + + + 1 + 2 + 1 + 2 + + + + + + True + 5 + REL + + + 2 + 3 + + + + + + True + 5 + DTG + + + 2 + 3 + 1 + 2 + + + + + + True + 5 + ABS + + + 2 + 3 + 2 + 3 + + + + + + True + 0 + 0.5 + + + X + True + True + True + + + + + 2 + + + + + True + 1 + 0 + + + True + 0000.0000 + + + + + 2 + 2 + 3 + + + + + + + + + True + True + + + + + 0 + + + + + True + 0 + etched-out + + + True + 1 + + + True + 3 + 3 + + + True + 0000.0000 + + + 1 + 2 + + + + + + True + 0000.0000 + + + 1 + 2 + 1 + 2 + + + + + + True + 5 + REL + + + 2 + 3 + + + + + + True + 5 + DTG + + + 2 + 3 + 1 + 2 + + + + + + True + 5 + ABS + + + 2 + 3 + 2 + 3 + GTK_FILL + + + + + True + 0 + 0.5 + + + Y + True + True + True + + + + + 2 + + + + + True + 1 + 0 + + + True + 0 + 0000.0000 + + + + + 2 + 2 + 3 + + + + + + + + + True + True + + + + + 1 + + + + + True + 0 + etched-out + + + True + 1 + + + True + 3 + 3 + + + True + 0000.0000 + + + 1 + 2 + + + + + + True + 0000.0000 + + + 1 + 2 + 1 + 2 + + + + + + True + 5 + REL + + + 2 + 3 + + + + + + True + 5 + DTG + + + 2 + 3 + 1 + 2 + + + + + + True + 5 + ABS + + + 2 + 3 + 2 + 3 + + + + + + True + 0 + 0.5 + + + Z + True + True + True + + + + + 2 + + + + + True + 1 + 0 + + + True + 0000.0000 + + + + + 2 + 2 + 3 + + + + + + + + + True + True + + + + + 2 + + + + + True + 0 + etched-out + + + True + 1 + + + True + 3 + 3 + + + True + 0000.0000 + + + 1 + 2 + + + + + + True + 0000.0000 + + + 1 + 2 + 1 + 2 + + + + + + True + 5 + REL + + + 2 + 3 + + + + + + True + 5 + DTG + + + 2 + 3 + 1 + 2 + + + + + + True + 5 + ABS + + + 2 + 3 + 2 + 3 + + + + + + True + 0 + 0.5 + + + A + True + True + True + + + + + 2 + + + + + True + 1 + 0 + + + True + 0000.0000 + + + + + 2 + 2 + 3 + + + + + + + + + True + True + + + + + 3 + + + + + True + 0 + etched-out + + + True + 3 + 3 + + + Spindle + True + True + True + + + 2 + GTK_FILL + + + + + True + 0.47999998927116394 + + + 1 + 2 + + + + + + True + + + 1 + 2 + 1 + 2 + + + + + + True + #bebebebebebe + #ffff00000000 + 2000 + #0000ffff0000 + False + #ffffffff0000 + + + 2 + 2 + 3 + + + + + Fwd + True + True + True + + + 2 + 3 + + + + + True + 1 + + + 2 + 3 + 1 + 2 + + + + + Rev + True + True + True + + + 2 + 3 + 2 + 3 + + + + + + + True + True + + + + + 4 + + + + + True + ../gscreen/images/linuxcnc-wizard.gif + + + 5 + + + + + + + True + + + + + 5 + GTK_FILL + GTK_FILL + + + + + True + 0 + none + + + True + + + True + Double click to resize Graphics + False + + + True + False + False + False + + + + + 0 + + + + + True + 0 + 0.5 + + + + + + + + + + False + False + 1 + + + + + + + True + True + automatic + automatic + + + True + False + True + 2 + 2 + True + True + True + True + True + + + + + + + True + G code + + + False + + + + + True + page 2 + + + 1 + + + + + True + page 2 + + + 1 + False + + + + + + + + True + page 3 + + + 2 + False + + + + + 2 + + + + + True + + + True + 0 + etched-out + + + True + + + True + 0 + 0.5 + 12 + + + True + 0 + label + True + + + + + 0 + + + + + True + 0 + 0 + 12 + + + True + label + True + + + + + 1 + + + + + True + 0 + 0 + 12 + + + True + label + True + + + + + 2 + + + + + + + True + <b>G Codes Active</b> + True + + + + + False + 0 + + + + + True + 0.70999997854232788 + 1 + 0.60000002384185791 + 0.5 + 1 + + + True + 4 + 4 + + + True + 0 + FO: 100% + + + GTK_FILL + + + + + True + 0 + SO: 100% + + + 1 + 2 + GTK_FILL + + + + + True + 0 + MV:100% + + + 2 + 3 + GTK_FILL + + + + + True + 2 + 2 + + + True + 0 + Mist + + + GTK_FILL + + + + + True + 0 + Flood + + + 1 + 2 + GTK_FILL + + + + + True + yellow + 1 + + + 1 + 2 + + + + + + True + green + 1 + + + 1 + 2 + 1 + 2 + + + + + + 2 + 3 + 2 + 4 + + + + + True + 0 + Jog: 10 Ipm + + + 3 + 4 + GTK_FILL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + False + 1 + + + + + False + 3 + + + + + + + + + + True + <b>Mode</b> + True + + + + + 1 + 3 + 5 + + + + + + + True + page 1 + + + False + + + + + True + 0 + none + + + True + 3 + + + True + 6 + 2 + + + True + liststore1 + + + + 0 + + + + + 1 + 2 + + + + + + + True + Themes + + + + + + + + + True + True + True + #000000000000 + + + + 1 + 2 + 1 + 2 + + + + + True + Relative +Text Color + + + 1 + 2 + + + + + True + Absolute +Text Color + + + 2 + 3 + + + + + True + True + True + #000000000000 + + + + 1 + 2 + 2 + 3 + + + + + True + True + True + #000000000000 + + + + 1 + 2 + 3 + 4 + + + + + True + DTG Text + Color + + + 3 + 4 + + + + + + + + + + + + + + + + + 1 + 2 + GTK_EXPAND + GTK_EXPAND + + + + + True + 6 + 2 + True + + + Metric + + True + True + True + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + Display +Aux Screen + True + True + True + + + 1 + 2 + 1 + 2 + + + + + + + True + label + + + 1 + 2 + + + + + True + label + + + 2 + 3 + + + + + Diameter + Mode + True + True + True + + + 1 + 2 + 2 + 3 + GTK_FILL + GTK_FILL + + + + + Show +Offsets + True + True + True + + + 1 + 2 + 3 + 4 + GTK_FILL + GTK_FILL + + + + + Show +DTG + True + True + True + + + 1 + 2 + 4 + 5 + GTK_FILL + GTK_FILL + + + + + Gscreen +fullscreen + True + True + True + + + + + + + + + + + + + + gtk-quit + True + True + True + True + + + 3 + 4 + + + + + GTK_EXPAND + GTK_EXPAND + + + + + + + + + + True + <b>Preference stuff</b> + True + + + + + 1 + False + + + + + True + page 2 + + + 1 + False + + + + + True + gtk-dialog-info + 6 + + + 2 + + + + + True + page 3 + + + 2 + False + + + + + 6 + 1 + 9 + + + + + True + 1 + False + + + 5 + GTK_FILL + GTK_FILL + + + + + True + True + + 0.10000000149011612 + adjustment1 + 4 + True + + + 6 + 7 + GTK_FILL + GTK_FILL + + + + + True + 0.50999999046325684 + + + True + + + True + True + True + + + True + True + + + True + Estop + + + 0 + + + + + True + green + 1 + + + False + False + 1 + + + + + + + False + False + 0 + + + + + True + + + True + True + + + Zero + True + True + True + + + 0 + + + + + Set At + True + True + True + + + 1 + + + + + gtk-go-up + True + True + True + True + + + 2 + + + + + gtk-go-down + True + True + True + True + + + 3 + + + + + Feed +Hold + True + True + True + + + 4 + + + + + + + + + + + + + + 0 + + + + + True + + + button + True + True + True + + + 0 + + + + + button + True + True + True + + + 1 + + + + + Change + View + True + True + True + + + 2 + + + + + Full +Graphics + True + True + True + + + 3 + + + + + Edit + True + True + True + + + 4 + + + + + button + True + True + True + + + 5 + + + + + button + True + True + True + + + 6 + + + + + True + True + True + + + True + ../gscreen/images/tool_clear.gif + + + + + 7 + + + + + 1 + + + + + True + + + + + + + + + + + + + + + + + + 2 + + + + + 1 + + + + + Menu +Level + True + True + True + + + False + False + 2 + + + + + + + 6 + 7 + 1 + 9 + GTK_FILL + + + + + gtk-page-setup + True + True + True + Double click to change mode + True + + + 6 + 7 + 9 + 10 + GTK_FILL + GTK_FILL + + + + + True + 0 + etched-out + + + True + G54 + + + + + True + True + + + + + 5 + 6 + GTK_FILL + GTK_FILL + + + + + True + True + + + True + True + + + Ignore +Limits + True + True + True + + + 0 + + + + + togglebutton + True + True + True + + + 1 + + + + + Home All + True + True + True + + + 2 + + + + + Home Axis + True + True + True + + + 3 + + + + + Unhome Axis + True + True + True + + + 4 + + + + + Toggle +Readout + True + True + True + + + 5 + + + + + + + + + + + False + 0 + + + + + True + + + Jog Mode + True + True + True + + + 0 + + + + + Override + True + True + True + + + 1 + + + + + True + True + True + + + True + ../gscreen/images/coolant_mist_plain.gif + + + + + 2 + + + + + True + True + True + + + True + ../gscreen/images/coolant_flood_plain.gif + + + + + 3 + + + + + Reload + Tool + True + True + True + + + 4 + + + + + Toggle +Readout + True + True + True + + + 5 + + + + + + + + + + + 1 + + + + + True + + + togglebutton + True + True + True + + + 0 + + + + + togglebutton + True + True + True + + + 1 + + + + + button + True + True + True + + + 2 + + + + + button + True + True + True + + + 3 + + + + + button + + True + True + True + + + 4 + + + + + button + True + True + True + + + 5 + + + + + + + + + + + 2 + + + + + True + + + True + Load Program + hal_action_open + Open + True + gtk-open + + + 0 + + + + + True + Stop Program + hal_toggleaction_stop + Stop + True + gtk-media-stop + + + 1 + + + + + True + Start program + hal_toggleaction_run + Run + True + gtk-media-play + True + + + + 2 + + + + + True + Pause Program + hal_toggleaction_pause + Pause + True + gtk-media-pause + True + + + 3 + + + + + True + True + True + Save-As + hal_action_saveas + True + image2 + 0.56999999284744263 + bottom + + + 4 + + + + + True + True + True + Save + hal_action_save + True + image3 + bottom + + + 5 + + + + + button + + True + True + True + + + 6 + + + + + Reload + True + True + True + hal_action_reload + + + 7 + + + + + 3 + + + + + 6 + 9 + 10 + GTK_FILL + GTK_FILL + + + + + + + + + + + + + + + + + + + + + + + + + + + + -1000 + 1000 + 1 + 10 + + + + True + gtk-save-as + 3 + + + + + + + + + test + + + test2 + + + + + gtk-media-play + True + + + gtk-stop + + + gtk-open + + + + gtk-media-pause + + + True + gtk-save + 3 + + + + + diff --git a/src/emc/usr_intf/gscreen/gscreen.py b/src/emc/usr_intf/gscreen/gscreen.py new file mode 100755 index 0000000..22ec043 --- /dev/null +++ b/src/emc/usr_intf/gscreen/gscreen.py @@ -0,0 +1,1098 @@ +#!/usr/bin/python2.4 + +# Gscreen a GUI for linuxcnc cnc controller +# Chris Morley copyright 2012 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import pygtk +pygtk.require("2.0") +import gtk +import gtk.glade +import gobject +import hal +import sys,os +from optparse import Option, OptionParser +import gladevcp.makepins +from gladevcp.gladebuilder import GladeBuilder +import pango +import traceback +import atexit + +BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..")) +libdir = os.path.join(BASE, "lib", "python") +datadir = os.path.join(BASE, "share", "linuxcnc") +sys.path.insert(0, libdir) +themedir = "/usr/share/themes" +xmlname = os.path.join(datadir,"gscreen.glade") +xmlname2 = os.path.join(datadir,"gscreen2.glade") +import gettext +LOCALEDIR = os.path.join(BASE, "share", "locale") +gettext.install("linuxcnc", localedir=LOCALEDIR, unicode=True) +gtk.glade.bindtextdomain("linuxcnc", LOCALEDIR) +gtk.glade.textdomain("linuxcnc") + +def set_active(w, s): + if not w: return + os = w.get_active() + if os != s: w.set_active(s) + +def set_label(w, l): + if not w: return + ol = w.get_label() + if ol != l: w.set_label(l) + +def set_text(w, t): + if not w: return + ot = w.get_label() + if ot != t: w.set_label(t) + +import linuxcnc +from gscreen import emc_interface +from gscreen import mdi +from gscreen import preferences + +def excepthook(exc_type, exc_obj, exc_tb): + try: + w = app.widgets.window1 + except KeyboardInterrupt: + sys.exit(0) + except NameError: + w = None + lines = traceback.format_exception(exc_type, exc_obj, exc_tb) + m = gtk.MessageDialog(w, + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, + gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, + ("Gscreen encountered an error. The following " + "information may be useful in troubleshooting:\n\n") + + "".join(lines)) + m.show() + m.run() + m.destroy() +sys.excepthook = excepthook + +# constants +X = 0;Y = 1;Z = 2;A = 3;B = 4;C = 5;U = 6;V = 7;W = 8 +_ABS = 0;_REL = 1;_DTG = 2 +_START = 0;_MAN = 1;_MDI = 2;_AUTO = 3 +_MM = 1;_IMPERIAL = 0 +_SPINDLE_INPUT = 9 + +class Trampoline(object): + def __init__(self,methods): + self.methods = methods + + def __call__(self, *a, **kw): + for m in self.methods: + m(*a, **kw) + +class Widgets: + def __init__(self, xml): + self._xml = xml + def __getattr__(self, attr): + r = self._xml.get_object(attr) + if r is None: raise AttributeError, "No widget %r" % attr + return r + def __getitem__(self, attr): + r = self._xml.get_object(attr) + if r is None: raise IndexError, "No widget %r" % attr + return r + +class Data: + def __init__(self): + self.use_screen2 = False + self.theme_name = "Follow System Theme" + self.abs_textcolor = "" + self.rel_textcolor = "" + self.dtg_textcolor = "" + self.err_textcolor = "" + self.window_geometry = "" + self.window_max = "" + self.axis_list = ("x","y","z","a","s") + self.active_axis_buttons = [(None,None)] + self.abs_color = (0, 65535, 0) + self.rel_color = (65535, 0, 0) + self.dtg_color = (0, 0, 65535) + self.highlight_color = (65535,65535,65535) + self.highlight_major = False + self.display_order = (_REL,_DTG,_ABS) + self.mode_order = (_START,_MAN,_MDI,_AUTO) + self.plot_view = ("P","X","Y","Z","Z2") + self.active_gcodes = [] + self.active_mcodes = [] + self.maxvelocity = 1 + self.x_abs = 0.0 + self.x_rel = 1.0 + self.x_dtg = -2.0 + self.y_abs = 0.0 + self.y_rel = 100.0 + self.y_dtg = 2.0 + self.z_abs = 0.0 + self.z_rel = 1.0 + self.z_dtg = 21.0 + self.a_abs = 0.0 + self.a_rel = 1.0 + self.a_dtg = 2.0 + self.x_is_homed = 0 + self.y_is_homed = 0 + self.z_is_homed = 0 + self.a_is_homed = 0 + self.spindle_request_rpm = 0 + self.spindle_dir = 0 + self.spindle_speed = 0 + self.active_spindle_command = "" # spindle command setting + self.active_feed_command = "" # feed command setting + self.system = 1 + self.estopped = True + self.dro_units = _IMPERIAL + self.machine_units = _IMPERIAL + self.tool_in_spindle = 0 + self.flood = False + self.mist = False + self.machine_on = False + self.or_limits = 0 + self.feed_override = 1.0 + self.spindle_override = 1.0 + self.max_velocity = 1.0 + self.edit_mode = False + self.full_graphics = False + self.file = "" + self.file_lines = 0 + self.line = 0 + self.id = 0 + self.dtg = 0.0 + self.velocity = 0.0 + self.delay = 0.0 + self.preppedtool = None + self.lathe_mode = False + self.diameter_mode = True + + def __getitem__(self, item): + return getattr(self, item) + def __setitem__(self, item, value): + return setattr(self, item, value) + +def load_handlers(usermod,halcomp,builder,useropts): + hdl_func = 'get_handlers' + + def add_handler(method, f): + if method in handlers: + handlers[method].append(f) + else: + handlers[method] = [f] + + handlers = {} + for u in usermod: + (directory,filename) = os.path.split(u) + (basename,extension) = os.path.splitext(filename) + if directory == '': + directory = '.' + if directory not in sys.path: + sys.path.insert(0,directory) + dbg('adding import dir %s' % directory) + + try: + mod = __import__(basename) + except ImportError,msg: + print "module '%s' skipped - import error: %s" %(basename,msg) + continue + dbg("module '%s' imported OK" % mod.__name__) + try: + # look for 'get_handlers' function + h = getattr(mod,hdl_func,None) + + if h and callable(h): + dbg("module '%s' : '%s' function found" % (mod.__name__,hdl_func)) + objlist = h(halcomp,builder,useropts) + else: + # the module has no get_handlers() callable. + # in this case we permit any callable except class Objects in the module to register as handler + dbg("module '%s': no '%s' function - registering only functions as callbacks" % (mod.__name__,hdl_func)) + objlist = [mod] + # extract callback candidates + for object in objlist: + dbg("Registering handlers in module %s object %s" % (mod.__name__, object)) + if isinstance(object, dict): + methods = dict.items() + else: + methods = map(lambda n: (n, getattr(object, n, None)), dir(object)) + for method,f in methods: + if method.startswith('_'): + continue + if callable(f): + dbg("Register callback '%s' in %s" % (method, object)) + add_handler(method, f) + except Exception, e: + print "gladevcp: trouble looking for handlers in '%s': %s" %(basename, e) + traceback.print_exc() + + # Wrap lists in Trampoline, unwrap single functions + for n,v in list(handlers.items()): + if len(v) == 1: + handlers[n] = v[0] + else: + handlers[n] = Trampoline(v) + + return handlers + + +class Gscreen: + + def __init__(self,inipath): + (progdir, progname) = os.path.split(sys.argv[0]) + print progdir,progname + #usage = "usage: %prog [options] myfile.ui" + #parser = OptionParser(usage=usage) + #parser.disable_interspersed_args() + #(opts, args) = parser.parse_args() + #print args + try: + # loading as a gtk.builder project + self.xml = gtk.Builder() + self.xml.add_from_file(xmlname) + except: + print "**** Gscreen GLADE ERROR: With xml file: %s"% xmlname + sys.exit(0) + try: + # loading as a gtk.builder project + self.xml.add_from_file(xmlname2) + self.screen2 = True + except: + print "**** Gscreen GLADE ERROR: With xml file: %s"% xmlname + self.screen2 = False + self.widgets = Widgets(self.xml) + self.data = Data() + + try: + halcomp = hal.component("gscreen") + except: + print "*** Gscreen ERROR: Asking for a HAL component using a name that already exists." + sys.exit(0) + + panel = gladevcp.makepins.GladePanel( halcomp, xmlname, self.xml, None) + halcomp.ready() + # at this point, any glade HL widgets and their pins are set up. + #handlers = load_handlers(None,halcomp,self.xml,None) + + #self.xml.connect_signals(handlers) + + self.xml.connect_signals( self ) + # access to saved prefernces + self.prefs = preferences.preferences() + + #setup default stuff + self.data.invisible_cursor = self.prefs.getpref('invisible_cursor', 'False', bool) + self.data.theme_name = self.prefs.getpref('gtk_theme', 'Follow System Theme', str) + self.data.abs_textcolor = self.prefs.getpref('abs_textcolor', '#0000FFFF0000', str) + self.widgets.abs_colorbutton.set_color(gtk.gdk.color_parse(self.data.abs_textcolor)) + self.set_abs_color() + self.data.rel_textcolor = self.prefs.getpref('rel_textcolor', '#FFFF00000000', str) + self.widgets.rel_colorbutton.set_color(gtk.gdk.color_parse(self.data.rel_textcolor)) + self.set_rel_color() + self.data.dtg_textcolor = self.prefs.getpref('dtg_textcolor', '#00000000FFFF', str) + self.widgets.dtg_colorbutton.set_color(gtk.gdk.color_parse(self.data.dtg_textcolor)) + self.set_dtg_color() + self.data.err_textcolor = self.prefs.getpref('err_textcolor', 'default', str) + self.data.error_font_name = self.prefs.getpref('error_font', 'Sans Bold 10', str) + self.data.window_geometry = self.prefs.getpref('window_geometry', 'default', str) + self.data.window_max = self.prefs.getpref('window_force_max', 'False', bool) + self.data.window2_geometry = self.prefs.getpref('window2_geometry', 'default', str) + self.data.window2_max = self.prefs.getpref('window2_force_max', 'False', bool) + self.data.use_screen2 = self.prefs.getpref('use_screen2', 'True', bool) + self.widgets.use_screen2.set_active(self.data.use_screen2) + self.widgets.fullscreen1.set_active( self.prefs.getpref('fullscreen1', 'True', bool) ) + self.widgets.show_offsets.set_active( self.prefs.getpref('show_offsets', 'True', bool) ) + self.widgets.gremlin.show_offsets = self.widgets.show_offsets.get_active() + self.data.diameter_mode = self.prefs.getpref('diameter_mode', 'True', bool) + self.widgets.diameter_mode.set_active(self.data.diameter_mode) + self.data.dro_units = self.prefs.getpref('units', 'False', bool) + self.widgets.dro_units.set_active(self.data.dro_units) + + w = self.widgets.statusbar1 + #w.set_font_name(self.data.error_font_name) + #self.error_font = pango.FontDescription(self.data.error_font_name) + #w.modify_font(self.error_font) + if not self.data.err_textcolor == "default": + print"change error color",self.data.err_textcolor + w.modify_fg(gtk.STATE_NORMAL,gtk.gdk.color_parse(self.data.err_textcolor)) + self.widgets.statusbar1.push(1,"Status bar text to here?") + self.widgets.data_input.set_value(50.567) + self.widgets.button_mode.set_label("Mode %d"% self.data.mode_order[0]) + + # If there are themes then add them to combo box + if os.path.exists(themedir): + model = self.widgets.theme_choice.get_model() + model.clear() + model.append(("Follow System Theme",)) + temp = 0 + names = os.listdir(themedir) + names.sort() + for search,dirs in enumerate(names): + model.append((dirs,)) + if dirs == self.data.theme_name: + temp = search+1 + self.widgets.theme_choice.set_active(temp) + # get the system wide theme + settings = gtk.settings_get_default() + self.data.system_theme = settings.get_property("gtk-theme-name") + if not self.data.theme_name == "Follow System Theme": + settings.set_string_property("gtk-theme-name", self.data.theme_name, "") + # maximize window or set geometry and optionally maximize + if self.data.window_geometry == "default": + self.widgets.window1.maximize() + else: + self.widgets.window1.parse_geometry(self.data.window_geometry) + if self.data.window_max: + self.widgets.window1.maximize() + if self.prefs.getpref('fullscreen1', 'True', bool): + self.widgets.window1.fullscreen() + # setup signals that can be blocked + cb = "axis_x" + i = "_sighandler_axis_x" + self.data[i] = int(self.widgets[cb].connect("clicked", self.on_axis_x_clicked)) + cb = "axis_y" + i = "_sighandler_axis_y" + self.data[i] = int(self.widgets[cb].connect("clicked", self.on_axis_y_clicked)) + cb = "axis_z" + i = "_sighandler_axis_z" + self.data[i] = int(self.widgets[cb].connect("clicked", self.on_axis_z_clicked)) + cb = "axis_a" + i = "_sighandler_axis_a" + self.data[i] = int(self.widgets[cb].connect("clicked", self.on_axis_a_clicked)) + + cb = "button_menu" + i = "_sighandler_mode_select" + self.data[i] = int(self.widgets[cb].connect("button_press_event", self.on_mode_select_clicked)) + + cb = "button_mode" + i = "_sighandler_mode" + self.data[i] = int(self.widgets[cb].connect("button_press_event", self.on_mode_clicked)) + cb = "gremlin" + i = "_sighandler_gremlin" + self.data[i] = int(self.widgets[cb].connect("button_press_event", self.on_gremlin_clicked)) + cb = "button_estop" + i = "_sighandler_estop" + self.data[i] = int(self.widgets[cb].connect("clicked", self.on_estop_clicked)) + for mode in range(0,4): + for num in range(0,24): + cb = "button_h%d_%d"% (mode,num) + i = "_sighandler_button_h%d_%d"% (mode,num) + try: + self.data[i] = int(self.widgets[cb].connect("clicked", self.on_hbutton_clicked,mode,num)) + except: + break + for mode in range(0,2): + for num in range(0,11): + cb = "button_v%d_%d"% (mode,num) + i = "_sighandler_button_v%d_%d"% (mode,num) + try: + self.data[i] = int(self.widgets[cb].connect("clicked", self.on_vbutton_clicked,mode,num)) + except: + break + self.widgets.button_v0_2.connect("pressed", self.on_button_v0_2_pressed) + self.widgets.button_v0_2.connect("released", self.on_button_v0_2_released) + self.widgets.button_v0_3.connect("pressed", self.on_button_v0_3_pressed) + self.widgets.button_v0_3.connect("released", self.on_button_v0_3_released) + self.widgets.theme_choice.connect("changed", self.on_theme_choice_changed) + self.widgets.use_screen2.connect("clicked", self.on_use_screen2_pressed) + self.widgets.dro_units.connect("clicked", self.on_dro_units_pressed) + self.widgets.diameter_mode.connect("clicked", self.on_diameter_mode_pressed) + self.widgets.show_offsets.connect("clicked", self.on_show_offsets_pressed) + self.widgets.show_dtg.connect("clicked", self.on_show_dtg_pressed) + self.widgets.fullscreen1.connect("clicked", self.on_fullscreen1_pressed) + self.widgets.shut_down.connect("clicked", self.on_window1_destroy) + + # access to EMC control + self.emc = emc_interface.emc_control(linuxcnc, self.widgets.statusbar1) + # access to EMC status + self.status = emc_interface.emc_status( self.data, linuxcnc) + # access to MDI + mdi_labels = mdi_eventboxes = [] + self.mdi_control = mdi.mdi_control(gtk, linuxcnc, mdi_labels, mdi_eventboxes) + # set up EMC stuff + + # check the ini file if UNITS are set to mm" + inifile=self.emc.emc.ini(inipath) + # first check the global settings + units=inifile.find("TRAJ","LINEAR_UNITS") + if units==None: + units=inifile.find("AXIS_0","UNITS") + + if units=="mm" or units=="metric" or units == "1.0": + self.machine_units_mm=1 + conversion=[1.0/25.4]*3+[1]*3+[1.0/25.4]*3 + else: + self.machine_units_mm=0 + conversion=[25.4]*3+[1]*3+[25.4]*3 + self.lathe_mode = bool(inifile.find("DISPLAY", "LATHE")) + self.status.set_machine_units(self.machine_units_mm,conversion) + + if self.prefs.getpref('toolsetting_fixture', 0): + self.g10l11 = 1 + else: + self.g10l11 = 0 + + if self.prefs.getpref('dro_mm', 0): + self.status.dro_mm(0) + else: + self.status.dro_inch(0) + + if self.prefs.getpref('dro_actual', 0): + self.status.dro_actual(0) + else: + self.status.dro_commanded(0) + + if self.prefs.getpref('blockdel', 0): + self.emc.blockdel_on(0) + else: + self.emc.blockdel_off(0) + + if self.prefs.getpref('opstop', 1): + self.emc.opstop_on(0) + else: + self.emc.opstop_off(0) + temp = inifile.find("TRAJ","MAX_LINEAR_VELOCITY") + if temp == None: + temp = inifile.find("TRAJ","MAX_VELOCITY") + if temp == None: + temp = 1.0 + self.data._maxvelocity = float(temp) + print "max velocity",(float(self.data._maxvelocity) ) + # timers for updates + gobject.timeout_add(50, self.periodic_status) + #gobject.timeout_add(100, self.periodic_radiobuttons) + + # and display everything + self.widgets.window1.set_title("Gscreen for linuxcnc") + + if self.screen2: + self.widgets.window2.show() + self.widgets.window2.move(0,0) + if not self.data.use_screen2: + self.widgets.window2.hide() + self.widgets.window1.show() + #self.widgets.window1.move(300,0) + self.update_position() + #self.widgets.gcode_view.set_sensitive(0) + #self.widgets.hal_led1.set_shape(2) + self.widgets.gremlin.set_property('view',self.data.plot_view[0]) + self.widgets.gremlin.set_property('metric_units',(self.data.dro_units == _MM)) + self.mode_changed(self.data.mode_order[0]) + +# *** GLADE callbacks **** + + def on_window1_destroy(self, widget, data=None): + print "kill" + gtk.main_quit() + + def on_axis_x_clicked(self,*args): + def unclick(): + self.widgets.axis_x.handler_block(self.data._sighandler_axis_x) + self.widgets.axis_x.set_active(False) + self.widgets.axis_x.handler_unblock(self.data._sighandler_axis_x) + + if self.widgets.button_v0_1.get_active(): + self.set_axis_checks() + unclick() + elif self.widgets.button_v0_0.get_active(): + self.zero_axis() + unclick() + self.update_active_axis_buttons() + + def on_axis_y_clicked(self,*args): + if self.widgets.button_v0_1.get_active(): + self.on_axis_set_clicked(None) + elif self.widgets.button_v0_1.get_active(): + self.on_axis_zero_clicked(None) + self.update_active_axis_buttons() + + def on_axis_z_clicked(self,*args): + if self.widgets.button_v0_1.get_active(): + self.on_axis_set_clicked(None) + if self.widgets.button_v0_0.get_active(): + self.on_axis_zero_clicked(None) + self.update_active_axis_buttons() + + def on_axis_a_clicked(self,*args): + if self.widgets.button_v0_1.get_active(): + self.on_axis_set_clicked(None) + if self.widgets.button_v0_0.get_active(): + self.on_axis_zero_clicked(None) + self.update_active_axis_buttons() + + def on_axis_s_clicked(self,*args): + if self.widgets.button_v0_1.get_active(): + self.on_axis_set_clicked(None) + if self.widgets.button_v0_0.get_active(): + self.on_axis_zero_clicked(None) + self.update_active_axis_buttons() + + def on_mode_clicked(self,widget,event): + # only change machine modes on click + if event.type == gtk.gdk.BUTTON_PRESS: + a,b,c,d = self.data.mode_order + self.data.mode_order = b,c,d,a + self.widgets.button_mode.set_label("Mode %d"% self.data.mode_order[0]) + self.mode_changed(self.data.mode_order[0]) + + def on_gremlin_clicked(self,widget,event): + # only change machine modes on double click + button1 = event.button == 1 + button2 = event.button == 2 + button3 = event.button == 3 + if button1 and event.type == gtk.gdk._2BUTTON_PRESS: + temp = self.widgets.dro_frame.get_visible() + temp = (temp * -1) +1 + self.widgets.dro_frame.set_visible(temp) + self.widgets.gremlin.set_property('enable_dro',(not temp)) + + def on_hbutton_clicked(self,widget,mode,number): + try: + if mode == 0: + if number == 0: self.toggle_ignore_limits() + elif number == 2: self.home_all() + elif number == 4: self.unhome_all() + elif number == 5: self.dro_toggle() + else: raise nofunnction + if mode == 1: + if number == 0: self.jog_mode() + elif number == 2: self.toggle_mist() + elif number == 3: self.toggle_flood() + elif number == 4: self.reload_tooltable() + elif number == 5: self.dro_toggle() + else: raise nofunnction + if mode == 3: + if number == 6: self.reload_plot() + else: raise nofunnction + else: raise nofunnction + except : + print "hbutton %d_%d clicked but no function"% (mode,number) + + def on_vbutton_clicked(self,widget,mode,number): + #try: + if mode == 0: + if number == 0: + self.zero_axis() + elif number == 1: + self.set_axis_checks() + elif number == 2: + pass + elif number == 3: + pass + elif number == 4: + self.toggle_feed_hold() + else: raise nofunnction + elif mode == 1: + if number == 3: + self.full_graphics() + elif number == 2: + self.toggle_view() + elif number == 4: + self.edit_mode() + elif number == 7: + self.clear_plot() + else: raise nofunnction + else: raise nofunnction + #except : + # print "Vbutton %d_%d clicked but no function"% (mode,number) + + def on_button_v0_2_pressed(self,*args): + self.do_jog(1) + def on_button_v0_2_released(self,*args): + self.do_jog(0) + def on_button_v0_3_pressed(self,*args): + self.do_jog(-1) + def on_button_v0_3_released(self,*args): + self.do_jog(0) + + def on_mode_select_clicked(self,widget,event): + # was it a multiple click? + if event.type == gtk.gdk.BUTTON_PRESS: + maxpage = self.widgets.notebook_mode.get_n_pages() + page = self.widgets.notebook_mode.get_current_page() + nextpage = page + 1 + print "mode select",maxpage,page,nextpage + if nextpage == maxpage:nextpage = 0 + self.widgets.notebook_mode.set_current_page(nextpage) + elif event.type == gtk.gdk._2BUTTON_PRESS: + maxpage = self.widgets.notebook_main.get_n_pages() + page = self.widgets.notebook_main.get_current_page() + nextpage = page + 1 + print "double" + print "mode select",maxpage,page,nextpage + if nextpage == maxpage:nextpage = 0 + self.widgets.notebook_main.set_current_page(nextpage) + + def on_estop_clicked(self,*args): + print "estop",self.data.estopped + if self.data.estopped: + self.emc.estop_reset(1) + self.emc.machine_on(1) + else: + self.emc.estop(1) + self.emc.machine_off(1) + + def on_theme_choice_changed(self,*args): + self.change_theme() + + def on_fullscreen1_pressed(self,*args): + self.toggle_fullscreen1() + + def on_use_screen2_pressed(self,*args): + self.toggle_screen2() + + def on_dro_units_pressed(self,*args): + self.toggle_dro_units() + + def on_diameter_mode_pressed(self, *args): + self.toggle_diameter_mode() + + def on_rel_colorbutton_color_set(self,*args): + self.set_rel_color() + + def on_abs_colorbutton_color_set(self,*args): + self.set_abs_color() + + def on_dtg_colorbutton_color_set(self,*args): + self.set_dtg_color() + + def on_show_offsets_pressed(self, *args): + self.toggle_show_offsets() + + def on_show_dtg_pressed(self, *args): + self.toggle_show_dtg() + +# ****** do stuff ***** + + def toggle_fullscreen1(self): + print "toggle fullscreen" + data = self.widgets.fullscreen1.get_active() + print data + if data: + self.widgets.window1.fullscreen() + else: + self.widgets.window1.unfullscreen() + self.prefs.putpref('fullscreen1', data, bool) + + def toggle_show_offsets(self): + data = self.widgets.show_offsets.get_active() + self.widgets.gremlin.show_offsets = data + self.prefs.putpref('show_offsets', data, bool) + + def toggle_show_dtg(self): + self.widgets.gremlin.set_property('show_dtg',self.widgets.show_dtg.get_active()) + + def toggle_diameter_mode(self): + print "toggle diameter mode" + self.data.diameter_mode = self.widgets.diameter_mode.get_active() + + def convert_to_rgb(self,spec): + color = spec.to_string() + temp = color.strip("#") + r = temp[0:4] + g = temp[4:8] + b = temp[8:] + return (int(r,16),int(g,16),int(b,16)) + + def set_rel_color(self): + print self.widgets.rel_colorbutton.get_color() + self.data.rel_color = self.convert_to_rgb(self.widgets.rel_colorbutton.get_color()) + self.prefs.putpref('rel_textcolor', self.widgets.rel_colorbutton.get_color(),str) + + def set_abs_color(self): + print self.widgets.abs_colorbutton.get_color() + self.data.abs_color = self.convert_to_rgb(self.widgets.abs_colorbutton.get_color()) + self.prefs.putpref('abs_textcolor', self.widgets.abs_colorbutton.get_color(),str) + + def set_dtg_color(self): + print self.widgets.dtg_colorbutton.get_color() + self.data.dtg_color = self.convert_to_rgb(self.widgets.dtg_colorbutton.get_color()) + self.prefs.putpref('dtg_textcolor', self.widgets.dtg_colorbutton.get_color(),str) + + def toggle_view(self): + print "toggle plot view" + a = self.data.plot_view[0] + b = self.data.plot_view[1] + c = self.data.plot_view[2] + d = self.data.plot_view[3] + e = self.data.plot_view[4] + self.data.plot_view = (b,c,d,e,a) + self.widgets.gremlin.set_property('view',self.data.plot_view[0]) + + def full_graphics(self): + print "graphics mode" + if self.data.full_graphics: + print "shrink" + self.data.full_graphics = False + self.widgets.notebook_mode.show() + else: + print "enlarge" + self.data.full_graphics = True + self.widgets.notebook_mode.hide() + + def edit_mode(self): + print "edit mode pressed" + if self.data.edit_mode: + self.widgets.gcode_view.set_sensitive(0) + self.data.edit_mode = False + self.widgets.eventbox_gremlin.show() + self.widgets.hbuttonbox.set_sensitive(True) + self.widgets.button_mode.set_sensitive(True) + else: + self.widgets.gcode_view.set_sensitive(1) + self.data.edit_mode = True + self.widgets.eventbox_gremlin.hide() + self.widgets.hbuttonbox.set_sensitive(False) + self.widgets.button_mode.set_sensitive(False) + + def toggle_dro_units(self): + print "toggle dro units",self.data.dro_units + if self.data.dro_units == _MM: + print "switch to imperial" + self.status.dro_inch(1) + self.widgets.gremlin.set_property('metric_units',False) + else: + print "switch to mm" + self.status.dro_mm(1) + self.widgets.gremlin.set_property('metric_units',True) + self.data.dro_units = self.widgets.dro_units.get_active() + + def save_edit(self): + print "edit" + + def update_active_axis_buttons(self): + count = 0;temp = [] + self.data.active_axis_buttons = [] + for num,i in enumerate(self.data.axis_list): + if self.widgets["axis_%s"%i].get_active(): + count +=1 + axisnum = num + self.data.active_axis_buttons.append((i,num)) + if count == 0: self.data.active_axis_buttons.append((None,None)) + + def jog_mode(self): + # if muliple axis selected - unselect all of them + if len(self.data.active_axis_buttons) > 1 and self.widgets.button_h1_0.get_active(): + for i in self.data.axis_list: + self.widgets["axis_%s"%i].set_active(False) + + def do_jog(self,direction): + # if manual mode, if jogging + # if only one axis button pressed + # jog positive at selected rate + if self.data.mode_order[0] == 1: + if len(self.data.active_axis_buttons) > 1: + self.widgets.statusbar1.push(2,"Can't jog multiple axis") + print self.data.active_axis_buttons + elif self.data.active_axis_buttons[0][0] == None: + self.widgets.statusbar1.push(1,"No axis selected to jog") + else: + print "Jog axis %s" % self.data.active_axis_buttons[0][0] + if not self.data.active_axis_buttons[0][0] == "s": + self.emc.jogging(1) + self.emc.continuous_jog_velocity(20) # TODO make selectable + self.emc.continuous_jog(self.data.active_axis_buttons[0][1],direction) + + def do_jog_to_position(self): + if len(self.data.active_axis_buttons) > 1: + self.widgets.statusbar1.push(2,"Can't jog multiple axis") + print self.data.active_axis_buttons + elif self.data.active_axis_buttons[0][0] == None: + self.widgets.statusbar1.push(1,"No axis selected to jog") + else: + print "Jog axis %s" % self.data.active_axis_buttons[0][0] + if not self.data.active_axis_buttons[0][0] == "s": + self.mdi_control.go_to_position(self.data.active_axis_buttons[0][0],self.get_qualified_input(),20) #TODO config jog rate + + def toggle_screen2(self): + self.data.use_screen2 = self.widgets.use_screen2.get_active() + if self.screen2: + if self.data.use_screen2: + self.widgets.window2.show() + else: + self.widgets.window2.hide() + self.prefs.putpref('use_screen2', self.data.use_screen2, bool) + + def get_qualified_input(self,switch = None): + raw = self.widgets.data_input.get_value() + if switch == _SPINDLE_INPUT: + return raw + else: + if self.data.dro_units != self.data.machine_units: + print "conversion needed" + if self.data.dro_units == _MM: + raw = raw / 25.4 + else: + raw = raw * 25.4 + print "converted to:",raw + else: + print "no conversion" + if switch == "x" and self.data.diameter_mode: + print "convert from diameter" + raw = raw / 2.0 + return raw + + def unhome_all(self): + self.emc.unhome_all(1) + + def home_all(self): + self.emc.home_all(1) + + def unhome_selected(self,axis): + if len(self.data.active_axis_buttons) > 1: + self.widgets.statusbar1.push(2,"Can't unhome multiple axis") + print self.data.active_axis_buttons + elif self.data.active_axis_buttons[0][0] == None: + self.widgets.statusbar1.push(1,"No axis selected to unhome") + else: + print "unhome axis %s" % self.data.active_axis_buttons[0][0] + + def zero_axis(self): + # cancel set mode + if self.widgets.button_v0_1.get_active(): + self.widgets.button_v0_1.set_active(False) + # if an axis is selected then set it + keep = True + for i in self.data.axis_list: + if self.widgets["axis_%s"%i].get_active(): + keep = False + if i == "s": + self.emc.spindle_off(1) + else: + print "zero %s axis" %i + self.mdi_control.set_axis(i,0) + self.reload_plot() + if keep == False: + self.widgets.button_v0_0.handler_block(self.data._sighandler_button_v0_0) + self.widgets.button_v0_0.set_active(keep) + self.widgets.button_v0_0.handler_unblock(self.data._sighandler_button_v0_0) + + def set_axis_checks(self): + # cancel zero mode + if self.widgets.button_v0_0.get_active(): + self.widgets.button_v0_0.set_active(False) + if self.data.mode_order[0] in (_START,_MAN): + # if in jog mode + if self.widgets.button_h1_0.get_active(): + "print jog to position" + # unpress toggle buttonn + self.widgets.button_v0_1.handler_block(self.data._sighandler_button_v0_1) + self.widgets.button_v0_1.set_active(False) + self.widgets.button_v0_1.handler_unblock(self.data._sighandler_button_v0_1) + self.do_jog_to_position() + else: + # if an axis is selected then set it + keep = True + for i in self.data.axis_list: + if self.widgets["axis_%s"%i].get_active(): + keep = False + print "set %s axis" %i + if i == "s": + if self.widgets.s_display_fwd.get_active(): + self.emc.spindle_forward(1) + elif self.widgets.s_display_rev.get_active(): + self.emc.spindle_reverse(1) + else: continue + self.mdi_control.set_spindle_speed(self.get_qualified_input(_SPINDLE_INPUT)) + else: + self.mdi_control.set_axis(i,self.get_qualified_input(i)) + self.reload_plot() + if keep == False: + self.widgets.button_v0_1.handler_block(self.data._sighandler_button_v0_1) + self.widgets.button_v0_1.set_active(keep) + self.widgets.button_v0_1.handler_unblock(self.data._sighandler_button_v0_1) + + def clear_plot(self): + self.widgets.gremlin.clear_live_plotter() + + def reload_plot(self): + print "reload plot" + self.widgets.button_h3_7.emit("clicked") + + def toggle_mist(self): + if self.data.mist: + self.emc.mist_off(1) + else: + self.emc.mist_on(1) + + def toggle_flood(self): + if self.data.flood: + self.emc.flood_off(1) + else: + self.emc.flood_on(1) + + def toggle_feed_hold(self): + print "toggle feed hold",self.data.feed_hold + if self.data.feed_hold: + self.emc.feed_hold(0) + else: + self.emc.feed_hold(1) + + def toggle_ignore_limits(self): + print "over ride limits" + self.emc.override_limits(1) + + def reload_tooltable(self): + self.emc.reload_tooltable(1) + + def dro_toggle(self): + print "toggle axis display" + a = self.data.display_order[0] + b = self.data.display_order[1] + c = self.data.display_order[2] + self.data.display_order = (c,a,b) + if self.data.display_order[2] == _ABS: + self.widgets.gremlin.set_property('use_relative',False) + else: + self.widgets.gremlin.set_property('use_relative',True) + self.update_position() + + def mode_changed(self,mode): + for i in range(0,4): + if i == mode: + self.widgets["mode%d"% i].show() + else: + self.widgets["mode%d"% i].hide() + if mode == _AUTO: + self.widgets.vmode0.hide() + self.widgets.vmode1.show() + if self.data.full_graphics: + self.widgets.notebook_mode.hide() + else: + self.widgets.notebook_mode.show() + self.widgets.hal_mdihistory.hide() + elif mode == _MDI: + self.widgets.hal_mdihistory.show() + self.widgets.vmode0.show() + self.widgets.vmode1.hide() + self.widgets.notebook_mode.hide() + else: + self.widgets.vmode0.show() + self.widgets.vmode1.hide() + self.widgets.notebook_mode.hide() + self.widgets.hal_mdihistory.hide() + + def change_theme(self): + theme = self.widgets.theme_choice.get_active_text() + self.prefs.putpref('gtk_theme', theme, str) + if theme == "Follow System Theme": + theme = self.data.system_theme + settings = gtk.settings_get_default() + settings.set_string_property("gtk-theme-name", theme, "") + + def periodic_status(self): + self.emc.mask() + self.emcstat = linuxcnc.stat() + self.emcerror = linuxcnc.error_channel() + self.emcstat.poll() + #self.radiobutton_mask = 1 + self.status.periodic() + self.data.system = self.status.get_current_system() + #print self.status.data.x_abs + #self.radiobutton_mask = 0 + e = self.emcerror.poll() + if e: + kind, text = e + self.widgets.statusbar1.push(1,text) + self.emc.unmask() + #self.hal.periodic(self.tab == 1) # MDI tab? + self.update_position() + return True + + def update_position(self,*args): + # DRO + for i in ("x","y","z","a","s"): + if i == "s": + self.widgets.s_display.set_value(abs(self.data.spindle_speed)) + self.widgets.s_display2.set_value(abs(self.data.spindle_speed)) + else: + + for j in range (0,3): + current = self.data.display_order[j] + attr = pango.AttrList() + if current == _ABS: + color = self.data.abs_color + data = self.data["%s_abs"%i] + #text = "%+ 10.4f"% self.data["%s_abs"%i] + label = "ABS" + elif current == _REL: + color = self.data.rel_color + data = self.data["%s_rel"%i] + #text = "%+ 10.4f"% self.data["%s_rel"%i] + label= "REL" + elif current == _DTG: + color = self.data.dtg_color + data = self.data["%s_dtg"%i] + #text = "%+ 10.4f"% self.data["%s_dtg"%i] + label = "DTG" + if j == 2: + if self.data.highlight_major: + hlcolor = self.data.highlight_color + bg_color = pango.AttrBackground(hlcolor[0],hlcolor[1],hlcolor[2], 0, -1) + attr.insert(bg_color) + size = pango.AttrSize(30000, 0, -1) + attr.insert(size) + weight = pango.AttrWeight(600, 0, -1) + attr.insert(weight) + + fg_color = pango.AttrForeground(color[0],color[1],color[2], 0, 11) + attr.insert(fg_color) + self.widgets["%s_display_%d"%(i,j)].set_attributes(attr) + h = " " + if current == _ABS and self.data["%s_is_homed"% i]: h = "*" + if self.data.diameter_mode and i == 'x': data = data * 2.0 + if self.data.dro_units == _MM: + text = "%s% 10.3f"% (h,data) + else: + text = "%s% 9.4f"% (h,data) + self.widgets["%s_display_%d"%(i,j)].set_text(text) + self.widgets["%s_display_%d"%(i,j)].set_alignment(0,.5) + self.widgets["%s_display_%d_label"%(i,j)].set_alignment(1,.5) + self.widgets["%s_display_%d_label"%(i,j)].set_text(label) + + # corodinate system: + systemlabel = ("Machine","G54","G55","G56","G57","G58","G59","G59.1","G59.2","G59.3") + # active codes + active_g = " ".join(self.data.active_gcodes) + self.widgets.active_gcodes_label.set_label("%s "% active_g) + self.widgets.active_mcodes_label.set_label(" ".join(self.data.active_mcodes)) + self.widgets.active_feed_speed_label.set_label("F%s S%s"% (self.data.active_feed_command,self.data.active_spindle_command)) + #tool = str(self.data.preppedtool) + tool = str(self.data.tool_in_spindle) + if tool == None: tool = "None" + self.widgets.system.set_text("Tool %s %s"%(tool,systemlabel[self.data.system])) + # coolant + self.widgets.led_mist.set_active(self.data.mist) + self.widgets.led_flood.set_active(self.data.flood) + # estop + self.widgets.led_estop.set_active(not self.data.estopped) + # overrides + self.widgets.fo.set_text("FO: %d%%"%(self.data.feed_override*100)) + self.widgets.so.set_text("SO: %d%%"%(self.data.spindle_override*100)) + self.widgets.mv.set_text("VO: %d%%"%( int(self.data.max_velocity/self.data._maxvelocity *100)) ) + #print self.data.max_velocity,self.data._maxvelocity + # Mode / view + modenames = ("Startup","Manual","MDI","Auto") + self.widgets.mode_label.set_label( "%s Mode View -%s"% (modenames[self.data.mode_order[0]],self.data.plot_view[0]) ) + +if __name__ == "__main__": + try: + print "ini", sys.argv[2] + app = Gscreen(sys.argv[2]) + gtk.main() + except KeyboardInterrupt: + print "linuxcnc closed down" + sys.exit(0) + diff --git a/src/emc/usr_intf/gscreen/gscreen2.glade b/src/emc/usr_intf/gscreen/gscreen2.glade new file mode 100644 index 0000000..28368ed --- /dev/null +++ b/src/emc/usr_intf/gscreen/gscreen2.glade @@ -0,0 +1,79 @@ + + + + + + + 600 + + + True + 3 + 3 + + + 200 + 200 + True + 2000 + #0000ffff0000 + #ffffffff0000 + 200 + #ffffffffffff + Spindle + #ffff00000000 + RPM + + + 2 + 3 + + + + + True + screen 2 + + + 2 + 3 + 1 + 2 + + + + + + + + + + + + + + + + + + + + + + + 300 + 301 + True + False + + + 2 + 3 + 2 + 3 + + + + + + diff --git a/src/emc/usr_intf/gscreen/mdi.py b/src/emc/usr_intf/gscreen/mdi.py new file mode 100644 index 0000000..07a6de5 --- /dev/null +++ b/src/emc/usr_intf/gscreen/mdi.py @@ -0,0 +1,329 @@ +# Touchy is Copyright (c) 2009 Chris Radek +# +# Touchy is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Touchy is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + + +# self.mcodes = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 30, 48, 49, 50, 51, +# 52, 53, 60, 61, 62, 63, 64, 65, 66, 67, 68) +# +# self.gcodes = (0, 10, 20, 30, 40, 50, 51, 52, 53, 70, 80, 100, +# 170, 171, 180, 181, 190, 191, 200, 210, 280, 281, +# 300, 301, 330, 331, 382, 383, 384, 385, 400, 410, +# 411, 420, 421, 430, 431, 490, 530, 540, 550, 560, +# 570, 580, 590, 591, 592, 593, 610, 611, 640, 730, +# 760, 800, 810, 820, 830, 840, 850, 860, 870, 880, +# 890, 900, 901, 910, 911, 920, 921, 922, 923, 930, +# 940, 950, 960, 970, 980, 990) + +class mdi: + def __init__(self, emc): + self.clear() + self.emc = emc + self.emcstat = emc.stat() + self.emccommand = emc.command() + + self.emcstat.poll() + am = self.emcstat.axis_mask + + self.axes = [] + self.polar = 0 + axisnames = ['X', 'Y', 'Z', 'A', 'B', 'C', 'U', 'V', 'W'] + for i in range(9): + if am & (1<= 100 and int(gcode[1:]) <= 199: + return ['P', 'Q'] + if not self.codes.has_key(gcode): + return [] + # strip description + words = self.codes[gcode][1:] + # replace A with the real axis names + if 'A' in words: + i = words.index('A') + words = words[:i] + self.axes + words[i+1:] + if self.polar and 'X' in self.axes and 'Y' in self.axes: + words[self.axes.index('X')] = '@' + words[self.axes.index('Y')] = '^' + return words + + def clear(self): + self.words = {} + + def set_word(self, word, value): + self.words[word] = value + + def set_polar(self, p): + self.polar = p; + + def issue(self): + m = self.gcode + if m.lower().startswith('o'): + codes = self.codes[m] + for code in self.codes[m][1:]: + v = self.words[code] or "0" + m = m + " [%s]" % v + else: + w = [i for i in self.words if len(self.words.get(i)) > 0] + if '@' in w: + m += '@' + self.words.get('@') + w.remove('@') + if '^' in w: + m += '^' + self.words.get('^') + w.remove('^') + for i in w: + if len(self.words.get(i)) > 0: + m += i + self.words.get(i) + self.emcstat.poll() + if self.emcstat.task_mode != self.emc.MODE_MDI: + self.emccommand.mode(self.emc.MODE_MDI) + self.emccommand.wait_complete() + self.emccommand.mdi(m) + + def set_axis_origin(self,axis,value): + m = "G10 L20 P0 %s%f"%(axis,value) + self.emcstat.poll() + if self.emcstat.task_mode != self.emc.MODE_MDI: + self.emccommand.mode(self.emc.MODE_MDI) + self.emccommand.wait_complete() + self.emccommand.mdi(m) + + def go_to_position(self,axis,position,feedrate): + m = "G1 %s %f F%f"%(axis,position,feedrate) + self.emcstat.poll() + if self.emcstat.task_mode != self.emc.MODE_MDI: + self.emccommand.mode(self.emc.MODE_MDI) + self.emccommand.wait_complete() + self.emccommand.mdi(m) + + def set_spindle_speed(self,value): + m = "s %f"%(value) + self.emcstat.poll() + if self.emcstat.task_mode != self.emc.MODE_MDI: + self.emccommand.mode(self.emc.MODE_MDI) + self.emccommand.wait_complete() + self.emccommand.mdi(m) + +class mdi_control: + def __init__(self, gtk, emc, labels, eventboxes): + self.labels = labels + self.eventboxes = eventboxes + self.numlabels = len(labels) + self.numwords = 1 + self.selected = 0 + self.gtk = gtk + + self.mdi = mdi(emc) + + #for i in range(self.numlabels): + # self.not_editing(i) + #self.editing(self.selected) + #self.set_text("G") + def set_axis(self,axis,value): + self.mdi.set_axis_origin(axis,value) + + def set_spindle_speed(self,value): + self.mdi.set_spindle_speed(value) + + def go_to_position(self,axis,position,feedrate): + self.mdi.go_to_position(axis,position,feedrate) + + def not_editing(self, n): + e = self.eventboxes[n] + e.modify_bg(self.gtk.STATE_NORMAL, self.gtk.gdk.color_parse("#ccc")) + + def editing(self, n): + self.not_editing(self.selected) + self.selected = n + e = self.eventboxes[n] + e.modify_bg(self.gtk.STATE_NORMAL, self.gtk.gdk.color_parse("#fff")) + + def get_text(self): + w = self.labels[self.selected] + return w.get_text() + + def set_text(self, t, n = -1): + if n == -1: n = self.selected + w = self.labels[n] + w.set_text(t) + if n > 0: + head = t.rstrip("0123456789.-") + tail = t[len(head):] + self.mdi.set_word(head, tail) + if len(t) < 2: + w.set_alignment(1.0, 0.5) + else: + w.set_alignment(0.0, 0.5) + + def clear(self, b): + t = self.get_text() + self.set_text(t.rstrip("0123456789.-")) + + def back(self, b): + t = self.get_text() + if t[-1:] in "0123456789.-": + self.set_text(t[:-1]) + + def fill_out(self): + if self.selected == 0: + w = self.mdi.get_words(self.get_text()) + self.numwords = len(w) + for i in range(1,self.numlabels): + if i <= len(w): + self.set_text(w[i-1], i) + else: + self.set_text("", i) + + def next(self, b): + self.fill_out(); + if self.numwords > 0: + self.editing(max(1,(self.selected+1) % (self.numwords+1))) + + def ok(self, b): + self.fill_out(); + self.mdi.issue() + + def decimal(self, b): + t = self.get_text() + if t.find(".") == -1: + self.set_text(t + ".") + + def minus(self, b): + t = self.get_text() + if self.selected > 0: + head = t.rstrip("0123456789.-") + tail = t[len(head):] + if tail.find("-") == -1: + self.set_text(head + "-" + tail) + else: + self.set_text(head + tail[1:]) + + def keypad(self, b): + t = self.get_text() + num = b.get_name() + self.set_text(t + num) + + def gp(self, b): + self.g(b, "G", 1) + + def g(self, b, code="G", polar=0): + self.mdi.set_polar(polar) + self.set_text(code, 0) + for i in range(1, self.numlabels): + self.set_text("", i) + self.editing(0) + self.mdi.clear() + + def m(self, b): + self.g(b, "M") + + def t(self, b): + self.g(b, "T") + + def o(self, b): + old_code = self.labels[0].get_text() + ocodes = self.mdi.ocodes + if old_code in ocodes: + j = (ocodes.index(old_code) + 1) % len(ocodes) + else: + j = 0 + self.g(b, ocodes[j]) + self.next(b) + + def select(self, eventbox, event): + n = int(eventbox.get_name()[12:]) + if self.selected == 0: + self.fill_out() + if n <= self.numwords: + self.editing(n) + + def set_tool(self, tool, g10l11): + self.g(0) + self.set_text("G10", 0) + self.next(0) + if g10l11: + self.set_text("L11", 1) + else: + self.set_text("L10", 1) + self.next(0) + self.set_text("P%d" % tool, 2) + self.next(0) + self.next(0) + self.next(0) + + def set_origin(self, system): + self.g(0) + self.set_text("G10", 0) + self.next(0) + self.set_text("L20", 1) + self.next(0) + self.set_text("P%d" % system, 2) + self.next(0) diff --git a/src/emc/usr_intf/gscreen/preferences.py b/src/emc/usr_intf/gscreen/preferences.py new file mode 100644 index 0000000..7085db4 --- /dev/null +++ b/src/emc/usr_intf/gscreen/preferences.py @@ -0,0 +1,45 @@ +# Touchy is Copyright (c) 2009 Chris Radek +# +# Touchy is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Touchy is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + + +import os, ConfigParser + +cp = ConfigParser.ConfigParser +class preferences(cp): + types = { + bool: cp.getboolean, + float: cp.getfloat, + int: cp.getint, + str: cp.get, + repr: lambda self,section,option: eval(cp.get(self,section,option)), + } + + def __init__(self): + cp.__init__(self) + self.fn = os.path.expanduser("~/.gscreen_preferences") + self.read(self.fn) + + def getpref(self, option, default=False, type=bool): + m = self.types.get(type) + try: + o = m(self, "DEFAULT", option) + except Exception, detail: + print detail + self.set("DEFAULT", option, default) + self.write(open(self.fn, "w")) + o = default + return o + + def putpref(self, option, value, type=bool): + self.set("DEFAULT", option, type(value)) + self.write(open(self.fn, "w")) -- 1.7.0.4 From dcba70e2ae40f478174154c4f0e36c5e9380f344 Mon Sep 17 00:00:00 2001 From: cmorley Date: Wed, 15 Feb 2012 22:49:40 -0800 Subject: [PATCH 3/6] gscreen -fix preference file errors If the preference file was empty gscreen would error. This was because the default return values were returned as (I think) strings instead of bool, int or floats Signed-off-by: cmorley --- src/emc/usr_intf/gscreen/preferences.py | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/src/emc/usr_intf/gscreen/preferences.py b/src/emc/usr_intf/gscreen/preferences.py index 7085db4..75fbb52 100644 --- a/src/emc/usr_intf/gscreen/preferences.py +++ b/src/emc/usr_intf/gscreen/preferences.py @@ -37,7 +37,10 @@ class preferences(cp): print detail self.set("DEFAULT", option, default) self.write(open(self.fn, "w")) - o = default + if type in(bool,float,int): + o = type(default) + else: + o = default return o def putpref(self, option, value, type=bool): -- 1.7.0.4 From 0736118a551a74d9063ef96451c1e998a185165d Mon Sep 17 00:00:00 2001 From: cmorley Date: Wed, 15 Feb 2012 22:53:16 -0800 Subject: [PATCH 4/6] gscreen -add hal pin to jogging mode button Signed-off-by: cmorley --- src/emc/usr_intf/gscreen/gscreen.glade | 40 ++++++++++++++++--------------- 1 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/emc/usr_intf/gscreen/gscreen.glade b/src/emc/usr_intf/gscreen/gscreen.glade index 09acad3..aa10926 100644 --- a/src/emc/usr_intf/gscreen/gscreen.glade +++ b/src/emc/usr_intf/gscreen/gscreen.glade @@ -15,6 +15,7 @@ True True + False True @@ -419,7 +420,6 @@ - True 0 etched-out @@ -594,12 +594,12 @@ True + #ffffffff0000 #bebebebebebe #ffff00000000 2000 - #0000ffff0000 False - #ffffffff0000 + #0000ffff0000 2 @@ -954,8 +954,8 @@ True - yellow 1 + yellow 1 @@ -966,8 +966,8 @@ True - green 1 + green 1 @@ -1331,15 +1331,6 @@ fullscreen - - - - - - - - - gtk-quit True @@ -1352,6 +1343,15 @@ fullscreen 4 + + + + + + + + + GTK_EXPAND @@ -1470,8 +1470,8 @@ fullscreen True - green 1 + green False @@ -1705,6 +1705,7 @@ Level True True True + Double click for preferences False @@ -1858,8 +1859,9 @@ Readout True - - Jog Mode + + Jogging + Mode True True True @@ -2091,8 +2093,8 @@ Readout True True Save-As - hal_action_saveas True + hal_action_saveas image2 0.56999999284744263 bottom @@ -2107,8 +2109,8 @@ Readout True True Save - hal_action_save True + hal_action_save image3 bottom -- 1.7.0.4 From 53fa25046089db91aad97a8179c77c2fc8f3c974 Mon Sep 17 00:00:00 2001 From: cmorley Date: Wed, 15 Feb 2012 22:54:10 -0800 Subject: [PATCH 5/6] gscreen -fix view changes for lathes, remember DRO display option lathes can only be shown in P and Y views. gscreen will remember What DRO view is shown in large size. Signed-off-by: cmorley --- src/emc/usr_intf/gscreen/gscreen.py | 26 +++++++++++++++++--------- 1 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/emc/usr_intf/gscreen/gscreen.py b/src/emc/usr_intf/gscreen/gscreen.py index 22ec043..1d3d7d6 100755 --- a/src/emc/usr_intf/gscreen/gscreen.py +++ b/src/emc/usr_intf/gscreen/gscreen.py @@ -319,6 +319,7 @@ class Gscreen: self.widgets.diameter_mode.set_active(self.data.diameter_mode) self.data.dro_units = self.prefs.getpref('units', 'False', bool) self.widgets.dro_units.set_active(self.data.dro_units) + self.data.display_order = self.prefs.getpref('display_order', (0,1,2), repr) w = self.widgets.statusbar1 #w.set_font_name(self.data.error_font_name) @@ -436,7 +437,7 @@ class Gscreen: else: self.machine_units_mm=0 conversion=[25.4]*3+[1]*3+[25.4]*3 - self.lathe_mode = bool(inifile.find("DISPLAY", "LATHE")) + self.data.lathe_mode = bool(inifile.find("DISPLAY", "LATHE")) self.status.set_machine_units(self.machine_units_mm,conversion) if self.prefs.getpref('toolsetting_fixture', 0): @@ -489,6 +490,7 @@ class Gscreen: #self.widgets.hal_led1.set_shape(2) self.widgets.gremlin.set_property('view',self.data.plot_view[0]) self.widgets.gremlin.set_property('metric_units',(self.data.dro_units == _MM)) + # set to 'start mode' self.mode_changed(self.data.mode_order[0]) # *** GLADE callbacks **** @@ -722,13 +724,17 @@ class Gscreen: self.prefs.putpref('dtg_textcolor', self.widgets.dtg_colorbutton.get_color(),str) def toggle_view(self): - print "toggle plot view" - a = self.data.plot_view[0] - b = self.data.plot_view[1] - c = self.data.plot_view[2] - d = self.data.plot_view[3] - e = self.data.plot_view[4] - self.data.plot_view = (b,c,d,e,a) + def shift(): + a = self.data.plot_view[0] + b = self.data.plot_view[1] + c = self.data.plot_view[2] + d = self.data.plot_view[3] + e = self.data.plot_view[4] + self.data.plot_view = (b,c,d,e,a) + shift() + if self.data.lathe_mode: + while not self.data.plot_view[0] in("P","Y","p","y"): + shift() self.widgets.gremlin.set_property('view',self.data.plot_view[0]) def full_graphics(self): @@ -953,6 +959,7 @@ class Gscreen: b = self.data.display_order[1] c = self.data.display_order[2] self.data.display_order = (c,a,b) + self.prefs.putpref('display_order', self.data.display_order, tuple) if self.data.display_order[2] == _ABS: self.widgets.gremlin.set_property('use_relative',False) else: @@ -965,6 +972,8 @@ class Gscreen: self.widgets["mode%d"% i].show() else: self.widgets["mode%d"% i].hide() + if not mode == _START or not mode == _MAN: + self.widgets.button_h1_0.set_active(False) if mode == _AUTO: self.widgets.vmode0.hide() self.widgets.vmode1.show() @@ -1046,7 +1055,6 @@ class Gscreen: attr.insert(size) weight = pango.AttrWeight(600, 0, -1) attr.insert(weight) - fg_color = pango.AttrForeground(color[0],color[1],color[2], 0, 11) attr.insert(fg_color) self.widgets["%s_display_%d"%(i,j)].set_attributes(attr) -- 1.7.0.4 From 7a30660afb5317ef4fce93b5b17b116fc85a46e0 Mon Sep 17 00:00:00 2001 From: cmorley Date: Sat, 18 Feb 2012 14:06:10 -0800 Subject: [PATCH 6/6] gscreen -add inbedded terminal and aux coolant controls --- src/emc/usr_intf/gscreen/gscreen.glade | 95 ++++++++++++++++++-------------- src/emc/usr_intf/gscreen/gscreen.py | 42 ++++++++++++-- 2 files changed, 91 insertions(+), 46 deletions(-) diff --git a/src/emc/usr_intf/gscreen/gscreen.glade b/src/emc/usr_intf/gscreen/gscreen.glade index aa10926..693feca 100644 --- a/src/emc/usr_intf/gscreen/gscreen.glade +++ b/src/emc/usr_intf/gscreen/gscreen.glade @@ -15,7 +15,6 @@ True True - False True @@ -594,12 +593,12 @@ True - #ffffffff0000 - #bebebebebebe - #ffff00000000 2000 + #ffff00000000 False #0000ffff0000 + #ffffffff0000 + #bebebebebebe 2 @@ -698,8 +697,8 @@ True False - False False + False @@ -954,8 +953,8 @@ True - 1 yellow + 1 1 @@ -966,8 +965,8 @@ True - 1 green + 1 1 @@ -1251,26 +1250,6 @@ Aux Screen - - True - label - - - 1 - 2 - - - - - True - label - - - 2 - 3 - - - Diameter Mode @@ -1344,6 +1323,32 @@ fullscreen + + On M7 Use +Aux Coolant + True + True + True + + + 1 + 2 + + + + + On M8 Use +Aux Coolant + True + True + True + + + 2 + 3 + + + @@ -1387,10 +1392,14 @@ fullscreen - + True - gtk-dialog-info - 6 + True + never + out + + + 2 @@ -1470,8 +1479,8 @@ fullscreen True - 1 green + 1 False @@ -1914,6 +1923,12 @@ Readout + + + + + + Reload Tool @@ -1922,7 +1937,7 @@ Readout True - 4 + 6 @@ -1934,15 +1949,9 @@ Readout True - 5 + 7 - - - - - - 1 @@ -2225,7 +2234,11 @@ Readout gtk-save 3 - - + + gcode_view + + + gcode_view + diff --git a/src/emc/usr_intf/gscreen/gscreen.py b/src/emc/usr_intf/gscreen/gscreen.py index 1d3d7d6..f47853b 100755 --- a/src/emc/usr_intf/gscreen/gscreen.py +++ b/src/emc/usr_intf/gscreen/gscreen.py @@ -30,6 +30,7 @@ from gladevcp.gladebuilder import GladeBuilder import pango import traceback import atexit +import vte BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..")) libdir = os.path.join(BASE, "lib", "python") @@ -130,6 +131,7 @@ class Data: self.display_order = (_REL,_DTG,_ABS) self.mode_order = (_START,_MAN,_MDI,_AUTO) self.plot_view = ("P","X","Y","Z","Z2") + self.task_mode = 0 self.active_gcodes = [] self.active_mcodes = [] self.maxvelocity = 1 @@ -276,15 +278,19 @@ class Gscreen: self.data = Data() try: - halcomp = hal.component("gscreen") + self.halcomp = hal.component("gscreen") + self.halcomp.newpin("aux-coolant-m7.out", hal.HAL_BIT, hal.HAL_OUT) + self.halcomp.newpin("aux-coolant-m8.out", hal.HAL_BIT, hal.HAL_OUT) + self.halcomp.newpin("mist-coolant.out", hal.HAL_BIT, hal.HAL_OUT) + self.halcomp.newpin("flood-coolant.out", hal.HAL_BIT, hal.HAL_OUT) except: print "*** Gscreen ERROR: Asking for a HAL component using a name that already exists." sys.exit(0) - panel = gladevcp.makepins.GladePanel( halcomp, xmlname, self.xml, None) - halcomp.ready() + panel = gladevcp.makepins.GladePanel( self.halcomp, xmlname, self.xml, None) + self.halcomp.ready() # at this point, any glade HL widgets and their pins are set up. - #handlers = load_handlers(None,halcomp,self.xml,None) + #handlers = load_handlers(None,self.halcomp,self.xml,None) #self.xml.connect_signals(handlers) @@ -331,6 +337,15 @@ class Gscreen: self.widgets.statusbar1.push(1,"Status bar text to here?") self.widgets.data_input.set_value(50.567) self.widgets.button_mode.set_label("Mode %d"% self.data.mode_order[0]) + # add terminal window + v = vte.Terminal () + v.connect ("child-exited", lambda term: gtk.main_quit()) + v.fork_command() + v.show() + window = self.widgets.terminal_window.add(v) + #window.add(v) + self.widgets.terminal_window.connect('delete-event', lambda window, event: gtk.main_quit()) + self.widgets.terminal_window.show() # If there are themes then add them to combo box if os.path.exists(themedir): @@ -359,6 +374,7 @@ class Gscreen: self.widgets.window1.maximize() if self.prefs.getpref('fullscreen1', 'True', bool): self.widgets.window1.fullscreen() + # setup signals that can be blocked cb = "axis_x" i = "_sighandler_axis_x" @@ -1006,7 +1022,7 @@ class Gscreen: self.emcstat = linuxcnc.stat() self.emcerror = linuxcnc.error_channel() self.emcstat.poll() - #self.radiobutton_mask = 1 + self.data.task_mode = self.emcstat.task_mode self.status.periodic() self.data.system = self.status.get_current_system() #print self.status.data.x_abs @@ -1076,6 +1092,22 @@ class Gscreen: active_g = " ".join(self.data.active_gcodes) self.widgets.active_gcodes_label.set_label("%s "% active_g) self.widgets.active_mcodes_label.set_label(" ".join(self.data.active_mcodes)) + # control aux_coolant - For Dave Armstrong + m7 = m8 = False + self.halcomp["aux-coolant-m8.out"] = False + self.halcomp["mist-coolant.out"] = False + self.halcomp["aux-coolant-m7.out"] = False + self.halcomp["flood-coolant.out"] = False + if self.data.mist: + if self.widgets.aux_coolant_m7.get_active(): + self.halcomp["aux-coolant-m7.out"] = True + else: + self.halcomp["mist-coolant.out"] = True + if self.data.flood: + if self.widgets.aux_coolant_m8.get_active(): + self.halcomp["aux-coolant-m8.out"] = True + else: + self.halcomp["flood-coolant.out"] = True self.widgets.active_feed_speed_label.set_label("F%s S%s"% (self.data.active_feed_command,self.data.active_spindle_command)) #tool = str(self.data.preppedtool) tool = str(self.data.tool_in_spindle) -- 1.7.0.4