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"
xmlns:pages="clr-namespace:ControlCatalog.Pages"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.MainView"
Background="Transparent"
x:Class="ControlCatalog.MainView"
Foreground="{DynamicResource ThemeForegroundBrush}"
FontSize="{DynamicResource FontSizeNormal}">
<Grid>

5
samples/ControlCatalog/MainWindow.xaml

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

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

@ -14,28 +14,32 @@ namespace Avalonia.Controls.Chrome
private CompositeDisposable? _disposables;
private readonly Window? _hostWindow;
private CaptionButtons? _captionButtons;
private Panel _underlay;
public TitleBar(Window hostWindow)
public TitleBar(Window hostWindow) : this()
{
_hostWindow = hostWindow;
}
public TitleBar()
{
_underlay = new Panel
{
IsHitTestVisible = false,
[~Panel.BackgroundProperty] = this[~BackgroundProperty],
VerticalAlignment = Layout.VerticalAlignment.Top
};
}
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)
.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();
}
}
private void UpdateSize()
@ -76,6 +84,7 @@ namespace Avalonia.Controls.Chrome
if (_hostWindow.WindowState != WindowState.FullScreen)
{
Height = _hostWindow.WindowDecorationMargins.Top;
_underlay.Height = Height;
if (_captionButtons != null)
{
@ -89,9 +98,14 @@ namespace Avalonia.Controls.Chrome
{
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 = null;

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

@ -6,6 +6,27 @@ using Avalonia.VisualTree;
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 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 ChromeZIndex = int.MaxValue - 99;
private const int OverlayZIndex = int.MaxValue - 98;
private const int UnderlayZIndex = int.MinValue;
private ILogicalRoot _logicalRoot;
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
{
get

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

@ -14,7 +14,7 @@
<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}" />
<Border x:Name="PART_Background" Background="{x:Null}" />
<CaptionButtons x:Name="PART_CaptionButtons" VerticalAlignment="Top" HorizontalAlignment="Right" Foreground="{TemplateBinding Foreground}" MaxHeight="30" />
</Panel>
</Panel>

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

@ -1,11 +1,11 @@
<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="FontSize" Value="{DynamicResource FontSizeNormal}"/>
<Setter Property="Template">
<ControlTemplate>
<Panel>
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" />
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" Margin="{TemplateBinding WindowDecorationMargins}" />
<Border Background="{TemplateBinding Background}">
<VisualLayerManager>
<ContentPresenter Name="PART_ContentPresenter"

Loading…
Cancel
Save