Browse Source

Merge branch 'master' into fixes/fluent-menuitem-style-adjustments

pull/4345/head
Max Katz 6 years ago
committed by GitHub
parent
commit
c9a0ca518c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      Avalonia.sln
  2. 6
      src/Avalonia.Controls/Chrome/CaptionButtons.cs
  3. 126
      src/Avalonia.Controls/Chrome/TitleBar.cs
  4. 51
      src/Avalonia.Controls/DateTimePickers/TimePicker.cs
  5. 38
      src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs
  6. 7
      src/Avalonia.Controls/Primitives/ChromeOverlayLayer.cs
  7. 29
      src/Avalonia.Controls/Primitives/VisualLayerManager.cs
  8. 18
      src/Avalonia.Controls/Window.cs
  9. 34
      src/Avalonia.Themes.Default/Window.xaml
  10. 2
      src/Avalonia.Themes.Fluent/NumericUpDown.xaml
  11. 22
      src/Avalonia.Themes.Fluent/Window.xaml

12
Avalonia.sln

@ -123,10 +123,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.NetCore", "s
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
build\AndroidWorkarounds.props = build\AndroidWorkarounds.props
build\Base.props = build\Base.props build\Base.props = build\Base.props
build\Binding.props = build\Binding.props build\Binding.props = build\Binding.props
build\BuildTargets.targets = build\BuildTargets.targets build\CoreLibraries.props = build\CoreLibraries.props
build\EmbedXaml.props = build\EmbedXaml.props
build\HarfBuzzSharp.props = build\HarfBuzzSharp.props build\HarfBuzzSharp.props = build\HarfBuzzSharp.props
build\iOSWorkarounds.props = build\iOSWorkarounds.props
build\JetBrains.Annotations.props = build\JetBrains.Annotations.props build\JetBrains.Annotations.props = build\JetBrains.Annotations.props
build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props
build\Magick.NET-Q16-AnyCPU.props = build\Magick.NET-Q16-AnyCPU.props build\Magick.NET-Q16-AnyCPU.props = build\Magick.NET-Q16-AnyCPU.props
@ -136,17 +139,24 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\NetCore.props = build\NetCore.props build\NetCore.props = build\NetCore.props
build\NetFX.props = build\NetFX.props build\NetFX.props = build\NetFX.props
build\ReactiveUI.props = build\ReactiveUI.props build\ReactiveUI.props = build\ReactiveUI.props
build\ReferenceCoreLibraries.props = build\ReferenceCoreLibraries.props
build\Rx.props = build\Rx.props build\Rx.props = build\Rx.props
build\SampleApp.props = build\SampleApp.props build\SampleApp.props = build\SampleApp.props
build\SharedVersion.props = build\SharedVersion.props
build\SharpDX.props = build\SharpDX.props build\SharpDX.props = build\SharpDX.props
build\SkiaSharp.props = build\SkiaSharp.props build\SkiaSharp.props = build\SkiaSharp.props
build\SourceLink.props = build\SourceLink.props
build\System.Drawing.Common.props = build\System.Drawing.Common.props
build\System.Memory.props = build\System.Memory.props build\System.Memory.props = build\System.Memory.props
build\UnitTests.NetFX.props = build\UnitTests.NetFX.props
build\XUnit.props = build\XUnit.props build\XUnit.props = build\XUnit.props
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6FAF79-58B4-482F-9122-0668C346364C}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6FAF79-58B4-482F-9122-0668C346364C}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
build\UnitTests.NetCore.targets = build\UnitTests.NetCore.targets build\UnitTests.NetCore.targets = build\UnitTests.NetCore.targets
build\BuildTargets.targets = build\BuildTargets.targets
build\LegacyProject.targets = build\LegacyProject.targets
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}"

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

@ -38,12 +38,10 @@ namespace Avalonia.Controls.Chrome
{ {
if (_disposables != null) if (_disposables != null)
{ {
var layer = ChromeOverlayLayer.GetOverlayLayer(_hostWindow);
layer?.Children.Remove(this);
_disposables.Dispose(); _disposables.Dispose();
_disposables = null; _disposables = null;
_hostWindow = null;
} }
} }

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

@ -12,106 +12,86 @@ namespace Avalonia.Controls.Chrome
public class TitleBar : TemplatedControl public class TitleBar : TemplatedControl
{ {
private CompositeDisposable? _disposables; private CompositeDisposable? _disposables;
private readonly Window? _hostWindow;
private CaptionButtons? _captionButtons; private CaptionButtons? _captionButtons;
public TitleBar(Window hostWindow) private void UpdateSize(Window window)
{ {
_hostWindow = hostWindow; if (window != null)
}
public TitleBar()
{
}
public void Attach()
{
if (_disposables == null)
{
var layer = ChromeOverlayLayer.GetOverlayLayer(_hostWindow);
layer?.Children.Add(this);
if (_hostWindow != null)
{
_disposables = new CompositeDisposable
{
_hostWindow.GetObservable(Window.WindowDecorationMarginProperty)
.Subscribe(x => UpdateSize()),
_hostWindow.GetObservable(Window.ExtendClientAreaTitleBarHeightHintProperty)
.Subscribe(x => UpdateSize()),
_hostWindow.GetObservable(Window.OffScreenMarginProperty)
.Subscribe(x => UpdateSize()),
_hostWindow.GetObservable(Window.WindowStateProperty)
.Subscribe(x =>
{
PseudoClasses.Set(":minimized", x == WindowState.Minimized);
PseudoClasses.Set(":normal", x == WindowState.Normal);
PseudoClasses.Set(":maximized", x == WindowState.Maximized);
PseudoClasses.Set(":fullscreen", x == WindowState.FullScreen);
})
};
_captionButtons?.Attach(_hostWindow);
}
UpdateSize();
}
}
private void UpdateSize()
{
if (_hostWindow != null)
{ {
Margin = new Thickness( Margin = new Thickness(
_hostWindow.OffScreenMargin.Left, window.OffScreenMargin.Left,
_hostWindow.OffScreenMargin.Top, window.OffScreenMargin.Top,
_hostWindow.OffScreenMargin.Right, window.OffScreenMargin.Right,
_hostWindow.OffScreenMargin.Bottom); window.OffScreenMargin.Bottom);
if (_hostWindow.WindowState != WindowState.FullScreen) if (window.WindowState != WindowState.FullScreen)
{ {
Height = _hostWindow.WindowDecorationMargin.Top; Height = window.WindowDecorationMargin.Top;
if (_captionButtons != null) if (_captionButtons != null)
{ {
_captionButtons.Height = Height; _captionButtons.Height = Height;
} }
} }
IsVisible = window.PlatformImpl.NeedsManagedDecorations;
} }
} }
public void Detach() protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{ {
if (_disposables != null) base.OnApplyTemplate(e);
{
var layer = ChromeOverlayLayer.GetOverlayLayer(_hostWindow);
layer?.Children.Remove(this);
_disposables.Dispose(); _captionButtons?.Detach();
_disposables = null;
_captionButtons = e.NameScope.Get<CaptionButtons>("PART_CaptionButtons");
_captionButtons?.Detach(); if (VisualRoot is Window window)
{
_captionButtons?.Attach(window);
UpdateSize(window);
} }
} }
protected override void OnApplyTemplate(TemplateAppliedEventArgs e) protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{ {
base.OnApplyTemplate(e); base.OnAttachedToVisualTree(e);
_captionButtons = e.NameScope.Get<CaptionButtons>("PART_CaptionButtons");
if (_hostWindow != null) if (VisualRoot is Window window)
{ {
_captionButtons.Attach(_hostWindow); _disposables = new CompositeDisposable
{
window.GetObservable(Window.WindowDecorationMarginProperty)
.Subscribe(x => UpdateSize(window)),
window.GetObservable(Window.ExtendClientAreaTitleBarHeightHintProperty)
.Subscribe(x => UpdateSize(window)),
window.GetObservable(Window.OffScreenMarginProperty)
.Subscribe(x => UpdateSize(window)),
window.GetObservable(Window.ExtendClientAreaChromeHintsProperty)
.Subscribe(x => UpdateSize(window)),
window.GetObservable(Window.WindowStateProperty)
.Subscribe(x =>
{
PseudoClasses.Set(":minimized", x == WindowState.Minimized);
PseudoClasses.Set(":normal", x == WindowState.Normal);
PseudoClasses.Set(":maximized", x == WindowState.Maximized);
PseudoClasses.Set(":fullscreen", x == WindowState.FullScreen);
}),
window.GetObservable(Window.IsExtendedIntoWindowDecorationsProperty)
.Subscribe(x => UpdateSize(window))
};
} }
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
UpdateSize(); _disposables?.Dispose();
_captionButtons?.Detach();
_captionButtons = null;
} }
} }
} }

51
src/Avalonia.Controls/DateTimePickers/TimePicker.cs

@ -15,7 +15,7 @@ namespace Avalonia.Controls
/// Defines the <see cref="MinuteIncrement"/> property /// Defines the <see cref="MinuteIncrement"/> property
/// </summary> /// </summary>
public static readonly DirectProperty<TimePicker, int> MinuteIncrementProperty = public static readonly DirectProperty<TimePicker, int> MinuteIncrementProperty =
AvaloniaProperty.RegisterDirect<TimePicker, int>(nameof(MinuteIncrement), AvaloniaProperty.RegisterDirect<TimePicker, int>(nameof(MinuteIncrement),
x => x.MinuteIncrement, (x, v) => x.MinuteIncrement = v); x => x.MinuteIncrement, (x, v) => x.MinuteIncrement = v);
/// <summary> /// <summary>
@ -34,17 +34,17 @@ namespace Avalonia.Controls
/// Defines the <see cref="ClockIdentifier"/> property /// Defines the <see cref="ClockIdentifier"/> property
/// </summary> /// </summary>
public static readonly DirectProperty<TimePicker, string> ClockIdentifierProperty = public static readonly DirectProperty<TimePicker, string> ClockIdentifierProperty =
AvaloniaProperty.RegisterDirect<TimePicker, string>(nameof(ClockIdentifier), AvaloniaProperty.RegisterDirect<TimePicker, string>(nameof(ClockIdentifier),
x => x.ClockIdentifier, (x, v) => x.ClockIdentifier = v); x => x.ClockIdentifier, (x, v) => x.ClockIdentifier = v);
/// <summary> /// <summary>
/// Defines the <see cref="SelectedTime"/> property /// Defines the <see cref="SelectedTime"/> property
/// </summary> /// </summary>
public static readonly DirectProperty<TimePicker, TimeSpan?> SelectedTimeProperty = public static readonly DirectProperty<TimePicker, TimeSpan?> SelectedTimeProperty =
AvaloniaProperty.RegisterDirect<TimePicker, TimeSpan?>(nameof(SelectedTime), AvaloniaProperty.RegisterDirect<TimePicker, TimeSpan?>(nameof(SelectedTime),
x => x.SelectedTime, (x, v) => x.SelectedTime = v); x => x.SelectedTime, (x, v) => x.SelectedTime = v);
//Template Items // Template Items
private TimePickerPresenter _presenter; private TimePickerPresenter _presenter;
private Button _flyoutButton; private Button _flyoutButton;
private Border _firstPickerHost; private Border _firstPickerHost;
@ -52,7 +52,7 @@ namespace Avalonia.Controls
private Border _thirdPickerHost; private Border _thirdPickerHost;
private TextBlock _hourText; private TextBlock _hourText;
private TextBlock _minuteText; private TextBlock _minuteText;
public TextBlock _periodText; private TextBlock _periodText;
private Rectangle _firstSplitter; private Rectangle _firstSplitter;
private Rectangle _secondSplitter; private Rectangle _secondSplitter;
private Grid _contentGrid; private Grid _contentGrid;
@ -145,7 +145,7 @@ namespace Avalonia.Controls
if (_flyoutButton != null) if (_flyoutButton != null)
_flyoutButton.Click -= OnFlyoutButtonClicked; _flyoutButton.Click -= OnFlyoutButtonClicked;
if(_presenter != null) if (_presenter != null)
{ {
_presenter.Confirmed -= OnConfirmed; _presenter.Confirmed -= OnConfirmed;
_presenter.Dismissed -= OnDismissPicker; _presenter.Dismissed -= OnDismissPicker;
@ -170,7 +170,6 @@ namespace Avalonia.Controls
_popup = e.NameScope.Find<Popup>("Popup"); _popup = e.NameScope.Find<Popup>("Popup");
_presenter = e.NameScope.Find<TimePickerPresenter>("PickerPresenter"); _presenter = e.NameScope.Find<TimePickerPresenter>("PickerPresenter");
if (_flyoutButton != null) if (_flyoutButton != null)
_flyoutButton.Click += OnFlyoutButtonClicked; _flyoutButton.Click += OnFlyoutButtonClicked;
@ -185,7 +184,6 @@ namespace Avalonia.Controls
_presenter[!TimePickerPresenter.MinuteIncrementProperty] = this[!MinuteIncrementProperty]; _presenter[!TimePickerPresenter.MinuteIncrementProperty] = this[!MinuteIncrementProperty];
_presenter[!TimePickerPresenter.ClockIdentifierProperty] = this[!ClockIdentifierProperty]; _presenter[!TimePickerPresenter.ClockIdentifierProperty] = this[!ClockIdentifierProperty];
} }
} }
private void SetGrid() private void SetGrid()
@ -195,30 +193,19 @@ namespace Avalonia.Controls
bool use24HourClock = ClockIdentifier == "24HourClock"; bool use24HourClock = ClockIdentifier == "24HourClock";
if (!use24HourClock) var columnsD = use24HourClock ? "*, Auto, *" : "*, Auto, *, Auto, *";
{ _contentGrid.ColumnDefinitions = new ColumnDefinitions(columnsD);
_contentGrid.ColumnDefinitions = new ColumnDefinitions("*,Auto,*,Auto,*");
_thirdPickerHost.IsVisible = true;
_secondSplitter.IsVisible = true;
Grid.SetColumn(_firstPickerHost, 0); _thirdPickerHost.IsVisible = !use24HourClock;
Grid.SetColumn(_secondPickerHost, 2); _secondSplitter.IsVisible = !use24HourClock;
Grid.SetColumn(_thirdPickerHost, 4);
Grid.SetColumn(_firstSplitter, 1); Grid.SetColumn(_firstPickerHost, 0);
Grid.SetColumn(_secondSplitter, 3); Grid.SetColumn(_secondPickerHost, 2);
}
else
{
_contentGrid.ColumnDefinitions = new ColumnDefinitions("*,Auto,*");
_thirdPickerHost.IsVisible = false;
_secondSplitter.IsVisible = false;
Grid.SetColumn(_firstPickerHost, 0); Grid.SetColumn(_thirdPickerHost, use24HourClock ? 0 : 4);
Grid.SetColumn(_secondPickerHost, 2);
Grid.SetColumn(_firstSplitter, 1); Grid.SetColumn(_firstSplitter, 1);
} Grid.SetColumn(_secondSplitter, use24HourClock ? 0 : 3);
} }
private void SetSelectedTimeText() private void SetSelectedTimeText()
@ -237,14 +224,13 @@ namespace Avalonia.Controls
hr = hr > 12 ? hr - 12 : hr == 0 ? 12 : hr; hr = hr > 12 ? hr - 12 : hr == 0 ? 12 : hr;
newTime = new TimeSpan(hr, newTime.Minutes, 0); newTime = new TimeSpan(hr, newTime.Minutes, 0);
} }
_hourText.Text = newTime.ToString("%h");
_hourText.Text = newTime.ToString("%h");
_minuteText.Text = newTime.ToString("mm"); _minuteText.Text = newTime.ToString("mm");
PseudoClasses.Set(":hasnotime", false); PseudoClasses.Set(":hasnotime", false);
_periodText.Text = time.Value.Hours >= 12 ? CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator : _periodText.Text = time.Value.Hours >= 12 ? CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator :
CultureInfo.CurrentCulture.DateTimeFormat.AMDesignator; CultureInfo.CurrentCulture.DateTimeFormat.AMDesignator;
} }
else else
{ {
@ -262,7 +248,7 @@ namespace Avalonia.Controls
SelectedTimeChanged?.Invoke(this, new TimePickerSelectedValueChangedEventArgs(oldTime, newTime)); SelectedTimeChanged?.Invoke(this, new TimePickerSelectedValueChangedEventArgs(oldTime, newTime));
} }
private void OnFlyoutButtonClicked(object sender, Avalonia.Interactivity.RoutedEventArgs e) private void OnFlyoutButtonClicked(object sender, Interactivity.RoutedEventArgs e)
{ {
_presenter.Time = SelectedTime ?? DateTime.Now.TimeOfDay; _presenter.Time = SelectedTime ?? DateTime.Now.TimeOfDay;
@ -270,7 +256,7 @@ namespace Avalonia.Controls
var deltaY = _presenter.GetOffsetForPopup(); var deltaY = _presenter.GetOffsetForPopup();
//The extra 5 px I think is related to default popup placement behavior // The extra 5 px I think is related to default popup placement behavior
_popup.Host.ConfigurePosition(_popup.PlacementTarget, PlacementMode.AnchorAndGravity, new Point(0, deltaY + 5), _popup.Host.ConfigurePosition(_popup.PlacementTarget, PlacementMode.AnchorAndGravity, new Point(0, deltaY + 5),
Primitives.PopupPositioning.PopupAnchor.Bottom, Primitives.PopupPositioning.PopupGravity.Bottom, Primitives.PopupPositioning.PopupAnchor.Bottom, Primitives.PopupPositioning.PopupGravity.Bottom,
Primitives.PopupPositioning.PopupPositionerConstraintAdjustment.SlideY); Primitives.PopupPositioning.PopupPositionerConstraintAdjustment.SlideY);
@ -287,6 +273,5 @@ namespace Avalonia.Controls
_popup.Close(); _popup.Close();
SelectedTime = _presenter.Time; SelectedTime = _presenter.Time;
} }
} }
} }

38
src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs

@ -39,7 +39,7 @@ namespace Avalonia.Controls
KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Cycle); KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Cycle);
} }
//TemplateItems // TemplateItems
private Grid _pickerContainer; private Grid _pickerContainer;
private Button _acceptButton; private Button _acceptButton;
private Button _dismissButton; private Button _dismissButton;
@ -55,8 +55,8 @@ namespace Avalonia.Controls
private Button _minuteDownButton; private Button _minuteDownButton;
private Button _periodDownButton; private Button _periodDownButton;
//Backing Fields // Backing Fields
private TimeSpan _Time; private TimeSpan _time;
private int _minuteIncrement = 1; private int _minuteIncrement = 1;
private string _clockIdentifier = "12HourClock"; private string _clockIdentifier = "12HourClock";
@ -83,7 +83,7 @@ namespace Avalonia.Controls
get => _clockIdentifier; get => _clockIdentifier;
set set
{ {
if (string.IsNullOrEmpty(value) || value == "" || !(value == "12HourClock" || value == "24HourClock")) if (string.IsNullOrEmpty(value) || !(value == "12HourClock" || value == "24HourClock"))
throw new ArgumentException("Invalid ClockIdentifier"); throw new ArgumentException("Invalid ClockIdentifier");
SetAndRaise(ClockIdentifierProperty, ref _clockIdentifier, value); SetAndRaise(ClockIdentifierProperty, ref _clockIdentifier, value);
InitPicker(); InitPicker();
@ -95,10 +95,10 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public TimeSpan Time public TimeSpan Time
{ {
get => _Time; get => _time;
set set
{ {
SetAndRaise(TimeProperty, ref _Time, value); SetAndRaise(TimeProperty, ref _time, value);
InitPicker(); InitPicker();
} }
} }
@ -213,26 +213,24 @@ namespace Avalonia.Controls
private void SetGrid() private void SetGrid()
{ {
if (ClockIdentifier == "12HourClock") bool use24HourClock = ClockIdentifier == "24HourClock";
{
_pickerContainer.ColumnDefinitions = new ColumnDefinitions("*,Auto,*,Auto,*"); var columnsD = use24HourClock ? "*, Auto, *" : "*, Auto, *, Auto, *";
_spacer2.IsVisible = true; _pickerContainer.ColumnDefinitions = new ColumnDefinitions(columnsD);
_periodHost.IsVisible = true;
} _spacer2.IsVisible = !use24HourClock;
else _periodHost.IsVisible = !use24HourClock;
{
_pickerContainer.ColumnDefinitions = new ColumnDefinitions("*,Auto,*"); Grid.SetColumn(_spacer2, use24HourClock ? 0 : 3);
_spacer2.IsVisible = false; Grid.SetColumn(_periodHost, use24HourClock ? 0 : 4);
_periodHost.IsVisible = false;
}
} }
private void OnDismissButtonClicked(object sender, Avalonia.Interactivity.RoutedEventArgs e) private void OnDismissButtonClicked(object sender, RoutedEventArgs e)
{ {
OnDismiss(); OnDismiss();
} }
private void OnAcceptButtonClicked(object sender, Avalonia.Interactivity.RoutedEventArgs e) private void OnAcceptButtonClicked(object sender, RoutedEventArgs e)
{ {
OnConfirmed(); OnConfirmed();
} }

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

@ -8,7 +8,7 @@ namespace Avalonia.Controls.Primitives
{ {
public class ChromeOverlayLayer : Panel, ICustomSimpleHitTest public class ChromeOverlayLayer : Panel, ICustomSimpleHitTest
{ {
public static ChromeOverlayLayer? GetOverlayLayer(IVisual visual) public static Panel? GetOverlayLayer(IVisual visual)
{ {
foreach (var v in visual.GetVisualAncestors()) foreach (var v in visual.GetVisualAncestors())
if (v is VisualLayerManager vlm) if (v is VisualLayerManager vlm)
@ -24,6 +24,11 @@ namespace Avalonia.Controls.Primitives
return null; return null;
} }
public void Add(Control c)
{
base.Children.Add(c);
}
public bool HitTest(Point point) => Children.HitTestCustom(point); public bool HitTest(Point point) => Children.HitTestCustom(point);
} }
} }

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

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Metadata;
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
{ {
@ -11,10 +12,12 @@ namespace Avalonia.Controls.Primitives
private ILogicalRoot _logicalRoot; private ILogicalRoot _logicalRoot;
private readonly List<Control> _layers = new List<Control>(); private readonly List<Control> _layers = new List<Control>();
public static readonly StyledProperty<ChromeOverlayLayer> ChromeOverlayLayerProperty =
AvaloniaProperty.Register<VisualLayerManager, ChromeOverlayLayer>(nameof(ChromeOverlayLayer));
public bool IsPopup { get; set; } public bool IsPopup { get; set; }
public AdornerLayer AdornerLayer public AdornerLayer AdornerLayer
{ {
get get
@ -30,10 +33,19 @@ namespace Avalonia.Controls.Primitives
{ {
get get
{ {
var rv = FindLayer<ChromeOverlayLayer>(); var current = GetValue(ChromeOverlayLayerProperty);
if (rv == null)
AddLayer(rv = new ChromeOverlayLayer(), ChromeZIndex); if (current is null)
return rv; {
var chromeOverlayLayer = new ChromeOverlayLayer();
AddLayer(chromeOverlayLayer, ChromeZIndex);
SetValue(ChromeOverlayLayerProperty, chromeOverlayLayer);
current = chromeOverlayLayer;
}
return current;
} }
} }
@ -44,7 +56,7 @@ namespace Avalonia.Controls.Primitives
if (IsPopup) if (IsPopup)
return null; return null;
var rv = FindLayer<OverlayLayer>(); var rv = FindLayer<OverlayLayer>();
if(rv == null) if (rv == null)
AddLayer(rv = new OverlayLayer(), OverlayZIndex); AddLayer(rv = new OverlayLayer(), OverlayZIndex);
return rv; return rv;
} }
@ -65,7 +77,8 @@ namespace Avalonia.Controls.Primitives
layer.ZIndex = zindex; layer.ZIndex = zindex;
VisualChildren.Add(layer); VisualChildren.Add(layer);
if (((ILogical)this).IsAttachedToLogicalTree) if (((ILogical)this).IsAttachedToLogicalTree)
((ILogical)layer).NotifyAttachedToLogicalTree(new LogicalTreeAttachmentEventArgs(_logicalRoot, layer, this)); ((ILogical)layer).NotifyAttachedToLogicalTree(
new LogicalTreeAttachmentEventArgs(_logicalRoot, layer, this));
InvalidateArrange(); InvalidateArrange();
} }

18
src/Avalonia.Controls/Window.cs

@ -6,6 +6,7 @@ using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls.Chrome; using Avalonia.Controls.Chrome;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
@ -70,8 +71,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot
{ {
private readonly List<(Window child, bool isDialog)> _children = new List<(Window, bool)>(); private readonly List<(Window child, bool isDialog)> _children = new List<(Window, bool)>();
private TitleBar _managedTitleBar;
private bool _isExtendedIntoWindowDecorations; private bool _isExtendedIntoWindowDecorations;
private Thickness _windowDecorationMargin; private Thickness _windowDecorationMargin;
private Thickness _offScreenMargin; private Thickness _offScreenMargin;
@ -552,20 +552,6 @@ namespace Avalonia.Controls
IsExtendedIntoWindowDecorations = isExtended; IsExtendedIntoWindowDecorations = isExtended;
WindowDecorationMargin = PlatformImpl.ExtendedMargins; WindowDecorationMargin = PlatformImpl.ExtendedMargins;
OffScreenMargin = PlatformImpl.OffScreenMargin; OffScreenMargin = PlatformImpl.OffScreenMargin;
if (PlatformImpl.NeedsManagedDecorations)
{
if (_managedTitleBar == null)
{
_managedTitleBar = new TitleBar(this);
_managedTitleBar.Attach();
}
}
else
{
_managedTitleBar?.Detach();
_managedTitleBar = null;
}
} }
/// <summary> /// <summary>

34
src/Avalonia.Themes.Default/Window.xaml

@ -1,23 +1,25 @@
<Style xmlns="https://github.com/avaloniaui" Selector="Window"> <Style xmlns="https://github.com/avaloniaui" Selector="Window">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/> <Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltHighBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/> <Setter Property="TransparencyBackgroundFallback" Value="{DynamicResource SystemControlBackgroundAltHighBrush}" />
<Setter Property="FontSize" Value="{DynamicResource FontSizeNormal}"/> <Setter Property="Foreground" Value="{DynamicResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="FontSize" Value="{DynamicResource ContentControlFontSize}"/>
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Panel> <Panel>
<Panel IsHitTestVisible="False" Margin="{TemplateBinding OffScreenMargin}"> <Border Name="PART_TransparencyFallback" IsHitTestVisible="False" />
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" /> <Border Background="{TemplateBinding Background}" IsHitTestVisible="False" />
</Panel> <VisualLayerManager>
<Border Background="{TemplateBinding Background}"> <VisualLayerManager.ChromeOverlayLayer>
<VisualLayerManager> <TitleBar />
<ContentPresenter Name="PART_ContentPresenter" </VisualLayerManager.ChromeOverlayLayer>
ContentTemplate="{TemplateBinding ContentTemplate}" <ContentPresenter Name="PART_ContentPresenter"
Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"
Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
</VisualLayerManager> VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border> </VisualLayerManager>
</Panel> </Panel>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

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

@ -43,7 +43,7 @@
<TextBox Name="PART_TextBox" <TextBox Name="PART_TextBox"
Background="Transparent" Background="Transparent"
BorderBrush="Transparent" BorderBrush="Transparent"
Margin="-2" Margin="-1"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Watermark="{TemplateBinding Watermark}" Watermark="{TemplateBinding Watermark}"
DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}" DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}"

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

@ -8,16 +8,18 @@
<ControlTemplate> <ControlTemplate>
<Panel> <Panel>
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" /> <Border Name="PART_TransparencyFallback" IsHitTestVisible="False" />
<Border Background="{TemplateBinding Background}"> <Border Background="{TemplateBinding Background}" IsHitTestVisible="False" />
<VisualLayerManager> <VisualLayerManager>
<ContentPresenter Name="PART_ContentPresenter" <VisualLayerManager.ChromeOverlayLayer>
ContentTemplate="{TemplateBinding ContentTemplate}" <TitleBar />
Content="{TemplateBinding Content}" </VisualLayerManager.ChromeOverlayLayer>
Margin="{TemplateBinding Padding}" <ContentPresenter Name="PART_ContentPresenter"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> Content="{TemplateBinding Content}"
</VisualLayerManager> Margin="{TemplateBinding Padding}"
</Border> HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</VisualLayerManager>
</Panel> </Panel>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

Loading…
Cancel
Save