From 9fb970523f3dde2d7a211f0fadbc43673aba9fec Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 23 Jan 2020 13:54:31 +0100 Subject: [PATCH] Initial implementation of new DevTools. --- .../Assets/Fonts/SourceSansPro-Regular.ttf | Bin 0 -> 293516 bytes .../Avalonia.Diagnostics.csproj | 12 +- src/Avalonia.Diagnostics/DevTools.xaml | 24 --- src/Avalonia.Diagnostics/DevTools.xaml.cs | 159 --------------- .../DevToolsExtensions.cs | 19 ++ .../Converters/BoolToBrushConverter.cs | 22 +++ .../Diagnostics/DevTools.cs | 61 ++++++ .../Diagnostics/Models/ConsoleContext.cs | 36 ++++ .../Diagnostics/Models/ConsoleHistoryItem.cs | 19 ++ .../Models/EventChainLink.cs | 0 .../{ => Diagnostics}/ViewLocator.cs | 8 +- .../ViewModels/AvaloniaPropertyViewModel.cs | 120 ++++++++++++ .../ViewModels/ClrPropertyViewModel.cs | 82 ++++++++ .../ViewModels/ConsoleViewModel.cs | 112 +++++++++++ .../ViewModels/ControlDetailsViewModel.cs | 185 ++++++++++++++++++ .../ViewModels/EventOwnerTreeNode.cs | 2 +- .../ViewModels/EventTreeNode.cs | 22 ++- .../ViewModels/EventTreeNodeBase.cs | 0 .../ViewModels/EventsPageViewModel.cs} | 17 +- .../ViewModels/FiredEvent.cs | 0 .../ViewModels/LogicalTreeNode.cs | 6 +- .../Diagnostics/ViewModels/MainViewModel.cs | 126 ++++++++++++ .../ViewModels/PropertyViewModel.cs | 11 ++ .../{ => Diagnostics}/ViewModels/TreeNode.cs | 15 +- .../ViewModels/TreePageViewModel.cs | 49 +++-- .../ViewModels/ViewModelBase.cs | 28 ++- .../ViewModels/VisualTreeNode.cs | 5 +- .../Diagnostics/Views/ConsoleView.xaml | 56 ++++++ .../Diagnostics/Views/ConsoleView.xaml.cs | 64 ++++++ .../Diagnostics/Views/ControlDetailsView.xaml | 24 +++ .../Views/ControlDetailsView.xaml.cs | 18 ++ .../Views/EventsPageView.xaml} | 5 +- .../Views/EventsPageView.xaml.cs} | 4 +- .../Diagnostics/Views/MainView.xaml | 55 ++++++ .../Diagnostics/Views/MainView.xaml.cs | 66 +++++++ .../Diagnostics/Views/MainWindow.xaml | 18 ++ .../Diagnostics/Views/MainWindow.xaml.cs | 74 +++++++ .../{ => Diagnostics}/Views/TreePageView.xaml | 19 +- .../Views/TreePageView.xaml.cs | 9 +- .../{ => Diagnostics}/VisualTreeDebug.cs | 0 .../ViewModels/ControlDetailsViewModel.cs | 25 --- .../ViewModels/DevToolsViewModel.cs | 76 ------- .../ViewModels/IDevToolViewModel.cs | 16 -- .../ViewModels/PropertyDetails.cs | 58 ------ .../Views/ControlDetailsView.cs | 75 ------- .../Views/GridRepeater.cs | 51 ----- .../Views/PropertyChangedExtensions.cs | 33 ---- src/Avalonia.Diagnostics/Views/SimpleGrid.cs | 146 -------------- 48 files changed, 1286 insertions(+), 746 deletions(-) create mode 100644 src/Avalonia.Diagnostics/Assets/Fonts/SourceSansPro-Regular.ttf delete mode 100644 src/Avalonia.Diagnostics/DevTools.xaml delete mode 100644 src/Avalonia.Diagnostics/DevTools.xaml.cs create mode 100644 src/Avalonia.Diagnostics/DevToolsExtensions.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Converters/BoolToBrushConverter.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/DevTools.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleContext.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleHistoryItem.cs rename src/Avalonia.Diagnostics/{ => Diagnostics}/Models/EventChainLink.cs (100%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewLocator.cs (70%) create mode 100644 src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/ViewModels/ConsoleViewModel.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/EventOwnerTreeNode.cs (98%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/EventTreeNode.cs (85%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/EventTreeNodeBase.cs (100%) rename src/Avalonia.Diagnostics/{ViewModels/EventsViewModel.cs => Diagnostics/ViewModels/EventsPageViewModel.cs} (69%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/FiredEvent.cs (100%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/LogicalTreeNode.cs (65%) create mode 100644 src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/TreeNode.cs (81%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/TreePageViewModel.cs (65%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/ViewModelBase.cs (50%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/ViewModels/VisualTreeNode.cs (85%) create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs rename src/Avalonia.Diagnostics/{Views/EventsView.xaml => Diagnostics/Views/EventsPageView.xaml} (92%) rename src/Avalonia.Diagnostics/{Views/EventsView.xaml.cs => Diagnostics/Views/EventsPageView.xaml.cs} (91%) create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml.cs create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml create mode 100644 src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs rename src/Avalonia.Diagnostics/{ => Diagnostics}/Views/TreePageView.xaml (60%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/Views/TreePageView.xaml.cs (90%) rename src/Avalonia.Diagnostics/{ => Diagnostics}/VisualTreeDebug.cs (100%) delete mode 100644 src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs delete mode 100644 src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs delete mode 100644 src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs delete mode 100644 src/Avalonia.Diagnostics/ViewModels/PropertyDetails.cs delete mode 100644 src/Avalonia.Diagnostics/Views/ControlDetailsView.cs delete mode 100644 src/Avalonia.Diagnostics/Views/GridRepeater.cs delete mode 100644 src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs delete mode 100644 src/Avalonia.Diagnostics/Views/SimpleGrid.cs diff --git a/src/Avalonia.Diagnostics/Assets/Fonts/SourceSansPro-Regular.ttf b/src/Avalonia.Diagnostics/Assets/Fonts/SourceSansPro-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..278ad8aa0a09592a759e39f8fc06d0fa9d986fb0 GIT binary patch literal 293516 zcmd444Sbg4|Ns9!&hzZNR;^mMTeV%gc2}!bTidF2ziQRGpNh6hEs79A2$dluVF*JQ zLI^_`!VrcKLI|ZKgb+fu|MPtv*V5RaeS9B}e-F=I$90^?{rz#A#~Cpq(we_K z$r?Ij((pOKBcBpCxDVSA1(QaNyy?0@72?fWAksc=WWn$e=Y4t6+2SS+5OJRySu|nN zj~S_ViJKx~oOUB89X|AeU$5vUURs>UfT2v4In%yks>1%OIdZhPUESfBBR?KhGE2(o&T(I!QW13GFaY#?Fc;3lJ z&x$&>AeH#YUvT<~vlh;8{D^Zl?kjK~I%(F4b8bqXcBweEYekw4oPY9Z3vT-yDg zjXK%Y{52LQ?1Shiy)AX$lBEis_lr6?Vy~XUe*)L44S!!D(Q<|~iac*Zbd(DvV#IZt zm~x(ov)m!aGRCTzA=!rNaGEx9UC(tKuT-3$op78s>>&k1CrG}8>g%0v>U~X#X&Dl8 zi#|2GoRvt3&@Yn`A=QqW$I4WvzvMc{qAg^q`360X-zzW&V4Ea5!_ZyWzXumX15`A&V@3?af!8+#5zV=n60FvqjWd>aoQBRiD5s}@PE6+n~4&KpE2fbiFRI>IPrXY8(D{v`znSxtcKk1nnn>qW$IX(7yB^XgeE8zORyg z&N*mv>WBXJKcvM!aqqU2ehtviq8j?N_Ul7&21=&(*#^S>UHkk$r`4ajWxODre~A;S z-%YwE9zvA-RKF)YzWh|b4fE^p1^fj3mOl2GbV4C)H?d(X(($MP#-$;qIlqq&k5Pkk zoRa$bAJI7D*VpTq)j)Xc((&sra04D|hb5zYoLcxH(Naz@UhE7z*|K z!sDrqsegi#k3YuR|D?W7?I`0h|7S3+>)75vczo9}{;y!{*YW>QoFwT*`wQ1WxIVv@ zVa$|c!gkoxUfVa!N7_zlZ)ssYz%w;3lQdQ~*|kNRJ=oj5}X^Tu%d7)KjXNLT%yaQjHatZm>)ScAW5jL`?d z-*~X?Fr@Vq&I@S?*TG==U;^oDb;x|E>AHn+M9bsZaGAK~R_g3Y%#TX|TAPsgPBZCG zx`J*W$Y)NQh@Q-xJcTq&A@5e>%#`}yFt>qDf7pfHs5_-Yc-%jvziT=ELsI^cyGXe= zl>eV8{a4o!Lrr7KOZ(_gl+{l%Jkr;HGKRHC2KkJvdCd2Wm1Fs>bF_}DI(IThF&~EK zKV8QhoZH$;PkqKbFg3jH=^z<8PlVSuZ%CG|b*R6=&YgtQo3foy|FyHR{%bQ5n0K9* z_+5-y*F$gDf9YgV*S%zd*@@fM#92c*t|6QR+ENqgZ+!Cbjf{dACmZtz;+qGUn_}@d zTG}~jGM+Zs!)&Bq*U5lzyV)*{od;#0^OWS6D%@q^ril#IXBwZzq2Y(a_DKU_so$`F z_2buX51R{^+XvSFKt9}XUS6r+=e)@87tm+XIgGJN!#e9i>@UQA0%2;t5AgdJe(y*3 z)&Jl+_50ul%HvBd6Zb5BpN{?M=qYGn{cgo9W;|M4{{vJP;@IbWMYyjKF6HYkAiOgOZ$3H?`?a9yD&{$5?;6a%!|Q|*nP=Tbgz+?$g^6s7Tti(<+*aXO!d6_eei>~2wjMti7r4# z*Y8%`yQI4pz~8UfUBt5s(DTtHXm8v=xNT_r_#Y5%KiY==f^fUiw)GF7edIv~?cr;* z0Nn;3M06+mZ3MOd8Qy^H5q5;zsJ7F;LfbAhw7vgV)pq`m`5%;JxZM9iIsHpn{!h}P zeT}{y?tgDlXE)Kmzn7Nsi)6x(2ouqK=7n!0pFS0ovtgh1UG&um&!Fqz8#oP4jOdx@ z`4Nsn7eqKiXpchQBg`)~T=|;cU-DaZ7rMTFw-WB#1&noLSxf3Txr8yEanel_-%YFk zi6em~PFL2`V+&@$}%Bsrw{dTRYOo*~iB&O z&vYzr$&Og_)>x9*SNQH^`uAjM9?sVS>`#fX5%;7k%r)2%cf4=n1 zN~C-kA9c?dPP?wnH4PfCqGW*#GK)DkUr)V)_gy* zCc?cFkYuzy>!*Q~Uk2I-a@Aef?O%uAGZLnTA9Q@$k%nvI>%ebKLwmHZ`GRl*tT}wv zT>mV*^vJl;FotBh>tu#WlEcH?O*nT;7H*2rBD60I#@rVMN6dpw3-(qmq_?>by$|g} zSt#42iyM+IjkZdcsETm;gn#32h{>X?_EAS5QrFL9QYV?jmr4AYtT{6&FVz{+M81>h zX!Ee%MxDJ#9LjgBo3aS^BAL$IaJY+q=Po%MI~Po(afH>`O__Zz zJx?0y6c912v5>S)A&8n_Gj}b zXG#v{N3g#bM!`6q`(e#-n)2)e#-X=~W28(m&oK6_m00rvXJ5Jo|B!Mdp8pG+TE>e8xC!aaZ%^*eoh`r`_%e4*zaoi?Xcgp?XY{e zjZhytkA~~|Df&{R&zbk=*IHMsN3`$pJ0n~sq{q2}ahv|ed_CAH!d}+{YX1@QZwYhq z6zsIGYq;7+G~R5+ed2WZV5|UTwFB#;N^E>*6Wq?lR_8jZ@D`6Ij1^ z#G`e5Qh1#(mAPuF`HA&Q5_V0bT|@t&tm8F)=91iSofF@|^^3Ok-$mSX{2WanD>rhetLoN`&GuY?aY^NGUo2)9O(hZkuMmxcQDreF~?*vm-J&! z_}4jR1#`>_<{F(xZk8_21L$AP5hqKEIhk?vWaboW?i$hVXf~*JmakbSe~msU-5@FA z=KufxN?1djL3&T5-Jd{zT1MHNLs{R5&Vso#9gk&a>Rv~lK|Y~s|oi#Qi~nRVtAexD?{a;J2a zyX$wE!!X}ZJIJIRoC2E0Gf@1KzQsOqz((1f#r@6ZBk zraxLg>ZUMaPC}I?azuSe18$zAc=t$(+f4H5Yx!NBrE2J3I)&^4i=>$zn5{`y1g8lE-ifXFjle=5nWOVY#Z_!!##Sn8lV<)UX( zoF}oqZRgx7CFXi*%NneQa{_D76PO!Lkj|>^xzZilLsGG-q?VO))=ggenJk!1A zVptBkAH5YGfcN21c#W}!(Y5{*I1BCoMzea}5!ZhLb6_4!f(dXA@c#ColH&TK;UqW? z)Za^y-*eIR5w1dc<5^z`H-HVdRs9akeIXk(EDh&XsDd{^{jY<2BldTJE2jxu?5lyGz{V z?h3cuz16+jt#Y4rUw7Yh-*Mk_-*-QBKXSKw0k4CX>Gkubcr(4Dz03LYIiIe204ir{s@n}fe3woOb(9G*BX@vy`xi6x2C5|2z=oVYG=L*m5|-I5EFOOxlM zB&JoSJ)HJf+EZ!IroEWoj>o9)}#M#UR^!+HAF(}Bl|J`PLo-3 zj#P$g>MB!d9-yXPGoPAW=1a5B>^BFTxNuDsIWxjFHP1QOS?DZw%A94+N~gkEMNQpG zO+Dm1<~->h$?^>_YyT`lVd(?ZvtMT6OHhZ6XyS#6_@2RPg)YJrO z>WG6i4_Q+HBR_fk_2 zhSr6u!!_0JU`-WKQ{|DGYDrDCKUh<yJ_8&mb#*{9S)xT{JFEsy`X*-zV13t3R%uQ2_fv^+&pIsmUAX zjdeGBh3<>`i{F{Ri0<|9x_jNc&R&X_tmoVHKh%HD7`6%Sue*=GAAq~-?ySG0ep&s+ z^%vD&5FYOq5%!}tq`&+7i#(Apa-k3O+P!`Ew%zalo%>Ha{qc0in>*g#F>A+BJ7)c1 zXHB0kYp~hLc)aVaU2pCjhb~mx&q&p0>ppvMSJbZPT}^g1-WA1@rn{V73|61jefELK zjvIDd_t}QeYWO|+vza@0?%c7H5r5|zcyZ_Yoj2?(+qrOi`SwZMhi@OYeem{y+bN~( z6SsZ4t>Tk!K3To>m3PbEoy-lPm0}Ej%m#QJ-Zfh_es`sNty_UsxR1Kk?i22M_i4Ar zeJ=bAxBvOat#uij^^g0aTWd|>U(Yd?ZN~OX*zhIh8N)Vs)A;a!d!rQ8znjlH*$K3L)1;H{z;Zt!08 zw$cOlc;Dder$%cUz13)|e@Kn_o&2NxSNvT82{Z}x2xK!oU@ZVw6P-`DHQ}O}$^FM+A=pBKquuDTu&-I@1@ARMX26;=o>&Vls z{$@&GIWxjd-kIJ){{#Ph|3hz)_mp?NcZ+v}|B1IU5Y1e1v$x9M9=O~)$G_LV%fG{4 z!(9V0*pW!X@cX*e2)qz-lwg0i7?so|^^FQAmE0sZ%Pmsrzbp62tFlpElQ-mZ-W^;b z`&rlhD!<7AsW;6{YZGr0Owfc(e>1=gG=t6KW}2C0jxtA^*=COao;lTAX|7@xzQ){V zo?w5`Uw)SXQpY>QW~>+6a7Npf^Tk-1Y}&~YCXO{~N117oq?G-@ER!O~n+!S9B+7~G z_fF!R@MP0d=Ccnu-Sn1)rk^ZgkFdn#%ThB!E-(dht{Evmv;Vx%6v{eNq>>RE&Q%$M-#D3^j_Br>O`Er{%R_^Bp-J|TO9yg2RF|$~n zGUv+fk%(e2SxlZ2Vmf+j0u|G7o%1+k8yUqRb zg?wYy$zDzYzcr8eYh{5vz}>^G<~DY~B4zA?ZZ~sfv$;XuVb}JqStalBHfIaF-0>zx zPGNWS2&a_u*cn~JE^HhptIwK?LOQPha4i=bY~>bsu3AdW>=CamJyi7>Sm-m#|*ClzI5F z@JxJ_do?50r|u4Sr~8?^%l+Kl?SAF%aldxI@mhE>UQ4f)*V=36#d>k>GhTbQ#_Qld z>veRW^Wxp-y##lI7j$3plH6J^*?rYZb6@w;-8Z~0?k2CR`=-~;eap*m-}bsQ^Ymb@ zf0vb5w)?)9<9^`fx*vMI+^t@3_am>5`>~hje&Y3Yw|V_ov-S5E`AhtB{R{nz{pJ4U z{uP`{wBl@`y%d`ca)RkDr9O<%c~z4tQqp_j1_zT8ZdE6gOh(i|>VnIq(C z_R80rBjpCpu5VX6}^joS*M9 zYvn8RpzPr+;%oD;^SQIz`O4YjeC>SWeCzCWE@l;Xsk6el%(>jT!YOz5IX^o4onM?^ zo!^|RS>Ij93h#R72IqkDJL@^)IJz>RX7vNmt#HfPlr zD=wyV zpYxpaJS)hToLc8)=N0Ew=L_dc=O=E*);aZVW4DRh-tEAOGS$rqul)zPLs(S~a|_r5 zjBs9aUU%ML_4%grmh-l=*&XGMcE`En-3e}ydzd@XdDnT5mFfG=2hNAiR_7!4aQ6te z#GUF+bEmsUx-*cfoarXAi|OWOIW?@ApJbQwxOO|O|$rFuPX-d zbhhqn@s^mA(!{VKeva(gYn^2wqIXCbI zqy3;iX7 z0i9v-KS5_&yp?FFC7>le3(kgkILG4Mh-%#6-Ha}_c&pGQ7JoZhX$i1`6D=?BG>qFU zK4&6wyT!i?U2XC2KqL5TFl#-5SBa`S@YJn7gFrjm9X;V`roUIA?% zuSU@F*$A)0S@1>#4S!RFA5hM*!f5+{3*H5->-Q|I3PrX=&~nxG`XOjMTO(-LA4T{a z)pAt!fwn(jH7T+UcEWzpa#ZSJm&G(k)jycl=x+EDvzF&q7864Ez&F_UN58e0!RTHK zHx`9A#$n7f^n3UT_p{KSExzVY(*c}N3oBh=r7Px2^nk@&gZ^&e?KWFdi_!YjbOWng zF&Gu?=gib$)E_f;8147W++j2f<5^@3+9(2Tj2S%)=c&TXZfS!?S%iHjGrgrP+QcG< zqfH~kqR|$ajB2<_JD_~SWqbtMB0?M*W8oVQF)br>L|a*O{LuOclZ0xTK*thR^p<2) z;{Y93Smj$%P>loRc(i?l477tq$1QdOmPC~L4%hjKXhMWcG-#2NP<5wdLC7K}qnbXY zCuo{L=A)VpB^y#Laypt8p*PyeA`8*Z5&EHw1&WS|tfDM~(5@C87g<$V@=?tj$WpX> zgb`>Di(G(eev|^xJb;{wYPyw?plJndv+NBlPocRMxe)CYp%B$PfLw(3i7*Pyi!c`L zYZ3Y*J1WaKRNF4drKq-7r3eOEWI3vNR>s3%i>yHNBTPVtSfm^s8bRCPFpI22HP1>h z47W%Hs%4~12hBgowW#JznF^X8r4&Y6!hKu&lJX>IK0)Us_JfvVP)#@JoWb7EG9T4^ zg3ev6<}Jsf6D>N2u)4RLhH8F5=KxmxmUGY}EIRhH1F&eD(R_l=73}LQi&4!Fh}P+} z2gI$Y7>u#Zi{kgD<2@{?_&c>{)1Fb*MIfRn{ zi`K8!6X-m{4$krjS{9)tdWA)PM6a^2`xkSyg>wKgl@?upaAIIld;JYMm$K`#Xghq) z;_%44X3;fb_|#A9LG9nLNExbipbP;mchL2h(Xv*w4z+wiHlq#PfcYJZsJTdExJZ9A4Iqb)p`P5FBr{_ax;8tk@4t`2r=j`i)fvH9w7()(xPiFZp>M< zp7vQp+n1KL(gXHe=!i`CB4zqAOjgL{GnE2?A4(V{FW3EMKfcB}4DD|Oe89VeNMa$SBZ_Y`W zDOcxY&^G-sx)9F6Oqn^fM`sCU%E_Vbou!!fpvyqp-*@Or(DI-RoQeoE8s~b8(LAoQ zXq`LMpQ3f^++r~wp|^sz$2zpi;-8N`WbujHdD!A>Sv_X)uSBaY{?+K?mOub~5-7_+ z6#6t!PJt$<)(7~c+tG5QoC3{J+O_j0_Sd3XMi7WYHLVcPy3+E3KzsBTl|Yq+O6VWhSF{opYnBS;z}S9HI_g!>R1A4C=QfBXVkL< zx}c3Lfo`a833Nv(7bVaWrCgK%eZg&P3G_lKBPBq4bemcNebH!3pg&6cR`gWbZD|SQ zqpd7~p=fJMpa7*D-4O0apefJ^Gi}?|bc3FIyXls|5vb;&EB3``h9xi+r60PaJunT; zwFG9On!bV9m!cXs1m>W_ErDavS(dX$Yb=6LkN2=h?tOmU{5 z7e_b-T?Wgs*EFxNXrFX1w>U?lS6CcPbGe1v-{M{gx8ip&dOO^WnSSryV{tUU_gb`n zyKCVA+$=)rFN&k-dJvw)tmW{WMf(=w2(!=+BOHa&55gRcZjUgVJ*_~1-{ixKf@sW-pv{1G<8RqSI=U?Xj;lGTHc)v}XLO1jwi@tmH9*&TKK5B8_Mjwm7nBzTRaW|t+M(BZR`BIkJraUb> zg?jZgeM&ZHnn2r^r|D2~K*Iv}162Jhx$v$<+o1PegkIDR{yFGKi@yjhgi(zD zj6(_IEdF`u1dGpDkx*puFGeR?{7cXyEdFwI3efKT%h72TzZ_j<@fV}CAH^?2pS1WZ zMS{LXh$k4Z=pH>tA60~~gY;8H_u0Yb79qZ13ybc#gY7JG0vc=4eQGddkyFtmi|#dp zsTMf{r5!7}zYNkA6*&{7{VBS?3}##O#!rwoq3B*Ms9}LDL#ca3_iRDxTan994HtAD z7R<8Q9j?Q0h$4{aJ93MXp2#TXcUG%(uu@=n#wU)q+DUay3f5E4ptB z7FgtZbht(LVZjj=xdEkZD7q&L(l!*i5v7eNx<3nQT0zeygPJ}tr=VINpl5}_5{vFF zf>SMeUKpHa;f)dhHi<=^L^T~?%216P^c*p$@qwXD21_kMzYWf^7_Ez=Eb=^hw1qcN z5}aqzbHw0@7T!up@FWYjKP7mw#b{k<+#sK#8XxfXN`mKGWCwbIg*RFfTx!wtzTkxx z-f~G$!va0y3u;}0?ty|@Paxl+S~tMkFbQfO0Qnxh#=;lZ61>)8^3dxnM#H<=qGzeW zN{gPY2XD3LSzYipi{zuXTlCy6xY{B^&^s)8h8MikB16%;EP9?7)cgbAJxNgW40^T~ zyvHI1sOA~;oG++t0%SOPpGD97g7;fQ+u8#bJ^u@8xq#5-f)85sEHL@g zMc-Ql-?r%aM{u)6-(dvbvFKSy@Lh|((+Iw2(Q}dD7K^^$2)=L8Gm_v37Sa0u(4uD^ z!L1g3cM<%^qURsMk1hHhBlw9$&q9LREc$LExZPqFqMusyT}N<-#hiuiwCH(%@H30K z1>I#4P1olZQ;F`jh^FNW3vY=f_@zbP2L!*e@a9$=sSeq&lcWT zOK`u1uLLCci^Wh@i3FW!SYwmdL_ zuEd_QNW2QJ!%SHuRsiMgyo*-Ct=J!q-UfGJ*78^b58&n#vMB&JXBg7I!3C4UZEJX-d?xeiHK~=z5Eui6m;dgG<>ZYPo~U7?P;v4z8AE zjm6cndDh}mE{R(1;Eq9`x47CCHdx%TsMZJQ`9$JN7IzX_3onzNYtUEVRm?Y`nkI1G zLA6Xl_wk90rHZTd_J+mPdfNnVV&4*d3*N@u2Gz0#J)cN?&*HX2x4`>^Pgy5^03Twe z4iZ1I=y^fn#}=3Nk*M_n?pf$I*nv3%WlT%_409s7%i?xJKexD9=x+Fe@U{HDgs(7D z2Z?(udXAO&H84)O=b+zOTy3-8TihwA)+@M^(R~)T82!oO_D6rVxHHlH@C$K0jQ$G0 zVb(f1V9~Rx#NRFMX=t6rJw+rGumr9^TUm7P8)^-dtG5DeYtcP$h%!~YJJC33kGTx( zVDXls@sNN${U#K&co(7}NWz|e5K6Y_{yEgi;!)31&_2xfXvJS_YS3pNn1wmt)qnthD&6&|5A3edub7e?NLBkPn}B z8`5-u{~)UQ0skR%t;N?gs~_+mN7WtA{fE(Y@CarIRa^WgP<4m;kD*UleA;Rf^{)7| z(+CY_|Sq)Qj+D%~VQx=Rnqlq~5f*^(o<(yQUFHF?ro(uc`3?nGB|Tjm$p zFTZjVpy!Bp>-tKDc}caYzpz>g5+0`>+?g}FS97Hy6dHb9L6s@xhm(Ot*Cb4CMrcHpn>J!%aY{*O zd1(2l*~>#CLUU)$uJY2t%7Zz}OEN=MGO74D{+?W%RFz-S@t|=|Nl8D#@iZK~;Cy)r zAsinG0S#Ma{*I$Y8Dm0KZl|K+!-}iQ3OZKh7nF2NN(v3Hswpb2swwE0R8oQ~|6oc< z@#5p+B54kgX1^=XqiiUXimUQFR!Pb7B{96(lob&el9JR>EmD$Fl1OJs0dY6Z7&EDOI4Mmk>CUFE8y9RHr<-|*Taew% zV{Sq3u1Reqs@r2;e#FGB^wPoso!Y6TQ#c?aRZa3xqo_c)DzVw4+Da!DR~gMrm7dVh zONQ~bb#nOTUvzyA|Jueb{*@IU2Eh_2hgy19!ym>XT1WUjv6IF4u!*%x0WijS>A=|9 zs1zz0gQ7qcyTBTes6yDwkg-Ul3FB$g7~pp_{-bL}n&pc$&w!mGElPo~V`y$I@!JZ& zt+RkJr%ky?yJ)~ZHV)Q`#1TduzuQ-cbjX8kA{{r2#Mf{xir-)eFeerR;f5-iYw}?? z<2rW9^I;iapIi;NN#9|eDZ8~ndcn}Y{ zFcxORQjx9&fWNNz>x#dws{wyq@z)i9-8{fw25HV9%^9RQqgbSS9FW)U$6Pop3-TvkhcG0Za$dkhv1pa^;nWMq##3hFDVOm(fijyw znN1+=6G;06(msK-7loh_h@)t~$YC*%4*5_FTVbEb#Arx`0WcZxJ8^}`Bk zNO7u23GPd9UxND*+?U|K1ous{LaAd4E)W&-wgcC#NSN(&BWhK{LP#X%b-%E zl=RIigi=@t<*){7U<>T!csdF~kOxID7s{Xls-PCO!G4acV;~*!p_rrUQjt06F>yd# z$5JM93FEjtk>k~fHyKSGy?H~caH~zbI*FNnpObM@1<_;rEKn{Y}UpA;jN{-*A~NkK37=5rwVIC9+=Fh3Gg6s zKZLu72;<=eu!YYNYWNIcF4s=+_b9)s<6teH8sPtlJUGDT1xtAy$n&QN|Eb+vA+6=p zf^{M_(?yD20Vk4r`zWw!mIKZ-{~r5vb_Fdvoy;k=H!*EhlL$R{3gXciPgDJ+C?SOYb%1@`g@NEC!14~k$eltBelK`m^9 z{UUG1Ksw|@G0cZ$Pzlwr33l7hN8XAm8mNISuvg^mC5vb_FdvpdB~-&E*e&voKpbR2A(X;GD2Fvr16yD(pSeUqI^gczxv&h@ zKrQU%^Oq<{heDVOWl#x(@!q!Z6<663Li3>%%AgWzU>oe`QyJ3oejXIVLa2ah*aG`S zK8S-nDCUzI`um62ZKXedMBE?Ik3U)kRj>i}@JUSwa$z}^{JRCq_++OT=0-l* z!Ov&J^BLiMM%ksk^7$1Sjz&wEzGI@kb& z_47g?E&Jz*{E`c`fWKcibN)qIe;WXk0rv+=`OK#cRC6AN))80zRxxIy81C5_cfJ@e zUreJY;I}_nOrRJxiHRx|(>M;&f!|Fk#Wclj(;DD+)7@g4Z4uKPf6Z6HTG#-aVUL&= z9<+fBC;-Ba!GBAEv4H=U`^B_^HY)*byHQNL*|11VY${+EmkY$%z8v`7fwXogh51kh zn_(xP)hvW%fSZH`fL#zb!F^(Q7iK~+P%S2jv?k|45zG~nG97TA8V{s3bpT9;y^&97 zwutG(^G-_vznzJ*GwJM1`0RU4`aD3pM8g`u%pTTsTgfLfgwsO+x0&n3WUUa>lixkp ziOI%oP8_TflS^81xADmf>Fs<~-8Tw*qkAw+1!=&-?PcAJ6-xLmm{t zTt0PKAZ7qz4Jw2!Vg{pwi9f$q%n+UrO^1DAhLwsbAWy@IZ-fV%#f-#mBDE=983sK1GQG%;P7+Y#=P9*$EwS0;~IERN|51*hEbA@RUpPP&Y!YSSf2gH=L0n$-|UCCZP zJ3*&q!E{&v#4|k_QeglT!8}+68-Z}96V8#ub0q$bB%UM7U=3`7{al5Lf_Rt<!0%)EeXRZ_J#)#+aT#Kc$NvfVIe~PZD6mb;No&QNjGI%6#GFc4rxwFL zF{iB;vtTl85OewfSjA^0xH*F`&y0roViraLc4rahS-3wN^VyrloU>ZYq5?6Cv0se4 z#e}zHwiwp?=3LBWb72eY6>}b8oJX3^%LDwM$FuXwpaQC(7D(rL`^B6e1L=?trLYjn zVGYy(?k=bnvlRQK*e}KYLi9pao?o~H_KLYE3PO+vMKBlea}jPY!tF)4y$H7#;r3$O zUX0s|aeFatFUIY~Wl#ZCPz&3{FvOZ=HGscm_`3vumxKU+m*DRb{9RH8_*=dRRsvwiIhynaxf&VM;f5m*j{}uSZ0{>TRg5CDBr}8*73ksnW7D73!fg0EX zd--HEhR=Rdp_Wg6$lulE@9GV(750f)84Ww(fS7CAKn4`RbXWi@06*8@=NkN6gP&{h zb8RXNfXOfqmWsKKbX-R|t|J}Sk&f#~$91Hm0{aT=E3mJ?z5@FSwI_YoM?nbkpa|wd z8B{M$&a7=~_j)R*|k%q-z!FT1C26k*-y%U>$6P zop3H0p3SheZ6zFE$-cl&0G7eUXVUK5S<=L%-b8EGj+eqhaS&$E;^)|w}JsRR+ z8Ib1N*N9gd6@7X-pMCsxO*fHFh9B!Rsqi+TLh%7n((R#uNrsNWnv!3?c;>;1ZjDKaGxxN zg+QL3Tq9qzm9%fn6Z0BzyoUYjOU1k~83HWS|F3Rnv~+q@Ze!vQhx z#6T+K!B{8-((n#>d1n<6&pR7n3+xg7#L2wd2GU^w6v1p*2rHlx)`@wKFyEU8#KU^t zydQ#UKF2DB^_7QGAQv02-U(CnRKp3ps&Bui>9p=MQ zr~v$YO!yzyiuoiDwu#wR3~S+lnCb&4@V*%fYXHCB&WFun_F}(xgP8BK zfM?%N2EzIQ-4_GpVpxZp9|`M6{QX4we#Xzw^PpDD{x~4M{VT-$LioQ%0pa~dnhx;n zz#cKIz0L0npaN=Ox0pJf*QfJFI71v01slb2W{cy_6UU2(4dVD{0HVf<(->`%FHX}q zaiUYjX%;O`bNn~oFHVc~;>0Wyr{w@xBTlOYuokdywGsA;(}u9y;HC}sZ8pI^aoQ4A zTl};wg{6RB*4|EA+_!53c`zNyU^Uc=6T1O+ixZatlVPPe?PDMn2&+AA+t-NG0skH5 z!e((g#slu+aTlKslf_Ax4GY8xjs?<_7=kRwhf3HcPKdN7Ed%0ACauZ%OI`!GPd*?{ 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 !Ih$)5?K~W=vG3ozB3)0nf!55x3ZA5aar=Ra8Fj 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 WZJ|m11)WV1+;LQ8al| netstandard2.0 + Avalonia + + %(Filename) + + + + @@ -14,7 +21,10 @@ - + + + + diff --git a/src/Avalonia.Diagnostics/DevTools.xaml b/src/Avalonia.Diagnostics/DevTools.xaml deleted file mode 100644 index 1df0f3a097..0000000000 --- a/src/Avalonia.Diagnostics/DevTools.xaml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - Hold Ctrl+Shift over a control to inspect. - - Focused: - - - Pointer Over: - - - - diff --git a/src/Avalonia.Diagnostics/DevTools.xaml.cs b/src/Avalonia.Diagnostics/DevTools.xaml.cs deleted file mode 100644 index 037e80e372..0000000000 --- a/src/Avalonia.Diagnostics/DevTools.xaml.cs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reactive.Linq; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Diagnostics.ViewModels; -using Avalonia.Input; -using Avalonia.Input.Raw; -using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; -using Avalonia.Rendering; -using Avalonia.VisualTree; - -namespace Avalonia -{ - public static class DevToolsExtensions - { - public static void AttachDevTools(this TopLevel control) - { - Diagnostics.DevTools.Attach(control, new KeyGesture(Key.F12)); - } - - public static void AttachDevTools(this TopLevel control, KeyGesture gesture) - { - Diagnostics.DevTools.Attach(control, gesture); - } - - public static void OpenDevTools(this TopLevel control) - { - Diagnostics.DevTools.OpenDevTools(control); - } - } -} - -namespace Avalonia.Diagnostics -{ - public class DevTools : UserControl - { - private static readonly Dictionary s_open = new Dictionary(); - private static readonly HashSet s_visualTreeRoots = new HashSet(); - private readonly IDisposable _keySubscription; - - public DevTools(IControl root) - { - InitializeComponent(); - Root = root; - DataContext = new DevToolsViewModel(root); - - _keySubscription = InputManager.Instance.Process - .OfType() - .Subscribe(RawKeyDown); - } - - // HACK: needed for XAMLIL, will fix that later - public DevTools() - { - } - - public IControl Root { get; } - - public static IDisposable Attach(TopLevel control, KeyGesture gesture) - { - void PreviewKeyDown(object sender, KeyEventArgs e) - { - if (gesture.Matches(e)) - { - OpenDevTools(control); - } - } - - return control.AddHandler( - KeyDownEvent, - PreviewKeyDown, - RoutingStrategies.Tunnel); - } - - internal static void OpenDevTools(TopLevel control) - { - if (s_open.TryGetValue(control, out var devToolsWindow)) - { - devToolsWindow.Activate(); - } - else - { - var devTools = new DevTools(control); - - devToolsWindow = new Window - { - Width = 1024, - Height = 512, - Content = devTools, - DataTemplates = { new ViewLocator() }, - Title = "Avalonia DevTools" - }; - - devToolsWindow.Closed += devTools.DevToolsClosed; - s_open.Add(control, devToolsWindow); - MarkAsDevTool(devToolsWindow); - devToolsWindow.Show(); - } - } - - private void DevToolsClosed(object sender, EventArgs e) - { - var devToolsWindow = (Window)sender; - var devTools = (DevTools)devToolsWindow.Content; - s_open.Remove((TopLevel)devTools.Root); - RemoveDevTool(devToolsWindow); - _keySubscription.Dispose(); - devToolsWindow.Closed -= DevToolsClosed; - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - - private void RawKeyDown(RawKeyEventArgs e) - { - const RawInputModifiers modifiers = RawInputModifiers.Control | RawInputModifiers.Shift; - - if (e.Modifiers == modifiers) - { - var point = (Root.VisualRoot as IInputRoot)?.MouseDevice?.GetPosition(Root) ?? default(Point); - var control = Root.GetVisualsAt(point, x => (!(x is AdornerLayer) && x.IsVisible)) - .FirstOrDefault(); - - if (control != null) - { - var vm = (DevToolsViewModel)DataContext; - vm.SelectControl((IControl)control); - } - } - } - - /// - /// Marks a visual as part of the DevTools, so it can be excluded from event tracking. - /// - /// The visual whose root is to be marked. - public static void MarkAsDevTool(IVisual visual) - { - s_visualTreeRoots.Add(visual.GetVisualRoot()); - } - - public static void RemoveDevTool(IVisual visual) - { - s_visualTreeRoots.Remove(visual.GetVisualRoot()); - } - - public static bool BelongsToDevTool(IVisual visual) - { - return s_visualTreeRoots.Contains(visual.GetVisualRoot()); - } - } -} diff --git a/src/Avalonia.Diagnostics/DevToolsExtensions.cs b/src/Avalonia.Diagnostics/DevToolsExtensions.cs new file mode 100644 index 0000000000..8083d4bc58 --- /dev/null +++ b/src/Avalonia.Diagnostics/DevToolsExtensions.cs @@ -0,0 +1,19 @@ +using Avalonia.Controls; +using Avalonia.Diagnostics; +using Avalonia.Input; + +namespace Avalonia +{ + public static class DevToolsExtensions + { + public static void AttachDevTools(this TopLevel root) + { + DevTools.Attach(root, new KeyGesture(Key.F12)); + } + + public static void AttachDevTools(this TopLevel root, KeyGesture gesture) + { + DevTools.Attach(root, gesture); + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/Converters/BoolToBrushConverter.cs b/src/Avalonia.Diagnostics/Diagnostics/Converters/BoolToBrushConverter.cs new file mode 100644 index 0000000000..37ba5155fd --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Converters/BoolToBrushConverter.cs @@ -0,0 +1,22 @@ +using System; +using System.Globalization; +using Avalonia.Data.Converters; +using Avalonia.Media; + +namespace Avalonia.Diagnostics.Converters +{ + internal class BoolToBrushConverter : IValueConverter + { + public IBrush Brush { get; set; } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return (bool)value ? Brush : Brushes.Transparent; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/DevTools.cs b/src/Avalonia.Diagnostics/Diagnostics/DevTools.cs new file mode 100644 index 0000000000..0464047273 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/DevTools.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Reactive.Disposables; +using Avalonia.Controls; +using Avalonia.Diagnostics.Views; +using Avalonia.Input; +using Avalonia.Interactivity; + +namespace Avalonia.Diagnostics +{ + public static class DevTools + { + private static readonly Dictionary s_open = new Dictionary(); + + public static IDisposable Attach(TopLevel root, KeyGesture gesture) + { + void PreviewKeyDown(object sender, KeyEventArgs e) + { + if (gesture.Matches(e)) + { + Open(root); + } + } + + return root.AddHandler( + InputElement.KeyDownEvent, + PreviewKeyDown, + RoutingStrategies.Tunnel); + } + + public static IDisposable Open(TopLevel root) + { + if (s_open.TryGetValue(root, out var window)) + { + window.Activate(); + } + else + { + window = new MainWindow + { + Width = 1024, + Height = 512, + Root = root, + }; + + window.Closed += DevToolsClosed; + s_open.Add(root, window); + window.Show(); + } + + return Disposable.Create(() => window?.Close()); + } + + private static void DevToolsClosed(object sender, EventArgs e) + { + var window = (MainWindow)sender; + s_open.Remove(window.Root); + window.Closed -= DevToolsClosed; + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleContext.cs b/src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleContext.cs new file mode 100644 index 0000000000..5927bd785e --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleContext.cs @@ -0,0 +1,36 @@ +#pragma warning disable IDE1006 // Naming Styles + +using Avalonia.Diagnostics.ViewModels; + +namespace Avalonia.Diagnostics.Models +{ + public class ConsoleContext + { + private readonly ConsoleViewModel _owner; + + internal ConsoleContext(ConsoleViewModel owner) => _owner = owner; + + public readonly string help = @"Welcome to Avalonia DevTools. Here you can execute arbitrary C# code using Roslyn scripting. + +The following variables are available: + +e: The control currently selected in the logical or visual tree view +root: The root of the visual tree + +The following commands are available: + +clear(): Clear the output history +"; + + public dynamic e { get; internal set; } + public dynamic root { get; internal set; } + + internal static object NoOutput { get; } = new object(); + + public object clear() + { + _owner.History.Clear(); + return NoOutput; + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleHistoryItem.cs b/src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleHistoryItem.cs new file mode 100644 index 0000000000..8fad299f60 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleHistoryItem.cs @@ -0,0 +1,19 @@ +using System; +using Avalonia.Media; + +namespace Avalonia.Diagnostics.Models +{ + public class ConsoleHistoryItem + { + public ConsoleHistoryItem(string input, object output) + { + Input = input; + Output = output; + Foreground = output is Exception ? Brushes.Red : Brushes.Green; + } + + public string Input { get; } + public object Output { get; } + public IBrush Foreground { get; } + } +} diff --git a/src/Avalonia.Diagnostics/Models/EventChainLink.cs b/src/Avalonia.Diagnostics/Diagnostics/Models/EventChainLink.cs similarity index 100% rename from src/Avalonia.Diagnostics/Models/EventChainLink.cs rename to src/Avalonia.Diagnostics/Diagnostics/Models/EventChainLink.cs diff --git a/src/Avalonia.Diagnostics/ViewLocator.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewLocator.cs similarity index 70% rename from src/Avalonia.Diagnostics/ViewLocator.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewLocator.cs index a66703301d..c06fbec801 100644 --- a/src/Avalonia.Diagnostics/ViewLocator.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewLocator.cs @@ -1,13 +1,11 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - using System; using Avalonia.Controls; using Avalonia.Controls.Templates; +using Avalonia.Diagnostics.ViewModels; namespace Avalonia.Diagnostics { - internal class ViewLocator : IDataTemplate + internal class ViewLocator : IDataTemplate { public bool SupportsRecycling => false; @@ -28,7 +26,7 @@ namespace Avalonia.Diagnostics public bool Match(object data) { - return data is TViewModel; + return data is ViewModelBase; } } } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs new file mode 100644 index 0000000000..56d274111d --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs @@ -0,0 +1,120 @@ +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using Avalonia.Collections; +using Avalonia.Data.Converters; + +namespace Avalonia.Diagnostics.ViewModels +{ + internal class AvaloniaPropertyViewModel : PropertyViewModel + { + private readonly AvaloniaObject _target; + private object _value; + private string _priority; + private TypeConverter _converter; + private string _group; + private DataGridCollectionView _bindingsView; + + public AvaloniaPropertyViewModel(AvaloniaObject o, AvaloniaProperty property) + { + _target = o; + Property = property; + + Name = property.IsAttached ? + $"[{property.OwnerType.Name}.{property.Name}]" : + property.Name; + + if (property.IsDirect) + { + _group = "Properties"; + Priority = "Direct"; + } + + Update(); + } + + public AvaloniaProperty Property { get; } + public override object Key => Property; + public override string Name { get; } + public bool IsAttached => Property.IsAttached; + + public string Priority + { + get => _priority; + private set => RaiseAndSetIfChanged(ref _priority, value); + } + + public override string Value + { + get + { + if (_value == null) + { + return "(null)"; + } + + return Converter?.CanConvertTo(typeof(string)) == true ? + Converter.ConvertToString(_value) : + _value.ToString(); + } + set + { + try + { + var convertedValue = Converter?.CanConvertFrom(typeof(string)) == true ? + Converter.ConvertFromString(value) : + DefaultValueConverter.Instance.ConvertBack(value, Property.PropertyType, null, CultureInfo.CurrentCulture); + _target.SetValue(Property, convertedValue); + } + catch { } + } + } + + public override string Group + { + get => _group; + } + + private TypeConverter Converter + { + get + { + if (_converter == null) + { + _converter = TypeDescriptor.GetConverter(_value.GetType()); + } + + return _converter; + } + } + + public override void Update() + { + if (Property.IsDirect) + { + RaiseAndSetIfChanged(ref _value, _target.GetValue(Property), nameof(Value)); + } + else + { + var val = _target.GetDiagnostic(Property); + + RaiseAndSetIfChanged(ref _value, val?.Value, nameof(Value)); + + if (val != null) + { + SetGroup(IsAttached ? "Attached Properties" : "Properties"); + Priority = val.Priority.ToString(); + } + else + { + SetGroup(Priority = "Unset"); + } + } + } + + private void SetGroup(string group) + { + RaiseAndSetIfChanged(ref _group, group, nameof(Group)); + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs new file mode 100644 index 0000000000..3fe6c93d28 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs @@ -0,0 +1,82 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Reflection; +using Avalonia.Data.Converters; + +namespace Avalonia.Diagnostics.ViewModels +{ + internal class ClrPropertyViewModel : PropertyViewModel + { + private readonly object _target; + private object _value; + private TypeConverter _converter; + + public ClrPropertyViewModel(object o, PropertyInfo property) + { + _target = o; + Property = property; + + if (!property.DeclaringType.IsInterface) + { + Name = property.Name; + } + else + { + Name = property.DeclaringType.Name + '.' + property.Name; + } + + Update(); + } + + public PropertyInfo Property { get; } + public override object Key => Name; + public override string Name { get; } + public override string Group => "CLR Properties"; + + public override string Value + { + get + { + if (_value == null) + { + return "(null)"; + } + + return Converter?.CanConvertTo(typeof(string)) == true ? + Converter.ConvertToString(_value) : + _value.ToString(); + } + set + { + try + { + var convertedValue = Converter?.CanConvertFrom(typeof(string)) == true ? + Converter.ConvertFromString(value) : + DefaultValueConverter.Instance.ConvertBack(value, Property.PropertyType, null, CultureInfo.CurrentCulture); + Property.SetValue(_target, convertedValue); + } + catch { } + } + } + + private TypeConverter Converter + { + get + { + if (_converter == null) + { + _converter = TypeDescriptor.GetConverter(_value.GetType()); + } + + return _converter; + } + } + + public override void Update() + { + var val = Property.GetValue(_target); + RaiseAndSetIfChanged(ref _value, val, nameof(Value)); + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ConsoleViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ConsoleViewModel.cs new file mode 100644 index 0000000000..67adc255a2 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ConsoleViewModel.cs @@ -0,0 +1,112 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using Avalonia.Collections; +using Avalonia.Diagnostics.Models; +using Microsoft.CodeAnalysis.CSharp.Scripting; +using Microsoft.CodeAnalysis.Scripting; + +namespace Avalonia.Diagnostics.ViewModels +{ + internal class ConsoleViewModel : ViewModelBase + { + readonly ConsoleContext _context; + readonly Action _updateContext; + private int _historyIndex = -1; + private string _input; + private bool _isVisible; + private ScriptState _state; + + public ConsoleViewModel(Action updateContext) + { + _context = new ConsoleContext(this); + _updateContext = updateContext; + } + + public string Input + { + get => _input; + set => RaiseAndSetIfChanged(ref _input, value); + } + + public bool IsVisible + { + get => _isVisible; + set => RaiseAndSetIfChanged(ref _isVisible, value); + } + + public AvaloniaList History { get; } = new AvaloniaList(); + + public async Task Execute() + { + if (string.IsNullOrWhiteSpace(Input)) + { + return; + } + + try + { + var options = ScriptOptions.Default + .AddReferences(Assembly.GetAssembly(typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo))); + + _updateContext(_context); + + if (_state == null) + { + _state = await CSharpScript.RunAsync(Input, options: options, globals: _context); + } + else + { + _state = await _state.ContinueWithAsync(Input); + } + + if (_state.ReturnValue != ConsoleContext.NoOutput) + { + History.Add(new ConsoleHistoryItem(Input, _state.ReturnValue ?? "(null)")); + } + } + catch (Exception ex) + { + History.Add(new ConsoleHistoryItem(Input, ex)); + } + + Input = string.Empty; + _historyIndex = -1; + } + + public void HistoryUp() + { + if (History.Count > 0) + { + if (_historyIndex == -1) + { + _historyIndex = History.Count - 1; + } + else if (_historyIndex > 0) + { + --_historyIndex; + } + + Input = History[_historyIndex].Input; + } + } + + public void HistoryDown() + { + if (History.Count > 0 && _historyIndex >= 0) + { + if (_historyIndex == History.Count - 1) + { + _historyIndex = -1; + Input = string.Empty; + } + else + { + Input = History[++_historyIndex].Input; + } + } + } + + public void ToggleVisibility() => IsVisible = !IsVisible; + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs new file mode 100644 index 0000000000..e712241282 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using Avalonia.Collections; +using Avalonia.VisualTree; + +namespace Avalonia.Diagnostics.ViewModels +{ + internal class ControlDetailsViewModel : ViewModelBase, IDisposable + { + private readonly IVisual _control; + private readonly IDictionary> _propertyIndex; + private AvaloniaPropertyViewModel _selectedProperty; + private string _propertyFilter; + + public ControlDetailsViewModel(IVisual control, string propertyFilter) + { + _control = control; + + var properties = GetAvaloniaProperties(control) + .Concat(GetClrProperties(control)) + .OrderBy(x => x, PropertyComparer.Instance) + .ThenBy(x => x.Name) + .ToList(); + + _propertyIndex = properties.GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.ToList()); + _propertyFilter = propertyFilter; + + var view = new DataGridCollectionView(properties); + view.GroupDescriptions.Add(new DataGridPathGroupDescription(nameof(AvaloniaPropertyViewModel.Group))); + view.Filter = FilterProperty; + PropertiesView = view; + + if (control is INotifyPropertyChanged inpc) + { + inpc.PropertyChanged += ControlPropertyChanged; + } + + if (control is AvaloniaObject ao) + { + ao.PropertyChanged += ControlPropertyChanged; + } + } + + public IEnumerable Classes + { + get; + private set; + } + + public DataGridCollectionView PropertiesView { get; } + + public string PropertyFilter + { + get => _propertyFilter; + set + { + if (RaiseAndSetIfChanged(ref _propertyFilter, value)) + { + PropertiesView.Refresh(); + } + } + } + + public AvaloniaPropertyViewModel SelectedProperty + { + get => _selectedProperty; + set => RaiseAndSetIfChanged(ref _selectedProperty, value); + } + + public void Dispose() + { + if (_control is INotifyPropertyChanged inpc) + { + inpc.PropertyChanged -= ControlPropertyChanged; + } + + if (_control is AvaloniaObject ao) + { + ao.PropertyChanged -= ControlPropertyChanged; + } + } + + private IEnumerable GetAvaloniaProperties(object o) + { + if (o is AvaloniaObject ao) + { + return AvaloniaPropertyRegistry.Instance.GetRegistered(ao) + .Concat(AvaloniaPropertyRegistry.Instance.GetRegisteredAttached(ao.GetType())) + .Select(x => new AvaloniaPropertyViewModel(ao, x)); + } + else + { + return Enumerable.Empty(); + } + } + + private IEnumerable GetClrProperties(object o) + { + foreach (var p in GetClrProperties(o, o.GetType())) + { + yield return p; + } + + foreach (var i in o.GetType().GetInterfaces()) + { + foreach (var p in GetClrProperties(o, i)) + { + yield return p; + } + } + } + + private IEnumerable GetClrProperties(object o, Type t) + { + return t.GetProperties() + .Where(x => x.GetIndexParameters().Length == 0) + .Select(x => new ClrPropertyViewModel(o, x)); + } + + private void ControlPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) + { + if (_propertyIndex.TryGetValue(e.Property, out var properties)) + { + foreach (var property in properties) + { + property.Update(); + } + } + } + + private void ControlPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (_propertyIndex.TryGetValue(e.PropertyName, out var properties)) + { + foreach (var property in properties) + { + property.Update(); + } + } + } + + private bool FilterProperty(object arg) + { + if (!string.IsNullOrWhiteSpace(PropertyFilter) && arg is PropertyViewModel property) + { + return property.Name.IndexOf(PropertyFilter, StringComparison.OrdinalIgnoreCase) != -1; + } + + return true; + } + + private class PropertyComparer : IComparer + { + public static PropertyComparer Instance { get; } = new PropertyComparer(); + + public int Compare(PropertyViewModel x, PropertyViewModel y) + { + var groupX = GroupIndex(x.Group); + var groupY = GroupIndex(y.Group); + + if (groupX != groupY) + { + return groupX - groupY; + } + else + { + return string.Compare(x.Name, y.Name); + } + } + + private int GroupIndex(string group) + { + switch (group) + { + case "Properties": return 0; + case "Attached Properties": return 1; + case "CLR Properties": return 2; + default: return 3; + } + } + } + } +} diff --git a/src/Avalonia.Diagnostics/ViewModels/EventOwnerTreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventOwnerTreeNode.cs similarity index 98% rename from src/Avalonia.Diagnostics/ViewModels/EventOwnerTreeNode.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventOwnerTreeNode.cs index 7e38749a6f..773140c446 100644 --- a/src/Avalonia.Diagnostics/ViewModels/EventOwnerTreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventOwnerTreeNode.cs @@ -19,7 +19,7 @@ namespace Avalonia.Diagnostics.ViewModels InputElement.PointerReleasedEvent, InputElement.PointerPressedEvent }; - public EventOwnerTreeNode(Type type, IEnumerable events, EventsViewModel vm) + public EventOwnerTreeNode(Type type, IEnumerable events, EventsPageViewModel vm) : base(null, type.Name) { Children = new AvaloniaList(events.OrderBy(e => e.Name) diff --git a/src/Avalonia.Diagnostics/ViewModels/EventTreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs similarity index 85% rename from src/Avalonia.Diagnostics/ViewModels/EventTreeNode.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs index 36f1904253..f017a50ea9 100644 --- a/src/Avalonia.Diagnostics/ViewModels/EventTreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs @@ -3,6 +3,7 @@ using System; using Avalonia.Diagnostics.Models; +using Avalonia.Diagnostics.Views; using Avalonia.Interactivity; using Avalonia.Threading; using Avalonia.VisualTree; @@ -12,11 +13,11 @@ namespace Avalonia.Diagnostics.ViewModels internal class EventTreeNode : EventTreeNodeBase { private readonly RoutedEvent _event; - private readonly EventsViewModel _parentViewModel; + private readonly EventsPageViewModel _parentViewModel; private bool _isRegistered; private FiredEvent _currentEvent; - public EventTreeNode(EventOwnerTreeNode parent, RoutedEvent @event, EventsViewModel vm) + public EventTreeNode(EventOwnerTreeNode parent, RoutedEvent @event, EventsPageViewModel vm) : base(parent, @event.Name) { Contract.Requires(@event != null); @@ -65,7 +66,7 @@ namespace Avalonia.Diagnostics.ViewModels { if (!_isRegistered || IsEnabled == false) return; - if (sender is IVisual v && DevTools.BelongsToDevTool(v)) + if (sender is IVisual v && BelongsToDevTool(v)) return; var s = sender; @@ -94,5 +95,20 @@ namespace Avalonia.Diagnostics.ViewModels else handler(); } + + private static bool BelongsToDevTool(IVisual v) + { + while (v != null) + { + if (v is MainView || v is MainWindow) + { + return true; + } + + v = v.VisualParent; + } + + return false; + } } } diff --git a/src/Avalonia.Diagnostics/ViewModels/EventTreeNodeBase.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNodeBase.cs similarity index 100% rename from src/Avalonia.Diagnostics/ViewModels/EventTreeNodeBase.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNodeBase.cs diff --git a/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventsPageViewModel.cs similarity index 69% rename from src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventsPageViewModel.cs index 1c868148ce..0d58952687 100644 --- a/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventsPageViewModel.cs @@ -12,12 +12,12 @@ using Avalonia.Media; namespace Avalonia.Diagnostics.ViewModels { - internal class EventsViewModel : ViewModelBase, IDevToolViewModel + internal class EventsPageViewModel : ViewModelBase { private readonly IControl _root; private FiredEvent _selectedEvent; - public EventsViewModel(IControl root) + public EventsPageViewModel(IControl root) { _root = root; @@ -45,17 +45,4 @@ namespace Avalonia.Diagnostics.ViewModels RecordedEvents.Clear(); } } - - internal class BoolToBrushConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return (bool)value ? Brushes.Green : Brushes.Transparent; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } } diff --git a/src/Avalonia.Diagnostics/ViewModels/FiredEvent.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/FiredEvent.cs similarity index 100% rename from src/Avalonia.Diagnostics/ViewModels/FiredEvent.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/FiredEvent.cs diff --git a/src/Avalonia.Diagnostics/ViewModels/LogicalTreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs similarity index 65% rename from src/Avalonia.Diagnostics/ViewModels/LogicalTreeNode.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs index 0b9bd85b4f..a7c2997346 100644 --- a/src/Avalonia.Diagnostics/ViewModels/LogicalTreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs @@ -1,6 +1,3 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - using Avalonia.Collections; using Avalonia.Controls; using Avalonia.LogicalTree; @@ -17,7 +14,8 @@ namespace Avalonia.Diagnostics.ViewModels public static LogicalTreeNode[] Create(object control) { - return control is ILogical logical ? new[] { new LogicalTreeNode(logical, null) } : null; + var logical = control as ILogical; + return logical != null ? new[] { new LogicalTreeNode(logical, null) } : null; } } } diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs new file mode 100644 index 0000000000..7addaba977 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs @@ -0,0 +1,126 @@ +using System; +using Avalonia.Controls; +using Avalonia.Diagnostics.Models; +using Avalonia.Input; + +namespace Avalonia.Diagnostics.ViewModels +{ + internal class MainViewModel : ViewModelBase, IDisposable + { + private readonly IControl _root; + private readonly TreePageViewModel _logicalTree; + private readonly TreePageViewModel _visualTree; + private readonly EventsPageViewModel _events; + private ViewModelBase _content; + private int _selectedTab; + private string _focusedControl; + private string _pointerOverElement; + + public MainViewModel(IControl root) + { + _root = root; + _logicalTree = new TreePageViewModel(LogicalTreeNode.Create(root)); + _visualTree = new TreePageViewModel(VisualTreeNode.Create(root)); + _events = new EventsPageViewModel(root); + + UpdateFocusedControl(); + KeyboardDevice.Instance.PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(KeyboardDevice.Instance.FocusedElement)) + { + UpdateFocusedControl(); + } + }; + + SelectedTab = 0; + root.GetObservable(TopLevel.PointerOverElementProperty) + .Subscribe(x => PointerOverElement = x?.GetType().Name); + Console = new ConsoleViewModel(UpdateConsoleContext); + } + + public ConsoleViewModel Console { get; } + + public ViewModelBase Content + { + get { return _content; } + private set + { + if (_content is TreePageViewModel oldTree && + value is TreePageViewModel newTree && + oldTree?.SelectedNode?.Visual is IControl control) + { + newTree.SelectControl(control); + } + + RaiseAndSetIfChanged(ref _content, value); + } + } + + public int SelectedTab + { + get { return _selectedTab; } + set + { + _selectedTab = value; + + switch (value) + { + case 0: + Content = _logicalTree; + break; + case 1: + Content = _visualTree; + break; + case 2: + Content = _events; + break; + } + + RaisePropertyChanged(); + } + } + + public string FocusedControl + { + get { return _focusedControl; } + private set { RaiseAndSetIfChanged(ref _focusedControl, value); } + } + + public string PointerOverElement + { + get { return _pointerOverElement; } + private set { RaiseAndSetIfChanged(ref _pointerOverElement, value); } + } + + private void UpdateConsoleContext(ConsoleContext context) + { + context.root = _root; + + if (Content is TreePageViewModel tree) + { + context.e = tree.SelectedNode?.Visual; + } + } + + public void SelectControl(IControl control) + { + var tree = Content as TreePageViewModel; + + if (tree != null) + { + tree.SelectControl(control); + } + } + + public void Dispose() + { + _logicalTree.Dispose(); + _visualTree.Dispose(); + } + + private void UpdateFocusedControl() + { + FocusedControl = KeyboardDevice.Instance.FocusedElement?.GetType().Name; + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs new file mode 100644 index 0000000000..7d284e1499 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs @@ -0,0 +1,11 @@ +namespace Avalonia.Diagnostics.ViewModels +{ + internal abstract class PropertyViewModel : ViewModelBase + { + public abstract object Key { get; } + public abstract string Name { get; } + public abstract string Group { get; } + public abstract string Value { get; set; } + public abstract void Update(); + } +} diff --git a/src/Avalonia.Diagnostics/ViewModels/TreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs similarity index 81% rename from src/Avalonia.Diagnostics/ViewModels/TreeNode.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs index 902eb81bd9..7c403e1b04 100644 --- a/src/Avalonia.Diagnostics/ViewModels/TreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs @@ -27,9 +27,9 @@ namespace Avalonia.Diagnostics.ViewModels var classesChanged = Observable.FromEventPattern< NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>( - x => styleable.Classes.CollectionChanged += x, - x => styleable.Classes.CollectionChanged -= x) - .TakeUntil(styleable.StyleDetach); + x => styleable.Classes.CollectionChanged += x, + x => styleable.Classes.CollectionChanged -= x) + .TakeUntil(((IStyleable)styleable).StyleDetach); classesChanged.Select(_ => Unit.Default) .StartWith(Unit.Default) @@ -55,8 +55,8 @@ namespace Avalonia.Diagnostics.ViewModels public string Classes { - get => _classes; - private set => RaiseAndSetIfChanged(ref _classes, value); + get { return _classes; } + private set { RaiseAndSetIfChanged(ref _classes, value); } } public IVisual Visual @@ -66,8 +66,8 @@ namespace Avalonia.Diagnostics.ViewModels public bool IsExpanded { - get => _isExpanded; - set => RaiseAndSetIfChanged(ref _isExpanded, value); + get { return _isExpanded; } + set { RaiseAndSetIfChanged(ref _isExpanded, value); } } public TreeNode Parent @@ -78,6 +78,7 @@ namespace Avalonia.Diagnostics.ViewModels public string Type { get; + private set; } } } diff --git a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs similarity index 65% rename from src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs index b2b1aaa723..eddffb385b 100644 --- a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs @@ -1,24 +1,20 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - +using System; using Avalonia.Controls; using Avalonia.VisualTree; namespace Avalonia.Diagnostics.ViewModels { - internal class TreePageViewModel : ViewModelBase, IDevToolViewModel + internal class TreePageViewModel : ViewModelBase, IDisposable { private TreeNode _selected; private ControlDetailsViewModel _details; + private string _propertyFilter; - public TreePageViewModel(TreeNode[] nodes, string name) + public TreePageViewModel(TreeNode[] nodes) { Nodes = nodes; - Name = name; } - public string Name { get; } - public TreeNode[] Nodes { get; protected set; } public TreeNode SelectedNode @@ -26,9 +22,16 @@ namespace Avalonia.Diagnostics.ViewModels get => _selected; set { + if (Details != null) + { + _propertyFilter = Details.PropertyFilter; + } + if (RaiseAndSetIfChanged(ref _selected, value)) { - Details = value != null ? new ControlDetailsViewModel(value.Visual) : null; + Details = value != null ? + new ControlDetailsViewModel(value.Visual, _propertyFilter) : + null; } } } @@ -36,9 +39,19 @@ namespace Avalonia.Diagnostics.ViewModels public ControlDetailsViewModel Details { get => _details; - private set => RaiseAndSetIfChanged(ref _details, value); + private set + { + var oldValue = _details; + + if (RaiseAndSetIfChanged(ref _details, value)) + { + oldValue?.Dispose(); + } + } } + public void Dispose() => _details?.Dispose(); + public TreeNode FindNode(IControl control) { foreach (var node in Nodes) @@ -66,7 +79,7 @@ namespace Avalonia.Diagnostics.ViewModels { control = control.GetVisualParent(); } - } + } if (node != null) { @@ -90,14 +103,16 @@ namespace Avalonia.Diagnostics.ViewModels { return node; } - - foreach (var child in node.Children) + else { - var result = FindNode(child, control); - - if (result != null) + foreach (var child in node.Children) { - return result; + var result = FindNode(child, control); + + if (result != null) + { + return result; + } } } diff --git a/src/Avalonia.Diagnostics/ViewModels/ViewModelBase.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ViewModelBase.cs similarity index 50% rename from src/Avalonia.Diagnostics/ViewModels/ViewModelBase.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/ViewModelBase.cs index a6ff4dd853..4e7d5f6604 100644 --- a/src/Avalonia.Diagnostics/ViewModels/ViewModelBase.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ViewModelBase.cs @@ -1,34 +1,42 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - +using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; -using JetBrains.Annotations; namespace Avalonia.Diagnostics.ViewModels { - internal class ViewModelBase : INotifyPropertyChanged + public class ViewModelBase : INotifyPropertyChanged { - public event PropertyChangedEventHandler PropertyChanged; + private PropertyChangedEventHandler _propertyChanged; + private List events = new List(); + + public event PropertyChangedEventHandler PropertyChanged + { + add { _propertyChanged += value; events.Add("added"); } + remove { _propertyChanged -= value; events.Add("removed"); } + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + } - [NotifyPropertyChangedInvocator] protected bool RaiseAndSetIfChanged(ref T field, T value, [CallerMemberName] string propertyName = null) { if (!EqualityComparer.Default.Equals(field, value)) { field = value; - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + RaisePropertyChanged(propertyName); return true; } return false; } - [NotifyPropertyChangedInvocator] protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + var e = new PropertyChangedEventArgs(propertyName); + OnPropertyChanged(e); + _propertyChanged?.Invoke(this, e); } } } diff --git a/src/Avalonia.Diagnostics/ViewModels/VisualTreeNode.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs similarity index 85% rename from src/Avalonia.Diagnostics/ViewModels/VisualTreeNode.cs rename to src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs index 47ef91507a..8c070261d9 100644 --- a/src/Avalonia.Diagnostics/ViewModels/VisualTreeNode.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs @@ -29,11 +29,12 @@ namespace Avalonia.Diagnostics.ViewModels } } - public bool IsInTemplate { get; } + public bool IsInTemplate { get; private set; } public static VisualTreeNode[] Create(object control) { - return control is IVisual visual ? new[] { new VisualTreeNode(visual, null) } : null; + var visual = control as IVisual; + return visual != null ? new[] { new VisualTreeNode(visual, null) } : null; } } } diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml new file mode 100644 index 0000000000..264a0de359 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + > + + + + + + + + + diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs new file mode 100644 index 0000000000..ae70b59fde --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ConsoleView.xaml.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Specialized; +using Avalonia.Controls; +using Avalonia.Diagnostics.ViewModels; +using Avalonia.Input; +using Avalonia.LogicalTree; +using Avalonia.Markup.Xaml; +using Avalonia.Threading; + +namespace Avalonia.Diagnostics.Views +{ + internal class ConsoleView : UserControl + { + private readonly ListBox _historyList; + private readonly TextBox _input; + + public ConsoleView() + { + this.InitializeComponent(); + _historyList = this.FindControl("historyList"); + ((ILogical)_historyList).LogicalChildren.CollectionChanged += HistoryChanged; + _input = this.FindControl("input"); + _input.KeyDown += InputKeyDown; + } + + public void FocusInput() => _input.Focus(); + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + private void HistoryChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems[0] is IControl control) + { + DispatcherTimer.RunOnce(control.BringIntoView, TimeSpan.Zero); + } + } + + private void InputKeyDown(object sender, KeyEventArgs e) + { + var vm = (ConsoleViewModel)DataContext; + + switch (e.Key) + { + case Key.Enter: + vm.Execute(); + e.Handled = true; + break; + case Key.Up: + vm.HistoryUp(); + _input.CaretIndex = _input.Text.Length; + e.Handled = true; + break; + case Key.Down: + vm.HistoryDown(); + _input.CaretIndex = _input.Text.Length; + e.Handled = true; + break; + } + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml new file mode 100644 index 0000000000..903f18aa19 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs new file mode 100644 index 0000000000..c6bd5a18aa --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs @@ -0,0 +1,18 @@ +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Avalonia.Diagnostics.Views +{ + internal class ControlDetailsView : UserControl + { + public ControlDetailsView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + } +} diff --git a/src/Avalonia.Diagnostics/Views/EventsView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/EventsPageView.xaml similarity index 92% rename from src/Avalonia.Diagnostics/Views/EventsView.xaml rename to src/Avalonia.Diagnostics/Diagnostics/Views/EventsPageView.xaml index 406dd433a2..b7f0860e70 100644 --- a/src/Avalonia.Diagnostics/Views/EventsView.xaml +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/EventsPageView.xaml @@ -1,9 +1,10 @@  + xmlns:conv="clr-namespace:Avalonia.Diagnostics.Converters" + x:Class="Avalonia.Diagnostics.Views.EventsPageView"> - + ("events"); diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml new file mode 100644 index 0000000000..663722acba --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hold Ctrl+Shift over a control to inspect. + + Focused: + + + Pointer Over: + + + + + diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml.cs new file mode 100644 index 0000000000..783709e54b --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml.cs @@ -0,0 +1,66 @@ +using Avalonia.Controls; +using Avalonia.Diagnostics.ViewModels; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; +using Avalonia.Threading; + +namespace Avalonia.Diagnostics.Views +{ + internal class MainView : UserControl + { + private readonly ConsoleView _console; + private readonly GridSplitter _consoleSplitter; + private readonly Grid _rootGrid; + private readonly int _consoleRow; + private double _consoleHeight = -1; + + public MainView() + { + InitializeComponent(); + AddHandler(KeyDownEvent, PreviewKeyDown, RoutingStrategies.Tunnel); + _console = this.FindControl("console"); + _consoleSplitter = this.FindControl("consoleSplitter"); + _rootGrid = this.FindControl("rootGrid"); + _consoleRow = Grid.GetRow(_console); + } + + public void ToggleConsole() + { + var vm = (MainViewModel)DataContext; + + if (_consoleHeight == -1) + { + _consoleHeight = Bounds.Height / 3; + } + + vm.Console.ToggleVisibility(); + _consoleSplitter.IsVisible = vm.Console.IsVisible; + + if (vm.Console.IsVisible) + { + _rootGrid.RowDefinitions[_consoleRow].Height = new GridLength(_consoleHeight, GridUnitType.Pixel); + Dispatcher.UIThread.Post(() => _console.FocusInput(), DispatcherPriority.Background); + } + else + { + _consoleHeight = _rootGrid.RowDefinitions[_consoleRow].Height.Value; + _rootGrid.RowDefinitions[_consoleRow].Height = new GridLength(0, GridUnitType.Pixel); + } + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + private void PreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + ToggleConsole(); + e.Handled = true; + } + } + } +} diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml new file mode 100644 index 0000000000..3623e95597 --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs new file mode 100644 index 0000000000..3abdb5034a --- /dev/null +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs @@ -0,0 +1,74 @@ +using System; +using System.Linq; +using System.Reactive.Linq; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Diagnostics.ViewModels; +using Avalonia.Input; +using Avalonia.Input.Raw; +using Avalonia.Markup.Xaml; +using Avalonia.Styling; +using Avalonia.VisualTree; + +namespace Avalonia.Diagnostics.Views +{ + internal class MainWindow : Window, IStyleHost + { + private TopLevel _root; + private IDisposable _keySubscription; + + public MainWindow() + { + InitializeComponent(); + + _keySubscription = InputManager.Instance.Process + .OfType() + .Subscribe(RawKeyDown); + } + + public TopLevel Root + { + get => _root; + set + { + if (_root != value) + { + _root = value; + DataContext = new MainViewModel(value); + } + } + } + + IStyleHost IStyleHost.StylingParent => null; + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + _keySubscription.Dispose(); + ((MainViewModel)DataContext)?.Dispose(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + private void RawKeyDown(RawKeyEventArgs e) + { + const RawInputModifiers modifiers = RawInputModifiers.Control | RawInputModifiers.Shift; + + if (e.Modifiers == modifiers) + { + var point = (Root as IInputRoot)?.MouseDevice?.GetPosition(Root) ?? default; + var control = Root.GetVisualsAt(point, x => (!(x is AdornerLayer) && x.IsVisible)) + .FirstOrDefault(); + + if (control != null) + { + var vm = (MainViewModel)DataContext; + vm.SelectControl((IControl)control); + } + } + } + } +} diff --git a/src/Avalonia.Diagnostics/Views/TreePageView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml similarity index 60% rename from src/Avalonia.Diagnostics/Views/TreePageView.xaml rename to src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml index 2619fd744a..a1e6ca7d37 100644 --- a/src/Avalonia.Diagnostics/Views/TreePageView.xaml +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml @@ -1,26 +1,29 @@ - - + + - - + + - - + + diff --git a/src/Avalonia.Diagnostics/Views/TreePageView.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml.cs similarity index 90% rename from src/Avalonia.Diagnostics/Views/TreePageView.xaml.cs rename to src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml.cs index 1326f718de..633d18ddd8 100644 --- a/src/Avalonia.Diagnostics/Views/TreePageView.xaml.cs +++ b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml.cs @@ -1,6 +1,3 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - using Avalonia.Controls; using Avalonia.Controls.Generators; using Avalonia.Controls.Primitives; @@ -12,14 +9,14 @@ using Avalonia.Media; namespace Avalonia.Diagnostics.Views { - public class TreePageView : UserControl + internal class TreePageView : UserControl { private Control _adorner; private TreeView _tree; public TreePageView() { - InitializeComponent(); + this.InitializeComponent(); _tree.ItemContainerGenerator.Index.Materialized += TreeViewItemMaterialized; } @@ -39,7 +36,7 @@ namespace Avalonia.Diagnostics.Views _adorner = new Rectangle { Fill = new SolidColorBrush(0x80a0c5e8), - [AdornerLayer.AdornedElementProperty] = node.Visual + [AdornerLayer.AdornedElementProperty] = node.Visual, }; layer.Children.Add(_adorner); diff --git a/src/Avalonia.Diagnostics/VisualTreeDebug.cs b/src/Avalonia.Diagnostics/Diagnostics/VisualTreeDebug.cs similarity index 100% rename from src/Avalonia.Diagnostics/VisualTreeDebug.cs rename to src/Avalonia.Diagnostics/Diagnostics/VisualTreeDebug.cs diff --git a/src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs deleted file mode 100644 index 4b832f7ce6..0000000000 --- a/src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System.Collections.Generic; -using System.Linq; -using Avalonia.VisualTree; - -namespace Avalonia.Diagnostics.ViewModels -{ - internal class ControlDetailsViewModel : ViewModelBase - { - public ControlDetailsViewModel(IVisual control) - { - if (control is AvaloniaObject avaloniaObject) - { - Properties = AvaloniaPropertyRegistry.Instance.GetRegistered(avaloniaObject) - .Select(x => new PropertyDetails(avaloniaObject, x)) - .OrderBy(x => x.IsAttached) - .ThenBy(x => x.Name); - } - } - - public IEnumerable Properties { get; } - } -} diff --git a/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs deleted file mode 100644 index 9f524a21eb..0000000000 --- a/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections.ObjectModel; -using System.Linq; -using Avalonia.Controls; -using Avalonia.Input; - -namespace Avalonia.Diagnostics.ViewModels -{ - internal class DevToolsViewModel : ViewModelBase - { - private IDevToolViewModel _selectedTool; - private string _focusedControl; - private string _pointerOverElement; - - public DevToolsViewModel(IControl root) - { - Tools = new ObservableCollection - { - new TreePageViewModel(LogicalTreeNode.Create(root), "Logical Tree"), - new TreePageViewModel(VisualTreeNode.Create(root), "Visual Tree"), - new EventsViewModel(root) - }; - - SelectedTool = Tools.First(); - - UpdateFocusedControl(); - - KeyboardDevice.Instance.PropertyChanged += (s, e) => - { - if (e.PropertyName == nameof(KeyboardDevice.Instance.FocusedElement)) - { - UpdateFocusedControl(); - } - }; - - root.GetObservable(TopLevel.PointerOverElementProperty) - .Subscribe(x => PointerOverElement = x?.GetType().Name); - } - - public IDevToolViewModel SelectedTool - { - get => _selectedTool; - set => RaiseAndSetIfChanged(ref _selectedTool, value); - } - - public ObservableCollection Tools { get; } - - public string FocusedControl - { - get => _focusedControl; - private set => RaiseAndSetIfChanged(ref _focusedControl, value); - } - - public string PointerOverElement - { - get => _pointerOverElement; - private set => RaiseAndSetIfChanged(ref _pointerOverElement, value); - } - - public void SelectControl(IControl control) - { - if (SelectedTool is TreePageViewModel tree) - { - tree.SelectControl(control); - } - } - - private void UpdateFocusedControl() - { - FocusedControl = KeyboardDevice.Instance.FocusedElement?.GetType().Name; - } - } -} diff --git a/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs deleted file mode 100644 index 0434230a63..0000000000 --- a/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -namespace Avalonia.Diagnostics.ViewModels -{ - /// - /// View model interface for tool showing up in DevTools - /// - public interface IDevToolViewModel - { - /// - /// Name of a tool. - /// - string Name { get; } - } -} diff --git a/src/Avalonia.Diagnostics/ViewModels/PropertyDetails.cs b/src/Avalonia.Diagnostics/ViewModels/PropertyDetails.cs deleted file mode 100644 index 523be406c8..0000000000 --- a/src/Avalonia.Diagnostics/ViewModels/PropertyDetails.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using Avalonia.Data; - -namespace Avalonia.Diagnostics.ViewModels -{ - internal class PropertyDetails : ViewModelBase - { - private object _value; - private string _priority; - private string _diagnostic; - - public PropertyDetails(AvaloniaObject o, AvaloniaProperty property) - { - Name = property.IsAttached ? - $"[{property.OwnerType.Name}.{property.Name}]" : - property.Name; - IsAttached = property.IsAttached; - - // TODO: Unsubscribe when view model is deactivated. - o.GetObservable(property).Subscribe(x => - { - var diagnostic = o.GetDiagnostic(property); - Value = diagnostic.Value ?? "(null)"; - Priority = (diagnostic.Priority != BindingPriority.Unset) ? - diagnostic.Priority.ToString() : - diagnostic.Property.Inherits ? - "Inherited" : - "Unset"; - Diagnostic = diagnostic.Diagnostic; - }); - } - - public string Name { get; } - - public bool IsAttached { get; } - - public string Priority - { - get => _priority; - private set => RaiseAndSetIfChanged(ref _priority, value); - } - - public string Diagnostic - { - get => _diagnostic; - private set => RaiseAndSetIfChanged(ref _diagnostic, value); - } - - public object Value - { - get => _value; - private set => RaiseAndSetIfChanged(ref _value, value); - } - } -} diff --git a/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs b/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs deleted file mode 100644 index fb867ab55e..0000000000 --- a/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Reactive.Linq; -using Avalonia.Controls; -using Avalonia.Diagnostics.ViewModels; -using Avalonia.Media; - -namespace Avalonia.Diagnostics.Views -{ - internal class ControlDetailsView : UserControl - { - private static readonly StyledProperty ViewModelProperty = - AvaloniaProperty.Register(nameof(ViewModel)); - - private SimpleGrid _grid; - - public ControlDetailsView() - { - InitializeComponent(); - this.GetObservable(DataContextProperty) - .Subscribe(x => ViewModel = (ControlDetailsViewModel)x); - } - - public ControlDetailsViewModel ViewModel - { - get => GetValue(ViewModelProperty); - private set - { - SetValue(ViewModelProperty, value); - _grid[GridRepeater.ItemsProperty] = value?.Properties; - } - } - - private void InitializeComponent() - { - Func> pt = PropertyTemplate; - - Content = new ScrollViewer { Content = _grid = new SimpleGrid { [GridRepeater.TemplateProperty] = pt } }; - } - - private IEnumerable PropertyTemplate(object i) - { - var property = (PropertyDetails)i; - - var margin = new Thickness(2); - - yield return new TextBlock - { - Margin = margin, - Text = property.Name, - TextWrapping = TextWrapping.NoWrap, - [!ToolTip.TipProperty] = property.GetObservable(nameof(property.Diagnostic)).ToBinding() - }; - - yield return new TextBlock - { - Margin = margin, - TextWrapping = TextWrapping.NoWrap, - [!TextBlock.TextProperty] = property.GetObservable(nameof(property.Value)) - .Select(v => v?.ToString()) - .ToBinding() - }; - - yield return new TextBlock - { - Margin = margin, - TextWrapping = TextWrapping.NoWrap, - [!TextBlock.TextProperty] = property.GetObservable((nameof(property.Priority))).ToBinding() - }; - } - } -} diff --git a/src/Avalonia.Diagnostics/Views/GridRepeater.cs b/src/Avalonia.Diagnostics/Views/GridRepeater.cs deleted file mode 100644 index b0ff26c7b6..0000000000 --- a/src/Avalonia.Diagnostics/Views/GridRepeater.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections; -using System.Collections.Generic; -using Avalonia.Controls; - -namespace Avalonia.Diagnostics.Views -{ - internal static class GridRepeater - { - public static readonly AttachedProperty ItemsProperty = - AvaloniaProperty.RegisterAttached("Items", typeof(GridRepeater)); - - public static readonly AttachedProperty>> TemplateProperty = - AvaloniaProperty.RegisterAttached>>("Template", - typeof(GridRepeater)); - - static GridRepeater() - { - ItemsProperty.Changed.Subscribe(ItemsChanged); - } - - private static void ItemsChanged(AvaloniaPropertyChangedEventArgs e) - { - var grid = (SimpleGrid)e.Sender; - var items = (IEnumerable)e.NewValue; - var template = grid.GetValue(TemplateProperty); - - grid.Children.Clear(); - - if (items != null) - { - int count = 0; - int cols = 3; - - foreach (var item in items) - { - foreach (var control in template(item)) - { - grid.Children.Add(control); - SimpleGrid.SetColumn(control, count % cols); - SimpleGrid.SetRow(control, count / cols); - ++count; - } - } - } - } - } -} diff --git a/src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs b/src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs deleted file mode 100644 index 24b2f29463..0000000000 --- a/src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.ComponentModel; -using System.Reactive.Linq; -using System.Reflection; - -namespace Avalonia.Diagnostics.Views -{ - internal static class PropertyChangedExtensions - { - public static IObservable GetObservable(this INotifyPropertyChanged source, string propertyName) - { - Contract.Requires(source != null); - Contract.Requires(propertyName != null); - - var property = source.GetType().GetTypeInfo().GetDeclaredProperty(propertyName); - - if (property == null) - { - throw new ArgumentException($"Property '{propertyName}' not found on '{source}."); - } - - return Observable.FromEventPattern( - e => source.PropertyChanged += e, - e => source.PropertyChanged -= e) - .Where(e => e.EventArgs.PropertyName == propertyName) - .Select(_ => (T)property.GetValue(source)) - .StartWith((T)property.GetValue(source)); - } - } -} diff --git a/src/Avalonia.Diagnostics/Views/SimpleGrid.cs b/src/Avalonia.Diagnostics/Views/SimpleGrid.cs deleted file mode 100644 index 4fc77666e1..0000000000 --- a/src/Avalonia.Diagnostics/Views/SimpleGrid.cs +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System.Collections.Generic; -using Avalonia.Controls; - -namespace Avalonia.Diagnostics.Views -{ - /// - /// A simple grid control that lays out columns with a equal width and rows to their desired - /// size. - /// - /// - /// This is used in the devtools because our performance sucks. - /// - public class SimpleGrid : Panel - { - private readonly List _columnWidths = new List(); - private readonly List _rowHeights = new List(); - private double _totalWidth; - private double _totalHeight; - - /// - /// Defines the Column attached property. - /// - public static readonly AttachedProperty ColumnProperty = - AvaloniaProperty.RegisterAttached("Column"); - - /// - /// Defines the Row attached property. - /// - public static readonly AttachedProperty RowProperty = - AvaloniaProperty.RegisterAttached("Row"); - - /// - /// Gets the value of the Column attached property for a control. - /// - /// The control. - /// The control's column. - public static int GetColumn(IControl control) - { - return control.GetValue(ColumnProperty); - } - - /// - /// Gets the value of the Row attached property for a control. - /// - /// The control. - /// The control's row. - public static int GetRow(IControl control) - { - return control.GetValue(RowProperty); - } - - /// - /// Sets the value of the Column attached property for a control. - /// - /// The control. - /// The column value. - public static void SetColumn(IControl control, int value) - { - control.SetValue(ColumnProperty, value); - } - - - /// - /// Sets the value of the Row attached property for a control. - /// - /// The control. - /// The row value. - public static void SetRow(IControl control, int value) - { - control.SetValue(RowProperty, value); - } - - protected override Size MeasureOverride(Size availableSize) - { - _columnWidths.Clear(); - _rowHeights.Clear(); - _totalWidth = 0; - _totalHeight = 0; - - foreach (var child in Children) - { - var column = GetColumn(child); - var row = GetRow(child); - - child.Measure(availableSize); - - var desired = child.DesiredSize; - UpdateCell(_columnWidths, column, desired.Width, ref _totalWidth); - UpdateCell(_rowHeights, row, desired.Height, ref _totalHeight); - } - - return new Size(_totalWidth, _totalHeight); - } - - protected override Size ArrangeOverride(Size finalSize) - { - var columnWidth = finalSize.Width / _columnWidths.Count; - - foreach (var child in Children) - { - var column = GetColumn(child); - var row = GetRow(child); - var rect = new Rect(column * columnWidth, GetRowTop(row), columnWidth, _rowHeights[row]); - child.Arrange(rect); - } - - return new Size(finalSize.Width, _totalHeight); - } - - private double UpdateCell(IList cells, int cell, double value, ref double total) - { - while (cells.Count < cell + 1) - { - cells.Add(0); - } - - var existing = cells[cell]; - - if (value > existing) - { - cells[cell] = value; - total += value - existing; - return value; - } - else - { - return existing; - } - } - - private double GetRowTop(int row) - { - var result = 0.0; - - for (var i = 0; i < row; ++i) - { - result += _rowHeights[i]; - } - - return result; - } - } -}