MainWindow.axaml.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using AsyncImageLoader.Loaders;
  2. using Avalonia;
  3. using Avalonia.Controls;
  4. using Avalonia.Controls.ApplicationLifetimes;
  5. using Avalonia.Interactivity;
  6. using Avalonia.OpenGL;
  7. using Avalonia.Rendering.Composition;
  8. using Avalonia.Threading;
  9. using Microsoft.Extensions.DependencyInjection;
  10. using Drawie.Backend.Core.Bridge;
  11. using PixiEditor.Extensions.CommonApi.UserPreferences;
  12. using PixiEditor.Extensions.Runtime;
  13. using PixiEditor.Helpers;
  14. using PixiEditor.Initialization;
  15. using PixiEditor.Models.AnalyticsAPI;
  16. using PixiEditor.Models.ExceptionHandling;
  17. using PixiEditor.Platform;
  18. using PixiEditor.ViewModels.SubViewModels;
  19. using PixiEditor.Views.Rendering;
  20. using ViewModels_ViewModelMain = PixiEditor.ViewModels.ViewModelMain;
  21. namespace PixiEditor.Views;
  22. internal partial class MainWindow : Window
  23. {
  24. private readonly IPreferences preferences;
  25. private readonly IPlatform platform;
  26. private readonly IServiceProvider services;
  27. private static ExtensionLoader extLoader;
  28. public StartupPerformance StartupPerformance { get; } = new();
  29. public new ViewModels_ViewModelMain DataContext
  30. {
  31. get => (ViewModels_ViewModelMain)base.DataContext;
  32. set => base.DataContext = value;
  33. }
  34. public static MainWindow? Current
  35. {
  36. get
  37. {
  38. if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
  39. return desktop.MainWindow as MainWindow;
  40. if (Application.Current is null)
  41. return null;
  42. throw new NotSupportedException("ApplicationLifetime is not supported");
  43. }
  44. }
  45. public MainWindow(ExtensionLoader extensionLoader, Guid? analyticsSessionId = null)
  46. {
  47. StartupPerformance.ReportToMainWindow();
  48. (Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime).MainWindow = this;
  49. extLoader = extensionLoader;
  50. services = new ServiceCollection()
  51. .AddPlatform()
  52. .AddPixiEditor(extensionLoader)
  53. .AddExtensionServices(extensionLoader)
  54. .BuildServiceProvider();
  55. AsyncImageLoader.ImageLoader.AsyncImageLoader = new DiskCachedWebImageLoader();
  56. preferences = services.GetRequiredService<IPreferences>();
  57. platform = services.GetRequiredService<IPlatform>();
  58. DataContext = services.GetRequiredService<ViewModels_ViewModelMain>();
  59. DataContext.Setup(services);
  60. StartupPerformance.ReportToMainViewModel();
  61. var analytics = services.GetService<AnalyticsPeriodicReporter>();
  62. analytics?.Start(analyticsSessionId);
  63. InitializeComponent();
  64. }
  65. public static MainWindow CreateWithRecoveredDocuments(CrashReport report, out bool showMissingFilesDialog)
  66. {
  67. if (!report.TryRecoverDocuments(out var documents, out var sessionInfo))
  68. {
  69. showMissingFilesDialog = true;
  70. return GetMainWindow(null);
  71. }
  72. var window = GetMainWindow(sessionInfo?.AnalyticsSessionId);
  73. var fileVM = window.services.GetRequiredService<FileViewModel>();
  74. var i = 0;
  75. foreach (var document in documents)
  76. {
  77. try
  78. {
  79. fileVM.OpenRecoveredDotPixi(document.Path, document.GetRecoveredBytes());
  80. i++;
  81. }
  82. catch (Exception e)
  83. {
  84. CrashHelper.SendExceptionInfo(e);
  85. }
  86. }
  87. showMissingFilesDialog = documents.Count != i;
  88. return window;
  89. MainWindow GetMainWindow(Guid? analyticsSession)
  90. {
  91. try
  92. {
  93. var app = (App)Application.Current;
  94. ClassicDesktopEntry entry = new(app.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime);
  95. return new MainWindow(entry.InitApp(), analyticsSession);
  96. }
  97. catch (Exception e)
  98. {
  99. CrashHelper.SendExceptionInfo(e, true);
  100. throw;
  101. }
  102. }
  103. }
  104. protected override void OnLoaded(RoutedEventArgs e)
  105. {
  106. base.OnLoaded(e);
  107. LoadingWindow.Instance?.SafeClose();
  108. Activate();
  109. StartupPerformance.ReportToInteractivity();
  110. Analytics.SendStartup(StartupPerformance);
  111. }
  112. protected override void OnClosing(WindowClosingEventArgs e)
  113. {
  114. if (!DataContext.UserWantsToClose)
  115. {
  116. e.Cancel = true;
  117. Task.Run(async () =>
  118. {
  119. await Dispatcher.UIThread.InvokeAsync(async () =>
  120. {
  121. await DataContext.CloseWindowCommand.ExecuteAsync(null);
  122. if (DataContext.UserWantsToClose)
  123. {
  124. Close();
  125. }
  126. });
  127. });
  128. }
  129. base.OnClosing(e);
  130. }
  131. private void MainWindow_Initialized(object? sender, EventArgs e)
  132. {
  133. AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
  134. {
  135. CrashHelper.SaveCrashInfo((Exception)e.ExceptionObject, DataContext.DocumentManagerSubViewModel.Documents);
  136. };
  137. }
  138. }