diff --git a/src/DynamoCoreWpf/DynamoCoreWpf.csproj b/src/DynamoCoreWpf/DynamoCoreWpf.csproj index b6ec89e35bf..1d7eb20da7b 100644 --- a/src/DynamoCoreWpf/DynamoCoreWpf.csproj +++ b/src/DynamoCoreWpf/DynamoCoreWpf.csproj @@ -569,6 +569,8 @@ Resources.resx + + diff --git a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt index 7ad7160276a..7ba7618bd5e 100644 --- a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt +++ b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt @@ -1753,6 +1753,7 @@ Dynamo.UI.Views.SplashScreen.OnRequestDynamicSplashScreen() -> void Dynamo.UI.Views.SplashScreen.OnRequestStaticSplashScreen() -> void Dynamo.UI.Views.SplashScreen.RequestLaunchDynamo -> System.Action Dynamo.UI.Views.SplashScreen.SplashScreen(bool enableSignInButton = true) -> void +Dynamo.UI.Views.SplashScreen.SplashScreen(Dynamo.Wpf.UI.SplashScreenStartupContext context, bool enableSignInButton = true) -> void Dynamo.UI.Views.SplashScreen.totalLoadingTime -> long Dynamo.Utilities.MouseClickManager Dynamo.Utilities.MouseClickManager.Click -> System.Windows.Input.MouseButtonEventHandler @@ -3818,12 +3819,21 @@ Dynamo.Wpf.UI.GuidedTour.UpdateLibraryInteractionsEventHandler Dynamo.Wpf.UI.GuidedTour.UpdatePopupLocationEventHandler Dynamo.Wpf.UI.GuidedTour.Welcome Dynamo.Wpf.UI.GuidedTour.Welcome.Welcome(Dynamo.Wpf.UI.GuidedTour.HostControlInfo host, double width, double height) -> void +Dynamo.Wpf.UI.HostStartup +static Dynamo.Wpf.UI.HostStartup.Current.get -> Dynamo.Wpf.UI.SplashScreenStartupContext +static Dynamo.Wpf.UI.HostStartup.TryInitialize(Dynamo.Wpf.UI.SplashScreenStartupContext context) -> bool +static Dynamo.Wpf.UI.HostStartup.Reset() -> void +static Dynamo.Wpf.UI.HostStartup.GetUserDirectory() -> string Dynamo.Wpf.UI.MouseBehaviour Dynamo.Wpf.UI.MouseBehaviour.MouseBehaviour() -> void Dynamo.Wpf.UI.MouseBehaviour.MouseX.get -> double Dynamo.Wpf.UI.MouseBehaviour.MouseX.set -> void Dynamo.Wpf.UI.MouseBehaviour.MouseY.get -> double Dynamo.Wpf.UI.MouseBehaviour.MouseY.set -> void +Dynamo.Wpf.UI.SplashScreenStartupContext +Dynamo.Wpf.UI.SplashScreenStartupContext.SplashScreenStartupContext(Dynamo.Models.HostAnalyticsInfo? hostInfo, string userDataFolder) -> void +Dynamo.Wpf.UI.SplashScreenStartupContext.HostInfo.get -> Dynamo.Models.HostAnalyticsInfo? +Dynamo.Wpf.UI.SplashScreenStartupContext.UserDataFolder.get -> string Dynamo.Wpf.UI.ToastManager Dynamo.Wpf.UI.ToastManager.CloseRealTimeInfoWindow() -> void Dynamo.Wpf.UI.ToastManager.CreateRealTimeInfoWindow(string content, bool stayOpen = false, string headerText = "", string hyperlinkText = "", System.Uri hyperlinkUri = null, System.Uri fileLinkUri = null) -> void diff --git a/src/DynamoCoreWpf/UI/HostStartup.cs b/src/DynamoCoreWpf/UI/HostStartup.cs new file mode 100644 index 00000000000..d32f5841df4 --- /dev/null +++ b/src/DynamoCoreWpf/UI/HostStartup.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using Dynamo.Configuration; +using Dynamo.Utilities; + +namespace Dynamo.Wpf.UI +{ + /// + /// Provides static methods and properties for initializing and managing the host startup context during application + /// launch. + /// + /// is intended for use during the application's splash screen or early + /// startup phase, before other core services are available. It allows initialization of a shared startup context + /// and provides access to user-specific directories based on the current host environment. + public static class HostStartup + { + private static int _initialized; + public static SplashScreenStartupContext? Current { get; private set; } + + /// + /// Initialize the HostStartup with the provided context. + /// + /// + /// + public static bool TryInitialize(SplashScreenStartupContext context) + { + if (context == null) return false; + if (Interlocked.CompareExchange(ref _initialized, 1, 0) != 0) return false; + Current = context; + return true; + } + + /// + /// Resets the static state of the class to its initial, uninitialized condition. + /// + /// Call this method to clear any existing state and reinitialize the class as if it had + /// not been used. This is typically used for testing scenarios or to force reinitialization. This method is + /// not thread-safe; ensure that no other threads are accessing the class while calling . + public static void Reset() + { + Current = null; + Interlocked.Exchange(ref _initialized, 0); + } + + /// + /// Gets the path to the user-specific directory for the current application version. + /// + /// The returned directory path is versioned based on the application's major and minor + /// version numbers. If user-specific host information is available, the path is constructed using the host's + /// user data folder; otherwise, it defaults to a standard location under the user's application data + /// folder. + /// A string containing the full path to the user directory for the current application version. The directory + /// may not exist and may need to be created by the caller. + public static string GetUserDirectory() + { + // we need to use userDataFolder and hostAnalyticsInfo just in SplashScreen because PathManager/PathResolver are not created yet when SplashScreen is launched from a host + if (Current != null && !string.IsNullOrEmpty(Current.UserDataFolder) && Current.HostInfo != null) + { + var version = Current.HostInfo.Value.HostVersion; + + return Path.Combine(Current.UserDataFolder,$"{version.Major}.{version.Minor}"); + } + else + { + var version = AssemblyHelper.GetDynamoVersion(); + + var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + return Path.Combine(Path.Combine(folder, Configurations.DynamoAsString, "Dynamo Core"), $"{version.Major}.{version.Minor}"); + } + + } + } +} diff --git a/src/DynamoCoreWpf/UI/SplashScreenStartupContext.cs b/src/DynamoCoreWpf/UI/SplashScreenStartupContext.cs new file mode 100644 index 00000000000..03a5ae4ceaf --- /dev/null +++ b/src/DynamoCoreWpf/UI/SplashScreenStartupContext.cs @@ -0,0 +1,38 @@ +using Dynamo.Models; + +namespace Dynamo.Wpf.UI +{ + /// + /// Provides contextual information for initializing a splash screen during application startup, including host + /// analytics data and the user data folder path. + /// + /// This context is typically used to supply startup-related information to components that + /// display or manage a splash screen. It encapsulates optional host analytics details and the location of the + /// user-specific data directory. + public sealed class SplashScreenStartupContext + { + /// + /// Initializes a new instance of the class with the specified host + /// analytics information and user data folder path. + /// + /// Use this constructor to provide context information required during the splash screen + /// startup process, such as analytics data and the location for user-specific files. + /// The analytics information for the host application, or if not available. + /// The path to the user data folder. If , an empty string is used. + public SplashScreenStartupContext(HostAnalyticsInfo ?hostInfo, string userDataFolder) + { + HostInfo = hostInfo; + UserDataFolder = userDataFolder ?? string.Empty; + } + + /// + /// Gets information about the host environment for analytics purposes. + /// + public HostAnalyticsInfo? HostInfo { get; } + + /// + /// Gets the path to the user data folder. + /// + public string UserDataFolder { get; } + } +} diff --git a/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs b/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs index 3c04457ab1c..c49bee0f4bf 100644 --- a/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs +++ b/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs @@ -15,6 +15,7 @@ using Dynamo.Models; using Dynamo.UI.Controls; using Dynamo.Utilities; +using Dynamo.Wpf.UI; using Dynamo.Wpf.UI.GuidedTour; using Dynamo.Wpf.Utilities; using DynamoUtilities; @@ -137,11 +138,7 @@ private void DynamoViewModel_PropertyChanged(object sender, System.ComponentMode /// private static string GetUserDirectory() { - var version = AssemblyHelper.GetDynamoVersion(); - - var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - return Path.Combine(Path.Combine(folder, "Dynamo", "Dynamo Core"), - String.Format("{0}.{1}", version.Major, version.Minor)); + return HostStartup.GetUserDirectory(); } private async void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e) diff --git a/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs b/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs index d1bfe5fd012..70e7664e2b1 100644 --- a/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs +++ b/src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs @@ -1,29 +1,30 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using Autodesk.DesignScript.Runtime; +using Dynamo.Models; +using Dynamo.PackageManager; +using Dynamo.PackageManager.UI; using Dynamo.Utilities; +using Dynamo.Wpf.UI; using Dynamo.Wpf.Utilities; using DynamoUtilities; +using Greg.Requests; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.Wpf; -using Autodesk.DesignScript.Runtime; -using System.Text.Json; -using System.Text.Json.Serialization; -using Dynamo.PackageManager; -using Dynamo.PackageManager.UI; using Newtonsoft.Json; -using JsonSerializer = System.Text.Json.JsonSerializer; -using Greg.Requests; using Newtonsoft.Json.Linq; -using Dynamo.Models; -using System.Globalization; +using JsonSerializer = System.Text.Json.JsonSerializer; namespace Dynamo.UI.Views { @@ -1007,11 +1008,7 @@ internal bool ProcessUri(string uri) /// private static string GetUserDirectory() { - var version = AssemblyHelper.GetDynamoVersion(); - - var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - return Path.Combine(Path.Combine(folder, "Dynamo", "Dynamo Core"), - String.Format("{0}.{1}", version.Major, version.Minor)); + return HostStartup.GetUserDirectory(); } /// diff --git a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs index 7b1b076fdcb..9f1bc59042f 100644 --- a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs +++ b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs @@ -10,11 +10,13 @@ using Dynamo.Configuration; using Dynamo.Controls; using Dynamo.Core; +using Dynamo.Interfaces; using Dynamo.Logging; using Dynamo.Models; using Dynamo.UI.Prompts; using Dynamo.Utilities; using Dynamo.ViewModels; +using Dynamo.Wpf.UI; using Dynamo.Wpf.Utilities; using DynamoUtilities; using Greg.AuthProviders; @@ -150,6 +152,8 @@ public void OnRequestStaticSplashScreen() StaticSplashScreenReady?.Invoke(); } + internal SplashScreenStartupContext StartupContext { get; } + /// /// Stores the value that indicates if the SignIn Button will be enabled(default) or not /// @@ -182,6 +186,17 @@ public SplashScreen(bool enableSignInButton = true) currentCloseMode = CloseMode.ByOther; } + /// + /// Overloaded Splash Screen Constructor to receive SplashScreenStartupContext information + /// + /// + /// + public SplashScreen(SplashScreenStartupContext context, bool enableSignInButton = true) + :this(enableSignInButton) + { + StartupContext = context; + } + protected override void OnClosing(CancelEventArgs e) { // If we have multiple OnClosing events (ex Clicking the close button multiple times) @@ -342,11 +357,8 @@ private void DynamoModel_RequestUpdateLoadBarStatus(SplashScreenLoadEventArgs ar /// private string GetUserDirectory() { - var version = AssemblyHelper.GetDynamoVersion(); - - var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - return Path.Combine(Path.Combine(folder, Configurations.DynamoAsString, "Dynamo Core"), - String.Format("{0}.{1}", version.Major, version.Minor)); + return HostStartup.GetUserDirectory(); + } protected override async void OnContentRendered(EventArgs e)