using System.Globalization; using System.Windows.Input; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Media; using ClaudeDo.Ui.Converters; namespace ClaudeDo.Ui.Views.Controls; /// Reusable modal chrome: titlebar (drag + close) wrapping a body and optional footer. public class ModalShell : ContentControl { public static readonly StyledProperty TitleProperty = AvaloniaProperty.Register(nameof(Title)); public static readonly StyledProperty FooterProperty = AvaloniaProperty.Register(nameof(Footer)); // Window-level actions rendered in the titlebar, left of maximise/close. Keeps a single // always-visible action (e.g. the usage monitor's refresh) out of the body's vertical flow. public static readonly StyledProperty HeaderActionsProperty = AvaloniaProperty.Register(nameof(HeaderActions)); public static readonly StyledProperty CloseCommandProperty = AvaloniaProperty.Register(nameof(CloseCommand)); // Opt-in: most modals are fixed-purpose dialogs that don't need maximise. Set true only // on windows (e.g. the diff viewer) that benefit from a maximised full-screen layout. public static readonly StyledProperty ShowMaximizeButtonProperty = AvaloniaProperty.Register(nameof(ShowMaximizeButton)); public string? Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); } public object? Footer { get => GetValue(FooterProperty); set => SetValue(FooterProperty, value); } public object? HeaderActions { get => GetValue(HeaderActionsProperty); set => SetValue(HeaderActionsProperty, value); } public ICommand? CloseCommand { get => GetValue(CloseCommandProperty); set => SetValue(CloseCommandProperty, value); } public bool ShowMaximizeButton { get => GetValue(ShowMaximizeButtonProperty); set => SetValue(ShowMaximizeButtonProperty, value); } private Window? _window; private PathIcon? _maxIcon; private Button? _maxButton; protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); if (e.NameScope.Find("PART_TitleBar") is { } bar) bar.PointerPressed += OnTitleBarPressed; _maxButton = e.NameScope.Find