diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..64fe33bbae --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at http://EditorConfig.org + +root = true + +[*] +end_of_line = CRLF + +[*.cs] +indent_style = space +indent_size = 4 diff --git a/Perspex.sln b/Perspex.sln index 20a7fa624e..6ac55754ca 100644 --- a/Perspex.sln +++ b/Perspex.sln @@ -1,20 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 +# Visual Studio 2012 VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Win32", "src\Windows\Perspex.Win32\Perspex.Win32.csproj", "{811A76CF-1CF6-440F-963B-BBE31BD72A82}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication", "samples\TestApplication\TestApplication.csproj", "{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}" - ProjectSection(ProjectDependencies) = postProject - {3E908F67-5543-4879-A1DC-08EACE79B3CD} = {3E908F67-5543-4879-A1DC-08EACE79B3CD} - {FB05AC90-89BA-4F2F-A924-F37875FB547C} = {FB05AC90-89BA-4F2F-A924-F37875FB547C} - {811A76CF-1CF6-440F-963B-BBE31BD72A82} = {811A76CF-1CF6-440F-963B-BBE31BD72A82} - {54F237D5-A70A-4752-9656-0C70B1A7B047} = {54F237D5-A70A-4752-9656-0C70B1A7B047} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Direct2D1", "src\Windows\Perspex.Direct2D1\Perspex.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Base", "src\Perspex.Base\Perspex.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.SceneGraph", "src\Perspex.SceneGraph\Perspex.SceneGraph.csproj", "{EB582467-6ABB-43A1-B052-E981BA910E3A}" @@ -23,6 +11,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Layout", "src\Persp EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windows", "Windows", "{B39A8919-9F95-48FE-AD7B-76E08B509888}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Win32", "src\Windows\Perspex.Win32\Perspex.Win32.csproj", "{811A76CF-1CF6-440F-963B-BBE31BD72A82}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Direct2D1", "src\Windows\Perspex.Direct2D1\Perspex.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Designer", "src\Windows\Perspex.Designer\Perspex.Designer.csproj", "{EC42600F-049B-43FF-AED1-8314D61B2749}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Input", "src\Perspex.Input\Perspex.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Interactivity", "src\Perspex.Interactivity\Perspex.Interactivity.csproj", "{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}" @@ -31,30 +25,30 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Controls", "src\Per EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Styling", "src\Perspex.Styling\Perspex.Styling.csproj", "{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Styling.UnitTests", "tests\Perspex.Styling.UnitTests\Perspex.Styling.UnitTests.csproj", "{47ECDF59-DEF8-4C53-87B1-2098A3429059}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Controls.UnitTests", "tests\Perspex.Controls.UnitTests\Perspex.Controls.UnitTests.csproj", "{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Themes.Default", "src\Perspex.Themes.Default\Perspex.Themes.Default.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.SceneGraph.UnitTests", "tests\Perspex.SceneGraph.UnitTests\Perspex.SceneGraph.UnitTests.csproj", "{76716382-3159-460E-BDA6-C5715CF606D7}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Application", "src\Perspex.Application\Perspex.Application.csproj", "{799A7BB5-3C2C-48B6-85A7-406A12C420DA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Diagnostics", "src\Perspex.Diagnostics\Perspex.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Base.UnitTests", "tests\Perspex.Base.UnitTests\Perspex.Base.UnitTests.csproj", "{2905FF23-53FB-45E6-AA49-6AF47A172056}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{2BAFBE53-7FA4-4BB9-976F-9AFCC4F9847D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NGenerics", "src\NGenerics\NGenerics.csproj", "{415E048E-4611-4815-9CF2-D774E29079AC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Layout.UnitTests", "tests\Perspex.Layout.UnitTests\Perspex.Layout.UnitTests.csproj", "{DB070A10-BF39-4752-8456-86E9D5928478}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Animation", "src\Perspex.Animation\Perspex.Animation.csproj", "{D211E587-D8BC-45B9-95A4-F297C8FA5200}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Styling.UnitTests", "tests\Perspex.Styling.UnitTests\Perspex.Styling.UnitTests.csproj", "{47ECDF59-DEF8-4C53-87B1-2098A3429059}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Controls.UnitTests", "tests\Perspex.Controls.UnitTests\Perspex.Controls.UnitTests.csproj", "{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.SceneGraph.UnitTests", "tests\Perspex.SceneGraph.UnitTests\Perspex.SceneGraph.UnitTests.csproj", "{76716382-3159-460E-BDA6-C5715CF606D7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Base.UnitTests", "tests\Perspex.Base.UnitTests\Perspex.Base.UnitTests.csproj", "{2905FF23-53FB-45E6-AA49-6AF47A172056}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Layout.UnitTests", "tests\Perspex.Layout.UnitTests\Perspex.Layout.UnitTests.csproj", "{DB070A10-BF39-4752-8456-86E9D5928478}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Interactivity.UnitTests", "tests\Perspex.Interactivity.UnitTests\Perspex.Interactivity.UnitTests.csproj", "{08478EF5-44E8-42E9-92D6-15E00EC038D8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Direct2D1.RenderTests", "tests\Perspex.RenderTests\Perspex.Direct2D1.RenderTests.csproj", "{DABFD304-D6A4-4752-8123-C2CCF7AC7831}" @@ -63,9 +57,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Input.UnitTests", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Direct2D1.UnitTests", "tests\Perspex.Direct2D1.UnitTests\Perspex.Direct2D1.UnitTests.csproj", "{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Cairo.RenderTests", "tests\Perspex.RenderTests\Perspex.Cairo.RenderTests.csproj", "{E106CF37-4066-4615-B684-172A6D30B058}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Markup.Xaml.UnitTests", "tests\Perspex.Markup.Xaml.UnitTests\Perspex.Markup.Xaml.UnitTests.csproj", "{99135EAB-653D-47E4-A378-C96E1278CA44}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Markup", "Markup", "{8B6A8209-894F-4BA1-B880-965FD453982C}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Markup.Xaml", "src\Markup\Perspex.Markup.Xaml\Perspex.Markup.Xaml.csproj", "{3E53A01A-B331-47F3-B828-4A5717E77A24}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlTestApplication", "samples\XamlTestApplication\XamlTestApplication.csproj", "{78CAFE33-DBEB-4132-8A28-81CFE8A4933C}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9B9E3891-2366-4253-A952-D08BCEB71098}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication", "samples\TestApplication\TestApplication.csproj", "{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}" ProjectSection(ProjectDependencies) = postProject {3E908F67-5543-4879-A1DC-08EACE79B3CD} = {3E908F67-5543-4879-A1DC-08EACE79B3CD} {FB05AC90-89BA-4F2F-A924-F37875FB547C} = {FB05AC90-89BA-4F2F-A924-F37875FB547C} @@ -73,9 +75,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlTestApplication", "samp {54F237D5-A70A-4752-9656-0C70B1A7B047} = {54F237D5-A70A-4752-9656-0C70B1A7B047} EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Markup", "Markup", "{8B6A8209-894F-4BA1-B880-965FD453982C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9B9E3891-2366-4253-A952-D08BCEB71098}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlTestApplication", "samples\XamlTestApplication\XamlTestApplication.csproj", "{78CAFE33-DBEB-4132-8A28-81CFE8A4933C}" + ProjectSection(ProjectDependencies) = postProject + {3E908F67-5543-4879-A1DC-08EACE79B3CD} = {3E908F67-5543-4879-A1DC-08EACE79B3CD} + {FB05AC90-89BA-4F2F-A924-F37875FB547C} = {FB05AC90-89BA-4F2F-A924-F37875FB547C} + {811A76CF-1CF6-440F-963B-BBE31BD72A82} = {811A76CF-1CF6-440F-963B-BBE31BD72A82} + {54F237D5-A70A-4752-9656-0C70B1A7B047} = {54F237D5-A70A-4752-9656-0C70B1A7B047} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DEF5-D50F-4975-8B72-124C9EB54066}" ProjectSection(SolutionItems) = preProject @@ -91,10 +97,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Cairo", "src\Gtk\Pe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.ReactiveUI", "src\Perspex.ReactiveUI\Perspex.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Markup.Xaml.UnitTests", "Tests\Perspex.Markup.Xaml.UnitTests\Perspex.Markup.Xaml.UnitTests.csproj", "{99135EAB-653D-47E4-A378-C96E1278CA44}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Cairo.RenderTests", "tests\Perspex.RenderTests\Perspex.Cairo.RenderTests.csproj", "{E106CF37-4066-4615-B684-172A6D30B058}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.HtmlRenderer", "src\Perspex.HtmlRenderer\Perspex.HtmlRenderer.csproj", "{5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}" EndProject Global @@ -103,157 +105,162 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Debug|Any CPU.Build.0 = Debug|Any CPU - {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Release|Any CPU.ActiveCfg = Release|Any CPU - {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Release|Any CPU.Build.0 = Release|Any CPU - {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Release|Any CPU.Build.0 = Release|Any CPU + {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|Any CPU.Build.0 = Release|Any CPU + {2905FF23-53FB-45E6-AA49-6AF47A172056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2905FF23-53FB-45E6-AA49-6AF47A172056}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|Any CPU.Build.0 = Release|Any CPU + {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Release|Any CPU.Build.0 = Release|Any CPU + {3E53A01A-B331-47F3-B828-4A5717E77A24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E53A01A-B331-47F3-B828-4A5717E77A24}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.Build.0 = Release|Any CPU {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E908F67-5543-4879-A1DC-08EACE79B3CD}.Release|Any CPU.Build.0 = Release|Any CPU - {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|Any CPU.Build.0 = Release|Any CPU - {EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.Build.0 = Release|Any CPU + {415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.Build.0 = Release|Any CPU {42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|Any CPU.Build.0 = Debug|Any CPU {42472427-4774-4C81-8AFF-9F27B8E31721}.Release|Any CPU.ActiveCfg = Release|Any CPU {42472427-4774-4C81-8AFF-9F27B8E31721}.Release|Any CPU.Build.0 = Release|Any CPU - {62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.Build.0 = Release|Any CPU - {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.Build.0 = Release|Any CPU - {D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|Any CPU.Build.0 = Release|Any CPU - {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.Build.0 = Release|Any CPU {47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {47ECDF59-DEF8-4C53-87B1-2098A3429059}.Debug|Any CPU.Build.0 = Debug|Any CPU {47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|Any CPU.ActiveCfg = Release|Any CPU {47ECDF59-DEF8-4C53-87B1-2098A3429059}.Release|Any CPU.Build.0 = Release|Any CPU + {54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.Build.0 = Release|Any CPU {5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Debug|Any CPU.Build.0 = Debug|Any CPU {5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Release|Any CPU.ActiveCfg = Release|Any CPU {5CCB5571-7C30-4E7D-967D-0E2158EBD91F}.Release|Any CPU.Build.0 = Release|Any CPU - {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Release|Any CPU.Build.0 = Release|Any CPU + {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Release|Any CPU.Build.0 = Release|Any CPU + {62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.Build.0 = Release|Any CPU + {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.Build.0 = Release|Any CPU + {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.Build.0 = Release|Any CPU + {7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.Build.0 = Release|Any CPU {76716382-3159-460E-BDA6-C5715CF606D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {76716382-3159-460E-BDA6-C5715CF606D7}.Debug|Any CPU.Build.0 = Debug|Any CPU {76716382-3159-460E-BDA6-C5715CF606D7}.Release|Any CPU.ActiveCfg = Release|Any CPU {76716382-3159-460E-BDA6-C5715CF606D7}.Release|Any CPU.Build.0 = Release|Any CPU + {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Release|Any CPU.Build.0 = Release|Any CPU {799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Debug|Any CPU.Build.0 = Debug|Any CPU {799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Release|Any CPU.ActiveCfg = Release|Any CPU {799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Release|Any CPU.Build.0 = Release|Any CPU - {7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.Build.0 = Release|Any CPU - {2905FF23-53FB-45E6-AA49-6AF47A172056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2905FF23-53FB-45E6-AA49-6AF47A172056}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2905FF23-53FB-45E6-AA49-6AF47A172056}.Release|Any CPU.Build.0 = Release|Any CPU - {415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.Build.0 = Release|Any CPU - {DB070A10-BF39-4752-8456-86E9D5928478}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DB070A10-BF39-4752-8456-86E9D5928478}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DB070A10-BF39-4752-8456-86E9D5928478}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DB070A10-BF39-4752-8456-86E9D5928478}.Release|Any CPU.Build.0 = Release|Any CPU + {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Debug|Any CPU.Build.0 = Debug|Any CPU + {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Release|Any CPU.ActiveCfg = Release|Any CPU + {811A76CF-1CF6-440F-963B-BBE31BD72A82}.Release|Any CPU.Build.0 = Release|Any CPU + {99135EAB-653D-47E4-A378-C96E1278CA44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99135EAB-653D-47E4-A378-C96E1278CA44}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99135EAB-653D-47E4-A378-C96E1278CA44}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99135EAB-653D-47E4-A378-C96E1278CA44}.Release|Any CPU.Build.0 = Release|Any CPU + {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|Any CPU.Build.0 = Release|Any CPU + {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|Any CPU.Build.0 = Release|Any CPU {D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.Build.0 = Debug|Any CPU {D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|Any CPU.ActiveCfg = Release|Any CPU {D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|Any CPU.Build.0 = Release|Any CPU - {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {08478EF5-44E8-42E9-92D6-15E00EC038D8}.Release|Any CPU.Build.0 = Release|Any CPU + {D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|Any CPU.Build.0 = Release|Any CPU {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Debug|Any CPU.Build.0 = Debug|Any CPU {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Release|Any CPU.ActiveCfg = Release|Any CPU {DABFD304-D6A4-4752-8123-C2CCF7AC7831}.Release|Any CPU.Build.0 = Release|Any CPU - {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AC18926A-E784-40FE-B09D-BB0FE2B599F0}.Release|Any CPU.Build.0 = Release|Any CPU + {DB070A10-BF39-4752-8456-86E9D5928478}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DB070A10-BF39-4752-8456-86E9D5928478}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DB070A10-BF39-4752-8456-86E9D5928478}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DB070A10-BF39-4752-8456-86E9D5928478}.Release|Any CPU.Build.0 = Release|Any CPU + {E106CF37-4066-4615-B684-172A6D30B058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E106CF37-4066-4615-B684-172A6D30B058}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E106CF37-4066-4615-B684-172A6D30B058}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E106CF37-4066-4615-B684-172A6D30B058}.Release|Any CPU.Build.0 = Release|Any CPU + {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Release|Any CPU.Build.0 = Release|Any CPU + {EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.Build.0 = Release|Any CPU + {EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC42600F-049B-43FF-AED1-8314D61B2749}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC42600F-049B-43FF-AED1-8314D61B2749}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC42600F-049B-43FF-AED1-8314D61B2749}.Release|Any CPU.Build.0 = Release|Any CPU {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Debug|Any CPU.Build.0 = Debug|Any CPU {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Release|Any CPU.ActiveCfg = Release|Any CPU {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}.Release|Any CPU.Build.0 = Release|Any CPU - {3E53A01A-B331-47F3-B828-4A5717E77A24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E53A01A-B331-47F3-B828-4A5717E77A24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.Build.0 = Release|Any CPU - {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {78CAFE33-DBEB-4132-8A28-81CFE8A4933C}.Release|Any CPU.Build.0 = Release|Any CPU - {54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.Build.0 = Debug|Any CPU - {54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.ActiveCfg = Release|Any CPU - {54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.Build.0 = Release|Any CPU + {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.Build.0 = Release|Any CPU {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.Build.0 = Debug|Any CPU {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.ActiveCfg = Release|Any CPU {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.Build.0 = Release|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.Build.0 = Release|Any CPU - {99135EAB-653D-47E4-A378-C96E1278CA44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99135EAB-653D-47E4-A378-C96E1278CA44}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99135EAB-653D-47E4-A378-C96E1278CA44}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99135EAB-653D-47E4-A378-C96E1278CA44}.Release|Any CPU.Build.0 = Release|Any CPU - {E106CF37-4066-4615-B684-172A6D30B058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E106CF37-4066-4615-B684-172A6D30B058}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E106CF37-4066-4615-B684-172A6D30B058}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E106CF37-4066-4615-B684-172A6D30B058}.Release|Any CPU.Build.0 = Release|Any CPU - {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {811A76CF-1CF6-440F-963B-BBE31BD72A82} = {B39A8919-9F95-48FE-AD7B-76E08B509888} - {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72} = {9B9E3891-2366-4253-A952-D08BCEB71098} {3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888} + {EC42600F-049B-43FF-AED1-8314D61B2749} = {B39A8919-9F95-48FE-AD7B-76E08B509888} + {415E048E-4611-4815-9CF2-D774E29079AC} = {2BAFBE53-7FA4-4BB9-976F-9AFCC4F9847D} {47ECDF59-DEF8-4C53-87B1-2098A3429059} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {5CCB5571-7C30-4E7D-967D-0E2158EBD91F} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {76716382-3159-460E-BDA6-C5715CF606D7} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {2905FF23-53FB-45E6-AA49-6AF47A172056} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} - {415E048E-4611-4815-9CF2-D774E29079AC} = {2BAFBE53-7FA4-4BB9-976F-9AFCC4F9847D} {DB070A10-BF39-4752-8456-86E9D5928478} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {08478EF5-44E8-42E9-92D6-15E00EC038D8} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {DABFD304-D6A4-4752-8123-C2CCF7AC7831} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {AC18926A-E784-40FE-B09D-BB0FE2B599F0} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} + {E106CF37-4066-4615-B684-172A6D30B058} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} + {99135EAB-653D-47E4-A378-C96E1278CA44} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {3E53A01A-B331-47F3-B828-4A5717E77A24} = {8B6A8209-894F-4BA1-B880-965FD453982C} + {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72} = {9B9E3891-2366-4253-A952-D08BCEB71098} {78CAFE33-DBEB-4132-8A28-81CFE8A4933C} = {9B9E3891-2366-4253-A952-D08BCEB71098} {54F237D5-A70A-4752-9656-0C70B1A7B047} = {B9894058-278A-46B5-B6ED-AD613FCC03B3} {FB05AC90-89BA-4F2F-A924-F37875FB547C} = {B9894058-278A-46B5-B6ED-AD613FCC03B3} - {99135EAB-653D-47E4-A378-C96E1278CA44} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} - {E106CF37-4066-4615-B684-172A6D30B058} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png deleted file mode 100644 index 0918b7fd51..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png deleted file mode 100644 index dc6050fec4..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_TopLeft.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_TopLeft.expected.png deleted file mode 100644 index 905ec5386a..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_TopLeft.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png deleted file mode 100644 index 9253eee164..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png deleted file mode 100644 index da7003b419..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png deleted file mode 100644 index 4bfcdb2dd3..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipY.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipY.expected.png deleted file mode 100644 index 74a01bb78c..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipY.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png deleted file mode 100644 index e1fcdbc1a6..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Absolute.expected.png deleted file mode 100644 index b2abed4041..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Absolute.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Percent.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Percent.expected.png deleted file mode 100644 index 1aedd35831..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Percent.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png deleted file mode 100644 index f1914a404f..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png deleted file mode 100644 index fb2ae9f8cc..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_UniformToFill.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_UniformToFill.expected.png deleted file mode 100644 index d0009b6abb..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_UniformToFill.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png deleted file mode 100644 index 64695d4bb1..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile_Alignment_BottomRight.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile_Alignment_BottomRight.expected.png deleted file mode 100644 index 0918b7fd51..0000000000 Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile_Alignment_BottomRight.expected.png and /dev/null differ diff --git a/Tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_No_Visual.expected.png b/Tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_No_Visual.expected.png deleted file mode 100644 index 31d16498cc..0000000000 Binary files a/Tests/TestFiles/Direct2D1/Media/VisualBrush/VisualBrush_No_Visual.expected.png and /dev/null differ diff --git a/appveyor.yml b/appveyor.yml index 9c83b1f9d1..25a2ba5b7b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,6 +3,20 @@ os: Visual Studio 2015 before_build: - git submodule update --init - nuget restore Perspex.sln + +environment: + myget_key: + secure: XOgD5bJUKNOS2kDDgb+affS4pDcslxALh+xvvnr1Koy0PjXlhILsBdNhxRe0KcNm + +configuration: + - Release + +after_test: +- ps: nuget\build-appveyor.ps1 + +artifacts: + - path: nuget\*.nupkg + build: project: Perspex.sln - verbosity: minimal \ No newline at end of file + verbosity: minimal diff --git a/docs/add-dialogs.png b/docs/add-dialogs.png new file mode 100644 index 0000000000..c89d025e01 Binary files /dev/null and b/docs/add-dialogs.png differ diff --git a/docs/add-packages.png b/docs/add-packages.png new file mode 100644 index 0000000000..4f7e57ad68 Binary files /dev/null and b/docs/add-packages.png differ diff --git a/docs/build.md b/docs/build.md index 4a25794ac5..41d8f965f3 100644 --- a/docs/build.md +++ b/docs/build.md @@ -27,8 +27,7 @@ please submit a PR if you have anything to add. ### Install Latest Mono That the time of writing, mono 4.2 aplha was needed to build. Add mono package sources by following -instructions below for the stable channel, and then add the alpha channel to -`/etc/apt/sources.list.d/mono-xamarin-alpha.list` as well. +instructions below for the stable channel and then add the alpha channel as well. http://www.mono-project.com/docs/getting-started/install/linux/#debian-ubuntu-and-derivatives diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md new file mode 100644 index 0000000000..21f85a7088 --- /dev/null +++ b/docs/gettingstarted.md @@ -0,0 +1,15 @@ +# Getting Started + +## Windows + +![](add-dialogs.png) + +The easiest way to try out Perspex is to install the Visual Studio Extension. + +This will add a Perspex project template and a Window template to the standard Visual Studo “Add” dialog (yes, icons still to come :) ): + +## OSX / Linux + +It is a little more manual on non-Windows platforms, but using Xamarin Studio you can install the Perspex NuGet package. + +![](add-packages.png) diff --git a/docs/perspex-video.png b/docs/perspex-video.png new file mode 100644 index 0000000000..2af3fd4c91 Binary files /dev/null and b/docs/perspex-video.png differ diff --git a/docs/screen.png b/docs/screen.png index 45914f87fc..a321a8d6e3 100644 Binary files a/docs/screen.png and b/docs/screen.png differ diff --git a/docs/styles.md b/docs/styles.md new file mode 100644 index 0000000000..755f097295 --- /dev/null +++ b/docs/styles.md @@ -0,0 +1,93 @@ +# Styling in Perspex + +The main difference between Perspex and existing XAML toolkits such as WPF and +UWP is in styling. Styling in Perspex uses a CSS-like system that aims to be +more powerful and flexible than existing XAML styling systems. For convenience +for the rest of this document we'll refer to existing XAML toolkit's styling as +"WPF styling" as that's where it originated. + +## Basics + +- Styles are defined on the `Control.Styles` collection (as opposed to in +`ResourceDictionaries` in WPF). +- Styles have a `Selector` and a collection of `Setter`s +- Selector works like a CSS selector. +- Setters function like WPF's setters. +- Styles are applied to a control and all its descendants, depending on whether + the selector matches. + +## Simple example + +Make all `Button`s in a `StackPanel` have a blue `Background`: + + + + + + + + +This is very similar to WPF, except `TargetType` is replaced by `Selector`. + +*Note that currently (as of Alpha 2) you **always** need to specify the fully +qualified property name (i.e. `Button.Background` instead of simply +`Background`). This restriction will be lifted in future.* + +## Style Classes + +As in CSS, controls can be given *style classes* which can be used in selectors: + + + + + + + + + +## Pseudoclasses + +Also as in CSS, controls can have pseudoclasses; these are classes that are +defined by the control itself rather than by the user. Pseudoclasses start +with a `:` character. + +One example of a pseudoclass is the `:pointerover` +pseudoclass (`:hover` in CSS - we may change to that in future). + +Pseudoclasses provide the functionality of `Triggers` in WPF and +`VisualStateManager` in UWP: + + + + + + + + +Other pseudoclasses include `:focus`, `:disabled`, `:pressed` for buttons, +`:checked` for checkboxes etc. + +## Named Controls + +Named controls can be selected using `#` as in CSS, e.g. `Button#Name`. + +## Children + +As with CSS, you can select children and descendants: + +- `StackPanel > Button#Foo` selects a `Button` named `"Foo"` that is the child + of a `StackPanel`. +- `StackPanel Button.foo` selects all `Button`s with the `foo` class that are + descendants of a `StackPanel`. + +## Templates + +You can select controls in the template of a lookless control by using the +`/template/` selector, so `Button /template/ Border#outline` selects `Border` +controls named `"outline"` in the template of a `Button`. diff --git a/nuget/.gitignore b/nuget/.gitignore index 93a9893778..d1dab00f5b 100644 --- a/nuget/.gitignore +++ b/nuget/.gitignore @@ -1,7 +1,2 @@ -- build/ - -**/lib/**/*.dll -**/lib/**/*.xml -**/build/**/*.dll -**/build/**/*.xml +Perspex *.nupkg \ No newline at end of file diff --git a/nuget/build-appveyor.ps1 b/nuget/build-appveyor.ps1 new file mode 100644 index 0000000000..d74216def0 --- /dev/null +++ b/nuget/build-appveyor.ps1 @@ -0,0 +1,33 @@ +$scriptpath = $MyInvocation.MyCommand.Path +$dir = Split-Path $scriptpath +Push-Location $dir + + +sv version $env:APPVEYOR_BUILD_NUMBER +#sv version "1-debug" + +sv version 9999.0.$version-nightly +sv key $env:myget_key + +sv file Perspex.$version.nupkg + +.\build-version.ps1 $version + + +sv reponame $env:APPVEYOR_REPO_NAME +sv repobranch $env:APPVEYOR_REPO_BRANCH +sv pullreq $env:APPVEYOR_PULL_REQUEST_NUMBER + +echo "Checking for publishing" +echo $reponame $repobranch $pullreq +if ($reponame -eq "Perspex/Perspex") +{ + echo Repo name matched + if($repobranch -eq "master") + { + echo Repo branch matched + nuget.exe push $file $key -Source https://www.myget.org/F/perspex-nightly/api/v2/package + } +} + + diff --git a/nuget/build-version.ps1 b/nuget/build-version.ps1 new file mode 100644 index 0000000000..c6136ba707 --- /dev/null +++ b/nuget/build-version.ps1 @@ -0,0 +1,47 @@ +rm -Force -Recurse .\Perspex -ErrorAction SilentlyContinue +rm -Force -Recurse *.nupkg -ErrorAction SilentlyContinue +Copy-Item template Perspex -Recurse +sv lib "Perspex\lib\portable-windows8+net45" +sv build "Perspex\build\net45" +mkdir $lib -ErrorAction SilentlyContinue +mkdir $build -ErrorAction SilentlyContinue + +Copy-Item ..\src\Perspex.Animation\bin\Release\Perspex.Animation.dll $lib +Copy-Item ..\src\Perspex.Animation\bin\Release\Perspex.Animation.xml $lib +Copy-Item ..\src\Perspex.Application\bin\Release\Perspex.Application.dll $lib +Copy-Item ..\src\Perspex.Application\bin\Release\Perspex.Application.xml $lib +Copy-Item ..\src\Perspex.Base\bin\Release\Perspex.Base.dll $lib +Copy-Item ..\src\Perspex.Base\bin\Release\Perspex.Base.xml $lib +Copy-Item ..\src\Perspex.Controls\bin\Release\Perspex.Controls.dll $lib +Copy-Item ..\src\Perspex.Controls\bin\Release\Perspex.Controls.xml $lib +Copy-Item ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.dll $lib +Copy-Item ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.xml $lib +Copy-Item ..\src\Perspex.Input\bin\Release\Perspex.Input.dll $lib +Copy-Item ..\src\Perspex.Input\bin\Release\Perspex.Input.xml $lib +Copy-Item ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.dll $lib +Copy-Item ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.xml $lib +Copy-Item ..\src\Perspex.Layout\bin\Release\Perspex.Layout.dll $lib +Copy-Item ..\src\Perspex.Layout\bin\Release\Perspex.Layout.xml $lib +Copy-Item ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.dll $lib +Copy-Item ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.xml $lib +Copy-Item ..\src\Perspex.Styling\bin\Release\Perspex.Styling.dll $lib +Copy-Item ..\src\Perspex.Styling\bin\Release\Perspex.Styling.xml $lib +Copy-Item ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.dll $lib +Copy-Item ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.xml $lib +Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.dll $lib +Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.xml $lib +Copy-Item ..\src\Perspex.HtmlRenderer\bin\Release\Perspex.HtmlRenderer.dll $lib +Copy-Item ..\src\NGenerics\bin\Release\NGenerics.dll $lib + +Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\Perspex.Direct2D1.dll $build +Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.dll $build +Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.Direct2D1.dll $build +Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.DXGI.dll $build +Copy-Item ..\src\Windows\Perspex.Win32\bin\Release\Perspex.Win32.dll $build +Copy-Item ..\src\Gtk\Perspex.Gtk\bin\Release\Perspex.Gtk.dll $build +Copy-Item ..\src\Gtk\Perspex.Cairo\bin\Release\Perspex.Cairo.dll $build + +(gc Perspex\Perspex.nuspec).replace('#VERSION#', $args[0]) | sc Perspex\Perspex.nuspec + +nuget.exe pack Perspex\Perspex.nuspec +rm -Force -Recurse .\Perspex \ No newline at end of file diff --git a/nuget/build.bat b/nuget/build.bat deleted file mode 100644 index 8ef89045de..0000000000 --- a/nuget/build.bat +++ /dev/null @@ -1,39 +0,0 @@ -SET lib="Perspex\lib\portable-windows8+net45" -SET build="Perspex\build\net45" - -mkdir %lib% -mkdir %build% - -copy ..\src\Perspex.Animation\bin\Release\Perspex.Animation.dll %lib% -copy ..\src\Perspex.Animation\bin\Release\Perspex.Animation.xml %lib% -copy ..\src\Perspex.Application\bin\Release\Perspex.Application.dll %lib% -copy ..\src\Perspex.Application\bin\Release\Perspex.Application.xml %lib% -copy ..\src\Perspex.Base\bin\Release\Perspex.Base.dll %lib% -copy ..\src\Perspex.Base\bin\Release\Perspex.Base.xml %lib% -copy ..\src\Perspex.Controls\bin\Release\Perspex.Controls.dll %lib% -copy ..\src\Perspex.Controls\bin\Release\Perspex.Controls.xml %lib% -copy ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.dll %lib% -copy ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.xml %lib% -copy ..\src\Perspex.Input\bin\Release\Perspex.Input.dll %lib% -copy ..\src\Perspex.Input\bin\Release\Perspex.Input.xml %lib% -copy ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.dll %lib% -copy ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.xml %lib% -copy ..\src\Perspex.Layout\bin\Release\Perspex.Layout.dll %lib% -copy ..\src\Perspex.Layout\bin\Release\Perspex.Layout.xml %lib% -copy ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.dll %lib% -copy ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.xml %lib% -copy ..\src\Perspex.Styling\bin\Release\Perspex.Styling.dll %lib% -copy ..\src\Perspex.Styling\bin\Release\Perspex.Styling.xml %lib% -copy ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.dll %lib% -copy ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.xml %lib% -copy ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.dll %lib% -copy ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.xml %lib% -copy ..\src\NGenerics\bin\Release\NGenerics.dll %lib% - -copy ..\src\Windows\Perspex.Direct2D1\bin\Release\Perspex.Direct2D1.dll %build% -copy ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.dll %build% -copy ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.Direct2D1.dll %build% -copy ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.DXGI.dll %build% -copy ..\src\Windows\Perspex.Win32\bin\Release\Perspex.Win32.dll %build% - -nuget.exe pack Perspex\Perspex.nuspec \ No newline at end of file diff --git a/nuget/build.ps1 b/nuget/build.ps1 new file mode 100644 index 0000000000..96362f30f3 --- /dev/null +++ b/nuget/build.ps1 @@ -0,0 +1 @@ +.\build-version.ps1 0.1.0-alpha2 \ No newline at end of file diff --git a/nuget/Perspex/Perspex.nuspec b/nuget/template/Perspex.nuspec similarity index 63% rename from nuget/Perspex/Perspex.nuspec rename to nuget/template/Perspex.nuspec index 432f210f05..45490d310e 100644 --- a/nuget/Perspex/Perspex.nuspec +++ b/nuget/template/Perspex.nuspec @@ -1,8 +1,8 @@ - + Perspex - 0.0.1-alpha + #VERSION# stevenk stevenk http://opensource.org/licenses/MIT @@ -13,12 +13,14 @@ Copyright 2015 Perspex - - - - + + + + + + \ No newline at end of file diff --git a/nuget/Perspex/build/net45/perspex.targets b/nuget/template/build/net45/perspex.targets similarity index 100% rename from nuget/Perspex/build/net45/perspex.targets rename to nuget/template/build/net45/perspex.targets diff --git a/readme.md b/readme.md index 03f69f235e..93cd355c60 100644 --- a/readme.md +++ b/readme.md @@ -7,6 +7,16 @@ A multi-platform .NET UI framework. ![](docs/screen.png) +![](docs/perspex-video.png)] + +## NuGet + +Perspex is delivered as a NuGet package. +You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Perspex/), [nightly](https://www.myget.org/F/perspex-nightly/api/v2/Packages)) + +You can install the package like this: +`Install-Package Perspex -Pre` + ## Background Perspex is a multi-platform windowing toolkit - somewhat like WPF - that is intended to be multi- @@ -26,8 +36,8 @@ framework. ## Documentation -As mentioned above, Perspex is still in alpha and as such there's not much documentation yet. You can -take a look at the [alpha release announcement](http://grokys.github.io/perspex/perspex-alpha/) for an +As mentioned above, Perspex is still in alpha and as such there's not much documentation yet. You can +take a look at the [getting started page](docs/gettingstarted.md) for an overview of how to get started but probably the best thing to do for now is to already know a little bit about WPF/Silverlight/UWP/XAML and ask questions in our [Gitter room](https://gitter.im/grokys/Perspex). diff --git a/samples/TestApplication/App.cs b/samples/TestApplication/App.cs index 8f3a2451d9..6c3ae2f2b7 100644 --- a/samples/TestApplication/App.cs +++ b/samples/TestApplication/App.cs @@ -12,8 +12,9 @@ namespace TestApplication public App() { RegisterServices(); - InitializeSubsystems((int)Environment.OSVersion.Platform); + InitializeSubsystems((int)Environment.OSVersion.Platform); Styles = new DefaultTheme(); + Styles.Add(new SampleTabStyle()); } } } diff --git a/samples/TestApplication/GalleryStyle.cs b/samples/TestApplication/GalleryStyle.cs new file mode 100644 index 0000000000..15cbb5749b --- /dev/null +++ b/samples/TestApplication/GalleryStyle.cs @@ -0,0 +1,123 @@ +using Perspex; +using Perspex.Controls; +using Perspex.Controls.Presenters; +using Perspex.Controls.Primitives; +using Perspex.Controls.Templates; +using Perspex.Media; +using Perspex.Styling; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestApplication +{ + internal class SampleTabStyle : Styles + { + public SampleTabStyle() + { + this.AddRange(new[] + { + new Style (s => s.Class(":container").OfType ()) + { + Setters = new[] + { + new Setter (TemplatedControl.TemplateProperty, new ControlTemplate (TabControlTemplate)) + } + }, + + new Style(s => s.Class(":container").OfType().Child().Child().Child().Child().Child().OfType()) + { + Setters = new[] + { + new Setter (TemplatedControl.TemplateProperty, new ControlTemplate (TabItemTemplate)), + } + }, + + new Style(s => s.Name("internalStrip").OfType().Child().OfType()) + { + Setters = new[] + { + new Setter(TemplatedControl.FontSizeProperty, 14.0), + new Setter(TemplatedControl.ForegroundProperty, Brushes.White) + } + }, + + new Style(s => s.Name("internalStrip").OfType().Child().OfType().Class("selected")) + { + Setters = new[] + { + new Setter(TemplatedControl.ForegroundProperty, Brushes.White), + new Setter(TemplatedControl.BackgroundProperty, new SolidColorBrush(Colors.White) { Opacity = 0.1 }), + }, + }, + }); + } + + public static Control TabItemTemplate(TabItem control) + { + return new ContentPresenter + { + DataTemplates = new DataTemplates + { + new DataTemplate(x => new Border + { + [~Border.BackgroundProperty] = control[~TemplatedControl.BackgroundProperty], + Padding = new Thickness(10), + Child = new TextBlock + { + VerticalAlignment = Perspex.Layout.VerticalAlignment.Center, + Text = x + } + }) + }, + Name = "headerPresenter", + [~ContentPresenter.ContentProperty] = control[~HeaderedContentControl.HeaderProperty], + }; + } + + public static Control TabControlTemplate(TabControl control) + { + return new Grid + { + ColumnDefinitions = new ColumnDefinitions + { + new ColumnDefinition(GridLength.Auto), + new ColumnDefinition(new GridLength(1, GridUnitType.Star)), + }, + Children = new Controls + { + new Border + { + Width = 190, + Background = SolidColorBrush.Parse("#1976D2"), + Child = new ScrollViewer + { + Content = new TabStrip + { + ItemsPanel = new FuncTemplate(() => new StackPanel { Orientation = Orientation.Vertical, Gap = 4 }), + Margin = new Thickness(0, 10, 0, 0), + Name = "internalStrip", + [!ItemsControl.ItemsProperty] = control[!ItemsControl.ItemsProperty], + [!!SelectingItemsControl.SelectedItemProperty] = control[!!SelectingItemsControl.SelectedItemProperty], + } + } + }, + new Deck + { + Name = "deck", + DataTemplates = new DataTemplates + { + new DataTemplate(x => (Control)control.MaterializeDataTemplate(x.Content)), + }, + [~Deck.TransitionProperty] = control[~TabControl.TransitionProperty], + [!ItemsControl.ItemsProperty] = control[!ItemsControl.ItemsProperty], + [!SelectingItemsControl.SelectedItemProperty] = control[!SelectingItemsControl.SelectedItemProperty], + [Grid.ColumnProperty] = 1, + } + } + }; + } + } +} \ No newline at end of file diff --git a/samples/TestApplication/Item.cs b/samples/TestApplication/Item.cs new file mode 100644 index 0000000000..4898274686 --- /dev/null +++ b/samples/TestApplication/Item.cs @@ -0,0 +1,8 @@ +namespace TestApplication +{ + internal class Item + { + public string Name { get; set; } + public string Value { get; set; } + } +} diff --git a/samples/TestApplication/Node.cs b/samples/TestApplication/Node.cs new file mode 100644 index 0000000000..2856598ad6 --- /dev/null +++ b/samples/TestApplication/Node.cs @@ -0,0 +1,16 @@ +using Perspex.Collections; + +namespace TestApplication +{ + internal class Node + { + public Node() + { + Children = new PerspexList(); + } + + public string Name { get; set; } + public PerspexList Children { get; set; } + } + +} diff --git a/samples/TestApplication/Program.cs b/samples/TestApplication/Program.cs index 54f7686e8c..bfbb8a17ce 100644 --- a/samples/TestApplication/Program.cs +++ b/samples/TestApplication/Program.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using System.Linq; using System.IO; using System.Reactive.Linq; using Perspex; @@ -23,23 +24,6 @@ using ReactiveUI; namespace TestApplication { - internal class Item - { - public string Name { get; set; } - public string Value { get; set; } - } - - internal class Node - { - public Node() - { - Children = new PerspexList(); - } - - public string Name { get; set; } - public PerspexList Children { get; set; } - } - internal class Program { private static readonly PerspexList s_treeData = new PerspexList @@ -94,17 +78,11 @@ namespace TestApplication private static void Main(string[] args) { - //Log.Logger = new LoggerConfiguration() - // .Filter.ByIncludingOnly(Matching.WithProperty("Area", "Layout")) - // .MinimumLevel.Verbose() - // .WriteTo.Trace(outputTemplate: "[{Id:X8}] [{SourceContext}] {Message}") - // .CreateLogger(); - // The version of ReactiveUI currently included is for WPF and so expects a WPF // dispatcher. This makes sure it's initialized. System.Windows.Threading.Dispatcher foo = System.Windows.Threading.Dispatcher.CurrentDispatcher; - App application = new App + new App { DataTemplates = new DataTemplates { @@ -115,15 +93,13 @@ namespace TestApplication }, }; - TextBlock fps; - - var testCommand = ReactiveCommand.Create(); - testCommand.Subscribe(_ => System.Diagnostics.Debug.WriteLine("Test command executed.")); + TabControl container; Window window = new Window { Title = "Perspex Test Application", - SizeToContent = SizeToContent.WidthAndHeight, + Width = 900, + Height = 480, Content = new Grid { ColumnDefinitions = new ColumnDefinitions @@ -139,126 +115,28 @@ namespace TestApplication }, Children = new Controls { - new Menu - { - Items = new[] - { - new MenuItem - { - Header = "_File", - Items = new[] - { - new MenuItem - { - Header = "_Open...", - Icon = new Image - { - Source = new Bitmap("github_icon.png"), - }, - }, - new MenuItem - { - Header = "_Save", - Items = new[] - { - new MenuItem - { - Header = "Sub Item _1", - }, - new MenuItem - { - Header = "Sub Item _2", - }, - } - }, - new MenuItem - { - Header = "Save _As", - Items = new[] - { - new MenuItem - { - Header = "Sub Item _1", - }, - new MenuItem - { - Header = "Sub Item _2", - }, - } - }, - new MenuItem - { - Header = "E_xit", - Command = testCommand, - }, - } - }, - new MenuItem - { - Header = "_Edit", - Items = new[] - { - new MenuItem - { - Header = "Cu_t", - }, - new MenuItem - { - Header = "_Copy", - }, - new MenuItem - { - Header = "_Paste", - }, - } - } - }, - [Grid.ColumnSpanProperty] = 2, - }, - new TabControl + (container = new TabControl { + Padding = new Thickness(5), Items = new[] { ButtonsTab(), TextTab(), HtmlTab(), - ImagesTab(), + ImagesTab(), ListsTab(), LayoutTab(), AnimationsTab(), }, - Transition = new PageSlide(TimeSpan.FromSeconds(0.25)), + Transition = new CrossFade(TimeSpan.FromSeconds(0.25)), [Grid.RowProperty] = 1, [Grid.ColumnSpanProperty] = 2, - }, - (fps = new TextBlock - { - HorizontalAlignment = HorizontalAlignment.Left, - Margin = new Thickness(2), - [Grid.RowProperty] = 2, - }), - new TextBlock - { - Text = "Press F12 for Dev Tools", - HorizontalAlignment = HorizontalAlignment.Right, - Margin = new Thickness(2), - [Grid.ColumnProperty] = 1, - [Grid.RowProperty] = 2, - }, + }) } }, }; - DevTools.Attach(window); - - //var renderer = ((IRenderRoot)window).Renderer; - //var last = renderer.RenderCount; - //DispatcherTimer.Run(() => - //{ - // fps.Text = "FPS: " + (renderer.RenderCount - last); - // last = renderer.RenderCount; - // return true; - //}, TimeSpan.FromSeconds(1)); + container.Classes.Add(":container"); window.Show(); Application.Current.Run(window); @@ -266,319 +144,580 @@ namespace TestApplication private static TabItem ButtonsTab() { - Button defaultButton; - - var showDialog = ReactiveCommand.Create(); - Button showDialogButton; - var result = new TabItem { - Header = "Buttons", - Content = new StackPanel - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Gap = 8, - MinWidth = 120, - Children = new Controls - { - (showDialogButton = new Button - { - Content = "Button", - Command = showDialog, - [ToolTip.TipProperty] = "Hello World!", - }), - new Button - { - Content = "Button", - Background = new SolidColorBrush(0xcc119eda), - [ToolTip.TipProperty] = "Goodbye Cruel World!", - }, - (defaultButton = new Button - { - Content = "Default", - IsDefault = true, - }), - new Button - { - Content = "Disabled", - IsEnabled = false, - }, - new Button - { - Content = "Disabled", - IsEnabled = false, - Background = new SolidColorBrush(0xcc119eda), - }, - new ToggleButton - { - Content = "Toggle", - }, - new ToggleButton - { - Content = "Disabled", - IsEnabled = false, - }, - new CheckBox - { - Content = "Checkbox", - }, - new RadioButton - { - Content = "RadioButton 1", - IsChecked = true, - }, - new RadioButton - { - Content = "RadioButton 2", - }, - } + Header = "Button", + Content = new ScrollViewer() + { + CanScrollHorizontally = false, + Content = new StackPanel + { + Margin = new Thickness(10), + Orientation = Orientation.Vertical, + Gap = 4, + Children = new Controls + { + new TextBlock + { + Text = "Button", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A button control", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new Button + { + Width = 150, + Content = "Button" + }, + new Button + { + Width = 150, + Content = "Disabled", + IsEnabled = false, + }, + new TextBlock + { + Margin = new Thickness(0, 40, 0, 0), + Text = "ToggleButton", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A toggle button control", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new ToggleButton + { + Width = 150, + IsChecked = true, + Content = "On" + }, + new ToggleButton + { + Width = 150, + IsChecked = false, + Content = "Off" + }, + } + } }, }; - - defaultButton.Click += (s, e) => - { - defaultButton.Content = ((string)defaultButton.Content == "Default") ? "Clicked" : "Default"; - }; - - showDialog.Subscribe(async _ => - { - var close = ReactiveCommand.Create(); - - var dialog = new Window - { - Content = new StackPanel - { - Width = 200, - Height = 200, - Children = new Controls - { - new Button { Content = "Yes", Command = close, CommandParameter = "Yes" }, - new Button { Content = "No", Command = close, CommandParameter = "No" }, - } - } - }; - - close.Subscribe(x => dialog.Close(x)); - - showDialogButton.Content = await dialog.ShowDialog(); - }); + return result; } private static TabItem HtmlTab() - { - var htmlText = - new StreamReader(typeof (Program).Assembly.GetManifestResourceStream("TestApplication.html.htm")) - .ReadToEnd(); - return new TabItem - { - Header = "Html", - Content = new ScrollViewer() - { - Width = 600, - MaxHeight = 600, - HorizontalAlignment = HorizontalAlignment.Center, - CanScrollHorizontally = false, - VerticalScrollBarVisibility = ScrollBarVisibility.Visible, - Content = - new HtmlLabel() - { - Text = htmlText - } - } - }; - } - - private static TabItem TextTab() { return new TabItem { Header = "Text", - Content = new StackPanel - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Gap = 8, - Width = 120, - Children = new Controls - { - new TextBlock - { - Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis dui quis libero suscipit tincidunt.", - TextWrapping = TextWrapping.Wrap, - TextAlignment = TextAlignment.Center, - }, - new TextBlock - { - Text = "Italic text.", - FontStyle = FontStyle.Italic, - TextAlignment = TextAlignment.Left, - }, - new TextBlock - { - Text = "Bold text.", - FontWeight = FontWeight.Bold, - TextAlignment = TextAlignment.Right, - }, - new TextBox - { - Text = "A non-wrapping text box. Lorem ipsum dolor sit amet.", - TextWrapping = TextWrapping.NoWrap, - }, - new TextBox - { - AcceptsReturn = true, - Text = "A wrapping text box. " + - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis dui quis libero suscipit tincidunt. " + - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis dui quis libero suscipit tincidunt.", - TextWrapping = TextWrapping.Wrap, - MaxHeight = 100, - }, - } - }, + Content = new ScrollViewer() + { + CanScrollHorizontally = false, + Content = new StackPanel() + { + Margin = new Thickness(10), + Orientation = Orientation.Vertical, + Gap = 4, + Children = new Controls + { + new TextBlock + { + Text = "TextBlock", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A control for displaying text.", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new TextBlock + { + Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.", + FontSize = 11 + }, + new TextBlock + { + Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.", + FontSize = 11, + FontWeight = FontWeight.Medium + }, + new TextBlock + { + Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.", + FontSize = 11, + FontWeight = FontWeight.Bold + }, + new TextBlock + { + Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.", + FontSize = 11, + FontStyle = FontStyle.Italic, + }, + new TextBlock + { + Margin = new Thickness(0, 40, 0, 0), + Text = "HtmlLabel", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A label capable of displaying HTML content", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new HtmlLabel + { + Background = SolidColorBrush.Parse("#CCCCCC"), + Padding = new Thickness(5), + Text = @"

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

+

Header Level 2

+ +
    +
  1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  2. +
  3. Aliquam tincidunt mauris eu risus.
  4. +
+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.

+ +

Header Level 3

+ + " + } + } + } + } }; } - private static TabItem ImagesTab() + private static TabItem TextTab() { - ScrollBar size; - return new TabItem { - Header = "Images", - Content = new StackPanel - { - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Gap = 8, - Children = new Controls - { - (size = new ScrollBar - { - Minimum = 100, - Maximum = 400, - Value = 100, - Orientation = Orientation.Horizontal, - }), - new ScrollViewer - { - Width = 200, - Height = 200, - CanScrollHorizontally = true, - Content = new Image - { - Source = new Bitmap("github_icon.png"), - [!Layoutable.WidthProperty] = size[!RangeBase.ValueProperty], - [!Layoutable.HeightProperty] = size[!RangeBase.ValueProperty], - }, - }, - new ProgressBar - { - [!RangeBase.MinimumProperty] = size[!RangeBase.MinimumProperty], - [!RangeBase.MaximumProperty] = size[!RangeBase.MaximumProperty], - [!RangeBase.ValueProperty] = size[!RangeBase.ValueProperty], - } - } - }, + Header = "Input", + Content = new ScrollViewer() + { + Content = new StackPanel + { + Margin = new Thickness(10), + Orientation = Orientation.Vertical, + Gap = 4, + Children = new Controls + { + new TextBlock + { + Text = "TextBox", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A text box control", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new TextBox { Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", Width = 200 }, + new TextBox { AcceptsReturn = true, TextWrapping = TextWrapping.Wrap, Width = 200, Height = 150, Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est." }, + new TextBlock + { + Margin = new Thickness(0, 40, 0, 0), + Text = "CheckBox", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A check box control", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new CheckBox { IsChecked = true, Margin = new Thickness(0, 0, 0, 5), Content = "Checked" }, + new CheckBox { IsChecked = false, Content = "Unchecked" }, + new TextBlock + { + Margin = new Thickness(0, 40, 0, 0), + Text = "RadioButton", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A radio button control", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new RadioButton { IsChecked = true, Content = "Option 1" }, + new RadioButton { IsChecked = false, Content = "Option 2" }, + new RadioButton { IsChecked = false, Content = "Option 3" }, + } + } + } }; } + private static TabItem ListsTab() { - ListBox listBox; - return new TabItem { Header = "Lists", - Content = new StackPanel - { - DataTemplates = new DataTemplates - { - new DataTemplate(x => - new StackPanel - { - Children = new Controls - { - new TextBlock { Text = x.Name, FontSize = 24 }, - new TextBlock { Text = x.Value }, - } - }) - }, - Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Gap = 8, - Children = new Controls - { - new TreeView - { - Name = "treeView", - Items = s_treeData, - }, - (listBox = new ListBox - { - Items = s_listBoxData, - MaxHeight = 300, - }), - new DropDown - { - Items = s_listBoxData, - SelectedItem = s_listBoxData[0], - VerticalAlignment = VerticalAlignment.Center, - } - } - }, + Content = new ScrollViewer() + { + CanScrollHorizontally = false, + Content = new StackPanel + { + HorizontalAlignment = HorizontalAlignment.Left, + Orientation = Orientation.Vertical, + VerticalAlignment = VerticalAlignment.Top, + Gap = 4, + Margin = new Thickness(10), + DataTemplates = new DataTemplates + { + new DataTemplate(x => + new StackPanel + { + Gap = 4, + Orientation = Orientation.Horizontal, + Children = new Controls + { + new Image { Width = 50, Height = 50, Source = new Bitmap("github_icon.png") }, + new TextBlock { Text = x.Name, FontSize = 18 } + } + }) + }, + Children = new Controls + { + new TextBlock + { + Text = "ListBox", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A list box control.", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new ListBox + { + BorderThickness = 2, + Items = s_listBoxData, + Height = 300, + Width = 300, + }, + new TextBlock + { + Margin = new Thickness(0, 40, 0, 0), + Text = "TreeView", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A tree view control.", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new TreeView + { + Name = "treeView", + Items = s_treeData, + Height = 300, + BorderThickness = 2, + Width = 300, + } + } + }, + } }; } + private static TabItem ImagesTab() + { + var imageDeck = new Deck + { + Width = 400, + Height = 400, + Transition = new PageSlide(TimeSpan.FromSeconds(0.25)), + Items = new[] + { + new Image { Source = new Bitmap("github_icon.png"), Width = 400, Height = 400 }, + new Image { Source = new Bitmap("pattern.jpg"), Width = 400, Height = 400 }, + } + }; + + imageDeck.AutoSelect = true; + + var next = new Button + { + VerticalAlignment = VerticalAlignment.Center, + Padding = new Thickness(20), + Content = new Perspex.Controls.Shapes.Path + { + Data = StreamGeometry.Parse("M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"), + Fill = Brushes.Black + } + }; + + var prev = new Button + { + VerticalAlignment = VerticalAlignment.Center, + Padding = new Thickness(20), + Content = new Perspex.Controls.Shapes.Path + { + Data = StreamGeometry.Parse("M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z"), + Fill = Brushes.Black + } + }; + + prev.Click += (s, e) => + { + if (imageDeck.SelectedIndex == 0) + imageDeck.SelectedIndex = 1; + else + imageDeck.SelectedIndex--; + }; + + next.Click += (s, e) => + { + if (imageDeck.SelectedIndex == 1) + imageDeck.SelectedIndex = 0; + else + imageDeck.SelectedIndex++; + }; + + return new TabItem + { + Header = "Images", + Content = new ScrollViewer + { + Content = new StackPanel + { + HorizontalAlignment = HorizontalAlignment.Left, + Orientation = Orientation.Vertical, + VerticalAlignment = VerticalAlignment.Top, + Gap = 4, + Margin = new Thickness(10), + Children = new Controls + { + new TextBlock + { + Text = "Deck", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "An items control that displays its items as pages that fill the controls.", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new StackPanel + { + Name = "deckVisual", + Orientation = Orientation.Horizontal, + Gap = 4, + Children = new Controls + { + prev, + imageDeck, + next + } + } + } + } + } + }; + } + private static TabItem LayoutTab() { return new TabItem { Header = "Layout", - Content = new Grid - { - ColumnDefinitions = new ColumnDefinitions - { - new ColumnDefinition(1, GridUnitType.Star), - new ColumnDefinition(1, GridUnitType.Star), - }, - Margin = new Thickness(50), - Children = new Controls - { - new StackPanel - { - Orientation = Orientation.Vertical, - Gap = 8, - Children = new Controls + Content = new ScrollViewer + { + Content = new StackPanel + { + HorizontalAlignment = HorizontalAlignment.Left, + Orientation = Orientation.Vertical, + VerticalAlignment = VerticalAlignment.Top, + Gap = 4, + Margin = new Thickness(10), + Children = new Controls + { + new TextBlock + { + Text = "Grid", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "Lays out child controls according to a grid.", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new Grid + { + Width = 600, + ColumnDefinitions = new ColumnDefinitions + { + new ColumnDefinition(1, GridUnitType.Star), + new ColumnDefinition(1, GridUnitType.Star), + }, + + RowDefinitions = new RowDefinitions + { + new RowDefinition(1, GridUnitType.Auto), + new RowDefinition(1, GridUnitType.Auto) + }, + Children = new Controls + { + + new Rectangle + { + Fill = SolidColorBrush.Parse("#FF5722"), + [Grid.ColumnSpanProperty] = 2, + Height = 200, + Margin = new Thickness(2.5) + }, + new Rectangle + { + Fill = SolidColorBrush.Parse("#FF5722"), + [Grid.RowProperty] = 1, + Height = 100, + Margin = new Thickness(2.5) + }, + new Rectangle + { + Fill = SolidColorBrush.Parse("#FF5722"), + [Grid.RowProperty] = 1, + [Grid.ColumnProperty] = 1, + Height = 100, + Margin = new Thickness(2.5) + }, + }, + }, + new TextBlock + { + Margin = new Thickness(0, 40, 0, 0), + Text = "StackPanel", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A panel which lays out its children horizontally or vertically.", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + new StackPanel + { + Orientation = Orientation.Vertical, + Gap = 4, + Width = 300, + Children = new Controls + { + new Rectangle + { + Fill = SolidColorBrush.Parse("#FFC107"), + Height = 50, + }, + new Rectangle + { + Fill = SolidColorBrush.Parse("#FFC107"), + Height = 50, + }, + new Rectangle + { + Fill = SolidColorBrush.Parse("#FFC107"), + Height = 50, + }, + } + }, + new TextBlock { - new Button { HorizontalAlignment = HorizontalAlignment.Left, Content = "Left Aligned" }, - new Button { HorizontalAlignment = HorizontalAlignment.Center, Content = "Center Aligned" }, - new Button { HorizontalAlignment = HorizontalAlignment.Right, Content = "Right Aligned" }, - new Button { HorizontalAlignment = HorizontalAlignment.Stretch, Content = "Stretch" }, + Margin = new Thickness(0, 40, 0, 0), + Text = "Canvas", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), }, - [Grid.ColumnProperty] = 0, - }, - new StackPanel - { - Orientation = Orientation.Horizontal, - Gap = 8, - Children = new Controls + new TextBlock { - new Button { VerticalAlignment = VerticalAlignment.Top, Content = "Top Aligned" }, - new Button { VerticalAlignment = VerticalAlignment.Center, Content = "Center Aligned" }, - new Button { VerticalAlignment = VerticalAlignment.Bottom, Content = "Bottom Aligned" }, - new Button { VerticalAlignment = VerticalAlignment.Stretch, Content = "Stretch" }, + Text = "A panel which lays out its children by explicit coordinates.", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) }, - [Grid.ColumnProperty] = 1, - }, - }, - } + new Canvas + { + Background = Brushes.Yellow, + Width = 300, + Height = 400, + Children = new Controls + { + new Rectangle + { + Fill = Brushes.Blue, + Width = 63, + Height = 41, + [Canvas.LeftProperty] = 40, + [Canvas.TopProperty] = 31, + }, + new Ellipse + { + Fill = Brushes.Green, + Width = 58, + Height = 58, + [Canvas.LeftProperty] = 130, + [Canvas.TopProperty] = 79, + }, + } + }, + } + } + } }; } @@ -592,70 +731,88 @@ namespace TestApplication var result = new TabItem { Header = "Animations", - Content = new Grid + Content = new StackPanel { - ColumnDefinitions = new ColumnDefinitions - { - new ColumnDefinition(1, GridUnitType.Star), - new ColumnDefinition(1, GridUnitType.Star), - }, - RowDefinitions = new RowDefinitions - { - new RowDefinition(1, GridUnitType.Star), - new RowDefinition(GridLength.Auto), - }, + HorizontalAlignment = HorizontalAlignment.Left, + Orientation = Orientation.Vertical, + VerticalAlignment = VerticalAlignment.Top, + Gap = 4, + Margin = new Thickness(10), Children = new Controls { - (border1 = new Border - { - Width = 100, - Height = 100, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Background = Brushes.Crimson, - RenderTransform = new RotateTransform(), - Child = new TextBox - { - Background = Brushes.White, - Text = "Hello!", - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - }, - }), - (border2 = new Border - { - Width = 100, - Height = 100, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Background = Brushes.Coral, - Child = new Image - { - Source = new Bitmap("github_icon.png"), - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - }, - RenderTransform = (rotate = new RotateTransform - { - PropertyTransitions = new PropertyTransitions - { - RotateTransform.AngleProperty.Transition(500), - } - }), - PropertyTransitions = new PropertyTransitions - { - Layoutable.WidthProperty.Transition(300), - Layoutable.HeightProperty.Transition(1000), - }, - [Grid.ColumnProperty] = 1, - }), - (button1 = new Button - { - HorizontalAlignment = HorizontalAlignment.Center, - Content = "Animate", - [Grid.ColumnProperty] = 1, - [Grid.RowProperty] = 1, - }), + new TextBlock + { + Text = "Animations", + FontWeight = FontWeight.Medium, + FontSize = 20, + Foreground = SolidColorBrush.Parse("#212121"), + }, + new TextBlock + { + Text = "A few animations showcased below", + FontSize = 13, + Foreground = SolidColorBrush.Parse("#727272"), + Margin = new Thickness(0, 0, 0, 10) + }, + (button1 = new Button + { + Content = "Animate", + Width = 120, + [Grid.ColumnProperty] = 1, + [Grid.RowProperty] = 1, + }), + new Canvas + { + Children = new Controls + { + (border1 = new Border + { + Width = 100, + Height = 100, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Background = Brushes.Crimson, + RenderTransform = new RotateTransform(), + Child = new TextBox + { + Background = Brushes.White, + Text = "Hello!", + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + }, + [Canvas.LeftProperty] = 100, + [Canvas.TopProperty] = 100, + }), + (border2 = new Border + { + Width = 100, + Height = 100, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Background = Brushes.Coral, + Child = new Image + { + Source = new Bitmap("github_icon.png"), + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + }, + RenderTransform = (rotate = new RotateTransform + { + PropertyTransitions = new PropertyTransitions + { + RotateTransform.AngleProperty.Transition(500), + } + }), + PropertyTransitions = new PropertyTransitions + { + Layoutable.WidthProperty.Transition(300), + Layoutable.HeightProperty.Transition(1000), + }, + [Canvas.LeftProperty] = 400, + [Canvas.TopProperty] = 100, + }), + } + } }, }, }; diff --git a/samples/TestApplication/TestApplication.csproj b/samples/TestApplication/TestApplication.csproj index 463e885e2a..4ccecb2cd0 100644 --- a/samples/TestApplication/TestApplication.csproj +++ b/samples/TestApplication/TestApplication.csproj @@ -35,18 +35,6 @@ 4 - - ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.dll - True - - - ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.FullNetFx.dll - True - - - ..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll - True - @@ -72,9 +60,21 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll + + ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.dll + + + ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.FullNetFx.dll + + + ..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll + + + + @@ -83,8 +83,12 @@ + + {FB05AC90-89BA-4F2F-A924-F37875FB547C} + Perspex.Cairo + - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation @@ -104,7 +108,7 @@ Perspex.Diagnostics - {5fb2b005-0a7f-4dad-add4-3ed01444e63d} + {5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D} Perspex.HtmlRenderer @@ -136,11 +140,11 @@ Perspex.Themes.Default - {3e908f67-5543-4879-a1dc-08eace79b3cd} + {3E908F67-5543-4879-A1DC-08EACE79B3CD} Perspex.Direct2D1 - {811a76cf-1cf6-440f-963b-bbe31bd72a82} + {811A76CF-1CF6-440F-963B-BBE31BD72A82} Perspex.Win32 @@ -149,6 +153,9 @@ PreserveNewest + + PreserveNewest + diff --git a/samples/TestApplication/pattern.jpg b/samples/TestApplication/pattern.jpg new file mode 100644 index 0000000000..72b35e0692 Binary files /dev/null and b/samples/TestApplication/pattern.jpg differ diff --git a/samples/XamlTestApplication/App.config b/samples/XamlTestApplication/App.config index bfc5697e01..5ce331f23a 100644 --- a/samples/XamlTestApplication/App.config +++ b/samples/XamlTestApplication/App.config @@ -1,7 +1,7 @@ - + diff --git a/samples/XamlTestApplication/XamlTestApplication.csproj b/samples/XamlTestApplication/XamlTestApplication.csproj index ece9ca4cfe..66ec3c93d5 100644 --- a/samples/XamlTestApplication/XamlTestApplication.csproj +++ b/samples/XamlTestApplication/XamlTestApplication.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,7 +9,7 @@ Properties XamlTestApplication XamlTestApplication - v4.5.1 + v4.5 512 @@ -36,51 +36,43 @@ 4 - - ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.dll + + + + + ..\..\packages\Rx-XAML.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll True - + + + + + + + + ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.dll + + ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.FullNetFx.dll - True - + ..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll - True - - ..\..\packages\Sprache.SuperJMN.2.0.0.50\lib\portable-net451+netcore451+wpa81\Sprache.dll - True + + ..\..\packages\Sprache.2.0.0.47\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid1+MonoTouch1\Sprache.dll - - - - + ..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll - True - + ..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll - True - + ..\..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll - True - + ..\..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll - True - - ..\..\packages\Rx-XAML.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll - True - - - - - - - @@ -94,39 +86,39 @@ - {415e048e-4611-4815-9cf2-d774e29079ac} + {415E048E-4611-4815-9CF2-D774E29079AC} NGenerics - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation - {799a7bb5-3c2c-48b6-85a7-406a12c420da} + {799A7BB5-3C2C-48B6-85A7-406A12C420DA} Perspex.Application - {b09b78d8-9b26-48b0-9149-d64a2f120f3f} + {B09B78D8-9B26-48B0-9149-D64A2F120F3F} Perspex.Base - {d2221c82-4a25-4583-9b43-d791e3f6820c} + {D2221C82-4A25-4583-9B43-D791E3F6820C} Perspex.Controls - {7062ae20-5dcc-4442-9645-8195bdece63e} + {7062AE20-5DCC-4442-9645-8195BDECE63E} Perspex.Diagnostics - {62024b2d-53eb-4638-b26b-85eeaa54866e} + {62024B2D-53EB-4638-B26B-85EEAA54866E} Perspex.Input - {6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b} + {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B} Perspex.Interactivity - {42472427-4774-4c81-8aff-9f27b8e31721} + {42472427-4774-4C81-8AFF-9F27B8E31721} Perspex.Layout @@ -134,27 +126,27 @@ Perspex.ReactiveUI - {eb582467-6abb-43a1-b052-e981ba910e3a} + {EB582467-6ABB-43A1-B052-E981BA910E3A} Perspex.SceneGraph - {f1baa01a-f176-4c6a-b39d-5b40bb1b148f} + {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F} Perspex.Styling - {3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f} + {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F} Perspex.Themes.Default - {3e53a01a-b331-47f3-b828-4a5717e77a24} + {3E53A01A-B331-47F3-B828-4A5717E77A24} Perspex.Markup.Xaml - {3e908f67-5543-4879-a1dc-08eace79b3cd} + {3E908F67-5543-4879-A1DC-08EACE79B3CD} Perspex.Direct2D1 - {811a76cf-1cf6-440f-963b-bbe31bd72a82} + {811A76CF-1CF6-440F-963B-BBE31BD72A82} Perspex.Win32 @@ -165,9 +157,9 @@ - + Designer - + diff --git a/samples/XamlTestApplication/packages.config b/samples/XamlTestApplication/packages.config index dea436fde4..0fafe14cb6 100644 --- a/samples/XamlTestApplication/packages.config +++ b/samples/XamlTestApplication/packages.config @@ -8,5 +8,5 @@ - + \ No newline at end of file diff --git a/src/Gtk/Perspex.Cairo/CairoExtensions.cs b/src/Gtk/Perspex.Cairo/CairoExtensions.cs index 5798796a37..fa66837194 100644 --- a/src/Gtk/Perspex.Cairo/CairoExtensions.cs +++ b/src/Gtk/Perspex.Cairo/CairoExtensions.cs @@ -43,37 +43,7 @@ namespace Perspex.Cairo public static Pango.Weight ToCairo(this Perspex.Media.FontWeight weight) { - if (weight == Perspex.Media.FontWeight.Light) - { - return Pango.Weight.Light; - } - - if (weight == Perspex.Media.FontWeight.Normal || weight == Perspex.Media.FontWeight.Regular) - { - return Pango.Weight.Normal; - } - - if (weight == Perspex.Media.FontWeight.DemiBold || weight == Perspex.Media.FontWeight.Medium) - { - return Pango.Weight.Semibold; - } - - if (weight == Perspex.Media.FontWeight.Bold) - { - return Pango.Weight.Bold; - } - - if (weight == Perspex.Media.FontWeight.UltraBold || weight == Perspex.Media.FontWeight.ExtraBold) - { - return Pango.Weight.Ultrabold; - } - - if (weight == Perspex.Media.FontWeight.Black || weight == Perspex.Media.FontWeight.Heavy || weight == Perspex.Media.FontWeight.UltraBlack) - { - return Pango.Weight.Heavy; - } - - return Pango.Weight.Ultralight; + return (Pango.Weight)weight; } public static Pango.Alignment ToCairo(this Perspex.Media.TextAlignment alignment) diff --git a/src/Gtk/Perspex.Cairo/Media/BrushImpl.cs b/src/Gtk/Perspex.Cairo/Media/BrushImpl.cs new file mode 100644 index 0000000000..76ad34b19a --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/BrushImpl.cs @@ -0,0 +1,17 @@ +using System; +using global::Cairo; + +namespace Perspex.Cairo +{ + public abstract class BrushImpl : IDisposable + { + public Pattern PlatformBrush { get; protected set; } + + public void Dispose() + { + if (this.PlatformBrush != null) + this.PlatformBrush.Dispose(); + } + } +} + diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index 895fbaa26e..c7bbb5aeec 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -74,14 +74,31 @@ namespace Perspex.Cairo.Media _context.Scale(scale.X, scale.Y); destRect /= scale; - Gdk.CairoHelper.SetSourcePixbuf( - _context, - impl.Surface, - -sourceRect.X + destRect.X, - -sourceRect.Y + destRect.Y); - - _context.Rectangle(destRect.ToCairo()); - _context.Fill(); + if (opacityOverride < 1.0f) { + _context.PushGroup (); + Gdk.CairoHelper.SetSourcePixbuf ( + _context, + impl.Surface, + -sourceRect.X + destRect.X, + -sourceRect.Y + destRect.Y); + + _context.Rectangle (destRect.ToCairo ()); + _context.Fill (); + _context.PopGroupToSource (); + _context.PaintWithAlpha (opacityOverride); + } else { + _context.PushGroup (); + Gdk.CairoHelper.SetSourcePixbuf ( + _context, + impl.Surface, + -sourceRect.X + destRect.X, + -sourceRect.Y + destRect.Y); + + _context.Rectangle (destRect.ToCairo ()); + _context.Fill (); + _context.PopGroupToSource (); + _context.PaintWithAlpha (opacityOverride); + } _context.Restore(); } @@ -95,11 +112,12 @@ namespace Perspex.Cairo.Media { var size = new Rect(p1, p2).Size; - SetPen(pen, size); - - _context.MoveTo(p1.ToCairo()); - _context.LineTo(p2.ToCairo()); - _context.Stroke(); + using (var p = SetPen(pen, size)) + { + _context.MoveTo(p1.ToCairo()); + _context.LineTo(p2.ToCairo()); + _context.Stroke(); + } } /// @@ -118,19 +136,22 @@ namespace Perspex.Cairo.Media if (brush != null) { - SetBrush(brush, geometry.Bounds.Size); - - if (pen != null) - _context.FillPreserve(); - else - _context.Fill(); + using (var b = SetBrush(brush, geometry.Bounds.Size)) + { + if (pen != null) + _context.FillPreserve(); + else + _context.Fill(); + } } } if (pen != null) { - SetPen(pen, geometry.Bounds.Size); - _context.Stroke(); + using (var p = SetPen(pen, geometry.Bounds.Size)) + { + _context.Stroke(); + } } } @@ -141,9 +162,11 @@ namespace Perspex.Cairo.Media /// The rectangle bounds. public void DrawRectange(Pen pen, Rect rect, float cornerRadius) { - SetPen(pen, rect.Size); - _context.Rectangle(rect.ToCairo()); - _context.Stroke(); + using (var p = SetPen(pen, rect.Size)) + { + _context.Rectangle(rect.ToCairo ()); + _context.Stroke(); + } } /// @@ -157,8 +180,10 @@ namespace Perspex.Cairo.Media var layout = ((FormattedTextImpl)text.PlatformImpl).Layout; _context.MoveTo(origin.X, origin.Y); - SetBrush(foreground, new Size(0, 0)); - Pango.CairoHelper.ShowLayout(_context, layout); + using (var b = SetBrush(foreground, new Size(0, 0))) + { + Pango.CairoHelper.ShowLayout(_context, layout); + } } /// @@ -168,9 +193,11 @@ namespace Perspex.Cairo.Media /// The rectangle bounds. public void FillRectange(Brush brush, Rect rect, float cornerRadius) { - SetBrush(brush, rect.Size); - _context.Rectangle(rect.ToCairo()); - _context.Fill(); + using (var b = SetBrush(brush, rect.Size)) + { + _context.Rectangle(rect.ToCairo ()); + _context.Fill(); + } } /// @@ -193,8 +220,15 @@ namespace Perspex.Cairo.Media /// A disposable used to undo the opacity. public IDisposable PushOpacity(double opacity) { - // TODO: Implement - return Disposable.Empty; + var tmp = opacityOverride; + + if (opacity < 1.0f) + opacityOverride = opacity; + + return Disposable.Create(() => + { + opacityOverride = tmp; + }); } /// @@ -212,38 +246,53 @@ namespace Perspex.Cairo.Media }); } - private void SetBrush(Brush brush, Size destinationSize) + private double opacityOverride = 1.0f; + + private IDisposable SetBrush(Brush brush, Size destinationSize) { + _context.Save (); + var solid = brush as SolidColorBrush; var linearGradientBrush = brush as LinearGradientBrush; - - if (solid != null) - { - _context.SetSourceRGBA( - solid.Color.R / 255.0, - solid.Color.G / 255.0, - solid.Color.B / 255.0, - solid.Color.A / 255.0); - } - else if (linearGradientBrush != null) + var radialGradientBrush = brush as RadialGradientBrush; + var imageBrush = brush as ImageBrush; + var visualBrush = brush as VisualBrush; + BrushImpl impl = null; + + if (solid != null) + { + impl = new SolidColorBrushImpl(solid, opacityOverride); + } + else if (linearGradientBrush != null) + { + impl = new LinearGradientBrushImpl(linearGradientBrush, destinationSize); + } + else if (radialGradientBrush != null) { - var start = linearGradientBrush.StartPoint.ToPixels(destinationSize); - var end = linearGradientBrush.EndPoint.ToPixels(destinationSize); - - Cairo.LinearGradient g = new Cairo.LinearGradient(start.X, start.Y, end.X, end.Y); - - foreach (var s in linearGradientBrush.GradientStops) - g.AddColorStop(s.Offset, s.Color.ToCairo()); - - g.Extend = Cairo.Extend.Pad; - - _context.SetSource(g); + impl = new RadialGradientBrushImpl(radialGradientBrush, destinationSize); } + else if (imageBrush != null) + { + impl = new ImageBrushImpl(imageBrush, destinationSize); + } + else if (visualBrush != null) + { + impl = new VisualBrushImpl(visualBrush, destinationSize); + } + else + { + impl = new SolidColorBrushImpl(null, opacityOverride); + } + + _context.SetSource(impl.PlatformBrush); + return Disposable.Create(() => + { + _context.Restore(); + }); } - private void SetPen(Pen pen, Size destinationSize) + private IDisposable SetPen(Pen pen, Size destinationSize) { - SetBrush(pen.Brush, destinationSize); if (pen.DashStyle != null) { if (pen.DashStyle.Dashes != null && pen.DashStyle.Dashes.Count > 0) @@ -261,6 +310,11 @@ namespace Perspex.Cairo.Media // TODO: Figure out a solution for this. _context.LineJoin = Cairo.LineJoin.Miter; _context.LineCap = Cairo.LineCap.Butt; + + if (pen.Brush == null) + return Disposable.Empty; + + return SetBrush(pen.Brush, destinationSize); } } } diff --git a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs index 81ae567817..0cbfc50097 100644 --- a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs @@ -30,12 +30,13 @@ namespace Perspex.Cairo.Media Layout.FontDescription = new Pango.FontDescription { Family = fontFamily, - Size = Pango.Units.FromDouble(fontSize * 0.73), + Size = Pango.Units.FromDouble(fontSize), Style = (Pango.Style)fontStyle, Weight = fontWeight.ToCairo() }; Layout.Alignment = textAlignment.ToCairo(); + Layout.Attributes = new Pango.AttrList(); } public Size Constraint @@ -115,7 +116,19 @@ namespace Perspex.Cairo.Media public void SetForegroundBrush(Brush brush, int startIndex, int count) { - // TODO: Implement. + var scb = brush as SolidColorBrush; + if (scb != null) + { + + var color = new Pango.Color(); + color.Parse(string.Format("#{0}", scb.Color.ToString().Substring(3))); + + var brushAttr = new Pango.AttrForeground(color); + brushAttr.StartIndex = (uint)startIndex; + brushAttr.EndIndex = (uint)(startIndex + count); + + Layout.Attributes.Insert(brushAttr); + } } } } diff --git a/src/Gtk/Perspex.Cairo/Media/ImageBrushImpl.cs b/src/Gtk/Perspex.Cairo/Media/ImageBrushImpl.cs new file mode 100644 index 0000000000..d6c781619c --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/ImageBrushImpl.cs @@ -0,0 +1,14 @@ +using System; +using global::Cairo; + +namespace Perspex.Cairo.Media +{ + public class ImageBrushImpl : BrushImpl + { + public ImageBrushImpl(Perspex.Media.ImageBrush brush, Size destinationSize) + { + this.PlatformBrush = TileBrushes.CreateImageBrush(brush, destinationSize); + } + } +} + diff --git a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs index ef816d6910..db35a22775 100644 --- a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs @@ -13,6 +13,7 @@ namespace Perspex.Cairo.Media.Imaging public RenderTargetBitmapImpl(Cairo.ImageSurface surface) { Surface = surface; + renderer = new Renderer(Surface); } public int PixelWidth => Surface.Width; @@ -21,7 +22,7 @@ namespace Perspex.Cairo.Media.Imaging public void Dispose() { - Surface.Dispose(); + renderer.Dispose(); } public Cairo.ImageSurface Surface @@ -29,9 +30,9 @@ namespace Perspex.Cairo.Media.Imaging get; } + private Renderer renderer; public void Render(IVisual visual) { - Renderer renderer = new Renderer(Surface); renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB")); } diff --git a/src/Gtk/Perspex.Cairo/Media/LinearGradientBrushImpl.cs b/src/Gtk/Perspex.Cairo/Media/LinearGradientBrushImpl.cs new file mode 100644 index 0000000000..f1502275c7 --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/LinearGradientBrushImpl.cs @@ -0,0 +1,22 @@ +using System; +using global::Cairo; + +namespace Perspex.Cairo +{ + public class LinearGradientBrushImpl : BrushImpl + { + public LinearGradientBrushImpl(Perspex.Media.LinearGradientBrush brush, Size destinationSize) + { + var start = brush.StartPoint.ToPixels(destinationSize); + var end = brush.EndPoint.ToPixels(destinationSize); + + this.PlatformBrush = new LinearGradient(start.X, start.Y, end.X, end.Y); + + foreach (var stop in brush.GradientStops) + ((LinearGradient)this.PlatformBrush).AddColorStop(stop.Offset, stop.Color.ToCairo()); + + ((LinearGradient)this.PlatformBrush).Extend = Extend.Pad; + } + } +} + diff --git a/src/Gtk/Perspex.Cairo/Media/RadialGradientBrushImpl.cs b/src/Gtk/Perspex.Cairo/Media/RadialGradientBrushImpl.cs new file mode 100644 index 0000000000..a345f1869d --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/RadialGradientBrushImpl.cs @@ -0,0 +1,25 @@ +using System; +using global::Cairo; + +namespace Perspex.Cairo +{ + public class RadialGradientBrushImpl : BrushImpl + { + public RadialGradientBrushImpl(Perspex.Media.RadialGradientBrush brush, Size destinationSize) + { + var center = brush.Center.ToPixels(destinationSize); + var gradientOrigin = brush.GradientOrigin.ToPixels(destinationSize); + var radius = brush.Radius; + + this.PlatformBrush = new RadialGradient(center.X, center.Y, radius, gradientOrigin.X, gradientOrigin.Y, radius); + + foreach (var stop in brush.GradientStops) + { + ((LinearGradient)this.PlatformBrush).AddColorStop(stop.Offset, stop.Color.ToCairo()); + } + + ((LinearGradient)this.PlatformBrush).Extend = Extend.Pad; + } + } +} + diff --git a/src/Gtk/Perspex.Cairo/Media/SolidColorBrushImpl.cs b/src/Gtk/Perspex.Cairo/Media/SolidColorBrushImpl.cs new file mode 100644 index 0000000000..10e63f0382 --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/SolidColorBrushImpl.cs @@ -0,0 +1,22 @@ +using System; +using global::Cairo; + +namespace Perspex.Cairo +{ + public class SolidColorBrushImpl : BrushImpl + { + public SolidColorBrushImpl(Perspex.Media.SolidColorBrush brush, double opacityOverride = 1.0f) + { + var color = brush?.Color.ToCairo() ?? new Color(); + + if (brush != null) + color.A = Math.Min(brush.Opacity, color.A); + + if (opacityOverride < 1.0f) + color.A = Math.Min(opacityOverride, color.A); + + this.PlatformBrush = new SolidPattern(color); + } + } +} + diff --git a/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs b/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs index b287146806..a49ac7ef90 100644 --- a/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs @@ -12,12 +12,17 @@ namespace Perspex.Cairo.Media public class StreamGeometryContextImpl : IStreamGeometryContextImpl { - private readonly StreamGeometryImpl _impl; - public StreamGeometryContextImpl(StreamGeometryImpl imp) + public StreamGeometryContextImpl(Cairo.Path path = null) { - _impl = imp; - _surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 0, 0); - _context = new Cairo.Context(_surf); + + _surf = new Cairo.ImageSurface (Cairo.Format.Argb32, 0, 0); + _context = new Cairo.Context (_surf); + this.Path = path; + + if (this.Path != null) + { + _context.AppendPath(this.Path); + } } public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) @@ -26,35 +31,43 @@ namespace Perspex.Cairo.Media public void BeginFigure(Point startPoint, bool isFilled) { - _context.MoveTo(startPoint.ToCairo()); + if (this.Path == null) + _context.MoveTo(startPoint.ToCairo()); } public void BezierTo(Point point1, Point point2, Point point3) { - _context.CurveTo(point1.ToCairo(), point2.ToCairo(), point3.ToCairo()); + if (this.Path == null) + _context.CurveTo(point1.ToCairo(), point2.ToCairo(), point3.ToCairo()); } public void LineTo(Point point) { - _context.LineTo(point.ToCairo()); + if (this.Path == null) + _context.LineTo(point.ToCairo()); } private readonly Cairo.Context _context; private readonly Cairo.ImageSurface _surf; + public Cairo.Path Path { get; private set; } + public Rect Bounds { get; private set; } public void EndFigure(bool isClosed) { - if (isClosed) - _context.ClosePath(); + if (this.Path == null) + { + if (isClosed) + _context.ClosePath (); - _impl.Bounds = _context.FillExtents().ToPerspex(); - _impl.Path = _context.CopyPath(); + Path = _context.CopyPath (); + Bounds = _context.FillExtents ().ToPerspex (); + } } public void Dispose() { - _context.Dispose(); - _surf.Dispose(); + _context.Dispose (); + _surf.Dispose (); } } } diff --git a/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs b/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs index a9e0266d4a..7e7f520f02 100644 --- a/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs @@ -15,26 +15,23 @@ namespace Perspex.Cairo.Media { public StreamGeometryImpl() { - _impl = new StreamGeometryContextImpl(this); + _impl = new StreamGeometryContextImpl(null); } - public StreamGeometryImpl(Cairo.Path path) + public StreamGeometryImpl(StreamGeometryContextImpl impl) { - _impl = new StreamGeometryContextImpl(this); - Path = path; - } - - public Cairo.Path Path - { - get; - set; + _impl = impl; } public Rect Bounds { - get; - set; - } + get { return _impl.Bounds; } + } + + public Cairo.Path Path + { + get { return _impl.Path; } + } private readonly StreamGeometryContextImpl _impl; @@ -55,14 +52,14 @@ namespace Perspex.Cairo.Media } public IStreamGeometryImpl Clone() - { - return new StreamGeometryImpl(Path); + { + return new StreamGeometryImpl(_impl); } public Rect GetRenderBounds(double strokeThickness) { // TODO: Calculate properly. - return Bounds; + return Bounds.Inflate(strokeThickness); } public IStreamGeometryContextImpl Open() diff --git a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs new file mode 100644 index 0000000000..e08565785a --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs @@ -0,0 +1,224 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using Cairo; +using Perspex.Cairo.Media.Imaging; +using Perspex.Layout; +using Perspex.Media; +using Perspex.Platform; + +namespace Perspex.Cairo.Media +{ + internal static class TileBrushes + { + public static SurfacePattern CreateImageBrush(ImageBrush brush, Size targetSize) + { + if (brush.Source == null) + { + return null; + } + + // TODO: This is directly ported from Direct2D and could probably be made more + // efficient on cairo by taking advantage of the fact that cairo has Extend.None. + var image = ((BitmapImpl)brush.Source.PlatformImpl).Surface; + var imageSize = new Size(brush.Source.PixelWidth, brush.Source.PixelHeight); + var tileMode = brush.TileMode; + var sourceRect = brush.SourceRect.ToPixels(imageSize); + var destinationRect = brush.DestinationRect.ToPixels(targetSize); + var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); + var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); + var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); + + var intermediate = new ImageSurface (Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height); + using (var context = new Context(intermediate)) + { + Rect drawRect; + var transform = CalculateIntermediateTransform( + tileMode, + sourceRect, + destinationRect, + scale, + translate, + out drawRect); + context.Rectangle(drawRect.ToCairo()); + context.Clip(); + context.Transform(transform.ToCairo()); + Gdk.CairoHelper.SetSourcePixbuf(context, image, 0, 0); + context.Rectangle(0, 0, imageSize.Width, imageSize.Height); + context.Fill(); + + var result = new SurfacePattern(intermediate); + + if ((brush.TileMode & TileMode.FlipXY) != 0) + { + // TODO: Currently always FlipXY as that's all cairo supports natively. + // Support separate FlipX and FlipY by drawing flipped images to intermediate + // surface. + result.Extend = Extend.Reflect; + } + else + { + result.Extend = Extend.Repeat; + } + + if (brush.TileMode != TileMode.None) + { + var matrix = result.Matrix; + matrix.InitTranslate(-destinationRect.X, -destinationRect.Y); + result.Matrix = matrix; + } + + return result; + } + } + + public static SurfacePattern CreateVisualBrush(VisualBrush brush, Size targetSize) + { + var visual = brush.Visual; + + if (visual == null) + { + return null; + } + + var layoutable = visual as ILayoutable; + + if (layoutable?.IsArrangeValid == false) + { + layoutable.Measure(Size.Infinity); + layoutable.Arrange(new Rect(layoutable.DesiredSize)); + } + + // TODO: This is directly ported from Direct2D and could probably be made more + // efficient on cairo by taking advantage of the fact that cairo has Extend.None. + var tileMode = brush.TileMode; + var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size); + var destinationRect = brush.DestinationRect.ToPixels(targetSize); + var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); + var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); + var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); + + using (var intermediate = new ImageSurface(Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height)) + using (var context = new Context(intermediate)) + { + Rect drawRect; + var transform = CalculateIntermediateTransform( + tileMode, + sourceRect, + destinationRect, + scale, + translate, + out drawRect); + var renderer = new Renderer(intermediate); + + context.Rectangle(drawRect.ToCairo()); + context.Clip(); + context.Transform(transform.ToCairo()); + renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB"), transform, drawRect); + + var result = new SurfacePattern(intermediate); + + if ((brush.TileMode & TileMode.FlipXY) != 0) + { + // TODO: Currently always FlipXY as that's all cairo supports natively. + // Support separate FlipX and FlipY by drawing flipped images to intermediate + // surface. + result.Extend = Extend.Reflect; + } + else + { + result.Extend = Extend.Repeat; + } + + if (brush.TileMode != TileMode.None) + { + var matrix = result.Matrix; + matrix.InitTranslate(-destinationRect.X, -destinationRect.Y); + result.Matrix = matrix; + } + + return result; + } + } + + /// + /// Calculates a translate based on a , a source and destination + /// rectangle and a scale. + /// + /// The brush. + /// The source rectangle. + /// The destination rectangle. + /// The scale factor. + /// A vector with the X and Y translate. + private static Vector CalculateTranslate( + TileBrush brush, + Rect sourceRect, + Rect destinationRect, + Vector scale) + { + var x = 0.0; + var y = 0.0; + var size = sourceRect.Size * scale; + + switch (brush.AlignmentX) + { + case AlignmentX.Center: + x += (destinationRect.Width - size.Width) / 2; + break; + case AlignmentX.Right: + x += destinationRect.Width - size.Width; + break; + } + + switch (brush.AlignmentY) + { + case AlignmentY.Center: + y += (destinationRect.Height - size.Height) / 2; + break; + case AlignmentY.Bottom: + y += destinationRect.Height - size.Height; + break; + } + + return new Vector(x, y); + } + + private static Size CalculateIntermediateSize( + TileMode tileMode, + Size targetSize, + Size destinationSize) + { + var result = tileMode == TileMode.None ? targetSize : destinationSize; + return result; + } + + private static Matrix CalculateIntermediateTransform( + TileMode tileMode, + Rect sourceRect, + Rect destinationRect, + Vector scale, + Vector translate, + out Rect drawRect) + { + var transform = Matrix.CreateTranslation(-sourceRect.Position) * + Matrix.CreateScale(scale) * + Matrix.CreateTranslation(translate); + Rect dr; + + if (tileMode == TileMode.None) + { + dr = destinationRect; + transform *= Matrix.CreateTranslation(destinationRect.Position); + } + else + { + dr = new Rect(destinationRect.Size); + } + + drawRect = dr; + + return transform; + } + } +} diff --git a/src/Gtk/Perspex.Cairo/Media/VisualBrushImpl.cs b/src/Gtk/Perspex.Cairo/Media/VisualBrushImpl.cs new file mode 100644 index 0000000000..634b2b38a5 --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/VisualBrushImpl.cs @@ -0,0 +1,14 @@ +using System; +using global::Cairo; + +namespace Perspex.Cairo.Media +{ + public class VisualBrushImpl : BrushImpl + { + public VisualBrushImpl(Perspex.Media.VisualBrush brush, Size destinationSize) + { + this.PlatformBrush = TileBrushes.CreateVisualBrush(brush, destinationSize); + } + } +} + diff --git a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj index 3232d64281..6e4155d610 100644 --- a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj +++ b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj @@ -32,22 +32,10 @@ 4 - - gtk-sharp-2.0 - - - glib-sharp-2.0 - - - gtk-sharp-2.0 - - - gtk-sharp-2.0 - - - ..\..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll - True - + + + + @@ -62,8 +50,9 @@ ..\..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll - - gtk-sharp-2.0 + + + ..\..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll @@ -72,21 +61,32 @@ + + + + + + + - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation {B09B78D8-9B26-48B0-9149-D64A2F120F3F} Perspex.Base + + {42472427-4774-4C81-8AFF-9F27B8E31721} + Perspex.Layout + {EB582467-6ABB-43A1-B052-E981BA910E3A} Perspex.SceneGraph @@ -97,7 +97,7 @@ - - {b09b78d8-9b26-48b0-9149-d64a2f120f3f} + {B09B78D8-9B26-48B0-9149-D64A2F120F3F} Perspex.Base diff --git a/src/Perspex.Application/Perspex.Application.csproj b/src/Perspex.Application/Perspex.Application.csproj index 775c869da9..9a16f9130b 100644 --- a/src/Perspex.Application/Perspex.Application.csproj +++ b/src/Perspex.Application/Perspex.Application.csproj @@ -77,10 +77,6 @@ - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -93,6 +89,9 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + diff --git a/src/Perspex.Base/Contract.cs b/src/Perspex.Base/Contract.cs index fb568841ca..95e2976474 100644 --- a/src/Perspex.Base/Contract.cs +++ b/src/Perspex.Base/Contract.cs @@ -1,6 +1,8 @@ // Copyright (c) The Perspex Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Runtime.CompilerServices; + namespace Perspex { using System; @@ -22,14 +24,13 @@ namespace Perspex /// The exception to throw if is false. /// /// The precondition. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Requires(bool condition) where TException : Exception, new() { -#if DEBUG if (!condition) { throw new TException(); } -#endif } } } diff --git a/src/Perspex.Base/Perspex.Base.csproj b/src/Perspex.Base/Perspex.Base.csproj index 0ab51860f1..2adf2545a2 100644 --- a/src/Perspex.Base/Perspex.Base.csproj +++ b/src/Perspex.Base/Perspex.Base.csproj @@ -78,14 +78,6 @@ - - ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll - True - - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -98,6 +90,12 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll + + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + @@ -105,7 +103,7 @@ - {415e048e-4611-4815-9cf2-d774e29079ac} + {415E048E-4611-4815-9CF2-D774E29079AC} NGenerics diff --git a/src/Perspex.Base/PerspexObjectExtensions.cs b/src/Perspex.Base/PerspexObjectExtensions.cs index c690d30996..cc595e0130 100644 --- a/src/Perspex.Base/PerspexObjectExtensions.cs +++ b/src/Perspex.Base/PerspexObjectExtensions.cs @@ -26,7 +26,13 @@ namespace Perspex Action action) where TTarget : PerspexObject { - return observable.Subscribe(e => action((TTarget)e.Sender, e)); + return observable.Subscribe(e => + { + if (e.Sender is TTarget) + { + action((TTarget)e.Sender, e); + } + }); } /// diff --git a/src/Perspex.Controls/Canvas.cs b/src/Perspex.Controls/Canvas.cs new file mode 100644 index 0000000000..950c7b3841 --- /dev/null +++ b/src/Perspex.Controls/Canvas.cs @@ -0,0 +1,202 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using Perspex.Input; + +namespace Perspex.Controls +{ + public class Canvas : Panel, INavigableContainer + { + /// + /// Defines the property. + /// + public static readonly PerspexProperty LeftProperty = + PerspexProperty.RegisterAttached("Left"); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty TopProperty = + PerspexProperty.RegisterAttached("Top"); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty RightProperty = + PerspexProperty.RegisterAttached("Right"); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty BottomProperty = + PerspexProperty.RegisterAttached("Bottom"); + + /// + /// Initializes static members of the class. + /// + static Canvas() + { + AffectsArrange(LeftProperty); + AffectsArrange(TopProperty); + AffectsArrange(RightProperty); + AffectsArrange(BottomProperty); + } + + /// + /// Gets the value of the Left attached property for a control. + /// + /// The control. + /// The control's left coordinate. + public static double GetLeft(PerspexObject element) + { + return element.GetValue(LeftProperty); + } + + /// + /// Sets the value of the Left attached property for a control. + /// + /// The control. + /// The left value. + public static void SetLeft(PerspexObject element, double value) + { + element.SetValue(LeftProperty, value); + } + + /// + /// Gets the value of the Top attached property for a control. + /// + /// The control. + /// The control's top coordinate. + public static double GetTop(PerspexObject element) + { + return element.GetValue(TopProperty); + } + + /// + /// Sets the value of the Top attached property for a control. + /// + /// The control. + /// The top value. + public static void SetTop(PerspexObject element, double value) + { + element.SetValue(TopProperty, value); + } + + /// + /// Gets the value of the Right attached property for a control. + /// + /// The control. + /// The control's right coordinate. + public static double GetRight(PerspexObject element) + { + return element.GetValue(RightProperty); + } + + /// + /// Sets the value of the Right attached property for a control. + /// + /// The control. + /// The right value. + public static void SetRight(PerspexObject element, double value) + { + element.SetValue(RightProperty, value); + } + + /// + /// Gets the value of the Bottom attached property for a control. + /// + /// The control. + /// The control's bottom coordinate. + public static double GetBottom(PerspexObject element) + { + return element.GetValue(BottomProperty); + } + + /// + /// Sets the value of the Bottom attached property for a control. + /// + /// The control. + /// The bottom value. + public static void SetBottom(PerspexObject element, double value) + { + element.SetValue(BottomProperty, value); + } + + /// + /// Gets the next control in the specified direction. + /// + /// The movement direction. + /// The control from which movement begins. + /// The control. + IInputElement INavigableContainer.GetControl(FocusNavigationDirection direction, IInputElement from) + { + // TODO: Implement this + return null; + } + + /// + /// Measures the control. + /// + /// The available size. + /// The desired size of the control. + protected override Size MeasureOverride(Size availableSize) + { + availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity); + + foreach (Control child in Children) + { + child.Measure(availableSize); + } + + return new Size(); + } + + /// + /// Arranges the control's children. + /// + /// The size allocated to the control. + /// The space taken. + protected override Size ArrangeOverride(Size finalSize) + { + foreach (Control child in Children) + { + double x = 0.0; + double y = 0.0; + double elementLeft = GetLeft(child); + + if (!double.IsNaN(elementLeft)) + { + x = elementLeft; + } + else + { + // Arrange with right. + double elementRight = GetRight(child); + if (!double.IsNaN(elementRight)) + { + x = finalSize.Width - child.DesiredSize.Width - elementRight; + } + } + + double elementTop = GetTop(child); + if (!double.IsNaN(elementTop) ) + { + y = elementTop; + } + else + { + double elementBottom = GetBottom(child); + if (!double.IsNaN(elementBottom)) + { + y = finalSize.Height - child.DesiredSize.Height - elementBottom; + } + } + + child.Arrange(new Rect(new Point(x, y), child.DesiredSize)); + } + + return finalSize; + } + } +} diff --git a/src/Perspex.Controls/Image.cs b/src/Perspex.Controls/Image.cs index 0782b51f2a..79b79c6141 100644 --- a/src/Perspex.Controls/Image.cs +++ b/src/Perspex.Controls/Image.cs @@ -73,29 +73,14 @@ namespace Perspex.Controls /// The desired size of the control. protected override Size MeasureOverride(Size availableSize) { - double width = 0; - double height = 0; - Vector scale = new Vector(); - if (Source != null) { - width = Source.PixelWidth; - height = Source.PixelHeight; - - if (Width > 0) - { - availableSize = new Size(Width, availableSize.Height); - } - - if (Height > 0) - { - availableSize = new Size(availableSize.Width, Height); - } - - scale = Stretch.CalculateScaling(availableSize, new Size(width, height)); + return new Size(Source.PixelWidth, Source.PixelHeight); + } + else + { + return new Size(); } - - return new Size(width * scale.X, height * scale.Y); } } } \ No newline at end of file diff --git a/src/Perspex.Controls/Panel.cs b/src/Perspex.Controls/Panel.cs index b3a95ca72c..0da3d2800e 100644 --- a/src/Perspex.Controls/Panel.cs +++ b/src/Perspex.Controls/Panel.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using Perspex.Collections; +using Perspex.Media; namespace Perspex.Controls { @@ -18,6 +19,12 @@ namespace Perspex.Controls /// public class Panel : Control, IReparentingControl, IPanel { + /// + /// Defines the property. + /// + public static readonly PerspexProperty BackgroundProperty = + Border.BackgroundProperty.AddOwner(); + private readonly Controls _children = new Controls(); private ILogical _childLogicalParent; @@ -57,6 +64,15 @@ namespace Perspex.Controls } } + /// + /// Gets or Sets Panel background brush. + /// + public Brush Background + { + get { return GetValue(BackgroundProperty); } + set { SetValue(BackgroundProperty, value); } + } + /// /// Requests that the visual children of the panel use another control as their logical /// parent. @@ -146,5 +162,21 @@ namespace Perspex.Controls InvalidateMeasure(); } + + /// + /// Renders the visual to a . + /// + /// The drawing context. + public override void Render(IDrawingContext context) + { + Brush background = Background; + if (background != null) + { + var renderSize = Bounds.Size; + context.FillRectange(background, new Rect(renderSize)); + } + + base.Render(context); + } } } diff --git a/src/Perspex.Controls/Perspex.Controls.csproj b/src/Perspex.Controls/Perspex.Controls.csproj index fe00a5d7dd..38d5486118 100644 --- a/src/Perspex.Controls/Perspex.Controls.csproj +++ b/src/Perspex.Controls/Perspex.Controls.csproj @@ -80,6 +80,7 @@ + @@ -169,14 +170,6 @@ - - ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll - True - - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -189,6 +182,12 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll + + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + @@ -196,7 +195,7 @@ - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation diff --git a/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj b/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj index e1b2142231..94bffe0f2e 100644 --- a/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj +++ b/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj @@ -40,7 +40,7 @@ - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation diff --git a/src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs b/src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs index 2dc9f2ea08..26dcaeb442 100644 --- a/src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs +++ b/src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs @@ -6,8 +6,10 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; using Perspex; +using Perspex.Input.Platform; using Perspex.Media; using Perspex.Media.Imaging; +using Splat; using TheArtOfDev.HtmlRenderer.Adapters; using TheArtOfDev.HtmlRenderer.Adapters.Entities; using TheArtOfDev.HtmlRenderer.Perspex.Utilities; @@ -108,5 +110,21 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters { return new FontAdapter(family.Name, size, style); } + + protected override void SetToClipboardInt(string html, string plainText) + { + SetToClipboardInt(plainText); + } + + protected override void SetToClipboardInt(string text) + { + Locator.Current.GetService().SetTextAsync(text); + } + + protected override void SetToClipboardInt(RImage image) + { + //Do not crash, just ignore + //TODO: implement image clipboard support + } } } diff --git a/src/Perspex.HtmlRenderer/HtmlControl.cs b/src/Perspex.HtmlRenderer/HtmlControl.cs index 2b42e6960c..3ea58487e4 100644 --- a/src/Perspex.HtmlRenderer/HtmlControl.cs +++ b/src/Perspex.HtmlRenderer/HtmlControl.cs @@ -112,7 +112,10 @@ namespace Perspex.Controls.Html = RoutedEvent.Register>("ImageLoad", RoutingStrategies.Bubble, typeof (HtmlControl)); - + static HtmlControl() + { + FocusableProperty.OverrideDefaultValue(typeof(HtmlControl), true); + } /// /// Creates a new HtmlPanel and sets a basic css for it's styling. diff --git a/src/Perspex.HtmlRenderer/Perspex.HtmlRenderer.csproj b/src/Perspex.HtmlRenderer/Perspex.HtmlRenderer.csproj index 197ca7634d..ef8f2edb78 100644 --- a/src/Perspex.HtmlRenderer/Perspex.HtmlRenderer.csproj +++ b/src/Perspex.HtmlRenderer/Perspex.HtmlRenderer.csproj @@ -1,5 +1,5 @@  - + 10.0 @@ -29,7 +29,7 @@ pdbonly true bin\Release\ - TRACE + TRACE;PCL prompt 4 @@ -136,11 +136,11 @@ - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation - {b09b78d8-9b26-48b0-9149-d64a2f120f3f} + {B09B78D8-9B26-48B0-9149-D64A2F120F3F} Perspex.Base @@ -148,15 +148,15 @@ Perspex.Controls - {62024b2d-53eb-4638-b26b-85eeaa54866e} + {62024B2D-53EB-4638-B26B-85EEAA54866E} Perspex.Input - {6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b} + {6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B} Perspex.Interactivity - {42472427-4774-4c81-8aff-9f27b8e31721} + {42472427-4774-4C81-8AFF-9F27B8E31721} Perspex.Layout @@ -164,7 +164,7 @@ Perspex.SceneGraph - {f1baa01a-f176-4c6a-b39d-5b40bb1b148f} + {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F} Perspex.Styling @@ -172,13 +172,14 @@ - + + ..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll + + ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll - True - + ..\..\packages\Rx-Interfaces.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Interfaces.dll - True diff --git a/src/Perspex.HtmlRenderer/packages.config b/src/Perspex.HtmlRenderer/packages.config index f23358716a..c5594cb5ab 100644 --- a/src/Perspex.HtmlRenderer/packages.config +++ b/src/Perspex.HtmlRenderer/packages.config @@ -4,4 +4,5 @@ + \ No newline at end of file diff --git a/src/Perspex.Input/Perspex.Input.csproj b/src/Perspex.Input/Perspex.Input.csproj index 3439d6b971..e9233cbf25 100644 --- a/src/Perspex.Input/Perspex.Input.csproj +++ b/src/Perspex.Input/Perspex.Input.csproj @@ -40,7 +40,7 @@ - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation @@ -114,10 +114,6 @@ - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -130,6 +126,9 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + diff --git a/src/Perspex.Interactivity/Perspex.Interactivity.csproj b/src/Perspex.Interactivity/Perspex.Interactivity.csproj index c9c659e4d9..1f18564d89 100644 --- a/src/Perspex.Interactivity/Perspex.Interactivity.csproj +++ b/src/Perspex.Interactivity/Perspex.Interactivity.csproj @@ -40,7 +40,7 @@ - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation @@ -69,10 +69,6 @@ - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -85,6 +81,9 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + diff --git a/src/Perspex.Layout/Perspex.Layout.csproj b/src/Perspex.Layout/Perspex.Layout.csproj index 38ab251150..70d6abb14e 100644 --- a/src/Perspex.Layout/Perspex.Layout.csproj +++ b/src/Perspex.Layout/Perspex.Layout.csproj @@ -40,11 +40,11 @@ - {415e048e-4611-4815-9cf2-d774e29079ac} + {415E048E-4611-4815-9CF2-D774E29079AC} NGenerics - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation @@ -69,14 +69,6 @@ - - ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll - True - - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -89,6 +81,12 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll + + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + diff --git a/src/Perspex.ReactiveUI/Perspex.ReactiveUI.csproj b/src/Perspex.ReactiveUI/Perspex.ReactiveUI.csproj index b0cd5cd67b..d891b601ea 100644 --- a/src/Perspex.ReactiveUI/Perspex.ReactiveUI.csproj +++ b/src/Perspex.ReactiveUI/Perspex.ReactiveUI.csproj @@ -1,5 +1,5 @@  - + 10.0 @@ -87,21 +87,17 @@ - + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - + ..\..\packages\Rx-Core.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Core.dll - True - + ..\..\packages\Rx-Interfaces.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Interfaces.dll - True - + ..\..\packages\Rx-Linq.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Linq.dll - True diff --git a/src/Perspex.SceneGraph/IVisual.cs b/src/Perspex.SceneGraph/IVisual.cs index 76ab95e6e6..7126558483 100644 --- a/src/Perspex.SceneGraph/IVisual.cs +++ b/src/Perspex.SceneGraph/IVisual.cs @@ -21,7 +21,7 @@ namespace Perspex public interface IVisual { /// - /// Gets the bounds of the scene graph node. + /// Gets the bounds of the scene graph node relative to its parent. /// Rect Bounds { get; } diff --git a/src/Perspex.SceneGraph/Media/ImageBush.cs b/src/Perspex.SceneGraph/Media/ImageBush.cs new file mode 100644 index 0000000000..1b3fd07d28 --- /dev/null +++ b/src/Perspex.SceneGraph/Media/ImageBush.cs @@ -0,0 +1,44 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using Perspex.Media.Imaging; + +namespace Perspex.Media +{ + /// + /// Paints an area with an . + /// + public class ImageBrush : TileBrush + { + /// + /// Defines the property. + /// + public static readonly PerspexProperty SourceProperty = + PerspexProperty.Register("Source"); + + /// + /// Initializes a new instance of the class. + /// + public ImageBrush() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The image to draw. + public ImageBrush(IBitmap source) + { + Source = source; + } + + /// + /// Gets or sets the image to draw. + /// + public IBitmap Source + { + get { return GetValue(SourceProperty); } + set { SetValue(SourceProperty, value); } + } + } +} diff --git a/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs b/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs index 1ebda2fe72..67cf73ce30 100644 --- a/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs +++ b/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs @@ -6,7 +6,7 @@ namespace Perspex.Media /// /// A brush that draws with a linear gradient. /// - public class LinearGradientBrush : GradientBrush + public sealed class LinearGradientBrush : GradientBrush { /// /// Defines the property. diff --git a/src/Perspex.SceneGraph/Media/RadialGradientBrush.cs b/src/Perspex.SceneGraph/Media/RadialGradientBrush.cs new file mode 100644 index 0000000000..f985ec4115 --- /dev/null +++ b/src/Perspex.SceneGraph/Media/RadialGradientBrush.cs @@ -0,0 +1,63 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Perspex.Media +{ + /// + /// Paints an area with a radial gradient. A focal point defines the beginning of the gradient, + /// and a circle defines the end point of the gradient. + /// + public sealed class RadialGradientBrush : GradientBrush + { + /// + /// Defines the property. + /// + public static readonly PerspexProperty CenterProperty = + PerspexProperty.Register( + nameof(Center), + RelativePoint.Center); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty GradientOriginProperty = + PerspexProperty.Register( + nameof(GradientOrigin), + RelativePoint.Center); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty RadiusProperty = + PerspexProperty.Register( + nameof(Radius), + 0.5); + + /// + /// Gets or sets the start point for the gradient. + /// + public RelativePoint Center + { + get { return GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + + /// + /// Gets or sets the location of the two-dimensional focal point that defines the beginning of the gradient. + /// + public RelativePoint GradientOrigin + { + get { return GetValue(GradientOriginProperty); } + set { SetValue(GradientOriginProperty, value); } + } + + /// + /// Gets or sets the horizontal and vertical radius of the outermost circle of the radial gradient. + /// + public double Radius + { + get { return GetValue(RadiusProperty); } + set { SetValue(RadiusProperty, value); } + } + } +} \ No newline at end of file diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index 660cbe38d7..4cf3651824 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -40,7 +40,7 @@ - {d211e587-d8bc-45b9-95a4-f297c8fa5200} + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation @@ -64,11 +64,12 @@ - + + @@ -97,6 +98,7 @@ + @@ -126,14 +128,6 @@ - - ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll - True - - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -146,6 +140,12 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll + + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + diff --git a/src/Perspex.SceneGraph/Visual.cs b/src/Perspex.SceneGraph/Visual.cs index a3733eb756..64eae2ff21 100644 --- a/src/Perspex.SceneGraph/Visual.cs +++ b/src/Perspex.SceneGraph/Visual.cs @@ -117,7 +117,7 @@ namespace Perspex } /// - /// Gets the bounds of the scene graph node. + /// Gets the bounds of the scene graph node relative to its parent. /// public Rect Bounds { diff --git a/src/Perspex.Styling/Perspex.Styling.csproj b/src/Perspex.Styling/Perspex.Styling.csproj index 5fe855077d..cd9816f9fc 100644 --- a/src/Perspex.Styling/Perspex.Styling.csproj +++ b/src/Perspex.Styling/Perspex.Styling.csproj @@ -65,10 +65,6 @@ - - ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll - True - ..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll @@ -81,6 +77,9 @@ ..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll + + ..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll + diff --git a/src/Perspex.Themes.Default/ButtonStyle.cs b/src/Perspex.Themes.Default/ButtonStyle.cs index fc9f9917a8..fb383100e8 100644 --- a/src/Perspex.Themes.Default/ButtonStyle.cs +++ b/src/Perspex.Themes.Default/ButtonStyle.cs @@ -30,8 +30,8 @@ namespace Perspex.Themes.Default { Setters = new[] { - new Setter(TemplatedControl.BackgroundProperty, new SolidColorBrush(0xffdddddd)), - new Setter(TemplatedControl.BorderBrushProperty, new SolidColorBrush(0xff707070)), + new Setter(TemplatedControl.BackgroundProperty, new SolidColorBrush(0xffaaaaaa)), + new Setter(TemplatedControl.BorderBrushProperty, new SolidColorBrush(0xffaaaaaa)), new Setter(TemplatedControl.BorderThicknessProperty, 2), new Setter(TemplatedControl.ForegroundProperty, new SolidColorBrush(0xff000000)), new Setter(Control.FocusAdornerProperty, new FuncTemplate(FocusAdornerTemplate)), @@ -44,22 +44,15 @@ namespace Perspex.Themes.Default { Setters = new[] { - new Setter(TemplatedControl.BackgroundProperty, new SolidColorBrush(0xffbee6fd)), - new Setter(TemplatedControl.BorderBrushProperty, new SolidColorBrush(0xff3c7fb1)), + new Setter(TemplatedControl.BorderBrushProperty, new SolidColorBrush(0xff888888)), }, }, new Style(x => x.OfType