Skip to content

Commit

Permalink
Add support for document window drag events
Browse files Browse the repository at this point in the history
  • Loading branch information
wieslawsoltes committed Jul 25, 2021
1 parent 3b40c50 commit 3b027ae
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 16 deletions.
5 changes: 4 additions & 1 deletion src/Dock.Avalonia/Controls/HostWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<Panel Background="Transparent" Margin="{TemplateBinding WindowDecorationMargin}" />
<VisualLayerManager>
<VisualLayerManager.ChromeOverlayLayer>
<TitleBar />
<idc:HostWindowTitleBar Name="PART_TitleBar" />
</VisualLayerManager.ChromeOverlayLayer>
<ContentPresenter Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Expand Down Expand Up @@ -94,4 +94,7 @@
<Setter Property="TransparencyLevelHint" Value="Transparent"/>
<Setter Property="Opacity" Value="0.5" />
</Style>
<Style Selector="idc|HostWindowTitleBar /template/ Border#PART_Background">
<Setter Property="IsHitTestVisible" Value="True" />
</Style>
</Styles>
62 changes: 47 additions & 15 deletions src/Dock.Avalonia/Controls/HostWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -15,12 +17,13 @@ namespace Dock.Avalonia.Controls
/// <summary>
/// Interaction logic for <see cref="HostWindow"/> xaml.
/// </summary>
[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;

/// <summary>
Expand Down Expand Up @@ -68,6 +71,45 @@ public HostWindow()
UpdatePseudoClasses(IsToolWindow);
}

/// <inheritdoc/>
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);

_hostWindowTitleBar = e.NameScope.Find<HostWindowTitleBar>("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;
}

/// <inheritdoc/>
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
Expand All @@ -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);
}
}
}
Expand All @@ -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);
Expand Down
49 changes: 49 additions & 0 deletions src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:idc="using:Dock.Avalonia.Controls">
<Design.PreviewWith>
<Border>
<idc:HostWindowTitleBar Background="SkyBlue" Height="30" Width="300" Foreground="Black" />
</Border>
</Design.PreviewWith>
<Style Selector="idc|HostWindowTitleBar">
<Setter Property="Foreground" Value="{DynamicResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<ControlTemplate>
<Panel HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="Stretch">
<Panel x:Name="PART_MouseTracker" Height="1" VerticalAlignment="Top" />
<Panel x:Name="PART_Container">
<Border x:Name="PART_Background" Background="{TemplateBinding Background}" />
<CaptionButtons x:Name="PART_CaptionButtons" VerticalAlignment="Top" HorizontalAlignment="Right" Foreground="{TemplateBinding Foreground}" />
</Panel>
</Panel>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="idc|HostWindowTitleBar:fullscreen">
<Setter Property="Background" Value="{DynamicResource SystemAccentColor}" />
</Style>
<Style Selector="idc|HostWindowTitleBar /template/ Border#PART_Background">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
<Style Selector="idc|HostWindowTitleBar:fullscreen /template/ Border#PART_Background">
<Setter Property="IsHitTestVisible" Value="True" />
</Style>
<Style Selector="idc|HostWindowTitleBar:fullscreen /template/ Panel#PART_MouseTracker">
<Setter Property="Background" Value="Transparent" />
</Style>
<Style Selector="idc|HostWindowTitleBar:fullscreen /template/ Panel#PART_Container">
<Setter Property="RenderTransform" Value="translateY(-30px)" />
<Setter Property="Transitions">
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:.25" />
</Transitions>
</Setter>
</Style>
<Style Selector="idc|HostWindowTitleBar:fullscreen:pointerover /template/ Panel#PART_Container">
<Setter Property="RenderTransform" Value="none" />
</Style>
</Styles>
26 changes: 26 additions & 0 deletions src/Dock.Avalonia/Controls/HostWindowTitleBar.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using Avalonia.Controls;
using Avalonia.Controls.Chrome;
using Avalonia.Controls.Primitives;
using Avalonia.Styling;

namespace Dock.Avalonia.Controls
{
/// <summary>
/// Interaction logic for <see cref="HostWindowTitleBar"/> xaml.
/// </summary>
public class HostWindowTitleBar : TitleBar, IStyleable
{
internal Control? BackgroundControl { get; private set; }

Type IStyleable.StyleKey => typeof(HostWindowTitleBar);

/// <inheritdoc/>
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);

BackgroundControl = e.NameScope.Find<Control>("PART_Background");
}
}
}
1 change: 1 addition & 0 deletions src/Dock.Avalonia/Themes/DefaultTheme.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<StyleInclude Source="avares://Dock.Avalonia/Controls/ToolControl.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/ToolPinnedControl.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/DockControl.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/HostWindowTitleBar.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/HostWindow.axaml" />
<Style>
<Style.Resources>
Expand Down
1 change: 1 addition & 0 deletions src/Dock.Avalonia/Themes/FluentTheme.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<StyleInclude Source="avares://Dock.Avalonia/Controls/ToolControl.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/ToolPinnedControl.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/DockControl.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/HostWindowTitleBar.axaml" />
<StyleInclude Source="avares://Dock.Avalonia/Controls/HostWindow.axaml" />
<Style>
<Style.Resources>
Expand Down

0 comments on commit 3b027ae

Please sign in to comment.