Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/DynamoCoreWpf/DynamoCoreWpf.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,8 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="UI\CustomSaveFileDialog.cs" />
<Compile Include="UI\HostStartup.cs" />
<Compile Include="UI\SplashScreenStartupContext.cs" />
<Compile Include="UI\ToastManager.cs" />
<Compile Include="UI\GuidedTour\CustomRichTextBox.cs" />
<Compile Include="UI\GuidedTour\CutOffArea.cs" />
Expand Down
10 changes: 10 additions & 0 deletions src/DynamoCoreWpf/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1753,6 +1753,7 @@ Dynamo.UI.Views.SplashScreen.OnRequestDynamicSplashScreen() -> void
Dynamo.UI.Views.SplashScreen.OnRequestStaticSplashScreen() -> void
Dynamo.UI.Views.SplashScreen.RequestLaunchDynamo -> System.Action<bool>
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
Expand Down Expand Up @@ -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
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Current property should be nullable (SplashScreenStartupContext?) to match the actual implementation in HostStartup.cs where it's declared as SplashScreenStartupContext? Current.

Suggested change
static Dynamo.Wpf.UI.HostStartup.Current.get -> Dynamo.Wpf.UI.SplashScreenStartupContext
static Dynamo.Wpf.UI.HostStartup.Current.get -> Dynamo.Wpf.UI.SplashScreenStartupContext?

Copilot uses AI. Check for mistakes.
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
Expand Down
79 changes: 79 additions & 0 deletions src/DynamoCoreWpf/UI/HostStartup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
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
{
/// <summary>
/// Provides static methods and properties for initializing and managing the host startup context during application
/// launch.
/// </summary>
/// <remarks><see cref="HostStartup"/> 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.</remarks>
public static class HostStartup
{
private static int _initialized;
public static SplashScreenStartupContext? Current { get; private set; }

/// <summary>
/// Initialize the HostStartup with the provided context.
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
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;
}

/// <summary>
/// Resets the static state of the class to its initial, uninitialized condition.
/// </summary>
/// <remarks>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 <see
/// cref="Reset"/>.</remarks>
public static void Reset()
{
Current = null;
Interlocked.Exchange(ref _initialized, 0);
}

/// <summary>
/// Gets the path to the user-specific directory for the current application version.
/// </summary>
/// <remarks>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.</remarks>
/// <returns>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.</returns>
public static string GetUserDirectory()
{
//we need to use userDataFolder and hostAnalyticsInfo just in SplashScreen due that 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,
String.Format("{0}.{1}", version.Major, version.Minor));
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use string interpolation instead of String.Format for better readability: $\"{version.Major}.{version.Minor}\"

Copilot uses AI. Check for mistakes.
}
else
{
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));
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use string interpolation instead of String.Format for better readability: $\"{version.Major}.{version.Minor}\"

Copilot uses AI. Check for mistakes.
}

}
}
}
38 changes: 38 additions & 0 deletions src/DynamoCoreWpf/UI/SplashScreenStartupContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Dynamo.Models;

namespace Dynamo.Wpf.UI
{
/// <summary>
/// Provides contextual information for initializing a splash screen during application startup, including host
/// analytics data and the user data folder path.
/// </summary>
/// <remarks>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.</remarks>
public sealed class SplashScreenStartupContext
{
/// <summary>
/// Initializes a new instance of the <see cref="SplashScreenStartupContext"/> class with the specified host
/// analytics information and user data folder path.
/// </summary>
/// <remarks>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.</remarks>
/// <param name="hostInfo">The analytics information for the host application, or <see langword="null"/> if not available.</param>
/// <param name="userDataFolder">The path to the user data folder. If <see langword="null"/>, an empty string is used.</param>
public SplashScreenStartupContext(HostAnalyticsInfo ?hostInfo, string userDataFolder)
{
HostInfo = hostInfo != null? hostInfo:null;
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing spaces around the ternary operator. Should be hostInfo != null ? hostInfo : null for consistency with C# formatting conventions.

Suggested change
HostInfo = hostInfo != null? hostInfo:null;
HostInfo = hostInfo != null ? hostInfo : null;

Copilot uses AI. Check for mistakes.
UserDataFolder = userDataFolder ?? string.Empty;
}

/// <summary>
/// Gets information about the host environment for analytics purposes.
/// </summary>
public HostAnalyticsInfo? HostInfo { get; }

/// <summary>
/// Gets the path to the user data folder.
/// </summary>
public string UserDataFolder { get; }
}
}
7 changes: 2 additions & 5 deletions src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -137,11 +138,7 @@ private void DynamoViewModel_PropertyChanged(object sender, System.ComponentMode
/// <returns></returns>
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -1007,11 +1008,7 @@ internal bool ProcessUri(string uri)
/// <returns></returns>
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();
}

/// <summary>
Expand Down
22 changes: 17 additions & 5 deletions src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
using Dynamo.Configuration;
using Dynamo.Controls;
using Dynamo.Core;
using Dynamo.Interfaces;
using Dynamo.Logging;
using Dynamo.Models;
using Dynamo.Utilities;
using Dynamo.ViewModels;
using Dynamo.Wpf.UI;
using Dynamo.Wpf.Utilities;
using DynamoUtilities;
using Greg.AuthProviders;
Expand Down Expand Up @@ -135,6 +137,8 @@ public void OnRequestStaticSplashScreen()
StaticSplashScreenReady?.Invoke();
}

internal SplashScreenStartupContext StartupContext { get; }

/// <summary>
/// Stores the value that indicates if the SignIn Button will be enabled(default) or not
/// </summary>
Expand Down Expand Up @@ -167,6 +171,17 @@ public SplashScreen(bool enableSignInButton = true)
currentCloseMode = CloseMode.ByOther;
}

/// <summary>
/// Overloaded Splash Screen Constructor to receive SplashScreenStartupContext information
/// </summary>
/// <param name="context"></param>
/// <param name="enableSignInButton"></param>
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)
Expand Down Expand Up @@ -327,11 +342,8 @@ private void DynamoModel_RequestUpdateLoadBarStatus(SplashScreenLoadEventArgs ar
/// <returns></returns>
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)
Expand Down
Loading