diff --git a/Avalonia.sln b/Avalonia.sln
index 38f8e5f720..e8d5034fb0 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -206,6 +206,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.FreeDesktop", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.DataGrid.UnitTests", "tests\Avalonia.Controls.DataGrid.UnitTests\Avalonia.Controls.DataGrid.UnitTests.csproj", "{351337F5-D66F-461B-A957-4EF60BDB4BA6}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Fluent", "src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj", "{C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@@ -1921,6 +1923,30 @@ Global
{351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|iPhone.Build.0 = Release|Any CPU
{351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhone.Build.0 = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/build.sh b/build.sh
index 40b1c225a6..a40e00f815 100755
--- a/build.sh
+++ b/build.sh
@@ -67,6 +67,8 @@ else
fi
fi
+export PATH=$DOTNET_DIRECTORY:$PATH
+
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]}
diff --git a/build/CoreLibraries.props b/build/CoreLibraries.props
index d61268173d..2b54ee3f56 100644
--- a/build/CoreLibraries.props
+++ b/build/CoreLibraries.props
@@ -11,6 +11,7 @@
+
diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h
index b86c679397..f9bfaf0b47 100644
--- a/native/Avalonia.Native/inc/avalonia-native.h
+++ b/native/Avalonia.Native/inc/avalonia-native.h
@@ -387,6 +387,9 @@ AVNCOM(IAvnClipboard, 0f) : IUnknown
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;
};
diff --git a/native/Avalonia.Native/src/OSX/AvnString.h b/native/Avalonia.Native/src/OSX/AvnString.h
index 88bc4e6963..5d299374e5 100644
--- a/native/Avalonia.Native/src/OSX/AvnString.h
+++ b/native/Avalonia.Native/src/OSX/AvnString.h
@@ -12,4 +12,5 @@
extern IAvnString* CreateAvnString(NSString* string);
extern IAvnStringArray* CreateAvnStringArray(NSArray* array);
extern IAvnStringArray* CreateAvnStringArray(NSString* string);
+extern IAvnString* CreateByteArray(void* data, int len);
#endif /* AvnString_h */
diff --git a/native/Avalonia.Native/src/OSX/AvnString.mm b/native/Avalonia.Native/src/OSX/AvnString.mm
index 6445a9fef1..00b748ef63 100644
--- a/native/Avalonia.Native/src/OSX/AvnString.mm
+++ b/native/Avalonia.Native/src/OSX/AvnString.mm
@@ -29,6 +29,13 @@ public:
memcpy((void*)_cstring, (void*)cstring, _length);
}
+ AvnStringImpl(void*ptr, int len)
+ {
+ _length = len;
+ _cstring = (const char*)malloc(_length);
+ memcpy((void*)_cstring, ptr, len);
+ }
+
virtual ~AvnStringImpl()
{
free((void*)_cstring);
@@ -114,3 +121,8 @@ IAvnStringArray* CreateAvnStringArray(NSString* string)
{
return new AvnStringArrayImpl(string);
}
+
+IAvnString* CreateByteArray(void* data, int len)
+{
+ return new AvnStringImpl(data, len);
+}
diff --git a/native/Avalonia.Native/src/OSX/clipboard.mm b/native/Avalonia.Native/src/OSX/clipboard.mm
index 18d60d3853..116a08670e 100644
--- a/native/Avalonia.Native/src/OSX/clipboard.mm
+++ b/native/Avalonia.Native/src/OSX/clipboard.mm
@@ -82,6 +82,40 @@ public:
return S_OK;
}
+
+ virtual HRESULT SetBytes(char* type, void* bytes, int len) override
+ {
+ auto typeString = [NSString stringWithUTF8String:(const char*)type];
+ auto data = [NSData dataWithBytes:bytes length:len];
+ if(_item == nil)
+ [_pb setData:data forType:typeString];
+ else
+ [_item setData:data forType:typeString];
+ return S_OK;
+ }
+
+ virtual HRESULT GetBytes(char* type, IAvnString**ppv) override
+ {
+ *ppv = nil;
+ auto typeString = [NSString stringWithUTF8String:(const char*)type];
+ NSData*data;
+ @try
+ {
+ if(_item)
+ data = [_item dataForType:typeString];
+ else
+ data = [_pb dataForType:typeString];
+ if(data == nil)
+ return E_FAIL;
+ }
+ @catch(NSException* e)
+ {
+ return E_FAIL;
+ }
+ *ppv = CreateByteArray((void*)data.bytes, (int)data.length);
+ return S_OK;
+ }
+
virtual HRESULT Clear() override
{
diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml
index e40509dfda..20ca291910 100644
--- a/samples/ControlCatalog/App.xaml
+++ b/samples/ControlCatalog/App.xaml
@@ -4,7 +4,7 @@
-
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/BaseDark.xaml b/src/Avalonia.Themes.Fluent/Accents/BaseDark.xaml
new file mode 100644
index 0000000000..44318ffa8f
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/BaseDark.xaml
@@ -0,0 +1,352 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/BaseLight.xaml b/src/Avalonia.Themes.Fluent/Accents/BaseLight.xaml
new file mode 100644
index 0000000000..e43a7ab4e7
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/BaseLight.xaml
@@ -0,0 +1,351 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentBaseDark.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentBaseDark.xaml
new file mode 100644
index 0000000000..8233ecd02c
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/FluentBaseDark.xaml
@@ -0,0 +1,330 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentBaseLight.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentBaseLight.xaml
new file mode 100644
index 0000000000..b3285bebf5
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/FluentBaseLight.xaml
@@ -0,0 +1,331 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml
new file mode 100644
index 0000000000..6412b2882e
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml
@@ -0,0 +1,385 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml
new file mode 100644
index 0000000000..65988f0e65
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml
@@ -0,0 +1,385 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentDark.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentDark.xaml
new file mode 100644
index 0000000000..5b6da70233
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/FluentDark.xaml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentLight.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentLight.xaml
new file mode 100644
index 0000000000..5825a2bf34
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Accents/FluentLight.xaml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml b/src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml
new file mode 100644
index 0000000000..44e7962e17
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml
@@ -0,0 +1,71 @@
+
+
+
+
+
+ Alabama
+ Alaska
+ Arizona
+ Arkansas
+ California
+ Colorado
+ Connecticut
+ Delaware
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj b/src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj
new file mode 100644
index 0000000000..3c3e14010d
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj
@@ -0,0 +1,22 @@
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Button.xaml b/src/Avalonia.Themes.Fluent/Button.xaml
new file mode 100644
index 0000000000..42fcee6cd5
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Button.xaml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+ 8,5,8,6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml b/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
new file mode 100644
index 0000000000..89fbb9d64d
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ButtonSpinner.xaml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Calendar.xaml b/src/Avalonia.Themes.Fluent/Calendar.xaml
new file mode 100644
index 0000000000..6ae334dbae
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Calendar.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/CalendarButton.xaml b/src/Avalonia.Themes.Fluent/CalendarButton.xaml
new file mode 100644
index 0000000000..87082ef21e
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/CalendarButton.xaml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/CalendarDayButton.xaml b/src/Avalonia.Themes.Fluent/CalendarDayButton.xaml
new file mode 100644
index 0000000000..ff72044c93
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/CalendarDayButton.xaml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/CalendarItem.xaml b/src/Avalonia.Themes.Fluent/CalendarItem.xaml
new file mode 100644
index 0000000000..df17da84dc
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/CalendarItem.xaml
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Carousel.xaml b/src/Avalonia.Themes.Fluent/Carousel.xaml
new file mode 100644
index 0000000000..955a49a974
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Carousel.xaml
@@ -0,0 +1,16 @@
+
diff --git a/src/Avalonia.Themes.Fluent/CheckBox.xaml b/src/Avalonia.Themes.Fluent/CheckBox.xaml
new file mode 100644
index 0000000000..d1d7f36478
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/CheckBox.xaml
@@ -0,0 +1,294 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ComboBox.xaml b/src/Avalonia.Themes.Fluent/ComboBox.xaml
new file mode 100644
index 0000000000..1fc657c1a3
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ComboBox.xaml
@@ -0,0 +1,192 @@
+
+
+
+
+
+ Item 1
+ Item 2
+
+
+
+ Item 1
+ Item 2
+
+
+
+
+
+ 0,0,0,4
+ 15
+ 7
+
+ 12,5,0,7
+ 11,5,32,6
+ 32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ComboBoxItem.xaml b/src/Avalonia.Themes.Fluent/ComboBoxItem.xaml
new file mode 100644
index 0000000000..c26dec3d34
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ComboBoxItem.xaml
@@ -0,0 +1,59 @@
+
+
+
+
+
+ Item 1
+ Item 2
+
+
+
+ Item 1
+ Item 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ContentControl.xaml b/src/Avalonia.Themes.Fluent/ContentControl.xaml
new file mode 100644
index 0000000000..d76eecee84
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ContentControl.xaml
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/src/Avalonia.Themes.Fluent/ContextMenu.xaml b/src/Avalonia.Themes.Fluent/ContextMenu.xaml
new file mode 100644
index 0000000000..75f8f7c23d
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ContextMenu.xaml
@@ -0,0 +1,23 @@
+
diff --git a/src/Avalonia.Themes.Fluent/DataValidationErrors.xaml b/src/Avalonia.Themes.Fluent/DataValidationErrors.xaml
new file mode 100644
index 0000000000..f4145a51f5
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/DataValidationErrors.xaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/DatePicker.xaml b/src/Avalonia.Themes.Fluent/DatePicker.xaml
new file mode 100644
index 0000000000..7adb1c2d5f
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/DatePicker.xaml
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/EmbeddableControlRoot.xaml b/src/Avalonia.Themes.Fluent/EmbeddableControlRoot.xaml
new file mode 100644
index 0000000000..9ffe51fae8
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/EmbeddableControlRoot.xaml
@@ -0,0 +1,19 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Expander.xaml b/src/Avalonia.Themes.Fluent/Expander.xaml
new file mode 100644
index 0000000000..d63f785e77
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Expander.xaml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/FluentTheme.xaml b/src/Avalonia.Themes.Fluent/FluentTheme.xaml
new file mode 100644
index 0000000000..266acce971
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/FluentTheme.xaml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs b/src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs
new file mode 100644
index 0000000000..9c65a7227c
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs
@@ -0,0 +1,12 @@
+using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
+
+namespace Avalonia.Themes.Fluent
+{
+ ///
+ /// The default Avalonia theme.
+ ///
+ public class FluentTheme : Styles
+ {
+ }
+}
diff --git a/src/Avalonia.Themes.Fluent/FocusAdorner.xaml b/src/Avalonia.Themes.Fluent/FocusAdorner.xaml
new file mode 100644
index 0000000000..2d5e369573
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/FocusAdorner.xaml
@@ -0,0 +1,10 @@
+
diff --git a/src/Avalonia.Themes.Fluent/GridSplitter.xaml b/src/Avalonia.Themes.Fluent/GridSplitter.xaml
new file mode 100644
index 0000000000..dc5cd002dc
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/GridSplitter.xaml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/InverseBooleanValueConverter.cs b/src/Avalonia.Themes.Fluent/InverseBooleanValueConverter.cs
new file mode 100644
index 0000000000..20bade2a67
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/InverseBooleanValueConverter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Globalization;
+using Avalonia.Data.Converters;
+
+namespace Avalonia.Themes.Fluent
+{
+ class InverseBooleanValueConverter : IValueConverter
+ {
+ public bool Default { get; set; }
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value is bool b ? !b : Default;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value is bool b ? !b : !Default;
+ }
+ }
+}
diff --git a/src/Avalonia.Themes.Fluent/ItemsControl.xaml b/src/Avalonia.Themes.Fluent/ItemsControl.xaml
new file mode 100644
index 0000000000..8bb0fc297c
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ItemsControl.xaml
@@ -0,0 +1,15 @@
+
diff --git a/src/Avalonia.Themes.Fluent/ListBox.xaml b/src/Avalonia.Themes.Fluent/ListBox.xaml
new file mode 100644
index 0000000000..7a87387de8
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ListBox.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+ Test
+ Test
+ Test
+ Test
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ListBoxItem.xaml b/src/Avalonia.Themes.Fluent/ListBoxItem.xaml
new file mode 100644
index 0000000000..430d3c5468
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ListBoxItem.xaml
@@ -0,0 +1,97 @@
+
+
+
+
+ Disabled
+ Test
+ Test
+
+
+
+
+ 12,9,12,12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Menu.xaml b/src/Avalonia.Themes.Fluent/Menu.xaml
new file mode 100644
index 0000000000..a1a5afb4a9
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Menu.xaml
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/src/Avalonia.Themes.Fluent/MenuItem.xaml b/src/Avalonia.Themes.Fluent/MenuItem.xaml
new file mode 100644
index 0000000000..314416cda0
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/MenuItem.xaml
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/NativeMenuBar.xaml b/src/Avalonia.Themes.Fluent/NativeMenuBar.xaml
new file mode 100644
index 0000000000..799fe6ffe4
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/NativeMenuBar.xaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/NotificationCard.xaml b/src/Avalonia.Themes.Fluent/NotificationCard.xaml
new file mode 100644
index 0000000000..47d5988e8c
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/NotificationCard.xaml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/NumericUpDown.xaml b/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
new file mode 100644
index 0000000000..24cbb62908
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/NumericUpDown.xaml
@@ -0,0 +1,38 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/Avalonia.Themes.Fluent/OverlayPopupHost.xaml b/src/Avalonia.Themes.Fluent/OverlayPopupHost.xaml
new file mode 100644
index 0000000000..36dbc1b761
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/OverlayPopupHost.xaml
@@ -0,0 +1,17 @@
+
diff --git a/src/Avalonia.Themes.Fluent/PopupRoot.xaml b/src/Avalonia.Themes.Fluent/PopupRoot.xaml
new file mode 100644
index 0000000000..25c71e3493
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/PopupRoot.xaml
@@ -0,0 +1,21 @@
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ProgressBar.xaml b/src/Avalonia.Themes.Fluent/ProgressBar.xaml
new file mode 100644
index 0000000000..d3c2f0c784
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ProgressBar.xaml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/RadioButton.xaml b/src/Avalonia.Themes.Fluent/RadioButton.xaml
new file mode 100644
index 0000000000..23bcfc616a
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/RadioButton.xaml
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/RepeatButton.xaml b/src/Avalonia.Themes.Fluent/RepeatButton.xaml
new file mode 100644
index 0000000000..702e4e6ebd
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/RepeatButton.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ScrollBar.xaml b/src/Avalonia.Themes.Fluent/ScrollBar.xaml
new file mode 100644
index 0000000000..0f8fa4986d
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ScrollBar.xaml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ScrollViewer.xaml b/src/Avalonia.Themes.Fluent/ScrollViewer.xaml
new file mode 100644
index 0000000000..1d893133e1
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ScrollViewer.xaml
@@ -0,0 +1,47 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Separator.xaml b/src/Avalonia.Themes.Fluent/Separator.xaml
new file mode 100644
index 0000000000..cf0db16ee6
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Separator.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/Slider.xaml b/src/Avalonia.Themes.Fluent/Slider.xaml
new file mode 100644
index 0000000000..b21cbf3650
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Slider.xaml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/TabControl.xaml b/src/Avalonia.Themes.Fluent/TabControl.xaml
new file mode 100644
index 0000000000..ed2e67df28
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/TabControl.xaml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/TabItem.xaml b/src/Avalonia.Themes.Fluent/TabItem.xaml
new file mode 100644
index 0000000000..92482a564c
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/TabItem.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/TabStrip.xaml b/src/Avalonia.Themes.Fluent/TabStrip.xaml
new file mode 100644
index 0000000000..29ca1e7c94
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/TabStrip.xaml
@@ -0,0 +1,20 @@
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/TabStripItem.xaml b/src/Avalonia.Themes.Fluent/TabStripItem.xaml
new file mode 100644
index 0000000000..28c4c68a3d
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/TabStripItem.xaml
@@ -0,0 +1,23 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/Avalonia.Themes.Fluent/TextBox.xaml b/src/Avalonia.Themes.Fluent/TextBox.xaml
new file mode 100644
index 0000000000..e89cf2b49c
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/TextBox.xaml
@@ -0,0 +1,152 @@
+
+
+ 0,0,0,4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/ToggleButton.xaml b/src/Avalonia.Themes.Fluent/ToggleButton.xaml
new file mode 100644
index 0000000000..9e05c38eef
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ToggleButton.xaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Avalonia.Themes.Fluent/ToolTip.xaml b/src/Avalonia.Themes.Fluent/ToolTip.xaml
new file mode 100644
index 0000000000..cf6f32f9bc
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/ToolTip.xaml
@@ -0,0 +1,78 @@
+
+
+
+
+ Hover Here
+
+
+
+
+
+ ToolTip
+ A control which pops up a hint when a control is hovered
+
+
+ ToolTip bottom placement
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/TreeView.xaml b/src/Avalonia.Themes.Fluent/TreeView.xaml
new file mode 100644
index 0000000000..6ed2fd17b8
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/TreeView.xaml
@@ -0,0 +1,23 @@
+
diff --git a/src/Avalonia.Themes.Fluent/TreeViewItem.xaml b/src/Avalonia.Themes.Fluent/TreeViewItem.xaml
new file mode 100644
index 0000000000..a3f8d8b7f7
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/TreeViewItem.xaml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Themes.Fluent/UserControl.xaml b/src/Avalonia.Themes.Fluent/UserControl.xaml
new file mode 100644
index 0000000000..f4d0c21367
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/UserControl.xaml
@@ -0,0 +1,15 @@
+
diff --git a/src/Avalonia.Themes.Fluent/Window.xaml b/src/Avalonia.Themes.Fluent/Window.xaml
new file mode 100644
index 0000000000..aee15347eb
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/Window.xaml
@@ -0,0 +1,22 @@
+
diff --git a/src/Avalonia.Themes.Fluent/WindowNotificationManager.xaml b/src/Avalonia.Themes.Fluent/WindowNotificationManager.xaml
new file mode 100644
index 0000000000..7c1efa2e82
--- /dev/null
+++ b/src/Avalonia.Themes.Fluent/WindowNotificationManager.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Visuals/Media/FontWeight.cs b/src/Avalonia.Visuals/Media/FontWeight.cs
index a9967b6a66..5a4a4963a5 100644
--- a/src/Avalonia.Visuals/Media/FontWeight.cs
+++ b/src/Avalonia.Visuals/Media/FontWeight.cs
@@ -29,6 +29,11 @@ namespace Avalonia.Media
///
Light = 300,
+ ///
+ /// Specifies a "semi light" font weight.
+ ///
+ SemiLight = 350,
+
///
/// Specifies a "normal" font weight.
///
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
index 8d4475d1c3..720185a3ad 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
@@ -32,6 +32,7 @@ namespace Avalonia.Media.TextFormatting
/// The text decorations.
/// The maximum width.
/// The maximum height.
+ /// The maximum number of text lines.
/// The text style overrides.
public TextLayout(
string text,
@@ -44,6 +45,7 @@ namespace Avalonia.Media.TextFormatting
TextDecorationCollection textDecorations = null,
double maxWidth = double.PositiveInfinity,
double maxHeight = double.PositiveInfinity,
+ int maxLines = 0,
IReadOnlyList textStyleOverrides = null)
{
_text = string.IsNullOrEmpty(text) ?
@@ -59,6 +61,8 @@ namespace Avalonia.Media.TextFormatting
MaxHeight = maxHeight;
+ MaxLines = maxLines;
+
UpdateLayout();
}
@@ -73,6 +77,12 @@ namespace Avalonia.Media.TextFormatting
///
public double MaxHeight { get; }
+
+ ///
+ /// Gets the maximum number of text lines.
+ ///
+ public double MaxLines { get; }
+
///
/// Gets the text lines.
///
@@ -192,7 +202,7 @@ namespace Avalonia.Media.TextFormatting
var currentPosition = 0;
- while (currentPosition < _text.Length)
+ while (currentPosition < _text.Length && (MaxLines == 0 || textLines.Count < MaxLines))
{
int length;
@@ -222,7 +232,7 @@ namespace Avalonia.Media.TextFormatting
var remainingLength = length;
- while (remainingLength > 0)
+ while (remainingLength > 0 && (MaxLines == 0 || textLines.Count < MaxLines))
{
var textSlice = _text.AsSlice(currentPosition, remainingLength);
diff --git a/src/Avalonia.X11/X11Atoms.cs b/src/Avalonia.X11/X11Atoms.cs
index dd16fae386..32f1822e51 100644
--- a/src/Avalonia.X11/X11Atoms.cs
+++ b/src/Avalonia.X11/X11Atoms.cs
@@ -22,6 +22,7 @@
//
using System;
+using System.Collections.Generic;
using System.Linq;
using static Avalonia.X11.XLib;
// ReSharper disable FieldCanBeMadeReadOnly.Global
@@ -40,8 +41,9 @@ namespace Avalonia.X11
internal class X11Atoms
{
+ private readonly IntPtr _display;
-// Our atoms
+ // Our atoms
public readonly IntPtr AnyPropertyType = (IntPtr)0;
public readonly IntPtr XA_PRIMARY = (IntPtr)1;
public readonly IntPtr XA_SECONDARY = (IntPtr)2;
@@ -187,10 +189,13 @@ namespace Avalonia.X11
public readonly IntPtr ATOM_PAIR;
public readonly IntPtr MANAGER;
public readonly IntPtr _KDE_NET_WM_BLUR_BEHIND_REGION;
+ public readonly IntPtr INCR;
-
+ private readonly Dictionary _namesToAtoms = new Dictionary();
+ private readonly Dictionary _atomsToNames = new Dictionary();
public X11Atoms(IntPtr display)
{
+ _display = display;
// make sure this array stays in sync with the statements below
@@ -204,7 +209,33 @@ namespace Avalonia.X11
XInternAtoms(display, atomNames, atomNames.Length, true, atoms);
for (var c = 0; c < fields.Length; c++)
+ {
+ _namesToAtoms[fields[c].Name] = atoms[c];
+ _atomsToNames[atoms[c]] = fields[c].Name;
fields[c].SetValue(this, atoms[c]);
+ }
+ }
+
+ public IntPtr GetAtom(string name)
+ {
+ if (_namesToAtoms.TryGetValue(name, out var rv))
+ return rv;
+ var atom = XInternAtom(_display, name, false);
+ _namesToAtoms[name] = atom;
+ _atomsToNames[atom] = name;
+ return atom;
+ }
+
+ public string GetAtomName(IntPtr atom)
+ {
+ if (_atomsToNames.TryGetValue(atom, out var rv))
+ return rv;
+ var name = XLib.GetAtomName(_display, atom);
+ if (name == null)
+ return null;
+ _atomsToNames[atom] = name;
+ _namesToAtoms[name] = atom;
+ return name;
}
}
}
diff --git a/src/Avalonia.X11/X11Clipboard.cs b/src/Avalonia.X11/X11Clipboard.cs
index a431ffcc1a..7023bb3ef3 100644
--- a/src/Avalonia.X11/X11Clipboard.cs
+++ b/src/Avalonia.X11/X11Clipboard.cs
@@ -1,8 +1,10 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
+using Avalonia.Input;
using Avalonia.Input.Platform;
using static Avalonia.X11.XLib;
namespace Avalonia.X11
@@ -10,12 +12,14 @@ namespace Avalonia.X11
class X11Clipboard : IClipboard
{
private readonly X11Info _x11;
- private string _storedString;
+ private IDataObject _storedDataObject;
private IntPtr _handle;
private TaskCompletionSource _requestedFormatsTcs;
- private TaskCompletionSource _requestedTextTcs;
+ private TaskCompletionSource