diff --git a/.gitignore b/.gitignore
index 61a3b53de1..bbf358b8f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -210,9 +210,9 @@ coc-settings.json
.ccls-cache
.ccls
*.map
-src/Web/Avalonia.Web.Blazor/wwwroot/*.js
-src/Web/Avalonia.Web.Blazor/Interop/Typescript/*.js
+src/Browser/Avalonia.Browser.Blazor/wwwroot/*.js
+src/Browser/Avalonia.Browser.Blazor/Interop/Typescript/*.js
node_modules
-src/Web/Avalonia.Web.Blazor/webapp/package-lock.json
-src/Web/Avalonia.Web.Blazor/wwwroot
-src/Web/Avalonia.Web/wwwroot
+src/Browser/Avalonia.Browser.Blazor/webapp/package-lock.json
+src/Browser/Avalonia.Browser.Blazor/wwwroot
+src/Browser/Avalonia.Browser/wwwroot
diff --git a/.ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject b/.ncrunch/Avalonia.Benchmarks.v3.ncrunchproject
similarity index 100%
rename from .ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject
rename to .ncrunch/Avalonia.Benchmarks.v3.ncrunchproject
diff --git a/.ncrunch/Avalonia.Web.v3.ncrunchproject b/.ncrunch/Avalonia.Browser.Blazor.v3.ncrunchproject
similarity index 100%
rename from .ncrunch/Avalonia.Web.v3.ncrunchproject
rename to .ncrunch/Avalonia.Browser.Blazor.v3.ncrunchproject
diff --git a/.ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject b/.ncrunch/Avalonia.Browser.v3.ncrunchproject
similarity index 100%
rename from .ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject
rename to .ncrunch/Avalonia.Browser.v3.ncrunchproject
diff --git a/.ncrunch/ControlCatalog.Web.v3.ncrunchproject b/.ncrunch/Avalonia.Designer.HostApp.v3.ncrunchproject
similarity index 100%
rename from .ncrunch/ControlCatalog.Web.v3.ncrunchproject
rename to .ncrunch/Avalonia.Designer.HostApp.v3.ncrunchproject
diff --git a/.ncrunch/Avalonia.Themes.Fluent.net6.0.v3.ncrunchproject b/.ncrunch/Avalonia.Themes.Fluent.net6.0.v3.ncrunchproject
new file mode 100644
index 0000000000..02eb0d211e
--- /dev/null
+++ b/.ncrunch/Avalonia.Themes.Fluent.net6.0.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ False
+
+
\ No newline at end of file
diff --git a/.ncrunch/Avalonia.Themes.Fluent.netstandard2.0.v3.ncrunchproject b/.ncrunch/Avalonia.Themes.Fluent.netstandard2.0.v3.ncrunchproject
new file mode 100644
index 0000000000..02eb0d211e
--- /dev/null
+++ b/.ncrunch/Avalonia.Themes.Fluent.netstandard2.0.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ False
+
+
\ No newline at end of file
diff --git a/.ncrunch/Avalonia.Themes.Simple.net6.0.v3.ncrunchproject b/.ncrunch/Avalonia.Themes.Simple.net6.0.v3.ncrunchproject
new file mode 100644
index 0000000000..02eb0d211e
--- /dev/null
+++ b/.ncrunch/Avalonia.Themes.Simple.net6.0.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ False
+
+
\ No newline at end of file
diff --git a/.ncrunch/Avalonia.Themes.Simple.netstandard2.0.v3.ncrunchproject b/.ncrunch/Avalonia.Themes.Simple.netstandard2.0.v3.ncrunchproject
new file mode 100644
index 0000000000..02eb0d211e
--- /dev/null
+++ b/.ncrunch/Avalonia.Themes.Simple.netstandard2.0.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ False
+
+
\ No newline at end of file
diff --git a/.ncrunch/ControlCatalog.Browser.Blazor.v3.ncrunchproject b/.ncrunch/ControlCatalog.Browser.Blazor.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/ControlCatalog.Browser.Blazor.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.ncrunch/ControlCatalog.Browser.v3.ncrunchproject b/.ncrunch/ControlCatalog.Browser.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/ControlCatalog.Browser.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.ncrunch/MobileSandbox.v3.ncrunchproject b/.ncrunch/MobileSandbox.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/MobileSandbox.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Avalonia.sln b/Avalonia.sln
index e2f04ddc35..34b5596119 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -198,9 +198,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTestApp", "sampl
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.IntegrationTests.Appium", "tests\Avalonia.IntegrationTests.Appium\Avalonia.IntegrationTests.Appium.csproj", "{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Web.Blazor", "src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj", "{25831348-EB2A-483E-9576-E8F6528674A5}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Browser", "Browser", "{86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{26A98DA1-D89D-4A95-8152-349F404DA2E2}"
EndProject
@@ -216,8 +214,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevGenerators", "src\tools\DevGenerators\DevGenerators.csproj", "{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Web", "src\Web\Avalonia.Web\Avalonia.Web.csproj", "{76D39FF6-6B4F-46C4-93CD-E6FC4665739E}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox", "samples\MobileSandbox\MobileSandbox.csproj", "{3B8519C1-2F51-4F12-A348-120AB91D4532}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Android", "samples\MobileSandbox.Android\MobileSandbox.Android.csproj", "{C90FE60B-B01E-4F35-91D6-379D6966030F}"
@@ -226,9 +222,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.iOS", "sample
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Desktop", "samples\MobileSandbox.Desktop\MobileSandbox.Desktop.csproj", "{62D392C9-81CF-487F-92E8-598B2AF3FDCE}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Blazor.Web", "samples\ControlCatalog.Blazor.Web\ControlCatalog.Blazor.Web.csproj", "{6A710364-AE6D-40BD-968B-024311527AC2}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Browser", "src\Browser\Avalonia.Browser\Avalonia.Browser.csproj", "{4A39637C-9338-4925-A4DB-D072E292EC78}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Web", "samples\ControlCatalog.Web\ControlCatalog.Web.csproj", "{8B3E8405-DE18-4048-A459-9CA4AC3319A2}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -480,10 +480,6 @@ Global
{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.Build.0 = Release|Any CPU
- {25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.Build.0 = Release|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -512,10 +508,6 @@ Global
{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Release|Any CPU.Build.0 = Release|Any CPU
- {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Release|Any CPU.Build.0 = Release|Any CPU
{3B8519C1-2F51-4F12-A348-120AB91D4532}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B8519C1-2F51-4F12-A348-120AB91D4532}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B8519C1-2F51-4F12-A348-120AB91D4532}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -533,14 +525,22 @@ Global
{62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Release|Any CPU.Build.0 = Release|Any CPU
- {6A710364-AE6D-40BD-968B-024311527AC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6A710364-AE6D-40BD-968B-024311527AC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6A710364-AE6D-40BD-968B-024311527AC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6A710364-AE6D-40BD-968B-024311527AC2}.Release|Any CPU.Build.0 = Release|Any CPU
- {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4A39637C-9338-4925-A4DB-D072E292EC78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4A39637C-9338-4925-A4DB-D072E292EC78}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -591,20 +591,20 @@ Global
{BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{676D6BFD-029D-4E43-BFC7-3892265CE251} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
- {25831348-EB2A-483E-9576-E8F6528674A5} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
{26A98DA1-D89D-4A95-8152-349F404DA2E2} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
{A0D0A6A4-5C72-4ADA-9B27-621C7D94F270} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{70B9F5CC-E2F9-4314-9514-EDE762ACCC4B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{2B390431-288C-435C-BB6B-A374033BD8D1} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{EABE2161-989B-42BF-BD8D-1E34B20C21F1} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
- {76D39FF6-6B4F-46C4-93CD-E6FC4665739E} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
{3B8519C1-2F51-4F12-A348-120AB91D4532} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{C90FE60B-B01E-4F35-91D6-379D6966030F} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{62D392C9-81CF-487F-92E8-598B2AF3FDCE} = {9B9E3891-2366-4253-A952-D08BCEB71098}
- {6A710364-AE6D-40BD-968B-024311527AC2} = {9B9E3891-2366-4253-A952-D08BCEB71098}
- {8B3E8405-DE18-4048-A459-9CA4AC3319A2} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+ {4A39637C-9338-4925-A4DB-D072E292EC78} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
+ {47F8530C-F19B-4B1A-B4D6-EB231522AE5D} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}
+ {15B93A4C-1B46-43F6-B534-7B25B6E99932} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+ {90B08091-9BBD-4362-B712-E9F2CC62B218} = {9B9E3891-2366-4253-A952-D08BCEB71098}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}
diff --git a/native/Avalonia.Native/src/OSX/AvnWindow.mm b/native/Avalonia.Native/src/OSX/AvnWindow.mm
index 4c7341f834..6611dcc73f 100644
--- a/native/Avalonia.Native/src/OSX/AvnWindow.mm
+++ b/native/Avalonia.Native/src/OSX/AvnWindow.mm
@@ -171,9 +171,7 @@
_closed = false;
_isEnabled = true;
- [self backingScaleFactor];
[self setOpaque:NO];
- [self setBackgroundColor: [NSColor clearColor]];
_isExtended = false;
_isTransitioningToFullScreen = false;
diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h
index 2baf3b09b5..7fb002e54f 100644
--- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h
+++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h
@@ -90,7 +90,7 @@ BEGIN_INTERFACE_MAP()
virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override;
- virtual HRESULT SetBlurEnabled(bool enable) override;
+ virtual HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode) override;
virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
IAvnClipboard *clipboard, IAvnDndResultCallback *cb,
diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
index 77f53332cd..9946ad9b10 100644
--- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
+++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
@@ -489,10 +489,11 @@ HRESULT WindowBaseImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut)
return S_OK;
}
-HRESULT WindowBaseImpl::SetBlurEnabled(bool enable) {
+HRESULT WindowBaseImpl::SetTransparencyMode(AvnWindowTransparencyMode mode) {
START_COM_CALL;
- [StandardContainer ShowBlur:enable];
+ [Window setBackgroundColor: (mode != Transparent ? [NSColor windowBackgroundColor] : [NSColor clearColor])];
+ [StandardContainer ShowBlur: mode == Blur];
return S_OK;
}
diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets
index 4f9c4d7720..1b822c14cf 100644
--- a/packages/Avalonia/AvaloniaBuildTasks.targets
+++ b/packages/Avalonia/AvaloniaBuildTasks.targets
@@ -74,7 +74,7 @@
ReportImportance="$(AvaloniaXamlReportImportance)"/>
+ Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:GenerateAvaloniaResources /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:TargetFramework=$(TargetFramework) /p:RuntimeIdentifier=$(RuntimeIdentifier) /p:BuildProjectReferences=false"/>
@@ -112,7 +112,7 @@
/>
+ Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:CompileAvaloniaXaml /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:TargetFramework=$(TargetFramework) /p:RuntimeIdentifier=$(RuntimeIdentifier) /p:BuildProjectReferences=false"/>
diff --git a/samples/BindingDemo/App.xaml b/samples/BindingDemo/App.xaml
index 175e838616..5a8e65ed22 100644
--- a/samples/BindingDemo/App.xaml
+++ b/samples/BindingDemo/App.xaml
@@ -2,8 +2,14 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="BindingDemo.App">
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog.Blazor.Web/App.razor b/samples/ControlCatalog.Browser.Blazor/App.razor
similarity index 100%
rename from samples/ControlCatalog.Blazor.Web/App.razor
rename to samples/ControlCatalog.Browser.Blazor/App.razor
diff --git a/samples/ControlCatalog.Blazor.Web/App.razor.cs b/samples/ControlCatalog.Browser.Blazor/App.razor.cs
similarity index 83%
rename from samples/ControlCatalog.Blazor.Web/App.razor.cs
rename to samples/ControlCatalog.Browser.Blazor/App.razor.cs
index 8cc0095f20..f38db2b055 100644
--- a/samples/ControlCatalog.Blazor.Web/App.razor.cs
+++ b/samples/ControlCatalog.Browser.Blazor/App.razor.cs
@@ -1,7 +1,7 @@
using Avalonia;
-using Avalonia.Web.Blazor;
+using Avalonia.Browser.Blazor;
-namespace ControlCatalog.Blazor.Web;
+namespace ControlCatalog.Browser.Blazor;
public partial class App
{
diff --git a/samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj b/samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj
similarity index 79%
rename from samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj
rename to samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj
index 03fb31f0d3..d0fb614840 100644
--- a/samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj
+++ b/samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj
@@ -15,15 +15,15 @@
-
+
-
-
+
+
diff --git a/samples/ControlCatalog.Blazor.Web/Pages/Index.razor b/samples/ControlCatalog.Browser.Blazor/Pages/Index.razor
similarity index 50%
rename from samples/ControlCatalog.Blazor.Web/Pages/Index.razor
rename to samples/ControlCatalog.Browser.Blazor/Pages/Index.razor
index 93ca07f9f1..7480e4c5e9 100644
--- a/samples/ControlCatalog.Blazor.Web/Pages/Index.razor
+++ b/samples/ControlCatalog.Browser.Blazor/Pages/Index.razor
@@ -1,5 +1,5 @@
@page "/"
-@using Avalonia.Web.Blazor
+@using Avalonia.Browser.Blazor
diff --git a/samples/ControlCatalog.Blazor.Web/Program.cs b/samples/ControlCatalog.Browser.Blazor/Program.cs
similarity index 94%
rename from samples/ControlCatalog.Blazor.Web/Program.cs
rename to samples/ControlCatalog.Browser.Blazor/Program.cs
index d71b125fa1..eb99ca518e 100644
--- a/samples/ControlCatalog.Blazor.Web/Program.cs
+++ b/samples/ControlCatalog.Browser.Blazor/Program.cs
@@ -3,7 +3,7 @@ using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
-using ControlCatalog.Blazor.Web;
+using ControlCatalog.Browser.Blazor;
public class Program
{
diff --git a/samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json b/samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json
similarity index 100%
rename from samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json
rename to samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json
diff --git a/samples/ControlCatalog.Blazor.Web/Shared/MainLayout.razor b/samples/ControlCatalog.Browser.Blazor/Shared/MainLayout.razor
similarity index 100%
rename from samples/ControlCatalog.Blazor.Web/Shared/MainLayout.razor
rename to samples/ControlCatalog.Browser.Blazor/Shared/MainLayout.razor
diff --git a/samples/ControlCatalog.Blazor.Web/_Imports.razor b/samples/ControlCatalog.Browser.Blazor/_Imports.razor
similarity index 88%
rename from samples/ControlCatalog.Blazor.Web/_Imports.razor
rename to samples/ControlCatalog.Browser.Blazor/_Imports.razor
index 0e6d11b419..dc4f778352 100644
--- a/samples/ControlCatalog.Blazor.Web/_Imports.razor
+++ b/samples/ControlCatalog.Browser.Blazor/_Imports.razor
@@ -6,5 +6,5 @@
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
-@using ControlCatalog.Blazor.Web.Shared
+@using ControlCatalog.Browser.Blazor.Shared
@using SkiaSharp
diff --git a/samples/ControlCatalog.Blazor.Web/wwwroot/css/app.css b/samples/ControlCatalog.Browser.Blazor/wwwroot/css/app.css
similarity index 100%
rename from samples/ControlCatalog.Blazor.Web/wwwroot/css/app.css
rename to samples/ControlCatalog.Browser.Blazor/wwwroot/css/app.css
diff --git a/samples/ControlCatalog.Blazor.Web/wwwroot/favicon.ico b/samples/ControlCatalog.Browser.Blazor/wwwroot/favicon.ico
similarity index 100%
rename from samples/ControlCatalog.Blazor.Web/wwwroot/favicon.ico
rename to samples/ControlCatalog.Browser.Blazor/wwwroot/favicon.ico
diff --git a/samples/ControlCatalog.Blazor.Web/wwwroot/index.html b/samples/ControlCatalog.Browser.Blazor/wwwroot/index.html
similarity index 100%
rename from samples/ControlCatalog.Blazor.Web/wwwroot/index.html
rename to samples/ControlCatalog.Browser.Blazor/wwwroot/index.html
diff --git a/samples/ControlCatalog.Web/ControlCatalog.Web.csproj b/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj
similarity index 85%
rename from samples/ControlCatalog.Web/ControlCatalog.Web.csproj
rename to samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj
index 06a5466619..c4278459f3 100644
--- a/samples/ControlCatalog.Web/ControlCatalog.Web.csproj
+++ b/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj
@@ -26,7 +26,7 @@
-
+
@@ -39,6 +39,6 @@
-
-
+
+
diff --git a/samples/ControlCatalog.Web/EmbedSample.Browser.cs b/samples/ControlCatalog.Browser/EmbedSample.Browser.cs
similarity index 95%
rename from samples/ControlCatalog.Web/EmbedSample.Browser.cs
rename to samples/ControlCatalog.Browser/EmbedSample.Browser.cs
index 5cfbb608cc..c367230ddf 100644
--- a/samples/ControlCatalog.Web/EmbedSample.Browser.cs
+++ b/samples/ControlCatalog.Browser/EmbedSample.Browser.cs
@@ -1,11 +1,11 @@
using System;
using System.Runtime.InteropServices.JavaScript;
using Avalonia.Platform;
-using Avalonia.Web;
+using Avalonia.Browser;
using ControlCatalog.Pages;
-namespace ControlCatalog.Web;
+namespace ControlCatalog.Browser;
public class EmbedSampleWeb : INativeDemoControl
{
diff --git a/samples/ControlCatalog.Web/Logo.svg b/samples/ControlCatalog.Browser/Logo.svg
similarity index 100%
rename from samples/ControlCatalog.Web/Logo.svg
rename to samples/ControlCatalog.Browser/Logo.svg
diff --git a/samples/ControlCatalog.Web/Program.cs b/samples/ControlCatalog.Browser/Program.cs
similarity index 90%
rename from samples/ControlCatalog.Web/Program.cs
rename to samples/ControlCatalog.Browser/Program.cs
index 7d05c8e462..53b7c60a6f 100644
--- a/samples/ControlCatalog.Web/Program.cs
+++ b/samples/ControlCatalog.Browser/Program.cs
@@ -1,8 +1,8 @@
using System.Runtime.Versioning;
using Avalonia;
-using Avalonia.Web;
+using Avalonia.Browser;
using ControlCatalog;
-using ControlCatalog.Web;
+using ControlCatalog.Browser;
[assembly:SupportedOSPlatform("browser")]
diff --git a/samples/ControlCatalog.Web/Roots.xml b/samples/ControlCatalog.Browser/Roots.xml
similarity index 100%
rename from samples/ControlCatalog.Web/Roots.xml
rename to samples/ControlCatalog.Browser/Roots.xml
diff --git a/samples/ControlCatalog.Web/app.css b/samples/ControlCatalog.Browser/app.css
similarity index 100%
rename from samples/ControlCatalog.Web/app.css
rename to samples/ControlCatalog.Browser/app.css
diff --git a/samples/ControlCatalog.Web/embed.js b/samples/ControlCatalog.Browser/embed.js
similarity index 100%
rename from samples/ControlCatalog.Web/embed.js
rename to samples/ControlCatalog.Browser/embed.js
diff --git a/samples/ControlCatalog.Web/favicon.ico b/samples/ControlCatalog.Browser/favicon.ico
similarity index 100%
rename from samples/ControlCatalog.Web/favicon.ico
rename to samples/ControlCatalog.Browser/favicon.ico
diff --git a/samples/ControlCatalog.Web/index.html b/samples/ControlCatalog.Browser/index.html
similarity index 100%
rename from samples/ControlCatalog.Web/index.html
rename to samples/ControlCatalog.Browser/index.html
diff --git a/samples/ControlCatalog.Web/main.js b/samples/ControlCatalog.Browser/main.js
similarity index 100%
rename from samples/ControlCatalog.Web/main.js
rename to samples/ControlCatalog.Browser/main.js
diff --git a/samples/ControlCatalog.Web/runtimeconfig.template.json b/samples/ControlCatalog.Browser/runtimeconfig.template.json
similarity index 100%
rename from samples/ControlCatalog.Web/runtimeconfig.template.json
rename to samples/ControlCatalog.Browser/runtimeconfig.template.json
diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs
index b1bacc6483..d5e5cb14dc 100644
--- a/samples/ControlCatalog.NetCore/Program.cs
+++ b/samples/ControlCatalog.NetCore/Program.cs
@@ -99,6 +99,15 @@ namespace ControlCatalog.NetCore
SilenceConsole();
return builder.StartLinuxDrm(args, scaling: GetScaling());
}
+ else if (args.Contains("--dxgi"))
+ {
+ builder.With(new Win32PlatformOptions()
+ {
+ UseLowLatencyDxgiSwapChain = true,
+ UseWindowsUIComposition = false
+ });
+ return builder.StartWithClassicDesktopLifetime(args);
+ }
else
return builder.StartWithClassicDesktopLifetime(args);
}
diff --git a/samples/ControlCatalog.NetCore/Properties/launchSettings.json b/samples/ControlCatalog.NetCore/Properties/launchSettings.json
new file mode 100644
index 0000000000..5964ca320e
--- /dev/null
+++ b/samples/ControlCatalog.NetCore/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+ "profiles": {
+ "ControlCatalog.NetCore": {
+ "commandName": "Project"
+ },
+ "Dxgi": {
+ "commandName": "Project",
+ "commandLineArgs": "--dxgi"
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj
index 6b550a30be..18f0dd16ba 100644
--- a/samples/ControlCatalog/ControlCatalog.csproj
+++ b/samples/ControlCatalog/ControlCatalog.csproj
@@ -33,4 +33,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Converter/DegToRadConverter.cs b/samples/ControlCatalog/Converter/DegToRadConverter.cs
new file mode 100644
index 0000000000..b062bcb64a
--- /dev/null
+++ b/samples/ControlCatalog/Converter/DegToRadConverter.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using Avalonia.Data.Converters;
+
+namespace ControlCatalog.Converter
+{
+ public class DegToRadConverter : IValueConverter
+ {
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is double rad)
+ {
+ return rad * 180.0d / Math.PI;
+ }
+ return 0.0d;
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is double deg)
+ {
+ return deg / 180.0d * Math.PI;
+ }
+ return 0.0d;
+ }
+ }
+}
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index b5a09b5fbd..b95b455ca4 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -66,6 +66,9 @@
+
+
+
diff --git a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs
index 80581007fe..1235d9aefe 100644
--- a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs
@@ -143,7 +143,7 @@ namespace ControlCatalog.Pages
.OfType();
}
- private bool StringContains(string str, string? query)
+ private static bool StringContains(string str, string? query)
{
if (query == null) return false;
return str.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;
diff --git a/samples/ControlCatalog/Pages/CustomDrawing.xaml b/samples/ControlCatalog/Pages/CustomDrawing.xaml
new file mode 100644
index 0000000000..04b7fcfea5
--- /dev/null
+++ b/samples/ControlCatalog/Pages/CustomDrawing.xaml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/CustomDrawing.xaml.cs b/samples/ControlCatalog/Pages/CustomDrawing.xaml.cs
new file mode 100644
index 0000000000..0416e587b9
--- /dev/null
+++ b/samples/ControlCatalog/Pages/CustomDrawing.xaml.cs
@@ -0,0 +1,67 @@
+using System;
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public partial class CustomDrawing : UserControl
+ {
+ public CustomDrawing()
+ {
+ InitializeComponent();
+ }
+
+ private CustomDrawingExampleControl? _customControl;
+ public CustomDrawingExampleControl CustomDrawingControl
+ {
+ get
+ {
+ if (_customControl is not null)
+ return _customControl;
+ throw new System.Exception("Control did not get initialized");
+ }
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ var cntrl = this.FindControl("CustomDrawingControl");
+ if (cntrl != null)
+ {
+ _customControl = cntrl;
+ }
+ else
+ {
+ // be sad about it
+ }
+ }
+
+ private void RotateMinus (object? sender, RoutedEventArgs e)
+ {
+ if (_customControl is null) return;
+ _customControl.Rotation -= Math.PI / 20.0d;
+ }
+
+ private void RotatePlus(object? sender, RoutedEventArgs e)
+ {
+ if (_customControl is null)
+ return;
+ _customControl.Rotation += Math.PI / 20.0d;
+ }
+
+ private void ZoomIn(object? sender, RoutedEventArgs e)
+ {
+ if (_customControl is null)
+ return;
+ _customControl.Scale *= 1.2d;
+ }
+
+ private void ZoomOut(object? sender, RoutedEventArgs e)
+ {
+ if (_customControl is null)
+ return;
+ _customControl.Scale /= 1.2d;
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs b/samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs
new file mode 100644
index 0000000000..11e5e32cf1
--- /dev/null
+++ b/samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs
@@ -0,0 +1,215 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Media;
+using Avalonia.Input;
+using Avalonia.Threading;
+using Avalonia.Controls.Shapes;
+
+namespace ControlCatalog.Pages
+{
+ public class CustomDrawingExampleControl : Control
+ {
+ private Point _cursorPoint;
+
+
+ public StyledProperty ScaleProperty = AvaloniaProperty.Register(nameof(Scale), 1.0d);
+ public double Scale { get => GetValue(ScaleProperty); set => SetValue(ScaleProperty, value); }
+
+ public StyledProperty RotationProperty = AvaloniaProperty.Register(nameof(Rotation));
+ ///
+ /// Rotation, measured in Radians!
+ ///
+ public double Rotation
+ {
+ get => GetValue(RotationProperty);
+ set
+ {
+ double valueToUse = value % (Math.PI * 2);
+ SetValue(RotationProperty, valueToUse);
+ }
+ }
+
+ public StyledProperty ViewportCenterYProperty = AvaloniaProperty.Register(nameof(ViewportCenterY), 0.0d);
+ public double ViewportCenterY { get => GetValue(ViewportCenterYProperty); set => SetValue(ViewportCenterYProperty, value); }
+
+ public StyledProperty ViewportCenterXProperty = AvaloniaProperty.Register(nameof(ViewportCenterX), 0.0d);
+ public double ViewportCenterX { get => GetValue(ViewportCenterXProperty); set => SetValue(ViewportCenterXProperty, value); }
+
+ private IPen _pen;
+
+ private System.Diagnostics.Stopwatch _timeKeeper = System.Diagnostics.Stopwatch.StartNew();
+
+ private bool _isPointerCaptured = false;
+
+ public CustomDrawingExampleControl()
+ {
+ _pen = new Pen(new SolidColorBrush(Colors.Black), lineCap: PenLineCap.Round);
+
+ var _arc = new ArcSegment()
+ {
+ IsLargeArc = false,
+ Point = new Point(0, 0),
+ RotationAngle = 0,
+ Size = new Size(25, 25),
+ SweepDirection = SweepDirection.Clockwise,
+
+ };
+ StreamGeometry sg = new StreamGeometry();
+ var cntx = sg.Open();
+ cntx.BeginFigure(new Point(-25.0d, -10.0d), false);
+ cntx.ArcTo(new Point(25.0d, -10.0d), new Size(10.0d, 10.0d), 0.0d, false, SweepDirection.Clockwise);
+ cntx.EndFigure(true);
+ _smileGeometry = sg.Clone();
+ }
+
+ private Geometry _smileGeometry;
+
+ protected override void OnPointerMoved(PointerEventArgs e)
+ {
+ base.OnPointerMoved(e);
+
+ Point previousPoint = _cursorPoint;
+
+ _cursorPoint = e.GetPosition(this);
+
+ if (_isPointerCaptured)
+ {
+ Point oldWorldPoint = UIPointToWorldPoint(previousPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
+ Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
+
+ Vector diff = newWorldPoint - oldWorldPoint;
+
+ ViewportCenterX -= diff.X;
+ ViewportCenterY -= diff.Y;
+ }
+ }
+
+ protected override void OnPointerPressed(PointerPressedEventArgs e)
+ {
+ e.Handled = true;
+ e.Pointer.Capture(this);
+ _isPointerCaptured = true;
+ base.OnPointerPressed(e);
+ }
+
+ protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
+ {
+ base.OnPointerWheelChanged(e);
+ var oldScale = Scale;
+ Scale *= (1.0d + e.Delta.Y / 12.0d);
+
+ Point oldWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, oldScale, Rotation);
+ Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
+
+ Vector diff = newWorldPoint - oldWorldPoint;
+
+ ViewportCenterX -= diff.X;
+ ViewportCenterY -= diff.Y;
+ }
+
+ protected override void OnPointerReleased(PointerReleasedEventArgs e)
+ {
+ e.Pointer.Capture(null);
+ _isPointerCaptured = false;
+ base.OnPointerReleased(e);
+ }
+
+ public override void Render(DrawingContext context)
+ {
+ var localBounds = new Rect(new Size(this.Bounds.Width, this.Bounds.Height));
+ var clip = context.PushClip(this.Bounds);
+ context.DrawRectangle(Brushes.White, _pen, localBounds, 1.0d);
+
+ var halfMax = Math.Max(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) * Math.Sqrt(2.0d);
+ var halfMin = Math.Min(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) / 1.3d;
+ var halfWidth = this.Bounds.Width / 2.0d;
+ var halfHeight = this.Bounds.Height / 2.0d;
+
+ // 0,0 refers to the top-left of the control now. It is not prime time to draw gui stuff because it'll be under the world
+
+ var translateModifier = context.PushPreTransform(Avalonia.Matrix.CreateTranslation(new Avalonia.Vector(halfWidth, halfHeight)));
+
+ // now 0,0 refers to the ViewportCenter(X,Y).
+ var rotationMatrix = Avalonia.Matrix.CreateRotation(Rotation);
+ var rotationModifier = context.PushPreTransform(rotationMatrix);
+
+ // everything is rotated but not scaled
+
+ var scaleModifier = context.PushPreTransform(Avalonia.Matrix.CreateScale(Scale, -Scale));
+
+ var mapPositionModifier = context.PushPreTransform(Matrix.CreateTranslation(new Vector(-ViewportCenterX, -ViewportCenterY)));
+
+ // now everything is rotated and scaled, and at the right position, now we're drawing strictly in world coordinates
+
+ context.DrawEllipse(Brushes.White, _pen, new Point(0.0d, 0.0d), 50.0d, 50.0d);
+ context.DrawLine(_pen, new Point(-25.0d, -5.0d), new Point(-25.0d, 15.0d));
+ context.DrawLine(_pen, new Point(25.0d, -5.0d), new Point(25.0d, 15.0d));
+ context.DrawGeometry(null, _pen, _smileGeometry);
+
+ Point cursorInWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
+ context.DrawEllipse(Brushes.Gray, _pen, cursorInWorldPoint, 20.0d, 20.0d);
+
+
+ for (int i = 0; i < 10; i++)
+ {
+ double orbitRadius = i * 100 + 200;
+ var orbitInput = ((_timeKeeper.Elapsed.TotalMilliseconds + 987654d) / orbitRadius) / 10.0d;
+ if (i % 3 == 0)
+ orbitInput *= -1;
+ Point orbitPosition = new Point(Math.Sin(orbitInput) * orbitRadius, Math.Cos(orbitInput) * orbitRadius);
+ context.DrawEllipse(Brushes.Gray, _pen, orbitPosition, 20.0d, 20.0d);
+ }
+
+
+ // end drawing the world
+
+ mapPositionModifier.Dispose();
+
+ scaleModifier.Dispose();
+
+ rotationModifier.Dispose();
+ translateModifier.Dispose();
+
+ // this is prime time to draw gui stuff
+
+ context.DrawLine(_pen, _cursorPoint + new Vector(-20, 0), _cursorPoint + new Vector(20, 0));
+ context.DrawLine(_pen, _cursorPoint + new Vector(0, -20), _cursorPoint + new Vector(0, 20));
+
+ clip.Dispose();
+
+ // oh and draw again when you can, no rush, right?
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+ }
+
+ private Point UIPointToWorldPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation)
+ {
+ Point workingPoint = new Point(inPoint.X, -inPoint.Y);
+ workingPoint += new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d);
+ workingPoint /= scale;
+
+ workingPoint = Matrix.CreateRotation(rotation).Transform(workingPoint);
+
+ workingPoint += new Vector(viewportCenterX, viewportCenterY);
+
+ return workingPoint;
+ }
+
+ private Point WorldPointToUIPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation)
+ {
+ Point workingPoint = new Point(inPoint.X, inPoint.Y);
+
+ workingPoint -= new Vector(viewportCenterX, viewportCenterY);
+ // undo rotation
+ workingPoint = Matrix.CreateRotation(-rotation).Transform(workingPoint);
+ workingPoint *= scale;
+ workingPoint -= new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d);
+ workingPoint = new Point(workingPoint.X, -workingPoint.Y);
+
+ return workingPoint;
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/DataGridPage.xaml b/samples/ControlCatalog/Pages/DataGridPage.xaml
index f1fcd8035a..4c3c211ca5 100644
--- a/samples/ControlCatalog/Pages/DataGridPage.xaml
+++ b/samples/ControlCatalog/Pages/DataGridPage.xaml
@@ -14,22 +14,6 @@
-
-
-
-
-
-
A control for displaying and interacting with a data source.
@@ -45,8 +29,7 @@
+ RowBackground="#1000">
@@ -59,6 +42,24 @@
IsVisible="{Binding #ShowGDP.IsChecked}"
x:DataType="local:Country" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -71,6 +72,20 @@
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ExpanderPage.xaml b/samples/ControlCatalog/Pages/ExpanderPage.xaml
index f0a80fd7ab..b5a2e6cdd0 100644
--- a/samples/ControlCatalog/Pages/ExpanderPage.xaml
+++ b/samples/ControlCatalog/Pages/ExpanderPage.xaml
@@ -52,6 +52,24 @@
Rounded
+
+
+ Expanded content
+
+
+
+
+ Expanded content
+
+
diff --git a/samples/ControlCatalog/Pages/ExpanderPage.xaml.cs b/samples/ControlCatalog/Pages/ExpanderPage.xaml.cs
index e8a080899a..98a494e533 100644
--- a/samples/ControlCatalog/Pages/ExpanderPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/ExpanderPage.xaml.cs
@@ -10,6 +10,12 @@ namespace ControlCatalog.Pages
{
this.InitializeComponent();
DataContext = new ExpanderPageViewModel();
+
+ var CollapsingDisabledExpander = this.Get("CollapsingDisabledExpander");
+ var ExpandingDisabledExpander = this.Get("ExpandingDisabledExpander");
+
+ CollapsingDisabledExpander.Collapsing += (s, e) => { e.Handled = true; };
+ ExpandingDisabledExpander.Expanding += (s, e) => { e.Handled = true; };
}
private void InitializeComponent()
diff --git a/samples/ControlCatalog/Pages/ListBoxPage.xaml b/samples/ControlCatalog/Pages/ListBoxPage.xaml
index 04129cb82d..dc0eaf0a51 100644
--- a/samples/ControlCatalog/Pages/ListBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/ListBoxPage.xaml
@@ -32,6 +32,7 @@
diff --git a/samples/ControlCatalog/Pages/TabControlPage.xaml b/samples/ControlCatalog/Pages/TabControlPage.xaml
index a830ce69ac..e289de90f9 100644
--- a/samples/ControlCatalog/Pages/TabControlPage.xaml
+++ b/samples/ControlCatalog/Pages/TabControlPage.xaml
@@ -53,14 +53,8 @@
-
-
-
-
-
-
diff --git a/samples/ControlCatalog/Pages/TabControlPage.xaml.cs b/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
index 74e9928b24..ac9fb31ab1 100644
--- a/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
@@ -25,13 +25,13 @@ namespace ControlCatalog.Pages
{
Header = "Arch",
Text = "This is the first templated tab page.",
- Image = LoadBitmap("avares://ControlCatalog/Assets/delicate-arch-896885_640.jpg"),
+ Image = TabControlPage.LoadBitmap("avares://ControlCatalog/Assets/delicate-arch-896885_640.jpg"),
},
new TabControlPageViewModelItem
{
Header = "Leaf",
Text = "This is the second templated tab page.",
- Image = LoadBitmap("avares://ControlCatalog/Assets/maple-leaf-888807_640.jpg"),
+ Image = TabControlPage.LoadBitmap("avares://ControlCatalog/Assets/maple-leaf-888807_640.jpg"),
},
new TabControlPageViewModelItem
{
@@ -49,7 +49,7 @@ namespace ControlCatalog.Pages
AvaloniaXamlLoader.Load(this);
}
- private IBitmap LoadBitmap(string uri)
+ private static IBitmap LoadBitmap(string uri)
{
var assets = AvaloniaLocator.Current!.GetService()!;
return new Bitmap(assets.Open(new Uri(uri)));
diff --git a/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
index 59489ebcc0..f89d9d1e20 100644
--- a/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Reactive;
using Avalonia.Controls;
using Avalonia.Controls.Selection;
+using ControlCatalog.Pages;
using MiniMvvm;
namespace ControlCatalog.ViewModels
@@ -20,9 +21,9 @@ namespace ControlCatalog.ViewModels
public ListBoxPageViewModel()
{
- Items = new ObservableCollection(Enumerable.Range(1, 10000).Select(i => GenerateItem()));
+ Items = new ObservableCollection(Enumerable.Range(1, 10000).Select(i => GenerateItem()));
- Selection = new SelectionModel();
+ Selection = new SelectionModel();
Selection.Select(1);
_selectionMode = this.WhenAnyValue(
@@ -58,8 +59,8 @@ namespace ControlCatalog.ViewModels
});
}
- public ObservableCollection Items { get; }
- public SelectionModel Selection { get; }
+ public ObservableCollection Items { get; }
+ public SelectionModel Selection { get; }
public IObservable SelectionMode => _selectionMode;
public bool Multiple
@@ -96,6 +97,31 @@ namespace ControlCatalog.ViewModels
public MiniCommand RemoveItemCommand { get; }
public MiniCommand SelectRandomItemCommand { get; }
- private string GenerateItem() => $"Item {_counter++.ToString()}";
+ private ItemModel GenerateItem() => new ItemModel(_counter ++);
+ }
+
+ ///
+ /// An Item model for the
+ ///
+ public class ItemModel
+ {
+ ///
+ /// Creates a new ItemModel with the given ID
+ ///
+ /// The ID to display
+ public ItemModel(int id)
+ {
+ ID = id;
+ }
+
+ ///
+ /// The ID of this Item
+ ///
+ public int ID { get; }
+
+ public override string ToString()
+ {
+ return $"Item {ID}";
+ }
}
}
diff --git a/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs b/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs
index 83892247e6..93857fd899 100644
--- a/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs
@@ -293,10 +293,10 @@ namespace ControlCatalog.ViewModels
///
/// Any one of the parameters may be null, but not both.
///
- private static IVisual GetVisualParent(IVisual? from, IVisual? to)
+ private static Visual GetVisualParent(Visual? from, Visual? to)
{
- var p1 = (from ?? to)!.VisualParent;
- var p2 = (to ?? from)!.VisualParent;
+ var p1 = (from ?? to)!.GetVisualParent();
+ var p2 = (to ?? from)!.GetVisualParent();
if (p1 != null && p2 != null && p1 != p2)
{
diff --git a/src/Android/Avalonia.Android/AndroidInputMethod.cs b/src/Android/Avalonia.Android/AndroidInputMethod.cs
index b6adbde738..8d56086470 100644
--- a/src/Android/Avalonia.Android/AndroidInputMethod.cs
+++ b/src/Android/Avalonia.Android/AndroidInputMethod.cs
@@ -95,6 +95,10 @@ namespace Avalonia.Android
_imm.UpdateSelection(_host, surroundingText.AnchorOffset, surroundingText.CursorOffset, surroundingText.AnchorOffset, surroundingText.CursorOffset);
}
+ else
+ {
+ _imm.HideSoftInputFromWindow(_host.WindowToken, HideSoftInputFlags.ImplicitOnly);
+ }
}
private void SurroundingTextChanged(object sender, EventArgs e)
diff --git a/src/Android/Avalonia.Android/AvaloniaMainActivity.cs b/src/Android/Avalonia.Android/AvaloniaMainActivity.cs
index de8d02f188..b24581fb8b 100644
--- a/src/Android/Avalonia.Android/AvaloniaMainActivity.cs
+++ b/src/Android/Avalonia.Android/AvaloniaMainActivity.cs
@@ -4,9 +4,12 @@ using Android.Content;
using Android.Content.Res;
using Android.OS;
using Android.Runtime;
+using Android.Views;
using AndroidX.AppCompat.App;
using AndroidX.Lifecycle;
+using AndroidRect = Android.Graphics.Rect;
+
namespace Avalonia.Android
{
public abstract class AvaloniaMainActivity : AppCompatActivity, IActivityResultHandler
@@ -15,6 +18,7 @@ namespace Avalonia.Android
public Action ActivityResult { get; set; }
internal AvaloniaView View;
+ private GlobalLayoutListener _listener;
protected override void OnCreate(Bundle savedInstanceState)
{
@@ -32,6 +36,10 @@ namespace Avalonia.Android
base.OnCreate(savedInstanceState);
SetContentView(View);
+
+ _listener = new GlobalLayoutListener(View);
+
+ View.ViewTreeObserver?.AddOnGlobalLayoutListener(_listener);
}
public object Content
@@ -57,6 +65,8 @@ namespace Avalonia.Android
{
View.Content = null;
+ View.ViewTreeObserver?.RemoveOnGlobalLayoutListener(_listener);
+
base.OnDestroy();
}
@@ -66,5 +76,20 @@ namespace Avalonia.Android
ActivityResult?.Invoke(requestCode, resultCode, data);
}
+
+ class GlobalLayoutListener : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener
+ {
+ private AvaloniaView _view;
+
+ public GlobalLayoutListener(AvaloniaView view)
+ {
+ _view = view;
+ }
+
+ public void OnGlobalLayout()
+ {
+ _view.TopLevelImpl?.Resize(_view.TopLevelImpl.ClientSize);
+ }
+ }
}
}
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
index 5f53eb36c8..4150b52946 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
@@ -26,6 +26,7 @@ using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using Java.Lang;
using Math = System.Math;
+using AndroidRect = Android.Graphics.Rect;
namespace Avalonia.Android.Platform.SkiaPlatform
{
@@ -63,7 +64,21 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public IInputRoot InputRoot { get; private set; }
- public virtual Size ClientSize => Size.ToSize(RenderScaling);
+ public virtual Size ClientSize
+ {
+ get
+ {
+ AndroidRect rect = new AndroidRect();
+ AndroidRect intersection = new AndroidRect();
+
+ _view.GetWindowVisibleDisplayFrame(intersection);
+ _view.GetGlobalVisibleRect(rect);
+
+ intersection.Intersect(rect);
+
+ return new PixelSize(intersection.Right - intersection.Left, intersection.Bottom - intersection.Top).ToSize(RenderScaling);
+ }
+ }
public Size? FrameSize => null;
@@ -94,7 +109,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
? new CompositingRenderer(root, AndroidPlatform.Compositor)
: AndroidPlatform.Options.UseDeferredRendering
? new DeferredRenderer(root, AvaloniaLocator.Current.GetRequiredService()) { RenderOnlyOnRenderThread = true }
- : new ImmediateRenderer(root);
+ : new ImmediateRenderer((Visual)root);
public virtual void Hide()
{
@@ -149,6 +164,11 @@ namespace Avalonia.Android.Platform.SkiaPlatform
Resized?.Invoke(size, PlatformResizeReason.Unspecified);
}
+ internal void Resize(Size size)
+ {
+ Resized?.Invoke(size, PlatformResizeReason.Layout);
+ }
+
class ViewImpl : InvalidationAwareSurfaceView, ISurfaceHolderCallback, IInitEditorInfo
{
private readonly TopLevelImpl _tl;
diff --git a/src/Avalonia.Base/Animation/PageSlide.cs b/src/Avalonia.Base/Animation/PageSlide.cs
index b22bc8b243..609441ae8c 100644
--- a/src/Avalonia.Base/Animation/PageSlide.cs
+++ b/src/Avalonia.Base/Animation/PageSlide.cs
@@ -157,7 +157,7 @@ namespace Avalonia.Animation
///
/// Any one of the parameters may be null, but not both.
///
- protected static IVisual GetVisualParent(IVisual? from, IVisual? to)
+ protected static Visual GetVisualParent(Visual? from, Visual? to)
{
var p1 = (from ?? to)!.VisualParent;
var p2 = (to ?? from)!.VisualParent;
diff --git a/src/Avalonia.Base/AttachedProperty.cs b/src/Avalonia.Base/AttachedProperty.cs
index 12c569c452..a43194153c 100644
--- a/src/Avalonia.Base/AttachedProperty.cs
+++ b/src/Avalonia.Base/AttachedProperty.cs
@@ -34,7 +34,7 @@ namespace Avalonia
///
/// The owner type.
/// The property.
- public new AttachedProperty AddOwner() where TOwner : IAvaloniaObject
+ public new AttachedProperty AddOwner() where TOwner : AvaloniaObject
{
AvaloniaPropertyRegistry.Instance.Register(typeof(TOwner), this);
return this;
diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index 29e0b0a7c9..21bdb794b3 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -42,7 +42,6 @@
-
diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs
index 68c8f19f19..a3a732428e 100644
--- a/src/Avalonia.Base/AvaloniaObject.cs
+++ b/src/Avalonia.Base/AvaloniaObject.cs
@@ -16,7 +16,7 @@ namespace Avalonia
///
/// This class is analogous to DependencyObject in WPF.
///
- public class AvaloniaObject : IAvaloniaObject, IAvaloniaObjectDebug, INotifyPropertyChanged
+ public class AvaloniaObject : IAvaloniaObjectDebug, INotifyPropertyChanged
{
private readonly ValueStore _values;
private AvaloniaObject? _inheritanceParent;
diff --git a/src/Avalonia.Base/AvaloniaObjectExtensions.cs b/src/Avalonia.Base/AvaloniaObjectExtensions.cs
index 9644063da7..867d6215a5 100644
--- a/src/Avalonia.Base/AvaloniaObjectExtensions.cs
+++ b/src/Avalonia.Base/AvaloniaObjectExtensions.cs
@@ -36,7 +36,7 @@ namespace Avalonia
///
/// The subscription to is created using a weak reference.
///
- public static IObservable