Browse Source

polish managed titlebar.

demo1
Dan Walmsley 6 years ago
parent
commit
765bd84c3e
  1. 18
      src/Avalonia.Controls/Chrome/CaptionButtons.cs
  2. 34
      src/Avalonia.Controls/Chrome/TitleBar.cs
  3. 12
      src/Avalonia.Themes.Fluent/TitleBar.xaml
  4. 48
      src/Windows/Avalonia.Win32/WindowImpl.cs

18
src/Avalonia.Controls/Chrome/CaptionButtons.cs

@ -20,18 +20,6 @@ namespace Avalonia.Controls.Chrome
_disposables = new CompositeDisposable
{
_hostWindow.GetObservable(Window.WindowDecorationMarginsProperty)
.Subscribe(x =>
{
Height = x.Top;
}),
_hostWindow.GetObservable(Window.ExtendClientAreaTitleBarHeightHintProperty)
.Subscribe(x => InvalidateSize()),
_hostWindow.GetObservable(Window.OffScreenMarginProperty)
.Subscribe(x => InvalidateSize()),
_hostWindow.GetObservable(Window.WindowStateProperty)
.Subscribe(x =>
{
@ -44,12 +32,6 @@ namespace Avalonia.Controls.Chrome
}
}
void InvalidateSize ()
{
Margin = new Thickness(1, _hostWindow.OffScreenMargin.Top, 1, 1);
Height = _hostWindow.WindowDecorationMargins.Top;
}
public void Detach()
{
if (_disposables != null)

34
src/Avalonia.Controls/Chrome/TitleBar.cs

@ -18,21 +18,6 @@ namespace Avalonia.Controls.Chrome
_hostWindow = hostWindow;
}
public TitleBar()
{
}
protected override Size MeasureOverride(Size availableSize)
{
return base.MeasureOverride(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
return base.ArrangeOverride(finalSize);
}
public void Attach()
{
if (_disposables == null)
@ -44,10 +29,7 @@ namespace Avalonia.Controls.Chrome
_disposables = new CompositeDisposable
{
_hostWindow.GetObservable(Window.WindowDecorationMarginsProperty)
.Subscribe(x =>
{
Height = x.Top;
}),
.Subscribe(x => InvalidateSize()),
_hostWindow.GetObservable(Window.ExtendClientAreaTitleBarHeightHintProperty)
.Subscribe(x => InvalidateSize()),
@ -71,8 +53,16 @@ namespace Avalonia.Controls.Chrome
void InvalidateSize()
{
Margin = new Thickness(1, _hostWindow.OffScreenMargin.Top, 1, 1);
Height = _hostWindow.WindowDecorationMargins.Top;
Margin = new Thickness(
_hostWindow.OffScreenMargin.Left,
_hostWindow.OffScreenMargin.Top,
_hostWindow.OffScreenMargin.Right,
_hostWindow.OffScreenMargin.Bottom);
if (_hostWindow.WindowState != WindowState.FullScreen)
{
Height = _hostWindow.WindowDecorationMargins.Top;
}
}
public void Detach()
@ -94,7 +84,7 @@ namespace Avalonia.Controls.Chrome
{
base.OnApplyTemplate(e);
_captionButtons = e.NameScope.Find<CaptionButtons>("PART_CaptionButtons");
_captionButtons = e.NameScope.Find<CaptionButtons>("PART_CaptionButtons");
_captionButtons.Attach(_hostWindow);
}

12
src/Avalonia.Themes.Fluent/TitleBar.xaml

@ -5,23 +5,27 @@
</Border>
</Design.PreviewWith>
<Style Selector="TitleBar">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/>
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/>
<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="15" VerticalAlignment="Top" />
<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}" />
<CaptionButtons x:Name="PART_CaptionButtons" VerticalAlignment="Stretch" HorizontalAlignment="Right" Foreground="{TemplateBinding Foreground}" MaxHeight="30" />
</Panel>
</Panel>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="TitleBar:fullscreen">
<Setter Property="Background" Value="{DynamicResource SystemAccentColor}" />
</Style>
<Style Selector="TitleBar /template/ Border#PART_Background">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>

48
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -671,6 +671,8 @@ namespace Avalonia.Win32
}
TaskBarList.MarkFullscreen(_hwnd, fullscreen);
ExtendClientArea();
}
private MARGINS UpdateExtendMargins()
@ -724,33 +726,41 @@ namespace Avalonia.Win32
{
_isClientAreaExtended = false;
return;
}
GetWindowRect(_hwnd, out var rcClient);
}
// Inform the application of the frame change.
SetWindowPos(_hwnd,
IntPtr.Zero,
rcClient.left, rcClient.top,
rcClient.Width, rcClient.Height,
SetWindowPosFlags.SWP_FRAMECHANGED);
if(_isClientAreaExtended)
if (!_isClientAreaExtended || WindowState == WindowState.FullScreen)
{
var margins = UpdateExtendMargins();
DwmExtendFrameIntoClientArea(_hwnd, ref margins);
_extendedMargins = new Thickness(0, 0, 0, 0);
_offScreenMargin = new Thickness();
}
else
{
var margins = new MARGINS();
DwmExtendFrameIntoClientArea(_hwnd, ref margins);
GetWindowRect(_hwnd, out var rcClient);
_offScreenMargin = new Thickness();
_extendedMargins = new Thickness();
// Inform the application of the frame change.
SetWindowPos(_hwnd,
IntPtr.Zero,
rcClient.left, rcClient.top,
rcClient.Width, rcClient.Height,
SetWindowPosFlags.SWP_FRAMECHANGED);
if (_isClientAreaExtended)
{
var margins = UpdateExtendMargins();
DwmExtendFrameIntoClientArea(_hwnd, ref margins);
}
else
{
var margins = new MARGINS();
DwmExtendFrameIntoClientArea(_hwnd, ref margins);
_offScreenMargin = new Thickness();
_extendedMargins = new Thickness();
}
}
ExtendClientAreaToDecorationsChanged?.Invoke(true);
ExtendClientAreaToDecorationsChanged?.Invoke(_isClientAreaExtended);
}
private void ShowWindow(WindowState state)

Loading…
Cancel
Save