diff --git a/src/Dock.Avalonia/Controls/HostWindow.axaml b/src/Dock.Avalonia/Controls/HostWindow.axaml index f1ba4da26..41bec5516 100644 --- a/src/Dock.Avalonia/Controls/HostWindow.axaml +++ b/src/Dock.Avalonia/Controls/HostWindow.axaml @@ -26,7 +26,7 @@ - + + diff --git a/src/Dock.Avalonia/Controls/HostWindow.axaml.cs b/src/Dock.Avalonia/Controls/HostWindow.axaml.cs index 099e1ea4f..a97ae13b1 100644 --- a/src/Dock.Avalonia/Controls/HostWindow.axaml.cs +++ b/src/Dock.Avalonia/Controls/HostWindow.axaml.cs @@ -3,7 +3,9 @@ using System.Reactive.Linq; using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.Chrome; using Avalonia.Controls.Metadata; +using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Styling; using Dock.Avalonia.Internal; @@ -15,12 +17,13 @@ namespace Dock.Avalonia.Controls /// /// Interaction logic for xaml. /// - [PseudoClasses(":toolwindow")] + [PseudoClasses(":toolwindow", ":dragging")] public class HostWindow : Window, IStyleable, IHostWindow { private readonly DockManager _dockManager; private readonly HostWindowState _hostWindowState; private Control? _chromeGrip; + private HostWindowTitleBar? _hostWindowTitleBar; private bool _mouseDown; /// @@ -68,6 +71,45 @@ public HostWindow() UpdatePseudoClasses(IsToolWindow); } + /// + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + + _hostWindowTitleBar = e.NameScope.Find("PART_TitleBar"); + if (_hostWindowTitleBar is { }) + { + _hostWindowTitleBar.ApplyTemplate(); + + if (_hostWindowTitleBar.BackgroundControl is { }) + { + _hostWindowTitleBar.BackgroundControl.PointerPressed += (_, args) => + { + MoveDrag(args); + }; + } + } + } + + private void MoveDrag(PointerPressedEventArgs e) + { + if (Window?.Factory?.OnWindowMoveDragBegin(Window) != true) + { + return; + } + + _mouseDown = true; + _hostWindowState.Process(e.GetPosition(this), EventType.Pressed); + + PseudoClasses.Set(":dragging", true); + BeginMoveDrag(e); + PseudoClasses.Set(":dragging", false); + + Window?.Factory?.OnWindowMoveDragEnd(Window); + _hostWindowState.Process(e.GetPosition(this), EventType.Released); + _mouseDown = false; + } + /// protected override void OnPointerPressed(PointerPressedEventArgs e) { @@ -77,19 +119,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) { if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) { - if (Window?.Factory?.OnWindowMoveDragBegin(Window) == true) - { - _mouseDown = true; - _hostWindowState.Process(e.GetPosition(this), EventType.Pressed); - - PseudoClasses.Set(":dragging", true); - BeginMoveDrag(e); - PseudoClasses.Set(":dragging", false); - - Window?.Factory?.OnWindowMoveDragEnd(Window); - _hostWindowState.Process(e.GetPosition(this), EventType.Released); - _mouseDown = false; - } + MoveDrag(e); } } } @@ -100,7 +130,9 @@ private void HostWindow_PositionChanged(object? sender, PixelPointEventArgs e) { Window.Save(); - if (_chromeGrip is { } && _chromeGrip.IsPointerOver && _mouseDown) + if ((_chromeGrip is { } && _chromeGrip.IsPointerOver) + || (_hostWindowTitleBar?.BackgroundControl is { } && (_hostWindowTitleBar?.BackgroundControl?.IsPointerOver ?? false)) + && _mouseDown) { Window.Factory?.OnWindowMoveDrag(Window); _hostWindowState.Process(Position.ToPoint(1.0), EventType.Moved); diff --git a/src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml b/src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml new file mode 100644 index 000000000..794809817 --- /dev/null +++ b/src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + diff --git a/src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml.cs b/src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml.cs new file mode 100644 index 000000000..7e9b22c21 --- /dev/null +++ b/src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml.cs @@ -0,0 +1,26 @@ +using System; +using Avalonia.Controls; +using Avalonia.Controls.Chrome; +using Avalonia.Controls.Primitives; +using Avalonia.Styling; + +namespace Dock.Avalonia.Controls +{ + /// + /// Interaction logic for xaml. + /// + public class HostWindowTitleBar : TitleBar, IStyleable + { + internal Control? BackgroundControl { get; private set; } + + Type IStyleable.StyleKey => typeof(HostWindowTitleBar); + + /// + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + + BackgroundControl = e.NameScope.Find("PART_Background"); + } + } +} diff --git a/src/Dock.Avalonia/Themes/DefaultTheme.axaml b/src/Dock.Avalonia/Themes/DefaultTheme.axaml index 1459e0c41..3fac001e4 100644 --- a/src/Dock.Avalonia/Themes/DefaultTheme.axaml +++ b/src/Dock.Avalonia/Themes/DefaultTheme.axaml @@ -10,6 +10,7 @@ +