using Avalonia.Controls; using Avalonia.Input; namespace DodoSSH.Client.App.Views; /// The window that is up while the application composes itself. /// /// A frame around and nothing else. Its whole lifetime is one call to /// DodoSshApp.ComposeBehind: shown by the desktop lifetime as the main window, replaced by the real /// one, closed. The exception is a composition that fails, which is the only case this window outlives. /// internal sealed partial class SplashWindow : Window { /// /// Whether Escape may close this. /// /// /// False while composition is running, and that is not caution for its own sake: this window has no /// close button, so Escape is the only key it could offer — and closing it mid-composition would leave a /// process that has opened the cache and bound a socket with no window and no way to reach either. Once /// there is nothing left to wait for, it is the only way out and has to work. /// private bool escapable; public SplashWindow() { InitializeComponent(); KeyDown += (_, e) => { if (escapable && e.Key == Key.Escape) { Close(); } }; } /// Says what is happening, while it still is. internal void Say(string what) => Card.Say(what); /// /// Says why nothing is going to happen, and becomes the last window there is. /// /// /// The way out is named in the message rather than drawn as a button. A failure here is a broken /// installation — a cache that cannot be opened, a port that cannot be bound — so what this window is /// for at that point is carrying one sentence to whoever has to act on it, and a control that has to be /// laid out and measured to say "close me" earns less than the words do. /// internal void CouldNotStart(string why) { escapable = true; Card.CouldNotStart($"DodoSSH could not start: {why} Press Escape to close."); } }