Browse Source

Merge branch 'master' into use-correct-toggleModifier-for-listBox-on-macOS-with-multiselection

pull/8637/head
Steven Kirk 4 years ago
committed by GitHub
parent
commit
ae91ee855f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      Avalonia.sln
  2. 6
      azure-pipelines.yml
  3. 2
      samples/BindingDemo/App.xaml
  4. 20
      samples/ControlCatalog/App.xaml.cs
  5. 2
      samples/ControlCatalog/ControlCatalog.csproj
  6. 4
      samples/ControlCatalog/MainView.xaml
  7. 20
      samples/ControlCatalog/MainView.xaml.cs
  8. 10
      samples/ControlCatalog/Models/CatalogTheme.cs
  9. 26
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  10. 3
      samples/PlatformSanityChecks/App.xaml
  11. 2
      samples/PlatformSanityChecks/PlatformSanityChecks.csproj
  12. 5
      samples/Previewer/App.xaml
  13. 2
      samples/Previewer/Previewer.csproj
  14. 16
      samples/VirtualizationDemo/App.xaml
  15. 2
      samples/VirtualizationDemo/VirtualizationDemo.csproj
  16. 5
      samples/interop/Direct3DInteropSample/App.paml
  17. 2
      samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
  18. 33
      src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs
  19. 2
      src/Avalonia.Base/Media/GlyphRun.cs
  20. 24
      src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs
  21. 17
      src/Avalonia.Base/Media/TextFormatting/InterWordJustification.cs
  22. 26
      src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs
  23. 7
      src/Avalonia.Base/Media/TextFormatting/TextLayout.cs
  24. 2
      src/Avalonia.Base/Media/TextFormatting/TextLine.cs
  25. 402
      src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
  26. 2
      src/Avalonia.Base/Media/TextFormatting/Unicode/Codepoint.cs
  27. 8
      src/Avalonia.Base/Platform/Storage/FileIO/BclStorageFile.cs
  28. 16
      src/Avalonia.Base/Platform/Storage/FileIO/BclStorageFolder.cs
  29. 2
      src/Avalonia.Base/Platform/Storage/IStorageBookmarkItem.cs
  30. 4
      src/Avalonia.Base/Platform/Storage/IStorageFile.cs
  31. 11
      src/Avalonia.Base/Platform/Storage/IStorageFolder.cs
  32. 2
      src/Avalonia.Base/Platform/Storage/IStorageItem.cs
  33. 7
      src/Avalonia.Base/Rendering/Composition/Animations/CompositionAnimation.cs
  34. 2
      src/Avalonia.Base/Rendering/Composition/Animations/ExpressionAnimation.cs
  35. 4
      src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimation.cs
  36. 4
      src/Avalonia.Base/Rendering/SceneGraph/GeometryNode.cs
  37. 6
      src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs
  38. 4
      src/Avalonia.Base/Rendering/SceneGraph/LineNode.cs
  39. 2
      src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs
  40. 2
      src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs
  41. 2
      src/Avalonia.Base/Utilities/MathUtilities.cs
  42. 4
      src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
  43. 188
      src/Avalonia.Controls.ColorPicker/Themes/Default/ColorSlider.xaml
  44. 44
      src/Avalonia.Controls.ColorPicker/Themes/Default/Default.xaml
  45. 20
      src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorPicker.xaml
  46. 4
      src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorView.xaml
  47. 23
      src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPreviewer.xaml
  48. 190
      src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorSlider.xaml
  49. 94
      src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorSpectrum.xaml
  50. 50
      src/Avalonia.Controls.ColorPicker/Themes/Simple/Simple.xaml
  51. 4
      src/Avalonia.Controls.DataGrid/Themes/Simple.xaml
  52. 56
      src/Avalonia.Controls/Button.cs
  53. 57
      src/Avalonia.Controls/Flyouts/FlyoutBase.cs
  54. 7
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  55. 2
      src/Avalonia.Controls/Primitives/Popup.cs
  56. 4
      src/Avalonia.Controls/ProgressBar.cs
  57. 24
      src/Avalonia.Controls/RichTextBlock.cs
  58. 6
      src/Avalonia.Controls/TextBox.cs
  59. 2
      src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj
  60. 5
      src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml
  61. 2
      src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
  62. 75
      src/Avalonia.Themes.Default/DefaultTheme.xaml
  63. 11
      src/Avalonia.Themes.Default/DefaultTheme.xaml.cs
  64. 30
      src/Avalonia.Themes.Fluent/Controls/ButtonSpinner.xaml
  65. 0
      src/Avalonia.Themes.Simple/Accents/Base.xaml
  66. 0
      src/Avalonia.Themes.Simple/Accents/BaseDark.xaml
  67. 0
      src/Avalonia.Themes.Simple/Accents/BaseLight.xaml
  68. 0
      src/Avalonia.Themes.Simple/ApiCompatBaseline.txt
  69. 0
      src/Avalonia.Themes.Simple/Avalonia.Themes.Simple.csproj
  70. 0
      src/Avalonia.Themes.Simple/Controls/AutoCompleteBox.xaml
  71. 0
      src/Avalonia.Themes.Simple/Controls/Button.xaml
  72. 6
      src/Avalonia.Themes.Simple/Controls/ButtonSpinner.xaml
  73. 0
      src/Avalonia.Themes.Simple/Controls/Calendar.xaml
  74. 0
      src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml
  75. 0
      src/Avalonia.Themes.Simple/Controls/CalendarDatePicker.xaml
  76. 0
      src/Avalonia.Themes.Simple/Controls/CalendarDayButton.xaml
  77. 0
      src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml
  78. 10
      src/Avalonia.Themes.Simple/Controls/CaptionButtons.xaml
  79. 0
      src/Avalonia.Themes.Simple/Controls/Carousel.xaml
  80. 0
      src/Avalonia.Themes.Simple/Controls/CheckBox.xaml
  81. 0
      src/Avalonia.Themes.Simple/Controls/ComboBox.xaml
  82. 0
      src/Avalonia.Themes.Simple/Controls/ComboBoxItem.xaml
  83. 0
      src/Avalonia.Themes.Simple/Controls/ContentControl.xaml
  84. 2
      src/Avalonia.Themes.Simple/Controls/ContextMenu.xaml
  85. 0
      src/Avalonia.Themes.Simple/Controls/DataValidationErrors.xaml
  86. 22
      src/Avalonia.Themes.Simple/Controls/DatePicker.xaml
  87. 22
      src/Avalonia.Themes.Simple/Controls/DateTimePickerShared.xaml
  88. 0
      src/Avalonia.Themes.Simple/Controls/DropDownButton.xaml
  89. 0
      src/Avalonia.Themes.Simple/Controls/EmbeddableControlRoot.xaml
  90. 34
      src/Avalonia.Themes.Simple/Controls/Expander.xaml
  91. 0
      src/Avalonia.Themes.Simple/Controls/FlyoutPresenter.xaml
  92. 0
      src/Avalonia.Themes.Simple/Controls/FocusAdorner.xaml
  93. 0
      src/Avalonia.Themes.Simple/Controls/GridSplitter.xaml
  94. 0
      src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml
  95. 0
      src/Avalonia.Themes.Simple/Controls/Label.xaml
  96. 0
      src/Avalonia.Themes.Simple/Controls/ListBox.xaml
  97. 0
      src/Avalonia.Themes.Simple/Controls/ListBoxItem.xaml
  98. 0
      src/Avalonia.Themes.Simple/Controls/ManagedFileChooser.xaml
  99. 6
      src/Avalonia.Themes.Simple/Controls/Menu.xaml
  100. 2
      src/Avalonia.Themes.Simple/Controls/MenuFlyoutPresenter.xaml

2
Avalonia.sln

@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1", "src\W
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls", "src\Avalonia.Controls\Avalonia.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls", "src\Avalonia.Controls\Avalonia.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Default", "src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Simple", "src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
EndProject EndProject

6
azure-pipelines.yml

@ -59,7 +59,7 @@ jobs:
variables: variables:
SolutionDir: '$(Build.SourcesDirectory)' SolutionDir: '$(Build.SourcesDirectory)'
pool: pool:
vmImage: 'macOS-10.15' vmImage: 'macos-12'
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Use .NET Core SDK 3.1.418' displayName: 'Use .NET Core SDK 3.1.418'
@ -91,10 +91,10 @@ jobs:
inputs: inputs:
actions: 'build' actions: 'build'
scheme: '' scheme: ''
sdk: 'macosx11.1' sdk: 'macosx12.3'
configuration: 'Release' configuration: 'Release'
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace' xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
xcodeVersion: '12' # Options: 8, 9, default, specifyPath xcodeVersion: '13' # Options: 8, 9, default, specifyPath
args: '-derivedDataPath ./' args: '-derivedDataPath ./'
- task: CmdLine@2 - task: CmdLine@2

2
samples/BindingDemo/App.xaml

@ -4,6 +4,6 @@
x:Class="BindingDemo.App"> x:Class="BindingDemo.App">
<Application.Styles> <Application.Styles>
<FluentTheme /> <FluentTheme />
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/> <StyleInclude Source="avares://Avalonia.Themes.Simple/Accents/BaseLight.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

20
samples/ControlCatalog/App.xaml.cs

@ -5,7 +5,7 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.Styling; using Avalonia.Markup.Xaml.Styling;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.Themes.Default; using Avalonia.Themes.Simple;
using Avalonia.Themes.Fluent; using Avalonia.Themes.Fluent;
using ControlCatalog.ViewModels; using ControlCatalog.ViewModels;
@ -23,9 +23,9 @@ namespace ControlCatalog
Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml") Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml")
}; };
public static readonly StyleInclude ColorPickerDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) public static readonly StyleInclude ColorPickerSimple = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
{ {
Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Default/Default.xaml") Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Simple/Simple.xaml")
}; };
public static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) public static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
@ -33,16 +33,16 @@ namespace ControlCatalog
Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml") Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml")
}; };
public static readonly StyleInclude DataGridDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) public static readonly StyleInclude DataGridSimple = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
{ {
Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Default.xaml") Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml")
}; };
public static FluentTheme Fluent = new FluentTheme(new Uri("avares://ControlCatalog/Styles")); public static FluentTheme Fluent = new FluentTheme(new Uri("avares://ControlCatalog/Styles"));
public static SimpleTheme Default = new SimpleTheme(new Uri("avares://ControlCatalog/Styles")); public static SimpleTheme Simple = new SimpleTheme(new Uri("avares://ControlCatalog/Styles"));
public static Styles DefaultLight = new Styles public static Styles SimpleLight = new Styles
{ {
new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
{ {
@ -56,10 +56,10 @@ namespace ControlCatalog
{ {
Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseLight.xaml") Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseLight.xaml")
}, },
Default Simple
}; };
public static Styles DefaultDark = new Styles public static Styles SimpleDark = new Styles
{ {
new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
{ {
@ -73,7 +73,7 @@ namespace ControlCatalog
{ {
Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseDark.xaml") Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseDark.xaml")
}, },
Default Simple
}; };
public override void Initialize() public override void Initialize()

2
samples/ControlCatalog/ControlCatalog.csproj

@ -29,7 +29,7 @@
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" /> <ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
<ProjectReference Include="..\SampleControls\ControlSamples.csproj" /> <ProjectReference Include="..\SampleControls\ControlSamples.csproj" />

4
samples/ControlCatalog/MainView.xaml

@ -187,8 +187,8 @@
<ComboBox.Items> <ComboBox.Items>
<models:CatalogTheme>FluentLight</models:CatalogTheme> <models:CatalogTheme>FluentLight</models:CatalogTheme>
<models:CatalogTheme>FluentDark</models:CatalogTheme> <models:CatalogTheme>FluentDark</models:CatalogTheme>
<models:CatalogTheme>DefaultLight</models:CatalogTheme> <models:CatalogTheme>SimpleLight</models:CatalogTheme>
<models:CatalogTheme>DefaultDark</models:CatalogTheme> <models:CatalogTheme>SimpleDark</models:CatalogTheme>
</ComboBox.Items> </ComboBox.Items>
</ComboBox> </ComboBox>
<ComboBox x:Name="TransparencyLevels" <ComboBox x:Name="TransparencyLevels"

20
samples/ControlCatalog/MainView.xaml.cs

@ -58,19 +58,19 @@ namespace ControlCatalog
Application.Current.Styles[1] = App.ColorPickerFluent; Application.Current.Styles[1] = App.ColorPickerFluent;
Application.Current.Styles[2] = App.DataGridFluent; Application.Current.Styles[2] = App.DataGridFluent;
} }
else if (theme == CatalogTheme.DefaultLight) else if (theme == CatalogTheme.SimpleLight)
{ {
App.Default.Mode = Avalonia.Themes.Default.SimpleThemeMode.Light; App.Simple.Mode = Avalonia.Themes.Simple.SimpleThemeMode.Light;
Application.Current.Styles[0] = App.DefaultLight; Application.Current.Styles[0] = App.SimpleLight;
Application.Current.Styles[1] = App.ColorPickerDefault; Application.Current.Styles[1] = App.ColorPickerSimple;
Application.Current.Styles[2] = App.DataGridDefault; Application.Current.Styles[2] = App.DataGridSimple;
} }
else if (theme == CatalogTheme.DefaultDark) else if (theme == CatalogTheme.SimpleDark)
{ {
App.Default.Mode = Avalonia.Themes.Default.SimpleThemeMode.Dark; App.Simple.Mode = Avalonia.Themes.Simple.SimpleThemeMode.Dark;
Application.Current.Styles[0] = App.DefaultDark; Application.Current.Styles[0] = App.SimpleDark;
Application.Current.Styles[1] = App.ColorPickerDefault; Application.Current.Styles[1] = App.ColorPickerSimple;
Application.Current.Styles[2] = App.DataGridDefault; Application.Current.Styles[2] = App.DataGridSimple;
} }
} }
}; };

10
samples/ControlCatalog/Models/CatalogTheme.cs

@ -1,14 +1,10 @@
using System; namespace ControlCatalog.Models
using System.Collections.Generic;
using System.Text;
namespace ControlCatalog.Models
{ {
public enum CatalogTheme public enum CatalogTheme
{ {
FluentLight, FluentLight,
FluentDark, FluentDark,
DefaultLight, SimpleLight,
DefaultDark SimpleDark
} }
} }

26
samples/ControlCatalog/Pages/DialogsPage.xaml.cs

@ -195,10 +195,10 @@ namespace ControlCatalog.Pages
{ {
// Sync disposal of StreamWriter is not supported on WASM // Sync disposal of StreamWriter is not supported on WASM
#if NET6_0_OR_GREATER #if NET6_0_OR_GREATER
await using var stream = await file.OpenWrite(); await using var stream = await file.OpenWriteAsync();
await using var reader = new System.IO.StreamWriter(stream); await using var reader = new System.IO.StreamWriter(stream);
#else #else
using var stream = await file.OpenWrite(); using var stream = await file.OpenWriteAsync();
using var reader = new System.IO.StreamWriter(stream); using var reader = new System.IO.StreamWriter(stream);
#endif #endif
await reader.WriteLineAsync(openedFileContent.Text); await reader.WriteLineAsync(openedFileContent.Text);
@ -243,8 +243,8 @@ namespace ControlCatalog.Pages
async Task SetPickerResult(IReadOnlyCollection<IStorageItem>? items) async Task SetPickerResult(IReadOnlyCollection<IStorageItem>? items)
{ {
items ??= Array.Empty<IStorageItem>(); items ??= Array.Empty<IStorageItem>();
var mappedResults = items.Select(FullPathOrName).ToList(); bookmarkContainer.Text = items.FirstOrDefault(f => f.CanBookmark) is { } f ? await f.SaveBookmarkAsync() : "Can't bookmark";
bookmarkContainer.Text = items.FirstOrDefault(f => f.CanBookmark) is { } f ? await f.SaveBookmark() : "Can't bookmark"; var mappedResults = new List<string>();
if (items.FirstOrDefault() is IStorageItem item) if (items.FirstOrDefault() is IStorageItem item)
{ {
@ -267,9 +267,9 @@ Content:
if (file.CanOpenRead) if (file.CanOpenRead)
{ {
#if NET6_0_OR_GREATER #if NET6_0_OR_GREATER
await using var stream = await file.OpenRead(); await using var stream = await file.OpenReadAsync();
#else #else
using var stream = await file.OpenRead(); using var stream = await file.OpenReadAsync();
#endif #endif
using var reader = new System.IO.StreamReader(stream); using var reader = new System.IO.StreamReader(stream);
@ -293,7 +293,19 @@ Content:
lastSelectedDirectory = await item.GetParentAsync(); lastSelectedDirectory = await item.GetParentAsync();
if (lastSelectedDirectory is not null) if (lastSelectedDirectory is not null)
{ {
mappedResults.Insert(0, "Parent: " + FullPathOrName(lastSelectedDirectory)); mappedResults.Add(FullPathOrName(lastSelectedDirectory));
}
foreach (var selectedItem in items)
{
mappedResults.Add("+> " + FullPathOrName(selectedItem));
if (selectedItem is IStorageFolder folder)
{
foreach (var innerItems in await folder.GetItemsAsync())
{
mappedResults.Add("++> " + FullPathOrName(innerItems));
}
}
} }
} }

3
samples/PlatformSanityChecks/App.xaml

@ -1,6 +1,5 @@
<Application xmlns="https://github.com/avaloniaui"> <Application xmlns="https://github.com/avaloniaui">
<Application.Styles> <Application.Styles>
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/> <SimpleTheme Mode="Light" />
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

2
samples/PlatformSanityChecks/PlatformSanityChecks.csproj

@ -7,7 +7,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Desktop\Avalonia.Desktop.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Desktop\Avalonia.Desktop.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
<ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" /> <ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" />
</ItemGroup> </ItemGroup>

5
samples/Previewer/App.xaml

@ -1,6 +1,5 @@
<Application xmlns="https://github.com/avaloniaui"> <Application xmlns="https://github.com/avaloniaui">
<Application.Styles> <Application.Styles>
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/> <SimpleTheme Mode="Light" />
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

2
samples/Previewer/Previewer.csproj

@ -10,7 +10,7 @@
<EmbeddedResource Include="**\*.xaml" /> <EmbeddedResource Include="**\*.xaml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\SampleApp.props" /> <Import Project="..\..\build\SampleApp.props" />

16
samples/VirtualizationDemo/App.xaml

@ -1,9 +1,7 @@
<Application <Application xmlns="https://github.com/avaloniaui"
xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="VirtualizationDemo.App">
x:Class="VirtualizationDemo.App"> <Application.Styles>
<Application.Styles> <SimpleTheme />
<StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/> </Application.Styles>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/> </Application>
</Application.Styles>
</Application>

2
samples/VirtualizationDemo/VirtualizationDemo.csproj

@ -5,7 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" /> <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup> </ItemGroup>

5
samples/interop/Direct3DInteropSample/App.paml

@ -1,6 +1,5 @@
<Application xmlns="https://github.com/avaloniaui"> <Application xmlns="https://github.com/avaloniaui">
<Application.Styles> <Application.Styles>
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/> <SimpleTheme Mode="Light" />
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

2
samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj

@ -22,7 +22,7 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" /> <ProjectReference Include="..\..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" /> <ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" /> <ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" />
<ProjectReference Include="..\..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\..\MiniMvvm\MiniMvvm.csproj" />

33
src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs

@ -1,6 +1,7 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -35,13 +36,13 @@ internal abstract class AndroidStorageItem : IStorageBookmarkItem
public bool CanBookmark => true; public bool CanBookmark => true;
public Task<string?> SaveBookmark() public Task<string?> SaveBookmarkAsync()
{ {
Context.ContentResolver?.TakePersistableUriPermission(Uri, ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantReadUriPermission); Context.ContentResolver?.TakePersistableUriPermission(Uri, ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantReadUriPermission);
return Task.FromResult(Uri.ToString()); return Task.FromResult(Uri.ToString());
} }
public Task ReleaseBookmark() public Task ReleaseBookmarkAsync()
{ {
Context.ContentResolver?.ReleasePersistableUriPermission(Uri, ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantReadUriPermission); Context.ContentResolver?.ReleasePersistableUriPermission(Uri, ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantReadUriPermission);
return Task.CompletedTask; return Task.CompletedTask;
@ -106,6 +107,30 @@ internal sealed class AndroidStorageFolder : AndroidStorageItem, IStorageBookmar
{ {
return Task.FromResult(new StorageItemProperties()); return Task.FromResult(new StorageItemProperties());
} }
public async Task<IReadOnlyList<IStorageItem>> GetItemsAsync()
{
using var javaFile = new JavaFile(Uri.Path!);
// Java file represents files AND directories. Don't be confused.
var files = await javaFile.ListFilesAsync().ConfigureAwait(false);
if (files is null)
{
return Array.Empty<IStorageItem>();
}
return files
.Select(f => (file: f, uri: AndroidUri.FromFile(f)))
.Where(t => t.uri is not null)
.Select(t => t.file switch
{
{ IsFile: true } => (IStorageItem)new AndroidStorageFile(Context, t.uri!),
{ IsDirectory: true } => new AndroidStorageFolder(Context, t.uri!),
_ => null
})
.Where(i => i is not null)
.ToArray()!;
}
} }
internal sealed class AndroidStorageFile : AndroidStorageItem, IStorageBookmarkFile internal sealed class AndroidStorageFile : AndroidStorageItem, IStorageBookmarkFile
@ -118,10 +143,10 @@ internal sealed class AndroidStorageFile : AndroidStorageItem, IStorageBookmarkF
public bool CanOpenWrite => true; public bool CanOpenWrite => true;
public Task<Stream> OpenRead() => Task.FromResult(OpenContentStream(Context, Uri, false) public Task<Stream> OpenReadAsync() => Task.FromResult(OpenContentStream(Context, Uri, false)
?? throw new InvalidOperationException("Failed to open content stream")); ?? throw new InvalidOperationException("Failed to open content stream"));
public Task<Stream> OpenWrite() => Task.FromResult(OpenContentStream(Context, Uri, true) public Task<Stream> OpenWriteAsync() => Task.FromResult(OpenContentStream(Context, Uri, true)
?? throw new InvalidOperationException("Failed to open content stream")); ?? throw new InvalidOperationException("Failed to open content stream"));
private Stream? OpenContentStream(Context context, AndroidUri uri, bool isOutput) private Stream? OpenContentStream(Context context, AndroidUri uri, bool isOutput)

2
src/Avalonia.Base/Media/GlyphRun.cs

@ -265,7 +265,7 @@ namespace Avalonia.Media
//RightToLeft //RightToLeft
var glyphIndex = FindGlyphIndex(characterIndex); var glyphIndex = FindGlyphIndex(characterIndex);
if (GlyphClusters != null) if (GlyphClusters != null && GlyphClusters.Count > 0)
{ {
if (characterIndex > GlyphClusters[0]) if (characterIndex > GlyphClusters[0])
{ {

24
src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Media.TextFormatting.Unicode;
using Avalonia.Utilities; using Avalonia.Utilities;
namespace Avalonia.Media.TextFormatting namespace Avalonia.Media.TextFormatting
@ -116,7 +117,30 @@ namespace Avalonia.Media.TextFormatting
length = text.Length; length = text.Length;
} }
length = CoerceLength(text, length);
return new ValueSpan<TextRunProperties>(firstTextSourceIndex, length, currentProperties); return new ValueSpan<TextRunProperties>(firstTextSourceIndex, length, currentProperties);
} }
private static int CoerceLength(ReadOnlySlice<char> text, int length)
{
var finalLength = 0;
var graphemeEnumerator = new GraphemeEnumerator(text);
while (graphemeEnumerator.MoveNext())
{
var grapheme = graphemeEnumerator.Current;
finalLength += grapheme.Text.Length;
if (finalLength >= length)
{
return finalLength;
}
}
return length;
}
} }
} }

17
src/Avalonia.Base/Media/TextFormatting/InterWordJustification.cs

@ -15,6 +15,13 @@ namespace Avalonia.Media.TextFormatting
public override void Justify(TextLine textLine) public override void Justify(TextLine textLine)
{ {
var lineImpl = textLine as TextLineImpl;
if(lineImpl is null)
{
return;
}
var paragraphWidth = Width; var paragraphWidth = Width;
if (double.IsInfinity(paragraphWidth)) if (double.IsInfinity(paragraphWidth))
@ -22,12 +29,12 @@ namespace Avalonia.Media.TextFormatting
return; return;
} }
if (textLine.NewLineLength > 0) if (lineImpl.NewLineLength > 0)
{ {
return; return;
} }
var textLineBreak = textLine.TextLineBreak; var textLineBreak = lineImpl.TextLineBreak;
if (textLineBreak is not null && textLineBreak.TextEndOfLine is not null) if (textLineBreak is not null && textLineBreak.TextEndOfLine is not null)
{ {
@ -39,7 +46,7 @@ namespace Avalonia.Media.TextFormatting
var breakOportunities = new Queue<int>(); var breakOportunities = new Queue<int>();
foreach (var textRun in textLine.TextRuns) foreach (var textRun in lineImpl.TextRuns)
{ {
var text = textRun.Text; var text = textRun.Text;
@ -68,10 +75,10 @@ namespace Avalonia.Media.TextFormatting
return; return;
} }
var remainingSpace = Math.Max(0, paragraphWidth - textLine.WidthIncludingTrailingWhitespace); var remainingSpace = Math.Max(0, paragraphWidth - lineImpl.WidthIncludingTrailingWhitespace);
var spacing = remainingSpace / breakOportunities.Count; var spacing = remainingSpace / breakOportunities.Count;
foreach (var textRun in textLine.TextRuns) foreach (var textRun in lineImpl.TextRuns)
{ {
var text = textRun.Text; var text = textRun.Text;

26
src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs

@ -38,7 +38,7 @@ namespace Avalonia.Media.TextFormatting
/// Gets a list of <see cref="ShapeableTextCharacters"/>. /// Gets a list of <see cref="ShapeableTextCharacters"/>.
/// </summary> /// </summary>
/// <returns>The shapeable text characters.</returns> /// <returns>The shapeable text characters.</returns>
internal IReadOnlyList<ShapeableTextCharacters> GetShapeableCharacters(ReadOnlySlice<char> runText, sbyte biDiLevel, internal IReadOnlyList<ShapeableTextCharacters> GetShapeableCharacters(ReadOnlySlice<char> runText, sbyte biDiLevel,
ref TextRunProperties? previousProperties) ref TextRunProperties? previousProperties)
{ {
var shapeableCharacters = new List<ShapeableTextCharacters>(2); var shapeableCharacters = new List<ShapeableTextCharacters>(2);
@ -65,7 +65,7 @@ namespace Avalonia.Media.TextFormatting
/// <param name="biDiLevel">The bidi level of the run.</param> /// <param name="biDiLevel">The bidi level of the run.</param>
/// <param name="previousProperties"></param> /// <param name="previousProperties"></param>
/// <returns>A list of shapeable text runs.</returns> /// <returns>A list of shapeable text runs.</returns>
private static ShapeableTextCharacters CreateShapeableRun(ReadOnlySlice<char> text, private static ShapeableTextCharacters CreateShapeableRun(ReadOnlySlice<char> text,
TextRunProperties defaultProperties, sbyte biDiLevel, ref TextRunProperties? previousProperties) TextRunProperties defaultProperties, sbyte biDiLevel, ref TextRunProperties? previousProperties)
{ {
var defaultTypeface = defaultProperties.Typeface; var defaultTypeface = defaultProperties.Typeface;
@ -76,7 +76,7 @@ namespace Avalonia.Media.TextFormatting
{ {
if (script == Script.Common && previousTypeface is not null) if (script == Script.Common && previousTypeface is not null)
{ {
if(TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out var fallbackCount, out _)) if (TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out var fallbackCount, out _))
{ {
return new ShapeableTextCharacters(text.Take(fallbackCount), return new ShapeableTextCharacters(text.Take(fallbackCount),
defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel); defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel);
@ -86,10 +86,10 @@ namespace Avalonia.Media.TextFormatting
return new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface), return new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface),
biDiLevel); biDiLevel);
} }
if (previousTypeface is not null) if (previousTypeface is not null)
{ {
if(TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out count, out _)) if (TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out count, out _))
{ {
return new ShapeableTextCharacters(text.Take(count), return new ShapeableTextCharacters(text.Take(count),
defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel); defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel);
@ -106,12 +106,12 @@ namespace Avalonia.Media.TextFormatting
{ {
continue; continue;
} }
codepoint = codepointEnumerator.Current; codepoint = codepointEnumerator.Current;
break; break;
} }
//ToDo: Fix FontFamily fallback //ToDo: Fix FontFamily fallback
var matchFound = var matchFound =
FontManager.Current.TryMatchCharacter(codepoint, defaultTypeface.Style, defaultTypeface.Weight, FontManager.Current.TryMatchCharacter(codepoint, defaultTypeface.Style, defaultTypeface.Weight,
@ -157,14 +157,14 @@ namespace Avalonia.Media.TextFormatting
/// <param name="script"></param> /// <param name="script"></param>
/// <returns></returns> /// <returns></returns>
protected static bool TryGetShapeableLength( protected static bool TryGetShapeableLength(
ReadOnlySlice<char> text, ReadOnlySlice<char> text,
Typeface typeface, Typeface typeface,
Typeface? defaultTypeface, Typeface? defaultTypeface,
out int length, out int length,
out Script script) out Script script)
{ {
length = 0; length = 0;
script = Script.Unknown; script = Script.Unknown;
if (text.Length == 0) if (text.Length == 0)
{ {
@ -182,7 +182,7 @@ namespace Avalonia.Media.TextFormatting
var currentScript = currentGrapheme.FirstCodepoint.Script; var currentScript = currentGrapheme.FirstCodepoint.Script;
if (currentScript != Script.Common && defaultFont != null && defaultFont.TryGetGlyph(currentGrapheme.FirstCodepoint, out _)) if (!currentGrapheme.FirstCodepoint.IsWhiteSpace && defaultFont != null && defaultFont.TryGetGlyph(currentGrapheme.FirstCodepoint, out _))
{ {
break; break;
} }
@ -192,7 +192,7 @@ namespace Avalonia.Media.TextFormatting
{ {
break; break;
} }
if (currentScript != script) if (currentScript != script)
{ {
if (script is Script.Unknown || currentScript != Script.Common && if (script is Script.Unknown || currentScript != Script.Common &&

7
src/Avalonia.Base/Media/TextFormatting/TextLayout.cs

@ -537,8 +537,13 @@ namespace Avalonia.Media.TextFormatting
/// </summary> /// </summary>
/// <param name="width">The collapsing width.</param> /// <param name="width">The collapsing width.</param>
/// <returns>The <see cref="TextCollapsingProperties"/>.</returns> /// <returns>The <see cref="TextCollapsingProperties"/>.</returns>
private TextCollapsingProperties GetCollapsingProperties(double width) private TextCollapsingProperties? GetCollapsingProperties(double width)
{ {
if(_textTrimming == TextTrimming.None)
{
return null;
}
return _textTrimming.CreateCollapsingProperties(new TextCollapsingCreateInfo(width, _paragraphProperties.DefaultTextRunProperties)); return _textTrimming.CreateCollapsingProperties(new TextCollapsingCreateInfo(width, _paragraphProperties.DefaultTextRunProperties));
} }
} }

2
src/Avalonia.Base/Media/TextFormatting/TextLine.cs

@ -153,7 +153,7 @@ namespace Avalonia.Media.TextFormatting
/// <returns> /// <returns>
/// A <see cref="TextLine"/> value that represents a collapsed line that can be displayed. /// A <see cref="TextLine"/> value that represents a collapsed line that can be displayed.
/// </returns> /// </returns>
public abstract TextLine Collapse(params TextCollapsingProperties[] collapsingPropertiesList); public abstract TextLine Collapse(params TextCollapsingProperties?[] collapsingPropertiesList);
/// <summary> /// <summary>
/// Create a justified line based on justification text properties. /// Create a justified line based on justification text properties.

402
src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs

@ -119,7 +119,7 @@ namespace Avalonia.Media.TextFormatting
} }
/// <inheritdoc/> /// <inheritdoc/>
public override TextLine Collapse(params TextCollapsingProperties[] collapsingPropertiesList) public override TextLine Collapse(params TextCollapsingProperties?[] collapsingPropertiesList)
{ {
if (collapsingPropertiesList.Length == 0) if (collapsingPropertiesList.Length == 0)
{ {
@ -128,6 +128,11 @@ namespace Avalonia.Media.TextFormatting
var collapsingProperties = collapsingPropertiesList[0]; var collapsingProperties = collapsingPropertiesList[0];
if(collapsingProperties is null)
{
return this;
}
var collapsedRuns = collapsingProperties.Collapse(this); var collapsedRuns = collapsingProperties.Collapse(this);
if (collapsedRuns is null) if (collapsedRuns is null)
@ -171,7 +176,7 @@ namespace Avalonia.Media.TextFormatting
return GetRunCharacterHit(firstRun, FirstTextSourceIndex, 0); return GetRunCharacterHit(firstRun, FirstTextSourceIndex, 0);
} }
if (distance > WidthIncludingTrailingWhitespace) if (distance >= WidthIncludingTrailingWhitespace)
{ {
var lastRun = _textRuns[_textRuns.Count - 1]; var lastRun = _textRuns[_textRuns.Count - 1];
@ -183,8 +188,52 @@ namespace Avalonia.Media.TextFormatting
var currentPosition = FirstTextSourceIndex; var currentPosition = FirstTextSourceIndex;
var currentDistance = 0.0; var currentDistance = 0.0;
foreach (var currentRun in _textRuns) for (var i = 0; i < _textRuns.Count; i++)
{ {
var currentRun = _textRuns[i];
if(currentRun is ShapedTextCharacters shapedRun && !shapedRun.ShapedBuffer.IsLeftToRight)
{
var rightToLeftIndex = i;
currentPosition += currentRun.TextSourceLength;
while (rightToLeftIndex + 1 <= _textRuns.Count - 1)
{
var nextShaped = _textRuns[rightToLeftIndex + 1] as ShapedTextCharacters;
if (nextShaped == null || nextShaped.ShapedBuffer.IsLeftToRight)
{
break;
}
currentPosition += nextShaped.TextSourceLength;
rightToLeftIndex++;
}
for (var j = i; i <= rightToLeftIndex; j++)
{
if(j > _textRuns.Count - 1)
{
break;
}
currentRun = _textRuns[j];
if(currentDistance + currentRun.Size.Width <= distance)
{
currentDistance += currentRun.Size.Width;
currentPosition -= currentRun.TextSourceLength;
continue;
}
characterHit = GetRunCharacterHit(currentRun, currentPosition, distance - currentDistance);
break;
}
}
if (currentDistance + currentRun.Size.Width < distance) if (currentDistance + currentRun.Size.Width < distance)
{ {
currentDistance += currentRun.Size.Width; currentDistance += currentRun.Size.Width;
@ -211,12 +260,16 @@ namespace Avalonia.Media.TextFormatting
{ {
characterHit = shapedRun.GlyphRun.GetCharacterHitFromDistance(distance, out _); characterHit = shapedRun.GlyphRun.GetCharacterHitFromDistance(distance, out _);
var offset = Math.Max(0, currentPosition - shapedRun.Text.Start); var offset = 0;
if (!shapedRun.GlyphRun.IsLeftToRight) if (shapedRun.GlyphRun.IsLeftToRight)
{ {
offset = Math.Max(0, offset - shapedRun.Text.End); offset = Math.Max(0, currentPosition - shapedRun.Text.Start);
} }
//else
//{
// offset = Math.Max(0, currentPosition - shapedRun.Text.Start + shapedRun.Text.Length);
//}
characterHit = new CharacterHit(characterHit.FirstCharacterIndex + offset, characterHit.TrailingLength); characterHit = new CharacterHit(characterHit.FirstCharacterIndex + offset, characterHit.TrailingLength);
@ -255,10 +308,56 @@ namespace Avalonia.Media.TextFormatting
{ {
var currentRun = _textRuns[index]; var currentRun = _textRuns[index];
if (TryGetDistanceFromCharacterHit(currentRun, characterHit, currentPosition, remainingLength, if (currentRun is ShapedTextCharacters shapedRun && !shapedRun.ShapedBuffer.IsLeftToRight)
flowDirection, out var distance, out _)) {
var i = index;
var rightToLeftWidth = currentRun.Size.Width;
while (i + 1 <= _textRuns.Count - 1)
{
var nextRun = _textRuns[i + 1];
if (nextRun is ShapedTextCharacters nextShapedRun && !nextShapedRun.ShapedBuffer.IsLeftToRight)
{
i++;
rightToLeftWidth += nextRun.Size.Width;
continue;
}
break;
}
if(i > index)
{
while (i >= index)
{
currentRun = _textRuns[i];
rightToLeftWidth -= currentRun.Size.Width;
if (currentPosition + currentRun.TextSourceLength >= characterIndex)
{
break;
}
currentPosition += currentRun.TextSourceLength;
remainingLength -= currentRun.TextSourceLength;
i--;
}
currentDistance += rightToLeftWidth;
}
}
if (currentPosition + currentRun.TextSourceLength >= characterIndex &&
TryGetDistanceFromCharacterHit(currentRun, characterHit, currentPosition, remainingLength, flowDirection, out var distance, out _))
{ {
return currentDistance + distance; return Math.Max(0, currentDistance + distance);
} }
//No hit hit found so we add the full width //No hit hit found so we add the full width
@ -283,7 +382,7 @@ namespace Avalonia.Media.TextFormatting
distance = currentGlyphRun.Size.Width - distance; distance = currentGlyphRun.Size.Width - distance;
} }
return currentDistance - distance; return Math.Max(0, currentDistance - distance);
} }
//No hit hit found so we add the full width //No hit hit found so we add the full width
@ -293,7 +392,7 @@ namespace Avalonia.Media.TextFormatting
} }
} }
return currentDistance; return Math.Max(0, currentDistance);
} }
private static bool TryGetDistanceFromCharacterHit( private static bool TryGetDistanceFromCharacterHit(
@ -442,92 +541,139 @@ namespace Avalonia.Media.TextFormatting
continue; continue;
} }
if (currentPosition + currentRun.TextSourceLength <= firstTextSourceIndex)
{
startX += currentRun.Size.Width;
currentPosition += currentRun.TextSourceLength;
continue;
}
var characterLength = 0; var characterLength = 0;
var endX = startX; var endX = startX;
var runWidth = 0.0;
TextRunBounds? currentRunBounds = null;
if (currentRun is ShapedTextCharacters currentShapedRun) var currentShapedRun = currentRun as ShapedTextCharacters;
if (currentShapedRun != null && !currentShapedRun.ShapedBuffer.IsLeftToRight)
{ {
var offset = Math.Max(0, firstTextSourceIndex - currentPosition); var rightToLeftIndex = index;
startX += currentShapedRun.Size.Width;
currentPosition += offset; while (rightToLeftIndex + 1 <= _textRuns.Count - 1)
{
var nextShapedRun = _textRuns[rightToLeftIndex + 1] as ShapedTextCharacters;
var startIndex = currentRun.Text.Start + offset; if (nextShapedRun == null || nextShapedRun.ShapedBuffer.IsLeftToRight)
{
break;
}
double startOffset; startX += nextShapedRun.Size.Width;
double endOffset;
if (currentShapedRun.ShapedBuffer.IsLeftToRight) rightToLeftIndex++;
}
if (TryGetTextRunBoundsRightToLeft(startX, firstTextSourceIndex, characterIndex, rightToLeftIndex, ref currentPosition, ref remainingLength, out currentRunBounds))
{ {
startOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex)); startX = currentRunBounds!.Rectangle.Left;
endX = currentRunBounds.Rectangle.Right;
endOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex + remainingLength)); runWidth = currentRunBounds.Rectangle.Width;
} }
else
currentDirection = FlowDirection.RightToLeft;
}
else
{
if (currentShapedRun != null)
{ {
endOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex)); if (currentPosition + currentRun.TextSourceLength <= firstTextSourceIndex)
{
startX += currentRun.Size.Width;
if (currentPosition < startIndex) currentPosition += currentRun.TextSourceLength;
continue;
}
var offset = Math.Max(0, firstTextSourceIndex - currentPosition);
currentPosition += offset;
var startIndex = currentRun.Text.Start + offset;
double startOffset;
double endOffset;
if (currentShapedRun.ShapedBuffer.IsLeftToRight)
{ {
startOffset = endOffset; startOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex));
endOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex + remainingLength));
} }
else else
{ {
startOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex + remainingLength)); endOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex));
if (currentPosition < startIndex)
{
startOffset = endOffset;
}
else
{
startOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex + remainingLength));
}
} }
}
startX += startOffset; startX += startOffset;
endX += endOffset; endX += endOffset;
var endHit = currentShapedRun.GlyphRun.GetCharacterHitFromDistance(endOffset, out _); var endHit = currentShapedRun.GlyphRun.GetCharacterHitFromDistance(endOffset, out _);
var startHit = currentShapedRun.GlyphRun.GetCharacterHitFromDistance(startOffset, out _); var startHit = currentShapedRun.GlyphRun.GetCharacterHitFromDistance(startOffset, out _);
characterLength = Math.Abs(endHit.FirstCharacterIndex + endHit.TrailingLength - startHit.FirstCharacterIndex - startHit.TrailingLength); characterLength = Math.Abs(endHit.FirstCharacterIndex + endHit.TrailingLength - startHit.FirstCharacterIndex - startHit.TrailingLength);
currentDirection = currentShapedRun.ShapedBuffer.IsLeftToRight ? currentDirection = FlowDirection.LeftToRight;
FlowDirection.LeftToRight : }
FlowDirection.RightToLeft; else
}
else
{
if (currentPosition < firstTextSourceIndex)
{ {
startX += currentRun.Size.Width; if (currentPosition + currentRun.TextSourceLength <= firstTextSourceIndex)
{
startX += currentRun.Size.Width;
currentPosition += currentRun.TextSourceLength;
continue;
}
if (currentPosition < firstTextSourceIndex)
{
startX += currentRun.Size.Width;
}
if (currentPosition + currentRun.TextSourceLength <= characterIndex)
{
endX += currentRun.Size.Width;
characterLength = currentRun.TextSourceLength;
}
} }
if (currentPosition + currentRun.TextSourceLength <= characterIndex) if (endX < startX)
{ {
endX += currentRun.Size.Width; (endX, startX) = (startX, endX);
}
characterLength = currentRun.TextSourceLength; //Lines that only contain a linebreak need to be covered here
if (characterLength == 0)
{
characterLength = NewLineLength;
} }
}
if (endX < startX) runWidth = endX - startX;
{ currentRunBounds = new TextRunBounds(new Rect(startX, 0, runWidth, Height), currentPosition, characterLength, currentRun);
(endX, startX) = (startX, endX);
}
//Lines that only contain a linebreak need to be covered here currentPosition += characterLength;
if (characterLength == 0)
{
characterLength = NewLineLength;
}
var runWidth = endX - startX; remainingLength -= characterLength;
var currentRunBounds = new TextRunBounds(new Rect(startX, 0, runWidth, Height), currentPosition, characterLength, currentRun); }
if (!MathUtilities.IsZero(runWidth) || NewLineLength > 0) if (currentRunBounds != null && !MathUtilities.IsZero(runWidth) || NewLineLength > 0)
{ {
if (lastDirection == currentDirection && result.Count > 0 && MathUtilities.AreClose(currentRect.Right, startX)) if (lastDirection == currentDirection && result.Count > 0 && MathUtilities.AreClose(currentRect.Right, startX))
{ {
@ -537,32 +683,26 @@ namespace Avalonia.Media.TextFormatting
textBounds.Rectangle = currentRect; textBounds.Rectangle = currentRect;
textBounds.TextRunBounds.Add(currentRunBounds); textBounds.TextRunBounds.Add(currentRunBounds!);
} }
else else
{ {
currentRect = currentRunBounds.Rectangle; currentRect = currentRunBounds!.Rectangle;
result.Add(new TextBounds(currentRect, currentDirection, new List<TextRunBounds> { currentRunBounds })); result.Add(new TextBounds(currentRect, currentDirection, new List<TextRunBounds> { currentRunBounds }));
} }
} }
currentWidth += runWidth; currentWidth += runWidth;
currentPosition += characterLength;
if (currentPosition > characterIndex) if (remainingLength <= 0 || currentPosition >= characterIndex)
{ {
break; break;
} }
startX = endX; startX = endX;
lastDirection = currentDirection; lastDirection = currentDirection;
remainingLength -= characterLength;
if (remainingLength <= 0)
{
break;
}
} }
return result; return result;
@ -674,7 +814,7 @@ namespace Avalonia.Media.TextFormatting
var currentRunBounds = new TextRunBounds(new Rect(Start + startX, 0, runWidth, Height), currentPosition, characterLength, currentRun); var currentRunBounds = new TextRunBounds(new Rect(Start + startX, 0, runWidth, Height), currentPosition, characterLength, currentRun);
if(!MathUtilities.IsZero(runWidth) || NewLineLength > 0) if (!MathUtilities.IsZero(runWidth) || NewLineLength > 0)
{ {
if (lastDirection == currentDirection && result.Count > 0 && MathUtilities.AreClose(currentRect.Right, Start + startX)) if (lastDirection == currentDirection && result.Count > 0 && MathUtilities.AreClose(currentRect.Right, Start + startX))
{ {
@ -692,7 +832,7 @@ namespace Avalonia.Media.TextFormatting
result.Add(new TextBounds(currentRect, currentDirection, new List<TextRunBounds> { currentRunBounds })); result.Add(new TextBounds(currentRect, currentDirection, new List<TextRunBounds> { currentRunBounds }));
} }
} }
currentWidth += runWidth; currentWidth += runWidth;
currentPosition += characterLength; currentPosition += characterLength;
@ -716,6 +856,107 @@ namespace Avalonia.Media.TextFormatting
return result; return result;
} }
private bool TryGetTextRunBoundsRightToLeft(double startX, int firstTextSourceIndex, int characterIndex, int runIndex, ref int currentPosition, ref int remainingLength, out TextRunBounds? textRunBounds)
{
textRunBounds = null;
for (var index = runIndex; index >= 0; index--)
{
if (TextRuns[index] is not DrawableTextRun currentRun)
{
continue;
}
if (currentPosition + currentRun.TextSourceLength <= firstTextSourceIndex)
{
startX -= currentRun.Size.Width;
currentPosition += currentRun.TextSourceLength;
continue;
}
var characterLength = 0;
var endX = startX;
if (currentRun is ShapedTextCharacters currentShapedRun)
{
var offset = Math.Max(0, firstTextSourceIndex - currentPosition);
currentPosition += offset;
var startIndex = currentRun.Text.Start + offset;
double startOffset;
double endOffset;
if (currentShapedRun.ShapedBuffer.IsLeftToRight)
{
if (currentPosition < startIndex)
{
startOffset = endOffset = 0;
}
else
{
endOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex + remainingLength));
startOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex));
}
}
else
{
endOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex));
startOffset = currentShapedRun.GlyphRun.GetDistanceFromCharacterHit(new CharacterHit(startIndex + remainingLength));
}
startX -= currentRun.Size.Width - startOffset;
endX -= currentRun.Size.Width - endOffset;
var endHit = currentShapedRun.GlyphRun.GetCharacterHitFromDistance(endOffset, out _);
var startHit = currentShapedRun.GlyphRun.GetCharacterHitFromDistance(startOffset, out _);
characterLength = Math.Abs(startHit.FirstCharacterIndex + startHit.TrailingLength - endHit.FirstCharacterIndex - endHit.TrailingLength);
}
else
{
if (currentPosition + currentRun.TextSourceLength <= characterIndex)
{
endX -= currentRun.Size.Width;
}
if (currentPosition < firstTextSourceIndex)
{
startX -= currentRun.Size.Width;
characterLength = currentRun.TextSourceLength;
}
}
if (endX < startX)
{
(endX, startX) = (startX, endX);
}
//Lines that only contain a linebreak need to be covered here
if (characterLength == 0)
{
characterLength = NewLineLength;
}
var runWidth = endX - startX;
remainingLength -= characterLength;
currentPosition += characterLength;
textRunBounds = new TextRunBounds(new Rect(Start + startX, 0, runWidth, Height), currentPosition, characterLength, currentRun);
return true;
}
return false;
}
public override IReadOnlyList<TextBounds> GetTextBounds(int firstTextSourceIndex, int textLength) public override IReadOnlyList<TextBounds> GetTextBounds(int firstTextSourceIndex, int textLength)
{ {
if (_paragraphProperties.FlowDirection == FlowDirection.LeftToRight) if (_paragraphProperties.FlowDirection == FlowDirection.LeftToRight)
@ -1295,6 +1536,11 @@ namespace Avalonia.Media.TextFormatting
var textAlignment = _paragraphProperties.TextAlignment; var textAlignment = _paragraphProperties.TextAlignment;
var paragraphFlowDirection = _paragraphProperties.FlowDirection; var paragraphFlowDirection = _paragraphProperties.FlowDirection;
if(textAlignment == TextAlignment.Justify)
{
textAlignment = TextAlignment.Start;
}
switch (textAlignment) switch (textAlignment)
{ {
case TextAlignment.Start: case TextAlignment.Start:
@ -1319,12 +1565,12 @@ namespace Avalonia.Media.TextFormatting
case TextAlignment.Center: case TextAlignment.Center:
var start = (_paragraphWidth - width) / 2; var start = (_paragraphWidth - width) / 2;
if(paragraphFlowDirection == FlowDirection.RightToLeft) if (paragraphFlowDirection == FlowDirection.RightToLeft)
{ {
start -= (widthIncludingTrailingWhitespace - width); start -= (widthIncludingTrailingWhitespace - width);
} }
return Math.Max(0, start); return Math.Max(0, start);
case TextAlignment.Right: case TextAlignment.Right:
return Math.Max(0, _paragraphWidth - widthIncludingTrailingWhitespace); return Math.Max(0, _paragraphWidth - widthIncludingTrailingWhitespace);

2
src/Avalonia.Base/Media/TextFormatting/Unicode/Codepoint.cs

@ -224,7 +224,7 @@ namespace Avalonia.Media.TextFormatting.Unicode
} }
/// <summary> /// <summary>
/// Returns <see langword="true"/> if <paramref name="value"/> is between /// Returns <see langword="true"/> if <paramref name="cp"/> is between
/// <paramref name="lowerBound"/> and <paramref name="upperBound"/>, inclusive. /// <paramref name="lowerBound"/> and <paramref name="upperBound"/>, inclusive.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

8
src/Avalonia.Base/Platform/Storage/FileIO/BclStorageFile.cs

@ -47,22 +47,22 @@ public class BclStorageFile : IStorageBookmarkFile
return Task.FromResult<IStorageFolder?>(null); return Task.FromResult<IStorageFolder?>(null);
} }
public Task<Stream> OpenRead() public Task<Stream> OpenReadAsync()
{ {
return Task.FromResult<Stream>(_fileInfo.OpenRead()); return Task.FromResult<Stream>(_fileInfo.OpenRead());
} }
public Task<Stream> OpenWrite() public Task<Stream> OpenWriteAsync()
{ {
return Task.FromResult<Stream>(_fileInfo.OpenWrite()); return Task.FromResult<Stream>(_fileInfo.OpenWrite());
} }
public virtual Task<string?> SaveBookmark() public virtual Task<string?> SaveBookmarkAsync()
{ {
return Task.FromResult<string?>(_fileInfo.FullName); return Task.FromResult<string?>(_fileInfo.FullName);
} }
public Task ReleaseBookmark() public Task ReleaseBookmarkAsync()
{ {
// No-op // No-op
return Task.CompletedTask; return Task.CompletedTask;

16
src/Avalonia.Base/Platform/Storage/FileIO/BclStorageFolder.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq;
using System.Security; using System.Security;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Metadata; using Avalonia.Metadata;
@ -43,12 +45,22 @@ public class BclStorageFolder : IStorageBookmarkFolder
return Task.FromResult<IStorageFolder?>(null); return Task.FromResult<IStorageFolder?>(null);
} }
public virtual Task<string?> SaveBookmark() public Task<IReadOnlyList<IStorageItem>> GetItemsAsync()
{
var items = _directoryInfo.GetDirectories()
.Select(d => (IStorageItem)new BclStorageFolder(d))
.Concat(_directoryInfo.GetFiles().Select(f => new BclStorageFile(f)))
.ToArray();
return Task.FromResult<IReadOnlyList<IStorageItem>>(items);
}
public virtual Task<string?> SaveBookmarkAsync()
{ {
return Task.FromResult<string?>(_directoryInfo.FullName); return Task.FromResult<string?>(_directoryInfo.FullName);
} }
public Task ReleaseBookmark() public Task ReleaseBookmarkAsync()
{ {
// No-op // No-op
return Task.CompletedTask; return Task.CompletedTask;

2
src/Avalonia.Base/Platform/Storage/IStorageBookmarkItem.cs

@ -6,7 +6,7 @@ namespace Avalonia.Platform.Storage;
[NotClientImplementable] [NotClientImplementable]
public interface IStorageBookmarkItem : IStorageItem public interface IStorageBookmarkItem : IStorageItem
{ {
Task ReleaseBookmark(); Task ReleaseBookmarkAsync();
} }
[NotClientImplementable] [NotClientImplementable]

4
src/Avalonia.Base/Platform/Storage/IStorageFile.cs

@ -18,7 +18,7 @@ public interface IStorageFile : IStorageItem
/// <summary> /// <summary>
/// Opens a stream for read access. /// Opens a stream for read access.
/// </summary> /// </summary>
Task<Stream> OpenRead(); Task<Stream> OpenReadAsync();
/// <summary> /// <summary>
/// Returns true, if file is writeable. /// Returns true, if file is writeable.
@ -28,5 +28,5 @@ public interface IStorageFile : IStorageItem
/// <summary> /// <summary>
/// Opens stream for writing to the file. /// Opens stream for writing to the file.
/// </summary> /// </summary>
Task<Stream> OpenWrite(); Task<Stream> OpenWriteAsync();
} }

11
src/Avalonia.Base/Platform/Storage/IStorageFolder.cs

@ -1,4 +1,6 @@
using Avalonia.Metadata; using System.Collections.Generic;
using System.Threading.Tasks;
using Avalonia.Metadata;
namespace Avalonia.Platform.Storage; namespace Avalonia.Platform.Storage;
@ -8,4 +10,11 @@ namespace Avalonia.Platform.Storage;
[NotClientImplementable] [NotClientImplementable]
public interface IStorageFolder : IStorageItem public interface IStorageFolder : IStorageItem
{ {
/// <summary>
/// Gets the files and subfolders in the current folder.
/// </summary>
/// <returns>
/// When this method completes successfully, it returns a list of the files and folders in the current folder. Each item in the list is represented by an <see cref="IStorageItem"/> implementation object.
/// </returns>
Task<IReadOnlyList<IStorageItem>> GetItemsAsync();
} }

2
src/Avalonia.Base/Platform/Storage/IStorageItem.cs

@ -44,7 +44,7 @@ public interface IStorageItem : IDisposable
/// <returns> /// <returns>
/// Returns identifier of a bookmark. Can be null if OS denied request. /// Returns identifier of a bookmark. Can be null if OS denied request.
/// </returns> /// </returns>
Task<string?> SaveBookmark(); Task<string?> SaveBookmarkAsync();
/// <summary> /// <summary>
/// Gets the parent folder of the current storage item. /// Gets the parent folder of the current storage item.

7
src/Avalonia.Base/Rendering/Composition/Animations/CompositionAnimation.cs

@ -1,12 +1,9 @@
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
// ReSharper disable CheckNamespace // ReSharper disable CheckNamespace
using System;
using System.Collections.Generic;
using System.Numerics; using System.Numerics;
using Avalonia.Rendering.Composition.Expressions; using Avalonia.Rendering.Composition.Expressions;
using Avalonia.Rendering.Composition.Server; using Avalonia.Rendering.Composition.Server;
using Avalonia.Rendering.Composition.Transport;
// Special license applies <see href="https://raw.githubusercontent.com/AvaloniaUI/Avalonia/master/src/Avalonia.Base/Rendering/Composition/License.md">License.md</see> // Special license applies <see href="https://raw.githubusercontent.com/AvaloniaUI/Avalonia/master/src/Avalonia.Base/Rendering/Composition/License.md">License.md</see>
@ -16,10 +13,10 @@ namespace Avalonia.Rendering.Composition.Animations
/// This is the base class for ExpressionAnimation and KeyFrameAnimation. /// This is the base class for ExpressionAnimation and KeyFrameAnimation.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Use the <see cref="CompositionObject.StartAnimation"/> method to start the animation. /// Use the <see cref="CompositionObject.StartAnimation(string , CompositionAnimation)"/> method to start the animation.
/// Value parameters (as opposed to reference parameters which are set using <see cref="SetReferenceParameter"/>) /// Value parameters (as opposed to reference parameters which are set using <see cref="SetReferenceParameter"/>)
/// are copied and "embedded" into an expression at the time CompositionObject.StartAnimation is called. /// are copied and "embedded" into an expression at the time CompositionObject.StartAnimation is called.
/// Changing the value of the variable after <see cref="CompositionObject.StartAnimation"/> is called will not affect /// Changing the value of the variable after <see cref="CompositionObject.StartAnimation(string , CompositionAnimation)"/> is called will not affect
/// the value of the ExpressionAnimation. /// the value of the ExpressionAnimation.
/// See the remarks section of ExpressionAnimation for additional information. /// See the remarks section of ExpressionAnimation for additional information.
/// </remarks> /// </remarks>

2
src/Avalonia.Base/Rendering/Composition/Animations/ExpressionAnimation.cs

@ -16,7 +16,7 @@ namespace Avalonia.Rendering.Composition.Animations
/// This contrasts <see cref="KeyFrameAnimation"/>s, which use an interpolator to define how the animating /// This contrasts <see cref="KeyFrameAnimation"/>s, which use an interpolator to define how the animating
/// property changes over time. The mathematical equation can be defined using references to properties /// property changes over time. The mathematical equation can be defined using references to properties
/// of Composition objects, mathematical functions and operators and Input. /// of Composition objects, mathematical functions and operators and Input.
/// Use the <see cref="CompositionObject.StartAnimation"/> method to start the animation. /// Use the <see cref="CompositionObject.StartAnimation(string , CompositionAnimation)"/> method to start the animation.
/// </remarks> /// </remarks>
public class ExpressionAnimation : CompositionAnimation public class ExpressionAnimation : CompositionAnimation
{ {

4
src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimation.cs

@ -24,9 +24,9 @@ namespace Avalonia.Rendering.Composition.Animations
/// The delay behavior of the key frame animation. /// The delay behavior of the key frame animation.
/// </summary> /// </summary>
public AnimationDelayBehavior DelayBehavior { get; set; } public AnimationDelayBehavior DelayBehavior { get; set; }
/// <summary> /// <summary>
/// Delay before the animation starts after <see cref="CompositionObject.StartAnimation"/> is called. /// Delay before the animation starts after <see cref="CompositionObject.StartAnimation(string , CompositionAnimation)"/> is called.
/// </summary> /// </summary>
public System.TimeSpan DelayTime { get; set; } public System.TimeSpan DelayTime { get; set; }

4
src/Avalonia.Base/Rendering/SceneGraph/GeometryNode.cs

@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Media.Immutable; using Avalonia.Media.Immutable;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph namespace Avalonia.Rendering.SceneGraph
{ {
@ -19,7 +17,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <param name="brush">The fill brush.</param> /// <param name="brush">The fill brush.</param>
/// <param name="pen">The stroke pen.</param> /// <param name="pen">The stroke pen.</param>
/// <param name="geometry">The geometry.</param> /// <param name="geometry">The geometry.</param>
/// <param name="childScenes">Child scenes for drawing visual brushes.</param> /// <param name="aux">Auxiliary data required to draw the brush.</param>
public GeometryNode(Matrix transform, public GeometryNode(Matrix transform,
IBrush? brush, IBrush? brush,
IPen? pen, IPen? pen,

6
src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs

@ -1,10 +1,6 @@
using System; using System;
using System.Collections.Generic;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Media.Immutable;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph namespace Avalonia.Rendering.SceneGraph
{ {
@ -19,7 +15,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <param name="transform">The transform.</param> /// <param name="transform">The transform.</param>
/// <param name="foreground">The foreground brush.</param> /// <param name="foreground">The foreground brush.</param>
/// <param name="glyphRun">The glyph run to draw.</param> /// <param name="glyphRun">The glyph run to draw.</param>
/// <param name="childScenes">Child scenes for drawing visual brushes.</param> /// <param name="aux">Auxiliary data required to draw the brush.</param>
public GlyphRunNode( public GlyphRunNode(
Matrix transform, Matrix transform,
IBrush foreground, IBrush foreground,

4
src/Avalonia.Base/Rendering/SceneGraph/LineNode.cs

@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Media.Immutable; using Avalonia.Media.Immutable;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph namespace Avalonia.Rendering.SceneGraph
{ {
@ -19,7 +17,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <param name="pen">The stroke pen.</param> /// <param name="pen">The stroke pen.</param>
/// <param name="p1">The start point of the line.</param> /// <param name="p1">The start point of the line.</param>
/// <param name="p2">The end point of the line.</param> /// <param name="p2">The end point of the line.</param>
/// <param name="childScenes">Child scenes for drawing visual brushes.</param> /// <param name="aux">Auxiliary data required to draw the brush.</param>
public LineNode( public LineNode(
Matrix transform, Matrix transform,
IPen pen, IPen pen,

2
src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs

@ -17,7 +17,7 @@ namespace Avalonia.Rendering.SceneGraph
/// </summary> /// </summary>
/// <param name="mask">The opacity mask to push.</param> /// <param name="mask">The opacity mask to push.</param>
/// <param name="bounds">The bounds of the mask.</param> /// <param name="bounds">The bounds of the mask.</param>
/// <param name="childScenes">Child scenes for drawing visual brushes.</param> /// <param name="aux">Auxiliary data required to draw the brush.</param>
public OpacityMaskNode(IBrush mask, Rect bounds, IDisposable? aux = null) public OpacityMaskNode(IBrush mask, Rect bounds, IDisposable? aux = null)
: base(Rect.Empty, Matrix.Identity, aux) : base(Rect.Empty, Matrix.Identity, aux)
{ {

2
src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs

@ -20,7 +20,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <param name="pen">The stroke pen.</param> /// <param name="pen">The stroke pen.</param>
/// <param name="rect">The rectangle to draw.</param> /// <param name="rect">The rectangle to draw.</param>
/// <param name="boxShadows">The box shadow parameters</param> /// <param name="boxShadows">The box shadow parameters</param>
/// <param name="childScenes">Child scenes for drawing visual brushes.</param> /// <param name="aux">Auxiliary data required to draw the brush.</param>
public RectangleNode( public RectangleNode(
Matrix transform, Matrix transform,
IBrush? brush, IBrush? brush,

2
src/Avalonia.Base/Utilities/MathUtilities.cs

@ -255,7 +255,7 @@ namespace Avalonia.Utilities
/// <summary> /// <summary>
/// Clamps a value between a minimum and maximum value. /// Clamps a value between a minimum and maximum value.
/// </summary> /// </summary>
/// <param name="val">The value.</param> /// <param name="value">The value.</param>
/// <param name="min">The minimum value.</param> /// <param name="min">The minimum value.</param>
/// <param name="max">The maximum value.</param> /// <param name="max">The maximum value.</param>
/// <returns>The clamped value.</returns> /// <returns>The clamped value.</returns>

4
src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

@ -326,8 +326,8 @@ namespace Avalonia.Build.Tasks
var op = i[c].Operand as MethodReference; var op = i[c].Operand as MethodReference;
// TODO: Throw an error // TODO: Throw an error
// This usually happens when same XAML resource was added twice for some weird reason // This usually happens when the same XAML resource was added twice for some weird reason
// We currently support it for dual-named default theme resource // We currently support it for dual-named default theme resources
if (op != null if (op != null
&& op.Name == TrampolineName) && op.Name == TrampolineName)
{ {

188
src/Avalonia.Controls.ColorPicker/Themes/Default/ColorSlider.xaml

@ -1,188 +0,0 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:CompileBindings="True">
<Style Selector="Thumb.ColorSliderThumbStyle">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="10" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style Selector="ColorSlider:horizontal">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="10" />
<Setter Property="Height" Value="20" />
<Setter Property="Template">
<ControlTemplate TargetType="{x:Type ColorSlider}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid Margin="{TemplateBinding Padding}">
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{StaticResource ColorControlCheckeredBackgroundBrush}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{TemplateBinding Background}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Track Name="PART_Track"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Minimum="{TemplateBinding Minimum}"
Maximum="{TemplateBinding Maximum}"
Value="{TemplateBinding Value, Mode=TwoWay}"
IsDirectionReversed="{TemplateBinding IsDirectionReversed}"
Orientation="Horizontal">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.DecreaseButton>
<Track.IncreaseButton>
<RepeatButton Name="PART_IncreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.IncreaseButton>
<Thumb Classes="ColorSliderThumbStyle"
Name="ColorSliderThumb"
Margin="0"
Padding="0"
DataContext="{TemplateBinding Value}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Height}" />
</Track>
</Grid>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="ColorSlider:vertical">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="10" />
<Setter Property="Width" Value="20" />
<Setter Property="Template">
<ControlTemplate TargetType="{x:Type ColorSlider}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid Margin="{TemplateBinding Padding}">
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{StaticResource ColorControlCheckeredBackgroundBrush}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{TemplateBinding Background}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Track Name="PART_Track"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Minimum="{TemplateBinding Minimum}"
Maximum="{TemplateBinding Maximum}"
Value="{TemplateBinding Value, Mode=TwoWay}"
IsDirectionReversed="{TemplateBinding IsDirectionReversed}"
Orientation="Vertical">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.DecreaseButton>
<Track.IncreaseButton>
<RepeatButton Name="PART_IncreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.IncreaseButton>
<Thumb Classes="ColorSliderThumbStyle"
Name="ColorSliderThumb"
Margin="0"
Padding="0"
DataContext="{TemplateBinding Value}"
Height="{TemplateBinding Width}"
Width="{TemplateBinding Width}" />
</Track>
</Grid>
</Border>
</ControlTemplate>
</Setter>
</Style>
<!-- Normal State -->
<Style Selector="ColorSlider /template/ Thumb.ColorSliderThumbStyle">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeForegroundBrush}" />
<Setter Property="BorderThickness" Value="3" />
</Style>
<!-- Selector/Thumb Color -->
<Style Selector="ColorSlider:pointerover /template/ Thumb.ColorSliderThumbStyle">
<Setter Property="Opacity" Value="0.75" />
</Style>
<Style Selector="ColorSlider:pointerover:dark-selector /template/ Thumb.ColorSliderThumbStyle">
<Setter Property="Opacity" Value="0.7" />
</Style>
<Style Selector="ColorSlider:pointerover:light-selector /template/ Thumb.ColorSliderThumbStyle">
<Setter Property="Opacity" Value="0.8" />
</Style>
<Style Selector="ColorSlider:dark-selector /template/ Thumb.ColorSliderThumbStyle">
<Setter Property="BorderBrush" Value="Black" />
</Style>
<Style Selector="ColorSlider:light-selector /template/ Thumb.ColorSliderThumbStyle">
<Setter Property="BorderBrush" Value="White" />
</Style>
</Styles>

44
src/Avalonia.Controls.ColorPicker/Themes/Default/Default.xaml

@ -1,44 +0,0 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:Avalonia.Controls.Converters">
<Styles.Resources>
<!-- Shared Resources -->
<VisualBrush x:Key="ColorControlCheckeredBackgroundBrush"
TileMode="Tile"
Stretch="Uniform"
DestinationRect="0,0,8,8">
<VisualBrush.Visual>
<DrawingPresenter Width="8"
Height="8">
<DrawingGroup>
<GeometryDrawing Geometry="M0,0 L2,0 2,2, 0,2Z"
Brush="Transparent" />
<GeometryDrawing Geometry="M0,1 L2,1 2,2, 1,2 1,0 0,0Z"
Brush="#19808080" />
</DrawingGroup>
</DrawingPresenter>
</VisualBrush.Visual>
</VisualBrush>
<!-- Shared Converters -->
<converters:EnumToBoolConverter x:Key="EnumToBoolConverter" />
<converters:ToBrushConverter x:Key="ToBrushConverter" />
<converters:CornerRadiusFilterConverter x:Key="LeftCornerRadiusFilterConverter" Filter="TopLeft, BottomLeft"/>
<converters:CornerRadiusFilterConverter x:Key="RightCornerRadiusFilterConverter" Filter="TopRight, BottomRight"/>
<converters:CornerRadiusFilterConverter x:Key="TopCornerRadiusFilterConverter" Filter="TopLeft, TopRight"/>
<converters:CornerRadiusFilterConverter x:Key="BottomCornerRadiusFilterConverter" Filter="BottomLeft, BottomRight"/>
<converters:CornerRadiusToDoubleConverter x:Key="TopLeftCornerRadiusConverter" Corner="TopLeft" />
<converters:CornerRadiusToDoubleConverter x:Key="BottomRightCornerRadiusConverter" Corner="BottomRight" />
</Styles.Resources>
<!-- Primitives -->
<StyleInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Default/ColorPreviewer.xaml" />
<StyleInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Default/ColorSlider.xaml" />
<StyleInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Default/ColorSpectrum.xaml" />
<!-- Controls -->
<!-- Note the ColorPicker and ColorView are unsupported in the default theme -->
<!-- These controls depend on fluent styles for TabControl, Button, TextBox, etc. -->
</Styles>

20
src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorPicker.xaml

@ -3,9 +3,6 @@
xmlns:controls="using:Avalonia.Controls" xmlns:controls="using:Avalonia.Controls"
x:CompileBindings="True"> x:CompileBindings="True">
<!-- This must follow OverlayCornerRadius -->
<CornerRadius x:Key="TopOverlayCornerRadius">5,5,0,0</CornerRadius>
<ControlTheme x:Key="{x:Type ColorPicker}" <ControlTheme x:Key="{x:Type ColorPicker}"
TargetType="ColorPicker"> TargetType="ColorPicker">
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" /> <Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
@ -25,7 +22,7 @@
Padding="0,0,10,0" Padding="0,0,10,0"
UseLayoutRounding="False"> UseLayoutRounding="False">
<DropDownButton.Styles> <DropDownButton.Styles>
<Style Selector="FlyoutPresenter.NoPadding"> <Style Selector="FlyoutPresenter.nopadding">
<Setter Property="Padding" Value="0" /> <Setter Property="Padding" Value="0" />
</Style> </Style>
</DropDownButton.Styles> </DropDownButton.Styles>
@ -45,7 +42,7 @@
</Panel> </Panel>
</DropDownButton.Content> </DropDownButton.Content>
<DropDownButton.Flyout> <DropDownButton.Flyout>
<Flyout FlyoutPresenterClasses="NoPadding"> <Flyout FlyoutPresenterClasses="nopadding">
<ColorView x:Name="FlyoutColorView" <ColorView x:Name="FlyoutColorView"
Color="{Binding Color, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" Color="{Binding Color, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
ColorModel="{Binding ColorModel, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" ColorModel="{Binding ColorModel, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
@ -73,7 +70,12 @@
PaletteColors="{TemplateBinding PaletteColors}" PaletteColors="{TemplateBinding PaletteColors}"
PaletteColumnCount="{TemplateBinding PaletteColumnCount}" PaletteColumnCount="{TemplateBinding PaletteColumnCount}"
Palette="{TemplateBinding Palette}" Palette="{TemplateBinding Palette}"
SelectedIndex="{Binding SelectedIndex, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" /> SelectedIndex="{Binding SelectedIndex, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<ColorView.Resources>
<!-- This radius must follow OverlayCornerRadius -->
<CornerRadius x:Key="ColorViewTabBackgroundCornerRadius">5,5,0,0</CornerRadius>
</ColorView.Resources>
</ColorView>
</Flyout> </Flyout>
</DropDownButton.Flyout> </DropDownButton.Flyout>
</DropDownButton> </DropDownButton>
@ -81,10 +83,4 @@
</Setter> </Setter>
</ControlTheme> </ControlTheme>
<!-- Adjust Background within Flyout -->
<!-- Note: This is implemented but there seems to be an issue and the selector can't match across the Flyout -->
<!--<Style Selector="ColorPicker /template/ ColorView#FlyoutColorView /template/ Border#TabBackgroundBorder">
<Setter Property="CornerRadius" Value="{DynamicResource TopOverlayCornerRadius}" />
</Style>-->
</ResourceDictionary> </ResourceDictionary>

4
src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorView.xaml

@ -77,6 +77,8 @@
17.7761 14 17.5 14H9.94999ZM7.5 16C6.67157 16 6 15.3284 6 14.5C6 13.6716 6.67157 13 7.5 17.7761 14 17.5 14H9.94999ZM7.5 16C6.67157 16 6 15.3284 6 14.5C6 13.6716 6.67157 13 7.5
13C8.32843 13 9 13.6716 9 14.5C9 15.3284 8.32843 16 7.5 16Z 13C8.32843 13 9 13.6716 9 14.5C9 15.3284 8.32843 16 7.5 16Z
</PathGeometry> </PathGeometry>
<!-- This radius should follow ControlCornerRadius -->
<CornerRadius x:Key="ColorViewTabBackgroundCornerRadius">3</CornerRadius>
<ControlTheme x:Key="{x:Type ColorView}" <ControlTheme x:Key="{x:Type ColorView}"
TargetType="ColorView"> TargetType="ColorView">
@ -97,7 +99,7 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Top" VerticalAlignment="Top"
Background="{DynamicResource SystemControlBackgroundBaseLowBrush}" Background="{DynamicResource SystemControlBackgroundBaseLowBrush}"
CornerRadius="{TemplateBinding CornerRadius}" /> CornerRadius="{DynamicResource ColorViewTabBackgroundCornerRadius}" />
<Border x:Name="ContentBackgroundBorder" <Border x:Name="ContentBackgroundBorder"
Grid.Row="0" Grid.Row="0"
Grid.RowSpan="2" Grid.RowSpan="2"

23
src/Avalonia.Controls.ColorPicker/Themes/Default/ColorPreviewer.xaml → src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorPreviewer.xaml

@ -1,15 +1,14 @@
<Styles xmlns="https://github.com/avaloniaui" <ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:pc="using:Avalonia.Controls.Primitives.Converters" xmlns:pc="using:Avalonia.Controls.Primitives.Converters"
x:CompileBindings="True"> x:CompileBindings="True">
<Styles.Resources> <pc:AccentColorConverter x:Key="AccentColorConverter" />
<pc:AccentColorConverter x:Key="AccentColorConverter" /> <x:Double x:Key="ColorPreviewerAccentSectionWidth">80</x:Double>
<x:Double x:Key="ColorPreviewerAccentSectionWidth">80</x:Double> <x:Double x:Key="ColorPreviewerAccentSectionHeight">40</x:Double>
<x:Double x:Key="ColorPreviewerAccentSectionHeight">40</x:Double>
</Styles.Resources>
<Style Selector="ColorPreviewer"> <ControlTheme x:Key="{x:Type ColorPreviewer}"
TargetType="ColorPreviewer">
<Setter Property="Height" Value="70" /> <Setter Property="Height" Value="70" />
<Setter Property="CornerRadius" Value="0" /> <Setter Property="CornerRadius" Value="0" />
<Setter Property="Template"> <Setter Property="Template">
@ -97,6 +96,6 @@
</Panel> </Panel>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </ControlTheme>
</Styles> </ResourceDictionary>

190
src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorSlider.xaml

@ -0,0 +1,190 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:CompileBindings="True">
<ControlTheme x:Key="ColorSliderThumbTheme"
TargetType="Thumb">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeForegroundBrush}" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="CornerRadius" Value="10" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</ControlTheme>
<ControlTheme x:Key="{x:Type ColorSlider}"
TargetType="ColorSlider">
<Style Selector="^:horizontal">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="10" />
<Setter Property="Height" Value="20" />
<Setter Property="Template">
<ControlTemplate TargetType="{x:Type ColorSlider}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid Margin="{TemplateBinding Padding}">
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{StaticResource ColorControlCheckeredBackgroundBrush}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{TemplateBinding Background}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Track Name="PART_Track"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Minimum="{TemplateBinding Minimum}"
Maximum="{TemplateBinding Maximum}"
Value="{TemplateBinding Value, Mode=TwoWay}"
IsDirectionReversed="{TemplateBinding IsDirectionReversed}"
Orientation="Horizontal">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.DecreaseButton>
<Track.IncreaseButton>
<RepeatButton Name="PART_IncreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.IncreaseButton>
<Thumb Name="ColorSliderThumb"
Theme="{StaticResource ColorSliderThumbTheme}"
Margin="0"
Padding="0"
DataContext="{TemplateBinding Value}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Height}" />
</Track>
</Grid>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="^:vertical">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="10" />
<Setter Property="Width" Value="20" />
<Setter Property="Template">
<ControlTemplate TargetType="{x:Type ColorSlider}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid Margin="{TemplateBinding Padding}">
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{StaticResource ColorControlCheckeredBackgroundBrush}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{TemplateBinding Background}"
RadiusX="{TemplateBinding CornerRadius, Converter={StaticResource TopLeftCornerRadiusConverter}}"
RadiusY="{TemplateBinding CornerRadius, Converter={StaticResource BottomRightCornerRadiusConverter}}" />
<Track Name="PART_Track"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Minimum="{TemplateBinding Minimum}"
Maximum="{TemplateBinding Maximum}"
Value="{TemplateBinding Value, Mode=TwoWay}"
IsDirectionReversed="{TemplateBinding IsDirectionReversed}"
Orientation="Vertical">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.DecreaseButton>
<Track.IncreaseButton>
<RepeatButton Name="PART_IncreaseButton"
Background="Transparent"
Focusable="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Border Name="FocusTarget"
Background="Transparent"
Margin="0,-10" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.IncreaseButton>
<Thumb Name="ColorSliderThumb"
Theme="{StaticResource ColorSliderThumbTheme}"
Margin="0"
Padding="0"
DataContext="{TemplateBinding Value}"
Height="{TemplateBinding Width}"
Width="{TemplateBinding Width}" />
</Track>
</Grid>
</Border>
</ControlTemplate>
</Setter>
</Style>
<!-- Selector/Thumb Color -->
<Style Selector="^:pointerover /template/ Thumb#ColorSliderThumb">
<Setter Property="Opacity" Value="0.75" />
</Style>
<Style Selector="^:pointerover:dark-selector /template/ Thumb#ColorSliderThumb">
<Setter Property="Opacity" Value="0.7" />
</Style>
<Style Selector="^:pointerover:light-selector /template/ Thumb#ColorSliderThumb">
<Setter Property="Opacity" Value="0.8" />
</Style>
<Style Selector="^:dark-selector /template/ Thumb#ColorSliderThumb">
<Setter Property="BorderBrush" Value="Black" />
</Style>
<Style Selector="^:light-selector /template/ Thumb#ColorSliderThumb">
<Setter Property="BorderBrush" Value="White" />
</Style>
</ControlTheme>
</ResourceDictionary>

94
src/Avalonia.Controls.ColorPicker/Themes/Default/ColorSpectrum.xaml → src/Avalonia.Controls.ColorPicker/Themes/Simple/ColorSpectrum.xaml

@ -1,9 +1,10 @@
<Styles xmlns="https://github.com/avaloniaui" <ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Avalonia.Controls" xmlns:controls="using:Avalonia.Controls"
x:CompileBindings="True"> x:CompileBindings="True">
<Style Selector="ColorSpectrum"> <ControlTheme x:Key="{x:Type ColorSpectrum}"
TargetType="ColorSpectrum">
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type ColorSpectrum}"> <ControlTemplate TargetType="{x:Type ColorSpectrum}">
@ -79,50 +80,51 @@
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Style>
<!-- Normal --> <!-- Normal -->
<!-- Separating this allows easier customization in applications --> <!-- Separating this allows easier customization in applications -->
<Style Selector="ColorSpectrum /template/ Ellipse#BorderEllipse, <Style Selector="^ /template/ Ellipse#BorderEllipse,
ColorSpectrum /template/ Rectangle#BorderRectangle"> ^ /template/ Rectangle#BorderRectangle">
<Setter Property="Stroke" Value="{DynamicResource ThemeBorderLowBrush}" /> <Setter Property="Stroke" Value="{DynamicResource ThemeBorderLowBrush}" />
<Setter Property="StrokeThickness" Value="1" /> <Setter Property="StrokeThickness" Value="1" />
</Style> </Style>
<!-- Focus --> <!-- Focus -->
<Style Selector="ColorSpectrum /template/ Ellipse#FocusEllipse"> <Style Selector="^ /template/ Ellipse#FocusEllipse">
<Setter Property="IsVisible" Value="False" /> <Setter Property="IsVisible" Value="False" />
</Style> </Style>
<Style Selector="ColorSpectrum:focus-visible /template/ Ellipse#FocusEllipse"> <Style Selector="^:focus-visible /template/ Ellipse#FocusEllipse">
<Setter Property="IsVisible" Value="True" /> <Setter Property="IsVisible" Value="True" />
</Style> </Style>
<!-- Selector Color --> <!-- Selector Color -->
<Style Selector="ColorSpectrum /template/ Ellipse#FocusEllipse"> <Style Selector="^ /template/ Ellipse#FocusEllipse">
<Setter Property="Stroke" Value="White" /> <Setter Property="Stroke" Value="White" />
</Style> </Style>
<Style Selector="ColorSpectrum /template/ Ellipse#SelectionEllipse"> <Style Selector="^ /template/ Ellipse#SelectionEllipse">
<Setter Property="Stroke" Value="Black" /> <Setter Property="Stroke" Value="Black" />
</Style> </Style>
<Style Selector="ColorSpectrum:light-selector /template/ Ellipse#FocusEllipse"> <Style Selector="^:light-selector /template/ Ellipse#FocusEllipse">
<Setter Property="Stroke" Value="Black" /> <Setter Property="Stroke" Value="Black" />
</Style> </Style>
<Style Selector="ColorSpectrum:light-selector /template/ Ellipse#SelectionEllipse"> <Style Selector="^:light-selector /template/ Ellipse#SelectionEllipse">
<Setter Property="Stroke" Value="White" /> <Setter Property="Stroke" Value="White" />
</Style> </Style>
<Style Selector="ColorSpectrum:pointerover /template/ Ellipse#SelectionEllipse"> <Style Selector="^:pointerover /template/ Ellipse#SelectionEllipse">
<Setter Property="Opacity" Value="0.8" /> <Setter Property="Opacity" Value="0.8" />
</Style> </Style>
<!-- Selector Size --> <!-- Selector Size -->
<Style Selector="ColorSpectrum /template/ Panel#PART_SelectionEllipsePanel"> <Style Selector="^ /template/ Panel#PART_SelectionEllipsePanel">
<Setter Property="Width" Value="16" /> <Setter Property="Width" Value="16" />
<Setter Property="Height" Value="16" /> <Setter Property="Height" Value="16" />
</Style> </Style>
<Style Selector="ColorSpectrum:large-selector /template/ Panel#PART_SelectionEllipsePanel"> <Style Selector="^:large-selector /template/ Panel#PART_SelectionEllipsePanel">
<Setter Property="Width" Value="48" /> <Setter Property="Width" Value="48" />
<Setter Property="Height" Value="48" /> <Setter Property="Height" Value="48" />
</Style> </Style>
</Styles> </ControlTheme>
</ResourceDictionary>

50
src/Avalonia.Controls.ColorPicker/Themes/Simple/Simple.xaml

@ -0,0 +1,50 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:Avalonia.Controls.Converters">
<Styles.Resources>
<ResourceDictionary>
<!-- Shared Resources -->
<VisualBrush x:Key="ColorControlCheckeredBackgroundBrush"
TileMode="Tile"
Stretch="Uniform"
DestinationRect="0,0,8,8">
<VisualBrush.Visual>
<DrawingPresenter Width="8"
Height="8">
<DrawingGroup>
<GeometryDrawing Geometry="M0,0 L2,0 2,2, 0,2Z"
Brush="Transparent" />
<GeometryDrawing Geometry="M0,1 L2,1 2,2, 1,2 1,0 0,0Z"
Brush="#19808080" />
</DrawingGroup>
</DrawingPresenter>
</VisualBrush.Visual>
</VisualBrush>
<!-- Shared Converters -->
<converters:EnumToBoolConverter x:Key="EnumToBoolConverter" />
<converters:ToBrushConverter x:Key="ToBrushConverter" />
<converters:CornerRadiusFilterConverter x:Key="LeftCornerRadiusFilterConverter" Filter="TopLeft, BottomLeft"/>
<converters:CornerRadiusFilterConverter x:Key="RightCornerRadiusFilterConverter" Filter="TopRight, BottomRight"/>
<converters:CornerRadiusFilterConverter x:Key="TopCornerRadiusFilterConverter" Filter="TopLeft, TopRight"/>
<converters:CornerRadiusFilterConverter x:Key="BottomCornerRadiusFilterConverter" Filter="BottomLeft, BottomRight"/>
<converters:CornerRadiusToDoubleConverter x:Key="TopLeftCornerRadiusConverter" Corner="TopLeft" />
<converters:CornerRadiusToDoubleConverter x:Key="BottomRightCornerRadiusConverter" Corner="BottomRight" />
<ResourceDictionary.MergedDictionaries>
<!-- Primitives -->
<ResourceInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Simple/ColorPreviewer.xaml" />
<ResourceInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Simple/ColorSlider.xaml" />
<ResourceInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Simple/ColorSpectrum.xaml" />
<!-- Controls -->
<!-- Note the ColorPicker and ColorView are currently unsupported in the simple theme -->
<!-- These controls depend on fluent styles for TabControl, Button, TextBox, etc. -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Styles.Resources>
</Styles>

4
src/Avalonia.Controls.DataGrid/Themes/Default.xaml → src/Avalonia.Controls.DataGrid/Themes/Simple.xaml

@ -223,7 +223,7 @@
</Style> </Style>
</ControlTheme> </ControlTheme>
<ControlTheme x:Key="DefaultDataGridRowGroupExpanderButtonTheme" <ControlTheme x:Key="SimpleDataGridRowGroupExpanderButtonTheme"
TargetType="ToggleButton"> TargetType="ToggleButton">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
@ -270,7 +270,7 @@
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}" CornerRadius="{TemplateBinding CornerRadius}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
Theme="{StaticResource DefaultDataGridRowGroupExpanderButtonTheme}" /> Theme="{StaticResource SimpleDataGridRowGroupExpanderButtonTheme}" />
<StackPanel Grid.Row="1" <StackPanel Grid.Row="1"
Grid.Column="3" Grid.Column="3"

56
src/Avalonia.Controls/Button.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows.Input; using System.Windows.Input;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
@ -281,24 +282,29 @@ namespace Avalonia.Controls
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {
if (e.Key == Key.Enter) switch (e.Key)
{ {
OnClick(); case Key.Enter:
e.Handled = true;
}
else if (e.Key == Key.Space)
{
if (ClickMode == ClickMode.Press)
{
OnClick(); OnClick();
e.Handled = true;
break;
case Key.Space:
{
if (ClickMode == ClickMode.Press)
{
OnClick();
}
IsPressed = true;
e.Handled = true;
break;
} }
IsPressed = true;
e.Handled = true; case Key.Escape when Flyout != null:
} // If Flyout doesn't have focusable content, close the flyout here
else if (e.Key == Key.Escape && Flyout != null) CloseFlyout();
{ break;
// If Flyout doesn't have focusable content, close the flyout here
Flyout.Hide();
} }
base.OnKeyDown(e); base.OnKeyDown(e);
@ -327,7 +333,14 @@ namespace Avalonia.Controls
{ {
if (IsEffectivelyEnabled) if (IsEffectivelyEnabled)
{ {
OpenFlyout(); if (_isFlyoutOpen)
{
CloseFlyout();
}
else
{
OpenFlyout();
}
var e = new RoutedEventArgs(ClickEvent); var e = new RoutedEventArgs(ClickEvent);
RaiseEvent(e); RaiseEvent(e);
@ -348,6 +361,14 @@ namespace Avalonia.Controls
Flyout?.ShowAt(this); Flyout?.ShowAt(this);
} }
/// <summary>
/// Closes the button's flyout.
/// </summary>
protected virtual void CloseFlyout()
{
Flyout?.Hide();
}
/// <summary> /// <summary>
/// Invoked when the button's flyout is opened. /// Invoked when the button's flyout is opened.
/// </summary> /// </summary>
@ -494,8 +515,7 @@ namespace Avalonia.Controls
// If flyout is changed while one is already open, make sure we // If flyout is changed while one is already open, make sure we
// close the old one first // close the old one first
if (oldFlyout != null && if (oldFlyout != null && oldFlyout.IsOpen)
oldFlyout.IsOpen)
{ {
oldFlyout.Hide(); oldFlyout.Hide();
} }

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

@ -12,17 +12,12 @@ namespace Avalonia.Controls.Primitives
{ {
public abstract class FlyoutBase : AvaloniaObject, IPopupHostProvider public abstract class FlyoutBase : AvaloniaObject, IPopupHostProvider
{ {
static FlyoutBase()
{
Control.ContextFlyoutProperty.Changed.Subscribe(OnContextFlyoutPropertyChanged);
}
/// <summary> /// <summary>
/// Defines the <see cref="IsOpen"/> property /// Defines the <see cref="IsOpen"/> property
/// </summary> /// </summary>
public static readonly DirectProperty<FlyoutBase, bool> IsOpenProperty = public static readonly DirectProperty<FlyoutBase, bool> IsOpenProperty =
AvaloniaProperty.RegisterDirect<FlyoutBase, bool>(nameof(IsOpen), AvaloniaProperty.RegisterDirect<FlyoutBase, bool>(nameof(IsOpen),
x => x.IsOpen); x => x.IsOpen);
/// <summary> /// <summary>
/// Defines the <see cref="Target"/> property /// Defines the <see cref="Target"/> property
@ -43,6 +38,14 @@ namespace Avalonia.Controls.Primitives
AvaloniaProperty.RegisterDirect<FlyoutBase, FlyoutShowMode>(nameof(ShowMode), AvaloniaProperty.RegisterDirect<FlyoutBase, FlyoutShowMode>(nameof(ShowMode),
x => x.ShowMode, (x, v) => x.ShowMode = v); x => x.ShowMode, (x, v) => x.ShowMode = v);
/// <summary>
/// Defines the <see cref="OverlayInputPassThroughElement"/> property
/// </summary>
public static readonly DirectProperty<FlyoutBase, IInputElement?> OverlayInputPassThroughElementProperty =
Popup.OverlayInputPassThroughElementProperty.AddOwner<FlyoutBase>(
o => o._overlayInputPassThroughElement,
(o, v) => o._overlayInputPassThroughElement = v);
/// <summary> /// <summary>
/// Defines the AttachedFlyout property /// Defines the AttachedFlyout property
/// </summary> /// </summary>
@ -57,6 +60,12 @@ namespace Avalonia.Controls.Primitives
private PixelRect? _enlargePopupRectScreenPixelRect; private PixelRect? _enlargePopupRectScreenPixelRect;
private IDisposable? _transientDisposable; private IDisposable? _transientDisposable;
private Action<IPopupHost?>? _popupHostChangedHandler; private Action<IPopupHost?>? _popupHostChangedHandler;
private IInputElement? _overlayInputPassThroughElement;
static FlyoutBase()
{
Control.ContextFlyoutProperty.Changed.Subscribe(OnContextFlyoutPropertyChanged);
}
public FlyoutBase() public FlyoutBase()
{ {
@ -101,11 +110,21 @@ namespace Avalonia.Controls.Primitives
private set => SetAndRaise(TargetProperty, ref _target, value); private set => SetAndRaise(TargetProperty, ref _target, value);
} }
/// <summary>
/// Gets or sets an element that should receive pointer input events even when underneath
/// the flyout's overlay.
/// </summary>
public IInputElement? OverlayInputPassThroughElement
{
get => _overlayInputPassThroughElement;
set => SetAndRaise(OverlayInputPassThroughElementProperty, ref _overlayInputPassThroughElement, value);
}
IPopupHost? IPopupHostProvider.PopupHost => Popup?.Host; IPopupHost? IPopupHostProvider.PopupHost => Popup?.Host;
event Action<IPopupHost?>? IPopupHostProvider.PopupHostChanged event Action<IPopupHost?>? IPopupHostProvider.PopupHostChanged
{ {
add => _popupHostChangedHandler += value; add => _popupHostChangedHandler += value;
remove => _popupHostChangedHandler -= value; remove => _popupHostChangedHandler -= value;
} }
@ -175,8 +194,9 @@ namespace Avalonia.Controls.Primitives
IsOpen = false; IsOpen = false;
Popup.IsOpen = false; Popup.IsOpen = false;
((ISetLogicalParent)Popup).SetParent(null); ((ISetLogicalParent)Popup).SetParent(null);
// Ensure this isn't active // Ensure this isn't active
_transientDisposable?.Dispose(); _transientDisposable?.Dispose();
_transientDisposable = null; _transientDisposable = null;
@ -231,6 +251,8 @@ namespace Avalonia.Controls.Primitives
Popup.Child = CreatePresenter(); Popup.Child = CreatePresenter();
} }
Popup.OverlayInputPassThroughElement = OverlayInputPassThroughElement;
if (CancelOpening()) if (CancelOpening())
{ {
return false; return false;
@ -356,10 +378,13 @@ namespace Avalonia.Controls.Primitives
private Popup CreatePopup() private Popup CreatePopup()
{ {
var popup = new Popup(); var popup = new Popup
popup.WindowManagerAddShadowHint = false; {
popup.IsLightDismissEnabled = true; WindowManagerAddShadowHint = false,
popup.OverlayDismissEventPassThrough = true; IsLightDismissEnabled = true,
//Note: This is required to prevent Button.Flyout from opening the flyout again after dismiss.
OverlayDismissEventPassThrough = false
};
popup.Opened += OnPopupOpened; popup.Opened += OnPopupOpened;
popup.Closed += OnPopupClosed; popup.Closed += OnPopupClosed;
@ -372,7 +397,7 @@ namespace Avalonia.Controls.Primitives
{ {
IsOpen = true; IsOpen = true;
_popupHostChangedHandler?.Invoke(Popup!.Host); _popupHostChangedHandler?.Invoke(Popup.Host);
} }
private void OnPopupClosing(object? sender, CancelEventArgs e) private void OnPopupClosing(object? sender, CancelEventArgs e)

7
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -9,6 +9,7 @@ using Avalonia.VisualTree;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Media.Immutable; using Avalonia.Media.Immutable;
using Avalonia.Controls.Documents; using Avalonia.Controls.Documents;
using Avalonia.Media.TextFormatting.Unicode;
namespace Avalonia.Controls.Presenters namespace Avalonia.Controls.Presenters
{ {
@ -496,14 +497,14 @@ namespace Avalonia.Controls.Presenters
var length = Math.Max(selectionStart, selectionEnd) - start; var length = Math.Max(selectionStart, selectionEnd) - start;
IReadOnlyList<ValueSpan<TextRunProperties>>? textStyleOverrides = null; IReadOnlyList<ValueSpan<TextRunProperties>>? textStyleOverrides = null;
if (length > 0) if (length > 0 && SelectionForegroundBrush != null)
{ {
textStyleOverrides = new[] textStyleOverrides = new[]
{ {
new ValueSpan<TextRunProperties>(start, length, new ValueSpan<TextRunProperties>(start, length,
new GenericTextRunProperties(typeface, FontSize, new GenericTextRunProperties(typeface, FontSize,
foregroundBrush: SelectionForegroundBrush ?? Brushes.White)) foregroundBrush: SelectionForegroundBrush))
}; };
} }

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

@ -501,7 +501,7 @@ namespace Avalonia.Controls.Primitives
if (dismissLayer != null) if (dismissLayer != null)
{ {
dismissLayer.IsVisible = true; dismissLayer.IsVisible = true;
dismissLayer.InputPassThroughElement = _overlayInputPassThroughElement; dismissLayer.InputPassThroughElement = OverlayInputPassThroughElement;
Disposable.Create(() => Disposable.Create(() =>
{ {

4
src/Avalonia.Controls/ProgressBar.cs

@ -119,14 +119,12 @@ namespace Avalonia.Controls
nameof(Percentage), nameof(Percentage),
o => o.Percentage); o => o.Percentage);
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public static readonly DirectProperty<ProgressBar, double> IndeterminateStartingOffsetProperty = public static readonly DirectProperty<ProgressBar, double> IndeterminateStartingOffsetProperty =
AvaloniaProperty.RegisterDirect<ProgressBar, double>( AvaloniaProperty.RegisterDirect<ProgressBar, double>(
nameof(IndeterminateStartingOffset), nameof(IndeterminateStartingOffset),
p => p.IndeterminateStartingOffset, p => p.IndeterminateStartingOffset,
(p, o) => p.IndeterminateStartingOffset = o); (p, o) => p.IndeterminateStartingOffset = o);
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public static readonly DirectProperty<ProgressBar, double> IndeterminateEndingOffsetProperty = public static readonly DirectProperty<ProgressBar, double> IndeterminateEndingOffsetProperty =
AvaloniaProperty.RegisterDirect<ProgressBar, double>( AvaloniaProperty.RegisterDirect<ProgressBar, double>(
nameof(IndeterminateEndingOffset), nameof(IndeterminateEndingOffset),
@ -139,14 +137,12 @@ namespace Avalonia.Controls
private set { SetAndRaise(PercentageProperty, ref _percentage, value); } private set { SetAndRaise(PercentageProperty, ref _percentage, value); }
} }
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public double IndeterminateStartingOffset public double IndeterminateStartingOffset
{ {
get => _indeterminateStartingOffset; get => _indeterminateStartingOffset;
set => SetAndRaise(IndeterminateStartingOffsetProperty, ref _indeterminateStartingOffset, value); set => SetAndRaise(IndeterminateStartingOffsetProperty, ref _indeterminateStartingOffset, value);
} }
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public double IndeterminateEndingOffset public double IndeterminateEndingOffset
{ {
get => _indeterminateEndingOffset; get => _indeterminateEndingOffset;

24
src/Avalonia.Controls/RichTextBlock.cs

@ -44,8 +44,8 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Inlines"/> property. /// Defines the <see cref="Inlines"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<InlineCollection> InlinesProperty = public static readonly StyledProperty<InlineCollection?> InlinesProperty =
AvaloniaProperty.Register<RichTextBlock, InlineCollection>( AvaloniaProperty.Register<RichTextBlock, InlineCollection?>(
nameof(Inlines)); nameof(Inlines));
public static readonly DirectProperty<TextBox, bool> CanCopyProperty = public static readonly DirectProperty<TextBox, bool> CanCopyProperty =
@ -138,7 +138,7 @@ namespace Avalonia.Controls
/// Gets or sets the inlines. /// Gets or sets the inlines.
/// </summary> /// </summary>
[Content] [Content]
public InlineCollection Inlines public InlineCollection? Inlines
{ {
get => GetValue(InlinesProperty); get => GetValue(InlinesProperty);
set => SetValue(InlinesProperty, value); set => SetValue(InlinesProperty, value);
@ -159,7 +159,7 @@ namespace Avalonia.Controls
remove => RemoveHandler(CopyingToClipboardEvent, value); remove => RemoveHandler(CopyingToClipboardEvent, value);
} }
internal bool HasComplexContent => Inlines.Count > 0; internal bool HasComplexContent => Inlines != null && Inlines.Count > 0;
/// <summary> /// <summary>
/// Copies the current selection to the Clipboard. /// Copies the current selection to the Clipboard.
@ -260,23 +260,23 @@ namespace Avalonia.Controls
{ {
if (!string.IsNullOrEmpty(_text)) if (!string.IsNullOrEmpty(_text))
{ {
Inlines.Add(_text); Inlines?.Add(_text);
_text = null; _text = null;
} }
Inlines.Add(text); Inlines?.Add(text);
} }
} }
protected override string? GetText() protected override string? GetText()
{ {
return _text ?? Inlines.Text; return _text ?? Inlines?.Text;
} }
protected override void SetText(string? text) protected override void SetText(string? text)
{ {
var oldValue = _text ?? Inlines?.Text; var oldValue = GetText();
AddText(text); AddText(text);
@ -301,10 +301,10 @@ namespace Avalonia.Controls
ITextSource textSource; ITextSource textSource;
var inlines = Inlines;
if (HasComplexContent) if (HasComplexContent)
{ {
var inlines = Inlines!;
var textRuns = new List<TextRun>(); var textRuns = new List<TextRun>();
foreach (var inline in inlines) foreach (var inline in inlines)
@ -537,7 +537,7 @@ namespace Avalonia.Controls
switch (change.Property.Name) switch (change.Property.Name)
{ {
case nameof(InlinesProperty): case nameof(Inlines):
{ {
OnInlinesChanged(change.OldValue as InlineCollection, change.NewValue as InlineCollection); OnInlinesChanged(change.OldValue as InlineCollection, change.NewValue as InlineCollection);
InvalidateTextLayout(); InvalidateTextLayout();
@ -553,7 +553,7 @@ namespace Avalonia.Controls
return ""; return "";
} }
var text = Inlines.Text ?? Text; var text = GetText();
if (string.IsNullOrEmpty(text)) if (string.IsNullOrEmpty(text))
{ {

6
src/Avalonia.Controls/TextBox.cs

@ -17,6 +17,7 @@ using Avalonia.Controls.Metadata;
using Avalonia.Media.TextFormatting; using Avalonia.Media.TextFormatting;
using Avalonia.Media.TextFormatting.Unicode; using Avalonia.Media.TextFormatting.Unicode;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
using System.Diagnostics;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -1240,9 +1241,10 @@ namespace Avalonia.Controls
MathUtilities.Clamp(point.X, 0, Math.Max(_presenter.Bounds.Width - 1, 0)), MathUtilities.Clamp(point.X, 0, Math.Max(_presenter.Bounds.Width - 1, 0)),
MathUtilities.Clamp(point.Y, 0, Math.Max(_presenter.Bounds.Height - 1, 0))); MathUtilities.Clamp(point.Y, 0, Math.Max(_presenter.Bounds.Height - 1, 0)));
_presenter.MoveCaretToPoint(point); _presenter.MoveCaretToPoint(point);
var caretIndex = _presenter.CaretIndex; var caretIndex = _presenter.CaretIndex;
var text = Text; var text = Text;
if (text != null && _wordSelectionStart >= 0) if (text != null && _wordSelectionStart >= 0)
@ -1266,7 +1268,7 @@ namespace Avalonia.Controls
} }
else else
{ {
SelectionEnd = _presenter.CaretIndex; SelectionEnd = caretIndex;
} }
} }
} }

2
src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj

@ -19,7 +19,7 @@
<ProjectReference Include="..\Markup\Avalonia.Markup\Avalonia.Markup.csproj" /> <ProjectReference Include="..\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" /> <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" /> <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" />
<ProjectReference Include="..\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" /> <ProjectReference Include="..\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.4.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.4.0" />

5
src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:Avalonia.Diagnostics.Views" xmlns:views="clr-namespace:Avalonia.Diagnostics.Views"
xmlns:diag="clr-namespace:Avalonia.Diagnostics" xmlns:diag="clr-namespace:Avalonia.Diagnostics"
xmlns:default="using:Avalonia.Themes.Default"
Title="Avalonia DevTools" Title="Avalonia DevTools"
x:Class="Avalonia.Diagnostics.Views.MainWindow" x:Class="Avalonia.Diagnostics.Views.MainWindow"
Theme="{StaticResource {x:Type Window}}"> Theme="{StaticResource {x:Type Window}}">
@ -11,8 +10,8 @@
</Window.DataTemplates> </Window.DataTemplates>
<Window.Styles> <Window.Styles>
<default:SimpleTheme Mode="Light"/> <SimpleTheme Mode="Light"/>
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Default.xaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml"/>
<StyleInclude Source="avares://Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.axaml" /> <StyleInclude Source="avares://Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.axaml" />
<StyleInclude Source="avares://Avalonia.Diagnostics/Diagnostics/Controls/FilterTextBox.axaml" /> <StyleInclude Source="avares://Avalonia.Diagnostics/Diagnostics/Controls/FilterTextBox.axaml" />
</Window.Styles> </Window.Styles>

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

@ -11,7 +11,7 @@ using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.Themes.Default; using Avalonia.Themes.Simple;
using Avalonia.VisualTree; using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.Views namespace Avalonia.Diagnostics.Views

75
src/Avalonia.Themes.Default/DefaultTheme.xaml

@ -1,75 +0,0 @@
<Styles x:Class="Avalonia.Themes.Default.DefaultTheme"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Styles.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Button.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/RadioButton.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Expander.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/RepeatButton.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ToggleSwitch.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ButtonSpinner.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ToggleButton.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/DropDownButton.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/PathIcon.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/CheckBox.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ToolTip.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Label.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ComboBoxItem.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ComboBox.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Window.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Carousel.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/CaptionButtons.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TitleBar.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TextBox.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/AutoCompleteBox.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/DataValidationErrors.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ContentControl.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/FlyoutPresenter.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/MenuFlyoutPresenter.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/GridSplitter.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ItemsControl.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ListBoxItem.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ListBox.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ScrollBar.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ScrollViewer.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TabStrip.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TabStripItem.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TabControl.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TabItem.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/PopupRoot.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/OverlayPopupHost.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/WindowNotificationManager.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/EmbeddableControlRoot.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TransitioningContentControl.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TreeView.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TreeViewItem.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ProgressBar.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Separator.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Menu.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/MenuItem.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ContextMenu.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/CalendarButton.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/CalendarDayButton.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/CalendarItem.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Calendar.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/CalendarDatePicker.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/Slider.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/NotificationCard.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/NativeMenuBar.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/NumericUpDown.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/DateTimePickerShared.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/DatePicker.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/TimePicker.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/SplitView.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/ManagedFileChooser.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/SplitButton.xaml" />
<ResourceInclude Source="avares://Avalonia.Themes.Default/Controls/RichTextBlock.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Styles.Resources>
<StyleInclude Source="avares://Avalonia.Themes.Default/Controls/FocusAdorner.xaml" />
<StyleInclude Source="avares://Avalonia.Themes.Default/Controls/UserControl.xaml" />
</Styles>

11
src/Avalonia.Themes.Default/DefaultTheme.xaml.cs

@ -1,11 +0,0 @@
using Avalonia.Styling;
namespace Avalonia.Themes.Default
{
/// <summary>
/// The default Avalonia theme.
/// </summary>
public class DefaultTheme : Styles
{
}
}

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

@ -41,13 +41,31 @@
<StreamGeometry x:Key="ButtonSpinnerIncreaseButtonIcon">M0,9 L10,0 20,9 19,10 10,2 1,10 z</StreamGeometry> <StreamGeometry x:Key="ButtonSpinnerIncreaseButtonIcon">M0,9 L10,0 20,9 19,10 10,2 1,10 z</StreamGeometry>
<StreamGeometry x:Key="ButtonSpinnerDecreaseButtonIcon">M0,1 L10,10 20,1 19,0 10,8 1,0 z</StreamGeometry> <StreamGeometry x:Key="ButtonSpinnerDecreaseButtonIcon">M0,1 L10,10 20,1 19,0 10,8 1,0 z</StreamGeometry>
<ControlTheme x:Key="FluentButtonSpinnerRepeatButton" TargetType="RepeatButton" BasedOn="{StaticResource {x:Type RepeatButton}}"> <ControlTheme x:Key="FluentButtonSpinnerRepeatButton" TargetType="RepeatButton">
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="MinWidth" Value="34" /> <Setter Property="MinWidth" Value="34" />
<Setter Property="VerticalAlignment" Value="Stretch" /> <Setter Property="Template">
<ControlTemplate>
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</ControlTemplate>
</Setter>
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource RepeatButtonBackgroundPointerOver}" />
</Style>
<Style Selector="^:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource RepeatButtonBackgroundPressed}" />
</Style>
<Style Selector="^:disabled /template/ ContentPresenter#PART_ContentPresenter"> <Style Selector="^:disabled /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="BorderBrush" Value="{TemplateBinding BorderBrush}" /> <Setter Property="Foreground" Value="{DynamicResource RepeatButtonForegroundDisabled}" />
<Setter Property="Foreground" Value="{DynamicResource RepeatButtonForegroundDisabled}"/>
</Style> </Style>
</ControlTheme> </ControlTheme>
@ -83,7 +101,6 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ButtonSpinnerLeftThickness}}" BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ButtonSpinnerLeftThickness}}"
CornerRadius="0"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
VerticalContentAlignment="Center" VerticalContentAlignment="Center"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
@ -99,7 +116,6 @@
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ButtonSpinnerLeftThickness}}" BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ButtonSpinnerLeftThickness}}"
CornerRadius="0"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
VerticalContentAlignment="Center" VerticalContentAlignment="Center"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"

0
src/Avalonia.Themes.Default/Accents/Base.xaml → src/Avalonia.Themes.Simple/Accents/Base.xaml

0
src/Avalonia.Themes.Default/Accents/BaseDark.xaml → src/Avalonia.Themes.Simple/Accents/BaseDark.xaml

0
src/Avalonia.Themes.Default/Accents/BaseLight.xaml → src/Avalonia.Themes.Simple/Accents/BaseLight.xaml

0
src/Avalonia.Themes.Default/ApiCompatBaseline.txt → src/Avalonia.Themes.Simple/ApiCompatBaseline.txt

0
src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj → src/Avalonia.Themes.Simple/Avalonia.Themes.Simple.csproj

0
src/Avalonia.Themes.Default/Controls/AutoCompleteBox.xaml → src/Avalonia.Themes.Simple/Controls/AutoCompleteBox.xaml

0
src/Avalonia.Themes.Default/Controls/Button.xaml → src/Avalonia.Themes.Simple/Controls/Button.xaml

6
src/Avalonia.Themes.Default/Controls/ButtonSpinner.xaml → src/Avalonia.Themes.Simple/Controls/ButtonSpinner.xaml

@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:CompileBindings="True"> x:CompileBindings="True">
<ControlTheme x:Key="DefaultButtonSpinnerRepeatButton" <ControlTheme x:Key="SimpleButtonSpinnerRepeatButton"
BasedOn="{StaticResource {x:Type RepeatButton}}" BasedOn="{StaticResource {x:Type RepeatButton}}"
TargetType="RepeatButton"> TargetType="RepeatButton">
<Setter Property="Background" Value="Transparent" /> <Setter Property="Background" Value="Transparent" />
@ -38,7 +38,7 @@
IsVisible="{TemplateBinding ShowButtonSpinner}" IsVisible="{TemplateBinding ShowButtonSpinner}"
Rows="2"> Rows="2">
<RepeatButton Name="PART_IncreaseButton" <RepeatButton Name="PART_IncreaseButton"
Theme="{StaticResource DefaultButtonSpinnerRepeatButton}"> Theme="{StaticResource SimpleButtonSpinnerRepeatButton}">
<Path Width="8" <Path Width="8"
Height="4" Height="4"
HorizontalAlignment="Center" HorizontalAlignment="Center"
@ -48,7 +48,7 @@
Stretch="Uniform" /> Stretch="Uniform" />
</RepeatButton> </RepeatButton>
<RepeatButton Name="PART_DecreaseButton" <RepeatButton Name="PART_DecreaseButton"
Theme="{StaticResource DefaultButtonSpinnerRepeatButton}"> Theme="{StaticResource SimpleButtonSpinnerRepeatButton}">
<Path Width="8" <Path Width="8"
Height="4" Height="4"
HorizontalAlignment="Center" HorizontalAlignment="Center"

0
src/Avalonia.Themes.Default/Controls/Calendar.xaml → src/Avalonia.Themes.Simple/Controls/Calendar.xaml

0
src/Avalonia.Themes.Default/Controls/CalendarButton.xaml → src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml

0
src/Avalonia.Themes.Default/Controls/CalendarDatePicker.xaml → src/Avalonia.Themes.Simple/Controls/CalendarDatePicker.xaml

0
src/Avalonia.Themes.Default/Controls/CalendarDayButton.xaml → src/Avalonia.Themes.Simple/Controls/CalendarDayButton.xaml

0
src/Avalonia.Themes.Default/Controls/CalendarItem.xaml → src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml

10
src/Avalonia.Themes.Default/Controls/CaptionButtons.xaml → src/Avalonia.Themes.Simple/Controls/CaptionButtons.xaml

@ -8,7 +8,7 @@
</Border> </Border>
</Design.PreviewWith> </Design.PreviewWith>
<ControlTheme x:Key="DefaultCaptionButton" <ControlTheme x:Key="SimpleCaptionButton"
TargetType="Button"> TargetType="Button">
<Setter Property="Background" Value="#ffe5e5e5" /> <Setter Property="Background" Value="#ffe5e5e5" />
<!-- Reusing BorderBrush to define pressed background color, as it's not used otherwise --> <!-- Reusing BorderBrush to define pressed background color, as it's not used otherwise -->
@ -44,7 +44,7 @@
TextElement.FontSize="10"> TextElement.FontSize="10">
<Button x:Name="PART_FullScreenButton" <Button x:Name="PART_FullScreenButton"
IsVisible="False" IsVisible="False"
Theme="{StaticResource DefaultCaptionButton}"> Theme="{StaticResource SimpleCaptionButton}">
<Viewbox Width="11" <Viewbox Width="11"
Margin="2"> Margin="2">
<Path Name="FullScreenButtonPath" <Path Name="FullScreenButtonPath"
@ -54,7 +54,7 @@
</Viewbox> </Viewbox>
</Button> </Button>
<Button x:Name="PART_MinimiseButton" <Button x:Name="PART_MinimiseButton"
Theme="{StaticResource DefaultCaptionButton}"> Theme="{StaticResource SimpleCaptionButton}">
<Viewbox Width="11" <Viewbox Width="11"
Margin="2"> Margin="2">
<Path Data="M2048 1229v-205h-2048v205h2048z" <Path Data="M2048 1229v-205h-2048v205h2048z"
@ -63,7 +63,7 @@
</Viewbox> </Viewbox>
</Button> </Button>
<Button x:Name="PART_RestoreButton" <Button x:Name="PART_RestoreButton"
Theme="{StaticResource DefaultCaptionButton}"> Theme="{StaticResource SimpleCaptionButton}">
<Viewbox Width="11" <Viewbox Width="11"
Margin="2"> Margin="2">
<Viewbox.RenderTransform> <Viewbox.RenderTransform>
@ -78,7 +78,7 @@
<Button x:Name="PART_CloseButton" <Button x:Name="PART_CloseButton"
Background="#ffe81123" Background="#ffe81123"
BorderBrush="#fff1707a" BorderBrush="#fff1707a"
Theme="{StaticResource DefaultCaptionButton}"> Theme="{StaticResource SimpleCaptionButton}">
<Viewbox Width="11" <Viewbox Width="11"
Margin="2"> Margin="2">
<Path Data="M1169 1024l879 -879l-145 -145l-879 879l-879 -879l-145 145l879 879l-879 879l145 145l879 -879l879 879l145 -145z" <Path Data="M1169 1024l879 -879l-145 -145l-879 879l-879 -879l-145 145l879 879l-879 879l145 145l879 -879l879 879l145 -145z"

0
src/Avalonia.Themes.Default/Controls/Carousel.xaml → src/Avalonia.Themes.Simple/Controls/Carousel.xaml

0
src/Avalonia.Themes.Default/Controls/CheckBox.xaml → src/Avalonia.Themes.Simple/Controls/CheckBox.xaml

0
src/Avalonia.Themes.Default/Controls/ComboBox.xaml → src/Avalonia.Themes.Simple/Controls/ComboBox.xaml

0
src/Avalonia.Themes.Default/Controls/ComboBoxItem.xaml → src/Avalonia.Themes.Simple/Controls/ComboBoxItem.xaml

0
src/Avalonia.Themes.Default/Controls/ContentControl.xaml → src/Avalonia.Themes.Simple/Controls/ContentControl.xaml

2
src/Avalonia.Themes.Default/Controls/ContextMenu.xaml → src/Avalonia.Themes.Simple/Controls/ContextMenu.xaml

@ -15,7 +15,7 @@
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"> CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer Theme="{StaticResource DefaultMenuScrollViewer}"> <ScrollViewer Theme="{StaticResource SimpleMenuScrollViewer}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
ItemTemplate="{TemplateBinding ItemTemplate}" ItemTemplate="{TemplateBinding ItemTemplate}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"

0
src/Avalonia.Themes.Default/Controls/DataValidationErrors.xaml → src/Avalonia.Themes.Simple/Controls/DataValidationErrors.xaml

22
src/Avalonia.Themes.Default/Controls/DatePicker.xaml → src/Avalonia.Themes.Simple/Controls/DatePicker.xaml

@ -42,7 +42,7 @@
<Thickness x:Key="DatePickerHostMonthPadding">9,3,0,6</Thickness> <Thickness x:Key="DatePickerHostMonthPadding">9,3,0,6</Thickness>
<x:Double x:Key="DatePickerSpacerThemeWidth">1</x:Double> <x:Double x:Key="DatePickerSpacerThemeWidth">1</x:Double>
<ControlTheme x:Key="DefaultDatePickerFlyoutButton" <ControlTheme x:Key="SimpleDatePickerFlyoutButton"
TargetType="Button"> TargetType="Button">
<Setter Property="RenderTransform" Value="none" /> <Setter Property="RenderTransform" Value="none" />
<Setter Property="Template"> <Setter Property="Template">
@ -115,7 +115,7 @@
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
IsEnabled="{TemplateBinding IsEnabled}" IsEnabled="{TemplateBinding IsEnabled}"
TemplatedControl.IsTemplateFocusTarget="True" TemplatedControl.IsTemplateFocusTarget="True"
Theme="{StaticResource DefaultDatePickerFlyoutButton}"> Theme="{StaticResource SimpleDatePickerFlyoutButton}">
<Grid Name="ButtonContentGrid" <Grid Name="ButtonContentGrid"
ColumnDefinitions="78*,Auto,132*,Auto,78*"> ColumnDefinitions="78*,Auto,132*,Auto,78*">
<TextBlock Name="DayText" <TextBlock Name="DayText"
@ -200,7 +200,7 @@
<Grid Name="PickerContainer"> <Grid Name="PickerContainer">
<Grid.Styles> <Grid.Styles>
<Style Selector="DateTimePickerPanel > ListBoxItem"> <Style Selector="DateTimePickerPanel > ListBoxItem">
<Setter Property="Theme" Value="{StaticResource DefaultDateTimePickerItem}" /> <Setter Property="Theme" Value="{StaticResource SimpleDateTimePickerItem}" />
</Style> </Style>
</Grid.Styles> </Grid.Styles>
<!-- Column Definitions set in code, ignore here --> <!-- Column Definitions set in code, ignore here -->
@ -213,9 +213,9 @@
ShouldLoop="True" /> ShouldLoop="True" />
</ScrollViewer> </ScrollViewer>
<RepeatButton Name="MonthUpButton" <RepeatButton Name="MonthUpButton"
Theme="{StaticResource DefaultDateTimePickerUpButton}" /> Theme="{StaticResource SimpleDateTimePickerUpButton}" />
<RepeatButton Name="MonthDownButton" <RepeatButton Name="MonthDownButton"
Theme="{StaticResource DefaultDateTimePickerDownButton}" /> Theme="{StaticResource SimpleDateTimePickerDownButton}" />
</Panel> </Panel>
<Panel Name="DayHost"> <Panel Name="DayHost">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" <ScrollViewer HorizontalScrollBarVisibility="Disabled"
@ -226,9 +226,9 @@
ShouldLoop="True" /> ShouldLoop="True" />
</ScrollViewer> </ScrollViewer>
<RepeatButton Name="DayUpButton" <RepeatButton Name="DayUpButton"
Theme="{StaticResource DefaultDateTimePickerUpButton}" /> Theme="{StaticResource SimpleDateTimePickerUpButton}" />
<RepeatButton Name="DayDownButton" <RepeatButton Name="DayDownButton"
Theme="{StaticResource DefaultDateTimePickerDownButton}" /> Theme="{StaticResource SimpleDateTimePickerDownButton}" />
</Panel> </Panel>
<Panel Name="YearHost"> <Panel Name="YearHost">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" <ScrollViewer HorizontalScrollBarVisibility="Disabled"
@ -239,9 +239,9 @@
ShouldLoop="False" /> ShouldLoop="False" />
</ScrollViewer> </ScrollViewer>
<RepeatButton Name="YearUpButton" <RepeatButton Name="YearUpButton"
Theme="{StaticResource DefaultDateTimePickerUpButton}" /> Theme="{StaticResource SimpleDateTimePickerUpButton}" />
<RepeatButton Name="YearDownButton" <RepeatButton Name="YearDownButton"
Theme="{StaticResource DefaultDateTimePickerDownButton}" /> Theme="{StaticResource SimpleDateTimePickerDownButton}" />
</Panel> </Panel>
<Rectangle Name="HighlightRect" <Rectangle Name="HighlightRect"
Grid.Column="0" Grid.Column="0"
@ -279,7 +279,7 @@
Height="{DynamicResource DatePickerFlyoutPresenterAcceptDismissHostGridHeight}" Height="{DynamicResource DatePickerFlyoutPresenterAcceptDismissHostGridHeight}"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Theme="{StaticResource DefaultDateTimePickerButton}"> Theme="{StaticResource SimpleDateTimePickerButton}">
<Path Data="M0.5,8.5 5,13.5 15.5,3" <Path Data="M0.5,8.5 5,13.5 15.5,3"
Stroke="{Binding $parent[Button].Foreground}" Stroke="{Binding $parent[Button].Foreground}"
StrokeLineCap="Round" StrokeLineCap="Round"
@ -290,7 +290,7 @@
Height="{DynamicResource DatePickerFlyoutPresenterAcceptDismissHostGridHeight}" Height="{DynamicResource DatePickerFlyoutPresenterAcceptDismissHostGridHeight}"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Theme="{StaticResource DefaultDateTimePickerButton}"> Theme="{StaticResource SimpleDateTimePickerButton}">
<Path Data="M2,2 14,14 M2,14 14 2" <Path Data="M2,2 14,14 M2,14 14 2"
Stroke="{Binding $parent[Button].Foreground}" Stroke="{Binding $parent[Button].Foreground}"
StrokeLineCap="Round" StrokeLineCap="Round"

22
src/Avalonia.Themes.Default/Controls/DateTimePickerShared.xaml → src/Avalonia.Themes.Simple/Controls/DateTimePickerShared.xaml

@ -13,17 +13,17 @@
<Border Width="200" <Border Width="200"
Padding="20"> Padding="20">
<StackPanel Spacing="20"> <StackPanel Spacing="20">
<ListBoxItem Theme="{DynamicResource DefaultDateTimePickerItem}">Standard Item</ListBoxItem> <ListBoxItem Theme="{DynamicResource SimpleDateTimePickerItem}">Standard Item</ListBoxItem>
<ListBoxItem Theme="{DynamicResource DefaultDateTimePickerItem}" Classes="MonthItem">Month Item</ListBoxItem> <ListBoxItem Theme="{DynamicResource SimpleDateTimePickerItem}" Classes="MonthItem">Month Item</ListBoxItem>
<RepeatButton Theme="{DynamicResource DefaultDateTimePickerButton}">Button</RepeatButton> <RepeatButton Theme="{DynamicResource SimpleDateTimePickerButton}">Button</RepeatButton>
<RepeatButton Theme="{DynamicResource DefaultDateTimePickerUpButton}" IsVisible="True"/> <RepeatButton Theme="{DynamicResource SimpleDateTimePickerUpButton}" IsVisible="True"/>
<RepeatButton Theme="{DynamicResource DefaultDateTimePickerDownButton}" IsVisible="True"/> <RepeatButton Theme="{DynamicResource SimpleDateTimePickerDownButton}" IsVisible="True"/>
</StackPanel> </StackPanel>
</Border> </Border>
</Design.PreviewWith> </Design.PreviewWith>
<!-- Theme for the items displayed in the selectors --> <!-- Theme for the items displayed in the selectors -->
<ControlTheme x:Key="DefaultDateTimePickerItem" <ControlTheme x:Key="SimpleDateTimePickerItem"
BasedOn="{StaticResource {x:Type ListBoxItem}}" BasedOn="{StaticResource {x:Type ListBoxItem}}"
TargetType="ListBoxItem"> TargetType="ListBoxItem">
<Setter Property="Padding" Value="{DynamicResource DatePickerFlyoutPresenterItemPadding}" /> <Setter Property="Padding" Value="{DynamicResource DatePickerFlyoutPresenterItemPadding}" />
@ -47,7 +47,7 @@
</ControlTheme> </ControlTheme>
<!-- This is used for both the accept/dismiss & repeatbuttons in the presenter --> <!-- This is used for both the accept/dismiss & repeatbuttons in the presenter -->
<ControlTheme x:Key="DefaultDateTimePickerButton" <ControlTheme x:Key="SimpleDateTimePickerButton"
TargetType="Button"> TargetType="Button">
<Setter Property="Background" Value="{DynamicResource ThemeControlTransparentBrush}" /> <Setter Property="Background" Value="{DynamicResource ThemeControlTransparentBrush}" />
<Setter Property="Height" Value="22" /> <Setter Property="Height" Value="22" />
@ -91,8 +91,8 @@
</Style> </Style>
</ControlTheme> </ControlTheme>
<ControlTheme x:Key="DefaultDateTimePickerUpButton" <ControlTheme x:Key="SimpleDateTimePickerUpButton"
BasedOn="{StaticResource DefaultDateTimePickerButton}" BasedOn="{StaticResource SimpleDateTimePickerButton}"
TargetType="RepeatButton"> TargetType="RepeatButton">
<Setter Property="VerticalAlignment" Value="Top" /> <Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Height" Value="22" /> <Setter Property="Height" Value="22" />
@ -114,8 +114,8 @@
</Setter> </Setter>
</ControlTheme> </ControlTheme>
<ControlTheme x:Key="DefaultDateTimePickerDownButton" <ControlTheme x:Key="SimpleDateTimePickerDownButton"
BasedOn="{StaticResource DefaultDateTimePickerButton}" BasedOn="{StaticResource SimpleDateTimePickerButton}"
TargetType="RepeatButton"> TargetType="RepeatButton">
<Setter Property="VerticalAlignment" Value="Bottom" /> <Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="Height" Value="22" /> <Setter Property="Height" Value="22" />

0
src/Avalonia.Themes.Default/Controls/DropDownButton.xaml → src/Avalonia.Themes.Simple/Controls/DropDownButton.xaml

0
src/Avalonia.Themes.Default/Controls/EmbeddableControlRoot.xaml → src/Avalonia.Themes.Simple/Controls/EmbeddableControlRoot.xaml

34
src/Avalonia.Themes.Default/Controls/Expander.xaml → src/Avalonia.Themes.Simple/Controls/Expander.xaml

@ -44,7 +44,7 @@
</Border> </Border>
</Design.PreviewWith> </Design.PreviewWith>
<ControlTheme x:Key="DefaultExpanderToggleButtonTheme" <ControlTheme x:Key="SimpleExpanderToggleButtonTheme"
TargetType="ToggleButton"> TargetType="ToggleButton">
<Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" /> <Setter Property="Background" Value="Transparent" />
@ -80,8 +80,8 @@
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowBrush}" />
</Style> </Style>
</ControlTheme> </ControlTheme>
<ControlTheme x:Key="DefaultExpanderToggleButtonUpTheme" <ControlTheme x:Key="SimpleExpanderToggleButtonUpTheme"
BasedOn="{StaticResource DefaultExpanderToggleButtonTheme}" BasedOn="{StaticResource SimpleExpanderToggleButtonTheme}"
TargetType="ToggleButton"> TargetType="ToggleButton">
<Style Selector="^ /template/ Path"> <Style Selector="^ /template/ Path">
<Setter Property="RenderTransform"> <Setter Property="RenderTransform">
@ -89,8 +89,8 @@
</Setter> </Setter>
</Style> </Style>
</ControlTheme> </ControlTheme>
<ControlTheme x:Key="DefaultExpanderToggleButtonDownTheme" <ControlTheme x:Key="SimpleExpanderToggleButtonDownTheme"
BasedOn="{StaticResource DefaultExpanderToggleButtonTheme}" BasedOn="{StaticResource SimpleExpanderToggleButtonTheme}"
TargetType="ToggleButton"> TargetType="ToggleButton">
<Style Selector="^ /template/ Path"> <Style Selector="^ /template/ Path">
<Setter Property="RenderTransform"> <Setter Property="RenderTransform">
@ -98,8 +98,8 @@
</Setter> </Setter>
</Style> </Style>
</ControlTheme> </ControlTheme>
<ControlTheme x:Key="DefaultExpanderToggleButtonLeftTheme" <ControlTheme x:Key="SimpleExpanderToggleButtonLeftTheme"
BasedOn="{StaticResource DefaultExpanderToggleButtonTheme}" BasedOn="{StaticResource SimpleExpanderToggleButtonTheme}"
TargetType="ToggleButton"> TargetType="ToggleButton">
<Style Selector="^ /template/ Path"> <Style Selector="^ /template/ Path">
<Setter Property="RenderTransform"> <Setter Property="RenderTransform">
@ -107,8 +107,8 @@
</Setter> </Setter>
</Style> </Style>
</ControlTheme> </ControlTheme>
<ControlTheme x:Key="DefaultExpanderToggleButtonRightTheme" <ControlTheme x:Key="SimpleExpanderToggleButtonRightTheme"
BasedOn="{StaticResource DefaultExpanderToggleButtonTheme}" BasedOn="{StaticResource SimpleExpanderToggleButtonTheme}"
TargetType="ToggleButton"> TargetType="ToggleButton">
<Style Selector="^ /template/ Path"> <Style Selector="^ /template/ Path">
<Setter Property="RenderTransform"> <Setter Property="RenderTransform">
@ -139,7 +139,7 @@
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"
IsChecked="{TemplateBinding IsExpanded, IsChecked="{TemplateBinding IsExpanded,
Mode=TwoWay}" Mode=TwoWay}"
Theme="{StaticResource DefaultExpanderToggleButtonRightTheme}" /> Theme="{StaticResource SimpleExpanderToggleButtonRightTheme}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Row="1" Grid.Row="1"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -153,7 +153,7 @@
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
<Style Selector="^:expanded /template/ ToggleButton#PART_toggle"> <Style Selector="^:expanded /template/ ToggleButton#PART_toggle">
<Setter Property="Theme" Value="{StaticResource DefaultExpanderToggleButtonDownTheme}" /> <Setter Property="Theme" Value="{StaticResource SimpleExpanderToggleButtonDownTheme}" />
</Style> </Style>
</Style> </Style>
<Style Selector="^[ExpandDirection=Up]"> <Style Selector="^[ExpandDirection=Up]">
@ -171,7 +171,7 @@
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"
IsChecked="{TemplateBinding IsExpanded, IsChecked="{TemplateBinding IsExpanded,
Mode=TwoWay}" Mode=TwoWay}"
Theme="{StaticResource DefaultExpanderToggleButtonRightTheme}" /> Theme="{StaticResource SimpleExpanderToggleButtonRightTheme}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Row="0" Grid.Row="0"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -185,7 +185,7 @@
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
<Style Selector="^:expanded /template/ ToggleButton#PART_toggle"> <Style Selector="^:expanded /template/ ToggleButton#PART_toggle">
<Setter Property="Theme" Value="{StaticResource DefaultExpanderToggleButtonUpTheme}" /> <Setter Property="Theme" Value="{StaticResource SimpleExpanderToggleButtonUpTheme}" />
</Style> </Style>
</Style> </Style>
<Style Selector="^[ExpandDirection=Right]"> <Style Selector="^[ExpandDirection=Right]">
@ -203,7 +203,7 @@
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"
IsChecked="{TemplateBinding IsExpanded, IsChecked="{TemplateBinding IsExpanded,
Mode=TwoWay}" Mode=TwoWay}"
Theme="{StaticResource DefaultExpanderToggleButtonLeftTheme}" /> Theme="{StaticResource SimpleExpanderToggleButtonLeftTheme}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Column="1" Grid.Column="1"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -217,7 +217,7 @@
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
<Style Selector="^:expanded /template/ ToggleButton#PART_toggle"> <Style Selector="^:expanded /template/ ToggleButton#PART_toggle">
<Setter Property="Theme" Value="{StaticResource DefaultExpanderToggleButtonRightTheme}" /> <Setter Property="Theme" Value="{StaticResource SimpleExpanderToggleButtonRightTheme}" />
</Style> </Style>
</Style> </Style>
<Style Selector="^[ExpandDirection=Left]"> <Style Selector="^[ExpandDirection=Left]">
@ -235,7 +235,7 @@
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"
IsChecked="{TemplateBinding IsExpanded, IsChecked="{TemplateBinding IsExpanded,
Mode=TwoWay}" Mode=TwoWay}"
Theme="{StaticResource DefaultExpanderToggleButtonRightTheme}" /> Theme="{StaticResource SimpleExpanderToggleButtonRightTheme}" />
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Grid.Column="0" Grid.Column="0"
Padding="{TemplateBinding Padding}" Padding="{TemplateBinding Padding}"
@ -249,7 +249,7 @@
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
<Style Selector="^:expanded /template/ ToggleButton#PART_toggle"> <Style Selector="^:expanded /template/ ToggleButton#PART_toggle">
<Setter Property="Theme" Value="{StaticResource DefaultExpanderToggleButtonLeftTheme}" /> <Setter Property="Theme" Value="{StaticResource SimpleExpanderToggleButtonLeftTheme}" />
</Style> </Style>
</Style> </Style>
</ControlTheme> </ControlTheme>

0
src/Avalonia.Themes.Default/Controls/FlyoutPresenter.xaml → src/Avalonia.Themes.Simple/Controls/FlyoutPresenter.xaml

0
src/Avalonia.Themes.Default/Controls/FocusAdorner.xaml → src/Avalonia.Themes.Simple/Controls/FocusAdorner.xaml

0
src/Avalonia.Themes.Default/Controls/GridSplitter.xaml → src/Avalonia.Themes.Simple/Controls/GridSplitter.xaml

0
src/Avalonia.Themes.Default/Controls/ItemsControl.xaml → src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml

0
src/Avalonia.Themes.Default/Controls/Label.xaml → src/Avalonia.Themes.Simple/Controls/Label.xaml

0
src/Avalonia.Themes.Default/Controls/ListBox.xaml → src/Avalonia.Themes.Simple/Controls/ListBox.xaml

0
src/Avalonia.Themes.Default/Controls/ListBoxItem.xaml → src/Avalonia.Themes.Simple/Controls/ListBoxItem.xaml

0
src/Avalonia.Themes.Default/Controls/ManagedFileChooser.xaml → src/Avalonia.Themes.Simple/Controls/ManagedFileChooser.xaml

6
src/Avalonia.Themes.Default/Controls/Menu.xaml → src/Avalonia.Themes.Simple/Controls/Menu.xaml

@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="using:System"> xmlns:sys="using:System">
<ControlTheme x:Key="DefaultTopLevelMenuItem" <ControlTheme x:Key="SimpleTopLevelMenuItem"
TargetType="MenuItem"> TargetType="MenuItem">
<Setter Property="Background" Value="Transparent" /> <Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="6 0" /> <Setter Property="Padding" Value="6 0" />
@ -32,7 +32,7 @@
<Border Background="{DynamicResource ThemeBackgroundBrush}" <Border Background="{DynamicResource ThemeBackgroundBrush}"
BorderBrush="{DynamicResource ThemeBorderMidBrush}" BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Theme="{StaticResource DefaultMenuScrollViewer}"> <ScrollViewer Theme="{StaticResource SimpleMenuScrollViewer}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Margin="2" Margin="2"
Grid.IsSharedSizeScope="True" Grid.IsSharedSizeScope="True"
@ -63,7 +63,7 @@
<ControlTheme x:Key="{x:Type Menu}" <ControlTheme x:Key="{x:Type Menu}"
TargetType="Menu"> TargetType="Menu">
<Setter Property="ItemContainerTheme" Value="{StaticResource DefaultTopLevelMenuItem}" /> <Setter Property="ItemContainerTheme" Value="{StaticResource SimpleTopLevelMenuItem}" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Padding="{TemplateBinding Padding}" <Border Padding="{TemplateBinding Padding}"

2
src/Avalonia.Themes.Default/Controls/MenuFlyoutPresenter.xaml → src/Avalonia.Themes.Simple/Controls/MenuFlyoutPresenter.xaml

@ -15,7 +15,7 @@
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"> CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" <ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
Theme="{StaticResource DefaultMenuScrollViewer}" Theme="{StaticResource SimpleMenuScrollViewer}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"> VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"

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

Loading…
Cancel
Save