From 5859a20d309893cb4ed06e092d78858c77efe6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Wed, 16 Sep 2020 20:31:59 +0100 Subject: [PATCH] WPF --- UVtools.WPF/App.axaml.cs | 28 ++- UVtools.WPF/Assets/Icons/Back-16x16.png | Bin 0 -> 138 bytes .../Assets/Icons/Button-Info-16x16.png | Bin 0 -> 197 bytes UVtools.WPF/Assets/Icons/CNCMachine-16x16.png | Bin 0 -> 261 bytes UVtools.WPF/Assets/Icons/Cancel-24x24.png | Bin 0 -> 513 bytes UVtools.WPF/Assets/Icons/Cancel-32x32.png | Bin 0 -> 588 bytes UVtools.WPF/Assets/Icons/DataList-16x16.png | Bin 0 -> 179 bytes UVtools.WPF/Assets/Icons/Donate-16x16.png | Bin 0 -> 212 bytes UVtools.WPF/Assets/Icons/GCode-16x16.png | Bin 0 -> 151 bytes UVtools.WPF/Assets/Icons/Geometry-16x16.png | Bin 0 -> 259 bytes .../Icons/Global-Network-icon-16x16.png | Bin 0 -> 876 bytes UVtools.WPF/Assets/Icons/Lock-16x16.png | Bin 0 -> 1261 bytes UVtools.WPF/Assets/Icons/Next-16x16.png | Bin 0 -> 140 bytes UVtools.WPF/Assets/Icons/Ok-24x24.png | Bin 0 -> 350 bytes UVtools.WPF/Assets/Icons/PhotoInfo-16x16.png | Bin 0 -> 196 bytes UVtools.WPF/Assets/Icons/Wrench-16x16.png | Bin 0 -> 237 bytes UVtools.WPF/Assets/Icons/accept-16x16.png | Bin 0 -> 382 bytes UVtools.WPF/Assets/Icons/arrow-down-16x16.png | Bin 0 -> 190 bytes .../Assets/Icons/arrow-down-double-16x16.png | Bin 0 -> 179 bytes UVtools.WPF/Assets/Icons/arrow-end-16x16.png | Bin 0 -> 154 bytes UVtools.WPF/Assets/Icons/arrow-top-16x16.png | Bin 0 -> 206 bytes UVtools.WPF/Assets/Icons/arrow-up-16x16.png | Bin 0 -> 193 bytes UVtools.WPF/Assets/Icons/blur-16x16.png | Bin 0 -> 202 bytes .../Assets/Icons/bowling-ball-16x16.png | Bin 0 -> 190 bytes UVtools.WPF/Assets/Icons/burn-16x16.png | Bin 0 -> 212 bytes .../Assets/Icons/checkbox-marked-16x16.png | Bin 0 -> 232 bytes .../Assets/Icons/checkbox-unmarked-16x16.png | Bin 0 -> 121 bytes UVtools.WPF/Assets/Icons/chessboard-16x16.png | Bin 0 -> 83 bytes UVtools.WPF/Assets/Icons/clipboard-16x16.png | Bin 0 -> 207 bytes UVtools.WPF/Assets/Icons/code-16x16.png | Bin 0 -> 199 bytes .../Assets/Icons/compress-alt-16x16.png | Bin 0 -> 142 bytes UVtools.WPF/Assets/Icons/convert-16x16.png | Bin 0 -> 629 bytes UVtools.WPF/Assets/Icons/copy_16x16.png | Bin 0 -> 114 bytes UVtools.WPF/Assets/Icons/crop-16x16.png | Bin 0 -> 104 bytes UVtools.WPF/Assets/Icons/crosshairs-16x16.png | Bin 0 -> 3295 bytes UVtools.WPF/Assets/Icons/cursor-16x16.png | Bin 0 -> 507 bytes UVtools.WPF/Assets/Icons/delete-16x16.png | Bin 0 -> 139 bytes UVtools.WPF/Assets/Icons/exit-16x16.png | Bin 0 -> 174 bytes UVtools.WPF/Assets/Icons/expand-16x16.png | Bin 0 -> 98 bytes UVtools.WPF/Assets/Icons/expand-alt-16x16.png | Bin 0 -> 129 bytes .../Assets/Icons/extract-object-16x16.png | Bin 0 -> 490 bytes UVtools.WPF/Assets/Icons/eye-16x16.png | Bin 0 -> 402 bytes UVtools.WPF/Assets/Icons/eye-24x24.png | Bin 0 -> 402 bytes UVtools.WPF/Assets/Icons/file-close-16x16.png | Bin 0 -> 247 bytes UVtools.WPF/Assets/Icons/file-image-16x16.png | Bin 0 -> 234 bytes .../Assets/Icons/file-import-16x16.png | Bin 0 -> 136 bytes .../Assets/Icons/file-refresh-16x16.png | Bin 0 -> 196 bytes .../Assets/Icons/filter-filled-16x16.png | Bin 0 -> 126 bytes UVtools.WPF/Assets/Icons/flip-16x16.png | Bin 0 -> 232 bytes .../Assets/Icons/internet-explorer-16x16.png | Bin 0 -> 276 bytes UVtools.WPF/Assets/Icons/island-16x16.png | Bin 0 -> 647 bytes UVtools.WPF/Assets/Icons/ladder-16x16.png | Bin 0 -> 241 bytes UVtools.WPF/Assets/Icons/layers-16x16.png | Bin 0 -> 358 bytes UVtools.WPF/Assets/Icons/layers-alt-16x16.png | Bin 0 -> 194 bytes UVtools.WPF/Assets/Icons/list-16x16.png | Bin 0 -> 90 bytes UVtools.WPF/Assets/Icons/log-16x16.png | Bin 0 -> 284 bytes UVtools.WPF/Assets/Icons/map-marker-16x16.png | Bin 0 -> 193 bytes UVtools.WPF/Assets/Icons/mask-16x16.png | Bin 0 -> 171 bytes UVtools.WPF/Assets/Icons/microchip_16x16.png | Bin 0 -> 116 bytes UVtools.WPF/Assets/Icons/minus_16x16.png | Bin 0 -> 89 bytes UVtools.WPF/Assets/Icons/move-16x16.png | Bin 0 -> 155 bytes .../Assets/Icons/object-group-16x16.png | Bin 0 -> 139 bytes UVtools.WPF/Assets/Icons/open-16x16.png | Bin 0 -> 248 bytes UVtools.WPF/Assets/Icons/pattern-16x16.png | Bin 0 -> 268 bytes UVtools.WPF/Assets/Icons/photo-16x16.png | Bin 0 -> 221 bytes UVtools.WPF/Assets/Icons/pixel-16x16.png | Bin 0 -> 454 bytes UVtools.WPF/Assets/Icons/plus-16x16.png | Bin 0 -> 114 bytes UVtools.WPF/Assets/Icons/pointer-16x16.png | Bin 0 -> 179 bytes UVtools.WPF/Assets/Icons/refresh-16x16.png | Bin 0 -> 245 bytes UVtools.WPF/Assets/Icons/resize-16x16.png | Bin 0 -> 229 bytes UVtools.WPF/Assets/Icons/save-16x16.png | Bin 0 -> 247 bytes UVtools.WPF/Assets/Icons/save-as-16x16.png | Bin 0 -> 244 bytes UVtools.WPF/Assets/Icons/search-16x16.png | Bin 0 -> 344 bytes UVtools.WPF/Assets/Icons/settings-16x16.png | Bin 0 -> 290 bytes .../Assets/Icons/sort-alpha-up-16x16.png | Bin 0 -> 174 bytes .../Assets/Icons/square-solid-16x16.png | Bin 0 -> 99 bytes UVtools.WPF/Assets/Icons/sync-16x16.png | Bin 0 -> 245 bytes UVtools.WPF/Assets/Icons/th-16x16.png | Bin 0 -> 99 bytes UVtools.WPF/Assets/Icons/toolbox-16x16.png | Bin 0 -> 116 bytes UVtools.WPF/Assets/Icons/trash-16x16.png | Bin 0 -> 105 bytes UVtools.WPF/Assets/Icons/undo-16x16.png | Bin 0 -> 231 bytes UVtools.WPF/Assets/Icons/undo-alt-16x16.png | Bin 0 -> 259 bytes UVtools.WPF/Assets/Icons/warning-16x16.png | Bin 0 -> 699 bytes UVtools.WPF/Controls/AdvancedImageBox.cs | 87 +++++++-- UVtools.WPF/Extensions/BitmapExtension.cs | 116 ++++++++++++ UVtools.WPF/Extensions/WindowExtensions.cs | 42 +++++ UVtools.WPF/MainWindow.axaml | 167 ++++++++++++++++- UVtools.WPF/MainWindow.axaml.cs | 169 ++++++++++++++++-- UVtools.WPF/Program.cs | 1 - UVtools.WPF/Themes/UVtools.themes | 58 ++++++ UVtools.WPF/Themes/UVtoolsDark.xaml | 58 ++++++ UVtools.WPF/Themes/UVtoolsLight.xaml | 58 ++++++ UVtools.WPF/UVtools.WPF.csproj | 28 ++- UVtools.WPF/ViewModels/MainWindowViewModel.cs | 32 ++++ 94 files changed, 807 insertions(+), 37 deletions(-) create mode 100644 UVtools.WPF/Assets/Icons/Back-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Button-Info-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/CNCMachine-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Cancel-24x24.png create mode 100644 UVtools.WPF/Assets/Icons/Cancel-32x32.png create mode 100644 UVtools.WPF/Assets/Icons/DataList-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Donate-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/GCode-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Geometry-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Global-Network-icon-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Lock-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Next-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Ok-24x24.png create mode 100644 UVtools.WPF/Assets/Icons/PhotoInfo-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/Wrench-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/accept-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/arrow-down-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/arrow-down-double-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/arrow-end-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/arrow-top-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/arrow-up-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/blur-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/bowling-ball-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/burn-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/checkbox-marked-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/checkbox-unmarked-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/chessboard-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/clipboard-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/code-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/compress-alt-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/convert-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/copy_16x16.png create mode 100644 UVtools.WPF/Assets/Icons/crop-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/crosshairs-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/cursor-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/delete-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/exit-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/expand-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/expand-alt-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/extract-object-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/eye-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/eye-24x24.png create mode 100644 UVtools.WPF/Assets/Icons/file-close-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/file-image-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/file-import-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/file-refresh-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/filter-filled-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/flip-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/internet-explorer-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/island-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/ladder-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/layers-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/layers-alt-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/list-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/log-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/map-marker-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/mask-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/microchip_16x16.png create mode 100644 UVtools.WPF/Assets/Icons/minus_16x16.png create mode 100644 UVtools.WPF/Assets/Icons/move-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/object-group-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/open-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/pattern-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/photo-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/pixel-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/plus-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/pointer-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/refresh-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/resize-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/save-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/save-as-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/search-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/settings-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/sort-alpha-up-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/square-solid-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/sync-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/th-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/toolbox-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/trash-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/undo-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/undo-alt-16x16.png create mode 100644 UVtools.WPF/Assets/Icons/warning-16x16.png create mode 100644 UVtools.WPF/Extensions/BitmapExtension.cs create mode 100644 UVtools.WPF/Extensions/WindowExtensions.cs create mode 100644 UVtools.WPF/Themes/UVtools.themes create mode 100644 UVtools.WPF/Themes/UVtoolsDark.xaml create mode 100644 UVtools.WPF/Themes/UVtoolsLight.xaml create mode 100644 UVtools.WPF/ViewModels/MainWindowViewModel.cs diff --git a/UVtools.WPF/App.axaml.cs b/UVtools.WPF/App.axaml.cs index 62a22e2..d4730d7 100644 --- a/UVtools.WPF/App.axaml.cs +++ b/UVtools.WPF/App.axaml.cs @@ -1,11 +1,21 @@ -using Avalonia; +using System.Diagnostics; +using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; +using Avalonia.ThemeManager; +using MessageBox.Avalonia.DTO; +using MessageBox.Avalonia.Enums; +using MessageBox.Avalonia.Models; +using UVtools.Core.FileFormats; namespace UVtools.WPF { public class App : Application { + public static IThemeSelector? Selector { get; set; } + + public static FileFormat SlicerFile = null; + public override void Initialize() { AvaloniaXamlLoader.Load(this); @@ -15,10 +25,24 @@ namespace UVtools.WPF { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - desktop.MainWindow = new MainWindow(); + Selector = ThemeSelector.Create("Themes"); + Selector.LoadSelectedTheme("UVtools.theme"); + desktop.MainWindow = new MainWindow + { + //DataContext = Selector + }; + desktop.Exit += (sender, e) + => Selector.SaveSelectedTheme("UVtools.theme"); + + Debug.WriteLine(Selector.Themes[1].Name); } base.OnFrameworkInitializationCompleted(); } + + #region Utilities + + + #endregion } } diff --git a/UVtools.WPF/Assets/Icons/Back-16x16.png b/UVtools.WPF/Assets/Icons/Back-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..c28c6216a9b191202258ac7ecec22ae5d1b1d909 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf60zF+ELn;`P6?hGdL>^C{ck;vh z318~>TuRX3Yk!k*N#cWYv-K(ywL9E_7dW0K9eOOln%g2`V5oB-moTNw9GDq;&_WZ2Cb<#=ww1O>2xw*SFi{Ho~@T6AK>QTmHXs{=2yXfh$TSvs-!ecj?wJ zt}uFjLSwVm4ioP_)d;ofXOpt;o@+U0%D>AXN#+gvKI6|^PKUNn*>LH{t!V=83Vj{k w|CH*UTFr}WGMXnTFB&QP@s;usD}{1?#lOpA#r`gO4s;iTr>mdKI;Vst0Lo5ItN;K2 literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/CNCMachine-16x16.png b/UVtools.WPF/Assets/Icons/CNCMachine-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..e2a5e4b377be126befa3deefddb022960e8f8a13 GIT binary patch literal 261 zcmV+g0s8)lP)Z~Rlj{G^S6GVY@9y$)w%m7btiK^F~ zlfn&caf=&Ny?M=pN2oXH19!NmL-FRp-^_e8n{bQHGySB)gYmQb443Fl<-GiJk4s81 z#ie0{?@i86eGITh|?Tc&$v@sJ)FbG)2Md5Tf0s~wcZUeM66DbG+ zmf|+px8)5+o!cPVofpefYMAYnr0_;kbR$WboyK%9aHs3jue>gmkoM-E;#eh( zJk}SN%!ut1U)F0nuH*mH%edZsmOC)G=SpI(9i2>c-};&G$o zy6MBv)h7NdOx|lgK0TA!pY^7Y?X&jAgzXDz7wz47f)lz^Vp;}=Oev4$IoF$lz}@16 zo!3Fc$mtH&%Y%miYk!2Y$L+3YLt7pjQk{9lg9{u1BhHLl`s9G%00000NkvXXu0mjf DE+z8F literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/Cancel-32x32.png b/UVtools.WPF/Assets/Icons/Cancel-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..a732caa26a8f0a218dc3a7e95dcb2a94993941b6 GIT binary patch literal 588 zcmV-S0<-;zP)kdg0006LNkl!!JF89R zPDgalh0aaSnLB4@?!X4|P&Txo9i6ECiWBWYJRN}{K$XjK)}yq|F5p=f&Ng$vM{ zK6MF=u3`a%zxo}i8qlWuxB`GAVuT|fNdW+~>M|S9?mEcpi>Yi*M!&cs>n^tgovs5B z0CovZ2g0Dsoc>tJTU>b1UsEe@Fi#_7WDv~NiY-5 zZA`_`HfE8zjqD&rEiHBE32La(@a-iv1J a!Gix2QN;^o?DqZu0000~yPTVT$JAOImEY9D?8dTF53Rd%)DC=l1uxp4Y`^GEdX&k}Cak?7_DS29LyE@O+b*$zaK4 z_nD!POG9Z#L9%z7EZct39Yu#PJZ$+|xs1D5ETq$cT}8 literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/Donate-16x16.png b/UVtools.WPF/Assets/Icons/Donate-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..37378b3d4cf63bbdc80e4447e81b58a083e9f565 GIT binary patch literal 212 zcmV;_04x8AP)u8{|1~eL7f`!v9(*9+!TlSM~*e>+VvGq@w%Q0gH_0@Cz9Hjp)0@}pj>FVdQ&MBb@0M*kt AY5)KL literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/Geometry-16x16.png b/UVtools.WPF/Assets/Icons/Geometry-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..da022c55fe672c5c61c0cde5f7f8e13748d3de70 GIT binary patch literal 259 zcmV+e0sQ`nP)(-u4#Sarge8nui+7|RNN)ul5r>FE*(pFLlTKh+SY+*CPer(&eZM$ttNh+=K*uQypN8&$Hdg03zUPL)T zQsmu%mA>QRFFHfMG5_W-epmM+$G86TUiz~rKkP}(*$}!uRv@2JT4Ia3ViQf@K*kF4 zapySGN8Z; zqj&0S24;RBEH?4tho8~cyoYDH!E!lKv;W08dEu=Ihp;sjFQAe^V$`08R2yn=C5vt$ z$((Y6N-+o3pTf7DZS)UzNS?jQ7P#IX%j3>Wv+dsaI zE=@5swi?G2D1IT~cs|0l?7_*@JY55?GC7p`-3MlPzkP{IcR!fHF}UZ=XD|$t@!-)y#Mfil4)a+X&&+}Z ziM7?NSs#Bx3FjBzKGx@-rOKw5H-;D)9>d4S^;|sH<-X^BV#}Hsd)4p7)#5cWLJ%(6 zNV2llOKwcuDFGypz5iBYYWOr3)8JTmo`)}F@B!bWcJp%5#sZE|(F@iSDOpKvQ{ipb z?z!=F1)zR?~sG` zrYoOp(S97CzkX~qeTp&KCyF$Ka41MDuLM)e$BhJ8zAEBrx^hSCm**=FFSh{xN9POQ zXsz%(agt?uyZW$F*JOYpBM_Kbf?|%kS%zBfkt&_e00000U8P*7-ZbZ>KLZ*U+lnSp_Ufq@}0xwybFAi#%#fq@|}KQEO56)-X|e7nZL z$iTqBa9P*U#mSX{G{Bl%P*lRez;J+pfx##xwK$o9f#C}S14DXwNkIt%17i#W1A|CX zc0maP17iUL1A|C*NRTrF17iyV0~1e4YDEbH0|SF|enDkXW_m`6f}y3QrGjHhep0GJ zaAk2xYHqQDXI^rCQ9*uDVo7QW0|Nup4h9AW240u^5(W3f%sd4n162kpgNVo|1qcff zJ_s=cNG>fZg9jx8g8+j9g8_pBLjXe}Lp{R+hNBE`7{wV~7)u#fFy3PlV+vxLz;uCG zm^qSpA@ds+OO_6nTdaDlt*rOhEZL^9ePa)2-_4=K(Z%tFGm-NGmm}8}ZcXk5JW@PU zd4+f<@d@)yL(o<5icqT158+-B6_LH7;i6x}CW#w~Uy-Pgl#@Irl`kzV zeL|*8R$ca%T%Wv){2zs_iiJvgN^h0dsuZZ2sQy$tsNSU!s;Q*;LF<6_B%M@UD?LHI zSNcZ`78uqV#TeU~$eS{ozBIdFzSClfs*^S+dw;4dus<{M;#|MXC)T}S9v!D zcV!QCPhBq)ZyO(X-(bH4|NMaZz==UigLj2o41F2S6d@OB6%`R(5i>J(Puzn9wnW{e zu;hl6HK{k#IWjCVGqdJqU(99Cv(K+6*i`tgSi2;vbXD1#3jNBGs$DgVwO(~o>mN4i zHPtkqZIx>)Y(Ls5-Br|mx>vQYvH$Kwn@O`L|D75??eGkZnfg$5<;Xeg_o%+-I&+-3%01W^SH2RkDT>t<8AY({UO#lFTB>(_`g8%^e z{{R4h=>PzAFaQARU;qF*m;eA5Z<1fdMgRZ-Pf0{URCwBKkh?EK0Tjl6x4nJW&{jhl z650+1Y(%7;G|`C1U=itHlVFng1FQy-U?E{>X#4{R^qKz7grlR*AgWEyV z-#4CpyHgcZQW7Vm0yDiiai!b_#xI4;V}04lf;{AixzV?vM{%FTtl8_zU!08DVr zJx3he5(vnj|hTb0xx!6C!IHX>Wy7q zC=%Ex_G0nF-whG0>@`@aEKf3p;h$4x#9~4ATN|mv)3KYz}z0XTJc! zy^Pe7V^t7T2t25dj)JbCP(c**){iuRBE6?C>HGcd{N#yJE;v@M`XoNDTA3UhZk+-76)W7e8#~<@(L35f%x|on`N28}E=;oO#vz>rCwy=o9GZDWxvDd>{ z-D--FjawD~E(N(2v&JQrBSA5q%AlOMy=m!yCqW~tG<*|F@4fPI=HaUR|HeBl(5K&= wZ*9UAjXgvw3b`r(fu}0D!4bnur;B0cGnSc*GCpbdu>b%707*qoM6N<$f>S=7ssI20 literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/PhotoInfo-16x16.png b/UVtools.WPF/Assets/Icons/PhotoInfo-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..f6a4c2fbaffd370750b602bda97c1fac03e73637 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6x;6P=4Ly{>_blHS}KEPri`K6Gu%d0)Qo<=^K{PfS^8rJRtszR04avGw?b8~c?r zTjS*J%>L#2WVw{fy4=SnZ@G#-xOuAaNMD`kjY%E4F$>l8n#Ii-&h4FcaCxhVe5yjc v<%NF%A>mwqBHP}WHJj8sT-Tkoznb}{K&Z-@{<{l-&SLO%^>bP0l+XkKY~N1} literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/Wrench-16x16.png b/UVtools.WPF/Assets/Icons/Wrench-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..2838a764ff7348dd2a26290d20fb58359dbe23b6 GIT binary patch literal 237 zcmVHJU_Idtw}e9_(Hn`LNc4qE#T_D%ifctL4wv=*ecG{4iW~#BTv(H+ z#+e}4l_kM@2ZCTPc}%t-2zmhjtv(k!2mHPpkNHdNjZHytYEF-B!8)-rwT^|T`bFBD zThbJ*oXZ8Ex=)Lgi-o~LCS$x*Ii)CXU_fg=lSW(8>7Hyd`Se0%h3AbaMIMA9D6Q^N z$H7aC#p4EnB0q}^{f)(AkB^q&o>}JDL51hg7J)~qz>g**(X;gcl$tzAtOJcB@OC;H zvF(=WSj5AV_ypWTJVhWFrW=%4X8-@8umUtX8b*{Z5?&-ifdU@%`>050Lcc}>7^dst zi1^{fgNKuNz&8s}T<7=dG_VG?uHgW*lHuSh?4-ne9%I<;{0+3Q%YhDpYr4Pi43y7E z$YsChw^_dWtmbuqcKNO5pFxN1F?Nwa!Qe4{s<}SBUj`cZ;WZnfe91UJzOy;rzxe_K c?qSzHo7hQnbK22+s{jB107*qoM6N<$f*ty|eE2Tth c!3hS2X?|k6&*FVdQ&MBb@0NN%y8~^|S literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/arrow-end-16x16.png b/UVtools.WPF/Assets/Icons/arrow-end-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9d9c7cf9ed1b248b44c85d876e489ad7bb714b GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf65)cXySxh z-n?AaGXwJ`OQ-S)IdXbAK5|*|HF}%Ubh~}`%$SqZ}1rz{XK;HzR@)bK-J zV7_G?{tba7wsrlmJZ-K(&Z4tab!Oyi;nh{soNVW zn3PQl9HhP*Okj&?+>u_Oq7rar$Ap#j*B^Xfa%EsR$R+XquHl76KnF5-y85}Sb4q9e E08_k2`v3p{ literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/arrow-up-16x16.png b/UVtools.WPF/Assets/Icons/arrow-up-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..585744a2bbad544a2ed79a5afd74600e36526e1a GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`9iA?ZAr-fhQx*sqJeruy^hiwM zAMX)fhd=X0m>p(4XDqatV$a=Syg~AiM@t%8O`CzxO3CGlJt`T;vN)7GXBqM|N(S&9 zk#)&xYZOv=cT}w7k;5ORb~R3gx=wuociskuGKD(UBQ+V1<~Ky}bkqwOF|gce+`-ea qbHSf{hdZoCtS^c_I^FBS$l&=`Mex{-IWamvt(cb4xJk zxl3=|)s$Sb8z&?L7B;#Z73Ag9QZn|MrKl0OOz3hNyKb73&%O$SM5!a)((^MeByh<* zIyHCuTv=8YWha{*Hx^Gk(!`;g@@0+1eXstXOi3|Wt7h+y;RQO5!PC{xWt~$(69D*V BOhNzv literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/bowling-ball-16x16.png b/UVtools.WPF/Assets/Icons/bowling-ball-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..f23166541a584f1c423787e1d34e77bc6bd94de4 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6T0LDHLn;_+Cu|gS5fouCpQ_=? zJN>1@0?|enLnhk{XLG-Vck{kKzumh*;zuH<$}1zm4H`DhnlcqEmHze9{%dS5^pWI{ zZCKd7^m1RL#LIYsk>PYjtXu@cf2oSES5NgE oSoyqEhRb=$g=wuFiJw_*POty9^U#iMKnF2+y85}Sb4q9e09jH+!~g&Q literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/burn-16x16.png b/UVtools.WPF/Assets/Icons/burn-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..217963c1176343c9f0b228010bd7046769f78661 GIT binary patch literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6W_!9ghEy;nJ1~EB=wLBe`ky(` zHZJpy*PTWoju(A;XO9<1xgN}1z`>Q#>ZOpNy=e>IVeu6oWE5I9>|=0!xPV`)g7wU9 zrl(&OMP!<}EE_8M0`3{^usKuwLe9HPDP)7|HMO?o4m&t4H!-BMrAWV8+VULeOa@O^ KKbLh*2~7aIT}sLT literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/checkbox-marked-16x16.png b/UVtools.WPF/Assets/Icons/checkbox-marked-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..ab94ab34d20f4b6fc653d993056117ff00caf7ac GIT binary patch literal 232 zcmVP)0 zC0Hb200hu??(P?_omo1;6Oc%J^hEDasighLxLI%XNW$IS&3-nm%S?S~2C9v@64H8R z$Y=gLSEtbbw3Zn#N5r7?-0&Lr?9wJ8J@t;%VmdSU?Nrc{4cs*>*zi6ZXb=Q7B!U}0 z0{%D`bdwC49IM0wBZ6hGlfffvf+*1_xKc$j;D;!2;!@B|8iqfhGVf&0)fo{0000)-muZzA*816472y85}Sb4q9e03x~|A&=hvC0xu>N)Gd`SGQp1rG(`6l-BiE5^xX7(8y;o4IkfrPFK^}&g z!AsU%mVTA->&uHbZ!WqAr#sI%-NGhhp)TBDmotTTQaZ0)m(%^^W>3G2ec2rKRufzI z&*Qlu$R;PvBeU@17-})R-g+RJYD@<);T3K F0RSKzO85W( literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/code-16x16.png b/UVtools.WPF/Assets/Icons/code-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa33a4197339e6988be0b2d3bf7736578c65dd3 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6`aE46Ln>}fJui5sDUhM{;c>&$ zk6srTo?ANg`RmOxQFB}~*FEjqsdl}*?r(l>`ENP9+q;wZC8Z}mP>Exkm-H!lebdyA zMYn#X3!Rl>|G4eS5y1yakJ#iMbN>G&}9ssu6{1-oD!M<)Gkzc literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/compress-alt-16x16.png b/UVtools.WPF/Assets/Icons/compress-alt-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..a2129b8e3cd93e026b9878788076d52dc1f35d88 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6LOop^Ln>~~?Z3!*z<`4_U+()! zo4#jEKi}AeW$3ajYMrxZ{cd?ncLTTO`ZCFfUF2nj%`DvMy+)D#$z zEl?;;@c?@Vq3)l6l_3`cpQ$bo!WwSXHE+}0c>8>Ti!nj*(D;Lc5(~~CCOnh z0j*X2T~br4?nq9lJjH3E&5x{EDn3v}b4vY0y%qgyfND3nnAiMYGA_UoZ-^rTuX_#10R0Wq{)05j&8oj{xM{{epy{SCHHO+kY&Z?j zSdIJxg5+@)9(ZKZ))b1%bLeJ!KGkPK$Ba)7@_WpX_u2<5wqxUYudNWt@`Q7ko7=``#}6} zQJ=LBNZiIikmK zFHQ!p2YTZ(lKhLz7&S>017@^Z1cN0Bzopr0CFZFcK`qY literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/crop-16x16.png b/UVtools.WPF/Assets/Icons/crop-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..225c3442112935c717a50564ccf6c0e60d186ea2 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6^gUf1Ln;`P8JhnmbjS*XeUN8c zn8R|%-{W9?6W50wi7&Jcyh~IPeRF&<1M>u_{R~^>Yndx;e58R|89ZJ6T-G@yGywp2 CeIDKb literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/crosshairs-16x16.png b/UVtools.WPF/Assets/Icons/crosshairs-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..62e9eef887d3fe2f6ad55b8cef1b0c2e844722d9 GIT binary patch literal 3295 zcmV<53?TD~P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0006CNkl~frNIXKAfl;gX=w=>lm?f| z#-am3e?U-UV?hp05okj}pkzmjEVaz9EDz<;^ESMXAr3uobMri0_s4Z#&z-u2Rs6sq zoJTz>fsw>%|AiSm!~m*MigW;o@Ecz+hE}vB&L@lqOg{L3aWU3x2{mlm%iTs+0yb)3 zrJcJqY|5|0$7=~zLwgz8_A${!_bQ`BW{b?OGTK0Q2NN0Ertt?wq#HvkJ1D)vAZlK7 zD#O!?q=-f8-gELGPp&eUCzGbIjFQ7iunS}xIQD?!Z|OgZpH$}=D5w81xiMZI;&KO7 z3p|^G6S$G^iRTzTjXvb?B3KT$a29h6$Hdpsh147$N~o%0>u=^}SdMr!&9yktOC{3Y ziMd!uSvgx4n2lMCglVon8}I*p@7h4&OlWr_g+83ae4ubM#6}%qh?Cr_WzShU%h7<{ zWOtLTM@2G&&KmZ7<=!srMXDDiiKeB!e5;`L4W}A;+7!C}O6nUY_w!_l`P*b73I(Lc z!x#Qcp@Jj5ygHBoM~ci!_TpV5?O3?ak>?b)qYP0LmZCnXlpCV?JJ}Si5nF?`&X66Z zd5TB*o%X;_ew;M3MEMiaK74x5vlA5+*F-ev-3 dXq}{g2LO6ruDN!jH}(Jk002ovPDHLkV1oE#A*=uZ literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/cursor-16x16.png b/UVtools.WPF/Assets/Icons/cursor-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..b0eeaa03e10647d3fbe545919afd5814bb12b597 GIT binary patch literal 507 zcmVb~m`WIi`y6wSz}SB#0D>n9l@hbLY*? zI(+1C0|G~ep)d?ReZ51;$%(Y zOP4Ntk(ZmdV%hSgm76wiwA{3DOPs2x{f{0$OmlU2MpHFz-@4bGl9F;p0Sv6It@Tw+ zrMtVE&dv_{dV2*R3=9o50|P?@Lg)8cO<7r)1nBJQqPC{Ct+%(gp8pI@Oifbb6XQCz z@7&f2*Z}|mz*;~DP+Z+yU!1>qw$H)Q;RXU51`&7zn*ac_-xu%3#>RdJoB)7O1Tl=k z%;hVWwSM~YL6%jN$kS&|cKjaWamK-N*X|uP{}w4%UcYg*AHh7v7>} literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/delete-16x16.png b/UVtools.WPF/Assets/Icons/delete-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..b5842b7f91aae6fe2a14c054429e4fa1f9ce23b1 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6f;?RuLn;`P7f4M=)ksfh`#hu3 zCNkvZZl3>=)10R;oP6qVFE&N>sYBy`0abxa1D*EM%A9)b8w8#uY8{;7rr|hQZB4@h m(H2?H8?#%Oy9xq=`535 z;7HqXyg;5~enaiYZbjBuN6T66{|&bo83=_q9N?NH)5-9uAYX`26nbB0Tt WF%ffB+U5ftz~JfX=d#Wzp$Pyi1vw!A literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/expand-16x16.png b/UVtools.WPF/Assets/Icons/expand-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..a8c87f4833acc9f38338d912c657d859b0006b57 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6G(BA$Ln;`P71;i?J4@_f5<6vgssbP0l+XkKK4KW- literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/expand-alt-16x16.png b/UVtools.WPF/Assets/Icons/expand-alt-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..22b181f78266ec8a84309b1f3ad3ff9531df7d81 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6JUm?-Ln;{O_HN{5FyJ^`!|z`t z#b5HqzU1T$4$kx~OE)~eFiUZ{!Va!IVNKT^i+%)Lnzo=L@aOwq`CVVi>jQBzwA&%Vx&S;}qQE-Bw&i)nJ+A}uyLXce#g6d|#ZC|< z*gOl~H9vz_?GLzI3p%GxV*l0_C(E>eH~|Kk@UiL*Ja4m{bs*nyYDj#Q)Tmu zb2DgG7&5hGabepWSzBLY*}h{Ng-|np=62clN5)TKe14|=d|&iBnC(9@5AUpHi`b%0j55!`OLNOPy|3RrqM zP_NGsW+`$l{b};;z$;iU53~YI;6vtn8r2Y82sFr|T}zc~Wxv4gb%b`p-v&th+a!^M zzm4GWA;pStrhe1rGQQ}iB=qjt-5{LF-!MFgTeK8SqZtWQ89cH(MVRHP^%m#hR+UmC zVTN0EJQKI8H1L@(RU(arrMXJN?9RRyl)x|fk&!LY(vG>C%tGz5Pu gihFtVJL@=a02XA0K_}uHw*UYD07*qoM6N<$f-jTjB>(^b literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/eye-16x16.png b/UVtools.WPF/Assets/Icons/eye-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..4f3c7e2dcce9a67b4c8c9be8b1d9d7e22bf53bd4 GIT binary patch literal 402 zcmV;D0d4+?P)E#x7PILGy*5Cv`Wb#WnmjzGX8 zHLO%|0UFjK(+e24u<{@MTqYMnxPV!eJX4iY6P2c~qRxMaK&9kVC7%U%onxZ~M#qoj z6-KM_DsfaONgK!SyH9C?QORBACf@tW*ZITB4E#x7PILGy*5Cv`Wb#WnmjzGX8 zHLO%|0UFjK(+e24u<{@MTqYMnxPV!eJX4iY6P2c~qRxMaK&9kVC7%U%onxZ~M#qoj z6-KM_DsfaONgK!SyH9C?QORBACf@tW*ZITB4@^d$XhI_|)&zM!D&klX4Xxq3QcbAS^#v}UUF5iv!kZ8t_Qk$sXSY{6#i(*@ x-RjjA{SpyGmFcu68Pb)haJ?K9nXoJ-nNu>zP~)A&iEID>002ovPDHLkV1m}cYa##u literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/file-image-16x16.png b/UVtools.WPF/Assets/Icons/file-image-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..7e10379a9276d014d089e23d7b626ede92739fc9 GIT binary patch literal 234 zcmV8`d)#acTI+pVoKYdfEVO&V+a`rlstU zd)wNyiqhf6k7Y@#5>x=-RPbXd6%?m|h*-!4c05OYcvFxH+AN9zs1#Hsga6(IQviz7 zLCm3hHRx8F4FJSkTh9)Q5%fcOy7(B?tyH!HSU7S|(^QnpAx{sF1!25lA~L ksW#j0{UPb@w9d4_FXnYxk?Dhl{{R3007*qoM6N<$f`L3>mjD0& literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/file-import-16x16.png b/UVtools.WPF/Assets/Icons/file-import-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..1712317e33c64079c9be6d71389fb77a989e6ddc GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6{5@S9Ln;`P8=C*05IA9fY5|+j zv6T!R>kU>s3}pyg)aTA9G4J?F2H`))`3yy`2nR5vs6Gg1VA^?tYh6NV7_TDh!XIln kj=paT;M)6hz6&cu_UifUGe6C+1scuZ>FVdQ&MBb@0JSSEdH?_b literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/file-refresh-16x16.png b/UVtools.WPF/Assets/Icons/file-refresh-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..39d6920d60123ff26b325154d40172c4d2a84927 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6x;*v_p-CH-Oz~KAJb`nCY{r&_P2C(D-bA!==aPcSfP)K+IM2_=~2wUas${ z@5?izaUC`mX?0<1k-Z4)EwGV9Alaz0n}VGRcLx0!46&4a`1CynDOSOa-a{7j@yvMl zrOAR6PsWwACuYGp-icQ~E{Y(p4uB iE!%9K+=i#@+5Q8Y6k>=arx9TQ0000M7SilDu*E4ZO;4WMEX7l2+d`dnZPowPv3|lA@(#+rV-^ZPg-p=eX1U#|6(U0ZyCkpWq;% zzdLcsd>E^@Pl9Ry%!vzPFv@vB@Jf`H_u>*=>=241zQ)goqC9C;ntGW$amZT-i8gNGja692A1z0FvsUdT)_;Hq_Cl5c6`e-XeIU!8K)9{ns6iR`jj ae}GmO$c-l0ZzOL30000RXW zLdSHiQA0!z@;r}-h)AeZY6=_EHI9?kZ$hI*N5>#NBNP4sK@>KoYhsZ=Rj+|SAV6V} z3_gAV@bM3%uyJ9b4ChZvK+jC)E!R#F|HEX$49@&uHG`z&6oiIHR3b4c8P_kJEite_ zY$4#EuEV-pPMFS_AE@{Rjjx{{Gl`2&ps=y8uP>y+$C-C@fPiw!HN|t_R@p}1qUN9zX16K1qcoa#%W%Pr3+?n8h_&ZBJsySJoC!N9hX#? zMaXc=JQ`EQ|2{P;QHN#AmhBe_Pid}SK96&pm`0W_oxTU}=MT>X-Iru<$PjF07W0H^Y-5#}T$2GQ70Y&P0T7X6f_JJG|48Eg z68@E79w~!GlpIsUH5g2l{L{YkNP{zZqD_n(HYD@5G3D6B%Hfiv!nvPem~iB+RW*a| zBNxn{O-l65FB?8-I=Clk;F_p{Yk~@HNouxc5mvzd-=)vE0gY-<%dW%b&Z7se{f&ZK zf)bJWCPqMpj;&23d)(y!cE@HBtBn69s=*)bWSkT6ON;Zz4O> h0Cl5ARp?nY@_(FdG5+txTj$xneZU#Q_gky8% z-JkSU3(w1Cj3`@Y#$T;MjoF?n)#G=RJPpmTDb@X@Wu3d> p;dvd0Z4ySVY@d$pxxxH{-C4t*f1carBS1eec)I$ztaD0e0st(WR~G;P literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/layers-16x16.png b/UVtools.WPF/Assets/Icons/layers-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..b8f66f5144f0be720d4c65cce4abf4e169461905 GIT binary patch literal 358 zcmV-s0h#`ZP)yVku|Z5GfQ5Qk)1@1oLR5;^F8`_g#SMXzd6A7Xi_=EAd)m9Fs4DoY9wsX z#tGaNK*8@I2@>)5&6Bt*z^<@2=ayNs-2T|>L&5|#g4C>CVSmigl1B!tS*%6_1X{bH<@w!KM124grO0p zPOsz0elf>5d$21UB*kQUBT|orH?04UW)Ox(kea@Tv|~P1%ng^8+*Hsa@GS+t4Bb=|7Zqb)A;|Pm(`|@V zh@p#TD^I+{Kj(+y3jTtMnWqhyH99!c8B!Y(L??7guTxsVkaW~(%_QyyqXdPM6HY8R zV=(cdwhz~dSqB!Jo4_!Iv8igqh2l0Pw!$`(Hg=wVNiT^T5}z8C910ic1n4@&+c%3f r%Q$OKiWFvRmgZnJeRx7i;x5DD%6WSo7fja#I*P&5)z4*}Q$iB}@wh)h literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/list-16x16.png b/UVtools.WPF/Assets/Icons/list-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..85d6795874d84f88ff73facb678a1afb4e289758 GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf66g^!WLn>}1EAYHJD8T=NzfGZl n)noBtZ6A?nM|1Z+D^>bP0l+XkKqS+WE literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/log-16x16.png b/UVtools.WPF/Assets/Icons/log-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..55d778559146a258ad0cb6204ab8446a693d1feb GIT binary patch literal 284 zcmV+%0ptFOP)i7=Y0;+cx6tHXCVZYqQkL>^9qOvyHrG+v(Z1&zCNLEi5%fNA23DqN+?E9JW$F zEo@S%qDf_foC08xLf=iX*>z#c>n^WTToSFq z3muG?;TjO^s-`CDqK^RIbODyjm*9%EdH_0lDas%K#@O$pLU~@=VYD+cP0~tl>)n#3 iT&XqM)xkVVG*Jm<*m7m=y}^J00000*af5HqP4@dS*Y>;kcknd(hs@ zt5HWkvu;qn<7%3@?!*RKZ)Ben$jJ)W{&q1!>VT;>gnH4Sz9*V%3k3q svBYM=l#M$-xgBGFEX8AgOWQ{M=%?IN>$wb-KsPaXy85}Sb4q9e0ITdxQ2+n{ literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/mask-16x16.png b/UVtools.WPF/Assets/Icons/mask-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0a450a408cc931a160fb4d1f368f59d7e58f234b GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6iacE$Ln?0VJ-=M?P=El#gZkc{ zBTA8vQ*!q8II#CG%M+CS+Q#wxg~g70-Txg`w=65`3|_lI7?uD4 literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/move-16x16.png b/UVtools.WPF/Assets/Icons/move-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..a01877066cf1e5a24975754b2f9277148b6a2cd6 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6l001;Ln>}fooLR;V93MVs}9xxy3AT;iiMR>#AzjeB9~plM^BN?(3QhK-(BRUHx3vIVCg! E0G*0A=>Px# literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/object-group-16x16.png b/UVtools.WPF/Assets/Icons/object-group-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..e5cd1e9531e16b50d17c3f4efa2cd5dbc17118e5 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6f;?RuLn>}4jc~4=yWW@E1QSsydiyIfOe$Qs?eY`9sCo3=f^x4CwTaGjM$jD9p zXRjmGwfNFM>m9#bIy=2LCQAr#P3h@4+3>hPq0jTwUwP5#osFg@UrjFZI%uf%)O(&j zu{lXXVEP>YHH_v4hZHQ7e%AXW@ddKAxG!IO+(1FetU2QL|LUJ@TY)Bt&Uf9yXjYb2 vsKM6Z?V;Ty)W3JKcwj`Jr*CiK4+e&_-uJ)hwMPc8St7(-u*h;-?uyo=@=P2xC05X-(2(RSEN?W0jfy_*( z>`mkVnL;QG4HUvmCWSjwA;j%#coarP!oW>~>w}?Gn&S67yO+8qFFY73l19i)?NvX~ zlD~F;H5bB%P^E*i6OKA_KCRHGrD_M1T54x2VInor*|=EKS37z8x9+*tTJIb2gJcF} S!L29&0000C#{r``F$<5ze<66;GN#;0j^%`D+T zHFx(M;x|~$7C$}lu(m|O>hIIvneJ;4+FPf8p09CUJ=Y;u&fm)?r1$=>|Gr}d`=!}V VUmiL=R|UG4!PC{xWt~$(69C!iTQmRw literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/pixel-16x16.png b/UVtools.WPF/Assets/Icons/pixel-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c46a76b19af8f41b29358b53d88c43ed2f4764 GIT binary patch literal 454 zcmV;%0XhDOP)$w}hfKsUG=eSLlaWNMsPy|_71rP!F8mXq7^-v2?Xd;BGW!aO zsX2GG8QX9VirDT z`llw8ltJSOzT+HLVXl}V+wb^+H3c%Ow4qj#7xWn)@D{J|9-r_7oBg3c!At`rq%w;x w;x>MW?>K_BGMsZI)KrT1(iZK|DYG>{0o`+&S@|J87ytkO07*qoM6N<$g3OP}kN^Mx literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/plus-16x16.png b/UVtools.WPF/Assets/Icons/plus-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..7614e37eab99c88f1cacc589f53dee8ae00919b9 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6EInNuLn;`P6?m5z{$W34a);~H zL9SQq4vrcD96X6!4-7;WJ+RO7Skh!NCu|9CTfqSi!3j(XoMbV|n8Eq~<+mEKeMs(tM}K^2E^z&2zq3o^YJr z{N`M6DI+0gRXV5?FtKbiG}t d;8LW(@bq42oN;;jHJ~dPJYD@<);T3K0RROnLZ<)# literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/refresh-16x16.png b/UVtools.WPF/Assets/Icons/refresh-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f7827087ff79cedfab80d96d7fead583fcc211 GIT binary patch literal 245 zcmV6S85jg%X_!SVhOgMx!#aq3*z1FtMUjWaszrnL@`PjiJciNV zmE-RCzxPQFT)J`V%8?ygrdEbjoqbdb;cPwr^60@w^lxe$;v@#WxsCIbgx6S)W%c)9 z63t9jb3%z`BwOg#Rs4g};+C>ee7exJAF8rh%=YO1T#xkzFXV(%8*_bod>mBoG5GZ4 v*|#C;LRhMpxHqI)ncA}J*tI)Vaj5wLIOc9Ey+Hpl00000NkvXXu0mjfI{b5b literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/resize-16x16.png b/UVtools.WPF/Assets/Icons/resize-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..3ba586cbf39984f8f06e7448e4b6b1916e765b46 GIT binary patch literal 229 zcmV^P)@w;w2+2v7 zoh6}1XQXpMrBy04YK2m(!bN9`gQKgbAD~xR@-PYEsWK2+Yd%7_Y6VGY$<42i$x$hB zR&4YQ4+n)4S#7I@U$uQEBUj7Q zqajmQ@!DliH9pYrFR=N4Rdk}wTT{07&{e$ur2kycYT%Om;~KW$>Kb#|H4F<`&Qz|B zS}}vS$?K+;+ZNK|7MH#3WlNLdkThklFU^*+CZySEaY&kx#&@=Q((NA7Yzul-->A;I z0&sclY?$_JgWm@K z^$)T!!xbn+0HuE^dV$z{EUKCMJ_bJw{wb$GrS-x3wWdILg4_o8^_S{)0L?fGRbaqq z@Y3L)lncx}c~^r!8ty;F$xF@2pKbKGQvFg8z!yQ$AAs! qABRf!FklB_vcNdJu2IH-0{{Sl(tM_fb-ES+0000 literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/settings-16x16.png b/UVtools.WPF/Assets/Icons/settings-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..83e560ca504c34ca3a64b9526f870460e53b9770 GIT binary patch literal 290 zcmV+-0p0$IP)rsYx zg`aGA&-=-y@VwLJ)xh!o^=kLzt)1R}7;LpWM@bd$E~0hQFG+-=U#**~*)CV;k@jb% zi6UH&j4mdH4+!aEQlFSX36Nabm6a0cSLbr;bOCNJ;e-H|_C&2LK;oLD?KVgj<8$}J z5(wqeE-gK!NEQgFxE7h*i;V6?hV;}XH^WLC&!FOao0$f%GV1G~lvAd2)c3PGFKb+1 oO4FWq%HZ{+I=HX9N9ldt2b_MTmP&zhYybcN07*qoM6N<$g7&|KSO5S3 literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/sort-alpha-up-16x16.png b/UVtools.WPF/Assets/Icons/sort-alpha-up-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..765a4ddcc4df6281f6722dbed82a8344365fbc7e GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6NA(>_`~ib z+u|S*p}=!4pY?NeVoY|Me?p_bgBZ)5WDDk&?+IN0lpO^)ST8AP|7VWmInkAnARY75 ztb~@ZEHQfLJ literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/square-solid-16x16.png b/UVtools.WPF/Assets/Icons/square-solid-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..d32f1a0ebb36fa66fccf31155f0c355208fa384a GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6v^-rLLn;`P71%@!{v`eAXZ^=? ws)5l-DwtE^&vD+)5Q9|>2?4@=I)@k-y8j)x>F(rd4%Efq>FVdQ&MBb@0F|B_)Bpeg literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/sync-16x16.png b/UVtools.WPF/Assets/Icons/sync-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f7827087ff79cedfab80d96d7fead583fcc211 GIT binary patch literal 245 zcmV6S85jg%X_!SVhOgMx!#aq3*z1FtMUjWaszrnL@`PjiJciNV zmE-RCzxPQFT)J`V%8?ygrdEbjoqbdb;cPwr^60@w^lxe$;v@#WxsCIbgx6S)W%c)9 z63t9jb3%z`BwOg#Rs4g};+C>ee7exJAF8rh%=YO1T#xkzFXV(%8*_bod>mBoG5GZ4 v*|#C;LRhMpxHqI)ncA}J*tI)Vaj5wLIOc9Ey+Hpl00000NkvXXu0mjfI{b5b literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/th-16x16.png b/UVtools.WPF/Assets/Icons/th-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..16bfb6ddc07654b2e397e4dd8931d29502d22945 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6v^-rLLn;`P6?pzRKMY|Dw1^ft x(Y*0t&tD$Cf^Ezb+}AKQgbP0l+XkKaUUji literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/trash-16x16.png b/UVtools.WPF/Assets/Icons/trash-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..ef9d610848992802c9700d5f40bcf5bc5173d319 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf63_M*NLn;`P9hkoI{8tn>;lvoe z;LwZ@T#2kMOfhN`RxFU?n0R91iiQG*tBbuAm1G$dyr(S|FIt@o)XU)M>gTe~DWM4f DT1Flj literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/undo-16x16.png b/UVtools.WPF/Assets/Icons/undo-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..a9b83da720c883436c20bde37f15f6e6fd8bb193 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6)_J-(hEyca0-E2rsKE1p!_zx3bdhr9dQtUC5+V}np$Er}kDB?N`F1E-9) fYU%Fm+7G#o#U?nX7o=zdUC!X?>gTe~DWM4fyj@%h literal 0 HcmV?d00001 diff --git a/UVtools.WPF/Assets/Icons/undo-alt-16x16.png b/UVtools.WPF/Assets/Icons/undo-alt-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..55f04c68750c3c6dad059fca4064c233b582107b GIT binary patch literal 259 zcmV+e0sQ`nP)l*xBU(EL{+mk~5H`(5b{Z$j~TSD<9Md<0sZ~FY@?)qSPRJVP&<~58h#eGcMx`y`K zX4!V>+|aNw0s0n^LM}={smg;i8%jPk$keO0b*62X_VtbI;MqZ!+3amkEKGLYlRdcD zd2pRHL+e_phBo^bIS-Xz_vDJNdwIlldiDYCtCcrBP<5-o@fA*kpjeJ9a~xWDP0pUT z$K5wGl{>v@bLhOXw;)iJ_{>$ieyxFGxpIJPq(9Vw${3*8xp12uRkQoM=4yI60QOc0 zgdiY7ZgjK|#P}N;GV3BEhdU76zKR6^KmaN^{Ri9N*I=Yi0KT1bUah$9f`#4PX(xT* zen!TO?=@>;j$d87;`h3BbK5_fRmGp#Uw}&+>}SibIbkvEot?IWS2S@8`BJSKmko0$ zZ`{Biy?UY8f6_L7CDcgLv!CAIyvwwH=52ppbi6OS=7^%-tNrm~<;oKI*|Ye$b!(~r zp>pL@Af|evw$A^n_J99hbwJV2H9q(*Jzer^%NBfBy}HzYo|blm5f6w7(o97}eLxB_ z1%8*w@o6PT8Ss@j5CkC?d-pCNAyWU^uV06y12!L49KHF7&inKO&JLROC*;t1#cW24 z2hGY~fEN!?sigKFj=Mhd<;z6`%1EQidiFC17(ONhm|JTMMq52MsiO(tPXT_uR;jj3 hdHHh8g`YqFWdZnA=Q!gFBC!Af002ovPDHLkV1oJ Zoom == 100; + private ISolidColorBrush _pixelGridColor = Brushes.DimGray; + /// + /// Gets or sets the color of the pixel grid. + /// + /// The color of the pixel grid. + public virtual ISolidColorBrush PixelGridColor + { + get => _pixelGridColor; + set + { + if (PixelGridColor != value) + { + _pixelGridColor = value; + + //this.OnPixelGridColorChanged(EventArgs.Empty); + } + } + } + + private int _pixelGridThreshold = 5; + /// + /// Gets or sets the minimum size of zoomed pixel's before the pixel grid will be drawn + /// + /// The pixel grid threshold. + + public virtual int PixelGridThreshold + { + get => _pixelGridThreshold; + set + { + if (PixelGridThreshold != value) + { + _pixelGridThreshold = value; + + //this.OnPixelGridThresholdChanged(EventArgs.Empty); + } + } + } + //Our render target we compile everything to and present to the user private RenderTargetBitmap RenderTarget; @@ -778,11 +819,13 @@ namespace UVtools.WPF.Controls /// The relative display point to offset scrolling by. public virtual void ScrollTo(Point imageLocation, Point relativeDisplayPoint) { - var x = HorizontalScrollBarMaximum - imageLocation.X * ZoomFactor + relativeDisplayPoint.X; - var y = VerticalScrollBarMaximum - imageLocation.Y * ZoomFactor + relativeDisplayPoint.Y; + var x = imageLocation.X * ZoomFactor - relativeDisplayPoint.X; + var y = imageLocation.Y * ZoomFactor - relativeDisplayPoint.Y; Offset = new Vector(x, y); - Debug.WriteLine($"{Offset} | {HorizontalScrollBarMaximum},{VerticalScrollBarMaximum} | {HorizontalScrollBarValue},{VerticalScrollBarValue}"); + Debug.WriteLine($"{Offset} | " + + $"{relativeDisplayPoint} | " + + $"{HorizontalScrollBarValue},{VerticalScrollBarValue}"); } /// @@ -989,6 +1032,7 @@ namespace UVtools.WPF.Controls public void LoadImage(string path) { Image = new Bitmap(path); + Image.Save("D:\\test2.png"); //ImageControl.Source = Image; //ImageControl.InvalidateVisual(); } @@ -997,6 +1041,8 @@ namespace UVtools.WPF.Controls { Debug.WriteLine($"Render: {DateTime.Now.Ticks}"); // base.Render(context); + + // Draw Grid if (ShowGrid) { // draw the background @@ -1021,22 +1067,33 @@ namespace UVtools.WPF.Controls } if (Image is null) return; - - context.DrawImage(Image, 1.0, + // Draw iamge + context.DrawImage(Image, GetSourceImageRegion(), GetImageViewPort() ); - /*using (var surface = SKSurface.Create(SkiaContext.GrContext, RenderTarget)) - { - surface.Canvas.DrawImage(Image, 0f, 0f); - surface.Canvas.Flush(); - var textureImage = surface.Snapshot(); //This should be texture backed - }*/ + //SkiaContext.SkCanvas.dr + // Draw pixel grid + var pixelSize = ZoomFactor; + if (pixelSize > PixelGridThreshold) + { + Rect viewport = GetImageViewPort(); + var offsetX = Offset.X % pixelSize; + var offsetY = Offset.Y % pixelSize; - /*context.DrawImage(RenderTarget, 1.0, - new Rect(0, 0, RenderTarget.PixelSize.Width, RenderTarget.PixelSize.Height), - new Rect(0, 0, Width, Height) - );*/ + Pen pen = new Pen(PixelGridColor); + for (double x = viewport.X + pixelSize - offsetX; x < viewport.Right; x += pixelSize) + { + context.DrawLine(pen, new Point(x, viewport.X), new Point(x, viewport.Bottom)); + } + + for (double y = viewport.Y + pixelSize - offsetY; y < viewport.Bottom; y += pixelSize) + { + context.DrawLine(pen, new Point(viewport.Y, y), new Point(viewport.Right, y)); + } + + context.DrawRectangle(pen, viewport); + } } /// diff --git a/UVtools.WPF/Extensions/BitmapExtension.cs b/UVtools.WPF/Extensions/BitmapExtension.cs new file mode 100644 index 0000000..deee547 --- /dev/null +++ b/UVtools.WPF/Extensions/BitmapExtension.cs @@ -0,0 +1,116 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using Avalonia; +using Avalonia.Media.Imaging; +using Avalonia.Platform; +using Emgu.CV; +using Emgu.CV.CvEnum; +using SkiaSharp; +using UVtools.Core.Extensions; + +namespace UVtools.WPF.Extensions +{ + /// + /// Provide extension method to convert IInputArray to and from Bitmap + /// + public static class BitmapExtension + { + public static SKBitmap ToSkBitmap(this Mat mat) + { + SKBitmap bitmap; + Mat target = mat; + SKColorType colorType; + switch (mat.NumberOfChannels) + { + case 1: + colorType = SKColorType.Gray8; + break; + case 2: + colorType = SKColorType.Rg1616; + break; + case 3: + CvInvoke.CvtColor(mat, target, ColorConversion.Bgr2Bgra); + colorType = SKColorType.Bgra8888; + break; + case 4: + colorType = SKColorType.Bgra8888; + break; + default: + throw new Exception("Unknown color type"); + } + + bitmap = new SKBitmap(new SKImageInfo(target.Width, target.Height, colorType)); + bitmap.SetPixels(target.DataPointer); + return bitmap; + } + + public static SKImage ToSkImage(this Mat mat) + { + var bitmap = mat.ToSkBitmap(); + if (bitmap is null) return null; + return SKImage.FromBitmap(bitmap); + } + + public static Bitmap ToBitmap(this Mat mat) + { + if (mat.NumberOfChannels == 1) + { + var writeableBitmap = new WriteableBitmap(new PixelSize(mat.Width, mat.Height), new Vector(72, 72), + PixelFormat.Rgba8888, AlphaFormat.Unpremul); + var span = mat.GetPixelSpan(); + var bytes = new[] {0, 0, 0, 255}; + using (var lockBuffer = writeableBitmap.Lock()) + { + for (var i = 1; i < span.Length; i++) + { + bytes[0] = bytes[1] = bytes[2] = span[i]; + Marshal.Copy(bytes, 0, + new IntPtr(lockBuffer.Address.ToInt64() + i * 4), bytes.Length); + } + } + + return writeableBitmap; + } + + return null; + } + /*PixelFormat targetPixelFormat = PixelFormat.Bgra8888; + + switch (mat.NumberOfChannels) + { + case 3: + targetPixelFormat = PixelFormat.Rgb565; + break; + case 4: + targetPixelFormat = PixelFormat.Bgra8888; + break; + default: + throw new Exception("Unknown color type"); + } + + + var writeableBitmap = new WriteableBitmap(new PixelSize(mat.Width, mat.Height), new Vector(72, 72), targetPixelFormat, AlphaFormat.Unpremul); + using var lockBuffer = writeableBitmap.Lock(); + var buffer = mat.GetBytes(); + for (var y = 0; y < mat.Height; y++) + { + Marshal.Copy(buffer, y * lockBuffer.RowBytes, new IntPtr(lockBuffer.Address.ToInt64() + y * lockBuffer.RowBytes), lockBuffer.RowBytes); + } + //Marshal.Copy(buffer, 0, lockBuffer.Address, buffer.Length); + + SKBitmap bitmap = new SKBitmap(new SKImageInfo(mat.Width, mat.Height, SKColorType.Gray8)); + bitmap.SetPixels(mat.DataPointer); + Debug.WriteLine(bitmap.Info.ColorType); + + bitmap = SKBitmap.Decode(buffer.AsSpan(), new SKImageInfo + { + Width = mat.Width, + Height = mat.Height, + ColorType = SKColorType.Gray8, + });*/ + + /*return writeableBitmap; + }*/ + } +} \ No newline at end of file diff --git a/UVtools.WPF/Extensions/WindowExtensions.cs b/UVtools.WPF/Extensions/WindowExtensions.cs new file mode 100644 index 0000000..191ae84 --- /dev/null +++ b/UVtools.WPF/Extensions/WindowExtensions.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Controls; +using MessageBox.Avalonia.DTO; +using MessageBox.Avalonia.Enums; +using MessageBox.Avalonia.Models; + +namespace UVtools.WPF.Extensions +{ + public static class WindowExtensions + { + public static async Task MessageBoxGeneric(this Window window, string message, string title = null, + ButtonEnum buttons = ButtonEnum.Ok, Icon icon = Icon.None, WindowStartupLocation location = WindowStartupLocation.CenterOwner, Style style = Style.None) + { + var messageBoxStandardWindow = MessageBox.Avalonia.MessageBoxManager.GetMessageBoxStandardWindow( + new MessageBoxStandardParams + { + ButtonDefinitions = buttons, + ContentTitle = title ?? window.Title, + ContentMessage = message, + Icon = icon, + Style = style, + WindowStartupLocation = location, + CanResize = false + }); + + return await messageBoxStandardWindow.ShowDialog(window); + } + + public static async Task MessageBoxInfo(this Window window, string message, string title = null, ButtonEnum buttons = ButtonEnum.Ok, Style style = Style.None) + => await window.MessageBoxGeneric(message, title ?? $"{window.Title} Information", buttons, Icon.Info, WindowStartupLocation.CenterOwner, style); + + public static async Task MessageBoxError(this Window window, string message, string title = null, ButtonEnum buttons = ButtonEnum.Ok, Style style = Style.None) + => await window.MessageBoxGeneric(message, title ?? $"{window.Title} Error", buttons, Icon.Error, WindowStartupLocation.CenterOwner, style); + + public static async Task MessageBoxQuestion(this Window window, string message, string title = null, ButtonEnum buttons = ButtonEnum.YesNo, Style style = Style.None) + => await window.MessageBoxGeneric(message, title ?? $"{window.Title} Question", buttons, Icon.Info, WindowStartupLocation.CenterOwner, style); + + } +} diff --git a/UVtools.WPF/MainWindow.axaml b/UVtools.WPF/MainWindow.axaml index 0e97bee..6a55a48 100644 --- a/UVtools.WPF/MainWindow.axaml +++ b/UVtools.WPF/MainWindow.axaml @@ -2,20 +2,175 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:manager="clr-namespace:Avalonia.ThemeManager;assembly=Avalonia.ThemeManager" xmlns:uc="clr-namespace:UVtools.WPF.Controls" + xmlns:idc="clr-namespace:Dock.Avalonia.Controls;assembly=Dock.Avalonia" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="UVtools.WPF.MainWindow" Title="UVtools"> - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Issues + + + + + + + + + GCode + + + + + + + + + Log + + + + + + + + + + + Up + + Down + +