Browse Source

Merge branch 'master' into SkiaOpacityMaskFixes

pull/6373/head
Dan Walmsley 5 years ago
committed by GitHub
parent
commit
ec62912ca2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      build/MicroCom.targets
  2. 1
      native/Avalonia.Native/src/OSX/KeyTransform.mm
  3. 7
      native/Avalonia.Native/src/OSX/window.mm
  4. 2
      samples/ControlCatalog/Pages/DataGridPage.xaml
  5. 1
      samples/ControlCatalog/SideBar.xaml
  6. 1
      samples/RenderDemo/SideBar.xaml
  7. 57
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  8. 10
      src/Avalonia.Controls.DataGrid/DataGridCell.cs
  9. 13
      src/Avalonia.Controls.DataGrid/Primitives/DataGridRowsPresenter.cs
  10. 6
      src/Avalonia.Controls.DataGrid/Themes/Default.xaml
  11. 6
      src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml
  12. 17
      src/Avalonia.Controls/ContextMenu.cs
  13. 23
      src/Avalonia.Controls/Diagnostics/IPopupHostProvider.cs
  14. 15
      src/Avalonia.Controls/Diagnostics/ToolTipDiagnostics.cs
  15. 18
      src/Avalonia.Controls/Flyouts/FlyoutBase.cs
  16. 9
      src/Avalonia.Controls/Flyouts/FlyoutPresenter.cs
  17. 5
      src/Avalonia.Controls/Primitives/OverlayPopupHost.cs
  18. 16
      src/Avalonia.Controls/Primitives/Popup.cs
  19. 34
      src/Avalonia.Controls/Primitives/ScrollBar.cs
  20. 40
      src/Avalonia.Controls/Primitives/TemplatedControl.cs
  21. 65
      src/Avalonia.Controls/TextBox.cs
  22. 40
      src/Avalonia.Controls/ToolTip.cs
  23. 11
      src/Avalonia.Controls/Utils/UndoRedoHelper.cs
  24. 8
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs
  25. 33
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs
  26. 123
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs
  27. 56
      src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml
  28. 165
      src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
  29. 2
      src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml
  30. 8
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  31. 1
      src/Avalonia.Themes.Default/AutoCompleteBox.xaml
  32. 3
      src/Avalonia.Themes.Default/Button.xaml
  33. 2
      src/Avalonia.Themes.Default/ButtonSpinner.xaml
  34. 3
      src/Avalonia.Themes.Default/Calendar.xaml
  35. 3
      src/Avalonia.Themes.Default/CalendarDatePicker.xaml
  36. 5
      src/Avalonia.Themes.Default/CalendarItem.xaml
  37. 3
      src/Avalonia.Themes.Default/Carousel.xaml
  38. 1
      src/Avalonia.Themes.Default/CheckBox.xaml
  39. 3
      src/Avalonia.Themes.Default/ComboBox.xaml
  40. 1
      src/Avalonia.Themes.Default/ComboBoxItem.xaml
  41. 3
      src/Avalonia.Themes.Default/ContentControl.xaml
  42. 1
      src/Avalonia.Themes.Default/ContextMenu.xaml
  43. 1
      src/Avalonia.Themes.Default/DataValidationErrors.xaml
  44. 3
      src/Avalonia.Themes.Default/DatePicker.xaml
  45. 5
      src/Avalonia.Themes.Default/Expander.xaml
  46. 1
      src/Avalonia.Themes.Default/GridSplitter.xaml
  47. 1
      src/Avalonia.Themes.Default/ItemsControl.xaml
  48. 1
      src/Avalonia.Themes.Default/Label.xaml
  49. 3
      src/Avalonia.Themes.Default/ListBox.xaml
  50. 1
      src/Avalonia.Themes.Default/ListBoxItem.xaml
  51. 3
      src/Avalonia.Themes.Default/Menu.xaml
  52. 6
      src/Avalonia.Themes.Default/MenuItem.xaml
  53. 1
      src/Avalonia.Themes.Default/NotificationCard.xaml
  54. 2
      src/Avalonia.Themes.Default/NumericUpDown.xaml
  55. 2
      src/Avalonia.Themes.Default/ProgressBar.xaml
  56. 1
      src/Avalonia.Themes.Default/RepeatButton.xaml
  57. 1
      src/Avalonia.Themes.Default/Separator.xaml
  58. 2
      src/Avalonia.Themes.Default/TabControl.xaml
  59. 2
      src/Avalonia.Themes.Default/TabItem.xaml
  60. 3
      src/Avalonia.Themes.Default/TabStripItem.xaml
  61. 3
      src/Avalonia.Themes.Default/TextBox.xaml
  62. 3
      src/Avalonia.Themes.Default/TimePicker.xaml
  63. 3
      src/Avalonia.Themes.Default/ToggleButton.xaml
  64. 3
      src/Avalonia.Themes.Default/ToolTip.xaml
  65. 3
      src/Avalonia.Themes.Default/TreeView.xaml
  66. 1
      src/Avalonia.Themes.Default/TreeViewItem.xaml
  67. 1
      src/Avalonia.Themes.Default/UserControl.xaml
  68. 4
      src/Avalonia.Themes.Fluent/Controls/AutoCompleteBox.xaml
  69. 6
      src/Avalonia.Themes.Fluent/Controls/Button.xaml
  70. 3
      src/Avalonia.Themes.Fluent/Controls/ButtonSpinner.xaml
  71. 10
      src/Avalonia.Themes.Fluent/Controls/Calendar.xaml
  72. 2
      src/Avalonia.Themes.Fluent/Controls/CalendarDatePicker.xaml
  73. 8
      src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml
  74. 3
      src/Avalonia.Themes.Fluent/Controls/Carousel.xaml
  75. 13
      src/Avalonia.Themes.Fluent/Controls/CheckBox.xaml
  76. 13
      src/Avalonia.Themes.Fluent/Controls/ComboBox.xaml
  77. 1
      src/Avalonia.Themes.Fluent/Controls/ComboBoxItem.xaml
  78. 3
      src/Avalonia.Themes.Fluent/Controls/ContentControl.xaml
  79. 3
      src/Avalonia.Themes.Fluent/Controls/ContextMenu.xaml
  80. 2
      src/Avalonia.Themes.Fluent/Controls/DataValidationErrors.xaml
  81. 16
      src/Avalonia.Themes.Fluent/Controls/DatePicker.xaml
  82. 29
      src/Avalonia.Themes.Fluent/Controls/Expander.xaml
  83. 1
      src/Avalonia.Themes.Fluent/Controls/GridSplitter.xaml
  84. 1
      src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml
  85. 3
      src/Avalonia.Themes.Fluent/Controls/Label.xaml
  86. 8
      src/Avalonia.Themes.Fluent/Controls/ListBox.xaml
  87. 1
      src/Avalonia.Themes.Fluent/Controls/ListBoxItem.xaml
  88. 1
      src/Avalonia.Themes.Fluent/Controls/Menu.xaml
  89. 6
      src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml
  90. 6
      src/Avalonia.Themes.Fluent/Controls/NotificationCard.xaml
  91. 2
      src/Avalonia.Themes.Fluent/Controls/NumericUpDown.xaml
  92. 3
      src/Avalonia.Themes.Fluent/Controls/ProgressBar.xaml
  93. 11
      src/Avalonia.Themes.Fluent/Controls/RadioButton.xaml
  94. 2
      src/Avalonia.Themes.Fluent/Controls/RepeatButton.xaml
  95. 1
      src/Avalonia.Themes.Fluent/Controls/Separator.xaml
  96. 4
      src/Avalonia.Themes.Fluent/Controls/Slider.xaml
  97. 4
      src/Avalonia.Themes.Fluent/Controls/TabControl.xaml
  98. 1
      src/Avalonia.Themes.Fluent/Controls/TabItem.xaml
  99. 14
      src/Avalonia.Themes.Fluent/Controls/TabStrip.xaml
  100. 1
      src/Avalonia.Themes.Fluent/Controls/TabStripItem.xaml

3
build/MicroCom.targets

@ -15,7 +15,8 @@
Inputs="@(AvnComIdl);$(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/**/*.cs" Inputs="@(AvnComIdl);$(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/**/*.cs"
Outputs="%(AvnComIdl.OutputFile)"> Outputs="%(AvnComIdl.OutputFile)">
<Message Importance="high" Text="Generating file %(AvnComIdl.OutputFile) from @(AvnComIdl)" /> <Message Importance="high" Text="Generating file %(AvnComIdl.OutputFile) from @(AvnComIdl)" />
<Exec Command="dotnet $(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/bin/$(Configuration)/netcoreapp3.1/MicroComGenerator.dll -i @(AvnComIdl) --cs %(AvnComIdl.OutputFile)" LogStandardErrorAsError="true" /> <Exec Command="dotnet &quot;$(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/bin/$(Configuration)/netcoreapp3.1/MicroComGenerator.dll&quot; -i @(AvnComIdl) --cs %(AvnComIdl.OutputFile)"
LogStandardErrorAsError="true" />
<ItemGroup> <ItemGroup>
<!-- Remove and re-add generated file, this is needed for the clean build --> <!-- Remove and re-add generated file, this is needed for the clean build -->
<Compile Remove="%(AvnComIdl.OutputFile)"/> <Compile Remove="%(AvnComIdl.OutputFile)"/>

1
native/Avalonia.Native/src/OSX/KeyTransform.mm

@ -222,6 +222,7 @@ std::map<int, const char*> s_QwertyKeyMap =
{ 45, "n" }, { 45, "n" },
{ 46, "m" }, { 46, "m" },
{ 47, "." }, { 47, "." },
{ 48, "\t" },
{ 49, " " }, { 49, " " },
{ 50, "`" }, { 50, "`" },
{ 51, "" }, { 51, "" },

7
native/Avalonia.Native/src/OSX/window.mm

@ -713,6 +713,12 @@ private:
if(cparent == nullptr) if(cparent == nullptr)
return E_INVALIDARG; return E_INVALIDARG;
// If one tries to show a child window with a minimized parent window, then the parent window will be
// restored but MacOS isn't kind enough to *tell* us that, so the window will be left in a non-interactive
// state. Detect this and explicitly restore the parent window ourselves to avoid this situation.
if (cparent->WindowState() == Minimized)
cparent->SetWindowState(Normal);
[cparent->Window addChildWindow:Window ordered:NSWindowAbove]; [cparent->Window addChildWindow:Window ordered:NSWindowAbove];
UpdateStyle(); UpdateStyle();
@ -1204,6 +1210,7 @@ private:
} }
_actualWindowState = _lastWindowState; _actualWindowState = _lastWindowState;
WindowEvents->WindowStateChanged(_actualWindowState);
} }

2
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -28,7 +28,7 @@
DockPanel.Dock="Top"/> DockPanel.Dock="Top"/>
<DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All"> <DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" /> <DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" MinWidth="400" />
<!-- CompiledBinding example of usage. --> <!-- CompiledBinding example of usage. -->
<DataGridTextColumn Header="Region" Binding="{CompiledBinding Region}" Width="4*" x:DataType="local:Country" /> <DataGridTextColumn Header="Region" Binding="{CompiledBinding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" /> <DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" />

1
samples/ControlCatalog/SideBar.xaml

@ -16,7 +16,6 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border <Border
Margin="{TemplateBinding Margin}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel> <DockPanel>

1
samples/RenderDemo/SideBar.xaml

@ -7,7 +7,6 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border <Border
Margin="{TemplateBinding Margin}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel> <DockPanel>

57
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -25,6 +25,7 @@ using System.ComponentModel.DataAnnotations;
using Avalonia.Controls.Utils; using Avalonia.Controls.Utils;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Controls.Metadata; using Avalonia.Controls.Metadata;
using Avalonia.Input.GestureRecognizers;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -2214,35 +2215,71 @@ namespace Avalonia.Controls
/// <param name="e">PointerWheelEventArgs</param> /// <param name="e">PointerWheelEventArgs</param>
protected override void OnPointerWheelChanged(PointerWheelEventArgs e) protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
{ {
if (IsEnabled && !e.Handled && DisplayData.NumDisplayedScrollingElements > 0) e.Handled = e.Handled || UpdateScroll(e.Delta * DATAGRID_mouseWheelDelta);
}
internal bool UpdateScroll(Vector delta)
{
if (IsEnabled && DisplayData.NumDisplayedScrollingElements > 0)
{ {
double scrollHeight = 0; var handled = false;
var delta = DATAGRID_mouseWheelDelta * e.Delta.Y; var scrollHeight = 0d;
var deltaAbs = Math.Abs(delta);
if (delta > 0) // Vertical scroll handling
if (delta.Y > 0)
{ {
scrollHeight = Math.Max(-_verticalOffset, -deltaAbs); scrollHeight = Math.Max(-_verticalOffset, -delta.Y);
} }
else if (delta < 0) else if (delta.Y < 0)
{ {
if (_vScrollBar != null && VerticalScrollBarVisibility == ScrollBarVisibility.Visible) if (_vScrollBar != null && VerticalScrollBarVisibility == ScrollBarVisibility.Visible)
{ {
scrollHeight = Math.Min(Math.Max(0, _vScrollBar.Maximum - _verticalOffset), deltaAbs); scrollHeight = Math.Min(Math.Max(0, _vScrollBar.Maximum - _verticalOffset), -delta.Y);
} }
else else
{ {
double maximum = EdgedRowsHeightCalculated - CellsHeight; double maximum = EdgedRowsHeightCalculated - CellsHeight;
scrollHeight = Math.Min(Math.Max(0, maximum - _verticalOffset), deltaAbs); scrollHeight = Math.Min(Math.Max(0, maximum - _verticalOffset), -delta.Y);
} }
} }
if (scrollHeight != 0) if (scrollHeight != 0)
{ {
DisplayData.PendingVerticalScrollHeight = scrollHeight; DisplayData.PendingVerticalScrollHeight = scrollHeight;
handled = true;
}
// Horizontal scroll handling
if (delta.X != 0)
{
var originalHorizontalOffset = HorizontalOffset;
var horizontalOffset = originalHorizontalOffset - delta.X;
var widthNotVisible = Math.Max(0, ColumnsInternal.VisibleEdgedColumnsWidth - CellsWidth);
if (horizontalOffset < 0)
{
horizontalOffset = 0;
}
if (horizontalOffset > widthNotVisible)
{
horizontalOffset = widthNotVisible;
}
if (horizontalOffset != originalHorizontalOffset)
{
HorizontalOffset = horizontalOffset;
handled = true;
}
}
if (handled)
{
InvalidateRowsMeasure(invalidateIndividualElements: false); InvalidateRowsMeasure(invalidateIndividualElements: false);
e.Handled = true; return true;
} }
} }
return false;
} }
/// <summary> /// <summary>

10
src/Avalonia.Controls.DataGrid/DataGridCell.cs

@ -173,7 +173,15 @@ namespace Avalonia.Controls
} }
if (OwningRow != null) if (OwningRow != null)
{ {
e.Handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, ColumnIndex, OwningRow.Slot, !e.Handled); var handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, ColumnIndex, OwningRow.Slot, !e.Handled);
// Do not handle PointerPressed with touch,
// so we can start scroll gesture on the same event.
if (e.Pointer.Type != PointerType.Touch)
{
e.Handled = handled;
}
OwningGrid.UpdatedStateOnMouseLeftButtonDown = true; OwningGrid.UpdatedStateOnMouseLeftButtonDown = true;
} }
} }

13
src/Avalonia.Controls.DataGrid/Primitives/DataGridRowsPresenter.cs

@ -5,6 +5,9 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Avalonia.Input;
using Avalonia.Input.GestureRecognizers;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Media; using Avalonia.Media;
@ -16,6 +19,11 @@ namespace Avalonia.Controls.Primitives
/// </summary> /// </summary>
public sealed class DataGridRowsPresenter : Panel public sealed class DataGridRowsPresenter : Panel
{ {
public DataGridRowsPresenter()
{
AddHandler(Gestures.ScrollGestureEvent, OnScrollGesture);
}
internal DataGrid OwningGrid internal DataGrid OwningGrid
{ {
get; get;
@ -176,6 +184,11 @@ namespace Avalonia.Controls.Primitives
return new Size(totalCellsWidth + headerWidth, totalHeight); return new Size(totalCellsWidth + headerWidth, totalHeight);
} }
private void OnScrollGesture(object sender, ScrollGestureEventArgs e)
{
e.Handled = e.Handled || OwningGrid.UpdateScroll(-e.Delta);
}
#if DEBUG #if DEBUG
internal void PrintChildren() internal void PrintChildren()
{ {

6
src/Avalonia.Controls.DataGrid/Themes/Default.xaml

@ -247,7 +247,11 @@
<DataGridColumnHeader Name="PART_TopRightCornerHeader" Grid.Column="2"/> <DataGridColumnHeader Name="PART_TopRightCornerHeader" Grid.Column="2"/>
<Rectangle Name="PART_ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" VerticalAlignment="Bottom" StrokeThickness="1" Height="1" Fill="{DynamicResource ThemeControlMidHighBrush}"/> <Rectangle Name="PART_ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" VerticalAlignment="Bottom" StrokeThickness="1" Height="1" Fill="{DynamicResource ThemeControlMidHighBrush}"/>
<DataGridRowsPresenter Name="PART_RowsPresenter" Grid.ColumnSpan="2" Grid.Row="1" /> <DataGridRowsPresenter Name="PART_RowsPresenter" Grid.ColumnSpan="2" Grid.Row="1">
<DataGridRowsPresenter.GestureRecognizers>
<ScrollGestureRecognizer CanHorizontallyScroll="True" CanVerticallyScroll="True" />
</DataGridRowsPresenter.GestureRecognizers>
</DataGridRowsPresenter>
<Rectangle Name="PART_BottomRightCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Column="2" Grid.Row="2" /> <Rectangle Name="PART_BottomRightCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Column="2" Grid.Row="2" />
<Rectangle Name="BottomLeftCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Row="2" Grid.ColumnSpan="2" /> <Rectangle Name="BottomLeftCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Row="2" Grid.ColumnSpan="2" />
<ScrollBar Name="PART_VerticalScrollbar" Orientation="Vertical" Grid.Column="2" Grid.Row="1" Width="{DynamicResource ScrollBarThickness}"/> <ScrollBar Name="PART_VerticalScrollbar" Orientation="Vertical" Grid.Column="2" Grid.Row="1" Width="{DynamicResource ScrollBarThickness}"/>

6
src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml

@ -601,7 +601,11 @@
<DataGridRowsPresenter Name="PART_RowsPresenter" <DataGridRowsPresenter Name="PART_RowsPresenter"
Grid.Row="1" Grid.Row="1"
Grid.RowSpan="2" Grid.RowSpan="2"
Grid.ColumnSpan="3" /> Grid.ColumnSpan="3">
<DataGridRowsPresenter.GestureRecognizers>
<ScrollGestureRecognizer CanHorizontallyScroll="True" CanVerticallyScroll="True" />
</DataGridRowsPresenter.GestureRecognizers>
</DataGridRowsPresenter>
<Rectangle Name="PART_BottomRightCorner" <Rectangle Name="PART_BottomRightCorner"
Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}" Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
Grid.Column="2" Grid.Column="2"

17
src/Avalonia.Controls/ContextMenu.cs

@ -2,7 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Generators; using Avalonia.Controls.Generators;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
@ -21,7 +21,7 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// A control context menu. /// A control context menu.
/// </summary> /// </summary>
public class ContextMenu : MenuBase, ISetterValue public class ContextMenu : MenuBase, ISetterValue, IPopupHostProvider
{ {
/// <summary> /// <summary>
/// Defines the <see cref="HorizontalOffset"/> property. /// Defines the <see cref="HorizontalOffset"/> property.
@ -82,6 +82,7 @@ namespace Avalonia.Controls
private Popup? _popup; private Popup? _popup;
private List<Control>? _attachedControls; private List<Control>? _attachedControls;
private IInputElement? _previousFocus; private IInputElement? _previousFocus;
private Action<IPopupHost?>? _popupHostChangedHandler;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ContextMenu"/> class. /// Initializes a new instance of the <see cref="ContextMenu"/> class.
@ -304,6 +305,14 @@ namespace Avalonia.Controls
} }
} }
IPopupHost? IPopupHostProvider.PopupHost => _popup?.Host;
event Action<IPopupHost?>? IPopupHostProvider.PopupHostChanged
{
add => _popupHostChangedHandler += value;
remove => _popupHostChangedHandler -= value;
}
protected override IItemContainerGenerator CreateItemContainerGenerator() protected override IItemContainerGenerator CreateItemContainerGenerator()
{ {
return new MenuItemContainerGenerator(this); return new MenuItemContainerGenerator(this);
@ -364,6 +373,8 @@ namespace Avalonia.Controls
{ {
_previousFocus = FocusManager.Instance?.Current; _previousFocus = FocusManager.Instance?.Current;
Focus(); Focus();
_popupHostChangedHandler?.Invoke(_popup!.Host);
} }
private void PopupClosing(object sender, CancelEventArgs e) private void PopupClosing(object sender, CancelEventArgs e)
@ -397,6 +408,8 @@ namespace Avalonia.Controls
RoutedEvent = MenuClosedEvent, RoutedEvent = MenuClosedEvent,
Source = this, Source = this,
}); });
_popupHostChangedHandler?.Invoke(null);
} }
private void PopupKeyUp(object sender, KeyEventArgs e) private void PopupKeyUp(object sender, KeyEventArgs e)

23
src/Avalonia.Controls/Diagnostics/IPopupHostProvider.cs

@ -0,0 +1,23 @@
using System;
using Avalonia.Controls.Primitives;
#nullable enable
namespace Avalonia.Controls.Diagnostics
{
/// <summary>
/// Diagnostics interface to retrieve an associated <see cref="IPopupHost"/>.
/// </summary>
public interface IPopupHostProvider
{
/// <summary>
/// The popup host.
/// </summary>
IPopupHost? PopupHost { get; }
/// <summary>
/// Raised when the popup host changes.
/// </summary>
event Action<IPopupHost?>? PopupHostChanged;
}
}

15
src/Avalonia.Controls/Diagnostics/ToolTipDiagnostics.cs

@ -0,0 +1,15 @@
#nullable enable
namespace Avalonia.Controls.Diagnostics
{
/// <summary>
/// Helper class to provide diagnostics information for <see cref="ToolTip"/>.
/// </summary>
public static class ToolTipDiagnostics
{
/// <summary>
/// Provides access to the internal <see cref="ToolTip.ToolTipProperty"/> for use in DevTools.
/// </summary>
public static AvaloniaProperty<ToolTip?> ToolTipProperty = ToolTip.ToolTipProperty;
}
}

18
src/Avalonia.Controls/Flyouts/FlyoutBase.cs

@ -1,19 +1,18 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using Avalonia.Controls.Diagnostics;
using System.Linq; using System.Linq;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.Rendering;
#nullable enable #nullable enable
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
{ {
public abstract class FlyoutBase : AvaloniaObject public abstract class FlyoutBase : AvaloniaObject, IPopupHostProvider
{ {
static FlyoutBase() static FlyoutBase()
{ {
@ -59,6 +58,7 @@ namespace Avalonia.Controls.Primitives
private Rect? _enlargedPopupRect; private Rect? _enlargedPopupRect;
private PixelRect? _enlargePopupRectScreenPixelRect; private PixelRect? _enlargePopupRectScreenPixelRect;
private IDisposable? _transientDisposable; private IDisposable? _transientDisposable;
private Action<IPopupHost?>? _popupHostChangedHandler;
public FlyoutBase() public FlyoutBase()
{ {
@ -103,6 +103,14 @@ namespace Avalonia.Controls.Primitives
private set => SetAndRaise(TargetProperty, ref _target, value); private set => SetAndRaise(TargetProperty, ref _target, value);
} }
IPopupHost? IPopupHostProvider.PopupHost => Popup?.Host;
event Action<IPopupHost?>? IPopupHostProvider.PopupHostChanged
{
add => _popupHostChangedHandler += value;
remove => _popupHostChangedHandler -= value;
}
public event EventHandler? Closed; public event EventHandler? Closed;
public event EventHandler<CancelEventArgs>? Closing; public event EventHandler<CancelEventArgs>? Closing;
public event EventHandler? Opened; public event EventHandler? Opened;
@ -363,6 +371,8 @@ namespace Avalonia.Controls.Primitives
private void OnPopupOpened(object sender, EventArgs e) private void OnPopupOpened(object sender, EventArgs e)
{ {
IsOpen = true; IsOpen = true;
_popupHostChangedHandler?.Invoke(Popup!.Host);
} }
private void OnPopupClosing(object sender, CancelEventArgs e) private void OnPopupClosing(object sender, CancelEventArgs e)
@ -376,6 +386,8 @@ namespace Avalonia.Controls.Primitives
private void OnPopupClosed(object sender, EventArgs e) private void OnPopupClosed(object sender, EventArgs e)
{ {
HideCore(false); HideCore(false);
_popupHostChangedHandler?.Invoke(null);
} }
// This method is handling both popup logical tree and target logical tree. // This method is handling both popup logical tree and target logical tree.

9
src/Avalonia.Controls/Flyouts/FlyoutPresenter.cs

@ -6,15 +6,6 @@ namespace Avalonia.Controls
{ {
public class FlyoutPresenter : ContentControl public class FlyoutPresenter : ContentControl
{ {
public static readonly StyledProperty<CornerRadius> CornerRadiusProperty =
Border.CornerRadiusProperty.AddOwner<FlyoutPresenter>();
public CornerRadius CornerRadius
{
get => GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {
if (e.Key == Key.Escape) if (e.Key == Key.Escape)

5
src/Avalonia.Controls/Primitives/OverlayPopupHost.cs

@ -140,10 +140,5 @@ namespace Avalonia.Controls.Primitives
return new OverlayPopupHost(overlayLayer); return new OverlayPopupHost(overlayLayer);
} }
public override void Render(DrawingContext context)
{
context.FillRectangle(Brushes.White, new Rect(default, Bounds.Size));
}
} }
} }

16
src/Avalonia.Controls/Primitives/Popup.cs

@ -2,6 +2,7 @@ using System;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives.PopupPositioning; using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Input; using Avalonia.Input;
@ -18,7 +19,7 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Displays a popup window. /// Displays a popup window.
/// </summary> /// </summary>
public class Popup : Control, IVisualTreeHost public class Popup : Control, IVisualTreeHost, IPopupHostProvider
{ {
public static readonly StyledProperty<bool> WindowManagerAddShadowHintProperty = public static readonly StyledProperty<bool> WindowManagerAddShadowHintProperty =
AvaloniaProperty.Register<PopupRoot, bool>(nameof(WindowManagerAddShadowHint), true); AvaloniaProperty.Register<PopupRoot, bool>(nameof(WindowManagerAddShadowHint), true);
@ -134,6 +135,7 @@ namespace Avalonia.Controls.Primitives
private bool _ignoreIsOpenChanged; private bool _ignoreIsOpenChanged;
private PopupOpenState? _openState; private PopupOpenState? _openState;
private IInputElement _overlayInputPassThroughElement; private IInputElement _overlayInputPassThroughElement;
private Action<IPopupHost?>? _popupHostChangedHandler;
/// <summary> /// <summary>
/// Initializes static members of the <see cref="Popup"/> class. /// Initializes static members of the <see cref="Popup"/> class.
@ -351,6 +353,14 @@ namespace Avalonia.Controls.Primitives
/// </summary> /// </summary>
IVisual? IVisualTreeHost.Root => _openState?.PopupHost.HostedVisualTreeRoot; IVisual? IVisualTreeHost.Root => _openState?.PopupHost.HostedVisualTreeRoot;
IPopupHost? IPopupHostProvider.PopupHost => Host;
event Action<IPopupHost?>? IPopupHostProvider.PopupHostChanged
{
add => _popupHostChangedHandler += value;
remove => _popupHostChangedHandler -= value;
}
/// <summary> /// <summary>
/// Opens the popup. /// Opens the popup.
/// </summary> /// </summary>
@ -482,6 +492,8 @@ namespace Avalonia.Controls.Primitives
} }
Opened?.Invoke(this, EventArgs.Empty); Opened?.Invoke(this, EventArgs.Empty);
_popupHostChangedHandler?.Invoke(Host);
} }
/// <summary> /// <summary>
@ -591,6 +603,8 @@ namespace Avalonia.Controls.Primitives
_openState.Dispose(); _openState.Dispose();
_openState = null; _openState = null;
_popupHostChangedHandler?.Invoke(null);
using (BeginIgnoringIsOpen()) using (BeginIgnoringIsOpen())
{ {
IsOpen = false; IsOpen = false;

34
src/Avalonia.Controls/Primitives/ScrollBar.cs

@ -57,6 +57,18 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<bool> AllowAutoHideProperty = public static readonly StyledProperty<bool> AllowAutoHideProperty =
AvaloniaProperty.Register<ScrollBar, bool>(nameof(AllowAutoHide), true); AvaloniaProperty.Register<ScrollBar, bool>(nameof(AllowAutoHide), true);
/// <summary>
/// Defines the <see cref="HideDelay"/> property.
/// </summary>
public static readonly StyledProperty<TimeSpan> HideDelayProperty =
AvaloniaProperty.Register<ScrollBar, TimeSpan>(nameof(HideDelay), TimeSpan.FromSeconds(2));
/// <summary>
/// Defines the <see cref="ShowDelay"/> property.
/// </summary>
public static readonly StyledProperty<TimeSpan> ShowDelayProperty =
AvaloniaProperty.Register<ScrollBar, TimeSpan>(nameof(ShowDelay), TimeSpan.FromSeconds(0.5));
private Button _lineUpButton; private Button _lineUpButton;
private Button _lineDownButton; private Button _lineDownButton;
private Button _pageUpButton; private Button _pageUpButton;
@ -126,6 +138,24 @@ namespace Avalonia.Controls.Primitives
get => GetValue(AllowAutoHideProperty); get => GetValue(AllowAutoHideProperty);
set => SetValue(AllowAutoHideProperty, value); set => SetValue(AllowAutoHideProperty, value);
} }
/// <summary>
/// Gets a value that determines how long will be the hide delay after user stops interacting with the scrollbar.
/// </summary>
public TimeSpan HideDelay
{
get => GetValue(HideDelayProperty);
set => SetValue(HideDelayProperty, value);
}
/// <summary>
/// Gets a value that determines how long will be the show delay when user starts interacting with the scrollbar.
/// </summary>
public TimeSpan ShowDelay
{
get => GetValue(ShowDelayProperty);
set => SetValue(ShowDelayProperty, value);
}
public event EventHandler<ScrollEventArgs> Scroll; public event EventHandler<ScrollEventArgs> Scroll;
@ -296,12 +326,12 @@ namespace Avalonia.Controls.Primitives
private void CollapseAfterDelay() private void CollapseAfterDelay()
{ {
InvokeAfterDelay(Collapse, TimeSpan.FromSeconds(2)); InvokeAfterDelay(Collapse, HideDelay);
} }
private void ExpandAfterDelay() private void ExpandAfterDelay()
{ {
InvokeAfterDelay(Expand, TimeSpan.FromMilliseconds(400)); InvokeAfterDelay(Expand, ShowDelay);
} }
private void Collapse() private void Collapse()

40
src/Avalonia.Controls/Primitives/TemplatedControl.cs

@ -5,7 +5,8 @@ using Avalonia.Logging;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.VisualTree;
#nullable enable
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
{ {
@ -17,13 +18,13 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Defines the <see cref="Background"/> property. /// Defines the <see cref="Background"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<IBrush> BackgroundProperty = public static readonly StyledProperty<IBrush?> BackgroundProperty =
Border.BackgroundProperty.AddOwner<TemplatedControl>(); Border.BackgroundProperty.AddOwner<TemplatedControl>();
/// <summary> /// <summary>
/// Defines the <see cref="BorderBrush"/> property. /// Defines the <see cref="BorderBrush"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<IBrush> BorderBrushProperty = public static readonly StyledProperty<IBrush?> BorderBrushProperty =
Border.BorderBrushProperty.AddOwner<TemplatedControl>(); Border.BorderBrushProperty.AddOwner<TemplatedControl>();
/// <summary> /// <summary>
@ -32,6 +33,12 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<Thickness> BorderThicknessProperty = public static readonly StyledProperty<Thickness> BorderThicknessProperty =
Border.BorderThicknessProperty.AddOwner<TemplatedControl>(); Border.BorderThicknessProperty.AddOwner<TemplatedControl>();
/// <summary>
/// Defines the <see cref="CornerRadius"/> property.
/// </summary>
public static readonly StyledProperty<CornerRadius> CornerRadiusProperty =
Border.CornerRadiusProperty.AddOwner<TemplatedControl>();
/// <summary> /// <summary>
/// Defines the <see cref="FontFamily"/> property. /// Defines the <see cref="FontFamily"/> property.
/// </summary> /// </summary>
@ -59,7 +66,7 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Defines the <see cref="Foreground"/> property. /// Defines the <see cref="Foreground"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<IBrush> ForegroundProperty = public static readonly StyledProperty<IBrush?> ForegroundProperty =
TextBlock.ForegroundProperty.AddOwner<TemplatedControl>(); TextBlock.ForegroundProperty.AddOwner<TemplatedControl>();
/// <summary> /// <summary>
@ -71,8 +78,8 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Defines the <see cref="Template"/> property. /// Defines the <see cref="Template"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<IControlTemplate> TemplateProperty = public static readonly StyledProperty<IControlTemplate?> TemplateProperty =
AvaloniaProperty.Register<TemplatedControl, IControlTemplate>(nameof(Template)); AvaloniaProperty.Register<TemplatedControl, IControlTemplate?>(nameof(Template));
/// <summary> /// <summary>
/// Defines the IsTemplateFocusTarget attached property. /// Defines the IsTemplateFocusTarget attached property.
@ -88,7 +95,7 @@ namespace Avalonia.Controls.Primitives
"TemplateApplied", "TemplateApplied",
RoutingStrategies.Direct); RoutingStrategies.Direct);
private IControlTemplate _appliedTemplate; private IControlTemplate? _appliedTemplate;
/// <summary> /// <summary>
/// Initializes static members of the <see cref="TemplatedControl"/> class. /// Initializes static members of the <see cref="TemplatedControl"/> class.
@ -111,7 +118,7 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Gets or sets the brush used to draw the control's background. /// Gets or sets the brush used to draw the control's background.
/// </summary> /// </summary>
public IBrush Background public IBrush? Background
{ {
get { return GetValue(BackgroundProperty); } get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); } set { SetValue(BackgroundProperty, value); }
@ -120,7 +127,7 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Gets or sets the brush used to draw the control's border. /// Gets or sets the brush used to draw the control's border.
/// </summary> /// </summary>
public IBrush BorderBrush public IBrush? BorderBrush
{ {
get { return GetValue(BorderBrushProperty); } get { return GetValue(BorderBrushProperty); }
set { SetValue(BorderBrushProperty, value); } set { SetValue(BorderBrushProperty, value); }
@ -135,6 +142,15 @@ namespace Avalonia.Controls.Primitives
set { SetValue(BorderThicknessProperty, value); } set { SetValue(BorderThicknessProperty, value); }
} }
/// <summary>
/// Gets or sets the radius of the border rounded corners.
/// </summary>
public CornerRadius CornerRadius
{
get { return GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
/// <summary> /// <summary>
/// Gets or sets the font family used to draw the control's text. /// Gets or sets the font family used to draw the control's text.
/// </summary> /// </summary>
@ -174,7 +190,7 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Gets or sets the brush used to draw the control's text and other foreground elements. /// Gets or sets the brush used to draw the control's text and other foreground elements.
/// </summary> /// </summary>
public IBrush Foreground public IBrush? Foreground
{ {
get { return GetValue(ForegroundProperty); } get { return GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); } set { SetValue(ForegroundProperty, value); }
@ -192,7 +208,7 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Gets or sets the template that defines the control's appearance. /// Gets or sets the template that defines the control's appearance.
/// </summary> /// </summary>
public IControlTemplate Template public IControlTemplate? Template
{ {
get { return GetValue(TemplateProperty); } get { return GetValue(TemplateProperty); }
set { SetValue(TemplateProperty, value); } set { SetValue(TemplateProperty, value); }
@ -265,7 +281,9 @@ namespace Avalonia.Controls.Primitives
var e = new TemplateAppliedEventArgs(nameScope); var e = new TemplateAppliedEventArgs(nameScope);
OnApplyTemplate(e); OnApplyTemplate(e);
#pragma warning disable CS0618 // Type or member is obsolete
OnTemplateApplied(e); OnTemplateApplied(e);
#pragma warning restore CS0618 // Type or member is obsolete
RaiseEvent(e); RaiseEvent(e);
} }

65
src/Avalonia.Controls/TextBox.cs

@ -31,7 +31,7 @@ namespace Avalonia.Controls
public static KeyGesture PasteGesture { get; } = AvaloniaLocator.Current public static KeyGesture PasteGesture { get; } = AvaloniaLocator.Current
.GetService<PlatformHotkeyConfiguration>()?.Paste.FirstOrDefault(); .GetService<PlatformHotkeyConfiguration>()?.Paste.FirstOrDefault();
public static readonly StyledProperty<bool> AcceptsReturnProperty = public static readonly StyledProperty<bool> AcceptsReturnProperty =
AvaloniaProperty.Register<TextBox, bool>(nameof(AcceptsReturn)); AvaloniaProperty.Register<TextBox, bool>(nameof(AcceptsReturn));
@ -117,7 +117,7 @@ namespace Avalonia.Controls
public static readonly StyledProperty<bool> RevealPasswordProperty = public static readonly StyledProperty<bool> RevealPasswordProperty =
AvaloniaProperty.Register<TextBox, bool>(nameof(RevealPassword)); AvaloniaProperty.Register<TextBox, bool>(nameof(RevealPassword));
public static readonly DirectProperty<TextBox, bool> CanCutProperty = public static readonly DirectProperty<TextBox, bool> CanCutProperty =
AvaloniaProperty.RegisterDirect<TextBox, bool>( AvaloniaProperty.RegisterDirect<TextBox, bool>(
nameof(CanCut), nameof(CanCut),
@ -135,7 +135,7 @@ namespace Avalonia.Controls
public static readonly StyledProperty<bool> IsUndoEnabledProperty = public static readonly StyledProperty<bool> IsUndoEnabledProperty =
AvaloniaProperty.Register<TextBox, bool>( AvaloniaProperty.Register<TextBox, bool>(
nameof(IsUndoEnabled), nameof(IsUndoEnabled),
defaultValue: true); defaultValue: true);
public static readonly DirectProperty<TextBox, int> UndoLimitProperty = public static readonly DirectProperty<TextBox, int> UndoLimitProperty =
@ -157,6 +157,10 @@ namespace Avalonia.Controls
} }
public bool Equals(UndoRedoState other) => ReferenceEquals(Text, other.Text) || Equals(Text, other.Text); public bool Equals(UndoRedoState other) => ReferenceEquals(Text, other.Text) || Equals(Text, other.Text);
public override bool Equals(object obj) => obj is UndoRedoState other && Equals(other);
public override int GetHashCode() => Text.GetHashCode();
} }
private string _text; private string _text;
@ -174,6 +178,10 @@ namespace Avalonia.Controls
private string _newLine = Environment.NewLine; private string _newLine = Environment.NewLine;
private static readonly string[] invalidCharacters = new String[1] { "\u007f" }; private static readonly string[] invalidCharacters = new String[1] { "\u007f" };
private int _selectedTextChangesMadeSinceLastUndoSnapshot;
private bool _hasDoneSnapshotOnce;
private const int _maxCharsBeforeUndoSnapshot = 7;
static TextBox() static TextBox()
{ {
FocusableProperty.OverrideDefaultValue(typeof(TextBox), true); FocusableProperty.OverrideDefaultValue(typeof(TextBox), true);
@ -202,7 +210,8 @@ namespace Avalonia.Controls
horizontalScrollBarVisibility, horizontalScrollBarVisibility,
BindingPriority.Style); BindingPriority.Style);
_undoRedoHelper = new UndoRedoHelper<UndoRedoState>(this); _undoRedoHelper = new UndoRedoHelper<UndoRedoState>(this);
_selectedTextChangesMadeSinceLastUndoSnapshot = 0;
_hasDoneSnapshotOnce = false;
UpdatePseudoclasses(); UpdatePseudoclasses();
} }
@ -331,6 +340,7 @@ namespace Avalonia.Controls
if (SetAndRaise(TextProperty, ref _text, value) && IsUndoEnabled && !_isUndoingRedoing) if (SetAndRaise(TextProperty, ref _text, value) && IsUndoEnabled && !_isUndoingRedoing)
{ {
_undoRedoHelper.Clear(); _undoRedoHelper.Clear();
SnapshotUndoRedo(); // so we always have an initial state
} }
} }
} }
@ -341,16 +351,16 @@ namespace Avalonia.Controls
get { return GetSelection(); } get { return GetSelection(); }
set set
{ {
SnapshotUndoRedo();
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
_selectedTextChangesMadeSinceLastUndoSnapshot++;
SnapshotUndoRedo(ignoreChangeCount: false);
DeleteSelection(); DeleteSelection();
} }
else else
{ {
HandleTextInput(value); HandleTextInput(value);
} }
SnapshotUndoRedo();
} }
} }
@ -422,7 +432,7 @@ namespace Avalonia.Controls
get { return _newLine; } get { return _newLine; }
set { SetAndRaise(NewLineProperty, ref _newLine, value); } set { SetAndRaise(NewLineProperty, ref _newLine, value); }
} }
/// <summary> /// <summary>
/// Clears the current selection, maintaining the <see cref="CaretIndex"/> /// Clears the current selection, maintaining the <see cref="CaretIndex"/>
/// </summary> /// </summary>
@ -480,11 +490,13 @@ namespace Avalonia.Controls
var oldValue = _undoRedoHelper.Limit; var oldValue = _undoRedoHelper.Limit;
_undoRedoHelper.Limit = value; _undoRedoHelper.Limit = value;
RaisePropertyChanged(UndoLimitProperty, oldValue, value); RaisePropertyChanged(UndoLimitProperty, oldValue, value);
} }
// from docs at // from docs at
// https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled: // https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled:
// "Setting UndoLimit clears the undo queue." // "Setting UndoLimit clears the undo queue."
_undoRedoHelper.Clear(); _undoRedoHelper.Clear();
_selectedTextChangesMadeSinceLastUndoSnapshot = 0;
_hasDoneSnapshotOnce = false;
} }
} }
@ -515,6 +527,8 @@ namespace Avalonia.Controls
// Therefore, if you disable undo and then re-enable it, undo commands still do not work // Therefore, if you disable undo and then re-enable it, undo commands still do not work
// because the undo stack was emptied when you disabled undo." // because the undo stack was emptied when you disabled undo."
_undoRedoHelper.Clear(); _undoRedoHelper.Clear();
_selectedTextChangesMadeSinceLastUndoSnapshot = 0;
_hasDoneSnapshotOnce = false;
} }
} }
@ -577,23 +591,25 @@ namespace Avalonia.Controls
{ {
return; return;
} }
input = RemoveInvalidCharacters(input); input = RemoveInvalidCharacters(input);
if (string.IsNullOrEmpty(input)) if (string.IsNullOrEmpty(input))
{ {
return; return;
} }
_selectedTextChangesMadeSinceLastUndoSnapshot++;
SnapshotUndoRedo(ignoreChangeCount: false);
string text = Text ?? string.Empty; string text = Text ?? string.Empty;
int caretIndex = CaretIndex; int caretIndex = CaretIndex;
int newLength = input.Length + text.Length - Math.Abs(SelectionStart - SelectionEnd); int newLength = input.Length + text.Length - Math.Abs(SelectionStart - SelectionEnd);
if (MaxLength > 0 && newLength > MaxLength) if (MaxLength > 0 && newLength > MaxLength)
{ {
input = input.Remove(Math.Max(0, input.Length - (newLength - MaxLength))); input = input.Remove(Math.Max(0, input.Length - (newLength - MaxLength)));
} }
if (!string.IsNullOrEmpty(input)) if (!string.IsNullOrEmpty(input))
{ {
DeleteSelection(); DeleteSelection();
@ -627,7 +643,6 @@ namespace Avalonia.Controls
SnapshotUndoRedo(); SnapshotUndoRedo();
Copy(); Copy();
DeleteSelection(); DeleteSelection();
SnapshotUndoRedo();
} }
public async void Copy() public async void Copy()
@ -647,7 +662,6 @@ namespace Avalonia.Controls
SnapshotUndoRedo(); SnapshotUndoRedo();
HandleTextInput(text); HandleTextInput(text);
SnapshotUndoRedo();
} }
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
@ -696,6 +710,7 @@ namespace Avalonia.Controls
{ {
try try
{ {
SnapshotUndoRedo();
_isUndoingRedoing = true; _isUndoingRedoing = true;
_undoRedoHelper.Undo(); _undoRedoHelper.Undo();
} }
@ -830,7 +845,6 @@ namespace Avalonia.Controls
CaretIndex -= removedCharacters; CaretIndex -= removedCharacters;
ClearSelection(); ClearSelection();
} }
SnapshotUndoRedo();
handled = true; handled = true;
break; break;
@ -858,7 +872,6 @@ namespace Avalonia.Controls
SetTextInternal(text.Substring(0, caretIndex) + SetTextInternal(text.Substring(0, caretIndex) +
text.Substring(caretIndex + removedCharacters)); text.Substring(caretIndex + removedCharacters));
} }
SnapshotUndoRedo();
handled = true; handled = true;
break; break;
@ -868,7 +881,6 @@ namespace Avalonia.Controls
{ {
SnapshotUndoRedo(); SnapshotUndoRedo();
HandleTextInput(NewLine); HandleTextInput(NewLine);
SnapshotUndoRedo();
handled = true; handled = true;
} }
@ -879,7 +891,6 @@ namespace Avalonia.Controls
{ {
SnapshotUndoRedo(); SnapshotUndoRedo();
HandleTextInput("\t"); HandleTextInput("\t");
SnapshotUndoRedo();
handled = true; handled = true;
} }
else else
@ -889,6 +900,10 @@ namespace Avalonia.Controls
break; break;
case Key.Space:
SnapshotUndoRedo(); // always snapshot in between words
break;
default: default:
handled = false; handled = false;
break; break;
@ -1319,11 +1334,19 @@ namespace Avalonia.Controls
} }
} }
private void SnapshotUndoRedo() private void SnapshotUndoRedo(bool ignoreChangeCount = true)
{ {
if (IsUndoEnabled) if (IsUndoEnabled)
{ {
_undoRedoHelper.Snapshot(); if (ignoreChangeCount ||
!_hasDoneSnapshotOnce ||
(!ignoreChangeCount &&
_selectedTextChangesMadeSinceLastUndoSnapshot >= _maxCharsBeforeUndoSnapshot))
{
_undoRedoHelper.Snapshot();
_selectedTextChangesMadeSinceLastUndoSnapshot = 0;
_hasDoneSnapshotOnce = true;
}
} }
} }
} }

40
src/Avalonia.Controls/ToolTip.cs

@ -1,9 +1,8 @@
#nullable enable #nullable enable
using System; using System;
using System.Reactive.Linq; using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Metadata; using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.VisualTree;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -17,7 +16,7 @@ namespace Avalonia.Controls
/// assigning the content that you want displayed. /// assigning the content that you want displayed.
/// </remarks> /// </remarks>
[PseudoClasses(":open")] [PseudoClasses(":open")]
public class ToolTip : ContentControl public class ToolTip : ContentControl, IPopupHostProvider
{ {
/// <summary> /// <summary>
/// Defines the ToolTip.Tip attached property. /// Defines the ToolTip.Tip attached property.
@ -61,7 +60,8 @@ namespace Avalonia.Controls
internal static readonly AttachedProperty<ToolTip?> ToolTipProperty = internal static readonly AttachedProperty<ToolTip?> ToolTipProperty =
AvaloniaProperty.RegisterAttached<ToolTip, Control, ToolTip?>("ToolTip"); AvaloniaProperty.RegisterAttached<ToolTip, Control, ToolTip?>("ToolTip");
private IPopupHost? _popup; private IPopupHost? _popupHost;
private Action<IPopupHost?>? _popupHostChangedHandler;
/// <summary> /// <summary>
/// Initializes static members of the <see cref="ToolTip"/> class. /// Initializes static members of the <see cref="ToolTip"/> class.
@ -251,35 +251,45 @@ namespace Avalonia.Controls
tooltip.RecalculatePosition(control); tooltip.RecalculatePosition(control);
} }
IPopupHost? IPopupHostProvider.PopupHost => _popupHost;
event Action<IPopupHost?>? IPopupHostProvider.PopupHostChanged
{
add => _popupHostChangedHandler += value;
remove => _popupHostChangedHandler -= value;
}
internal void RecalculatePosition(Control control) internal void RecalculatePosition(Control control)
{ {
_popup?.ConfigurePosition(control, GetPlacement(control), new Point(GetHorizontalOffset(control), GetVerticalOffset(control))); _popupHost?.ConfigurePosition(control, GetPlacement(control), new Point(GetHorizontalOffset(control), GetVerticalOffset(control)));
} }
private void Open(Control control) private void Open(Control control)
{ {
Close(); Close();
_popup = OverlayPopupHost.CreatePopupHost(control, null); _popupHost = OverlayPopupHost.CreatePopupHost(control, null);
_popup.SetChild(this); _popupHost.SetChild(this);
((ISetLogicalParent)_popup).SetParent(control); ((ISetLogicalParent)_popupHost).SetParent(control);
_popup.ConfigurePosition(control, GetPlacement(control), _popupHost.ConfigurePosition(control, GetPlacement(control),
new Point(GetHorizontalOffset(control), GetVerticalOffset(control))); new Point(GetHorizontalOffset(control), GetVerticalOffset(control)));
WindowManagerAddShadowHintChanged(_popup, false); WindowManagerAddShadowHintChanged(_popupHost, false);
_popup.Show(); _popupHost.Show();
_popupHostChangedHandler?.Invoke(_popupHost);
} }
private void Close() private void Close()
{ {
if (_popup != null) if (_popupHost != null)
{ {
_popup.SetChild(null); _popupHost.SetChild(null);
_popup.Dispose(); _popupHost.Dispose();
_popup = null; _popupHost = null;
_popupHostChangedHandler?.Invoke(null);
} }
} }

11
src/Avalonia.Controls/Utils/UndoRedoHelper.cs

@ -7,7 +7,7 @@ using Avalonia.Utilities;
namespace Avalonia.Controls.Utils namespace Avalonia.Controls.Utils
{ {
class UndoRedoHelper<TState> : WeakTimer.IWeakTimerSubscriber where TState : struct, IEquatable<TState> class UndoRedoHelper<TState>
{ {
private readonly IUndoRedoHost _host; private readonly IUndoRedoHost _host;
@ -31,7 +31,6 @@ namespace Avalonia.Controls.Utils
public UndoRedoHelper(IUndoRedoHost host) public UndoRedoHelper(IUndoRedoHost host)
{ {
_host = host; _host = host;
WeakTimer.StartWeakTimer(this, TimeSpan.FromSeconds(1));
} }
public void Undo() public void Undo()
@ -61,7 +60,7 @@ namespace Avalonia.Controls.Utils
if (_states.Last != null) if (_states.Last != null)
{ {
_states.Last.Value = state; _states.Last.Value = state;
} }
} }
public void UpdateLastState() public void UpdateLastState()
@ -103,11 +102,5 @@ namespace Avalonia.Controls.Utils
_states.Clear(); _states.Clear();
_currentNode = null; _currentNode = null;
} }
bool WeakTimer.IWeakTimerSubscriber.Tick()
{
Snapshot();
return true;
}
} }
} }

8
src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs

@ -1,6 +1,5 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Diagnostics.Models; using Avalonia.Diagnostics.Models;
using Avalonia.Input; using Avalonia.Input;
@ -22,6 +21,7 @@ namespace Avalonia.Diagnostics.ViewModels
private bool _shouldVisualizeMarginPadding = true; private bool _shouldVisualizeMarginPadding = true;
private bool _shouldVisualizeDirtyRects; private bool _shouldVisualizeDirtyRects;
private bool _showFpsOverlay; private bool _showFpsOverlay;
private bool _freezePopups;
#nullable disable #nullable disable
// Remove "nullable disable" after MemberNotNull will work on our CI. // Remove "nullable disable" after MemberNotNull will work on our CI.
@ -41,6 +41,12 @@ namespace Avalonia.Diagnostics.ViewModels
Console = new ConsoleViewModel(UpdateConsoleContext); Console = new ConsoleViewModel(UpdateConsoleContext);
} }
public bool FreezePopups
{
get => _freezePopups;
set => RaiseAndSetIfChanged(ref _freezePopups, value);
}
public bool ShouldVisualizeMarginPadding public bool ShouldVisualizeMarginPadding
{ {
get => _shouldVisualizeMarginPadding; get => _shouldVisualizeMarginPadding;

33
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs

@ -1,26 +1,28 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.VisualTree; using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.ViewModels namespace Avalonia.Diagnostics.ViewModels
{ {
internal abstract class TreeNode : ViewModelBase, IDisposable internal abstract class TreeNode : ViewModelBase, IDisposable
{ {
private IDisposable? _classesSubscription; private readonly IDisposable? _classesSubscription;
private string _classes; private string _classes;
private bool _isExpanded; private bool _isExpanded;
public TreeNode(IVisual visual, TreeNode? parent) protected TreeNode(IVisual visual, TreeNode? parent, string? customName = null)
{ {
_classes = string.Empty;
Parent = parent; Parent = parent;
Type = visual.GetType().Name; Type = customName ?? visual.GetType().Name;
Visual = visual; Visual = visual;
_classes = string.Empty; FontWeight = IsRoot ? FontWeight.Bold : FontWeight.Normal;
if (visual is IControl control) if (visual is IControl control)
{ {
@ -52,6 +54,12 @@ namespace Avalonia.Diagnostics.ViewModels
} }
} }
private bool IsRoot => Visual is TopLevel ||
Visual is ContextMenu ||
Visual is IPopupHost;
public FontWeight FontWeight { get; }
public abstract TreeNodeCollection Children public abstract TreeNodeCollection Children
{ {
get; get;
@ -95,20 +103,5 @@ namespace Avalonia.Diagnostics.ViewModels
_classesSubscription?.Dispose(); _classesSubscription?.Dispose();
Children.Dispose(); Children.Dispose();
} }
private static int IndexOf(IReadOnlyList<TreeNode> collection, TreeNode item)
{
var count = collection.Count;
for (var i = 0; i < count; ++i)
{
if (collection[i] == item)
{
return i;
}
}
throw new AvaloniaInternalException("TreeNode was not present in parent Children collection.");
}
} }
} }

123
src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs

@ -1,5 +1,10 @@
using System; using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Primitives;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.VisualTree; using Avalonia.VisualTree;
@ -7,31 +12,30 @@ namespace Avalonia.Diagnostics.ViewModels
{ {
internal class VisualTreeNode : TreeNode internal class VisualTreeNode : TreeNode
{ {
public VisualTreeNode(IVisual visual, TreeNode? parent) public VisualTreeNode(IVisual visual, TreeNode? parent, string? customName = null)
: base(visual, parent) : base(visual, parent, customName)
{ {
Children = new VisualTreeNodeCollection(this, visual); Children = new VisualTreeNodeCollection(this, visual);
if ((Visual is IStyleable styleable)) if (Visual is IStyleable styleable)
{
IsInTemplate = styleable.TemplatedParent != null; IsInTemplate = styleable.TemplatedParent != null;
}
} }
public bool IsInTemplate { get; private set; } public bool IsInTemplate { get; }
public override TreeNodeCollection Children { get; } public override TreeNodeCollection Children { get; }
public static VisualTreeNode[] Create(object control) public static VisualTreeNode[] Create(object control)
{ {
var visual = control as IVisual; return control is IVisual visual ?
return visual != null ? new[] { new VisualTreeNode(visual, null) } : Array.Empty<VisualTreeNode>(); new[] { new VisualTreeNode(visual, null) } :
Array.Empty<VisualTreeNode>();
} }
internal class VisualTreeNodeCollection : TreeNodeCollection internal class VisualTreeNodeCollection : TreeNodeCollection
{ {
private readonly IVisual _control; private readonly IVisual _control;
private IDisposable? _subscription; private readonly CompositeDisposable _subscriptions = new CompositeDisposable(2);
public VisualTreeNodeCollection(TreeNode owner, IVisual control) public VisualTreeNodeCollection(TreeNode owner, IVisual control)
: base(owner) : base(owner)
@ -41,15 +45,106 @@ namespace Avalonia.Diagnostics.ViewModels
public override void Dispose() public override void Dispose()
{ {
_subscription?.Dispose(); _subscriptions.Dispose();
}
private static IObservable<PopupRoot?>? GetHostedPopupRootObservable(IVisual visual)
{
static IObservable<PopupRoot?> GetPopupHostObservable(
IPopupHostProvider popupHostProvider,
string? providerName = null)
{
return Observable.FromEvent<IPopupHost?>(
x => popupHostProvider.PopupHostChanged += x,
x => popupHostProvider.PopupHostChanged -= x)
.StartWith(popupHostProvider.PopupHost)
.Select(popupHost =>
{
if (popupHost is IControl control)
return new PopupRoot(
control,
providerName != null ? $"{providerName} ({control.GetType().Name})" : null);
return (PopupRoot?)null;
});
}
return visual switch
{
Popup p => GetPopupHostObservable(p),
Control c => Observable.CombineLatest(
c.GetObservable(Control.ContextFlyoutProperty),
c.GetObservable(Control.ContextMenuProperty),
c.GetObservable(FlyoutBase.AttachedFlyoutProperty),
c.GetObservable(ToolTipDiagnostics.ToolTipProperty),
(ContextFlyout, ContextMenu, AttachedFlyout, ToolTip) =>
{
if (ContextMenu != null)
//Note: ContextMenus are special since all the items are added as visual children.
//So we don't need to go via Popup
return Observable.Return<PopupRoot?>(new PopupRoot(ContextMenu));
if (ContextFlyout != null)
return GetPopupHostObservable(ContextFlyout, "ContextFlyout");
if (AttachedFlyout != null)
return GetPopupHostObservable(AttachedFlyout, "AttachedFlyout");
if (ToolTip != null)
return GetPopupHostObservable(ToolTip, "ToolTip");
return Observable.Return<PopupRoot?>(null);
})
.Switch(),
_ => null
};
} }
protected override void Initialize(AvaloniaList<TreeNode> nodes) protected override void Initialize(AvaloniaList<TreeNode> nodes)
{ {
_subscription = _control.VisualChildren.ForEachItem( _subscriptions.Clear();
(i, item) => nodes.Insert(i, new VisualTreeNode(item, Owner)),
(i, item) => nodes.RemoveAt(i), if (GetHostedPopupRootObservable(_control) is { } popupRootObservable)
() => nodes.Clear()); {
VisualTreeNode? childNode = null;
_subscriptions.Add(
popupRootObservable
.Subscribe(popupRoot =>
{
if (popupRoot != null)
{
childNode = new VisualTreeNode(
popupRoot.Value.Root,
Owner,
popupRoot.Value.CustomName);
nodes.Add(childNode);
}
else if (childNode != null)
{
nodes.Remove(childNode);
}
}));
}
_subscriptions.Add(
_control.VisualChildren.ForEachItem(
(i, item) => nodes.Insert(i, new VisualTreeNode(item, Owner)),
(i, item) => nodes.RemoveAt(i),
() => nodes.Clear()));
}
private struct PopupRoot
{
public PopupRoot(IControl root, string? customName = null)
{
Root = root;
CustomName = customName;
}
public IControl Root { get; }
public string? CustomName { get; }
} }
} }
} }

56
src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml

@ -5,14 +5,14 @@
<Grid Name="rootGrid" RowDefinitions="Auto,Auto,*,Auto,0,Auto"> <Grid Name="rootGrid" RowDefinitions="Auto,Auto,*,Auto,0,Auto">
<Menu> <Menu>
<MenuItem Header="_File"> <MenuItem Header="_File">
<MenuItem Header="E_xit" Command="{Binding $parent[Window].Close}"/> <MenuItem Header="E_xit" Command="{Binding $parent[Window].Close}" />
</MenuItem> </MenuItem>
<MenuItem Header="_View"> <MenuItem Header="_View">
<MenuItem Header="_Console" Command="{Binding $parent[UserControl].ToggleConsole}"> <MenuItem Header="_Console" Command="{Binding $parent[UserControl].ToggleConsole}">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox BorderThickness="0" <CheckBox BorderThickness="0"
IsChecked="{Binding Console.IsVisible}" IsChecked="{Binding Console.IsVisible}"
IsEnabled="False"/> IsEnabled="False" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
</MenuItem> </MenuItem>
@ -21,58 +21,68 @@
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox BorderThickness="0" <CheckBox BorderThickness="0"
IsChecked="{Binding ShouldVisualizeMarginPadding}" IsChecked="{Binding ShouldVisualizeMarginPadding}"
IsEnabled="False"/> IsEnabled="False" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Visualize dirty rects" Command="{Binding ToggleVisualizeDirtyRects}"> <MenuItem Header="Visualize dirty rects" Command="{Binding ToggleVisualizeDirtyRects}">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox BorderThickness="0" <CheckBox BorderThickness="0"
IsChecked="{Binding ShouldVisualizeDirtyRects}" IsChecked="{Binding ShouldVisualizeDirtyRects}"
IsEnabled="False"/> IsEnabled="False" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Show fps overlay" Command="{Binding ToggleFpsOverlay}"> <MenuItem Header="Show fps overlay" Command="{Binding ToggleFpsOverlay}">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox BorderThickness="0" <CheckBox BorderThickness="0"
IsChecked="{Binding ShowFpsOverlay}" IsChecked="{Binding ShowFpsOverlay}"
IsEnabled="False"/> IsEnabled="False" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
</MenuItem> </MenuItem>
</Menu> </Menu>
<TabStrip Grid.Row="1" SelectedIndex="{Binding SelectedTab, Mode=TwoWay}"> <TabStrip Grid.Row="1" SelectedIndex="{Binding SelectedTab, Mode=TwoWay}">
<TabStripItem Content="Logical Tree"/> <TabStripItem Content="Logical Tree" />
<TabStripItem Content="Visual Tree"/> <TabStripItem Content="Visual Tree" />
<TabStripItem Content="Events"/> <TabStripItem Content="Events" />
</TabStrip> </TabStrip>
<ContentControl Grid.Row="2" <ContentControl Grid.Row="2"
BorderBrush="{DynamicResource ThemeControlMidBrush}" BorderBrush="{DynamicResource ThemeControlMidBrush}"
BorderThickness="0,1,0,0" BorderThickness="0,1,0,0"
Content="{Binding Content}"/> Content="{Binding Content}" />
<GridSplitter Name="consoleSplitter" Grid.Row="3" Height="1" <GridSplitter Name="consoleSplitter" Grid.Row="3" Height="1"
Background="{DynamicResource ThemeControlMidBrush}" Background="{DynamicResource ThemeControlMidBrush}"
IsVisible="False"/> IsVisible="False" />
<views:ConsoleView Name="console" <views:ConsoleView Name="console"
Grid.Row="4" Grid.Row="4"
DataContext="{Binding Console}" DataContext="{Binding Console}"
IsVisible="{Binding IsVisible}"/> IsVisible="{Binding IsVisible}" />
<Border Grid.Row="5" <Border Grid.Row="5"
BorderBrush="{DynamicResource ThemeControlMidBrush}" BorderBrush="{DynamicResource ThemeControlMidBrush}"
BorderThickness="0,1,0,0"> BorderThickness="0,1,0,0">
<StackPanel Spacing="4" Orientation="Horizontal"> <Grid ColumnDefinitions="*, Auto">
<TextBlock>Hold Ctrl+Shift over a control to inspect.</TextBlock> <StackPanel Grid.Column="0" Spacing="4" Orientation="Horizontal">
<Separator Width="8"/> <TextBlock>Hold Ctrl+Shift over a control to inspect.</TextBlock>
<TextBlock>Focused:</TextBlock> <Separator Width="8" />
<TextBlock Text="{Binding FocusedControl}"/> <TextBlock>Focused:</TextBlock>
<Separator Width="8"/> <TextBlock Text="{Binding FocusedControl}" />
<TextBlock>Pointer Over:</TextBlock> <Separator Width="8" />
<TextBlock Text="{Binding PointerOverElement}"/> <TextBlock>Pointer Over:</TextBlock>
</StackPanel> <TextBlock Text="{Binding PointerOverElement}" />
</StackPanel>
<TextBlock Grid.Column="1"
Foreground="Gray"
Margin="2 0"
Text="Popups frozen"
IsVisible="{Binding FreezePopups}" />
</Grid>
</Border> </Border>
</Grid> </Grid>
</UserControl> </UserControl>

165
src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs

@ -1,8 +1,11 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Diagnostics;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Diagnostics.ViewModels; using Avalonia.Diagnostics.ViewModels;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
@ -15,6 +18,7 @@ namespace Avalonia.Diagnostics.Views
internal class MainWindow : Window, IStyleHost internal class MainWindow : Window, IStyleHost
{ {
private readonly IDisposable _keySubscription; private readonly IDisposable _keySubscription;
private readonly Dictionary<Popup, IDisposable> _frozenPopupStates;
private TopLevel? _root; private TopLevel? _root;
public MainWindow() public MainWindow()
@ -23,23 +27,26 @@ namespace Avalonia.Diagnostics.Views
_keySubscription = InputManager.Instance.Process _keySubscription = InputManager.Instance.Process
.OfType<RawKeyEventArgs>() .OfType<RawKeyEventArgs>()
.Where(x => x.Type == RawKeyEventType.KeyDown)
.Subscribe(RawKeyDown); .Subscribe(RawKeyDown);
_frozenPopupStates = new Dictionary<Popup, IDisposable>();
EventHandler? lh = default; EventHandler? lh = default;
lh = (s, e) => lh = (s, e) =>
{ {
this.Opened -= lh; this.Opened -= lh;
if ((DataContext as MainViewModel)?.StartupScreenIndex is int index) if ((DataContext as MainViewModel)?.StartupScreenIndex is { } index)
{ {
var screens = this.Screens; var screens = this.Screens;
if (index > -1 && index < screens.ScreenCount) if (index > -1 && index < screens.ScreenCount)
{ {
var screen = screens.All[index]; var screen = screens.All[index];
this.Position = screen.Bounds.TopLeft; this.Position = screen.Bounds.TopLeft;
this.WindowState = WindowState.Maximized; this.WindowState = WindowState.Maximized;
} }
} }
}; };
this.Opened += lh; this.Opened += lh;
} }
@ -77,6 +84,13 @@ namespace Avalonia.Diagnostics.Views
base.OnClosed(e); base.OnClosed(e);
_keySubscription.Dispose(); _keySubscription.Dispose();
foreach (var state in _frozenPopupStates)
{
state.Value.Dispose();
}
_frozenPopupStates.Clear();
if (_root != null) if (_root != null)
{ {
_root.Closed -= RootClosed; _root.Closed -= RootClosed;
@ -91,6 +105,53 @@ namespace Avalonia.Diagnostics.Views
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
private IControl? GetHoveredControl(TopLevel topLevel)
{
#pragma warning disable CS0618 // Type or member is obsolete
var point = (topLevel as IInputRoot)?.MouseDevice?.GetPosition(topLevel) ?? default;
#pragma warning restore CS0618 // Type or member is obsolete
return (IControl?)topLevel.GetVisualsAt(point, x =>
{
if (x is AdornerLayer || !x.IsVisible)
{
return false;
}
return !(x is IInputElement ie) || ie.IsHitTestVisible;
})
.FirstOrDefault();
}
private static List<PopupRoot> GetPopupRoots(IVisual root)
{
var popupRoots = new List<PopupRoot>();
void ProcessProperty<T>(IControl control, AvaloniaProperty<T> property)
{
if (control.GetValue(property) is IPopupHostProvider popupProvider
&& popupProvider.PopupHost is PopupRoot popupRoot)
{
popupRoots.Add(popupRoot);
}
}
foreach (var control in root.GetVisualDescendants().OfType<IControl>())
{
if (control is Popup p && p.Host is PopupRoot popupRoot)
{
popupRoots.Add(popupRoot);
}
ProcessProperty(control, ContextFlyoutProperty);
ProcessProperty(control, ContextMenuProperty);
ProcessProperty(control, FlyoutBase.AttachedFlyoutProperty);
ProcessProperty(control, ToolTipDiagnostics.ToolTipProperty);
}
return popupRoots;
}
private void RawKeyDown(RawKeyEventArgs e) private void RawKeyDown(RawKeyEventArgs e)
{ {
var vm = (MainViewModel?)DataContext; var vm = (MainViewModel?)DataContext;
@ -99,34 +160,72 @@ namespace Avalonia.Diagnostics.Views
return; return;
} }
const RawInputModifiers modifiers = RawInputModifiers.Control | RawInputModifiers.Shift; switch (e.Modifiers)
if (e.Modifiers == modifiers)
{ {
#pragma warning disable CS0618 // Type or member is obsolete case RawInputModifiers.Control | RawInputModifiers.Shift:
var point = (Root as IInputRoot)?.MouseDevice?.GetPosition(Root) ?? default; {
#pragma warning restore CS0618 // Type or member is obsolete IControl? control = null;
foreach (var popupRoot in GetPopupRoots(Root))
{
control = GetHoveredControl(popupRoot);
if (control != null)
{
break;
}
}
control ??= GetHoveredControl(Root);
var control = Root.GetVisualsAt(point, x => if (control != null)
{ {
if (x is AdornerLayer || !x.IsVisible) return false; vm.SelectControl(control);
if (!(x is IInputElement ie)) return true; }
return ie.IsHitTestVisible;
}) break;
.FirstOrDefault(); }
if (control != null) case RawInputModifiers.Control | RawInputModifiers.Alt when e.Key == Key.F:
{ {
vm.SelectControl((IControl)control); vm.FreezePopups = !vm.FreezePopups;
foreach (var popupRoot in GetPopupRoots(Root))
{
if (popupRoot.Parent is Popup popup)
{
if (vm.FreezePopups)
{
var lightDismissEnabledState = popup.SetValue(
Popup.IsLightDismissEnabledProperty,
!vm.FreezePopups,
BindingPriority.Animation);
if (lightDismissEnabledState != null)
{
_frozenPopupStates[popup] = lightDismissEnabledState;
}
}
else
{
//TODO Use Dictionary.Remove(Key, out Value) in netstandard 2.1
if (_frozenPopupStates.ContainsKey(popup))
{
_frozenPopupStates[popup].Dispose();
_frozenPopupStates.Remove(popup);
}
}
}
}
break;
} }
}
else if (e.Modifiers == RawInputModifiers.Alt) case RawInputModifiers.Alt when e.Key == Key.S || e.Key == Key.D:
{
if (e.Key == Key.S || e.Key == Key.D)
{ {
var enable = e.Key == Key.S; vm.EnableSnapshotStyles(e.Key == Key.S);
vm.EnableSnapshotStyles(enable); break;
} }
} }
} }

2
src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml

@ -11,7 +11,7 @@
<TreeDataTemplate DataType="vm:TreeNode" <TreeDataTemplate DataType="vm:TreeNode"
ItemsSource="{Binding Children}"> ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Spacing="8"> <StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock Text="{Binding Type}"/> <TextBlock Text="{Binding Type}" FontWeight="{Binding FontWeight}"/>
<TextBlock Text="{Binding Classes}"/> <TextBlock Text="{Binding Classes}"/>
<TextBlock Foreground="Gray" Text="{Binding ElementName}"/> <TextBlock Foreground="Gray" Text="{Binding ElementName}"/>
</StackPanel> </StackPanel>

8
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -109,11 +109,17 @@ namespace Avalonia.Native
.Bind<IRenderLoop>().ToConstant(new RenderLoop()) .Bind<IRenderLoop>().ToConstant(new RenderLoop())
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60)) .Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs())) .Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs()))
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Meta)) .Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Meta, wholeWordTextActionModifiers: KeyModifiers.Alt))
.Bind<IMountedVolumeInfoProvider>().ToConstant(new MacOSMountedVolumeInfoProvider()) .Bind<IMountedVolumeInfoProvider>().ToConstant(new MacOSMountedVolumeInfoProvider())
.Bind<IPlatformDragSource>().ToConstant(new AvaloniaNativeDragSource(_factory)) .Bind<IPlatformDragSource>().ToConstant(new AvaloniaNativeDragSource(_factory))
.Bind<IPlatformLifetimeEventsImpl>().ToConstant(applicationPlatform); .Bind<IPlatformLifetimeEventsImpl>().ToConstant(applicationPlatform);
var hotkeys = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
hotkeys.MoveCursorToTheStartOfLine.Add(new KeyGesture(Key.Left, hotkeys.CommandModifiers));
hotkeys.MoveCursorToTheStartOfLineWithSelection.Add(new KeyGesture(Key.Left, hotkeys.CommandModifiers | hotkeys.SelectionModifiers));
hotkeys.MoveCursorToTheEndOfLine.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers));
hotkeys.MoveCursorToTheEndOfLineWithSelection.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers | hotkeys.SelectionModifiers));
if (_options.UseGpu) if (_options.UseGpu)
{ {
try try

1
src/Avalonia.Themes.Default/AutoCompleteBox.xaml

@ -11,6 +11,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Watermark="{TemplateBinding Watermark}" Watermark="{TemplateBinding Watermark}"
DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}" /> DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}" />

3
src/Avalonia.Themes.Default/Button.xaml

@ -13,6 +13,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -31,4 +32,4 @@
<Style Selector="Button:disabled"> <Style Selector="Button:disabled">
<Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/> <Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/>
</Style> </Style>
</Styles> </Styles>

2
src/Avalonia.Themes.Default/ButtonSpinner.xaml

@ -47,6 +47,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"> VerticalAlignment="{TemplateBinding VerticalAlignment}">
@ -73,6 +74,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"> VerticalAlignment="{TemplateBinding VerticalAlignment}">

3
src/Avalonia.Themes.Default/Calendar.xaml

@ -22,10 +22,11 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
HeaderBackground="{TemplateBinding HeaderBackground}"/> HeaderBackground="{TemplateBinding HeaderBackground}"/>
</StackPanel> </StackPanel>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
</Styles> </Styles>

3
src/Avalonia.Themes.Default/CalendarDatePicker.xaml

@ -88,7 +88,8 @@
<TextBox Name="PART_TextBox" <TextBox Name="PART_TextBox"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Watermark="{TemplateBinding Watermark}" Watermark="{TemplateBinding Watermark}"
UseFloatingWatermark="{TemplateBinding UseFloatingWatermark}" UseFloatingWatermark="{TemplateBinding UseFloatingWatermark}"

5
src/Avalonia.Themes.Default/CalendarItem.xaml

@ -8,14 +8,15 @@
<Styles xmlns="https://github.com/avaloniaui" <Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="CalendarItem"> <Style Selector="CalendarItem">
<Setter Property="CornerRadius" Value="1" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Panel> <Panel>
<Border BorderThickness="{TemplateBinding BorderThickness}" <Border BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
Margin="0,2,0,2" Margin="0,2,0,2">
CornerRadius="1">
<Border CornerRadius="1" <Border CornerRadius="1"
BorderBrush="{DynamicResource ThemeBackgroundBrush}" BorderBrush="{DynamicResource ThemeBackgroundBrush}"

3
src/Avalonia.Themes.Default/Carousel.xaml

@ -3,7 +3,8 @@
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<CarouselPresenter IsVirtualized="{TemplateBinding IsVirtualized}" <CarouselPresenter IsVirtualized="{TemplateBinding IsVirtualized}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}" ItemsPanel="{TemplateBinding ItemsPanel}"

1
src/Avalonia.Themes.Default/CheckBox.xaml

@ -14,6 +14,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Width="18" Width="18"
Height="18" Height="18"
VerticalAlignment="Center"> VerticalAlignment="Center">

3
src/Avalonia.Themes.Default/ComboBox.xaml

@ -32,7 +32,8 @@
<Border Name="border" <Border Name="border"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid ColumnDefinitions="*,Auto"> <Grid ColumnDefinitions="*,Auto">
<TextBlock Name="PlaceholderTextBlock" <TextBlock Name="PlaceholderTextBlock"
Grid.Column="0" Grid.Column="0"

1
src/Avalonia.Themes.Default/ComboBoxItem.xaml

@ -10,6 +10,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"

3
src/Avalonia.Themes.Default/ContentControl.xaml

@ -5,6 +5,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -12,4 +13,4 @@
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"/> HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>

1
src/Avalonia.Themes.Default/ContextMenu.xaml

@ -9,6 +9,7 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}"> Padding="{TemplateBinding Padding}">
<ScrollViewer Classes="menuscroller"> <ScrollViewer Classes="menuscroller">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"

1
src/Avalonia.Themes.Default/DataValidationErrors.xaml

@ -12,6 +12,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"/> Padding="{TemplateBinding Padding}"/>

3
src/Avalonia.Themes.Default/DatePicker.xaml

@ -134,6 +134,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
IsEnabled="{TemplateBinding IsEnabled}" IsEnabled="{TemplateBinding IsEnabled}"
MinWidth="{DynamicResource DatePickerThemeMinWidth}" MinWidth="{DynamicResource DatePickerThemeMinWidth}"
MaxWidth="{DynamicResource DatePickerThemeMaxWidth}" MaxWidth="{DynamicResource DatePickerThemeMaxWidth}"
@ -148,6 +149,7 @@
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
TextBlock.Foreground="{TemplateBinding Foreground}" TextBlock.Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
@ -242,6 +244,7 @@
<Border Name="Background" Background="{TemplateBinding Background}" <Border Name="Background" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{DynamicResource DateTimeFlyoutBorderPadding}" Padding="{DynamicResource DateTimeFlyoutBorderPadding}"
MaxHeight="398"> MaxHeight="398">
<Grid Name="ContentRoot" RowDefinitions="*,Auto"> <Grid Name="ContentRoot" RowDefinitions="*,Auto">

5
src/Avalonia.Themes.Default/Expander.xaml

@ -10,7 +10,10 @@
<Style Selector="Expander[ExpandDirection=Down]"> <Style Selector="Expander[ExpandDirection=Down]">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}"> <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<ToggleButton Name="PART_toggle" Grid.Row="0" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" /> <ToggleButton Name="PART_toggle" Grid.Row="0" Content="{TemplateBinding Header}" IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"

1
src/Avalonia.Themes.Default/GridSplitter.xaml

@ -15,6 +15,7 @@
<Border <Border
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}"/> Background="{TemplateBinding Background}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

1
src/Avalonia.Themes.Default/ItemsControl.xaml

@ -4,6 +4,7 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}"> Padding="{TemplateBinding Padding}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"

1
src/Avalonia.Themes.Default/Label.xaml

@ -6,6 +6,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"

3
src/Avalonia.Themes.Default/ListBox.xaml

@ -9,7 +9,8 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Name="border" BorderBrush="{TemplateBinding BorderBrush}" <Border Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer Name="PART_ScrollViewer" <ScrollViewer Name="PART_ScrollViewer"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"

1
src/Avalonia.Themes.Default/ListBoxItem.xaml

@ -10,6 +10,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"

3
src/Avalonia.Themes.Default/Menu.xaml

@ -4,6 +4,7 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}"> Padding="{TemplateBinding Padding}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
@ -13,4 +14,4 @@
</Border> </Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>

6
src/Avalonia.Themes.Default/MenuItem.xaml

@ -14,7 +14,8 @@
<Border Name="root" <Border Name="root"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/> <ColumnDefinition Width="20"/>
@ -96,7 +97,8 @@
<Border Name="root" <Border Name="root"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Panel> <Panel>
<ContentPresenter Name="PART_HeaderPresenter" <ContentPresenter Name="PART_HeaderPresenter"
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"

1
src/Avalonia.Themes.Default/NotificationCard.xaml

@ -12,6 +12,7 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="8,8,0,0"> Margin="8,8,0,0">
<ContentControl Name="PART_Content" Content="{TemplateBinding Content}" /> <ContentControl Name="PART_Content" Content="{TemplateBinding Content}" />
</Border> </Border>

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

@ -9,6 +9,7 @@
<ButtonSpinner Name="PART_Spinner" <ButtonSpinner Name="PART_Spinner"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
@ -18,7 +19,6 @@
<TextBox Name="PART_TextBox" <TextBox Name="PART_TextBox"
BorderThickness="0" BorderThickness="0"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Watermark="{TemplateBinding Watermark}" Watermark="{TemplateBinding Watermark}"
DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}" DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}"

2
src/Avalonia.Themes.Default/ProgressBar.xaml

@ -16,7 +16,7 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid> <Grid>
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}">
<Panel> <Panel>
<Border Name="PART_Indicator" Background="{TemplateBinding Foreground}" IsVisible="{Binding !IsIndeterminate, RelativeSource={RelativeSource TemplatedParent}}"/> <Border Name="PART_Indicator" Background="{TemplateBinding Foreground}" IsVisible="{Binding !IsIndeterminate, RelativeSource={RelativeSource TemplatedParent}}"/>
<Border Name="PART_IndeterminateIndicator" Background="{TemplateBinding Foreground}" IsVisible="{Binding IsIndeterminate, RelativeSource={RelativeSource TemplatedParent}}"/> <Border Name="PART_IndeterminateIndicator" Background="{TemplateBinding Foreground}" IsVisible="{Binding IsIndeterminate, RelativeSource={RelativeSource TemplatedParent}}"/>

1
src/Avalonia.Themes.Default/RepeatButton.xaml

@ -20,6 +20,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"

1
src/Avalonia.Themes.Default/Separator.xaml

@ -6,6 +6,7 @@
<ControlTemplate> <ControlTemplate>
<Border BorderBrush="{TemplateBinding BorderBrush}" <Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}"/> Background="{TemplateBinding Background}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

2
src/Avalonia.Themes.Default/TabControl.xaml

@ -3,9 +3,9 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border <Border
Margin="{TemplateBinding Margin}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"> VerticalAlignment="{TemplateBinding VerticalAlignment}">

2
src/Avalonia.Themes.Default/TabItem.xaml

@ -12,11 +12,11 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplate="{TemplateBinding HeaderTemplate}"
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Margin}"
Padding="{TemplateBinding Padding}"/> Padding="{TemplateBinding Padding}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

3
src/Avalonia.Themes.Default/TabStripItem.xaml

@ -9,6 +9,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -20,4 +21,4 @@
<Style Selector="TabStripItem:selected"> <Style Selector="TabStripItem:selected">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/> <Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}"/>
</Style> </Style>
</Styles> </Styles>

3
src/Avalonia.Themes.Default/TextBox.xaml

@ -30,7 +30,8 @@
<Border Name="border" <Border Name="border"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<DockPanel Margin="{TemplateBinding Padding}" <DockPanel Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> VerticalAlignment="{TemplateBinding VerticalContentAlignment}">

3
src/Avalonia.Themes.Default/TimePicker.xaml

@ -58,6 +58,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
IsEnabled="{TemplateBinding IsEnabled}" IsEnabled="{TemplateBinding IsEnabled}"
MinWidth="{DynamicResource TimePickerThemeMinWidth}" MinWidth="{DynamicResource TimePickerThemeMinWidth}"
MaxWidth="{DynamicResource TimePickerThemeMaxWidth}" MaxWidth="{DynamicResource TimePickerThemeMaxWidth}"
@ -71,6 +72,7 @@
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
TextBlock.Foreground="{TemplateBinding Foreground}" TextBlock.Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
@ -178,6 +180,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{DynamicResource DateTimeFlyoutBorderPadding}" Padding="{DynamicResource DateTimeFlyoutBorderPadding}"
MaxHeight="398"> MaxHeight="398">
<Grid Name="ContentPanel" RowDefinitions="*,Auto"> <Grid Name="ContentPanel" RowDefinitions="*,Auto">

3
src/Avalonia.Themes.Default/ToggleButton.xaml

@ -13,6 +13,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -35,4 +36,4 @@
<Style Selector="ToggleButton:disabled"> <Style Selector="ToggleButton:disabled">
<Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/> <Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/>
</Style> </Style>
</Styles> </Styles>

3
src/Avalonia.Themes.Default/ToolTip.xaml

@ -9,9 +9,10 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"/> Padding="{TemplateBinding Padding}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>

3
src/Avalonia.Themes.Default/TreeView.xaml

@ -8,7 +8,8 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border BorderBrush="{TemplateBinding BorderBrush}" <Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer Background="{TemplateBinding Background}" <ScrollViewer Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"

1
src/Avalonia.Themes.Default/TreeViewItem.xaml

@ -15,6 +15,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
TemplatedControl.IsTemplateFocusTarget="True"> TemplatedControl.IsTemplateFocusTarget="True">
<Grid Name="PART_Header" <Grid Name="PART_Header"
ColumnDefinitions="16, *" ColumnDefinitions="16, *"

1
src/Avalonia.Themes.Default/UserControl.xaml

@ -5,6 +5,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"

4
src/Avalonia.Themes.Fluent/Controls/AutoCompleteBox.xaml

@ -22,7 +22,8 @@
<Setter Property="Foreground" Value="{DynamicResource TextControlForeground}" /> <Setter Property="Foreground" Value="{DynamicResource TextControlForeground}" />
<Setter Property="Background" Value="{DynamicResource TextControlBackground}" /> <Setter Property="Background" Value="{DynamicResource TextControlBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource TextControlBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource TextControlBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource TextControlBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource TextControlBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="Padding" Value="{DynamicResource TextControlThemePadding}" /> <Setter Property="Padding" Value="{DynamicResource TextControlThemePadding}" />
<Setter Property="MaxDropDownHeight" Value="{DynamicResource AutoCompleteListMaxHeight}" /> <Setter Property="MaxDropDownHeight" Value="{DynamicResource AutoCompleteListMaxHeight}" />
@ -36,6 +37,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
FontFamily="{TemplateBinding FontFamily}" FontFamily="{TemplateBinding FontFamily}"
FontWeight="{TemplateBinding FontWeight}" FontWeight="{TemplateBinding FontWeight}"

6
src/Avalonia.Themes.Fluent/Controls/Button.xaml

@ -16,6 +16,7 @@
<Setter Property="Foreground" Value="{DynamicResource ButtonForeground}" /> <Setter Property="Foreground" Value="{DynamicResource ButtonForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource ButtonBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource ButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource ButtonBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource ButtonBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Padding" Value="{DynamicResource ButtonPadding}" /> <Setter Property="Padding" Value="{DynamicResource ButtonPadding}" />
<Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
@ -29,6 +30,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -93,8 +95,4 @@
<Setter Property="BorderBrush" Value="{DynamicResource AccentButtonBorderBrushDisabled}" /> <Setter Property="BorderBrush" Value="{DynamicResource AccentButtonBorderBrushDisabled}" />
<Setter Property="TextBlock.Foreground" Value="{DynamicResource AccentButtonForegroundDisabled}" /> <Setter Property="TextBlock.Foreground" Value="{DynamicResource AccentButtonForegroundDisabled}" />
</Style> </Style>
<Style Selector="Button /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
</Style>
</Styles> </Styles>

3
src/Avalonia.Themes.Fluent/Controls/ButtonSpinner.xaml

@ -58,6 +58,7 @@
<Setter Property="Background" Value="{DynamicResource TextControlBackground}" /> <Setter Property="Background" Value="{DynamicResource TextControlBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource TextControlBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource TextControlBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource TextControlBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource TextControlBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="MinHeight" Value="{DynamicResource TextControlThemeMinHeight}" /> <Setter Property="MinHeight" Value="{DynamicResource TextControlThemeMinHeight}" />
<Setter Property="MinWidth" Value="{DynamicResource TextControlThemeMinWidth}" /> <Setter Property="MinWidth" Value="{DynamicResource TextControlThemeMinWidth}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
@ -69,7 +70,7 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{DynamicResource ControlCornerRadius}" CornerRadius="{TemplateBinding CornerRadius}"
MinHeight="{TemplateBinding MinHeight}"> MinHeight="{TemplateBinding MinHeight}">
<Grid ColumnDefinitions="Auto,*,Auto"> <Grid ColumnDefinitions="Auto,*,Auto">
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"

10
src/Avalonia.Themes.Fluent/Controls/Calendar.xaml

@ -5,7 +5,12 @@
// All other rights reserved. // All other rights reserved.
--> -->
<Styles xmlns="https://github.com/avaloniaui"> <Styles xmlns="https://github.com/avaloniaui">
<Design.PreviewWith>
<Border Padding="20">
<Calendar />
</Border>
</Design.PreviewWith>
<Style Selector="Calendar"> <Style Selector="Calendar">
<Setter Property="Foreground" Value="{DynamicResource CalendarViewForeground}" /> <Setter Property="Foreground" Value="{DynamicResource CalendarViewForeground}" />
<Setter Property="Background" Value="{DynamicResource CalendarViewBackground}" /> <Setter Property="Background" Value="{DynamicResource CalendarViewBackground}" />
@ -23,7 +28,8 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
HeaderBackground="{TemplateBinding HeaderBackground}"/> HeaderBackground="{TemplateBinding HeaderBackground}"
CornerRadius="{TemplateBinding CornerRadius}"/>
</StackPanel> </StackPanel>
</ControlTemplate> </ControlTemplate>

2
src/Avalonia.Themes.Fluent/Controls/CalendarDatePicker.xaml

@ -26,6 +26,7 @@
<Setter Property="Foreground" Value="{DynamicResource CalendarDatePickerForeground}"/> <Setter Property="Foreground" Value="{DynamicResource CalendarDatePickerForeground}"/>
<Setter Property="BorderBrush" Value="{DynamicResource CalendarDatePickerBorderBrush}"/> <Setter Property="BorderBrush" Value="{DynamicResource CalendarDatePickerBorderBrush}"/>
<Setter Property="BorderThickness" Value="{DynamicResource CalendarDatePickerBorderThemeThickness}"/> <Setter Property="BorderThickness" Value="{DynamicResource CalendarDatePickerBorderThemeThickness}"/>
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Padding" Value="4"/> <Setter Property="Padding" Value="4"/>
@ -102,6 +103,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Watermark="{TemplateBinding Watermark}" Watermark="{TemplateBinding Watermark}"
UseFloatingWatermark="{TemplateBinding UseFloatingWatermark}" UseFloatingWatermark="{TemplateBinding UseFloatingWatermark}"

8
src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml

@ -7,7 +7,13 @@
<Styles xmlns="https://github.com/avaloniaui" <Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith>
<Border Padding="20">
<Calendar />
</Border>
</Design.PreviewWith>
<Style Selector="CalendarItem"> <Style Selector="CalendarItem">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="DayTitleTemplate"> <Setter Property="DayTitleTemplate">
<Template> <Template>
<TextBlock Text="{Binding}" <TextBlock Text="{Binding}"
@ -21,7 +27,7 @@
<Border BorderThickness="{TemplateBinding BorderThickness}" <Border BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{DynamicResource ControlCornerRadius}"> CornerRadius="{TemplateBinding CornerRadius}">
<Border.Styles> <Border.Styles>
<Style Selector="Button.CalendarHeader"> <Style Selector="Button.CalendarHeader">
<Setter Property="HorizontalAlignment" Value="Stretch" /> <Setter Property="HorizontalAlignment" Value="Stretch" />

3
src/Avalonia.Themes.Fluent/Controls/Carousel.xaml

@ -3,7 +3,8 @@
<ControlTemplate> <ControlTemplate>
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<CarouselPresenter IsVirtualized="{TemplateBinding IsVirtualized}" <CarouselPresenter IsVirtualized="{TemplateBinding IsVirtualized}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}" ItemsPanel="{TemplateBinding ItemsPanel}"

13
src/Avalonia.Themes.Fluent/Controls/CheckBox.xaml

@ -11,6 +11,7 @@
<Setter Property="HorizontalContentAlignment" Value="Left" /> <Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="MinHeight" Value="32" /> <Setter Property="MinHeight" Value="32" />
<!--<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" /> <!--<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />--> <Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />-->
@ -21,11 +22,13 @@
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" /> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}" />
<Grid VerticalAlignment="Top" Height="32"> <Grid VerticalAlignment="Top" Height="32">
<Border x:Name="NormalRectangle" <Border x:Name="NormalRectangle"
BorderThickness="{DynamicResource CheckBoxBorderThemeThickness}" BorderThickness="{DynamicResource CheckBoxBorderThemeThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
UseLayoutRounding="False" UseLayoutRounding="False"
Height="20" Height="20"
Width="20" /> Width="20" />
@ -49,14 +52,6 @@
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
<Style Selector="CheckBox /template/ Border#PART_Border">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
</Style>
<Style Selector="CheckBox /template/ Border#NormalRectangle">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
</Style>
<!-- Unchecked Normal State --> <!-- Unchecked Normal State -->
<Style Selector="CheckBox"> <Style Selector="CheckBox">

13
src/Avalonia.Themes.Fluent/Controls/ComboBox.xaml

@ -34,6 +34,7 @@
<Setter Property="Background" Value="{DynamicResource ComboBoxBackground}" /> <Setter Property="Background" Value="{DynamicResource ComboBoxBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource ComboBoxBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource ComboBoxBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource ComboBoxBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource ComboBoxBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" /> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" /> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="HorizontalContentAlignment" Value="Stretch" />
@ -62,6 +63,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
MinWidth="{DynamicResource ComboBoxThemeMinWidth}" /> MinWidth="{DynamicResource ComboBoxThemeMinWidth}" />
<Border x:Name="HighlightBackground" <Border x:Name="HighlightBackground"
@ -70,7 +72,8 @@
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Background="{DynamicResource ComboBoxBackgroundUnfocused}" Background="{DynamicResource ComboBoxBackgroundUnfocused}"
BorderBrush="{DynamicResource ComboBoxBackgroundBorderBrushUnfocused}" BorderBrush="{DynamicResource ComboBoxBackgroundBorderBrushUnfocused}"
BorderThickness="{TemplateBinding BorderThickness}" /> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}" />
<TextBlock x:Name="PlaceholderTextBlock" <TextBlock x:Name="PlaceholderTextBlock"
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
@ -227,14 +230,6 @@
<Setter Property="Fill" Value="{DynamicResource ComboBoxDropDownGlyphForegroundFocusedPressed}" /> <Setter Property="Fill" Value="{DynamicResource ComboBoxDropDownGlyphForegroundFocusedPressed}" />
</Style> </Style>
<Style Selector="ComboBox /template/ Border#Background">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
</Style>
<Style Selector="ComboBox /template/ Border#HighlightBackground">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
</Style>
<!-- Error State --> <!-- Error State -->
<Style Selector="ComboBox:error /template/ Border#Background"> <Style Selector="ComboBox:error /template/ Border#Background">
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlErrorTextForegroundBrush}"/> <Setter Property="BorderBrush" Value="{DynamicResource SystemControlErrorTextForegroundBrush}"/>

1
src/Avalonia.Themes.Fluent/Controls/ComboBoxItem.xaml

@ -29,6 +29,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"

3
src/Avalonia.Themes.Fluent/Controls/ContentControl.xaml

@ -5,6 +5,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -12,4 +13,4 @@
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"/> HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>

3
src/Avalonia.Themes.Fluent/Controls/ContextMenu.xaml

@ -39,6 +39,7 @@
<Setter Property="Background" Value="{DynamicResource MenuFlyoutPresenterBackground}" /> <Setter Property="Background" Value="{DynamicResource MenuFlyoutPresenterBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource OverlayCornerRadius}" />
<Setter Property="MaxWidth" Value="{DynamicResource FlyoutThemeMaxWidth}" /> <Setter Property="MaxWidth" Value="{DynamicResource FlyoutThemeMaxWidth}" />
<Setter Property="MinHeight" Value="{DynamicResource MenuFlyoutThemeMinHeight}" /> <Setter Property="MinHeight" Value="{DynamicResource MenuFlyoutThemeMinHeight}" />
<Setter Property="Padding" Value="{DynamicResource MenuFlyoutPresenterThemePadding}" /> <Setter Property="Padding" Value="{DynamicResource MenuFlyoutPresenterThemePadding}" />
@ -55,7 +56,7 @@
MaxWidth="{TemplateBinding MaxWidth}" MaxWidth="{TemplateBinding MaxWidth}"
MinHeight="{TemplateBinding MinHeight}" MinHeight="{TemplateBinding MinHeight}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
CornerRadius="{DynamicResource OverlayCornerRadius}"> CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer Classes="menuscroller"> <ScrollViewer Classes="menuscroller">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"

2
src/Avalonia.Themes.Fluent/Controls/DataValidationErrors.xaml

@ -48,6 +48,7 @@
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" /> ContentTemplate="{TemplateBinding ContentTemplate}" />
</DockPanel> </DockPanel>
@ -88,6 +89,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" /> ContentTemplate="{TemplateBinding ContentTemplate}" />
</DockPanel> </DockPanel>

16
src/Avalonia.Themes.Fluent/Controls/DatePicker.xaml

@ -8,6 +8,12 @@
<Styles xmlns="https://github.com/avaloniaui" <Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"> xmlns:sys="clr-namespace:System;assembly=netstandard">
<Design.PreviewWith>
<Border Padding="20">
<DatePicker CornerRadius="10" />
</Border>
</Design.PreviewWith>
<Styles.Resources> <Styles.Resources>
<Thickness x:Key="DatePickerTopHeaderMargin">0,0,0,4</Thickness> <Thickness x:Key="DatePickerTopHeaderMargin">0,0,0,4</Thickness>
<x:Double x:Key="DatePickerFlyoutPresenterHighlightHeight">40</x:Double> <x:Double x:Key="DatePickerFlyoutPresenterHighlightHeight">40</x:Double>
@ -50,6 +56,7 @@
<Setter Property="Background" Value="{DynamicResource DateTimePickerFlyoutButtonBackground}" /> <Setter Property="Background" Value="{DynamicResource DateTimePickerFlyoutButtonBackground}" />
<Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<!-- <!--
@ -67,7 +74,7 @@
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
CornerRadius="{DynamicResource ControlCornerRadius}"/> CornerRadius="{TemplateBinding CornerRadius}"/>
</Border> </Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
@ -121,6 +128,7 @@
<Setter Property="Background" Value="{DynamicResource DatePickerButtonBackground}"/> <Setter Property="Background" Value="{DynamicResource DatePickerButtonBackground}"/>
<Setter Property="BorderBrush" Value="{DynamicResource DatePickerButtonBorderBrush}"/> <Setter Property="BorderBrush" Value="{DynamicResource DatePickerButtonBorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template"> <Setter Property="Template">
@ -140,6 +148,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
IsEnabled="{TemplateBinding IsEnabled}" IsEnabled="{TemplateBinding IsEnabled}"
MinWidth="{DynamicResource DatePickerThemeMinWidth}" MinWidth="{DynamicResource DatePickerThemeMinWidth}"
MaxWidth="{DynamicResource DatePickerThemeMaxWidth}" MaxWidth="{DynamicResource DatePickerThemeMaxWidth}"
@ -158,7 +167,7 @@
TextBlock.Foreground="{TemplateBinding Foreground}" TextBlock.Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
CornerRadius="{DynamicResource ControlCornerRadius}"/> CornerRadius="{TemplateBinding CornerRadius}"/>
</ControlTemplate> </ControlTemplate>
</Button.Template> </Button.Template>
<Grid Name="ButtonContentGrid" ColumnDefinitions="78*,Auto,132*,Auto,78*"> <Grid Name="ButtonContentGrid" ColumnDefinitions="78*,Auto,132*,Auto,78*">
@ -246,13 +255,14 @@
<Setter Property="Background" Value="{DynamicResource DatePickerFlyoutPresenterBackground}" /> <Setter Property="Background" Value="{DynamicResource DatePickerFlyoutPresenterBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource DatePickerFlyoutPresenterBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource DatePickerFlyoutPresenterBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource DateTimeFlyoutBorderThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource DateTimeFlyoutBorderThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource OverlayCornerRadius}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Name="Background" Background="{TemplateBinding Background}" <Border Name="Background" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
Padding="{DynamicResource DateTimeFlyoutBorderPadding}" Padding="{DynamicResource DateTimeFlyoutBorderPadding}"
MaxHeight="398" CornerRadius="{DynamicResource OverlayCornerRadius}"> MaxHeight="398" CornerRadius="{TemplateBinding CornerRadius}">
<Grid Name="ContentRoot" RowDefinitions="*,Auto"> <Grid Name="ContentRoot" RowDefinitions="*,Auto">
<Grid Name="PickerContainer"> <Grid Name="PickerContainer">
<!--Column Definitions set in code, ignore here--> <!--Column Definitions set in code, ignore here-->

29
src/Avalonia.Themes.Fluent/Controls/Expander.xaml

@ -1,23 +1,23 @@
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith> <Design.PreviewWith>
<Border Padding="20"> <Border Padding="20">
<StackPanel Orientation="Vertical" Spacing="20"> <StackPanel Orientation="Vertical" Spacing="20" Width="350">
<Expander ExpandDirection="Up" Header="Expand Up"> <Expander ExpandDirection="Up" Header="Expand Up" CornerRadius="25">
<StackPanel> <StackPanel>
<TextBlock>Expanded content</TextBlock> <TextBlock>Expanded content</TextBlock>
</StackPanel> </StackPanel>
</Expander> </Expander>
<Expander ExpandDirection="Down" Header="Expand Down"> <Expander ExpandDirection="Down" Header="Expand Down" CornerRadius="25">
<StackPanel> <StackPanel>
<TextBlock>Expanded content</TextBlock> <TextBlock>Expanded content</TextBlock>
</StackPanel> </StackPanel>
</Expander> </Expander>
<Expander ExpandDirection="Left" Header="Expand Left"> <Expander ExpandDirection="Left" Header="Expand Left" CornerRadius="25">
<StackPanel> <StackPanel>
<TextBlock>Expanded content</TextBlock> <TextBlock>Expanded content</TextBlock>
</StackPanel> </StackPanel>
</Expander> </Expander>
<Expander ExpandDirection="Right" Header="Expand Right"> <Expander ExpandDirection="Right" Header="Expand Right" CornerRadius="25">
<StackPanel> <StackPanel>
<TextBlock>Expanded content</TextBlock> <TextBlock>Expanded content</TextBlock>
</StackPanel> </StackPanel>
@ -51,6 +51,7 @@
<Setter Property="Background" Value="{DynamicResource ExpanderBackground}" /> <Setter Property="Background" Value="{DynamicResource ExpanderBackground}" />
<Setter Property="BorderThickness" Value="{DynamicResource ExpanderBorderThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource ExpanderBorderThickness}" />
<Setter Property="BorderBrush" Value="{DynamicResource ExpanderBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource ExpanderBorderBrush}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Padding" Value="{DynamicResource ExpanderHeaderPadding}" /> <Setter Property="Padding" Value="{DynamicResource ExpanderHeaderPadding}" />
<Setter Property="HorizontalAlignment" Value="Stretch" /> <Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Left" /> <Setter Property="HorizontalContentAlignment" Value="Left" />
@ -140,31 +141,31 @@
</Style> </Style>
<Style Selector="Expander:not(:expanded) /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground"> <Style Selector="Expander:not(:expanded) /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius}" />
</Style> </Style>
<Style Selector="Expander:expanded:up /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground"> <Style Selector="Expander:expanded:up /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource BottomCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource BottomCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:expanded:up /template/ Border#ExpanderContent"> <Style Selector="Expander:expanded:up /template/ Border#ExpanderContent">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource TopCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:expanded:down /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground"> <Style Selector="Expander:expanded:down /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource TopCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:expanded:down /template/ Border#ExpanderContent"> <Style Selector="Expander:expanded:down /template/ Border#ExpanderContent">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource BottomCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource BottomCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:expanded:left /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground"> <Style Selector="Expander:expanded:left /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource RightCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource RightCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:expanded:left /template/ Border#ExpanderContent"> <Style Selector="Expander:expanded:left /template/ Border#ExpanderContent">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource LeftCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource LeftCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:expanded:right /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground"> <Style Selector="Expander:expanded:right /template/ ToggleButton#ExpanderHeader /template/ Border#ToggleButtonBackground">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource LeftCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource LeftCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:expanded:right /template/ Border#ExpanderContent"> <Style Selector="Expander:expanded:right /template/ Border#ExpanderContent">
<Setter Property="CornerRadius" Value="{Binding Source={StaticResource ControlCornerRadius}, Converter={StaticResource RightCornerRadiusFilterConverter}}" /> <Setter Property="CornerRadius" Value="{Binding $parent[Expander].CornerRadius, Converter={StaticResource RightCornerRadiusFilterConverter}}" />
</Style> </Style>
<Style Selector="Expander:left /template/ ToggleButton#ExpanderHeader"> <Style Selector="Expander:left /template/ ToggleButton#ExpanderHeader">

1
src/Avalonia.Themes.Fluent/Controls/GridSplitter.xaml

@ -15,6 +15,7 @@
<Border <Border
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}"/> Background="{TemplateBinding Background}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

1
src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml

@ -4,6 +4,7 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}"> Padding="{TemplateBinding Padding}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"

3
src/Avalonia.Themes.Fluent/Controls/Label.xaml

@ -5,7 +5,8 @@
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"

8
src/Avalonia.Themes.Fluent/Controls/ListBox.xaml

@ -19,10 +19,12 @@
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Name="border" BorderBrush="{TemplateBinding BorderBrush}" <Border Name="border"
BorderThickness="{TemplateBinding BorderThickness}"> Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer Name="PART_ScrollViewer" <ScrollViewer Name="PART_ScrollViewer"
Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"> AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">

1
src/Avalonia.Themes.Fluent/Controls/ListBoxItem.xaml

@ -25,6 +25,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"

1
src/Avalonia.Themes.Fluent/Controls/Menu.xaml

@ -21,6 +21,7 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Padding="{TemplateBinding Padding}"> Padding="{TemplateBinding Padding}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"

6
src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml

@ -61,7 +61,8 @@
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" <ColumnDefinition Width="Auto"
@ -143,7 +144,8 @@
<Border Name="PART_LayoutRoot" <Border Name="PART_LayoutRoot"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Panel> <Panel>
<ContentPresenter Name="PART_HeaderPresenter" <ContentPresenter Name="PART_HeaderPresenter"
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"

6
src/Avalonia.Themes.Fluent/Controls/NotificationCard.xaml

@ -12,7 +12,8 @@
<Setter Property="Foreground" Value="White"/> <Setter Property="Foreground" Value="White"/>
<Setter Property="RenderTransformOrigin" Value="50%,75%"/> <Setter Property="RenderTransformOrigin" Value="50%,75%"/>
<Setter Property="BorderThickness" Value="0" /> <Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="{DynamicResource NotificationCardBackgroundBrush}" /> <Setter Property="Background" Value="{DynamicResource NotificationCardBackgroundBrush}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<LayoutTransformControl Name="PART_LayoutTransformControl" UseRenderTransform="True"> <LayoutTransformControl Name="PART_LayoutTransformControl" UseRenderTransform="True">
@ -20,7 +21,8 @@
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{DynamicResource ControlCornerRadius}" ClipToBounds="True"> CornerRadius="{TemplateBinding CornerRadius}"
ClipToBounds="True">
<DockPanel> <DockPanel>
<Panel x:Name="PART_HeaderBar" Height="4" DockPanel.Dock="Top" /> <Panel x:Name="PART_HeaderBar" Height="4" DockPanel.Dock="Top" />
<ContentControl Name="PART_Content" Content="{TemplateBinding Content}" /> <ContentControl Name="PART_Content" Content="{TemplateBinding Content}" />

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

@ -29,12 +29,14 @@
<Setter Property="MinWidth" Value="{DynamicResource TextControlThemeMinWidth}" /> <Setter Property="MinWidth" Value="{DynamicResource TextControlThemeMinWidth}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="Padding" Value="{DynamicResource TextControlThemePadding}" /> <Setter Property="Padding" Value="{DynamicResource TextControlThemePadding}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<ButtonSpinner Name="PART_Spinner" <ButtonSpinner Name="PART_Spinner"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="0" Padding="0"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" VerticalContentAlignment="Stretch"

3
src/Avalonia.Themes.Fluent/Controls/ProgressBar.xaml

@ -14,12 +14,13 @@
<Setter Property="Foreground" Value="{DynamicResource SystemControlHighlightAccentBrush}" /> <Setter Property="Foreground" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}" /> <Setter Property="Background" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource ProgressBarBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource ProgressBarBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlHighlightTransparentBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource SystemControlHighlightTransparentBrush}" />
<Setter Property="MinHeight" Value="{DynamicResource ProgressBarThemeMinHeight}" /> <Setter Property="MinHeight" Value="{DynamicResource ProgressBarThemeMinHeight}" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border x:Name="ProgressBarRoot" ClipToBounds="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{DynamicResource ControlCornerRadius}"> <Border x:Name="ProgressBarRoot" ClipToBounds="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}">
<Panel> <Panel>
<Panel x:Name="DeterminateRoot"> <Panel x:Name="DeterminateRoot">
<Border CornerRadius="{DynamicResource ControlCornerRadius}" x:Name="PART_Indicator" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" /> <Border CornerRadius="{DynamicResource ControlCornerRadius}" x:Name="PART_Indicator" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />

11
src/Avalonia.Themes.Fluent/Controls/RadioButton.xaml

@ -2,7 +2,7 @@
<Design.PreviewWith> <Design.PreviewWith>
<Border Padding="20"> <Border Padding="20">
<StackPanel Spacing="10"> <StackPanel Spacing="10">
<RadioButton Content="Option 1" /> <RadioButton Content="Option 1" Background="Green" />
<RadioButton Content="Option 2" /> <RadioButton Content="Option 2" />
<RadioButton IsEnabled="False" Content="Option 3" /> <RadioButton IsEnabled="False" Content="Option 3" />
<RadioButton Content="Option 2" /> <RadioButton Content="Option 2" />
@ -13,6 +13,7 @@
<Setter Property="Background" Value="{DynamicResource RadioButtonBackground}" /> <Setter Property="Background" Value="{DynamicResource RadioButtonBackground}" />
<Setter Property="Foreground" Value="{DynamicResource RadioButtonForeground}" /> <Setter Property="Foreground" Value="{DynamicResource RadioButtonForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource RadioButtonBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource RadioButtonBorderBrush}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Padding" Value="8,0,0,0" /> <Setter Property="Padding" Value="8,0,0,0" />
<Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
@ -24,7 +25,8 @@
<Border Name="RootBorder" <Border Name="RootBorder"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid ColumnDefinitions="20,*"> <Grid ColumnDefinitions="20,*">
<Grid VerticalAlignment="Top" <Grid VerticalAlignment="Top"
Height="32"> Height="32">
@ -75,11 +77,6 @@
<Setter Property="Stroke" Value="{DynamicResource RadioButtonCheckGlyphStroke}" /> <Setter Property="Stroke" Value="{DynamicResource RadioButtonCheckGlyphStroke}" />
<Setter Property="Fill" Value="{DynamicResource RadioButtonCheckGlyphFill}" /> <Setter Property="Fill" Value="{DynamicResource RadioButtonCheckGlyphFill}" />
</Style> </Style>
<Style Selector="RadioButton /template/ Border#RootBorder">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
</Style>
<!-- PointerOver State --> <!-- PointerOver State -->
<Style Selector="RadioButton:pointerover /template/ ContentPresenter#PART_ContentPresenter"> <Style Selector="RadioButton:pointerover /template/ ContentPresenter#PART_ContentPresenter">

2
src/Avalonia.Themes.Fluent/Controls/RepeatButton.xaml

@ -15,6 +15,7 @@
<Setter Property="Foreground" Value="{DynamicResource RepeatButtonForeground}" /> <Setter Property="Foreground" Value="{DynamicResource RepeatButtonForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource RepeatButtonBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource RepeatButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource ButtonBorderThemeThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource ButtonBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Padding" Value="{StaticResource ButtonPadding}" /> <Setter Property="Padding" Value="{StaticResource ButtonPadding}" />
<Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
@ -28,6 +29,7 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"

1
src/Avalonia.Themes.Fluent/Controls/Separator.xaml

@ -10,6 +10,7 @@
VerticalAlignment="{TemplateBinding VerticalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}"/> Background="{TemplateBinding Background}"/>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

4
src/Avalonia.Themes.Fluent/Controls/Slider.xaml

@ -43,7 +43,7 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<DataValidationErrors> <DataValidationErrors>
<Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{DynamicResource ControlCornerRadius}"> <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding CornerRadius}">
<Grid Name="grid" Margin="{TemplateBinding Padding}" RowDefinitions="Auto, *"> <Grid Name="grid" Margin="{TemplateBinding Padding}" RowDefinitions="Auto, *">
<ContentPresenter x:Name="HeaderContentPresenter" Grid.Row="0" TextBlock.FontWeight="{DynamicResource SliderHeaderThemeFontWeight}" TextBlock.Foreground="{DynamicResource SliderHeaderForeground}" <ContentPresenter x:Name="HeaderContentPresenter" Grid.Row="0" TextBlock.FontWeight="{DynamicResource SliderHeaderThemeFontWeight}" TextBlock.Foreground="{DynamicResource SliderHeaderForeground}"
Margin="{DynamicResource SliderTopHeaderMargin}" /> Margin="{DynamicResource SliderTopHeaderMargin}" />
@ -105,7 +105,7 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<DataValidationErrors> <DataValidationErrors>
<Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{DynamicResource ControlCornerRadius}"> <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding CornerRadius}">
<Grid Name="grid" Margin="{TemplateBinding Padding}" RowDefinitions="Auto, *"> <Grid Name="grid" Margin="{TemplateBinding Padding}" RowDefinitions="Auto, *">
<ContentPresenter x:Name="HeaderContentPresenter" Grid.Row="0" TextBlock.FontWeight="{DynamicResource SliderHeaderThemeFontWeight}" TextBlock.Foreground="{DynamicResource SliderHeaderForeground}" <ContentPresenter x:Name="HeaderContentPresenter" Grid.Row="0" TextBlock.FontWeight="{DynamicResource SliderHeaderThemeFontWeight}" TextBlock.Foreground="{DynamicResource SliderHeaderForeground}"
Margin="{DynamicResource SliderTopHeaderMargin}" /> Margin="{DynamicResource SliderTopHeaderMargin}" />

4
src/Avalonia.Themes.Fluent/Controls/TabControl.xaml

@ -29,9 +29,9 @@
<Setter Property="Background" Value="{DynamicResource TabControlBackground}" /> <Setter Property="Background" Value="{DynamicResource TabControlBackground}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Margin="{TemplateBinding Margin}" <Border BorderBrush="{TemplateBinding BorderBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"> VerticalAlignment="{TemplateBinding VerticalAlignment}">

1
src/Avalonia.Themes.Fluent/Controls/TabItem.xaml

@ -28,6 +28,7 @@
<Border Name="PART_LayoutRoot" <Border Name="PART_LayoutRoot"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}"> Padding="{TemplateBinding Padding}">
<Panel> <Panel>
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"

14
src/Avalonia.Themes.Fluent/Controls/TabStrip.xaml

@ -11,10 +11,16 @@
<Style Selector="TabStrip"> <Style Selector="TabStrip">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<ItemsPresenter Name="PART_ItemsPresenter" <Border Background="{TemplateBinding Background}"
Items="{TemplateBinding Items}" BorderBrush="{TemplateBinding BorderBrush}"
ItemsPanel="{TemplateBinding ItemsPanel}" BorderThickness="{TemplateBinding BorderThickness}"
ItemTemplate="{TemplateBinding ItemTemplate}" /> CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}">
<ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}" />
</Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
<Setter Property="ItemsPanel"> <Setter Property="ItemsPanel">

1
src/Avalonia.Themes.Fluent/Controls/TabStripItem.xaml

@ -27,6 +27,7 @@
<Border Name="PART_LayoutRoot" <Border Name="PART_LayoutRoot"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}"> Padding="{TemplateBinding Padding}">
<Panel> <Panel>
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save