Browse Source

Merge branch 'master' into pr/4823-fix-for-hotkey-manager-memory-leak

pull/4823/head
Steven Kirk 5 years ago
parent
commit
a8aea90731
  1. 3
      .editorconfig
  2. 31
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 20
      .github/ISSUE_TEMPLATE/feature_request.md
  4. 4
      .ncrunch/Avalonia.Build.Tasks.v3.ncrunchproject
  5. 5
      .ncrunch/Avalonia.MicroCom.v3.ncrunchproject
  6. 80
      Avalonia.sln
  7. 3
      Avalonia.sln.DotSettings
  8. 2
      Avalonia.v3.ncrunchsolution
  9. 2
      Directory.Build.props
  10. 12
      Documentation/build.md
  11. 2
      NuGet.Config
  12. 19
      azure-pipelines.yml
  13. 4
      build.ps1
  14. 2
      build.sh
  15. 2
      build/AndroidWorkarounds.props
  16. 2
      build/ApiDiff.props
  17. 1
      build/CoreLibraries.props
  18. 3
      build/EmbedXaml.props
  19. 4
      build/HarfBuzzSharp.props
  20. 33
      build/MicroCom.targets
  21. 2
      build/ReactiveUI.props
  22. 2
      build/Rx.props
  23. 6
      build/SharedVersion.props
  24. 23
      build/SourceLink.props
  25. 1
      native/Avalonia.Native/inc/.gitignore
  26. 516
      native/Avalonia.Native/inc/avalonia-native.h
  27. 1020
      native/Avalonia.Native/inc/key.h
  28. 12
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  29. 7
      native/Avalonia.Native/src/OSX/KeyTransform.h
  30. 151
      native/Avalonia.Native/src/OSX/KeyTransform.mm
  31. 2
      native/Avalonia.Native/src/OSX/clipboard.mm
  32. 4
      native/Avalonia.Native/src/OSX/main.mm
  33. 6
      native/Avalonia.Native/src/OSX/menu.h
  34. 67
      native/Avalonia.Native/src/OSX/menu.mm
  35. 2
      native/Avalonia.Native/src/OSX/platformthreading.mm
  36. 22
      native/Avalonia.Native/src/OSX/rendertarget.mm
  37. 10
      native/Avalonia.Native/src/OSX/window.mm
  38. 29
      nukebuild/Build.cs
  39. 2
      nukebuild/BuildParameters.cs
  40. 14
      nukebuild/MicroComGen.cs
  41. 6
      nukebuild/_build.csproj
  42. 19
      packages/Avalonia/Avalonia.csproj
  43. 4
      packages/Avalonia/AvaloniaBuildTasks.targets
  44. 11
      readme.md
  45. 2
      samples/BindingDemo/App.xaml.cs
  46. 3
      samples/BindingDemo/BindingDemo.csproj
  47. 4
      samples/BindingDemo/ViewModels/ExceptionErrorViewModel.cs
  48. 4
      samples/BindingDemo/ViewModels/IndeiErrorViewModel.cs
  49. 12
      samples/BindingDemo/ViewModels/MainWindowViewModel.cs
  50. 8
      samples/BindingDemo/ViewModels/NestedCommandViewModel.cs
  51. 4
      samples/BindingDemo/ViewModels/TestItem.cs
  52. 14
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  53. 21
      samples/ControlCatalog.Android/MainActivity.cs
  54. 2
      samples/ControlCatalog.Android/Properties/AndroidManifest.xml
  55. 59
      samples/ControlCatalog.Android/Resources/Resource.Designer.cs
  56. BIN
      samples/ControlCatalog.Android/Resources/drawable/Icon.png
  57. 13
      samples/ControlCatalog.Android/Resources/drawable/splash_screen.xml
  58. 13
      samples/ControlCatalog.Android/Resources/layout/Main.axml
  59. 5
      samples/ControlCatalog.Android/Resources/values/Strings.xml
  60. 4
      samples/ControlCatalog.Android/Resources/values/colors.xml
  61. 17
      samples/ControlCatalog.Android/Resources/values/styles.xml
  62. 32
      samples/ControlCatalog.Android/SplashActivity.cs
  63. 4
      samples/ControlCatalog.Desktop/Program.cs
  64. 8
      samples/ControlCatalog.NetCore/Program.cs
  65. 4
      samples/ControlCatalog/App.xaml.cs
  66. BIN
      samples/ControlCatalog/Assets/Fonts/WenQuanYiMicroHei-01.ttf
  67. 2
      samples/ControlCatalog/ControlCatalog.csproj
  68. 30
      samples/ControlCatalog/DecoratedWindow.xaml
  69. 66
      samples/ControlCatalog/MainWindow.xaml
  70. 2
      samples/ControlCatalog/MainWindow.xaml.cs
  71. 11
      samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
  72. 11
      samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
  73. 13
      samples/ControlCatalog/Pages/ComboBoxPage.xaml
  74. 4
      samples/ControlCatalog/Pages/DataGridPage.xaml
  75. 20
      samples/ControlCatalog/Pages/DateTimePickerPage.xaml
  76. 29
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  77. 1
      samples/ControlCatalog/Pages/LabelsPage.axaml.cs
  78. 2
      samples/ControlCatalog/Pages/ListBoxPage.xaml
  79. 1
      samples/ControlCatalog/Pages/MenuPage.xaml.cs
  80. 10
      samples/ControlCatalog/Pages/NumericUpDownPage.xaml
  81. 4
      samples/ControlCatalog/Pages/NumericUpDownPage.xaml.cs
  82. 4
      samples/ControlCatalog/Pages/ScrollViewerPage.xaml.cs
  83. 24
      samples/ControlCatalog/Pages/SliderPage.xaml
  84. 4
      samples/ControlCatalog/Pages/TabControlPage.xaml.cs
  85. 14
      samples/ControlCatalog/Pages/TextBoxPage.xaml
  86. 27
      samples/ControlCatalog/Pages/ToolTipPage.xaml
  87. 14
      samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs
  88. 6
      samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs
  89. 27
      samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
  90. 28
      samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
  91. 14
      samples/ControlCatalog/ViewModels/MenuPageViewModel.cs
  92. 10
      samples/ControlCatalog/ViewModels/NotificationViewModel.cs
  93. 4
      samples/ControlCatalog/ViewModels/SplitViewPageViewModel.cs
  94. 16
      samples/ControlCatalog/ViewModels/TreeViewPageViewModel.cs
  95. 66
      samples/MiniMvvm/MiniCommand.cs
  96. 6
      samples/MiniMvvm/MiniMvvm.csproj
  97. 108
      samples/MiniMvvm/PropertyChangedExtensions.cs
  98. 26
      samples/MiniMvvm/ViewModelBase.cs
  99. 1
      samples/Previewer/Previewer.csproj
  100. 2
      samples/RenderDemo/App.xaml

3
.editorconfig

@ -156,6 +156,9 @@ indent_size = 2
[*.{props,targets,config,nuspec}] [*.{props,targets,config,nuspec}]
indent_size = 2 indent_size = 2
[*.json]
indent_size = 2
# Shell scripts # Shell scripts
[*.sh] [*.sh]
end_of_line = lf end_of_line = lf

31
.github/ISSUE_TEMPLATE/bug_report.md

@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Windows, Mac, Linux (State distribution)]
- Version [e.g. 0.10.0-rc1 or 0.9.12]
**Additional context**
Add any other context about the problem here.

20
.github/ISSUE_TEMPLATE/feature_request.md

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

4
.ncrunch/Avalonia.Build.Tasks.v3.ncrunchproject

@ -1,5 +1,3 @@
<ProjectConfiguration> <ProjectConfiguration>
<Settings> <Settings />
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration> </ProjectConfiguration>

5
.ncrunch/Avalonia.MicroCom.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

80
Avalonia.sln

@ -226,6 +226,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.Events"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "samples\Sandbox\Sandbox.csproj", "{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "samples\Sandbox\Sandbox.csproj", "{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
EndProject
Global Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13 src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@ -2064,6 +2070,78 @@ Global
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhone.Build.0 = Release|Any CPU {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhone.Build.0 = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhone.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhone.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|Any CPU.Build.0 = Release|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhone.ActiveCfg = Release|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhone.Build.0 = Release|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhone.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhone.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|Any CPU.Build.0 = Release|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhone.ActiveCfg = Release|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhone.Build.0 = Release|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhone.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhone.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|Any CPU.Build.0 = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.ActiveCfg = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.Build.0 = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -2123,6 +2201,8 @@ Global
{3C84E04B-36CF-4D0D-B965-C26DD649D1F3} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9} {3C84E04B-36CF-4D0D-B965-C26DD649D1F3} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
{909A8CBD-7D0E-42FD-B841-022AD8925820} = {8B6A8209-894F-4BA1-B880-965FD453982C} {909A8CBD-7D0E-42FD-B841-022AD8925820} = {8B6A8209-894F-4BA1-B880-965FD453982C}
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098} {11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A} SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

3
Avalonia.sln.DotSettings

@ -38,4 +38,5 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EDaemon_002ESettings_002EMigration_002ESwaWarningsModeSettingsMigrate/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EDaemon_002ESettings_002EMigration_002ESwaWarningsModeSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fcitx/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

2
Avalonia.v3.ncrunchsolution

@ -4,6 +4,8 @@
<Value>tests\TestFiles\**.*</Value> <Value>tests\TestFiles\**.*</Value>
<Value>src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Avalonia.Build.Tasks.dll</Value> <Value>src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Avalonia.Build.Tasks.dll</Value>
<Value>src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Mono.Cecil.dll</Value> <Value>src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Mono.Cecil.dll</Value>
<Value>src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Mono.Cecil.Rocks.dll</Value>
<Value>src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Mono.Cecil.Pdb.dll</Value>
</AdditionalFilesToIncludeForSolution> </AdditionalFilesToIncludeForSolution>
<AllowParallelTestExecution>True</AllowParallelTestExecution> <AllowParallelTestExecution>True</AllowParallelTestExecution>
<CustomBuildProperties> <CustomBuildProperties>

2
Directory.Build.props

@ -2,5 +2,7 @@
<PropertyGroup> <PropertyGroup>
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)build-intermediate/nuget</PackageOutputPath> <PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)build-intermediate/nuget</PackageOutputPath>
<AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\netcoreapp2.0\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath> <AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\netcoreapp2.0\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath>
<!-- https://github.com/dotnet/msbuild/issues/2661 -->
<AddSyntheticProjectReferencesForSolutionDependencies>false</AddSyntheticProjectReferencesForSolutionDependencies>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

12
Documentation/build.md

@ -30,7 +30,7 @@ The build process needs [Xcode](https://developer.apple.com/xcode/) to build the
Linux operating systems ship with their own respective package managers however we will use [Homebrew](https://brew.sh/) to manage packages on macOS. To install follow the instructions [here](https://docs.brew.sh/Installation). Linux operating systems ship with their own respective package managers however we will use [Homebrew](https://brew.sh/) to manage packages on macOS. To install follow the instructions [here](https://docs.brew.sh/Installation).
### Install CastXML ### Install CastXML (pre Nov 2020)
Avalonia requires [CastXML](https://github.com/CastXML/CastXML) for XML processing during the build process. The easiest way to install this is via the operating system's package managers, such as below. Avalonia requires [CastXML](https://github.com/CastXML/CastXML) for XML processing during the build process. The easiest way to install this is via the operating system's package managers, such as below.
@ -60,14 +60,10 @@ git submodule update --init --recursive
### Build native libraries (macOS only) ### Build native libraries (macOS only)
On macOS it is necessary to build and manually install the respective native libraries using [Xcode](https://developer.apple.com/xcode/). The steps to get this working correctly are: On macOS it is necessary to build and manually install the respective native libraries using [Xcode](https://developer.apple.com/xcode/). Execute the build script in the root project with the `CompileNative` task. It will build the headers, build the libraries, and place them in the appropriate place to allow .NET to find them at compilation and run time.
- Navigate to the Avalonia/native/Avalonia.Native/src/OSX folder and open the `Avalonia.Native.OSX.xcodeproj` project
- Build the library via the Product->Build menu. This will generate binaries in your local path under ~/Library/Developer/Xcode/DerivedData/Avalonia.Native.OSX-*guid* where "guid" is uniquely generated every time you build.
- Manually install the native library by copying it from the build artifacts folder into the shared dynamic library path:
``` ```bash
cd ~/Library/Developer/Xcode/DerivedData/Avalonia.Native.OSX-[guid]/Build/Products/Debug ./build.sh CompileNative
cp libAvalonia.Native.OSX.dylib /usr/local/lib/libAvaloniaNative.dylib
``` ```
### Build and Run Avalonia ### Build and Run Avalonia

2
NuGet.Config

@ -4,6 +4,6 @@
<packageSources> <packageSources>
<clear /> <clear />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" /> <add key="dotnet-eng" value="https://nuget.avaloniaui.net/repository/avalonia-devdeps/index.json" protocolVersion="3" />
</packageSources> </packageSources>
</configuration> </configuration>

19
azure-pipelines.yml

@ -3,13 +3,6 @@ jobs:
pool: pool:
vmImage: 'ubuntu-16.04' vmImage: 'ubuntu-16.04'
steps: steps:
- task: CmdLine@2
displayName: 'Install CastXML'
inputs:
script: |
sudo apt-get update
sudo apt-get install castxml
- task: CmdLine@2 - task: CmdLine@2
displayName: 'Install Nuke' displayName: 'Install Nuke'
inputs: inputs:
@ -34,7 +27,7 @@ jobs:
variables: variables:
SolutionDir: '$(Build.SourcesDirectory)' SolutionDir: '$(Build.SourcesDirectory)'
pool: pool:
vmImage: 'macOS-10.14' vmImage: 'macOS-10.15'
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Use .NET Core SDK 3.1.401' displayName: 'Use .NET Core SDK 3.1.401'
@ -48,14 +41,20 @@ jobs:
curl -o ./mono.pkg https://download.mono-project.com/archive/5.18.0/macos-10-universal/MonoFramework-MDK-5.18.0.225.macos10.xamarin.universal.pkg curl -o ./mono.pkg https://download.mono-project.com/archive/5.18.0/macos-10-universal/MonoFramework-MDK-5.18.0.225.macos10.xamarin.universal.pkg
sudo installer -verbose -pkg ./mono.pkg -target / sudo installer -verbose -pkg ./mono.pkg -target /
- task: CmdLine@2
displayName: 'Generate avalonia-native'
inputs:
script: |
cd src/tools/MicroComGenerator; dotnet run -i ../../Avalonia.Native/avn.idl --cpp ../../../native/Avalonia.Native/inc/avalonia-native.h
- task: Xcode@5 - task: Xcode@5
inputs: inputs:
actions: 'build' actions: 'build'
scheme: '' scheme: ''
sdk: 'macosx10.14' sdk: 'macosx11.1'
configuration: 'Release' configuration: 'Release'
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace' xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
xcodeVersion: '10' # Options: 8, 9, default, specifyPath xcodeVersion: '12' # Options: 8, 9, default, specifyPath
args: '-derivedDataPath ./' args: '-derivedDataPath ./'
- task: CmdLine@2 - task: CmdLine@2

4
build.ps1

@ -43,7 +43,7 @@ if (Test-Path $DotNetGlobalFile) {
} }
# If dotnet is installed locally, and expected version is not set or installation matches the expected version # If dotnet is installed locally, and expected version is not set or installation matches the expected version
if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and ` if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
(!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) { (!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) {
$env:DOTNET_EXE = (Get-Command "dotnet").Path $env:DOTNET_EXE = (Get-Command "dotnet").Path
} }
@ -53,7 +53,7 @@ else {
# Download install script # Download install script
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
md -force $TempDirectory > $null mkdir -force $TempDirectory > $null
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
# Install by channel or version # Install by channel or version

2
build.sh

@ -47,7 +47,7 @@ if [ -f "$DOTNET_GLOBAL_FILE" ]; then
fi fi
# If dotnet is installed locally, and expected version is not set or installation matches the expected version # If dotnet is installed locally, and expected version is not set or installation matches the expected version
if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") || "$SKIP_DOTNET_DOWNLOAD" == "1" ]]; then
export DOTNET_EXE="$(command -v dotnet)" export DOTNET_EXE="$(command -v dotnet)"
else else
DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix" DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"

2
build/AndroidWorkarounds.props

@ -2,7 +2,7 @@
<ItemGroup Condition="'$(AndroidApplication)' == 'true'"> <ItemGroup Condition="'$(AndroidApplication)' == 'true'">
<!-- WORKAROUND: The packages below are transitively referenced by System.Memory, <!-- WORKAROUND: The packages below are transitively referenced by System.Memory,
but Xamarin.Android applications need the newest versions directly referenced for the linker. --> but Xamarin.Android applications need the newest versions directly referenced for the linker. -->
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.1" /> <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.6.0" />
<PackageReference Include="System.Buffers" Version="4.5.0" /> <PackageReference Include="System.Buffers" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<Target Name="_RemoveNonExistingResgenFile" BeforeTargets="CoreCompile" Condition="'$(_SdkSetAndroidResgenFile)' == 'true' And '$(AndroidResgenFile)' != '' And !Exists('$(AndroidResgenFile)')"> <Target Name="_RemoveNonExistingResgenFile" BeforeTargets="CoreCompile" Condition="'$(_SdkSetAndroidResgenFile)' == 'true' And '$(AndroidResgenFile)' != '' And !Exists('$(AndroidResgenFile)')">

2
build/ApiDiff.props

@ -1,6 +1,6 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ApiContractPackageVersion>0.10.0-preview3</ApiContractPackageVersion> <ApiContractPackageVersion>0.10.0</ApiContractPackageVersion>
<NugetPackageName Condition="'$(PackageId)' != ''">$(PackageId)</NugetPackageName> <NugetPackageName Condition="'$(PackageId)' != ''">$(PackageId)</NugetPackageName>
<NugetPackageName Condition="'$(PackageId)' == ''">Avalonia</NugetPackageName> <NugetPackageName Condition="'$(PackageId)' == ''">Avalonia</NugetPackageName>
</PropertyGroup> </PropertyGroup>

1
build/CoreLibraries.props

@ -15,6 +15,7 @@
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.MicroCom/Avalonia.MicroCom.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesktopRuntime/Avalonia.DesktopRuntime.csproj" Condition="'$(TargetFramework)' != 'netstandard2.0'" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesktopRuntime/Avalonia.DesktopRuntime.csproj" Condition="'$(TargetFramework)' != 'netstandard2.0'" />
</ItemGroup> </ItemGroup>
</Project> </Project>

3
build/EmbedXaml.props

@ -4,8 +4,9 @@
<Compile Update="**\*.xaml.cs"> <Compile Update="**\*.xaml.cs">
<DependentUpon>%(Filename)</DependentUpon> <DependentUpon>%(Filename)</DependentUpon>
</Compile> </Compile>
<None Remove="**\*.xaml"/>
<AvaloniaResource Include="**\*.xaml"> <AvaloniaResource Include="**\*.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AvaloniaResource> </AvaloniaResource>
</ItemGroup> </ItemGroup>
</Project> </Project>

4
build/HarfBuzzSharp.props

@ -1,6 +1,6 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<PackageReference Include="HarfBuzzSharp" Version="2.6.1.6" /> <PackageReference Include="HarfBuzzSharp" Version="2.6.1.7" />
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.6.1.6" /> <PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.6.1.7" />
</ItemGroup> </ItemGroup>
</Project> </Project>

33
build/MicroCom.targets

@ -0,0 +1,33 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Ensure that code generator is actually built -->
<ItemGroup>
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\src\tools\MicroComGenerator\MicroComGenerator.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<ExcludeAssets>all</ExcludeAssets>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
</ProjectReference>
</ItemGroup>
<Target Name="GenerateAvaloniaNativeComInterop"
BeforeTargets="CoreCompile"
DependsOnTargets="ResolveReferences"
Inputs="@(AvnComIdl);$(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/**/*.cs"
Outputs="%(AvnComIdl.OutputFile)">
<Message Importance="high" Text="Generating file %(AvnComIdl.OutputFile) from @(AvnComIdl)" />
<Exec Command="dotnet $(MSBuildThisFileDirectory)../src/tools/MicroComGenerator/bin/$(Configuration)/netcoreapp3.1/MicroComGenerator.dll -i @(AvnComIdl) --cs %(AvnComIdl.OutputFile)" LogStandardErrorAsError="true" />
<ItemGroup>
<!-- Remove and re-add generated file, this is needed for the clean build -->
<Compile Remove="%(AvnComIdl.OutputFile)"/>
<Compile Include="%(AvnComIdl.OutputFile)"/>
</ItemGroup>
</Target>
<ItemGroup>
<UpToDateCheckInput Include="@(AvnComIdl)"/>
<UpToDateCheckInput Include="$(MSBuildThisFileDirectory)/../src/tools/MicroComGenerator/**/*.cs"/>
</ItemGroup>
<PropertyGroup>
<_AvaloniaPatchComInterop>true</_AvaloniaPatchComInterop>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)/BuildTargets.targets" />
</Project>

2
build/ReactiveUI.props

@ -1,5 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<PackageReference Include="ReactiveUI" Version="11.5.17" /> <PackageReference Include="ReactiveUI" Version="12.1.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

2
build/Rx.props

@ -1,5 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Reactive" Version="4.4.1" /> <PackageReference Include="System.Reactive" Version="5.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

6
build/SharedVersion.props

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<Product>Avalonia</Product> <Product>Avalonia</Product>
<Version>0.10.999</Version> <Version>0.10.999</Version>
<Copyright>Copyright 2020 &#169; The AvaloniaUI Project</Copyright> <Copyright>Copyright 2021 &#169; The AvaloniaUI Project</Copyright>
<PackageProjectUrl>https://avaloniaui.net</PackageProjectUrl> <PackageProjectUrl>https://avaloniaui.net</PackageProjectUrl>
<RepositoryUrl>https://github.com/AvaloniaUI/Avalonia/</RepositoryUrl> <RepositoryUrl>https://github.com/AvaloniaUI/Avalonia/</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
@ -16,11 +16,11 @@
<PackageReleaseNotes>https://github.com/AvaloniaUI/Avalonia/releases</PackageReleaseNotes> <PackageReleaseNotes>https://github.com/AvaloniaUI/Avalonia/releases</PackageReleaseNotes>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)\avalonia.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)\avalonia.snk</AssemblyOriginatorKeyFile>
<SignAssembly>false</SignAssembly> <SignAssembly>true</SignAssembly>
<DefineConstants Condition="$(SignAssembly) == true">$(DefineConstants);SIGNED_BUILD</DefineConstants> <DefineConstants Condition="$(SignAssembly) == true">$(DefineConstants);SIGNED_BUILD</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="PackageIcon"> <ItemGroup Label="PackageIcon">
<None Include="$(MSBuildThisFileDirectory)/Assets/Icon.png" Pack="true" PackagePath=""/> <None Include="$(MSBuildThisFileDirectory)/Assets/Icon.png" Pack="true" Visible="false" PackagePath=""/>
</ItemGroup> </ItemGroup>
</Project> </Project>

23
build/SourceLink.props

@ -1,5 +1,26 @@
<Project> <Project>
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>false</IncludeSymbols>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<DebugType>embedded</DebugType>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup>
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" PrivateAssets="All" /> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
<!-- Workaround for https://github.com/dotnet/sdk/issues/11105 -->
<ItemGroup>
<SourceRoot Include="$(NuGetPackageRoot)" Condition="'$(NuGetPackageRoot)' != ''" />
</ItemGroup> </ItemGroup>
</Project> </Project>

1
native/Avalonia.Native/inc/.gitignore

@ -0,0 +1 @@
avalonia-native.h

516
native/Avalonia.Native/inc/avalonia-native.h

@ -1,516 +0,0 @@
#include "com.h"
#include "key.h"
#include "stddef.h"
#define AVNCOM(name, id) COMINTERFACE(name, 2e2cda0a, 9ae5, 4f1b, 8e, 20, 08, 1a, 04, 27, 9f, id)
struct IAvnWindowEvents;
struct IAvnWindow;
struct IAvnPopup;
struct IAvnMacOptions;
struct IAvnPlatformThreadingInterface;
struct IAvnSystemDialogEvents;
struct IAvnSystemDialogs;
struct IAvnScreens;
struct IAvnClipboard;
struct IAvnCursor;
struct IAvnCursorFactory;
struct IAvnGlFeature;
struct IAvnGlContext;
struct IAvnGlDisplay;
struct IAvnGlSurfaceRenderTarget;
struct IAvnGlSurfaceRenderingSession;
struct IAvnMenu;
struct IAvnMenuItem;
struct IAvnStringArray;
struct IAvnDndResultCallback;
struct IAvnGCHandleDeallocatorCallback;
struct IAvnMenuEvents;
struct IAvnNativeControlHost;
struct IAvnNativeControlHostTopLevelAttachment;
enum SystemDecorations {
SystemDecorationsNone = 0,
SystemDecorationsBorderOnly = 1,
SystemDecorationsFull = 2,
};
struct AvnSize
{
double Width, Height;
};
struct AvnPixelSize
{
int Width, Height;
};
struct AvnRect
{
double X, Y, Width, Height;
};
struct AvnVector
{
double X, Y;
};
struct AvnPoint
{
double X, Y;
};
struct AvnScreen
{
AvnRect Bounds;
AvnRect WorkingArea;
float PixelDensity;
bool Primary;
};
enum AvnPixelFormat
{
kAvnRgb565,
kAvnRgba8888,
kAvnBgra8888
};
struct AvnFramebuffer
{
void* Data;
int Width;
int Height;
int Stride;
AvnVector Dpi;
AvnPixelFormat PixelFormat;
};
struct AvnColor
{
unsigned char Alpha;
unsigned char Red;
unsigned char Green;
unsigned char Blue;
};
enum AvnRawMouseEventType
{
LeaveWindow,
LeftButtonDown,
LeftButtonUp,
RightButtonDown,
RightButtonUp,
MiddleButtonDown,
MiddleButtonUp,
XButton1Down,
XButton1Up,
XButton2Down,
XButton2Up,
Move,
Wheel,
NonClientLeftButtonDown,
TouchBegin,
TouchUpdate,
TouchEnd,
TouchCancel
};
enum AvnRawKeyEventType
{
KeyDown,
KeyUp
};
enum AvnInputModifiers
{
AvnInputModifiersNone = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
LeftMouseButton = 16,
RightMouseButton = 32,
MiddleMouseButton = 64,
XButton1MouseButton = 128,
XButton2MouseButton = 256
};
enum class AvnDragDropEffects
{
None = 0,
Copy = 1,
Move = 2,
Link = 4,
};
enum class AvnDragEventType
{
Enter,
Over,
Leave,
Drop
};
enum AvnWindowState
{
Normal,
Minimized,
Maximized,
FullScreen,
};
enum AvnStandardCursorType
{
CursorArrow,
CursorIbeam,
CursorWait,
CursorCross,
CursorUpArrow,
CursorSizeWestEast,
CursorSizeNorthSouth,
CursorSizeAll,
CursorNo,
CursorHand,
CursorAppStarting,
CursorHelp,
CursorTopSide,
CursorBottomSize,
CursorLeftSide,
CursorRightSide,
CursorTopLeftCorner,
CursorTopRightCorner,
CursorBottomLeftCorner,
CursorBottomRightCorner,
CursorDragMove,
CursorDragCopy,
CursorDragLink,
CursorNone
};
enum AvnWindowEdge
{
WindowEdgeNorthWest,
WindowEdgeNorth,
WindowEdgeNorthEast,
WindowEdgeWest,
WindowEdgeEast,
WindowEdgeSouthWest,
WindowEdgeSouth,
WindowEdgeSouthEast
};
enum AvnMenuItemToggleType
{
None,
CheckMark,
Radio
};
enum AvnExtendClientAreaChromeHints
{
AvnNoChrome = 0,
AvnSystemChrome = 0x01,
AvnPreferSystemChrome = 0x02,
AvnOSXThickTitleBar = 0x08,
AvnDefaultChrome = AvnSystemChrome,
};
AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown
{
public:
virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator) = 0;
virtual IAvnMacOptions* GetMacOptions() = 0;
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv) = 0;
virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv) = 0;
virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0;
virtual HRESULT CreateSystemDialogs (IAvnSystemDialogs** ppv) = 0;
virtual HRESULT CreateScreens (IAvnScreens** ppv) = 0;
virtual HRESULT CreateClipboard(IAvnClipboard** ppv) = 0;
virtual HRESULT CreateDndClipboard(IAvnClipboard** ppv) = 0;
virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) = 0;
virtual HRESULT ObtainGlDisplay(IAvnGlDisplay** ppv) = 0;
virtual HRESULT SetAppMenu(IAvnMenu* menu) = 0;
virtual HRESULT CreateMenu (IAvnMenuEvents* cb, IAvnMenu** ppv) = 0;
virtual HRESULT CreateMenuItem (IAvnMenuItem** ppv) = 0;
virtual HRESULT CreateMenuItemSeperator (IAvnMenuItem** ppv) = 0;
};
AVNCOM(IAvnString, 17) : IUnknown
{
virtual HRESULT Pointer(void**retOut) = 0;
virtual HRESULT Length(int*ret) = 0;
};
AVNCOM(IAvnWindowBase, 02) : IUnknown
{
virtual HRESULT Show() = 0;
virtual HRESULT Hide () = 0;
virtual HRESULT Close() = 0;
virtual HRESULT Activate () = 0;
virtual HRESULT GetClientSize(AvnSize*ret) = 0;
virtual HRESULT GetScaling(double*ret)=0;
virtual HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize) = 0;
virtual HRESULT Resize(double width, double height) = 0;
virtual HRESULT Invalidate (AvnRect rect) = 0;
virtual HRESULT BeginMoveDrag () = 0;
virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) = 0;
virtual HRESULT GetPosition (AvnPoint*ret) = 0;
virtual HRESULT SetPosition (AvnPoint point) = 0;
virtual HRESULT PointToClient (AvnPoint point, AvnPoint*ret) = 0;
virtual HRESULT PointToScreen (AvnPoint point, AvnPoint*ret) = 0;
virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) = 0;
virtual HRESULT SetTopMost (bool value) = 0;
virtual HRESULT SetCursor(IAvnCursor* cursor) = 0;
virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ret) = 0;
virtual HRESULT SetMainMenu(IAvnMenu* menu) = 0;
virtual HRESULT ObtainNSWindowHandle(void** retOut) = 0;
virtual HRESULT ObtainNSWindowHandleRetained(void** retOut) = 0;
virtual HRESULT ObtainNSViewHandle(void** retOut) = 0;
virtual HRESULT ObtainNSViewHandleRetained(void** retOut) = 0;
virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut) = 0;
virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
IAvnClipboard* clipboard, IAvnDndResultCallback* cb, void* sourceHandle) = 0;
virtual HRESULT SetBlurEnabled (bool enable) = 0;
};
AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase
{
};
AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
{
virtual HRESULT SetEnabled (bool enable) = 0;
virtual HRESULT SetParent (IAvnWindow* parent) = 0;
virtual HRESULT SetCanResize(bool value) = 0;
virtual HRESULT SetDecorations(SystemDecorations value) = 0;
virtual HRESULT SetTitle (void* utf8Title) = 0;
virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
virtual HRESULT SetWindowState(AvnWindowState state) = 0;
virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
virtual HRESULT TakeFocusFromChildren() = 0;
virtual HRESULT SetExtendClientArea (bool enable) = 0;
virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) = 0;
virtual HRESULT GetExtendTitleBarHeight (double*ret) = 0;
virtual HRESULT SetExtendTitleBarHeight (double value) = 0;
};
AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
{
virtual HRESULT Paint() = 0;
virtual void Closed() = 0;
virtual void Activated() = 0;
virtual void Deactivated() = 0;
virtual void Resized(const AvnSize& size) = 0;
virtual void PositionChanged (AvnPoint position) = 0;
virtual void RawMouseEvent (AvnRawMouseEventType type,
unsigned int timeStamp,
AvnInputModifiers modifiers,
AvnPoint point,
AvnVector delta) = 0;
virtual bool RawKeyEvent (AvnRawKeyEventType type, unsigned int timeStamp, AvnInputModifiers modifiers, unsigned int key) = 0;
virtual bool RawTextInputEvent (unsigned int timeStamp, const char* text) = 0;
virtual void ScalingChanged(double scaling) = 0;
virtual void RunRenderPriorityJobs() = 0;
virtual void LostFocus() = 0;
virtual AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position,
AvnInputModifiers modifiers, AvnDragDropEffects effects,
IAvnClipboard* clipboard, void* dataObjectHandle) = 0;
};
AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents
{
/**
* Closing Event
* Called when the user presses the OS window close button.
* return true to allow the close, return false to prevent close.
*/
virtual bool Closing () = 0;
virtual void WindowStateChanged (AvnWindowState state) = 0;
virtual void GotInputWhenDisabled () = 0;
};
AVNCOM(IAvnMacOptions, 07) : IUnknown
{
virtual HRESULT SetShowInDock(int show) = 0;
virtual HRESULT SetApplicationTitle (void* utf8string) = 0;
};
AVNCOM(IAvnActionCallback, 08) : IUnknown
{
virtual void Run() = 0;
};
AVNCOM(IAvnSignaledCallback, 09) : IUnknown
{
virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0;
};
AVNCOM(IAvnLoopCancellation, 0a) : IUnknown
{
virtual void Cancel() = 0;
};
AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown
{
virtual bool GetCurrentThreadIsLoopThread() = 0;
virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;
virtual IAvnLoopCancellation* CreateLoopCancellation() = 0;
virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) = 0;
// Can't pass int* to sharpgentools for some reason
virtual void Signal(int priority) = 0;
virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0;
};
AVNCOM(IAvnSystemDialogEvents, 0c) : IUnknown
{
virtual void OnCompleted (int numResults, void* ptrFirstResult) = 0;
};
AVNCOM(IAvnSystemDialogs, 0d) : IUnknown
{
virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle,
IAvnSystemDialogEvents* events,
const char* title,
const char* initialPath) = 0;
virtual void OpenFileDialog (IAvnWindow* parentWindowHandle,
IAvnSystemDialogEvents* events,
bool allowMultiple,
const char* title,
const char* initialDirectory,
const char* initialFile,
const char* filters) = 0;
virtual void SaveFileDialog (IAvnWindow* parentWindowHandle,
IAvnSystemDialogEvents* events,
const char* title,
const char* initialDirectory,
const char* initialFile,
const char* filters) = 0;
};
AVNCOM(IAvnScreens, 0e) : IUnknown
{
virtual HRESULT GetScreenCount (int* ret) = 0;
virtual HRESULT GetScreen (int index, AvnScreen* ret) = 0;
};
AVNCOM(IAvnClipboard, 0f) : IUnknown
{
virtual HRESULT GetText (char* type, IAvnString**ppv) = 0;
virtual HRESULT SetText (char* type, void* utf8Text) = 0;
virtual HRESULT ObtainFormats(IAvnStringArray**ppv) = 0;
virtual HRESULT GetStrings(char* type, IAvnStringArray**ppv) = 0;
virtual HRESULT SetBytes(char* type, void* utf8Text, int len) = 0;
virtual HRESULT GetBytes(char* type, IAvnString**ppv) = 0;
virtual HRESULT Clear() = 0;
};
AVNCOM(IAvnCursor, 10) : IUnknown
{
};
AVNCOM(IAvnCursorFactory, 11) : IUnknown
{
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0;
};
AVNCOM(IAvnGlDisplay, 13) : IUnknown
{
virtual HRESULT CreateContext(IAvnGlContext* share, IAvnGlContext**ppv) = 0;
virtual void LegacyClearCurrentContext() = 0;
virtual HRESULT WrapContext(void* native, IAvnGlContext**ppv) = 0;
virtual void* GetProcAddress(char* proc) = 0;
};
AVNCOM(IAvnGlContext, 14) : IUnknown
{
virtual HRESULT MakeCurrent(IUnknown** ppv) = 0;
virtual HRESULT LegacyMakeCurrent() = 0;
virtual int GetSampleCount() = 0;
virtual int GetStencilSize() = 0;
virtual void* GetNativeHandle() = 0;
};
AVNCOM(IAvnGlSurfaceRenderTarget, 15) : IUnknown
{
virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) = 0;
};
AVNCOM(IAvnGlSurfaceRenderingSession, 16) : IUnknown
{
virtual HRESULT GetPixelSize(AvnPixelSize* ret) = 0;
virtual HRESULT GetScaling(double* ret) = 0;
};
AVNCOM(IAvnMenu, 17) : IUnknown
{
virtual HRESULT InsertItem (int index, IAvnMenuItem* item) = 0;
virtual HRESULT RemoveItem (IAvnMenuItem* item) = 0;
virtual HRESULT SetTitle (void* utf8String) = 0;
virtual HRESULT Clear () = 0;
};
AVNCOM(IAvnPredicateCallback, 18) : IUnknown
{
virtual bool Evaluate() = 0;
};
AVNCOM(IAvnMenuItem, 19) : IUnknown
{
virtual HRESULT SetSubMenu (IAvnMenu* menu) = 0;
virtual HRESULT SetTitle (void* utf8String) = 0;
virtual HRESULT SetGesture (void* utf8String, AvnInputModifiers modifiers) = 0;
virtual HRESULT SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) = 0;
virtual HRESULT SetIsChecked (bool isChecked) = 0;
virtual HRESULT SetToggleType (AvnMenuItemToggleType toggleType) = 0;
virtual HRESULT SetIcon (void* data, size_t length) = 0;
};
AVNCOM(IAvnMenuEvents, 1A) : IUnknown
{
/**
* NeedsUpdate
*/
virtual void NeedsUpdate () = 0;
};
AVNCOM(IAvnStringArray, 20) : IUnknown
{
virtual unsigned int GetCount() = 0;
virtual HRESULT Get(unsigned int index, IAvnString**ppv) = 0;
};
AVNCOM(IAvnDndResultCallback, 21) : IUnknown
{
virtual void OnDragAndDropComplete(AvnDragDropEffects effecct) = 0;
};
AVNCOM(IAvnGCHandleDeallocatorCallback, 22) : IUnknown
{
virtual void FreeGCHandle(void* handle) = 0;
};
AVNCOM(IAvnNativeControlHost, 20) : IUnknown
{
virtual HRESULT CreateDefaultChild(void* parent, void** retOut) = 0;
virtual IAvnNativeControlHostTopLevelAttachment* CreateAttachment() = 0;
virtual void DestroyDefaultChild(void* child) = 0;
};
AVNCOM(IAvnNativeControlHostTopLevelAttachment, 21) : IUnknown
{
virtual void* GetParentHandle() = 0;
virtual HRESULT InitializeWithChildHandle(void* child) = 0;
virtual HRESULT AttachTo(IAvnNativeControlHost* host) = 0;
virtual void ShowInBounds(float x, float y, float width, float height) = 0;
virtual void HideWithSize(float width, float height) = 0;
virtual void ReleaseChild() = 0;
};
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();

1020
native/Avalonia.Native/inc/key.h

File diff suppressed because it is too large

12
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@ -8,19 +8,20 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; }; 1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; };
1A1852DC23E05814008F0DED /* deadlock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A1852DB23E05814008F0DED /* deadlock.mm */; };
1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */; }; 1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */; };
1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */; }; 1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */; };
1A1852DC23E05814008F0DED /* deadlock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A1852DB23E05814008F0DED /* deadlock.mm */; };
1AFD334123E03C4F0042899B /* controlhost.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AFD334023E03C4F0042899B /* controlhost.mm */; };
1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EAD23E9FB1300EDE661 /* cgl.mm */; }; 1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EAD23E9FB1300EDE661 /* cgl.mm */; };
1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */; }; 1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */; };
1A465D10246AB61600C5858B /* dnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A465D0F246AB61600C5858B /* dnd.mm */; }; 1A465D10246AB61600C5858B /* dnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A465D0F246AB61600C5858B /* dnd.mm */; };
1AFD334123E03C4F0042899B /* controlhost.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AFD334023E03C4F0042899B /* controlhost.mm */; };
37155CE4233C00EB0034DCE9 /* menu.h in Headers */ = {isa = PBXBuildFile; fileRef = 37155CE3233C00EB0034DCE9 /* menu.h */; }; 37155CE4233C00EB0034DCE9 /* menu.h in Headers */ = {isa = PBXBuildFile; fileRef = 37155CE3233C00EB0034DCE9 /* menu.h */; };
37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; }; 37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; }; 37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DDA9AF219330F8002E132B /* AvnString.mm */; }; 37DDA9B0219330F8002E132B /* AvnString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DDA9AF219330F8002E132B /* AvnString.mm */; };
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; }; 37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; };
520624B322973F4100C4DCEF /* menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 520624B222973F4100C4DCEF /* menu.mm */; }; 520624B322973F4100C4DCEF /* menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 520624B222973F4100C4DCEF /* menu.mm */; };
522D5959258159C1006F7F7A /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 522D5958258159C1006F7F7A /* Carbon.framework */; };
5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; }; 5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; };
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; }; 5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; }; AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; };
@ -32,13 +33,13 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = "<group>"; }; 1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = "<group>"; };
1A1852DB23E05814008F0DED /* deadlock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = deadlock.mm; sourceTree = "<group>"; };
1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = rendertarget.mm; sourceTree = "<group>"; }; 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = rendertarget.mm; sourceTree = "<group>"; };
1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = System/Library/Frameworks/IOSurface.framework; sourceTree = SDKROOT; }; 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = System/Library/Frameworks/IOSurface.framework; sourceTree = SDKROOT; };
1A1852DB23E05814008F0DED /* deadlock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = deadlock.mm; sourceTree = "<group>"; };
1AFD334023E03C4F0042899B /* controlhost.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = controlhost.mm; sourceTree = "<group>"; };
1A3E5EAD23E9FB1300EDE661 /* cgl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cgl.mm; sourceTree = "<group>"; }; 1A3E5EAD23E9FB1300EDE661 /* cgl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cgl.mm; sourceTree = "<group>"; };
1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
1A465D0F246AB61600C5858B /* dnd.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = dnd.mm; sourceTree = "<group>"; }; 1A465D0F246AB61600C5858B /* dnd.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = dnd.mm; sourceTree = "<group>"; };
1AFD334023E03C4F0042899B /* controlhost.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = controlhost.mm; sourceTree = "<group>"; };
37155CE3233C00EB0034DCE9 /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; }; 37155CE3233C00EB0034DCE9 /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; };
379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = "<group>"; }; 379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = "<group>"; };
37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = "<group>"; }; 37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = "<group>"; };
@ -49,6 +50,7 @@
37DDA9B121933371002E132B /* AvnString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnString.h; sourceTree = "<group>"; }; 37DDA9B121933371002E132B /* AvnString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnString.h; sourceTree = "<group>"; };
37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; }; 37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; };
520624B222973F4100C4DCEF /* menu.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = menu.mm; sourceTree = "<group>"; }; 520624B222973F4100C4DCEF /* menu.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = menu.mm; sourceTree = "<group>"; };
522D5958258159C1006F7F7A /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; }; 5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; };
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; }; 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; };
5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; }; 5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
@ -69,6 +71,7 @@
1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */, 1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */,
1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */, 1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */,
AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */, AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */,
522D5959258159C1006F7F7A /* Carbon.framework in Frameworks */,
AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */, AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -79,6 +82,7 @@
AB661C1C2148230E00291242 /* Frameworks */ = { AB661C1C2148230E00291242 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
522D5958258159C1006F7F7A /* Carbon.framework */,
1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */, 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */,
1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */, 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */,
AB1E522B217613570091CD71 /* OpenGL.framework */, AB1E522B217613570091CD71 /* OpenGL.framework */,

7
native/Avalonia.Native/src/OSX/KeyTransform.h

@ -1,9 +1,14 @@
#ifndef keytransform_h #ifndef keytransform_h
#define keytransform_h #define keytransform_h
#include "common.h" #include "common.h"
#include "key.h"
#include <map> #include <map>
extern std::map<int, AvnKey> s_KeyMap; extern std::map<int, AvnKey> s_KeyMap;
extern std::map<AvnKey, int> s_AvnKeyMap;
extern std::map<int, const char*> s_QwertyKeyMap;
extern std::map<AvnKey, int> s_UnicodeKeyMap;
#endif #endif

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

@ -120,6 +120,138 @@ const int kVK_UpArrow = 0x7E;
//const int kVK_JIS_Eisu = 0x66; //const int kVK_JIS_Eisu = 0x66;
const int kVK_JIS_Kana = 0x68; const int kVK_JIS_Kana = 0x68;
// converts from AvaloniaKeys to UnicodeSpecial keys.
std::map<AvnKey, int> s_UnicodeKeyMap =
{
{ Up, NSUpArrowFunctionKey },
{ Down, NSDownArrowFunctionKey },
{ Left, NSLeftArrowFunctionKey },
{ Right, NSRightArrowFunctionKey },
{ F1, NSF1FunctionKey },
{ F2, NSF2FunctionKey },
{ F3, NSF3FunctionKey },
{ F4, NSF4FunctionKey },
{ F5, NSF5FunctionKey },
{ F6, NSF6FunctionKey },
{ F7, NSF7FunctionKey },
{ F8, NSF8FunctionKey },
{ F9, NSF9FunctionKey },
{ F10, NSF10FunctionKey },
{ F11, NSF11FunctionKey },
{ F12, NSF12FunctionKey },
{ F13, NSF13FunctionKey },
{ F14, NSF14FunctionKey },
{ F15, NSF15FunctionKey },
{ F16, NSF16FunctionKey },
{ F17, NSF17FunctionKey },
{ F18, NSF18FunctionKey },
{ F19, NSF19FunctionKey },
{ F20, NSF20FunctionKey },
{ F21, NSF21FunctionKey },
{ F22, NSF22FunctionKey },
{ F23, NSF23FunctionKey },
{ F24, NSF24FunctionKey },
{ Insert, NSInsertFunctionKey },
{ Delete, NSDeleteFunctionKey },
{ Home, NSHomeFunctionKey },
//{ Begin, NSBeginFunctionKey },
{ End, NSEndFunctionKey },
{ PageUp, NSPageUpFunctionKey },
{ PageDown, NSPageDownFunctionKey },
{ PrintScreen, NSPrintScreenFunctionKey },
{ Scroll, NSScrollLockFunctionKey },
//{ SysReq, NSSysReqFunctionKey },
//{ Break, NSBreakFunctionKey },
//{ Reset, NSResetFunctionKey },
//{ Stop, NSStopFunctionKey },
//{ Menu, NSMenuFunctionKey },
//{ UserFunction, NSUserFunctionKey },
//{ SystemFunction, NSSystemFunctionKey },
{ Print, NSPrintFunctionKey },
//{ ClearLine, NSClearLineFunctionKey },
//{ ClearDisplay, NSClearDisplayFunctionKey },
};
// Converts from Ansi virtual keys to Qwerty Keyboard map.
std::map<int, const char*> s_QwertyKeyMap =
{
{ 0, "a" },
{ 1, "s" },
{ 2, "d" },
{ 3, "f" },
{ 4, "h" },
{ 5, "g" },
{ 6, "z" },
{ 7, "x" },
{ 8, "c" },
{ 9, "v" },
{ 10, "§" },
{ 11, "b" },
{ 12, "q" },
{ 13, "w" },
{ 14, "e" },
{ 15, "r" },
{ 16, "y" },
{ 17, "t" },
{ 18, "1" },
{ 19, "2" },
{ 20, "3" },
{ 21, "4" },
{ 22, "6" },
{ 23, "5" },
{ 24, "=" },
{ 25, "9" },
{ 26, "7" },
{ 27, "-" },
{ 28, "8" },
{ 29, "0" },
{ 30, "]" },
{ 31, "o" },
{ 32, "u" },
{ 33, "[" },
{ 34, "i" },
{ 35, "p" },
{ 37, "l" },
{ 38, "j" },
{ 39, "'" },
{ 40, "k" },
{ 41, ";" },
{ 42, "\\" },
{ 43, "," },
{ 44, "/" },
{ 45, "n" },
{ 46, "m" },
{ 47, "." },
{ 49, " " },
{ 50, "`" },
{ 51, "" },
{ 52, "" },
{ 53, "" },
{ 65, "." },
{ 66, "" },
{ 67, "*" },
{ 69, "+" },
{ 70, "" },
{ 71, "" },
{ 72, "" },
{ 75, "/" },
{ 76, "" },
{ 77, "" },
{ 78, "-" },
{ 81, "=" },
{ 82, "0" },
{ 83, "1" },
{ 84, "2" },
{ 85, "3" },
{ 86, "4" },
{ 87, "5" },
{ 88, "6" },
{ 89, "7" },
{ 91, "8" },
{ 92, "9" }
};
// converts from ansi virtualkeys to AvnKeys.
std::map<int, AvnKey> s_KeyMap = std::map<int, AvnKey> s_KeyMap =
{ {
{kVK_ANSI_A, A}, {kVK_ANSI_A, A},
@ -237,3 +369,22 @@ const int kVK_JIS_Kana = 0x68;
{kVK_UpArrow, Up}, {kVK_UpArrow, Up},
{kVK_JIS_Kana, AvnKeyKanaMode}, {kVK_JIS_Kana, AvnKeyKanaMode},
}; };
static std::map<AvnKey, int> BuildAvnKeyMap ()
{
std::map<AvnKey, int> result;
for( auto it = s_KeyMap.begin(); it != s_KeyMap.end(); ++it )
{
int key = it->first;
AvnKey value = it->second;
result[value] = key;
}
return result;
}
// Converts AvnKeys to Ansi VirtualKeys
std::map<AvnKey, int> s_AvnKeyMap = BuildAvnKeyMap();

2
native/Avalonia.Native/src/OSX/clipboard.mm

@ -67,7 +67,7 @@ public:
} }
} }
virtual HRESULT SetText (char* type, void* utf8String) override virtual HRESULT SetText (char* type, char* utf8String) override
{ {
Clear(); Clear();
@autoreleasepool @autoreleasepool

4
native/Avalonia.Native/src/OSX/main.mm

@ -104,9 +104,9 @@ class MacOptions : public ComSingleObject<IAvnMacOptions, &IID_IAvnMacOptions>
public: public:
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
virtual HRESULT SetApplicationTitle(void* utf8String) override virtual HRESULT SetApplicationTitle(char* utf8String) override
{ {
auto appTitle = [NSString stringWithUTF8String:(const char*)utf8String]; auto appTitle = [NSString stringWithUTF8String: utf8String];
[[NSProcessInfo processInfo] setProcessName:appTitle]; [[NSProcessInfo processInfo] setProcessName:appTitle];

6
native/Avalonia.Native/src/OSX/menu.h

@ -43,9 +43,9 @@ public:
virtual HRESULT SetSubMenu (IAvnMenu* menu) override; virtual HRESULT SetSubMenu (IAvnMenu* menu) override;
virtual HRESULT SetTitle (void* utf8String) override; virtual HRESULT SetTitle (char* utf8String) override;
virtual HRESULT SetGesture (void* key, AvnInputModifiers modifiers) override; virtual HRESULT SetGesture (AvnKey key, AvnInputModifiers modifiers) override;
virtual HRESULT SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) override; virtual HRESULT SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) override;
@ -80,7 +80,7 @@ public:
virtual HRESULT RemoveItem (IAvnMenuItem* item) override; virtual HRESULT RemoveItem (IAvnMenuItem* item) override;
virtual HRESULT SetTitle (void* utf8String) override; virtual HRESULT SetTitle (char* utf8String) override;
virtual HRESULT Clear () override; virtual HRESULT Clear () override;
}; };

67
native/Avalonia.Native/src/OSX/menu.mm

@ -2,6 +2,9 @@
#include "common.h" #include "common.h"
#include "menu.h" #include "menu.h"
#include "window.h" #include "window.h"
#include "KeyTransform.h"
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h> /* For kVK_ constants, and TIS functions. */
@implementation AvnMenu @implementation AvnMenu
{ {
@ -109,7 +112,7 @@ HRESULT AvnAppMenuItem::SetSubMenu (IAvnMenu* menu)
} }
} }
HRESULT AvnAppMenuItem::SetTitle (void* utf8String) HRESULT AvnAppMenuItem::SetTitle (char* utf8String)
{ {
@autoreleasepool @autoreleasepool
{ {
@ -122,23 +125,57 @@ HRESULT AvnAppMenuItem::SetTitle (void* utf8String)
} }
} }
HRESULT AvnAppMenuItem::SetGesture (void* key, AvnInputModifiers modifiers)
HRESULT AvnAppMenuItem::SetGesture (AvnKey key, AvnInputModifiers modifiers)
{ {
@autoreleasepool @autoreleasepool
{ {
NSEventModifierFlags flags = 0; if(key != AvnKeyNone)
{
if (modifiers & Control) NSEventModifierFlags flags = 0;
flags |= NSEventModifierFlagControl;
if (modifiers & Shift) if (modifiers & Control)
flags |= NSEventModifierFlagShift; flags |= NSEventModifierFlagControl;
if (modifiers & Alt) if (modifiers & Shift)
flags |= NSEventModifierFlagOption; flags |= NSEventModifierFlagShift;
if (modifiers & Windows) if (modifiers & Alt)
flags |= NSEventModifierFlagCommand; flags |= NSEventModifierFlagOption;
if (modifiers & Windows)
flags |= NSEventModifierFlagCommand;
auto it = s_UnicodeKeyMap.find(key);
if(it != s_UnicodeKeyMap.end())
{
auto keyString= [NSString stringWithFormat:@"%C", (unsigned short)it->second];
[_native setKeyEquivalent: keyString];
[_native setKeyEquivalentModifierMask:flags];
return S_OK;
}
else
{
auto it = s_AvnKeyMap.find(key); // check if a virtual key is mapped.
if(it != s_AvnKeyMap.end())
{
auto it1 = s_QwertyKeyMap.find(it->second); // convert virtual key to qwerty string.
if(it1 != s_QwertyKeyMap.end())
{
[_native setKeyEquivalent: [NSString stringWithUTF8String: it1->second]];
[_native setKeyEquivalentModifierMask:flags];
return S_OK;
}
}
}
}
[_native setKeyEquivalent:[NSString stringWithUTF8String:(const char*)key]]; // Nothing matched... clear.
[_native setKeyEquivalentModifierMask:flags]; [_native setKeyEquivalent: @""];
[_native setKeyEquivalentModifierMask: 0];
return S_OK; return S_OK;
} }
@ -296,7 +333,7 @@ HRESULT AvnAppMenu::RemoveItem (IAvnMenuItem* item)
} }
} }
HRESULT AvnAppMenu::SetTitle (void* utf8String) HRESULT AvnAppMenu::SetTitle (char* utf8String)
{ {
@autoreleasepool @autoreleasepool
{ {

2
native/Avalonia.Native/src/OSX/platformthreading.mm

@ -101,7 +101,7 @@ public:
virtual bool GetCurrentThreadIsLoopThread() override virtual bool GetCurrentThreadIsLoopThread() override
{ {
return [[NSThread currentThread] isMainThread]; return [NSThread isMainThread];
} }
virtual void SetSignaledCallback(IAvnSignaledCallback* cb) override virtual void SetSignaledCallback(IAvnSignaledCallback* cb) override
{ {

22
native/Avalonia.Native/src/OSX/rendertarget.mm

@ -2,6 +2,7 @@
#include "rendertarget.h" #include "rendertarget.h"
#import <IOSurface/IOSurface.h> #import <IOSurface/IOSurface.h>
#import <IOSurface/IOSurfaceObjC.h> #import <IOSurface/IOSurfaceObjC.h>
#import <QuartzCore/QuartzCore.h>
#include <OpenGL/CGLIOSurface.h> #include <OpenGL/CGLIOSurface.h>
#include <OpenGL/OpenGL.h> #include <OpenGL/OpenGL.h>
@ -110,7 +111,11 @@
if(_renderbuffer != 0) if(_renderbuffer != 0)
glDeleteRenderbuffers(1, &_renderbuffer); glDeleteRenderbuffers(1, &_renderbuffer);
} }
CFRelease(surface);
if(surface != nullptr)
{
CFRelease(surface);
}
} }
@end @end
@ -143,13 +148,23 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
return _layer; return _layer;
} }
- (void)resize:(AvnPixelSize)size withScale: (float) scale;{ - (void)resize:(AvnPixelSize)size withScale: (float) scale{
if(size.Height <= 0)
size.Height = 1;
if(size.Width <= 0)
size.Width = 1;
@synchronized (lock) { @synchronized (lock) {
if(surface == nil if(surface == nil
|| surface->size.Width != size.Width || surface->size.Width != size.Width
|| surface->size.Height != size.Height || surface->size.Height != size.Height
|| surface->scale != scale) || surface->scale != scale)
{
surface = [[IOSurfaceHolder alloc] initWithSize:size withScale:scale withOpenGlContext:_glContext.getRaw()]; surface = [[IOSurfaceHolder alloc] initWithSize:size withScale:scale withOpenGlContext:_glContext.getRaw()];
[self updateLayer];
}
} }
} }
@ -159,12 +174,15 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
@synchronized (lock) { @synchronized (lock) {
if(_layer == nil) if(_layer == nil)
return; return;
[CATransaction begin];
[_layer setContents: nil]; [_layer setContents: nil];
if(surface != nil) if(surface != nil)
{ {
[_layer setContentsScale: surface->scale]; [_layer setContentsScale: surface->scale];
[_layer setContents: (__bridge IOSurface*) surface->surface]; [_layer setContents: (__bridge IOSurface*) surface->surface];
} }
[CATransaction commit];
[CATransaction flush];
} }
} }
else else

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

@ -106,13 +106,13 @@ public:
return Window; return Window;
} }
virtual HRESULT Show() override virtual HRESULT Show(bool activate) override
{ {
@autoreleasepool @autoreleasepool
{ {
SetPosition(lastPositionSet); SetPosition(lastPositionSet);
UpdateStyle(); UpdateStyle();
if(ShouldTakeFocusOnShow()) if(ShouldTakeFocusOnShow() && activate)
{ {
[Window makeKeyAndOrderFront:Window]; [Window makeKeyAndOrderFront:Window];
[NSApp activateIgnoringOtherApps:YES]; [NSApp activateIgnoringOtherApps:YES];
@ -561,11 +561,11 @@ private:
} }
} }
virtual HRESULT Show () override virtual HRESULT Show (bool activate) override
{ {
@autoreleasepool @autoreleasepool
{ {
WindowBaseImpl::Show(); WindowBaseImpl::Show(activate);
HideOrShowTrafficLights(); HideOrShowTrafficLights();
@ -768,7 +768,7 @@ private:
} }
} }
virtual HRESULT SetTitle (void* utf8title) override virtual HRESULT SetTitle (char* utf8title) override
{ {
@autoreleasepool @autoreleasepool
{ {

29
nukebuild/Build.cs

@ -107,7 +107,7 @@ partial class Build : NukeBuild
.AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_8_X64"))) .AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_8_X64")))
.AddProperty("PackageVersion", Parameters.Version) .AddProperty("PackageVersion", Parameters.Version)
.AddProperty("iOSRoslynPathHackRequired", true) .AddProperty("iOSRoslynPathHackRequired", true)
.SetToolPath(MsBuildExe.Value) .SetProcessToolPath(MsBuildExe.Value)
.SetConfiguration(Parameters.Configuration) .SetConfiguration(Parameters.Configuration)
.SetVerbosity(MSBuildVerbosity.Minimal) .SetVerbosity(MSBuildVerbosity.Minimal)
.Apply(configurator)); .Apply(configurator));
@ -132,15 +132,16 @@ partial class Build : NukeBuild
var webappDir = RootDirectory / "src" / "Avalonia.DesignerSupport" / "Remote" / "HtmlTransport" / "webapp"; var webappDir = RootDirectory / "src" / "Avalonia.DesignerSupport" / "Remote" / "HtmlTransport" / "webapp";
NpmTasks.NpmInstall(c => c NpmTasks.NpmInstall(c => c
.SetWorkingDirectory(webappDir) .SetProcessWorkingDirectory(webappDir)
.SetArgumentConfigurator(a => a.Add("--silent"))); .SetProcessArgumentConfigurator(a => a.Add("--silent")));
NpmTasks.NpmRun(c => c NpmTasks.NpmRun(c => c
.SetWorkingDirectory(webappDir) .SetProcessWorkingDirectory(webappDir)
.SetCommand("dist")); .SetCommand("dist"));
}); });
Target CompileNative => _ => _ Target CompileNative => _ => _
.DependsOn(Clean) .DependsOn(Clean)
.DependsOn(GenerateCppHeaders)
.OnlyWhenStatic(() => EnvironmentInfo.IsOsx) .OnlyWhenStatic(() => EnvironmentInfo.IsOsx)
.Executes(() => .Executes(() =>
{ {
@ -156,7 +157,7 @@ partial class Build : NukeBuild
{ {
if (Parameters.IsRunningOnWindows) if (Parameters.IsRunningOnWindows)
MsBuildCommon(Parameters.MSBuildSolution, c => c MsBuildCommon(Parameters.MSBuildSolution, c => c
.SetArgumentConfigurator(a => a.Add("/r")) .SetProcessArgumentConfigurator(a => a.Add("/r"))
.AddTargets("Build") .AddTargets("Build")
); );
@ -193,7 +194,7 @@ partial class Build : NukeBuild
var eventsProject = Path.Combine(eventsDirectory, "Avalonia.ReactiveUI.Events.csproj"); var eventsProject = Path.Combine(eventsDirectory, "Avalonia.ReactiveUI.Events.csproj");
if (Parameters.IsRunningOnWindows) if (Parameters.IsRunningOnWindows)
MsBuildCommon(eventsProject, c => c MsBuildCommon(eventsProject, c => c
.SetArgumentConfigurator(a => a.Add("/r")) .SetProcessArgumentConfigurator(a => a.Add("/r"))
.AddTargets("Build") .AddTargets("Build")
); );
else else
@ -233,6 +234,21 @@ partial class Build : NukeBuild
} }
} }
Target RunHtmlPreviewerTests => _ => _
.DependsOn(CompileHtmlPreviewer)
.OnlyWhenStatic(() => !(Parameters.SkipPreviewer || Parameters.SkipTests))
.Executes(() =>
{
var webappTestDir = RootDirectory / "tests" / "Avalonia.DesignerSupport.Tests" / "Remote" / "HtmlTransport" / "webapp";
NpmTasks.NpmInstall(c => c
.SetProcessWorkingDirectory(webappTestDir)
.SetProcessArgumentConfigurator(a => a.Add("--silent")));
NpmTasks.NpmRun(c => c
.SetProcessWorkingDirectory(webappTestDir)
.SetCommand("test"));
});
Target RunCoreLibsTests => _ => _ Target RunCoreLibsTests => _ => _
.OnlyWhenStatic(() => !Parameters.SkipTests) .OnlyWhenStatic(() => !Parameters.SkipTests)
.DependsOn(Compile) .DependsOn(Compile)
@ -332,6 +348,7 @@ partial class Build : NukeBuild
.DependsOn(RunCoreLibsTests) .DependsOn(RunCoreLibsTests)
.DependsOn(RunRenderTests) .DependsOn(RunRenderTests)
.DependsOn(RunDesignerTests) .DependsOn(RunDesignerTests)
.DependsOn(RunHtmlPreviewerTests)
.DependsOn(RunLeakTests); .DependsOn(RunLeakTests);
Target Package => _ => _ Target Package => _ => _

2
nukebuild/BuildParameters.cs

@ -62,7 +62,7 @@ public partial class Build
public AbsolutePath ZipTargetControlCatalogDesktopDir { get; } public AbsolutePath ZipTargetControlCatalogDesktopDir { get; }
public BuildParameters(Build b) public BuildParameters(Build b)
{ {
// ARGUMENTS // ARGUMENTS
Configuration = b.Configuration ?? "Release"; Configuration = b.Configuration ?? "Release";

14
nukebuild/MicroComGen.cs

@ -0,0 +1,14 @@
using System.IO;
using MicroComGenerator;
using Nuke.Common;
partial class Build : NukeBuild
{
Target GenerateCppHeaders => _ => _.Executes(() =>
{
var text = File.ReadAllText(RootDirectory / "src" / "Avalonia.Native" / "avn.idl");
var ast = AstParser.Parse(text);
File.WriteAllText(RootDirectory / "native" / "Avalonia.Native" / "inc" / "avalonia-native.h",
CppGen.GenerateCpp(ast));
});
}

6
nukebuild/_build.csproj

@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Nuke.Common" Version="0.24.0" /> <PackageReference Include="Nuke.Common" Version="5.0.0" />
<PackageReference Include="xunit.runner.console" Version="2.3.1" /> <PackageReference Include="xunit.runner.console" Version="2.3.1" />
<PackageReference Include="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" /> <PackageReference Include="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" />
<PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " /> <PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " />
@ -39,4 +39,8 @@
<Compile Include="Numerge/Numerge/**/*.cs" /> <Compile Include="Numerge/Numerge/**/*.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\tools\MicroComGenerator\MicroComGenerator.csproj" />
</ItemGroup>
</Project> </Project>

19
packages/Avalonia/Avalonia.csproj

@ -5,9 +5,10 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj"/> <ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj" />
<ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj" /> <ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj" >
<PrivateAssets>all</PrivateAssets>
</ProjectReference>
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
@ -15,9 +16,7 @@
</PropertyGroup> </PropertyGroup>
<Target Name="AddDesignerHostAppsToPackage" BeforeTargets="GenerateNuspec"> <Target Name="AddDesignerHostAppsToPackage" BeforeTargets="GenerateNuspec">
<MSBuild Projects="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj" <MSBuild Projects="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj" Properties="Configuration=$(Configuration);&#xA; Platform=$(Platform)" />
Properties="Configuration=$(Configuration);
Platform=$(Platform)" />
<ItemGroup> <ItemGroup>
<_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/netcoreapp2.0/Avalonia.Designer.HostApp.dll"> <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/netcoreapp2.0/Avalonia.Designer.HostApp.dll">
@ -32,21 +31,23 @@
</_PackageFiles> </_PackageFiles>
</ItemGroup> </ItemGroup>
</Target> </Target>
<ItemGroup> <ItemGroup>
<Content Include="*.props"> <Content Include="*.props">
<Pack>true</Pack> <Pack>true</Pack>
<PackagePath>build\</PackagePath> <PackagePath>build\;buildTransitive\</PackagePath>
</Content> </Content>
<Content Include="*.targets"> <Content Include="*.targets">
<Pack>true</Pack> <Pack>true</Pack>
<PackagePath>build\</PackagePath> <PackagePath>build\;buildTransitive\</PackagePath>
</Content> </Content>
<Content Include="AvaloniaItemSchema.xaml"> <Content Include="AvaloniaItemSchema.xaml">
<Pack>true</Pack> <Pack>true</Pack>
<PackagePath>build\</PackagePath> <PackagePath>build\;buildTransitive\</PackagePath>
</Content> </Content>
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\SharedVersion.props" /> <Import Project="..\..\build\SharedVersion.props" />
<Import Project="..\..\build\NetFX.props" /> <Import Project="..\..\build\NetFX.props" />
<Import Project="..\..\build\CoreLibraries.props" /> <Import Project="..\..\build\CoreLibraries.props" />
<Import Project="..\..\build\SourceLink.props" Condition="'$(DisableSourceLink)' == ''" />
</Project> </Project>

4
packages/Avalonia/AvaloniaBuildTasks.targets

@ -3,6 +3,8 @@
<_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild)</_AvaloniaUseExternalMSBuild> <_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild)</_AvaloniaUseExternalMSBuild>
<_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false</_AvaloniaUseExternalMSBuild> <_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false</_AvaloniaUseExternalMSBuild>
<AvaloniaXamlReportImportance Condition="'$(AvaloniaXamlReportImportance)' == ''">low</AvaloniaXamlReportImportance> <AvaloniaXamlReportImportance Condition="'$(AvaloniaXamlReportImportance)' == ''">low</AvaloniaXamlReportImportance>
<_AvaloniaPatchComInterop Condition="'$(_AvaloniaPatchComInterop)' == ''">false</_AvaloniaPatchComInterop>
<_AvaloniaSkipXamlCompilation Condition="'$(_AvaloniaSkipXamlCompilation)' == ''">false</_AvaloniaSkipXamlCompilation>
</PropertyGroup> </PropertyGroup>
<!-- Unfortunately we have to update default items in .targets since custom nuget props are improted before Microsoft.NET.Sdk.DefaultItems.props --> <!-- Unfortunately we have to update default items in .targets since custom nuget props are improted before Microsoft.NET.Sdk.DefaultItems.props -->
@ -90,6 +92,8 @@
AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)" AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)"
SignAssembly="$(SignAssembly)" SignAssembly="$(SignAssembly)"
DelaySign="$(DelaySign)" DelaySign="$(DelaySign)"
EnableComInteropPatching="$(_AvaloniaPatchComInterop)"
SkipXamlCompilation="$(_AvaloniaSkipXamlCompilation)"
/> />
<Exec <Exec
Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'" Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'"

11
readme.md

@ -10,6 +10,8 @@ Avalonia is a cross-platform XAML-based UI framework providing a flexible stylin
<img src="https://user-images.githubusercontent.com/6759207/84751662-7c79da00-afc5-11ea-8780-dda28db70b76.png" width="700" /> <img src="https://user-images.githubusercontent.com/6759207/84751662-7c79da00-afc5-11ea-8780-dda28db70b76.png" width="700" />
([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
> **Note:** The UI theme you see in the picture above is still work-in-progress and will be available in the upcoming Avalonia 0.10.0 release. However, you can connect to our nightly build feed and install latest pre-release versions of Avalonia NuGet packages, if you are willing to help out with the development and testing. See [Using nightly build feed](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed) for more info. > **Note:** The UI theme you see in the picture above is still work-in-progress and will be available in the upcoming Avalonia 0.10.0 release. However, you can connect to our nightly build feed and install latest pre-release versions of Avalonia NuGet packages, if you are willing to help out with the development and testing. See [Using nightly build feed](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed) for more info.
To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239). You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been. [Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia! To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239). You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been. [Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia!
@ -31,15 +33,22 @@ Install-Package Avalonia.Desktop
Examples of UIs built with Avalonia Examples of UIs built with Avalonia
![image](https://user-images.githubusercontent.com/4672627/84707589-5b69a880-af35-11ea-87a6-7ad57a31d314.png) ![image](https://user-images.githubusercontent.com/4672627/84707589-5b69a880-af35-11ea-87a6-7ad57a31d314.png)
([Synfonia](https://github.com/jmacato/Synfonia))
![image](https://user-images.githubusercontent.com/4672627/85069644-d8419000-b18a-11ea-8732-be9055bb61fd.PNG) ![image](https://user-images.githubusercontent.com/4672627/85069644-d8419000-b18a-11ea-8732-be9055bb61fd.PNG)
([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
![image](https://user-images.githubusercontent.com/4672627/85069659-dc6dad80-b18a-11ea-8375-39ef95315b5c.PNG) ![image](https://user-images.githubusercontent.com/4672627/85069659-dc6dad80-b18a-11ea-8375-39ef95315b5c.PNG)
([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
![image](https://user-images.githubusercontent.com/4672627/84708947-c3b98980-af37-11ea-8c9d-503334615bbf.png) ![image](https://user-images.githubusercontent.com/4672627/84708947-c3b98980-af37-11ea-8c9d-503334615bbf.png)
([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
## JetBrains Rider ## JetBrains Rider
If you need to develop Avalonia app with JetBrains Rider you can use latest Rider [preview builds](https://www.jetbrains.com/rider/nextversion/). [JetBrains Rider](https://www.jetbrains.com/rider/whatsnew/?mkt_tok=eyJpIjoiTURBNU1HSmhNV0kwTUdFMiIsInQiOiJtNnU2VEc1TlNLa1ZRVkROYmdZYVpYREJsaU1qdUhmS3dxSzRHczdYWHl0RVlTNDMwSFwvNUs3VENTNVM0bVcyNFdaRmVYZzVWTTF1N3VrQWNGTkJreEhlam1hMlB4UVVWcHBGM1dNOUxoXC95YnRQdGgyUXl1YmZCM3h3d3BVWWdBIn0%3D#avalonia-support) now has official support for Avalonia.
Code completion, inspections and refactorings are supported out of the box, for XAML previewer add `https://plugins.jetbrains.com/plugins/dev/14839` to plugin repositories and install [AvaloniaRider](https://github.com/ForNeVeR/AvaloniaRider) plugin.
## Bleeding Edge Builds ## Bleeding Edge Builds

2
samples/BindingDemo/App.xaml.cs

@ -1,7 +1,6 @@
using Avalonia; using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace BindingDemo namespace BindingDemo
{ {
@ -25,7 +24,6 @@ namespace BindingDemo
public static AppBuilder BuildAvaloniaApp() public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>() => AppBuilder.Configure<App>()
.UsePlatformDetect() .UsePlatformDetect()
.UseReactiveUI()
.LogToTrace(); .LogToTrace();
} }
} }

3
samples/BindingDemo/BindingDemo.csproj

@ -6,12 +6,11 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" /> <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj" /> <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\SampleApp.props" /> <Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\EmbedXaml.props" /> <Import Project="..\..\build\EmbedXaml.props" />
<Import Project="..\..\build\Rx.props" /> <Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\ReactiveUI.props" />
<Import Condition="'$(TargetFramework)'=='net461'" Project="..\..\build\NetFX.props" /> <Import Condition="'$(TargetFramework)'=='net461'" Project="..\..\build\NetFX.props" />
<Import Project="..\..\build\ReferenceCoreLibraries.props" /> <Import Project="..\..\build\ReferenceCoreLibraries.props" />
<Import Project="..\..\build\BuildTargets.targets" /> <Import Project="..\..\build\BuildTargets.targets" />

4
samples/BindingDemo/ViewModels/ExceptionErrorViewModel.cs

@ -1,9 +1,9 @@
using ReactiveUI; using MiniMvvm;
using System; using System;
namespace BindingDemo.ViewModels namespace BindingDemo.ViewModels
{ {
public class ExceptionErrorViewModel : ReactiveObject public class ExceptionErrorViewModel : ViewModelBase
{ {
private int _lessThan10; private int _lessThan10;

4
samples/BindingDemo/ViewModels/IndeiErrorViewModel.cs

@ -1,11 +1,11 @@
using ReactiveUI; using MiniMvvm;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Collections; using System.Collections;
namespace BindingDemo.ViewModels namespace BindingDemo.ViewModels
{ {
public class IndeiErrorViewModel : ReactiveObject, INotifyDataErrorInfo public class IndeiErrorViewModel : ViewModelBase, INotifyDataErrorInfo
{ {
private int _maximum = 10; private int _maximum = 10;
private int _value; private int _value;

12
samples/BindingDemo/ViewModels/MainWindowViewModel.cs

@ -5,14 +5,14 @@ using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
using ReactiveUI; using MiniMvvm;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Controls.Selection; using Avalonia.Controls.Selection;
namespace BindingDemo.ViewModels namespace BindingDemo.ViewModels
{ {
public class MainWindowViewModel : ReactiveObject public class MainWindowViewModel : ViewModelBase
{ {
private string _booleanString = "True"; private string _booleanString = "True";
private double _doubleValue = 5.0; private double _doubleValue = 5.0;
@ -32,13 +32,13 @@ namespace BindingDemo.ViewModels
Selection = new SelectionModel<TestItem> { SingleSelect = false }; Selection = new SelectionModel<TestItem> { SingleSelect = false };
ShuffleItems = ReactiveCommand.Create(() => ShuffleItems = MiniCommand.Create(() =>
{ {
var r = new Random(); var r = new Random();
Items.Move(r.Next(Items.Count), 1); Items.Move(r.Next(Items.Count), 1);
}); });
StringValueCommand = ReactiveCommand.Create<object>(param => StringValueCommand = MiniCommand.Create<object>(param =>
{ {
BooleanFlag = !BooleanFlag; BooleanFlag = !BooleanFlag;
StringValue = param.ToString(); StringValue = param.ToString();
@ -60,7 +60,7 @@ namespace BindingDemo.ViewModels
public ObservableCollection<TestItem> Items { get; } public ObservableCollection<TestItem> Items { get; }
public SelectionModel<TestItem> Selection { get; } public SelectionModel<TestItem> Selection { get; }
public ReactiveCommand<Unit, Unit> ShuffleItems { get; } public MiniCommand ShuffleItems { get; }
public string BooleanString public string BooleanString
{ {
@ -93,7 +93,7 @@ namespace BindingDemo.ViewModels
} }
public IObservable<DateTimeOffset> CurrentTimeObservable { get; } public IObservable<DateTimeOffset> CurrentTimeObservable { get; }
public ReactiveCommand<object, Unit> StringValueCommand { get; } public MiniCommand StringValueCommand { get; }
public DataAnnotationsErrorViewModel DataAnnotationsValidation { get; } = new DataAnnotationsErrorViewModel(); public DataAnnotationsErrorViewModel DataAnnotationsValidation { get; } = new DataAnnotationsErrorViewModel();
public ExceptionErrorViewModel ExceptionDataValidation { get; } = new ExceptionErrorViewModel(); public ExceptionErrorViewModel ExceptionDataValidation { get; } = new ExceptionErrorViewModel();

8
samples/BindingDemo/ViewModels/NestedCommandViewModel.cs

@ -1,18 +1,18 @@
using ReactiveUI; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using MiniMvvm;
namespace BindingDemo.ViewModels namespace BindingDemo.ViewModels
{ {
public class NestedCommandViewModel : ReactiveObject public class NestedCommandViewModel : ViewModelBase
{ {
public NestedCommandViewModel() public NestedCommandViewModel()
{ {
Command = ReactiveCommand.Create(() => { }); Command = MiniCommand.Create(() => { });
} }
public ICommand Command { get; } public ICommand Command { get; }

4
samples/BindingDemo/ViewModels/TestItem.cs

@ -1,8 +1,8 @@
using ReactiveUI; using MiniMvvm;
namespace BindingDemo.ViewModels namespace BindingDemo.ViewModels
{ {
public class TestItem : ReactiveObject public class TestItem : ViewModelBase
{ {
private string _stringValue = "String Value"; private string _stringValue = "String Value";
private string _detail; private string _detail;

14
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@ -16,7 +16,7 @@
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidUseLatestPlatformSdk>False</AndroidUseLatestPlatformSdk> <AndroidUseLatestPlatformSdk>False</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion> <TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -71,21 +71,23 @@
<Compile Include="MainActivity.cs" /> <Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" /> <Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SplashActivity.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Resources\AboutResources.txt" /> <None Include="Resources\AboutResources.txt" />
<None Include="Assets\AboutAssets.txt" /> <None Include="Assets\AboutAssets.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="Resources\layout\Main.axml"> <AndroidResource Include="Resources\drawable\splash_screen.xml" />
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="Resources\values\Strings.xml" /> <AndroidResource Include="Resources\values\colors.xml" />
<AndroidResource Include="Resources\values\styles.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="Resources\drawable\Icon.png" /> <AndroidResource Include="..\..\build\Assets\Icon.png">
<Link>Resources\drawable\Icon.png</Link>
</AndroidResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Properties\AndroidManifest.xml" /> <None Include="Properties\AndroidManifest.xml" />

21
samples/ControlCatalog.Android/MainActivity.cs

@ -1,31 +1,18 @@
using System; using Android.App;
using Android.App;
using Android.OS; using Android.OS;
using Android.Content.PM; using Android.Content.PM;
using Avalonia.Android; using Avalonia.Android;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.Themes.Default;
using Avalonia;
namespace ControlCatalog.Android namespace ControlCatalog.Android
{ {
[Activity(Label = "ControlCatalog.Android", MainLauncher = true, Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)] [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)]
public class MainActivity : AvaloniaActivity public class MainActivity : AvaloniaActivity
{ {
protected override void OnCreate(Bundle savedInstanceState) protected override void OnCreate(Bundle savedInstanceState)
{ {
if (Avalonia.Application.Current == null)
{
AppBuilder.Configure<App>()
.UseAndroid()
.SetupWithoutStarting();
Content = new MainView();
}
base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState);
Content = new MainView();
} }
} }
} }

2
samples/ControlCatalog.Android/Properties/AndroidManifest.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ControlCatalog.Android" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ControlCatalog.Android" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk /> <uses-sdk android:targetSdkVersion="29" />
<application android:label="ControlCatalog.Android"></application> <application android:label="ControlCatalog.Android"></application>
</manifest> </manifest>

59
samples/ControlCatalog.Android/Resources/Resource.Designer.cs

@ -2,7 +2,6 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@ -15,7 +14,7 @@ namespace ControlCatalog.Android
{ {
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
public partial class Resource public partial class Resource
{ {
@ -26,8 +25,6 @@ namespace ControlCatalog.Android
public static void UpdateIdValues() public static void UpdateIdValues()
{ {
global::Avalonia.Android.Resource.String.ApplicationName = global::ControlCatalog.Android.Resource.String.ApplicationName;
global::Avalonia.Android.Resource.String.Hello = global::ControlCatalog.Android.Resource.String.Hello;
} }
public partial class Attribute public partial class Attribute
@ -43,69 +40,59 @@ namespace ControlCatalog.Android
} }
} }
public partial class Drawable public partial class Color
{ {
// aapt resource value: 0x7f020000 // aapt resource value: 0x7F010000
public const int Icon = 2130837504; public const int splash_background = 2130771968;
static Drawable() static Color()
{ {
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); global::Android.Runtime.ResourceIdManager.UpdateIdValues();
} }
private Drawable() private Color()
{ {
} }
} }
public partial class Id public partial class Drawable
{ {
// aapt resource value: 0x7f050000 // aapt resource value: 0x7F020000
public const int MyButton = 2131034112; public const int Icon = 2130837504;
static Id()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Id()
{
}
}
public partial class Layout
{
// aapt resource value: 0x7f030000 // aapt resource value: 0x7F020001
public const int Main = 2130903040; public const int splash_screen = 2130837505;
static Layout() static Drawable()
{ {
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); global::Android.Runtime.ResourceIdManager.UpdateIdValues();
} }
private Layout() private Drawable()
{ {
} }
} }
public partial class String public partial class Style
{ {
// aapt resource value: 0x7f040001 // aapt resource value: 0x7F030000
public const int ApplicationName = 2130968577; public const int MyTheme = 2130903040;
// aapt resource value: 0x7F030001
public const int MyTheme_NoActionBar = 2130903041;
// aapt resource value: 0x7f040000 // aapt resource value: 0x7F030002
public const int Hello = 2130968576; public const int MyTheme_Splash = 2130903042;
static String() static Style()
{ {
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); global::Android.Runtime.ResourceIdManager.UpdateIdValues();
} }
private String() private Style()
{ {
} }
} }

BIN
samples/ControlCatalog.Android/Resources/drawable/Icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

13
samples/ControlCatalog.Android/Resources/drawable/splash_screen.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="@color/splash_background"/>
</item>
<item android:drawable="@drawable/icon"
android:width="120dp"
android:height="120dp"
android:gravity="center" />
</layer-list>

13
samples/ControlCatalog.Android/Resources/layout/Main.axml

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/MyButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/Hello"
/>
</LinearLayout>

5
samples/ControlCatalog.Android/Resources/values/Strings.xml

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="Hello">Hello World, Click Me!</string>
<string name="ApplicationName">ControlCatalog.Android</string>
</resources>

4
samples/ControlCatalog.Android/Resources/values/colors.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splash_background">#FFFFFF</color>
</resources>

17
samples/ControlCatalog.Android/Resources/values/styles.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme">
</style>
<style name="MyTheme.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="MyTheme.Splash" parent ="MyTheme.NoActionBar">
<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowContentOverlay">@null</item>
</style>
</resources>

32
samples/ControlCatalog.Android/SplashActivity.cs

@ -0,0 +1,32 @@
using Android.App;
using Android.Content;
using Android.OS;
using Application = Android.App.Application;
using Avalonia;
namespace ControlCatalog.Android
{
[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
protected override void OnResume()
{
base.OnResume();
if (Avalonia.Application.Current == null)
{
AppBuilder.Configure<App>()
.UseAndroid()
.SetupWithoutStarting();
}
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
}
}
}

4
samples/ControlCatalog.Desktop/Program.cs

@ -3,7 +3,6 @@ using System.Linq;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.ReactiveUI;
namespace ControlCatalog namespace ControlCatalog
{ {
@ -19,8 +18,7 @@ namespace ControlCatalog
public static AppBuilder BuildAvaloniaApp() public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>() => AppBuilder.Configure<App>()
.LogToTrace() .LogToTrace()
.UsePlatformDetect() .UsePlatformDetect();
.UseReactiveUI();
private static void ConfigureAssetAssembly(AppBuilder builder) private static void ConfigureAssetAssembly(AppBuilder builder)
{ {

8
samples/ControlCatalog.NetCore/Program.cs

@ -10,7 +10,6 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Dialogs; using Avalonia.Dialogs;
using Avalonia.Headless; using Avalonia.Headless;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
namespace ControlCatalog.NetCore namespace ControlCatalog.NetCore
@ -110,15 +109,14 @@ namespace ControlCatalog.NetCore
.With(new X11PlatformOptions .With(new X11PlatformOptions
{ {
EnableMultiTouch = true, EnableMultiTouch = true,
UseDBusMenu = true UseDBusMenu = true,
EnableIme = true,
}) })
.With(new Win32PlatformOptions .With(new Win32PlatformOptions
{ {
EnableMultitouch = true, EnableMultitouch = true
AllowEglInitialization = true
}) })
.UseSkia() .UseSkia()
.UseReactiveUI()
.UseManagedSystemDialogs() .UseManagedSystemDialogs()
.LogToTrace(); .LogToTrace();

4
samples/ControlCatalog/App.xaml.cs

@ -23,7 +23,7 @@ namespace ControlCatalog
{ {
new StyleInclude(new Uri("avares://ControlCatalog/Styles")) new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
{ {
Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/FluentDark.xaml") Source = new Uri("avares://Avalonia.Themes.Fluent/FluentDark.xaml")
}, },
DataGridFluent DataGridFluent
}; };
@ -32,7 +32,7 @@ namespace ControlCatalog
{ {
new StyleInclude(new Uri("avares://ControlCatalog/Styles")) new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
{ {
Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/FluentLight.xaml") Source = new Uri("avares://Avalonia.Themes.Fluent/FluentLight.xaml")
}, },
DataGridFluent DataGridFluent
}; };

BIN
samples/ControlCatalog/Assets/Fonts/WenQuanYiMicroHei-01.ttf

Binary file not shown.

2
samples/ControlCatalog/ControlCatalog.csproj

@ -24,8 +24,8 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" /> <ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\BuildTargets.targets" /> <Import Project="..\..\build\BuildTargets.targets" />

30
samples/ControlCatalog/DecoratedWindow.xaml

@ -6,25 +6,21 @@
<NativeMenu.Menu> <NativeMenu.Menu>
<NativeMenu> <NativeMenu>
<NativeMenuItem Header="Decorated"> <NativeMenuItem Header="Decorated">
<NativeMenuItem.Menu> <NativeMenu>
<NativeMenu> <NativeMenuItem Header="Open"/>
<NativeMenuItem Header="Open"/> <NativeMenuItem Header="Recent">
<NativeMenuItem Header="Recent"> <NativeMenuItem.Menu>
<NativeMenuItem.Menu> <NativeMenu/>
<NativeMenu/> </NativeMenuItem.Menu>
</NativeMenuItem.Menu> </NativeMenuItem>
</NativeMenuItem> <NativeMenuItem Header="Quit Avalonia" Gesture="CMD+Q"/>
<NativeMenuItem Header="Quit Avalonia" Gesture="CMD+Q"/> </NativeMenu>
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem> </NativeMenuItem>
<NativeMenuItem Header="Edit"> <NativeMenuItem Header="Edit">
<NativeMenuItem.Menu> <NativeMenu>
<NativeMenu> <NativeMenuItem Header="Copy"/>
<NativeMenuItem Header="Copy"/> <NativeMenuItem Header="Paste"/>
<NativeMenuItem Header="Paste"/> </NativeMenu>
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem> </NativeMenuItem>
</NativeMenu> </NativeMenu>
</NativeMenu.Menu> </NativeMenu.Menu>

66
samples/ControlCatalog/MainWindow.xaml

@ -16,47 +16,39 @@
<NativeMenu.Menu> <NativeMenu.Menu>
<NativeMenu> <NativeMenu>
<NativeMenuItem Header="File"> <NativeMenuItem Header="File">
<NativeMenuItem.Menu> <NativeMenu>
<NativeMenu> <NativeMenuItem Icon="/Assets/test_icon.ico" Header="Open" Clicked="OnOpenClicked" Gesture="Ctrl+O"/>
<NativeMenuItem Icon="/Assets/test_icon.ico" Header="Open" Clicked="OnOpenClicked" Gesture="Ctrl+O"/> <NativeMenuItemSeperator/>
<NativeMenuItemSeperator/> <NativeMenuItem Icon="/Assets/github_icon.png" Header="Recent">
<NativeMenuItem Icon="/Assets/github_icon.png" Header="Recent"> <NativeMenu/>
<NativeMenuItem.Menu> </NativeMenuItem>
<NativeMenu/> <NativeMenuItemSeperator/>
</NativeMenuItem.Menu> <NativeMenuItem Header="{x:Static local:MainWindow.MenuQuitHeader}"
</NativeMenuItem> Gesture="{x:Static local:MainWindow.MenuQuitGesture}"
<NativeMenuItemSeperator/> Clicked="OnCloseClicked" />
<NativeMenuItem Header="{x:Static local:MainWindow.MenuQuitHeader}" </NativeMenu>
Gesture="{x:Static local:MainWindow.MenuQuitGesture}"
Clicked="OnCloseClicked" />
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem> </NativeMenuItem>
<NativeMenuItem Header="Edit"> <NativeMenuItem Header="Edit">
<NativeMenuItem.Menu> <NativeMenu>
<NativeMenu> <NativeMenuItem Header="Copy"/>
<NativeMenuItem Header="Copy"/> <NativeMenuItem Header="Paste"/>
<NativeMenuItem Header="Paste"/> </NativeMenu>
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem> </NativeMenuItem>
<NativeMenuItem Header="Options"> <NativeMenuItem Header="Options">
<NativeMenuItem.Menu> <NativeMenu>
<NativeMenu> <NativeMenuItem Header="Check Me (None)"
<NativeMenuItem Header="Check Me (None)" Command="{Binding ToggleMenuItemCheckedCommand}"
Command="{Binding ToggleMenuItemCheckedCommand}" ToggleType="None"
ToggleType="None" IsChecked="{Binding IsMenuItemChecked}" />
IsChecked="{Binding IsMenuItemChecked}" /> <NativeMenuItem Header="Check Me (CheckBox)"
<NativeMenuItem Header="Check Me (CheckBox)" Command="{Binding ToggleMenuItemCheckedCommand}"
Command="{Binding ToggleMenuItemCheckedCommand}" ToggleType="CheckBox"
ToggleType="CheckBox" IsChecked="{Binding IsMenuItemChecked}" />
IsChecked="{Binding IsMenuItemChecked}" /> <NativeMenuItem Header="Check Me (Radio)"
<NativeMenuItem Header="Check Me (Radio)" Command="{Binding ToggleMenuItemCheckedCommand}"
Command="{Binding ToggleMenuItemCheckedCommand}" ToggleType="Radio"
ToggleType="Radio" IsChecked="{Binding IsMenuItemChecked}" />
IsChecked="{Binding IsMenuItemChecked}" /> </NativeMenu>
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem> </NativeMenuItem>
</NativeMenu> </NativeMenu>
</NativeMenu.Menu> </NativeMenu.Menu>

2
samples/ControlCatalog/MainWindow.xaml.cs

@ -67,7 +67,7 @@ namespace ControlCatalog
if (Application.Current.Styles.Contains(App.FluentDark) if (Application.Current.Styles.Contains(App.FluentDark)
|| Application.Current.Styles.Contains(App.FluentLight)) || Application.Current.Styles.Contains(App.FluentLight))
{ {
var theme = new Avalonia.Themes.Fluent.FluentTheme(); var theme = new Avalonia.Themes.Fluent.Controls.FluentControls();
theme.TryGetResource("Button", out _); theme.TryGetResource("Button", out _);
} }
else else

11
samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="ControlCatalog.Pages.AutoCompleteBoxPage"> x:Class="ControlCatalog.Pages.AutoCompleteBoxPage">
<StackPanel Orientation="Vertical" Spacing="4"> <StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">AutoCompleteBox</TextBlock> <TextBlock Classes="h1">AutoCompleteBox</TextBlock>
@ -56,6 +57,16 @@
Width="200" Width="200"
Margin="0,0,0,8" Margin="0,0,0,8"
FilterMode="None"/> FilterMode="None"/>
<TextBlock Text="With Validation Errors"/>
<AutoCompleteBox Name="ValidationErrors"
Width="200"
Margin="0,0,0,8"
FilterMode="None">
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
</AutoCompleteBox>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>

11
samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml

@ -1,6 +1,7 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl 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="ControlCatalog.Pages.ButtonSpinnerPage"> x:Class="ControlCatalog.Pages.ButtonSpinnerPage"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<StackPanel Orientation="Vertical" Spacing="4"> <StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">ButtonSpinner</TextBlock> <TextBlock Classes="h1">ButtonSpinner</TextBlock>
@ -19,6 +20,14 @@
ShowButtonSpinner="{Binding #showSpinCheck.IsChecked}"> ShowButtonSpinner="{Binding #showSpinCheck.IsChecked}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Everest"/> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Everest"/>
</ButtonSpinner> </ButtonSpinner>
<ButtonSpinner MinHeight="30" Spin="OnSpin" ButtonSpinnerLocation="Left"
AllowSpin="{Binding #allowSpinCheck.IsChecked}"
ShowButtonSpinner="{Binding #showSpinCheck.IsChecked}">
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Everest"/>
</ButtonSpinner>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>

13
samples/ControlCatalog/Pages/ComboBoxPage.xaml

@ -1,6 +1,7 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl 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="ControlCatalog.Pages.ComboBoxPage"> x:Class="ControlCatalog.Pages.ComboBoxPage"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<StackPanel Orientation="Vertical" Spacing="4"> <StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">ComboBox</TextBlock> <TextBlock Classes="h1">ComboBox</TextBlock>
<TextBlock Classes="h2">A drop-down list.</TextBlock> <TextBlock Classes="h2">A drop-down list.</TextBlock>
@ -35,6 +36,16 @@
</DataTemplate> </DataTemplate>
</ComboBox.ItemTemplate> </ComboBox.ItemTemplate>
</ComboBox> </ComboBox>
<ComboBox PlaceholderText="Pick an Item">
<ComboBoxItem>Inline Items</ComboBoxItem>
<ComboBoxItem>Inline Item 2</ComboBoxItem>
<ComboBoxItem>Inline Item 3</ComboBoxItem>
<ComboBoxItem>Inline Item 4</ComboBoxItem>
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
</ComboBox>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>

4
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -38,8 +38,8 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" /> <DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" />
<DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" /> <DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" />
<DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" /> <DataGridTextColumn DisplayIndex="3" Header="Population" Binding="{Binding Population}" Width="3*" />
<DataGridTextColumn Header="Area" Binding="{Binding Area}" Width="3*" /> <DataGridTextColumn DisplayIndex="2" Header="Area" Binding="{Binding Area}" Width="3*" />
<DataGridTextColumn Header="GDP" Binding="{Binding GDP}" Width="3*" /> <DataGridTextColumn Header="GDP" Binding="{Binding GDP}" Width="3*" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

20
samples/ControlCatalog/Pages/DateTimePickerPage.xaml

@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=netstandard"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ControlCatalog.Pages.DateTimePickerPage"> x:Class="ControlCatalog.Pages.DateTimePickerPage">
<StackPanel Orientation="Vertical" Spacing="4" HorizontalAlignment="Stretch"> <StackPanel Orientation="Vertical" Spacing="4" HorizontalAlignment="Stretch">
@ -30,6 +31,16 @@
</Panel> </Panel>
</StackPanel> </StackPanel>
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}"
BorderThickness="1" Padding="15">
<DatePicker Header="Pick a date">
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
</DatePicker>
</Border>
<TextBlock FontSize="18">A DatePicker with day formatted and year hidden.</TextBlock> <TextBlock FontSize="18">A DatePicker with day formatted and year hidden.</TextBlock>
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}" <Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}"
@ -66,6 +77,15 @@
</TextBlock> </TextBlock>
</Panel> </Panel>
</StackPanel> </StackPanel>
<Border BorderBrush="{DynamicResource SystemControlHighlightBaseLowBrush}"
BorderThickness="1" Padding="15">
<TimePicker Header="Pick a time">
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
</TimePicker>
</Border>
<TextBlock FontSize="18">A TimePicker with a header and minute increments specified.</TextBlock> <TextBlock FontSize="18">A TimePicker with a header and minute increments specified.</TextBlock>
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">

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

@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Dialogs; using Avalonia.Dialogs;
using Avalonia.Layout;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
#pragma warning disable 4014 #pragma warning disable 4014
@ -112,11 +113,29 @@ namespace ControlCatalog.Pages
private Window CreateSampleWindow() private Window CreateSampleWindow()
{ {
var window = new Window(); Button button;
window.Height = 200;
window.Width = 200; var window = new Window
window.Content = new TextBlock { Text = "Hello world!" }; {
window.WindowStartupLocation = WindowStartupLocation.CenterOwner; Height = 200,
Width = 200,
Content = new StackPanel
{
Spacing = 4,
Children =
{
new TextBlock { Text = "Hello world!" },
(button = new Button
{
HorizontalAlignment = HorizontalAlignment.Center,
Content = "Click to close"
})
}
},
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
button.Click += (_, __) => window.Close();
return window; return window;
} }

1
samples/ControlCatalog/Pages/LabelsPage.axaml.cs

@ -2,7 +2,6 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using ControlCatalog.Models; using ControlCatalog.Models;
using ReactiveUI;
namespace ControlCatalog.Pages namespace ControlCatalog.Pages
{ {

2
samples/ControlCatalog/Pages/ListBoxPage.xaml

@ -20,6 +20,6 @@
<ListBox Items="{Binding Items}" <ListBox Items="{Binding Items}"
Selection="{Binding Selection}" Selection="{Binding Selection}"
AutoScrollToSelectedItem="{Binding AutoScrollToSelectedItem}" AutoScrollToSelectedItem="{Binding AutoScrollToSelectedItem}"
SelectionMode="{Binding SelectionMode}"/> SelectionMode="{Binding SelectionMode^}"/>
</DockPanel> </DockPanel>
</UserControl> </UserControl>

1
samples/ControlCatalog/Pages/MenuPage.xaml.cs

@ -6,7 +6,6 @@ using System.Windows.Input;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using ControlCatalog.ViewModels; using ControlCatalog.ViewModels;
using ReactiveUI;
namespace ControlCatalog.Pages namespace ControlCatalog.Pages
{ {

10
samples/ControlCatalog/Pages/NumericUpDownPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="ControlCatalog.Pages.NumericUpDownPage"> x:Class="ControlCatalog.Pages.NumericUpDownPage">
<StackPanel Orientation="Vertical" Spacing="4"> <StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Margin="2" Classes="h1">Numeric up-down control</TextBlock> <TextBlock Margin="2" Classes="h1">Numeric up-down control</TextBlock>
@ -75,6 +76,15 @@
<NumericUpDown Name="upDown" Minimum="0" Maximum="10" Increment="0.5" <NumericUpDown Name="upDown" Minimum="0" Maximum="10" Increment="0.5"
CultureInfo="en-US" VerticalAlignment="Center" CultureInfo="en-US" VerticalAlignment="Center"
Watermark="Enter text" FormatString="{Binding SelectedFormat.Value}"/> Watermark="Enter text" FormatString="{Binding SelectedFormat.Value}"/>
<TextBlock FontSize="14" FontWeight="Bold" VerticalAlignment="Center">NumericUpDown with Validation Errors:</TextBlock>
<NumericUpDown Minimum="0" Maximum="10" Increment="0.5"
CultureInfo="en-US" VerticalAlignment="Center"
Watermark="Enter text" FormatString="{Binding SelectedFormat.Value}">
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
</NumericUpDown>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>

4
samples/ControlCatalog/Pages/NumericUpDownPage.xaml.cs

@ -6,7 +6,7 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.Pages namespace ControlCatalog.Pages
{ {
@ -26,7 +26,7 @@ namespace ControlCatalog.Pages
} }
public class NumbersPageViewModel : ReactiveObject public class NumbersPageViewModel : ViewModelBase
{ {
private IList<FormatObject> _formats; private IList<FormatObject> _formats;
private FormatObject _selectedFormat; private FormatObject _selectedFormat;

4
samples/ControlCatalog/Pages/ScrollViewerPage.xaml.cs

@ -2,11 +2,11 @@ using System.Collections.Generic;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.Pages namespace ControlCatalog.Pages
{ {
public class ScrollViewerPageViewModel : ReactiveObject public class ScrollViewerPageViewModel : ViewModelBase
{ {
private bool _allowAutoHide; private bool _allowAutoHide;
private ScrollBarVisibility _horizontalScrollVisibility; private ScrollBarVisibility _horizontalScrollVisibility;

24
samples/ControlCatalog/Pages/SliderPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="ControlCatalog.Pages.SliderPage"> x:Class="ControlCatalog.Pages.SliderPage">
<StackPanel Orientation="Vertical" Spacing="4"> <StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Slider</TextBlock> <TextBlock Classes="h1">Slider</TextBlock>
@ -21,6 +22,29 @@
IsSnapToTickEnabled="True" IsSnapToTickEnabled="True"
Ticks="0,20,25,40,75,100" Ticks="0,20,25,40,75,100"
Width="300" /> Width="300" />
<Slider Name="SliderWithTooltip"
Value="0"
Minimum="0"
Maximum="100"
Width="300">
<Slider.Styles>
<Style Selector="Slider /template/ Thumb">
<Setter Property="ToolTip.Tip" Value="{Binding $parent[Slider].Value, Mode=OneWay, StringFormat='Value \{0:f\}'}" />
<Setter Property="ToolTip.Placement" Value="Top" />
<Setter Property="ToolTip.VerticalOffset" Value="-10" />
<Setter Property="ToolTip.HorizontalOffset" Value="-30" />
</Style>
</Slider.Styles>
</Slider>
<Slider Value="0"
Minimum="0"
Maximum="100"
TickFrequency="10"
Width="300">
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
</Slider>
</StackPanel> </StackPanel>
<Slider Value="0" <Slider Value="0"
Minimum="0" Minimum="0"

4
samples/ControlCatalog/Pages/TabControlPage.xaml.cs

@ -6,7 +6,7 @@ using Avalonia.Markup.Xaml;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.Pages namespace ControlCatalog.Pages
{ {
@ -56,7 +56,7 @@ namespace ControlCatalog.Pages
return new Bitmap(assets.Open(new Uri(uri))); return new Bitmap(assets.Open(new Uri(uri)));
} }
private class PageViewModel : ReactiveObject private class PageViewModel : ViewModelBase
{ {
private Dock _tabPlacement; private Dock _tabPlacement;

14
samples/ControlCatalog/Pages/TextBoxPage.xaml

@ -1,6 +1,7 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl 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="ControlCatalog.Pages.TextBoxPage"> x:Class="ControlCatalog.Pages.TextBoxPage"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<StackPanel Orientation="Vertical" Spacing="4"> <StackPanel Orientation="Vertical" Spacing="4">
<Label Classes="h1">TextBox</Label> <Label Classes="h1">TextBox</Label>
<Label Classes="h2">A control into which the user can input text</Label> <Label Classes="h2">A control into which the user can input text</Label>
@ -11,12 +12,18 @@
Spacing="16"> Spacing="16">
<StackPanel Orientation="Vertical" Spacing="8"> <StackPanel Orientation="Vertical" Spacing="8">
<TextBox Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit." Width="200" /> <TextBox Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit." Width="200" />
<TextBox Watermark="ReadOnly" IsReadOnly="True" Text="This is read only"/> <TextBox Width="200" Watermark="ReadOnly" IsReadOnly="True" Text="This is read only"/>
<TextBox Width="200" Watermark="Watermark" /> <TextBox Width="200" Watermark="Watermark" />
<TextBox Width="200" <TextBox Width="200"
Watermark="Floating Watermark" Watermark="Floating Watermark"
UseFloatingWatermark="True" UseFloatingWatermark="True"
Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit."/> Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit."/>
<TextBox Width="200" Text="Validation Error">
<DataValidationErrors.Error>
<sys:Exception />
</DataValidationErrors.Error>
</TextBox>
<TextBox Width="200" <TextBox Width="200"
Watermark="Password Box" Watermark="Password Box"
@ -57,5 +64,8 @@
<TextBox Width="200" Text="Custom font italic bold" FontWeight="Bold" FontStyle="Italic" FontFamily="/Assets/Fonts/SourceSansPro-*.ttf#Source Sans Pro"/> <TextBox Width="200" Text="Custom font italic bold" FontWeight="Bold" FontStyle="Italic" FontFamily="/Assets/Fonts/SourceSansPro-*.ttf#Source Sans Pro"/>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
<TextBox AcceptsReturn="True" TextWrapping="Wrap" Height="200" MaxWidth="400"
FontFamily="avares://ControlCatalog/Assets/Fonts#WenQuanYi Micro Hei"
Text="计算机科学(是系统性研究信息与计算的理论基础以及它们在计算机系统中如何实现与应用的实用技术的学科。它通常被形容为对那些创造、描述以及转换信息的算法处理的系统研究。计算机科学包含很多分支领域;有些强调特定结果的计算,比如计算机图形学;而有些是探討计算问题的性质,比如计算复杂性理论;还有一些领域專注于怎样实现计算,比如程式語言理論是研究描述计算的方法,而程式设计是应用特定的程式語言解决特定的计算问题,人机交互则是專注于怎样使计算机和计算变得有用、好用,以及随时随地为人所用。&#xD;&#xD;有时公众会误以为计算机科学就是解决计算机问题的事业(比如信息技术),或者只是与使用计算机的经验有关,如玩游戏、上网或者文字处理。其实计算机科学所关注的,不仅仅是去理解实现类似游戏、浏览器这些软件的程序的性质,更要通过现有的知识创造新的程序或者改进已有的程序。" />
</StackPanel> </StackPanel>
</UserControl> </UserControl>

27
samples/ControlCatalog/Pages/ToolTipPage.xaml

@ -6,7 +6,7 @@
<TextBlock Classes="h1">ToolTip</TextBlock> <TextBlock Classes="h1">ToolTip</TextBlock>
<TextBlock Classes="h2">A control which pops up a hint when a control is hovered</TextBlock> <TextBlock Classes="h2">A control which pops up a hint when a control is hovered</TextBlock>
<Grid RowDefinitions="Auto,Auto" <Grid RowDefinitions="Auto,Auto,Auto"
ColumnDefinitions="Auto,Auto" ColumnDefinitions="Auto,Auto"
Margin="0,16,0,0" Margin="0,16,0,0"
HorizontalAlignment="Center"> HorizontalAlignment="Center">
@ -38,6 +38,31 @@
</ToolTip.Tip> </ToolTip.Tip>
<TextBlock>ToolTip bottom placement</TextBlock> <TextBlock>ToolTip bottom placement</TextBlock>
</Border> </Border>
<Border Grid.Row="2"
Grid.ColumnSpan="2"
Background="{DynamicResource SystemAccentColor}"
Margin="5"
Padding="50"
ToolTip.Tip="Hello"
ToolTip.Placement="Top">
<Border.Styles>
<Style Selector="Border">
<Style.Animations>
<Animation Duration="0:0:2" IterationCount="Infinite">
<KeyFrame KeyTime="0:0:0">
<Setter Property="ToolTip.HorizontalOffset" Value="0" />
<Setter Property="ToolTip.VerticalOffset" Value="-50" />
</KeyFrame>
<KeyFrame KeyTime="0:0:2" >
<Setter Property="ToolTip.HorizontalOffset" Value="100" />
<Setter Property="ToolTip.VerticalOffset" Value="50" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Border.Styles>
<TextBlock>Moving offset</TextBlock>
</Border>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

14
samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs

@ -3,7 +3,7 @@ using System.Reactive;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
@ -12,9 +12,9 @@ namespace ControlCatalog.ViewModels
public Control View { get; set; } public Control View { get; set; }
public ContextMenuPageViewModel() public ContextMenuPageViewModel()
{ {
OpenCommand = ReactiveCommand.CreateFromTask(Open); OpenCommand = MiniCommand.CreateFromTask(Open);
SaveCommand = ReactiveCommand.Create(Save); SaveCommand = MiniCommand.Create(Save);
OpenRecentCommand = ReactiveCommand.Create<string>(OpenRecent); OpenRecentCommand = MiniCommand.Create<string>(OpenRecent);
MenuItems = new[] MenuItems = new[]
{ {
@ -44,9 +44,9 @@ namespace ControlCatalog.ViewModels
} }
public IReadOnlyList<MenuItemViewModel> MenuItems { get; set; } public IReadOnlyList<MenuItemViewModel> MenuItems { get; set; }
public ReactiveCommand<Unit, Unit> OpenCommand { get; } public MiniCommand OpenCommand { get; }
public ReactiveCommand<Unit, Unit> SaveCommand { get; } public MiniCommand SaveCommand { get; }
public ReactiveCommand<string, Unit> OpenRecentCommand { get; } public MiniCommand OpenRecentCommand { get; }
public async Task Open() public async Task Open()
{ {

6
samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs

@ -2,11 +2,11 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Avalonia.Media; using Avalonia.Media;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
public class ItemsRepeaterPageViewModel : ReactiveObject public class ItemsRepeaterPageViewModel : ViewModelBase
{ {
private int _newItemIndex = 1; private int _newItemIndex = 1;
private int _newGenerationIndex = 0; private int _newGenerationIndex = 0;
@ -59,7 +59,7 @@ namespace ControlCatalog.ViewModels
})); }));
} }
public class Item : ReactiveObject public class Item : ViewModelBase
{ {
private double _height = double.NaN; private double _height = double.NaN;

27
samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs

@ -4,18 +4,18 @@ using System.Linq;
using System.Reactive; using System.Reactive;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Selection; using Avalonia.Controls.Selection;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
public class ListBoxPageViewModel : ReactiveObject public class ListBoxPageViewModel : ViewModelBase
{ {
private bool _multiple; private bool _multiple;
private bool _toggle; private bool _toggle;
private bool _alwaysSelected; private bool _alwaysSelected;
private bool _autoScrollToSelectedItem = true; private bool _autoScrollToSelectedItem = true;
private int _counter; private int _counter;
private ObservableAsPropertyHelper<SelectionMode> _selectionMode; private IObservable<SelectionMode> _selectionMode;
public ListBoxPageViewModel() public ListBoxPageViewModel()
{ {
@ -29,14 +29,13 @@ namespace ControlCatalog.ViewModels
x => x.Toggle, x => x.Toggle,
x => x.AlwaysSelected, x => x.AlwaysSelected,
(m, t, a) => (m, t, a) =>
(m ? SelectionMode.Multiple : 0) | (m ? Avalonia.Controls.SelectionMode.Multiple : 0) |
(t ? SelectionMode.Toggle : 0) | (t ? Avalonia.Controls.SelectionMode.Toggle : 0) |
(a ? SelectionMode.AlwaysSelected : 0)) (a ? Avalonia.Controls.SelectionMode.AlwaysSelected : 0));
.ToProperty(this, x => x.SelectionMode);
AddItemCommand = ReactiveCommand.Create(() => Items.Add(GenerateItem())); AddItemCommand = MiniCommand.Create(() => Items.Add(GenerateItem()));
RemoveItemCommand = ReactiveCommand.Create(() => RemoveItemCommand = MiniCommand.Create(() =>
{ {
var items = Selection.SelectedItems.ToList(); var items = Selection.SelectedItems.ToList();
@ -46,7 +45,7 @@ namespace ControlCatalog.ViewModels
} }
}); });
SelectRandomItemCommand = ReactiveCommand.Create(() => SelectRandomItemCommand = MiniCommand.Create(() =>
{ {
var random = new Random(); var random = new Random();
@ -60,7 +59,7 @@ namespace ControlCatalog.ViewModels
public ObservableCollection<string> Items { get; } public ObservableCollection<string> Items { get; }
public SelectionModel<string> Selection { get; } public SelectionModel<string> Selection { get; }
public SelectionMode SelectionMode => _selectionMode.Value; public IObservable<SelectionMode> SelectionMode => _selectionMode;
public bool Multiple public bool Multiple
{ {
@ -86,9 +85,9 @@ namespace ControlCatalog.ViewModels
set => this.RaiseAndSetIfChanged(ref _autoScrollToSelectedItem, value); set => this.RaiseAndSetIfChanged(ref _autoScrollToSelectedItem, value);
} }
public ReactiveCommand<Unit, Unit> AddItemCommand { get; } public MiniCommand AddItemCommand { get; }
public ReactiveCommand<Unit, Unit> RemoveItemCommand { get; } public MiniCommand RemoveItemCommand { get; }
public ReactiveCommand<Unit, Unit> SelectRandomItemCommand { get; } public MiniCommand SelectRandomItemCommand { get; }
private string GenerateItem() => $"Item {_counter++.ToString()}"; private string GenerateItem() => $"Item {_counter++.ToString()}";
} }

28
samples/ControlCatalog/ViewModels/MainWindowViewModel.cs

@ -5,11 +5,11 @@ using Avalonia.Controls.Notifications;
using Avalonia.Dialogs; using Avalonia.Dialogs;
using Avalonia.Platform; using Avalonia.Platform;
using System; using System;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
class MainWindowViewModel : ReactiveObject class MainWindowViewModel : ViewModelBase
{ {
private IManagedNotificationManager _notificationManager; private IManagedNotificationManager _notificationManager;
@ -27,22 +27,22 @@ namespace ControlCatalog.ViewModels
{ {
_notificationManager = notificationManager; _notificationManager = notificationManager;
ShowCustomManagedNotificationCommand = ReactiveCommand.Create(() => ShowCustomManagedNotificationCommand = MiniCommand.Create(() =>
{ {
NotificationManager.Show(new NotificationViewModel(NotificationManager) { Title = "Hey There!", Message = "Did you know that Avalonia now supports Custom In-Window Notifications?" }); NotificationManager.Show(new NotificationViewModel(NotificationManager) { Title = "Hey There!", Message = "Did you know that Avalonia now supports Custom In-Window Notifications?" });
}); });
ShowManagedNotificationCommand = ReactiveCommand.Create(() => ShowManagedNotificationCommand = MiniCommand.Create(() =>
{ {
NotificationManager.Show(new Avalonia.Controls.Notifications.Notification("Welcome", "Avalonia now supports Notifications.", NotificationType.Information)); NotificationManager.Show(new Avalonia.Controls.Notifications.Notification("Welcome", "Avalonia now supports Notifications.", NotificationType.Information));
}); });
ShowNativeNotificationCommand = ReactiveCommand.Create(() => ShowNativeNotificationCommand = MiniCommand.Create(() =>
{ {
NotificationManager.Show(new Avalonia.Controls.Notifications.Notification("Error", "Native Notifications are not quite ready. Coming soon.", NotificationType.Error)); NotificationManager.Show(new Avalonia.Controls.Notifications.Notification("Error", "Native Notifications are not quite ready. Coming soon.", NotificationType.Error));
}); });
AboutCommand = ReactiveCommand.CreateFromTask(async () => AboutCommand = MiniCommand.CreateFromTask(async () =>
{ {
var dialog = new AboutAvaloniaDialog(); var dialog = new AboutAvaloniaDialog();
@ -51,12 +51,12 @@ namespace ControlCatalog.ViewModels
await dialog.ShowDialog(mainWindow); await dialog.ShowDialog(mainWindow);
}); });
ExitCommand = ReactiveCommand.Create(() => ExitCommand = MiniCommand.Create(() =>
{ {
(App.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime).Shutdown(); (App.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime).Shutdown();
}); });
ToggleMenuItemCheckedCommand = ReactiveCommand.Create(() => ToggleMenuItemCheckedCommand = MiniCommand.Create(() =>
{ {
IsMenuItemChecked = !IsMenuItemChecked; IsMenuItemChecked = !IsMenuItemChecked;
}); });
@ -153,16 +153,16 @@ namespace ControlCatalog.ViewModels
set { this.RaiseAndSetIfChanged(ref _isMenuItemChecked, value); } set { this.RaiseAndSetIfChanged(ref _isMenuItemChecked, value); }
} }
public ReactiveCommand<Unit, Unit> ShowCustomManagedNotificationCommand { get; } public MiniCommand ShowCustomManagedNotificationCommand { get; }
public ReactiveCommand<Unit, Unit> ShowManagedNotificationCommand { get; } public MiniCommand ShowManagedNotificationCommand { get; }
public ReactiveCommand<Unit, Unit> ShowNativeNotificationCommand { get; } public MiniCommand ShowNativeNotificationCommand { get; }
public ReactiveCommand<Unit, Unit> AboutCommand { get; } public MiniCommand AboutCommand { get; }
public ReactiveCommand<Unit, Unit> ExitCommand { get; } public MiniCommand ExitCommand { get; }
public ReactiveCommand<Unit, Unit> ToggleMenuItemCheckedCommand { get; } public MiniCommand ToggleMenuItemCheckedCommand { get; }
} }
} }

14
samples/ControlCatalog/ViewModels/MenuPageViewModel.cs

@ -4,7 +4,7 @@ using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
@ -13,9 +13,9 @@ namespace ControlCatalog.ViewModels
public Control View { get; set; } public Control View { get; set; }
public MenuPageViewModel() public MenuPageViewModel()
{ {
OpenCommand = ReactiveCommand.CreateFromTask(Open); OpenCommand = MiniCommand.CreateFromTask(Open);
SaveCommand = ReactiveCommand.Create(Save, Observable.Return(false)); SaveCommand = MiniCommand.Create(Save);
OpenRecentCommand = ReactiveCommand.Create<string>(OpenRecent); OpenRecentCommand = MiniCommand.Create<string>(OpenRecent);
var recentItems = new[] var recentItems = new[]
{ {
@ -65,9 +65,9 @@ namespace ControlCatalog.ViewModels
public IReadOnlyList<MenuItemViewModel> MenuItems { get; set; } public IReadOnlyList<MenuItemViewModel> MenuItems { get; set; }
public IReadOnlyList<MenuItemViewModel> RecentItems { get; set; } public IReadOnlyList<MenuItemViewModel> RecentItems { get; set; }
public ReactiveCommand<Unit, Unit> OpenCommand { get; } public MiniCommand OpenCommand { get; }
public ReactiveCommand<Unit, Unit> SaveCommand { get; } public MiniCommand SaveCommand { get; }
public ReactiveCommand<string, Unit> OpenRecentCommand { get; } public MiniCommand OpenRecentCommand { get; }
public async Task Open() public async Task Open()
{ {

10
samples/ControlCatalog/ViewModels/NotificationViewModel.cs

@ -1,6 +1,6 @@
using System.Reactive; using System.Reactive;
using Avalonia.Controls.Notifications; using Avalonia.Controls.Notifications;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
@ -8,12 +8,12 @@ namespace ControlCatalog.ViewModels
{ {
public NotificationViewModel(INotificationManager manager) public NotificationViewModel(INotificationManager manager)
{ {
YesCommand = ReactiveCommand.Create(() => YesCommand = MiniCommand.Create(() =>
{ {
manager.Show(new Avalonia.Controls.Notifications.Notification("Avalonia Notifications", "Start adding notifications to your app today.")); manager.Show(new Avalonia.Controls.Notifications.Notification("Avalonia Notifications", "Start adding notifications to your app today."));
}); });
NoCommand = ReactiveCommand.Create(() => NoCommand = MiniCommand.Create(() =>
{ {
manager.Show(new Avalonia.Controls.Notifications.Notification("Avalonia Notifications", "Start adding notifications to your app today. To find out more visit...")); manager.Show(new Avalonia.Controls.Notifications.Notification("Avalonia Notifications", "Start adding notifications to your app today. To find out more visit..."));
}); });
@ -22,9 +22,9 @@ namespace ControlCatalog.ViewModels
public string Title { get; set; } public string Title { get; set; }
public string Message { get; set; } public string Message { get; set; }
public ReactiveCommand<Unit, Unit> YesCommand { get; } public MiniCommand YesCommand { get; }
public ReactiveCommand<Unit, Unit> NoCommand { get; } public MiniCommand NoCommand { get; }
} }
} }

4
samples/ControlCatalog/ViewModels/SplitViewPageViewModel.cs

@ -1,10 +1,10 @@
using System; using System;
using Avalonia.Controls; using Avalonia.Controls;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
public class SplitViewPageViewModel : ReactiveObject public class SplitViewPageViewModel : ViewModelBase
{ {
private bool _isLeft = true; private bool _isLeft = true;
private int _displayMode = 3; //CompactOverlay private int _displayMode = 3; //CompactOverlay

16
samples/ControlCatalog/ViewModels/TreeViewPageViewModel.cs

@ -3,11 +3,11 @@ using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reactive; using System.Reactive;
using Avalonia.Controls; using Avalonia.Controls;
using ReactiveUI; using MiniMvvm;
namespace ControlCatalog.ViewModels namespace ControlCatalog.ViewModels
{ {
public class TreeViewPageViewModel : ReactiveObject public class TreeViewPageViewModel : ViewModelBase
{ {
private readonly Node _root; private readonly Node _root;
private SelectionMode _selectionMode; private SelectionMode _selectionMode;
@ -19,16 +19,16 @@ namespace ControlCatalog.ViewModels
Items = _root.Children; Items = _root.Children;
SelectedItems = new ObservableCollection<Node>(); SelectedItems = new ObservableCollection<Node>();
AddItemCommand = ReactiveCommand.Create(AddItem); AddItemCommand = MiniCommand.Create(AddItem);
RemoveItemCommand = ReactiveCommand.Create(RemoveItem); RemoveItemCommand = MiniCommand.Create(RemoveItem);
SelectRandomItemCommand = ReactiveCommand.Create(SelectRandomItem); SelectRandomItemCommand = MiniCommand.Create(SelectRandomItem);
} }
public ObservableCollection<Node> Items { get; } public ObservableCollection<Node> Items { get; }
public ObservableCollection<Node> SelectedItems { get; } public ObservableCollection<Node> SelectedItems { get; }
public ReactiveCommand<Unit, Unit> AddItemCommand { get; } public MiniCommand AddItemCommand { get; }
public ReactiveCommand<Unit, Unit> RemoveItemCommand { get; } public MiniCommand RemoveItemCommand { get; }
public ReactiveCommand<Unit, Unit> SelectRandomItemCommand { get; } public MiniCommand SelectRandomItemCommand { get; }
public SelectionMode SelectionMode public SelectionMode SelectionMode
{ {

66
samples/MiniMvvm/MiniCommand.cs

@ -0,0 +1,66 @@
using System;
using System.Threading.Tasks;
using System.Windows.Input;
namespace MiniMvvm
{
public sealed class MiniCommand<T> : MiniCommand, ICommand
{
private readonly Action<T> _cb;
private bool _busy;
private Func<T, Task> _acb;
public MiniCommand(Action<T> cb)
{
_cb = cb;
}
public MiniCommand(Func<T, Task> cb)
{
_acb = cb;
}
private bool Busy
{
get => _busy;
set
{
_busy = value;
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
public override event EventHandler CanExecuteChanged;
public override bool CanExecute(object parameter) => !_busy;
public override async void Execute(object parameter)
{
if(Busy)
return;
try
{
Busy = true;
if (_cb != null)
_cb((T)parameter);
else
await _acb((T)parameter);
}
finally
{
Busy = false;
}
}
}
public abstract class MiniCommand : ICommand
{
public static MiniCommand Create(Action cb) => new MiniCommand<object>(_ => cb());
public static MiniCommand Create<TArg>(Action<TArg> cb) => new MiniCommand<TArg>(cb);
public static MiniCommand CreateFromTask(Func<Task> cb) => new MiniCommand<object>(_ => cb());
public abstract bool CanExecute(object parameter);
public abstract void Execute(object parameter);
public abstract event EventHandler CanExecuteChanged;
}
}

6
samples/MiniMvvm/MiniMvvm.csproj

@ -0,0 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<Import Project="..\..\build\Rx.props" />
</Project>

108
samples/MiniMvvm/PropertyChangedExtensions.cs

@ -0,0 +1,108 @@
using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Reflection;
namespace MiniMvvm
{
public static class PropertyChangedExtensions
{
class PropertyObservable<T> : IObservable<T>
{
private readonly INotifyPropertyChanged _target;
private readonly PropertyInfo _info;
public PropertyObservable(INotifyPropertyChanged target, PropertyInfo info)
{
_target = target;
_info = info;
}
class Subscription : IDisposable
{
private readonly INotifyPropertyChanged _target;
private readonly PropertyInfo _info;
private readonly IObserver<T> _observer;
public Subscription(INotifyPropertyChanged target, PropertyInfo info, IObserver<T> observer)
{
_target = target;
_info = info;
_observer = observer;
_target.PropertyChanged += OnPropertyChanged;
_observer.OnNext((T)_info.GetValue(_target));
}
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == _info.Name)
_observer.OnNext((T)_info.GetValue(_target));
}
public void Dispose()
{
_target.PropertyChanged -= OnPropertyChanged;
_observer.OnCompleted();
}
}
public IDisposable Subscribe(IObserver<T> observer)
{
return new Subscription(_target, _info, observer);
}
}
public static IObservable<TRes> WhenAnyValue<TModel, TRes>(this TModel model,
Expression<Func<TModel, TRes>> expr) where TModel : INotifyPropertyChanged
{
var l = (LambdaExpression)expr;
var ma = (MemberExpression)l.Body;
var prop = (PropertyInfo)ma.Member;
return new PropertyObservable<TRes>(model, prop);
}
public static IObservable<TRes> WhenAnyValue<TModel, T1, TRes>(this TModel model,
Expression<Func<TModel, T1>> v1,
Func<T1, TRes> cb
) where TModel : INotifyPropertyChanged
{
return model.WhenAnyValue(v1).Select(cb);
}
public static IObservable<TRes> WhenAnyValue<TModel, T1, T2, TRes>(this TModel model,
Expression<Func<TModel, T1>> v1,
Expression<Func<TModel, T2>> v2,
Func<T1, T2, TRes> cb
) where TModel : INotifyPropertyChanged =>
Observable.CombineLatest(
model.WhenAnyValue(v1),
model.WhenAnyValue(v2),
cb);
public static IObservable<ValueTuple<T1, T2>> WhenAnyValue<TModel, T1, T2>(this TModel model,
Expression<Func<TModel, T1>> v1,
Expression<Func<TModel, T2>> v2
) where TModel : INotifyPropertyChanged =>
model.WhenAnyValue(v1, v2, (a1, a2) => (a1, a2));
public static IObservable<TRes> WhenAnyValue<TModel, T1, T2, T3, TRes>(this TModel model,
Expression<Func<TModel, T1>> v1,
Expression<Func<TModel, T2>> v2,
Expression<Func<TModel, T3>> v3,
Func<T1, T2, T3, TRes> cb
) where TModel : INotifyPropertyChanged =>
Observable.CombineLatest(
model.WhenAnyValue(v1),
model.WhenAnyValue(v2),
model.WhenAnyValue(v3),
cb);
public static IObservable<ValueTuple<T1, T2, T3>> WhenAnyValue<TModel, T1, T2, T3>(this TModel model,
Expression<Func<TModel, T1>> v1,
Expression<Func<TModel, T2>> v2,
Expression<Func<TModel, T3>> v3
) where TModel : INotifyPropertyChanged =>
model.WhenAnyValue(v1, v2, v3, (a1, a2, a3) => (a1, a2, a3));
}
}

26
samples/MiniMvvm/ViewModelBase.cs

@ -0,0 +1,26 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Reactive.Joins;
using System.Runtime.CompilerServices;
namespace MiniMvvm
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool RaiseAndSetIfChanged<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
RaisePropertyChanged(propertyName);
return true;
}
return false;
}
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

1
samples/Previewer/Previewer.csproj

@ -8,7 +8,6 @@
<DependentUpon>%(Filename)</DependentUpon> <DependentUpon>%(Filename)</DependentUpon>
</Compile> </Compile>
<EmbeddedResource Include="**\*.xaml" /> <EmbeddedResource Include="**\*.xaml" />
<ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\SampleApp.props" /> <Import Project="..\..\build\SampleApp.props" />

2
samples/RenderDemo/App.xaml

@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RenderDemo.App"> x:Class="RenderDemo.App">
<Application.Styles> <Application.Styles>
<StyleInclude Source="avares://Avalonia.Themes.Fluent/Accents/FluentLight.xaml"/> <FluentTheme/>
<StyleInclude Source="avares://RenderDemo/SideBar.xaml"/> <StyleInclude Source="avares://RenderDemo/SideBar.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

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

Loading…
Cancel
Save