Hi.WpfPlus/Disp/WpfDispUtil.cs
2026-02-17 15:42:50 +08:00

102 lines
3.2 KiB
C#

using Google.Protobuf.WellKnownTypes;
using Hi.Disp;
using Hi.Geom;
using Hi.Licenses;
using System.Collections.Concurrent;
using System.Windows;
namespace Hi.WpfPlus.Disp;
/// <summary>
/// Registers WPF as the display framework for <see cref="DispFrameUtil"/>,
/// supporting multiple windows identified by key.
/// </summary>
/// <remarks>
/// <para>
/// Usage pattern: call <see cref="DispFrameUtil.Call"/> to queue display content,
/// then call <see cref="RunApplication()"/> to start the WPF application and show windows.
/// </para>
/// <para>
/// Each unique key creates a separate <see cref="RenderingWindow"/>.
/// Calling <see cref="DispFrameUtil.Call"/> with the same key updates the existing window.
/// </para>
/// <example>
/// <code>
/// // Queue display content (before or after Run)
/// DispFrameUtil.CallDispFrame("Window1", displayee1);
/// DispFrameUtil.CallDispFrame("Window2", displayee2);
/// // Start the WPF application (blocks until all windows are closed)
/// DispFrameWpf.Run();
/// </code>
/// </example>
/// </remarks>
public static class WpfDispUtil
{
static readonly ConcurrentDictionary<string, RenderingWindow> KeyToWindowDictionary = new();
static WpfDispUtil()
{
DispFrameUtil.UpdateByDispEngineConfigFunc = ApplyConfig;
}
/// <summary>
/// Initializes the display engine.
/// </summary>
public static void Init() {
DispEngine.Init();
}
static void ApplyConfig(string key, DispEngineConfig config)
{
if (!KeyToWindowDictionary.TryGetValue(key, out var window))
{
window = new RenderingWindow() { Title = key };
window.Closed += (s, e) => KeyToWindowDictionary.TryRemove(key, out _);
KeyToWindowDictionary[key] = window;
window.Show();
}
var dispEngine = window.GetDispEngine();
if (config.Displayee != null)
dispEngine.Displayee = config.Displayee;
if (config.SketchView == null)
config.SketchView = config.Displayee?.GetBox3d()?.FrontView;
if (config.SketchView != null)
dispEngine.SketchView = config.SketchView;
}
/// <summary>
/// Configures the display engine with the specified displayees for the given title.
/// </summary>
/// <param name="title">The title/key to identify the display window.</param>
/// <param name="displayees">The displayees to be configured.</param>
/// <returns>The display engine configuration.</returns>
public static DispEngineConfig Call(
string title, params IDisplayee[] displayees)=>
DispFrameUtil.Call(title, displayees);
/// <summary>
/// Configures the display engine with the specified displayees and starts the WPF application.
/// </summary>
/// <param name="title">The title/key to identify the display window.</param>
/// <param name="displayees">The displayees to be configured.</param>
public static void RunApplication(string title, params IDisplayee[] displayees)
{
DispFrameUtil.Call(title, displayees);
RunApplication();
}
/// <summary>
/// Starts the WPF application and shows all configured windows.
/// Blocks until all windows are closed.
/// </summary>
public static void RunApplication()
{
Application app = new Application()
{
ShutdownMode = ShutdownMode.OnLastWindowClose
};
//app.Exit += (o, e) =>
//{
// License.LogOutAll();
//};
app.Run();
}
}