From 1bccd5d33bdf90be19e83ef70461f466f3ad51fd Mon Sep 17 00:00:00 2001 From: Miguel Date: Sun, 19 May 2024 19:56:08 +0200 Subject: [PATCH] con UserControl Photecell creada y el boton de Eliminar UserControl --- Convertidores/Converters.cs | 69 +++++-- CtrEditor.csproj | 4 + Icons/borrar.png | Bin 0 -> 10818 bytes Icons/fotocelula.png | Bin 0 -> 15582 bytes MainViewModel.cs | 16 ++ MainWindow.xaml | 15 +- ObjetosSim/UserControls/ucPhotocell.xaml | 44 +++++ ObjetosSim/UserControls/ucPhotocell.xaml.cs | 208 ++++++++++++++++++++ ObjetosSim/osBase.cs | 11 ++ Simulacion/FPhysics.cs | 9 +- 10 files changed, 359 insertions(+), 17 deletions(-) create mode 100644 Icons/borrar.png create mode 100644 Icons/fotocelula.png create mode 100644 ObjetosSim/UserControls/ucPhotocell.xaml create mode 100644 ObjetosSim/UserControls/ucPhotocell.xaml.cs diff --git a/Convertidores/Converters.cs b/Convertidores/Converters.cs index e711305..46ff7a0 100644 --- a/Convertidores/Converters.cs +++ b/Convertidores/Converters.cs @@ -10,6 +10,22 @@ using System.Windows.Media; namespace CtrEditor.Convertidores { + public class HalfWidthConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is double width) + { + return (width / 2.0) - (double.Parse(parameter.ToString()) / 2.0); + } + return 0; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } public class WidthPercentageConverter : IValueConverter { @@ -107,24 +123,55 @@ namespace CtrEditor.Convertidores { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - float meters = (float)value; - float factor = 1; - if (parameter != null) - if (parameter.ToString() == "0.5") factor = 0.5f; - else if (parameter.ToString() == "-0.5") factor = -0.5f; - else if (parameter.ToString() == "1.5") factor = 1.5f; + if (value == null) return 0; // Aseguramos que el valor no sea nulo + // Convertimos el valor de entrada en un número flotante + float meters = System.Convert.ToSingle(value); + + float factor = 1; // Valor por defecto del factor + + // Si el parámetro no es nulo, intentamos convertirlo a float + if (parameter != null) + { + string paramStr = parameter.ToString(); + + // Normalizamos el parámetro para asegurar que el punto sea el separador decimal + paramStr = paramStr.Replace(',', '.'); + + // Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal + if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor)) + { + factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa + } + } + + // Calculamos los píxeles llamando a la instancia de PixelToMeter y multiplicamos por el factor return PixelToMeter.Instance.calc.MetersToPixels(meters) * factor; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - float pixels = (float)value; - float factor = 1; + if (value == null) return 0; // Aseguramos que el valor no sea nulo + + // Convertimos el valor de entrada en un número flotante + float pixels = System.Convert.ToSingle(value); + + float factor = 1; // Valor por defecto del factor + + // Si el parámetro no es nulo, intentamos convertirlo a float if (parameter != null) - if (parameter.ToString() == "0.5") factor = 0.5f; - else if (parameter.ToString() == "-0.5") factor = -0.5f; - else if (parameter.ToString() == "1.5") factor = 1.5f; + { + string paramStr = parameter.ToString(); + + // Normalizamos el parámetro para asegurar que el punto sea el separador decimal + paramStr = paramStr.Replace(',', '.'); + + // Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal + if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor)) + { + factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa + } + } return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor; } diff --git a/CtrEditor.csproj b/CtrEditor.csproj index 44fca82..014de43 100644 --- a/CtrEditor.csproj +++ b/CtrEditor.csproj @@ -17,8 +17,10 @@ + + @@ -59,8 +61,10 @@ + + diff --git a/Icons/borrar.png b/Icons/borrar.png new file mode 100644 index 0000000000000000000000000000000000000000..38557a7fd2484d9f405f4b3db3c8ff624cfa0930 GIT binary patch literal 10818 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 LC!10$@~Qs=+VC`6 literal 0 HcmV?d00001 diff --git a/Icons/fotocelula.png b/Icons/fotocelula.png new file mode 100644 index 0000000000000000000000000000000000000000..7669a169b7c7a6186e9f144a0576588455897e80 GIT binary patch literal 15582 zcmb_@2{@E(`0qQLeMz!!6S9_l~A@&ALNmv^9VB=)GUKPkjmey*-j9!v5umOrd#gR>#;_B}?jJRa`r zc-+>>`*@(Yfsee&F04^30Wb*mjr79C1_y;i5MqtxfAJ-N-`S5f<*~m=A_I-(&DaxS zoo(!~yFGsimWi(<0z@67=-3e}3e_ zY~enB1cyC)|I7vcGL}CU8A&E+YR1IGXvFAfgogWTY8e;+9@?7P+UkHpJt8h7(koUy zBtqdI4tsnfyu(T4NK$ABmd(-YXlPWVu{@CU_Y#81|FR8<_@gGEFwIymvZj^>j=iK` zgg)N?(vhRWgMLl!;E(XP_2#4zjOST zvIGbJJ4HmKc{EtYABFsv)Dcc`WM54O--yttaBpApXdtEndo^Uj?r>kP$k1@7(9ocN zHp>1Vk+Irf)mW9oq!6Fbm7xIF_s6)(IAn02zXsxyuQA!p1L1?Cr%ybtLv?P)Cc_OrS0c~_tVq&^3wPDXZ)T} z?<}zT5nxy2{+N!VZ`hyTf=Jk3a3Oekv(3O* z-kZJuzF-BvACvyu8u&dv=9n*F`hUR1Z?cF`zsMM`a9=ZjpsoKa?lgh$nrwspy$;R) zb&0>;{RiXzha7ke_OJiCD)7g@&dxUkc(`!j%I-v6=Yt^q5UV|APO;RP!MOTa?`Ine zJ$>;~RbKt_+U-6X1^4VFB)@##a`#>7RmCW$Df0G4j$(qV*Wg7Y4 ztZExtEKf*u%iswtTV;9V&i#1SP&P3dX7c^ZmAO^d!N9?uiH28K-oHPfXywpoeXI_V zuBdto11nk?`yjAZ4uUR_WqQ|cQ7B#UN7{e;u}wf7!dpT@f>g(y-en$$iid8Zq@ev! z1RM`bA&=)OytJ`vc|1p$Su+Y0{d3!lOuAB17*l<08Qil{tYQmH<)SUE)Lfv@oTET4J#c{(#_y=VUx2S=P$^=S^>PhrDv8X}g)ZXQ( z9>HUp{*n?T?DkSdU7JrDl!x-x24qeE9x=w8HEGMCpDV29;SkFb<=(s>{nJG;^x&;^&Ucr}*j#1C z5%Ea<>a=Gf^Y2B&_0VipXtbl~kP_zv9pS;XriHKmht{2io*w*bR*_Lh`&->75CTwi z%AHH6&s?t3m|p;+p&~Ha_CosE(H>rU4sX3UULRkLf4NllQvV&&G@auKg0v5N+?f?X z6ejK^ha3Q_%|WIW9CzoDe)rdGAI<+r^9MX0iM9G+czszR-hwg%cbaV`!;f>K>i&1u2O&Utxwc>xDa%E77h5(Z7rtTurT%EY345Q?k;Cjn zX>iknZ6?=C6aWX4*T`XBy4xmvx-S21q%+W;$uqGUReVGQF_&R&jA6^t=&{dri};F} zp^P(UjRLMxhD``H?jXh!ix}3Qwg6Ug>O5}yp0?<>{Gk1$wbELrf8$Nj_&p!7jM4gmBFN#t zcnhqwK$+=Hyg{o^raYnaBXugbKTC{4o2GyF8M2uUdv*cJ5e>5B@d{Qo^9XiCwtR&9VX+7ul;?a8CJt@kAS~ zRozlwBzoT;ehZnHdJ}x-0hkY1snuu{&peY>9}FMHjQ=r9&_gf_>|1h&-m?JtdgEyju%rupdgA%UA9nRRtp1#SP17)QsYV9cfB7}hUJHv0 z3057#r3mVtpVtitufBRPh{OOX{+Wt{R)(lo#}l)U&q#c8%y0mc$hMQ) z*0yx1I;jQ`>%luSQyIGXFyzK=NS!I zI%q-2ldDA%F(jAqAr63K`};tOFf!cl%K3|Lk&k``g>_Usb3{J!L+o&**bBamZZRRqE5an)}QUlhw z?dewhoTAYGxFtC`nEFV}79MQ6%ne$?NQ7L8VuPKz=i zS(paq{IRTkx?;=2j8=YF5beL%7EC)}=JFMx$=foe2=H}nDvq|&D*raQ0*7^O{7!s?SBLvz0<(F7gCS<-Vu&mOvR?wSr^`SCa@1P> zNm=9=b25+0P4h5w$r;@O7j(?n_Lay@%7Q@FJd<*g$;mi_Fjz_#;K&wA`yqIK&htVj zV@(87pgDE?xNReekyTnB$yiU!aH@wa?x;H($ z(JuHii&glK9i&!5&N4NpYdkX-L{Z8}&13UR79A#p?B&K8yVGkv>$(!lJGACTV@@R$ zHj?T#N{gXb4su&(eeJeqw#t5C7rOK>2yGb5&}X+*fc_PGRWv5_;X*l=Ej#l@u-) zL)*E#{!?({EW+ahV=hB+dCLN3y?d*Pi%E`k>+152dvaWaca2qp@QND5ifPt=Hq&Fo zxDY#0)0J^1C6}ir<#D)sTmSW%C9Uc1*T3x09nVeHF5lgMQM`j|GX07p*}S6bv`fLW z!F=y^L8iw?$#BWAVfwIahGV_P7AVlcuBg^{{>afX{I!56NwN=lT-hr5Qn5=u z&CATC4tasYSL6XN#x%Gjv>KgY?%JkC!pkWw)(qXXS`xk&_ZlIH{;X!ZR-A4=^%uh4 z+oD!=Ubw@ku;BS1=Lr=&bDj1S?BYDve12YOHOJT%Hme6!oDJR43I#mU{A)(IP%{RT zEz}-+dUu!pQ=<@3Xy&-#{L?C_tp|yr9TejO9%qtIj?Ig8s8eb$LZLj(s@WLR)k}&p zVQM6@K8lmmKS2p!rr98pQ7L9Thl*c+A$F8|2y;UTsEFnYe>S9@m%WKpU$LCVp zcEOlOkjjf4l*G_FA&1v(m?1H092W`i(w1d4@cwNb=h&7v$UNy}hN^c*IbB|+M#R^# zqaj>x$JB}B#G==A6>3mRg=j*WrA@3RX}?QG(n959(hbB7&d=7{W}2tAC6eBbAQU?0 zL(l^Jtw*E;ufN$EAW6KDM;%Eu`t)~>{KeGNY2;eXOf>p9f}GHQF^v$S)luDiE$Leb z)UD9wSt79?Rh^!glE6`pl(5~Z#*XoMM)6gHP%%GMQqW8(7=~Cgz6j@D`w~7Ihc{h@gE>OmV1WhSe|F8Q^t8ko|%UfibV9V46 zVXIE4_Sxz0ANzNRLcYhX`uWqghwUO;6Nk)bNJ`w3o2WG`)?dEd+tl^|VE_0ao8X%k zG1|U6`}-O>i|-PD%j94P#0zW3eYn>}m7?S$nF6%-Zl(1znL3E*JpWFJm42Nh;%2R= zH#u4`;~~^tm^`ecW4H_JjX1uOpNOz8JXdggk5yYuQtu1Ou2V5+-AQrmQOA>IJo>zF zxO#Uqs-WeBY>lQ$pf}^7nafGCIyuCYE>M6&VK0 z7%{C*s2_P174GV4$c;;kRoaqbKL_czJi7<%n4(aK;-)9O4;$Efv_c3MdfRfnZe2V#u}+SArRnxPI)jAPd(ZRd2GozSZ4@dK!)EpX?_Dj zbMDFOk5zDgHvnq#KGRoEY4;HZ4=MnE|7w(pK+DgV`q6wp8PE?=evrJ#e#>9 z@B?JHs~0#zlDCt+?7L;n44$kS&-cL88=O9m{|0Gc`tGFgXpTc%E%!f4Gj1RZ%D9@3 zodH?#HWS71^gJutEW+UArUOtZubNbvFr7WXg&nr$n%akz*3M?iNFRKNnisQAXUzuE zreUhym**}_#O$_lC))OE6#Jk#JcwLVRC)UnZo}(g^ILMHfQ;WS3-GpllyTNpDe)7U zK$Id&WzvLO0CU!R1DXiJ-~trN*IYbk(4;nW!o_s23edyP!^2>Rx=N8BGbM`yC?MlQ zCB+U|bVU^3CV!GPXia#ym_+;b;K@UiOGsJ%=8v15wXj9eMHrtTnKYrm$jHZE#L9Vb zeJ^@6UNqKCrP)}@thv2n4QB4{s|?wi*7K%m?LnjF6zBck?M?NEOD-232wuwdekP4b z>(fIlq6pw{-1hDB3I1G8x_#CiOQ{YGvll5fWZ%P{Cp-k-587g~m0R0P#;u z!>KbU?Y}{qHxnySo|x2bNDZUg1vE%oWv{lik>F1``&izT!*}mA>hMCUL#Jp${3a1R z^B2$Ns@90&b+G>Xi4S0E_Mm{9WEyh>PTeF5In?JgN8Im?b~^4C_qIVUP3te$-r`SG zp|k^S(WY!BN3?gX@-D{=J{Gp>*NNx{yAjwFumjqirYN!+)ia{RsrHgMB>C5p) zU|+g!!+IMSN#&7Vr(g1=2N%Jqedei1r!ZL<18)gbRGC0IXP*g%Rq2y&z`H8nY+>d|e6&#!zl>eD0bSL`Z02A7-|{LYkhBlF-`Gg4l&r6Uq3% zX@ZgEZvLo+&G+j;3Hs2TvyG0#?FNVTio&bsVXpmY4+RhD$SMx@X7<}Ie>5sJ0RWLr zyK=43$D#h7$QZPm*6`q-gfiMkjnhaUTjVFSgbb1d?}3YpY0eFr^3(n8b>QBzQ!G!~Mt+!1dqQvQP&7Sv+lP@jZ&IzgS^4hrEm9@v2 zCpI38rb?$(aF-u7wS6#)(rBkvh?m=rrP_bws|Sa*#xV=3k2s=M%_UBJ`<@%@B9>lkl2Cx3U+b(9f*uJ z?XcfV(FEBvYI;+~!OB3`5EVYakE_{_(gxP2`*;+VN_w=&)lxj@f{^G3%MBoqEyh!A zV2rlE4{&YQyand3<(1}G^|$I$QydZ1T+R1fX1`V|qXPZuY{|C2t)|qW!j%xA0Jwvp zDD6Xv?n0%{_fRX}zlo9rYjcrRnk}U1bB=XQpMC978!Vc3pd{r1oKwH08JV|w9aIVf z271obMkI(BNtAO7)geyga@>gLfus@k`x|Ur&z;aFW6NbkG43%^^KbJ?jg!Iy{1En4 zZ($1^e>^g;Ta9a3&HjjYe(SSa}Ic=#G>tN2&vQM1j}bmJ3D_da+i(EMdU1;&^*S|dGnKW+NF zkMWH5ckoV2yRYIM^S&X5BlF+NK`^}@kA~EsuC0NnY2PJ3^5C(M&T^eq7+XjxQNI3pE2qB9OX{UN2^62rqNO-1BfzHDZ z0F8pE@aqb}dYudaezG!+5gv+p4B3l_LIT*}-OTMBi!x#v%=>v%SMx1U&a>lHP>+8C z>rR1=3jwIm&flgZ;rr!JbNg;;$oq*f-=eew7GJ}Bc4%q0StLZ*$-_u~`brzIjGyOa zWX53bPriy2b7Q;z5Z3rT`q7Rlu z$bdEZy%6w)$5JuyD{l-#moeNIVkrocCP7>g;_TJc*%cvTQme$1^UJG~U148EA<42c zmdTxK7XAE_w^I(l!9Xg}Fl-uzMx5o4ZDH$R%0_X}C6NpWvT`|mjFK+3d5bEI%&uHS zY6nDlk59x*Egs~B_(!oFVSk?w)0m`X4M=0e-DXuG@>T{eyzD(Nr)S?h7%zhL?V%9z5}Ffx(3#p38%V_HAHf# zK^!7lnEBG*G^Dr4*Q3(Dw*DMG&JZ76XX34h7Ltg_^N2^x*H%d#sL-LjZN9nIjWGO>8ed+f;D9~iGbifob@j!KcltK&~ zPTH;2m;*Zw0DznBepYk_KL2;438h{AE>A zi!q@xXnaB+sI7JeQ~zjYuhSPhgoG3a;Bi#O)L($A+UlN_+qk71$OBZO^0z*0-XF5Z z_aRj1Pj^nfbRtbe<)||48(VRPSnpyu^|lM3+866Y?i^3wnEHsBAIUN^PlY1=>Ri0S zHIb(yOZ*nppep+%*Kd*4u-6{pB!{no&b3S2T~7ysQ=6qKA;MMe!-cAaJMhA)rfs zoF0=Y1>nB3l&AhFkWc;&G~ZPF{PV7G(E%R(y;W_K#ERDT(9;;W@7s8ll>NCt;Iz4$ z?;V&`@V~9FyA9J~i~%(! zsQ>~@Q`1)&aH`~3gN1hh*hvr={1>7cDQ`4iP!B=*SB_0aqO_fdY`Vnz!OOX7%OvG;zVe zn8U@OoaLk5h`g%ckI|^@X&_R78dhpw>$XIT(JkP8qvkuxNGlK^{y;zfJ=3PPh#Y)> zy=kol;{2Qs&ksw}y$i`XF3`Q;o1?%l&vG}D(L`LW*iCh?MNhIN(hjTV23{^-ULu@0Ad&-3I(F4(qKV3T=O07_6T+3OtliSO~7x0&+v)GLuo-=S{wViMIh% za74Q8LA*P65Gd0fQcGiV7EY@mo4&GFgPf4O@TbqaKJXE6xvCd;Hw~vcLLDbSMq%4T zE{tePdSl!(jqD2-@zgy6-9w8)FV6LL4xG!k;mxSSGfzrbH)+5lKz{Uv(d|sH!Q7RV zgia?Lc{)M`9KQB_+QcO9)iD`fvbYaC=e|$&y)^G1(+|y z`|;k0N1GaehIA9*7n0M!Ehb`Gvy_Hn_;PVOBe70-KyEo)iPFA8Z?t!@@6jLo2_fld*%W|*bLmA^2nB#1517TuUzM9R!K-c3nU~WaMZg}i%M9DvSuS4)!aT>-I;cjI$qW>!Aa|R?9pdzmI)sR`5{P;LZABov z5x1V5$$Cf8+$jnL^cw&?A$OpCta;gX_}k)+ikU9>>w-nw=uj&ALiS(|y;)l$MKb!W zDcAXaqgJqes_CHwK*85#h_KxhEgD8ICY zX7g*ENE+}spNBZW{ipFo3plrGFoj3Wj)k$Q_De{3AU~d^4sqxJKVn#62*Pymie5sj zo>v>3dIW^Z$8M&t)`2SkZo+;|)D)O;O;78v+uAxEeO==s=6Yr7m~mQDqM0Yh8Q${prn zJ4tbTDeyEtgRSj};$jGa?MvJjV@6l_k}|DX`LLmu9`FRmUNefrZCtpV4I^IZf#p>W z^y{oInq&?Pvu-QohKWMwb*1nHY%a#%hC%X(s~HG{Lf)>evC|t+)ZX~4!Z-^8;1zxp z8x1;F)*PW2U$!1X+Ckmo7Lj9q7znB@gaOBA2|d@dYq@1HKHxnS84HZ;j`XEr=j8ow*x2nL=!AWs`re{Hn@ScTs4T89-gXmR@cooF>1~L{`<6j_X=V=DV3R$MC(PA~} zYx>4tS9efAO4}815l-#@6>X4=E%2VF3v*3Cw%ctWVQ0y?0Vk-eE15 zwlRqK>cNzK#wOTNa3pmdlSO1+yrIj#eTmD|zncK!V9`l99>C|WhjiM)>)#YLn9Lgn z`G;zIKtO_(c%iXx>WtH1mSX?(4K79;ZG#=(|N1QF*RTsf_<9}mrL_+n#Ky>o`5|_u z@BqHjDsdR+Zh%-Itma13N#T0*@$u@hZDFY1EUZPZU9ZAov9F=V;P z@lM-v=pAmCKz$>~NBsd{DJ|gIqV*x|Khokq4Z&z@}G&O&^&na&&|qBHpbL_+vGqS;6PT zS#p>J8F1RPDrmeyokh*I1M5jaGS0%OubiP{Y7rEaReyW^$1>wG!RDGw0hyx?c~P*r zwto#oCf|CuY)3`D>#XI7H6$MbS#j+IvR$A#Y&j8slhem-6Z@Pd1lx)L6Z!I{6|svu z=yXmZ_mFr-#6Ekr(jhTOKqCe*ze(mP_a zjtw@YqiCVX@PNfTa4Hi3L*xMDCYJVIg%?i9Lal9CCd?bwFFc5>ySnjN+w#JO8Zx<( z^b3jI+|4!He;vSnNNo$2AzaaIO*~T9_8woapfbT}W}sIIsT={Dfq~ECr0}TakKSdr zId1Hp=YixG8!udMt;Ik_Xtyf{`F^#$@MPq)II$eM_j0gcCVs+XvEAfK!qyM& zbG$7EXPj^WWKDtQW!_0A+l#|US^y{)EX@F%1kBrZ$ZLG?#vEN_p+F(bu@aOaVv!6+ zH;0lRy+)hKtelsIXDgXy?R8eeuHki8BHvs+>kZDtDLb-3#|nS&){c9&r{_j&)4bI8 zvxLWK3bn~XVdfFaMIbO0JgS!kVaQ*0-UMOrq<=ehRFn|i7UU%#eJt`D+rWyYh2agJ z7J^JnvaVM@oEiZ%cs-tnxRV?;o~i~Igx8b1aRb%&FGPab<_zxT#4V2bkWSQ=xA_07v=13p@x~TYc-Fhw3r!? z*eCs#!fEleFa;S|4-Hzxo8i~%X9VO5eG%9v{$316N?gKfs4b|$)v>EAd>b)8f9b_| z6DbusSlFCH}hv z7kIKm>yc0c$AA>5^z|byU_RqFOsG+B68DWJMV>%lLEZGdD1S?>;Bt`tA{wQ?H?O5JR_UI%x9N!rXf(?RRBk#EulNh_1k8-VmHMe zPHK02gq-hysc$KPpu)VU_RSMQlMk8h1&K+qOk@5>ou5le>Nuy$Xyx&Ujw?4mnV(o~ zOghh^14$R9A!&opI(sSWuy=CEMb<|&u`I9D8x(S?f=%~|tZvAG!tE3P4Benclld>u z1`AaXde1ZX(Se^g)hQoP;nJ+oS8suCdN(%kU^aKAWzk|VVvV|TL=4A?zZ5yX61I}v z9UqS#!>^gt|A0XW{Jtb2vnv{8D${7px>SFyxMIoD50o*q1YjDl5eQ79lZ`1eL-cJEnZ{El*aQ~CoZe8Ipe5z9K?@V9YE z{(*qKs>`NWJNxbmr>Z;k+cY`%BEu6T(u989leojzkm2KqVZP?cq{C<*H;#eLe{N7t zCWYG;-Qo3h)fMX1z)l=SNIU@hUhsG(l$lpL2g;Bkyhp1x4jQZhyGTceac&GG`ETg^ z-hfk+iz7Kfu438oh<3}&#R7F1?fW5Q0(e02=|Vb42Eet@9H*#2a~AMRX`P&3g)50n zaO&*_L#8V4o-3K0_=pC5yp9S6B*63!YbU+ZY8VEPBvgvYAYo@vp+PT;)dFs#NUEuNt# zw!9CN#`jFGbK(tDiVlLc{~Ql)n%zm$h-cDNucdO6cjcochJL>@V!*~c&j{@$KrR-bI&!e=z&0O?RuQ_~wm^Y1> zeEB$U0$xsiXTLn^PP|O3*F;pJm;u#T(yC`j1Vs+>dCN;=o>8aej+AZub8l%)AgaNk zoW4I^3N%d*;Q4EGutlI8Ft&mymb|7*b+?qU%xF))bmd^goxP!#cw1D@V@%^3hQS3b zk2S|Gxy+ay^FL_yyPO4LZA|Ibj3$^m0t6V-q{;P%oOYs|v?|%iUo&yAxHCS@qqZq6 zV*5Pt_pSBF``aD!*Ev}`aC6%kiJ*68jJu+7&gF0F~9mGXrNM-=aq=|Ftf9}l`gsHLVQW9uM3+sxlz5T za(T{-k%$UE-*X1ZAQ1QVUp&^V3E#L9vUXLMDu$fnqZ@77NQlUU>XlW#T6~Y4+YpYr z4aK6Dqu8w>DwC0q67%V*{HlF_(W+AhnTbO4IbaLpRLlMBug`rN{ncb<>=)>u-1o9) zkXCZ@M7!dG)yT&6YMzxhKPP>T4!yW=CjtA#bfYgCHC_q9y8fNf{=07VxOMDoyqmom zm5vTFb3G@wvUDQ6*{<8}Yg*NqdHv-%fuC9bvt1^g_F*(OzyHKKPi(@~M$2?4(|T=! z#z*`B=RPPCP#!-?wI%rBt^3y}oXa#y5wQa&X#zBnVExakMm%fi-p#QFnXxnaU}U`@%p)VO?}=!%|fL;&5n_eUW!Y^wU{>qUe&l5`@?%9F8q~W>$ZcJ z^wR~P+VhcoUp{tKnjhHy(TNdGtYr)wPAmN0RnJ|}-gOQ6NJDY)jtX4#bMui@4KZjV zXnQ&F#lq$Gjaq-FfF7-;oXtx$qZIcfomC&@k%wl(7ewhS&4xtv1`5*?vb^6pOIu3P znNxmX+h~ZdwxcWfReVR$zCE5dfB2pCWd8+d+mCi0nwR?L1aZR+s>hxI+v2%TDzjIC zlXZHu+p;tMN<#ACm*b0{@~E}6!>1k*UaLY@caO`G41+%>)2xXKjBHwK!$+tlGjr)j zQNhi_M-Kezoh)#8cD0u-*D-S{niVHwIiYq37X@19uEK^X#-5{_J3JOFP&%uA z2OTJSs@SjE9mjSD{_a+Fy7T1R%-Y12s`DRLCVnIwB_z)GZ)AdCckS2{M*Rz`{*H`x z?E+E`*Aip_`p&Mid*;-oGNUBsZ`0}<`fk=MSM7Qq16u%bK~Cs!PL``Bi+|eeY0vHz zHO#bFhMq89SEZ!$7eiNjdJ*LU@Rva*9p)iImpDQ|ON(v{0<`gs(4KvE$3<(*AMNnc zYMGEII3iMn_Gv?PE4cS|KmDhXj}Rv|W}`f~J9HvESoUt1i*f6I_n7JGT@zd$P1!W0gV_Ps} zGvM*P;fQ3fGHyU|ZkjrTrXBV=E#pTeVye&_~@mp0&Wb^a$%^MYe3@LW} zsL$VBFN^UI9+=$~uY^nbG*r1zKeUPIebJ5$eoc0xUx)yymzB>KeQ1N9)?M%({c_ok zcqOk?3LZ^*G}RG}8R3Ep!knd+B}k1+&ci%K2swoiq3ra7mPHG|_au6@Ue-(a)tz9( zW$7UH09`K{%RPDiSA(aOWS4S^F=?SQvVb{<1S+#i z>fKb67U|-6+T^OJB%QxS%Jolgv6=KfH}F}3_B}da3GM`}B+GK(U?h{iZEz-!gWWJK zdHD@(tYClUogfrdD6=Q!H*%~-7rc%dZe0CB{3G#rPXNug-~i0UgfGgzou>XFV}9M= z6vcvGcf1Fv0{791ZI=%tiqPY2SofuPf1+RhpAPSfzCw(0M(c}7ww^%hQcxkiXF6`9 z8p`Es{kp9PEWyrSy~Ah?Ny&;w4hy!vz4N<$xWiEbaS2<+Y=j>#+hu_qD*aZ=O-gW* zj)`d>tEiQVOj9(@+GcflT|*`_j%PCS)Am0qI0_;>zMSs{p6`V<| zM*CI$QOi_OF)b!#W(^@wz?qXM2GUdq6B$J57HXW({15h*0Bj)Vy2FE~bo^1FoZ}o5 zQ>tvD#!{XWm1hPtuk3}KxWo|q91^V|I_Scp#!Hl|8XL|v{_{z~(&pinb_M?RrTah! zY-Y)Al=dfS@rvYxKc6!=HLB9i&?KMN>O)cpLCl2c?cZbX4_BX?TeGm*z42^%tqxT6 z)2FJG%L939lTnRn4HV_XjTqz9Eu;j(0K0NiZjzpOAEgE&SBv{c!^rxG!w}ZMAmsv z3>yG|cAe};SC8)bL;PH=S;4=B)+1!;)^RCltCE)05 zH5jekW`k)(ETT1nzr=0-^|{mVF51%B6R+GDZM1VQ^eujQoI!oDSSd1Y^2l23AYvLV z-Q$z*v=cz;{tM6%Lu0~@R{l$u$GjL^#NCV=E7^scYk2`?9xF|LyETE3N(&L7@(*yX z2`!`M6&OR;`wl+?9=StG#VS2}0(?{Q|MlxMwtwl`y& !IsConnected); TBDisconnectPLCCommand = new RelayCommand(DisconnectPLC, () => IsConnected); + TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl); + stopwatch_PLCRefresh = new Stopwatch(); stopwatch_SimRefresh = new Stopwatch(); } @@ -309,6 +319,12 @@ namespace CtrEditor } } + private void EliminarUserControl() + { + if (SelectedItemOsList is osBase objEliminar) + RemoverObjetoSimulable(objEliminar); + } + private void InitializeTipoSimulableList() { var baseType = typeof(osBase); diff --git a/MainWindow.xaml b/MainWindow.xaml index b65635a..74aa1f3 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -6,7 +6,7 @@ xmlns:Siemens="clr-namespace:CtrEditor.Siemens" xmlns:convert="clr-namespace:CtrEditor.Convertidores" xmlns:ObjetosSim="clr-namespace:CtrEditor.ObjetosSim" x:Class="CtrEditor.MainWindow" - Height="900" Width="1600" + Height="900" Width="1600" WindowState="Maximized" ResizeMode="CanResize" Title="{Binding directorioTrabajo}"> @@ -142,6 +142,7 @@ + @@ -167,6 +168,18 @@ + + + + + + + diff --git a/ObjetosSim/UserControls/ucPhotocell.xaml b/ObjetosSim/UserControls/ucPhotocell.xaml new file mode 100644 index 0000000..5e1854c --- /dev/null +++ b/ObjetosSim/UserControls/ucPhotocell.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ObjetosSim/UserControls/ucPhotocell.xaml.cs b/ObjetosSim/UserControls/ucPhotocell.xaml.cs new file mode 100644 index 0000000..af4c154 --- /dev/null +++ b/ObjetosSim/UserControls/ucPhotocell.xaml.cs @@ -0,0 +1,208 @@ +using CtrEditor.Convertidores; +using CtrEditor.Siemens; +using CtrEditor.Simulacion; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace CtrEditor.ObjetosSim.UserControls +{ + /// + /// Interaction logic for ucPhotocell.xaml + /// + public class osPhotocell : osBase + { + private float _ancho; + private float _altoPhotocell; + private float _left; + private float _top; + private float _angulo; + private string _nombre = "Photocell"; + private bool _luzCortada; + + private simBarrera Simulation_Photocell; + + public bool LuzCortada + { + get => _luzCortada; + set + { + if (_luzCortada != value) + { + _luzCortada = value; + OnPropertyChanged(nameof(LuzCortada)); + } + } + } + + public override float Left + { + get => _left; + set + { + _left = value; + ActualizarGeometrias(); + CanvasSetLeftinMeter(value); + OnPropertyChanged(nameof(Left)); + } + } + public override float Top + { + get => _top; + set + { + _top = value; + ActualizarGeometrias(); + CanvasSetTopinMeter(value); + OnPropertyChanged(nameof(Top)); + } + } + + public float Ancho + { + get => _ancho; + set + { + _ancho = value; + ActualizarGeometrias(); + OnPropertyChanged(nameof(Ancho)); + } + } + + public float Alto + { + get => _altoPhotocell; + set + { + _altoPhotocell = value; + ActualizarGeometrias(); + OnPropertyChanged(nameof(Alto)); + } + } + + public float Angulo + { + get => _angulo; + set + { + _angulo = value; + ActualizarGeometrias(); + OnPropertyChanged(nameof(Angulo)); + } + } + + public override string Nombre + { + get => _nombre; + set + { + if (_nombre != value) + { + _nombre = value; + OnPropertyChanged(nameof(Nombre)); + } + } + } + + private void ActualizarGeometrias() + { + if (_visualRepresentation is ucPhotocell uc) + UpdateRectangle(Simulation_Photocell, uc.Photocell, Alto, Ancho, Angulo); + } + + public osPhotocell() + { + Ancho = 1; + Alto = 0.03f; + } + + public override void UpdateGeometryStart() + { + // Se llama antes de la simulacion + ActualizarGeometrias(); + } + public override void UpdateControl(int elapsedMilliseconds) + { + LuzCortada = Simulation_Photocell.LuzCortada; + } + public override void UpdateGeometryStep() + { + Simulation_Photocell.LuzCortada = false; + } + public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { } + public override void ucLoaded() + { + // El UserControl ya se ha cargado y podemos obtener las coordenadas para + // crear el objeto de simulacion + ActualizarLeftTop(); + + if (_visualRepresentation is ucPhotocell uc) + Simulation_Photocell = AddBarrera(simulationManager, uc.Photocell, Alto, Ancho, Angulo); + } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + simulationManager.Remove(Simulation_Photocell); + } + + + } + + public partial class ucPhotocell : UserControl, IDataContainer + { + public osBase? Datos { get; set; } + + public ucPhotocell() + { + InitializeComponent(); + this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; + } + private void OnLoaded(object sender, RoutedEventArgs e) + { + Datos?.ucLoaded(); + } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } + public void Resize(float width, float height) + { + if (width == 0) return; + if (Datos is osPhotocell datos) + datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width); + } + public void Move(float LeftPixels, float TopPixels) + { + if (Datos != null) + { + Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels); + Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels); + } + } + public void Rotate(float Angle) + { + if (Datos != null) + if (Datos is osPhotocell datos) + datos.Angulo = Angle; + } + public void Highlight(bool State) { } + public int ZIndex() + { + return 1; + } + + } +} diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 7952e82..823873e 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -231,11 +231,22 @@ namespace CtrEditor.ObjetosSim simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } + public void UpdateRectangle(simBarrera simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) + { + if (simRect != null) + simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); + } + public simTransporte AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } + public simBarrera AddBarrera(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) + { + return simulationManager.AddBarrera(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); + } + public void UpdateOrCreateLine(simGuia simGuia, System.Windows.Shapes.Rectangle wpfRect) { if (simGuia != null) diff --git a/Simulacion/FPhysics.cs b/Simulacion/FPhysics.cs index 61af798..e9af1a8 100644 --- a/Simulacion/FPhysics.cs +++ b/Simulacion/FPhysics.cs @@ -223,7 +223,7 @@ namespace CtrEditor.Simulacion // Restablecer manejador de eventos de colisión Body.OnCollision += HandleCollision; - Body.OnSeparation += HandleOnSeparation; + //Body.OnSeparation += HandleOnSeparation; Body.UserData = this; // Importante para la identificación durante la colisión @@ -295,8 +295,7 @@ namespace CtrEditor.Simulacion private void HandleOnSeparation(Fixture fixtureA, Fixture fixtureB) { - if (fixtureB.Body.UserData is simBarrera Sensor) - Sensor.LuzCortada = false; + } private void ApplyConveyorEffect(simTransporte conveyor, Fixture circleFixture, float porcentajeCompartido) @@ -365,9 +364,9 @@ namespace CtrEditor.Simulacion return rectangle; } - public simTransporte AddBarrera(float width, float height, Vector2 position, float angle) + public simBarrera AddBarrera(float width, float height, Vector2 position, float angle) { - simTransporte rectangle = new simTransporte(world, width, height, position, angle); + simBarrera rectangle = new simBarrera(world, width, height, position, angle); Cuerpos.Add(rectangle); return rectangle; }