Browse Source

dont cover titlebar, and allow titlebar to have a background placed in an underlay layer so it doesnt cover content.

pull/3967/head
Dan Walmsley 6 years ago
parent
commit
4be53b2d8a
  1. 3
      samples/ControlCatalog/MainView.xaml
  2. 5
      samples/ControlCatalog/MainWindow.xaml
  3. 38
      src/Avalonia.Controls/Chrome/TitleBar.cs
  4. 21
      src/Avalonia.Controls/Primitives/ChromeOverlayLayer.cs
  5. 12
      src/Avalonia.Controls/Primitives/VisualLayerManager.cs
  6. 2
      src/Avalonia.Themes.Fluent/TitleBar.xaml
  7. 4
      src/Avalonia.Themes.Fluent/Window.xaml

3
samples/ControlCatalog/MainView.xaml

@ -1,8 +1,7 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:pages="clr-namespace:ControlCatalog.Pages" xmlns:pages="clr-namespace:ControlCatalog.Pages"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.MainView" x:Class="ControlCatalog.MainView"
Background="Transparent"
Foreground="{DynamicResource ThemeForegroundBrush}" Foreground="{DynamicResource ThemeForegroundBrush}"
FontSize="{DynamicResource FontSizeNormal}"> FontSize="{DynamicResource FontSizeNormal}">
<Grid> <Grid>

5
samples/ControlCatalog/MainWindow.xaml

@ -60,6 +60,11 @@
</NativeMenuItem> </NativeMenuItem>
</NativeMenu> </NativeMenu>
</NativeMenu.Menu> </NativeMenu.Menu>
<Window.Styles>
<Style Selector="TitleBar">
<Setter Property="Background" Value="Green" />
</Style>
</Window.Styles>
<Window.DataTemplates> <Window.DataTemplates>
<DataTemplate DataType="vm:NotificationViewModel"> <DataTemplate DataType="vm:NotificationViewModel">

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

@ -14,28 +14,32 @@ namespace Avalonia.Controls.Chrome
private CompositeDisposable? _disposables; private CompositeDisposable? _disposables;
private readonly Window? _hostWindow; private readonly Window? _hostWindow;
private CaptionButtons? _captionButtons; private CaptionButtons? _captionButtons;
private Panel _underlay;
public TitleBar(Window hostWindow) public TitleBar(Window hostWindow) : this()
{ {
_hostWindow = hostWindow; _hostWindow = hostWindow;
} }
public TitleBar() public TitleBar()
{ {
_underlay = new Panel
{
IsHitTestVisible = false,
[~Panel.BackgroundProperty] = this[~BackgroundProperty],
VerticalAlignment = Layout.VerticalAlignment.Top
};
} }
public void Attach() public void Attach()
{ {
if (_disposables == null) if (_disposables == null && _hostWindow != null)
{ {
var layer = ChromeOverlayLayer.GetOverlayLayer(_hostWindow); var overlay = ChromeOverlayLayer.GetOverlayLayer(_hostWindow);
layer?.Children.Add(this); overlay?.Children.Add(this);
if (_hostWindow != null) _disposables = new CompositeDisposable
{
_disposables = new CompositeDisposable
{ {
_hostWindow.GetObservable(Window.WindowDecorationMarginsProperty) _hostWindow.GetObservable(Window.WindowDecorationMarginsProperty)
.Subscribe(x => UpdateSize()), .Subscribe(x => UpdateSize()),
@ -56,11 +60,15 @@ namespace Avalonia.Controls.Chrome
}) })
}; };
_captionButtons?.Attach(_hostWindow); _captionButtons?.Attach(_hostWindow);
}
var underlay = ChromeUnderlayLayer.GetUnderlayLayer(_hostWindow);
underlay?.Children.Add(_underlay);
UpdateSize(); UpdateSize();
} }
} }
private void UpdateSize() private void UpdateSize()
@ -76,6 +84,7 @@ namespace Avalonia.Controls.Chrome
if (_hostWindow.WindowState != WindowState.FullScreen) if (_hostWindow.WindowState != WindowState.FullScreen)
{ {
Height = _hostWindow.WindowDecorationMargins.Top; Height = _hostWindow.WindowDecorationMargins.Top;
_underlay.Height = Height;
if (_captionButtons != null) if (_captionButtons != null)
{ {
@ -89,9 +98,14 @@ namespace Avalonia.Controls.Chrome
{ {
if (_disposables != null) if (_disposables != null)
{ {
var layer = ChromeOverlayLayer.GetOverlayLayer(_hostWindow); if (_hostWindow != null)
{
var overlay = ChromeOverlayLayer.GetOverlayLayer(_hostWindow);
overlay?.Children.Remove(this);
layer?.Children.Remove(this); var underlay = ChromeUnderlayLayer.GetUnderlayLayer(_hostWindow);
underlay?.Children.Remove(_underlay);
}
_disposables.Dispose(); _disposables.Dispose();
_disposables = null; _disposables = null;

21
src/Avalonia.Controls/Primitives/ChromeOverlayLayer.cs

@ -6,6 +6,27 @@ using Avalonia.VisualTree;
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
{ {
public class ChromeUnderlayLayer : Panel, ICustomSimpleHitTest
{
public static ChromeUnderlayLayer? GetUnderlayLayer(IVisual visual)
{
foreach (var v in visual.GetVisualAncestors())
if (v is VisualLayerManager vlm)
if (vlm.OverlayLayer != null)
return vlm.ChromeUnderlayLayer;
if (visual is TopLevel tl)
{
var layers = tl.GetVisualDescendants().OfType<VisualLayerManager>().FirstOrDefault();
return layers?.ChromeUnderlayLayer;
}
return null;
}
public bool HitTest(Point point) => Children.HitTestCustom(point);
}
public class ChromeOverlayLayer : Panel, ICustomSimpleHitTest public class ChromeOverlayLayer : Panel, ICustomSimpleHitTest
{ {
public static ChromeOverlayLayer? GetOverlayLayer(IVisual visual) public static ChromeOverlayLayer? GetOverlayLayer(IVisual visual)

12
src/Avalonia.Controls/Primitives/VisualLayerManager.cs

@ -8,6 +8,7 @@ namespace Avalonia.Controls.Primitives
private const int AdornerZIndex = int.MaxValue - 100; private const int AdornerZIndex = int.MaxValue - 100;
private const int ChromeZIndex = int.MaxValue - 99; private const int ChromeZIndex = int.MaxValue - 99;
private const int OverlayZIndex = int.MaxValue - 98; private const int OverlayZIndex = int.MaxValue - 98;
private const int UnderlayZIndex = int.MinValue;
private ILogicalRoot _logicalRoot; private ILogicalRoot _logicalRoot;
private readonly List<Control> _layers = new List<Control>(); private readonly List<Control> _layers = new List<Control>();
@ -26,6 +27,17 @@ namespace Avalonia.Controls.Primitives
} }
} }
public ChromeUnderlayLayer ChromeUnderlayLayer
{
get
{
var rv = FindLayer<ChromeUnderlayLayer>();
if (rv == null)
AddLayer(rv = new ChromeUnderlayLayer(), UnderlayZIndex);
return rv;
}
}
public ChromeOverlayLayer ChromeOverlayLayer public ChromeOverlayLayer ChromeOverlayLayer
{ {
get get

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

@ -14,7 +14,7 @@
<Panel HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="Stretch"> <Panel HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="Stretch">
<Panel x:Name="PART_MouseTracker" Height="1" VerticalAlignment="Top" /> <Panel x:Name="PART_MouseTracker" Height="1" VerticalAlignment="Top" />
<Panel x:Name="PART_Container"> <Panel x:Name="PART_Container">
<Border x:Name="PART_Background" Background="{TemplateBinding Background}" /> <Border x:Name="PART_Background" Background="{x:Null}" />
<CaptionButtons x:Name="PART_CaptionButtons" VerticalAlignment="Top" HorizontalAlignment="Right" Foreground="{TemplateBinding Foreground}" MaxHeight="30" /> <CaptionButtons x:Name="PART_CaptionButtons" VerticalAlignment="Top" HorizontalAlignment="Right" Foreground="{TemplateBinding Foreground}" MaxHeight="30" />
</Panel> </Panel>
</Panel> </Panel>

4
src/Avalonia.Themes.Fluent/Window.xaml

@ -1,11 +1,11 @@
<Style xmlns="https://github.com/avaloniaui" Selector="Window"> <Style xmlns="https://github.com/avaloniaui" Selector="Window">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundChromeMediumBrush}"/> <Setter Property="Background" Value="{DynamicResource SystemControlBackgroundChromeBlackHighBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/> <Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/>
<Setter Property="FontSize" Value="{DynamicResource FontSizeNormal}"/> <Setter Property="FontSize" Value="{DynamicResource FontSizeNormal}"/>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Panel> <Panel>
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" /> <Border Name="PART_TransparencyFallback" IsHitTestVisible="False" Margin="{TemplateBinding WindowDecorationMargins}" />
<Border Background="{TemplateBinding Background}"> <Border Background="{TemplateBinding Background}">
<VisualLayerManager> <VisualLayerManager>
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"

Loading…
Cancel
Save